Daniel JablonskiPedro Mendez
Published © GPL3+

Interactive LED Name

Name on a box that lights up and has three different patterns that provide a cool light show.

IntermediateFull instructions provided10 hours6,649
Interactive LED Name

Things used in this project

Hardware components

Arduino UNO
Arduino UNO
×1
Slide Switch
Slide Switch
×1
LED (generic)
LED (generic)
×36
SparkFun Rocker Switch
×1
SparkFun Potentiometer
×2
SparkFun Toggle Switch
×1
SparkFun Button
×1
SparkFun Shift Register - SN74HC595
×5
SparkFun Triple Axis Accelerometer Breakout - LIS3DH
SparkFun Triple Axis Accelerometer Breakout - LIS3DH
×1
SparkFun Piezo Alarm
×1
Breadboard (generic)
Breadboard (generic)
×2
Resistor 330 ohm
Resistor 330 ohm
×36

Software apps and online services

Arduino IDE
Arduino IDE

Hand tools and fabrication machines

Laser cutter (generic)
Laser cutter (generic)
Soldering iron (generic)
Soldering iron (generic)

Story

Read more

Custom parts and enclosures

Interactive LED Box

This is the enclosure file cut on wood using a laser cutter

Schematics

Wiring Diagram for Shift Registers

Code

Interactive LED Name

Arduino
This code runs certain light patterns depending on which button/switch is clicked/flipped.
#include <SoftReset.h>

#include <SparkFunLIS3DH.h>


#include <Wire.h>
#include <SPI.h>

//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 j = 0;
int mode = 0;
int blinkBtn = 4;
int waveBtn = 2;
int loopBtn = 3;
int masterSwitch = 5;
int blinkBtnState, waveBtnState, loopBtnState, masterState;
int speedPot = A0;
int speedValue = 0;
int master = 0;
int buzzer = 9;
LIS3DH myIMU;
int reset = 6;
//holders for infromation you're going to pass to shifting function
byte waveOne, waveTwo, waveThree, waveFour, waveFive, loopOne, loopTwo, loopThree, loopFour, loopFive;
byte waveDataOne[16], waveDataTwo[16], waveDataThree[16], waveDataFour[16], waveDataFive[16];
byte loopDataOne[10], loopDataTwo[10], loopDataThree[10], loopDataFour[10], loopDataFive[10];


