TinySkiff ESP32-S3 Lab · Day 5 of 30

Turn a press
into a lamp

Yesterday the LED only glowed while you held the button. Today it stays. With a little memory and a trick called debounce, one press latches the light on and the next press turns it off — the leap from a raw button to a product.

About 20 minutesArduino firstMicroPython optionalSame circuit as Day 4
Agent assist code TSK-DAY05-LAMP

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

Nothing new to buy — this is the exact circuit you built on Day 4. If it's still wired up, you only need to upload a new sketch. Tap Define on anything you'd like refreshed.

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 a red LED with its longer positive leg and shorter negative leg labelled.
Manual photo

LED

The lamp — same LED, same one-way rule as Day 4.

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

220 Ω resistor

Still in series with the LED, keeping the current gentle.

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

2 × 10 kΩ resistors

Hold the button's pin steady between presses.

Official manual photo of a four-pin push button switch with its pin pairs labelled 1 and 2.
Manual photo

Push button

The same switch — now it toggles instead of holds.

Official manual image of a jumper wire.
Manual photo

Jumper wires

Temporary, solder-free connections.

Official manual screenshot of the Arduino IDE interface.
Manual screenshot

Arduino IDE

Uploads the new lamp sketch to the board.

02 Make the physical circuit

Chart the circuit

This is the Day 4 circuit, unchanged — the same chart, so the same chart applies. Click it to enlarge, or skip straight to the sketch if your circuit is still assembled.

Official Freenove circuit — C Tutorial, Chapter 2 (Button & LED), page 48. The table lamp reuses Project 2.1's circuit.
LED long leg (+) GPIO 2 via 220 Ω This pin switches the LED on and off.
LED short leg (−) GND Completes the LED's path back to zero volts.
Push button GPIO 13 The board reads this pin to catch each press.
10 kΩ resistor 3.3V Holds GPIO 13 HIGH until a press pulls it LOW.

Same circuit, same care. Nothing moves on the breadboard today. If you do rewire, keep the LED's long leg toward GPIO 2 through the 220 Ω resistor, and unplug USB first.

03 One action at a time

Build it

Mostly upload-and-watch — the wiring is yesterday's. Tap each step as you go to keep your place.

0 / 6 done
  1. Confirm the Day 4 circuit is still wired, or rebuild it from the chart.

  2. Keep USB unplugged until every wire matches the chart.

  3. Open Sketch_02.2_TableLamp.ino in Arduino IDE.

  4. Upload it to the ESP32-S3.

  5. Press the button once and let go — the LED should latch on.

  6. Press once more — it should turn off.

You built a lamp.

A momentary button now behaves like a real switch. Head to Test & debug to confirm the toggle and check for double-presses.

04 Read just enough code

Read the code

The circuit is the same; the loop is what changed. It now remembers the LED's state, waits out the switch's chatter, and flips only on a clean press. Switch to MicroPython to see the same idea in Python.

Sketch_02.2_TableLamp.ino
void loop() {
  if (digitalRead(PIN_BUTTON) == LOW) {
    delay(20);                       // wait out the chatter
    if (digitalRead(PIN_BUTTON) == LOW) {
      reverseGPIO(PIN_LED);          // clean press -> flip the LED
    }
    while (digitalRead(PIN_BUTTON) == LOW);   // hold here until release
  }
}

void reverseGPIO(int pin) {
  digitalWrite(pin, !digitalRead(pin));
}
delay(20)The debounce pause — long enough for the switch's chatter to settle.
reverseGPIO(PIN_LED)Flips the LED to the opposite of whatever it is now — on becomes off, off becomes on.
while (digitalRead(PIN_BUTTON) == LOW);Waits right here until you let go, so one press can't count twice.

05 Understand, don't memorise

Memory and debounce

Two small ideas turn a button into a lamp: the code remembers the light's state, and it refuses to trust a press until the switch has stopped bouncing.

Notice

A press starts

The loop sees GPIO 13 go LOW and pauses briefly.

Confirm

Check again

If it is still LOW after the pause the press was real.

Flip

Toggle the LED

reverseGPIO sets the LED to the opposite of what it was.

Wait

Until release

The code holds until you let go so one press counts once.

The model one clean press → flip the remembered state → the lamp stays

Why the LED bounced before

A switch chatters for a few milliseconds as it closes. Without the pause the board would toggle many times per press.

What toggling really is

Instead of following the button live, the code keeps a state and inverts it — that memory is the whole difference from Day 4.

06 Know it worked

Test & debug

Nothing prints today — the proof is whether the lamp stays without your finger.

What you should see
Lamp
  • Press once and release — the LED latches on and stays on.
  • Press once more — it turns off and stays off.
  • Each full press flips the light exactly once, cleanly.

If a single press sometimes flips twice, the debounce pause is doing its job when it's present — and failing when it's removed.

If it doesn't
  • One press flips it twice? Confirm the debounce delay and the wait-until-release line are both present.
  • Nothing latches? Re-run Day 4's checks — LED direction, the resistors, GPIO 2 and 13.
  • LED flickers while held? You may be on the Day 4 sketch — upload Sketch_02.2_TableLamp.
  • Upload fails? Swap in a data-capable USB cable.

07 Make the idea yours

Try this: change how the lamp feels

Same working lamp, one deliberate change to its behaviour. Pick one and note what changed — it fits inside today's 30 minutes.

Tune the debounce

Try delay(5) and then delay(80). Find where presses feel crisp without ever double-flipping.

Name the interaction

In one sentence, describe how this lamp should feel to use — then judge whether your timing delivers it.

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-DAY05-LAMP

How the agent should behave: keep it to upload-and-watch on the existing circuit, explain debounce and toggle on request, and check wiring, board, port, and USB before changing code.

Field note

Shortcut

Prompt copied