Model Engine Ignitions

Home Model Engine Machinist Forum

Help Support Home Model Engine Machinist Forum:

This site may earn a commission from merchant affiliate links, including eBay, Amazon, and others.
I've not used the pulseln function - I'll have to look into that one. Yes, absolutely agree on keeping serial communication out of ISRs, and if the main loop handles ...


Just to be pendantic ... a 16MHz clock gives a .0625 millisecond cycle, which is to say, a 62.5 nanosecond cycle, or a .0000625 second cycle. :)

And to be a Pain In The A** more pedantic , a 16 MHz clock is .0625 microsecond cycle. You correctly had that as 62.5 nanoseconds but then wrote the decimal as 62.5 microseconds.

The Rarely Stated Laws of the Universe includes one that covers this. It's also included as a corollary of Murphy's Law.

When correcting someone else's error, the chance of the corrector introducing their own mistake approaches 1.0.
 
And to be a Pain In The A** more pedantic , a 16 MHz clock is .0625 microsecond cycle. You correctly had that as 62.5 nanoseconds but then wrote the decimal as 62.5 microseconds.

The Rarely Stated Laws of the Universe includes one that covers this. It's also included as a corollary of Murphy's Law.

When correcting someone else's error, the chance of the corrector introducing their own mistake approaches 1.0.
Where's the egg-on-my-face icon when I need it! Thanks, Bob. So that means that I was also wrong on .0000625 seconds - that one should be milliseconds instead. Sigh ... it's been a long, long time since I made a living bit-banging code and counting cycles, but I'm starting to remember one of the things on which I always had to check myself at least three times! Thank goodness I never had to do this with the multiple-gigahertz clocks of modern CPUs ... it would only be a matter of time before I substituted a femtosecond for a picosecond, and before you know it, I would have my code scheduled to complete before it started! :)
 
I rarely worked at frequencies that low as the input. I designed two receivers that would cover 16 MHz, both for commercial aircraft. Most of the time, I had handed the signals off to someone else by the time they were that slow. I find working in "engineering notation" helped me the most. That's scientific notation except with the exponents in multiples of 3. 16 MHz would usually be written as 16e6.

I got chastised by a design reviewer from the JPL on a satellite we were doing for them, and instead of saying something like 16*10^6, I said 16e6. "That's not 16 times e! Correct your documentation!"
 
I've been to your website and I like it for the tid-bits and info. I worked for the railroad for 10 years and I still can remember seeing the flames come out of those arc-chutes on the switch gear and the bang that sounded like a gun going off in the cab. LOL

Ray
We once had a control circuit failure that closed a breaker connecting a stopped 1Mw synchronous alternator the the 12.5 kv line. Started a fire and made the whole city of Dallas sag just a little bit.
 
Ray: re: post #220: Flame chutes on circuit breakers (with associated loud bangs!) were "before my time": I was designing 400kV SF6 gas breakers.... so the "bang" was inside the insulator containing 6~7 bar of SF6. A REALLY corrosive toxic gas, but excellent dielectric! So the only "Bang" that could be heard was when the valves operated and opened 6litres of air at 28barg from one side of the actuator piston, to atmosphere. The resulting differential pressure on the piston caused a very rapid acceleration (recorded 120g on the piston rod!). - It took about 4ms to operate the valves, and 0.1ms for the piston to start moving.... well that was the resolution of the "clockwork" paper recorders of the era. I also designed the silencers to bring the exhaust noise from the actuator exhaust down from 136dBA (previous design of silencer) at 1m to below 124dBA at 1m. People in the village 1.5 miles away were very happy with the "new" breakers, that didn't sound loud... more like a small gunshot when the weather was in the right direction, not the echo-ey "Boom" of not-too-distant gunfire or quarry blasting from the air-blast circuit breakers!
Nowadays, the actuator is hydraulic, so the whole thing is much quieter. No exciting flashes and bangs either!
K2
 
