Hi everyone,

    I want to write a software on an ignition system for a 125cc four stroke engine.The purpose of my program is to produce a variable time delay for spark to occur in the ignition system. As the engine starts, pulses from the alternator assembly via the pulser coil(positioned at 36degree BTDC) will be collected. The time from the 1st and 2nd pulse will determined the speed of the engine. By using the speed of the engine, the program will call a suitable delay value for spark to occur. This means that spark will only be produce after the 2nd pulse and one spark is wasted.

    Its been 2 weeks since ive started the project, learning about the ignition system and how to program a PIC using c or assembly. Ive decided to program PIC16F84 with Wiz-C by using assembly language because it is quite easy to understand. So far i was able to do simple task such as flashing LED with a push button.

*** some back ground on the ignition system
Ideally a mixture of air and fuel needs to be burn exactly at the top dead centre(TDC) of the combustion chamber. In reality, a fixed quantity of air and fuel needs a particular time to combust. Although this can be solve by allowing the spark to occur before TDC say at 36 degrees before TDC, the engine however have a range of operating speed. Thus there needs to be a  variable delay system(depends on the speed of the engine) where combustion occur before TDC. 

*** Information about my program

Assume that the engine can run up to 8000rpm.
At engine speed of 1200 RPM;

1200 / 60 = 20 revs per second
1 / 20 = 50mS per rev
1 rev = 360 degrees

36 degrees at 1200 RPM = (36 / 360) X 50 = 5mS

So  at max rpm, delay = 0.
    at min rpm( 0-1200rpm), delay should be lower than 5mS say 4mS

The program have 8 set of delay values.
8000rpm= 0mS
1200rpm or lower =fixed at 4mS

      I came across a website that has an assembly code which is similar to the one that i want. I cant really follow the logic of the code and was wondering if someone can give me a simple example plus explanation on how to use timers to calculate rpm and use data tables to retrieve corresponding delay output using assembly language. I know this is too much but i really appreciate all the help that i can get.

Posted on 2008-02-05 20:16:17 by eddy123456
This will all depend on what chipset you use with which modules. They should offer documentation with whatever ecu you use. Megasquirt would be *the* way to go IMHO. http://www.megasquirt.info/ they have a whole forum section where you can discuss this. Since this is more firmware, it may have better results if a mod moved it to the low level section, but the megasquirt forum would be the best place to start.
Posted on 2008-02-06 22:31:14 by jakor
The 16F84 is quite limited, so the author of that ignition system had to inline everything and he chose not use interrupts (because he'd have to do silly things to get a 16-bit timer out of the clobbered single 8-bit timer).

Could you explain why at 8000rpm the delay is 0ms? And why do you divide by 10 (I know, 36 degrees,.. but the timing...).

Actually, like in the image I've attached, could you graphically represent:
*assuming that when the rotor rotates, the angle increases, like in 0 degrees, 1 degrees, 2 degrees, 3 degrees.... 359 degrees, 0 degrees,..."
- when the rotor is at 0 degrees
- when the 36-degree (or is it -36 degrees? ) signal is pulsed.
- when we must spark.
- when we must stop the spark

I'm eager to help, it's just that I don't know the timing. (no time to research :P )
I have much more experience with the newer PICs, that cost just as much - yet have much more facilities (internal 16-bit timers, robust interrupts, 10x faster). But I think I can help with writing the code for that F84, or at least outlining what should be written.

Btw, using only 8 values of delay is quite limiting and probably will waste fuel, right? It's just as easy to implement ~200 values of delay, imho.
Posted on 2008-02-08 11:53:02 by Ultrano
Im glad you guys replied because i am still stuck with the programming stuff.

1) Jakor, im planning to write a program and build a basic electronic ignition system of a small motorcycle engine(no ecu, just a CDI) by using PIC16f84. Megasquirt seems too complicated for me.

2) Ultrano, the image that i uploaded basically sums up what im trying to do.

Assuming that the engine is constantly running at 1000RPM, pulses from pulser coil is collected.The time between each pulse is:

1000RPM = 1000/60 = 16.667 Revolution per seconds

The pulser coil is located at 36 degree before TDC and it moving anticlockwise (towards TDC:36,35,34...........2,1,0,359,358.....38,37,36), Maximum Delay for spark from the moment pulse is collected must not exceed :

                      60m*(36)/360    =  6mS

