Go Down

Topic: LCD 16x2 menu, controlled with pushbuttons (Read 1 time) previous topic - next topic

Amaliaairi

Hi!!

I hope someone could help me by reading my code, may be you can find a solution by seeing it from a different point of view...

I'm in the middle of a project and I have to make a menu with LCD and pushbuttons. in the end I have to use 6 pushbuttons, and in order to save the use of digital pins for pushbuttons, I used 2 analog pins to read the changing of voltage provided by some resistors and pushbuttons. but I suspected that this was the source of my problem, so I changed for digital pins to read the pushbutton. that's how desperate I am now.

sorry it took this long; My problem is that I can't move the cursor, after the first time I do. you see, this code I'm posting it's only a small part of the whole final program. so I had to be resourceful and used some functions that I'm not so used to. may be there is the problem.

I'm posting the simulation in circuit io, because I think that it's easier for all of us:

https://circuits.io/circuits/3971304-first-test#breadboard

it may have many comments and looks messy but please ignore it, I need them for my team members after this...

it's a simple code, that consists on counting the pushbutton (for now the left one is the only one available) and there's a function that counts how many times is pushed. according to the counts there's another function that specializes in displaying some words. I know it's easy but, I think I need some fresh and different point of view to recognize my mistake...

please help me!!

Code: [Select]
#include <LiquidCrystal.h>
// Constantes:
#define pinLedB 9 // Led Azul y Amarillo, ambos en un pin PWM.
#define pinLedY 10
#define intervaloTiempo 5//cada pulsacion equivale al aumento o diminucion de 5min el tiempo
#define intervaloRPM 500//cada pulsacion son 500revoluciones que aumentan o disminuyen

// Variables globales:
int Tiempo;
int RPM;
int opcion=1;
int submenus=0;

//caracteres
byte arrowDown[8] = {
  B00000, B01110, B01110, B01110, B11111, B01110, B00100}; // Caracteres personalizados para el LCD
byte cursorLCD[8] = {
  B00000, B00000, B00110, B01111, B01111, B00110, B00000};

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

void setup()
{
  lcd.begin(16, 2);
  // Se aden los caracteres especiales al objeto LCD:
  lcd.createChar(0, cursorLCD);
  lcd.createChar(1, arrowDown);
  Serial.begin(9600);
    pinMode(6, INPUT);     

  // Se imprime la pantalla de inicio:
  lcd.setCursor(3, 0);
  lcd.print("PRESVAC");
  lcd.setCursor(0, 1);
  lcd.print("Presiona Abajo");
  lcd.write(byte(1));
  delay(20);
}

void loop()
{
  char resultButton[7] = "null";//reinicia el valor de la lectura de los botones
  // Se comprueba si se ha pulsado un bot:
  getButtonPush( resultButton, 0, 200);
  // Si se pulsa la tecla abajo, se entra en el men・
  if ( !strcmp(resultButton, "bottom"))
    LCDmenu();

}
//////////////////////////////////////////////////////////////////////////
//lista de menus en pantalla

void PantallaMenuPrincipal(int posEnElMenu)
{
   int    pos = posEnElMenu - 1;//se resta uno para poner el cursor en el lcd: en la prgramacion empieza desde , en cambio en la LCD empieza desde la fila 0.
  if ( posEnElMenu == 1 || posEnElMenu == 2)
  {
    lcd.clear();
    Serial.print("posEnElMenu1:");
    Serial.print(posEnElMenu);
    lcd.setCursor(0, pos);
    lcd.write(byte(0));
    lcd.setCursor(2, 0);
    lcd.print("1. MANUAL");
    lcd.setCursor(2, 1);
    lcd.print("2. PROGRAMAR");
  }
  if ( posEnElMenu == 3 || posEnElMenu == 4)
  {
    lcd.clear();
    Serial.print("posEnElMenu3:");
    Serial.print(posEnElMenu);
    lcd.setCursor(0, posEnElMenu);
    lcd.write(byte(0));
    lcd.setCursor(2, 0);
    lcd.print("3. ELEGIR PROGRAMA");
    lcd.setCursor(2, 1);
    lcd.print("4. BORRAR PROGRAMA");
  }
    Serial.println("LCD row status ");
    Serial.println(opcion);

}
// ciclo para evaluar que boton se presiono de acuerdo al rango de voltage
//el resultado se guarda como string en la variable resultButton
void getButtonPush(char *resultButton, int pin, int pause)
{
  int data = digitalRead(6);
    if (data==HIGH)
  {
      strcpy(resultButton, "bottom");
    }
    delay(pause);
    Serial.println("digital reading status");
    Serial.println(resultButton);
  }

