Push button to toggle display output not working

Hi all,
I am relatively new to arduino/programming. I am building a chicken egg incubator with an arduino as the controller and am having a problem with a push button. I have a 16 x2 lcd screen and am trying to use a push button to toggle through several potential message displays on the screen.

It is supposed to work like this: I have a variable “displaynumber” that starts at one, each time through the loop, the arduino reads the push button pin and if it is high, it is supposed to add 1 to the displaynumber variable. The displaynumber can get as high as 3 before it resets to 1. Depending on what the displaynumber is, the output to the LCD screen changes.

The momentary on pushbutton has one end wired to +5v on the arduino, and the other end wired to digital pin 6.

With a multimeter I confirmed that there is normally no continuity between the two pins of the pushbutton, and is continuity when pushed, so I don’t think it is an issue with the button itself. I also confirmed that with the button pushed, there is +5v between pin 6 on the arduino, and ground on the arduino. I have made sure to push the button for a long period of time to account for the 2 second delay at the end of the code.

I’m not sure what to troubleshoot next…any ideas?

Thanks!

// Incubator code 4/7/18
// ---------------------------------------------
#include <LiquidCrystal.h>
#include <DHT.h>
//#include <Servo.h>
#define DHTPIN 1                  // Define the temp sensor data pin
#define DHTTYPE DHT22             // define the temp/hum sensor type
#define RELAY 7                  // define the relay control pin - Pin 7                        
//#define SERVO (insert pin here!!!)
DHT dht(DHTPIN, DHTTYPE);         //initialize the temp sensor
//Servo servo;                      //initialize the servo

// LCD Connections:
// rs (LCD pin 4) to Arduino pin 12
// rw (LCD pin 5) to Arduino pin 11
// enable (LCD pin 6) to Arduino pin 10
// LCD pin 15 to Arduino pin 13
// LCD pins d4, d5, d6, d7 to Arduino pins 5, 4, 3, 2
LiquidCrystal lcd(12, 11, 10, 5, 4, 3, 2);    //set up what port the LCD will use
const int backlightPin = 13;                         // pin 13 will control the backlight
const int buttonPin = 6;
int is, im, ih, id, ida;                      // variables for time
float time, s1, m1, h1, d1;                   //  Set up variables to calculate time
int ic, ip, ik;
int angle=90;                                  // variable for angle of servo, set to servo midpoint
int clockwise = 0;                             // variable to set direction of servo sweep
float servotimestep = 1.00;                    // variable to set the time interval in minutes for each degree of servo motion
int displaynumber = 1;                           // variable to switch display screens
float highf=0;                                  // variables to store highest temperature recorded
float lowf=200;                                 // variables to store lowest temperature recorded

// done with initial parameters
void setup()
{
  dht.begin();                                //start the temp sensor
  pinMode(RELAY, OUTPUT);
  pinMode(backlightPin, OUTPUT);
  pinMode(buttonPin, INPUT);                  //set button pin as input
  digitalWrite(backlightPin, HIGH);           // turn backlight on. Replace 'HIGH' with 'LOW' to turn it off.
  lcd.begin(16, 2);                           // columns, rows.  use 16,2 for a 16x2 LCD, etc.
  lcd.clear();                                // start with a blank screen
  lcd.setCursor(0, 0);                        // set cursor to column 0, row 0 (the first row)
  lcd.print("Incubator 1.0");                 // opening line
  lcd.setCursor(0, 1);                        // set cursor to column 0, row 1
  lcd.print("Hatch Them!");
 
  //servo.attach(SERVO);
  
  delay(2000);  
}

