Controlling hydraulic press using LCD Keypad (HD44780)

Hi all,

I’m currently trying to make a hydraulic press which can be controlled using an LCD keypad shield on my Arduino UNO board. I’ve grasped the output side of things i.e. controlling the (piston) motor using PMW and a H-bridge shield, however I’m struggling with the code for the LCD Keypad.

The bit I’m struggling with is using the keywords from the library in order to assemble the required functions. As you can see from the code I have attached, I understand that the ‘if’ function needs to be used to recognise if a key has been pressed but I don’t understand what the key should equal when pressed. I’ve tried to find out by looking through the h file and keywords txt doc. in the library but unfortunately to no avail.

I’m certain my code is missing other key parts too (like defining the A0 pin as being the one that reads the keys - I think) so any feedback / criticism on what’s missing; I’d really appreciate it.

Thanks in advance,
Brad

#include <Timer.h>
#include <TimerContext.h>
#include <UptimeInfo.h>
#include <LcdKeypad.h>
#include <LiquidCrystal.h>      // LCD Libary


//Keycodes
#define None       0
#define Select     1
#define Left       2
#define Up         3
#define Down       4
#define Right      5

// LCD interface pins
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

int F = 0

void setup() 
{
// LCD Display
  lcd.begin(16,2);
  lcd.setCursor(0, 0);             
  lcd.print("Applied Force:");
  
}

void loop()
{ 
      
      if(Up == the button thats been pressed)   // What should the buttons = , when pressed?
        {
          F++;
        }

      if(Down == the button thats been pressed)
        {
          F--;
        }

  while(1)                                     // This should mean it continuously updates LCD right?
  {                                       
     lcd.setCursor(13, 0);             
     lcd.print("F", "N");   // F = Force integer, N just to indicate its in Newtons
  }
}

sketch_oct27a.ino (1.01 KB)

If you post your code as described in the how to use this forum-please read stickies more members can see it. Those on phones and tablets may not be able to open a .ino file and others will not download code.

Hi Bradj98, welcome

Your code seems to already have something built in for those keys.
The part starting with //Keycodes tells you what numbers to expect to come back from your library.
I can't tell how to use that library, to me these LCD Keypads are too straightforward to use a library at all.
But any library is supposed to have some kind of instructions on how to use it.
Most of them also have some examples with them which will be very helpful.
The results start with a zero in case no keypresses were detected, and so on.
You can build your code using the 'if' function as you call it.
You can also do that using switch...case (click !)(you may need to do ctrl-F5, a forced refresh, due to some problem at the moment of writing this).

Do not use while() if you don't exactly know what it does.
Because it will block your code permanently (it will 'hang').
It doesn't do what your comment in the same line tells us you assume it would do.
Your value F will not be updated and it will not be printed at all.
Instead it will print the character F.

The code you have so far, isn't close to finished code and isn't that long.
As groundFungus already pointed out, it would be better to show it for all to copy it and paste it in their editor of choice, without the need to download it.

Hi MAS3,

The library came with one example which I spent a couple of hours trying to decipher / adapt to my own scenario, but again, that failed miserably. It uses the following code (see below)…

My understanding of the while loop is that the program will run it over and over, continuously, for as long as the statement is true. Isn’t this what I’d want if the display is to be updated whenever the F value changes?

All the code for controlling the motor I’ve left out as I have tested that using push buttons and works fine, it’s just the code for the LCD keypad I’m trying to complete. I would have thought once I can get it to a state where if the up button is pressed it increases the integer by 1; then I’ll be able to write all the other code (buttons) based on that.

P.s.
I attached the code using the method stated in the ‘how to use this forum’ (inserting
code between the

), are you still not able to see it below my orignal post?

[code]// Timer library, https://github.com/dniklaus/arduino-utils-timer
#include <Timer.h>

// LcdKeypad, https://github.com/dniklaus/arduino-display-lcdkeypad
#include <LcdKeypad.h>