void LCDmenu()
{
  char resultButton[7];
  do {
    strcpy(resultButton, "null");//borra los datos de resultButton para una nueva lectura
    getButtonPush(resultButton, 0, 200);
    Serial.println("button response before IF");
    Serial.println(resultButton);
    if (!strcmp(resultButton, "up"))
   {
      opcion=opcion -1;//variable que acumula los movimientos verticales del cursor, con el boton hacia arriba va disminuyendo
      if (opcion<=0)
      {
       opcion=opcion-1;
      }
    }

     if (!strcmp(resultButton, "bottom"))
    {
      Serial.println("opcion value BEFORE ");
      Serial.println(opcion);
      opcion=opcion+1;//con el boton de abajo va aumentando para indicar en que fila va el cursor
    }
    lcd.setCursor(0, opcion);
    lcd.write(byte(0)); // muestra el punto que indica donde esta el cursor
    Serial.println("opcion value AFTER ");
    Serial.println(opcion);
    PantallaMenuPrincipal(opcion);//muestra opciones dependiendo de cuantas veces se oprima
  }
  while ( !strcmp(resultButton, "right"));

  //     Seg佖 lo que contenga el opcion, acciona algo
//      switch ( opcion )
//      {
//        case 0:       // entra a la funcion manual.
//          ProgramaManual();
//          opcion=1;
//          break;
//        case 1://entra a registrar una rutina
//          LCDmenu1();
//          opcion=1;
//          break;
// 
//      };
}

// pedira tiempo y RPM al usuario para una operacion manual
//void ProgramaManual()
//{
//  char resultButton[7];
//  //  int posCursor = 0, opcMenu = -2;
//  // visualizacion del Menu
//  lcd.clear();
//  lcd.setCursor(2, 0);
//  lcd.print("Tiempo en minutos");
//  lcd.setCursor(2, 1);
//  lcd.print("RPM");
//  //lectura de donde esta el cursor y actualizacion de posCursor para actuar segun el numero
//
//  strcpy(resultButton, "null");//Borra para volover a leer que boton se pulso
//  getButtonPush( resultButton, 0, 200);
//  lcd.setCursor(0, opcion);
//  lcd.write(byte(0));//muestra el cursor moviendose de acuerdo a las pulsaciones
//
//  // Seg佖 la opci elegida del men・ se pide digitar el tiempo o las revoluciones
//  switch ( opcion )
//  {
//  case 0:
//    if (!strcmp(resultButton, "right"))
//      if (Tiempo + intervaloTiempo < 40)
//        Tiempo += intervaloTiempo;
//      else
//        Tiempo = 40;
//    else if ( !strcmp(resultButton, "left") ) // A la izquierda se apaga.
//      if (Tiempo - intervaloTiempo > 0)
//        Tiempo -= intervaloTiempo;
//      else
//        Tiempo = 0;
//    //  opcMenu = -2;
//    Serial.print("tiempo:");
//    Serial.print(Tiempo);
//    lcd.clear();
//    lcd.setCursor(2, 0);
//    lcd.print(Tiempo);
//    break;
//
//  case 1:
//    if (!strcmp(resultButton, "right"))
//      if (RPM + intervaloRPM < 5000)
//        RPM += intervaloRPM;
//      else
//        RPM = 40;
//    else if ( !strcmp(resultButton, "left") ) // A la izquierda se apaga.
//      if (RPM - intervaloRPM > 0)
//        RPM -= intervaloRPM;
//      else
//        RPM = 0;
//    // opcMenu = -2;
//    Serial.print("RPM");
//    Serial.print(RPM);
//    lcd.clear();
//    lcd.setCursor(2, 0);
//    lcd.print(RPM);
//    break;
//  };
//
//  // Al salir del Menu1 se imprime el men・anterior:
//  lcd.clear();
//  lcd.setCursor(2, 0);
//  lcd.print("Tiempo en minutos");
//  lcd.setCursor(2, 1);
//  lcd.print("RPM");
//}

