RGB LED Interfacing

Pat13

Senior Member
I have played around with eclectic's code and I am happy with the results. i have noticed that blue and green and more powerful than the red and have reduced the values of bTime and gTime. This has helped, although I am not getting the colour seperation between blue and green that I want. I have used "random" to change the intensities of R, B, and G. The biggest difference is with red, blue and green just mixing.
Code:
#18M2 RGB Witch Eyes
symbol R_Eyes = B.4
symbol B_Eyes = B.5
symbol G_Eyes = B.6
symbol Dummy = B.7
symbol Trigger = pinC.1
symbol Decay = w13
symbol rTime = b12
symbol bTime = b14
symbol gtime = b16
symbol xtime = w9
 			do
  			let w10 =time
  			random w10
  			let w11 = time
  			random w11
  			let w12 = time
  			random w12
  			rTime = w10//50+255
 			bTime = w11//5+150
  			gTime = w12//5+125
  
 			xTime = 766 - rTime - bTime - gTime
 			PulsOut R_Eyes, rTime
 			PulsOut B_Eyes, bTime
 			PulsOut G_Eyes, gTime
 			PulsOut DUMMY, xTime
 			if Trigger =1 then
 				gosub Strobe_Eyes
 			endif
			loop
		Strobe_Eyes:
			Do
			Decay =15
		 	for rTime = 50 to 255 step 2
 			for bTime = 20 to 150 step 2
 			for gTime = 10 to 80 step 2
  
			 xTime = 766 - rTime - gTime - bTime

 			PulsOut R_Eyes, rTime
 			PulsOut B_Eyes, bTime
 			PulsOut G_Eyes, gTime
 			PulsOut DUMMY, xTime
 
 			Decay = Decay-1
 			Loop until Decay = 0
 			next
 			next
 			next
 
			return
With "do...loop" left in Strobe_Eyes, the pulse is eliminated, which I don't want. As well, the code did not end after a 15 count but just kept going. I would like Strobe_Eyes to last 15 seconds, but not sure how to achieve this.
 

inglewoodpete

Senior Member
Does your code actually work? There seems to me to have an illogical looping structure: the Do:Loop has For:Next loops cutting across it.
 

Pat13

Senior Member
Does your code actually work? There seems to me to have an illogical looping structure: the Do:Loop has For:Next loops cutting across it.
yes and no. With the do:loop in Strobe_Eyes, the LEDs turn on, but do not pulse (pulse is the effect I am looking for). I put do:loop in as I am trying to find a way for the sub routine to last 15 seconds. I kept it in the example above for forum critique.
 

eclectic

Moderator
@Pat13

Another approach.
The 18M2 has two "real" pwmout pins.

I modified the circuit a little.

Red = pin B.3 (pwm)
Green = pin B.6 (pwm)

Blue = B.4 (pulsout)

Dummy (NC) = B.7

Possibly have a play, then modify the following

Code:
;http://www.picaxeforum.co.uk/showthread.php?9657-RGB-LED-Interfacing&p=215786#post215786

#picaxe 18M2

symbol rTime = b0
symbol gTime = b1
symbol btime = b2

symbol xtime = w2

symbol R_LED = B.3 ;pwm output
symbol G_LED = B.6 ;pwm output
symbol B_LED = B.4 ;                     pulse output
symbol dummy = B.7 ; unconnected

setfreq m4 

pwmout R_LED, 62, 0 ; turn on pwmout at zero outpu
pwmout G_LED, 62, 0

 main:
 
 Goingup:
 for bTime = 0 to 255 step 2 ; basic control on blue duty
  
 xTime = 256  - bTime
 
 pulsout B_LED, btime
 
 pwmduty R_LED, bTime
 pwmduty G_LED, bTime
 
 pause 10 ; change if needed
 
 PulsOut DUMMY, xTime
 next

Goingdown:

for bTime = 255 to 0 step -5 ; change if required
  
 xTime = 256  - bTime
 
 pulsout B_LED, btime
 
 pwmduty R_LED, bTime
 pwmduty G_LED, bTime
 
 pause 10 ; change if needed
 
 PulsOut DUMMY, xTime
 next
 
 goto main
