InicioTarjetas de DesarrolloArduinoControl de Leds mediante Módulo Sensor Encoder KY-040

Control de Leds mediante Módulo Sensor Encoder KY-040

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:

  • Al Girar el interruptor en el sentido de las agujas del reloj hará que el interruptor que conecta A y C cambie de estado primero.
  • Girar el interruptor en sentido antihorario hará que el interruptor que conecta B y C cambie de estado primero.
  • Si tuviéramos que representar la apertura y el cierre de los interruptores como formas de onda, seria la siguiente:

    Ahora procederemos a probar esta teoría en la practica desarrollando la conexión y programa propuesto.

    Utilizaremos el siguiente material:

    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:

  • Ubicación de la posición del led, acotando que solo se cuentan con 16 posiciones.
  • El número de veces que sea ejecutado el pulsador nos indica el color que se visualizará en la Neopixel.
  • Ya que se cuente con la información de la posición y el color que desplegara los led, la función colorse ejecutara.
  •  
    //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?.

    TUTORIALES RELACIONADOS