Go Down

Topic: ShiftPWM support topic. Latest update: Schematics, high power LED's, LED strips (Read 86667 times) previous topic - next topic

elcojacobs

Easier to use RGB and HSV functions, flexibility in LED setup, memory optimizations, possibility to use BCM instead of PWM (more speed and levels at the cost of double memory usage).

I also want to move everything to GitHub to make user contributions easier.

But I also have brewing to do today, so I will probably not get this all done today.

ematson5897

I have added some functions to my copy on my laptop for rgb leds and advanced chases if you want them

billieblaze

@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!

ematson5897

These are from a while back...
Quote
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

billieblaze

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

ematson5897

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
Code: [Select]
bool ShiftPWM_invertOutputs

elcojacobs

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:
https://github.com/elcojacobs/ShiftPWM

elcojacobs

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:
https://github.com/elcojacobs/ShiftPWM/tree/PinFlexibility

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.

billieblaze

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?

elcojacobs

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:

* Download it here:
https://github.com/elcojacobs/ShiftPWM/downloads
* Extract it to libraries/ShiftPWM
* Open one of the examples

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.

billieblaze

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?

elcojacobs

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.

NicksonYap

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:
Code: [Select]


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:
Code: [Select]
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! :)

elcojacobs

Try something like this:

Code: [Select]

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.

NicksonYap

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

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)
Code: [Select]

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! :D

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:
Code: [Select]
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! :D

Thanks!!!!

Go Up