ShiftPWM support topic. Latest update: Schematics, high power LED's, LED strips

@elco - so is that RGB,RGB,etc from 0-7 of the first thru 3rd 595s?

@ematson, i'd love to check those out too!

These are from a while back...

So far the added functions are:

ShiftPWM.SetAllRGB(red,green,blue); For RGB Leds, Sets all of them to the same color

ShiftPWM.Chase(Brightness,DelayTime,StartPin,EndPin,Direction); Chases from StartPin to EndPin at selected brightness. The Direction is selectable. 1 is low pin to high pin and 0 is high pin to low pin.

ShiftPWM.ChaseRGB(Red,Green,Blue,DelayTime,StartLED,EndLED,Direction); For RGB LEDs. Chases from StartLED to EndLED at selected color. The Direction is selectable. 1 is low LED to high LED and 0 is high LED to low LED.

Are there any functions that anyone would like to see added?

Library is attached

ShiftPWM.zip (15 KB)

I was thinking some bit sorta functions would be cool.. invert, etc..

There is already a variable for that, but its a constant, so you can only edit it once. I can change that.

Ok I changed it. The variable is called ShiftPWM_invertOutputs and isnt a constant so It can be changed at will
You do have to declare it like so

bool ShiftPWM_invertOutputs

ShiftPWM.zip (14.9 KB)

Those variables are constant for a good reason: speed.
When they are constant, the compiler can optimize the if statements away.

The invert variable is only meant to adjust the library for common anode or common cathode LED's.

I have started updating the code. So far I have integrated the RGB and HSV functions and added some more examples (HSV fading, random colors, and a fake VU meter). Next up is support for different setups than RGBRGBRGB and support for gaps (unused pins in between).

Follow along at:

All right, next update is online. I created a new branch, called pinFlexibily. After testing I will merge it with the master branch.
You can find it here:

This update introduces two new things:

Offset
An optional argument to all functions that set one led/group, called offset. When would you use this?
Say you have 2 boards, each with 4 shift registers and 10 RGB LED's. That means that you have 2 empty outputs on your board.

The second board would be misaligned because of this gap. You can now use ShiftPWM.SetRGB(lednr, r,g,b,2) for the second board to correct this. You can still use SetRGB(lednr, r,g,b), because offset defaults to 0.

Pin Grouping
With the function ShiftPWM.SetPinGrouping(int grouping), you can now set how your pins are grouped together by color.
If your LED's are connected like this: RRRR-GGGG-BBBB-RRRR-GGGG-BBBB.. you can use SetPinGrouping(4).
SetRGB(5,255,0,255) will set output 13 and 21 to 255. (remember counting starts at 0).

I would appreciate some feedback before I merge this into the main branch.

Next up, in order: better documentation, bit code modulation instead of PWM, debugging the Matrix version.

quick question..

So, i'm running the matrix version and mostly having luck.. I'm using a led matrix / keypad.. so, i'm going to use 74hc164/165 to scan the key matrix. being an SPI device, I'd like to use the same SPI bus, but I'm thinking i'll have to tweak the schematic (and maybe code) a little to allow it to address each spi line.. does that sound right? any insight there?

Furthermore, any thoughts of putting the "blanking" shift register on the same chain as the RGB SRs?

I am not sure what you are mean by your question but I did upload a new version, with support for not using the SPI port!
It is about 2.5x slower, but it lets you freely choose the pins. New version:

I think I would prefer to use the SPI for the LED's and use ShiftIn (http://arduino.cc/en/Reference/ShiftIn) for the inputs.

so, to clarify. It's my understanding that with SPI, i can use the same 3 serial lines (clock, latch, data) - but address them via "Slave Select" (OE on the 595? )

This would mean that instead of using 6 pins total to drive my matrix, i could reuse the same serial lines, but use slave select to "address" data to either the RGB or the Blanking SR's. Giving a total of 5 pins.

