Tabla de contenido:

Una solución rotativa Arduino completa: 5 pasos
Una solución rotativa Arduino completa: 5 pasos

Video: Una solución rotativa Arduino completa: 5 pasos

Video: Una solución rotativa Arduino completa: 5 pasos
Video: Arduino desde cero en Español - Capítulo 30 - Paso a Paso (unipolar) 28BYJ-48 con Driver ULN2003 2024, Noviembre
Anonim
Una solución rotativa completa de Arduino
Una solución rotativa completa de Arduino

Los codificadores rotatorios son perillas de control giratorias para proyectos electrónicos, que a menudo se utilizan con los microcontroladores de la familia Arduino. Se pueden utilizar para ajustar los parámetros, navegar por los menús, mover objetos en la pantalla, establecer valores de cualquier tipo. Son reemplazos comunes de los potenciómetros, ya que se pueden girar de manera más precisa e infinita, aumentan o disminuyen un valor discreto a la vez y, a menudo, se integran con un interruptor que se puede presionar para funciones de selección. Vienen en todas las formas y tamaños, pero es difícil interactuar con el rango de precios más bajo, como se explica a continuación.

Hay innumerables artículos sobre los detalles de funcionamiento y los modos de uso de los codificadores rotatorios, y numerosos códigos de muestra y bibliotecas sobre cómo usarlos. El único problema es que ninguno de ellos funciona con una precisión del 100% con los módulos rotativos chinos del rango de precio más bajo.

Paso 1: codificadores rotatorios en el interior

Codificadores rotativos en el interior
Codificadores rotativos en el interior
Codificadores rotativos en el interior
Codificadores rotativos en el interior
Codificadores rotativos en el interior
Codificadores rotativos en el interior

La parte giratoria del codificador tiene tres pines (y dos más para la parte del interruptor opcional). Uno es terreno común (GND negro), los otros dos son para determinar la dirección cuando se gira la perilla (a menudo se les llama CLK azul y DT rojo). Ambos están conectados a un pin de entrada PULLUP del microcontrolador, lo que hace que el nivel ALTO sea su lectura predeterminada. Cuando se gira la perilla hacia adelante (o en el sentido de las agujas del reloj), primero el CLK azul cae al nivel LOW, luego sigue el DT rojo. Volviendo más allá, el CLK azul vuelve a subir a ALTO, luego, cuando el parche GND común abandona ambos pines de conexión, el DT rojo también vuelve a subir a ALTO. Completando así un tic completo FWD (o en el sentido de las agujas del reloj). Lo mismo ocurre en la otra dirección BWD (o en sentido contrario a las agujas del reloj), pero ahora el rojo cae primero y el azul vuelve a subir al final, como se muestra en las imágenes de dos niveles, respectivamente.

Paso 2: Miseria que causa dolor real a muchos

Miseria que causa dolor real a muchos
Miseria que causa dolor real a muchos
Miseria que causa dolor real a muchos
Miseria que causa dolor real a muchos
Miseria que causa dolor real a muchos
Miseria que causa dolor real a muchos

Problema común para los aficionados a Arduino, que los módulos de codificador rotatorio baratos rebotan cambios adicionales en los niveles de salida, lo que provoca lecturas de recuento de direcciones adicionales e incorrectas. Esto evita un recuento impecable y hace que sea imposible integrar estos módulos en proyectos rotativos precisos. Estos rebotes adicionales son causados por los movimientos mecánicos de los parches sobre los pines de conexión, e incluso la aplicación de condensadores adicionales no puede eliminarlos por completo. Los rebotes pueden aparecer en cualquier lugar de los ciclos completos de ticks y se ilustran con escenarios de la vida real en las imágenes.

Paso 3: Solución de máquina de estado finito (FSM)

Solución de máquina de estado finito (FSM)
Solución de máquina de estado finito (FSM)

La imagen muestra el espacio de estado completo de los posibles cambios de nivel para los dos pines (CLK azul y DT rojo), tanto para rebotes correctos como falsos. Con base en esta máquina de estado se puede programar una solución completa que siempre funcione con una precisión del 100%. Dado que en esta solución no se necesitan retrasos en el filtrado, también es la más rápida posible. Otro beneficio de separar el espacio de estado de los pines del modo de trabajo es que uno puede aplicar ambos modos de interrogación o interrupción a su gusto. El sondeo o las interrupciones pueden detectar cambios de nivel en los pines y una rutina separada calculará el nuevo estado en función del estado actual y los eventos reales de cambios de nivel.

Paso 4: Código Arduino

Código Arduino
Código Arduino

El siguiente código cuenta los tics FWD y BWD en el monitor en serie y también integra la función de interruptor opcional.

// Peter Csurgay 2019-04-10

// Pines del rotativo asignados a puertos Arduino

#define SW 21 #define CLK 22 #define DT 23

// Valor actual y anterior del contador sintonizado por el rotativo

int curVal = 0; int prevVal = 0;

// Siete estados de FSM (máquina de estados finitos)

#define IDLE_11 0 #define SCLK_01 1 #define SCLK_00 2 #define SCLK_10 3 #define SDT_10 4 #define SDT_00 5 #define SDT_01 6 int state = IDLE_11;

configuración vacía () {

Serial.begin (250000); Serial.println ("Iniciar …"); // El nivel ALTO será el predeterminado para todos los pines pinMode (SW, INPUT_PULLUP); pinMode (CLK, INPUT_PULLUP); pinMode (DT, INPUT_PULLUP); // Tanto CLK como DT activarán interrupciones para todos los cambios de nivel attachInterrupt (digitalPinToInterrupt (CLK), rotaryCLK, CHANGE); attachInterrupt (digitalPinToInterrupt (DT), rotaryDT, CHANGE); }

bucle vacío () {

// Manejo del interruptor opcional integrado en algunos codificadores rotativos if (digitalRead (SW) == LOW) {Serial.println ("Pressed"); while (! digitalRead (SW)); } // Cualquier cambio en el valor del contador se muestra en Serial Monitor if (curVal! = PrevVal) {Serial.println (curVal); prevVal = curVal; }}

// Transiciones de máquina de estado para cambios de nivel CLK

void rotaryCLK () {if (digitalRead (CLK) == LOW) {if (state == IDLE_11) state = SCLK_01; si no (estado == SCLK_10) estado = SCLK_00; si no (estado == SDT_10) estado = SDT_00; } else {if (estado == SCLK_01) estado = IDLE_11; si no (estado == SCLK_00) estado = SCLK_10; si no (estado == SDT_00) estado = SDT_10; de lo contrario si (estado == SDT_01) {estado = IDLE_11; curVal--; }}}

// Transiciones de máquina de estado para cambios de nivel de DT

void rotaryDT () {if (digitalRead (DT) == LOW) {if (state == IDLE_11) state = SDT_10; de lo contrario, si (estado == SDT_01) estado = SDT_00; si no (estado == SCLK_01) estado = SCLK_00; } else {if (estado == SDT_10) estado = IDLE_11; si no (estado == SDT_00) estado = SDT_01; si no (estado == SCLK_00) estado = SCLK_01; si no (estado == SCLK_10) {estado = IDLE_11; curVal ++; }}}

Paso 5: Integración impecable

Puede comprobar en el vídeo adjunto que la solución FSM funciona con precisión y rapidez incluso en el caso de codificadores rotativos de rango bajo con varios efectos de rebote esporádicos.

Recomendado: