Motorcycle ignition advance, simple project?


I've fiddled a bit with Arduino basic stuff, and my bigg plans for an EV controller have stumbled upon legislation, so that has never really taken off. I am in the mean time working on a custom motorcycle, and I feel the ignition needs some improvement. It has no part-load advance. Here's what I like to do with Arduino: Measure revolution time (1 puls per revolution generated). Look up standard advance the ignition degrees conform a table as a result of rpm Devide measured revolution time by 360 degrees and multiply by advance value just looked up plus 180 degrees (sensor opposite to TDC), and subtract dwell time. Wait for next pulse, start revolution time counter again and start counting the just calculated number of ms, write ignition pin high, wait dwell time, write ignition pin low, done.

It will rely on two tables that I can make as detailed as possible, but could be simple to start with: RPM < 1000 advance 18 degrees RPM 1000 - 4000 advance 18 - 10 degrees (linear) RPM 4000 - 8000 advance 10 - 5 degrees (linear) RPM > 8000 advance 5 degrees

MAP value 0 - 1,5V advance 0 - 4 degrees (linear) MAP value 1,5 - 3,5V advance 4 - 7,5 degrees (linear) MAP value 3,5 - 5V advance 7,5 - 10 degrees (linear)

And I could split the tables into more fractions as desired.

Can this be done? The max RPM of my engine is 12k rpm (in theory, never go there) and I require only one spark, it's a 2 cilinder and I will fire a dual coil with waisted spark. Hooking everything up mechanically and sensor-wise I can do.

Thanks for input, Cheers,


An Arduino is possibly not the best choice for this. There are chips specifically built as ECU computers. They build in a lot of hardware features that make this work easy.

There have been many other Arduino ECU projects successfully completed. Most of them I know of were student projects on single cylinder lawnmower engines. Google can find them for you.

Thanks, I have found some projects googling, even 'complete' EFI projects. Why would Arduino not be the best choice?



Dedicated ECU chips keep a clock synchronized with the crankshaft. So if you want to do something at 359.9 degrees, it is only one simple instruction. They also have memory optimized for large lookup tables. There are probably other features I am not aware of.

The Arduino is a general-purpose processor that is relatively old and slow. It may not be able to reach your relatively high RPM with the accuracy you require. But it is a great way to learn because it is so easy to program. There is also a good upgrade path to faster processors so you can run the same code on a processor 5 or 10 times faster than the original Arduino.

Ah, OK, I understand, thanks. I will look into the faster processors, and stick to Arduino to begin with. I used MicroSquirt a long time ago when it was still open source, but that seems to be closed source now. It will be a fun project.

All input is welcome of course.



If you go with rolling your own gadget, time in microseconds instead of milliseconds.

Also why convert to RPM in the code? Make it time to turn, which saves you converting back and forth.

1000 rpm = 60 seconds / 1000 turns = 60000 microseconds per turn. Halfway around is 30000 usecs, 1 degree is 167 usecs but only use that to calculate advance times!

At 12k rpm, the time from TDC to TDC will be 5000 usecs.

You can make a table with entries for how long since the last TDC, starting at 5000 and going up to 60000 by 100's and the time to delay for each (8 bytes per entry) and it should fit into a corner of flash (PROGMEM) memory instead of RAM. In this case, lookup is a LOT faster than calculating.

So for each engine cycle the time to turn makes the time to wait, etc, directly.

Those other processors, a Teensy 3.2 safely overclocks to 96MHz (6x Uno speed) and costs less than $30 with pins, $4 less if you solder your own in (very close to tiny leads, scares me!) and is Teensy-small.

At 12k rpm, a single degree takes 14 usecs to cover. Your code has to be extremely fast to match that with an Uno. You may find the advance to be a bit late.

Note that it is possible to run 20 MHz AVRs at 24 MHz without getting them warm (I have a 24 MHz 1284P-Pro board, it rocks.) That board is 50% faster.. my fast code that runs loop() at 86 KHz on the Uno runs loop() at 125 KHz on the Pro-Badio.

125 KHz is 8 micros average loop time where 86 KHz takes 12 (11.62...). If it misses, the bit off will be about 1 degree off at 12k rpm engine speed and that is worst case right there.

Great input, thanks. I also found the due R3 board at 84Mhz standard, and I will look into the Teensy 3.2. I also read about speeding up by replacing read and write comands, but I don't understand that, yet...

Keep it coming!



I also read about speeding up by replacing read and write comands, but I don't understand that, yet...

Many Arduino commands like pin read/write have extra 'safety' code so that they're easier to use for beginners. But it's not so hard to learn to make code that doesn't need the extra, you can read/write ports directly in less than a microsecond.

But in your code, the read should be done by an interrupt that copies the time it fired and sets a flag for the regular code to see and act upon.

I like the part where the signal happens 180 deg from when the reaction must occur. This is because the interrupt saves the time more than a millisecond before the action is taken, the code has a lot of time before it has to be ready. For an Uno, I liken 1 ms to an hour for a human, 16000 clock cycles per ms.

Be sure that there are gate-array chips that could do this job down to nanoseconds accuracy.