This gets more interesting because i want to add 164/165 to decode my keypad. Also SPI devices - so i'd use 2 more pins (or a 2 to 4 decoder) to be able to now address 4 seperate SPI "busses" - RGB / Blanking / Keypad Out / Keypad in.

On top of that, my last point was that I was just wondering why the matrix version could not have all 4 SRs on one SPI rather then 2 seperate..

is that any clearer?

I believe the OE pin sets the outputs in a high impedance state. It does not disable input from the data line at every clock pulse.
The 595 is not a true SPI device. The 595 does not have a slave select input and just clocks in at every clock pulse as far as I know.
To prevent the leds from getting corrupted, you would have to block the clock line.

What you might be able to do is modify the library. In a SPI port, clocking bits out and clocking bits in is simultaneous. The MISO pin (pin 12 on a regular arduino) is shifted in. My library just discards that data, but you might be able to use it.

But why bother and not just use 3 regular pins?

I don't use the SPI for switching between rows, because it doesn't have to happen often. For every 255 brightness levels, I just have to give the row register 1 clock pulse to go to the next row (=1shift). I also don't even have to send out a full byte. Just one pulse on the clock line and writing a 1 to the data line to switch back to the first row.

Hi,

It took me some time to understand millis()
And I found out it's just basically a timer.

For now what works best by far for me is:

 unsigned long elapsed=millis();

if(elapsed > 1000){
    int j =255*0/100; //at 1-st second, brightness is 0%
    ShiftPWM.SetOne(0 ,j);
  }
  if(elapsed > 1100){
    int j =255*10/100; //at 1.1-st second, brightness is 10%
    ShiftPWM.SetOne(0 ,j);
  }
  if(elapsed > 1200){
    int j =255*20/100; //at 1.2-nd second, brightness is 20%
    ShiftPWM.SetOne(0 ,j);
  }
  if(elapsed > 1300){
    int j =255*30/100;
    ShiftPWM.SetOne(0 ,j);
  }
  if(elapsed > 1400){
    int j =255*40/100;
    ShiftPWM.SetOne(0 ,j);
  }
  if(elapsed > 1500){
    int j =255*50/100;
    ShiftPWM.SetOne(0 ,j);
  }
  if(elapsed > 1600){
    int j =255*60/100;
    ShiftPWM.SetOne(0 ,j);
  }
  if(elapsed > 1700){
    int j =255*70/100; //at 1.7-th second, brightness is 70%
    ShiftPWM.SetOne(0 ,j);
  }
  if(elapsed > 1800){
    int j =255*80/100;
    ShiftPWM.SetOne(0 ,j);
  }
  if(elapsed > 1900){
    int j =255*90/100;
    ShiftPWM.SetOne(0 ,j);
  }
  if(elapsed > 2000){
    int j =255*100/100; //at 2-nd second, brightness is 100%
    ShiftPWM.SetOne(0 ,j);
  }

(fading period=1000, increases brightness by 10% after every 100ms)

I need to find a better way to set brightness after every 1ms.

I cannot use:

for(int j=0;j<maxBrightness;j++){
   ShiftPWM.SetOne(0, j);  
   delay(20);
   }

Because delay() will also stop the next task to proceed.

How do I set a function to have any fading period, and increases brightness after every 1ms?

Thanks! :slight_smile:

Try something like this:

unsigned long elapsed=millis();
if(elapsed>1000 && elapsed < 2000){
   unsigned char j = elapsed>>2; // shift right 2 to divide by 4.
   ShiftPWM.SetOne(0 ,j);
}

Of course this will go to 250 instead of 255, but it is a very fast calculation.

Thanks a lot! That gave me a big boost! :smiley:

That code doesn't really work smoothly, the LED blinks a few times and then fades in.

