ESP32 - Codificador Rotatorio

En esta guía, aprenderás a usar el codificador rotatorio con un ESP32. Esto es lo que aprenderemos:

Hardware Requerido

1×Módulo de Desarrollo ESP32 ESP-WROOM-32
1×Cable USB Tipo-A a Tipo-C (para PC USB-A)
1×Cable USB Tipo-C a Tipo-C (para PC USB-C)
1×Codificador Rotatorio
1×Protoboard
1×Cables Puente
1×(Recomendado) Placa de Expansión de Terminales de Tornillo para ESP32
1×(Recomendado) Breakout Expansion Board for ESP32
1×(Recomendado) Divisor de Alimentación para ESP32

Or you can buy the following kits:

1×DIYables ESP32 Starter Kit (ESP32 included)
1×DIYables Sensor Kit (30 sensors/displays)
1×DIYables Sensor Kit (18 sensors/displays)
Divulgación: Algunos de los enlaces proporcionados en esta sección son enlaces de afiliado de Amazon. Podemos recibir una comisión por las compras realizadas a través de estos enlaces sin costo adicional para usted. Apreciamos su apoyo.

Sobre el codificador rotatorio

Un botón giratorio, como el de una radio, puede enviar señales que se convierten en electricidad. Nos ayuda a saber cuánto ha girado y dónde está colocado. Hay dos tipos principales:

  • Codificador incremental: Este utiliza señales rápidas para medir cuánto cambió la posición de algo.
  • Codificador absoluto: Este tipo proporciona un código secreto para cada posición, lo que nos ayuda a saber dónde está algo, incluso si se corta la energía.

Esta lección se centra principalmente en el primer tipo, el codificador incremental.

Diagrama de pines del módulo codificador rotatorio

Disposición de pines del codificador rotatorio

Un módulo de codificador rotatorio tiene 4 pines:

  • Pin CLK (Salida A): es el pulso principal que nos indica cuánta rotación ha ocurrido. Cada vez que giras la perilla un clic en cualquiera de las direcciones, el pin CLK emite una señal que completa un ciclo completo (BAJO → ALTO → BAJO).
  • Pin DT (Salida B): funciona como el pin CLK, pero emite una señal con un desfase de 90 grados respecto a la señal CLK. Nos ayuda a determinar la dirección de giro (horario o antihorario).
  • Pin SW: proviene del botón del encoder. Normalmente está abierto. Cuando añadimos una resistencia pull-up a este pin, el pin SW estará en ALTO cuando la perilla no esté pulsada y BAJO cuando esté pulsada.
  • Pin VCC (+): debe conectarse a VCC (entre 3,3 y 5 voltios).
  • Pin GND: debe conectarse a GND (0 V).

Codificador giratorio vs Potenciómetro

Podrías confundir el codificador rotatorio con el potenciómetro, pero son componentes distintos. A continuación, una comparación entre ellos:

  • El codificador rotatorio es como la versión moderna del potenciómetro, pero puede hacer más cosas.
  • El codificador rotatorio puede girar por completo en un círculo sin detenerse, mientras que el potenciómetro solo puede girar aproximadamente tres cuartos del círculo.
  • El codificador rotatorio emite pulsos, mientras que el potenciómetro genera el voltaje analógico.
  • El codificador rotatorio es práctico cuando solo necesitas saber cuánto se ha movido la perilla, no exactamente dónde se encuentra. El potenciómetro es útil cuando realmente necesitas saber exactamente dónde se encuentra la perilla.

Cómo funciona un codificador rotatorio

salida del codificador rotatorio

Dentro del codificador, hay un pequeño disco con ranuras que está conectado a un pin llamado C, el cual actúa como una tierra común. Tienes dos pines más, A y B.

  • Cuando giras la perilla, los pines A y B tocan ese pin de tierra compartido C, pero el orden en que lo tocan depende de la dirección en la que giras la perilla (ya sea en sentido horario o antihorario).
  • Estos contactos generan dos señales. Son un poco diferentes en su temporización porque un pin toca la tierra antes que el otro. Esas señales están desfasadas 90 grados, lo que se llama codificación en cuadratura.
  • Si giras la perilla en sentido horario, el pin A toca la tierra antes que el pin B. Pero si lo haces en sentido antihorario, el pin B toca la tierra primero.
  • Al verificar cuándo cada pin toca o se separa de la tierra, podemos averiguar hacia qué dirección está girando la perilla. Hacemos esto al comprobar qué pasa con el pin B cuando el pin A cambia.
Cómo funciona un codificador rotatorio

Cuando A cambia de estado de BAJO a ALTO:

  • Si B está en ALTO, la perilla se gira en sentido antihorario.
  • Si B está en BAJO, la perilla se gira en sentido horario.

