Sunday, May 12, 2013

Microcontrollers Are Slow

Efficient code
When writing program code for modern computers typically you need to focus on program correctness and reliability. In other words, the program shouldn't do crazy stuff and shouldn't crash. It's a good idea, but you might end up with code that uses more computer resources than it needs to. Usually that doesn't matter. Who cares if your sort method has 5 times as many move operations. Even a crappy 2GB RAM, 2GHz dual core box will take 3ms instead of 800ns. Extra 2.2 ms doesn't matter!

A microcontroller works on a different scale. The PIC16F1519 has 1KB of RAM and can run at 20MHz. Or 0.00000069GB and 0.02GHz. Frequency isn't a direct indication of processing speed, but it's still far slower than the modern CPUs i'm used to! In addition I have to be very sure the code is executed at the correct time. If I switch a coil or injector on/off at the wrong time I'll ruin the efficiency and power output and could even damage the engine!

Firstly a quick explanation of some of the terms i use for the microcontroller.
1. Interrupt: A signal that will interrupt the processor from what it is doing so that something urgent can be executed immediately. After the interrupt is done the processor can continue with what it was doing before.
2. Timer: A module that counts at a specified rate. Some can count to a higher number which makes them more precise.
3. CCP: A module that can generate an interrupt at a specified timer value.

I had initially wanted to use a method I called "action queue" where each "action" would turn on, turn off, or pulse (using a built in timer module) an injector or coil at the correct time. When each action would occur is based on the current cam position, air flow and other variables. When the action (along with its activation time) was determined, it was added to the action queue, sometimes with an activation time earlier than the existing items in the queue. Once the activation time of the soonest-to-be-activated action was reached, it would be run and the next item would be read from the queue. I thought it was clever since it provides plenty of flexibility. I was definitely wrong! Unfortunately I had exhausted the resources of the PIC16F1519 pretty quickly. In the space of less than a second I was trying to get the chip to determine the next action(s) to be run, add them to the queue, determine the next to be processed (from an unsorted list!), read the struct information with the function pointer (what to set), parameter value (how to set it) and the timer value (when to set it). THEN set the one available CCP module with the correct value so that the function is executed on time. AND have enough processing power to run any CURRENTLY executing action while also continuing secondary functions!

It was never going to work.

The main problem was that I couldn't set the single available CCP value before the intended timer value was reached. It was already to late to execute the action by the time I had set it. I potentially could have improved it by programming it entirely in assembly, but i would still exhaust the available resources when everything was implemented. I don't think the compiled C code is really inefficient anyway. I'm working on a more sensible solution that makes better use of the built in timer, CCP and Port change interrupts. This allows me to set actions to run at specific times without consuming as much of the available processing power. I'll also change to a more powerful microcontroller

He's dead, Jim
This is the device I use to program and debug the microcontrollers that I use. Unfortunately it decided to die.
Super awesome blurry photgraphy
Microchip, the company that created it, is sending out a replacement for me. I don't know how long it's going to take, so until then... Uni Studies!

Ignition coils and Electromagnetic Interference

A simplified way to think of ignition coils (and most transformers) is to imagine them like mechanical gear boxes. For example; you can have a gear ratio that increases your output torque at the cost of decreasing your output speed. In the case of transformers and coils you are trading voltage and current. Basic operation of a coil works like this:
1. 12v is applied to the primary winding for a few milliseconds. This produces a magnetic field around both the primary and secondary coils (they are really close together). An electrical current produces a magnetic field.
2. The voltage is suddenly shut off and the magnetic field collapses. The changing magnetic field will induce a voltage across the output coil. It has many more windings of wire than the input coil which means a few thousand volts to produce a really strong spark (at fewer amps compared to input).

I found three challenges while powering ignition coils. The first thing is that the coil will produce a voltage spike on the input winding that is opposite to the voltage used to power it. This is called Back EMF or Counter EMF. The problem is that the negative voltage can damage any connected electronic components or cause them to malfunction. It can be solved with the use of diodes and IGBT transistors designed specifically for powering ignition coils. Even easier is to use the existing ignition module in the car which was designed specifically to switch ignition coils and isolate the ECU providing the on/off signal from any back emf. Secondly, ignition coils require a fair bit of current which means the power supply voltage could dip low if it wasn't powerful enough. In order have a power supply that can supply enough current for the coils and provide a stable voltage for the microcontroller I used a car battery in parallel with a bench power supply at 13v.

The third problem was by far the most challenging for me. Even while subbing the back emf spike I found that the microcontroller would reset itself. I wrongly assumed that it was due to either the power supply becoming unstable or the back emf not being completely removed. I tried all kinds of filter and isolation methods on the power and signal lines of the microcontroller. In the end I realised that I could see a fluctuating voltage everywhere in the circuit, on every microcontroller pin, even those pulled direct to ground! (thanks to Maverick for letting me borrow his Rigol scope). It turns out that the high voltage spark creates strong electromagnetic interference. With the coil 1m away it was still enough to cause problems. Once I discovered the problem it was pretty easy to solve. Typically you would have some shielding in the form of a metal case. I just installed everything back into the MX5 and set my project onto passenger side floor. The metal firewall between the ignition coil and microcontroller was enough to shield from the interference. I'm now able to repeatedly fire the ignition coil without interfering with the operation of the microcontroller :)

This was an interesting learning process for me and I'm really excited to learn more about these kinds of effects. Can't wait till I can start my physics classes and continue with the next electronics classes :D