Go Down

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

ematson5897

#195
Feb 09, 2012, 10:13 pm Last Edit: Feb 10, 2012, 02:25 am by ematson5897 Reason: 1
I actually made a 4x4x4 cube in december. Then I realised I forgot to diffuse it. I'm using a dremel to try to do it without desoldering

EDIT
I ground to far in 8 of the LEDs. I also need a new tip for my iron. I'll try to fix it tomorrow

dutchronnie

Hello,

I need some help, maybe somebody can help me.
A few post ago there was told me to use the rsv2rgb function to control the brightness. but i don't getting any futher with it.
I think i do something wrong.

This is the working code so far.

Code: [Select]
/******************************************************************************
* This example shows how to use the ShiftPWM library to PWM many outputs.
* All shift registers are chained, so they can be driven with 3 pins from the arduino.
* A timer interrupt updates all PWM outputs according to their duty cycle setting.
* The outputs can be inverted by making ShiftPWM_invertOutputs true.
*
* How the library works:
* The ShiftPWM class keeps a setting for the duty cycle for each output pin, which
* can be set using the provided functions. It also keeps a counter which it compares
* to these duty cycles. This timer continuously runs from 0 to the maximum duty cycle.
*
* A timer interrupt is configured by ShiftPWM.Start(pwmFrequency,maxBrightness).
* The interrupt frequency is set to pwmFrequency * (maxBrightness+1).
* Each interrupt all duty cycles are compared to the counter and the corresponding pin
* is written 1 or 0 based on the result. Then the counter is increased by one.
*
* The duration of the interrupt depends on the number of shift registers (N).
* T = 112 + 43*N
*
* The load of the interrupt function on your program can be calculated:
* L = Interrupt frequency * interrupt duration / clock frequency
* L = F*(Bmax+1)*(112+43*N)/F_CPU
* Quick reference for load:
* 3 registers  255 maxBrightness 75Hz  load = 0.29
* 6 registers  255 maxBrightness 75Hz  load = 0.45
* 24 registers 100 maxBrightness 75Hz  load = 0.54
* 48 registers  64 maxBrightness 75Hz  load = 0.66
* 96 registers  32 maxBrightness 75Hz  load = 0.66
*
* A higher interrupt load will mean less computional power for your main program,
* so try to keep it as low as possible and at least below 0.9.
*
* The following functions are used:
*
* ShiftPWM.Start(int ledFrequency, int max_Brightness) Enable ShiftPWM with desired frequency and brightness levels
* ShiftPWM.SetAmountOfRegisters(int newAmount) Set or change the amount of output registers. Can be changed at runtime.
* ShiftPWM.PrintInterruptLoad() Print information on timer usage, frequencies and interrupt load
* ShiftPWM.OneByOneSlow()          Fade in and fade out all outputs slowly
* ShiftPWM.OneByOneFast() Fade in and fade out all outputs fast
* ShiftPWM.SetOne(int pin, unsigned char value) Set the duty cycle of one output
* ShiftPWM.SetAll(unsigned char value) Set all outputs to the same duty cycle
*
* ShiftPWM.SetGroupOf2(int group, unsigned char v0, unsigned char v1);
* ShiftPWM.SetGroupOf3(int group, unsigned char v0, unsigned char v1, unsigned char v2);
* ShiftPWM.SetGroupOf4(int group, unsigned char v0, unsigned char v1, unsigned char v2, unsigned char v3);
* ShiftPWM.SetGroupOf5(int group, unsigned char v0, unsigned char v1, unsigned char v2, unsigned char v3, unsigned char v4);
* --> Set a group of outputs to the given values. SetGroupOf3 is useful for RGB LED's. Each LED will be a group.
*
* Debug information for wrong input to functions is also send to the serial port,
* so check the serial port when you run into problems.
*
* (c) Elco Jacobs, E-atelier Industrial Design TU/e, July 2011.
*
*****************************************************************************/
//#include <Servo.h>
#include <SPI.h>
#include "hsv2rgb.h"


//Data pin is MOSI (atmega168/328: pin 11. Mega: 51)
//Clock pin is SCK (atmega168/328: pin 13. Mega: 52)
const int ShiftPWM_latchPin=8;
const bool ShiftPWM_invertOutputs = 0; // if invertOutputs is 1, outputs will be active low. Usefull for common anode RGB led's.

#include <ShiftPWM.h>   // include ShiftPWM.h after setting the pins!


