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!