Using two 8-bit shift registers

Hi,
following this tutorial http://arduino.cc/en/Tutorial/ShiftOut I'm trying to use two shift registers. I want to be able to light any LED I want, sending data to Arduino from Pure Data. With one shift register everything is fine. This is the code:

//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;



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

void loop() {
  if (Serial.available() > 0) {
    int numberToDisplay = Serial.read();
    // 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:
    delay(500);
  }
}

I'm sending a decimal value from Pd, by converting sequencial ones and zeros which represent the LEDs, and everything works fine. But I can't find a way to do the same with two shift registers wired as instructed in the tutorial. The examples code provided does stuff like lighting them one by one etc. but I can't tweak it to make it work. I've attached the Pd patch if anyone want's to check.
Any help greatly appreciated.

Cheers

shift_register.pd (2.4 KB)

I don't know if this by Nick Gammon will be of any use?

alexandros301:

void loop() {

if (Serial.available() > 0) {
    int numberToDisplay = Serial.read();
    // 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:
    delay(500);
  }
}

Two problems:

  1. numberToDisplay is of type "int" which is 32 bits long (you're pushing 32 bits of data onto two shift registers that can only display 16 bits).
  2. serial.Read() only reads one byte (8 bits) at a time.

Simplest solution:

void loop() {
  if (Serial.available() > 0) {
    byte numberToDisplay1 = Serial.read();
    byte numberToDisplay2 = Serial.read();
    // 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, numberToDisplay1);  
    shiftOut(dataPin, clockPin, MSBFIRST, numberToDisplay2);  
    //take the latch pin high so the LEDs will light up:
    digitalWrite(latchPin, HIGH);
    // pause before next value:
    delay(500);
  }
}

data type int is only 16 bits.
long is 32 bits.

if (Serial.available() > 1 { // got 2 bytes?

dannable:
I don't know if this by Nick Gammon will be of any use?

Gammon Forum : Electronics : Microprocessors : Using a 74HC595 output shift register as a port-expander

It does the trick indeed, thanks. Although with the code provided I can set any LED I want on or off, but for now only through Arduino's serial monitor. The commands to be sent to Arduino are like: 011 (turn the first LED of the first register on), 010 (turn it off), 121 (turn the 2nd LED of the 2nd register on) etc.

Sending similar number to Arduino from Pd doesn't seem to work. Any idea on how to achieve communication?

Thanks

I guess it has to do with the '\n' and '\r' characters since they denote the end of a command, right? How is this possible from another environment, like Pd?
If i send a three digit number (or something like 5s which in the last code of the tutorial means turn the 5th LED on) from Pd, how can I let Arduino know that I'm done with sending commands, so it can execute it?

Finally managed to do it. I'm not used to sending ASCII numbers to Arduino, I keep on forgetting. That was the problem and it's now solved.
Thanks everyone.