void setup() {
  digitalWrite(reset, HIGH);
  delay(200);
  pinMode(reset, OUTPUT);

  //set pins to output because they are addressed in the main loop
  pinMode(latchPin, OUTPUT);
  pinMode(blinkBtn, INPUT_PULLUP);
  pinMode(waveBtn, INPUT_PULLUP);
  pinMode(loopBtn, INPUT_PULLUP);
  pinMode(buzzer, OUTPUT);
  pinMode(masterSwitch, INPUT_PULLUP);
  myIMU.begin();
  Serial.begin(9600);
  MCUSR = 0;
  loopDataOne[0] = 1;
  loopDataOne[1] = 3;
  loopDataOne[2] = 6;
  loopDataOne[3] = 12;
  loopDataOne[4] = 24;
  loopDataOne[5] = 48;
  loopDataOne[6] = 96;
  loopDataOne[7] = 192;
  loopDataOne[8] = 128;
  loopDataOne[9] = 0;

  loopDataTwo[0] = 2;
  loopDataTwo[1] = 6;
  loopDataTwo[2] = 12;
  loopDataTwo[3] = 24;
  loopDataTwo[4] = 48;
  loopDataTwo[5] = 96;
  loopDataTwo[6] = 192;
  loopDataTwo[7] = 128;
  loopDataTwo[8] = 1;
  loopDataTwo[9] = 1;

  loopDataThree[0] = 8;
  loopDataThree[1] = 24;
  loopDataThree[2] = 48;
  loopDataThree[3] = 96;
  loopDataThree[4] = 192;
  loopDataThree[5] = 128;
  loopDataThree[6] = 0;
  loopDataThree[7] = 1;
  loopDataThree[8] = 3;
  loopDataThree[9] = 6;

  loopDataFour[0] = 4;
  loopDataFour[1] = 12;
  loopDataFour[2] = 24;
  loopDataFour[3] = 48;
  loopDataFour[4] = 224;
  loopDataFour[5] = 193;
  loopDataFour[6] = 3;
  loopDataFour[7] = 2;
  loopDataFour[8] = 2;
  loopDataFour[9] = 2;

  loopDataFive[0] = 0;
  loopDataFive[1] = 0;
  loopDataFive[2] = 0;
  loopDataFive[3] = 0;
  loopDataFive[4] = 0;
  loopDataFive[5] = 1;
  loopDataFive[6] = 3;
  loopDataFive[7] = 6;
  loopDataFive[8] = 12;
  loopDataFive[9] = 8;

  waveDataOne[0] = 56;
  waveDataOne[1] = 124;
  waveDataOne[2] = 198;
  waveDataOne[3] = 131;
  waveDataOne[4] = 1;
  waveDataOne[5] = 0;
  waveDataOne[6] = 0;
  waveDataOne[7] = 0;
  waveDataOne[8] = 0;
  waveDataOne[9] = 0;
  waveDataOne[10] = 0;
  waveDataOne[11] = 0;
  waveDataOne[12] = 0;
  waveDataOne[13] = 0;
  waveDataOne[14] = 0;
  waveDataOne[15] = 0;

  waveDataTwo[0] = 0;
  waveDataTwo[1] = 0;
  waveDataTwo[2] = 0;
  waveDataTwo[3] = 1;
  waveDataTwo[4] = 25;
  waveDataTwo[5] = 60;
  waveDataTwo[6] = 102;
  waveDataTwo[7] = 194;
  waveDataTwo[8] = 128;
  waveDataTwo[9] = 0;
  waveDataTwo[10] = 0;
  waveDataTwo[11] = 0;
  waveDataTwo[12] = 0;
  waveDataTwo[13] = 0;
  waveDataTwo[14] = 0;
  waveDataTwo[15] = 0;

  waveDataThree[0] = 0;
  waveDataThree[1] = 0;
  waveDataThree[2] = 0;
  waveDataThree[3] = 0;
  waveDataThree[4] = 0;
  waveDataThree[5] = 0;
  waveDataThree[6] = 0;
  waveDataThree[7] = 4;
  waveDataThree[8] = 7;
  waveDataThree[9] = 251;
  waveDataThree[10] = 248;
  waveDataThree[11] = 0;
  waveDataThree[12] = 0;
  waveDataThree[13] = 0;
  waveDataThree[14] = 0;
  waveDataThree[15] = 0;

  waveDataFour[0] = 0;
  waveDataFour[1] = 0;
  waveDataFour[2] = 0;
  waveDataFour[3] = 0;
  waveDataFour[4] = 0;
  waveDataFour[5] = 0;
  waveDataFour[6] = 0;
  waveDataFour[7] = 0;
  waveDataFour[8] = 0;
  waveDataFour[9] = 0;
  waveDataFour[10] = 1;
  waveDataFour[11] = 3;
  waveDataFour[12] = 114;
  waveDataFour[13] = 248;
  waveDataFour[14] = 140;
  waveDataFour[15] = 4;

  waveDataFive[0] = 0;
  waveDataFive[1] = 0;
  waveDataFive[2] = 0;
  waveDataFive[3] = 0;
  waveDataFive[4] = 0;
  waveDataFive[5] = 0;
  waveDataFive[6] = 0;
  waveDataFive[7] = 0;
  waveDataFive[8] = 0;
  waveDataFive[9] = 0;
  waveDataFive[10] = 0;
  waveDataFive[11] = 0;
  waveDataFive[12] = 3;
  waveDataFive[13] = 4;
  waveDataFive[14] = 12;
  waveDataFive[15] = 8;
}

void loop() {
  //Read button states and analog value
  blinkBtnState = digitalRead(blinkBtn);
  waveBtnState = digitalRead(waveBtn);
  loopBtnState = digitalRead(loopBtn);
  masterState = digitalRead(masterSwitch);
  speedValue = analogRead(speedPot);
  
  speedValue = speedValue / 3;
  Serial.println(speedValue);
  //Prevents lights from flashing too fast to avoid epilepsy
  if(speedValue < 30)
    speedValue = 30;

  //Checks if button is clicked and then changes mode appropriately
  if(masterState == LOW)
  {
    master = 1;
  }
  else
  {
    master = 0;
    turnOff();
    digitalWrite(reset, LOW); 
  }
  if(blinkBtnState == LOW)
  {
    mode = 1;
  }
  if(waveBtnState == LOW)
  {
    mode = 2;
  }
  if(loopBtnState == LOW)
  {
    mode = 3;
  }

  //Beeps at a certain frequency when enclosure is rotated too much
  if(myIMU.readFloatAccelX() > 0.5 || myIMU.readFloatAccelX() < -0.5 || myIMU.readFloatAccelY() > 0.5 || myIMU.readFloatAccelY() < -0.5)
  {
    tone(buzzer,350,100);
  }

  //Runs led modes based on current mode
  if(mode == 1 && master == 1)
  {
    if(speedValue < 150)
      speedValue = 150;
    blinkLeds(speedValue);
  }
  if(mode == 2 && master == 1)
  {
    colorWave(speedValue);
  }
  if(mode == 3 && master == 1)
  {
    loopLetters(speedValue);
  }
}

