TinySkiff ESP32-S3 Lab · Day 16 of 30

Mix your own colour
with three knobs

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.

About 25 minutesArduino firstMicroPython optionalDay 9's dome meets Day 15's knob
Agent assist code 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

What you need

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.

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 its three legs visible.
Manual photo

3 × rotary potentiometers

Three knobs — one for each colour channel.

Official manual photo of an RGB LED showing its long common pin and three colour legs.
Manual photo

RGB LED

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

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

3 × 220 Ω resistors

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

Official manual image of a jumper wire.
Manual photo

Jumper wires

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

Official manual screenshot of the Arduino IDE interface.
Manual screenshot

Arduino IDE

Uploads the sketch to the board.

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 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.

Official Freenove circuit — C Tutorial, Chapter 10 (Potentiometer & LED), page 113.
Red knob middle pin GPIO 12 The board reads this knob to set how much red shows.
Green knob middle pin GPIO 13 The board reads this knob to set how much green shows.
Blue knob middle pin GPIO 14 The board reads this knob to set how much blue shows.
Each knob's outer legs 3.3V and GND The two ends give the middle pin a full sweep from zero to full voltage.
Red leg (via 220 Ω) GPIO 38 PWM on this pin sets the red brightness.
Green leg (via 220 Ω) GPIO 39 PWM on this pin sets the green brightness.
Blue leg (via 220 Ω) GPIO 40 PWM on this pin sets the blue brightness.
Common (long) pin 3.3V All three colours share this positive pin so a colour lights when its pin goes LOW.

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

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. Place the three potentiometers on the breadboard with room to turn each knob.

  3. Wire each knob's outer legs to 3.3V and GND so its middle pin can sweep the full range.

  4. Run the middle pins to GPIO 12, 13, and 14 — red, green, and blue in that order.

  5. Wire the RGB LED's red leg through a 220 Ω resistor to GPIO 38, green to GPIO 39, blue to GPIO 40.

  6. Run the LED's long common pin to 3.3V.

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

  8. Open Sketch_10.2_SoftColorfulLight.ino in Arduino IDE and upload it.

  9. Turn each knob in turn and watch its colour rise and fall in the dome.

Your own mixing desk.

Three knobs now hold the colour between them. Head to Test & debug to confirm each channel answers its own knob.

04 Read just enough code

Read the 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.

Sketch_10.2_SoftColorfulLight.ino
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.

05 Understand, don't memorise

Three chains, one loop

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.

Read three

Knobs in

analogRead measures each knob on GPIO 12 13 14 every pass.

Rescale

map()

Each reading up to 4095 becomes a colour value from 0 to 255.

Invert

256 minus

The common-anode dome lights when its pin goes LOW so the sketch flips the scale before writing.

Repeat

Every 10 ms

The loop refreshes all three channels fast enough that the colour rides your hands.

The model colour = three knob readings → three mapped brightnesses

Why arrays and a loop

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 same inversion as Day 9

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

Test & debug

Nothing prints to the screen today — the proof is the colour under your fingers.

What you should see
RGB LED
  • Turn one knob and one colour sweeps smoothly from dark to full while the other two hold steady.
  • Set the knobs in combinations and the dome mixes the shades — red and green up makes yellow.
  • All three knobs up glows white; all three down leaves the dome dark.

Every knob turned down means darkness by design — white takes all three channels at full.

If it doesn't
  • One colour never changes? Check that knob's middle wire on GPIO 12, 13, or 14 — the board is reading air.
  • Turning the red knob changes the wrong colour? The RGB legs are in the wrong order — red goes to GPIO 38, green to 39, blue to 40.
  • The dome stays dark with knobs up? Check the common pin — it goes to 3.3V.
  • Upload fails? Swap in a data-capable USB cable.

07 Make the idea yours

Try this: dial a sunset

Same working circuit, two experiments — one with your hands, one with a single line of code. It fits inside today's 25 minutes.

Dial a sunset

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.

Two-knob mixer

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

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-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.

Field note

Shortcut

Prompt copied