31#include <ArduinoJson.h>
36#include <LiquidCrystal_I2C.h>
48constexpr char WIFI_PASS[] =
"mrbombasticcallmefantastic";
171 lcd.setCursor(0, line);
173 lcd.setCursor(0, line);
184 lcd.setCursor(0, line);
186 lcd.setCursor(0, line);
222 memset(
enteredPins + pinLength,
' ', 4 - pinLength);
240void callback(
char* topic,
byte* payload,
unsigned int length) {
242 if (length == 0)
return;
244 StaticJsonDocument<512> doc;
247 DeserializationError err = deserializeJson(doc, payload, length);
251 Serial.print(
"JSON parse failed: ");
252 Serial.println(err.c_str());
259 if (strcmp(topic,
net.makeTopic(
"access/response").c_str()) == 0) {
262 uint32_t requestMs = doc[
"sent_ts_ms"] | 0;
265 uint32_t deltaMs = millis() - requestMs;
268 "Request/Response time diff: %lu ms\n",
274 Serial.println(
"Took too long to respond");
279 rfidAccess = (doc[
"response"][
"hasAccess"] |
false)
283 Serial.println(
"UID match: waiting for PIN...");
302 else if (strcmp(topic,
net.makeTopic(
"access/keypad_response").c_str()) == 0) {
314 Serial.println(
"Access Denied");
322 Serial.println(
"Access Granted");
331 else if (strcmp(topic,
net.makeTopic(
"keypad/beep").c_str()) == 0) {
337 uint8_t pinLength = doc[
"data"][
"pinlength"] | 0;
367 Serial.println(F(
"Motion detected"));
420 if (outputSize < (uid.size * 2 + 1)) {
426 for (
byte i = 0; i < uid.size; i++) {
427 sprintf(&output[i * 2],
"%02X", uid.uidByte[i]);
431 output[uid.size * 2] =
'\0';
443 if (!
mfrc522.PICC_IsNewCardPresent()) {
448 if (!
mfrc522.PICC_ReadCardSerial()) {
455 Serial.println(uidString);
462 StaticJsonDocument<64> data;
463 data[
"uid"] = uidString;
464 data[
"event"] =
"RFID_Try";
467 bool ok =
net.publishJson(
"access/request", data);
468 Serial.println(ok ?
"MQTT publish OK" :
"MQTT publish FAILED");
483 Serial.begin(115200);
497 Serial.println(
"RC522 initialized");
512 Serial.println(
"MQTT ready");
517 Serial.printf(
"access/response MQTT subscribe %s\n",
518 net.subscribe(
net.makeTopic(
"access/response").c_str()) ?
"OK" :
"FAILED");
520 Serial.printf(
"access/keypad_response MQTT subscribe %s\n",
521 net.subscribe(
net.makeTopic(
"access/keypad_response").c_str()) ?
"OK" :
"FAILED");
523 Serial.printf(
"keypad/beep MQTT subscribe %s\n",
524 net.subscribe(
net.makeTopic(
"keypad/beep").c_str()) ?
"OK" :
"FAILED");
540 const uint32_t now = millis();
Lightweight WiFi + MQTT helper wrapper for ESP-based Arduino systems.
Combined WiFi and MQTT client abstraction.
constexpr char WIFI_PASS[]
WiFi password.
uint32_t showTextUntil
Timestamp (ms) when the displayed text should expire.
constexpr char DEVICE_ID[]
Unique device identifier used in MQTT topics.
WifiMqttClient net
WiFi + MQTT client wrapper.
constexpr uint8_t LCD_COLUMNS
Number of LCD columns.
constexpr uint32_t PIN_TIME_MS
Time window (ms) for entering PIN after RFID success.
void lcdPrintLine(const __FlashStringHelper *msg, uint8_t line)
Clears an LCD line and prints a flash-resident string.
MFRC522 mfrc522(RFID_SS_PIN, RFID_RST_PIN)
MFRC522 RFID reader instance.
uint32_t showDisplayUntil
Timestamp (ms) when LCD backlight should turn off.
constexpr char MQTT_USER[]
MQTT username.
constexpr char MQTT_PASS[]
MQTT password.
AccessResult accessGranted
Result of PIN verification.
constexpr char MQTT_HOST[]
MQTT broker hostname.
void setup()
Arduino setup function.
constexpr uint8_t RFID_RST_PIN
RC522 Reset pin (D0 / GPIO16).
bool motionActive
Indicates whether motion is currently considered active.
constexpr uint8_t I2C_SDA_PIN
I2C SDA pin for LCD (D2 / GPIO4).
AccessResult
Access result enumeration.
constexpr uint32_t UNLOCK_TIME_MS
Door unlock display duration (ms).
constexpr uint8_t RFID_SS_PIN
RC522 SPI Slave Select pin (D8 / GPIO15).
bool textshown
Indicates whether a status message is currently displayed.
constexpr uint32_t DISPLAY_BACKLIGHT_MS
Duration (ms) to keep LCD backlight on after motion.
constexpr uint32_t DISPLAY_MS
Duration (ms) to display text before resetting.
void updateMotionState(uint32_t now)
Updates motion state based on PIR sensor input.
constexpr uint8_t MOTION_PIN
Motion sensor pin (D3 / GPIO0).
constexpr uint16_t MQTT_PORT
MQTT broker port.
constexpr uint8_t I2C_SCL_PIN
I2C SCL pin for LCD (D1 / GPIO5).
constexpr uint8_t LCD_ADDRESS
I2C address of the LCD module.
LiquidCrystal_I2C lcd(LCD_ADDRESS, LCD_COLUMNS, LCD_ROWS)
I2C LCD instance.
void uidToHexString(const MFRC522::Uid &uid, char *output, size_t outputSize)
Converts an RFID UID to a hexadecimal string.
void callback(char *topic, byte *payload, unsigned int length)
MQTT message callback handler.
void makeEnteredPins(uint8_t pinLength)
Builds a masked PIN string for LCD display.
void onMotionIdle(uint32_t now)
Handles motion-idle state.
void onMotionDetected(uint32_t now)
Handles motion-detected events.
constexpr char WIFI_SSID[]
WiFi SSID.
constexpr uint8_t LCD_ROWS
Number of LCD rows.
void handleRFID()
Handles RFID card detection and request publishing.
static char enteredPins[5]
Masked PIN buffer shown on LCD (max 4 digits + null terminator).
AccessResult rfidAccess
Result of RFID authentication.
constexpr uint32_t POLL_MS
Main loop polling delay (ms).
bool isDisplayActive(uint32_t now)
Checks whether the LCD backlight should remain active.
void loop()
Arduino main loop.
static void forceLock()
Forces the system back into locked idle state.