CDI Tester

Greetings to all.
First post here from a newbie in the Arduino world.

I'm trying to build a tester for motorcycle CDI units.
CDI stands for Capacitor Discharge Ignition and it's an electronic unit that controls several aspects of a motorcycle or a car, like ignition advance, solenoids etc. It was severely used in the '80-'90s era on many motorcycles and cars that used to have carburetors instead of nowadays injection systems.
The CDI used to be triggered from a flywheel that had lobes and sensors positioned nearby, mostly hall or variable reluctance sensors.
The sensors provided the CDI with info on where the crankshaft is located along with rpm speed.

I'm trying to simulate this exact signal from the sensors, as to trigger a CDI hence it starts supplying spark at the plugs, switch on solenoids etc. WITHOUT having the engine working. This would be very helpful for diagnosing possible issues with any CDI unit while still keeping engine noises away from my workshop.

Ps.1 English is not my native language, so sorry for any issues.
Ps. 2 to be continued...

After numerous (and unsuccessful, so to speak) attempts to construct an analog device that mimics the variable-hall sensors, a friend of mine suggested that I should enter the Arduino world. :slight_smile:

Along with his valuable help while I myself still learning on Arduino programming language, we came close to something that pretty much seems to work though it's still far away from perfect.

In my case,
we used a flywheel that had 4 lobes and 2 sensors.
It's a V2, 90 degree cylinder, motorcycle engine.

We measured the dimensions of the flywheel, the lobes etc. etc. and build a sketch that integrated Timer1 Library.

Ps. be continued.

Even though the above code works, the result has some issues.

The tachometer needle is flickering a bit and we cannot test the CDI above 4.500rpm.
It just stops working no matter what, while the CDI is still working perfectly and reaches 13.000rpms on the tacho while used on an actual motorcycle. It just won't rev more than 4.500 rpms while being triggered from the Arduino.

Here is a video of the CDI unit in action with the help of Arduino. You will understand better what I'm trying to do.

Any info on how to proceed, is more than welcome. :slight_smile:
Many thanks.

I see that your solution is based on the Timer1 library. While I'm sure it is a well written library, and I'm sure there are plenty of people who get good results from it and will advocate its use, IMO it is an inappropriate approach to take for the majority of timing applications - principally because it requires you to design all of your code to run in an interrupt context which introduces significant issues and I don't see the need for that here.

The frequencies you're trying to achieve can be achieved quite easily using conventional programming techniques. The approach I'd use would be to use the technique demonstrated in the blink without delay example to run code at regular intervals. Currently the code is incrementing a tooth count. You could probably make this work (although reading the analog input once per tooth might limit the speed you can achieve) but since you ignore the majority of teeth I would have thought it was simpler to time the trigger events directly. In this scheme each output would have a state variable which records whether the output was currently high or low, and check whether it was time to change it.

I would anticipate the whole sketch fitting in a couple of dozen of lines of code and not needing any external libraries.

Thanks for your reply Peter.
I've checked the blink without delay sketch and I have no idea on how to use it for my application.

Is it possible to give me a very small example based on the code that I provided before?
I want to see the basic idea that might be enough to get me going for a while.

I assume the Problem is here:
Timer1.setPeriod(pot); // setPeriod (uS)
at some point the period might become smaller than the amount of time needed to call and execute the SignalGen() method.

Try replacing:
void SignalGen()
void loop()

Timer1.setPeriod(pot); // setPeriod (uS)

for a start.

The 'Mark 1' version making minimal changes to your original code would just increment the tooth count at regular intervals and do stuff when the tooth count reaches the trigger values in your code:

// not compiled or tested

unsigned long lastToothTime;
unsigned long toothInterval;
const int TOOTH_COUNT = 70; // number of teeth per revolution, whatever that is
int toothNumber;

void setup()
  toothInterval = getToothInterval();

