Homebrew 2-stroke ignition?

Hi,
I am thinking about making my scooter ignition mit an Arduino being able to adjust the igntion timing curves by myself:

  1. Using a voltage divider with a Hall sensor detecting the top death center TDC. The attachInterrupt command gives the according accuracy. Timing needs to be recorded in microseconds.
  2. Having some tiny calculation understanding how long to "wait" (without delay - command ) before to ignite in [microseconds]
  3. Pull the ignition coil pin to low to get the ignition spark.

Here is my question: As the igntion timing is critical I need to pull the coil pin to low with an internal interrupt command. I've never used interrupts except the existing commands like attachInterrupt. Can someone guide me?

Have you ever monkeyed with engine ignition systems before?

Timing is critical, and I think you'll find it very difficult to get an accurate indication of crank angle and speed around the firing angle from a single sensor positioned at TDC.

To get accurate spark timing, you will need many pulses per revolution of the crank. On my 4 cylinder suzuki, it has 22 pulses and a 2 non-pulse are to determine 'TDC on #1 cylinder.

For a single cylinder engine I would think you need at least 6 pulses per revolution.

You are right that TDC accuracy is important. Please bear in mind that the scooter originally works with a FIXED (!!!) ignition value and one sensor/ actuator in the CDI ignition system- you can make it only better :slight_smile:
I do not mind too much about the lower RPMs- here are the biggest variations regarding angular speed over 360° crankshaft angle. The higher revs are of more importance- and here is luckily the changes much lower.

Important to me is that the sensor in and acuator out is perfectly running. Sensor "in" is no problem with AttachInterrupt.

But how to kick out the OUT actuator signal with highest accuracy? I'd like to avoid the "ifthen" loop looking for micorseconds, which is timingwise not what I need!

cyclegadget:
To get accurate spark timing, you will need many pulses per revolution of the crank. On my 4 cylinder suzuki, it has 22 pulses and a 2 non-pulse are to determine 'TDC on #1 cylinder.

For a single cylinder engine I would think you need at least 6 pulses per revolution.

Nearly every high performance/drag racing style engine runs an MSD crank trigger ignition. 4 magnets located around a trigger wheel on the balancer at 90 degree intervals corresponding to each 4 TDC positions (V8). A pickup fires the ignition each time a magnet flies past.
These engines turn 10,000 rpm plus and make thousands of horsepower.

The trick I can see here is having the pickup trigger advanced some amount before you actually want the ignition to fire and work a delay into the controller. This allows you time for processing. (I've got no idea how much timing a 2 stroke engine runs but to use my drag engine as an example, we run (depending on gear, fuel, weather and other tune up factors) somewhere around 38 degrees BTDC ignition timing. The pickup is actually adjusted to be somewhere around 40 - 42 degrees. The processing in the ignition controller then fires at 38 (as seen if you check the timing with a timing light).

You can then work a 'retard' curve into your controller, referencing RPM or boost/MAP or any other factor you care to use. Remember, the controller can only retard the timing from your base setting. It can't predict into the future to fire before the trigger, it can only trigger after the trigger, so your pickup must be set at the maximum amount of advance you want anywhere in the curve, then retard back from that value in your curve.

In my case we pull 1 degree out when it shifts from low to top gear, and can ramp a few degrees out on launch if traction is marginal, or plot an entire curve for each gear based on RPM or time.

The maths/interfacing for an Arduino to do this and whether it can actually do the job; I have no idea. But I do know it works with only 1 reference per cylinder TDC event in some pretty high performance applications, so it may well be possible.

Have fun with it!

Here is a couple links to help you determine how you should proceed with your project.

I think your project is doable but, would be better with more timing sensors.

Old magneto ignitions had one pickup which just made or broke a switch to fire the coil. You could set a baseline timing delay and then change it as you measure rpms.

By the way, the micro-controller can do if/than loops far faster than your engine will ever run while doing other stuff.

Mhhh- a 360° stroke at 10.000RPM takes about 6mS. I am sure you agree that using interrupts is the best way to handle it not using IFTHEN loops. 1° of ignition is 17microseconds at 10.000RPM. The 328 is not as quick as that...

I know I am naggy, but beside learning something about engines no one answered my question from my first post:
As the igntion timing is critical I need to pull the coil pin to low with an internal interrupt command

Can anyone help me with that?

I don't have your answer but, maybe you can find what you need here.

As the igntion timing is critical I need to pull the coil pin to low with an internal interrupt command

Can anyone help me with that?

I don't even understand what you think you need to do, here. Interrupts are external events of interest, usually, although they can be internal, timer-based, too.

In the interrupt handler, you can set the pin LOW. That isn't a problem. The problem is what is going to trigger the interrupt handler. What do you envision generating the interrupt to trigger the interrupt handler?

soulid:
Mhhh- a 360° stroke at 10.000RPM takes about 6mS. I am sure you agree that using interrupts is the best way to handle it not using IFTHEN loops. 1° of ignition is 17microseconds at 10.000RPM. The 328 is not as quick as that...

I know I am naggy, but beside learning something about engines no one answered my question from my first post:
As the igntion timing is critical I need to pull the coil pin to low with an internal interrupt command

Can anyone help me with that?

I have worked with ignition systems, and I think you are glibly ignoring some fundamental problems which will prevent you from getting a solution that works as well as the original, let alone better. I suspect you'll find it difficult to get it to start at all.

But since you only want to ask about interrupts, you need a power transistor to pull the coil dopwn, and a driver circuit to drive that from the Arduino output. Remember that you will get some savage voltage transients back from the coil LT circuit and the supply voltage will also be all over the place - it will need quite a bit of work to prevent the Arduino being damaged or confused by the electrical transients. I assume you're also going to deal with dwell timing which means that as well as your firing point changing with speed the advance needed to charge the coil will also need to change with speed.

I think your best bet is to decide what ignition timing you want to start the engine. You [should] know what dwell time you're going for, and you should know the cranking speed, so you can calculate how far in advance of the firing point you need to start charging the coil. Position your crank position sensor there and start charging as soon as you see the trigger, this will give you the cranking spark at about the right place. This will probably be well retarded to get it to fire reliably at low speed.

Once you start getting consecutive crank triggers fast enough to show you are running you can start averaging these to produce an estimated speed and use that to decide how much to advance the ignition and control your dwell. Remember that in this scheme with a single crank position sensor your ignition timing and speed estimates will will be based on a pulse that is probably 300 degrees old so you won't get very accurate timing.

Hi soulid
I'm playing with a programmable timing (retard) for a Bultaco Pursang. This is an old motorcross bike (1977) that will rev to about 9000.
I've replaced the points with a CDI from a Chinese bike (this is a fair job in itself). I cut 2 keyways in the flywheel, one to run without programmable retard and another about 50 deg advanced from this. The Arduino goes in the CDI trigger circuit.

I adapted this basic circuit and code.(thanks to Martin Nawrath)
http://interface.khm.de/index.php/lab/experiments/frequency-measurement-library/

At the moment I've got the bike to run (and rev but not taken it for a ride) without any retard. Trigger signal goes into Arduino, I measure the RPM do a few calculations and then send a trigger to the CDI box. This is with the flywheel in normal non advanced position. This is where I'm up to .

My understanding is that the timing needs to be retarded at starting , advancing as you go up the rev range and retarded again at max power (for a 2 stroke), but can't really find any solid info on the actual numbers. I guess this will be a bit of trial and error. The static timing from the factory must be a big compromise to cover what is really ideal.
I'm no expert on any of this so don't take my word for it.

Mark

The optimum timing will vary with both load and speed, so ideally you'd have a manifold pressure sensor of some sort and determine the spark timing from a two dimensional map. I don't know how easy it will be to measure manifold pressure on your engine, though. A MAP sensor connected immediately downstream of the throttle plate would be your best bet.

Hi PeterH,
I do agree to this, but this will be too complicated for me because the MAP Sensor needs a AnalogRead command. But Arduino takes about 20mS...takes too long for the for the 10.000RPM and its cycle time.
So I leave it to the first step of changeing the retard over RPM.

A map sensor is slower than the Arduino. The map sensor is slow enough that it creates an average of the current pressure. When I say slow, I am guessing it will read at about 10Hz.

Yes- the sensor respone is slower (see Bosch PSA-C Sensor datasheet), but this is only delay in response. I meant the time to measure an analog voltage from the arduino itself is the downside of it.

I seem to remember that it is possible to do an analog read asynchronously if you access it at a lower level than the normal API. But that would be academic if you are using an interrupt-based scheduling mechanism for your sparks, which I agree seems the only feasible way to meet your timing requirements.

Just little bit theory of ignition.
Ignition angle is used only because this is most convenient way to ignite fuel air mixture. When using microcontroller, there is no need to stick with calculating ignition angle specifically.

What matters is burning time. Air-fuel mixture must be allowed to burn completely through by the time exhaust opens. Also, what might be even more important is maximum pressure during burning pressure, that must be achieved right after upper dead point.
Burning time does not depend on RPM or engine load. It depends on air-fuel mixture pressure at ignition and air-fuel mixture ratio. Deviation from optimal mixture causes it to burn slower. Burning speed depends also on mixture temperature. It means, microcontroller need to know throttle position along with cylinder and ambient air temperature.