On locomotives they don't have anything that fancy, just switch gear for forward and reverse and power contactors for for power and dynamic braking. It's the power contactors that handled up to 1Kv and 1,200 amps each, 6 of them, one for each motor. If the power contactors opened somehow under full power/load then the arc usually got it's guts burned out of the arc chute, where that red label is. Opening under full load sounds more like an explosion and not a gun shot. They are not suppose to open until the generator field has decade. The contacts are made from pure silver about 3" long by 1"h x 1" thick.
1652460454847.png


On the RADARSs I worked on all the switching was done electronically into the megawatts range, that's all I can say.

ray
 
Thanks Ray. Interesting stuff (to me at least!). I do find though, that only people who have had hands-on experience of high power electrical stuff are interested in it. As a subject, Power station and smelter bus bars just "hum"! And (hopefully!) No-one ever knows circuit breakers are there, and do their job reliably!
Not subjects for general conversation!
So that's probably why I am such a boring old what's it to most people.
K2
 
Thanks Ray. Interesting stuff (to me at least!). I do find though, that only people who have had hands-on experience of high power electrical stuff are interested in it. As a subject, Power station and smelter bus bars just "hum"! And (hopefully!) No-one ever knows circuit breakers are there, and do their job reliably!
Not subjects for general conversation!
So that's probably why I am such a boring old what's it to most people.
K2
I know when things get into high power & voltage things tend to get a bit weird. :)
Anyway I did some more testing of code to see how long it takes to do the calculations of RPM, degrees to TDC, and to lookup a value stored in the EEPROM. It shows that all the calculations and lookup will take less than 1 usec see below. I didn't use the average stuff here. Also the total time will be less because I won't be printing everything out to the serial monitor or the LCD.

P_Time is the pulse width time I manually enter
R_EEPROM is the EEPROM read at location zero.
RPM is the calculated RPM
DPS is the Degrees per second calculated
T_TDC is the calculated Time to TDC

All times are in seconds.
P_Time 0.00120000
0.00039000
2564.10253906
R_EEPROM 32
RPM 1538.462
DPS 9230.769531
T_TDC 0.005958
1
148
147
0.669us

The Arduino code I used:
#include <EEPROM.h>
int before, after, timeSpent;
float average = 0;
float P_Time = 0.0012; //pulse time
float RPM = 0;
float DPS = 0; //Degrees per Second
float T_TDC = 0; //Time to TDC
float x;
float y;
int R_EEPROM; //Read Stored EEPROM location '0' and place it in here

void setup()
{
Serial.begin(115200);
TCCR1B = (1 << CS10); //Start Timer1 with /1 prescaler
EEPROM.put(0, 0x20); //Store the value 32 in HEX (20) to location '0'
}

void loop() {
float average = 0;
{
TCNT1 = 0; //Clear Timer counter
before = TCNT1; //Read timer value
// Function to be tested
//(1/(Tm*0.325)*600) = RPM original formula
Serial.print("P_Time ");
Serial.println(P_Time, 8); //Print pulse time to 8 decimal places
x = (P_Time*0.325); //Had to break down the formula into sections to work
y =(1/x);
Serial.println(x, 8);
Serial.println(y, 8);
RPM = y * 0.6; //Couldn't use 600 for some reason, will look into it
DPS = (RPM*360)/60; //Degrees per Second
T_TDC = 55/DPS; //Time to TDC, Hall is at 55 degrees
EEPROM.get(0, R_EEPROM); //Get the advance in degrees from the EEPROM
Serial.print("R_EEPROM ");
Serial.println(R_EEPROM);
Serial.print("RPM ");
Serial.println(RPM, 3);
Serial.print("DPS ");
Serial.println(DPS, 6);
Serial.print("T_TDC ");
Serial.println(T_TDC, 6);

//Serial.println(x);
after = TCNT1;
timeSpent = after-before;

Serial.println(before);
Serial.println(after);
Serial.println(timeSpent);

average += timeSpent;
}

average = (((average/10.0)-4.0)*62.5)/1000.0;//get average, substract the time it takes to manipulate TCNT1, multiply it by real time per timer tick and convert to us

Serial.print(average,3); //Time it took to do all the above in the loop
Serial.println("us");

delay(5000);
}

