#include <Wire.h>
#include <LiquidCrystal_I2C.h>
// LCD1602 I2C (odatda 0x27 yoki 0x3F bo‘ladi, kerak bo‘lsa almashtiring)
LiquidCrystal_I2C lcd(0x27, 16, 2);
// Flow sensor pinlari
int sensorInterrupt = 0;
int sensorPin = 2;
int solenoidValve = 5;
float calibrationFactor = 90;
volatile byte pulseCount = 0;
float flowRate = 0.0;
unsigned int flowMilliLitres = 0;
unsigned long totalMilliLitres = 0, volume = 0;
unsigned long oldTime;
const int relais_moteur = 3;
// Joystick pinlari
const int joyX = A0; // X o‘qi
const int joySW = 12; // tugma (SW)
// O‘zgaruvchilar
int selectedVolume = 0; // joystik bilan tanlanadigan hajm
bool volumeSet = false;
void setup() {
totalMilliLitres = 0;
pinMode(relais_moteur, OUTPUT);
digitalWrite(relais_moteur, LOW);
lcd.init();
lcd.backlight();
lcd.setCursor(0, 0);
lcd.print("Set Volume:");
pinMode(solenoidValve, OUTPUT);
digitalWrite(solenoidValve, HIGH);
pinMode(sensorPin, INPUT);
digitalWrite(sensorPin, HIGH);
attachInterrupt(sensorInterrupt, pulseCounter, FALLING);
pinMode(joySW, INPUT_PULLUP); // joystick tugmasi
}
void loop() {
// Hajm tanlash rejimi
if (!volumeSet) {
int xValue = analogRead(joyX);
// Joystick chapga siljisa (kamaytirish)
if (xValue < 400 && selectedVolume > 0) {
selectedVolume -= 1;
delay(100);
}
// Joystick o‘ngga siljisa (oshirish)
else if (xValue > 600 && selectedVolume < 1500) {
selectedVolume += 1;
delay(100);
}
lcd.setCursor(0, 1);
lcd.print("Vol: ");
lcd.print(selectedVolume);
lcd.print(" ml ");
// Joystick tugmasini bosib tasdiqlash
if (digitalRead(joySW) == LOW) {
volume = selectedVolume;
volumeSet = true;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Target: ");
lcd.print(volume);
lcd.print(" ml");
delay(500);
}
}
else {
// Suv to‘ldirish jarayoni
if (totalMilliLitres < volume) {
digitalWrite(relais_moteur, HIGH);
if ((millis() - oldTime) > 1000) {
detachInterrupt(sensorInterrupt);
flowRate = ((1000.0 / (millis() - oldTime)) * pulseCount) / calibrationFactor;
oldTime = millis();
flowMilliLitres = (flowRate / 60) * 1000;
totalMilliLitres += flowMilliLitres;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Speed:");
lcd.print(flowMilliLitres);
lcd.print(" ml/s");
lcd.setCursor(0, 1);
lcd.print("Filled:");
lcd.print(totalMilliLitres);
lcd.print(" ml");
pulseCount = 0;
attachInterrupt(sensorInterrupt, pulseCounter, FALLING);
}
} else {
digitalWrite(relais_moteur, LOW);
volume = 0;
volumeSet = false; // qayta hajm tanlash uchun
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Done!");
delay(2000);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Set Volume:");
}
}
}
void pulseCounter() {
pulseCount++;
}