#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
byte sensorInt = 0;
byte flowsensor = 2;
float konstanta = 7.5; //konstanta flow meter
float l_minute;
volatile int pulse;
unsigned long lastTime;
float volume,flowRate;
unsigned long currentTime;
unsigned long cloopTime;
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
char selectedMode = ' '; // Default selected mode is none
bool flowDetectionRunning = false; // Flag to indicate if flow detection is running
float debit;
unsigned int flowmlt;
unsigned long totalmlt;
unsigned long oldTime;
void setup()
{
pulse = 0;
debit = 0.0;
flowmlt = 0;
totalmlt = 0;
oldTime = 0;
pinMode(buzzer, OUTPUT);
pinMode(motorDriver, OUTPUT);
pinMode(flowsensor, INPUT);
digitalWrite(flowsensor, HIGH);
lcd.init();
lcd.backlight();
startTime = millis(); // Record the start time
//Liters per Minute
pulse=0;
attachInterrupt(sensorInt, flow, RISING);
currentTime = millis();
cloopTime = currentTime;
lcd.clear();
lcd.setCursor(1, 0);
lcd.print("Kontrol Aliran");
lcd.setCursor(4, 1);
lcd.print("Tekan(#)");
}
void displayMenu()
{
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Lanjut ");
lcd.setCursor(0, 1);
lcd.print("Tekan B");
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
}
} 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 'B':
modeB(); // Enter Mode b
break;
}
} else if (selectedMode != ' ') { // If mode is selected
// Handle mode-specific button presses here
}
}
}
}
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
}
}
return volume;
}
void detectFlow(float setVolume) {
unsigned long lastTime = 0;
float totalVolume=0;
lcd.setCursor(9, 1);
lcd.print(": mL"); // Clear previous value
while (true)
{
currentTime = millis();
if (currentTime >= (cloopTime + 1000)) { // Calculate flow rate every 'interval' milliseconds
//detachInterrupt(sensorInt);
cloopTime = currentTime;
if (pulse != 0)
{
l_minute= (pulse / 7.5); // (Pulse frequency x 60 min) / 7.5Q = flowrate in L/hour
analogWrite(motorDriver, 255); // Stop the pump
//flowRate = ((1000.0 / (millis() - oldTime)) * pulse) / konstanta;
//oldTime = millis();
l_minute = (l_minute / 60);
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, FALLING);
}
}
}
}
void flow()
{
pulse++;
}