I should have enough to actually come up with an overall code for the ignition.

Cheers
Ray
 
Well I did some more work today as much as I can because of my surgery.
Anyway this is what I've done today. For starters I have disabled the temperature and LCD functions in my code for now and will add them back in later. I want to concentrate on the core of get a spark out which means I'm doing things in steps. I got the pulse width, RPM, hold-off time to TDC, and EEPROM lookup location done and working in code. Right now I'm using my little signal generator to send square pulses to interrupt '0'. Inside int0 the ISR function, I'm using the pulseIn() to get the pulse width in micro-seconds and so far the code is very close to the spreadsheet calculations. I'll have to verify it all later using my scope. The next step is to connect the Nano to the Hall circuit and get those working together.

What I did learn is using 55 degrees BTDC as a Hall setting is not going to work very well. At 55 degrees there is only enough time to have a dwell of 2 milli-seconds at a max RPM of 4200. If I move the Hall sensor to give me 90 degrees BTDC then the max RPM jumps up to 12,000 RPM which is something I thought would happen. Mind you this 12,000 RPM limit is for inductive or TCI ignitions (LS1&2 coils) but, as RPM goes up the amount of advance available goes down. If I were using my Sparky CDI then this goes up to 15,000 RPM. Also using 90 degrees allows for a max advance @40 degrees which is fine by me. The 2 biggest problems is the speed of the mcu and charging the coil. It's easy to use a faster mcu but the coil charging time is a lot harder to overcome. This is a good example of why on multiple cylinder engine manufacturers have gone to using distributorless with multiple coils even with constantly charging CDI's.

I'm really happy that I could place the pulseIn() function inside the trigger interrupt routine because it saves a lot of coding/code. If I were using the time between pulses then I would use the ICP1 input capture. The nice thing about using the trigger interrupt is that when it happens the mcu puts everything else on hold like the temperature reading and the LCD update. Once the interrupt is done then the main code can run again normally and take the temperature reading and update the LCD until the next interrupt.

My majour concerns:
Storing the advance table in the EEPROM from my PC. I don't want to do what we did 10 years ago where we had to place the array in the code and reflash the mcu. We had made a Excel spreadsheet that allowed one to set their degrees advance to the RPM table. Once this was done you would click on a button and the spreadsheet would actually write the whole code for you to copy and paste into the Microchip IDE to reflash the mcu, PITA. I still have to write the program to do this as a one and done process and haven't figured that out yet, need time.

Tomorrow I'm going to hook the Nano up to the Hall circuit.

Cheers
Ray
 
I'm really happy that I could place the pulseIn() function inside the trigger interrupt routine because it saves a lot of coding/code. If I were using the time between pulses then I would use the ICP1 input capture. The nice thing about using the trigger interrupt is that when it happens the mcu puts everything else on hold like the temperature reading and the LCD update. Once the interrupt is done then the main code can run again normally and take the temperature reading and update the LCD until the next interrupt.
Hmm ... as best I can tell, and matching what you are saying above, pulseIn() blocks everything else while it waits for the pulse to complete. I'm not a fan of putting a blocking function inside an interrupt; not a problem if you genuinely have nothing else for the μcu to do, but if you want to report RPM or other information to an LCD, I would think you will have trouble with slow response. This is why I'd much rather keep all the time-critical code in short ISRs. But of course, the proof is in the pudding, and I will be happy to be proved wrong!

