#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <Keypad.h>
#include <Encoder.h> // Include the Rotary Encoder library
LiquidCrystal_I2C lcd = LiquidCrystal_I2C(0x27, 16, 2); // Initialize 16x2 LCD
#define buzzer 3
#define motorDriver 4
float totalVolume=0;
int inputReset=0;
byte sensorInt = 0;
byte flowsensor = 2;
volatile long pulse;
unsigned long lastTime;
float volume,flowRate;
const byte ROWS = 4;
const byte COLS = 4;
char keys[ROWS][COLS] = {
{'1', '4', '7', '*'},
{'2', '5', '8', '0'},
{'3', '6', '9', '#'},
{'A', 'B', 'C', 'D'}};
const byte colPins[ROWS] = {13, 12, 11, 10};
const byte rowPins[COLS] = {9, 8, 7, 6};
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
unsigned long startTime;
bool menuDisplayed = false; // Track if the menu is currently displayed or not
bool menuReset = false;
char selectedMode = ' '; // Default selected mode is none
bool flowDetectionRunning = false; // Flag to indicate if flow detection is running
unsigned int flowmlt;
unsigned long totalmlt;
unsigned long oldTime;
void setup()
{
pulse = 0;
flowmlt = 0;
totalmlt = 0;
oldTime = 0;
pinMode(5,INPUT);
pinMode(buzzer, OUTPUT);
pinMode(motorDriver, OUTPUT);
pinMode(flowsensor, INPUT);
digitalWrite(flowsensor, HIGH);
digitalWrite(5,HIGH);
lcd.init();
lcd.backlight();
startTime = millis(); // Record the start time
//Liters per Minute
pulse=0;
attachInterrupt(sensorInt, flow, RISING);
lcd.clear();
lcd.setCursor(1, 0);
lcd.print("Kontrol Aliran");
lcd.setCursor(4, 1);
lcd.print("Tekan(A)");
menuDisplayed = true;
}
void displayMenu()
{
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Lanjut ");
lcd.setCursor(0, 1);
lcd.print("Tekan A");
menuDisplayed = true;
}
void loop() {
char key = keypad.getKey(); // Get the key pressed
if (key != NO_KEY) {
tone(buzzer, 1300, 50); // Play tone for keypress
if (key == '#') { // If asterisk (*) key is pressed
if (!menuDisplayed) { // If menu is not already displayed
//displayMenu(); // Display the menu
menuDisplayed = true;
}
} else if (key == '*') { // If '*' key is pressed
} else if (menuDisplayed) { // If menu is displayed
if (key >= 'A' && key <= 'B' && selectedMode == ' ') { // If a valid mode key is pressed and no mode is currently running
selectedMode = key;
switch (selectedMode) {
case 'A':
modeB();
break;
}
} else if (selectedMode != ' ') { // If mode is selected
} else if (key =="D") {
}
}
}
}
void displayModeB(float actualVolume)
{
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Set Point:");
lcd.setCursor(0, 1);
lcd.print("Actual :");
lcd.print(actualVolume, 1); // Display the actual accumulated volume
lcd.print(" mL");
}
void modeB() {
displayModeB(0);
// Get the desired volume from the user
float setVolume = getSetVolume();
if (flowDetectionRunning) // Start flow detection
{
detectFlow(setVolume);
}
}
float getSetVolume() {
float volume = 0;
bool volumeEntered = false;
while (!volumeEntered) {
char key = keypad.getKey();
if (key >= '0' && key <= '9') {
tone(buzzer, 1300, 50); // Play tone for keypress
volume = volume * 10 + (key - '0');
lcd.setCursor(10, 0);
lcd.print(volume,0);
lcd.setCursor(14, 0);
lcd.print("mL");
} else if (key == '#') {
tone(buzzer, 1300, 50); // Play tone for keypress
volumeEntered = true; // asal true
flowDetectionRunning = true; // Set flow detection flag diubah jadi true
} else if (inputReset =="D"){
}
}
return volume;
}
void detectFlow(float setVolume) {
unsigned long lastTime = 0;
unsigned long totalPulses = 0;
//float totalVolume=0;
lcd.setCursor(8, 1);
lcd.print(" "); // Clear previous value
while (true)
{
unsigned long currentTime = millis();
if (currentTime - oldTime >= 1000) { // Calculate flow rate every 'interval' milliseconds
//detachInterrupt(sensorInt);
//float flowRate = (pulse - totalPulses) * 60.0 / (interval * 7.5); // Assuming 7.5 pulses per liter
//totalPulses = pulse;
//lastTime = currentTime; // Update total volume
// totalVolume += flowRate / 1000.0; // Convert flow rate from L/min to L/s, then accumulate
// lcd.setCursor(8, 1); // Update LCD with actual accumulated volume under "Actual: " section
// lcd.print(totalVolume, 1); // Print actual accumulated volume with 1 decimal place
//lcd.print(" mL");
analogWrite(motorDriver, 255); // Stop the pump
flowRate = ((1000.0 / (millis() - oldTime)) * pulse) / 7.5;
oldTime = millis();
flowmlt = (flowRate/ 60)*1000;
totalVolume += flowmlt;
lcd.setCursor(0, 1);
lcd.print("Volume :");
lcd.setCursor(10,1);
lcd.print(totalVolume,0);
lcd.setCursor(14,1);
lcd.print("mL");
if (totalVolume >= setVolume) { // Check if accumulated volume meets or exceeds set volume
tone(buzzer, 1300, 50); // Play tone for keypress
analogWrite(motorDriver, 0); // Stop the pump
flowDetectionRunning = false; // Reset flow detection flag
menuDisplayed = false; // Return to mode selection
break;
}
pulse=0;
attachInterrupt(sensorInt, flow, RISING);
}
}
}
void flow()
{
pulse++;
}