La detección de la pulsación, interruptores o incluso relés en las placas ESP32 es básica para la realización de dispositivos con los que podamos interactuar. Resulta importante por tanto entender como se debe hacer el uso de este tipo de dispositivos y su interacción con nuestras placas y dispositivos basados en ESP32.
Tabla de contenidos
Primer intento: Conexión directa del puerto a +5V o a GND
Para detectar la activación de un puerto de nuestra placa puede parecer adecuado conectar directamente la salida de tensión a uno de los pines a través del relé o bien la salida GND. En ambos casos, al realizarse la pulsación obtendremos un estado HIGH en el caso de conectar a +5V o un estado LOW al conectar a GND. Este resultado parece el correcto pero la realidad es algo más compleja.
Este diseño puede parecer acertado pero genera un problema ya que funciona correctamente cuando el pulsador/interruptor se activa pero cuando el circuito se encuentra abierto, el estado que se puede leer en el puerto GPIO es indeterminado, por este motivo se hace necesario que si al activar queremos detectar estado HIGH, el estado sin activar debe ser LOW y así recíprocamente.
Segundo intento: Doble conexión a +5v y a GND. Spoiler: Provocando un cortocircuito
Para evitar que el sistema se encuentre en un estado indeterminado al no activar el pulsador, podríamos buscar una formula que permita mantener por ejemplo el estado LOW por defecto y conectar a 5V cuando se cierre el relé.
La solución podría ser algo como lo siguiente:
Al revisar cualquiera de estos dos esquemas podemos observar que el estado por defecto cuando no está activado el pulsador está determinado. En el primero es LOW ya que esta conectado a GND y en el segundo HIGH ya que está conectado a +5V.
El problema es que tal y como se observa, en el momento en el que activemos el relé o pulsador, en lugar de cambiar el estado conectamos directamente la salida de tensión a GND provocando un cortocircuito. Por este motivo lo que aparentemente era una solución, en realidad vuelve a no ser eficaz y nos genera un nuevo problema.
Tercer intento: La solución utilizando resistencias (Pull-Up o Pull-Down)
Finalmente para subsanar los problemas que hemos ido viendo, es necesario realizar un circuito ligeramente más complejo para poder determinar el estado del relé en todos los momentos y a la vez evitar un cortocircuito. Este circuito se conoce por el uso de Resistencia Pull-Down o Resistencia Pull-Up en función de cómo se utilice.
En este último esquema se aprecia el uso de estas resistencias, tanto en la modalidad Pull-Down, como en la modalidad Pull-Up. En el primer caso, el estado por defecto del Pin del ESP32 es LOW y cuando se activa el relé pasa a estado HIGH evitando mediante la resistencia provocar un cortocircuito con el uso de la resistencia Pull-Down.
En el segundo caso, la modalidad Pull-Up, mantiene el estado HIGH con el relé abierto y una vez que se activa cambia al estado LOW.
Uso de la resistencia interna del ESP-32
Hay que recordar, que el uso de estas resistencias es recomendable pero si profundizamos ligeramente en el ESP-32, podemos encontrar, tal y como vimos en el artículo Mapeo de Pines y Sensores Internos del ESP-32, salvo los pines 34 a 39, el resto cuentan con una resistencia que se puede activar mediante código.
Por este motivo, a pesar de la explicación y de la recomendación de hacer uso de este sistema para controlar el estado de nuestro pulsador, cabe la posibilidad de definir mediante constantes el uso de esta resistencia para que se encuentre activada en los GPIO y evitar la conexión externa.
pinMode(17, INPUT_PULLUP);
pinMode(17, INPUT_PULLDOWN);
En los ejemplos anteriores, al declarar el GPIO que vamos a utilizar, en nuestro ejemplo el 17, activamos la resistencia en una de las modalidades que hemos visto en nuestro ejemplo. De esta forma evitamos el uso de resistencias externas y en todo caso el valor del GPIO estaría determinado.
Un ejemplo completo del uso en el código de estas resistencias es el siguiente:
// Definición de uso de los pines const int pulsadorGPIO = 3; const int ledGPIO = 15; bool estadoBoton = false; void setup(){ // Activamosde los GPIO, el de entrada en modalidad PULL DOWN pinMode(pulsadorGPIO, INPUT_PULLDOWN); pinMode(ledGPIO, OUTPUT); } void loop() { // Leemos el estado del GPIO estadoBoton = digitalRead(pulsadorGPIO); // Controlamos el led según el resultado if (estadoBoton == HIGH) { digitalWrite(ledPin, HIGH); } else { digitalWrite(ledPin, LOW); } }
Mediante este pequeño código, conectando el + del led al GPIO 15, el – a GND, el pulsador al GPIO 3 y el otro terminal a +3v, conseguimos que nuestro sistema detecte el estado LOW mientras el pulsador se encuentra desconectado y al activarlo pasa al estado HIGH, provocando el encendido del led.
En nuestro ejemplo no hacemos uso de resistencias externas ya que hemos activado mediante código la resistencia Pull-Down en el GPIO 3.