My majour concerns:
Storing the advance table in the EEPROM from my PC. I don't want to do what we did 10 years ago where we had to place the array in the code and reflash the mcu. We had made a Excel spreadsheet that allowed one to set their degrees advance to the RPM table. Once this was done you would click on a button and the spreadsheet would actually write the whole code for you to copy and paste into the Microchip IDE to reflash the mcu, PITA. I still have to write the program to do this as a one and done process and haven't figured that out yet, need time.
With apologies if I am "teaching grandma to suck eggs ..." there are a few approaches that I would consider. Depending on the size of the tables and available code space, I might build a default table as a const array. This will compile the table into the code space, but you can access it as a variable, e.g., to reset the EEPROM to default values. Alternately, if you can define the constants that let you calculate a default table, that code might be smaller than the tables - depending on the size of the tables. Finally, you could flash a program to set up your EEPROM with the default values, and then reflash just the code to your running program. If you had enough room in EEPROM, you might be able to store the default values there as well as the active tables. Just keep in mind that when it comes to actually running the program, you will want to access the tables from RAM - reading EEPROM is much slower.

Again, apologies if I am stating the obvious or telling you things you already know ... or worse yet, trying to make helpful suggestions while getting it all wrong!
 
Hmm ... as best I can tell, and matching what you are saying above, pulseIn() blocks everything else while it waits for the pulse to complete. I'm not a fan of putting a blocking function inside an interrupt; not a problem if you genuinely have nothing else for the μcu to do, but if you want to report RPM or other information to an LCD, I would think you will have trouble with slow response. This is why I'd much rather keep all the time-critical code in short ISRs. But of course, the proof is in the pudding, and I will be happy to be proved wrong!
Point taken. Yes it will block in the ISR but, I can get away with using an interrupt with the pulseIn. Normally the pulseIn is just placed in the main loop and blocks there until the pulse is done so, it will still block the updating of the LCD. I don't plan on using the LCD as a primary tach it's more like a FYI thing. I believe getting the PW, RPM, and EEPROM reading is the most important. I did use your advice on using the RPM as an index for getting the EEPROM location, no searching is done., just 1 quick calc and straight to the location. "EP_Loc = (RPM/100)-1;" And 2 'if' statements for high and low ends. If I have to I will copy the array into RAM for more speed. The EEPROM can store 1024 entries but, right now I'm just using 115. Yup it's going to be interesting to see how all this is going to work together. From past experience it should work out ok.

With apologies if I am "teaching grandma to suck eggs ..." there are a few approaches that I would consider. Depending on the size of the tables and available code space, I might build a default table as a const array. This will compile the table into the code space, but you can access it as a variable, e.g., to reset the EEPROM to default values. Alternately, if you can define the constants that let you calculate a default table, that code might be smaller than the tables - depending on the size of the tables. Finally, you could flash a program to set up your EEPROM with the default values, and then reflash just the code to your running program. If you had enough room in EEPROM, you might be able to store the default values there as well as the active tables. Just keep in mind that when it comes to actually running the program, you will want to access the tables from RAM - reading EEPROM is much slower.

Again, apologies if I am stating the obvious or telling you things you already know ... or worse yet, trying to make helpful suggestions while getting it all wrong!
No apologies required, you are making informed suggestions and hey there is more than one way to skin a cat, I try not to have a closed mind. The way I have been doing the EEPROM and variables is by using a 'serial check' in my main loop and a Serial_Com routine. When it sees data coming in it parses out the data stream and updates everything. So "0-99" is my advance array(100) and "100-109" is for the temperature array(10) and "110-114" is for the other variables(5). Oh I have found out that if a store an 8 bit ASCII character it takes up 2 byte locations in the EEPROM whereas if I store HEX values it only takes up 1 location, nuts. In my old group ignition we had used 2 ignition advance curve arrays that could be switched back and forth while the engine is running and I might incorporate this feature in the future. If everything works out well today then I think I'll jump onto writing the PC software so I don't have to do the copy and paste from Excel.

I also plan on using the DS1822 which is an updated version of the DS18B20. It is in a TO92 package so it is small, sort of. I really like this temp sensor because it is a 1 wire device and it has self diagnostic functions. $9.00 CAD though.

Cheers
Ray
 
Good news, bad news, good news.
The first good news; I hooked the Nano up to the Hall-Effect circuit and it works nicely no adjustments required other than 1 line of code.

Bad news is that my trigger out pin had tons of jitter and I had very poor control of it. The trigger out pulses when set for 2ms ranged from 0.750 to 2.1ms and this sucked. I checked for noise, voltage problems, and even my interrupt routine, nothing worked but, it was very consistent in it's behavior. So I researched the Arduino site for answers.

Second good news; one of the suggestions and there was many, was to use delayMicroseconds() instead of delay() for my dwell setting. Doing this made the trigger out pulse rock solid from 6 to 11,914 RPM. Note: because I'm using 2 magnets on my flywheel the RPM max is actually double of what I recorded and stated earlier so, real RPM limit is around 23,000 RPM, cool. This is because the time between input triggers would be double of what I recorded, yes :D.

Now that I had steady pulses except for the difference between the magnets which is about 13 RPM. I was able to do some more testing and this is what I found:
For a single magnet:
1.3ms dwell limits RPM to @23,000 RPM which is what my Sparky CDI needs to charge the cap and discharge through the coil.
2ms dwell limits RPM to @20,000 RPM
3.5ms dwell limits RPM to @12,000 RPM

Execution time:
The time for the following below is 1.1ms. Serial printing to the built in Arduino serial monitor which shows up on my PC screen.
pulsewidth 0.165000
0.05362500
18.64801979
RPM 11188
DPS 67128
T_TDC in seconds 0.00134072
EP_Loc 99
Advance 0

With no serial printing the execution time is:
220usec.

Now Andy (awake) is correct in stating that using the pulseIn() and the delayMicroseconds() is frowned upon when used inside a interrupt routine because they both do what is known as blocking. When one uses a blocking function everything is put on hold until the function is finished. This is also what a ISR interrupt routine does so, it's basically putting an ISR inside a ISR which, kind of negates the purpose of an ISR. ISR's are supposed to be used when something important is "time critical". In other words use very small code and get out of it. But sometimes one has no choice or the benefits out weigh the negatives. But as I said previously mechanical things when compared to electronics, the mechanical is very slow. In my case here, my theory worked out.

Now that I have the Hall_effect pulse going to the mcu and I have the RPM, degrees per second, and the time to TDC calculations done the next thing to do is calculate the hold-off time to get the proper timing advance. Ok more math. Problem is that as RPM goes up the degrees per second goes up so the amount of hold-off time changes and the degrees of advance goes up, usually. But there is a relationship going on here. so the first thing to do is find out how long does 1 degree take. Also since I now know that the Nano works better with micro-seconds, I want to bring the hold-off time down to micro-seconds. First we need the DPS (degrees per second) which I got from the RPM. Next I need to know how long 1 degree takes: (Time per 1 degree = 1/DPS).
Example:
RPM = 3600
Revs Per Second = 3600 / 60 = 60 RPS
DPS = 60 x 360 = 21,600 degrees per second

Next I need to know how long in seconds does 1 degree take at 3,600 RPM.
Time for 1 degree in seconds = 1 / 21,600 = 0.0000462963 seconds per degree

Next I need to know how much time do I have to TDC from 90 degrees (Hall-Effect), this changes with RPM
Time to TDC in seconds = 90/DPS or 90/21,600 = 0.0041667sec or 4,166.7 usec

So now let's say I want 10 degrees advance timing at 3,600 RPM. Got the 10 degrees that was programmed into the EEPROM.
The time before TDC for 10 degrees at 3,600 RPM is:
10 x 0.0000462963 seconds per degree = 0.000462963 seconds Before TDC. or 462.962 micro-seconds at 3,600 RPM.

Now to get there I need to know how long it takes to go from getting the Hall pulse length to the end of calculations before I start my Hold-off time. Right now I'm just going to use 220 usec.

Time to TDC in usec = 4,166.7
4,166.7 - 220 = 3,946.7 usec is my Time to TDC now. Got the pulse, measured it and did the calculations needed so what's my Hold-off time now?

