Control bi-color LED w/ single pin

jims

Senior Member
Picaxe Manual 3, page 9 shows a method to control a bi-color LED using 2 Picaxe pins. I have a project where I control a bi-color LED (red/green/off) using a single pin. With this set-up, the pin draws these currents (red: 2.6 mA...green: 4.3 mA...OFF: mA) as measured with my meter.

Code:
'**************************************
'* Use a single Picaxe pin to control a 
'* bi-color R/G LED (Red/Green/OFF).
'**************************************
;   18M2    
;+--------+             
;|            |                          2 pin RG LED
'|	       |			    +--------+			 
'|    	       |	 		    |<R LED |----|---100 ohm---+5  
'|       C.1 |Pin 18 --------------|            |
'|	       |                            |G LED> |----|---100 ohm---gnd 
'+---------+			    +---------+		


#picaxe 18m2

symbol RGled	= C.1	'pin 18.

#macro RGled_green
	high C.1
#endmacro

#macro RGled_red
	low C.1
#endmacro
	
#macro RGled_off	'Makes B.7 an input & turns led off.
	reverse C.1
#endmacro

Init:
	pause 500	'Pause to initialize system.

Main:
	do
	 RGled_green
	 pause 5000
	 RGled_red
	 pause 5000
	 RGled_off	
	 pause 5000
	loop
 

techElder

Well-known member
Not that it makes much difference, another way to do the same is use #define substitutions.

Code:
#define RG_ledRed low C.1
Don't put anything on the line at the end or it becomes part of the substitution.

That's different than #MACRO but I don't know if it makes any difference in your program.
 

hippy

Technical Support
Staff member
I would recommend using "Input C.1" instead of "Reverse C.1" for the #MACRO/#DEFINE to turn the LED off.

That allows a RGled_off to follow a previous RGled_off. Not so important in your example but in more complicated code one might want to turn the LED off but not know if it were off already.

You can also add a parameter to the #MACRO/#DEFINE so you can control LED's on multiple pins -

Code:
#picaxe 18m2

symbol RGled	= C.1	'pin 18.

#macro led_green(pin)
	high pin
#endmacro

#macro led_red(pin)
	low pin
#endmacro
	
#macro led_off(pin)
	input pin
#endmacro

Init:
	pause 500	'Pause to initialize system.

Main:
	do
	 led_green(RGled)
	 pause 5000
	 led_red(RGled)
	 pause 5000
	 led_off(RGled)
	 pause 5000
	loop
 

jims

Senior Member
I would recommend using "Input C.1" instead of "Reverse C.1" for the #MACRO/#DEFINE to turn the LED off.

That allows a RGled_off to follow a previous RGled_off. Not so important in your example but in more complicated code one might want to turn the LED off but not know if it were off already.

You can also add a parameter to the #MACRO/#DEFINE so you can control LED's on multiple pins -

Code:
#picaxe 18m2

symbol RGled	= C.1	'pin 18.

#macro led_green(pin)
	high pin
#endmacro

#macro led_red(pin)
	low pin
#endmacro
	
#macro led_off(pin)
	input pin
#endmacro

Init:
	pause 500	'Pause to initialize system.

Main:
	do
	 led_green(RGled)
	 pause 5000
	 led_red(RGled)
	 pause 5000
	 led_off(RGled)
	 pause 5000
	loop
Good points...Thank you Hippy and Tex. JimS
 

erco

Senior Member
I have used one pin to control 2 discrete LEDs in series, center tapped to the I/O pin. It takes just the right balance of resistors (individually determined by experimentation, often wildly different between LED colors) to get satisfactory on brightness and true off, as opposed to dim, since there is always some current flowing.

I think your way is better, LEDS in opposing polarities, since yours worked fine with 100 ohm resistors each!
 

jims

Senior Member
Not that it makes much difference, another way to do the same is use #define substitutions.

Code:
#define RG_ledRed low C.1
Don't put anything on the line at the end or it becomes part of the substitution.

That's different than #MACRO but I don't know if it makes any difference in your program.
I need some help on this..I've been here before but the "grey cells" don't work as well as they used to. When should I use the #define statement in place of the #Macro? JimS
 

premelec

Senior Member
It's not so much as which to use as when you use #define you put ONLY the instructions without any REMs and such... AND ONLY ONE line of instructions
 
Last edited:

techElder

Well-known member
Defining a #macro with multiple commands and lines is one reason to use macro over define.

One very good reason to use the #macro format is when you want to pass a variable's value (a parameter) to the routine within the macro. Hippy showed you an example in the third macro.

In that example, the parameter is defined with the macro as the word "pin". The word "pin" is just a placeholder used to describe the macro.

When the macro is called, you would replace the word "pin" with the pin you wanted the macro to work on; in this case led_off(RGled).

Just remember that when you place a macro name within your lines of code, just like a #define directive, the code defined within the macro is inserted into the code (as it is pre-processed).

PS. Don't use labels within a macro (unless you are only going to call it once), because as the macro code is inserted your label is also inserted each time you use the macro. So, you end up with multiples of the same label name and many syntax check errors because of duplicate label names.

I do wish for a solution to labels within macros.
 

hippy

Technical Support
Staff member
One very good reason to use the #macro format is when you want to pass a variable's value (a parameter) to the routine within the macro.
You can also do that with #DEFINE ...