※ Nota:

Los pines A y B están conectados a los pines CLK y DT. Sin embargo, dependiendo de los fabricantes, el orden puede variar. Los códigos proporcionados a continuación han sido probados con el codificador rotatorio de DIYables

Cómo programar para un codificador rotatorio

  • ESP32 lee la señal del pin CLK
  • Si el estado cambia de bajo a alto, entonces ESP32 lee el estado del pin DT.
    • Si el pin DT está alto, la perilla se gira en sentido antihorario, ESP32 incrementa el contador en 1
    • Si el pin DT está bajo, la perilla se gira en sentido horario, ESP32 disminuye el contador en 1

Diagrama de Cableado

Diagrama de cableado del codificador rotatorio ESP32

This image is created using Fritzing. Click to enlarge image

Si no sabe c\u00f3mo alimentar ESP32 y otros componentes, encuentre instrucciones en el siguiente tutorial: C\u00f3mo alimentar ESP32.

Código ESP32 – Codificador Rotatorio

El código ESP32 que se muestra abajo hace lo siguiente:

  • Detecta la dirección y la cantidad de rotación del codificador.
    • Si detecta que el mando ha girado un detent (clic) en sentido horario, incremente el contador en uno.
    • Si detecta que el mando ha girado un detent (clic) en sentido antihorario, disminuya el contador en uno.
  • Detecta si el botón está presionado.
/* * Este código de ESP32 fue desarrollado por es.newbiely.com * Este código de ESP32 se proporciona al público sin ninguna restricción. * Para tutoriales completos y diagramas de cableado, visite: * https://es.newbiely.com/tutorials/esp32/esp32-rotary-encoder */ #include <ezButton.h> // the library to use for SW pin #define CLK_PIN 25 // ESP32 pin GPIO25 connected to the rotary encoder's CLK pin #define DT_PIN 26 // ESP32 pin GPIO26 connected to the rotary encoder's DT pin #define SW_PIN 27 // ESP32 pin GPIO27 connected to the rotary encoder's SW pin #define DIRECTION_CW 0 // clockwise direction #define DIRECTION_CCW 1 // counter-clockwise direction int counter = 0; int direction = DIRECTION_CW; int CLK_state; int prev_CLK_state; ezButton button(SW_PIN); // create ezButton object that attach to pin 7; void setup() { Serial.begin(9600); // configure encoder pins as inputs pinMode(CLK_PIN, INPUT); pinMode(DT_PIN, INPUT); button.setDebounceTime(50); // set debounce time to 50 milliseconds // read the initial state of the rotary encoder's CLK pin prev_CLK_state = digitalRead(CLK_PIN); } void loop() { button.loop(); // MUST call the loop() function first // read the current state of the rotary encoder's CLK pin CLK_state = digitalRead(CLK_PIN); // If the state of CLK is changed, then pulse occurred // React to only the rising edge (from LOW to HIGH) to avoid double count if (CLK_state != prev_CLK_state && CLK_state == HIGH) { // if the DT state is HIGH // the encoder is rotating in counter-clockwise direction => decrease the counter if (digitalRead(DT_PIN) == HIGH) { counter--; direction = DIRECTION_CCW; } else { // the encoder is rotating in clockwise direction => increase the counter counter++; direction = DIRECTION_CW; } Serial.print("Rotary Encoder:: direction: "); if (direction == DIRECTION_CW) Serial.print("Clockwise"); else Serial.print("Counter-clockwise"); Serial.print(" - count: "); Serial.println(counter); } // save last CLK state prev_CLK_state = CLK_state; if (button.isPressed()) { Serial.println("The button is pressed"); } }

Para simplificar el código del rebote del botón, se utiliza la biblioteca ezButton.

Pasos R\u00e1pidos

Si es la primera vez que usas ESP32, consulta cómo configurar el entorno para ESP32 en Arduino IDE.

  • Instala ezButton library en Arduino IDE.
  • Copia el código anterior y ábrelo con Arduino IDE
  • Haz clic en el botón Cargar en Arduino IDE para cargar el código en ESP32
  • Gira la perilla en sentido horario, luego en sentido antihorario
  • Presiona la perilla
  • Ve el resultado en el Monitor Serial.
COM6
Send
Rotary Encoder:: direction: CLOCKWISE - count: 1 Rotary Encoder:: direction: CLOCKWISE - count: 2 Rotary Encoder:: direction: CLOCKWISE - count: 3 Rotary Encoder:: direction: CLOCKWISE - count: 4 Rotary Encoder:: direction: CLOCKWISE - count: 5 Rotary Encoder:: direction: ANTICLOCKWISE - count: 4 Rotary Encoder:: direction: ANTICLOCKWISE - count: 3 Rotary Encoder:: direction: ANTICLOCKWISE - count: 2 Rotary Encoder:: direction: ANTICLOCKWISE - count: 1 Rotary Encoder:: direction: ANTICLOCKWISE - count: 0 The button is pressed
Autoscroll Show timestamp
Clear output
9600 baud  
Newline  

Explicación del código

Revisa los comentarios línea por línea en el código.

Código ESP32 – Codificador rotatorio con interrupción

En el código anterior, usar sondeo para comprobar de forma continua el estado del pin puede desperdiciar recursos del ESP32 y provocar conteos perdidos si la ejecución de otro código es lenta.

Una solución efectiva es utilizar la interrupción, lo cual elimina la necesidad de sondear. Esto permite al ESP32 realizar otras tareas sin perder los conteos. A continuación se muestra el código del ESP32 que utiliza la interrupción para leer la dirección y la posición del codificador rotatorio.

/* * Este código de ESP32 fue desarrollado por es.newbiely.com * Este código de ESP32 se proporciona al público sin ninguna restricción. * Para tutoriales completos y diagramas de cableado, visite: * https://es.newbiely.com/tutorials/esp32/esp32-rotary-encoder */ #include <ezButton.h> // the library to use for SW pin #define CLK_PIN 25 // ESP32 pin GPIO25 connected to the rotary encoder's CLK pin #define DT_PIN 26 // ESP32 pin GPIO26 connected to the rotary encoder's DT pin #define SW_PIN 27 // ESP32 pin GPIO27 connected to the rotary encoder's SW pin #define DIRECTION_CW 0 // clockwise direction #define DIRECTION_CCW 1 // counter-clockwise direction volatile int counter = 0; volatile int direction = DIRECTION_CW; volatile unsigned long last_time; // for debouncing int prev_counter; ezButton button(SW_PIN); // create ezButton object that attach to pin 7; void IRAM_ATTR ISR_encoder() { if ((millis() - last_time) < 50) // debounce time is 50ms return; if (digitalRead(DT_PIN) == HIGH) { // the encoder is rotating in counter-clockwise direction => decrease the counter counter--; direction = DIRECTION_CCW; } else { // the encoder is rotating in clockwise direction => increase the counter counter++; direction = DIRECTION_CW; } last_time = millis(); } void setup() { Serial.begin(9600); // configure encoder pins as inputs pinMode(CLK_PIN, INPUT); pinMode(DT_PIN, INPUT); button.setDebounceTime(50); // set debounce time to 50 milliseconds // use interrupt for CLK pin is enough // call ISR_encoder() when CLK pin changes from LOW to HIGH attachInterrupt(digitalPinToInterrupt(CLK_PIN), ISR_encoder, RISING); } void loop() { button.loop(); // MUST call the loop() function first if (prev_counter != counter) { Serial.print("Rotary Encoder:: direction: "); if (direction == DIRECTION_CW) Serial.print("CLOCKWISE"); else Serial.print("ANTICLOCKWISE"); Serial.print(" - count: "); Serial.println(counter); prev_counter = counter; } if (button.isPressed()) { Serial.println("The button is pressed"); } // TO DO: your other work here }

Ahora, a medida que giras la perilla, notarás que aparece información en el Monitor Serial, similar a lo que viste en el código anterior.

※ Nota:

  • Podrías encontrarte con tutoriales en otros sitios web que usan dos interrupciones para un único codificador, pero esto es innecesario y desperdiciado. Solo una interrupción es suficiente.
  • Es importante usar la palabra clave volatile para las variables globales que se utilizan en la interrupción. Ignorarlas podría provocar problemas inesperados.
  • Mantén el código dentro de la interrupción lo más sencillo posible. Evita usar Serial.print() o Serial.println() dentro de la interrupción.

Aplicación del codificador rotatorio para ESP32

Con el codificador rotatorio, podemos realizar las siguientes aplicaciones, pero no se limitan a:

  • ESP32 - El codificador rotatorio controla la posición del servomotor
  • ESP32 - El codificador rotatorio controla el brillo del LED
  • ESP32 - El codificador rotatorio controla la velocidad del motor paso a paso

Video Tutorial

Estamos considerando crear tutoriales en video. Si considera que los tutoriales en video son importantes, suscríbase a nuestro canal de YouTube para motivarnos a crear los videos.

Referencias de funciones

※ NUESTROS MENSAJES

  • No dude en compartir el enlace de este tutorial. Sin embargo, por favor no use nuestro contenido en otros sitios web. Hemos invertido mucho esfuerzo y tiempo en crear el contenido, ¡por favor respete nuestro trabajo!