LcdKeypad* myLcdKeypad = 0;

// Implement specific LcdKeypadAdapter in order to allow receiving key press events
class MyLcdKeypadAdapter : public LcdKeypadAdapter
{
private:
  LcdKeypad* m_lcdKeypad;
  unsigned char m_value;
public:
  MyLcdKeypadAdapter(LcdKeypad* lcdKeypad)
  : m_lcdKeypad(lcdKeypad)
  , m_value(7)
  { }

  // Specific handleKeyChanged() method implementation - define your actions here
  void handleKeyChanged(LcdKeypad::Key newKey)
  {
    if (0 != m_lcdKeypad)
    {
      if (LcdKeypad::UP_KEY == newKey)
      {
        m_value++;
      }
      else if (LcdKeypad::DOWN_KEY == newKey)
      {
        m_value--;
      }
      m_lcdKeypad->setCursor(0, 1);  // position the cursor at beginning of the second line
     
      m_lcdKeypad->print(m_value);             // print the value on first line of the display
      m_lcdKeypad->print("                ");  // wipe out characters behind the printed value
     
      // RGB colored backlight: set according to the current value
      // monochrome backlight: set backlight on or off according to the current value
      m_lcdKeypad->setBacklight(static_cast<LcdKeypad::LcdBacklightColor>(LcdKeypad::LCDBL_WHITE & m_value));
    }
  }
};
    
void setup()
{
  myLcdKeypad = new LcdKeypad();  // instatiate an object of the LcdKeypad class, using default parameters
  
  // Attach the specific LcdKeypadAdapter implementation (dependency injection)
  myLcdKeypad->attachAdapter(new MyLcdKeypadAdapter(myLcdKeypad));
  
  myLcdKeypad->setCursor(0, 0);   // position the cursor at beginning of the first line
  myLcdKeypad->print("Value:");   // print a Value label on the second line of the display
}
    
void loop()
{
  yield();  // Get the timer(s) ticked, in particular the LcdKeypad dirver's keyPollTimer
}

Hi again.

