Eindhoven
Offline
Jr. Member
Karma: 1
Posts: 87
|
 |
« Reply #210 on: May 05, 2012, 07:02:55 am » |
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.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Full Member
Karma: 0
Posts: 189
|
 |
« Reply #211 on: May 05, 2012, 10:26:28 am » |
I have added some functions to my copy on my laptop for rgb leds and advanced chases if you want them
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 10
|
 |
« Reply #212 on: May 05, 2012, 04:04:39 pm » |
@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!
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Full Member
Karma: 0
Posts: 189
|
 |
« Reply #213 on: May 05, 2012, 04:21:11 pm » |
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
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 10
|
 |
« Reply #214 on: May 05, 2012, 04:22:50 pm » |
I was thinking some bit sorta functions would be cool.. invert, etc..
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Full Member
Karma: 0
Posts: 189
|
 |
« Reply #215 on: May 05, 2012, 04:47:32 pm » |
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
|
|
|
|
|
Logged
|
|
|
|
|
Eindhoven
Offline
Jr. Member
Karma: 1
Posts: 87
|
 |
« Reply #216 on: May 06, 2012, 04:51:47 pm » |
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
|
|
|
|
|
Logged
|
|
|
|
|
Eindhoven
Offline
Jr. Member
Karma: 1
Posts: 87
|
 |
« Reply #217 on: May 07, 2012, 06:22:44 pm » |
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/PinFlexibilityThis update introduces two new things: OffsetAn 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 GroupingWith 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.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 10
|
 |
« Reply #218 on: May 09, 2012, 02:08:32 pm » |
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?
|
|
|
|
« Last Edit: May 09, 2012, 02:17:44 pm by billieblaze »
|
Logged
|
|
|
|
|
Eindhoven
Offline
Jr. Member
Karma: 1
Posts: 87
|
 |
« Reply #219 on: May 09, 2012, 04:59:39 pm » |
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.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 10
|
 |
« Reply #220 on: May 09, 2012, 09:14:39 pm » |
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?
|
|
|
|
|
Logged
|
|
|
|
|
Eindhoven
Offline
Jr. Member
Karma: 1
Posts: 87
|
 |
« Reply #221 on: May 10, 2012, 04:24:13 pm » |
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.
|
|
|
|
|
Logged
|
|
|
|
|
Kuala Lumpur, Malaysia
Offline
Newbie
Karma: 0
Posts: 13
Absorbing knowledge! Will give it back :)
|
 |
« Reply #222 on: May 26, 2012, 11:00:58 am » |
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! 
|
|
|
|
|
Logged
|
|
|
|
|
Eindhoven
Offline
Jr. Member
Karma: 1
Posts: 87
|
 |
« Reply #223 on: May 26, 2012, 11:53:22 am » |
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.
|
|
|
|
|
Logged
|
|
|
|
|
Kuala Lumpur, Malaysia
Offline
Newbie
Karma: 0
Posts: 13
Absorbing knowledge! Will give it back :)
|
 |
« Reply #224 on: May 27, 2012, 09:50:10 am » |
Thanks a lot! That gave me a big boost!  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!  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!  Thanks!!!!
|
|
|
|
|
Logged
|
|
|
|
|
|