Controlling RGB LED using PICAXE-08: Basics of software PWM

Driving RGB LED with PICAXE-08M
Driving RGB LED with PICAXE-08M
I’m working on a new RTFMs episode that involves packing an RGB LED and a microcontroller into a very tight space. The microcontroller I decided to use is PICAXE-08. I chose it for three reasons:
– I had one in the box
– I had no other plans for it as it appeared to be not very suitable for what I got it for (a high-altitude balloon project)
– Using it to dim RGB LED is a challenge


I googled for a while and found no solution to make RGB LED and PICAXE-08M work together as I planned. While switching between three different colors of the LED is not a problem at all with, mixing colors is not trivial with this chip. I wanted to control each color separately with 256 gradations of brightness/dimming so the LED can produce true RGB mix. This is typically achieved with pulse width modulation (PWM) and not a problem with Arduino for instance. ATMega328 has 6 PWM channels, so it can drive two RGB LEDs. But PICAXE08 has just one PWM channel so the mission might seem impossible. I solved the problem by implementing software PWM that worked surprisingly well giving PICAXE08 limited performance. Here is my code:

#rem
Simple PICAXE 08m basic program that randomly and independently controls
brightness of all 3 colors in a RGB LED
creating calming patterms (like in a mood lamp).
See my blog http://andrey.mikhalchuk.com for more details

You’re free to do whatever you want with this code, just mention my blog http://andrey.mikhalchuk.com
in the comments, so people can find updated code. Thanks!

This is my very first program for PICAXE, I apologize if this code doesn’t meet your quality
expectations and harms your feelings about how good code should look like :)
#endrem

#picaxe 08m
setfreq m4

; config
symbol SPEED = 3 ; the smaller the value the higher the color change speed
symbol SPEED_VARIATIONS = 7 ; defines how many different color change speeds should it use

; map pins
symbol RED0_PIN = 0
symbol GREEN0_PIN = 1
symbol BLUE0_PIN = 2

; map pin values to mem
; pin value is the current brightness of the LED
symbol red0 = b0
symbol green0 = b1
symbol blue0 = b2

; map pin_deltas to mem
; delta is the speed of the brightness change
symbol red0_delta = b3
symbol green0_delta = b4
symbol blue0_delta = b5

; temp values for the subroutine
symbol delta_w = w3
symbol tmp = b7

; subroutine parameters
symbol pin = b8
symbol val = b9
symbol delta = b10

; initialize everything
red0 = 0
green0 = 70
blue0 = 200
red0_delta = 1
green0_delta = 5
blue0_delta = 9

; start servo mode
; note that “servopos RED0_PIN, 255” renders LED off!!
; “servopos RED0_PIN, 0” makes it really dim, but lit. Is that a bug in PICAXE?
servo RED0_PIN, 255
servo GREEN0_PIN, 255
servo BLUE0_PIN, 255

; this code is like loop() in arduino
main:
; emulating function call in function-less environment
pin = RED0_PIN : val = red0 : delta = red0_delta : gosub set_color_val : red0 = val : red0_delta = delta
pin = GREEN0_PIN : val = green0 : delta = green0_delta : gosub set_color_val : green0 = val : green0_delta = delta
pin = BLUE0_PIN : val = blue0 : delta = blue0_delta : gosub set_color_val : blue0 = val : blue0_delta = delta
goto main

; this sub adjusts the brightness of the LED and delta
set_color_val:
val = val + delta
if delta < 128 and val < delta then ; fwd random delta_w delta = delta % SPEED_VARIATIONS + 1 delta = 255 - delta val = 255 elseif delta >= 128 and val >= delta then ; reverse
random delta_w
delta = delta % SPEED_VARIATIONS + 1
val = 0
endif
tmp = val – 1 ; servopos bug workaround
; yeah, servopos takes only constant as the first argument :(
if pin = RED0_PIN then
servopos RED0_PIN, tmp
elseif pin = GREEN0_PIN then
servopos GREEN0_PIN, tmp
elseif pin = BLUE0_PIN then
servopos BLUE0_PIN, tmp
endif
pause SPEED
return

; see my other blog http://rtfms.com and video blog RTFMs on youtube for demo
; this is covered in episode #7: Microcontroller Meets Jewelry

A few notes about this code:
– it implements “RGB mood lamp”. Feel free to change it for your needs
– since PICAXE keeps looping all the time I suspect the power consumption is horrible. Still it’s good for an hour at least when power by two tiny batteries as shown in the RTFMs video blog episode #7
– performance of PICAXE08 is so-so. As you can see on the RTFMs video the light is slightly shimmering. You probably won’t notice it at while looking at the LED in person, but video camera makes the effect noticeable. In fact in mood lamp I even like it :)
– the program size is 146 byte (out of 256 available on 08). You probably can optimize it a bit.
– the RTFMs video about the mood lamp project mentioned here is to be released a bit later

Leave a Reply