I have to to subtract the time before TDC for 10 degrees.
3,946.7 usec - 462.962 usec = 3,483.73 usec hold-off time. But since I want to use 2 msec dwell I have to account for that, so 2 msec = 2,000 usec.
3,484 -2,000 = 1,484 usec Hold-off time using a LS1/2 coil. On a CDI ignition there is no real dwell time so the firing time is at the end of the Hold-off time. The dwell part of it starts at the end of the spark on a CDI.

So at the end of the Hold-off time I turn the trigger output on for 2 msec (dwell time) and then turn it off. The LS1/2 coil will fire when they see a negative going pulse.

I know it's a long post and there is lots of math. I'm sure most people who have read this, if they read all of it are saying 'Ray who gives a sh*t, all I want is to see is 10 degrees of advance when I say I want it'. Well I'm getting there and besides as I said at the start of this thread "I want to show people what it takes to make things happen". When I start to make the PC software I won't be doing these long posts. Using Visual Studio to write a PC program is very advanced for this forum but, I'll show some pictures and ask for input on it's design from people on here.

Next up:
Turn the stuff up above into code, test it, fix it, and then hook up an LS coil to make sparks, I'll make a movie when I get there with a little LED timing light. For the connection between the coil and the Nano I will be using a 2N7000 FET, I love these little buggers.

Cheers
Ray
 
I have an ESP32, but so far I've been playing with code on a PIC18 dev kit just for practise with no consideration of execution speed.
I should add that I am very much an amateur programmer, but we seem to have arrived at the same mathematical solution.
I have wondered whether to keep the advance value in time (rather than converting to angle) as it seems intuitively that what the engine needs is a time advance, to allow for flame front speed.
 
Well I did more testing yesterday and this morning. Didn't get as much done as I had wished but, that's the way it goes sometimes.
First of all, I bought myself a new digital scope to replace my old Phillips one some months ago. It's a Rigol DS1054 4 channel with all the updates including unlocked firmware and now does 100mhz. This thing is miles ahead of what I was used to and has more bells and whistles than I really need but. what the heck gotta treat yourself sometime. Still trying to learn this thing.

So I added the code for the Hold-off time and moved the serial printing to the void loop() and guess what no 'loop' coming out of the interrupt routine. I found the problem and it's related to the pulseIn() blocking function. To get around this I had to add a call to the void loop() routine. Does the trig-in interrupt still work? yes it does. Printing to the serial monitor is interrupted during the interrupt. The serial print will be replaced with the LCD updating later but, the update will not be steady because of the ISR routine. To do this properly I would either need to use another Nano or an external tach, just to let you'se know. Also it updates faster at higher RPM because of having to use a call to the 'loop' routine but, I'm happy with it.

It is really nice to see the Hold-off working properly and matching the calculations. But we'll have to see how well it works on an actual engine. Which got me thinking: how much timing advance can this thing handle? and how will someone without a scope going to set the timing up correctly?

I tested the max timing with the Hall set at both 90 & 60 degrees. In both cases the max timing has to be 5 degrees less than what the Hall is set at. So if you have a Hall fixed at 90 degrees then the max would be 85 degrees advanced timing and likewise for 60 it would be 55 degrees. More than enough to blow an engine up.

Because not everyone is going to be using the same magnet, Hall-Effect, and the distance between them that I use, there has to be a way to help them. What I thought up was, one would enter in the degrees that the Hall turns the Trig_In LED on when you turn the crank by hand. Then they would set timing to 0' degrees advance. You would then start the engine and play with the processing time setting until you get a showing of 0' degrees on the crank with a timing light. Mind you one could also use something like 10' degrees advance. To do this no other advance can be used while setting this up, so a locked in setting.

Also I found that the minimum RPM reading is 60 and I believe that's because of the math involved. Anyway, next I want to clean out the EEPROM and load in an advance curve to make sure that part is working then attach an LS2 coil.

Cheers
Ray
 