/////////////////////////////////////////////////////////////////

// MENU 2
void LCDmenu1()
{
  int xxx = 50;
}



I'm displaying some variables status in serial window, just to check the changing of them, and I know I can't go in to an IF, that contains "opcion value BEFORE", but I have no idea WHY.

J-M-L

#1
Feb 11, 2017, 06:55 pm Last Edit: Feb 11, 2017, 06:59 pm by J-M-L
can you put a link to your LCD module? is it the one with the embedded buttons?


Can you explain otherwise how you wired the buttons?
Hello - Please do not PM me for help,  others will benefit as well if you post your question publicly on the forums.
Bonjour Pas de messages privés SVP, postez dans le forum directement pour que ça profite à tous

sterretje

@J-M-L

OP posted https://circuits.io/circuits/3971304-first-test#breadboard

And from the description in the opening post, OP seems to try to make something from scratch (similar to how the buttons on the shield that you show work).
If you understand an example, use it.
If you don't understand an example, don't use it.

Electronics engineer by trade, software engineer by profession. Trying to get back into electronics after 15 years absence.

J-M-L

@J-M-L
OP posted https://circuits.io/circuits/3971304-first-test#breadboard
does not work on my tablet nor on my Mac... (and I don't like clicking away from the site...)
Hello - Please do not PM me for help,  others will benefit as well if you post your question publicly on the forums.
Bonjour Pas de messages privés SVP, postez dans le forum directement pour que ça profite à tous

sterretje

#4
Feb 11, 2017, 07:58 pm Last Edit: Feb 11, 2017, 08:00 pm by sterretje
OK, just a description.

1)
An ordinary 16x2 LCD (no I2C or whatever)
2)
Two buttons with pull-down resistors, connected to pins 6 and 7 of an Arduino

Note:
From OP's description, this is just a test; no analogReads involved.
If you understand an example, use it.
If you don't understand an example, don't use it.

Electronics engineer by trade, software engineer by profession. Trying to get back into electronics after 15 years absence.

J-M-L

#5
Feb 11, 2017, 08:00 pm Last Edit: Feb 11, 2017, 08:01 pm by J-M-L
this only handles the "bottom" case on pin 6
Code: [Select]
void getButtonPush(char *resultButton, int pin, int pause)
{
  int data = digitalRead(6);
  if (data == HIGH)
  {
    strcpy(resultButton, "bottom");
  }
  delay(pause);
  Serial.println("digital reading status");
  Serial.println(resultButton);
}


your arduino is super fast, I don't see any boundary check on the value of opcion.. what happens when you go beyond the number or columns of your LCD?
Code: [Select]
    if (!strcmp(resultButton, "bottom"))
    {
      Serial.println("opcion value BEFORE ");
      Serial.println(opcion);
      opcion=opcion+1;//con el boton de abajo va aumentando para indicar en que fila va el cursor
    }
    lcd.setCursor(0, opcion);
    lcd.write(byte(0)); // muestra el punto que indica donde esta el cursor


Hello - Please do not PM me for help,  others will benefit as well if you post your question publicly on the forums.
Bonjour Pas de messages privés SVP, postez dans le forum directement pour que ça profite à tous

sterretje

@Amaliaairi

Do you see the message "button response before IF" in the serial monitor after pressing the button? If not, you have your button wired incorrectly.

Further, why do you use text like "bottom" or "up" to know which button is pressed? Numeric values are far easier (and cheaper on memory).
If you understand an example, use it.
If you don't understand an example, don't use it.

Electronics engineer by trade, software engineer by profession. Trying to get back into electronics after 15 years absence.

Go Up