<?xml version="1.0" encoding="UTF-8"?>
<!-- generator="bbPress/1.0.2" -->
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<title>LeafLabs Garden &#187; Topic: Fun with timings</title>
		<link>http://forums.leaflabs.com/topic.php?id=101</link>
		<description>A place to share, learn, and grow...</description>
		<language>en-US</language>
		<pubDate>Sat, 18 May 2013 22:34:50 +0000</pubDate>
		<generator>http://bbpress.org/?v=1.0.2</generator>
		<textInput>
			<title><![CDATA[Search]]></title>
			<description><![CDATA[Search all topics from these forums.]]></description>
			<name>q</name>
			<link>http://forums.leaflabs.com/search.php</link>
		</textInput>
		<atom:link href="http://forums.leaflabs.com/rss.php?topic=101" rel="self" type="application/rss+xml" />

		<item>
			<title>Silntknight on "Fun with timings"</title>
			<link>http://forums.leaflabs.com/topic.php?id=101&amp;page=4#post-2660</link>
			<pubDate>Tue, 16 Nov 2010 21:56:06 +0000</pubDate>
			<dc:creator>Silntknight</dc:creator>
			<guid isPermaLink="false">2660@http://forums.leaflabs.com/</guid>
			<description>&#60;p&#62;The flywheel actually has a magnet, as all current Briggs engine, AFAIK, use magneto ignition systems. Mine does at any rate.
&#60;/p&#62;</description>
		</item>
		<item>
			<title>Skids on "Fun with timings"</title>
			<link>http://forums.leaflabs.com/topic.php?id=101&amp;page=4#post-2643</link>
			<pubDate>Tue, 16 Nov 2010 18:20:21 +0000</pubDate>
			<dc:creator>Skids</dc:creator>
			<guid isPermaLink="false">2643@http://forums.leaflabs.com/</guid>
			<description>&#60;p&#62;Hi,&#60;br /&#62;
Interesting thread - I wish I understood it all!&#60;/p&#62;
&#60;p&#62;Earlier this year I played with hall effect sensor and an Arduino, I was looking at wheel speed but this would apply to crank shaft speed as well : it is possible to mount the magnet behind the hall sensor (i.e. static) and the sensor will trigger when some metal passes through the magnetic field, this metal could be a nut on a fly wheel and means that you don't have to fix the magnet to the crank shaft.  It is suppose to be possible to count the teeth on the starter ring as they pass the sensor.&#60;/p&#62;
&#60;p&#62;best wishes&#60;/p&#62;
&#60;p&#62;Simon
&#60;/p&#62;</description>
		</item>
		<item>
			<title>Silntknight on "Fun with timings"</title>
			<link>http://forums.leaflabs.com/topic.php?id=101&amp;page=4#post-2132</link>
			<pubDate>Sun, 31 Oct 2010 03:43:12 +0000</pubDate>
			<dc:creator>Silntknight</dc:creator>
			<guid isPermaLink="false">2132@http://forums.leaflabs.com/</guid>
			<description>&#60;p&#62;I guess the math wasn't as hard as I thought it would be. What do you think?&#60;/p&#62;
&#60;pre&#62;&#60;code&#62;/*
*ECU/EFI for Maple V1.0
*Copyright (c) 2010 Hari Ganti
*More stuff will go here later...
*/

//Pins in use: 15- pot, 17- pressure, 19- temp, 2- pulse, 3- intake valve, 4-corr_state, 5- exhaust valve, 6- corr_deg, 7- corr_injector, 8- corr_PWM, 9- kill, 11- injector, 12- spark

volatile int delta_t; //Period of the engine

volatile bool fire = false;

int corr_deg = 0; //Correction factor for spark timing- calibrated in degrees
int corr_injector = 0; //Correction factor for injection length- calibrated in counts (100us)
int corr_PWM = 0; //Correction factor for phase- calibrated in 100us
int exhaustDelay; //Delay after exhaust opens for intake to open (and exhaust to close)
int intakeDelay; //Delay after intake opens for injector to fire (and intake to close)
int a;
int b;
int c;
int p; //Manifold Absolute Pressure
int t; //Manifold Air Temp
int pulseDelay; //Pulse length time (in microseconds)
int sparkDelay; //Delay after injector fires (in microseconds)
int tach; //Tachometer

