Built-in project · Arduino Uno R3

Falling rain on eight LEDs (74HC595, pins 11, 12 and 13), on an Arduino Uno

Eight LEDs on a 74HC595 (DS 11, ST_CP 12, SH_CP 13) show a drop of light with a fading tail running along them, the brightness of each made by the sketch switching it on for part of every cycle. The whole build, an Arduino Uno and 17 more parts, runs here in your browser on the firmware below; open it in the editor to change the wiring or the code and run it again.

Teaching? Assign it to your class in one click.

Intermediate About 25 minutes to build and run. Runs in your browser. Free, and no account needed.

The parts retail for about $34. On Mokxi they're free.

The circuit runs here once the page has loaded.

What you'll learn

  • Driving eight LEDs from three pins
  • Software PWM: faking brightness by switching fast
  • Using a lookup table to shape an animation
  • Moving a window over a table to create motion
  • Difficulty: Intermediate
  • Time: About 25 minutes
  • Board: Arduino Uno R3
  • Parts: 19

How it works

Eight LEDs, each with a 220 ohm resistor, hang off the outputs of a 74HC595 shift register. The Uno drives it with just three pins: data on 11, latch on 12 and clock on 13.

The chip cannot dim LEDs, so the sketch fakes it. It repeats a pass of 64 steps, and an LED is on for only as many steps as its brightness value. Your eye averages that into a dim or bright glow. A table holds a bright head followed by a fading tail, and a window slides along it so the drop seems to fall down the row.

Parts list

19 parts, plus the jumper wires. They retail for about $34; on Mokxi they're free.

Wiring table

Every connection, pin by pin, read from the circuit itself. Each row joins the pin on the left to the pin on the right, by a jumper wire or a breadboard strip.

Part and pinConnects to
74HC595 shift register pin GNDArduino Uno R3 pin GND
74HC595 shift register pin OEArduino Uno R3 pin GND
LED, red (1) pin CArduino Uno R3 pin GND
LED, red (2) pin CArduino Uno R3 pin GND
LED, red (3) pin CArduino Uno R3 pin GND
LED, red (4) pin CArduino Uno R3 pin GND
LED, red (5) pin CArduino Uno R3 pin GND
LED, red (6) pin CArduino Uno R3 pin GND
LED, red (7) pin CArduino Uno R3 pin GND
LED, red (8) pin CArduino Uno R3 pin GND
74HC595 shift register pin SHCPArduino Uno R3 pin 13
74HC595 shift register pin STCPArduino Uno R3 pin 12
74HC595 shift register pin DSArduino Uno R3 pin 11
74HC595 shift register pin MRArduino Uno R3 pin 5V
74HC595 shift register pin VCCArduino Uno R3 pin 5V
Resistor, 220 Ω (2) pin 174HC595 shift register pin Q1
Resistor, 220 Ω (3) pin 174HC595 shift register pin Q2
Resistor, 220 Ω (4) pin 174HC595 shift register pin Q3
Resistor, 220 Ω (5) pin 174HC595 shift register pin Q4
Resistor, 220 Ω (6) pin 174HC595 shift register pin Q5
Resistor, 220 Ω (7) pin 174HC595 shift register pin Q6
Resistor, 220 Ω (8) pin 174HC595 shift register pin Q7
Resistor, 220 Ω (1) pin 174HC595 shift register pin Q0
LED, red (1) pin AResistor, 220 Ω (1) pin 2
LED, red (2) pin AResistor, 220 Ω (2) pin 2
LED, red (3) pin AResistor, 220 Ω (3) pin 2
LED, red (4) pin AResistor, 220 Ω (4) pin 2
LED, red (5) pin AResistor, 220 Ω (5) pin 2
LED, red (6) pin AResistor, 220 Ω (6) pin 2
LED, red (7) pin AResistor, 220 Ω (7) pin 2
LED, red (8) pin AResistor, 220 Ω (8) pin 2

The code

The firmware exactly as the editor opens it. Change a line there and press Run: it compiles in the browser.

sketch.ino · Arduino Uno R3
// Falling rain: a drop of light with a fading tail runs along eight LEDs.
//
//   74HC595 DS -> pin 11   ST_CP -> pin 12   SH_CP -> pin 13
//   VCC and MR -> 5V   OE and GND -> GND   Q0..Q7 -> 220 ohm -> LEDs -> GND
//
// The 74HC595 has no PWM, so the sketch makes its own: each pass of 64 steps
// switches an LED on for as many steps as its brightness in TAIL, and the
// eye averages it. Sliding the window over TAIL moves the drop along.

