ESP32-S3 Lab · Day 15 of 30

Turn the knob
and shade the light

Today your hand takes the helm. You wire Day 13's knob to one pin and Day 7's LED to another, then upload a sketch that reads the knob and sets the brightness to match. Underneath the knob is a voltage divider — the pattern almost every analog sensor in the kit uses to reach the board — and today you watch it drive a light in real time.

About 20 minutesArduino firstMicroPython optionalDay 13's knob meets Day 7's fade
Agent assist code TSK-DAY15-SOFTLIGHT

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 most of them are old friends from earlier days. 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 a rotary potentiometer with three pins.
Manual photo

Rotary potentiometer

The knob — its middle pin picks off any voltage between its two ends.

Official manual photo of a red LED with its longer positive leg and shorter negative leg labelled.
Manual photo

LED

The light you'll shade — it only works one way round.

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

220 Ω resistor

Sits in series with the LED to keep the current gentle.

Official manual image of a jumper wire.
Manual photo

5 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. Two small circuits share the board today, so check the knob's side and the LED's side separately.

Official Freenove circuit — C Tutorial, Chapter 10 (Potentiometer & LED), page 110.
Pot middle pin GPIO 1 The divider's midpoint — the board reads this voltage as a number.
Pot outer pin 3.3V Sets the top of the knob's voltage divider at 3.3V.
Pot other outer pin GND Sets the bottom of the divider at 0V.
LED long leg (+) GPIO 14 via 220 Ω This pin shades the LED with PWM.
LED short leg (−) GND Completes the LED's path back to zero volts.

Mind the LED's legs. The LED only lights one way round — long leg toward GPIO 14 through the 220 Ω resistor, short leg to ground. 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. Stand the potentiometer on the breadboard so each of its three pins lands in its own row.

  3. Wire one outer pot pin to 3.3V and the other outer pin to GND.

  4. Run the pot's middle pin — the divider's midpoint — to GPIO 1, the wire the board reads.

  5. Place the LED so its long leg (+) is on the GPIO 14 side and its short leg (−) heads toward ground.

  6. Put the 220 Ω resistor in series between GPIO 14 and the LED's long leg.

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

  8. Open Sketch_10.1_SoftLight.ino in Arduino IDE and upload it.

  9. Turn the knob slowly from end to end and watch the LED follow your hand.

The knob owns the light.

Every turn of your wrist becomes a brightness. Head to Test & debug to confirm the sweep.

04 Read just enough code

Read the code

The whole sketch is four working lines. One line sets up PWM on the LED's pin; the loop reads the knob and hands that number straight to the light. Switch to MicroPython if you'd rather see the same idea in Python — the wiring never changes.

Sketch_10.1_SoftLight.ino
#define PIN_ANALOG_IN   1
#define PIN_LED         14
#define CHAN            0
void setup() {
  ledcAttachChannel(PIN_LED, 1000, 12, CHAN);
}

void loop() {
  int adcVal = analogRead(PIN_ANALOG_IN); //read adc
  int pwmVal = adcVal;        // adcVal re-map to pwmVal
  ledcWrite(PIN_LED, pwmVal);    // set the pulse width.
  delay(10);
}
ledcAttachChannel(PIN_LED, 1000, 12, CHAN)Sets up PWM on GPIO 14 at 12-bit resolution, so brightness runs 0 to 4095 — the same span the ADC produces.
analogRead(PIN_ANALOG_IN)Reads the knob's voltage on GPIO 1 as a number from 0 to 4095.
ledcWrite(PIN_LED, pwmVal)Sets the LED's duty to that number. The two scales match, so the raw reading passes straight through as a brightness — the "re-map" comment overstates what this line does.

05 Understand, don't memorise

One loop from hand to light

Everything you've learned about pins joins up today. Day 13 turned a voltage into a number and Day 7 turned a number into brightness; this sketch links them. The piece worth slowing down for is what makes the knob a voltage in the first place — a voltage divider, the pattern nearly every analog sensor in the kit leans on.

The split

A voltage divider

The knob is two resistances in series across 3.3V and ground, with the wiper tapping their meeting point. Turn it and you move where the 3.3V splits, so the middle pin's voltage slides anywhere from 0 to 3.3V.

Sense

Voltage to number

analogRead measures that midpoint voltage on GPIO 1 and hands back a number from 0 to 4095.

Carry

One variable

pwmVal takes the ADC number straight across — both scales run 0 to 4095, so nothing needs rescaling.

Act

Number to light

ledcWrite sets the LED's PWM duty to that number, so a higher voltage at the wiper lands as a brighter LED.

Repeat

Every 10 ms

The loop runs again at once, so the light tracks your hand the moment you turn.

The model voltage divider → ADC number → PWM duty → brightness

Why the knob is a voltage divider

Two resistances in series split the supply at their meeting point in proportion to their sizes. The knob makes that split adjustable — the wiper moves the boundary between the upper stretch of track and the lower one, so the midpoint voltage moves with your wrist.

The same divider, without a hand

Replace one half of the divider with a photoresistor and the split shifts on its own as the light changes — no knob to turn. That is how most of the kit's sensors reach the ADC, which is why this one pattern is worth knowing cold.

Why there's no map() call

The sketch sets the PWM to 12 bits on purpose. Both scales run 0 to 4095, so the ADC reading is already a valid duty and passes through untouched. When the scales differ — as in the MicroPython version — you remap first.

06 Know it worked

Test & debug

Nothing prints to the screen today — the proof is the LED under your fingertips.

What you should see
LED
  • Turn the knob to one end — the LED sits dark.
  • Turn it to the other end — the LED reaches full brightness.
  • Everywhere in between, the brightness follows the knob smoothly, with no jumps or dead spots.

Which end is dark depends on which outer pin you wired to GND — either way round is a working circuit.

If it doesn't
  • LED stuck at full or stuck dark? Check the pot's middle-pin wire — it must reach GPIO 1.
  • Turning the knob changes nothing? Check the outer pot pins — one to 3.3V, one to GND.
  • LED dark at every knob position? Check the LED's direction and the 220 Ω resistor on the GPIO 14 side.
  • Upload fails? Swap in a data-capable USB cable.

07 Make the idea yours

Try this: watch the raw numbers

You've seen the LED follow the knob. Now watch the number in the middle — the raw ADC reading the whole loop is built on — and use it to reason about which way the mapping runs. It fits inside today's session.

See the reading

Add Serial.begin(115200); to setup() and Serial.println(adcVal); inside the loop, then upload and open Serial Monitor. Turn the knob end to end and watch the number climb from 0 to about 4095 — that is the divider's midpoint voltage, digitised live.

Flip the mapping

Change the carry line to int pwmVal = 4095 - adcVal; and, before you upload, predict which end of the travel will now go dark. Upload and check — the raw numbers still climb the same way while the light falls, because you reversed only the mapping, not the reading.

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-DAY15-SOFTLIGHT

How the agent should behave: guide one physical connection at a time and wait for confirmation, then make the voltage divider the centre of the explanation — the knob splits 3.3V, the ADC reads the split, and PWM turns that number into brightness. Always check wiring, board, port, and USB before changing code.

Keep your place

Finished Day 15?

Mark it complete — it shows on your course map, and your place is saved on this device.

Field note

Shortcut

Prompt copied