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

Could you add a link for the most recent ShiftMatrixPWM Library/.pde, please? has there been substantial progress recently?

edit: order

The latest version posted here is still the most recent version, but it seems to work fine.
I just have not updated the comments and documentation. I have been too busy building my new project, a fermentation fridge with data logging and a web interface.

Just use the code posted here and post again if you encounter problems.

How appropriate...keep me up to date on the fermentation fridge. I am in the process (still gathering supplies) of building an arduino-controlled corny kegerator. Re-purposed chest freezer, temperature controlled with the arduino and LCD readout for temps and beer names (and possibly amount left in keg). Brewing our pale ale this weekend along with a pumpkin ale. Anyway, off-topic, I will post back when I get a chance to try the matrix fully. Thanks!

hello,

I've made the circuit as shown in the ShiftOut Tutorial on the arduino website .i've used six 595 registers and common Anode Led's & i'm running the example that came with the code but it doesn't work as shown in the video ,Please help . . . .i'm attaching a video clip too ,kindly note that the last few led's don't light up properly

Video0030.3gp (116 KB)

Hello ,

I've tried all possible things that i'm aware of to make this thing work but its not happening ,the LED's Flicker too fast and the whole thing freezes ,Kindly help !!!

Abhay:
Hello ,

I've tried all possible things that i'm aware of to make this thing work but its not happening ,the LED's Flicker too fast and the whole thing freezes ,Kindly help !!!

Hello Abhay,
How exactly have you setup your circuit?
Did you setup as it says on the site:

Which hardware is used with ShiftPWM?

Basically just an Arduino and a chain of Shift registers. The circuit is exactly the same as in the ShiftOut tutorial on arduino.cc, but leave out the latch pin capacitor. You can choose the latch pin yourself, but the data and clock pins should be connected to the SPI pins MOSI and SCK.

What is not shown in that tutorial example is a decoupling capacitor, the capacitor that is shown in the tutorial is an error and should not be included on the latch pin! A decoupling capacitor is usually a .1uF ceramic type capacitor that is kept close to the IC and is across its Vcc and Gnd. This helps stop electrical noise from interfering with the IC. Using Shiftregisters like this is creating noise as you are switching power very fast. The effect gets worse the further from the source(Arduino) the signal gets. This could be what is effecting your output.

Grumpy_Mike is seen on a lot on the boards/threads here making sure that people use decoupling capacitors. Only reason I know of them is because of him (Big thanks Mike!). He even went so far as to make a tutorial of his own about them:
http://www.thebox.myzen.co.uk/Tutorial/De-coupling.html

I hope this helps with your issues.(Did I get it right Mike?)

I removed the latch pin Capacitor,but it's still no good,the LED's keep flickering too fast and the last few LED's don't glow as brightly as the first few ,I'm using the same example that comes with the library ,still don't know what to do,plz help !!!

Did you connect the Shift Register clock pin to 12 or 13 on the Arduino?

Bingo !!!! That's it yes i had connected to pin 12 ,the moment i connected it to pin 13,everything worked perfectly

Thank you for your help :slight_smile:

Hi elcojacob,

Great work on the library, and i'm hoping you may be able to help with what i think might be a small problem but I dont know.

Now bare in mind I don't have a great deal of knowledge but I am using the code below which utilizes a code i have been using for "boblight" for my diy ambilight and tried to integrated (mash up in my case lolol) shiftPWM.

To my surprise (i don't have a lot of faith in my abilities! lol) this actually works quite well with the one exception that the fade time between colours is a little slow when using 'ShiftPWM.SetOne' over 'analogWrite'.

Am i missing a setting in shiftPWM to make the fade faster???

I've actually got four channels from boblight working, Top, Bottom, Left and Right, so the only thing missing is speeding up the fade.

Thanks for your time.

My Code:

#include <SPI.h>
const int ShiftPWM_latchPin=8;
const bool ShiftPWM_invertOutputs = 0;
#include <ShiftPWM.h>

#define checkByte1 0x55 
#define checkByte2 0xAA

#define channelCount 6
unsigned char maxBrightness = 255;
unsigned char pwmFrequency = 75;
int numRegisters = 1;
word channels[channelCount];
int channelPins[channelCount] = {0, 1, 2, 3, 4, 5}; // ShiftPWM pins to control LEDs (2x Common Cathode RGB's)

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

  for (int i =0; i<channelCount; i++)
  {
    channels[i] = 0;
    pinMode(channelPins[i], OUTPUT);
  }
  setLight();
}

void loop() 
{
  pollSerialPort();             
}