So basically there will be a range of delays from 0 to <6mS. Note that,if there is no ignition control then the position of pulser coil is fixed at maximum (36 degree BTDC, not optimised for whole range of speed, only good for higher RPM.typically at low RPM <1000, spark will occur at 10degree before TDC).

***i need to correct something about my last post.I just realize that the spark will only occur after/at the instant the third pulses have been collected( only at the power/compression stroke,not the exhaust/intake stroke). Ive looked through Transmic and i am not sure if the program actually sends spark everytime the piston is near TDC. 

The program that im working on will:
-Calculate RPM and find a suitable delay values.
-No delay at high RPM,spark will occur at 36 degree BTDC
-Fixed delay for RPM lower than 1000, say at 10 degree.
-Spark occur for a limited amount of time,1mS

As i said before, im a noob in PIC programming, thats the real reason why im using PIC16F84(theres a lot of resources,tutorials available). Youre right about the tables,i did 8 values of delay just because i want things to be simple at first and move on with other complicated stuff(i hope). So far, ive learned how to use call table instruction(example : 8 LEDs that flashes from side to side) but im not sure about rpm calc.. 

Posted on 2008-02-10 02:11:54 by eddy123456
Do you think the following HLL outline will work? Especially about CurPhase, I don't see a way to determine which phase the engine is in.

// Assume 8MHz clock, so 2 million instructions per second

#define TICK_CYCLES 20 // how many cycles the "tick" loop takes, including the branching

1 tick = 10us,  100 ticks=1ms
1000 RPM = 60ms per revolution = 6000 ticks
2000 RPM = 30ms per revolution = 3000 ticks
4000 RPM = 15ms per revolution  = 1500 ticks
8000 RPM = 7.5ms per revolution =  750 ticks

unsigned short TimeBetweenCoilPulses = 0xFFFF;

unsigned short CurTickCount=0;
unsigned short PrevTickCount=0x8000;

unsigned short Time_TillSpark=0;
unsigned short Time_TillUnspark=0;

TimeBetweenCoilPulses = CurTickCount-PrevTickCount;
PrevTickCount = CurTickCount;
_outSparkPin = 0;

static byte CurPhase=0; // how do we KNOW when we're being pulsed about which phase?! In 50% of the startups, we'd be out of phase!

