User avatar
MarkHaysHarris777
Posts: 1820
Joined: Mon Mar 23, 2015 7:39 am
Location: Rochester, MN
Contact: Website

RGB four lead LED (common anode)

Tue May 31, 2016 9:29 pm

RGB_LED.jpg
Red Blue Green (four lead) LED (common anode)
RGB_LED.jpg (26.34 KiB) Viewed 3117 times
I found a couple of these devices in the bottom of a starter kit box I purchased a couple of years ago from Make (I had completely missed them from the inventory!)

This LED has four leads, the longest lead being a common anode. So, with this configuration you would connect the anode (green wire on the red board) to Vcc (3v3) and you connect the cathodes to your GPIO pins (where everything is backwards, if the LED is off then the pin is ON High!).

So, I code it with layers that actually say what they do... in this snippet (incomplete)

Code: Select all

Red = binH_rom_STD[3][0]
Green = binH_rom_STD[2][0]
Blue = binH_rom_STD[1][0]

def pin_on(pin):
    GPIO.output(pin, HIGH)

def pin_off(pin):
    GPIO.output(pin, LOW)

def led_on(color):
    pin_off(color)

def led_off(color):
    pin_on(color)

def R(on_off):
    if (on_off):
        led_on(Red)
    else:
        led_off(Red)

&c
These little jewels are used in color bill-boards as the RGB pixels in large screen displays. They are fun to play with (very colorful) and are very bright.

Each of the LEDs in my unit have a forward voltage of about 1.9v and a forward current of about 2.5ma. Although, with the same ballast resistor the Green and Blue LEDs for the same forward current have a slightly higher forward voltage than the Red, and they're not as bright.

marcus
marcus
:ugeek:

User avatar
MarkHaysHarris777
Posts: 1820
Joined: Mon Mar 23, 2015 7:39 am
Location: Rochester, MN
Contact: Website

Re: RGB four lead LED (common anode)

Tue May 31, 2016 10:22 pm

This is my actual RGB_blink.sh test script, in Python:

Code: Select all

#!/usr/bin/python
from binary import *
from time import sleep

Red = binH_rom_STD[1][0]
Green = binH_rom_STD[2][0]
Blue = binH_rom_STD[3][0]

colors = [Red, Green, Blue]

def c_on(color):
    led_off(color)

def c_off(color):
    led_on(color)

def rgb_blink(colors):
    for color in colors:
        c_on(color)
        sleep(0.713)
        c_off(color)
        sleep(0.140)

def blinker():
    while(1):
        rgb_blink(colors)
        sleep(0.77)

try:
    blinker()
except KeyboardInterrupt:
    print("blinker ended by interrupt, bye!")
except:
    print("unmonitored exception in rgb_blink()")
finally:
    gpio.cleanup()

You can get binary.py here.
marcus
:ugeek:

User avatar
MarkHaysHarris777
Posts: 1820
Joined: Mon Mar 23, 2015 7:39 am
Location: Rochester, MN
Contact: Website

Re: RGB four lead LED (common anode)

Wed Jun 01, 2016 1:17 am

RGB_blue.jpg
RGB Blue LED glowing PWM 7
RGB_blue.jpg (24.06 KiB) Viewed 3027 times
The LEDs are just too bright normally... so, I decided to use PWM to control the intensity, as well as the color, of this cool RGB lamp/

I have included an updated version of binary.py and RGB_blink.sh below. I have selected channel 0 PWM GPIO18 (pin12) as the source pin. I moved the common anode wire from Vcc (3v3) to the PWM pin GPIO18.

Now, the PWM (pulse width modulation) duty cycle controls the source +voltage on the common anode thereby allowing us to dim the LED by reducing the duty_cycle. I have set the frequency to 440 (concert A) and the initial duty_cycle is passed to the RGB_blink.sh script as a parameter.

Code: Select all

./RGB_blink.sh 7
The ballast resistors are 330 ohms for all three LEDs; consequently the Blue LED was considerably more 'dim' (less 'bright') than the other two... so, easily fixed, when the Blue LED is lit the c_on() function increases the duty_cycle by +25... now all three LEDs light with the same brightness !

I like the Blue LED in this setup... so I had it 'pose' for the pic above so I could get the focus right...

binary.py

Code: Select all

