The first press
Four wires, one library, and a sketch that reads BUTTON, lights the key red while it is held and prints each change. BUTTON goes to the TK04 book's pin: D2 on an Uno, GPIO 25 on an ESP32, GPIO 4 on an ESP32-S3, GP15 on a Pico.
Four 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. WS2812 to an output pin. BUTTON to an input pin.
One library
In the Arduino IDE, open the Library Manager and install Adafruit
NeoPixel. It knows how to make the WS2812's pulses on every board in this
book. MicroPython needs nothing: neopixel is built into the ESP32 and Pico
firmware.
The sketch
pinMode(BUTTON_PIN, INPUT) makes the key's pin an input with nothing of its
own switched on, because the block already has its pull-down.
Adafruit_NeoPixel key(1, LED_PIN, NEO_GRB + NEO_KHZ800) describes the
light: one LED, on that pin, green first, 800 kbit/s.
The loop reads BUTTON and compares it with the last reading. Only when it
changes does the sketch set the colour, call key.show() and print a line.
Setting the colour alone changes nothing on the wire; show() sends the 24
bits.
Red is on purpose. On a 3.3 V board the LED runs below its rated supply, and red is the colour that holds up there; One VCC, two jobs explains why.
What you should see
Press and release, and the serial monitor at 115200 prints:
HIGH pressed
LOW releasedThe key glows red for exactly as long as you hold it. Sometimes a press prints HIGH, LOW, HIGH in quick succession: the contacts bouncing, which the next sketch deals with.
An earlier demo
These two clips are from before this handbook, when the example drove a separate TK01 XL LED instead of the key's own light. The key half is the same.
The code
Adafruit NeoPixel drives the LED; digitalRead reads the key. loop() reads BUTTON every 5 ms and, when it changes, sets the key red or off, calls show() and prints the new level. Change BUTTON_PIN and LED_PIN to the pins you wired.
/*
Mechanical Key and LED - the first press TK96 / /p/tk96
Wiring. Count from the square pad on the TinkerBlock board, key
up, header at the bottom:
GND -> GND
VCC -> 5V on an Uno; 3V3 on an ESP32, ESP32-S3 or Pico
(pressed, BUTTON gives your pin whatever VCC is)
WS2812 -> D6 on an Uno, GPIO 4 on an ESP32, GPIO 5 on an
ESP32-S3, GP14 on a Raspberry Pi Pico
BUTTON -> D2 on an Uno, GPIO 25 on an ESP32, GPIO 4 on an
ESP32-S3, GP15 on a Raspberry Pi Pico
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)
Library Manager: install "Adafruit NeoPixel".
*/
#include <Adafruit_NeoPixel.h>
// The GPIO number BUTTON is wired to.
// Uno: 2. ESP32: 25. ESP32-S3: 4. Pico: 15.
const int BUTTON_PIN = 4;
// The GPIO number the WS2812 pin is wired to.
// Uno: 6. ESP32: 4. ESP32-S3: 5. Pico: 14.
const int LED_PIN = 5;
// One LED on the block. It reads green first, at 800 kbit/s.
Adafruit_NeoPixel key(1, LED_PIN, NEO_GRB + NEO_KHZ800);
int last = LOW;
void setup() {
Serial.begin(115200);
pinMode(BUTTON_PIN, INPUT); // the block has its own pull-down
key.begin();
key.show(); // a dark frame: the LED starts unset
}
void loop() {
int level = digitalRead(BUTTON_PIN);
if (level != last) { // print only when it changes
last = level;
if (level == HIGH) {
key.setPixelColor(0, key.Color(255, 0, 0)); // red
Serial.println("HIGH pressed");
} else {
key.setPixelColor(0, 0); // off
Serial.println("LOW released");
}
key.show(); // nothing changes until show()
}
delay(5);
}INPUT, not INPUT_PULLUP: the block has its own 10 kΩ pull-down, and HIGH means pressed. show() once in setup() sends a dark frame, so the LED starts in a known state. The sketch compiles for an ESP32-S3 and an Uno.
View on GitHub · blocks/tk96-mechanical-key/arduino/key_first_press/key_first_press.ino @ v1.8The same sketch in MicroPython, for an ESP32, an ESP32-S3 or a Pico. The neopixel module is built in; key[0] is the one LED, and write() sends it.
"""
Mechanical Key and LED - the first press, MicroPython TK96 / /p/tk96
Wiring. Count from the square pad on the TinkerBlock board, key
up, header at the bottom:
GND -> GND
VCC -> 3V3 (never 5V: pressed, BUTTON gives your pin VCC)
WS2812 -> GPIO 4 on an ESP32, GPIO 5 on an ESP32-S3,
GP14 on a Raspberry Pi Pico
BUTTON -> GPIO 25 on an ESP32, GPIO 4 on an ESP32-S3,
GP15 on a Raspberry Pi Pico
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, neopixel and time are built in.
"""
from machine import Pin
from neopixel import NeoPixel
import time
# ESP32: 25 and 4. ESP32-S3: 4 and 5. Pico: 15 and 14.
BUTTON_PIN = 4
LED_PIN = 5
button = Pin(BUTTON_PIN, Pin.IN) # no pull: the block has its own
key = NeoPixel(Pin(LED_PIN), 1) # one LED; it sends green first
key[0] = (0, 0, 0)
key.write() # a dark frame: it starts unset
last = 0
while True:
level = button.value()
if level != last: # print only when it changes
last = level
if level == 1:
key[0] = (255, 0, 0) # red
print("HIGH pressed")
else:
key[0] = (0, 0, 0) # off
print("LOW released")
key.write() # nothing changes until write()
time.sleep_ms(5)There is no Uno here: an Uno cannot run MicroPython. Pass colours as (red, green, blue); the module sends them green first. VCC goes to 3V3 on all three boards. Stop it with Ctrl-C.
View on GitHub · blocks/tk96-mechanical-key/micropython/key_first_press.py @ v1.8When it does not work
The key half works, so look at the light. Check the WS2812 wire is on the pin LED_PIN names, that Adafruit NeoPixel is installed, and that the sketch still calls key.show() after setting the colour. On a 3.3 V board red is the colour most likely to show, which is why the sketch uses it.
Check VCC first: with VCC unconnected the switch has nothing to join BUTTON to, and the pull-down keeps it LOW. Then check BUTTON is on the pin BUTTON_PIN names, the GPIO number printed beside the pin rather than its position on the header.
That is contact bounce: the switch makes and breaks a few times as it closes, and this sketch prints every change it sees. It is harmless here, because it only lights while held. A sketch that counts presses has to wait it out, as the next article's does.
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.
Each press steps to the next mode, and the colour says which mode it is in.
A key that remembers →Edit this page — content/books/mechanical-key/the-first-press.mdx
Questions about this product
See what other owners have asked, and read their solutions.
Mechanical Key and LED
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.