NodeX iHub is now part of Microsoft for Startups Founders Hub


Juice Dispenser System

56 View(s)

0 Like(s)

2 Comment(s)


SO

Seun Omolayo

Author


Image

Project Description

The Juice Dispenser System is an innovative solution designed to streamline and enhance the juice dispensing process at juice shop. The system uses advanced technology, including NFC (Near Field Communication) authentication to provide a secure, efficient, and user-friendly experience for both customers and management, and in addition a remote sales data transmission to keep the management informed of their juice dispenser machine performance in real-time.


Apps and IDE

· Arduino IDE - The Arduino IDE (Integrated Development Environment) is a software application used to program and develop projects for Arduino microcontrollers. Arduino is an open-source electronics platform that provides a simple and user-friendly way to create interactive projects and prototypes.

· Proteus 8 - Proteus 8 is a popular electronic design automation (EDA) software package developed by Labcenter Electronics. It is widely used for simulating, designing, and testing electronic circuits and microcontroller-based projects. Proteus 8 offers an integrated solution for circuit design, PCB layout, and microcontroller simulation, making it a valuable tool for electronics engineers, hobbyists, and students.

 

Components

· Arduino Board

· ESP01 module

· Flow Sensor

· I2C LCD module

· NFC Card Reader

· 4 x 4 Button Pad

· NFC reader and tag

· DC pump

· Relay

· Transistor

· Resistor

· Headers

· Hose

· Tank

 

Project Documentation

The Juice Dispenser System represents a groundbreaking solution that not only modernizes the juice dispensing process but also offers heightened security, efficiency, and real-time insights into juice dispenser operations. In this project, we have integrated cutting-edge technology, including NFC (Near Field Communication) authentication, to create a secure and user-friendly experience for both juice dispenser machine, customers and operators. Furthermore, our system introduces the capability to transmit real-time sales data to owners, ensuring they are always informed about their business’s performance.


Hardware Overview


Schematic diagram

 

The Arduino 5V pin is connected to positive of the 5V SMPS, while the GND is connected to the negative terminal of the SMPS. Both the LCD and the NFC reader are using I2C module so we connect the I2C GND to the ground of the Arduino, we connect both the SCL and SDA to analog pin A5 and A4 respectively, the flow sensor has 3 pin GND, 5V and signal, the 5V and GND pin is connected to the I2C module 5V pin and GND of the Arduino, while the signal pin is connected to the interrupted pin of the Arduino which is the digital pin 2. ESP 8266 VN pin is connected to the 5V of the SMPS, the GND is connected to ground and RX and TX is connected to TX and RX respectively of the Arduino. Also, the keypad we connect pin 4 to 1 and D to A, to the digital pin 5 to pin 13 respectively. The Arduino digital pin 4 is connected to the base of a transistor, and a 10k resistor is placed in parallel with it. The transistor's emitter is connected to the negative terminal of the GND, while its collector is linked to one of the relay's pins. To protect the circuit, a diode is connected across the relay's pins with the correct polarity to dissipate high voltage spikes when the relay turns off, the other pin of the relay is connected to the positive terminal of the 12V SMPS. The negative terminal of the DC pump is connected to the negative of the 12V SMPS, then the positive terminal of the DC pump is connected to the normally open (NO) and the common (C) of the relay is connected to the positive of the 12V SMPS.

 

· Arduino

The Arduino Nano is an integral component in the project, the Juice Dispenser System with NFC Authentication and Remote Sales Data Transmission. It serves as the primary microcontroller that controls and manages various aspects of the juicedispenser system.

 

· ESP 8266

The ESP8266 is a critical component in the project, the Juice Dispenser System with NFC Authentication and Remote Sales Data Transmission. It serves as the gateway for data connectivity, enabling your system to communicate with external networks and servers, particularly for remote sales data transmission.

 

· Flow Sensor

The Flow Sensor is a critical component for accurately measuring the flow rate of the dispensed petrol. It ensures precise control of the amount of juice delivered to the customer. The data from the flow sensor is used for tracking and recording transactions, helping to prevent juice wastage.


· NFC Reader and Tag

The NFC Reader and NFC Tags work in tandem to enable secure and contactless user authentication. The reader communicates with NFC tags, which may be issued to authorized users, and verifies their identity. This technology streamlines the user authentication process and adds an extra layer of security to the system.

 

· 4 x 4 Keypad

The 4 x 4 Button Pad serves as an input device for users to interact with the system. It allows customers to select the desired juice dispensing method, input the quantity of juice they wish to dispense, and confirm their choices. The button pad simplifies user interactions and enhances the system's usability.


· 16x2 I2C LCD

The 16x2 I2C (Inter-Integrated Circuit) LCD Module is a display unit that provides a user-friendly interface. It is used to convey information to the user, such as juice dispensing method selection, quantity input, and transaction status. Its I2C communication simplifies interfacing with the microcontroller and offers a clear and easy-to-read display.


· Relay

A relay is an essential component in many electronic and control systems, including your Juice Dispenser System. It serves as an electrically controlled switch that is connected to the 12V DC pump.

 

· Headers

These headers are connectors that will be soldered to the board to facilitate incoming connections.

 

· Resistor 10k x2

Resistors are renowned for their capability to impede the flow of electric current within a circuit. In the project, a 10k resistor was utilized as a pull-up resistor and as a base resistor.

 

· 1N4007 Diode

The 1N4007 Diode is a versatile and commonly used general-purpose diode. In this context, it is employed as a protection diode for the transistor, serving to mitigate the impact of high voltage spikes generated by the relay when it is switched OFF.

 

· Transistor BC547

To avoid unhealthy conditions when triggering the relay directly from the Arduino board, a BC547 transistor is introduced to serve as an intermediary for relay activation.

  

· DC Pump

The DC (Direct Current) pump in your Juice Dispenser System is a crucial component responsible for transferring juice from the storage tank to the customer's vehicle.


· Hose

The hose in your Juice Dispenser System is a vital component responsible for delivering the Juice from the tank to the pump, and from the pump to the customer's container.


· Vero Board

 

All the components will be arranged and soldered onto the Vero board.

 

Software Overview

 

#include <ESP8266WiFi.h>
#include <FirebaseESP8266.h>
#include <ArduinoJson.h>
#include <NTPClient.h>
#include <WiFiUdp.h>
#include <FS.h>
#include <LittleFS.h>

 Here we include the different library we need for the code. The ESP8266Wifi.h library is essential for working with Wi-Fi connectivity on the ESP8266 module, the #include <FirebaseESP8266.h> this library allows ESP8266 device interact with firebase services, #include <ArduinoJson.h> this library is used for handling JSON data which allows the ESP to create JSON data structures, #include <NTPClient.h> library is used to enable the ESP to synchronize its internal clock with NTP server, #include <WiFiUdp.h> is used for UDP communication with the NTP server, #include <FS.h> library is used for working on files on the ESP and lastly, the #include <LittleFS.h> provides a file system that allows user to read and write files on the ESP.

 

#define FIREBASE_HOST "https://fuel-dispenser-system-default-rtdb.firebaseio.com/"
#define FIREBASE_DB_SECRET ""
#define FIREBASE_PROJECT_ID "fuel-dispenser-system"
 
#define dataPath "/datafile.txt"
#define temppath "/temp.txt"
 
#define brandPath "/brand.txt"
#define branchPath "/branch.txt"
#define passwordPath "/password.txt"
#define pricePath "/price.txt"
#define led 13

 In this section of the code, we are defining the constant variable that would be used in the ESP. The first line defines the firebase host URL, the second line deals with firebase database secret which is a security token that provide Arduino-based device access to firebase project, the next line defines the firebase project ID, the next 4 lines defines the various file path for various data and configuration, and last line defines the pin that the LED is connected to on the Arduino.

 

String brand;
String branch;
String password;
String price;
 
String timeOfTranz;
String quantity;
bool fromFile = false;
String fileName = "";

 This section of code, we are defining the various set of string variables which are used to store data. The various variables are brand, branch, password, price, time of transaction and quantity of petrol bought. The “bool fromfile = false” is a Boolean variable that is used as flag to indicate whether data is being retrieved from a file. While the filename is a variable used to store the name of the file.

 

FirebaseData firebaseData;
FirebaseJson json;
 
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "pool.ntp.org");
 
String readFile(String path) {
  String a = "";
  File file = LittleFS.open(path, "r");
  if (!file) {
    return "";
  }
  while (file.available()) { a += file.readString(); }
  file.close();
  a.trim();
  return a;
}

 This section of the code, we are defining several objects and functions that are used to interact with firebase, retrieve time information from an NTP server, and read data from files stored on the ESP8266 device.

 

 

void writeFile(String path, String message) {
  File file = LittleFS.open(path, "w");
  if (!file) {
    return;
  }
  if (file.print(message)) {
    Serial.println("Y");
  } else {
    Serial.println("F");
  }
  delay(200);
  file.close();
  return;
}

 In this section of the code, we are defining the function ‘’writeFile” that is used to write data to the file located at the specified path on the ESP8266 using the littleFS file system.

 

bool appendFile(String path, const char *message) {
  Serial.printf("Appending to file: %s\n", path);
 
  File file = LittleFS.open(path, "a");
  if (!file) {
    Serial.println("Failed to open file for appending");
    return false;
  }
  if (file.print(message)) {
    Serial.println("Message appended");
  } else {
    Serial.println("Append failed");
  }
  file.close();
  return true;
}
 
void deleteFile(String path) {
  if (LittleFS.remove(path)) {
    Serial.println("D");
    return;
  } else {
    Serial.println("F");
    return;
  }
}

 In this section of code, we have two functions “appendFile” this function is designed to add text to an existing fille by the “path”, it takes two parameters which are path and message. The second functions is the “delete file” this function is designed to delete a file by the path. it takes one parameter which is path.

 

 

void sendPW() {
  Serial.println(password);
}
 
void pricePerLitre() {
  Serial.println(price);
}
void savePW(String data) {
  password = data.substring(14, data.length());
  writeFile(passwordPath, password);
}
void changePrice(String data) {
  price = data.substring(6, data.length());
  writeFile(pricePath, price);
}
 
In this section of the code, we have several functions related to password management and price setting which are print and password, price per liter.
 
void uploadData(String data) {
 
  if (WiFi.status() == WL_CONNECTED) {
    timeClient.update();
 
    json.set("brand", brand);
    json.set("location", branch);
    json.set("quantity", data.substring(1, data.length()));
    json.set("price", price);
    json.set("time", timeClient.getEpochTime());
 
    if (Firebase.push(firebaseData, "/data", json)) {
      // delete if sent
      if (fromFile) {
        deleteFile(fileName);
        fromFile = false;
      }
 
    } else if (!fromFile) {
 
      for (byte i = 0; i < 50; i++) {
        if (!LittleFS.exists("/" + String(i) + ".txt")) {
          writeFile("/" + String(i) + ".txt", data);
          break;
        }
      }
    }
  }
}

 In this section of the code, we created a function called “uploadData” that is responsible for uploading data to Firebase and if the upload fails, it saves the data to the local files on the ESP device. This ensures that data is preserved, even in the absence of internet connection, and can be uploaded to the cloud when connection is available.

 

void checkForLogs() {
  for (byte i = 0; i < 50; i++) {
    if (LittleFS.exists("/" + String(i) + ".txt")) {
      fileName = "/" + String(i) + ".txt";
      fromFile = true;
      uploadData(readFile(fileName));
    }
  }
}
 
void interpret(String data) {
  // this function will check the kind of data pass to it
  data.trim();
  // Serial.println(data);
 
  if (data.equals("PWDETAILS")) {
    sendPW();
  } else if (data.equals("GET_PRICE")) {
    pricePerLitre();
  } else if (data.startsWith("SAVEPWDETAILS:")) {
    savePW(data);
  } else if (data.startsWith("PRICE:")) {
    changePrice(data);
  } else if (data.startsWith(":")) {
    uploadData(data);
  }
}
 

In this section of code, we have two functions “checkforlogs” that is responsible for checking if there are any transaction logs stored locally on the ESP device, it iterates through a set of possible files and if a file with a specific name exists, then it calls uploadData function to upload the data from the file to firebase. Also, the second function “interepret” is designed to interpret and process various commands or data that are passed to it as the data parameter.

 

void getData() {
  brand = readFile(brandPath);
  if (brand.equals("")) {
    writeFile(brandPath, "NodeX");
    brand = "NodeX";
  }
 
  branch = readFile(branchPath);
  if (branch.equals("")) {
    writeFile(branchPath, "Warri");
    branch = "Warri";
  }
 
  password = readFile(passwordPath);
  if (password.equals("")) {
    writeFile(passwordPath, "0000");
    password = "0000";
  }
 
  price = readFile(pricePath);
  if (price.equals("")) {
    writeFile(pricePath, "500");
    price = "500";
  }
 
  Serial.println("START");
 
  // Serial.println(brand);
  // Serial.println(branch);
  // Serial.println(password);
  // Serial.println(price);
}

 In this section of code, we are creating a function called getData which is responsible for retrieving and initializing certain data like brand, branch, password and price. Also, the Serial.println(“start”) is a debugging process to the serial monitor to indicate the start of the retrieval process.

 

void setup() {
 
  Serial.begin(9600);
 
  WiFi.mode(WIFI_STA);
  WiFi.begin("Infinix NOTE 8", "090526921");
 
  LittleFS.begin();
  getData();
 
  while (WiFi.status() != WL_CONNECTED) {
    delay(200);
  }
  //Serial.write('C');
 
  Firebase.begin(FIREBASE_HOST, FIREBASE_PROJECT_ID);
  Firebase.reconnectWiFi(true);
 
  timeClient.begin();
  timeClient.setTimeOffset(0);
}

 This section of the code, we have the setup function which initializes the ESP board, the serial.begin initializes the serial communication with a baud rate of 9600, the wifi.mode simply means the ESP will operate in a station mode, the wifi.begin initiates a connection to a Wi-Fi network. The littleFs.begin initializes the littleFs system that is used to store file to the ESP. we also initialize the getData, while (Wi-Fi is connected), firebase, and time client.

 

void loop() {
 
  while (WiFi.status() != WL_CONNECTED) {
    delay(200);
    digitalWrite(led, LOW);
  }
  digitalWrite(led, HIGH);
 
  checkForLogs();
 
  if (Serial.available()) {
    interpret(Serial.readStringUntil('\n'));
  }
  delay(1000);
}

 This is the main function of the code, the first line of the loop checks continuously for Wi-Fi signal, the LED is an output device that shows if there is a Wi-Fi connection, it turns ON if there is a connection and turns OFF if no connection. Once there is connection, we call on the logs function to check for available stored transaction on the ESP. lastly, we check if there is data available to be read from the serial communication, it then reads data line by line and interprets the data.

 

Arduino code


#include <Keypad.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <PN532_SWHSU.h>
#include <PN532_I2C.h>
#include <PN532.h>
#include <NfcAdapter.h>
 
#define calib 5260
#define relay 4

 In this section of the code, we are including all the various libraries we need in the project, ranging from the keypad library, I2C LCD libraries and NFC libraries to communicate with NFC. The next are the constant variable that we use in the project, the relay pin and the calibration threshold.

 

PN532_I2C pn532_i2c(Wire);
NfcAdapter nfc = NfcAdapter(pn532_i2c);
 
short perLit = 620;
 
char keys[4][4] = {
  { '1', '2', '3', 'A' },
  { '4', '5', '6', 'B' },
  { '7', '8', '9', 'C' },
  { '*', '0', '#', 'D' }
};
 
byte pin_rows[4] = { 5, 6, 7, 8 };      //Row pins
byte pin_column[4] = { 9, 10, 11, 12 }; //Column pins
 
Keypad keypad = Keypad(makeKeymap(keys), pin_rows, pin_column, 4, 4);
LiquidCrystal_I2C lcd(0x27, 16, 2);

 In this section of the code, we are creating various objects and initializing them for the project. Firstly, we create an object PN532_I2C that is used to communicate I2C with the NFC module, the next line we created an object NFCADAPTER this is used to initialize the previous object, the next line defines a variable holds the value 620. Next, we created a multi-dimensional array that defines the layout of keys on our keypad, then we create two array that would initialize the pin numbers for the row and column connections. Lastly, we initialize the LCD and I2C module.

 

int cursorColumn = 0;
int flowPin = 2;
double flowRate;
volatile int count;
const char* menu[] = {
  "1. Change Pw",
  "2. View details",
  "3. Set Brand",
  "4. set location",
  "5. Set litre",
};

 In this section of code, we define several variables and constant. Firstly, we initialize the column variable responsible for tracking the current position of the cursor, then we initialize the flow sensor pin on the Arduino, then we create a double data type to store the calculated flow rate. Lastly, we create a constant struct variable to define the structure of the menu.

 

void setup() {
 
  Serial.begin(9600);
  lcd.init();
  lcd.backlight();
 
  //nfc.begin();
 
  pinMode(flowPin, INPUT);
  pinMode(relay, OUTPUT);
  attachInterrupt(0, Flow, RISING);
 
  display();
 
  Serial.println("GET_PRICE");
  while (1) {
    if (Serial.available()) {
      reader = Serial.readStringUntil("\n");
      reader.trim();
 
      perLit = reader.toInt();
 
      break;
    }
  }
}

 In this void setup function, we are initializing various components and sensors. Firstly, we initialize the serial communication with a baud rate of 9600, then we initialize and turn on the backlight of the LCD. Next, we set the pin mode of the flow sensor to input then pin mode of the relay to output. The next line we added an interrupt pin that is used to count flow sensor pulses, then we call on display function to display initial information on the LCD. Lastly, we get information from the ESP on the price, and we create a loop that wait for the data to be available.

 

void Flow() {
  count++;
}
 
void display() {
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Fuel Dispenser");
  lcd.setCursor(4, 1);
  lcd.print("By NodeX");
}
 
void changePw() {
  Serial.println("PWDETAILS");
 
  while (true) {
    if (Serial.available()) {
      reader = Serial.readStringUntil("\n");
      reader.trim();
      break;
    }
  }
 
  lcd.clear();
  lcd.print("Old PW: ");
 
  if (reader != getValue()) {
    lcd.clear();
    lcd.print("Wrong Password!");
    delay(1000);
    return;
  }
 
  lcd.clear();
  lcd.print("New PW: ");
  reader = getValue();
 
  lcd.clear();
  lcd.print("Con PW: ");
  if (reader != getValue()) {
    lcd.clear();
    lcd.print("Pw don't match!");
    delay(1000);
    return;
  }
 
  Serial.println("SAVEPWDETAILS:" + reader);
 
  while (true) {
    if (Serial.available()) {
      if (Serial.read() == 'Y') {
        lcd.clear();
        lcd.print("Successfull");
        delay(1000);
        return;
      } else {
        lcd.clear();
        lcd.print("Failed!");
        delay(1000);
        return;
      }
    }
  }
}

 In this section of the code, we created several functions, including flow function that has a counter variable, which helps track the flow rate of the flow sensor. Next, we have the display function that is responsible for displaying message on the LCD. Lastly, we the changepw function that is responsible for changing password in the functions.

 

void viewDetails() {
  reader = "";
  Serial.println("VIEW");
 
  while (true) {
    if (Serial.available()) {
      reader = Serial.readStringUntil("\n");
      break;
    }
  }
 
  lcd.clear();
  lcd.print(reader);
 
  while (true) {
    key = keypad.getKey();
 
    switch (key) {
      case 'A':
        lcd.scrollDisplayRight();
        break;
      case 'B':
        lcd.scrollDisplayLeft();
        break;
      case 'C':
        return;
    }
  }
}
void setBrand() {
 
  lcd.clear();
  lcd.print("Brand: ");
}
void setLocation() {}
void setLitre() {
 
  lcd.clear();
  lcd.print("Litre: #");
  reader = getValue();
 
  Serial.println("LITRE:" + reader);
 
  while (true) {
    if (Serial.available()) {
      if (Serial.read() == 'Y') {
        lcd.clear();
        lcd.print("Successfull");
        perLit = reader.toInt();
        delay(1000);
        return;
      } else {
        lcd.clear();
        lcd.print("Failed!");
        delay(1000);
        return;
      }
    }
  }
}

 In this section of cold we created four other functions, the viewDetails function allows the management to view information on the LCD screen. Next, the setbrand function allows the management to set their brands name. Next, the setlocation function helps the management in setting location information for the system. Lastly, the setlitre function is used to set calibration value or price per lite on the system.

 

void security() {
 
  Serial.println("PWDETAILS");
 
  while (true) {
    if (Serial.available()) {
      reader = Serial.readStringUntil("\n");
      reader.trim();
      break;
    }
  }
 
  lcd.clear();
  lcd.print("Ent PW: ");
  if (reader != getValue()) {
    lcd.clear();
    lcd.print("Wrong Password!");
    delay(1000);
    display();
    return;
  }
  count = 0;
  setting();
  display();
}
void setting() {
 
  lcd.clear();
  lcd.print(menu[count]);
 
  lcd.setCursor(0, 1);
  lcd.print(menu[count + 1]);
  while (true) {
    key = keypad.getKey();
 
    switch (key) {
      case 'A':
        if (count != 0) {
          count--;
          setting();
          return;
        }
        break;
      case 'B':
        if (count != 4) {
          count++;
          setting();
          return;
        }
        break;
      case 'C':
        display();
        return;
      case '1':
        changePw();
        setting();
        return;
      case '2':
        viewDetails();
        setting();
        return;
      case '3':
        setBrand();
        setting();
        return;
      case '4':
        setLocation();
        setting();
        return;
      case '5':
        setLitre();
        setting();
        return;
    }
  }
}

 In this section of code, we created two important functions, the security functions that is responsible for handling the security aspect of the project. Also, the settings functions that is used to navigate the menu and manage user settings, also it displays the current menu option and the next one on the LCD.

 

void keypadAction(char key) {
 
  switch (key) {
    case 'D':
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("Litres");
 
      lcd.setCursor(8, 0);
      lcd.print("Amount");
 
      lcd.setCursor(2, 1);
      lcd.print("A");
 
      lcd.setCursor(11, 1);
      lcd.print("B");
 
      bool a = false;
      while (true) {
        key = keypad.getKey();
 
        switch (key) {
          case 'A':
            inLitres();
            a = true;
            break;
          case 'B':
            inAmount();
            a = true;
            break;
          case 'C':
            display();
            return;
        }
 
        if (a) break;
        delay(50);
      }
  }
}
 
void inLitres() {
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Litre: ");
 
  lcd.setCursor(0, 1);
  lcd.print("1 Lit:  #");
 
 
  lcd.setCursor(9, 1);
  lcd.print(perLit);
 
  // from here the operation will comntune further to dispense the fuel
 
  float litres = atof(getValue().c_str());
 
  float amount = float(litres * perLit);
  pump(float(litres * calib));
 
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Amt:  #");
  lcd.setCursor(8, 0);
  lcd.print(amount);
 
  lcd.setCursor(0, 1);
  lcd.print("Lit: ");
  lcd.setCursor(7, 1);
  lcd.print(litres);
 
  Serial.println(":" + String(litres));
}

 In this section of code, we created two functions that handle actions related to the keypad input and fuel dispensing operations. Firstly, we created the keypadAction function that is responsible for handling actions based on the key pressed, it switches actions based on the key pressed. Also, the inLitres function is used to handle process on of dispensing juice by liters, it clears the LCD screen and displays information about the amount in liters.

 

void inAmount() {
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Amt:  #");
 
  lcd.setCursor(0, 1);
  lcd.print("1 Lit:  #");
 
  lcd.setCursor(9, 1);
  lcd.print(perLit);
 
  // from here the operation will continue further to dispense the fuel
  float amount = atof(getValue().c_str());
  float litres = amount / perLit;
  pump(litres * calib);
 
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Amt:  #");
  lcd.setCursor(8, 0);
  lcd.print(amount);
 
  lcd.setCursor(0, 1);
  lcd.print("Lit: ");
  lcd.setCursor(7, 1);
  lcd.print(litres);
 
  Serial.println(":" + String(litres));
}
 
 
//float temp;
void pump(int pulse) {
  Serial.println(pulse);
  digitalWrite(relay, HIGH);
  count = 0;
  interrupts();
  while (1) {
    delay(50);
    if (count >= pulse) break;
 
    //temp = (count / 5880.0) * 620.00;
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Amt:  #");
    lcd.setCursor(8, 0);
    lcd.print(((float)count / calib) * (float)perLit);
 
    lcd.setCursor(0, 1);
    lcd.print("Lit: ");
    lcd.setCursor(7, 1);
    lcd.print((float)count / calib);
 
    // lcd.clear();
    // lcd.setCursor(0, 0);
    // lcd.print(count);
  }
  //noInterrupts();
  digitalWrite(relay, LOW);
  count = 0;
}
String getValue() {
  String value = "";
  byte pos = 8;
 
  while (true) {
    key = keypad.getKey();
    switch (key) {
      case '1':
      case '2':
      case '3':
      case '4':
      case '5':
      case '6':
      case '7':
      case '8':
      case '9':
      case '0':
        value += key;
        lcd.setCursor(pos, 0);
        lcd.print(key);
        pos++;
        break;
      case '*':
        value += '.';
        lcd.setCursor(pos, 0);
        lcd.print('.');
        pos++;
        break;
      case '#':
        if (pos > 8) {
          value = value.substring(0, value.length() - 1);
          pos--;
          lcd.setCursor(pos, 0);
          lcd.print(' ');
        }
        break;
      case 'D':
        return value;
    }
  }
}

 In this section of the code, we have created additional functions that are crucial for the dispensing process, which includes inAmount function that handles the process of dispensing juice based on the specified amount. Next, the pump function that is responsible for controlling the juice pump to dispense the specified volume of juice. It receives number of pulses from the flow sensor that is needed to dispense a desired volume. Lastly, the getvalue function that handles user input to get a numeric value.

 

void loop() {
  key = keypad.getKey();
 
  if (key) {
 
    keypadAction(key);
    if (key == '*') {
      count++;
      if (count == 3) {
        count = 0;
        security();
      }
    }
  }
 delay(100);
 }

 In this section code, we have the loop function which continually checking for keypad input using the keypad.getkey function, and then taking specific actions based on the key pressed.

 

 

Conclusions

The Juice Dispenser System aims to revolutionize the juice dispensing industry by combining technology, security, and user-friendliness. This project seeks to provide an efficient and reliable solution that benefits both juice shops management and customers, ensuring accurate juice dispensing, enhanced security, and operational efficiency, while also offering owners the ability to monitor their dispenser performance in real-time.




NaN



AK

Abdulmajid Kafayat

a year ago

Hi!! Good evening please I would really love to learn this project

0 Likes

·

Reply

Pic

Eddy Ejembi

a year ago

Learn how to build exciting projects like this. Register for the cohort: www.nodexihub.com/program

0 Likes

·

Reply






Contact Us


  • support@nodexihub.com

  • +234 9071085512


© 2023 NodeX iHub | Security | Your Privacy | Terms