void setup() {
  pinMode(15, INPUT_ANALOG);
  pinMode(17, INPUT_ANALOG);
  pinMode(19, INPUT_ANALOG);
  pinMode(2, INPUT_PULLDOWN);
  pinMode(4, INPUT_PULLDOWN);
  pinMode(6, INPUT_PULLDOWN);
  pinMode(7, INPUT_PULLDOWN);
  pinMode(8, INPUT_PULLDOWN);
  pinMode(9, INPUT_PULLDOWN);
  pinMode(3, PWM);
  pinMode(5, PWM);
  pinMode(11, PWM);
  pinMode(12, OUTPUT);
  Timer2.setPeriod(6553500); //Pin 3- Intake
  Timer4.setPeriod(6553500); //Pin 5- Exhaust
  Timer3.setPeriod(6553500); //6.5535 sec, 65535 counts/cycle, 10986496 clocks/cycle
  Timer3.setChannel2Mode(TIMER_OUTPUTCOMPARE);
  Timer3.attachCompare2Interrupt(spark);
  attachInterrupt(0, pulse, RISING); //Trigger void pulse when sensor is deactivated (digital pin 2)- can be changed if needed
  attachInterrupt(8, corrDeg, RISING); //Trigger void corrDeg when button is pushed
  attachInterrupt(9, corrInjector, RISING); //Trigger void corrInjector when button is pushed
  attachInterrupt(6, corrPWM, RISING); //Trigger void corr3 when button is pushed
}

void loop() { //The fun stuff goes on here
  if (digitalRead(9) == LOW) {
    delta_t = 50*delta_t;
    //
    exhaustDelay = delta_t/200;
    pwmWrite(5, exhaustDelay); //Exhaust valve control
    b = 65536-exhaustDelay; //65535 or 65536?
    //
    intakeDelay = (analogRead(15)*150)/4096; //Servo PWM duty cycle
    a = (delta_t*intakeDelay)/36000;
    pwmWrite(3, a); //Intake valve control
    c = b-a;
    //
    p = ((analogRead(17)-164)*230)/3850+20; //MAP actual (kPa)
    //
    t = (analogRead(19)*500)/4096; //MAT actual (K)
    //The following is no longer accurate- D (evacuation) must be a function of intakeDelay
    pulseDelay = ((100*2029712256)/2478997185)*(p/t); //Injector delay length
    //pulseDelay = (818763437/10000000)*(p/t); //Simplified, less accurate- compare graphs later
    pulseDelay = pulseDelay + corr_injector;
    pwmWrite(11, pulseDelay);
    //
    sparkDelay = ((77+corr_deg)*delta_t)/36000; //Delay before spark fires
    Timer3.setCompare2(sparkDelay);
    //
    tach = 60000000/delta_t;
  } else {
    delayMicroseconds(5);
    if (digitalRead(9) == LOW) {
      delay(1000);
    }
  }
}

void pulse() { //Synchronize the PWM for the fuel injector
  if (fire == false) {
    delta_t = Timer3.getCount(); //Get twice the period in microseconds
    if (corr_3 == 0) { //Reset the timer
      Timer3.setCount(c);
      Timer2.setCount(b);
      Timer4.setCount(0);
    } else { //&#38;quot;Reset&#38;quot; the timer
      Timer3.setCount(c-corr_PWM);
      Timer2.setCount(b-corr_PWM);
      Timer4.setCount(65536-corr_PWM); //65535 or 65536?
    }
    fire = true;
  } else {
    fire = false;
  }
}

void spark() { //Ignite the spark plug
  digitalWrite(12, HIGH);
  delayMicroseconds(3); //Check if it&#38;#39;s necessary
  digitalWrite(12, LOW)
}

void corrDeg() { //Diagnostic spark timing utility
  delayMicroseconds(5);
  if (digitalRead(6) == HIGH) {
    if (digitalRead(4) == HIGH) {
      corr_deg++;
    } else {
      core_deg--;
    }
  }
}

void corrInjector() { //Diagnostic injector length utility
  delayMicroseconds(5);
  if (digitalRead(7) == HIGH) {
    if (digitalRead(4) == HIGH) {
      corr_injector++;
    } else {
      corr_injector--;
    }
  }
}

void corrPWM() { //Diagnostic PWM phase utility
  delayMicroseconds(5);
  if (digitalRead(8) == HIGH) {
    corr_PWM++;
  }
}&#60;/code&#62;&#60;/pre&#62;
&#60;p&#62;The code is much more complicated than before. I am actually changing timer count values even more than before. Basically, the timers are all synchronized to the same pulse. The synchronization happens once every TWO pulse signals though (twice the period). Below is a phase diagram of the PWMs (represented by their timers) and the spark interrupt in order of occurrence:&#60;br /&#62;
&#60;pre&#62;&#60;code&#62;Engine: &#124;----------&#124;----------&#124;----------&#124;----------&#124;----------&#124;----------&#124;
Timer4: /-----\---------------/-----\---------------/-----\----------------
Timer2: ------/-----\---------------/-----\---------------/-----\----------
Timer3: ------------/-----\---------------/-----\---------------/-----\----
Spark:  -------------------/-\-------------------/-\-------------------/-\-&#60;/code&#62;&#60;/pre&#62;
&#60;p&#62;Hopefully that illustrates the timings a little better.
&#60;/p&#62;</description>
		</item>
		<item>
			<title>Silntknight on "Fun with timings"</title>
			<link>http://forums.leaflabs.com/topic.php?id=101&amp;page=4#post-2130</link>
			<pubDate>Sat, 30 Oct 2010 18:24:25 +0000</pubDate>
			<dc:creator>Silntknight</dc:creator>
			<guid isPermaLink="false">2130@http://forums.leaflabs.com/</guid>
			<description>&#60;p&#62;I'd really like to use one timer to control multiple signals, but I'm not sure if that's possible. From what I know, even if I put all the signal outputs on the same timer (pins controlled by that timer), I couldn't get phase shifts. By that I mean that the signal is sent on the 0 count no matter what, and I can set a multi-phase output. See below:&#60;br /&#62;
Signal sent at the normal time (on the vertical)&#60;br /&#62;
Timer 1: --&#124;-------&#124;-------&#124;-------&#124;-------&#124;-------&#124;-------&#124;-------&#124;-------&#124;--&#60;br /&#62;
Timer 2: -----&#124;-------&#124;-------&#124;-------&#124;-------&#124;-------&#124;-------&#124;-------&#124;-------&#124;--&#60;br /&#62;
Timer 3: ------&#124;-------&#124;-------&#124;-------&#124;-------&#124;-------&#124;-------&#124;-------&#124;-------&#124;--&#60;br /&#62;
I would like:&#60;br /&#62;
Timer    : &#124;-o--vr-&#124;-o--vr-&#124;-o--vr-&#124;-o--vr-&#124;-o--vr-&#124;-o--vr-&#124;-o--vr-&#124;-o--vr-&#124;-o--vr-&#124;&#60;br /&#62;
I already have the timer configured to reset at the correct time. It resets based on the Hall being activated. For now, we'll just assume that the engine is at constant rpm because it is easier. RPM won't actually change the underlying idea anyway, because phase shifts are independent of period. I hope my ASCII (or maybe Unicode) drawing helps you all to understand what I mean.
&#60;/p&#62;</description>
		</item>
		<item>
			<title>Silntknight on "Fun with timings"</title>
			<link>http://forums.leaflabs.com/topic.php?id=101&amp;page=3#post-2127</link>
			<pubDate>Sat, 30 Oct 2010 17:41:44 +0000</pubDate>
			<dc:creator>Silntknight</dc:creator>
			<guid isPermaLink="false">2127@http://forums.leaflabs.com/</guid>
			<description>&#60;p&#62;I have another idea... This one is much more abstract, though there is a precedent for this (&#60;a href=&#34;http://me.engin.umich.edu/autolab/Publications/Adobe/P1998_02.PDF)&#34; rel=&#34;nofollow&#34;&#62;http://me.engin.umich.edu/autolab/Publications/Adobe/P1998_02.PDF)&#60;/a&#62;. I am currently using a throttle plate (like just about every engine) to control the amount of air entering the cylinder. Assuming I can do the math right (not hard if I really sit down and do it), I could try another method of throttling that solves all the problems we have so far. Unfortunately, it adds a few dozen more; though, to be fair, they are more math oriented problems so I'd rather deal with them anyway. I am thinking about doing away with the camshaft altogether. Instead, I will use solenoids with return springs to control the valves. I wanted to make it overhead valves (OHV) from L-Head anyway, this makes it even easier, I guess. The idea is then that instead of using a throttle plate, which causes losses in energy from throttling, I just adjust the time that the intake valve is open. I had already decided to implement a Miller Cycle conversion (&#60;a href=&#34;http://www.howstuffworks.com/question132.htm)&#34; rel=&#34;nofollow&#34;&#62;http://www.howstuffworks.com/question132.htm)&#60;/a&#62;. Originally, I was going to modify the camshaft lobes to change how long the valve is open for. Now, I can just adjust that at will. I get the feeling that doing this right would do away with every problem from actually modifying camshaft lobes to determining stroke. As far as the latter goes, think of it this way. The engine just moves a piston up and down. If I choose when to open the valves (provided I use a Hall to time it right), then the stroke is always deterministic. I like this solution because it is, theoretically, the simplest. What do you all think? To be honest, I am finally unnerved by this modification just because it is so advanced. Most cars don't even have fully electric valve control.
&#60;/p&#62;</description>
		</item>
		<item>
			<title>Silntknight on "Fun with timings"</title>
			<link>http://forums.leaflabs.com/topic.php?id=101&amp;page=3#post-2125</link>
			<pubDate>Sat, 30 Oct 2010 14:42:59 +0000</pubDate>
			<dc:creator>Silntknight</dc:creator>
			<guid isPermaLink="false">2125@http://forums.leaflabs.com/</guid>
			<description>&#60;p&#62;If you can tell me how I can test this on a computer, I'd love to hear it. Otherwise, I am working on getting a Maple right now (school-sponsored project = delays).&#60;/p&#62;
&#60;p&#62;I am getting both anyway. I found a Hall for about a dollar and my reed switch was the same, so it doesn't matter to me which is better because I am getting both.&#60;/p&#62;
&#60;blockquote&#62;&#60;p&#62;I am not sure they are put inside the crankcase of an engine.&#60;/p&#62;&#60;/blockquote&#62;
&#60;p&#62;This is very true, and I am aware that very little is actually in the crankcase. Still, the temperatures really aren't that high. Most of the heat is contained in the cylinder (or so we hope).&#60;/p&#62;
&#60;blockquote&#62;&#60;p&#62;I think I'd avoid welding a magnet to the crankshaft.&#60;br /&#62;
Is the flywheel running at the same speed as the engine?&#60;/p&#62;&#60;/blockquote&#62;
&#60;p&#62;I think it would be fine to weld to these, though I meant camshaft when I said crankshaft. And yes, the flywheel is directly connected to the crankshaft so it spins at the same speed. It also has a magnet on it, for the magneto. Like I said (elsewhere maybe), the crank and the engine turn at twice the rate I need them to, and I can't be sure of what cycle the engine is on. I was thinking that I could use some clever gearing and attach sprockets to the flywheel and have those sprockets turn at half the speed. Probably a better idea, the sprockets could be attached to the crankshaft so that the gears can be smaller. Then the Hall/reed can be externally mounted and everything operates at the right time.
&#60;/p&#62;</description>
		</item>
		<item>
			<title>gbulmer on "Fun with timings"</title>
			<link>http://forums.leaflabs.com/topic.php?id=101&amp;page=3#post-2110</link>
			<pubDate>Fri, 29 Oct 2010 04:08:30 +0000</pubDate>
			<dc:creator>gbulmer</dc:creator>
			<guid isPermaLink="false">2110@http://forums.leaflabs.com/</guid>
			<description>&#60;p&#62;A quick comment (off to work)&#60;/p&#62;
&#60;p&#62;The code is looking good. Have you got an approach to testing it? Are you testing this on an ordinary computer to see how it works? &#60;/p&#62;
&#60;blockquote&#62;&#60;p&#62;what are your takes on reed switch vs. Hall sensors? The former is less expensive and I can get something like twenty and just play around with them for the same cost as a Hall.&#60;/p&#62;
&#60;/blockquote&#62;
&#60;p&#62;I am definitely not an expert on these things. I know that an awful lot of telephone systems used reed switches, so they are very reliable under normal &#34;office&#34; conditions. I am concerned that the vibration and heat combined might stress them. If this is a school project, where the engine only runs for short periods, you might be okay.&#60;/p&#62;
&#60;p&#62;I know that Hall sensors are used a lot in the auto industry, but now that I think about it, I am not sure they are put inside the crankcase of an engine. What sort of temperature does that reach? Clearly cooler than boiling oil :-)&#60;/p&#62;
&#60;p&#62;I think I'd avoid welding a magnet to the crankshaft.&#60;br /&#62;
Is the flywheel running at the same speed as the engine?&#60;/p&#62;
&#60;p&#62;Maybe Mr Google can help with some of the questions? I can ask questions, but I feel out of my comfort zone.
&#60;/p&#62;</description>
		</item>
		<item>
			<title>Silntknight on "Fun with timings"</title>
			<link>http://forums.leaflabs.com/topic.php?id=101&amp;page=3#post-2103</link>
			<pubDate>Fri, 29 Oct 2010 00:13:50 +0000</pubDate>
			<dc:creator>Silntknight</dc:creator>
			<guid isPermaLink="false">2103@http://forums.leaflabs.com/</guid>
			<description>&#60;p&#62;I thought I could edit past posts, but I guess I can only do so relatively quickly after the latest one. Anyway, here is my new code. I had intended to just edit the one in which I posted it before:&#60;/p&#62;
&#60;pre&#62;&#60;code&#62;/*
*ECU/EFI for Maple V1.0
*Copyright (c) 2010 Hari Ganti
*More stuff will go here later...
*/

//Pins in use: 15- pot, 17- pressure, 19- temp, 2- pulse, 3- corr_deg, 4- corr_injector, 5- corr_PWM, 8- corr_state, 9- kill, 11- injector, 12- spark, 14- servo

volatile int delta_t; //Period of the engine

int corr_deg = 0; //Correction factor for spark timing- calibrated in degrees
int corr_injector = 0; //Correction factor for injection length- calibrated in counts (100us)
int corr_PWM = 0; //Correction factor for spark length- calibrated in microseconds
int a; //Servo PWM
int p; //Manifold Absolute Pressure
int t; //Manifold Air Temp
int pulseDelay; //Pulse length time (in microseconds)
int sparkDelay; //Delay after injector fires (in microseconds)
int tach; //Tachometer

void setup() {
  pinMode(15, INPUT_ANALOG);
  pinMode(17, INPUT_ANALOG);
  pinMode(19, INPUT_ANALOG);
  pinMode(2, INPUT_PULLDOWN);
  pinMode(3, INPUT_PULLDOWN);
  pinMode(4, INPUT_PULLDOWN);
  pinMode(5, INPUT_PULLDOWN);
  pinMode(8, INPUT_PULLDOWN);
  pinMode(9, INPUT_PULLDOWN);
  pinMode(11, PWM);
  pinMode(14, PWM);
  pinMode(12, OUTPUT);
  Timer4.setPeriod(20000); //20ms
  Timer3.setPeriod(period); //6.5535 sec, 65535 counts/cycle, 10986496 clocks/cycle
  Timer3.setChannel2Mode(TIMER_OUTPUTCOMPARE);
  Timer3.attachCompare2Interrupt(spark);
  attachInterrupt(0, pulse, RISING); //Trigger void pulse when sensor is deactivated (digital pin 2)- can be changed if needed
  attachInterrupt(1, corrDeg, RISING); //Trigger void corrDeg when button is pushed
  attachInterrupt(5, corrInjector, RISING); //Trigger void corrInjector when button is pushed
  attachInterrupt(6, corrPWM, RISING); //Trigger void corrPWM when button is pushed
}

void loop() { //The fun stuff goes on here
  if (digitalRead(9) == LOW) {
    a = (analogRead(15)*2949)/4096+1966; //Servo PWM duty cycle
    pwmWrite(14, a); //Servo control from 0 to 90
    //
    p = ((analogRead(17)-164)*230)/3850+20; //MAP actual (kPa)
    //
    t = (analogRead(19)*500)/4096; //MAT actual (K)
    //
    pulseDelay = ((100*2029712256)/2478997185)*(p/t); //Injector delay length
    //pulseDelay = (818763437/10000000)*(p/t); //Simplified, less accurate- compare graphs later
    pulseDelay = pulseDelay + corr_injector;
    pwmWrite(11, pulseDelay);
    //
    delta_t = delta_t/2;
    //
    sparkDelay = ((77+corr_deg)*delta_t)/36000; //Delay before spark fires
    Timer3.setCompare2(sparkDelay);
    //
    tach = 60000000/delta_t;
  } else {
    delayMicroseconds(5);
    if (digitalRead(9) == LOW) {
      delay(1000);
    }
  }
}

void pulse() { //Synchronize the PWM for the fuel injector
  delta_t = Timer3.getCount(); //Get twice the period in microseconds
  Timer3.setCount(0+corr_PWM); //Reset the timer
}

void spark() { //Ignite the spark plug
  digitalWrite(12, HIGH);
  delayMicroseconds(3); //Check if it&#38;#39;s necessary
  digitalWrite(12, LOW)
}

void corrDeg() { //Diagnostic spark timing utility
  delayMicroseconds(5);
  if (digitalRead(3) == HIGH) {
    if (digitalRead(8) == HIGH) {
      corr_deg++;
    } else {
      core_deg--;
    }
  }
}

void corrInjector() { //Diagnostic injector length utility
  delayMicroseconds(5);
  if (digitalRead(4) == HIGH) {
    if (digitalRead(8) == HIGH) {
      corr_injector++;
    } else {
      corr_injector--;
    }
  }
}

void corrPWM() { //Diagnostic PWM phase utility
  delayMicroseconds(5);
  if (digitalRead(5) == HIGH) {
    if (digitalRead(8) == HIGH) {
      corr_PWM++;
    } else {
      corr_PWM--;
    }
  }
}&#60;/code&#62;&#60;/pre&#62;</description>
		</item>
		<item>
			<title>Silntknight on "Fun with timings"</title>
			<link>http://forums.leaflabs.com/topic.php?id=101&amp;page=3#post-2102</link>
			<pubDate>Thu, 28 Oct 2010 22:34:09 +0000</pubDate>
			<dc:creator>Silntknight</dc:creator>
			<guid isPermaLink="false">2102@http://forums.leaflabs.com/</guid>
			<description>&#60;p&#62;Poslathian, that seems like an incredibly robust system. The problem is that I am a high schooler working in a woodshop with relatively few metalworking tools, let alone anything to get a nicely set up system like that. I never said this before, so I understand the assumption that I would be able to do that. That's just for the idea about multiple sensor breaks. The code aspect is possible, but the engine speed doesn't change appreciably between intake valve openings, especially above 1200 rpm. I might use your idea about basing the period on the actual period. It might add a little math, but it would, hopefully, make the code run more reliably. What do you think? If I adjust the period, it makes the math run slower because I add another instruction (divide) to each step that requires timer calculations. The rest is very close to what I have (as I understand it), so it's good to see that you agree! Quick question, I am pretty sure that if I initialize a variable and assign a value before the setup, it only does that once, so it can be changed in the loop and will not revert to the original value. Am I right?&#60;/p&#62;
&#60;p&#62;Gbulmer, to be honest, I hate the idea of a Hall on the crankshaft just because it has such a small diameter that I might get false reads, but I'll check that out on my own. Much as I hate it, I think that is what I am going to do. I'll just weld a small magnet to the crank (and hope the heat from welding doesn't affect the magnetic properties!) I'm sure I can come up with a mount that keeps both parts vibrating the same amount so that it is steady in the crankcase.&#60;/p&#62;
&#60;p&#62;Poslathian and Gbulmer, what are your takes on reed switch vs. Hall sensors? The former is less expensive and I can get something like twenty and just play around with them for the same cost as a Hall.&#60;/p&#62;
&#60;p&#62;I realized that Timer3.getCount() returns a uint16, not the actual microseconds since the last pulse. I am going to modify the code with the parts I stated in this post. Thanks, both of you.&#60;/p&#62;
&#60;p&#62;EDIT: I'm actually not going to have the period for the PWM be based on the real engine period. It makes the code way to complicated, at least for me. I'm not too sure of how much of a benefit it will have either.
&#60;/p&#62;</description>
		</item>
		<item>
			<title>gbulmer on "Fun with timings"</title>
			<link>http://forums.leaflabs.com/topic.php?id=101&amp;page=3#post-2098</link>
			<pubDate>Thu, 28 Oct 2010 18:12:46 +0000</pubDate>
			<dc:creator>gbulmer</dc:creator>
			<guid isPermaLink="false">2098@http://forums.leaflabs.com/</guid>
			<description>&#60;blockquote&#62;&#60;p&#62;I'm starting to get the terrible feeling that there are no button switches that have high electrical isolation. To make things worse, the only switch I saw that had a datasheet was rated for no more than 200 throws/min. I'm going to be revving the engine up to 4000 rpm... Anyone have ideas? I am starting to consider attaching a Hall to the crankshaft, though adding a magnet and calibrating it will be terrible. &#60;/p&#62;&#60;/blockquote&#62;
&#60;p&#62;Use a Hall switch. They are fast (1.5uS switch time), and quite robust as there are no physical switch contacts.&#60;/p&#62;
&#60;p&#62;Maybe you can attach the magnet to some part of the crankshaft to make calibration easier.
&#60;/p&#62;</description>
		</item>
		<item>
			<title>poslathian on "Fun with timings"</title>
			<link>http://forums.leaflabs.com/topic.php?id=101&amp;page=3#post-2093</link>
			<pubDate>Thu, 28 Oct 2010 01:59:49 +0000</pubDate>
			<dc:creator>poslathian</dc:creator>
			<guid isPermaLink="false">2093@http://forums.leaflabs.com/</guid>
			<description>&#60;p&#62;This may have been said before, but heres an idea for an overall design:&#60;/p&#62;