I have an ESP32, but so far I've been playing with code on a PIC18 dev kit just for practise with no consideration of execution speed.
I should add that I am very much an amateur programmer, but we seem to have arrived at the same mathematical solution.
I have wondered whether to keep the advance value in time (rather than converting to angle) as it seems intuitively that what the engine needs is a time advance, to allow for flame front speed.
That's what I was going to use (ESP32) as a backup mcu incase the Nano didn't/doesn't work out. The code I'm using and because Arduino works with both our processors my code should workout for both.

Ray
 
Silicon Chip magazine did a programable ignition 3 issue series on this
subject. They used a 16f88 I believe. They sell the complete assembly code for 3$
I played with it and it works. Generating the timing code table is a bit tedious.

https://www.siliconchip.com.au/Issue/2007/March/Programmable+Ignition+System+For+Cars;+Pt.1
I have been working with electronic ignitions since 1975 and programmable ignitions since 1996. I have seen many different types from ones using the intel 386 to dedicated processors of today (ASICs). All the ones that I have seen or read about need at least 2 pulses to sync the angular velocity to ignition timing, never doing this with just one pulse. Also they were all a PITA to program the ignition curve unless one bought PC software from @ $100 and up and that's even if there was an offering. There has been an explosion in programmable ignitions ever since mcu/mpu manufacturers started offering their IDE or development software for free. Then again there are dev software like the Arduino that have simplified things a lot and brought coding to the masses. There are so many ways to do things today that it becomes hard to decide which way to go. Do I go for cost, speed, features, or a combination of them. My main concern is to make it cheap enough that anyone can build one and provide PC software that allows one to make an ignition curve easily. This is just my flavour of the day.

Ray
 
The ignition curve: Ignition advance movie
1653316760825.png

Have you ever had one of those days when you have a brain fart and spend hours doing something only to realize the answer was staring you in the face? Of course you have, your a hobbyist. Well I had one and it related to the EEPROM. To check out the writing and reading of the EEPROM I created an ignition curve in Excel and saved it as a *.csv (comma separated values) file and using notepad I copied and pasted it into my code. During the setup routine I had the values programmed into the EEPROM from locations 0-99 for 100 values.

0,0,0,5,5,5,5,5,5,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40

Each one is a step of 100 RPM up to and including 10,000 RPM. Remember I was saying that the EEPROM stores values in HEX as 1 byte and everything else is 2 bytes? The problem with this is that the locations would not go up 1 at a time, it is more like 2 at a time. This is because unless you tell the firmware that you are using 8 bit bytes it treats the bytes as 16 bit taking up 2 locations. This creates 2 problems; one you use twice as many locations than you need and second you have to compensate in the code by jumping 2 locations for every read of the EEPROM. So if you want to store a single 8 bit byte then you have to use the 'uint8_t' as compared to the 'uint16_t' and I forgot this. Also I could not find anywhere that would explain this behavior properly. According to the datasheets the 328 mcu uses a 9 bit byte to allow for signed (+-) values. So if one doesn't say 'uint8_t' (unsigned integer) then it adds in a signed value and spills over into the next location. Also the 328mcu doesn't write 1 location at a time but, instead writes a whole page at a time, just some FYI.

Anyway does timing advance work, yes it does. On the scope I can see the input trigger pulse width get smaller, the output trigger stays the same 2 msec dwell, but, the distance between the input trigger and the output trigger changes with the RPM and the programmed advance timing. As the RPM goes up and the advance increases you can see the sudden decrease in distance. Less distance between them means more advance in the timing, less Hold-off time.

I made a video of the scope and computer screens to show the advance working away. The values I used were:

0,0,0,0,0,0,0,0,0,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40

no advance from 0-800, 20 degrees from 900-3,300, and 40 degrees 3,400-10,000 RPM. Actually in the video I hit @11,300 RPM. Sorry about the shaking and poor audio. Ok I think I'm ready for the ignition coil now, I think.

Cheers
Ray
 
Last edited:

Latest posts

Back
Top