If you do try with AVR's, this could probably run on an 8-pin ATTiny85 with crystal. We have the core files, you can program it on a breadboard with an Uno for programmer using the MIT High/Low tech site instructions.

Nick Gammon has an excellent, full-help blog page on making breadboard 'duinos with the best software I've used for the job yet. He is thorough, not just every step but alternate paths and hardware covered fully.

Nicks Microprocessor blogs menu page.

The breadboard duino page.

If you go through Nick's site you will find the full how-to and why for loads of AVR apps. He even shows how to drive TV and VGA interfaces using 328P chips (used in Uno, Mini, Nano).

One thing I find helpful is keeping my Arduino bookmarks in a folder. When I open the IDE to code I also open a browser and a tab for each web page I reference. When I need to double-check or look anything up, it's usually a tab away if not right up front. Best part, I can zoom the pages to where I don't have to squint or grab the magnifier visor like I do with books (so easy to read 20 years ago!) and boards -- that's right, I need a magnifier to get the jumper in the right 10 per inch hole.

I still have a lot to learn... But loving it already! Can I let you all in on a little secret? I 'm thinking of a board that can hold for instance two Teensies. One doing the ignition timing, the other actuating some injectors for say, fuel... The board would hold all electronics to convert and clean up signals going in and coming out. At first I would only use the ignition module with the carbs still on the bike, adding the fuel system later. I made a very simple MegaSquirt variant a long time ago, running only RPM, MAP and O2 sensor (and motor temp, to avoid use of the O2 sensor with a cold engine). It didn't even have a TPS! It only gave problems when revving up too quickly, opening the butterfly valves to quick. I fixed that my mounting an RC car coil-over damper to the mechanism, avoiding the opening going to quick. I could press the pedal as quick as I liked, the damper would reduce the speed if it was too quick to the EFI's liking. I am thinking of doing the same this time... But that is still a long way away. Let's get the sparky project going first.



Hmmm, cannot edit previous post;

just wanted to add that although very interesting, with items like the Teensies for sale I will not go and build my own boards. Maybe later, but I feel I have set myself quite a challange already with the spark project, and going to full (basic) EFI would be next and a lot more difficult.



The fuel injectors don't fire anywhere near spark time, a single Teensy 3.2 should be more than enough to handle that engine. That's a 32-bit ARM with 64K RAM, it should be overkill.

Do you have a regular Arduino now? If you read the magnet sensor (please use a Hall switch, not a reed switch!) and generate a strobe with a led that only fires at spark time, is there somewhere on the engine you can see if it synchs steady? That would give you a measure of how well that chip can keep up... or not.

Haha, a reed switch at 12k rpm would be funny! Hall of course it is.

I am looking at making a wiring tap on the current ignition module and sending data to my regular Uno. Tap the signal coming from the sensors on the crank, and tap the signals sent to the coils. I cannot see if having any form of load adjustment, but I think it might have some basic curve in it. I would like the Arduino to tell me the rpm and the degrees of crank rotation difference between crank pulse and coil pulse. This way I can see if it has a curve, and if so what it is. And since (again) I think there is no load adjustment, I can do this revving the engine without riding the bike. Which in itself will be quite a challange, as the bike is in 34856724934762847539 pieces on the floor. But it will be a bike again within the next few decades weeks.


When current flows it makes a field, a linear Hall sensor might pick up even weak pulses.

I like the idea of using the controller to read the operation of the bike before using it to control the operation. How well you do at the one job may tell if the other is possible.

Remember that all of these events take enough time that you can probably get that data too and not just a set of start points.

Be aware that printing to serialwill impact your sketch speed if you overfill the serial output buffer. Best to do is use the highest baudrate you can (running 1.6.9 my serial is 250000 baud), keep the messages short and don't print lines per milli.

You might also look into using one of the analog sensors used to pick up wheel motion on car's ABS systems. These are ruggedized to handle both vibration and temperature. You need to have something like a zero cross circuit to read into the uP. Dwight

The engine aleady has some sort of sensory system instead of point, so I hop to use those. That would be the easiest.

And with a bit of help I found the basic curve on the motor (without vacuum advance): 20 degrees below 1650 rpm 40 degrees above 3500 rpm So I won't make a table for the rpm vs advance numbers, making five if-then-else rules will already make it possible to make the curve more detailed then it is now!



Well, starting the count / setting the trigger signal at 180 degrees from TDC proves not to be very useful, I better start counting. With a dwell time of 4000us (micro symbol?!?) I get a negative amount of us about 6.700 rpm! Setting the trigger / starting the count at TDC leaves a bit more time. I'll see if I can post the excel I made about it.


Spanner in the works; on a forum about the bike I am building I am advised to say away from tuning these engines. They are air cooled and prone to cracking the heads even without tuning. Adding advance ignition will increase combustion efficiency, and therefor temperature. Without controlled cooling (liquid cooling with a thermostat) it is best to stay away from tuning...



Time to find an old engine to improve. Perhaps a lawnmower or chainsaw engine. If it breaks, not a big loss and you won't be riding it.

Well, I am looking into adding oil cooling to the engine, see whether that makes a significant change to running temperatures. If I can manage the temperature, I feel comfortable adding performance.