Done some changes (I don't really understand bit shifting also, so I used simple math)

unsigned long elapsed=millis();

if(elapsed > 1000 && elapsed < 11000){ //fade in for 10secs at 1-st sec
   unsigned long h = 1000; // total time before trigger (from "elapsed > 1000")
   unsigned long p = 10000; //fading period (11000 minus 1000)
   unsigned long eh = elapsed-h; //timer-head (time passed)
   unsigned long j = maxBrightness*eh/p; //time passed over fading period multiply maxBrightness
   ShiftPWM.SetOne(0 ,j);
}

if(elapsed > 1500 && elapsed < 2500){ //fade in for 1sec at 1.5-th sec
   unsigned long h = 1500; // total time before trigger (from "elapsed > 1500")
   unsigned long p = 1000; //fading period (2500 minus 1500)
   unsigned long eh = elapsed-h; //timer-head (time passed)
   unsigned long j = maxBrightness*eh/p; //time passed over fading period multiply maxBrightness
   ShiftPWM.SetOne(2 ,j);
}

That's a big help! :smiley:

Perhaps an easier way that I could set values of 'h' and 'p' using calculations?
That way I would need a function, right?

For this one:

if(elapsed > 1500 && elapsed < 2500){ //fade in for 1sec at 1.5-th sec
   unsigned long h = 1500; // total time before trigger (from "elapsed > 1500")
   unsigned long p = 1000; //fading period (2500 minus 1500)
   unsigned long eh = elapsed-h; //timer-head (time passed)
   unsigned long j = maxBrightness*eh/p; //time passed over fading period multiply maxBrightness
   ShiftPWM.SetOne(2 ,j);

I want to make it to just need me to manually set two values (which is 1500 and 2500) then value of 'h' and 'p' will be automatically set.
Perhaps also need a way to set if I want to fade in or fade out (invert the value 'j'? - 0 to represent 255 and 255 to represent 0?)

I'm trying to set the functions now, any tip will surely be useful too! :smiley:

Thanks!!!!

Thanks a lot!
I think it's done.
I hope this code of mine will also be useful to others.
Or maybe someone would modify it to make it better.

fIn(1, 1000, 2000); //led1, trigger the fade in at 1st second (1000ms), for 2secs (2000ms) 

fOut(1, 3000, 500); //led1, trigger the fade out at 3rd second (3000ms), for .5secs (500ms) 

//it takes led1 2secs to get to maximum brightness, so the fade out trigger will start at the 3rd second.


void fIn(int ledN, int tStart, int period){
  //ledN - which LED?
  //tStart - start from when
  //period - for how long
  unsigned long elapsed=millis(); //timer
  int tEnd = tStart+period; //the end of the fading is after the period.
  int tEndX = tEnd+100; // give extra time to complete fading
  if(elapsed > tStart && elapsed <= tEndX){ //fade in for 'period'sec from tStart to tEndX.
    unsigned long h = tStart; // total time before trigger
    unsigned long p = tEnd-tStart; //fading period 
    //or "unsigned long p = period;" will do.
    unsigned long eh = elapsed-h; //total time passed since triggered
    unsigned long j = maxBrightness*eh/p; //"eh/p" = time passed over fading period (percentage) then multiply by maxBrightness
    if (elapsed >= tEnd){
      j = maxBrightness;
    } //when ending, bring j to maximum brightness (to complete the fading) because millis(); is not perfect.
    ShiftPWM.SetOne(ledN ,j);
  }
}

void fOut(int ledN, int tStart, int period){
  unsigned long elapsed=millis(); 
  int tEnd = tStart+period;
  int tEndX = tEnd+100;
  if(elapsed > tStart && elapsed <= tEndX){ 
    unsigned long h = tStart; 
    unsigned long p = tEnd-tStart; 
    unsigned long eh = elapsed-h; 
    unsigned long j = maxBrightness*eh/p; 
    if (elapsed >= tEnd){
      j = maxBrightness;
    }
    unsigned long k = maxBrightness-j; // invert value of fade in to become fade out
    ShiftPWM.SetOne(ledN ,k);
  }
}

But this code will be quite different when it comes to RGB leds, right?
Is there a colour cross-fading (or morphing) effect in ShiftPWM for RGB leds?
-to change from blue to green smoothly.

Will my code work for RGB leds to simply set it's brightness without affecting it's current colour?
for example that led1 is set to keep on changing from green to blue then back to green, then with my code i just make its brightness dimmer without affecting the colour changing?
Or is there a function in SHiftPWM to do this?

haven't any RGB led yet...
So, sorry if I might be asking this question for granted :confused:

Thank you very much :slight_smile:

Hi,

I need to shrink my project...
I'm using an Arduino Mega 2560 and it's size is too big for what I need.

I heard about the ATtiny :confused:

which ATtiny can I use for ShiftPWM?
What are the requirements for ShiftPWM to run

Or which other method do you recommend?

Can you also give me some tips on how to power many LEDs?
I know that you are selling powerful LED drivers but if it's in my budget and if it would be worth it to buy and works just fine for me, I would buy yours! :slight_smile:

More details:
My team will be performing something and we will be using LEDs.
Some effects to fade in and fade out, perhaps in some props we will need RGB leds.

I've bought 4 single coloured led strips, (600 leds in each strip - red, green, blue and white)
I've also bought 1 RGB led strip, 300 leds in that strip
I bought few EL wires of different colours (they need AC current)

The idea is to use the blue led strip one of the props, (just switch on)
one guy to use the red led strip and EL wire(use one ATtiny to run ShiftPWM? with shift registers?)
the other guy to use the green led strip or RGB led strip and EL wire (use one more ATtiny to run ShiftPWM? with shift registers again?)
one more prop will use about 5 leds, just fade in and fade out selected ones in a certain time (use one more ATtiny to run ShiftPWM? with shift registers again?)

So I need some recommendations how to power the LEDs...

I'm still a newbie specifically in this (circuitry) but not very newbie in stuffs like this (creating stuff).

Really grateful of any help that you can provide, I just need some tips to kick start what to do next...

Hi,

is it possible to fade those Duo-LED with the shiftPWM Library (without the SPI)?

http://www.reichelt.de/DUO-LEDs-Blink-LEDs/LED-5-RG-3/3/index.html?;ACTION=3;LA=446;ARTICLE=6820;GROUPID=3022;artnr=LED+5+RG-3;SID=13Txfp1H8AAAIAAByzpaYc92665776fcaa200aa737138599d280f

-tsaG

NicksonYap:
Is there a colour cross-fading (or morphing) effect in ShiftPWM for RGB leds?
-to change from blue to green smoothly.

Will my code work for RGB leds to simply set it's brightness without affecting it's current colour?
for example that led1 is set to keep on changing from green to blue then back to green, then with my code i just make its brightness dimmer without affecting the colour changing?
Or is there a function in SHiftPWM to do this?

There are functions to set HSV values. With the hue you can smoothly go from blue to green. With the value you can change the brightness.

NicksonYap:
... stuff about shrinking and high power

I have not used ShiftPWM with an attiny. As far as I know there are no AtTiny arduino clones. The code uses some Arduino functions, so it will not be directly compatible. Maybe you could have a look at the teensy 2.0? Teensy USB Development Board. It is really small and arduino compatible.

My high power led drivers are meant to drive high power, luxeon type, LED's without resistors. You are using LED strips, which have resistors on them. You are better off using transistors to switch them. I will design a transistor board for ShiftPWM, but it is not available now.

tsaG:
Hi,

is it possible to fade those Duo-LED with the shiftPWM Library (without the SPI)?

LED 5 RG-3: Duo-LED, 5 mm, THT, 3-Pin, rt - gn, CC, 60 mcd, 30° bei reichelt elektronik

-tsaG

They are basically two LED's in one case, so yes. They share a cathode or anode, but you would just tie that to ground/vcc and use PWM for the other pin.

Thanks for the reply :smiley:

I bought some ULN2803 transistor that was intended for me to make RainBoard... but now still waiting for my shipment of RGB LED strips :confused:

The UL2803 transistor looks like a complicated transistor to me.
They do work well for me to switch the LED strip, right?

Thanks again :slight_smile: