Troubleshoot Frozen LCD Display

Job ID: 39645280

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(&currentBalance, buffer, sizeof(currentBalance));
return true;
}

bool writeBalance() {
byte newData[16] = {0};
memcpy(newData, &currentBalance, 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
Related categories: C++ Programming Arduino Debugging I2C