tbd.pi
Posts: 34
Joined: Sat Aug 11, 2012 11:21 am
Location: NJ,USA
Contact: Website

Controlling multiple RGB Leds

Thu Sep 17, 2015 5:50 pm

I am certain this has been asked and answered a lot, but I can't a post with an explanation. I'm looking to control multiple RGB leds from a PI, I've seen a variety of different ways of doing this and am slightly confused as to how to get it working. I have an Adafruit TLC59711 board and I'm sure I could take that. But I also saw Controlling one RGB LED via hardware PWM? where joan noted being able to control 8 rgb leds from the pi2. I don't want to hijack a thread, so I figured I would start a new one.

I guess what I'm looking for is a diagram that helps me understand what's working and then a brief explanation of the code that I can expand on and work into my greater project.

User avatar
Jednorozec
Posts: 809
Joined: Sun Nov 24, 2013 2:17 pm
Location: Deposit, NY

Re: Controlling multiple RGB Leds

Thu Sep 17, 2015 6:13 pm

Instead of using RGB leds try DotStars or NeoPixels https://learn.adafruit.com/adafruit-dotstar-leds
The most important leg of a three legged stool is the one that's missing.
It's called thinking. Why don't you try it sometime?

User avatar
joan
Posts: 14251
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: Controlling multiple RGB Leds

Thu Sep 17, 2015 7:11 pm

There is nothing difficult in controlling multiple RGB LEDs apart from the boring wiring up.

In effect they are 3 LEDs in one package. So you need 3 GPIOs per LED rather than 1. Mine are common cathode so one leg is connected to ground and the rest are connected to GPIOs via individual series resistors.

I used 1k for the red leg and 410 for the blue and green legs.
reb-leds.jpg
reb-leds.jpg (60.23 KiB) Viewed 3089 times
I was only playing with the LEDs so the attached code doesn't serve any useful purpose.

Code: Select all

#!/usr/bin/env python

# rgb-leds.py
# 2014-09-22
# Public Domain

import time
import random

import pigpio

RUNTIME=300
CYCLE=0.02

STOP=0
BOUNCE=1
RAMP=2

class LED:

   def __init__(self, pi, gpio, incv=1.0, low=0, high=255, mode=BOUNCE):

      self.pi = pi
      self.gpio = gpio
      self.incv     = incv
      self.bottom  = low
      self.top     = high
      self.endmode = BOUNCE

      self.old_mode = pi.get_mode(gpio)

      pi.set_mode(gpio, pigpio.OUTPUT)

      self.gpio_dc = 0

      pi.set_PWM_dutycycle(gpio, 0)

   def cancel(self):

      self.pi.set_PWM_dutycycle(self.gpio, 0)

      self.pi.set_mode(self.gpio, self.old_mode)

   def set(self, gpio_dc):

      self.gpio_dc = gpio_dc

      self.pi.set_PWM_dutycycle(self.gpio, int(gpio_dc))

   def get(self):

      return self.gpio_dc

   def inc(self, incv, bottom, top, endmode):

      self.incv     = incv
      self.bottom  = bottom
      self.top     = top
      self.endmode = endmode

   def update(self):

      self.gpio_dc += self.incv

      if self.gpio_dc > self.top:
         if self.endmode == STOP:
            self.gpio_dc = self.top
         elif self.endmode == BOUNCE:
            self.incv = -self.incv
            self.gpio_dc += self.incv
         elif self.endmode == RAMP:
            self.gpio_dc = self.bottom

      elif self.gpio_dc < self.bottom:
         if self.endmode == STOP:
            self.gpio_dc = self.bottom
         elif self.endmode == BOUNCE:
            self.incv = -self.incv
            self.gpio_dc += self.incv
         elif self.endmode == RAMP:
            self.gpio_dc = self.top

      pi.set_PWM_dutycycle(self.gpio, int(self.gpio_dc))

      return self.gpio_dc