e
 
If it is any help to anyone I wrote the attached code to drive a 3 colour (4 pin) led. It will work with any three leds whether in one package or all separate.

It was my first piece of code for the picaxe so it is less than perfect, in particular I had not discovered the DO/LOOP construct so it has a few unnecessary GOTO statements.

The code needs a 14M2 or equivalent. It provides a randomly changing colour sequence by ramping each LED intensity up and down at a varying rate, the rates being different and changing for each led. My original plan was to use three 08M2 chips to do this, one for each led but then realised it was much neater to use one 14M2 with four internal tasks running in parallel. So the code contains one task (Start0: ...) to initiate and update the random values used to control the delay times. Then there are three more near identical tasks updating each led (Start1, Start2, Start3 ...). Doing it this way does I feel make the code structure simpler, especially I you want to control each led in a different manner.

Seems to work OK but I would like to improve it later to provide better control of the total light output.


Code:
start0: ;THIS PROCESS DEFINES AND MANAGES THE COLOUR RAMP TIMING
symbol maxlight=625
symbol minlight=1
symbol led1= c.0
symbol led2= c.2
symbol led3= b.4

w0 = time
random w0
for b2 = 1 To 20 ;power up random sequence
; as the first few values in the counter tend to be low order
; and we want both bytes of w0 to have content
random w0
next

randoms: ; this is the loop that regularly changes the colour increment delay values
random w0
;set b8,b9 and b10 as random rgb ramp time delay values
;between 10 and 50
w4 = w0; set w4 (hence b8, b9) to the random value
b10 = b8 * b9 //40 +10
b8 = b8//40 +10
b9 = b9//40 +10
pause 20000 ;wait some time before setting new randoms
goto randoms
end

start1: ;PROCESS TO UPDATE THE PWM SETTING FOR ONE LED COLOUR
init1:
pause 200 ;let the random sequence grow
pwmout pwmdiv64, led1, 155, 0
main1: ;alter intensities(PWM duty values) up then down
for w1 = minlight TO maxlight
pwmduty led1,w1
pause b8
next
for w1 = maxlight TO minlight Step -1
pwmduty led1,w1
pause b8
next
goto main1
end

start2: ;PROCESS TO UPDATE THE PWM SETTING FOR ONE LED COLOUR
init2:
pause 200 ;let the random sequence grow
pwmout pwmdiv64, led2, 155, 0
main2:
for w2 = minlight TO maxlight
pwmduty led2,w2
pause b9
next
for w2 = maxlight TO minlight Step -1
pwmduty led2,w2
pause b9
next
goto main2
end

start3: ;PROCESS TO UPDATE THE PWM SETTING FOR ONE LED COLOUR
init3:
pause 200 ;let the random sequence grow
pwmout pwmdiv64, led3, 155, 0
main3:
for w3 = minlight TO maxlight
pwmduty led3,w3
pause b10
next
for w3 = maxlight TO minlight Step -1
pwmduty led3,w3
pause b10
next
goto main3
end
 
Last edited by a moderator:

Pat13

Senior Member
@Pat13

Another approach.
The 18M2 has two "real" pwmout pins.

I modified the circuit a little.

Red = pin B.3 (pwm)
Green = pin B.6 (pwm)

Blue = B.4 (pulsout)

Dummy (NC) = B.7

Possibly have a play

e
Thank you eclectic, that is what I am looking for, a nice even cascade thru the colours.
Hundred1906 i will definitely give this a go, I need to order in a couple more 14M2s.
 

westaust55

Moderator
yes and no. With the do:loop in Strobe_Eyes, the LEDs turn on, but do not pulse (pulse is the effect I am looking for). I put do:loop in as I am trying to find a way for the sub routine to last 15 seconds. I kept it in the example above for forum critique.
@Pat13,

I don't think that you fully understood IWP's comment.

You have the LOOP statement for the DO...LOOP structure located within the three tiered FOR...NEXT structures.

