Sparky Danger Organ Now On The Autopian

Discovering I can just treat Sparky Danger Organ like a piezo buzzer for making music was great, it opened up a world of already-written Arduino sketches playing music with tone(). Now Sparky is getting its 15 minutes of fame with Emily’s This Is How Electronic Ignition Works And Also How To Make A Spark Plug Play Music published on The Autopian.

In Emily’s article, she compared modern electronic ignition with electromechanical ignition from BC (before computers) era of cars. The distributor diagram is a pretty good explanation why I couldn’t do very much with an old ~1950s Chrysler ignition coil my neighbor had sitting on a shelf: I needed something to interrupt power to the ignition coil so its primary winding’s 12V field can collapse and induce high-voltage in its secondary winding. Since I usually play with electronics manipulating 5V or less, at well under 1A, I didn’t have anything on hand suitable to handle such power.

However, a modern electronic ignition coil has that switch built-in. (The “Igniter” box in the LS1 Coil diagram of Emily’s article.) So to repurpose a retired coil+plug only requires a 5V, low-current, digital control signal to be sent on its IGT pin. Now that’s something Arduino tone() can do easily and help Sparky find its singing voice.

So what’s next? There was a bit of confusion between Emily and I about Arduino tone(). She referred to an installed library, but I found it as a built-in function. Investigating this confusion led me to https://github.com/bhagman/Tone where I learned we were both right. There’s a full non-core version that Emily had to install into her (presumably older) Arduino IDE, and Arduino had incorporated a simplified version of this library into core which is what I found. The simplified version can only generate one voice. The full version can generate more voices: one per hardware timer on the AVR chip. ATmega8-based chips have two timers so two voices. ATmega328P (like that on the Arduino Nano I used) can do three voices, and an ATmega1280-based board like the Arduino Mega can control six spark plugs. Useful facts to keep in mind whenever Emily or I get our hands on more retired electronic ignition coils.

Arduino tone() Can Play Sparky Danger Organ

I got a spark plug to sing a song, but it was singing out of tune and I didn’t know why. I barely know enough about music to get this far. My friend Emily had more sheet music reading skill and offered to double-check my music translation. If her translation sounds good, then we’ll know the problem was my sheet music translation. If her translation also sounds odd, we’ll know the problem is with my timing code controlling spark frequency.

I replaced my version of the song with hers, and it sounded great! So that’s settled: Sparky’s first performance sounded bad because I didn’t know how to read sheet music. I also received feedback that the way I represented music in my Arduino code was peculiar. No argument from me, because I wrote it out of ignorance and it was what I could hack together at the time. Emily then asked if there was a reason why I’m not using tone() if I’m using an Arduino anyway. The answer was that I didn’t know it existed.

Prompted by this question, a bit of searching on “Arduino tone library” found a GitHub repository at https://github.com/bhagman/Tone, whose README explained it was a library to use AVR timers to generate 50% duty cycle square waves of a specified frequencies along with a list of #define that mapped musical notes to frequencies. It also said a single-timer version of the library has been incorporated into Arduino core, so for single-voice applications like Sparky we wouldn’t even need to install an additional library.

I thought the 50% duty cycle (half of time signal is on, half off) might be a problem, because I’ve been using 0.5ms signal pulses and leaving the pin off the rest of the time. I looked in the tone library but wasn’t familiar enough with AVR timer configuration registers to understand how I might convert it over. Then I remembered the always-useful mantra: check the easy thing first. Maybe Sparky doesn’t mind if the trigger pulse was longer.

Since the single-timer version of tone was now built into Arduino, I looked for Arduino built-in examples illustrating its use. I found “Examples/02.Digital/toneMelody” which was designed to work with a piezo buzzer. I pointed it to Sparky’s IGT pin and heard it play the little melody. Great! Sparky doesn’t mind longer IGT pulses and I can throw out all of my hacked-up music-hampering playback code and just use tone(). I don’t even need to struggle with sheet music or convert them to MIDI notes anymore, I can play songs other people have already translated for tone() playback. I found several collections and the first collection with its own take on Beethoven’s “Ode to Joy” is https://github.com/robsoncouto/arduino-songs. I gave to Sparky and yeah, way better than my version and a lot easier too. I wish I knew tone() existed a few days ago, but at least I know now. This tone() music earned Sparky 15 minutes of fame on The Autopian.

Sparky Danger Organ

