Andrew Cowan
Senior Member
My current project - a four channel RGBY LED fader.
I'm using a 28X2 at 1MHz in order to get four PWM channels at 98Hz.
The finished project will be much more complex and controlled via a radio link, but to start, I'm trying to write a fading subroutine.
I'm not worried about the fading rate at the moment - that's just a matter of adding a pause in the loop.
The idea is to step through a loop, slowly adjusting the PWM rate until it is desired. The tricky part is to adjust all four PWM channels at the correct rate - eg if red needs to increase by 200, and green needs to increase by 50, the red channel should increase at four times the rate of the green channel.
I've written this code several times in C before for RGB faders - with signed, floating point variables, it's pretty simple:
However, as PICAXE doesn't have floating point or signed varibles, I'm a bit stuck.
The basic functionality should be a subroutine called 'set' that fits into code such as:
Any thoughts or inspiration on designing this would be very appreciated!
I think that Actual and Target PWM duty should be a 0-255 scale; this can then easily be scaled by about 2.5 to the 0-636 required by a 98hz PWM.
One thing to bare in mind is that I'm running the chip at 1MHz, so a complex loop might take quite a while to go through!
Many thanks
Andrew
Note: don't worry about small issues such as the required duty cycle (0-636) not fitting in a byte variable - that's fine!).
I'm using a 28X2 at 1MHz in order to get four PWM channels at 98Hz.
The finished project will be much more complex and controlled via a radio link, but to start, I'm trying to write a fading subroutine.
I'm not worried about the fading rate at the moment - that's just a matter of adding a pause in the loop.
The idea is to step through a loop, slowly adjusting the PWM rate until it is desired. The tricky part is to adjust all four PWM channels at the correct rate - eg if red needs to increase by 200, and green needs to increase by 50, the red channel should increase at four times the rate of the green channel.
I've written this code several times in C before for RGB faders - with signed, floating point variables, it's pretty simple:
Code:
void Fade (byte ActualR, byte ActualG, byte ActualB, byte TargetR, byte TargetG, byte TargetB, byte rate)
{
int RDiff = TargetR - ActualR; //signed int showing change and direction
int GDiff = TargetG - ActualG;
int BDiff = TargetB - ActualB;
int NoOfSteps = max(abs(RDiff),max(abs(GDiff), abs(BDiff)));
for (int i = 0; i <= NoOfSteps; i++)
{
int NewR = ActualR + (i * RDiff / NoOfSteps);
int NewG = ActualG + (i * GDiff / NoOfSteps);
int NewB = ActualB + (i * BDiff / NoOfSteps);
delay(4 * rate);
setnewPWMrate(NewR, NewG, NewB);
}
}
The basic functionality should be a subroutine called 'set' that fits into code such as:
Code:
setfreq m1
Symbol oRe = C.1
Symbol oGr = C.2
Symbol oBl = B.0
Symbol oYe = B.5
Symbol ActualR = b0
Symbol ActualG = b1
Symbol ActualB = b2
Symbol ActualY = b3
Symbol TargetR = b4
Symbol TargetG = b5
Symbol TargetB = b6
Symbol TargetY = b7
init:
low oRe
low oGr
low oBl
low oYe
pwmout pwmdiv16, oRe, 158, 0
pwmout pwmdiv16, oGr, 158, 0
pwmout pwmdiv16, oBl, 158, 0
pwmout pwmdiv16, oYe, 158, 0
main:
gosub red
gosub set
gosub orange
gosub set
goto main
set:
'start loop
pwmduty oRe, ActualR
pwmduty oGr, ActualG
pwmduty oBl, ActualB
pwmduty oYe, ActualY
'carry on round loop
return
red:
TargetR = 255
TargetG = 0
TargetB = 0
targetY = 0
return
orange:
TargetR = 255
TargetG = 0
TargetB = 0
targetY = 255
return
I think that Actual and Target PWM duty should be a 0-255 scale; this can then easily be scaled by about 2.5 to the 0-636 required by a 98hz PWM.
One thing to bare in mind is that I'm running the chip at 1MHz, so a complex loop might take quite a while to go through!
Many thanks
Andrew
Note: don't worry about small issues such as the required duty cycle (0-636) not fitting in a byte variable - that's fine!).