Configuring the Multi-channel Breathing LED (PWM)

Discussion in 'The Projects Forum' started by Scott Corwin, Mar 7, 2016.

  1. Scott Corwin

    Thread Starter New Member

    Dec 31, 2015
    7
    0
    Configuring the Multi-channel Breathing LED (PWM)


    This is my first time posting on a forum like this.
    I’ll begin by explaining my end goal/result. I plan on making a nightlight for my niece similar to something like the image below (found at: http://i1.wp.com/craphound.com/images/la006-4p0604.jpg?w=970 )

    [​IMG]

    This has been done before and there is actually an instructable covering this. http://www.instructables.com/id/Luminous-Mushroom-Night-Light/

    Where this project takes a turn:
    I’m wanting to have each LED fade, “breathe”, essentially as if it were alive. It would almost have an effect to something you might find in Avatar. This particular lamp pictured, shows 6 LED’s. I think a lamp with maybe 10-12 LED’s would be much more engaging as well as impressive.

    Most Arduino’s have 6 PWM pins, but again, are these individually controlled? I imagine code could be written, but would involve multiple interrupts/delays in order to get all 6 LED’s to be breathing continuously without having to pause while the other 5 LED’s take a “breath”.

    I understand the Arduino has four PWM channels and the Arduino Mega has up to 14 PWM pins! This is nice, but the price is not very nice. I’m making this for my niece and was wanting to keep the price of the project relatively cheap. I’m really new to electronics and am not sure about the channels on the Arduino Mega. I don’t know if those 14 pins means that all pins are capable of varying voltage (using PWM) at different frequencies, or if some are paired.

    I’m looking to control about 10-12 LED’s individually. Ideally, I’d like to vary the period of each LED’s breathing “sinusoidal” wave so that it doesn’t look autonomous or like a bunch of LED’s fading on and off.

    The research I’ve done already:
    “If I have 6 PWM pins, I can double my output by charliplexing the LED’s!”

    Originally, I thought I could use charlieplexing to get the most of my output pins. Charlieplexing is driving lots of LEDs with only a few pins. It is possible to set your pins to high/low ( 5v / 0v ) in a manner to control N number of pins * ( N-1) = number of LED’s controlled.

    Example: 6 pins * (6-1) = 30 LEDs

    The theory can be further explained here:
    http://www.instructables.com/id/Charlieplexing-LEDs--The-theory/?ALLSTEPS

    Using this theory, I had imagined using 2 pins to control 2 LEDs, or possibly more.

    This would be very simple to do with a sinusoidal output with 1 LED.

    [​IMG]


    Even using 2 LEDs using Charlieplexing seemingly would be possible

    [​IMG]

    As long as both LEDs were at half brightness, this could work. What would not work however, is if there was a phase shift. I decided to move away from outputting the diagram above because if all LEDs were paired and glowing in this manner, it would look like there were only 2 synchronized sets of lights breathing on and off. This effect would not be very lifelike as well as this sinusoidal output is not very natural. Charlieplexing more than 2 LEDs would be impossible as three LEDs can not all share half brightness

    I then found some great code to use in order to achieve the “breathing LED effect” - http://sean.voisen.org/blog/2011/10/breathing-led-with-arduino/

    Code:

    #include <math.h>
    void setup()
    pinMode(11, OUTPUT);
    }
    void loop()
    {
    float val = (exp(sin(millis()/2000.0*PI)) - 0.36787944)*108.0;
    analogWrite(11, val);
    }


    The sinusoidal wave has peaks in it to reflect more naturally inhaling and exhaling. The voltage visual output would look something similar to the image below.

    [​IMG]

    I realized, in theory, multiplexing using only 2 LEDs would only be possible because the peaked voltage, 5v, is sent very briefly. More time is spent in the lower voltages allowing for 2 LEDs to share 2 pins using charlieplexing. Using 3 or more LEDs using this method I can see causing issues. I have failed to mention, using the code previously provided, I am not sure how to program the pins to switch between high and low whilst still peforming this pulse width modulating sinusoidal wave.

    [​IMG]


    Next I had pondered about writing a looping code in an Arduino or similar Atmega chip to write this PWM output to multiple pins, but I believe, the code executes in sequence. If I were to write code to output to multiple pins in a looping sequence, I think the the image below would reflect the end result.


    [​IMG]

    This output would give the LED’s a chasing, twinkling effect. Again, not the desired result.

    Ideally (though visually looks chaotic) I would like the output to be similar to below.

    [​IMG]

    While this visual only uses 6 outputs, (red, orange, yellow, green, blue and violet) I would not be uninclined to use the same output for a duplicate LED, meaning: 2x red, 2x orange, 2x yellow, 2x green, 2x blue and 2x violet. It may be recognizable that there are pairs of LED’s, but I believe with varying wave frequencies/periods this would be more easily concealed.


    What’s next?
    I’m wondering if by using shift registers, the intended effect can still be achieved while keeping costs low.

    This is my question to the forum: will using shift registers achieve the desired result or will the LED’s appear to be twinkling and chasing each other?

    At this point, I’m not really certain what other options I have besides using multiple controllers/arduinos independently programmed using their 4-6 PWM channels/pins. Ideally, I'd like to stay away from using the arduino and instead using either a single or multiple micro IC's (low cost).

    Any assistance or input would be greatly appreciated and please let me know if my description of my project was unclear.


    -Scott C.
     
  2. Colin55

    Member

    Aug 27, 2015
    191
    19
    You can buy those breathing LEDs for 20 cents each.
    I bought 50 of them. But you have to keep watering them to keep them alive.
     
  3. ebeowulf17

    Active Member

    Aug 12, 2014
    678
    79
    You could use a pwm driver chip like the one on this board to control 12 LEDs with one micro:

    https://www.adafruit.com/products/1455

    There are similar chips for 16 outputs instead of 12, and in I2C or SPI configurations.

    The only one I have personal experience with is this:

    https://www.adafruit.com/products/815

    I'm using it to control proportional valves, not LEDs, but I've been quite happy with it.
     
    Scott Corwin likes this.
  4. Colin55

    Member

    Aug 27, 2015
    191
    19
    It's funny how you get all these microcontroller designs from electronics wizards, who have never come across the problem before, and suggest spending tens of dollars on a project that can be solved by buying readily available componentry from eBay for 20 cents.
     
  5. ebeowulf17

    Active Member

    Aug 12, 2014
    678
    79
    :rolleyes:
    Sure, your eBay solution will probably work just fine. However, if the thread starter wants to have specific control over the patterns and their interaction, or if the speed of the "breathing" on the eBay LEDs isn't quite right, then pwm drivers might be helpful.

    As for pricing, I never said my links were the best way to go. I simply suggested that the chips used in boards like that might be helpful. Surely if the thread starter is interested in using loose microcontrollers instead of complete Arduino boards, the thread starter can also figure out how to use a pwm chip instead of the whole breakout board. I shared the links I did because that's what I've actually used myself - quite often, when I want to use some nifty little IC, I'll end up buying a breakout board like one of these because I don't want to mess with surface mount soldering. The chips at the heart of these boards are available for much less money if they prove helpful:

    http://www.digikey.com/product-detail/en/texas-instruments/TLC59711PWPR/296-36745-1-ND/4341358

    http://www.digikey.com/product-detail/en/nxp-semiconductors/PCA9685PW/Q900,118/568-5931-1-ND/2531218
     
    Scott Corwin likes this.
  6. blocco a spirale

    AAC Fanatic!

    Jun 18, 2008
    1,440
    368
  7. AnalogKid

    Distinguished Member

    Aug 1, 2013
    4,542
    1,251
    No schematic yet, all in my head - a linear feedback shift register (LFSR) with 6 or 10 or however many taps, each with a 1-transistor asymmetrical attack/decay circuit as in post #6. Each LED would get the same pattern, shifted in time (but this can be randomized with one quad-OR gate package). If the timing is slow and the LEDs are arranged randomly, after a few seconds the whole thing would look completely random. With a 16-bit shift register and a 1-second clock, the pattern would repeat every 18 hours. Amplitude modulation is done real-time, so no PWM. This approach can be moved to a uC with way less programing.

    Note, no 555's or microcontrollers were harmed in the making of this post. Carelessly brushed aside, sure.

    ak
     
  8. Scott Corwin

    Thread Starter New Member

    Dec 31, 2015
    7
    0
    ^^ Thank you for the input. I knew there was an option for the arduino to build upon and achieve this but could not locate it. If I run into too high or too many hurdles using loose controllers/chips, I'm thinking this will be the route I'll have to go. My only objection is, if this is successful and I wanted to make another, purchasing an additional arduino board would be required. (just looking at $$$)

    Again, thank you for the info, these are the prices I had in mind. Though the other boards you provided honestly weren't all that expensive, I know the arduino isn't the cheapest of boards as opposed to single chips. I'm not intimidated by making my own pc boards and surface mount soldering, I may end up purchasing a few of these.

    AnalogKid, I like where you're going with this however, would a linear feedback shift register be absolutely necessary? I understand using an LFSR would make essentially a random output. Couldn't you use 2 uc's and 2 8 bit shift registers? Would that be possible?

    I'd be really interested in seeing this "schematic" that's in your head. Also, I believe I'm understanding Shift registers correctly. I've created a gif to illustrate my understanding. Please let me know if I am mistaken and thank you all for your input and assistance.

    https://media.giphy.com/media/3ornk35i22Diz25tZK/giphy.gif
    [​IMG]

    If this were continually looping, or looping essentially 6 slightly different "breathing" codes, the LED's would appear to be breathing at different rates, and many LED's could be driven off of one uC.

    The pin outs may not be completely accurate, but this is just for conceptual understanding. I could look up the white pages for a shift register upon purchasing.

    - Scott
     
  9. Sensacell

    Well-Known Member

    Jun 19, 2012
    1,131
    267
    Generally the "breathing LED's" on E-bay look terrible, not smooth or subtle.

    The easier way to approach this is to use a super small and cheap MCU (PIC10F series?)
    Write code to make ONE LED breath just the way you want it too, then build a bunch of them.
    Separate chips give you better true randomness too- as the on-chip oscillators are never the same frequency, they drift in and out of phase in a very organic way.

    Trying to do multiple LED's with a single MCU is much harder and requires more nasty wiring compromises when you install the thing, separate units make it easy and simple to install.
     
  10. ebeowulf17

    Active Member

    Aug 12, 2014
    678
    79
    As with my other comments, I'm not claiming this is the best way to go, but for those who want Arduino IDE environment, libraries, community support, etc. one option is to buy just the micro, not the whole board. You need to add an appropriate power supply and a few components for the oscillator, but I think that's it.

    https://www.adafruit.com/products/1...AeeLhJ4ZoQcI-CkwE5mhwH38xA9JMmdefYaAkLP8P8HAQ

    Presumably these chips are also available from a variety of sources beyond Adafruit. Not sure how much harder (or not) it is to work with the chips if they don't already have an Arduino compatible bootloader installed.

    Again, I'm not saying Arduino compatible is a better or worse path than pics or other micros, just that you do have options, including chip-only, lower-cost options, regardless of platform.
     
  11. wayneh

    Expert

    Sep 9, 2010
    12,139
    3,054
    I have a couple of these, from a friend that's fond of garage sales. Anyway, the 5 butterflies each contain an LED and they throb nicely. But there are only two channels, one with 3 LEDs and one with 2. It seems impossible, but you have to watch for a while before you notice that.

    My point is, I don't believe you need so many channels of throbbing. I'll bet your 6 channels will appear plenty random. I don't think our brains could tell the difference between, say, 5 versus 8 channels. It would be very hard.
     
  12. Scott Corwin

    Thread Starter New Member

    Dec 31, 2015
    7
    0
    [​IMG]

    I got my LEDs and shift registers in the mail today! I'll update on any successes/failures
     
  13. Scott Corwin

    Thread Starter New Member

    Dec 31, 2015
    7
    0
    It's back to the drawing board, I'm pretty sure using SR's to control multiple outputs won't work as the shift register doesn't remember the PWM cycle it's given
     
  14. dannyf

    Well-Known Member

    Sep 13, 2015
    1,821
    364
    A SR doesn't work here because you want independent multi-channel PWM. A SR works well for multi-channel synchronized PWM.

    But it can be made to mimic what you want.

    For example, one way to do so is to generate multiple channels of sweeping pwm - pwm whose duty cycle varies goes up and down slightly. When you AND those PWM signals, you can get much wider and much slower changes in duty cycle -> kind like beat rate in radio.

    In your case, generate a main pwm that drives the SR' OE pin -> you can make it change slightly (or not, depending on your design).

    Then high-side switch the LEDs through a few channels of independent PWM -> again, varying their DC at differing speed, rate and range.

    Most led cubs use this approach to generate seemingly independent pwm.
     
    Scott Corwin likes this.
  15. Scott Corwin

    Thread Starter New Member

    Dec 31, 2015
    7
    0
    I'm not sure I quite understand what you mean when you say high-side switching the LEDs
    I've been looking through the white pages of ATtiny's for multiple PWM or Output-Compare pins because I wasn't sure I could use my SR's (I have 25 of them) :(

    Here's kinda what I have, mind you, I really have no idea what I'm doing. Assuming everyone starts at a beginning learning point, what do you think I should change to achieve what you're talking about?

    Code (C):
    1.  
    2. #include <math.h>
    3. //Pin connected to ST_CP of 74HC595
    4. int latchPin = 9;
    5. //Pin connected to SH_CP of 74HC595
    6. int clockPin = 10;
    7. ////Pin connected to DS of 74HC595
    8. int dataPin = 6;
    9.  
    10. void setup() {
    11.   //set pins to output because they are addressed in the main loop
    12.   pinMode(latchPin, OUTPUT);
    13.   pinMode(clockPin, OUTPUT);
    14.   pinMode(dataPin, OUTPUT);
    15. }
    16.  
    17. void loop() {
    18.   //breathing LED sinusoidal wave
    19.   float j = (exp(sin(millis()/2500.0*PI)) - 0.36787944)*108.0; {
    20.   //ground latchPin and hold low for as long as you are transmitting
    21.   digitalWrite(latchPin, LOW);
    22.   shiftOut(dataPin, clockPin, LSBFIRST, j);
    23.   //return the latch pin high to signal chip that it
    24.   //no longer needs to listen for information
    25.   digitalWrite(latchPin, HIGH);
    26.   delay(300);
    27.   }
    28. }
    29.  
    Moderators note: used code tags for C
     
  16. Scott Corwin

    Thread Starter New Member

    Dec 31, 2015
    7
    0
  17. Scott Corwin

    Thread Starter New Member

    Dec 31, 2015
    7
    0
    I'll see if I can explain this well.
    So I wired up an additional LED outside of the SR and sent it the same sinusoidal wave the Shift Register was receiving. I altered the sin wave to never hit 0, but instead, the bottom value of the sin wave would hit 2. While watching the single LED, it would never fully turn off, but hit its lowest value of 2, being very dim.

    Watching the LEDs attached to the shift register, I noticed that together, they were all representing the value of brightness the single LED was receiving. So, at the very dimmest, only the second LED was lit, because in binary... 1,2,4,8,16,32, and so forth. If I set the lowest brightness value to be at four, only the third LED. If at 3, only the first two LEDs would light up (2+1).

    Where things got really peculiar, was when I hooked up another PWM from the arduino, running the same algorithm for the breathing effect, and hooked it up to the same data pin that the arduino was already hooked up to.

    This made the LEDs almost light up in the breathing pattern. It doesn't really display the lower values of the sin wave very well, but you can certainly tell the LEDs are getting brighter and dimming.

    Still, the end result is to have them light up and "breath" in what would appear, independently.

    Anyone have any suggestions?
     
  18. dougy83

    Member

    May 11, 2011
    11
    4
    You can send 8 channels of PWM out the SR (or 16 channels if you have two SR). If you want your PWM frequency to be 1kHz and have 8-bits resolution, then for naive PWM you have to send a new value to the SR 256000 times per second (or if you use binary-weighted bit periods, then you have to update the SR 8000 times per second).

    Here's an example of 4-bit PWM on eight channels (the values on channel one is 1, channel two is 2, and so on to channel eight):
    Code (Text):
    1. time   value
    2. 0        0b01010101
    3.  
    4. 1        0b01100110
    5. 2        0b01100110
    6.  
    7. 3        0b01111000
    8. 4        0b01111000
    9. 5        0b01111000
    10. 6        0b01111000
    11.  
    12. 7        0b10000000
    13. 8        0b10000000
    14. 9        0b10000000
    15. 10       0b10000000
    16. 11       0b10000000
    17. 12       0b10000000
    18. 13       0b10000000
    19. 14       0b10000000
    20.  
    21. 15       start next cycle
    for the binary-weighted time, the above example is simply:
    Code (Text):
    1. time   value
    2. 0        0b01010101
    3.  
    4. 1        0b01100110
    5.  
    6. 3        0b01111000
    7.  
    8. 7        0b10000000
    9.  
    10. 15       start next cycle
    You can use a timer interrupt to schedule the transfer of the data to the SR; the second method uses fewer CPU cycles (log_2 N). It may suffer from flickering when you change the value though, which may be overcome if you use phase-correct modulation, but it may not be an issue.
     
  19. Sensacell

    Well-Known Member

    Jun 19, 2012
    1,131
    267
    Trying to do PWM via shift register requires a huge bandwidth overhead to update the LED's fast enough.
    You are doing this the hard way- see my post #9
     
  20. hp1729

    Well-Known Member

    Nov 23, 2015
    1,956
    219
    Electronic Goldmine has a variety of blinking and flashing LEDs.
     
Loading...