void loop()
  if(millis() - lastToothTime >= toothInterval)
    lastToothTime += toothInterval;
    toothNumber = (toothNumber + 1) % TOOTH_COUNT;

    if (toothNumber == 0 || toothNumber == 8 || toothNumber == 25 || toothNumber == 33)
      digitalWrite(3, HIGH);
      digitalWrite(3, LOW);

    if (toothNumber == 17 || toothNumber == 25 || toothNumber == 42 || toothNumber == 50)
      digitalWrite(4, HIGH);
      digitalWrite(4, LOW);

    // once per revolution, recalculate the required engine speed
    if(toothNumber == 0)
      toothInterval = getToothInterval();

int getToothInterval()
  // TODO: read the analog input, and calculate the current tooth interval from it

Thank you both for your time.

I will give it another go on the sketch along with bennob's notes and also try to work on the MK1 version of Peter. :slight_smile:

Hello to you.
got your email.
what engine, CDI, 1 cylinder, 2 or ?
does the CDI have cam and crank signals?>
you're building the CDI tester (ive run them since Delta mark 10s in 1970 (first ones) so am fully aware of them.
Ive hooked up many spark systems to Megasquirt ECU's (both sides, input and output)
you are building a signal generator, to make your motor cycle, CDI box happy.
CDI are none the two alike (in details) (triggers)., the CDI part, simple and not new. )

we dont have the spec. engine, (scope photos work for me)
or the spec on the CDI inputs, just a 90s comment, (lots of 90s bikes, to be sure... )
as you saw, there non HALL inputs , on my page (mag coils only) needed transformers.
the ECU I used, has inside, zero crossing detectors. so a 5vdc square wave is useless for that.

that crank signal. will only be 233 pulses per second, very slow,. 14,000 divided by 60minutes (converts to seconds ) PRT.
My ford simulator runs to 5500 rpm and the ECU cuts spark. so the arduous does that.

my guess is the CDI needs, zero crossing , signals, (un seen or no spec)
then there is timing, the CDI may need a correctly timed cam signal.. does it?
to make a 1 channel signal generator is easy with or with out a computer
but timing, is more easy with the puter. (it can count)

the inputs can be , level sensitive. , and zero cross and , timing.

take a cars CKP it only has this very tiny 1v signal.. (what is yours) normal. (use a scope)
but on many cars the CMP (cam) is a pefect hall effect 5vdc square wave. (and must return to TTL low level.)
on a twin engine, there will be 2 TDC signals. one for each cylinder. some twins are pistons, 180 out and others not, even.
like my old 305 honda. has.

ive no idea what your is., ?

you should make a electrical drawing, of the normal system.

ok look in mail. old two stroke V2 90 degree motorcycle
2 stock, not 4.
so it fires every 180 degree , front the rear, repeat. or?
a Bimbota. 97?

this is like the old TV show, What's my line . (fun because the other 2 lie or obfuscate) what engine. ?

a photo of the flywheel and mag , handy?

black box, reverse engineering. (basics, background)
is this a one off tester?, or many of same type?, or for many engines,? (you stated a range of years,so thought this..)
or just for one personal, motorcycle, not going in to the CDI business????
but no matter, you need the following...
the input resistance on each pin of the CDI to the power pin and ground pins (not connected to power)
then power the unit up, and measure each input pin, volts.
then measure the current shorted to ground. (ammeter) WE measure IIH and IIL, Current input high and low.
if the current is too high, it can very easily burn the Arduino up , same with volts. (might take a second, or week, (like many things damage can be progressive and for sure in electronics)
then the mag coils, we need the voltages, while running, a scope is all that works here.
as a start.

So what do you think, helpful so far, or daunting....?

PS: one more point, the coils. some are very high powered used in an older generation.
after all it dont take a dynamo like my 1966 bike has to trigger the CDI
but on some years, they use old style powerful mag coils because, they have too many in stock.
Some are very powerful not the car like mags that are 1v, but have huge 10v pulses, and the CDI has a voltage divider and clamp
to use these pulses., in this case we need to emulate that with driver connected .

is the CDI potted.? lots and lots of question, with no photo of engine or its part, and the original ignition schematic.
all are clues to what is needed.

did you have any advance with this project?

I am really interested in using Adruino as a signal generator to excite a CDI, even use arduino to test CDIs.

Please contact me if you want... I will be working on this.


I'm trying to build a tester for motorcycle CDI units.

I would have thought a simple 555 timer would do the trick.