#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <Keypad.h>
#include <Servo.h>
#include <SoftwareSerial.h>
// ------------------ LCD ------------------
LiquidCrystal_I2C lcd(0x27, 16, 2); // Change address to 0x3F if 0x27 doesn’t work
// ------------------ Keypad ------------------
const byte ROWS = 4;
const byte COLS = 4;
char keys[ROWS][COLS] = {
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}
};
byte rowPins[ROWS] = {2, 3, 4, 5};
byte colPins[COLS] = {6, 7, 8, 9};
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
// ------------------ Servo ------------------
Servo dispenserServo;
int servoPin = 15;
// ------------------ UART Devices ------------------
SoftwareSerial sim800(10, 11); // RX, TX (to SIM800L)
SoftwareSerial rfid(12, 13); // RX, TX (from EM18 RFID)
SoftwareSerial fingerprint(14, 16); // RX, TX (fingerprint sensor)
// ------------------ Constants ------------------
String rationItems = "Wheat=3kg Rice=5kg Dal=1kg";
String phoneNumber = "+91XXXXXXXXXX"; // replace with your number
// ------------------ Helper Functions ------------------
void lcdPrint(String line1, String line2 = "") {
lcd.clear();
lcd.setCursor(0,0);
lcd.print(line1);
lcd.setCursor(0,1);
lcd.print(line2);
}
bool verifyFingerprint() {
// Placeholder function - adapt for your sensor
// Simulate fingerprint success for now
lcdPrint("Place Finger...");
delay(2000);
// If real module connected, use serial commands here
return true; // Assume fingerprint matched
}
void sendSMS(String msg) {
sim800.println("AT");
delay(500);
sim800.println("AT+CMGF=1");
delay(500);
sim800.print("AT+CMGS=\"");
sim800.print(phoneNumber);
sim800.println("\"");
delay(500);
sim800.print(msg);
sim800.write(26); // Ctrl+Z to send
delay(3000);
}
void releaseRation() {
lcdPrint("Dispensing...", "");
dispenserServo.write(90);
delay(2000);
dispenserServo.write(0);
delay(500);
lcdPrint("Ration Released", "");
delay(2000);
}
// ------------------ Setup ------------------
void setup() {
Wire.begin();
lcd.init();
lcd.backlight();
dispenserServo.attach(servoPin);
dispenserServo.write(0);
sim800.begin(9600);
rfid.begin(9600);
fingerprint.begin(57600);
lcdPrint("Ration Card", "Vending Machine");
delay(1000);
}
// ------------------ Loop ------------------
void loop() {
String enteredID = "";
char key;
lcdPrint("Enter Ration", "Card ID:");
while (true) {
key = keypad.getKey();
if (key) {
if (key == '#') {
if (enteredID.length() > 0) break;
}
else if (key == '*') {
if (enteredID.length() > 0) enteredID.remove(enteredID.length() - 1);
}
else {
if (enteredID.length() < 12) enteredID += key;
}
lcdPrint("ID:", enteredID);
}
// Optional: Read RFID tag if available
if (rfid.available()) {
String tag = rfid.readStringUntil('\n');
tag.trim();
if (tag.length() > 0) {
enteredID = tag;
lcdPrint("RFID:", tag);
delay(1000);
break;
}
}
}
lcdPrint("Card ID Saved", enteredID);
delay(1000);
lcdPrint("Scan Fingerprint", "");
bool verified = verifyFingerprint();
if (verified) {
lcdPrint("Fingerprint", "Matched");
delay(1000);
releaseRation();
sendSMS("Ration dispensed to ID: " + enteredID);
lcdPrint("Wheat=3kg", "Rice=5kg Dal=1kg");
delay(3000);
} else {
lcdPrint("Fingerprint", "Failed!");
delay(2000);
}
lcdPrint("Thank You", "Next Customer");
delay(2000);
}