The first read
Five wires, no library, and a sketch that prints X, Y and SW five times a second as raw numbers. It is for finding out what your stick does: where it rests, which pin moves when you push which way, and that SW goes to 1 on a click.
Five wires
Five of the six pins get a wire. GND never changes; VCC follows your board's logic voltage, and X, Y and SW follow its pinout.
Pick your board and the wires move to its pins. GND to GND, VCC to your board's logic voltage, X and Y to two analog pins, SW to a digital one, and nothing on NC:
| Board | X | Y | SW | VCC to |
|---|---|---|---|---|
| Arduino Uno | A0 | A1 | D2 | 5V |
| ESP32 | GPIO 34 | GPIO 35 | GPIO 25 | 3V3 |
| ESP32-S3 | GPIO 4 | GPIO 5 | GPIO 7 | 3V3 |
| Raspberry Pi Pico | GP26 | GP27 | GP15 | 3V3(OUT) |
The pins are the same in every sketch in this book. On the ESP32s, X and Y are on ADC1, the converter that keeps working with Wi-Fi on, and none of the three is a pin the chip reads at boot.
The sketch
No library: analogRead for the two axes and digitalRead for the click.
X and Y print as plain counts, on purpose. The next article turns them into
something tidier; this one is for finding out what your stick does.
What you should see
The serial monitor at 115200 prints five lines a second. On an Uno, with the stick let go, then pushed, then clicked, something like:
X 507 Y 521 SW 0
X 507 Y 521 SW 0
X 1023 Y 519 SW 0
X 506 Y 520 SW 1Let go, X and Y sit near the middle of the scale: near 512 on an Uno or a Pico, near 2048 on an ESP32, and never exactly. Now push the stick towards the header, then away, then left and right, and write down which number moves and which way. From the drawing, X should be the one that follows towards and away from the header; your board is the one that decides.
SW prints 1 only while the stick is pressed straight down, and the blue SW light comes on at the same moment. If the light comes on and SW stays 0, the wire or the pin number is wrong, not the board.
The code
No library. X and Y print as analogRead counts, SW as 0 or 1. Change the three _PIN numbers to the pins you wired; the comment above them lists all four boards.
/*
Dual Axis Joystick - first read TK23 / /p/tk23
Wiring. Parts up, header along the bottom. Count from the square pad,
which is GND at the left-hand end, rightwards:
GND -> GND
VCC -> 5V on an Uno; 3V3 on an ESP32, ESP32-S3 or Pico
NC -> nothing (in no net on the board)
X -> A0 on an Uno, GPIO 34 on an ESP32, GPIO 4 on an
ESP32-S3, GP26 on a Raspberry Pi Pico (analog)
Y -> A1, GPIO 35, GPIO 5, GP27 (same order, analog)
SW -> D2, GPIO 25, GPIO 7, GP15 (digital)
Arduino IDE
Tools > Board your board, e.g. ESP32S3 Dev Module
Tools > Port the one that appears when you plug in
Tools > USB CDC On Boot Enabled (ESP32-S3 only)
No library needed.
*/
// The pins X, Y and SW are wired to.
// Uno: A0 A1 2. ESP32: 34 35 25. ESP32-S3: 4 5 7. Pico: 26 27 15.
const int X_PIN = 4;
const int Y_PIN = 5;
const int SW_PIN = 7;
void setup() {
Serial.begin(115200);
pinMode(SW_PIN, INPUT); // R10 on the board pulls it down
}
void loop() {
int x = analogRead(X_PIN);
int y = analogRead(Y_PIN);
int sw = digitalRead(SW_PIN); // HIGH while the stick is pressed
Serial.print("X ");
Serial.print(x);
Serial.print(" Y ");
Serial.print(y);
Serial.print(" SW ");
Serial.println(sw);
delay(200); // five lines a second
}The counts run 0 to 1023 on an Uno and a Pico and 0 to 4095 on an ESP32 or ESP32-S3, so the resting numbers differ from board to board. That is fine here: this sketch is for watching which way they move.
The same read in MicroPython, for an ESP32, an ESP32-S3 or a Pico. X and Y print as 16-bit counts, 0 to 65535 on every board, and SW as 0 or 1.
"""
Dual Axis Joystick - first read, MicroPython TK23 / /p/tk23
Wiring. Parts up, header along the bottom. Count from the square pad,
which is GND at the left-hand end, rightwards:
GND -> GND
VCC -> 3V3 (never 5V: X, Y and SW all reach VCC)
NC -> nothing (in no net on the board)
X -> GPIO 34 on an ESP32, GPIO 4 on an ESP32-S3,
GP26 on a Raspberry Pi Pico (analog)
Y -> GPIO 35, GPIO 5, GP27 (same order, analog)
SW -> GPIO 25, GPIO 7, GP15 (digital)
Thonny
Run > Configure interpreter MicroPython (ESP32) or
MicroPython (Raspberry Pi Pico)
Save it to the board as main.py to run it on every power-up.
Nothing to install: machine, sys and time are built in.
"""
import sys
import time
from machine import ADC, Pin
# The GPIO numbers X, Y and SW are wired to.
# ESP32: 34 35 25. ESP32-S3: 4 5 7. Pico: 26 27 15.
X_PIN, Y_PIN, SW_PIN = 4, 5, 7
ESP = sys.platform == "esp32" # ESP32 and ESP32-S3
def analog(pin):
adc = ADC(Pin(pin))
if ESP:
adc.atten(ADC.ATTN_11DB) # the full range, to about 3.1 V
return adc
x_adc = analog(X_PIN)
y_adc = analog(Y_PIN)
sw = Pin(SW_PIN, Pin.IN) # R10 on the board pulls it down
while True:
print("X %5d Y %5d SW %d" % (
x_adc.read_u16(), y_adc.read_u16(), sw.value()))
time.sleep_ms(200) # five lines a secondThere is no Uno here: an Uno cannot run MicroPython. The atten line matters on an ESP32: without it the ADC stops near 1 V and most of the stick's travel reads as full. SW is Pin.IN with no pull, because R10 on the board already pulls it down. Stop it with Ctrl-C.
When it does not work
Look at the PWR light. If it is dark, VCC or GND is missing. If it is on, X and Y are not on the pins the sketch reads: count from the square pad, which is GND at the left-hand end with the header at the bottom, and remember the third hole, NC, goes nowhere.
The sketch sets SW to INPUT because R10 on the board pulls it down. If you changed it to INPUT_PULLUP, change it back. If SW is not wired, the pin floats and prints anything.
Set Tools > USB CDC On Boot to Enabled and upload again. Without it the S3's USB port does not bring up a serial port at boot, so the sketch runs with nowhere to print.
Expected on this board, as far as the drawing shows: the X potentiometer sits on the side of the stick and turns with the tilt towards and away from the header. The names are the pins', not directions. The eight-directions sketch has a line to swap them.
Turning the raw numbers into −100 to 100, with 0 when the stick is let go.
A centre and a dead zone →Edit this page — content/books/dual-axis-joystick/the-first-read.mdx
Questions about this product
See what other owners have asked, and read their solutions.
Dual Axis Joystick
Loading discussions…
Discuss this article
Ask about this page. The answer stays here, on the page it belongs to, for whoever hits the same wall next.