Menú en LCD 1602 con Arduino

Veamos cómo crear un menú controlado por un codificador rotativo en una pantalla LCD 1602 I2C. Presentaremos dos ejemplos: un menú para encender los LEDs y un menú en la pantalla con control de codificador del brillo de los LEDs. Le recomendamos que lea la información sobre la conexión del LCD 1602 i2c y el módulo de codificador rotativo al Arduino. Si ya has conectado estos módulos, puedes iniciar este proyecto.

Para esta actividad necesitaremos:

  • Arduino Uno / Arduino Nano / Arduino Mega
  • el codificador rotativo;
  • la pantalla LCD 1602 I2C;
  • LEDs y resistencias de 220 Ohm;
  • placa de pruebas;
  • cables de conexion;
  • librerias LiquidCrystal_I2C.h y RotaryEncoder.h

Como crear un menú LCD con Arduino y encoder

Los menús de muestra con módulo codificador rotativo y pantalla LCD 1602 presentados en esta página pueden adaptarse a sus necesidades. Muchos proyectos de Arduino requieren que el usuario configure o controle un dispositivo en el microcontrolador Arduino Uno. El codificador rotativo permite crear un sencillo menú nativo en la pantalla LCD 1602 i2c para controlar los LEDs, el micro servo de Arduino o para otras tareas.

Menú en LCD 16×2 con codificador
El circuito eléctrico. Menú en LCD 16×2 con codificador rotativo
LCD 1602 i2c Arduino Uno Arduino Nano Arduino Mega
GND GND GND GND
VCC 5V 5V 5V
SDA A4 A4 20
SCL A5 A5 21

En el primer ejemplo, más sencillo, el menú de la pantalla tiene tres elementos que se pueden cambiar girando el mando del codificador. Al pulsar el botón del codificador, se activa el color del LED RGB seleccionado. En función de la posición del cursor en la pantalla, se activa el color deseado mediante la sentencia condicional if. Monta el circuito como se muestra en la imagen y carga el programa en el microcontrolador Arduino.

Programa Arduino para menú sencillo con encoder

#include "Wire.h"
#include "LiquidCrystal_I2C.h"
LiquidCrystal_I2C LCD(0x27, 16, 2);

#include "RotaryEncoder.h"
RotaryEncoder encoder(4, 5);  // DT, CLK

#define STEPS  6
#define POSMIN 0
#define POSMAX 12

int lastPos, newPos;
boolean buttonWasUp = true;

void setup() {
   LCD.init();
   LCD.backlight();

   pinMode(9, OUTPUT);
   pinMode(10, OUTPUT);
   pinMode(11, OUTPUT);
   pinMode(2, INPUT_PULLUP);

   Serial.begin(9600);
   encoder.setPosition(10 / STEPS);
}

void loop() {
   LCD.setCursor(0, 0);
   LCD.print("LED1  LED2  LED3");
   encoder.tick();
   newPos = encoder.getPosition() * STEPS;
   if (newPos < POSMIN) { 
      encoder.setPosition(POSMIN / STEPS);
      newPos = POSMIN;
   }
   else if (newPos > POSMAX) {
      encoder.setPosition(POSMAX / STEPS);
      newPos = POSMAX;
   }
   if (lastPos != newPos) {
      Serial.println(newPos);
      LCD.setCursor(lastPos, 1);
      LCD.print("    ");
      LCD.setCursor(newPos, 1);
      LCD.print("====");
      lastPos = newPos;
   }

   boolean buttonIsUp = digitalRead(2);
   if (buttonWasUp && !buttonIsUp) {
      delay(10);
      buttonIsUp = digitalRead(2);
      if (!buttonIsUp  && newPos == 0) {
         digitalWrite(9,HIGH); digitalWrite(10,LOW); digitalWrite(11,LOW);
      }
      if (!buttonIsUp  && newPos == 6) {
         digitalWrite(9,LOW); digitalWrite(10,HIGH); digitalWrite(11,LOW);
      }
      if (!buttonIsUp  && newPos == 12) {
         digitalWrite(9,LOW); digitalWrite(10,LOW); digitalWrite(11,HIGH);
      }
   }

}

Explicación del código menú sencillo con codificador:

  1. la posición del cursor en la pantalla LCD puede tomar tres valores: 0, 6 o 12;
  2. el botón del codificador se conecta al puerto digital mediante la configuración de pines con el parámetro INPUT_PULLUP, que permite leer la presión del botón.

En el siguiente ejemplo, el menú tiene un segundo nivel en el que se puede ajustar el brillo de cada LED por separado. El cambio de un menú a otro se realiza pulsando el botón del codificador, que cambia el valor de la variable global w en el script. El diagrama de cableado desde los LEDs y los módulos hasta el microcontrolador sigue siendo el mismo que en la imagen anterior, sólo hay que cargar el siguiente código de programa en la placa.

Programme Arduino menú desplegable con encoder

#include "Wire.h"
#include "LiquidCrystal_I2C.h"
LiquidCrystal_I2C LCD(0x27, 16, 2);

#include "RotaryEncoder.h"
RotaryEncoder encoder(4, 5);  // DT, CLK

#define STEPS  6
#define POSMIN 0
#define POSMAX 12
#define STEPS_2  10
#define POSMIN_2 0
#define POSMAX_2 250

int lastPos, newPos;
boolean buttonWasUp = true;
byte w = 2;