#################################################################
## binary.py header for BreadBoard (8) bit LED binary display
#  v0.02c
#
#  Mark H. Harris
#  5-31-2016
#  Rochester, MN
#
#################################################################
## 
# Import the GPIO library and set the mode to "board numbering"
#
from time import sleep
from sys import argv
import RPi.GPIO as gpio
gpio.setmode(gpio.BOARD)

# Define the binary pin dictionarys REV {reverse} STD {standard} 
#      note 1: GPIO #s in these dictionarys are text labels only.
#                    {index:[pin#,"GPIO#"]}
bin_rom_STD = {0:[37,"GPIO26"], 1:[35,"GPIO19"], 2:[33,"GPIO13"], 3:[32,"GPIO12"], 4:[18,"GPIO24"], 5:[15,"GPIO22"], 6:[13,"GPIO27"], 7:[11,"GPIO17"]}

bin_rom_REV = {7:[37,"GPIO26"], 6:[35,"GPIO19"], 5:[33,"GPIO13"], 4:[32,"GPIO12"], 3:[18,"GPIO24"], 2:[15,"GPIO22"], 1:[13,"GPIO27"], 0:[11,"GPIO17"]}

binH_rom_STD = {0:[18,"GPIO24"], 1:[15,"GPIO22"], 2:[13,"GPIO27"], 3:[11,"GPIO17"]}

binL_rom_STD = {0:[37,"GPIO26"], 1:[35,"GPIO19"], 2:[33,"GPIO13"], 3:[32,"GPIO12"]}

binH_rom_REV = {3:[18,"GPIO24"], 2:[15,"GPIO22"], 1:[13,"GPIO27"], 0:[11,"GPIO17"]}

binL_rom_REV = {3:[37,"GPIO26"], 2:[35,"GPIO19"], 1:[33,"GPIO13"], 0:[32,"GPIO12"]}

# Set the pinblock for PWM on GPIO18
#
gpio.setup(12, gpio.OUT)
p = gpio.PWM(12, 440)
p.stop()

# Set the pinblock for input on GPIO16
#
button1=36
gpio.setup(button1, gpio.IN, pull_up_down=gpio.PUD_UP)

# Set the pinblock for output on all eight dictionary pins
#
for n in range(8):
    gpio.setup(bin_rom_STD[n][0],gpio.OUT)
    
## FUNCTION DEFINTIONS ##########################################
#
def push_button():
    if gpio.input(button1):
        return False
    else:
        return True

def led_on(pin):
    gpio.output(pin, True)

def led_off(pin):
    gpio.output(pin, False)

def test_leds(orient):
    if (orient=="REV"):
        pins=bin_rom_REV
    else:
        pins=bin_rom_STD
    for n in range(8):
        led_on(pins[n][0])
        sleep(.68)
    for n in range(7,-1,-1):
        led_off(pins[n][0])
        sleep(.68)

def bin_nibble_display(nval,high_low,orient):
    if (orient=="REV"):
       if (high_low=="H"):
           pins=binH_rom_REV
       else:
           pins=binL_rom_REV
    else:
       if (high_low=="H"):
           pins=binH_rom_STD
       else:
           pins=binL_rom_STD
    for n in range(3,-1,-1):
        if (nval & 2**n != 0):
            led_on(pins[n][0])
        else:
            led_off(pins[n][0])

def nl(val):
    bin_nibble_display(val,"L","REV")

def nh(val):
    bin_nibble_display(val,"H","REV")

def binary_display(nval,orient):
    if (orient=="REV"):
        pins=bin_rom_REV
    else:
        pins=bin_rom_STD
    for n in range(7,-1,-1):
        if (nval & 2**n != 0):
            led_on(pins[n][0])
        else:
            led_off(pins[n][0])

def bd(val):
    binary_display(val,"REV")

def all_off():
    nl(0x0)
    nh(0x0)

def all_on():
    bd(0xff)

def p_count(orient,t_delay):
    button=False
    for n in range(1,256,1):
        binary_display(n,orient)
        sleep(t_delay)
        if push_button():
            button=True
            break
    return button

def t_count(orient,t_delay):
    for n in range(1,256,1):
        binary_display(n,orient)
        sleep(t_delay)
        if push_button():
            sleep(2)
            break

def counter(maxVal,orient,t_delay):
    for n in range(1,maxVal,1):
        binary_display(n,orient)
        sleep(t_delay)

def count(orient,t_delay):
    for n in range(1,256,1):
        binary_display(n,orient)
        sleep(t_delay)