void setLight() {
  word val;
  byte high, low;
  for (int i=0; i<channelCount; i++) 
  {
    val  = channels[i];
    high = val >> 8;
    low  = val & 0xFF;
    ShiftPWM.SetOne(channelPins[i], high);
  }  
}

void pollSerialPort() {
  int data;
  if (Serial.available() >= 4) { 
    data = Serial.read(); 
    echo(data);
    if (data == checkByte1) {
      data = Serial.read(); 
      echo(data);
      if (data == checkByte2) {
        data = Serial.read(); 
        if (data < 127)
          readChannels(data);
        else
          readCommand(data); 
        return;
      }
    }
  }
}
void echo(int data) {
}

void readChannels(int startChannel) {
  int numChannels = Serial.read();
  while (Serial.available() < numChannels * 2)
    delay(10);
  byte high, low;
  word val;
  for (int i = 0; i < numChannels; i++)
  {
    high = Serial.read();
    low  = Serial.read();
    val  = word(high, low);

    if (startChannel+i < channelCount)
      channels[startChannel+i] = val;
  }
  setLight();                                    
}

void readCommand(int command) {
  int numBytes = Serial.read();
  
  if (command == 0x81)
  {
    requestValues();
  }
  else if (command == 0x83)
  {
    setLight();                                    
  }
  else if (command == 0x84)
  {
    for (int i =0; i<channelCount; i++) {
      channels[i] = 0;
    }
    setLight();                                    
  }
}

void requestValues()
{
    int startChannel = Serial.read();
    int numChannels =  Serial.read();   
    Serial.print(checkByte1, BYTE);
    Serial.print(checkByte2, BYTE);
    
    if (startChannel >= channelCount || numChannels <=0)
    {
      Serial.print(0, BYTE);
      Serial.print(0, BYTE);
    }
    else 
    {
      numChannels = min(channelCount - startChannel, numChannels);
      Serial.print(startChannel, BYTE);
      Serial.print(numChannels, BYTE);
     
      byte high, low;
      word val;
      for (int i=startChannel; i< startChannel + numChannels; i++)
      {
         val = channels[i];
 	 high = val >> 8;
         low  = val & 0xFF;
         Serial.print(high, BYTE);
         Serial.print(low, BYTE);
      }
   }
}

First, thanks for the great library. I'm gearing up to do some RGB matrix stuff and have demo'd up your code on a RGB led matrix. Here's some pics. This one is a common cathode and a weird pinout (only $11 from LED Matrix). I'll post more as I move forward. I plan on testing the shift matrix code eventually too.

Hardware setup:
Duemilanove, 3x595's, RGB matrix, resistors

Too bright!

All rows hooked up, it just repeats what was on the first row. Note the difference in colors across the rows, i'm guessing this is because i need to give this a dedicated 5v instead of just off the arduino rail.

Thanks for the library. I am testing on a 16x32 matrix (eight red 8x8s) with a Duemilanove and 6 595s

elcojacobs:
Do you have a 16x16 RGB matrix? I am very curious how that will look.

Hey Elco,
I'm actually trying to get this to work with my 16x16 rgb matrix (consisting of 4 8x8 submodules). however i've wired the shift registers in a different way. I made one long chain of 8 shift registers with just the three lines (data, latch and clock) going to the arduino.
The order of the shift registers is like this:

[arduino]---[v+ 1-8 (row)]---[+ 9-16]---[r 1-8 (cols)]---[r 9-16]---[g 1-8]---[g 9-16]---[b 1-8]---[b 9-16]

I already started on writing my own code to try and adress the matrix until i came across this post in your thread and i thought i want to try that one, seems so much more simple!

What would be the easiest way to get your library to work, what do i need to change to get the data to the correct registers.

Thanks in advance!

ps. In the meantime ill try to get it working by myself but your help is greatly appreciated :).

What would be the easiest way to get your library to work, what do i need to change to get the data to the correct registers.

The ShiftMatrixPWM code doesn't work on just one chain of shift registers and the normal ShiftPWM code would need to be rewritten to do the timings required for using only one chain to drive a full matrix. Also it would mean updating SR's that don't need to be updated every PWM cycle.

The following is how I understand it and please correct me if I am wrong.

For example an 8x8 matrix. 8 columns and 8 rows. As one chain it would be 2 SR's chained, 1 controlling the rows and 1 controlling the columns(or however you want). To do 16 level PWM the chain would have to be update 16 times per row which means that your updating 8 of the bits 15 times more that you need to and having to send an extra 8 bits every time. So an extra 8 bits x 15 times x 8 rows and that is only 1 full scan of the matrix, this would then be performed at 50+ HZ. This adds up to alot of extra data that really doesn't have to be shifted and scales up as the matrix gets bigger.

But with 2 seperate chains the way Elco made his code. Using the example above, the Row chain gets updated once to say which row is active. Then the Column chain does its 16 passes to accomplish PWM. The Row chain gets updated and selects the next row. The Column chain does the next lot of PWM passes. Even though the Row chain is being updated using a slower method (not SPI) it still saves time.

To help I have made a Fritzing Diagram of the setup I am using for my 16x16 RGB breadboard test. This is in my ShiftMatrixPWM thread.

I'm not the creator of this code only a happy user :). The ShiftPWM could probably be altered to accomadate what you want but I don't know what would need to be changed. I am just putting forward how to use the library as is.

Elco, would this be a big change?

Hey Milamber,
Thanks for the reply, even though as you already pointed out youre not the creator of the code.
However whem im reading this i think it will be way easier to split the row registers from the collum registers. (thats then a chain of 2 and a chain of 6). I was thinking originaly about having a multiplexer switch between the four groups of two shift registers each but i abandoned that idea a bit earlier. However after reading this that maybe could be a better idea, and maybe keeping the latch signal controlled seperately for each of the 4 registers. this would mean i need 8 pins instead of six if i made two chains, but it would also mean i only need 8 pins instead of twelve if i made 4 chains of two shift registers.

Elco, what do you think would be the easiest?

Hi elco and others,

sorry about posting to the blog, I did'nt know about the support thread.

Ok so I have a problem using more than 7 registers and passing data on the fly trough serial. You can see a video of the thing working with 7 SR here: http://vimeo.com/33354111

When I take the serial option out I can go way over 7 SR but with the serial option I get very weird behavior from 8 and up. Including the servo.h didn't change anything.

Have anyone had this problem ? Where do I go wrong ? (see code below)

Also, there are concepts about the timer library that I still don't get, anyone knows a tutorial that "really takes you by the hand" on this ?

Thanks,

here is my arduino code:

//#include <Servo.h>
#include <SPI.h>
#include <Messenger.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;

#include <ShiftPWM.h> // include ShiftPWM.h after setting the pins!
unsigned char maxBrightness = 255;
unsigned char pwmFrequency = 75;
int numRegisters = 7;
Messenger message = Messenger();
int r = 0;

// Define messenger function
void messageCompleted() {
int pin = message.readInt();
int value = message.readInt();
ShiftPWM.SetOne(pin, value);
}

void setup() {
pinMode(ShiftPWM_latchPin, OUTPUT);
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(115200);

ShiftPWM.SetAmountOfRegisters(numRegisters);
ShiftPWM.Start(pwmFrequency,maxBrightness);
ShiftPWM.SetAll(r);
// ShiftPWM.PrintInterruptLoad();
message.attach(messageCompleted);
}

void loop() {
while ( Serial.available( ) ) message.process(Serial.read( ) );
}

Because the Serial receives data using interrupts, interrupts that are interrupting the function that is sending data to the shift-register.

ok, so if I understand, serial uses interrupts which "pauses" the process that talks to the SR and somehow this is not a problem with only 7 SR. But with 8 SR and more it gets serious enough to make the thing work like crap.

Question: Is there a way to speak to the arduino without interrupting ? Or better, is there a solution for this, like "pausing" what I send to the SR without them going crazy?

thanks,
p

Hello patrick88,

Your project looks really cool. I hope you can get your issues cleared up. I haven't seen the Messenger Library before but I have a feeling that using this on an interrupt is slowing things down. As there are function calls and returns that introduce delays.

I am not sure what sort of data stream you are sending to the arduino but in a project I am doing with a big LED matrix, I am sending 768 byte values to the arduino 15 times a second. I am not using 0-255 levels however, I am only using 0-31 but they are still being sent as each value is one byte. I am simply using a start byte (a number above 31) then directly filling the PWM array used by ShiftPWM with the frame data. I have been able to get a high amount of through put using this method. I am not sure if this information can help in your project.

Integrating Serial and interrupts seems to be a bit tricky. I found that keeping the routine for using the serial data short helped alot.

Hi milamber,

thanks for the tips. I actually found what the problem was. It was coming from the supercollider side of things where I was using the arduino quarks. Somehow, when using the arduino quarks, I get stuck to 7 SR but if I use the Serial Class then everything works smoothly. I have tested with 12 SR so far and I'm still counting.

thanks everyone and special thanks to Elco for this library this is amazing work.

p