My Buttons just start going haywire when theres a lcd i2c on it

I'm making an auto gardener, which is my first project. Before I added the header file of LCD I2C, my buttons were all connected and working. It stopped working when I put my first LCD.print() in the void loop() including interaction with the float variable I wanted to print out in the LCD, which would be updated if someone pressed the button. I'm a newbie and I don't want to fail my project. Can someone please help?

Lots of volunteers here offer their skills and time to aid new users with their projects.

By the way, I’m running a simulation in TinkerCAD

Hi, @joemamaandarduino
Welcome to the forum.

Can you please post your code?
Can you please post a circuit diagram?

Have you actually built your project in the real world?

Thanks.. Tom.. :grinning: :+1: :coffee: :australia:

#include <LiquidCrystal_I2C.h>

int lastButtonState = HIGH;
int lastButtonStateLess = HIGH;
int lastButtonStateTarget = HIGH;
int buttonState = HIGH;
int buttonStateLess = HIGH;
int buttonStateTarget = HIGH;
int lastDebounceTime = 0;
int lastDebounceTimeLess = 0;
int lastDebounceTimeTarget = 0;
int debounceDelay = 50;
int count = 0;
char moistLimitString[10];

float moistLimit = 436.0;
unsigned int tempLimit = 18;
unsigned int tempLimitMax = 25;
int changetarget = 0; // Target: 1 = Moisture 2 = Temperature Min 3 = Temperature Max

LiquidCrystal_I2C lcd(0x20,16,2);

void setup()
{
  pinMode(2, INPUT_PULLUP);
  pinMode(3, INPUT_PULLUP);
  pinMode(4, INPUT_PULLUP);
  pinMode(7, OUTPUT);
  pinMode(8, OUTPUT);
  pinMode(12, OUTPUT);
  Serial.begin(9600);
  pinMode(A0, OUTPUT);
  pinMode(A1, INPUT);
  pinMode(A2, INPUT);
  lcd.init();
  lcd.clear();
  lcd.backlight();
  lcd.print("This is");

}

void loop()
{ 
  dtostrf(moistLimit, 6, 2, moistLimitString);
  lcd.setCursor(0,1);
  lcd.print(moistLimitString);
  // Moisture Program
  digitalWrite(A0, HIGH);
  delay(10);
  int moisture = analogRead(A1);
  digitalWrite(A0, LOW);
  // DEBUGGING USE
  // Serial.println(moisture);
  if (moisture < moistLimit) {
    digitalWrite(8, HIGH);
  } else {
    digitalWrite(8, LOW);
  }
  
  // Temperature Program
  const int sensorinput = analogRead(A2);
  float voltage = sensorinput * (5.0 / 1024.0);
  float temp = (voltage-0.5) * 100;
  // DEBUGGING USE
  // Serial.println("Temperature: ");
  // Serial.println(temp);
  if (temp > tempLimitMax || temp < tempLimit) {
    digitalWrite(12, HIGH);
  } else {
    digitalWrite(12, LOW);
  }
  
  // Button Code
  // Increase Button
  int pinValue = digitalRead(2);
  if (pinValue != lastButtonState) {
    lastDebounceTime = millis();
  }
  if ((millis() - lastDebounceTime) > debounceDelay) {
    if (pinValue != buttonState) {
      buttonState = pinValue;
      if (buttonState == LOW) {
        digitalWrite(7, HIGH);
        if (changetarget == 1) {
          moistLimit += 87.2;
          Serial.println(moistLimit);
        } else if (changetarget == 2) {
          	tempLimit += 1;
          	Serial.println(tempLimit);
        } else if (changetarget == 3) {
            tempLimitMax += 1;
            Serial.println(tempLimitMax);
        }
      }
    }
  }
  digitalWrite(7, LOW);

  lastButtonState = pinValue;
  
  // Decrease Button
  int pinValueLess = digitalRead(3); 
  if (pinValueLess != lastButtonStateLess) {
    lastDebounceTimeLess = millis();
  }
  if ((millis() - lastDebounceTimeLess) > debounceDelay) {
    if (pinValueLess != buttonStateLess) {
      buttonStateLess = pinValueLess;
      if (buttonStateLess == LOW) {
        digitalWrite(7, HIGH);
        if (changetarget == 1) {
          moistLimit -= 87.2;
          if (moistLimit < 0) {
            moistLimit = 0.0;
          }
          Serial.println(moistLimit);
        } else if (changetarget == 2) {
          tempLimit -= 1;
          Serial.println(tempLimit);
        } else if (changetarget == 3) {
          tempLimitMax -= 1;
          Serial.println(tempLimitMax);
        } else {
        digitalWrite(7, LOW);
        }
      }
    }
  }
  lastButtonStateLess = pinValueLess;
  
  // Change Target Button
  int pinValueTarget = digitalRead(4);
  if (pinValueTarget != lastButtonStateTarget) {
    lastDebounceTimeTarget = millis();
  }
  if ((millis() - lastDebounceTimeTarget) > debounceDelay) {
    if (pinValueTarget != buttonStateTarget) {
      buttonStateTarget = pinValueTarget;
      if (buttonStateTarget == LOW) {
        digitalWrite(7, HIGH);
        changetarget += 1;
        if (changetarget > 3) {
          changetarget = 0;
        }
        Serial.println(changetarget);
      } else {
        digitalWrite(7, LOW);
      }
    }
  }
  lastButtonStateTarget = pinValueTarget;
}

    
    

  • Do not use magic numbers in your sketches.
    Example do not code like this:
pinValue = digitalRead(2);
  • Instead, code your lines like this:
const byte incrementSwitch = 2;
. . . 
pinValue = digitalRead(incrementSwitch);
  • Always add good comments to you lines of code.

Suggest you install and use the hd44780 library for the LCD.


Please show us actual good images of the wiring.

See post #7.

Where did you determine the LCD has an address of 0x20 ?

I guessed that the default address would be either 0x20 or 0x27. Both of them work.

I implemented the magic number variable thing, and I guess the series resistor looks like this..?
image

1 Like

Please describe what is not working.

Oh, after I made the changes that you said, my buttons now work!

I would've used the hd44780 library if it wasn't for tinkercad, and your suggestions fixed my buttons perfectly! Thank you so much!!!

Is everything working as you want ?

Yes! Do you have any more suggestions for my code and wires?

#include <LiquidCrystal_I2C.h>

byte lastButtonState = HIGH;
byte lastButtonStateLess = HIGH;
byte lastButtonStateTarget = HIGH;
byte buttonState = HIGH;
byte buttonStateLess = HIGH;
byte buttonStateTarget = HIGH;
byte lastDebounceTime = 0;
byte lastDebounceTimeLess = 0;
byte lastDebounceTimeTarget = 0;
const byte debounceDelay = 50;
char moistLimitString[10];

float moistLimit = 436.0;
unsigned int tempLimit = 18;
unsigned int tempLimitMax = 25;
byte changetarget = 0; // Target: 1 = Moisture 2 = Temperature Min 3 = Temperature Max

const byte buttonHigher = 2;
const byte buttonLower = 3;
const byte buttonTarget = 4;
const byte ledYellow = 7;
const byte ledRed = 8;
const byte ledBlue = 12;
const byte moistureOutput = A0;
const byte moistureInput = A1;
const byte tempInput = A2;
LiquidCrystal_I2C lcd(0x20,16,2);

