Using Two Buttons For changing device modes in Arduino

Hi Everyone,

I have made an Ultrasonic Distance meter, using a LM35 temperature sensor for accounting for change in the speed of sound due to temperature. I am also using the DHT11 sensor for measuring humidity (the LM35 measures temperature more accurately than the DHT11) so I can account for changes in the speed of sound due to humidity.

I have put in two buttons. BUTTON is used for making distance measurements. The second button BUTTONTWO is for changing the mode of the device i.e. if the measurements should be made in centimetres, feet and inches or to activate Temperature mode. BUTTONTWO only works if BUTTON is not pressed.

However I find my buttons are behaving rather naughty. When I switch on my distance meter, the device keeps changing modes on its own and settles on one mode arbitrarily. The program is written such that when none of the buttons are pressed, the screen will be blank. So when the meter is switched on, it might do its own thing or it might listen to the user. BUTTON for making distance measurements seems to work well. BUTTONTWO is frankly quite arbitrary. Leaving the meter for 5-10 seconds puts the screen into blank mode.

Methinks that upon pressing BUTTONTWO, Arduino reads the button many times for the one second that a user presses it. Hence it keeps on changing modes. But it might or might not change mode when no one is touching it also. Do I need to add some kind a delay in my program so that it measures a button press of at least half a second or so? And how exactly can I do that?

Note: I have connected a 10k resistor to BUTTONTWO and a 4.7k resistor to BUTTON.

// Ultrasonic ranging module

int echoPort = 8;      // Ultrasonic sensor 
int triggerPort = 9;   // Ultrasonic sensor 
#define BUTTON 10     // Button for activating distance meter
#define DHTPIN 11      // Temp & Humidity sensor
#define BUTTONTWO 12  // Button for selecting Cms, Inches or Temp mode
#define DHTTYPE DHT11

int l = 255;
int CHOICE = 1;   // CHOICE is the variable that keeps a track of which mode (cms, inches or temp) the device is to operate in
const int inPin = 0;

// include the library code:
#include <LiquidCrystal.h>
#include <DHT.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(2, 3, 4, 5, 6, 7);
DHT dht(DHTPIN, DHTTYPE);

void setup() {
 pinMode(BUTTON, INPUT);
 pinMode( triggerPort, OUTPUT );
 pinMode( echoPort, INPUT );
 pinMode(BUTTONTWO, INPUT);
 dht.begin();
 Serial.begin( 115200 ); 
 lcd.print( "Ultrasonic ranging module: ");
 delay( 3000 );

 // set up the LCD's number of columns and rows:
 lcd.begin(16, 2);
}

void loop() {

 if (digitalRead(BUTTON) == LOW && digitalRead(BUTTONTWO) == LOW)
 {     
   // This is the temperature mode where the device constantly displays temperature and humidity if CHOICE = 3
        if (CHOICE == 3)
     { int value = analogRead(inPin);      // read the LM35
       float millivolts = (value / 1024.0) * 5000;   // calculate voltage
       float celsius = millivolts / 10;              // calculate temp
       float h = dht.readHumidity();                 //  read humidity

       lcd.clear();
       lcd.setCursor(0, 0);        // print temp
       lcd.print("Temp: ");
       lcd.print(celsius);
       lcd.print("deg C ");
       lcd.setCursor (0, 1);
       lcd.print("Humidity: ");
       lcd.print(h);
       lcd.print(" %\t");
       delay(1500);
     }
     else 
     { lcd.clear();
     }

   // The following code is for reading input on Button 2 and hence changing the device mode
   while (digitalRead(BUTTONTWO) == HIGH && digitalRead(BUTTON) == LOW )
   { CHOICE = CHOICE + 1;
     if (CHOICE == 4) {        CHOICE == 1;      }
     if (CHOICE == 1) {
       lcd.clear();
       lcd.setCursor(0, 0);
       lcd.print("Centimetres Mode ");
       delay(1000 );
     }

     if (CHOICE == 2)  {
       lcd.clear();
       lcd.setCursor(0, 0);
       lcd.print("Inches Mode");
       delay(1000 );
     }

     if (CHOICE == 3){
       lcd.clear();
       lcd.setCursor(0, 0);
       lcd.print("Temp Monitor");
       delay(1000 );
     }

   }
 }

// The following code is for making distance measurements when Button 1 is pressed

if (digitalRead(BUTTON) == HIGH)
{  if (CHOICE != 3)
 {
   digitalWrite(triggerPort, LOW);      // set to LOW trigger's output
   digitalWrite(triggerPort, HIGH);    // send a 10us pulse to the trigger
   delayMicroseconds( 10 );
   digitalWrite(triggerPort, LOW);
   long duration = pulseIn(echoPort, HIGH);

   int value = analogRead(inPin);      // read the LM35
   float millivolts = (value / 1024.0) * 5000;   // calculate voltage
   float celsius = millivolts / 10;              // calculate temp
   float hum = dht.readHumidity();
   float speedofsound = 331.3 + (0.606 * celsius) + (0.0124 * hum );   // calculate speed of sound
   float r = (speedofsound / 100) * duration / 2;    // here we calculate the distance using duration

   lcd.setCursor(0, 0);
   lcd.print("time: ");
   lcd.print(duration);
   lcd.print(" us    ");
   lcd.setCursor(0, 1);

   // For cms

   if (CHOICE == 1) {
     float distance = r / 100.00;
     if ( duration > 38000 ) {
       lcd.println("Out of reach    ");  // if duration is greater than 38ms, the obstacle is out of reach
     }
     else {
       lcd.print("Dist: ");
       lcd.print(distance);
       lcd.println(" cm    ");
     }
   }

   // For Feet and inches

   if (CHOICE == 2) {
     float distance = r / 100.00 * 0.0328084;
     int feet = (int) (distance);
     float inches = 12 * (distance - feet);
     if ( duration > 38000 ) {
       lcd.println("Out of reach    ");  // if duration is greater than 38ms, the obstacle is out of reach
     }
     else {
       lcd.print("Dist: ");
       lcd.print(feet);
       lcd.print(" feet ");
       lcd.print(inches);
       lcd.print(" inches ");
     }
   }

   delay( 1500 );              // wait for 1.5 s

 }
}
}

Please modify your post and use the code button </>

so your code looks like this

and is easy to copy to a text editor. See How to use the Forum Your code is too long to study quickly.

You should probably use pinMode(pin, INPUT_PULLUP) to ensure the pins are not producing spurious values. Then the buttons should connect the pin to GND when pressed and a button press will be detected as LOW so you may need to change your program to match.

…R
PS you can modify your Post.