Hi, I have constructed a home plant watering system with an I2C 2x16 LCD display, 4x4 keypad and relay module (to control the water pump). I have a programming problem. In the code I wrote, the LCD display goes crazy and shows kind of simultaneous text from different loops, and the keyboard is completely unresponsive. The program was intended to work like this:
- display a message on the LCD: "Hello, take care of your plants!",
- display a message on the LCD asking you to input a variable ( for how many hours watering will happen):
"Interval [h]:" (it must be possible to enter more than one number). - after pressing "#" on the keypad, clearing the screen and displaying a message on the screen asking you to input a variable (how long the plants will be watered):
"Watering [s]:" (as for the interval, more than one number). - after pressing "A" on the keypad , start the timer and display a message on the display: "Wait :)"
- when the time expires, clearing the LCD display, displaying the message "Watering!!!" and activation of the pump relay
for a previously specified time. - after watering return to start timer function again and display message on the display: "Wait :)"
- after pressing the "B" button - Additional watering beyond the countdown and return to step 6.
- after the "C" button is pressed - reset the program, so that the variables can be re-entered.
I've tried many different approaches and I can't get over the problem. I would greatly appreciate your help.
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <Keypad.h>
#include <millisDelay.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);
const byte ROWS = 4;
const byte COLS = 4;
char keys[ROWS][COLS] = {
{'1', '2', '3', 'A'},
{'4', '5', '6', 'B'},
{'7', '8', '9', 'C'},
{'*', '0', '#', 'D'}
};
byte rowPins[ROWS] = {9, 8, 7, 6};
byte colPins[COLS] = {5, 4, 3, 2};
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
const int Relay= 10;
bool RelayState= HIGH;
int hoursToWater;
int wateringTime;
millisDelay mdTimer1;
void setup() {
pinMode(Relay, OUTPUT);
digitalWrite(Relay, HIGH);
lcd.init();
lcd.backlight();
lcd.setCursor(0,0);
lcd.print("Hello, take care");
lcd.setCursor(0,1);
lcd.print("of your plants!");
delay(3000);
}
void loop() {
watering_interval();
watering_time();
watering_loop();
}
void watering_interval() {
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Interval [h]:");
char key = keypad.getKey();
static String firstNumber = "";
if (key != NO_KEY) {
if (key >= '0' && key <= '9') {
firstNumber += key;
}
else if (key == '#') {
int hoursToWater = atoi(firstNumber.c_str());
lcd.setCursor(0,1);
lcd.print(hoursToWater);
delay(3000);
watering_time();
}
}
}
void watering_time() {
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Watering [s]:");
char key = keypad.getKey();
static String secondNumber = "";
if (key != NO_KEY) {
if (key >= '0' && key <= '9') {
secondNumber += key;
}
else if (key == '#') {
int wateringTime = atoi(secondNumber.c_str());
lcd.setCursor(0,1);
lcd.print(wateringTime);
delay(3000);
watering_loop();
}
}
}
void watering_loop() {
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Press A)");
char key = keypad.getKey();
if (key != NO_KEY) {
if (key == 'A') {
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Wait :)");
int hoursToWater2= hoursToWater*3600000;
mdTimer1.start(hoursToWater2);
//delay(hoursToWater2);
if (mdTimer1.justFinished()){
lcd.print("Watering!!!");
digitalWrite(Relay, LOW);
int wateringTime2= wateringTime*1000;
delay(wateringTime2);
digitalWrite(Relay, HIGH);
}
}
else if (key == 'B') {
int hoursToWater2= hoursToWater*3600000;
delay(hoursToWater2);
lcd.print("Watering!!!");
digitalWrite(Relay, LOW);
int wateringTime2= wateringTime*1000;
delay(wateringTime2);
digitalWrite(Relay, HIGH);
watering_loop();
}
else if (key == 'C') {
watering_interval();
}
}
}