#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <Keypad.h>
#include <EEPROM.h>
const int passwordLength = 4; // Set the length of the password
char password[] = "1234"; // Set your desired password here
float pricePerLiter = 200; // Default price per liter
const int eepromAddress = 0; // EEPROM address for storing the price
const int flowSensorPin = 2; // Connect your flow sensor to this pin
const int solenoidValvePin = 3; // Connect your solenoid valve to this pin
const int waterPumpPin = 12; // Connect your water pump to this pin
const int startButtonPin = 13; // Connect a push button to this pin to start dispensing
volatile unsigned int pulseCount = 0;
float volumeDispensed = 0.0;
float amountSpent = 0.0;
short a = 0, i = 0, s = 0, j = 0; // Variables used later
float calibrationFactor = 90;
float flowRate = 0.0;
unsigned int flowMilliLitres = 0;
unsigned long totalMilliLitres = 0, volume = 0;
unsigned long oldTime;
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] = {11, 10, 9, 8};
byte colPins[COLS] = {7, 6, 5, 4};
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
LiquidCrystal_I2C lcd(0x27, 16, 2);
bool dispensingInProgress = false; // Flag to indicate dispensing is in progress
bool dispenseButtonPressed = false; // Flag to indicate the dispense button is pressed
void setup() {
Serial.begin(9600);
lcd.init();
lcd.backlight();
pinMode(flowSensorPin, INPUT_PULLUP);
pinMode(solenoidValvePin, OUTPUT);
pinMode(waterPumpPin, OUTPUT);
pinMode(startButtonPin, INPUT);
attachInterrupt(digitalPinToInterrupt(flowSensorPin), pulseCounter, FALLING);
// Read price per liter from EEPROM
EEPROM.get(eepromAddress, pricePerLiter);
updateLCD();
}
void loop() {
char key = keypad.getKey();
if (key != NO_KEY) {
if (key == '*') {
lcd.clear();
lcd.print("Enter password");
lcd.setCursor(0, 1);
// User is entering the password
char enteredPassword[passwordLength];
int passwordIndex = 0;
while (true) {
key = keypad.getKey();
if (key != NO_KEY) {
if (key == 'A') {
break; // Exit password entry if 'A' is pressed
}
enteredPassword[passwordIndex++] = key;
//lcd.setCursor(0,1);
lcd.print("*"); // Display asterisks to mask the password
}
if (passwordIndex == passwordLength) {
// Check if the entered password is correct
enteredPassword[passwordLength] = '\0'; // Null-terminate the entered password
if (strcmp(enteredPassword, password) == 0) {
// Password is correct, allow access to the menu
inputMoney();
} else {
// Password is incorrect, show an error message
lcd.clear();
lcd.print("Invalid password");
delay(1000);
updateLCD();
}
break;
}
}
}
if (key == '#') {
adjustPrice();
}
if (key == 'D') {
// Clear the amount input
lcd.clear();
updateLCD();
}
}
// Check if the start button is pressed to initiate dispensing
//if (digitalRead(startButtonPin) == HIGH && !dispensingInProgress && dispenseButtonPressed) {
// Call startDispensing with the calculated litersToDispense
//startDispensing();
//}
}
void inputMoney() {
lcd.clear();
lcd.print("EnterAmount:");
Serial.println("Enter the amount to spend (e.g., 5.00): ");
String inputAmount = "";
while (true) {
char key = keypad.getKey();
if (key == 'A') {
// Calculate the volume based on user input and price per liter
float moneyToSpend = inputAmount.toFloat();
float litersToDispense = moneyToSpend / pricePerLiter;
// Prompt the user to press the dispense button
lcd.clear();
lcd.print("To despense");
lcd.setCursor(0, 1);
lcd.print (litersToDispense);
lcd.setCursor(5,1);
lcd.print("Liters");
//lcd.print("Press DISPENSE");
//lcd.setCursor(0, 1);
//lcd.print("to start");
dispenseButtonPressed = false; // Reset the dispense button flag
while (true) {
if (digitalRead(startButtonPin) == HIGH) {
// Dispense button pressed, start dispensing
startDispensing(litersToDispense);
break; // Exit the inner loop
}
}
break;
} else if (key != NO_KEY) {
inputAmount += key;
lcd.print(key);
Serial.print(key);
}
if (key == 'D') {
// Clear the amount input
lcd.clear();
updateLCD();
}
}
}
void adjustPrice() {
lcd.clear();
lcd.print("Enter price:");
Serial.println("Enter the new price per liter: ");
String inputPrice = "";
while (true) {
char key = keypad.getKey();
if (key == 'A') {
break; // Exit loop when the '#' key is pressed
} else if (key != NO_KEY) {
inputPrice += key;
lcd.print(key);
Serial.print(key);
}
}
pricePerLiter = inputPrice.toFloat();
EEPROM.put(eepromAddress, pricePerLiter); // Store the new price in EEPROM
lcd.clear();
lcd.print("Price updated");
delay(1000);
updateLCD();
}
void startDispensing(float litersToDispense) {
lcd.clear();
flowRate = ((1000.0 / (millis() - oldTime)) * pulseCount) / calibrationFactor;
oldTime = millis();
flowMilliLitres = (flowRate / 60) * 1000;
totalMilliLitres += flowMilliLitres;
unsigned int frac;
Serial.print("Flow rate :-");
Serial.print(flowMilliLitres, DEC);
Serial.print("mL/Second");
Serial.print("\t");
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Speed :");
lcd.print(flowMilliLitres);
lcd.print(" ml/s");
Serial.print("Output Liquid Quantity: ");
Serial.print(totalMilliLitres, DEC);
Serial.println("mL");
Serial.print("\t");
lcd.setCursor(0, 1);
lcd.print("Filled:");
lcd.print(totalMilliLitres);
lcd.setCursor(14, 1);
lcd.print("ml");
// Set dispensing flag to true
dispensingInProgress = true;
// Your dispensing logic goes here
// Example: Dispense for a certain volume
//float targetVolume = 1.0; // 1 liter, adjust as needed
while (volumeDispensed < litersToDispense) {
// Control the solenoid valve and water pump here
digitalWrite(solenoidValvePin, HIGH); // Open solenoid valve
digitalWrite(waterPumpPin, HIGH); // Turn on water pump
// You may need to adjust the flow rate control here based on your setup.
}
digitalWrite(solenoidValvePin, LOW); // Close solenoid valve
digitalWrite(waterPumpPin, LOW); // Turn off water pump
// Reset dispensing flag
dispensingInProgress = false;
Serial.println("Dispensing complete");
updateLCD();
}
void updateLCD() {
lcd.clear();
lcd.print("Press * = Unlock");
lcd.setCursor(0, 1);
lcd.print("Price/Li: ");
lcd.setCursor(11, 1);
lcd.print(pricePerLiter);
}
void pulseCounter() {
pulseCount++;
volumeDispensed = pulseCount / 7.5;
updateLCD();
}