&#60;p&#62;1) use whatever mechanism you like to measure the frequency of your engine, you can use a hall sensor with a gain stage so that you get a nice pulse at the same point in the stroke, or you can use some other mechanical trick, like a beam break sensor...anything that will give you a pulse once per stroke at the same point in the cycle. You can even put multiple of these sensors in such a way that they trigger in sequence during a single stroke (such as a beam break sensor with 8 fins on your output shaft, so youll get 8 ticks per turn). This way you can update your estimate of your engine period more than once per cycle. You can take this to the limit and build what is effectively and encoder. &#60;/p&#62;
&#60;p&#62;2) attach this pulse input to an external interrupt. At each pulse, update your estimate of the motor period and get out of the ISR (interrupt)!&#60;/p&#62;
&#60;p&#62;3) setup a single timer, with a total period of your engine stroke period. You can change this period throughout the program in 2&#60;/p&#62;
&#60;p&#62;4) setup multiple outputcompare interrupt channels on this single timer. I think you can get up to 4. Set each channel compareval to go off at the right time in the stroke. You can adjust these with your motor period, or not depending on how you set things up.&#60;/p&#62;
&#60;p&#62;5) each output compare fires a different interrupt to do whatever, fire your relays and such.
&#60;/p&#62;</description>
		</item>
		<item>
			<title>Silntknight on "Fun with timings"</title>
			<link>http://forums.leaflabs.com/topic.php?id=101&amp;page=3#post-2092</link>
			<pubDate>Thu, 28 Oct 2010 00:52:49 +0000</pubDate>
			<dc:creator>Silntknight</dc:creator>
			<guid isPermaLink="false">2092@http://forums.leaflabs.com/</guid>
			<description>&#60;p&#62;I'm starting to get the terrible feeling that there are no button switches that have high electrical isolation. To make things worse, the only switch I saw that had a datasheet was rated for no more than 200 throws/min. I'm going to be revving the engine up to 4000 rpm... Anyone have ideas? I am starting to consider attaching a Hall to the crankshaft, though adding a magnet and calibrating it will be terrible.
&#60;/p&#62;</description>
		</item>
		<item>
			<title>Silntknight on "Fun with timings"</title>
			<link>http://forums.leaflabs.com/topic.php?id=101&amp;page=3#post-2091</link>
			<pubDate>Wed, 27 Oct 2010 23:39:41 +0000</pubDate>
			<dc:creator>Silntknight</dc:creator>
			<guid isPermaLink="false">2091@http://forums.leaflabs.com/</guid>
			<description>&#60;blockquote&#62;&#60;p&#62;What is the valve position sensor currently?&#60;/p&#62;&#60;/blockquote&#62;
&#60;p&#62;It is mechanical. I was going to use a simple switch. I am going to modify the engine to use rocker arms with pushrods instead of its current system. As the rocker arm moves, it will also depress the switch. A Hall wouldn't really work (see the other thread about that).&#60;/p&#62;
&#60;blockquote&#62;&#60;p&#62;You could program the spark handler just to start another timer which delivers the right duration of spark pulse.&#60;/p&#62;&#60;/blockquote&#62;
&#60;p&#62;What exactly do you mean? The spark's duration shouldn't change all too much. I just need to test it to see if not having a delay causes problems later down the line. What's funny is that this controls a solid state relay, which controls an ignition coil, which controls the spark. As far as the spark duration goes, I would be fine with adding a separate timer for that, provided it didn't make the interrupt last longer. Later, I'll be running this on the engine with a diagnostic version of the code so that I can manually adjust things like injector pulse length, spark delay, and spark pulse length.&#60;br /&#62;
Now that I think about it more, I will definitely add an LCD to the setup. If a computer isn't present, I can use it to debug the code.
&#60;/p&#62;</description>
		</item>
		<item>
			<title>gbulmer on "Fun with timings"</title>
			<link>http://forums.leaflabs.com/topic.php?id=101&amp;page=3#post-2081</link>
			<pubDate>Wed, 27 Oct 2010 20:38:29 +0000</pubDate>
			<dc:creator>gbulmer</dc:creator>
			<guid isPermaLink="false">2081@http://forums.leaflabs.com/</guid>
			<description>&#60;p&#62;Quick one - on my way to land of nod&#60;/p&#62;
