Arduino - Codificador Rotatorio

En este tutorial, vamos a aprender cómo usar el codificador incremental con Arduino. En detalle, aprenderemos:

Hardware Requerido

1×Arduino Uno R3
1×Cable USB 2.0 tipo A/B (para PC USB-A)
1×Cable USB 2.0 tipo C/B (para PC USB-C)
1×Codificador Rotatorio
1×Cables Puente
1×(Recomendado) Shield de Bloque de Terminales de Tornillo para Arduino Uno
1×(Recomendado) Shield de Protoboard para Arduino Uno
1×(Recomendado) Carcasa para Arduino Uno
1×(Recomendado) Placa Base de Prototipado y Kit de Protoboard para Arduino Uno

Or you can buy the following kits:

1×DIYables STEM V3 Starter Kit (Arduino 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.

Acerca del codificador rotatorio

Un codificador rotatorio es un dispositivo electromecánico que convierte el movimiento de rotación en una señal eléctrica. Mide la rotación y la posición de un eje o perilla. Hay dos tipos principales:

  • Codificador incremental: que genera pulsos para medir el cambio relativo
  • Codificador absoluto: que proporciona un código digital único para cada posición, lo que lo hace ideal para el posicionamiento preciso incluso tras una pérdida de energía

Esta guía trata sobre 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 (LOW HIGH LOW).
  • Pin DT (Salida B): actúa como el pin CLK, pero la señal de salida llega con un desfase de 90 grados respecto a la señal CLK. Nos ayuda a determinar la dirección de rotación (horaria o antihoraria).
  • Pin SW: es la salida del pulsador dentro del codificador rotatorio. Está normalmente abierto. Si usamos una resistencia pull-up en este pin, el pin SW estará en ALTO cuando la perilla no esté presionada, y BAJO cuando esté presionada.
  • Pin VCC (+): debe conectarse a VCC (entre 3,3 y 5 voltios).
  • Pin GND: debe conectarse a GND (0 V).

Codificador rotatorio frente a potenciómetro

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

  • El codificador rotatorio es como la versión moderna de un potenciómetro, pero puede hacer más cosas.
  • El codificador rotatorio puede girar completamente 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 proporciona el voltaje analógico.
  • El codificador rotatorio es útil cuando solo necesitas saber cuánto se ha movido la perilla, no exactamente dónde está. El potenciómetro es útil cuando realmente necesitas saber exactamente dónde está una perilla.

Cómo funciona un codificador rotatorio

salida del codificador rotatorio

Dentro del codificador, hay un disco con ranuras conectado a un pin llamado C, que es como una tierra común. También hay dos pines más, A y B.

  • Cuando giras la perilla, los pines A y B tocan el pin de tierra común C, pero en un cierto orden según la dirección en la que gires la perilla (horario o antihorario).
  • Estos contactos generan dos señales. Tienen un ligero desfase en el tiempo porque uno de los pines toca la tierra antes que el otro. Las dos señales están desfasadas 90 grados entre sí. A esto se le llama codificación en cuadratura.
  • Cuando giras la perilla en dirección horario, el pin A toca la tierra antes que el pin B. Cuando giras la perilla en dirección antihoraria, el pin B toca la tierra antes que el pin A.
  • Al supervisar cuándo cada pin toca o deja la tierra, podemos determinar hacia qué dirección está girando la perilla. Hacemos esto comprobando qué ocurre con el pin B cuando cambia el pin A.
Cómo funciona un codificador rotatorio.

Cuando A cambia de estado de BAJO a ALTO:

  • Si B está bajo, la perilla gira en sentido horario.
  • Si B está alto, la perilla gira en sentido antihorario.

※ Nota:

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

Cómo programar para un codificador rotatorio

  • Verifica la señal del pin CLK
  • Si el estado cambia de bajo a alto, verifica el estado del pin DT.
    • Si el estado del pin DT es alto, la perilla se gira en dirección antihoraria; incrementa el contador en 1
    • Si el estado del pin DT es bajo, la perilla se gira en dirección horarios; disminuye el contador en 1

Diagrama de Cableado

Diagrama de cableado del codificador rotatorio para Arduino

This image is created using Fritzing. Click to enlarge image

Código de Arduino – Codificador rotatorio sin interrupciones

Lo que hace el código de Arduino que se muestra a continuación:

  • Detecta la dirección y la cantidad de giro del codificador.
    • Si detecta que el mando ha girado un tope (clic) en sentido horario, incrementa el contador en uno.
    • Si detecta que el mando ha girado un tope (clic) en sentido antihorario, disminuye el contador en uno.
  • Detecta si el botón está presionado.
/* * Este código de Arduino fue desarrollado por es.newbiely.com * Este código de Arduino se proporciona al público sin ninguna restricción. * Para tutoriales completos y diagramas de cableado, visite: * https://es.newbiely.com/tutorials/arduino/arduino-rotary-encoder */ #include <ezButton.h> // the library to use for SW pin #define CLK_PIN 2 #define DT_PIN 3 #define SW_PIN 4 #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 4 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("DIRECTION: "); if (direction == DIRECTION_CW) Serial.print("Clockwise"); else Serial.print("Counter-clockwise"); Serial.print(" | COUNTER: "); 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 antirrebote del botón, se utiliza la biblioteca ezButton.

Pasos R\u00e1pidos

  • Instala la biblioteca ezButton en el IDE de Arduino. Ver Cómo hacerlo
  • Copia el código anterior y ábrelo con el IDE de Arduino
  • Haz clic en el botón Subir en el IDE de Arduino para cargar el código en Arduino
  • Gira la perilla en sentido horario, luego antihorario
  • Presiona la perilla
  • Ver el resultado en el Monitor Serial.
COM6
Send
DIRECTION: Clockwise | COUNTER: 1 DIRECTION: Clockwise | COUNTER: 2 DIRECTION: Clockwise | COUNTER: 3 DIRECTION: Clockwise | COUNTER: 4 DIRECTION: Clockwise | COUNTER: 5 DIRECTION: Counter-clockwise | COUNTER: 4 DIRECTION: Counter-clockwise | COUNTER: 3 DIRECTION: Counter-clockwise | COUNTER: 2 DIRECTION: Counter-clockwise | COUNTER: 1 DIRECTION: Counter-clockwise | COUNTER: 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 de Arduino – Codificador rotatorio con interrupción

En el código de ejemplo anterior, utilizamos el método de sondeo, que verifica continuamente el estado del pin. Esto tiene dos desventajas:

  • Desperdiciar recursos de Arduino
  • Algunos contadores pueden omitirse si otro código tarda mucho en ejecutarse.

Una forma de manejar esto es mediante interrupciones. Las interrupciones eliminan la necesidad de revisar constantemente un evento en particular. Esto permite que el Arduino lleve a cabo otras tareas sin pasar por alto un evento.

Aquí tienes un ejemplo de cómo leer un codificador rotatorio con interrupciones.

/* * Este código de Arduino fue desarrollado por es.newbiely.com * Este código de Arduino se proporciona al público sin ninguna restricción. * Para tutoriales completos y diagramas de cableado, visite: * https://es.newbiely.com/tutorials/arduino/arduino-rotary-encoder */ #include <ezButton.h> // the library to use for SW pin #define CLK_PIN 2 #define DT_PIN 3 #define SW_PIN 4 #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 4 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_encoderChange() when CLK pin changes from LOW to HIGH attachInterrupt(digitalPinToInterrupt(CLK_PIN), ISR_encoderChange, RISING); } void loop() { button.loop(); // MUST call the loop() function first if (prev_counter != counter) { Serial.print("DIRECTION: "); if (direction == DIRECTION_CW) Serial.print("Clockwise"); else Serial.print("Counter-clockwise"); Serial.print(" | COUNTER: "); Serial.println(counter); prev_counter = counter; } if (button.isPressed()) { Serial.println("The button is pressed"); } // TO DO: your other work here } void ISR_encoderChange() { 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(); }

Ahora, mientras giras la perilla, notarás que la información aparece en el Monitor Serial, al igual que lo que viste en el código anterior.

※ Nota:

  • Si usas la interrupción, necesitas conectar el pin CLK del codificador a un pin de Arduino que pueda manejar interrupciones. Pero recuerda, no todos los pines de Arduino pueden hacerlo. Por ejemplo, en el Arduino Uno, solo los pines 2 y 3 pueden funcionar con interrupciones.
  • Puede que te encuentres con tutoriales en otros sitios web que usen dos interrupciones para un solo codificador, pero esto es innecesario y despilfarrador. Solo una interrupción es suficiente.
  • Es importante usar la palabra clave volatile para las variables globales utilizadas en la interrupción. Omitir esto 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 de Arduino

Con un codificador rotatorio, podemos realizar las siguientes aplicaciones, pero no limitado a:

  • Arduino - El codificador giratorio controla la posición del servomotor
  • Arduino - El codificador giratorio controla el brillo del LED
  • Arduino - El codificador giratorio 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!