Attached is the code with the DO...LOOP properly structured and 'wrapped around the inner FOR...NEXT structures
Code:
#18M2 RGB Witch Eyes
symbol R_Eyes = B.4
symbol B_Eyes = B.5
symbol G_Eyes = B.6
symbol Dummy = B.7
symbol Trigger = pinC.1
symbol Decay = w13
symbol rTime = b12
symbol bTime = b14
symbol gtime = b16
symbol xtime = w9
Main:
 	do
  		let w10 =time
  		random w10
  		let w11 = time
  		random w11
  		let w12 = time
  		random w12
  		rTime = w10//50+255
 		bTime = w11//5+150
  		gTime = w12//5+125
  
 		xTime = 766 - rTime - bTime - gTime
 		PulsOut R_Eyes, rTime
 		PulsOut B_Eyes, bTime
 		PulsOut G_Eyes, gTime
 		PulsOut DUMMY, xTime
 		if Trigger =1 then
 			gosub Strobe_Eyes
 		endif
	loop
Strobe_Eyes:
	Decay =15
	Do
	 	for rTime = 50 to 255 step 2
 			for bTime = 20 to 150 step 2
 			        for gTime = 10 to 80 step 2
  			                 xTime = 766 - rTime - gTime - bTime
			                 PulsOut R_Eyes, rTime
			                 PulsOut B_Eyes, bTime
			                 PulsOut G_Eyes, gTime
			                 PulsOut DUMMY, xTime
  			        next
 			next
 		next
                 Decay = Decay - 1
	Loop until Decay = 0
	return
If you do want 15 seconds duration, why not consider using the system variable TIME available on the M2 parts and which increments each second.

BTW, figured out how to get Strobe_Eyes to cycle for 15 seconds. Used "dec".
Doubt that DEC will solve the problem.
changing:
Decay = Decay - 1​
to
Dec Decay​
is the same thing. The PE compiler converts DEC variable to variable = variable - 1. DEC as a commands is purely for the users convienience for possibly easier to understand/read BASIC program input text.
 
Last edited:

Pat13

Senior Member
@Pat13,


If you do want 15 seconds duration, why not consider using the system variable TIME available on the M2 parts and which increments each second.
I am unaware of the TIME command. I looked it up in manual two but could not find it. Would you elaborate?

I tried "dec" in the code but I had to increase the value of Decay from 15 to 1000. It is roughly 15 seconds. Would certainly like to be more accurate.
 

eclectic

Moderator
I am unaware of the TIME command. I looked it up in manual two but could not find it. Would you elaborate?

I tried "dec" in the code but I had to increase the value of Decay from 15 to 1000. It is roughly 15 seconds. Would certainly like to be more accurate.
Timer
try Manual 2, page 223

e
 

AllyCat

Senior Member
Hi Pat,

You might have an out-of-date manual, but TIME is a "System" or "Special Function" Variable with M2 devices (as opposed to TIMER which applies to X2 devices). It's a word variable which starts at zero and increments once each second (with a 4MHz clock). See Manual 2 from about page 13 onwards and commands "enabletime" / "disabletime".

Cheers, Alan.
 

westaust55

Moderator
I am unaware of the TIME command. I looked it up in manual two but could not find it. Would you elaborate?

I tried "dec" in the code but I had to increase the value of Decay from 15 to 1000. It is roughly 15 seconds. Would certainly like to be more accurate.
PICAXE Manual 2 (V7.9) page 13 and also see page 15. Then see pages 57 and 63.
 

Pat13

Senior Member
westaust55, I downloaded the current manual 2 and read those pages. However, I do not understand how to use "enabletime" in this context. The example show used it with debug. Is there a thread?
 

AllyCat

Senior Member
Hi Pat,

Time is automatically enabled when the program starts, so enabletime is only actually needed to cancel a disabletime command. Probably the simplest way to use Time for a 15 second delay is:

Time = 0
Do
; Put any code you want here
Loop until Time >= 15

If you want to use several time delays then don't reset Time but use something like:

Decay = Time + 15 ; Prepare a 15 second delay
Do
; ...
Loop until Time >= Decay

You can run these in the simulator, but Time runs at the "real" speed whilst other code runs much slower.

Note that the code in #48 is not correctly structured, the Decay = Decay - 1 (or Dec Decay is identical) should be located in a line immediately before the Loop until Decay = 0 and not nested within the For loops.

Cheers, Alan.
 

westaust55

Moderator
westaust55, I downloaded the current manual 2 and read those pages.
For your future reference, unless Rev Ed issue an update on the PICAXE manuals, the latest revision of the Programming Editor as installed includes the current version of the manuals at the time the PE update is release.
From the Toolbar: HELP / PICAXE manual 1, 2, 3.
 
Last edited:

westaust55

Moderator
Note that the code in #48 is not correctly structured, the Decay = Decay - 1 (or Dec Decay is identical)
should be located in a line immediately before the Loop until Decay = 0 and not nested within the For loops.
.
Well spotted Alan.
Furthermore even the decay = 15 should be moved up before the DO statement otherwise each cycle through the DO...LOOP would reset decay back to 15 so the loop would never end. :mad:
I have corrected the code to prevent others getting caught out at a future time.
 

AllyCat

Senior Member
Hi,

I'm not sure the outer FOR loop will ever terminate anyway because of:

for rTime = 50 to 255 step 2

which as far as I can see will never be true if rTime is a byte variable (b12) because 256 wraps to 0. It's OK with a word variable since Manual 2 says:

"When the end value is exceeded the looping stops...."

Interestingly, an end value of 254 doesn't terminate the loop either, when using a byte value (at least in the simulator), presumably because neither 254 nor 0 exceeds 254.

EDIT: Looking earlier in this thread is for rTime = 10 to 255 step 10 which is also "suspect" when using a byte variable. However, it appears that this and all the others above do run "correctly" in a real PICaxe. It seems to be the Simulator (and the "Exceeded" condition in the manual) which have an "issue".

Cheers, Alan.
 
Last edited:

hippy

Technical Support
Staff member
However, it appears that this and all the others above do run "correctly" in a real PICaxe. It seems to be the Simulator (and the "Exceeded" condition in the manual) which have an "issue".
Thanks for drawing our attention to that and we will investigate the simulator behaviour.

In a real chip the index variable is loaded as a 16-bit value even if a byte, then incremented by the step value, and comparison done on that so '50 TO 255 STEP 2' should give 50, 52 ... 250, 252, 254 then continue after the NEXT
 

westaust55

Moderator
I recall this bug existing before (but cannot quickly find a post on it).

a quick test in the simulator finds that any sequence that should end in 254 involving STEP x fails unless x = 1 ( having STEP 1 will stop correctly).

All of these fail in the simulator:

Code:
FOR b0 = 200 to 254 step 2
 sertxd (#b0," ")
NEXT b0
Code:
FOR b0 = 199 to 254 step 5
 sertxd (#b0," ")
NEXT b0
Code:
FOR b0 = 154 to 254 step 10
 sertxd (#b0," ")
NEXT b0
but for example
Code:
for b0 = 154 to 244 step 10
 sertxd (#b0," ")
next
does cease looping at 244
 

AllyCat

Senior Member
Hi,

Thanks hippy and westaust, and apologies to Pat for "diverting" this thread. Hopefully the answer to your question is back at #56 and #57.

The issue with the simulator is not just with 254 but any end value that is larger than "255 minus step". Obviously the simulator is testing for the exit condition after converting the (next) loop value to a byte.

IMHO For bn = 10 to 255 step 10 is "poor" programming, but For bn = 0 to 250 step 10 also fails in the simulator (the loop terminates only after a second pass when the value has exceeded 500, i.e. at a byte value of 254) which is not to be expected (unless you read the manual very carefully).

Cheers, Alan.
 

Pat13

Senior Member
Thanks AllyCat and westaust55, thanks for the help, especially the correct placement of the commands within the code. Since I have no formal computer/code education, your input is greatly appreciated.
 
Top