
ESP32-S3 board
The brain that runs your uploaded sketch.
TinySkiff ESP32-S3 Lab · Day 16 of 30
Today the colour mixing moves into your hands. Three knobs each feed a reading to the board, and each reading sets the brightness of one colour in the RGB dome — red, green, and blue on their own channels. Turn them together and you are mixing light the way a deckhand trims three sheets at once.
TSK-DAY16-SOFTCOLOUR
Hand this to an agent so it can pull the lesson packet and coach you step by step.
01 First, know the pieces
Seven things, and every one of them has been aboard before. 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.

Three knobs — one for each colour channel.

Three lights — red, green, blue — in one dome with a shared pin.

One in series with each colour leg to keep the current gentle.

Temporary, solder-free connections — thirteen of them today.

Uploads the sketch to the board.
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. The pairing to keep in your head: the knob on GPIO 12 drives the red leg on GPIO 38, 13 drives green on 39, and 14 drives blue on 40.
The common pin goes to 3.3V. This is the same common-anode LED as Day 9 — the long common pin goes to 3.3V, the opposite of a single LED's ground leg. Each colour leg reaches its own GPIO through a 220 Ω resistor. 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.
Place the three potentiometers on the breadboard with room to turn each knob.
Wire each knob's outer legs to 3.3V and GND so its middle pin can sweep the full range.
Run the middle pins to GPIO 12, 13, and 14 — red, green, and blue in that order.
Wire the RGB LED's red leg through a 220 Ω resistor to GPIO 38, green to GPIO 39, blue to GPIO 40.
Run the LED's long common pin to 3.3V.
Compare every wire to the chart before you plug in USB.
Open Sketch_10.2_SoftColorfulLight.ino in Arduino IDE and upload it.
Turn each knob in turn and watch its colour rise and fall in the dome.
04 Read just enough code
Day 15 built one chain — read a knob, rescale it, write a brightness. Today the sketch runs that chain three times per pass using three small arrays and one loop. Switch to MicroPython if you'd rather see the same idea in Python — the wiring never changes.
const byte adcChns[] = {12, 13, 14}; // define the adc channels
const byte ledPins[] = {38, 39, 40}; // define led pins
const byte pwmChns[] = { 0, 1, 2}; // define the pwm channels
int colors[] = {0, 0, 0}; // red, green ,blue values of color.
void setup() {
for (int i = 0; i < 3; i++) { //setup the pwm channels
ledcAttachChannel(ledPins[i], 1000, 8, pwmChns[i]);//1KHz, 8bit(0-255).
}
}
void loop() {
for (int i = 0; i < 3; i++) {
colors[i] = map(analogRead(adcChns[i]), 0, 4096, 0, 255); //calculate color value.
ledcWrite(ledPins[i], 256 - colors[i]); //set color
}
delay(10);
}
const byte adcChns[] = {12, 13, 14}Three matched arrays pair each knob with a colour leg — position 0 links the knob on 12 to the red leg on 38 and so on down the line. colors[i] = map(analogRead(adcChns[i]), 0, 4096, 0, 255)Reads one knob (0–4095) and rescales it onto the 0–255 brightness range in a single line. ledcWrite(ledPins[i], 256 - colors[i])Day 9's common-anode inversion — this dome lights when its pin goes LOW so the sketch subtracts the value before writing it. ledcAttachChannel(ledPins[i], 1000, 8, pwmChns[i])Gives each colour leg its own hardware PWM channel at 1 kHz with 8-bit brightness. Optional side path · same circuit
pwm0=PWM(Pin(40,Pin.OUT),10000)
pwm1=PWM(Pin(39,Pin.OUT),10000)
pwm2=PWM(Pin(38,Pin.OUT),10000)
adc0=ADC(Pin(12))
adc1=ADC(Pin(13))
adc2=ADC(Pin(14))
pwm0.duty(1023-remap(adc0.read(),0,4095,0,1023))
pwm1.duty(1023-remap(adc1.read(),0,4095,0,1023))
pwm2.duty(1023-remap(adc2.read(),0,4095,0,1023))
pwm0.duty(1023-remap(adc0.read(),0,4095,0,1023))The whole chain in one line — read the knob, rescale to the 10-bit duty range, and subtract for the common-anode dome.Same wiring, one difference to expect: Freenove's Python version pairs the knobs to the colours in the reverse order — the knob on GPIO 12 drives the leg on GPIO 40 — and both pairings work fine. 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
Day 15's single control chain — read the knob, rescale the number, write the brightness — appears here three times over, copied by a loop over three arrays.
analogRead measures each knob on GPIO 12 13 14 every pass.
Each reading up to 4095 becomes a colour value from 0 to 255.
The common-anode dome lights when its pin goes LOW so the sketch flips the scale before writing.
The loop refreshes all three channels fast enough that the colour rides your hands.
colour = three knob readings → three mapped brightnesses
Writing the pins as three matched arrays lets one loop serve every channel. Adding a fourth channel would mean one more entry in each array and nothing else.
The common pin sits at 3.3V, so a colour is brightest when its own pin is pulled LOW. Subtracting the value from 256 flips the scale so a bigger knob reading still means a brighter colour.
06 Know it worked
Nothing prints to the screen today — the proof is the colour under your fingers.
Every knob turned down means darkness by design — white takes all three channels at full.
07 Make the idea yours
Same working circuit, two experiments — one with your hands, one with a single line of code. It fits inside today's 25 minutes.
Turn the knobs until the dome glows sunset orange — red high, green partway, blue low. Write down roughly where each knob sits, as three numbers from 0 to 255.
In the loop, make the blue channel reuse the green knob's value — set colors[2] = colors[1] after the map line — and the mix now lives on two knobs.
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-DAY16-SOFTCOLOUR
How the agent should behave: guide one physical connection at a time, wait for you to confirm, explain the knob-to-colour pairing on request, and always check wiring, board, port, and USB before changing code.