void loop() {
 //loop to read the sensor and display
  time = millis();                            //  Get time in milliseconds since tunit turn on
  s1 = time / 1000;                           //  Convert time to seconds, minutes, hours, days
  m1 = s1 / 60;
  h1 = m1 / 60;
  d1 = h1 / 24;
  id = int(d1);                               //  Strip out remainder to leave Days:Hours:Minutes:Seconds
  ih = int((d1 - int(d1)) * 24);
  im = int((h1 - int(h1)) * 60);
  is = int((m1 - int(m1)) * 60);
  // Calculate approximate days till hatch (assume 21 days to hatch)
  ida = 21 - id;
  
  float h = dht.readHumidity();                 // Read the humidity
  float t = dht.readTemperature();              // Read temperature in celsius
  float f = dht.readTemperature(true);          // get the temperature in Fahreheit

 
  if (isnan(h) || isnan(t) || isnan(f)) {
    // if sensor can't be read
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("sensor failure");
    delay(5000);
    return;
  }
  else {
    //set high temp and low temp
  if (h1 > 1 && f > highf){  //1 hour delay for temp stabilization
    highf = f;
  }
  if (h1 > 1 && f < lowf) {  //1 hour delay for temp stabilization
    lowf = f;
  }

if (displaynumber == 1){
    //sensor was read succesfully so print values to LCD
    lcd.clear();                                // Clear the LCD
    //Print temperature and humidity in first line
    lcd.setCursor(0, 0);
    lcd.print("T");
    lcd.print(f, 1);
    lcd.print("F  ");
    lcd.print("H");
    lcd.print(h, 0);
    lcd.print("%");
    lcd.setCursor(0, 1);
      // Print time in format Time: xxd:xxh:xxm:xxs
    lcd.print(id);
    lcd.print("d:");
    lcd.print(ih);
    lcd.print("h:");
    lcd.print(im);
    lcd.print("m:");
    lcd.print(is);
    lcd.print("s");
} 
else if (displaynumber == 2){
 
    lcd.clear();   // Clear the LCD
    //Print max and min temperatures
    lcd.setCursor(0, 0);
    lcd.print("Temp Min: ");
    lcd.print(lowf, 1);
    lcd.print(" F");
    lcd.setCursor(0, 1);
    lcd.print("Temp Max: ");
    lcd.print(highf, 1);
    lcd.print(" F");
}
else if (displaynumber == 3){
    lcd.clear();   // Clear the LCD
    //Print Days to hatch
    lcd.setCursor(0, 0);
    lcd.print("Days 'til hatch:");
    lcd.setCursor(0, 1);
    lcd.print(ida);
}
     
    //Temperature controller
    if (f  < 99.2) {                      //  Set the temperature for the relay to come on (somewhere around 90-101F to get eggs to hatch)
      digitalWrite(RELAY, HIGH);          // Turns ON Relay
    
    }
    else if (f > 99.9) {
      digitalWrite(RELAY, LOW);         // Turns Relay Off
    
    }
    
  }

//manipulate servo for egg turning
//if (m1==servotimestep){

//servotimestep = servotimestep + 1;

//angle = servo.read();
//if (angle <=135 && angle >= 45 && clockwise == 0) {
//  angle = angle-1;
//  servo.write(angle);
//}
//else if (angle < 45 && clockwise == 0) {
//  angle = angle + 1;
//  clockwise = 1;
//  servo.write(angle);
//}
//else if (angle <=135 && angle >= 45 && clockwise == 1) {
//  angle = angle +1;
//  servo.write(angle);
//}
//else if (angle > 135 && clockwise == 1){
//  angle = angle - 1;
//  clockwise = 0;
//  servo.write(angle);  
//}
//}

digitalRead(buttonPin);
if (buttonPin == HIGH){
  displaynumber = displaynumber + 1;
     if (displaynumber > 3){
      displaynumber = 1;
     }
  
}
delay(2000); //delay for dht sensor


}

You haven't stated what the problem is , at least I didn't see it, but, the first thing you should address is whether or not buttonPin needs a pullup/pulldown resistor. The Atmega 328 has built-in pullups you can invoke with input pullup. You may need to adjust the code to account for an inverted signal.

Next, [color=blue]buttonPin[/color] should be debounced. In the IDE - file/examples/digital/debounce.

Thirdly, you're checking to see if [color=blue]buttonPin[/color] is high. If it is, every pass through the code will increment the screen number. What you need to do is sense when [color=blue]buttonPin[/color] _becomes _ high/low. This will give one and only one pulse to the increment code when [color=blue]buttonPin[/color] is active. In the IDE - file/examples/digital/state change detection.

The problem is that my output doesn't change no matter what I do to the button. Doesn't the 2 second delay at the end of the code act as a "debounce"? If anything, a bit much of one :) Because my button is a momentary on, I do only want to detect when it is HIGH, otherwise it would be detecting two state changes per push, low to high, and then high to low.

I do need to add a pull down resistor, thanks for catching that :), but even without one wouldn't the worst thing that could happen be that the display would change without my input (detecting high and switching without my button press? That isn't happening, I can't get the display to change no matter what.

digitalRead(buttonPin);
if (buttonPin == HIGH){
  displaynumber = displaynumber + 1;
     if (displaynumber > 3){
      displaynumber = 1;
     }
  
}

First, sort out your button connections. Second, "buttonPin" is a number = 6. It will always be HIGH, that is not equal to 0. Your conditional test needs to be if( digitalRead(buttonPin)== HIGH)

That solved it, thanks so much!!!