I’m playing around with a retired Denso ignition coil-on-plug pack. After gaining a marginally better understanding of its limitations, I will convert my test circuit to a proof of concept discussed with my friend Emily Velasco (who gave me this thing to play with): make it into a silly music instrument I’ve named Sparky Danger Organ.

This ignition coil came out of a Toyota Sienna’s V6 engine which probably redlines somewhere around 7000 RPM. At 7200 RPM this coil would be firing sixty times a second, but 60Hz is on the low side for music-making. So my workbench experiments were to find out how much faster I can drive this thing and I think it’s somewhere between 1 kHz and 1.5 kHz. (There isn’t an exact number because sparks fade out rather than abruptly cut off.) But judging from Wikipedia’s list of piano notes and their frequencies, even a limit of 1kHz should be enough to represent an interesting range of music notes.

I then started looking for music I can map to frequencies. I found a Blogspot page Image of 88 piano keys on sheet music with note names, octaves and midi numbers, and downloaded the PDF version of the chart. Then I looked for a relatively simple and well-known piece of music and settled on “Ode to Joy” from Beethoven’s Symphony No. 9. I quickly found a simple arrangement by Benedict Westenra intended for piano beginners. Perfect!

Putting all that together gave Sparky Danger Organ its first performance, and it’s definitely along the lines of a bear riding a bicycle: the novelty is not that Sparky Danger Organ is a great music instrument, but that it can make an attempt at all. There’s only a very limited range of frequencies where it sounds like an acceptable tone, and even within that range the music does not sound great. I may have made mistakes translating piano sheet music into Arduino code. Or maybe the frequency I generated is not what I had intended to generate, throwing the instrument out of tune. The top suspect along these lines is the possibility Arduino framework is doing work behind the scenes and adding delays throwing off the output frequency.

Despite those potential problems, it was a successful proof of concept. Emily has some ideas on how to troubleshoot this device. [UPDATE: the solution was to throw away all of my crappy code and use Arduino tone().] And if we ever get our hands on one or more engine’s worth of ignition coils, there may be a Sparky Danger Orchestra.


Public GitHub repository for this project: https://github.com/Roger-random/ignition_coil

Denso Ignition Coil-On-Plug Module On Workbench

Experiment to control a Denso ignition coil-on-plug module was far more successful than I had expected. It was a lot of fun! Because high voltages are involved (the very core purpose of an ignition coil…) the first round was done on my garage floor, away from most of my electronics components and equipment. Now that I have gained some confidence it won’t send sparks shooting everywhere, the test rig was moved to my workbench to get some measurements.

These numbers won’t be very good, though. It would be better if I can get an idea of what parameters are important to an ignition coil and what values to expect from a data sheet, but I had no luck finding such official engineering information. Searching for “Denso 90080-19016” found many auto parts suppliers offering to sell me more of those units and/or non-Denso substitutes, but no details beyond which cars the part would fit. Furthermore, this ignition coil was retired from a Toyota Sienna due to error codes relating to the ignition system, so it is probably not functioning to spec anyway.

Its power supply requirement is my biggest unknown. I had tried connecting it to a lithium-ion battery power pack delivering approximately 12 volts, but its power protection circuit believed there was a short circuit and cut power. My bench power supply has a red LED indicating “amperage limit reached”. When using it to power my experiment circuit, that red LED blinks every time the coil fired a spark. So clearly this coil has a brief but very high current draw. As a digital logic person, my understanding of solving such problems only went as far as “add capacitors”. I had some salvaged electrolytic capacitors available and connected them. I installed so much that the inrush current upon plugin would trigger power protection even before the coil started firing. If I disconnect power while running the coil, I can hear those capacitors supply enough to spark three or four times (each less energetic than the last) before fading out. And even with these capacitors, the brief current draw is still high enough to trigger errors. I’m either not using the right types of capacitors, or of the wrong values, to smooth this out. Such is my ignorance of proper electric power system design.

I had thought if the power requirements were simple enough, I could power the whole thing with a USB power bank. With a boost converter to kick USB 5V up to supply the coil at 12V. But given these high draw symptoms, I am skeptical an Amazon lowest-bidder DC boost converter will survive this coil’s demands. I will continue using a lead-acid battery that has (so far) tolerated such abuse.

