mechanical key/Using it/07. The first press
Using it · 07 of 9

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

Four wires
Your board
VCC to
3V3
WS2812 to
GPIO 5
BUTTON to
GPIO 4
GND to GND, VCC to 3V3, WS2812 to GPIO 5, BUTTON to GPIO 4. None of them is a strapping pin or a flash pin, so the block cannot stop the board from starting. Not the 5V pin: a press would put about 4.6 V on GPIO 4.

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   released

The 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 TK96 on a LEGO baseplate, cabled to an Uno-format TinkerBlock board beside a TK01 XL LED. A finger presses the key and the XL LED lights.
The TK96 wired to a Raspberry Pi Pico 2 on a LEGO baseplate with jumper wires, beside a TK01 XL LED. A finger presses the key and the XL LED lights.

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.

key_first_press.ino
/*
  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.8

When it does not work

It prints HIGH and LOW but the key never lights.

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.

It prints nothing when I press.

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.

One press printed HIGH, LOW, HIGH.

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.

The serial monitor stays empty on my ESP32-S3.

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.

Where this goes next

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

Community

Questions about this product

See what other owners have asked, and read their solutions.

Ask a question ↗

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.

Browse Modules and blocks on the forum →