&#60;p&#62;Wow! Looking good.&#60;/p&#62;
&#60;p&#62;What is the valve position sensor currently? Is it mechanical? I would have imagined Hall effect just for robustness, in which case, it make not need anything doing to the signal.&#60;/p&#62;
&#60;p&#62;Side note. You could program the spark handler just to start another timer which delivers the right duration of spark pulse.
&#60;/p&#62;</description>
		</item>
		<item>
			<title>Silntknight on "Fun with timings"</title>
			<link>http://forums.leaflabs.com/topic.php?id=101&amp;page=3#post-2075</link>
			<pubDate>Wed, 27 Oct 2010 19:37:55 +0000</pubDate>
			<dc:creator>Silntknight</dc:creator>
			<guid isPermaLink="false">2075@http://forums.leaflabs.com/</guid>
			<description>&#60;p&#62;I think it's done:&#60;br /&#62;
&#60;pre&#62;&#60;code&#62;/*ECU/EFI for Maple V1.0
*Copyright (c) 2010 Hari Ganti
*More stuff will go here later...
*/

//Pins in use: 15- pot, 17- pressure, 19- temp, 2- interrupt, 3- kill, 11- injector, 12- spark, 14- servo

volatile int delta_t; //Period of the engine

int corr = 0; //Correction factor for spark timing based on rpm (or fuel pulse grams or both...)
int a; //Servo PWM
int p; //Manifold Absolute Pressure
int t; //Manifold Air Temp
int pulseDelay; //Pulse length time (in microseconds)
int sparkDelay; //Delay after injector fires (in microseconds)
int tach = 0; //Tachometer

void setup() {
  pinMode(15, INPUT_ANALOG);
  pinMode(17, INPUT_ANALOG);
  pinMode(19, INPUT_ANALOG);
  pinMode(2, INPUT_PULLDOWN);
  pinMode(3, INPUT_PULLUP);
  pinMode(11, PWM);
  pinMode(14, PWM);
  pinMode(12, OUTPUT);
  Timer4.setPeriod(20000); //20ms
  Timer3.setPeriod(6553500); //6.5535 sec, 65535 counts/cycle, 10986496 clocks/cycle
  Timer3.setChannel2Mode(TIMER_OUTPUTCOMPARE);
  Timer3.attachCompare2Interrupt(spark);
  attachInterrupt(0, pulse, FALLING); //Trigger void pulse when sensor is deactivated (digital pin 2)
}

void loop() { //The fun stuff goes on here
  if (digitalRead(3) == LOW) {
    a = (analogRead(15)*2949)/4096+1966; //Servo PWM duty cycle
    pwmWrite(14, a); //Servo control from 0 to 90
    p = ((analogRead(17)-164)*230)/3850+20; //MAP actual (kPa)
    t = (analogRead(19)*500)/4096; //MAT actual (K)
    pulseDelay = 10*(((.79*2*14.01+.21*2*16)*7920*.148*.6)/(.0821*14.9*101.325*20))*(MAP/MAT); //Stoichiometry
    pwmWrite(11, pulseDelay);
    delta_t = delta_t/2;
    sparkDelay = (7.79*delta_t)/360; //Delay before spark fires
    Timer3.setCompare2(sparkDelay);
    tach = 60000000/delta_t;
  } else {
    delayMicroseconds(5);
    if (digitalRead(3) == LOW) {
      delay(1000);
    }
  }
}

void pulse() { //Synchronize the PWM for the fuel injector
  delta_t = Timer3.getCount(); //Get twice the period in microseconds
  Timer3.setCount(0); //Reset the timer
}

void spark() { //Ignite the spark plug
  digitalWrite(12, HIGH);
  delayMicroseconds(3); //Check if it&#38;#39;s necessary
  digitalWrite(12, LOW)
}&#60;/code&#62;&#60;/pre&#62;
&#60;p&#62;I just need to know if &#60;code&#62;Timer3.getCount();&#60;/code&#62; returns microseconds or what. As Poslathian suggested on another thread (&#60;a href=&#34;http://forums.leaflabs.com/topic.php?id=262)&#34; rel=&#34;nofollow&#34;&#62;http://forums.leaflabs.com/topic.php?id=262)&#60;/a&#62;, I added a debounce to the kill switch. I'm not sure how to do that for the valve position sensor because it is run on an interrupt and VERY time sensitive. I might just have to get a really good switch with high electrical isolation (thinking solid state relay).
&#60;/p&#62;</description>
		</item>

	</channel>
</rss>
