TinySkiff ESP32-S3 Lab · Day 21 of 30

Turn one byte
into a digit

Today the shift register earns its keep. You wire its eight outputs to a 7-segment display, upload a sketch that sends one pattern byte per character, and the display counts 0 through F — a readable digit from the same three wires you ran on Day 20.

About 30 minutesArduino firstMicroPython optionalSame three wires as Day 20
Agent assist code TSK-DAY21-SEVENSEG

Hand this to an agent so it can pull the lesson packet and coach you step by step.

01 First, know the pieces

What you need

Six things, and two of them are old friends from Day 20. Tap Define on any part you haven't met — the answer opens as a field note you can read and dismiss without losing your place.

Official manual photo of the ESP32-S3 development board.
Manual photo

ESP32-S3 board

The brain that runs your uploaded sketch.

Official manual image of the ESP32-S3 GPIO extension board.
Manual photo

GPIO extension board

Spreads the pins into rows you can reach and label.

Official manual photo of the 74HC595 shift register chip with its pins labelled.
Manual photo

74HC595 shift register

Day 20's chip — takes a byte in on three wires and holds it on eight outputs.

Official manual photo of a one-digit seven-segment display module with its pins numbered 10, 6, 1, and 5 at the corners.
Manual photo

7-segment display

Eight lit bars arranged as a figure — together they draw one character.

Official manual photo of a resistor with coloured value bands.
Manual photo

8 × 220 Ω resistors

One per segment, each keeping its own current gentle.

Official manual image of a jumper wire.
Manual photo

Jumper wires

Temporary, solder-free connections.

02 Make the physical circuit

Chart the circuit

The official Freenove diagram is your chart — schematic on top, the same circuit built on a breadboard below. Click it to enlarge. The three control wires are exactly where Day 20 left them; today's work is the eight resistor paths from the chip's outputs to the display's segments.

Official Freenove circuit — C Tutorial, Chapter 15 (74HC595 & 7-Segment Display), page 140.
GPIO 12 74HC595 DS (pin 14) Carries each bit of the pattern byte into the chip.
GPIO 13 74HC595 ST_CP (pin 12) The latch — a low-high pulse shows the finished byte on all eight outputs at once.
GPIO 14 74HC595 SH_CP (pin 11) The clock tick that moves each bit one place along.
74HC595 Q0-Q7 segments A-G and DP via 220 Ω each Each output drives one segment through its own resistor.
Display common pins (3 and 8) positive rail (3.3V/5V) Feeds the shared anode so a 0 bit can light its segment.

Mind the chip and the display's orientation. Seat the 74HC595 with its notch matching the diagram, and place the display the way the breadboard photo shows — its segments only line up with the right Q pins one way round. Unplug USB before you move any wire.

03 One action at a time

Build it

This is the main path — you can finish the day without opening a single field note. Tap each step as you go to keep your place.

0 / 9 done
  1. Seat the ESP32-S3 on the GPIO extension board and keep USB unplugged while you wire.

  2. Straddle the 74HC595 across the breadboard's centre gap with its notch matching the diagram — the same seat as Day 20.

  3. Place the 7-segment display nearby the way the breadboard photo shows, and find its two common pins (3 and 8).

  4. Run the three control wires — GPIO 12 to DS, GPIO 13 to ST_CP, GPIO 14 to SH_CP.

  5. Wire each chip output Q0 through Q7 to its segment through its own 220 Ω resistor, following the diagram one row at a time.

  6. Wire the display's common pins (3 and 8) to the positive rail so the shared anode has power.

  7. Compare every wire to the chart before you plug in USB.

  8. Open Sketch_15.1_1_Digit_7-Segment_Display.ino in Arduino IDE and upload it.

  9. Watch the display count 0 through F, one character per second.

A digit you can read.

The board is drawing characters now, one byte each. Head to Test & debug to confirm the full count.

04 Read just enough code

Read the code

The sketch keeps Day 20's writeData() helper word for word. The new piece is a table of sixteen bytes — one ready-made segment pattern per character — and a loop that sends them one per second. Switch to MicroPython if you'd rather see the same idea in Python — the wiring never changes.

