#include <I2CKeyPad.h>
#include <Wire.h>
#include <RTClib.h>
#include <LiquidCrystal_I2C.h>
#include <IRremote.h>
#define PIN_IR 4 // Signal Pin of IR IR
IRrecv IR(PIN_IR);
bool next = false;
#include <TM1637.h>
TM1637 TM1, TM2, TM3; // Each display needs its own object
LiquidCrystal_I2C lcd = LiquidCrystal_I2C(0x27, 16, 2);
RTC_DS3231 rtc;
I2CKeyPad keypad(0x38);
char keypad_layout[19] = "123A456B789C*0#DNF"; // N = NO_KEY, F = FAILED
int sensorInterrupt = 0; // interrupt 0
int sensorPin = 2; //Digital Pin 2
int solenoidValve1 = 27;
int solenoidValve2 = 12;
int relay_motor = 14; // Digital pin 5
//unsigned int SetPoint = 400; //400 milileter
#define FS300A_PULSE 508 // PULSE / LITER
#define FS300A_FLOW_RATE 60 // LITER / MINUTE
float calibrationFactor = 60.0F / 508.0F; // FS300A_FLOW_RATE / FS300A_PULSE
/*The hall-effect flow sensor outputs pulses per second per litre/minute of flow.*/
//float calibrationFactor = 90; //You can change according to your datasheet
volatile byte pulse = 0;
uint16_t pulseCount;
bool busy;
float flowRate = 0.0;
float flowMilliLitres = 0;
float totalMilliLitres = 0, dispAmt = 0;
float volume = 0;
float totvol;
float vol = 0;
unsigned long oldTime = 0;
//const int relay_motor = 10;
//const int mech_countr = 14;
const int roto = 26;
const int emergencyButtonPin = 13;
long code = 0 ;
float price = 90.0;
float rate; // ml per rupee
String company = ("Machlab.ltd");
const int pwmPin = 15; // Choose the GPIO pin where you want to generate the PWM signal
float frequency; // Frequency in Hz (adjust as needed)
const int dutyCycle = 50; // Duty cycle in percentage (adjust as needed)
void setup() {
Serial.begin(115200);
if (!keypad.begin()) {
Serial.print("Cannot connect to I2C.\n");
while (1);
}
keypad.loadKeyMap(keypad_layout);
rtc.begin();
pinMode(sensorPin, INPUT);
digitalWrite(sensorPin, INPUT_PULLUP);
pinMode(pwmPin, OUTPUT);
digitalWrite(pwmPin, HIGH);
pinMode(solenoidValve1, OUTPUT);
pinMode(solenoidValve2, OUTPUT);
pinMode(relay_motor, OUTPUT);
//pin Mode(mech_countr, OUTPUT);
pinMode(roto, INPUT_PULLUP);
pinMode(emergencyButtonPin, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(emergencyButtonPin), emergencyStop, FALLING);
DateTime now = rtc.now(); // Get the current time from RTC
lcd.init();
lcd.backlight();
lcd.setCursor(0, 0);
lcd.print(company);
delay(4000);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Time: ");
lcd.print(now.hour(), DEC);
lcd.print(':');
lcd.print(now.minute(), DEC);
lcd.print(':');
lcd.print(now.second(), DEC);
lcd.setCursor(0, 1);
lcd.print("Enter Amount:");
delay(1000);
// First display
// -----------------------------------------
TM1.begin(22, 19, 4); // clockpin, datapin, #digits
TM1.displayClear();
TM1.setBrightness(7); // full brightness, default is 3
// -----------------------------------------
// Second display
// -----------------------------------------
TM2.begin(22, 18, 4); // clockpin, datapin, #digits
TM2.displayClear();
TM2.setBrightness(7); // full brightness, default is 3
// -----------------------------------------
// Third display
// -----------------------------------------
TM3.begin(22, 5, 4); // clockpin, datapin, #digits
TM3.displayClear();
TM3.setBrightness(7); // full brightness, default is 3
TM3.displayPChar("90Rs"); // Initial text on third display
// put your setup code here, to run once:
Serial.println("Hello, ESP32!");
attachInterrupt(digitalPinToInterrupt(sensorInterrupt), pulseCounter, CHANGE); //you can use Rising or Falling
// Print the time on the LCD
IR.enableIRIn(); // Start the IR
randomSeed(analogRead(0)); // Seed the random number generator with an analog reading
}
void loop() {
// Checks received an IR signal
if (IR.decode()) {
RemoteController();
IR.resume(); // Receive the next value
}
rs232();
char key = keypad.getChar();
DateTime now = rtc.now(); // Get the current time from RTC
if (key >= '0' && key <= '9') {
//code += key;
code = code * 10 + (key - '0');
lcd.clear();
lcd.setCursor(0, 1);
lcd.print(code);
delay(100);
}
if (key == 'C')
{
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Time: ");
lcd.print(now.hour(), DEC);
lcd.print(':');
lcd.print(now.minute(), DEC);
lcd.print(':');
lcd.print(now.second(), DEC);
lcd.setCursor(0, 1);
lcd.print("Enter Amount:");
code = 0;
// inputIndex = 0; // Reset the input index
// memset(inputBuffer, 0, sizeof(inputBuffer));
delay(200);
//code = ;
}
if (key == 'D') {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Amount: Rs.");
lcd.print(code);
rate = 1000.0 / price;
vol = (code * rate);
volume = round(vol * 100.0) / 100000.0;
totvol += volume;
lcd.setCursor(0, 1);
lcd.print("Volume = ");
lcd.print(volume, 2);
lcd.print("ltr");
delay(1500);
}
if (totalMilliLitres < volume) {
digitalWrite(relay_motor, HIGH);
// Check the state of the fuel dispensing switch
if (digitalRead(roto) == LOW) {
solenoidLoop();
if ((millis() - oldTime) > 1000) {
detachInterrupt(sensorInterrupt);
// static unsigned long startTime;
// if (micros() - startTime < 1000000UL) return; // 1000 milliseconds Interval
// startTime = micros();
// while (busy) {};
// pulseCount = pulse;
// pulse = 0;
// frequency = pulseCount / 2.0f;
//flowRate = frequency * calibrationFactor;
//flowRate = ((1000.0 / (millis() - oldTime)) * pulseCount) / calibrationFactor;
oldTime = millis();
for (int i = 0; i < 50; i++) {
float flowRate = random(0, 100) / 10.0; // Simulating values between 0.0 and 10.0 L/min
flowMilliLitres = (flowRate / 60) * 1000;
totalMilliLitres += flowMilliLitres;
}
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.print(" ml");
dispAmt = totalMilliLitres / rate ;
TM1.displayInt(dispAmt);
TM2.displayInt(totalMilliLitres);
// if (totalMilliLitres > 40) {
// SetSolinoidValve();
// }
solenoidLoop();
pulseCount = 0;
attachInterrupt(sensorInterrupt, pulseCounter, FALLING);
}
}
else {
digitalWrite(relay_motor, LOW);
digitalWrite(solenoidValve1, LOW);
digitalWrite(solenoidValve2, LOW);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("please turn on ");
lcd.setCursor(0, 1);
lcd.print("roto switch");
delay(2000);
return;
}
}
else if (totalMilliLitres == vol) {
digitalWrite(relay_motor, LOW);
//saveToEEPROM(inputBuffer);
// if(key == 'A')
// printBill();
// inputIndex = 0; // Reset the input index
// memset(inputBuffer, 0, sizeof(inputBuffer));
volume = 0;
//delay(4000);
// else{
// inputIndex = 0; // Reset the input index
// memset(inputBuffer, 0, sizeof(inputBuffer));
// volume = 0;
// }
}
else {
digitalWrite(relay_motor, LOW);
volume = 0;
}
}
void pulseCounter()
{
// Increment the pulse counter
pulseCount++;
}
void emergencyStop() {
// Stop the liquid dispensing process and perform any necessary cleanup.
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Emergency btn");
lcd.setCursor(0, 1);
lcd.print("pressed");
delay(1000);
code = 0;
// inputIndex = 0; // Reset the input index
// memset(inputBuffer, 0, sizeof(inputBuffer));
digitalWrite(relay_motor, LOW);
digitalWrite(solenoidValve1, LOW);
digitalWrite(solenoidValve2, LOW);
exit(0);
}
// void dispensedamount(){
// dispAmt = totalMilliLitres/rate ;
// dispAmt++;
// }
void solenoidLoop() {
// bool fuelDispensed = false;
// Check if total milliliters dispensed exceed 80% of the volume
if (totalMilliLitres < (0.8 * vol)) {
digitalWrite(solenoidValve1, HIGH);
digitalWrite(solenoidValve2, HIGH);
}
else if (totalMilliLitres == (0.8 * vol)) {
// Turn off solenoidValve1
digitalWrite(solenoidValve1, LOW);
// Turn on solenoidValve2
digitalWrite(solenoidValve2, HIGH);
}
else {
digitalWrite(solenoidValve1, LOW);
// Turn off solenoidValve2
digitalWrite(solenoidValve2, LOW);
}
}
//------------REMOTE CONTROLLER FUNCTION------------
void RemoteController() {
if (IR.decode()) {
long long key = IR.decodedIRData.decodedRawData;
//Serial.println(IR.decodedIRData.decodedRawData, HEX);
switch (key) {
case 0xFD02FF00:
Serial.println("+");
next ? price += 1 : price++;
Serial.println(price);
break;
case 0x6798FF00:
Serial.println("-");
next ? price -= 1 : price--;
Serial.println(price);
break;
case 0x57A8FF00:
Serial.println("total dispensed volume:");
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("dispensed volume:");
lcd.setCursor(0, 1);
lcd.println(totvol);
break;
}
delay(100);
IR.resume();
}
}
void rs232() {
if (Serial.available() > 0) {
char command = Serial.read(); // Read the incoming command
if (command == 'C') {
//float newCalibrationFactor = 0.0;
Serial.print("Enter new calibration factor: ");
float newCalibrationFactor = Serial.parseFloat();
calibrationFactor = newCalibrationFactor;
Serial.print("Calibration factor updated to: ");
Serial.print(calibrationFactor);
}
if (command == 'N') {
Serial.print("Enter Company name: ");
String newString = Serial.readString();
// Update the customString
company = newString;
Serial.print("Updated name: " + company);
lcd.clear();
lcd.print(company);
delay(1500);
// exit(0);
}
if (command == 'P') {
Serial.print("Enter new price: ");
float newprice = Serial.parseFloat();
price = newprice;
Serial.print("price is updated to: ");
Serial.println(price);
}
}
}
esp:VIN
esp:GND.2
esp:D13
esp:D12
esp:D14
esp:D27
esp:D26
esp:D25
esp:D33
esp:D32
esp:D35
esp:D34
esp:VN
esp:VP
esp:EN
esp:3V3
esp:GND.1
esp:D15
esp:D2
esp:D4
esp:RX2
esp:TX2
esp:D5
esp:D18
esp:D19
esp:D21
esp:RX0
esp:TX0
esp:D22
esp:D23
chip1:R1
chip1:R2
chip1:R3
chip1:R4
chip1:C1
chip1:C2
chip1:C3
chip1:C4
chip1:SDA
chip1:SCL
chip1:GND
chip1:VCC
keypad1:R1
keypad1:R2
keypad1:R3
keypad1:R4
keypad1:C1
keypad1:C2
keypad1:C3
keypad1:C4
lcd1:GND
lcd1:VCC
lcd1:SDA
lcd1:SCL
rtc1:GND
rtc1:5V
rtc1:SDA
rtc1:SCL
rtc1:SQW
Loading
ds18b20
ds18b20
r1:1
r1:2
sevseg1:CLK
sevseg1:DIO
sevseg1:VCC
sevseg1:GND
relay1:VCC
relay1:GND
relay1:IN
relay1:NC
relay1:COM
relay1:NO
sw2:1
sw2:2
sw2:3
relay2:VCC
relay2:GND
relay2:IN
relay2:NC
relay2:COM
relay2:NO
relay3:VCC
relay3:GND
relay3:IN
relay3:NC
relay3:COM
relay3:NO
sevseg2:CLK
sevseg2:DIO
sevseg2:VCC
sevseg2:GND
sevseg3:CLK
sevseg3:DIO
sevseg3:VCC
sevseg3:GND
led1:A
led1:C
gnd1:GND
vcc1:VCC
vcc2:VCC
led2:A
led2:C
led3:A
led3:C
vcc3:VCC
gnd2:GND
gnd3:GND
ir2:GND
ir2:VCC
ir2:DAT
vcc4:VCC
gnd4:GND
pulse1:GND
pulse1:VCC
pulse1:PULSE
chip2:A0
chip2:A1
chip2:A2
chip2:GND
chip2:VCC
chip2:WP
chip2:SCL
chip2:SDA
btn1:1.l
btn1:2.l
btn1:1.r
btn1:2.r