En este tutorial se explicará el uso del Módulo Sensor Encoder KY-040 Rotativo y cómo utilizarlo para control de leds de una Neopixel Circular RGB.
Funcionamiento del Encoder KY-040
El Módulo Sensor Encoder KY-040 es un dispositivo de entrada rotatorio (perilla) que proporciona una posición (por medio de pasos) y dirección cuando la perilla esté girando a su vez esta perilla actúa como una entrada de pulsador.
Un codificador rotatorio tiene un número fijo de posiciones por revolución que se sienten como “Clicks”. El módulo KY-040 tiene treinta de estas posiciones. Internamente tienen 3 posiciones: A, B y C. Dentro del codificador hay dos interruptores. Una vez que el interruptor conecta el pin A al pin C y el otro interruptor conecta el pin B al C.
Las posiciones de interés son:
Ahora procederemos a probar esta teoría en la practica desarrollando la conexión y programa propuesto.
Utilizaremos el siguiente material:
- Arduino UNO R3
- Cables Dupont
- Módulo KY-040 Sensor Encoder Rotativo
- Neopixel circular CJMCU 16 Bit WS2812 5050 RGB LED
- Protoboard 400 Pts
Diagrama de Conexión entre Arduino y KY-040
Primero realizaremos la conexión simple del Encoder en el Arduino UNO para poder comprender el funcionamiento de codificación para posteriormente usarlo en el control del encendido/apagado de leds RGB.
Programa en IDE Arduino
Se realizará la codificación de la gráfica antes mostrada por medio de las funciones IF, desde el inicio del programa se analiza la posición del KY-040; para realizar las comparaciones y saber si el giro ha sido horario o antihorario.
Adicional cuando se active el pulsador, la posición del Encoder se reiniciará al valor 0.
#define outCLK 2 //Salida A del codificador un valor constante definido antes de compilar el programa #define outDT 3 //Salida B del codificador un #define boton 4 //Salida del SW/Swich Pulsador del Encoder int paso = 0; //Variable entera para realizar el conteo de avance del Encoder int edoCLK; //Variable de posición del CLK/A/Pin 2 int anteriorCLK; //Variable que guardara el estado anterior de la entrada CLK/A/Pin 2 void setup() { Serial.begin (9600); //Inicia Puerto Serial a 9600 baudios pinMode (outCLK,INPUT); // Pin de entrada CLK/A/Pin 2 Arduino pinMode (outDT,INPUT); // Pin de entrada DT/B/Pin 3 Arduino pinMode (boton, INPUT_PULLUP); // El SW/Swich Pulsador del Encoder será entrada con la resistencia Pull-up interna habilitada anteriorCLK= digitalRead(outCLK); // Siempre se leerá el valor de CLK/A/Pin 2 Arduino y se guarda la información en la variable anteriorCLK } void loop() { edoCLK = digitalRead(outCLK); // Lee el estado de la salida CLK/A/Pin 2 Arduino y se guarda en estadoCLK para tener un valor actualizado if (edoCLK != anteriorCLK){ // Si el estado previo y el valor actualizado son diferentes, entonces existe un pulso if (digitalRead(outDT) != edoCLK) { // Si el estado de salidaDT/B/Pin 3 es diferente del estado de salidaCLK/A/Pin 2 el codificador esta girando a la derecha paso --; //por lo tanto se avanzara un paso en el Encoder } else { // de lo contrario paso ++; // se estará girando de lado izquierdo y se retrocederá el paso del Encoder } Serial.print("Ubicación: "); //Se visualizara en el monitor serial la impresión del mensaje que nos dará la posición del ENCODER Serial.println(paso); } anteriorCLK = edoCLK; //actualizaremos el valor anterior bool Bot = digitalRead(boton); //Se compara que el valor obtenido de "boton" que sea diferente de cero if (!Bot) // si se pulsa el botón su valor va a BAJO { Serial.println("Botón pulsado: Reinicia a 0"); //Se mandara un mensaje en donde se dará aviso que el conteo de pasos se reiniciara paso = 0 ; //Se actualiza el valor de paso a 0 delay(300); //Se espera .3 segundos para continuar } } }
A continuación la ejecución del programa, visualizando las posiciones del Encoder en el Monitor Serial en paralelo con el funcionamiento físico:
Ya teniendo en cuenta como es el funcionamiento del Encoder KY-040, realizaremos el control de los LED en la Neopixel Circular.
Diagrama de Conexión
A la conexión anterior solo agregaremos el Neopixel Circular en los pines de alimentación de Arduino y el PIN de Datos al Pin PWM 5 de la tarjeta de desarrollo. Apóyate de la protoboard para realizar tu conexión.
Código para el control de Leds con el KY-040
Para nuestro siguiente programa requeriremos de la librería de Adafruit_Neopixel, la cual puedes encontrar dentro de la barra de herramientas de IDE de Arduino como:
Programa>>Incluir Librería>>Administrar Bibliotecas>>Neopixel>>Adafruit NeoPixel
El código se divide en 3 fases:
//Incluimos librerías para poder utilizar la Neopixel Circular #include <Adafruit_NeoPixel.h> #ifdef __AVR__ #include <avr/power.h> //16 MHz Adafruit Trinket #endif //Definimos variables de entrada del KY-040 Encoder #define outCLK 2 //Salida A del codificador un valor constante definido antes de compilar el programa #define outDT 3 //Salida B del codificador un #define boton 4 //Salida del SW/Swich Pulsador del Encoder #define led 5 //Definimos Pin 5 para datos de salida para la Neopixel Circular #define NUMPIXELS 16 //Se declara el uso de los 16 pixeles de Neopixel Circular Adafruit_NeoPixel pixels(NUMPIXELS, led, NEO_GRB + NEO_KHZ800); int paso = 0; //Variable entera para realizar el conteo de avance del Encoder int edoCLK; //Variable de posición del CLK/A/Pin 2 int anteriorCLK; //Variable que guardara el estado anterior de la entrada CLK/A/Pin 2 int leds; //Variable que nos dirán # de la posición del LED de en la Neopixel int cuenta, dato; //Variables que guardaran la veces que ha sido presionado el ENCODER void setup() { Serial.begin (9600); //Inicia Puerto Serial a 9600 baudios #if defined(__AVR_ATtiny85__) && (F_CPU == 16000000) //Se definen los parámetros para que los leds de la Neopixel funcionen a 16 MHZ clock_prescale_set(clock_div_1); // #endif pixels.begin(); pinMode (outCLK,INPUT); // Pin de entrada CLK/A/Pin 2 Arduino pinMode (outDT,INPUT); // Pin de entrada DT/B/Pin 3 Arduino pinMode (boton, INPUT_PULLUP); // El SW/Swich Pulsador del Encoder será entrada con la resistencia Pull-up interna habilitada anteriorCLK= digitalRead(outCLK); // Siempre se leerá el valor de CLK/A/Pin 2 Arduino y se guarda la información en la variable anteriorCLK } void loop() { edoCLK = digitalRead(outCLK); // Lee el estado de la salida CLK/A/Pin 2 Arduino y se guarda en estadoCLK para tener un valor actualizado if (edoCLK != anteriorCLK){ // Si el estado previo y el valor actualizado son diferentes, entonces existe un pulso if (digitalRead(outDT) != edoCLK) { // Si el estado de salidaDT/B/Pin 3 es diferente del estado de salidaCLK/A/Pin 2 el codificador esta girando a la derecha paso --; //por lo tanto se avanzara un paso en el Encoder } else { // de lo contrario paso ++; // se estará girando de lado izquierdo y se retrocederá el paso del Encoder } if (paso >= 16) { //Si el paso supera el valor de 16 el contador se reiniciara a 0 paso = 0; } else if (paso < 0) { //Además si el paso es menor que 0(negativo), se sumara 1 para poderlo hacer nuevamente positivo paso = paso + 1; } leds = paso; Serial.print("Ubicación: "); //Se visualizara en el monitor serial la impresión del mensaje que nos dará la posición del ENCODER Serial.println(paso); } anteriorCLK = edoCLK; //actualizaremos el valor anterior bool Bot = digitalRead(boton); //Se compara que el valor obtenido de "boton" que sea diferente de cero if (Bot==0) { dato = cuenta++; //da el valor de la posición del Encoder delay(300); //Se espera .3 segundos para continuar if (dato > 7) { //Si la cuenta de pulsos es superior a 7 se reinicia el conteo cuenta = 0; dato = cuenta; //Estas cuentas se guardaran en la variable DATO } } color(dato,leds); //Datos para la FUNCION COLOR } //Función que manejara los colores y cambio de posición de inicio de led de encendido de la NEOPIXEL CIRCULAR void color(int dato, int leds) { switch (dato) { case 1: //Color de pixel Rojo pixels.setPixelColor(leds, pixels.Color(150, 0, 0)); pixels.show(); break; case 2: //Color de pixel Verde pixels.setPixelColor(leds, pixels.Color(0, 150, 0)); pixels.show(); break; case 3: //Color de pixel Azul pixels.setPixelColor(leds, pixels.Color(0, 0, 150)); pixels.show(); break; case 4: //Color de pixel Amarillo pixels.setPixelColor(leds, pixels.Color(150, 150, 0)); pixels.show(); break; case 5: //Color de pixel Naranja pixels.setPixelColor(leds, pixels.Color(150, 36, 0)); pixels.show(); break; case 6: //Color de pixel Morado pixels.setPixelColor(leds, pixels.Color(128, 0, 128)); pixels.show(); break; case 7: //Color de pixel Blanco pixels.setPixelColor(leds, pixels.Color(138, 43, 226)); pixels.show(); break; case 0: //Pixel APAGADO pixels.setPixelColor(leds, pixels.Color(0, 0, 0)); pixels.show(); break; } }
A continuación el sistema en funcionamiento:
Si te interesa realizar otro sistema con leds te sugerimos el tutorial de ¿Cómo conectar y programar la Matriz LED 8×8 1088AS?.