Si eres un apasionado de la electrónica y la programación, seguro has escuchado hablar del codificador y su utilidad en la interacción con dispositivos como Arduino. En este artículo te explicaremos en detalle cómo funciona este componente y cómo puedes conectarlo de forma sencilla a tu placa Arduino para sacarle el máximo provecho. ¡Sigue leyendo para descubrir todas las posibilidades que ofrece esta herramienta!
Estamos rodeados de codificadores sin siquiera darnos cuenta, ya que se utilizan en muchos objetos cotidianos, desde impresoras y cámaras hasta máquinas CNC y robots. La aplicación más común de un codificador rotatorio es el control de volumen de la radio de un automóvil.
Un codificador rotatorio es un tipo de sensor de posición que convierte la posición angular (rotación) de una perilla en una señal de salida que se puede usar para determinar en qué dirección se gira la perilla.
Los codificadores rotatorios se dividen en dos tipos: absolutos e incrementales. El codificador absoluto informa la posición exacta de la perilla en grados, mientras que el codificador incremental informa el número de incrementos que se ha movido el eje.
El codificador rotatorio utilizado en este tutorial es de tipo incremental.
Codificador rotatorio versus potenciómetro
Los codificadores rotatorios son el equivalente digital moderno de los potenciómetros y son más versátiles.
Los codificadores rotatorios pueden girar 360° sin detenerse, mientras que los potenciómetros solo pueden girar 3/4 del círculo.
Los potenciómetros se utilizan en situaciones en las que es necesario saber la ubicación exacta de la perilla. Los codificadores rotatorios, por otro lado, se utilizan en situaciones en las que es necesario conocer el cambio de posición y no la posición exacta.
¿Cómo funcionan los codificadores rotativos?
Dentro del codificador hay un disco ranurado conectado al pin C, la tierra común. También tiene dos pines de contacto A y B como se muestra a continuación.
A medida que gira la perilla, A y B hacen contacto con el pin de tierra común C en un orden específico dependiendo de en qué dirección gire la perilla.
Al entrar en contacto con el terreno común, se generan dos señales. Estas señales están desfasadas 90° porque un pin hace contacto con tierra común antes que el otro. Se le conoce como Codificación en cuadratura.
Cuando se gira la perilla en el sentido de las agujas del reloj, el pin A se conecta a tierra antes que el pin B. Cuando se gira la perilla en sentido antihorario, el pin B se conecta a tierra antes que el pin A.
Al monitorear cuándo cada pin está conectado o desconectado de tierra, podemos determinar la dirección en la que se gira la perilla. Esto se puede lograr simplemente observando el estado de B a medida que cambia el estado de A.
Si A cambia de estado:
- si B != A, entonces la perilla se gira en el sentido de las agujas del reloj.
- si B = A, la perilla se gira en sentido antihorario.
Asignación de pines del codificador
La asignación de pines del módulo codificador es la siguiente:
Tierra es la conexión a tierra.
VCC es el voltaje de suministro positivo, que normalmente está entre 3,3 y 5 voltios.
SUDOESTE es la salida del interruptor de presión (activo bajo). Cuando se presiona el botón, el voltaje baja.
DT (salida B) es similar a la salida de CLK, pero va por detrás de CLK en un cambio de fase de 90°. Esta salida se utiliza para determinar la dirección de rotación.
CLK (salida A) es el pulso de salida principal utilizado para determinar la cantidad de rotación. Cada vez que se gira la perilla solo un tope (clic) en una dirección u otra, la salida “CLK” pasa por un ciclo de subida a ALTO y luego a BAJO.
Cableado de un codificador rotatorio a un Arduino
Ahora que entendemos cómo funciona el codificador, ¡es hora de usarlo!
Conectemos el codificador al Arduino. Las conexiones son bastante simples. Primero, conecte el pin +V del módulo a la salida de 5V del Arduino y el pin GND a tierra.
Ahora conecte los pines CLK y DT a los pines digitales n.° 2 y n.° 3 respectivamente. Finalmente, conecte el pin SW al pin digital n.° 4.
La siguiente imagen muestra el cableado.
Código de ejemplo 1 de Arduino: lectura del codificador rotatorio
Nuestro primer ejemplo es muy simple; Simplemente detecta el sentido de rotación del codificador y cuándo se presiona el botón.
Pruebe primero el boceto y luego lo analizaremos con más detalle.
// Rotary Encoder Inputs
#define CLK 2
#define DT 3
#define SW 4
int counter = 0;
int currentStateCLK;
int lastStateCLK;
String currentDir ="";
unsigned long lastButtonPress = 0;
void setup() {
// Set encoder pins as inputs
pinMode(CLK,INPUT);
pinMode(DT,INPUT);
pinMode(SW, INPUT_PULLUP);
// Setup Serial Monitor
Serial.begin(9600);
// Read the initial state of CLK
lastStateCLK = digitalRead(CLK);
}
void loop() {
// Read the current state of CLK
currentStateCLK = digitalRead(CLK);
// If last and current state of CLK are different, then pulse occurred
// React to only 1 state change to avoid double count
if (currentStateCLK != lastStateCLK && currentStateCLK == 1){
// If the DT state is different than the CLK state then
// the encoder is rotating CCW so decrement
if (digitalRead(DT) != currentStateCLK) {
counter --;
currentDir ="CCW";
} else {
// Encoder is rotating CW so increment
counter ++;
currentDir ="CW";
}
Serial.print("Direction: ");
Serial.print(currentDir);
Serial.print(" | Counter: ");
Serial.println(counter);
}
// Remember last CLK state
lastStateCLK = currentStateCLK;
// Read the button state
int btnState = digitalRead(SW);
//If we detect LOW signal, button is pressed
if (btnState == LOW) {
//if 50ms have passed since last LOW pulse, it means that the
//button has been pressed, released and pressed again
if (millis() - lastButtonPress > 50) {
Serial.println("Button pressed!");
}
// Remember last button press event
lastButtonPress = millis();
}
// Put in a slight delay to help debounce the reading
delay(1);
}
Debería ver un resultado similar en el monitor serie.
Si la rotación informada es la opuesta a la esperada, intente intercambiar los pines CLK (Salida A) y DT (Salida B).
Explicación del código:
El boceto comienza especificando los pines Arduino a los que están conectados los pines CLK, DT y SW del codificador.
#define CLK 2
#define DT 3
#define SW 4
Luego se definen algunas variables.
- El
counter
La variable aumenta cada vez que se gira la perilla una muesca (clic). - las variables
currentStateCLK
YlastStateCLK
Guarda el estado de la salida CLK y se utiliza para calcular la cantidad de rotación. - Una cadena que contiene el nombre.
currentDir
se utiliza para mostrar la dirección de rotación actual en el monitor serie. - La variable
lastButtonPress
se utiliza para rebotar un interruptor.
int counter = 0;
int currentStateCLK;
int lastStateCLK;
String currentDir ="";
unsigned long lastButtonPress = 0;
En la sección de configuración, primero configuramos las conexiones del codificador como entradas y luego habilitamos la entrada pull-up en el pin SW. También configuramos el monitor serial.
Finalmente, leemos el valor actual del pin CLK y lo guardamos en la variable lastStateCLK
.
pinMode(CLK,INPUT);
pinMode(DT,INPUT);
pinMode(SW, INPUT_PULLUP);
Serial.begin(9600);
lastStateCLK = digitalRead(CLK);
En la sección de bucle comprobamos nuevamente el estado de CLK y lo comparamos con el lastStateCLK
Valor. Si son diferentes significa que se ha girado el mando. También comprobamos si currentStateCLK
es 1 para reaccionar solo ante un cambio de estado y evitar el doble conteo.
currentStateCLK = digitalRead(CLK);
if (currentStateCLK != lastStateCLK && currentStateCLK == 1){
Dentro de if
Se determina el sentido de rotación. Para lograr esto, simplemente leemos el pin DT y lo comparamos con el estado actual del pin CLK.
- Si estos dos valores son diferentes, significa que el mando está girado en sentido antihorario. El
counter
luego se reduce y elcurrentDir
está configurado en “CCW”. - Si estos dos valores son iguales, significa que la perilla está girada en el sentido de las agujas del reloj. El
counter
luego se incrementa y elcurrentDir
está ajustado en “CW”.
if (digitalRead(DT) != currentStateCLK) {
counter --;
currentDir ="CCW";
} else {
counter ++;
currentDir ="CW";
}
Luego, los resultados se imprimen en el monitor serie.
Serial.print("Direction: ");
Serial.print(currentDir);
Serial.print(" | Counter: ");
Serial.println(counter);
Siguiendo el if
Declaración, actualizamos lastStateCLK
con el estado actual de CLK.
lastStateCLK = currentStateCLK;
El siguiente paso es leer y eliminar el rebote del interruptor de botón. Primero leemos el estado actual de la clave y, cuando cambia a BAJO, esperamos 50 ms hasta que la clave rebote.
Si el botón permanece BAJO durante más de 50 ms, esto indica que realmente fue presionado. Como resultado, imprimimos «¡Botón presionado!» en el monitor en serie.
int btnState = digitalRead(SW);
if (btnState == LOW) {
if (millis() - lastButtonPress > 50) {
Serial.println("Button pressed!");
}
lastButtonPress = millis();
}
Luego repetimos el proceso.
Código de muestra 2 de Arduino: uso de interrupciones
Para leer el codificador, necesitamos monitorear constantemente los cambios en las señales DT y CLK.
Una forma de detectar estos cambios es sondearlos continuamente, como hicimos en nuestro boceto anterior. Sin embargo, no es la mejor solución por las siguientes razones.
- A menudo necesitamos comprobar si el valor ha cambiado. Si el nivel de la señal no cambia, se desperdician ciclos.
- Existe la posibilidad de latencia entre el momento en que ocurre el evento y el momento en que lo revisamos. Cuando necesitamos responder rápidamente, esta latencia provoca retrasos.
- Si el cambio dura poco tiempo, existe la posibilidad de que el cambio de señal se pase por alto por completo.
Una forma de lidiar con esto es usar interrumpe.
Con las interrupciones no es necesario preguntar constantemente por un evento específico. Esto permite que Arduino realice otras tareas sin perderse ningún evento.
alambrado
Dado que la mayoría de las placas Arduino (incluida Arduino UNO) solo tienen dos interrupciones externas, solo podemos monitorear los cambios en las señales DT y CLK. Por lo tanto eliminaremos la conexión del pin SW.
Algunas placas (como la Arduino Mega 2560) tienen más interrupciones externas que otras. Si tiene uno de estos, puede conservar la conexión del pin SW y modificar el siguiente esquema para incluir el código del botón pulsador.
El diseño de cableado actualizado es el siguiente:
código arduino
A continuación se muestra un ejemplo de lectura de un codificador con interrupciones.
// Rotary Encoder Inputs
#define CLK 2
#define DT 3
int counter = 0;
int currentStateCLK;
int lastStateCLK;
String currentDir ="";
void setup() {
// Set encoder pins as inputs
pinMode(CLK,INPUT);
pinMode(DT,INPUT);
// Setup Serial Monitor
Serial.begin(9600);
// Read the initial state of CLK
lastStateCLK = digitalRead(CLK);
// Call updateEncoder() when any high/low changed seen
// on interrupt 0 (pin 2), or interrupt 1 (pin 3)
attachInterrupt(0, updateEncoder, CHANGE);
attachInterrupt(1, updateEncoder, CHANGE);
}
void loop() {
//Do some useful stuff here
}
void updateEncoder(){
// Read the current state of CLK
currentStateCLK = digitalRead(CLK);
// If last and current state of CLK are different, then pulse occurred
// React to only 1 state change to avoid double count
if (currentStateCLK != lastStateCLK && currentStateCLK == 1){
// If the DT state is different than the CLK state then
// the encoder is rotating CCW so decrement
if (digitalRead(DT) != currentStateCLK) {
counter --;
currentDir ="CCW";
} else {
// Encoder is rotating CW so increment
counter ++;
currentDir ="CW";
}
Serial.print("Direction: ");
Serial.print(currentDir);
Serial.print(" | Counter: ");
Serial.println(counter);
}
// Remember last CLK state
lastStateCLK = currentStateCLK;
}
Tenga en cuenta que el bucle principal de este programa se deja vacío, por lo que Arduino está ocupado sin hacer nada.
Ahora, cuando gire la perilla, debería ver una salida similar en el monitor serie.
Explicación del código:
Este boceto solo monitorea los pines digitales 2 (correspondiente a la interrupción 0) y 3 (correspondiente a la interrupción 1) para detectar cambios de señal. En otras palabras, detecta cuando el voltaje cambia de ALTO a BAJO o de BAJO a ALTO girando la perilla.
Cuando ocurre un cambio, Arduino lo detecta inmediatamente, guarda su estado de ejecución y ejecuta la función. updateEncoder()
(también conocido como Interrumpir la rutina del servicio. o simplemente ISR) y luego vuelve a lo que estaba haciendo antes.
Las siguientes dos líneas configuran las interrupciones. El attachInterrupt()
La función le dice al Arduino qué pin monitorear, qué ISR ejecutar cuando se activa la interrupción y qué tipo de disparador buscar.
attachInterrupt(0, updateEncoder, CHANGE);
attachInterrupt(1, updateEncoder, CHANGE);
Código de ejemplo 3 de Arduino: control del servomotor con codificador rotatorio
En el siguiente ejemplo, utilizamos un codificador rotatorio para controlar la posición de un servomotor.
Este proyecto puede resultar muy útil en diversas situaciones. Por ejemplo, si desea operar un brazo robótico, puede ayudarle a colocar con precisión el brazo y su mango.
Si no está familiarizado con los servomotores, lea el siguiente tutorial.
LECTURAS SUGERIDAS
alambrado
Incluyamos un servomotor en nuestro proyecto. Conecte el cable rojo del servomotor al suministro externo de 5 V, el cable negro/marrón a tierra y el cable naranja/amarillo al pin digital 9 habilitado para PWM.
Por supuesto, puedes utilizar la salida de 5 V del Arduino. Sin embargo, tenga en cuenta que el servo puede causar ruido eléctrico en la línea de suministro de 5 V que podría dañar su Arduino. Por lo tanto, se recomienda utilizar una fuente de alimentación externa.
código arduino
Aquí está el código para usar el codificador rotatorio para controlar con precisión el servomotor. Cada vez que se gira la perilla un tope (clic), la posición del brazo del servo cambia un grado.
// Include the Servo Library
#include <Servo.h>
// Rotary Encoder Inputs
#define CLK 2
#define DT 3
Servo servo;
int counter = 0;
int currentStateCLK;
int lastStateCLK;
void setup() {
// Set encoder pins as inputs
pinMode(CLK,INPUT);
pinMode(DT,INPUT);
// Setup Serial Monitor
Serial.begin(9600);
// Attach servo on pin 9 to the servo object
servo.attach(9);
servo.write(counter);
// Read the initial state of CLK
lastStateCLK = digitalRead(CLK);
}
void loop() {
// Read the current state of CLK
currentStateCLK = digitalRead(CLK);
// If last and current state of CLK are different, then pulse occurred
// React to only 1 state change to avoid double count
if (currentStateCLK != lastStateCLK && currentStateCLK == 1){
// If the DT state is different than the CLK state then
// the encoder is rotating CCW so decrement
if (digitalRead(DT) != currentStateCLK) {
counter --;
if (counter<0)
counter=0;
} else {
// Encoder is rotating CW so increment
counter ++;
if (counter>179)
counter=179;
}
// Move the servo
servo.write(counter);
Serial.print("Position: ");
Serial.println(counter);
}
// Remember last CLK state
lastStateCLK = currentStateCLK;
}
Explicación del código:
Si comparas este boceto con nuestro primer boceto, notarás que son bastante similares con algunas excepciones.
Para comenzar, incluiremos la biblioteca de servos Arduino incorporada y crearemos un objeto Servo para representar nuestro servomotor.
#include <Servo.h>
Servo servo;
En la configuración, conectamos el objeto servo al pin 9 (al que está conectado el pin de control del servomotor).
servo.attach(9);
En el bucle, limitamos el contador al rango de 0 a 179 porque los servomotores solo aceptan valores dentro de este rango.
if (digitalRead(DT) != currentStateCLK) {
counter --;
if (counter<0)
counter=0;
} else {
counter ++;
if (counter>179)
counter=179;
}
Finalmente, el valor del contador se utiliza para posicionar el servomotor.
servo.write(counter);
Cómo funciona el codificador rotativo y cómo conectarlo a Arduino
Estamos rodeados de codificadores rotativos sin siquiera darnos cuenta, ya que se utilizan en tantos elementos cotidianos, desde impresoras y cámaras hasta máquinas CNC y robots. La aplicación más común de un codificador rotativo es la perilla de volumen de un radio de automóvil.
Tipos de codificadores rotativos
Un codificador rotativo es un tipo de sensor de posición que convierte la posición angular (rotación) de una perilla en una señal de salida que se puede utilizar para determinar en qué dirección se gira la perilla. Los codificadores rotativos se clasifican en dos tipos: absolutos e incrementales. El codificador absoluto informa la posición exacta de la perilla en grados, mientras que el codificador incremental informa el número de incrementos que el eje se ha movido. El codificador rotativo utilizado en este tutorial es del tipo incremental.
Los codificadores rotativos son el equivalente digital moderno de los potenciómetros y son más versátiles. Los codificadores rotativos pueden girar 360° sin detenerse, mientras que los potenciómetros solo pueden girar 3/4 de círculo. Los potenciómetros se utilizan en situaciones donde se necesita conocer la posición exacta de la perilla. Los codificadores rotativos, por otro lado, se utilizan en situaciones donde se necesita conocer el cambio de posición en lugar de la posición exacta.
¿Cómo funcionan los codificadores rotativos?
En el interior del codificador hay un disco ranurado que está conectado al pin C, la tierra común. También tiene dos pines de contacto A y B. Cuando giras la perilla, A y B hacen contacto con el pin común C en un orden específico dependiendo de la dirección en la que gires la perilla.
Cuando hacen contacto con tierra común, se generan dos señales. Estas señales están desfasadas 90° porque un pin hace contacto con tierra común antes que el otro, lo que se conoce como codificación en cuadratura.
Al monitorear cuándo cada pin hace contacto o deja de hacer contacto con tierra, podemos determinar la dirección en la que se gira la perilla. Esto se puede lograr simplemente observando el estado de B cuando el estado de A cambia.
La conexión del codificador rotativo a Arduino se puede hacer de la siguiente manera:
- Conectar el pin +V del módulo a la salida de 5V de Arduino y el pin GND a tierra.
- Conectar los pines CLK y DT a los pines digitales #2 y #3, respectivamente.
- Conectar el pin SW al pin digital #4.
Para ver ejemplos de códigos para leer codificadores rotativos con Arduino, puedes consultar el sitio oficial de Arduino para obtener más información.
¡Qué buena información! Me ha ayudado a entender mejor cómo usar el codificador con Arduino. ¡Gracias por compartir!
Interesante, me gustaría probarlo en mi propio proyecto con Arduino.