class RGB:

   def __init__(self, pi, r, g, b, inc=1.0, low=0, high=255, mode=BOUNCE):

      self.pi = pi

      self.r = LED(pi, r, inc, low, high, mode)
      self.g = LED(pi, g, inc, low, high, mode)
      self.b = LED(pi, b, inc, low, high, mode)

      self.rdc = 0
      self.gdc = 0
      self.bdc = 0

      self.low = low
      self.high = high

   def cancel(self):

      self.r.cancel()
      self.g.cancel()
      self.b.cancel()

   def set(self, rdc, gdc, bdc):

      self.rdc = rdc
      self.gdc = gdc
      self.bdc = bdc

      self.r.set(rdc)
      self.g.set(gdc)
      self.b.set(bdc)

   def get(self):

      return self.rdc, self.gdc, self.bdc

   def inc(self, rinc, ginc, binc, rend=BOUNCE, gend=BOUNCE, bend=BOUNCE):

      self.r.inc(rinc, self.low, self.high, rend)
      self.g.inc(ginc, self.low, self.high, gend)
      self.b.inc(binc, self.low, self.high, bend)

   def update(self):

      self.r.update()
      self.g.update()
      self.b.update()

LIM=32

def cycle(r, g, b):
   if g < LIM and b > 0:
       return (r, g+1, b-1)
   elif r < LIM:
      return (r+1, 0, LIM)
   else:
      return (-1, -1, -1)

#led = [
#   [2, 3, 4], [14, 15, 18], [17, 27, 22], [23, 24, 25], 
#   [10, 9, 11], [8, 7, 12], [5, 6, 13], [16, 20, 21]]

led = [
   [2, 3, 4], [14, 18, 15], [22, 17, 27], [25, 24, 23], 
   [9, 10, 11], [7, 12, 8], [5, 6, 13], [16, 21, 20]]


rgb = [0]*len(led)

pi=pigpio.pi()

for l in range(len(led)):

   rgb[l] = RGB(pi, led[l][0],led[l][1],led[l][2], 1.0, 0, 32, BOUNCE)
   rgb[l].set(l, l, l)

start = time.time()

while (time.time()-start) < RUNTIME:

   for l in range(len(led)):

      r, g, b = rgb[l].get()
      r, g, b = cycle(r, g, b)
      if r != -1:
         rgb[l].set(r, g, b)

      time.sleep(CYCLE)

for l in range(len(led)):

   rgb[l].cancel()

pi.stop()
I don't remember if I left the code in a working state or not, the LEDs are currently being driven by shift registers.

tbd.pi
Posts: 34
Joined: Sat Aug 11, 2012 11:21 am
Location: NJ,USA
Contact: Website

Re: Controlling multiple RGB Leds

Thu Sep 17, 2015 8:08 pm

I do like the idea of using the Neopixels, I have a Neopixel stick that I've been meaning to get to but that won't do quite what I want of it right now. The RGB leds are what I'm focused on right now.

Thank you for that joan, I appreciate the detail as always. If I might ask some dumb questions;

- How would the circuit change if using a common anode RGB?
- I think I get the concept of shift registers, that they allow me to increase the number of outputs from a single input. Do you know of any good examples of using the shift registers for this? I would like to be able to extend this once I get comfortable building.

User avatar
joan
Posts: 14251
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: Controlling multiple RGB Leds

Thu Sep 17, 2015 8:51 pm

I think for a common anode you have the same circuit apart from connecting the common to 3V3 rather than ground. In this case the GPIOs sink rather than source the current. So the logic is inverted. You set a GPIO leg to 0 (connect to ground) for fully on. So 100% PWM dutycycle become off, 0% becomes fully on 20% becomes 80% on etc.

I wouldn't use shift registers for RGB LEDs (I was playing). You need to use software timing to feed the bit stream and the glitches will be obvious.

User avatar
Jednorozec
Posts: 809
Joined: Sun Nov 24, 2013 2:17 pm
Location: Deposit, NY

Re: Controlling multiple RGB Leds

Thu Sep 17, 2015 9:12 pm

NeoPixels are available in a couple of different led packages.
The most important leg of a three legged stool is the one that's missing.
It's called thinking. Why don't you try it sometime?

Return to “General discussion”