Help with shift registers/LEDs

basically, I am trying to convert the example Physical Pixel Sketch so that it is able to light up LEDs using the shift registers

Now, I have seen the tutorials on how to properly wire the registers and the example sketches, but my knowledge of digital logic/programming is limited (always been more of an emag guy), and I could not really follow them

I am actually sending the code through a C++ program, so I would like to be able to send an 8 character string

so, assuming I want to send an 8 character string, "ABCDEFGH" or something, with each letter corresponding to the on position of an LED, could someone give me any pointers on how to modify the code to work with the shift registers?

I am thinking something like this, but like I said, I have limited (bad) programming/digital logic skills

-clock high -read serial input -output to shift register -clock low -reset serial input to 0 -clock high -read serial input -output to shift register -clock low -reset serial input to 0 -repeat 6 more times

would this work? I'm sure I'm missing something here...

Would really appreciate any advice, I'm unsure of how to even approach this problem

Thanks

so I would like to be able to send an 8 character string

So how many shift registers are you planning to have. You will need one shift register per character so that means 8 shift registers hence controlling 64 LEDs. Somehow I think this is not what you want.

well, the shift register has 8 output pins so I would like to be able to send an 8 character string, each character corresponding to one output pin on the shift register

does that make sense?

does that make sense?

The desire makes sense but that is not how things work. You have to send a byte or single character. Each bit in that byte will control the state of one LED. So if you were to do this with a character there would be many unprintable characters and each one would control a combination of LEDs on and off. So in total you would have 256 possible characters one for each combination of LED. In practice you just set and clear bits in a byte and ship that out to the shift register. If you want a fancy front end to this then you can write code to turn your characters into bit state and position but if you can write this then you can deal with the bits directly.

so, can I just send characters one at a time, instead of the string all at once, and get the same effect?

Yes but finding what that character is can be tricky. Try to think in bits. see this:- http://www.arduino.cc/playground/Code/BitMath

Okay, I see what you are saying

To explain my project in further detail, just to clarify,

I will basically be taking in a sequence of 0s and 1s from another program, which will tell me which LEDs to light up

I am actually planning on having 16 different LEDs, so I would need 2 different shift registers

so, assuming I find the proper character for each possible combination of LEDs that could be lit up. (I would end up having 2^16 possible combinations, correct?)

Each time I get the user input, I would have to scan through 2^8 combinations two times, until I found the proper character that corresponds to the correct output for each shift register

I guess scanning through 512 characters isn't that bad, but could you give me a little bit of advice on how to actually program this using the arduino?

Like I said, I'm using the PhysicaPixel sketch right now, so how would I set up the clock/latch pins if I plan on doing it this way?

Thanks for all your help

a sequence of 0s and 1s from another program,

As a binary stream (ie 16 bits) or as characters (16 bytes)?

If you have the data as 16 bits then just do two shiftOut()s.

If the data is 16 bytes ('1's and '0's) then there are a few ways to do it.

I guess scanning through 512 characters isn't that bad,

You don't have to scan 512 chars, at most 16 if the data is in bytes.

Tell us the exact format of the data and we can go from there.


Rob

Okay, well I figured out how to get this to work by modifying the hello world shiftout example

//Pin connected to ST_CP of 74HC595
int latchPin = 8;
//Pin connected to SH_CP of 74HC595
int clockPin = 12;
////Pin connected to DS of 74HC595
int dataPin = 11;

int incomingByte;

void setup() {
  //set pins to output so you can control the shift register
  Serial.begin(115200);
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
}

void loop() {
  // count from 0 to 255 and display the number 
  // on the LEDs
  if (Serial.available() > 0) {
   incomingByte = Serial.read();
   int numberToDisplay = incomingByte;
    // take the latchPin low so 
    // the LEDs don't change while you're sending in bits:
    digitalWrite(latchPin, LOW);
    // shift out the bits:
    shiftOut(dataPin, clockPin, MSBFIRST, numberToDisplay);  
    //take the latch pin high so the LEDs will light up:
    digitalWrite(latchPin, HIGH);
    // pause before next value:
  }
}

This code will take in a character, then output the corresponding value to the LEDs for example, the character @ has a value of 64, so my LEDs will light up like so

00000010, where 1 indicates an LED in the "on" position

but one last thing, is there anyway to send the data over the serial port in binary form? So instead of sending the character @, I could just send 0000010 through the arduino serial monitor?

or even being able to send an INT value would be much more convenient

nevermind, I got it…
if anyone is interested…

//Pin connected to ST_CP of 74HC595
int latchPin = 8;
//Pin connected to SH_CP of 74HC595
int clockPin = 12;
////Pin connected to DS of 74HC595
int dataPin = 11;
int incomingByte;
int serReadInt()

{
 int i, serAva;                           // i is a counter, serAva hold number of serial available
 char inputBytes [7];                 // Array hold input bytes
 char * inputBytesPtr = &inputBytes[0];  // Pointer to the first element of the array
     
 if (Serial.available()>0)            // Check to see if there are any serial input
 {
   delay(5);                              // Delay for terminal to finish transmitted
                                              // 5mS work great for 9600 baud (increase this number for slower baud)
   serAva = Serial.available();  // Read number of input bytes
   for (i=0; i<serAva; i++)       // Load input bytes into array
     inputBytes[i] = Serial.read();
   inputBytes[i] =  '\0';             // Put NULL character at the end
   return atoi(inputBytesPtr);    // Call atoi function and return result
 }
 else
   return -1;                           // Return -1 if there is no input
}

void setup() {
  //set pins to output so you can control the shift register
  Serial.begin(115200);
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
}

void loop() {
  // count from 0 to 255 and display the number 
  // on the LEDs
  if (Serial.available() > 0) {
   incomingByte = serReadInt();
   int numberToDisplay = incomingByte;
    // take the latchPin low so 
    // the LEDs don't change while you're sending in bits:
    digitalWrite(latchPin, LOW);
    // shift out the bits:
    shiftOut(dataPin, clockPin, MSBFIRST, numberToDisplay);  
    //take the latch pin high so the LEDs will light up:
    digitalWrite(latchPin, HIGH);
    // pause before next value:
  }
}

now to make it work with two shift registers…
any ideas on how to go about doing this?