The next set of experiments concern IGT signal duration. My experiments started with 2ms as a value I eyeballed from a blurry oscilloscope screen capture. If I want to drive this coil faster, I need to know how short of an IGT pulse I can get away with. I modified my Arduino sketch to use the knob to adjust signal duration, and output the current duration to one of my less-precious computers. The results were:

  • 2ms: initial guess that worked.
  • ~1ms: start to hear a difference in the sound of the spark.
  • ~0.8ms: sound of spark is weaker, and I no longer see IGF LED blink. So the coil thinks the spark is no good beyond this point to run an engine. Thankfully I’m not running one.
  • ~0.4ms: even weaker spark sound, and spark generation becomes intermittent.
  • ~0.2ms: no spark at all, just worrisome whining noises from the coil.

Those are the duration of IGT signal pulses with the caveat that I measured these with a constant 17ms (“redline”) between pulses. As the time between pulses shrink as well, it affects behavior in response to IGT signal pulse. The two variables are related, but I don’t understand exactly how. And without a good way to quantify results it’s not very feasible for me to map out a 2D graph charting how those two variables interact.

Lacking such metrics for better understanding, I settled on a maximum of IGT pulses 0.5ms in duration, and 0.5ms between pulses. In other words, an 50% duty cycle square wave at a frequency of 1kHz. Referencing Wikipedia’s chart of piano note frequencies, an upper limit of 1 kHz should still be enough for a bit of silly fun.


Public GitHub repository for this project: https://github.com/Roger-random/ignition_coil

Toyota Sienna Denso Coil-On-Plug Module

The problem with deciding I need to sit down and do some reading is that I’m vulnerable to get distracted by something shiny. Or in this case, something sparkly. Some time back I learned how voltage boost converters worked for laptop screen LED backlights. A little after that, it occurred to me ignition coils in modern electronic ignition engines must be boost converters as well. Except instead of driving a bunch of LEDs in series, an ignition coil raises the car’s 12V DC up high enough to jump across a spark plug gap. I thought it might be fun to try driving a coil in a non-automotive context and discussed the idea with other local makers. I was too cheap to buy a new coil just for this experiment, because I knew eventually someone would replace their car’s ignition coil and I can ask for the old one. That day has come: my friend Emily Velasco let me know she was going to stop by with a Denso ignition coil-on-plug module with associated spark plug, recently retired from her parents’ Toyota Sienna.

Research

The first step is information gathering. Thanks to ubiquity of Toyota vehicles, Emily found a pinout diagram for the ignition coil. This module has four pins. Two for power (+12V DC and ground) and two for signal (IGT and IGF). Toyota’s official workshop service information would have more details on its operation and troubleshooting, but I don’t have access to that. Fortunately there are other web resources like TOYOTAtech’s How to Find Toyota Ignition System Faults Fast! Dotting the IGFs and Crossing the IGTs.

According to this page “IGT” (I guess “ignition trigger”) is a signal from ECU telling the coil to do its thing, and “IGF” (guessing “ignition feedback”) is a signal from coil back to ECU to signal successful operation. Both operate with +5V DC logic. IGT is usually at ground level and briefly raised to +5V by the ECU to call for spark ignition. Looking at the blurry oscilloscope screen capture on TOYOTAtech’s page, my best guess is raised for approximately 2 milliseconds. In contrast, IGF is usually up at +5V DC and the coil pulls it low for roughly 1 millisecond to signal successful spark generation. This open-drain system allows multiple coils to share a common IGF line back to the ECU.

Circuit Board

Armed with this knowledge, I built a quick experiment circuit out of components immediately available at my workbench. Emily helped me by making a connector as CAD practice, for which I was thankful. My board’s output side needs to interface with that connector. On the input side, I needed two voltage levels: +12V DC for the coil and +5V DC for the signal. I have a 3S Lithium-Ion battery pack for 12-ish volts, but its battery management system (BMS) freaked out at the workload. As a backup, I switched to an old-fashioned lead-acid battery. For 5V I used the most expedient thing: an Arduino Nano with its USB socket and +5V DC output pin. To run the coil it will be connected to a cheap disposable USB power bank instead of a computer.

The experiment circuit had two input paths to IGT, switchable by a jumper. The first path is a “manual override” test mechanism with a small push-button switch. Once everything is hooked up, a push on the switch will raise IGT to +5V DC. If there is no spark, we have to backtrack and see what went wrong. If there is a spark, I can move the jumper to the other input path: pulse-generating Arduino Nano.

I’ve already established it needs to raise the line to +5V for approximately 2 milliseconds, but how long should it wait between pulses? A Toyota Sienna should idle somewhere just under 1000 RPM, and redline somewhere around 7000 RPM. This coil is responsible for a single spark plug. As a four-stroke piston engine, it would need to spark once every two revolutions of the crankshaft. The math then works out to: 1000 revolutions/minute * 1 minute/60 seconds * 1 spark/2 revolution = ~8.3 sparks/second. Invert that value to arrive at 120 milliseconds between sparks. Doing the same math for 7000 RPM arrives at 17 milliseconds between sparks. So I would expect this coil to reliably spark once every 120ms to 17ms. For the default program, I programmed the Arduino to raise IGT to +5VDC for 2ms then wait 120ms before repeating.

Coil Arrives

I started building the experiment board immediately after Emily told me she would stop by, hoping to have something ready by the time she arrived. So it was slapped together with speed as the utmost priority and everything else (visual neatness, design elegance, and… ahem… electrical safety) relegated to be dealt with later. We connected the coil’s four wires to my test circuit, and it was time for the moment of truth.

I tapped the switch, and we saw a spark. Woohoo! We powered down the system and moved the jumper. Once powered back up, the Arduino sent its pulses and we have a steady stream of sparks. Success!

Enhancements

I honestly expected a lot more debugging before getting to this point, so I didn’t have anything else prepared. Emily suggested that we connect a potentiometer to the system for interactivity, so out came the soldering iron and associated tools. Emily has built a lot of projects with potentiometer knob adjustments so she handled that addition. As the code monkey I updated my Arduino code to read knob position so we can adjust from “1000 RPM idle” to “7000 RPM redline”.

Emily also fixed a problem with my board: I had connected a LED to IGF but it stayed dark. Reviewing the circuit I realized out of habit I had set it up to shine whenever IGF is high: but the coil never raises IGF to high! It pulls IGF low to report a successful spark. Emily added a 1k pull-up resistor and rewired the LED so it shines when IGF is low.

We connected everything back up and the adjustment knob worked wonders. We can “rev up” our system and it was fun, with Emily capturing a few video clips. Unfortunately the IGF LED stayed dark, but it didn’t dampen our enthusiasm. Now that the coil is up and running under conditions approximating its designed purpose, we enter the “screwing around” phase pushing it beyond original operating range.

Adventuring Beyond Spec

Emily asked for a fluorescent tube, but my house had almost entirely converted to LED lighting. I had but a single remaining tube and it was only still there because I haven’t figured out how to open up its enclosure. Emily figured it out in five seconds and pulled out the tube, connecting its ends in place of the spark plug. The ignition coil was able to act as a (poor) fluorescent tube ballast dimly flashing the tube. (The room had to go dark for Emily to shoot that video.)

After this fluorescent tube experiment, we reinstalled the spark plug and made a fascinating discovery. With no other (intentional) changes, the IGF LED now blinks in sync with sparks as originally expected. We have no idea why. Perhaps something about the workload of driving a fluorescent tube? This coil and plug was replaced because the Toyota Sienna’s engine control unit (ECU) reported codes for ignition issues. It’s possible cylinder combustion was working properly but poor IGF reporting triggered the malfunction indicator light (MIL). We agreed if this was the case, it obviously meant Toyota/Denso must add a fluorescent tube to their official list of repair tools.

Emily tried to see if this spark can light a sheet of paper on fire. There was a lot of glowing, charring, and pitting, but it took persistence before she got a real flame. There are far more effective ways to start a fire! But it did make us wonder if it’d be practical to build a crude electrical-discharge machining (EDM) system out of an ignition coil. That idea has been added to the ever-growing project to-do list.

The most promising experiment was revving this thing far beyond “redline” by shortening time between pulses below 17ms. To go even faster, we reduced the duration of IGT pulse itself. This quickly extinguished the IGF LED, which was the coil’s way to complain things are going too fast for a good combustion-initiating spark. But that’s OK, because we’re not here to ignite air-fuel mixtures, we were trying to turn it into a silly and pointless musical instrument. Still, there was a limit. We started losing the spark (and our musical note) when we went too fast. Exactly how fast is too fast? To make further progress on this front I’ll have to better characterize parameters of this ignition coil-on-plug module.


Public GitHub repository for this project: https://github.com/Roger-random/ignition_coil