unsigned char maxBrightness = 255;
unsigned char pwmFrequency = 75;
int  numRegisters = 2;
byte potPin=0;      //Analog 0 potentiometer
int  potValueRed=0; //Value of potentiometer
const int buttonPin = 2;
int buttonState = 0;         
float h;
int h_int;
int r=0, g=0, b=0;
int val=0;

void h2rgb(float h, int &R, int &G, int &B);


void setup()   {               
  pinMode(ShiftPWM_latchPin, OUTPUT); 
  pinMode(buttonPin, INPUT);     
 
 
  SPI.setBitOrder(LSBFIRST);
  // SPI_CLOCK_DIV2 is only a tiny bit faster in sending out the last byte.
  // SPI transfer and calculations overlap for the other bytes.
  SPI.setClockDivider(SPI_CLOCK_DIV4);
  SPI.begin();

  Serial.begin(9600);
  ShiftPWM.SetAmountOfRegisters(numRegisters);
  ShiftPWM.Start(pwmFrequency,maxBrightness); 
}



void loop()
{   

  val=analogRead(potPin);    // Read the pin and display the value
  h = ((float)val)/1024;
  h_int = (int) 360*h;
  h2rgb(h,r,g,b); 
 
  ShiftPWM.SetAll(0);
  buttonState = digitalRead(buttonPin);

  if (buttonState == HIGH) {     
    for(int ledstrip=0; ledstrip<5; ledstrip++)
  {
    ShiftPWM.SetGroupOf3(ledstrip, b, g, r);
    delay(500);
  }
    delay(1000);


  for(int ledstrip=0; ledstrip<5; ledstrip++)
  {
    ShiftPWM.SetGroupOf3(ledstrip, 0, 0, 0);
    delay(500);
  }
}
  else {
    ShiftPWM.SetAll(0);
  }
}

// function to set the color with a potentiometer

void h2rgb(float H, int& R, int& G, int& B) {

  int var_i;
  float S=1, V=1, var_1, var_2, var_3, var_h, var_r, var_g, var_b;

  if ( S == 0 )                       //HSV values = 0 ÷ 1
  {
    R = V * 255;
    G = V * 255;
    B = V * 255;
  }
  else
  {
    var_h = H * 6;
    if ( var_h == 6 ) var_h = 0;      //H must be < 1
    var_i = int( var_h ) ;            //Or ... var_i = floor( var_h )
    var_1 = V * ( 1 - S );
    var_2 = V * ( 1 - S * ( var_h - var_i ) );
    var_3 = V * ( 1 - S * ( 1 - ( var_h - var_i ) ) );

    if      ( var_i == 0 ) {
      var_r = V     ;
      var_g = var_3 ;
      var_b = var_1 ;
    }
    else if ( var_i == 1 ) {
      var_r = var_2 ;
      var_g = V     ;
      var_b = var_1 ;
    }
    else if ( var_i == 2 ) {
      var_r = var_1 ;
      var_g = V     ;
      var_b = var_3 ;
    }
    else if ( var_i == 3 ) {
      var_r = var_1 ;
      var_g = var_2 ;
      var_b = V     ;
    }
    else if ( var_i == 4 ) {
      var_r = var_3 ;
      var_g = var_1 ;
      var_b = V     ;
    }
    else                   {
      var_r = V     ;
      var_g = var_1 ;
      var_b = var_2 ;
    }

    R = (1-var_r) * 255;                  //RGB results = 0 ÷ 255
    G = (1-var_g) * 255;
    B = (1-var_b) * 255;
  }
}


with this line:
    ShiftPWM.SetGroupOf3(ledstrip, b, g, r);
i turn on the ledstrip.
But i want the ledstrip to fade in, in the same color.
I think it must have a brightness of 0 to 255 in half a second.

Can somebody tell me how i can do that?
I don't know :smiley-mr-green:



dutchronnie

Nobody who can put me in the good direction?

I have tried with rsv2rgb, but i don't get it to work.

vardlokk

Hi!
I connected my Mono LED Cube 5*5*5 to ShifMatrixPWM as a matrix of 5 * 25, and wrote the function SetVoxel, by which row and col are converted to coordinates x, y, z:

Quote

void SetVoxel(int x, int y, int z, int value){
     ShiftMatrixPWM.SetOne(y, numRows*z+x, value);
    }



I am not a programmer, so I doubt that I did the right thing. Maybe it could be better done directly in the library? But how?

Here's the videos:
http://youtu.be/_e79UnxVjgY
http://youtu.be/GePPOiQrW3k

ringz

You have done a great job with your cube.

It really makes an incredible difference being able to control the brightness of the LED's. It's difficult to remember that it's a 5x5x5 cube when you are watching because it's so captivating :)

Martyn.

vardlokk

