
ESP32-S3 board
The brain that runs your uploaded sketch.
TinySkiff ESP32-S3 Lab · Day 19 of 30
Today you wire the control that steers every gamepad. Under the stick sit two potentiometers at right angles and a push button hiding beneath them. The sketch reads all three and prints their values twice a second, so you can watch your hand become numbers.
TSK-DAY19-JOYSTICK
Hand this to an agent so it can pull the lesson packet and coach you step by step.
01 First, know the pieces
Five things, one of them brand new. 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.

A thumb stick over two dials and a hidden push button.

Female ends grip the module's header pins; male ends reach the board.

Uploads code and opens Serial Monitor.
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. Each connection tells you where the wire goes and why.
Power from 3.3V. The module's pin is printed +5V, and the official diagram feeds it from the 3.3V rail — follow the diagram. 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.
Push the five female jumper ends onto the module's header pins — the labels VRX, VRY, SW, +5V, and GND are printed beside them.
Connect VRX → GPIO 14, VRY → GPIO 13, and SW → GPIO 12.
Connect the module's +5V pin to the 3.3V rail and GND → GND, just as the chart shows.
Compare every wire to the chart before you plug in USB.
Open Sketch_13.1_Joystick.ino in Arduino IDE and upload it.
Open Serial Monitor and set the baud rate to 115200.
Glide the stick to its edges, then press it straight down like a button.
04 Read just enough code
The loop is three reads and one print. Two pins are measured with analogRead, one with digitalRead, and printf lines all three up. Switch to MicroPython if you'd rather see the same idea in Python — the wiring never changes.
int xyzPins[] = {14, 13, 12}; //x,y,z pins
void setup() {
Serial.begin(115200);
pinMode(xyzPins[2], INPUT_PULLUP); //z axis is a button.
}
void loop() {
int xVal = analogRead(xyzPins[0]);
int yVal = analogRead(xyzPins[1]);
int zVal = digitalRead(xyzPins[2]);
Serial.printf("X,Y,Z: %d,\t%d,\t%d\n", xVal, yVal, zVal);
delay(500);
}
int xyzPins[] = {14, 13, 12}One array holds all three pins — X on GPIO 14, Y on GPIO 13, Z on GPIO 12. pinMode(xyzPins[2], INPUT_PULLUP)Sets the button pin so it rests at 1 and a press pulls it to 0. analogRead(xyzPins[0])Measures the X potentiometer's voltage as a number from 0 to 4095. Serial.printf("X,Y,Z: %d,\t%d,\t%d\n", …)Prints all three values on one tab-separated line, twice a second. Optional side path · same circuit
xVal=ADC(Pin(14))
yVal=ADC(Pin(13))
zVal=Pin(12,Pin.IN,Pin.PULL_UP)
xVal.atten(ADC.ATTN_11DB)
xVal.width(ADC.WIDTH_12BIT)
print("X,Y,Z:",xVal.read(),",",yVal.read(),",",zVal.value())
ADC(Pin(14))Wraps GPIO 14 in an ADC reader — the same measurement analogRead does in C.Pin(12,Pin.IN,Pin.PULL_UP)The button pin with the internal pull-up — 1 at rest, 0 while pressed.Same pins, same three values. This version prints once a second where the Arduino sketch prints twice. 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
You already know every part inside this module. The joystick simply packs them under a single stick — the same arrangement lives inside every gamepad you've ever held.
Pushing the stick rotates two potentiometers set at right angles.
analogRead turns each pot's voltage into a number from 0 to 4095.
INPUT_PULLUP holds GPIO 12 at 1 until a press pulls it to 0.
Twice a second the sketch prints all three values on one line.
one joystick = two potentiometers at right angles + one push button
Each axis is the dial you've already read — one turned by side-to-side motion, one by forward-and-back. At rest both sit near the middle of their travel.
The internal pull-up holds the button pin HIGH with nothing connected in the module. Pressing the stick closes the switch to ground, so the reading drops to 0.
06 Know it worked
Success and recovery sit side by side, so you never have to go hunting when something looks off.
A new line lands twice a second. At rest both axes sit near mid-scale — anywhere around 1800–2200 is healthy, and your exact numbers will differ. A full push drives one axis toward 0 or 4095, and a straight-down press flips Z from 1 to 0.
07 Make the idea yours
Same working circuit, one new habit: learning your instrument's true numbers. It fits inside today's 20 minutes.
Let the stick rest and write down the X and Y values. Watch a few more lines land and count how far the numbers drift while nothing touches the stick.
Push the stick to north, south, east, and west, and record the X and Y pair at each full deflection. Sketch them as a compass with your centre numbers in the middle.
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-DAY19-JOYSTICK
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.