Características

Los botones del kode dot se distribuyen entre un pad direccional de cuatro botones y dos botones independientes. Con estos botones se puede navegar por kodeOS, controlar el estado del ESP32-S3 y apagar o encender el dispositivo.

Esquema de conexión

Todos los botones están conectados al expansor de pines, exceptuando el botón de arriba que está conectado directamente al ESP32-S3. Además, todos tienen conectada una resistencia de pull-up física. La conexión de los botones es la siguiente:
BotónExpansor de pines
Pad IzquierdoEXP7
Pad ArribaEXP6
Pad DerechaEXP11
Pad AbajoEXP8
Botón ArribaGPIO0
Botón AbajoEXP9
Ve a Expansor de pines para conocer cómo funciona el expansor de pines.
El botón de arriba está conectado al pin GPIO0, para controlar el estado BOOT del ESP32-S3.

Librerías recomendadas

Arduino

ESP-IDF

Ejemplo de código

Con este código puedes comprobar el funcionamiento de los botones. Conecta el kode dot al monitor serie y según qué botón pulses, verás un mensaje en el monitor.
buttons_check.ino
/**
 * Detecta pulsaciones de botones conectados a un expansor I/O TCA95XX_16BIT y a un pin directo del ESP32-S3.
 * Usa interrupciones para responder a eventos de pulsación sin necesidad de sondeo constante.
 * Muestra en el monitor serie el botón detectado.
 */
/* ───────── KODE | docs.kode.diy ───────── */

#include <esp_io_expander.hpp> /* Librería para controlar expansores de I/O en ESP32 */

/* Configuración del expansor */
#define CHIP_NAME         TCA95XX_16BIT
#define I2C_SCL_PIN       (47)  /* Pin SCL del bus I2C */
#define I2C_SDA_PIN       (48)  /* Pin SDA del bus I2C */
#define EXP_INT_PIN       (18)  /* Pin de interrupción del expansor */
#define I2C_ADDR          (0x20)/* Dirección I2C del expansor */

/* Conexiones de botones en el expansor */
#define PAD_UP            6
#define PAD_LEFT          7
#define PAD_DOWN          8
#define PAD_RIGHT         11
#define BUTTON_BOTTOM     9

/* Botón conectado directamente al ESP32-S3 */
#define BUTTON_UP_PIN     0    /* GPIO0 */

/* Instancia del expansor */
esp_expander::Base *expander = nullptr;

/* Banderas para interrupciones pendientes */
volatile bool expanderInterrupted = false;
volatile bool buttonUpInterrupted = false;

/* ISR para interrupción del expansor */
void IRAM_ATTR handleExpanderIRQ() {
  expanderInterrupted = true;
}

/* ISR para el botón en GPIO0 */
void IRAM_ATTR handleButtonUpIRQ() {
  buttonUpInterrupted = true;
}

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

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

  /* Configura pines del expansor como entradas */
  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);

  /* Configura pin de interrupción del expansor */
  pinMode(EXP_INT_PIN, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(EXP_INT_PIN),
                  handleExpanderIRQ, FALLING);

  /* Configura botón directo en GPIO0 */
  pinMode(BUTTON_UP_PIN, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(BUTTON_UP_PIN),
                  handleButtonUpIRQ, FALLING);

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

void loop() {
  /* Si no hay interrupciones pendientes, espera */
  if (!expanderInterrupted && !buttonUpInterrupted) {
    delay(10);
    return;
  }

  /* Gestiona botón directo */
  if (buttonUpInterrupted) {
    buttonUpInterrupted = false;
    Serial.println("→ BUTTON_UP (GPIO0) pressed");
    delay(50);
  }

  /* Gestiona botones del expansor */
  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);
  }
}

Descarga de ejemplos

Puedes probar los códigos de ejemplo mediante el IDE de Arduino o el IDE de ESP-IDF o descargar los códigos en nuestro drive: Ejemplos usando los botones