#include <SPI.h>
#include <MFRC522.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <ESP32Servo.h>
#include <DFRobotDFPlayerMini.h>
#define SS 5
#define RST 14
#define BUTTON_PIN 4
#define servoPin 13
struct Product {
String tag;
String name;
String expiry;
float price;
};
Product products[10] = {
{"A1B2C3", "Milk", "2025-08-01", 2500},
{"D4E5F6", "Bread", "2025-07-15", 500},
{"123ABC", "Sugar", "2026-01-01", 5000},
{"456DEF", "Soap", "2027-03-10", 3000},
{"789GHI", "Juice", "2025-12-12", 1500},
{"JKL012", "Rice", "2026-05-20", 3500},
{"MNO345", "Salt", "2025-09-09", 1000},
{"PQR678", "Soda", "2024-12-25", 1200},
{"STU901", "Water", "2026-06-06", 750},
{"VWX234", "Oil", "2026-08-15", 8500}
};
float totalAmount = 0.0;
bool checkout = true;
LiquidCrystal_I2C lcd(0x27, 20, 4);
MFRC522 scanner(SS,RST);
DFRobotDFPlayerMini myDFPlayer;
Servo myServo;
void setup() {
Serial.begin(9600);
delay(500);
Serial.println("initializing");
pinMode(BUTTON_PIN, INPUT);
lcd.init();
lcd.backlight();
welcomeDisplay();
myServo.attach(servoPin);
myServo.write(0);
Serial.println("Type RFID Tag ID to scan a product...");
lcd.clear();
}
void loop()
{
init_display();
if (digitalRead(BUTTON_PIN) == HIGH)
{
delay(1000);
while(digitalRead(BUTTON_PIN) == LOW)
{
pickProduct();
}
delay(1000);
while(digitalRead(BUTTON_PIN) == LOW)
{
if(checkout)
{
setBill();
checkout=LOW;
}
}
checkout=HIGH;
Serial.println("Cart reset for next user.");
delay(2000);
lcd.clear();
}
}
void pickProduct()
{
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("-TOTAL EXPENDITURE:-");
lcd.setCursor(0, 1);
lcd.print("Tsh.:");
lcd.setCursor(7, 1);
lcd.print(totalAmount, 2);
lcd.setCursor(0, 2);
lcd.print("SCAN NEXT PRODUCT OR");
lcd.setCursor(0, 3);
lcd.print("PRESS BUTTON TO END");
if (Serial.available()) {
String inputTag = Serial.readStringUntil('\n');
inputTag.trim();
bool found = false;
for (int i = 0; i < 10; i++) {
if (products[i].tag == inputTag) {
found = true;
Serial.println("Product found: " + products[i].name);
Serial.println("Opening door... Product dropped.");
totalAmount += products[i].price;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("FOUND PRODUCT DETAIL");
lcd.setCursor(0, 1);
lcd.print("NAME:");
lcd.setCursor(5, 1);
lcd.print(products[i].name);
lcd.setCursor(0, 2);
lcd.print("Exp :");
lcd.setCursor(5, 2);
lcd.print(products[i].expiry);
lcd.setCursor(0, 3);
lcd.print("PRICE:");
lcd.setCursor(6, 3);
lcd.print(products[i].price);
delay(3000);
myServo.write(90);
delay(3000);
myServo.write(0);
totalAmount += products[i].price;
break;
}
}
if (!found) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("UNKNOW/UNREGISTERED");
lcd.setCursor(0, 1);
lcd.print(" PRODUCT TAG ");
lcd.setCursor(0, 2);
lcd.print("CONTACT SALES OFFICE");
lcd.setCursor(0, 3);
lcd.print(" FOR PRODUCT DETAIL ");
Serial.println("Tag not recognized!");
delay(2000);
}
}delay(500);
}
void setBill()
{
lcd.clear();
lcd.setCursor(0,0);
lcd.print("GENERATING PAYMENT");
lcd.setCursor(0,1);
lcd.print("CONTROLL NUMBER FOR");
lcd.setCursor(0,2);
lcd.print("AMOUNT(Tsh):");
lcd.setCursor(12,2);
lcd.print(totalAmount);
lcd.setCursor(0,3);
lcd.print("PLEASE WAIT");
for(uint8_t i=11;i<20;i++)
{
lcd.setCursor(i,3);
lcd.print("_");
delay(500);
}
int controlNum = random(100000, 999999);
lcd.clear();
lcd.setCursor(0,0);
lcd.print("===>- CHECKOUT -<===");
lcd.setCursor(0,1);
lcd.print("BILL(Tsh.):");
lcd.setCursor(11,1);
lcd.print(totalAmount);
lcd.setCursor(0,2);
lcd.print("CONT. NO:");
lcd.setCursor(10,2);
lcd.print(controlNum);
lcd.setCursor(0,3);
lcd.print("=========<>=========");
Serial.println("=== Checkout ===");
Serial.print("Total Amount: ");
Serial.println(totalAmount, 2);
Serial.print("Payment Control #: ");
Serial.println(controlNum);
}
void init_display()
{
lcd.setCursor(0,0);
lcd.print("--------<<>>--------");
lcd.setCursor(0,1);
lcd.print(" PRESS BUTTON ");
lcd.setCursor(0,2);
lcd.print("TO START SHOPPING");
lcd.setCursor(0,3);
lcd.print("--------<<>>--------");
}
void welcomeDisplay()
{
lcd.clear();
lcd.setCursor(0,0);
lcd.print("SMART SHOPPING CART");
lcd.setCursor(0,1);
lcd.print(" BY USING RFID ");
lcd.setCursor(0,2);
lcd.print("SYSTEM INITIALIZE");
lcd.setCursor(0,3);
lcd.print("PLEASE WAIT");
for(uint8_t i=11;i<20;i++)
{
lcd.setCursor(i,3);
lcd.print("_");
delay(500);
}
}
/*
void error_display()
{
myDFPlayer.play(6);
lcd.clear();
lcd.setCursor(0,0);
lcd.print("--------<<>>--------");
lcd.setCursor(0,1);
lcd.print("Soory!,Locker Loaded");
lcd.setCursor(0,2);
lcd.print("Please Retry Later");
lcd.setCursor(0,3);
lcd.print("--------<<>>--------");
delay(6000);
}
String readTag()
{
if(!scanner.PICC_IsNewCardPresent())
{
//Serial.println("no card present");
return "error";
}
if(!scanner.PICC_ReadCardSerial())
{
//Serial.println("card not readable");
return "error";
}
//save data and return output
String myTag;
for (int i = 0; i < scanner.uid.size; i++)
{
myTag += String(scanner.uid.uidByte[i],HEX);
}
//Serial.print("THE TAG DETECTED IS:");
//Serial.println(myTag);
return myTag;
}*/