Hi All,
I am currently prototyping a project to open and close my garage door via RFID and a keypad, in addition to integration with homekit via mqtt.
i have an arduino and an esp8266 (The Thing).
The arduino controls the keypad and the RFID reader. It is basically a "stupid" controller with no authentication logic. All authentication logic is in the ESP8266.
So when the pincode is entered on the keypad or RFID is scanned, the code is sent via SoftSerial from the Arduino to the ESP8266. It works great in a happy flow scenario.
Now i am testing the unhappy paths. I am currently trying to find of if the ESP8266 would still be able to do it's thing then no connection to the arduino can be made via softserial. Because control via Homekit should still be posible, even when keypad and RFID reader are unavailable.
But it doesn't seem to be the case with my current code.
I could try to fix this by not using the serial connection but instead go all the way over mqtt. But i don't want to be dependant of the wifi connection being up. that's also why i chose to store all authentication data in the EEPROM of the ESP. It will only retrieve new codes over the wifi network if it detects a new version of those pincode sets.
Please point me in the right direction on how to "ignore" the software serial until it becomes available.
#include <EEPROM.h>
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <Wire.h>
#include <ArduinoJson.h>
#include <SoftwareSerial.h>
// PINS
#define RELAY_TRIGGER_PIN 12
#define BRAIN_RX_PIN 2
#define BRAIN_TX_PIN 14
#define SENSOR_GARAGE_CLOSED_PIN 4
#define SENSOR_GARAGE_OPENED_PIN 0
#define BUTTON_PIN 13
#define LED_PIN 5
//*********
// Timings
#define RELAY_TRIGGER_DELAY 300
#define RFID_IGNORE_TIME 2500
//********
// Communication codes
#define RFIDCODE "1"
#define KEYPADCODE "2"
#define EOT '\4'
//********************
// Variable sizes
#define jsonBufferSize 468
#define RFIDArrayLength 13
#define PincodeArrayLength 5
//***************
// EEPROM Addresses
#define EEPROM_PINCODE_ADDRESS 0
#define EEPROM_RFID_ADDRESS 60
//*****************
const char *ssid = "xxxxxxxxxxxxxxx";
const char *password = "xxxxxxxxxxx";
const char *mqtt_server = "xxxxxxxxxxxx";
const char *device_id = "xxxxxxxxxxxxx";
unsigned long lastRFIDReadTime;
unsigned long lastWifiReconnectTime;
unsigned long lastMQTTReconnectTime;
bool initialWifiConnect = true;
bool initialMQTTConnect = true;
WiFiClient espClient;
PubSubClient client(espClient);
StaticJsonDocument<jsonBufferSize> jsonDoc;
SoftwareSerial brainconnection(BRAIN_RX_PIN, BRAIN_TX_PIN);
char message_buffer[500];
struct {
int count;
int version;
char pincodes[10][PincodeArrayLength];
} pinEEPROM;
struct {
int count;
int version;
char rfids[10][RFIDArrayLength];
} rfidEEPROM;
char pincodes[10][PincodeArrayLength];
int pincode_count = 0;
int pincode_version = 0;
bool setupComplete = false;
char rfids[10][RFIDArrayLength];
int rfid_count = 0;
int rfid_version = 0;
char serial_buffer[500];
char lastIncomingChar = '\0';
String keypadData = "";
int count = 0;
// Button debouncing
int buttonState; // the current reading from the input pin
int lastButtonState = LOW; // the previous reading from the input pin
unsigned long lastDebounceTime = 0; // the last time the output pin was toggled
unsigned long debounceDelay = 50; // the debounce time; increase if the output flickers
//******************
// Sensor variables
int lastGarageClosedState = 2;
//*****************
void setup()
{
Serial.begin(115200);
Serial.println("");
// PIN Setup
//**********
Serial.println("PIN setup");
//setup led pin
pinMode(LED_PIN, OUTPUT);
digitalWrite(LED_PIN, LOW);
//setup garage door closed pin
pinMode(SENSOR_GARAGE_CLOSED_PIN, INPUT_PULLUP);
//Setup relay
pinMode(RELAY_TRIGGER_PIN, OUTPUT);
digitalWrite(RELAY_TRIGGER_PIN, LOW);
//Setup button pin
pinMode(BUTTON_PIN, INPUT);
digitalWrite(BUTTON_PIN, LOW);
pinMode(BRAIN_RX_PIN, INPUT);
pinMode(BRAIN_TX_PIN, OUTPUT);
// End PIN Setup
//***************
delay(1000);
Serial.println("Brain connection setup");
brainconnection.begin(9600);
Serial.println("EEPROM setup");
EEPROM.begin(200);
readPincodesFromEEPROM();
readRFIDsFromEEPROM();
readKeypadData();
setup_wifi();
client.setServer(mqtt_server, 1883);
client.setCallback(callback);
}
void loop()
{
readKeypadData();
setup_wifi();
if (!client.connected())
{
reconnect();
}
client.loop();
checkGarageDoorOpen();
checkOpenGarageDoorButtonPressed();
}
void readKeypadData() {
// if data is coming from software serial port ==> data is coming from SoftSerial shield
if (!brainconnection.isListening()) {
return;
}
if (brainconnection.available()) {
while (brainconnection.available()) // reading data into char array
{
count++;
if (count == 64)
break;
lastIncomingChar = (char) brainconnection.read();
keypadData.concat(lastIncomingChar);
}
//Serial.println(keypadData.length());
count = 0; // set counter of while loop to zero
//if (keypadData.length() == 13) {
if (lastIncomingChar == EOT) {
if (keypadData.startsWith(RFIDCODE)) {
keypadData = keypadData.substring(1, keypadData.length() - 1);
Serial.println(keypadData);
keypadData.toCharArray(serial_buffer, 500);
if (lastRFIDReadTime + RFID_IGNORE_TIME < millis()) {
client.publish("home/garage/door/rfid/login/request", serial_buffer, false);
lastRFIDReadTime = millis();
if (verifyRFID(keypadData)) {
triggerRelay();
}
}
keypadData = "";
} else if (keypadData.startsWith(KEYPADCODE)) {
keypadData = keypadData.substring(1, keypadData.length() - 1);
Serial.println(keypadData);
keypadData.toCharArray(serial_buffer, 500);
client.publish("home/garage/door/keypad/login/request", serial_buffer, false);
if (verifyPincode(keypadData)) {
triggerRelay();
}
}
keypadData = "";
}
}
}
void setup_wifi() {
}
void callback(char *topic, byte * payload, unsigned int length)
}
void deserializeJSONData(char* json) {
// Deserialize the JSON document
DeserializationError error = deserializeJson(jsonDoc, json);
if (error) {
Serial.print(F("deserializeJson() failed: "));
Serial.println(error.c_str());
return;
}
}
I had to cut down on the code because aparently i can't make posts with more than 9000 characters, so it won't compile because code is missing