Thank You, Martyn! Actually, all of the work made El?o. Many thanks to him!))
I want to say that I will also connect the cubes 8 * 8 * 8 and RGB 5 * 5 * 5)))
Need help to modify the library for 3D, and writing new functions.
Of course, if anyone is interested)

dutchronnie

Hello Vardlokk,

The cubes look great.
I have plans to make a led cube to, Is it possibel to share the code you have used?
And can you tell me how you build the cube.

I am not experienced in this, but i want some examples to learn.

vardlokk

Dear Colleagues! This topic is dedicated to the ShiftPWM  library. Let's not clutter. Please, if you are interested in only the LED cubes, drop me a PM.

BlackTie

Hello. I have a question about using this library with a Teensy 2.0++. It seems to be incompatible with the Wire library. When I use Wire.endTransmission(), the program halts. Is it because both libraries are using the same timer, timer1?, This also happens when using timer2 if I include the servo library, so it might not be that. Would it be possible to use timer3 or timer4 in case the uC has it, such as the AT90USB1286, or maybe have a function to stop using the interrupts while I2C operations are in progress, and then enable them afterwards?

If you're interested, I'm building a clock. http://www.youtube.com/watch?v=-NVY2vCfBZY

Paul Stoffregen

The Wire library doesn't use any timers.  I'm not sure why it would hang, other than it may be a bug in Wire itself?

Servo does indeed use timers.  You can edit Servo.h to configure which timers it will use.  It's pretty easy to make Servo use only timer1 or timer3 on Teensy or Teensy++.  Look in Servo.h for details.

Here's a photo of ShiftMatrixPWM....


BlackTie

Must be something in Wire, as you say. I used another I2C library (http://dsscircuits.com/articles/arduino-i2c-master-library.html) and it works, so there's that. Thanks though!

NicksonYap

#206
May 01, 2012, 06:41 pm Last Edit: May 01, 2012, 06:44 pm by NicksonYap Reason: 1
Hi,

I'm quite new to this, but I've done websites and modifying other people's Javascripts to suit for my websites.

I'm trying to fade in and out LEDs simultaneously (non-RGB LED, just one colour).

I'm using Arduino Mega 2560...

Meaning:
I'm trying to fade in LED Two and halfway, LED Three fades in and out before LED Two even completes fading out.


I can't figure how to do this using ShiftPWM.
SoftPWM can fade LEDs without delay, but not through shift registers.
(http://code.google.com/p/rogue-code/wiki/SoftPWMLibraryDocumentation)

My attempt in ShiftPWM:
Code: [Select]

#include <SPI.h>
#include "hsv2rgb.h"
const int ShiftPWM_latchPin=8;
const bool ShiftPWM_invertOutputs = 0;
#include <ShiftPWM.h>
unsigned char maxBrightness = 255;
unsigned char pwmFrequency = 75;
int numRegisters = 3;

void setup()   {                
 pinMode(ShiftPWM_latchPin, OUTPUT);  
 SPI.setBitOrder(LSBFIRST);
 SPI.setClockDivider(SPI_CLOCK_DIV4);
 SPI.begin();
 Serial.begin(9600);
 ShiftPWM.SetAmountOfRegisters(numRegisters);
 ShiftPWM.Start(pwmFrequency,maxBrightness);  
}

void loop()
{  

 int fxDuration=1000; //standardises effect duration
 int d=fxDuration/255; //the delays are for each change in brightness, so I devide them for each brightness change

 ShiftPWM.SetAll(0);
 ShiftPWM.PrintInterruptLoad();


 // "int j=0;j<maxBrightness;j++" kinda means fade in

 //fades in LED 0
 for(int j=0;j<maxBrightness;j++){
   ShiftPWM.SetOne(0 ,j);
   delay(d);
 }

 //fades out LED 0
 for(int f=maxBrightness;f>=0;f--){
   ShiftPWM.SetOne(0 ,f);
   delay(d);
 }

 //attept to fade in LED 2 while LED 1 still fading in
 for(int j=0;j<maxBrightness;j++){
   int fxDuration=5000;
   int d=fxDuration/255;
   ShiftPWM.SetOne(1 ,j);
   delay(d);
   ShiftPWM.SetOne(2 ,j);

 }

 //fades out LED 2
 for(int f=maxBrightness;f>=0;f--){
   ShiftPWM.SetOne(2 ,f);
   delay(d);
 }
}



SoftPWM code which works will for now but not using shift registers and not for RGB LEDs (might need RBG LEDs in the future)
Code: [Select]
#include <SoftPWM.h>

void setup(void)
{
 int ledPin1 = 12;
 int ledPin2 = 11;
 int ledPin3 = 9;
 SoftPWMBegin();
 
 // Create on pins 9, 11, 12.
 SoftPWMSetPercent(ledPin1, 0);
 SoftPWMSetPercent(ledPin2, 0);
 SoftPWMSetPercent(ledPin3, 0);

 // Set full scale fade time of pin 9 (fade in duration 1000 ms, fade out duration 1000 ms)
 SoftPWMSetFadeTime(ledPin1, 1000, 1000);
 // Set full scale fade time of pin 9 (fade in duration 4000 ms, fade out duration 4000 ms)
 SoftPWMSetFadeTime(ledPin2, 4000, 4000);
 SoftPWMSetFadeTime(ledPin3, 2000, 2000);
}

void loop(void)
{
 int ledPin1 = 12;
 int ledPin2 = 11;
 int ledPin3 = 9;


//fades led 1 brightness to 100%
 SoftPWMSetPercent(ledPin1, 100);
 delay(1000); //to allow led 1 to fade completely not allowing the next one to come in
 //fades led 1 brightness to 0%
 SoftPWMSetPercent(ledPin1, 0);
 delay(1000);
 //fades led 2 brightness to 100%
 SoftPWMSetPercent(ledPin2, 100);
 delay(2000);//to allow led 2 to fade halfway (50%) allowing led 3 to come in
 //fades led 3 brightness to 100%
 SoftPWMSetPercent(ledPin3, 100);
 delay(2000);//led 2 completes fading in to 100%
 //fades led 2 brightness to 0%
 SoftPWMSetPercent(ledPin3, 0);
 delay(2000);
 SoftPWMSetPercent(ledPin2, 0);
 delay(4000);//just to delay the time before next loop

}


Please help me...

Thanks a lot  :)

billieblaze

#207
May 02, 2012, 01:09 am Last Edit: May 02, 2012, 05:44 am by billieblaze Reason: 1
I'm testing out shiftMatrixPWM with a SparkFun 4x4 LED Button Matrix and i'm at wits end..  I've googled pretty much all day, and read all over the forums, etc.. 

So, I've got a common cathode RGB Matrix - 4x4 like i said.    I've run ShiftPWM and I guess it was working..   So I moved on to Matrix - From what I understand, you've added a single SR on pins 6,7,8 which should be responsible for row selection.    So, I've got one 595 on 6,7,8 which is going to my GND's and three daisy chained on 9,11,13 which drive one color each..   sound right?   

I've set invertColumnOutputs to 0 and invertRowOutputs to 1 and set numColumnRegisters to 3 and numRows to 4.  Is that right as well? 

The example pretty much runs, i expected the one by one function to do a single LED, but its doing a column..  It just doesn't seem right..

setOne seems to allow me to change each pixels color..   eg, 0,0 - 0,1 - 0,2 show a single pixel.. and i can manipulate single pixels around the board, but when i use setGroupOf3 to try to set rgb in one call, it doesn't seem to be in the position i'm expecting.. 

HELP!  :-)  TIA

elcojacobs

#208
May 04, 2012, 02:53 pm Last Edit: May 04, 2012, 03:04 pm by elcojacobs Reason: 1

Something about non block led stuff..


Tomorrow is brew day en ShiftPWM day.
I am aware that the documentation is very minimal. It will receive a big update soon, because I am going to sell high power led drivers for ShiftPWM.

It seems to me that your problem is not that hard. For nonblocking, something like this, with the millis() function. This is untested code, because I am at work now.

Example for one led: fadein 1 sec, fadeout 1 sec, off 5 sec.
Code: [Select]

void setup(){
  timerstart=millis();
}

void loop(){
  unsigned long timer=millis();
  unsigned long elapsed = timer - timerstart;
  if(elapsed > 7000){
      timerstart=millis();
      elapsed = 0;
  }
  if(elapsed)< 1000){
      ShiftPWM.setOne(1, maxBrightness*elapsed/1000);
  }
  else if(elapsed < 2000){
      ShiftPWM.setOne(1, maxBrightness - maxBrightness*elapsed/1000);
  }
  else{
      ShiftPWM.setOne(1,0);
 }

 /* do other stuff here */

}


Billieblaze, your question is a bit more complicated and I don't have time to answer it now in detail. I believe the current version of matrix pwm is RGBRGBRGB... and not R..RRG..GGB..BB. But the led driver board I designed myself uses the same setup as you have, so I will create a new version with that setup, but I am overloaded with work so I cannot promise you when.

ematson5897

What kind of features will be included in said update?

Go Up