void setup()
{
  pinMode(buttonHigher, INPUT_PULLUP);
  pinMode(buttonLower, INPUT_PULLUP);
  pinMode(buttonTarget, INPUT_PULLUP);
  pinMode(ledYellow, OUTPUT);
  pinMode(ledRed, OUTPUT);
  pinMode(ledBlue, OUTPUT);
  Serial.begin(9600);
  pinMode(moistureOutput, OUTPUT);
  pinMode(moistureInput, INPUT);
  pinMode(tempInput, INPUT);
  lcd.init();
  lcd.clear();
  lcd.backlight();
  lcd.print("Moist Temp- Temp+");

}

void loop()
{ 
  lcd.setCursor(0,1);
  lcd.print(moistLimit / 87.2);
  lcd.setCursor(6,1);
  lcd.print(tempLimit);
  lcd.setCursor(9,1);
  lcd.print(tempLimitMax);
  
  // Moisture Program
  digitalWrite(moistureOutput, HIGH);
  delay(10);
  int moisture = analogRead(moistureInput);
  digitalWrite(moistureOutput, LOW);
  // DEBUGGING USE
  // Serial.println(moisture);
  if (moisture < moistLimit) {
    digitalWrite(ledRed, HIGH);
  } else {
    digitalWrite(ledRed, LOW);
  }
  
  // Temperature Program
  const int sensorinput = analogRead(tempInput);
  float voltage = sensorinput * (5.0 / 1024.0);
  float temp = (voltage-0.5) * 100;
  // DEBUGGING USE
  // Serial.println("Temperature: ");
  // Serial.println(temp);
  if (temp > tempLimitMax || temp < tempLimit) {
    digitalWrite(ledBlue, HIGH);
  } else {
    digitalWrite(ledBlue, LOW);
  }
  
  // Button Code
  // Increase Button
  int pinValue = digitalRead(buttonHigher);
  if (pinValue != lastButtonState) {
    lastDebounceTime = millis();
  }
  if ((millis() - lastDebounceTime) > debounceDelay) {
    if (pinValue != buttonState) {
      buttonState = pinValue;
      if (buttonState == LOW) {
        digitalWrite(ledYellow, HIGH);
        if (changetarget == 1) {
          delay(50);
          moistLimit += 87.2;
        } else if (changetarget == 2) {
          	tempLimit += 1;
          	Serial.println(tempLimit);
        } else if (changetarget == 3) {
            tempLimitMax += 1;
            Serial.println(tempLimitMax);
        }
      }
    }
  }
  digitalWrite(ledYellow, LOW);

  lastButtonState = pinValue;
  
  // Decrease Button
  int pinValueLess = digitalRead(buttonLower); 
  if (pinValueLess != lastButtonStateLess) {
    lastDebounceTimeLess = millis();
  }
  if ((millis() - lastDebounceTimeLess) > debounceDelay) {
    if (pinValueLess != buttonStateLess) {
      buttonStateLess = pinValueLess;
      if (buttonStateLess == LOW) {
        digitalWrite(ledYellow, HIGH);
        if (changetarget == 1) {
          moistLimit -= 87.2;
          if (moistLimit < 0) {
            moistLimit = 0.0;
          }
          Serial.println(moistLimit);
        } else if (changetarget == 2) {
          tempLimit -= 1;
          Serial.println(tempLimit);
        } else if (changetarget == 3) {
          tempLimitMax -= 1;
          Serial.println(tempLimitMax);
        } else {
        digitalWrite(ledYellow, LOW);
        }
      }
    }
  }
  lastButtonStateLess = pinValueLess;
  
  // Change Target Button
  int pinValueTarget = digitalRead(buttonTarget);
  if (pinValueTarget != lastButtonStateTarget) {
    lastDebounceTimeTarget = millis();
  }
  if ((millis() - lastDebounceTimeTarget) > debounceDelay) {
    if (pinValueTarget != buttonStateTarget) {
      buttonStateTarget = pinValueTarget;
      if (buttonStateTarget == LOW) {
        digitalWrite(ledYellow, HIGH);
        changetarget += 1;
        if (changetarget > 3) {
          changetarget = 0;
        }
        Serial.println(changetarget);
      } else {
        digitalWrite(ledYellow, LOW);
      }
    }
  }
  lastButtonStateTarget = pinValueTarget;
}

Here are some changes to the sketch.

I think there is a bit more work to be done to get it 100%.

See if you can follow what is being done.

#include <LiquidCrystal_I2C.h>

int lastButtonState            = HIGH;
int lastButtonStateLess        = HIGH;
int lastButtonStateTarget      = HIGH;
int buttonState                = HIGH;
int buttonStateLess            = HIGH;
int buttonStateTarget          = HIGH;
unsigned long lastDebounceTime;
unsigned long lastDebounceTimeLess;
unsigned long lastDebounceTimeTarget;
int debounceDelay              = 50;
int count                      = 0;

int moisture;
int sensorinput;
float temp;

char moistLimitString[10];

float moistLimit               = 436.0;
unsigned int tempLimitMin      = 18;
unsigned int tempLimitmax      = 25;
int changetarget               = 0; // Target: 1 = Moisture 2 = Temperature Min 3 = Temperature Max

//timing stuff
unsigned long updateTime;


LiquidCrystal_I2C lcd(0x20, 16, 2);


//********************************************^************************************************
void setup()
{
  Serial.begin(9600);

  pinMode(2, INPUT_PULLUP);
  pinMode(3, INPUT_PULLUP);
  pinMode(4, INPUT_PULLUP);

  pinMode(7, OUTPUT);
  pinMode(8, OUTPUT);
  pinMode(12, OUTPUT);
  pinMode(A0, OUTPUT);

  lcd.init();
  lcd.backlight();
  lcd.clear();

}


//********************************************^************************************************
void loop()
{
  //*******************************************
  // Moisture Program
  digitalWrite(A0, HIGH);
  delay(10);

  moisture = analogRead(A1);
  digitalWrite(A0, LOW);

  // DEBUGGING USE
  //Serial.println(moisture);

  if (moisture < moistLimit)
  {
    digitalWrite(8, HIGH);
  }

  else
  {
    digitalWrite(8, LOW);
  }

  //*******************************************
  // Temperature Program
  sensorinput = analogRead(A2);
  float voltage = sensorinput * (5.0 / 1024.0);
  temp = (voltage - 0.5) * 100;
  //DEBUGGING USE
  //Serial.println("Temperature: ");
  //Serial.println(temp);

  if (temp > tempLimitmax || temp < tempLimitMin)
  {
    digitalWrite(12, HIGH);
  }

  else
  {
    digitalWrite(12, LOW);
  }

  //*******************************************                          2
  // Button Code
  // Increase Button
  int pinValue = digitalRead(2);

  if (pinValue != lastButtonState)
  {
    lastDebounceTime = millis();
  }

  if ((millis() - lastDebounceTime) > debounceDelay)
  {
    if (pinValue != buttonState)
    {
      buttonState = pinValue;

      if (buttonState == LOW)
      {
        digitalWrite(7, HIGH);

        switch (changetarget)
        {
          //******************
          case 1:
            {
              moistLimit += 87.2;
            }
            break;

          //******************
          case 2:
            {
              tempLimitMin += 1;
            }
            break;

          //******************
          case 3:
            {
              tempLimitmax += 1;
            }
            break;

        } //END of   switch/case

        //updateLCD();

      }

      else
      {
        digitalWrite(7, LOW);
      }
    }
  }

  lastButtonState = pinValue;

  //*******************************************                          3
  // Decrease Button
  int pinValueLess = digitalRead(3);

  if (pinValueLess != lastButtonStateLess)
  {
    lastDebounceTimeLess = millis();
  }

  if ((millis() - lastDebounceTimeLess) > debounceDelay)
  {
    if (pinValueLess != buttonStateLess)
    {
      buttonStateLess = pinValueLess;
      if (buttonStateLess == LOW)
      {
        digitalWrite(7, HIGH);

        switch (changetarget)
        {
          //******************
          case 1:
            {
              moistLimit -= 87.2;
            }
            break;

          //******************
          case 2:
            {
              tempLimitMin -= 1;
            }
            break;

          //******************
          case 3:
            {
              tempLimitmax -= 1;
            }
            break;

        } //END of   switch/case

        //updateLCD();
      }

      else
      {
        digitalWrite(7, LOW);
      }
    }
  }

  lastButtonStateLess = pinValueLess;

  //*******************************************                          4
  // Change Target Button
  int pinValueTarget = digitalRead(4);

  if (pinValueTarget != lastButtonStateTarget)
  {
    lastDebounceTimeTarget = millis();
  }

  if ((millis() - lastDebounceTimeTarget) > debounceDelay)
  {
    if (pinValueTarget != buttonStateTarget)
    {
      buttonStateTarget = pinValueTarget;

      if (buttonStateTarget == LOW)
      {
        digitalWrite(7, HIGH);
        changetarget += 1;

        if (changetarget > 3)
        {
          changetarget = 0;
        }

        //updateLCD();
      }

      else
      {
        digitalWrite(7, LOW);
      }
    }
  }

  lastButtonStateTarget = pinValueTarget;


  //*******************************************                   TIMER LCD update
  if (millis() - updateTime >= 500ul)
  {
    //restart this TIMER
    updateTime = millis();

    updateLCD();
  }

}


