program
program
h>
#include <SPI.h>
#include <MFRC522.h>
#include <HX711.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include "QRCodeGenerator.h"
// Configuration Constants
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
#define OLED_ADDRESS 0x3C
#define RST_PIN 22
#define SS_PIN 21
#define LOADCELL_DOUT_PIN 32
#define LOADCELL_SCK_PIN 33
#define GREEN_LED 25
#define RED_LED 26
#define BUZZER_PIN 27
#define PAYMENT_BUTTON 13
#define HELP_BUTTON 14
#define MAX_ITEMS 50
Product productDatabase[PRODUCT_COUNT] = {
{"46 35 0B 4E", "Milk", "Dairy", 2.99, 1000},
{"16 D1 90 40", "Bread", "Bakery", 1.49, 500},
{"26 4D 8A 5F", "Apples", "Produce", 3.99, 1500},
{"16 7D 0A 4E", "Chicken", "Meat", 8.99, 1200},
{"46 4C 0E 4E", "Water", "Beverage", 0.99, 1500}
};
struct Cart {
Product items[MAX_ITEMS];
int count = 0;
float total = 0;
float totalWeight = 0;
String transactionId;
};
// Global Objects
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
MFRC522 mfrc522(SS_PIN, RST_PIN);
HX711 scale;
// Global Variables
Cart cart;
bool securityAlert = false;
bool needsRefresh = true;
unsigned long lastDisplayUpdate = 0;
// Forward Declarations
void displaySplashScreen();
void displayWelcomeScreen();
void displayCartScreen();
void displaySecurityScreen();
void displayMessage(String msg);
void displayQRCode(String data);
void displayBillQR();
String generateBillString();
String getDateTime();
void generateTransactionId();
String getRFIDUID();
Product findProduct(String uid);
void addToUnknownItems(String uid);
int findProductIndex(String uid);
void toggleProductInCart(Product product);
void indicateAddToCart();
void indicateRemoveFromCart();
void monitorWeight();
bool isUserInteracting();
void checkSecurity();
void triggerSecurityAlert(String message);
void handleButtons();
void handlePayment();
void resetCart();
int getCartItemCount();
void updateDisplay();
void setup() {
Serial.begin(115200);
while (!Serial);
// Initialize hardware
SPI.begin();
mfrc522.PCD_Init();
scale.begin(LOADCELL_DOUT_PIN, LOADCELL_SCK_PIN);
scale.set_scale(-1000);
scale.tare();
pinMode(GREEN_LED, OUTPUT);
pinMode(RED_LED, OUTPUT);
pinMode(BUZZER_PIN, OUTPUT);
pinMode(PAYMENT_BUTTON, INPUT_PULLUP);
pinMode(HELP_BUTTON, INPUT_PULLUP);
// Initialize display
if(!display.begin(SSD1306_SWITCHCAPVCC, OLED_ADDRESS)) {
Serial.println("OLED initialization failed");
while(1);
}
display.clearDisplay();
display.display();
displaySplashScreen();
}
void loop() {
// Handle RFID scanning
if (mfrc522.PICC_IsNewCardPresent() && mfrc522.PICC_ReadCardSerial()) {
String uid = getRFIDUID();
Product product = findProduct(uid);
if(product.uid == "") {
addToUnknownItems(uid);
} else {
toggleProductInCart(product);
}
mfrc522.PICC_HaltA();
}
// Monitor systems
monitorWeight();
checkSecurity();
handleButtons();
// Display Functions
void displaySplashScreen() {
display.clearDisplay();
display.setTextSize(2);
display.setTextColor(WHITE);
display.setCursor(10, 20);
display.println("SMART CART");
display.setTextSize(1);
display.setCursor(20, 45);
display.println("Initializing...");
display.display();
delay(2000);
}
void displayWelcomeScreen() {
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0, 0);
display.println("Welcome to SmartCart");
display.println("Scan items to begin");
display.println("Weight: " + String(scale.get_units(), 1) + "g");
display.display();
}
void displayCartScreen() {
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
// Header
display.setCursor(0, 0);
display.println("MY CART");
display.drawLine(0, 10, 127, 10, WHITE);
// Summary
display.drawLine(0, 45, 127, 45, WHITE);
display.setCursor(0, 47);
display.println("Total: $" + String(cart.total * 1.1, 2)); // Include tax
display.println("Items: " + String(getCartItemCount()));
// Instructions
display.setCursor(0, 57);
display.println("[Pay] [Help]");
display.display();
}
void displaySecurityScreen() {
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0, 0);
display.println("SECURITY ALERT!");
display.println("Unauthorized access");
display.println("detected!");
display.println("Please wait for");
display.println("assistance");
display.display();
}
void displayBillQR() {
String billText = generateBillString();
displayQRCode(billText);
}
void displayQRCode(String data) {
QRCode qrcode;
uint8_t qrcodeData[qrcode_getBufferSize(3)];
qrcode_initText(&qrcode, qrcodeData, 3, ECC_LOW, data.c_str());
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0, 0);
display.println("Scan Receipt:");
// Bill Generation
String generateBillString() {
String bill = "SMART CART RECEIPT\n";
bill += "Transaction: " + cart.transactionId + "\n";
bill += "Date: " + getDateTime() + "\n\n";
bill += "ITEMS:\n";
bill += "\n";
bill += "Subtotal: $" + String(cart.total, 2) + "\n";
bill += "Tax: $" + String(cart.total * 0.1, 2) + "\n"; // 10% tax
bill += "TOTAL: $" + String(cart.total * 1.1, 2) + "\n\n";
bill += "Thank you for shopping!";
return bill;
}
// Helper Functions
String getDateTime() {
return "2023-11-15 14:30"; // In real implementation, use RTC
}
void generateTransactionId() {
cart.transactionId = String(millis(), HEX);
}
// RFID Functions
String getRFIDUID() {
String content = "";
for (byte i = 0; i < mfrc522.uid.size; i++) {
content.concat(String(mfrc522.uid.uidByte[i] < 0x10 ? "0" : ""));
content.concat(String(mfrc522.uid.uidByte[i], HEX));
}
content.toUpperCase();
return content;
}
// Not found
Product empty;
return empty;
}
if(index == -1) {
// Add new product to cart
if(cart.count < MAX_ITEMS) {
product.inCart = true;
product.scanTime = millis();
cart.items[cart.count] = product;
cart.count++;
cart.total += product.price;
cart.totalWeight += product.weight;
indicateAddToCart();
}
} else {
// Toggle existing product
cart.items[index].inCart = !cart.items[index].inCart;
if(cart.items[index].inCart) {
cart.total += product.price;
cart.totalWeight += product.weight;
indicateAddToCart();
} else {
cart.total -= product.price;
cart.totalWeight -= product.weight;
indicateRemoveFromCart();
}
}
needsRefresh = true;
}
void indicateAddToCart() {
digitalWrite(GREEN_LED, HIGH);
tone(BUZZER_PIN, 1000, 100);
delay(200);
digitalWrite(GREEN_LED, LOW);
}
void indicateRemoveFromCart() {
digitalWrite(RED_LED, HIGH);
tone(BUZZER_PIN, 500, 100);
delay(200);
digitalWrite(RED_LED, LOW);
}
// Sensor Functions
void monitorWeight() {
float currentWeight = scale.get_units(5);
float expectedWeight = cart.totalWeight;
float discrepancy = abs(currentWeight - expectedWeight);
bool isUserInteracting() {
return digitalRead(PAYMENT_BUTTON) == LOW || digitalRead(HELP_BUTTON) == LOW;
}
void checkSecurity() {
// Security checks now only based on weight and unknown items
// (Previous ultrasonic sensor checks removed)
}
// Button Handling
void handleButtons() {
if(digitalRead(PAYMENT_BUTTON) == LOW) {
handlePayment();
delay(1000);
}
if(digitalRead(HELP_BUTTON) == LOW) {
displayMessage("Help requested");
delay(1000);
}
}
void handlePayment() {
if(getCartItemCount() == 0) {
displayMessage("Cart is empty");
return;
}
displayBillQR();
delay(5000); // Show QR for 5 seconds
resetCart();
}
void resetCart() {
cart.count = 0;
cart.total = 0;
cart.totalWeight = 0;
generateTransactionId();
needsRefresh = true;
}
int getCartItemCount() {
int count = 0;
for(int i = 0; i < cart.count; i++) {
if(cart.items[i].inCart) count++;
}
return count;
}
void updateDisplay() {
if(securityAlert) {
displaySecurityScreen();
securityAlert = false;
} else if(getCartItemCount() == 0) {
displayWelcomeScreen();
} else {
displayCartScreen();
}
}