The first read
Three wires and a sketch with no library that prints SIGNAL five times a second, in thousandths of VCC, with the push it names. SIGNAL goes to A0 on an Uno, GPIO 34 on an ESP32, GPIO 4 on an ESP32-S3 and GP26 on a Pico; VCC to 5V on the Uno and 3V3 on the rest.
Three wires
GND to GND. VCC to your board's logic voltage: 5V on an Uno, 3V3 on an ESP32, an ESP32-S3 or a Pico. SIGNAL to the analog pin. NC to nothing.
The sketch
readPermille() is the only part that differs between boards. On an ESP32
or an ESP32-S3 it asks analogReadMilliVolts for calibrated millivolts and
divides by 3300, the VCC it assumes. On an Uno or a Pico it divides the count
by 1023, because those two measure against their own supply, which is VCC.
whichPush() then walks the five lines from
telling them apart,
highest first, and returns the first one the reading is above. Below all
five is nothing pressed.
What you should see
Hold the block with the header on the left and push each way. The serial monitor at 115200 prints, on an Uno:
SIGNAL 0/1000 none
SIGNAL 111/1000 up
SIGNAL 181/1000 press
SIGNAL 272/1000 left
SIGNAL 444/1000 down
SIGNAL 1000/1000 rightA few thousandths either way is normal: 1 % resistors and a little noise. On an ESP32 right prints a little under 1000, often about 940: the top of its ADC, which is still far over the line. Printed five times a second, a push you let go of can sometimes show one line of a lower push on the way down; the next article is about that.
The code
readPermille() turns a reading into thousandths of VCC on any of the four boards: millivolts over 3300 on an ESP32, the count over 1023 on an Uno or a Pico. whichPush() checks the five lines, highest first. loop() prints both five times a second. Change SIGNAL_PIN to the pin you wired.
/*
Five-Direction Joystick - first read TK94 / /p/tk94
Wiring. Parts up, header at the bottom. Count from the square pad,
which is GND at the left-hand end:
GND -> GND
VCC -> 5V on an Uno; 3V3 on an ESP32, ESP32-S3 or Pico
NC -> nothing: it is connected to nothing on the board
SIGNAL -> A0 on an Uno, GPIO 34 on an ESP32, GPIO 4 on an
ESP32-S3, GP26 on a Raspberry Pi Pico (analog)
The names are for the block held with the header on the left,
the way the words on its front read.
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 analog pin SIGNAL is wired to.
// Uno: A0. ESP32: 34. ESP32-S3: 4. Pico: 26.
const int SIGNAL_PIN = 4;
// The pushes, highest level first, and the line under each one:
// halfway to the next level down, in thousandths of VCC.
const char* NAME[] = {"right", "down", "left", "press", "up"};
const int LIMIT[] = {722, 359, 227, 146, 56};
// SIGNAL in thousandths of VCC, on any of the four boards.
int readPermille() {
#if defined(ARDUINO_ARCH_ESP32)
// Measured against a reference in the chip: calibrated
// millivolts, over VCC's 3300.
return analogReadMilliVolts(SIGNAL_PIN) * 1000L / 3300;
#else
// The Uno and Pico measure against their supply, which is VCC.
return analogRead(SIGNAL_PIN) * 1000L / 1023;
#endif
}
// Which push a reading is: 0 to 4 as in NAME, or -1 for none.
int whichPush(int permille) {
for (int i = 0; i < 5; i++) {
if (permille > LIMIT[i]) return i;
}
return -1;
}
void setup() {
Serial.begin(115200);
}
void loop() {
int p = readPermille();
int d = whichPush(p);
Serial.print("SIGNAL ");
Serial.print(p);
Serial.print("/1000 ");
Serial.println(d < 0 ? "none" : NAME[d]);
delay(200); // five lines a second
}No library and no pinMode: analogRead sets the pin up itself. The lines are halfway between the levels the ladder makes, so they need no calibration. The sketch compiles for an Uno, an ESP32 and an ESP32-S3.
View on GitHub · blocks/tk94-five-direction-joystick/arduino/joystick_first_read/joystick_first_read.ino @ v1.11The same sketch in MicroPython, for an ESP32, an ESP32-S3 or a Pico. On the ESP32s the ADC is set to its full range and read_uv() gives calibrated microvolts; on a Pico read_u16() is a fraction of its 3.3 V.
"""
Five-Direction Joystick - first read, MicroPython TK94 / /p/tk94
Wiring. Parts up, header at the bottom. Count from the square pad,
which is GND at the left-hand end:
GND -> GND
VCC -> 3V3 (never 5V: a push to the right puts VCC on the pin)
NC -> nothing: it is connected to nothing on the board
SIGNAL -> GPIO 34 on an ESP32, GPIO 4 on an ESP32-S3,
GP26 on a Raspberry Pi Pico (analog)
The names are for the block held with the header on the left,
the way the words on its front read.
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 SIGNAL is wired to.
# ESP32: 34. ESP32-S3: 4. Pico: 26.
SIGNAL_PIN = 4
# The pushes, highest level first, and the line under each one:
# halfway to the next level down, in thousandths of VCC.
NAME = ("right", "down", "left", "press", "up")
LIMIT = (722, 359, 227, 146, 56)
ESP = sys.platform == "esp32" # ESP32 and ESP32-S3
adc = ADC(Pin(SIGNAL_PIN))
if ESP:
adc.atten(ADC.ATTN_11DB) # the full range, to about 3.1 V
def read_permille():
if ESP:
return adc.read_uv() // 3300 # calibrated, over VCC's 3.3 V
return adc.read_u16() * 1000 // 65535
def which_push(p):
for i, limit in enumerate(LIMIT):
if p > limit:
return i
return -1
while True:
p = read_permille()
d = which_push(p)
print("SIGNAL %4d/1000 %s" % (p, "none" if d < 0 else NAME[d]))
time.sleep_ms(200) # five lines a secondThere is no Uno here: an Uno cannot run MicroPython. VCC goes to 3V3 on all three boards. Stop it with Ctrl-C.
View on GitHub · blocks/tk94-five-direction-joystick/micropython/joystick_first_read.py @ v1.11When it does not work
Check VCC first: with VCC unconnected the ladder has no top and R14 holds SIGNAL at 0. Then check SIGNAL is on the pin SIGNAL_PIN names, and not on NC, the third hole from the square pad, which goes nowhere.
SIGNAL is not reaching the pin you are reading, which then floats. Check the wire and the number in SIGNAL_PIN: on an ESP32 it is the GPIO number, 34, not the position on the board's header.
The ESP32's ADC tops out a little under 3.3 V, so 3.3 V reads as its ceiling, roughly 3.1 V. It is still far over the line at 722, so the name is right. The other four levels are well inside its range.
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.
A menu that moves once for each push, however long it is held.
One step per push →Edit this page — content/books/five-direction-joystick/the-first-read.mdx
Questions about this product
See what other owners have asked, and read their solutions.
Five-Direction 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.