LCD & Keypad shield question.

The LCD and Keypad Shield gives you a handy 16-character by 2-line display, 5 buttons and a controllable backlight.
Post Reply
aus_sparky
Posts: 5
Joined: Mon Feb 09, 2015 10:04 am

LCD & Keypad shield question.

Post by aus_sparky » Mon Feb 09, 2015 10:20 am

Hi,
I am very new to Arduino, so please forgive my ignorance. I have the Freetronics starter kit, LCD & keypad shield and temp/Humidity sensor and have been able to make up a temperature and humidity display with high humidity alarm. I have also been playing with the example code on the Freetronics website for interfacing the LCD/keypad (up, down, right, left, etc). I don't know if it is able to be done, but I wanted to setup a user adjustable interface where I can adjust the alarm set-point via the up/down keys. I was wondering what is the best way to set up this kind of interface (if it can be done)?
Thanks, Rob.

andrew
Freetronics Staff
Freetronics Staff
Posts: 978
Joined: Sun Jul 14, 2013 7:06 am
Location: Melbourne, Australia
Contact:

Re: LCD & Keypad shield question.

Post by andrew » Mon Feb 09, 2015 11:36 am

This is quite easy to accomplish. Like any problem, just break it down into smaller pieces and tackle each one individually.

The first is to create a sequence of events of what you want to happen - not in code but just normal instructions - for example "if UP button pressed, increase set point". Once you have planned your device you will have an algorithm - a sequence of events that can generally be translated into a sketch.

For example, consider the example sketch for the LCD keypad shield that displays words when buttons are pressed. You can then look at how it works and see how actions are taken when a button is pressed, then change those actions to your requirement.

Have fun, and let us know if you have any questions.

jackperez
Posts: 1
Joined: Mon May 04, 2015 8:06 pm

Re: LCD & Keypad shield question.

Post by jackperez » Thu May 07, 2015 6:56 pm

aus_sparky, as mentioned earlier, it is important to know that you have to break these problems not just because they are easier to implement but also because you can then test your code at each individual stage in order to check if it’s working. About this particular problem, since you’re just starting development, just go with checking these two digital IOs in each cycle. This could be done with external interrupts as well.

quick-turn pcb assembly

aus_sparky
Posts: 5
Joined: Mon Feb 09, 2015 10:04 am

Re: LCD & Keypad shield question.

Post by aus_sparky » Mon May 16, 2016 11:55 am

Thank you for your replies, much appreciated. This is off my original topic but based upon the LCD/keypad example code on the Freetronics website, I am trying to develop an interface on the LCD/keypad shield whereby I am controlling two motors via a Hbridge shield. The lcd will be used to select the individual motor speeds for motors 1 & 2.I am using the left button for motor 1 and the right for motor 2 while the up and down keys are common to both functions. So what I am trying to achieve is by pressing either the left or right button to bring up the speed percentage, then adjust it to the required setting independent of each other. So basically I am trying to setup an "or" type function which I am struggling with currently. I was looking at the "switch" function but not sure if that is the correct function to use, so I am asking for advice please. Please be gentle, I am only a novice... :oops:

My code thus far:

Code: Select all

#include <Wire.h>
#include <LiquidCrystal.h>   // include LCD library

int CounterA;
int CounterB;

// Pins in use
#define BUTTON_ADC_PIN           A0  // A0 is the button ADC input
#define LCD_BACKLIGHT_PIN         3  // D3 controls LCD backlight
// ADC readings expected for the 5 buttons on the ADC input
#define RIGHT_10BIT_ADC           0  // right
#define UP_10BIT_ADC            145  // up
#define DOWN_10BIT_ADC          329  // down
#define LEFT_10BIT_ADC          505  // left
#define SELECT_10BIT_ADC        741  // right
#define BUTTONHYSTERESIS         10  // hysteresis for valid button sensing window
//return values for ReadButtons()
#define BUTTON_NONE               0  // 
#define BUTTON_RIGHT              1  // 
#define BUTTON_UP                 2  // 
#define BUTTON_DOWN               3  // 
#define BUTTON_LEFT               4  // 
#define BUTTON_SELECT             5  // 
//some example macros with friendly labels for LCD backlight/pin control, tested and can be swapped into the example code as you like
#define LCD_BACKLIGHT_OFF()     digitalWrite( LCD_BACKLIGHT_PIN, LOW )
#define LCD_BACKLIGHT_ON()      digitalWrite( LCD_BACKLIGHT_PIN, HIGH )
#define LCD_BACKLIGHT(state)    { if( state ){digitalWrite( LCD_BACKLIGHT_PIN, HIGH );}else{digitalWrite( LCD_BACKLIGHT_PIN, LOW );} }