//********************************************^************************************************
void updateLCD()
{
  switch (changetarget)
  {
    //******************
    case 0:
      {
        Serial.println("Moisture");
        Serial.println(moisture);

        Serial.println("Temperature");
        Serial.println(temp);

        lcd.setCursor(0, 0);
        //         0000000000111111
        //         0123456789012345
        lcd.print("Moisture Sensor ");
        lcd.setCursor(0, 1);
        //         0000000000111111
        //         0123456789012345
        //clear line
        lcd.print("                ");
        lcd.setCursor(0, 1);
        lcd.print(moisture);
        lcd.setCursor(9, 1);
        lcd.print(temp);
      }
      break;
    //******************
    case 1:
      {
        Serial.println(moistLimit);

        lcd.setCursor(0, 0);
        //         0000000000111111
        //         0123456789012345
        lcd.print("Mode 1          ");
        lcd.setCursor(0, 1);
        //         0000000000111111
        //         0123456789012345
        //clear line
        lcd.print("                ");
        lcd.setCursor(0, 1);
        lcd.print(moistLimit);
      }
      break;

    //******************
    case 2:
      {
        Serial.println(tempLimitMin);

        lcd.setCursor(0, 0);
        //         0000000000111111
        //         0123456789012345
        lcd.print("Mode 2          ");
        lcd.setCursor(0, 1);
        //         0000000000111111
        //         0123456789012345
        lcd.print("                ");
        lcd.setCursor(0, 1);
        //         0000000000111111
        //         0123456789012345
        //clear line
        lcd.print("                ");
        lcd.setCursor(0, 1);
        lcd.print(tempLimitMin);
      }
      break;

    //******************
    case 3:
      {
        Serial.println(tempLimitmax);

        lcd.setCursor(0, 0);
        //         0000000000111111
        //         0123456789012345
        lcd.print("Mode 3          ");
        lcd.setCursor(0, 1);
        //         0000000000111111
        //         0123456789012345
        //clear line
        lcd.print("                ");
        lcd.setCursor(0, 1);
        lcd.print(tempLimitmax);
      }
      break;

  } //END of   switch/case


}

I don’t know what the part which says updateLCD means.

Also, in mode 0, does the lcd print only the words “Moisture Sensor”?

Every 500ms (1/2 second) the LCD data display is updated.

In mode 0, the moisture and temperature (which still needs some work) is displayed on the second line in the LCD.