> ## Documentation Index
> Fetch the complete documentation index at: https://docs.kode.diy/llms.txt
> Use this file to discover all available pages before exploring further.

# Botones

> Entiende la distribución de los botones y cómo usarlos en tus proyectos.

# 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ón         | Expansor de pines |
| ------------- | ----------------- |
| Pad Izquierdo | EXP7              |
| Pad Arriba    | EXP6              |
| Pad Derecha   | EXP11             |
| Pad Abajo     | EXP8              |
| Botón Arriba  | GPIO0             |
| Botón Abajo   | EXP9              |

<Note>Ve a [Expansor de pines](/es/kode-dot/io-expander) para conocer cómo funciona el expansor de pines.</Note>
<Tip>El botón de arriba está conectado al pin GPIO0, para controlar el estado BOOT del ESP32-S3.</Tip>

## Librerías recomendadas

### Arduino

* [ESP32\_IO\_Expander](https://github.com/esp-arduino-libs/ESP32_IO_Expander)

### ESP-IDF

* [button](https://components.espressif.com/components/espressif/button)
* [esp\_io\_expander\_tca95xx\_16bit](https://components.espressif.com/components/espressif/esp_io_expander_tca95xx_16bit)

## 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.

```cpp buttons_check.ino lines icon="microchip"	 theme={null}
/**
 * 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](https://drive.google.com/drive/folders/1-K3qP_pf7niBGDafzZQtoZ7c4Zyx9w1W)