void setup() {
  LCD.init();
  LCD.backlight();

  pinMode(9, OUTPUT);
  pinMode(10, OUTPUT);
  pinMode(11, OUTPUT);
  pinMode(2, INPUT_PULLUP);

  Serial.begin(9600);
  encoder.setPosition(10 / STEPS);
}

void loop() {

   // CYCLE AVEC MENU PRINCIPAL À L'ÉCRAN
  while (w == 0) {
    LCD.setCursor(0, 0);
    LCD.print("LED1  LED2  LED3");
    encoder.tick();
    newPos = encoder.getPosition() * STEPS;
    if (newPos < POSMIN) {
      encoder.setPosition(POSMIN / STEPS);
      newPos = POSMIN;
    }
    else if (newPos > POSMAX) {
      encoder.setPosition(POSMAX / STEPS);
      newPos = POSMAX;
    }
    if (lastPos != newPos) {
      Serial.println(newPos);
      LCD.setCursor(lastPos, 1);
      LCD.print("    ");
      LCD.setCursor(newPos, 1);
      LCD.print("====");
      lastPos = newPos;
    }
    boolean buttonIsUp = digitalRead(2);
    if (buttonWasUp && !buttonIsUp) {
      delay(10);
      buttonIsUp = digitalRead(2);
      if (!buttonIsUp  && newPos == 0)  { LCD.clear(); delay(500); w = 1; }
      if (!buttonIsUp  && newPos == 6)  { LCD.clear(); delay(500); w = 2; }
      if (!buttonIsUp  && newPos == 12) { LCD.clear(); delay(500); w = 3; }
    }
  }

   // MENÚ ANIDADO CON UN PRIMER LED
  while (w == 1) {
    LCD.setCursor(0, 0);
    LCD.print("LED1  - ");
    encoder.tick();
    newPos = encoder.getPosition() * STEPS_2;
    if (newPos < POSMIN_2) {
      encoder.setPosition(POSMIN_2 / STEPS_2);
      newPos = POSMIN_2;
    }
    else if (newPos > POSMAX_2) {
      encoder.setPosition(POSMAX_2 / STEPS_2);
      newPos = POSMAX_2;
    }
    if (lastPos != newPos) {
      LCD.setCursor(7, 0);
      LCD.print(newPos);
      analogWrite(9, newPos);
    }
    boolean buttonIsUp = digitalRead(2);
    if (buttonWasUp && !buttonIsUp) {
      delay(10);
      buttonIsUp = digitalRead(2);
      if (!buttonIsUp) { LCD.clear();digitalWrite(9,LOW);delay(500);w=0; }
  } 
}

   // MENÚ ANIDADO CON UN SEGUNDO LED
  while (w == 2) {
    LCD.setCursor(0, 0);
    LCD.print("LED2 - ");
    encoder.tick();
    newPos = encoder.getPosition() * STEPS_2;
    if (newPos < POSMIN_2) {
      encoder.setPosition(POSMIN_2 / STEPS_2);
      newPos = POSMIN_2;
    }
    else if (newPos > POSMAX_2) {
      encoder.setPosition(POSMAX_2 / STEPS_2);
      newPos = POSMAX_2;
    }
    if (lastPos != newPos) {
      LCD.setCursor(7, 0);
      LCD.print(newPos);
      analogWrite(10, newPos);
    }
    boolean buttonIsUp = digitalRead(2);
    if (buttonWasUp && !buttonIsUp) {
      delay(10);
      buttonIsUp = digitalRead(2);
      if (!buttonIsUp) { LCD.clear();digitalWrite(10,LOW);delay(500);w=0; }
  }
}

   // MENÚ ANIDADO CON UN TERCER LED
  while (w == 3) {
    LCD.setCursor(0, 0);
    LCD.print("LED3 - ");
    encoder.tick();
    newPos = encoder.getPosition() * STEPS_2;
    if (newPos < POSMIN_2) {
      encoder.setPosition(POSMIN_2 / STEPS_2);
      newPos = POSMIN_2;
    }
    else if (newPos > POSMAX_2) {
      encoder.setPosition(POSMAX_2 / STEPS_2);
      newPos = POSMAX_2;
    }
    if (lastPos != newPos) {
      LCD.setCursor(7, 0);
      LCD.print(newPos);
      analogWrite(11, newPos);
    }
    boolean buttonIsUp = digitalRead(2);
    if (buttonWasUp && !buttonIsUp) {
      delay(10);
      buttonIsUp = digitalRead(2);
      if (!buttonIsUp) { LCD.clear();digitalWrite(11,LOW);delay(500);w=0; }
  } 
}

}

Explicación del código menú desplegable con codificador:

  1. se utiliza un bucle while para cada sección del menú, porque inicialmente la variable global w=0 se ejecuta un bucle while (w == 0);
  2. si no quiere que los LEDs se apaguen al salir del menú principal – elimine el comando digitalWrite() de todos los bucles del submenú.

Conclusión. Hemos visto dos ejemplos de creación de un menú sencillo / desplegable con un codificador rotativo en la pantalla del Arduino 16×2 IIC. Si ha comprendido la esencia del control de menús con un codificador rotatorio (encoder), podrá utilizar fácilmente los ejemplos presentados en sus propios proyectos con una pantalla Arduino. Si aún tienes dudas sobre este tema, puedes dejarlas en los comentarios de este post.


Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *