Pages: [1] 2   Go Down
Author Topic: LCD shield menu  (Read 2042 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 9
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hello,
I'm beginig my adventure with Arduino Mega 2560.
I was bought a LCD shield with keyboard.
I want to build some menu.
This shield have 6 push buttons who's connected to analog pin A0 (select, right, left, up, down, reset).
They gives values: 142, 328, 0, 504, 741.
Menu must have 6 windows for egzample:
1
2
3
4
5
6
If I will start the program on LCD should be 1.
When I press a right button should be 2.
When I press a right button once again it sholud go to 3.
.
.
.
as to 6.
When i press left it shold revers to previous.

I try to do this with switch case structures but is no good idea.

How i shold to do this??

Sorry for my english - im begining smiley
Thank you!




Logged

Germany
Offline Offline
Full Member
***
Karma: 0
Posts: 214
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I didn't understand how the LCD shield is exactly wired to your Arduino?
All pushbuttons are connected to A0 and you distinguish which is pressed by an analogread value?
Maybe post a link where you bought it.
Logged

using Arduino Uno Rev 3

Offline Offline
Newbie
*
Karma: 0
Posts: 9
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

By an analogread value i read a value of button.
All pushbutton are connected to A0, everyone of this button have another value
for egzample right = 0.
Logged

Germany
Offline Offline
Full Member
***
Karma: 0
Posts: 214
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

sounds interesting
hav never heard about this before
maybe share a link where you bought it?

Switch case is not a bad approach but allow a range because analogread is not exact.
By the way how big is your screen character resolution 16x02 e.g. ?
Logged

using Arduino Uno Rev 3

Germany
Offline Offline
Full Member
***
Karma: 0
Posts: 214
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

i just found
   MenuBackend
hope it helps
Logged

using Arduino Uno Rev 3

Offline Offline
Newbie
*
Karma: 0
Posts: 9
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I bought lcd shield like this one:
http://www.robotshop.com/dfrobot-lcd-keypad-shield-arduino-3.html

My screen character resolution is 16x2.

this is problem - analogread is not exact,
i sholud give a section of value for every key,
becouse raesitance can change with temparature etc.


'karlok' i just seen MenuBackend i google.
Can you post link with your?

Logged

Germany
Offline Offline
Full Member
***
Karma: 0
Posts: 214
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks for the link. Now I understand better.

i sholud give a section of value for every key,
yes, a range. maybe +/- 5% or so, it depends on your given values.
What is analogread when no pushbutton is connected? If it is not a constant value, you might use a pullup/pulldown resistor.
Maybe post your exact table. If you don't know - just test it.
You mentioned 6 buttons (select, right, left, up, down, reset) but only 5 values (142, 328, 0, 504, 741).

If they are linearray arranged you could calculate the pushbutton's id. Something like analogread(0)/6
see attached graph

And MenuBackend is a library I just found, however you can make your own menu like you want it without this library.
Just google it  - menubackend arduino → arduino.cc › ... › Software › Development → MenuBackend, new menu managment library.


* Screenshot 20121027 14.06.05.png (1.92 KB, 439x173 - viewed 22 times.)
Logged

using Arduino Uno Rev 3

Offline Offline
Newbie
*
Karma: 0
Posts: 9
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

When no pushbutton is connected analogread value is 1023.
I didnt write 6th value becouse is reset, the same whos on arduino board.

I want to write my own menu.
So I have one idea:

dod is a intiger

void loop()
{
  dod == 0;
  sensVal = analogRead(A0);
 
  if (sensVal == 142 )
 {
  dod ++;
  delay(500);
 }
 
  if (sensVal == 0 )
 {
  dod --;
  delay(500);
  }
switch (dod) {
    case 0:
      lcd.clear();
      lcd.setCursor(0,0);             
      lcd.print("work");
      delay(1000);
      break;
    case 1:
      lcd.clear();
      lcd.setCursor(0,0);             
      lcd.print("do");
      delay(100);
      break;
   
.
.
.
.
.
.
    case 6:
         lcd.clear();
         lcd.setCursor(0,0);             
         lcd.print("nothing");
         delay(100);
         break;

 }

What are You thinkig about this?

I must limit a dod value to 6 and 0.
This program is working, but it's not exact.
When it's in example case 1, on lcd is ''nothing'',
so what sholud i do to eliminate blink with delay frequency?
I want to constans print on lcd and I dont have Idea to do this.
« Last Edit: October 28, 2012, 08:18:40 am by employer » Logged

Germany
Offline Offline
Full Member
***
Karma: 0
Posts: 214
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I already told you how I would use the fact that the values are arranged in a linear correlation, look my diagram above.
And use some round function, there has to be one already I think. (I don't mean casting the value but really rounding it like 2.5~3; 2.4~2)
Logged

using Arduino Uno Rev 3

Offline Offline
Newbie
*
Karma: 0
Posts: 9
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I already told you how I would use the fact that the values are arranged in a linear correlation, look my diagram above.
And use some round function, there has to be one already I think. (I don't mean casting the value but really rounding it like 2.5~3; 2.4~2)

I dont understand what you exact mean.
I should divide anlaogread by 6 and suply a sensVal and give a range for every button?

How can I exterminade a blink inscription on lcd??
 case 0:
      lcd.clear();
      lcd.setCursor(0,0);             
      lcd.print("work");
      delay(1000);
      break;
I want to constans descirption show for every case without delay.
Is it any command to do this?

Logged

Germany
Offline Offline
Full Member
***
Karma: 0
Posts: 214
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Do you see my diagram I have created for you?
What do you recognize?

This is the table, isn't it? Please check it, that is important.

Code:
BUTTON | READ
left       0
select   142
right    328
up       504
down     741
reset  reset


If you see that this curve is linear, you may assume that all the values are multiples of the smallest one (142) which is not exact but approximately.
You should repeat the analogRead test some times to get a good average value for each button.

Just divide the analogRead by the smallest one whose the other values are multiples of or use some average value approach.

And I forgot the best: You don't even range checking!


* Screenshot 20121029 12.36.25.png (10.75 KB, 609x521 - viewed 22 times.)
Logged

using Arduino Uno Rev 3

Offline Offline
Newbie
*
Karma: 0
Posts: 9
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

So i should create some buttons id?
I should divide every button value by for example 2 and save it in intiger?

Can you post part of program with this?
Will be very easier to understand.

Thank you for intersting my problem.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 32
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hello, try this code:

Code:
/* FILE:    ARD_LCD_HCARDU014_Buttons_Example.pde
   DATE:    02/07/12
   VERSION: 0.1

 This is a simple example of how to use the buttons included on the
 HobbyComponents Arduino LCD shield (HCARDU0014). The shield will work
 with the standard Arduino LiquidCrystal library.
 
 The buttons when pressed apply different offset voltages to the
 Arduino ADC0. Reading the ADC will give an ADC code in the following
 range depending on which button has been pressed:

     Between 0 & 49 = RIGHT button pressed.
     Between 50 & 194 = UP button pressed.
     Between 195 & 379 = DOWN button pressed.
     Between 380 & 555 = LEFT button pressed.
     Between 555 & 789 = SELECT button pressed.
 
     Above and ADC code of 790, assume no button has been pressed.
 
You may copy, alter and reuse this code in any way you like but please
leave reference to HobbyComponents.com in your comments if you
redistribute this code. */



/* Include the standard LiquidCrystal library */
#include <LiquidCrystal.h>


/* DIO pin definitions */
#define LCD_DATA4 4         /* LCD data DIO pin 4 */
#define LCD_DATA5 5         /* LCD data DIO pin 5 */
#define LCD_DATA6 6         /* LCD data DIO pin 6 */
#define LCD_DATA7 7         /* LCD data DIO pin 7 */
#define LCD_RESET 8         /* LCD Reset DIO pin */
#define LCD_ENABLE 9        /* LCD Enable DIO pin */
#define LCD_BACKLIGHT 10    /*LCD backlight DIO pin */


/* Definitions for current button state */
typedef enum
{
  E_LCD_BTN_RIGHT,          /* LCD RIGHT button pressed */
  E_LCD_BTN_UP,             /* LCD UP button pressed */
  E_LCD_BTN_DOWN,           /* LCD DOWN button pressed */
  E_LCD_BTN_LEFT,           /* LCD LEFT button pressed */
  E_LCD_BTN_SELECT,         /* LCD SELECT button pressed */
  E_LCD_BTN_NONE,           /* LCD NONE button pressed */
}
teButtonState;       


/* Initiliase the LiquidCrystal library with the correct DIO pins */
LiquidCrystal lcd(LCD_RESET, LCD_ENABLE, LCD_DATA4, LCD_DATA5, LCD_DATA6, LCD_DATA7);


void setup() {

  /* Set the correct display size (16 character, 2 line display) */
  lcd.begin(16, 2); 
}


/* Main program loop */
void loop()
{

  /* Put the LCD cursor on the first row and prompt the user to press a button */
  lcd.setCursor(0,0);
  lcd.print("Press a button...");

  /* Keep checking for a button press */
  while (1)
  {
    /* Put the LCD cursor on the second row */
    lcd.setCursor(0,1);

    /* Get the current state of the LCD buttons */
    switch(iGetLCDButtonState())
    {
      /* If the RIGHT button has been pressed then display this on the LCD */
    case E_LCD_BTN_RIGHT:
      lcd.print("RIGHT ");
      break;

      /* If the LEFT button has been pressed then display this on the LCD */
    case E_LCD_BTN_LEFT:
      lcd.print("LEFT   ");
      break;

      /* If the UP button has been pressed then display this on the LCD */
    case E_LCD_BTN_UP:
      lcd.print("UP    ");
      break;

      /* If the DOWN button has been pressed then display this on the LCD */
    case E_LCD_BTN_DOWN:
      lcd.print("DOWN  ");
      break;

      /* If the SELECT button has been pressed then display this on the LCD */
    case E_LCD_BTN_SELECT:
      lcd.print("SELECT");
      break;

      /* If no button has been pressed then display NONE on the LCD */
    case E_LCD_BTN_NONE:
      lcd.print("NONE  ");
      break;
    }
  }
}



/* Read the current state of the LCD buttons using the ADC */
int iGetLCDButtonState()
{
  int iADC_Value;
  int iADC_Button_State = E_LCD_BTN_NONE;

  iADC_Value = analogRead(0);      /* Read the ADC */


  /* If ADC reads above 1000 then assume no buttons have been pressed */
  if (iADC_Value > 1000)
  {
    iADC_Button_State = E_LCD_BTN_NONE;
  }
  else /* If it was below 1000 then a button is pressed... */
  {

    /* If ADC reads between 0 & 49, then the RIGHT button has been pressed */
    if (iADC_Value < 50)             
    {
      iADC_Button_State = E_LCD_BTN_RIGHT;
    }
    else
    {
      /* If ADC reads between 50 & 194, then the UP button has been pressed */
      if (iADC_Value < 195)
      {     
        iADC_Button_State = E_LCD_BTN_UP;     
      }
      else
      {
        /* If ADC reads between 195 & 379, then the DOWN button has been pressed */
        if (iADC_Value < 380)
        {
          iADC_Button_State = E_LCD_BTN_DOWN;
        }
        else
        {
          /* If ADC reads between 380 & 555, then the LEFT button has been pressed */
          if (iADC_Value < 555) 
          {
            iADC_Button_State = E_LCD_BTN_LEFT;
          }
          else
          {
            /* If ADC reads between 555 & 789, then the SELECT button has been pressed */
            if (iADC_Value < 790) 
              iADC_Button_State = E_LCD_BTN_SELECT; 
          }
        }
      }
    }
  }
  return iADC_Button_State;
}
Logged

Germany
Offline Offline
Full Member
***
Karma: 0
Posts: 214
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

That is possible, too. But inconvenient IMHO.
Concerning my approach: To round the value, just operate on the quotient the following
Code:
(int)((float)Q+0.5)
This will round (adding 0.5) instead of trunacte and additionally turning it into an int !
Now simple switch case or the like.

P.S.: Maybe you must cast analogRead to float as well ...
Logged

using Arduino Uno Rev 3

Dee Why NSW
Offline Offline
Full Member
***
Karma: 5
Posts: 206
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I'm not sure what your problem is but the sketch below has worked for me. I have not worried about the analogue values and this just uses the key returns. Check your pins LCD D4 is usually on D4, and my ladder is on pin 14. I don't know what pin 13 is for, and the code seems to work if it is disconnected. This is work in progress. There is an if,do command around line 56

Code:
/*
  The circuit:
 * LCD RS pin to digital pin 8
 * LCD Enable pin to digital pin 9
 * LCD D4 pin to digital pin 16
 * LCD D5 pin to digital pin 5
 * LCD D6 pin to digital pin 6
 * LCD D7 pin to digital pin 7
 * LCD BL pin to digital pin 10
 * KEY pin to analog pin 0        (14)  THIS IS THE BUTTON PIN
 */

#include <LiquidCrystal.h>

LiquidCrystal lcd(8, 13, 9, 16, 5, 6, 7);

char msgs[5][16] = {"Right Key OK ",
                    "Up Key OK    ",               
                    "Down Key OK  ",
                    "Left Key OK  ",
                    "Select Key OK" };

int adc_key_val[5] ={50, 200, 400, 600, 800 };
int NUM_KEYS = 5;
int adc_key_in;
int key=-1;
int oldkey=-1;

void setup()
{
    Serial.begin(9600);
  lcd.clear();
  lcd.begin(16, 2);
  lcd.setCursor(0,0);
  lcd.print("ADC key testing");
}

void loop()
{ //1
  adc_key_in = analogRead(0);    // read the value from the sensor
  key = get_key(adc_key_in);  // convert into key press
 
  if (key != oldkey)   // if keypress is detected "!=" means not equal!!
   {//2
    delay(50);  // wait for debounce time
    adc_key_in = analogRead(0);    // read the value from the sensor
    key = get_key(adc_key_in);    // convert into key press
    if (key != oldkey)   
    {//3   
      lcd.setCursor(0, 1);
      oldkey = key;
      if (key >=0){//4
           lcd.print(msgs[key]);
      Serial.println(key);
     
      if (key == 2)
 {
  Serial.println("            down  ");
 }
     
     
lcd.setCursor(15,1); 
lcd.print(key);

      }//4
    }//3

   }//2
  /*
 if (key = 800)
 {
   delay(2000);
   lcd.clear();
  }
*/
 delay(100);
 
}//1

// Convert ADC value to key number
int get_key(unsigned int input)
{
    int k;
   
    for (k = 0; k < NUM_KEYS; k++)
    {
      if (input < adc_key_val[k])
 {
            return k;
        }
   }
   
    if (k >= NUM_KEYS)k = -1;  // No valid key pressed
    return k;
}
Logged

Pages: [1] 2   Go Up
Jump to: