#include <LiquidCrystal_I2C.h>
#include <Keypad.h>
#include <Servo.h>
/* Pins */
const int RELAY_PIN = 4;
const int SERVO_PIN = 3;
/* LCD */
LiquidCrystal_I2C lcd(0x27, 16, 2);
/* Servo */
Servo valve;
/* Keypad setup */
const byte KEYPAD_ROWS = 4;
const byte KEYPAD_COLS = 4;
byte rowPins[KEYPAD_ROWS] = {12, 11, 10, 9};
byte colPins[KEYPAD_COLS] = {8, 7, 6, 5};
// Updated keypad layout
char keys[KEYPAD_ROWS][KEYPAD_COLS] = {
{'1', '2', '3', ' '},
{'4', '5', '6', ' '},
{'7', '8', '9', ' '},
{'.', '0', 'E', '*'} // 'E' = Enter ↵
};
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, KEYPAD_ROWS, KEYPAD_COLS);
/* Global */
float enteredLiters = 0.0;
bool dispensing = false;
unsigned long startTime = 0;
unsigned long dispenseTime = 0; // ms
bool decimalMode = false;
float decimalFactor = 0.1;
void setup() {
pinMode(RELAY_PIN, OUTPUT);
digitalWrite(RELAY_PIN, LOW);
valve.attach(SERVO_PIN);
valve.write(0); // closed
lcd.init();
lcd.backlight();
lcd.print("Enter volume (L):");
}
void loop() {
char key = keypad.getKey();
if (key) {
if (key >= '0' && key <= '9') {
if (!decimalMode) {
enteredLiters = enteredLiters * 10 + (key - '0');
} else {
enteredLiters = enteredLiters + (key - '0') * decimalFactor;
decimalFactor *= 0.1;
}
lcd.clear();
lcd.print("Volume: ");
lcd.print(enteredLiters, 2);
lcd.print(" L");
}
else if (key == '.') { // decimal point
if (!decimalMode) {
decimalMode = true;
}
}
else if (key == 'E') { // Enter key as E
dispenseTime = enteredLiters * 2000UL; // Assuming 1L is dispensed in 2sec.
lcd.clear();
lcd.print("Dispensing ");
lcd.setCursor(0,1);
lcd.print(enteredLiters, 2);
lcd.print(" L");
dispensing = true;
startTime = millis();
valve.write(90); // open valve
digitalWrite(RELAY_PIN, HIGH); // turn on pump
}
else if (key == '*') { // reset
enteredLiters = 0.0;
decimalMode = false;
decimalFactor = 0.1;
dispensing = false;
valve.write(0);
digitalWrite(RELAY_PIN, LOW);
lcd.clear();
lcd.print("Enter volume (L):");
}
}
if (dispensing) {
if (millis() - startTime >= dispenseTime) {
valve.write(0); // close valve
digitalWrite(RELAY_PIN, LOW);
dispensing = false;
lcd.clear();
lcd.print("Done!");
delay(1500);
lcd.clear();
lcd.print("Enter volume (L):");
enteredLiters = 0.0;
decimalMode = false;
decimalFactor = 0.1;
}
}
}