Sketch_15.1_1_Digit_7-Segment_Display.ino
int dataPin  = 12;          // Pin connected to DS of 74HC595(Pin14)
int latchPin = 13;          // Pin connected to ST_CP of 74HC595(Pin12)
int clockPin = 14;          // Pin connected to SH_CP of 74HC595(Pin11)

// Define the encoding of characters 0-F for the common-anode 7-Segment Display
byte num[] = {
  0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8,
  0x80, 0x90, 0x88, 0x83, 0xc6, 0xa1, 0x86, 0x8e
};

void setup() {
  // set pins to output
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
}

void loop() {
  // display 0-F on digital tube
  for (int i = 0; i < 16; i++) {
    writeData(num[i]);// Send data to 74HC595
    delay(1000);      // delay 1 second
    writeData(0xff);  // Clear the display content
  }
}

void writeData(int value) {
  // Make latchPin output low level
  digitalWrite(latchPin, LOW);
  // Send serial data to 74HC595
  shiftOut(dataPin, clockPin, LSBFIRST, value);
  // Make latchPin output high level, then 74HC595 will update the data to parallel output
  digitalWrite(latchPin, HIGH);
}
byte num[]Sixteen ready-made segment patterns — one byte per character, 0 through F.
shiftOut(dataPin, clockPin, LSBFIRST, value)Clocks the byte into the chip one bit at a time — the same move as Day 20.
writeData(0xff)All eight bits set to 1 means every segment off — this line blanks the display.
delay(1000)Holds each character on the display for one full second.

05 Understand, don't memorise

A byte is a picture

The display is eight little lights arranged as a figure. Feed them the right on-off pattern and your eye reads a character — the code table is just sixteen of those patterns, stored and ready.

Eight lights

Eight bits

Segments A through G plus the decimal point line up with the eight bits of one byte.

Zero lights

Common anode

All segments share the positive rail so a 0 bit pulls its segment low and lights it.

Look it up

The code table

The table stores one ready-made pattern per character from 0 to F.

Deliver it

Shift and latch

The 74HC595 from Day 20 carries the byte in on three wires and holds it on eight outputs.

The model character → one byte → eight segments → a shape you can read

How the byte maps to segments

From the top bit down the order is DP G F E D C B A. So 0xc0 is 1100 0000 — DP and G stay dark while the other six light up and draw a 0.

Why 0 means on

This display is common anode — every segment's positive side is tied to the rail, so an output has to sit LOW to let current flow and light its segment. 0xff is all HIGH, which is a blank display.

06 Know it worked

Test & debug

Nothing prints to the screen today — the proof is the count running on the display in front of you.

What you should see
Display
  • The display counts 0 1 2 3 4 5 6 7 8 9 then A b C d E F — one character per second.
  • After F it wraps back to 0 and the count runs again.
  • Each character sits steady for its full second.

Lowercase b and d are deliberate — with all seven segments a capital B would read as 8 and a capital D as 0.

If it doesn't
  • Every segment lit, all the time? The patterns aren't reaching the chip — check the latch wire on GPIO 13.
  • One segment never lights? Trace that segment's 220 Ω wire back to its Q pin on the chip.
  • Shapes are nonsense? Segment wires are on the wrong Q pins — re-check them against the diagram one row at a time.
  • Display completely dark? Run Day 20's chip power and orientation checklist, then confirm the common pins (3 and 8) reach the positive rail.

07 Make the idea yours

Try this: draw your own byte

Same working circuit, three small moves — pick a digit, change the pace, and invent one character the table never had. It fits inside today's 30 minutes.

Pick a boot digit

Add a writeData(num[7]) call at the end of setup() and empty out loop() — your favourite digit (swap the 7) now holds steady from the moment power arrives.

Slow the count

Change delay(1000) to 2000 and upload — each character now holds for two seconds. Find a pace you could actually read across the room.

Draw an H

Segments F E G B C make an H, and in bit order DP G F E D C B A that pattern is the byte 0x89. Call writeData(0x89) and check the shape that appears.

Logbook

08 Learn it with a hand on the tiller

Coach me through it

Every lesson ships with a code and a machine-readable packet, so an agent can guide you with full context.

Lesson code

TSK-DAY21-SEVENSEG

How the agent should behave: guide one physical connection at a time, wait for you to confirm, explain terms on request, and always check wiring, board, port, and USB before changing code.

Field note

Shortcut

Prompt copied