Built-in project · Arduino Uno R3

Hatching chick on an Arduino Uno

An egg on an 8x8 MAX7219 matrix wobbles, cracks three times and hatches into a chick that blinks and peeps on a piezo. A button taps the shell to help it along. The whole build, an Arduino Uno and 3 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.

Beginner Runs in your browser. Free, and no account needed.

Hatching chick · Arduino Uno R3live0.000 s 0.00x
Press the button to tap the shell
The circuit itself, running here on the simulator. Press what can be pressed; click anything else to open it in the editor.

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
// Hatching chick: an egg on an 8x8 LED matrix wobbles, cracks and hatches
// into a chick that blinks and peeps. Tap the button to help it along.
//
//   MAX7219   8x8 matrix module: DIN -> pin 11, CLK -> pin 13, CS -> pin 10,
//             VCC -> 5 V, GND -> GND
//   button    pin 2 -> button -> GND        (INPUT_PULLUP): a tap on the shell
//   piezo     pin 8 -> piezo -> GND
//
// A spring build for Easter, or for any classroom that has watched real eggs
// in an incubator. The story goes in stages: the egg rests, wobbles, shows one
// crack, then two, then three, and then the top of the shell opens and the
// chick looks out. Each stage waits a random few seconds, so it never plays
// out quite the same way twice, and a press of the button moves straight on
// to the next stage.
//
// The pictures are eight bytes each, one per row. A crack is drawn by
// clearing a few dots of the egg, and a wobble by shifting every row one
// place left or right, so the whole animation is three small tables.
//
// Things to try. Press the button to tap the shell. Draw a different hatchling
// in CHICK. Make the chick peep a tune.

#include <LedControl.h>

const int BUTTON_PIN = 2;
const int PIEZO_PIN = 8;

LedControl matrix(11, 13, 10, 1);   // DIN, CLK, CS, one module

const uint8_t EGG[8] = {0b00011000, 0b00111100, 0b01111110, 0b01111110,
                        0b01111110, 0b01111110, 0b00111100, 0b00000000};
// The dots each crack clears from the egg.
const uint8_t CRACKS[3][8] = {
  {0, 0, 0, 0b00010000, 0, 0, 0, 0},
  {0, 0, 0b00001000, 0b00010100, 0, 0, 0, 0},
  {0, 0, 0b00101000, 0b01010100, 0b00000010, 0, 0, 0},
};
const uint8_t CHICK[8] = {0b00011000, 0b00111100, 0b00101110, 0b00111100,
                          0b01011010, 0b01111110, 0b00111100, 0b00000000};

int stage = 0;          // 0 resting, 1 wobbling, 2 to 4 cracks, 5 hatched
unsigned long nextStage = 0;
int hatched = 0;

void draw(const uint8_t rows[8], int shift, int cracks) {
  for (int r = 0; r < 8; r++) {
    uint8_t row = rows[r];
    for (int c = 0; c < cracks; c++) row &= ~CRACKS[c][r];
    if (shift > 0) row >>= 1;
    if (shift < 0) row <<= 1;
    matrix.setRow(0, r, row);
  }
}

void peep() {
  for (int f = 2000; f < 3200; f += 200) {
    tone(PIEZO_PIN, f, 15);
    delay(15);
  }
}

void advance() {
  stage++;
  if (stage > 5) {
    stage = 0;
    Serial.println("A new egg");
  } else if (stage == 1) {
    Serial.println("The egg is wobbling");
  } else if (stage <= 4) {
    Serial.print("Crack ");
    Serial.println(stage - 1);
    tone(PIEZO_PIN, 300, 30);
  } else {
    hatched++;
    Serial.print("Peep! Chick ");
    Serial.print(hatched);
    Serial.println(" has hatched");
    peep();
  }
  nextStage = millis() + (stage == 5 ? 6000 : random(1500, 3500));
}

void setup() {
  Serial.begin(9600);
  pinMode(BUTTON_PIN, INPUT_PULLUP);
  matrix.shutdown(0, false);
  matrix.setIntensity(0, 6);
  matrix.clearDisplay(0);
  randomSeed(analogRead(A0));
  nextStage = millis() + 2000;
  Serial.println("An egg, keeping warm");
}

void loop() {
  unsigned long now = millis();
  if (digitalRead(BUTTON_PIN) == LOW) {
    advance();
    while (digitalRead(BUTTON_PIN) == LOW) delay(10);
  } else if (now >= nextStage) {
    advance();
  }

  if (stage == 5) {
    // The chick blinks every so often and peeps now and then.
    bool blink = (now / 150) % 20 == 0;
    uint8_t rows[8];
    for (int r = 0; r < 8; r++) rows[r] = CHICK[r];
    if (blink) rows[2] |= 0b00010000;
    draw(rows, 0, 0);
    if (random(0, 400) == 0) peep();
  } else {
    // From the first wobble on, the egg rocks a little now and then.
    int shift = 0;
    if (stage >= 1 && (now / 200) % 5 == 0) shift = (now / 1000) % 2 ? 1 : -1;
    draw(EGG, shift, stage >= 2 ? stage - 1 : 0);
  }
  delay(20);
}

Parts list

5 parts, plus the jumper wires. Every one is in the editor's parts bin.

How it is wired

7 connections, pin by pin, read from the circuit itself. Each line is one set of pins joined together, by a jumper wire or a breadboard strip.

  • Arduino Uno R3 pin 13; LED matrix, 8x8 pin CLK
  • Arduino Uno R3 pin 11; LED matrix, 8x8 pin DIN
  • Arduino Uno R3 pin 10; LED matrix, 8x8 pin CS
  • Arduino Uno R3 pin 8; Piezo speaker pin 1
  • Arduino Uno R3 pin 2; Pushbutton pin 1a
  • Arduino Uno R3 pin 5V; LED matrix, 8x8 pin VCC
  • Ground: Arduino Uno R3 pin GND; Pushbutton pin 2a; Piezo speaker pin 2; LED matrix, 8x8 pin GND

Change it and keep it

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