const int LATCH = 12;  // ST_CP
const int CLOCK = 13;  // SH_CP
const int DATA = 11;   // DS

void write595(byte value, int order) {
  digitalWrite(LATCH, LOW);
  shiftOut(DATA, CLOCK, order, value);
  digitalWrite(LATCH, HIGH);
}

const byte TAIL[24] = {0, 0, 0, 0, 0, 0, 0, 0, 64, 48, 32, 16, 8, 4, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0};

void setup() {
  pinMode(LATCH, OUTPUT);
  pinMode(CLOCK, OUTPUT);
  pinMode(DATA, OUTPUT);
  Serial.begin(9600);
  Serial.println("Mokxi Uno: falling rain on a 74HC595 (11, 12 and 13)");
}

void loop() {
  static byte offset = 0;
  static unsigned int frames = 0;
  if (frames++ % 8 == 0) offset = offset < 15 ? offset + 1 : 0;
  for (int step = 0; step < 64; step++) {
    byte bits = 0;
    for (int j = 0; j < 8; j++) {
      if (step < TAIL[j + offset]) bits |= 1 << j;
    }
    write595(bits, MSBFIRST);
  }
}

Code walkthrough

The key functions of the sketch, and what each one does.

write595 sketch.ino

Sends one byte to the chip. It pulls the latch LOW, calls shiftOut with the bit order given, and raises the latch HIGH so the eight outputs update together.

void write595(byte value, int order) {
  digitalWrite(LATCH, LOW);
  shiftOut(DATA, CLOCK, order, value);
  digitalWrite(LATCH, HIGH);
}

setup sketch.ino

Makes the latch, clock and data pins outputs and opens serial at 9600.

void setup() {
  pinMode(LATCH, OUTPUT);
  pinMode(CLOCK, OUTPUT);
  pinMode(DATA, OUTPUT);
  Serial.begin(9600);
  Serial.println("Mokxi Uno: falling rain on a 74HC595 (11, 12 and 13)");
}

loop sketch.ino

Every 8 passes, offset moves the window one place along TAIL (it wraps after 15). For each of the 64 steps, it builds a byte: LED j is on if the step number is below TAIL[j + offset]. A big table value means a bright LED. It then sends that byte, so the loop is really fast on/off switching.

void loop() {
  static byte offset = 0;
  static unsigned int frames = 0;
  if (frames++ % 8 == 0) offset = offset < 15 ? offset + 1 : 0;
  for (int step = 0; step < 64; step++) {
    byte bits = 0;
    for (int j = 0; j < 8; j++) {
      if (step < TAIL[j + offset]) bits |= 1 << j;
    }
    write595(bits, MSBFIRST);
  }
}

Troubleshooting

The usual mistakes with this circuit, and the fix for each.

  • The LEDs flicker visibly or look dim. This project
    Some flicker and softness is normal here, since the Uno does the dimming in software and also sends each byte slowly. Do not add delays to the loop.
  • Nothing lights. This project
    Check the pin order: DS goes to 11, STCP (latch) to 12 and SHCP (clock) to 13. OE goes to GND and MR to 5V.
  • Outputs show garbage, or the register never clears. 74HC595 shift register
    Tie OE low and SRCLR (pin 10) high. Left floating, these pins make the chip behave randomly. Then pulse the latch pin after shifting the byte.
  • The bits come out in the wrong order, or LEDs are dim. 74HC595 shift register
    Choose MSBFIRST or LSBFIRST in shiftOut to flip the order. Give each LED its own resistor, since each output can source only about 6 mA safely.
  • The LED is dim, burns out, or the pin reads wrong because the resistor value is off. Resistor
    Read the color bands again. A 220 ohm to 330 ohm resistor suits a typical LED on 5 V. 10k is a common pull-up or pull-down value. Check with a multimeter if unsure.
  • A pull-up or pull-down resistor is missing, so the input floats and reads random values. Resistor
    Tie the input to 5 V or ground through about 10k. Or use INPUT_PULLUP and wire the switch to ground.
  • The LED does not light, or it lights once and then dies. LED
    LEDs have polarity. The longer leg (anode) goes toward the positive side. Always add a series resistor, about 220 ohms to 1 k ohm on a 5 V pin.
  • A blue or white LED stays dark on 3.3 V. LED
    Blue and white LEDs drop about 3 V, so 3.3 V leaves almost nothing for the resistor. Use a 5 V supply, or a smaller resistor and a red or green LED.

Change it and keep it

Open it in the editor, change the circuit or the code, and keep your version in a free account.