Lava lamp project, part 2 — firmware
In part 1, I described the hardware of my project of a computer controllable lava lamp. In this second part, I want to discuss the necessary firmware, which is the software necessary to teach the Picaxe Microcontroller the desired functionality.
We need to keep two areas in focus:
- We need to be able to read the desired color values from the USB serial port, defining the desired intensities of the colors green, red and blue.
- These desired values have to be turned into actual light in desired color and intensity. This means, the LEDs have to be turned on.
A few words about the Picaxe
The Picaxe has a predefined set of commands, which is similar to BASIC and which is quite powerful. For example, a single commannd can read in a row of input data assign them to memory. But the processor speed is limited. This is understandable, greater working speeds would mean more heat dissipation and then the microcontroller would need cooling. This would significantly increase the effort required for designing a device with this kind of processor.
The Picaxe is available in different versions, which differ in package size and special equipment, such as the number of digital/analog converters or pulse width modulators. The smallest model is available as a 8 pin dual-in-line chip and sports the following pin out:
- 2 pins for 5V and ground (power supply)
- 2 pins for serial input and output. These pins are being used for programming and later for transmission of the desired color values. They could also be used as normal input or output pins if desired.
- 1 digital input
- 3 very versatile input/output pins with numerous special functions
Here is the data sheet for the PICAXE.
The Picaxe has an integrated development environment (IDE), called “Picaxe Editor 6″, which can be used for developing, simulating and transferring programs to the Picaxe. There are cost effective prototyping boards available as well. I bought myself his board for my first attempts.
Functional principles of the firmware
The lighting intensity of LEDs is not controlled by varying the power supply voltage (which could be done using a analog output), as is done for light bulbs. Instead it is done by varying the width of pulses at an appropriate frequency fast enough so that the flicker is not noticed by the human eye. The small Picaxe-08M2 used by me has one pulse-width-modulation (pwm) output, as can be seen in the above pin out. But that is only enough for one of the colors red, green or blue, not for all three of them. Only the significantly larger models 14M2 or 20M2 would have 3, or even 4, pwm outputs. For this reason, I have to program my own pwm output manually, which, alas, can only be done with limited speed, which means that my LED flickers slightly. That is a pity, but it can not be avoided within the limited space. The larger Picaxe chips would require more space not available inside the lava lamp.
To use the processing power of the Picaxe as effective as possible, I built my firmware like this:
One big loop is repeating for ever. Inside this loop, the following things are happening:
- First, all three color LEDs are turned on, if their correponding number of duty cycles is greater than zero.
- In an inside loop, which is always performed the same number of times
- …each color, whose duty cycle expired, is being turned off.
- …also, we wait 3 Milliseconds for the beginning of an input datagram
- If a character “C” is recognized, we jump to a subprogram, which reads the rest of the datagram and recalculates and adjusts the duty cycles of each color.
- After the number of inside loop cycles is reached, we jump back to the outer loop and the whole cycle starts from scratch.
The length of an outside loop cycle determines the amount of flickering of the LEDs. The shorter one outside loop cycle, the less flickering.
The inside loop cycle length is determined by the serial input waiting time, which has to be performed regularly, in order to read desired color changes transmitted from the connected computer. The longer this waiting time, the more reliably datagrams will be recognized, but the more flickering occurs as well. I figured 3 milliseconds should be quite ok. If during this time, a character “C” is noticed, we quickly jump out of the inside loop and perform a subpgram to read three more characters, whose value defines the brightness of the colors red, green and blue, respectively. The possible brightness values go from 0 (“constant off”) to n+1 (“constant on”).
The number of inner cycles defines the “flicker frequency” of the LEDs, inversely proportional. This means: The less the LEDs are supposed to flicker, the less times the inner loop can be performed, and the less number of brightness levels are possible. The more levels of brightness are desired, the more the LEDs will flicker. I thought that 7 inner cycles make a useful compromise.
The serial port receives the desired color and brightness through a “datagram” consisting of four bytes of data. Every datagram starts with a “C”, and the following three digits define the number of inner cycles for the colors red, green and blue. Here are a few examples:
- ‘C000’ — LED is completely turned off, or dark
- ‘C888’ — LED is completely turned on, or white
- ‘C800’ — LED is rot
- ‘C080’ — LED is green
- ‘C008’ — LED is blue
- ‘C440’ — LED is yellow with about half intensity
- ‘C808’ — LED is purple with full power
- ‘C740’ — LED is brown
- etc.
Unfortunately, the serial receiver is not dependable enough to receive every datagram cleanly. Most of the time, the computer has to send the datagram multiple times until it is received. An acknowledgement is not currently implemented in my code.
Possible improvements
The code could be made more flexible, for example by making the number of inside loop cycles variable. With this, the computer could reduce the flicker, if only a few brightness levels are required.
An ackowledgment mechanism for signalling successful reception of a datagram to the computer would be useful so that it knows it can stop repeating its last datagram.
Also, it would be nice to make the switch or key do something, such as turning the LED on or off, or starting a special color program on the LED.
You can, of course, also experiment with the adjustments:
- Clock frequency of the processor. Currently set to 16 MHz. The faster, the less flicker. 16 MHz is the maximum frequency possible for the Picaxe 08M2.
- Number of inner loop cycles for one working cycle. Currently 7. The less cycles, the less flicker. The more inner cycles, the more levels of brightness are available.
- Waiting time for begin of datagram. Currently 3ms. The longer this time the more reliably datagrams will be recognized, but the greater the flicker.
Listing
I don’t want to list the whole firmware program here. Just ask me, if you are interested