ALGORITMO PARA CREACIÓN DE MENÚ
Hola a todos, en esta ocasión les traigo un algoritmo para crear un menú interactivo en el LCD, básicamente es la continuación de la lección II, ya que utilizamos el mismo material, con la diferencia de que esta vez, ya se tiene un menú en forma.
Material:
1 encoder
1 LCD con interfaz I2C
1 Placa arduino 1
10 cables dupont
Conexiones:
Encoder - Arduino
GND ------- GND
+ ---------- Vcc (5V)
SW --------- 4
DT ---------- 3
CLK -------- 2
LCD - Arduino
GND -------- GND
Vcc -------- Vcc (5V)
SDA ------- A4
SCL ------- A5
Circuito
Algoritmo
#include <Timer.h>
#include <LiquidCrystal_I2C.h>
Timer t; //Declaramos un timer, para dar base de tiempo
//Definición de pines de entrada
#define encoder0PinA 2
#define encoder0PinB 3
#define encoder0Pulse 4
//Variables utilizadas tanto en la ISR, como en el void loop
volatile unsigned int encoder0Pos = 6;
volatile char indicadorDegiro;
volatile boolean flagLCD=0; //Bandera indicadora de interrupción
boolean flagPulse=0; //Bandera indicadora de pulsador presionado
String mensaje1,mensaje2; //Variables para almacenar mensajes que se desplegará en LCD
int conteoInt=0; //Variable para conteo de interrupciones, es necesario puesto que se interrumpe en dos ocasiones, ya que existen 2 flancos de bajada por por giro
boolean renglonLCD=0; //indica el renglon actual
unsigned int indexLCD=6; //Apuntador de LCD; indica el "item" actual
LiquidCrystal_I2C lcd(0x27, 16, 2); // Configura LCD
void setup() {
lcd.begin();
pinMode(encoder0PinA, INPUT_PULLUP); //Habilita pull ups, para contrar siempre con un voltaje de referencia
pinMode(encoder0PinB, INPUT_PULLUP);
pinMode(encoder0Pulse,INPUT_PULLUP);
//Inicializar menú
mensaje1="Item1";
mensaje2="Item2";
lcd.setCursor(0,0);
lcd.print(">");
lcd.print(mensaje1);
lcd.setCursor(1,1);
lcd.print(mensaje2);
attachInterrupt(0, task1,FALLING); // Habilita interrupción en pin 2, por flanco descendente
attachInterrupt(1, task1,FALLING); // Habilita interrupción en pin 3, por flanco descendente
}
void loop(){
t.update();
if (flagLCD==1 && conteoInt==0){
flagLCD=0;
conteoInt++; //Incrementa contador de interrupciones.
t.after(170,esperaCambio); //Da tiempo para que se estabilice el encoder, antes de habilitar nuevamente las interrupciones
}
else if (flagLCD==1 && conteoInt>0){
flagLCD=0;
lcd.clear();
imprimeLCD();
conteoInt=0; //Limpia contador de interrupciones
t.after(170,esperaCambio); //Da tiempo para que se estabilice el encoder, antes de habilitar nuevamente las interrupciones
}
if (digitalRead(encoder0Pulse)==0 && flagPulse==0){ //Si pulso botón y flag=0 entonces
t.after(250,verificaPulso); //Llama a rutina verificaPulso despues de 150 ms, para evitar rebote
flagPulse=1;
}
}
void task1() {
// Deshabilitar ambas interrupciones para evitar falsas lecturas en el LCD
detachInterrupt(0);
detachInterrupt(1);
if (digitalRead(encoder0PinA)==0 && digitalRead(encoder0PinB)==1) {
if (encoder0Pos<6){
encoder0Pos++;
}
indicadorDegiro='+';
}
if (digitalRead(encoder0PinA)==1 && digitalRead(encoder0PinB)==0) {
if (encoder0Pos>0){
encoder0Pos--;
}
indicadorDegiro='-';
}
indexLCD=encoder0Pos; //Instrucción necesaria, porque el compilador no permite leer la variable volatile dentro del switch case
flagLCD=1;
}
void esperaCambio(){
attachInterrupt(0, task1,FALLING); // Habilita interrupción en pin 2, por cambio de nivel
attachInterrupt(1, task1,FALLING); // Habilita interrupción en pin 2, por cambio de nivel
}
void verificaPulso(){
static boolean conmutador1=0, conmutador2=0; //Variable para conmutar brillo del LCD
if (renglonLCD==0){ //Si el índice es par, significa que estoy en el renglon 0
if (conmutador1==0){
lcd.setCursor(8,0);
lcd.print("OK");
}
else{
lcd.setCursor(8,0);
lcd.print(" ");
}
conmutador1=!conmutador1;// Cambia de estado (conmuta)
}
if (renglonLCD==1){ //Si el índice es par, significa que estoy en el renglon 0
if (conmutador2==0){
lcd.setCursor(8,1);
lcd.print("OK");
}
else{
lcd.setCursor(8,1);
lcd.print(" ");
}
conmutador2=!conmutador2;// Cambia de estado (conmuta)
}
flagPulse=0;
}
void imprimeLCD(){
if (indicadorDegiro=='+' && renglonLCD==0 && indexLCD<6){ //Si está en item1 y mueve hacia "-"
lcd.setCursor(0,1); //Celda y línea
renglonLCD=1;
}
else if (indicadorDegiro=='+' && renglonLCD==1 && indexLCD<=6){
lcd.setCursor(0,0); //Celda y línea
renglonLCD=0;
}
else if (indicadorDegiro=='-' && renglonLCD==0 && indexLCD>0){
lcd.setCursor(0,1); //Celda y línea
renglonLCD=1;
}
else if (indicadorDegiro=='-' && renglonLCD==1 && indexLCD>=0){
lcd.setCursor(0,0); //Celda y línea
renglonLCD=0;
}
if (indexLCD==5 || indexLCD==6){
mensaje1="Item1";
mensaje2="Item2";
}
if (indexLCD==3 || indexLCD==4){
mensaje1="Item3";
mensaje2="Item4";
}
if (indexLCD==1 || indexLCD==2){
mensaje1="Item5";
mensaje2="Item6";
}
if (indexLCD==0){
mensaje1="Item7";
mensaje2="";
}
lcd.print(">");
lcd.setCursor(1,0);
lcd.print(mensaje1);
lcd.setCursor(1,1);
lcd.print(mensaje2);
}
Análisis de algoritmo
Dudas o sugerencias:
talleresarduino@gmail.com
facebook.com/ConsultorMic
Ing. Francisco Galindo.
Comentarios
Publicar un comentario