Troubleshoot Frozen LCD Display
Budget: ₹600 – ₹1,500 INR
#include <SPI.h>
#include <MFRC522.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#define RST_PIN 22
#define SS_PIN 5
#define BALANCE_BLOCK 4
#define RELAY_PIN 13 // Relay pin (Active LOW)
#define CHECK_INTERVAL 60000 // 1 minute in milliseconds
MFRC522 mfrc522(SS_PIN, RST_PIN);
LiquidCrystal_I2C lcd(0x27, 16, 2); // Try 0x3F if 0x27 doesn't work
MFRC522::MIFARE_Key key;
bool relayActive = false;
unsigned long lastDeductionTime = 0;
int currentBalance = 0;
bool cardPresent = false;
void setup() {
Serial.begin(115200);
Wire.begin(); // Initialize I2C
SPI.begin();
mfrc522.PCD_Init();
lcd.init(); // Initialize LCD
lcd.backlight();
delay(100); // Stabilize LCD
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Initializing...");
Serial.println("LCD Initialized");
pinMode(RELAY_PIN, OUTPUT);
digitalWrite(RELAY_PIN, HIGH); // Relay OFF
for (byte i = 0; i < 6; i++) key.keyByte[i] = 0xFF;
checkReaderConnection();
showReadyMessage();
Serial.println("System Ready - Waiting for card...");
}
void loop() {
static unsigned long lastCheckTime = 0;
const unsigned long checkInterval = 300; // Check every 300ms
static int missedDetections = 0;
unsigned long currentTime = millis();
if (currentTime - lastCheckTime >= checkInterval) {
lastCheckTime = currentTime;
// Reset RFID reader
mfrc522.PCD_Init();
delay(10); // Brief delay to avoid I2C/SPI conflict
// Check for card presence
bool isCardPresent = mfrc522.PICC_IsNewCardPresent() && mfrc522.PICC_ReadCardSerial();
if (!isCardPresent) {
if (cardPresent) {
missedDetections++;
if (missedDetections >= 3) {
handleCardRemoved();
missedDetections = 0;
cardPresent = false;
}
}
} else {
missedDetections = 0;
if (!cardPresent) {
cardPresent = true;
handleCardInserted();
}
if (cardPresent && relayActive) {
if (currentTime - lastDeductionTime >= CHECK_INTERVAL) {
if (processDeduction()) {
lastDeductionTime = currentTime;
}
}
}
}
}
delay(50);
}
bool processDeduction() {
if (currentBalance <= 0) {
endService();
return false;
}
if (!verifyCardPresence()) {
Serial.println("Card verification failed during deduction");
digitalWrite(RELAY_PIN, HIGH);
relayActive = false;
return false;
}
currentBalance -= 1;
Serial.print("Deducted Rs.1. New balance: Rs.");
Serial.println(currentBalance);
if (!writeBalance()) {
showError("Write Error");
digitalWrite(RELAY_PIN, HIGH);
relayActive = false;
return false;
}
updateDisplay();
if (currentBalance == 0) {
endService();
}
return true;
}
bool verifyCardPresence() {
mfrc522.PCD_Init();
delay(10); // Avoid I2C/SPI conflict
if (!mfrc522.PICC_IsNewCardPresent() || !mfrc522.PICC_ReadCardSerial()) {
Serial.println("Card not present during verification");
digitalWrite(RELAY_PIN, HIGH);
return false;
}
if (!authenticateCard()) {
Serial.println("Re-authentication failed");
digitalWrite(RELAY_PIN, HIGH);
return false;
}
return true;
}
void handleCardInserted() {
Serial.println("Card detected");
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Reading Card...");
Serial.println("LCD: Reading Card...");
if (!verifyCardPresence()) {
showError("Card Verify Fail");
digitalWrite(RELAY_PIN, HIGH);
relayActive = false;
return;
}
if (!readBalance()) {
showError("Read Error");
digitalWrite(RELAY_PIN, HIGH);
relayActive = false;
return;
}
Serial.print("Initial Balance: Rs.");
Serial.println(currentBalance);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Balance: Rs.");
lcd.print(currentBalance);
Serial.print("LCD: Balance: Rs.");
Serial.println(currentBalance);
if (currentBalance > 0) {
startService();
} else {
showInsufficientBalance();
}
}
void handleCardRemoved() {
Serial.println("Card removed");
digitalWrite(RELAY_PIN, HIGH);
relayActive = false;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Card Removed");
lcd.setCursor(0, 1);
lcd.print("Service Stopped");
Serial.println("LCD: Card Removed, Service Stopped");
delay(2000);
resetCard();
showReadyMessage();
}
bool authenticateCard() {
for (byte i = 0; i < 3; i++) {
if (mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, BALANCE_BLOCK, &key, &(mfrc522.uid)) == MFRC522::STATUS_OK) {
return true;
}
delay(100);
}
return false;
}
bool readBalance() {
byte buffer[18];
byte size = sizeof(buffer);
if (mfrc522.MIFARE_Read(BALANCE_BLOCK, buffer, &size) != MFRC522::STATUS_OK) {
return false;
}
memcpy(¤tBalance, buffer, sizeof(currentBalance));
return true;
}
bool writeBalance() {
byte newData[16] = {0};
memcpy(newData, ¤tBalance, sizeof(currentBalance));
for (byte i = 0; i < 3; i++) {
if (mfrc522.MIFARE_Write(BALANCE_BLOCK, newData, 16) == MFRC522::STATUS_OK) {
int verifyBalance;
byte verifyBuffer[18];
byte verifySize = sizeof(verifyBuffer);
if (mfrc522.MIFARE_Read(BALANCE_BLOCK, verifyBuffer, &verifySize) == MFRC522::STATUS_OK) {
memcpy(&verifyBalance, verifyBuffer, sizeof(verifyBalance));
if (verifyBalance == currentBalance) {
return true;
}
}
}
delay(100);
}
return false;
}
void startService() {
relayActive = true;
digitalWrite(RELAY_PIN, LOW);
lastDeductionTime = millis();
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Service Started");
lcd.setCursor(0, 1);
lcd.print("Bal: Rs.");
lcd.print(currentBalance);
Serial.println("LCD: Service Started, Bal: Rs." + String(currentBalance));
Serial.println("Service started - Relay ON");
}
void showInsufficientBalance() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Balance: Rs.0");
lcd.setCursor(0, 1);
lcd.print("Insufficient Bal");
Serial.println("LCD: Insufficient Balance");
delay(2000);
resetCard();
showReadyMessage();
}
void endService() {
digitalWrite(RELAY_PIN, HIGH);
relayActive = false;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Service Ended");
lcd.setCursor(0, 1);
lcd.print("Balance: Rs.0");
Serial.println("LCD: Service Ended, Balance: Rs.0");
delay(2000);
resetCard();
showReadyMessage();
}
void updateDisplay() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Service Active");
lcd.setCursor(0, 1);
lcd.print("Bal: Rs.");
lcd.print(currentBalance);
Serial.println("LCD: Service Active, Bal: Rs." + String(currentBalance));
}
void showError(const char* message) {
Serial.println("Error: " + String(message));
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Error:");
lcd.setCursor(0, 1);
lcd.print(message);
Serial.println("LCD: Error: " + String(message));
delay(2000);
resetCard();
showReadyMessage();
}
void resetCard() {
mfrc522.PICC_HaltA();
mfrc522.PCD_StopCrypto1();
currentBalance = 0;
}
void showReadyMessage() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("System Ready");
lcd.setCursor(0, 1);
lcd.print("Insert Card...");
Serial.println("LCD: System Ready, Insert Card...");
}
void checkReaderConnection() {
byte version = mfrc522.PCD_ReadRegister(MFRC522::VersionReg);
Serial.print("MFRC522 Version: 0x");
Serial.println(version, HEX);
if (version == 0x00 || version == 0xFF) {
Serial.println("WARNING: Communication failure, check wiring!");
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Reader Error!");
lcd.setCursor(0, 1);
lcd.print("Check Wiring");
Serial.println("LCD: Reader Error, Check Wiring");
while (true);
}
}
In this code my LCD like frozen but I lcd show available balance and time left
#include <MFRC522.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#define RST_PIN 22
#define SS_PIN 5
#define BALANCE_BLOCK 4
#define RELAY_PIN 13 // Relay pin (Active LOW)
#define CHECK_INTERVAL 60000 // 1 minute in milliseconds
MFRC522 mfrc522(SS_PIN, RST_PIN);
LiquidCrystal_I2C lcd(0x27, 16, 2); // Try 0x3F if 0x27 doesn't work
MFRC522::MIFARE_Key key;
bool relayActive = false;
unsigned long lastDeductionTime = 0;
int currentBalance = 0;
bool cardPresent = false;
void setup() {
Serial.begin(115200);
Wire.begin(); // Initialize I2C
SPI.begin();
mfrc522.PCD_Init();
lcd.init(); // Initialize LCD
lcd.backlight();
delay(100); // Stabilize LCD
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Initializing...");
Serial.println("LCD Initialized");
pinMode(RELAY_PIN, OUTPUT);
digitalWrite(RELAY_PIN, HIGH); // Relay OFF
for (byte i = 0; i < 6; i++) key.keyByte[i] = 0xFF;
checkReaderConnection();
showReadyMessage();
Serial.println("System Ready - Waiting for card...");
}
void loop() {
static unsigned long lastCheckTime = 0;
const unsigned long checkInterval = 300; // Check every 300ms
static int missedDetections = 0;
unsigned long currentTime = millis();
if (currentTime - lastCheckTime >= checkInterval) {
lastCheckTime = currentTime;
// Reset RFID reader
mfrc522.PCD_Init();
delay(10); // Brief delay to avoid I2C/SPI conflict
// Check for card presence
bool isCardPresent = mfrc522.PICC_IsNewCardPresent() && mfrc522.PICC_ReadCardSerial();
if (!isCardPresent) {
if (cardPresent) {
missedDetections++;
if (missedDetections >= 3) {
handleCardRemoved();
missedDetections = 0;
cardPresent = false;
}
}
} else {
missedDetections = 0;
if (!cardPresent) {
cardPresent = true;
handleCardInserted();
}
if (cardPresent && relayActive) {
if (currentTime - lastDeductionTime >= CHECK_INTERVAL) {
if (processDeduction()) {
lastDeductionTime = currentTime;
}
}
}
}
}
delay(50);
}
bool processDeduction() {
if (currentBalance <= 0) {
endService();
return false;
}
if (!verifyCardPresence()) {
Serial.println("Card verification failed during deduction");
digitalWrite(RELAY_PIN, HIGH);
relayActive = false;
return false;
}
currentBalance -= 1;
Serial.print("Deducted Rs.1. New balance: Rs.");
Serial.println(currentBalance);
if (!writeBalance()) {
showError("Write Error");
digitalWrite(RELAY_PIN, HIGH);
relayActive = false;
return false;
}
updateDisplay();
if (currentBalance == 0) {
endService();
}
return true;
}
bool verifyCardPresence() {
mfrc522.PCD_Init();
delay(10); // Avoid I2C/SPI conflict
if (!mfrc522.PICC_IsNewCardPresent() || !mfrc522.PICC_ReadCardSerial()) {
Serial.println("Card not present during verification");
digitalWrite(RELAY_PIN, HIGH);
return false;
}
if (!authenticateCard()) {
Serial.println("Re-authentication failed");
digitalWrite(RELAY_PIN, HIGH);
return false;
}
return true;
}
void handleCardInserted() {
Serial.println("Card detected");
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Reading Card...");
Serial.println("LCD: Reading Card...");
if (!verifyCardPresence()) {
showError("Card Verify Fail");
digitalWrite(RELAY_PIN, HIGH);
relayActive = false;
return;
}
if (!readBalance()) {
showError("Read Error");
digitalWrite(RELAY_PIN, HIGH);
relayActive = false;
return;
}
Serial.print("Initial Balance: Rs.");
Serial.println(currentBalance);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Balance: Rs.");
lcd.print(currentBalance);
Serial.print("LCD: Balance: Rs.");
Serial.println(currentBalance);
if (currentBalance > 0) {
startService();
} else {
showInsufficientBalance();
}
}
void handleCardRemoved() {
Serial.println("Card removed");
digitalWrite(RELAY_PIN, HIGH);
relayActive = false;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Card Removed");
lcd.setCursor(0, 1);
lcd.print("Service Stopped");
Serial.println("LCD: Card Removed, Service Stopped");
delay(2000);
resetCard();
showReadyMessage();
}
bool authenticateCard() {
for (byte i = 0; i < 3; i++) {
if (mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, BALANCE_BLOCK, &key, &(mfrc522.uid)) == MFRC522::STATUS_OK) {
return true;
}
delay(100);
}
return false;
}
bool readBalance() {
byte buffer[18];
byte size = sizeof(buffer);
if (mfrc522.MIFARE_Read(BALANCE_BLOCK, buffer, &size) != MFRC522::STATUS_OK) {
return false;
}
memcpy(¤tBalance, buffer, sizeof(currentBalance));
return true;
}
bool writeBalance() {
byte newData[16] = {0};
memcpy(newData, ¤tBalance, sizeof(currentBalance));
for (byte i = 0; i < 3; i++) {
if (mfrc522.MIFARE_Write(BALANCE_BLOCK, newData, 16) == MFRC522::STATUS_OK) {
int verifyBalance;
byte verifyBuffer[18];
byte verifySize = sizeof(verifyBuffer);
if (mfrc522.MIFARE_Read(BALANCE_BLOCK, verifyBuffer, &verifySize) == MFRC522::STATUS_OK) {
memcpy(&verifyBalance, verifyBuffer, sizeof(verifyBalance));
if (verifyBalance == currentBalance) {
return true;
}
}
}
delay(100);
}
return false;
}
void startService() {
relayActive = true;
digitalWrite(RELAY_PIN, LOW);
lastDeductionTime = millis();
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Service Started");
lcd.setCursor(0, 1);
lcd.print("Bal: Rs.");
lcd.print(currentBalance);
Serial.println("LCD: Service Started, Bal: Rs." + String(currentBalance));
Serial.println("Service started - Relay ON");
}
void showInsufficientBalance() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Balance: Rs.0");
lcd.setCursor(0, 1);
lcd.print("Insufficient Bal");
Serial.println("LCD: Insufficient Balance");
delay(2000);
resetCard();
showReadyMessage();
}
void endService() {
digitalWrite(RELAY_PIN, HIGH);
relayActive = false;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Service Ended");
lcd.setCursor(0, 1);
lcd.print("Balance: Rs.0");
Serial.println("LCD: Service Ended, Balance: Rs.0");
delay(2000);
resetCard();
showReadyMessage();
}
void updateDisplay() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Service Active");
lcd.setCursor(0, 1);
lcd.print("Bal: Rs.");
lcd.print(currentBalance);
Serial.println("LCD: Service Active, Bal: Rs." + String(currentBalance));
}
void showError(const char* message) {
Serial.println("Error: " + String(message));
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Error:");
lcd.setCursor(0, 1);
lcd.print(message);
Serial.println("LCD: Error: " + String(message));
delay(2000);
resetCard();
showReadyMessage();
}
void resetCard() {
mfrc522.PICC_HaltA();
mfrc522.PCD_StopCrypto1();
currentBalance = 0;
}
void showReadyMessage() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("System Ready");
lcd.setCursor(0, 1);
lcd.print("Insert Card...");
Serial.println("LCD: System Ready, Insert Card...");
}
void checkReaderConnection() {
byte version = mfrc522.PCD_ReadRegister(MFRC522::VersionReg);
Serial.print("MFRC522 Version: 0x");
Serial.println(version, HEX);
if (version == 0x00 || version == 0xFF) {
Serial.println("WARNING: Communication failure, check wiring!");
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Reader Error!");
lcd.setCursor(0, 1);
lcd.print("Check Wiring");
Serial.println("LCD: Reader Error, Check Wiring");
while (true);
}
}
In this code my LCD like frozen but I lcd show available balance and time left