def walk(orient,t_delay):
    for n in range(8):
        binary_display(2**n,orient)
        sleep(t_delay)
    all_off()

def dsp_rom(high_low,orient):
    if (orient=="REV"):
       if (high_low=="H"):
           pins=binH_rom_REV
       else:
           pins=binL_rom_REV
    else:
       if (high_low=="H"):
           pins=binH_rom_STD
       else:
           pins=binL_rom_STD
    for n in range(4):
        print(pins[n][1]," BRD#:",pins[n][0],"  index:",n)

def dsp_bin_rom():
    print("L------------------------------------------")
    dsp_rom("L","REV")
    print("H------------------------------------------")
    dsp_rom("H","REV")

def end():
    gpio.cleanup()
    quit()

RGB_blink.sh

Code: Select all

#!/usr/bin/python
from binary import *
from time import sleep
import signal, os

Red = binH_rom_STD[1][0]
Green = binH_rom_STD[2][0]
Blue = binH_rom_STD[3][0]

colors = [Red, Green, Blue]

def c_on(color, duty_cycle):
    if(color==Blue):
        p.ChangeDutyCycle(duty_cycle+25)
    else:
        p.ChangeDutyCycle(duty_cycle)
    led_off(color)

def c_off(color, duty_cycle):
    led_on(color)

def c_none(colors):
    for color in colors:
        c_off(color, 50)

c_none(colors)

def rgb_blink(colors, duty_cycle):
    for color in colors:
        c_on(color, duty_cycle)
        sleep(0.713)
        c_off(color, duty_cycle)
        sleep(0.140)

def blinker(duty_cycle):
    p.start(duty_cycle)
    while(1):
        rgb_blink(colors, duty_cycle)
        sleep(0.77)

def handler(signum, frame):
    c_none(colors)
    sleep(.47)
    for n in range(7):
        c_on(Red, 50)
        sleep(.256)
        c_off(Red, 50)
        sleep(.256)
    
signal.signal(signal.SIGHUP, handler)

try:
    duty_cycle=int(argv[1])
    blinker(duty_cycle)
except KeyboardInterrupt:
    print(" ")
    print("blinker ended by interrupt, bye!")
except:
    print(" ")
    print("unmonitored exception in rgb_blink()")
    print("check args: ./RGB_blink.sh <duty_cycle>  ie: ./RGB_blink.sh 12")
finally:
    p.stop()
    gpio.cleanup()

marcus
marcus
:ugeek:

User avatar
MarkHaysHarris777
Posts: 1820
Joined: Mon Mar 23, 2015 7:39 am
Location: Rochester, MN
Contact: Website

Re: RGB four lead LED (common anode)

Wed Jun 01, 2016 6:42 am

edit: OP posted update to RGB_blink.sh in the previous post. {final}

In follow-up to the signal handler discussion of last week, I added a signal handler to the RGB_blink.sh code, which is not only fun from a lighting standpoint, but is also instructional from a programming standpoint.

You may run the code in the background like this:
./RGB_blink.sh 7 &
The '&' character tells the shell to execute the process in the background. The shell immediately reports the processes number. (remember the number, or write it down!)

With the process no longer running in the foreground you cannot interrupt it with a Ctrl-c, but you can accomplish the same thing by sending the process number a signal!

Code: Select all

kill -SIGINT <processNumber>
The above command will send the SIGINT signal to the running process, and it will stop just as if you had pressed the Ctrl-c in the foreground. But, what about other signals?

Code: Select all

kill -SIGHUP <processNumber>
The above command will send the SIGHUP signal to the running process; originally meant HangUp and was used to process a terminal tty hangup. Almost universally it now means to instruct the running process to 'take a brake' and re-read configuration information ('n such) and then resume... handy for making server changes and pulling them in without stopping the process or rebooting!

In our RGB test demo code above, I have added a SIGHUP handler, which instructs the process to take a break (flash the red LED quickly seven times) and then resume! Try it!

marcus

edit: PS I really don't like the command 'kill' to send signals... so I invented my own:

sshup.sh

Code: Select all

#!/bin/sh
exec kill -SIGHUP $1
ssint.sh

Code: Select all

#!/bin/sh
exec kill -SIGINT $1
Place the commands in your ~/bin/ directory (make it if you don't have one) and then use the commands like this:

Code: Select all

sshup.sh <processNumber>

Code: Select all

ssint.sh <processNumber>
marcus
marcus
:ugeek:

Return to “General discussion”