I needed to take a break from working on my hexapod. So I decided to go back to basics, blinking leds 😀 The first Arduino sketch most people try out must be the blink example sketch. It blinks one led, and uses only one pin. If you want to blink lots of leds you might run out of pins. You could of course use an Arduino Mega which has a lot of pins. But there are cheaper options. Like the 74HC595 shift register. I bought a dozen from Tayda Electronics, they only cost $0.20 a piece. The 74HC595 is an 8-bit serial-in, serial or parallel-out shift register with output latches.
That description sounds very complex. But a lot of information can be found on the internet about interfacing the 74HC595 with Arduino. The chip needs only needs 3 pins, in return you get 8 outputs. I tried some different sketches that I found online to try and understand how the chip works. The following sites I found the most useful:
Adafruit lesson on the 74HC595
Bildr 74HC595 tutorial
Arduino shiftout function
My goal was to blink 16 leds nightrider style. I used 2 74HC595 shift registers and 16 leds with 220ohm resistors. As I wanted to integrate the code in an other sketch I used the millis function to time the shifting of the leds. This is the result:
This is the code I used:
// http://www.bajdi.com // Nightrider effect using 16 leds and 2 74HC595 shift registers //Pin connected to Pin 12 of 74HC595 (Latch) int latchPin = 8; //Pin connected to Pin 11 of 74HC595 (Clock) int clockPin = 12; //Pin connected to Pin 14 of 74HC595 (Data) int dataPin = 11; //data for LED on. Second shift register will be written first. int ledOn2[]={ 1,2,4,8,16,32,64,128,0,0,0,0, 0, 0, 0, 0, 0, 0, 0,0,0,0,0,128,64,32,16,8,4,2,1}; int ledOn1[]={ 0,0,0,0, 0, 0, 0, 0,1,2,4,8,16,32,64,128,64,32,16,8,4,2,1, 0, 0, 0, 0,0,0,0,0}; byte nextLed; unsigned long Timer; void setup() { pinMode(latchPin, OUTPUT); pinMode(clockPin, OUTPUT); pinMode(dataPin, OUTPUT); } void loop() { unsigned long ledMillis = millis(); if (ledMillis >= Timer){ Timer = Timer+50; nextLed = nextLed +1; digitalWrite(latchPin, LOW); shiftOut(ledOn2[nextLed]); shiftOut(ledOn1[nextLed]); //set latchPin to high to lock and send data digitalWrite(latchPin, HIGH); if (nextLed == 30){ nextLed = 0; } } } void shiftOut(byte dataOut) { // Shift out 8 bits LSB first, // on rising edge of clock boolean pinState; //clear shift register ready for sending data digitalWrite(dataPin, LOW); digitalWrite(clockPin, LOW); // for each bit in dataOut send out a bit for (int i=0; i<=7; i++) { //set clockPin to LOW prior to sending bit digitalWrite(clockPin, LOW); // if the value of DataOut and (logical AND) a bitmask // are true, set pinState to 1 (HIGH) if ( dataOut & (1<<i) ) { pinState = HIGH; } else { pinState = LOW; } //sets dataPin to HIGH or LOW depending on pinState digitalWrite(dataPin, pinState); //send bit out on rising edge of clock digitalWrite(clockPin, HIGH); } //stop shifting out data digitalWrite(clockPin, LOW); }
thank you…I’ve been scratching my head using millis() with shift register…I was using for loop but then I see you use array and suddenly I understand…
Thanks again!
one of the rare examples using millis, thanks a lot.