Features

The buttons of the kode dot are distributed between a directional pad of four buttons and two independent buttons. With these buttons you can navigate through kodeOS, control the state of the ESP32-S3 and turn the device on or off.

Connection diagram

All buttons are connected to the IO expander, except for the top button that is connected directly to the ESP32-S3. In addition, all have a physical pull-up resistor. The connection of the buttons is as follows:
ButtonIO expander
Left padEXP7
Up padEXP6
Right padEXP11
Down padEXP8
Up buttonGPIO0
Down buttonEXP9
See IO expander to learn how the IO expander works.
The top button is connected to GPIO0, to control the BOOT state of the ESP32-S3.

Arduino

ESP-IDF

Example code

With this code you can check the functionality of the buttons. Connect the kode dot to the serial monitor and depending on which button you press, you will see a message in the monitor.
buttons_check.ino
/**
 * Detects button presses from a TCA95XX_16BIT I/O expander and a direct ESP32-S3 pin.
 * Uses interrupts to respond to button events without constant polling.
 * Prints the detected button to the serial monitor.
 */
/* ───────── KODE | docs.kode.diy ───────── */

#include <esp_io_expander.hpp> /* Library to control I/O expanders on ESP32 */

/* Expander configuration */
#define CHIP_NAME         TCA95XX_16BIT
#define I2C_SCL_PIN       (47)  /* I2C bus SCL pin */
#define I2C_SDA_PIN       (48)  /* I2C bus SDA pin */
#define EXP_INT_PIN       (18)  /* Expander interrupt pin */
#define I2C_ADDR          (0x20)/* Expander I2C address */

/* Button connections on expander */
#define PAD_UP            6
#define PAD_LEFT          7
#define PAD_DOWN          8
#define PAD_RIGHT         11
#define BUTTON_BOTTOM     9

/* Button connected directly to ESP32-S3 */
#define BUTTON_UP_PIN     0    /* GPIO0 */

/* Expander instance */
esp_expander::Base *expander = nullptr;

/* Flags for pending interrupts */
volatile bool expanderInterrupted = false;
volatile bool buttonUpInterrupted = false;

/* ISR for expander interrupt */
void IRAM_ATTR handleExpanderIRQ() {
  expanderInterrupted = true;
}

/* ISR for button on GPIO0 */
void IRAM_ATTR handleButtonUpIRQ() {
  buttonUpInterrupted = true;
}

void setup() {
  Serial.begin(115200);
  Serial.println("Button interrupt test start");

  /* Initialize expander */
  expander = new esp_expander::TCA95XX_16BIT(I2C_SCL_PIN, I2C_SDA_PIN, I2C_ADDR);
  expander->init();
  expander->begin();

  /* Configure expander pins as inputs */
  expander->pinMode(PAD_UP,        INPUT);
  expander->pinMode(PAD_LEFT,      INPUT);
  expander->pinMode(PAD_DOWN,      INPUT);
  expander->pinMode(PAD_RIGHT,     INPUT);
  expander->pinMode(BUTTON_BOTTOM, INPUT);

  /* Configure expander interrupt pin */
  pinMode(EXP_INT_PIN, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(EXP_INT_PIN),
                  handleExpanderIRQ, FALLING);

  /* Configure direct button on GPIO0 */
  pinMode(BUTTON_UP_PIN, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(BUTTON_UP_PIN),
                  handleButtonUpIRQ, FALLING);

  Serial.println("Setup complete. Waiting for button presses...");
}

void loop() {
  /* If there are no pending interrupts, wait */
  if (!expanderInterrupted && !buttonUpInterrupted) {
    delay(10);
    return;
  }

  /* Handle direct button */
  if (buttonUpInterrupted) {
    buttonUpInterrupted = false;
    Serial.println("→ BUTTON_UP (GPIO0) pressed");
    delay(50);
  }

  /* Handle expander buttons */
  if (expanderInterrupted) {
    expanderInterrupted = false;
    if (expander->digitalRead(PAD_UP) == LOW) {
      Serial.println("→ PAD_UP pressed");
    }
    if (expander->digitalRead(PAD_LEFT) == LOW) {
      Serial.println("→ PAD_LEFT pressed");
    }
    if (expander->digitalRead(PAD_DOWN) == LOW) {
      Serial.println("→ PAD_DOWN pressed");
    }
    if (expander->digitalRead(BUTTON_BOTTOM) == LOW) {
      Serial.println("→ BUTTON_BOTTOM pressed");
    }
    if (expander->digitalRead(PAD_RIGHT) == LOW) {
      Serial.println("→ PAD_RIGHT pressed");
    }
    delay(50);
  }
}

Download examples

You can test the example codes using the Arduino IDE or the ESP-IDF IDE or download the codes in our drive: Examples using the buttons