One question I often see in the USENET newgroups is, ``Why don't automobile manufacturers publish schematics and source code of their engine control computers?'' I wondered the same thing myself. Could you image what the state-of-the-art would be today if thousands of tinkerers like us could play with the engine controller? Could you imagine the emissions problems we horsepower-mongers would create?. Maybe this isn't the safest idea; cars aren't toys. Yeah, right.
For the performance seeker with a limited budget there exist no affordable high performance engine controllers and calibration tools. For this, among other reasons, the Formula SAE competition was created involving as many as 40 universities. The goal is to create a fast, agile, and creative race car under $7000. Only until the last year or so have the schools tackled homebrew electronic engine controllers and it seems to be a rapidly growing trend. Systems such as DFI, MSD, and Haltech simply cost too much for a car that must be inexpensive. We are shooting for an ignition system that will cost about $50. No kidding. The most expensive piece isn't even the microprocessor, it's the transistor that charges the coil.
The powerplant in the Georgia Tech car is a Honda CBR 600, or Honda Hurricane, that displaces 600cc with four inline cylinders. We replaced the stock carburetors with GM's 1987 Sunbird Turbo fuel injection system, but kept the stock Honda ignition. However, the GM system proved too complicated for our needs and did not integrate well with the Honda ignition. For example, the GM fuel injection had to be fooled into seeing half the actual RPMs since the CBR 600 is capable of 12,500 RPM. Because of this, we had to recalibrate the fuel injection for the new RPM curve which proved a daunting task due to the myriad parameters involved.
I decided to build a fuel injection and ignition control system that could handle the Honda's phenomenal performance, but also be easily calibrated for optimum power and performance. I started with the ignition system ( Figure 1) since it could be developed separately and is simpler than a fuel injection system. I wanted a system that could send all its operating information to a PC and also be re-programmed by the same PC -- in real time. The end user's main parameter would be a curve of spark advance vs. RPM. This curve would be displayed on the PC screen and the user could modify it and instantly see and hear the effects on the engine.
The ignition controller will be presented in two parts: the microcontroller circuit and the ignition peripheral. This emphasizes the modularity of the system. The microcontroller circuit runs stand-alone, but does nothing without external circuitry. You may add any number of peripherals to the microcontroller as long as resources and processing time are available. This article concentrates on the capabilities of the microcontroller, the design of the microcontroller circuit, and an outline of the software. A little background and theory are introduced so you can develop your own peripherals besides the ignition peripheral discussed in the next installment.
Many manufacturers are moving to digital-distributorless ignition systems. They have virtually no mechanical parts to wear and are easy to maintain, calibrate, and upgrade. Race cars have been using direct fire ignition systems for some time, with good reasons. Ignition energy is not wasted sparking across the contact breaker in a distributor. This also reduces electromagnetic interference that causes errant signals in other electrical equipment. Advance is no longer calculated using vacuum lines and centrifugal mechanisms; it is now calculated by a microprocessor based on RPM sent by an inductive sensor near the crankshaft.
Since the ignition system is microprocessor controlled it can be programmed to deliver maximum power under all conditions. An ignition system can be programmed for different gasoline, for example. If racing fuel is used, such as 116 octane that powers the Georgia Tech car, more advance can be programmed into the ignition controller. Higher octane fuel burns slower so ignition needs to start earlier for complete combustion.
The ignition system can also be used for traction control. Only a few more sensors are needed. Speed sensors for both front wheels and both rear wheels, unless a limited slip differential is used then only one sensor is needed since the differential will control slipping of the drive wheels with respect to each other. If slipping is detected by the microprocessor, it can retard the spark of the ignition system. Retarding the spark away from its optimum firing angle reduces power and can help the driver recover the slipping wheels.
A distributorless ignition consists of coils, ignitors to fire the coils, a computer, and some sensors. The distributorless ignitions require a coil for each pair of cylinders. The coil fires both plugs simultaneously -- one firing in the combustion stroke, the other in the exhaust stroke. Most of the energy is used to ignite the compressed mixture (about 35,000 volts) and very little is needed for the other (a 1,000 or so volts). Since the coils take turns firing they have more time to fully charge at high RPMs, thereby delivering more power.
Because cars must follow strict emission controls, the engine controllers run closed-loop. A closed-loop system monitors the output and adjusts the input until a more desired output is obtained. The oxygen sensor, for example, tells the computer what the air/fuel ratio is by sampling the exhaust gases. The computer can than adjust the mixture for better performance or cleaner exhaust. Knock sensors also provide feedback to the computer, telling the controller when pre-ignition is occurring. Open-loop systems run regardless of the output, and must be calibrated to get good performance. Our ignition system runs open loop since this is simpler and costs less. The system can be modified to run closed loop by adding a knock sensor, bandpass filter, and modifying the software. The knock sensor will be described in the next article but not implemented since knock sensors are very engine dependent.
We need a microprocessor to run the software that converts the data from the sensors into accurate spark timing. Since we are using a microprocessor, its trivial to added more functionality by changing the software. Let's add real-time data acquisition and real-time calibration of the spark timing linked to a PC via the serial port. For future software upgrades, the system should be able to download a new program into an EEPROM. Some microprocessors have built in timers, serial ports, and analog-to-digital converters. These are called microcontrollers. We will use Motorola's 68HC11 microcontroller for the ignition system.
The program that governs the control and acquisition of the ignition circuit will be stored in EEPROM which allows us to retain the program when power is turned off. EEPROM was chosen over conventional EPROM since it can be re-programmed without having to expose it to ultraviolet light. The ignition controller will be able to re-program itself with new calibration parameters or download a new program over the RS-232 link. The EEPROM takes about ten milliseconds to write a byte, or two seconds to re-program the entire EEPROM. Since the 68HC11 cannot fetch an instruction while the EEPROM is being re-programmed, the ignition controller is shut down while calibration parameters or a new program is being stored. This means the engine should be turned off before re-programming. Note that recalibration can still occur while the engine is running, since the calibration parameters are copied to SRAM when the system is turned on. Only when the calibration data or a new program is to be stored in EEPROM must the engine be shut off.
The internal RAM of the 68HC11 is only 256 bytes. Planning for expandability, an external static RAM (SRAM) chip replaces the internal RAM. Eight kilobytes is overkill for the ignition circuit, but may be integrated into a larger fuel injection system. You can never have enough RAM. Static RAM was chosen since it doesn't require refresh circuitry. It is more expensive per chip than dynamic RAM, but for small projects using only one or two RAM chips, a better choice.
The Motorola 68HC11 family of microcontrollers vary in size of internal ROM, RAM, and EEPROM. The 68HC11 can operate in single chip mode or expanded mode. Single chip mode runs a program from the internal ROM or EEPROM; expanded mode takes two 8-bit I/O ports and brings the address and data bus outside the microcontroller. Since the ignition controller uses the expanded operating mode, using external EEPROM for code and RAM for variables, no internal memory is needed. The MC68HC11A0 has no internal ROM or EEPROM, and is the cheapest 68HC11 family member.
The 68HC11 has a 16-bit internal clock with three input capture ports and five output compare ports. The input capture ports detect pulse edges and can generate interrupts. The output compare ports can be programmed to generate pulse trains with variable duty cycles, also known as pulse modulated signals. These can be used to open many electric valves, like idle air bypass. A serial communications port can be interfaced to a PC and supports very high baud rates; our project will communicate at 9600 baud. These ports will be discussed in more detail in the design section.
The serial peripheral interface is similar to the serial communications interface, but is used primarily to connect multiple 68HC11s together in master-slave configurations. The serial peripheral interface is much faster than PC serial communications, operating at around a megahertz, compared with 9.6 kilohertz for PC serial communications. The ignition controller could conceivably be a slave in a larger engine control system. A master 68HC11 could control multiple slave 68HC11s that manage fuel delivery, ignition control, and intelligent sensor management. The master would also be responsible for user interface, including programming and data acquisition.
The 52-pin PLCC package has an eight channel A/D, while the 48-pin DIP only has a four channel A/D. While prototyping with the 52-pin 68HC11 may be more difficult since there are no wire wrap sockets, the extra four A/D channels are essential for engine control and data acquisition. An eight channel, 8-bit A/D may digitize the analog inputs of engine sensors such as manifold air pressure and temperature, coolant temperature, knock, throttle position, and O2.
The microcontroller circuit is shown in Figure 2. This circuit is generic and not confined to any specific purpose. You may find this circuit in your toaster oven as well as half a million cars. The software (or firmware, since it resides in EEPROM) and peripherals constrain the circuit to a more specific role. At the heart of the ignition system is Motorola's 68HC11 microcontroller.
The two 8-bit digital I/O ports of the 68HC11 are sacrificed for the 16-bit address bus and 8-bit data bus when the 68HC11 is used in expanded mode. Both buses are squeezed into two 8-bit ports by multiplexing the data bus and the low byte of the address bus. The timing diagram in Figure 3 is essential to peripheral design for the microcontroller. The EEPROM and RAM chips must present their data 192 nanoseconds after E clock goes high -- a 200 nanosecond part is commonly used. The RAM chip must perform an internal write 128 nanoseconds after the E clock goes high and should finish before the Write Data Hold time is over. The 16-bit address is valid when the Address Strobe (AS) line goes low. An 8-bit latch should be used to hold the lower eight address lines since it changes into the data bus when E clock is high.
The input capture ports of the 68HC11 records the value of the 16-bit internal clock at rising edges of an input pulse train. One of these ports is used to calculate RPM and engine angle for the ignition controller. The Honda CBR 600 has a steel wheel attached to the crank shaft. The wheel has seven teeth arranged as eight symmetrically placed teeth with one missing. An inductive pickup sensor is used to detect the teeth as they move by the sensor. RPM is calculated by counting the time between the teeth. The missing tooth is used to find engine angle. The next tooth after the missing tooth is some known angle before top dead center (BTDC) of cylinder one, let's assume it is 40 degrees BTDC. If I wanted the ignition controller to fire 15 degrees BTDC at 2000 RPM, then the 68HC11 looks for the first tooth after the missing tooth. When the first tooth is detected the 68HC11 counts down from 40 degrees to 15 degrees, then triggers the ignition chip to fire the spark plug. This system can be modified in software to accommodate many kinds of RPM/engine angle sensors.
The output capture ports can trigger an external event when a 16-bit programmable time is reached by the internal clock. Two output capture ports will be used to trigger the ignition circuit to fire the spark plugs. The 16-bit programmable time will be set by the interrupt service routine that detects rising edges from the crank shaft sensor. The programmed time is the retarded spark angle past the 40 degrees advance offset built into the crank shaft wheel. In the above example 25 degrees (40 - 15) would be programmed into the output capture port after converted into microcontroller clock cycles.
The serial communications interface links the ignition controller to a PC. From the PC the user may re-program the ignition controller or download data captured in real-time. A TTL-to-RS232 converter will be needed to change the serial data from 0 and +5 volts (TTL) to -10 and +10 volts (RS-232). Maxim sells many parts to do this; the ignition controller will use a device that requires only a +5 volt supply and external capacitors.
The 68HC11 is driven by an 8 MHz CMOS compatible crystal. The internal clock divides this frequency by four causing the chip to run 2 MHz. The maximum internal frequency is 2.1 MHz, but the 2 MHz clock can be divided internally to provide the 9600 baud serial communications clock.
Motorola's MC34064 controls the RESET line of the 68HC11. If the power supply voltage drops low enough, then the internal and external EEPROM could start re-programming themselves with random values. Because of this the MC34064 senses when the supply voltage drops too low then drops the RESET line of the 68HC11 causing it to stop operating.
Since the data bus and low byte of the address bus share the same eight I/O pins on the 68HC11, a 74HC373 (eight bit latch) is used to hold the address lines when the data bus takes over. From the timing diagram, you can see that the multiplexed bus is an address bus during the low cycle of the E clock, and it becomes the data bus during the high cycle of the E clock. The address strobe (AS) output goes low when a valid address is present on the multiplexed bus. The falling edge latches the eight lower address lines into the 74HC373.
Attached to the address and data bus are the EEPROM and SRAM. The EEPROM requires eleven address lines. It takes the lower eight from the 74HC373 latch, and the low three bits of the upper address byte output directly from the 68HC11. Its eight data lines are connected directly to the multiplexed address/data bus. The EEPROM is selected when the upper five address lines are all high. The two kilobyte EEPROM occupies the upper two kilobytes of addressable memory or F800 to FFFF. Its output is enabled when the chip is selected and when the E clock is high and the R/W (read/write) line is high. A byte can be programmed into the EEPROM when the chip is selected, the E clock is high, and the R/W line is low. After a byte is written the RDY/BUSY (read/busy) line must be monitored, since it takes ten milliseconds to write a byte two consecutive writes are not allowed. All addressing control lines are handled by the ignition controller PAL.
The SRAM uses all the lower eight address lines output by the 74HC373 latch and uses lower five bits of the upper address bus output directly from the 68HC11. Its eight data lines are connected directly to the multiplexed address/data bus. The SRAM is selected when the upper three address lines are high, low, and low, respectively. This maps the SRAM to addresses 2000 to 3FFF. The output is enabled when the SRAM is selected and when the E clock is high and the R/W line is high. The write enable (WE) must be low to write a byte into the SRAM. This is enabled when the SRAM is selected, the E clock is high, and the R/W line is low.
All address and control decoding is performed using a 16L8 programmable array logic (PAL) chip. The PAL generates the chip select signal, decodes the output enable lines and the write enable lines for the SRAM and the EEPROM. The source code is shown below. The format below can be compiled using AMD's Palasm software to make a JEDEC file. Most PAL programmers accept JEDEC files. ???
Now a few words on prototyping. The best form of circuit prototyping that I know of is wire wrapping. Wire wrapping can be performed with battery powered tools (expensive), slit-wrap tools, or a hand wire wrap tool. The slit wrap tool is a cylindrical tube with a spool of 30 gauge wire at one end and a wire wrap tip at the other. Wire is pulled down the tube as you twist the tube around a wire wrap post. The insulation on the wire a slit as the tool is twisted, but I have found that shorts to other wire wrap posts occur easily as you run wire across a protoboard. My tool of choice is the hand wire wrap tool which costs about $10. This tool has a wrapping side and unwrapping side with a 30 gauge wire stripper built into the middle. I usually strip off about one inch of insulation, wrap it around one post, then run the wire around chips and components to its destination. I cut the wire about an inch longer than required, strip that inch, and wrap it around the destination post.
I prefer wire wrapping over bread boards because its more durable and rugged. I have seen military installations dating back to the 60s that still have functioning wire wrap boards. One draw back of wire wrap is its susceptibility to high frequency signals and noise. Each wire wrap post acts as a small antenna, transmitting the signal it carries and receiving other signals. Digital switching frequencies are fairly high; the 68HC11 switching time is 20 nanoseconds which corresponds to 50 MHz. For brief switching periods this noise does not present a problem, but prototyping circuits that regularly carry signals over 30 MHz can be.
As with most prototypes, a printed circuit board is the eventual goal. Having one designed and built for you can cost about $300, which is beyond the budget of this ignition system. There are two ways I know of to make your own printed circuit board. One method is to draw the circuit on a copper plated circuit board with chemically resistive ink. The copper board is placed into a try with etching solution and the copper is removed everywhere except under the ink. This method is limited to large copper traces and neat, trim circuits are hard to create. A better method is almost like developing film. The printed circuit layout is created using transfers or by ironing a laser printer ``reverse image'' of the circuit onto the copper. The copper is then exposed to UV light and etched in a chemical bath. This method results in very profession looking circuits when done with a drawing or CAD system and ironed onto the copper.
The software written for the ignition controller performs three primary functions. It must handle the serial communications to and from the PC, it must calculate the RPM and engine angle and fire the spark plug at the correct time, and it also blinks a LED to show that it hasn't wandered off somewhere in memory and hung.
Since the ignition timing is time-critical, it will be handled using interrupts. For each tooth on the ignition timing wheel a pulse is generated and sent to the input capture port of the 68HC11. The rising edge of the pulse causes an interrupt to be generated in the microcontroller and the interrupt service routine is called. The interrupt service routine determines the RPM and also counts which pulse it is currently on and may start a countdown to trigger the ignition coil. If a trigger pulse is counted then an output capture port is prepared to fire; recall that the trigger pulse is 40 degrees BTDC. The calculated RPM is used to find a spark advance value in a look up table. The spark advance value is adjusted to 68HC11 clock units instead of degrees and written into an output capture port. At this point the ignition firing is automatic and the interrupt service routine can return to the main program.
The RS-232 serial communications is also interrupt driven. For each byte received by the 68HC11 an interrupt service routine is called. The PC will send a message to the ignition controller telling it whether to read some bytes from memory and send them to the PC, or to read bytes from the RS-232 link and write them into RAM. The table below summarizes the message types.
The first byte the interrupt service routine expects is the ``type'' byte which must be zero to two. Depending on the type, the interrupt service routine reads the remaining bytes, stores them in a buffer and then checks the additive total of the bytes against a checksum -- the last byte sent. If the checksum does not match the additive total of the bytes sent, then the message is ignored.
My favorite feature of the ignition controller is that it can send bytes continuously back to the PC so that the PC can monitor changes in real-time. This will not interfere with the spark timing interrupt since that interrupt has a higher priority than the RS232 interrupt. The spark timing interrupt will actually interrupt the serial communications interrupt if necessary.
Next time I will explain the signal conditioning hardware for the inductive pickup. This will be added to the extra prototyping area left on the wire wrap board. I will also describe the ignitor unit that charges and fires the coil. This unit would be better located away from the ignition controller due to its susceptibility to noise. I will also give source code listing of the microcontroller program. I am working on the PC interface software, and am strongly considering porting it to OS/2. If someone wants to volunteer to port it to Windows, I'll give as much help (and aspirin) as I can.