You understood that part right:
A while statement checks for some condition, and while that condition is true, it will do what's between the {curly braces} that are part of the loop.
True is a 1 and false is a 0.
So while (1) is always true.
Once your code has passed the while(1) part, it will lock itself in it's {} and keep doing what is in there, unless the condition is broken.
But it never will unless you break it (and you're not doing that).
Now have a look what happens within those {}.
All i can see is a cursor is set to the same position, after which 2 characters are being printed to the LCD.
And an assumption that some value is printed.
Your description hints you expect some automagically updated value, but that is nowhere in your code.

Dump the while() it does not do what you thought it would do, and you really don't need it at all.
Hint:
Open the Arduino IDE.
It will show you the minimum contents of a sketch, needed for the compiler to run without errors.
What you see are 2 functions, now have a look at their names and their descriptions.
I am confident that you now see you do not need to use while() to get what you really want.

You fixed your 1st. post by putting the code between [code] [/code] tags.
But in your last post you told us about you using these tags by typing them in your text.
But you can't do that the way you did because of the way the forum software works.
So now your code contains text which isn't part of your code.
But kudos for trying.

The example code you put in your last post, seems to get a value called newKey (a function or library named LcdKeypad is called to get that).
So if you are using this example in your code, do your if (or switch...case) on this variable.
You could also call the function/library yourself and put the result in a variable with a name you like better.

On a personal note:
I don't like using such libraries very much.
It does some 'magic' so you don't have to think about what's happening.
But that way, you'll have a hard time understanding what's going on in YOUR sketch.
If you want to understand what's all going on, you'd have to study this library's internal workings.
All you know now is that if a (new) key state is detected (which means any key or no key at all is now pressed), you will get another value from some black box.
If getting this is very complicated (like some timing sensitive actions), then a library would be OK.
But as i said, this doesn't seem to be that complicated to me.
So i like to use code for this i wrote myself after studying how things are supposed to work.

Dump the while() it does not do what you thought it would do

I understand, the loop{} already does what a while(1) would do, so it’s pointless to use it the way I had.

You’re spot on about the use of libraries and how unless you thoroughly understand them it will complicate the sketch.

I was fortunate enough to have someone send me this working sketch which I was able to play around with and understand the Switch…case you mentioned in your first comment. I’ve since adapted it to my application and it works great. Thank you for your help.

// forum 643180

//Sample using LiquidCrystal library
#include <LiquidCrystal.h>

//BASED ON.....
/*******************************************************

  This program will test the LCD panel and the buttons
  Mark Bramwell, July 2010

********************************************************/

// select the pins used on the LCD panel
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

// define some values used by the panel and buttons
int lcd_key     = 0;
int adc_key_in  = 0;
#define btnRIGHT  0
#define btnUP     1
#define btnDOWN   2
#define btnLEFT   3
#define btnSELECT 4
#define btnNONE   5

// read the buttons
int read_LCD_buttons()
{
  adc_key_in = analogRead(0);      // read the value from the sensor
  // my buttons when read are centered at these valies: 0, 144, 329, 504, 741
  // we add approx 50 to those values and check to see if we are close
  if (adc_key_in > 1000) return btnNONE; // We make this the 1st option for speed reasons since it will be the most likely result
  // For V1.1 us this threshold
  if (adc_key_in < 50)   return btnRIGHT;
  if (adc_key_in < 250)  return btnUP;
  if (adc_key_in < 450)  return btnDOWN;
  if (adc_key_in < 650)  return btnLEFT;
  if (adc_key_in < 850)  return btnSELECT;

  // For V1.0 comment the other threshold and use the one below:
  /*
    if (adc_key_in < 50)   return btnRIGHT;
    if (adc_key_in < 195)  return btnUP;
    if (adc_key_in < 380)  return btnDOWN;
    if (adc_key_in < 555)  return btnLEFT;
    if (adc_key_in < 790)  return btnSELECT;
  */


  return btnNONE;  // when all others fail, return this...
}

int myVal = 0; 

void setup()
{
  lcd.begin(16, 2);              // start the library
  lcd.setCursor(0, 0);
  lcd.print("Push the buttons"); // print a simple message
  lcd.setCursor(12, 1);
  if (myVal < 1000) lcd.print(" ");
  if (myVal < 100) lcd.print(" ");
  if (myVal < 10) lcd.print(" ");
  lcd.print(myVal);
}

void loop()
{
  lcd.setCursor(7, 1);           // move cursor to second line "1" and 7 spaces over
  lcd.print(millis() / 1000);    // display seconds elapsed since power-up


  lcd.setCursor(0, 1);           // move to the begining of the second line
  lcd_key = read_LCD_buttons();  // read the buttons

  switch (lcd_key)               // depending on which button was pushed, we perform an action
  {
    case btnRIGHT:
      {
        lcd.print("RIGHT ");
        break;
      }
    case btnLEFT:
      {
        lcd.print("LEFT   ");
        break;
      }
    case btnUP:
      {
        lcd.print("UP    ");
        myVal++;
        lcd.setCursor(12, 1);
        if (myVal < 1000) lcd.print(" ");
        if (myVal < 100) lcd.print(" ");
        if (myVal < 10) lcd.print(" ");
        lcd.print(myVal);
        delay(100);
        break;
      }
    case btnDOWN:
      {
        lcd.print("DOWN  ");
        myVal--;
        if (myVal < 0) myVal = 0;
        lcd.setCursor(12, 1);
        if (myVal < 1000) lcd.print(" ");
        if (myVal < 100) lcd.print(" ");
        if (myVal < 10) lcd.print(" ");
        lcd.print(myVal);
        delay(100);
        break;
      }
    case btnSELECT:
      {
        lcd.print("SELECT");
        break;
      }
    case btnNONE:
      {
        lcd.print("NONE  ");
        break;
      }
  }

}

}