jueves, 15 de octubre de 2015

Joystick LCD Menu Arduino

Os dejo aquí una plantilla de código para comenzar a trabajar, Es un sistema de menús en Arduino que utiliza un joystick como dispositivo de entrada.



Las características de este código son:

- La pantalla no parpadea, solo se refresca cuando mandemos.
- La estructura de menús no utiliza librerías especificas, todo está en el código.
- Con el botón del joystick entramos en modo edición para ingresar valores, cambiar estados, etc.
- El joystick tiene un retardo en la lectura para evitar lecturas falsas basado en el ejemplo "debounce" que viene con la IDE Arduino. Ademas, pasado ese tiempo, cada pulsación cuenta como una sola.

Cosillas que se quedaron en el tintero:

- Utilizo la última versión de la librería LiquidCristal_I2C. La primera comprobación que hay que hacer si no se muestran caracteres es regular el potenciómetro que esta detrás del LCD, en su circuito controlador. Si esto no resulta, para saber la dirección I2C de nuestra pantalla, cargamos en Arduino un código que encontraremos facilmente "googleando" "I2C scanner", que nos dará las direcciones de los dispositivos conectados al bus sda/scl.

Veo erratas en el código de abajo y dejo un enlace para que podáis descargarlo.


/*  
    LCD Menu & Joytick por JMLoureiro77

    http://jmloureiro77.blogspot.com.es

  328P Flash 5300 (17%) RAM 409(19%)

 - LCD SIN parpadeo
 - Sistema de menus SIN libreria
 - Joystick una pulsacion con retardo
 - editMode para introducir valores en Menu 1 

CC-BY 3.0 */

//---------------------------------------------------
// 1. Librerias
//---------------------------------------------------

#include "Wire.h"
#include "LiquidCrystal_I2C.h" 

//----------------------------------------------------
// 2. Pines
//----------------------------------------------------
#define xPin     A1   
#define yPin     A0   
#define kPin      7   
//SDA            A4
//SCL            A5

//----------------------------------------------------
// 3. Variables y Comandos
//----------------------------------------------------
int tCount1;
bool refresh;//lcd clear On/Off
//leerJoystick
int joyRead;
int joyPos; // lectura de 
int lastJoyPos;
long lastDebounceTime = 0; 
long debounceDelay = 100;               //user define
//Control Joystick
bool PQCP;
bool editMode;
//sistema de menus
int mNivel1;  
int mNivel2;  
//editmode
byte n[19];
int lastN;
int lcdX;
//int lcdY;
bool exiT;
//----------------------------------------------------
// 4. Objetos
//----------------------------------------------------
LiquidCrystal_I2C lcd(0x27,16,2); 

//====================================================
// SETUP
//====================================================
void setup() {
//----------------------------------------------------
// S1. Pines
//----------------------------------------------------
  pinMode(xPin, INPUT);
  pinMode(yPin, INPUT);
  pinMode(kPin, INPUT_PULLUP);
//----------------------------------------------------
// S2. Objetos
//----------------------------------------------------
  lcd.init();
  lcd.backlight(); 
}

//====================================================
// LOOP
//====================================================
void loop() {
  controlJoystick();
  menu();
/*  if (millis()%50==0){
    tCount1++;}
  if (tCount1>1000){tCount1=0;}*/
}

