Could use some arduino advice for dealing with 74HC595 Shift registers

I’m trying to make a wall hanging version of the Ouija wall from stranger things.


basically when the board detects movement I want it to wake up and pick a predefined message and start blinking it out one LED at a time. I know there are lots of ways to accomplish this, but I decided on using 74HC595 shift registers.

I started with setting up a simple push button circuit. Then daisy chained 3 and swapped the buttons for an ESP8266. I’m good on the hardware side. The 3 74HC595s are controlling 24 of the 26 needed LEDs. I’m still trying to get my monkey brain around the code. I’m finding lots of examples for doing effects with the shift registers but not much about controlling one pin at a time. Either that or my math deficiencies are keeping me from understanding how they work. What I want to do is be able to push 000000000000000000000000 into the register for clear, 000000000000000000000001 for LED A, 000000000000000000000010 for LED B, 000000000000000000000100…100000000000000000000000 for LED X, then just control Y&7 with a couple of individual pins from the µC. I guess I could just use 24+ digitalwrite statements for each letter or clear, but that just seems like an ugly/kludgy hack.

At that point I could hard code the messages into cases or functions, but I’d like to be able to store them as stings and get the code to parse them and output to the LEDs letter by letter. That way the messages could be from the random hard coded list or come from a user input like the serial monitor or an MIT app inventor2 app.

The last part which I haven’t looked into yet, but I don’t really think will be a problem, is to use an ultrasonic sensor as a motion detector to wake the thing up and make it pick a message to send

This is my first jump back into programming arduino after like 6 months, so I’d appreciate any ideas, pointers, tutorials, or videos you think might be helpful. But please no recommendations about switching to a premade WS2xxx addressable string/strip. I know that’s an option, but I want to grok the shift registers for some other project ideas I have floating around.

Carefully consider this question… Will you ever want to light two or more LEDs simultaneously?

Why not a PIR?

I’m only really planning on using them because I have a few on hand. I figure once I get the hard part sorted I’ll worry about the trigger

I might eventually want it to do some kind of a wake up pattern that does some chase effect or something, maybe make it hunt a little before settling on each letter, but thats fluff I can worry about after I figure out how to switch them on one at a time.

So that’s a “yes”.

The Arduino API includes a useful function for outputting to shift registers: shiftOut. Have you tried it?

That’s a yes, unless it makes things significantly easier for it to be a no then I’m fine with that

I’ve been poking and prodding at shiftout and bitwise but not really getting it. The code in that example seems to be counting the binary equivalent from 1-256 and it echoes through the 3 registers as it goes.

I used TI’s TLC5916 to drive 2x 7 seg rgb led dsplys from Adafruit… (2x 3 in series)
http://www.ti.com/product/TLC5916
Advantages over '595 is more current sinking per chnl and a single resistor per ic for current limiting.
Cntlrs and clocking are similar to the '595 - so whatever code you come up with should work with it.
Have some ideas on how to “walk” through the leds to do a msg.

Well I figured out a way to do it without having to write 24+ individual digitalWrite statements it still seems kinda kludgy, but it does what I need to. If anyone has a better idea or can break down the bitwise/bitshift command down to bite sized pieces that my monkey brain can understand I’d appreciate it.

I always wanted to do this for Halloween on my garage door. My concept was to use a Raspberry Pi and link in a chat bot. Then you could ask it questions and get an answer.

2 Likes

I will need some time to refresh my memory, but I covered the 74HC595 in my Arduino multiplexing class many moons ago.

This is my slide deck: Multiplexing and Charlieplexing.ppt (36 KB)

This is my code: MultiplexShift.zip (672 Bytes)

And a couple of Fritzing files: Fritzing.zip (27.0 KB)

Edit: I’m sorry, I included the wrong Fritzing file. The 595 one was something I used to generate a pinout diagram for the class. The new zip is correct.

Forgive me if I’m off base here…

//Light up the letter given (lowercase only)
int lightLetter(char letter) {
    int letterIdx;
    uint32_t shiftOut = 0;

    letterIdx = (int)letter - 97; // ASCII 'a'=97
    if ((letterIdx < 0) || (letterIdx > 26)) {
        return E_BAD_LETTER;
    }
    shiftOut = 1 << idxLetter; // Put a one in the right place

    /* Unlatch (?) the output */
    // Actually I'm pretty sure this while loop is what shiftOut does
    // You can totally just use that instead. It's probably faster.
    for(int i = 0; i < 24; i++) {
        /* Do the clock stuff */
        digitalWrite(shiftOut & 0x1, OUTPUT_PIN);
        /* Do the other clock stuff */
        shiftOut = shiftOut >> 1;
    }
    /* Latch the output */

    digitalWrite(shiftOut & (1<<25), Y_PIN);
    digitalWrite(shiftOut & (1<<26), Z_PIN);
    
    return E_SUCCESS;
}

Of course you’ll have to stick your clock stuff in the write places.

So after banging my head on it for a while here is where I’m at. I currently have it running on an esp8266. It does what I want now, though I’m sure it could be better. I still have to add the distance or motion detector trigger to turn it on, but I’m pleased with the progress.

/*Adam Overman 8.16.2019 Stranger Things Wall Hanger code Currently running as expected 
 * I still need to add the activation sensor.
 * 
 */
 //Pin connected to ST_CP of 74HC595
int latchPin = 13;
//Pin connected to SH_CP of 74HC595
int clockPin = 15;
////Pin connected to DS of 74HC595
int dataPin = 12;
//Pin connected to Y
int LEDpiny = 5;
//Pin connected to 
int LEDpinz = 4;
void setup() {
  //set pins to output because they are addressed in the main loop
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
  pinMode(LEDpiny, OUTPUT);
  pinMode(LEDpinz, OUTPUT);
}
void loop() {
 int whichMessage = 0;
 whichMessage = random(1,3); 
 switch (whichMessage) {
  case 1:
    helloWorld();
    break;
  case 2:
    helpMe();
    break;
  case 3:
  itsSOdark();
 
    break;
} 

}
void helloWorld()
{ allLEDoff();
  allLEDon();
  allLEDoff(); 
  LEDh();
  LEDe();
  LEDl();
  allLEDoff();
  LEDl();
  LEDo();
  allLEDoff();
  allLEDon();
  allLEDoff();
  allLEDon();
  LEDw();
  LEDo();
  LEDr();
  LEDl();
  LEDd();
  allLEDoff();
  allLEDon();
  allLEDoff();}
void helpMe()
{allLEDoff();
  allLEDon();
  allLEDoff();
  LEDh();
  LEDe();
  LEDl();
  LEDp();
  allLEDoff();
  allLEDon();
  allLEDoff();
  allLEDon();
  LEDm();
  LEDe();
  allLEDoff();
  allLEDon();
  allLEDoff();}
void itsSOdark()
{allLEDoff();
  allLEDon();
  allLEDoff();
  LEDi();
  LEDt();
  LEDs();
  allLEDoff();
  allLEDon();
  allLEDoff();
  allLEDon();
  LEDs();
  LEDo();
  allLEDoff();
  allLEDon();
  allLEDoff();
  allLEDon(); 
  LEDd();
  LEDa();
  LEDr();
  LEDk();
  allLEDoff();
  allLEDon();
  allLEDoff();
  allLEDon();
  LEDh();
  LEDe();
  LEDr();
  LEDe();
  allLEDoff();
  allLEDon();
  allLEDoff();} 

//These are the functions that control the LEDs by shifting out 24 bits to the shift register and flipping the Y and Z pins  
void allLEDoff()
{digitalWrite(latchPin, LOW);
 shiftOut(dataPin, clockPin, MSBFIRST, B00000000);
 shiftOut(dataPin, clockPin, MSBFIRST, B00000000);
 shiftOut(dataPin, clockPin, MSBFIRST, B00000000);
 digitalWrite(latchPin, HIGH);
 digitalWrite(LEDpiny, LOW);
 digitalWrite(LEDpinz, LOW);
    delay(1500);}
 void allLEDon()
 {digitalWrite(latchPin, LOW);
 shiftOut(dataPin, clockPin, MSBFIRST, B11111111);
 shiftOut(dataPin, clockPin, MSBFIRST, B11111111);
 shiftOut(dataPin, clockPin, MSBFIRST, B11111111);
 digitalWrite(latchPin, HIGH);
 digitalWrite(LEDpiny,HIGH);
 digitalWrite(LEDpinz,HIGH);
 delay(1500);}
 
 void LEDa ()
 {digitalWrite(latchPin, LOW);
 shiftOut(dataPin, clockPin, MSBFIRST, B00000000);
 shiftOut(dataPin, clockPin, MSBFIRST, B00000000);
 shiftOut(dataPin, clockPin, MSBFIRST, B00000001);
 digitalWrite(latchPin, HIGH);
 digitalWrite(LEDpiny, LOW);
 digitalWrite(LEDpinz, LOW);
    delay(1500);}
    
 void LEDb ()
 {digitalWrite(latchPin, LOW);
 shiftOut(dataPin, clockPin, MSBFIRST, B00000000);
 shiftOut(dataPin, clockPin, MSBFIRST, B00000000);
 shiftOut(dataPin, clockPin, MSBFIRST, B00000010);
 digitalWrite(latchPin, HIGH);
 digitalWrite(LEDpiny, LOW);
 digitalWrite(LEDpinz, LOW);
    delay(1500);}
    
  void LEDc ()
 {digitalWrite(latchPin, LOW);
 shiftOut(dataPin, clockPin, MSBFIRST, B00000000);
 shiftOut(dataPin, clockPin, MSBFIRST, B00000000);
 shiftOut(dataPin, clockPin, MSBFIRST, B00000100);
 digitalWrite(latchPin, HIGH);
 digitalWrite(LEDpiny, LOW);
 digitalWrite(LEDpinz, LOW);
    delay(1500);}
  void LEDd ()
 {digitalWrite(latchPin, LOW);
 shiftOut(dataPin, clockPin, MSBFIRST, B00000000);
 shiftOut(dataPin, clockPin, MSBFIRST, B00000000);
 shiftOut(dataPin, clockPin, MSBFIRST, B00001000);
 digitalWrite(latchPin, HIGH);
 digitalWrite(LEDpiny, LOW);
 digitalWrite(LEDpinz, LOW);
    delay(1500);}
   void LEDe ()
 {digitalWrite(latchPin, LOW);
 shiftOut(dataPin, clockPin, MSBFIRST, B00000000);
 shiftOut(dataPin, clockPin, MSBFIRST, B00000000);
 shiftOut(dataPin, clockPin, MSBFIRST, B00010000);
 digitalWrite(latchPin, HIGH);
 digitalWrite(LEDpiny, LOW);
 digitalWrite(LEDpinz, LOW);
    delay(1500);}
   void LEDf ()
 {digitalWrite(latchPin, LOW);
 shiftOut(dataPin, clockPin, MSBFIRST, B00000000);
 shiftOut(dataPin, clockPin, MSBFIRST, B00000000);
 shiftOut(dataPin, clockPin, MSBFIRST, B00100000);
 digitalWrite(latchPin, HIGH);
 digitalWrite(LEDpiny, LOW);
 digitalWrite(LEDpinz, LOW);
    delay(1500);}
   void LEDg ()
 {digitalWrite(latchPin, LOW);
 shiftOut(dataPin, clockPin, MSBFIRST, B00000000);
 shiftOut(dataPin, clockPin, MSBFIRST, B00000000);
 shiftOut(dataPin, clockPin, MSBFIRST, B01000000);
 digitalWrite(latchPin, HIGH);
 digitalWrite(LEDpiny, LOW);
 digitalWrite(LEDpinz, LOW);
    delay(1500);}
   void LEDh ()
 {digitalWrite(latchPin, LOW);
 shiftOut(dataPin, clockPin, MSBFIRST, B00000000);
 shiftOut(dataPin, clockPin, MSBFIRST, B00000000);
 shiftOut(dataPin, clockPin, MSBFIRST, B10000000);
 digitalWrite(latchPin, HIGH);
 digitalWrite(LEDpiny, LOW);
 digitalWrite(LEDpinz, LOW);
    delay(1500);}
   void LEDi ()
 {digitalWrite(latchPin, LOW);
 shiftOut(dataPin, clockPin, MSBFIRST, B00000000);
 shiftOut(dataPin, clockPin, MSBFIRST, B00000001);
 shiftOut(dataPin, clockPin, MSBFIRST, B00000000);
 digitalWrite(latchPin, HIGH);
 digitalWrite(LEDpiny, LOW);
 digitalWrite(LEDpinz, LOW);
    delay(1500);}
   void LEDj ()
 {digitalWrite(latchPin, LOW);
 shiftOut(dataPin, clockPin, MSBFIRST, B00000000);
 shiftOut(dataPin, clockPin, MSBFIRST, B00000010);
 shiftOut(dataPin, clockPin, MSBFIRST, B00000000);
 digitalWrite(latchPin, HIGH);
 digitalWrite(LEDpiny, LOW);
 digitalWrite(LEDpinz, LOW);
    delay(1500);}
   void LEDk ()
 {digitalWrite(latchPin, LOW);
 shiftOut(dataPin, clockPin, MSBFIRST, B00000000);
 shiftOut(dataPin, clockPin, MSBFIRST, B00000100);
 shiftOut(dataPin, clockPin, MSBFIRST, B00000000);
 digitalWrite(latchPin, HIGH);
 digitalWrite(LEDpiny, LOW);
 digitalWrite(LEDpinz, LOW);
    delay(1500);}
   void LEDl ()
 {digitalWrite(latchPin, LOW);
 shiftOut(dataPin, clockPin, MSBFIRST, B00000000);
 shiftOut(dataPin, clockPin, MSBFIRST, B00001000);
 shiftOut(dataPin, clockPin, MSBFIRST, B00000000);
 digitalWrite(latchPin, HIGH);
 digitalWrite(LEDpiny, LOW);
 digitalWrite(LEDpinz, LOW);
    delay(1500);}
   void LEDm ()
 {digitalWrite(latchPin, LOW);
 shiftOut(dataPin, clockPin, MSBFIRST, B00000000);
 shiftOut(dataPin, clockPin, MSBFIRST, B00010000);
 shiftOut(dataPin, clockPin, MSBFIRST, B00000000);
 digitalWrite(latchPin, HIGH);
 digitalWrite(LEDpiny, LOW);
 digitalWrite(LEDpinz, LOW);
    delay(1500);}
   void LEDn ()
 {digitalWrite(latchPin, LOW);
 shiftOut(dataPin, clockPin, MSBFIRST, B00000000);
 shiftOut(dataPin, clockPin, MSBFIRST, B00100000);
 shiftOut(dataPin, clockPin, MSBFIRST, B00000000);
 digitalWrite(latchPin, HIGH);
 digitalWrite(LEDpiny, LOW);
 digitalWrite(LEDpinz, LOW);
    delay(1500);}
   void LEDo ()
 {digitalWrite(latchPin, LOW);
 shiftOut(dataPin, clockPin, MSBFIRST, B00000000);
 shiftOut(dataPin, clockPin, MSBFIRST, B01000000);
 shiftOut(dataPin, clockPin, MSBFIRST, B00000000);
 digitalWrite(latchPin, HIGH);
 digitalWrite(LEDpiny, LOW);
 digitalWrite(LEDpinz, LOW);
    delay(1500);}
   void LEDp ()
 {digitalWrite(latchPin, LOW);
 shiftOut(dataPin, clockPin, MSBFIRST, B00000000);
 shiftOut(dataPin, clockPin, MSBFIRST, B10000000);
 shiftOut(dataPin, clockPin, MSBFIRST, B00000000);
 digitalWrite(latchPin, HIGH);
 digitalWrite(LEDpiny, LOW);
 digitalWrite(LEDpinz, LOW);
    delay(1500);}
   void LEDq ()
 {digitalWrite(latchPin, LOW);
 shiftOut(dataPin, clockPin, MSBFIRST, B00000001);
 shiftOut(dataPin, clockPin, MSBFIRST, B00000000);
 shiftOut(dataPin, clockPin, MSBFIRST, B00000000);
 digitalWrite(latchPin, HIGH);
 digitalWrite(LEDpiny, LOW);
 digitalWrite(LEDpinz, LOW);
    delay(1500);}
   void LEDr ()
 {digitalWrite(latchPin, LOW);
 shiftOut(dataPin, clockPin, MSBFIRST, B00000010);
 shiftOut(dataPin, clockPin, MSBFIRST, B00000000);
 shiftOut(dataPin, clockPin, MSBFIRST, B00000000);
 digitalWrite(latchPin, HIGH);
 digitalWrite(LEDpiny, LOW);
 digitalWrite(LEDpinz, LOW);
    delay(1500);}
   void LEDs ()
 {digitalWrite(latchPin, LOW);
 shiftOut(dataPin, clockPin, MSBFIRST, B00000100);
 shiftOut(dataPin, clockPin, MSBFIRST, B00000000);
 shiftOut(dataPin, clockPin, MSBFIRST, B00000000);
 digitalWrite(latchPin, HIGH);
 digitalWrite(LEDpiny, LOW);
 digitalWrite(LEDpinz, LOW);
    delay(1500);}
   void LEDt ()
 {digitalWrite(latchPin, LOW);
 shiftOut(dataPin, clockPin, MSBFIRST, B00001000);
 shiftOut(dataPin, clockPin, MSBFIRST, B00000000);
 shiftOut(dataPin, clockPin, MSBFIRST, B00000000);
 digitalWrite(latchPin, HIGH);
 digitalWrite(LEDpiny, LOW);
 digitalWrite(LEDpinz, LOW);
    delay(1500);}
   void LEDu ()
 {digitalWrite(latchPin, LOW);
 shiftOut(dataPin, clockPin, MSBFIRST, B00010000);
 shiftOut(dataPin, clockPin, MSBFIRST, B00000000);
 shiftOut(dataPin, clockPin, MSBFIRST, B00000000);
 digitalWrite(latchPin, HIGH);
 digitalWrite(LEDpiny, LOW);
 digitalWrite(LEDpinz, LOW);
    delay(1500);}
   void LEDv ()
 {digitalWrite(latchPin, LOW);
 shiftOut(dataPin, clockPin, MSBFIRST, B00100000);
 shiftOut(dataPin, clockPin, MSBFIRST, B00000000);
 shiftOut(dataPin, clockPin, MSBFIRST, B00000000);
 digitalWrite(latchPin, HIGH);
 digitalWrite(LEDpiny, LOW);
 digitalWrite(LEDpinz, LOW);
    delay(1500);}
   void LEDw ()
 {digitalWrite(latchPin, LOW);
 shiftOut(dataPin, clockPin, MSBFIRST, B01000000);
 shiftOut(dataPin, clockPin, MSBFIRST, B00000000);
 shiftOut(dataPin, clockPin, MSBFIRST, B00000000);
 digitalWrite(latchPin, HIGH);
 digitalWrite(LEDpiny, LOW);
 digitalWrite(LEDpinz, LOW);
    delay(1500);}
   void LEDx ()
 {digitalWrite(latchPin, LOW);
 shiftOut(dataPin, clockPin, MSBFIRST, B10000000);
 shiftOut(dataPin, clockPin, MSBFIRST, B00000000);
 shiftOut(dataPin, clockPin, MSBFIRST, B00000000);
 digitalWrite(latchPin, HIGH);
 digitalWrite(LEDpiny, LOW);
 digitalWrite(LEDpinz, LOW);
    delay(1500);}
void LEDy ()
 {digitalWrite(latchPin, LOW);
 shiftOut(dataPin, clockPin, MSBFIRST, B00000000);
 shiftOut(dataPin, clockPin, MSBFIRST, B00000000);
 shiftOut(dataPin, clockPin, MSBFIRST, B00000000);
 digitalWrite(latchPin, HIGH);
 digitalWrite(LEDpiny, HIGH);
 digitalWrite(LEDpinz, LOW);
    delay(1500);}
   void LEDz ()
 {digitalWrite(latchPin, LOW);
 shiftOut(dataPin, clockPin, MSBFIRST, B00000000);
 shiftOut(dataPin, clockPin, MSBFIRST, B00000000);
 shiftOut(dataPin, clockPin, MSBFIRST, B00000000);
 digitalWrite(latchPin, HIGH);
 digitalWrite(LEDpiny, LOW);
 digitalWrite(LEDpinz, HIGH);
    delay(1500);}
    
1 Like