//LEDs light up by columns, two at a time from left to right
void colorWave(int d)
{
    if(j==16)
      j=0;
    waveOne = waveDataOne[j];
    waveTwo = waveDataTwo[j];
    waveThree = waveDataThree[j];
    waveFour = waveDataFour[j];
    waveFive = waveDataFive[j];
    //ground latchPin and hold low for as long as you are transmitting
    digitalWrite(latchPin, 0);
    //move 'em out
    shiftOut(dataPin, clockPin, waveFive);
    shiftOut(dataPin, clockPin, waveFour);
    shiftOut(dataPin, clockPin, waveThree);
    shiftOut(dataPin, clockPin, waveTwo);
    shiftOut(dataPin, clockPin, waveOne);
    //return the latch pin high to signal chip that it 
    //no longer needs to listen for information
    digitalWrite(latchPin, 1);
    j++;
    delay(d);
}

//LEDs make a trail and loop each letter individually
void loopLetters(int d)
{
  if(j==10)
      j=0;
    loopOne = loopDataOne[j];
    loopTwo = loopDataTwo[j];
    loopThree = loopDataThree[j];
    loopFour = loopDataFour[j];
    loopFive = loopDataFive[j];
    //ground latchPin and hold low for as long as you are transmitting
    digitalWrite(latchPin, 0);
    //move 'em out
    shiftOut(dataPin, clockPin, loopFive);
    shiftOut(dataPin, clockPin, loopFour);
    shiftOut(dataPin, clockPin, loopThree);
    shiftOut(dataPin, clockPin, loopTwo);
    shiftOut(dataPin, clockPin, loopOne);
    //return the latch pin high to signal chip that it 
    //no longer needs to listen for information
    digitalWrite(latchPin, 1);
    j++;
    delay(d);
}

void turnOff()
{
  digitalWrite(latchPin, 0);
  shiftOut(dataPin, clockPin, 0);
  shiftOut(dataPin, clockPin, 0);
  shiftOut(dataPin, clockPin, 0);
  shiftOut(dataPin, clockPin, 0);
  shiftOut(dataPin, clockPin, 0);
  digitalWrite(latchPin, 1);
}

//blinks the whole register based on the number of times you want to 
//blink "n" and the pause between them "d"
//starts with a moment of darkness to make sure the first blink
//has its full visual effect.
void blinkLeds(int d) 
{
  digitalWrite(latchPin, 0);
  shiftOut(dataPin, clockPin, 255);
  shiftOut(dataPin, clockPin, 255);
  shiftOut(dataPin, clockPin, 255);
  shiftOut(dataPin, clockPin, 255);
  shiftOut(dataPin, clockPin, 255);
  digitalWrite(latchPin, 1);
  delay(d);
  digitalWrite(latchPin, 0);
  shiftOut(dataPin, clockPin, 0);
  shiftOut(dataPin, clockPin, 0);
  shiftOut(dataPin, clockPin, 0);
  shiftOut(dataPin, clockPin, 0);
  shiftOut(dataPin, clockPin, 0);
  digitalWrite(latchPin, 1);
  delay(d);
}

// the heart of the program
void shiftOut(int myDataPin, int myClockPin, byte myDataOut) 
{
  // This shifts 8 bits out MSB first, 
  //on the rising edge of the clock,
  //clock idles low

  //internal function setup
  int i=0;
  int pinState;
  pinMode(myClockPin, OUTPUT);
  pinMode(myDataPin, OUTPUT);

  //clear everything out just in case to
  //prepare shift register for bit shifting
  digitalWrite(myDataPin, 0);
  digitalWrite(myClockPin, 0);

  //for each bit in the byte myDataOut�
  //NOTICE THAT WE ARE COUNTING DOWN in our for loop
  //This means that %00000001 or "1" will go through such
  //that it will be pin Q0 that lights. 
  for (i=7; i>=0; i--)  
  {
    digitalWrite(myClockPin, 0);

    //if the value passed to myDataOut and a bitmask result 
    // true then... so if we are at i=6 and our value is
    // %11010100 it would the code compares it to %01000000 
    // and proceeds to set pinState to 1.
    if ( myDataOut & (1<<i) ) 
    {
      pinState= 1;
    }
    else 
    {  
      pinState= 0;
    }

    //Sets the pin to HIGH or LOW depending on pinState
    digitalWrite(myDataPin, pinState);
    //register shifts bits on upstroke of clock pin  
    digitalWrite(myClockPin, 1);
    //zero the data pin after shift to prevent bleed through
    digitalWrite(myDataPin, 0);
  }
  //stop shifting
  digitalWrite(myClockPin, 0);
} 

Credits

Daniel Jablonski

Daniel Jablonski

2 projects • 8 followers
Pedro Mendez

Pedro Mendez

2 projects • 2 followers
Thanks to Henlij.

Comments