//====================================================
// Menu
//====================================================
void menu(){
  switch (mNivel1){
    case 0:
      menu0();//pantalla de inicio
    break;
    case 1:
        if(mNivel2==1){menu11();
        }else if (mNivel2==2){menu12();
        }else if (mNivel2==3){menu13();}
        else{menu1();}
    break;
    case 2:
      menu2();
        if(mNivel2==1){menu21();
        }else if (mNivel2==2){menu22();
        }else if (mNivel2==3){menu23();}
        else{menu2();}
    break;
    case 3:
      menu3(); //
    break;
  }//switch
}
//----------------------------------------------------
// Pantalla de inicio
//----------------------------------------------------
void menu0(){
  if (refresh){lcd.clear();refresh=0;}
  leeJoystick();
  lcd.setCursor(0,0);
  lcd.print("Pantalla Inicio");
}
//----------------------------------------------------
// Menu 1
//----------------------------------------------------
void menu1(){
  if (refresh){lcd.clear();refresh=0;}
  lcd.setCursor(0,0);
  lcd.print("Menu 1");
  lcd.setCursor(0,1);
//++++++++++++++++++++
  while(editMode){
    controlJoystick();
    lcd.setCursor(lcdX,1);
    if(n[lcdX]!=lastN){
      lcd.print(n[lcdX]);
      lastN=n[lcdX];
    }
  }
}
//-------------------------------------------------1.1
void menu11(){
  if (refresh){lcd.clear();refresh=0;}
  lcd.setCursor(0,0);
  lcd.print("Menu 1.1");
}
//-------------------------------------------------1.2
void menu12(){
  if (refresh){lcd.clear();refresh=0;}
  lcd.setCursor(0,0);
  lcd.print("Menu 1.2");
}
//-------------------------------------------------1.3
void menu13(){
  if (refresh){lcd.clear();refresh=0;}
  lcd.setCursor(0,0);
  lcd.print("Menu 1.3");
}
//----------------------------------------------------
// Menu 2
//----------------------------------------------------
void menu2(){
  if (refresh){lcd.clear();refresh=0;}
  lcd.setCursor(0,0);
  lcd.print("Menu 2");
}
//-------------------------------------------------2.1
void menu21(){
  if (refresh){lcd.clear();refresh=0;}
  lcd.setCursor(0,0);
  lcd.print("Menu 2.1");
}
//-------------------------------------------------2.2
void menu22(){
  if (refresh){lcd.clear();refresh=0;}
  lcd.setCursor(0,0);
  lcd.print("Menu 2.2");
}
//-------------------------------------------------2.3
void menu23(){
  if (refresh){lcd.clear();refresh=0;}
  lcd.setCursor(0,0);
  lcd.print("Menu 2.3");
}
//----------------------------------------------------
// Menu 3
//----------------------------------------------------
void menu3(){
  if (refresh){lcd.clear();refresh=0;}
  lcd.setCursor(0,0);
  lcd.print("Menu 3");
  switch (mNivel2){
    case 0:
      return;
    case 1:
      menu31();
    break;
    case 2:
      menu32();
    break;
    case 3:
      menu33();
    break;
    default:
    break;
  }//switch
}
//-------------------------------------------------3.1
void menu31(){
  if (refresh){lcd.clear();refresh=0;}
  lcd.setCursor(0,0);
  lcd.print("Menu 3.1");
}
//-------------------------------------------------3.2
void menu32(){
  if (refresh){lcd.clear();refresh=0;}
  lcd.setCursor(0,0);
  lcd.print("Menu 3.2");
}
//-------------------------------------------------3.3
void menu33(){
  if (refresh){lcd.clear();refresh=0;}
  lcd.setCursor(0,0);
  lcd.print("Menu 3.3");
}
//====================================================
// Control Joystic
//====================================================
void controlJoystick(){
  leeJoystick();
  if(PQCP) {
    PQCP=0;
    if (joyPos==5){editMode=!editMode;}
    switch (editMode){
       case 1: 
          lcd.blink();
          if (joyPos==4&&n[lcdX]<9 arriba="" if="" joypos="=3&&n[lcdX]" lcdx="" n="" refresh="0;}">0){n[lcdX]--;   //abajo
              refresh=0;} 
          if (joyPos==1&&lcdX<19 derecha="" if="" joypos="=2&&lcdX" lcdx="" refresh="0;}">0){lcdX--;         //izq
           refresh=0;}
        break;
        case 0:
          lcd.noBlink();
          if (mNivel1<3 abajo="" if="" joypos="=3){mNivel1++;" mnivel1="" mnivel2="0;}" refresh="1;">0&&joyPos==4){mNivel1--;    //arriba
            mNivel2=0;
            refresh=1;}
          if (mNivel2<3 derecha="" if="" joypos="=1){mNivel2++;" mnivel2="" refresh="1;}">0&&joyPos==2){mNivel2--;    //izq
           refresh=1;}
        }//!edit
  }//PQCP
}
int leeJoystick(){
  int x = analogRead(xPin);
  int y = analogRead(yPin);
  int k = digitalRead(kPin);
    if(x>900){joyRead=1;        //x+
    }else if(x<100 else="" if="" joyread="2;" x-="" y="">900){joyRead=3;  //y+
    }else if(y<100 -="" else="" if="" joyread="" k="" lastdebouncetime="" lastjoypos="" millis="" y-=""> debounceDelay)&&(joyRead!=joyPos)){
    joyPos=joyRead;
    if(!PQCP){PQCP=1;}
    }
  lastJoyPos=joyRead;
}