if(TimeBetweenCoilPulses<=750){ // 8000+ RPM
Time_TillSpark = 0;
_outSparkPin = 1;
}else if(TimeBetweenCoilPulses>6000){ // less than 1000 RPM
Time_TillSpark = 525;
}else{ // 1000-8000 RPM, TimeBetwCP is [750;6000]
Time_TillSpark = TimeBetweenCoilPulses/10 - 75;
Time_TillUnspark = Time_TillSpark+100;


void main(){
_outSparkPin = 0;

for(;;){ //--------[ this is the "tick" loop ! ]--------[
if(Time_TillSpark==0) _outSparkPin = 1;
if(Time_TillUnspark==0) _outSparkPin = 0;
NOP; // filler-in. If an interrupt happened in the last ~20 cycles, we'll be interrupted now

Posted on 2008-02-10 04:30:11 by Ultrano
Im sorry about the last post, it was really confusing. I misunderstood the concept of "wasted spark". I thought it was mainly about wasting the 1st spark(which corresponds to the 1st pulse) in order to calculate RPM as you start up the engine (i need to give it a new name, "nofirstsparkwhenyoustart"  :lol:). since theres no way you can calculate RPM using only the first pulse. The actual concept of ''wasted spark'' refers to the spark which occurs at exhaust/intake stroke(rather than than compression/power, this happens when we provide spark at every pulse which solves the phase problem). This "wasted spark" is use to burn excess fuel.

Thanks a lot for the hll code, i am not familiar with the codings but ill try to learn it this week but I guess the CurPhase can be neglected?
Posted on 2008-02-11 09:37:33 by eddy123456

Wouldn't you simply get pinking or detonation?

Maybe a two-stroke would be a safer bet....at least to start with.
Posted on 2008-02-11 19:53:30 by eek
Your distributer should already have all these gadgets, except nowadays its put together in an electronic ignition system that uses sensors.

The distributor also houses the centrifugal advance unit: a set of hinged weights attached to the distributor shaft, that cause the breaker points mounting plate to slightly rotate and advance the spark timing with higher engine rpm. In addition, the distributor has a vacuum advance unit that advances the timing even further as a function of the vacuum in the inlet manifold. Usually there is also a capacitor attached to the distributor. The capacitor is connected parallel to the breaker points, to suppress sparking and prevent wear of the points.

Anyway. Best of luck.

Plus you need to take account of the engine load, not simply the speed, which is done via the inlet manifold vacuum pressure.


Torque is the ability of the engine to continue to twist (rotate) the rear wheel with great force. Torque has nothing to do with speed. Maximum torque is not to be found at the highest revs but somewhere below that - perhaps as much as 25%. Because lower revs are involved, the rear wheel is less inclined to spin and loose traction - an important issue when riding your bike up a steep gravel road.


Horsepower is the ability of your engine to move your bike forward at a certain speed - the higher the speed, the shorter the time taken, the greater the horsepower needed.
Every engine has its own characteristics of torque and horsepower - something you as the rider can only learn with experience and hopefully, not too much trial and error! In the example specs given below the engine develops the most torque at 4000 rpm before it starts to drop again. By contrast the horsepower available increases steadily all the way to 5000 rpm.

Posted on 2008-02-11 20:14:23 by eek
What Happens When the Timing Is Advanced  :shock:

Posted on 2008-02-11 21:12:04 by eek
The whole ballgame must be different for a 125 single.

If the pulser is fixed at 36 degrees BTDC then that would destroy an ordinary engine, which needs about 10 degrees at lower revs.

And yet a standard 125 can idle with a fixed BTDC of 36 degrees.... :shock:
Posted on 2008-02-11 21:40:18 by eek
Hi eek,

From what ive read (googled wasted spark), wasted spark wont lead to detonation and pinging since in exhaust stroke, air and fuel is not compressed but the extra spark lowers the lifespan of the spark plug(but i stand to be corrected).The engine that im working on uses CDI type of ignition, where in lower revs sparks occur 13 degree BTDC, 38 degree at Higher RPM. The main purpose of what im doing is to emulate this system by using PIC, so that if i want to use a fuel with higher octane, i can just pug in the timing curve (if it is provided).
Posted on 2008-02-11 23:13:30 by eddy123456
At 36 dbtdc, ur asking for a broken crank, I rebuild veteran single cylinder engines, 36 is too much even for a lightweight single piston engine, your crank ends up doing all the work not absorbed by the con rod.
Sure, it CAN idle at 36, but SHOULD it?
Luckily for me, the engines I work on support manual advance and retard, so changing the timing is easy, and I have control...
Posted on 2008-02-12 03:00:37 by Homer
Your wasted spark is fine.
I used to have a 2CV 652cc with electronic ignition, which was a flat twin and a sensor on the flywheel would set off the coil and it would ignite one on the power cycle while the opposite cylinder was on the exhaust stroke, which saved bothering with a distributer.

Visa Special - Club (two cylinder) 1978-1988

From the start in September 1978 until the end in 1988, the Visa was available with a two cylinder aircooled engine. This engine is similar to the engines which have been used on other two-cylinder CitroŽn models (like the 2CV) for many years. The principal differences are that its capacity has been increased to 652cc and that it is equipped with an electronic ignition system, controlled by a computer.
The Club is the more luxurious model of the two with some extras like adjustable seats, parcel shelf, side overriding strips, a grille with chrome accents and stainless steel wheel covers. The two cylinder models do not have a rear spoiler.

The computer was for timing advance and engine loading purposes.

What I find unusual about your wee 125 is it seems to NOT have any timing advance system as standard.

From these 125cc examples it looks like about 20 degrees BTDC is the norm.


Posted on 2008-02-12 05:05:14 by eek
oops...missed your 13/36 post sorry.

Higher octane fuel will help you take advantage of anything you can write yourself, I see what you're aiming for here, because higher octane fuel is more timing predictable.

Okay. I'll leave you in the hands of the ASM experts.

Good luck dude.
Posted on 2008-02-12 05:12:44 by eek