/*--------------------------------------------------------------------------------------
  Variables
--------------------------------------------------------------------------------------*/
byte buttonJustPressed  = false;         //this will be true after a ReadButtons() call if triggered
byte buttonJustReleased = false;         //this will be true after a ReadButtons() call if triggered
byte buttonWas          = BUTTON_NONE;   //used by ReadButtons() for detection of button events
/*--------------------------------------------------------------------------------------
  Init the LCD library with the LCD pins to be used
--------------------------------------------------------------------------------------*/
LiquidCrystal lcd( 8, 9, 4, 5, 6, 7 );   //Pins for the freetronics 16x2 LCD shield. LCD: ( RS, E, LCD-D4, LCD-D5, LCD-D6, LCD-D7 )
/*--------------------------------------------------------------------------------------
  setup()
  Called by the Arduino framework once, before the main loop begins
--------------------------------------------------------------------------------------*/
void setup()
{
   //button adc input
   pinMode( BUTTON_ADC_PIN, INPUT );         //ensure A0 is an input
   digitalWrite( BUTTON_ADC_PIN, LOW );      //ensure pullup is off on A0
   //lcd backlight control
   digitalWrite( LCD_BACKLIGHT_PIN, HIGH );  //backlight control pin D3 is high (on)
   pinMode( LCD_BACKLIGHT_PIN, OUTPUT );     //D3 is an output
    
   lcd.begin( 16, 2 );
   lcd.setCursor( 0, 0 );
   lcd.print( "MOTOR 1 SPD: " );
   
   lcd.setCursor( 0, 1 );
   lcd.print( "MOTOR 2 SPD:" );

}

/*--------------------------------------------------------------------------------------
  loop()
  Arduino main loop
--------------------------------------------------------------------------------------*/
void loop()
{
   byte button;
   byte timestamp;
   
   //get the latest button pressed, also the buttonJustPressed, buttonJustReleased flags
   button = ReadButtons();
   //blank the demo text line if a new button is pressed or released, ready for a new label to be written
   if( buttonJustPressed || buttonJustReleased )
   {
     lcd.setCursor( 13, 1 );
     lcd.print( "            " );
     lcd.setCursor(13, 0 );
     lcd.print( "            " );
   }
   //show text label for the button pressed
   switch( button )
   {
      case BUTTON_NONE:
      {
         break;
      }
      case BUTTON_RIGHT:
      {
         lcd.setCursor( 13, 0 );
         lcd.print(CounterB);
         delay (300);
         break;
      }
      case BUTTON_UP:
      {
         CounterA +=10;
         lcd.setCursor( 13, 1 );
         lcd.print(CounterA);
         delay (300);
         break;
      }
      {
         CounterB +=10;
         lcd.setCursor( 13, 0 );
         lcd.print(CounterB);
         delay (300);
         break;
      }
      case BUTTON_DOWN:
      {
         CounterA -=10;
         lcd.setCursor( 13, 1 );
         lcd.print(CounterA);
         delay (300);
         break;

        CounterB -=10;
        lcd.setCursor( 13, 0 );
        lcd.print(CounterB);
        delay (300);
        break;
      }
         
      case BUTTON_LEFT:
      {
        lcd.setCursor( 13, 1 );
        lcd.print(CounterA);
        delay (300);
        break;
     }
     case BUTTON_SELECT:
     {
        lcd.setCursor( 13, 1 );
        lcd.print( "CONFIRM" );    
        
        //SELECT is a special case, it pulses the LCD backlight off and on for demo
        digitalWrite( LCD_BACKLIGHT_PIN, LOW );
        delay( 250 );
        digitalWrite( LCD_BACKLIGHT_PIN, HIGH );   //leave the backlight on at exit
        delay( 250 );
        
        /* an example of LCD backlight control via macros with nice labels
        LCD_BACKLIGHT_OFF();
        delay( 150 );
        LCD_BACKLIGHT_ON();   //leave the backlight on at exit
        delay( 150 );
        */
        
        break;
      }
      default:
     {
        break;
     }
   }
   
   //clear the buttonJustPressed or buttonJustReleased flags, they've already done their job now.
   if( buttonJustPressed )
      buttonJustPressed = false;
   if( buttonJustReleased )
      buttonJustReleased = false;
}
/*--------------------------------------------------------------------------------------
  ReadButtons()
  Detect the button pressed and return the value
  Uses global values buttonWas, buttonJustPressed, buttonJustReleased.
--------------------------------------------------------------------------------------*/
byte ReadButtons()
{
   unsigned int buttonVoltage;
   byte button = BUTTON_NONE;   // return no button pressed if the below checks don't write to btn
   
   //read the button ADC pin voltage
   buttonVoltage = analogRead( BUTTON_ADC_PIN );
   //sense if the voltage falls within valid voltage windows
   if( buttonVoltage < ( RIGHT_10BIT_ADC + BUTTONHYSTERESIS ) )
   {
      button = BUTTON_RIGHT;
   }
   else if(   buttonVoltage >= ( UP_10BIT_ADC - BUTTONHYSTERESIS )
           && buttonVoltage <= ( UP_10BIT_ADC + BUTTONHYSTERESIS ) )
   {
      button = BUTTON_UP;
   }
   else if(   buttonVoltage >= ( DOWN_10BIT_ADC - BUTTONHYSTERESIS )
           && buttonVoltage <= ( DOWN_10BIT_ADC + BUTTONHYSTERESIS ) )
   {
      button = BUTTON_DOWN;
   }
   else if(   buttonVoltage >= ( LEFT_10BIT_ADC - BUTTONHYSTERESIS )
           && buttonVoltage <= ( LEFT_10BIT_ADC + BUTTONHYSTERESIS ) )
   {
      button = BUTTON_LEFT;
   }
   else if(   buttonVoltage >= ( SELECT_10BIT_ADC - BUTTONHYSTERESIS )
           && buttonVoltage <= ( SELECT_10BIT_ADC + BUTTONHYSTERESIS ) )
   {
      button = BUTTON_SELECT;
   }
   //handle button flags for just pressed and just released events
   if( ( buttonWas == BUTTON_NONE ) && ( button != BUTTON_NONE ) )
   {
      //the button was just pressed, set buttonJustPressed, this can optionally be used to trigger a once-off action for a button press event
      //it's the duty of the receiver to clear these flags if it wants to detect a new button change event
      buttonJustPressed  = true;
      buttonJustReleased = false;
   }
   if( ( buttonWas != BUTTON_NONE ) && ( button == BUTTON_NONE ) )
   {
      buttonJustPressed  = false;
      buttonJustReleased = true;
   }
   
   //save the latest button value, for change event detection next time round
   buttonWas = button;
   
   return( button );
}
Thanks, Rob.

angusgr
Freetronics Staff
Freetronics Staff
Posts: 853
Joined: Tue Apr 09, 2013 11:19 pm
Location: Melbourne, Australia
Contact:

Re: LCD & Keypad shield question.

Post by angusgr » Wed May 18, 2016 7:11 am

Hi aus_sparky,

Your code looks good, the switch statement is probably the right one to use.

It looks like you might be missing a "case" statement between BUTTON_DOWN and BUTTON_UP, inside the switch.

Angus

aus_sparky
Posts: 5
Joined: Mon Feb 09, 2015 10:04 am

Re: LCD & Keypad shield question.

Post by aus_sparky » Wed May 18, 2016 8:14 am

Thank angus, I will have a play tonight and see if I can achieve what I set out to do.

Post Reply

Who is online

Users browsing this forum: No registered users and 2 guests