Code:
#Define Add(lhs,rhs) lhs + rhs

b0 = Add(1,2)
SerTxd( "1 + 2 = ", #b0 )
Multiple lines can be included in a define by using the colon trick ...

Code:
#Define AddThenIncB0(lhs,rhs) lhs + rhs : b0 = b0 + 1
As to whether to use #MACRO or #DEFINE that's a bit like whether to say "large" or "big" - It really depends on whichever takes your fancy or is most appropriate for the context.
 

OLDmarty

Senior Member
Referring to JIMS original post/diagram, won't BOTH LEDS stay on if the control pin is made an input (Hi-Z) ?????

The LEDs are in series afterall, or am i missing something sneaky??
 

techElder

Well-known member
There is a certain total series resistance that will not allow enough voltage across each LED for it to light up.

The PICAXE pin going high removes the "upper" resistance while the PICAXE pin going low removes the "lower" resistance.
 

hippy

Technical Support
Staff member
Going back to #MACRO/#DEFINE there is one important difference - #MACRO allows the replacement of a line/command, while #DEFINE allows a replacement within the line. You couldn't do this with a #MACRO -

Code:
#Define PRODUCT "Magic LED Controller"

SerOut C.7, N2400, ( "Welcome to the ", PRODUCT, CR, LF )
 

AllyCat

Senior Member
Hi,

There is a certain total series resistance that will not allow enough voltage across each LED for it to light up.
That's not entirely correct, it is the forward voltage drop across the two LEDs together which ensures that they are not illuminated. But if the supply rail is higher than the sum of the two forward drops (specified for minimal brightness), then both LEDs will illuminate "dimly". It's the "shorting out" of the "other" LED (which then of course becomes totally dark), as much as the unwanted resistance, which causes the desired LED to illuminate brightly.

The voltage drop across the two LEDs and two resistors may indeed give a very low current, but remember that the response of the human eye is logarithmic, so even a very low current (uA) may "light" the LEDs in some circumstances (e.g. with low ambient light levels).

If the supply rail is greater than the sum of the two forward voltage drops, you could add a further resistor across each LED to extinguish them (but increase the current drain from the supply rail). However, in most circumstances, using a second pin probably will be cheaper than the additional resistors. ;)

The diagram in #1 is not clear on my screen (or in my PE) but I believe that circuit can completely extinguish both LEDs. But in this case there is always a significant current drain between the supply rails through the two 100 ohm resistors (i.e. I = Vdd / 200, or 25 mA for a 5 volt rail).

Cheers, Alan.
 

techElder

Well-known member
That's not entirely correct, ...
Of course it isn't entirely correct! :D Its a simple circuit, (jims circuit) and I added a simple explanation. Everything doesn't need deep analysis. :D :D :D
 

inglewoodpete

Senior Member
If one or both LEDs light dimly when the pin is set as an input, you can add one or two diodes in series with the LEDs (anode towards positive) to soak up a little voltage. Most likely won't be needed in battery circuits but may be needed if run from a 5v regulator.
 

jims

Senior Member
I have breadboarded this and it works perfectly. Extinguishes completely (as viewed with my eyes).
Also tried with 50 ohm resistance and LED brightness increases. Have these readings with 50 ohm resistors, measuring current flowing to the Picaxe pin. green ON:3.0mA...red ON: 5.8 mA...LEDs OFF:0 mA.. JimS
 
Last edited:

hippy

Technical Support
Staff member
The diagram in #1 is not clear on my screen (or in my PE)
Basically as below which I am guessing is how you would expect it to be ...

Code:
-.- V+       LED       LED
 |    ___                     ___
 `---|___|---|>|---.---|>|---|___|---.
                   |                _|_ 0V
                   ^ 
        From PICAXE Output Pin
 

AllyCat

Senior Member
Hi,

measuring current flowing to the Picaxe pin. green ON:3.0mA...red ON: 5.8 mA...LEDs OFF:0 mA.. JimS
Yes, but how much current is flowing in the resistors (between the supply rails) when the PICaxe pin is off (i.e. an input) ?

@Hippy: No, I don't think so because the diagram describes it as a "2-pin" dual R/G LED.

Cheers, Alan.
 

hippy

Technical Support
Staff member
Fair point; the diagram isn't clear. I guess it's -

Code:
                                ___   -.- V+
               .--|>|--.   .---|___|---'
PICAXE Pin |---|       |---{    ___
               `--|<|--'   `---|___|---.
                                      _|_ 0V
In which case there always will be current flowing between V+ and 0V.
 

erco

Senior Member
jims' diagram says 5V, each resistor 100, so I make 5/200= 25 mA of "wasted" current flowing through the resistors even with the LEDs off (pin an input). That's significant in a battery powered device, especially compared to LED consumption of 3-5 mA.

My discrete LEDs in series are more of a PITA to set up (experimentally determine resistances), but the standby current would be lower since the series string has both resistors plus both LEDs.
 

jims

Senior Member
Thanks for all your useful analysis of this approach of controlling a 2 pin bi-color LED with 1 Picaxe pin. Since I have enough Pixaxe pins available, I plan to use the 2 pin approach as shown in Manual 1. Jims
 
Top