2x16 LCD Shield 'select' button and project code problem

I’ve been looking online for awhile now, and I just can’t seem to figure out how to set a function for the ‘select’ button on the 2x16 LCD Shield (connected to an Arduino Uno). I have tried a number of codes from similar projects, altering them to suit mine, but it doesn’t do what I tell it to do.

My end goal is for the user to press ‘select’ (on the LCD) which will allow the ultrasonic sensor (US) to measure the distance from its placement on the wall (e.g 40cm, above the bathtub’s top edge) to the bottom of the empty bathtub. The code will then take away that 40cm + another 10cm (as an overflow barrier) equalling 50cm in total, revealing the maximum depth (for example 60cm- which equals the distance from the bottom of the bathtub to 10cm from the top). The arduino now knowing the distance, will minus the height/depth the user sets for their water height (e.g 35cm) from the maximum depth measurement (60cm).

The simple calculation would be something like this 60cm (maximum depth) – 35cm (distance set by user) = 25cm (which is the gap, between the water’s surface/level (35cm) and the 10cm mark before the top).

The code below shows some of my work, however I’d need some help altering the code to fit want I stated above.


// include the library code:
#include <LiquidCrystal.h>
#define echoPin 1
#define trigPin 2
#define solenoidPin 3
#define buttonsPin A0
// initialize the library by associating any needed LCD interface pin
// with the arduino pin number it is connected to
const int rs = 8, en = 9, d4 = 4 , d5 = 5, d6 = 6, d7 = 7;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
void setup() {
  Serial.begin (9600);
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
  pinMode(3, OUTPUT); // connected to S terminal of Relay
  pinMode(A0, INPUT);
void loop() {
  // set up the LCD's number of columns and rows:
  lcd.begin(16, 2);
  lcd.setCursor (1, 1); // put your setup code here, to run once:
  lcd.setCursor (0, 0);
  // Print a message to the LCD.
  delay (250);
  lcd.setCursor (0, 0);
  lcd.print("Maximum Distance:");
  lcd.setCursor(1, 1);
  lcd.print("(Hold Select)");
  delay (2000);
  lcd.clear ();
  lcd.setCursor(1, 0);
  lcd.print("Wait till the");
  lcd.setCursor (1, 1);
  lcd.print("screen clears");
  delay (1200);
  int x;
  x = analogRead (0);
  lcd.setCursor(10, 1);
  if (x < 800) {
    lcd.clear ();
    delay (10000);
    Serial.println(x, DEC);
    // Ultrasonic sensor function
    float duration, distance;
    digitalWrite(trigPin, LOW);
    digitalWrite(trigPin, HIGH);
    digitalWrite(trigPin, LOW);
    duration = pulseIn(echoPin, HIGH);
    distance = (duration / 2) * 0.0344;

Thank you for tidying up your posting of code. I use “boilerplate” prompt messages to remind people, so my comments will have moved on to “nudge” someone else. :sunglasses:


I'll have to take your word for it, so i'm assuming now you already tried, and played with this display shield of yours.
In your sketch, you are reading A0 and as i've started assuming already i'll also assume that's where your button presses come in to your Arduino (it is with the shield i've got here).
But in your code, you are making no attempt to do something with it.

If you don't know how to handle each button, here's some advice:

Do what i did when i got the shield years ago.
You've got the display.
That's a great debug tool.
Use the display to show what values you get when pressing the buttons.
Make notes while pressing the buttons.
Expect to see slight variations while pressing the same button multiple times.
So look for a value range instead of some absolute value when processing the button presses.

By the way i'm 100% sure this info is already available, as this is not the first time i'm writing this.

Again: Use that display while debugging your sketches.
It's a powerful tool to use, certainly when it is already available in your design.

But in your code, you are making no attempt to do something with it.

Hello, yes I'm not quite sure how actually to do this function. I updated the code if that changes anything, but when I try and use the US it doesn't work like it would with other codes aimed towards getting the component to read the distance, and shut off the solenoid/relay.

I'm not sure what you want to know right now.
Your updated code shows that you are displaying the values you get from the key presses, and that you only will show these key presses if that value is less than 800.
So other keys won't generate a value lower than 800 ?
I'm sure that's not true.

Your code starts telling something about a maximum distance, but doesn't show anything holding such value.
Instead you're instructing to press a key and wait until the screen clears, after which you'll make an attempt to read the button which might already be released by then (because you instructed so).

There's no need to re-initialise the screen every iteration, and there's no need to waste huge amounts of time.
3.2 seconds to the controller is like waiting 3.2 days to you.
That part is probably just an attempt to read the key and show it, i'd add some comment to remind myself and others what's going on there.
This would make it easier for you to find, and to comment out once you don't need it any more.

Your Ultrasonic function is no function, so do not name it that way.
The word function has a meaning in code, and what you've shown thus far doesn't have a function at that place.

Because your sketch is quite short, i'd make 2 sketches out of them.
A sketch dedicated to testing the key presses, and a sketch measuring your distance and displaying it.
The key press test sketch should tell you the value coming in from each of the keys, and would help you for all future sketches handling these keys.
Use comment lines to clarify what you've found out, and save your sketch for future reference whenever you'll need to use those keys again.

Thanks for the advice, the code was really just bits and pieces of other codes put together, so I truly had no idea what such terminology meant. Despite my efforts exploring the internet, I still hadn't grasped a proper understanding, nor had the time to do so. Even now, I don't completely understand the sections I need to change (its my first project), with a limited time period I might need to do trial and error.

Do you recommend any helpful online sources/examples?

Well all i can tell you, is what works for me.

If i find some interesting code, i'll study it to try and understand what's exactly going on.
I'll test what i think i've learned by altering the code and see if that does what i wanted it to do, and why it doesn't.

I won't start using bits and pieces of code before i'm confident i understand what it does.
Sometimes that means i'll figure out another way to do what i had in mind, and sometimes i can alter some code i found and studied.

So to gather a heap of code, shake it up a bit and expect it to work is not a very effective way to get things done.
It'll frustrate you and make you want to give up, so it's just a waste of time.

Studying code to understand it, takes time.
But it'll be time well spent, as opposed by the alternative mentioned above.

Thanks for the advice. May I ask how you got just the 'select' button to work? Am I doing it right?


I can’t tell for sure from the code so far.
You are testing for a value of less than 800 on A0.
The range of an analog input is 0 - 1023 (so 1024 possible results).
There’s 5 buttons on my shield (which isn’t necessarily the same as yours), so if the range from the buttons would be between 800 and 1023, that would be waste of over half the range.
So i’m sure there’s some buttons which will have a result lower than 800.
These buttons would be processed as the “select” button, if you don’t test that too.
So you’d need to be sure you’re within the range belonging to that “select” button.

Let’s assume your button does resolve to a value of 789 (so <800).
You’d want to know what the next lower value is.
That’s why i pitched the test sketch which will print the read out value to the display already present in your setup; you’ll know all values of each key press.

After that, and if you only need to know whether the “select” button was pressed, you need to check if the value at A0 is between your known values of these buttons.

This way you allow for some deviations which could occur from different causes (like power dips on your Arduino board, for whatever reason).

If you (later) would like to use the other buttons, you’d need to test each of the buttons.
That would be possible with a small loop, a smart order of values to test, and results in a button number which would then be translated to whatever button was pressed.
Remember that no press is also a possibility (like 0 is also a number).

Also, dump the delays.
You don’t need them and there’s a much more elegant way to get the same result without a total waste of processing power.
Do take a look at my signature (which means it is part of each and all of my forum postings).