
ESP32-S3 board
The brain that runs your uploaded sketch.
TinySkiff ESP32-S3 Lab · Day 15 of 30
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 — the first day an input steers an output inside one loop.
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
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.

The brain that runs your uploaded sketch.

Spreads the pins into rows you can reach and label.

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

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

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

Temporary, solder-free connections.
02 Make the physical 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.
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
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.
Seat the ESP32-S3 on the GPIO extension board and keep USB unplugged while you wire.
Stand the potentiometer on the breadboard so each of its three pins lands in its own row.
Wire one outer pot pin to 3.3V and the other outer pin to GND.
Run the pot's middle pin to GPIO 1 — this is the wire the board reads.
Place the LED so its long leg (+) is on the GPIO 14 side and its short leg (−) heads toward ground.
Put the 220 Ω resistor in series between GPIO 14 and the LED's long leg.
Compare every wire to the chart before you plug in USB.
Open Sketch_10.1_SoftLight.ino in Arduino IDE and upload it.
Turn the knob slowly from end to end and watch the LED follow your hand.
04 Read just enough 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.
#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. Optional side path · same circuit
pwm =PWM(Pin(14,Pin.OUT),1000)
adc=ADC(Pin(1))
adc.atten(ADC.ATTN_11DB)
adc.width(ADC.WIDTH_12BIT)
adcValue=adc.read()
pwmValue=remap(adcValue,0,4095,0,1023)
pwm.duty(pwmValue)
adc.width(ADC.WIDTH_12BIT)Sets the ADC to 12 bits so readings run 0 to 4095 — the same span the Arduino sketch reads.remap(adcValue,0,4095,0,1023)MicroPython's duty here is 10-bit, so the reading is squeezed from 0–4095 down to 0–1023 before it drives the LED.Same pins, same wiring. MicroPython's duty runs 0–1023, so this version remaps the reading down before writing it; the Arduino sketch matches the two resolutions so the number passes straight through. Run it in Thonny if MicroPython is set up; otherwise skip it — it should never block the Arduino-first path.
05 Understand, don't memorise
Everything you've learned about pins joins up today. Day 13 turned a voltage into a number; Day 7 turned a number into brightness. This sketch links the two, many times a second.
analogRead turns the wiper's voltage into a number from 0 to 4095.
pwmVal takes the ADC number straight across — both scales run 0 to 4095.
ledcWrite sets the duty so the LED holds that brightness.
The loop runs again at once so the light tracks your hand as you turn.
knob voltage → ADC number → PWM duty → brightness
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.
Its two outer pins hold 3.3V and 0V across a resistive track, and the middle pin slides along that track as you turn — picking off any voltage in between.
06 Know it worked
Nothing prints to the screen today — the proof is the LED under your fingertips.
Which end is dark depends on which outer pin you wired to GND — either way round is a working circuit.
07 Make the idea yours
Same working circuit, one line to play with — the line that carries the number across. It fits inside today's 20 minutes.
Change the middle line to int pwmVal = 4095 - adcVal; and upload. The light now fades the opposite way as you turn — the same chain, flipped in one subtraction.
Replace the pass-through with if-bands — below 1000 write 0, up to 3000 write 2048, above that write 4095 — and feel the knob become an off / half / full switch.
Logbook
08 Learn it with a hand on the tiller
Every lesson ships with a code and a machine-readable packet, so an agent can guide you with full context.
TSK-DAY15-SOFTLIGHT
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.