Skip to content

Instantly share code, notes, and snippets.

@bkbilly
Created May 20, 2020 03:06
Show Gist options
  • Select an option

  • Save bkbilly/54cfa23248e4b94cf40a7cf933d62961 to your computer and use it in GitHub Desktop.

Select an option

Save bkbilly/54cfa23248e4b94cf40a7cf933d62961 to your computer and use it in GitHub Desktop.
/*
*
* Created by bkbilly
* https://github.com/omersiar/RFID522-Door-Unlock/blob/master/EEPROM/EEPROM.ino
*
*
*/
#include <WiFi.h>
#include <ESPmDNS.h>
#include <ArduinoOTA.h>
#include <PubSubClient.h>
#include <SPI.h>
#include <MFRC522.h>
#include <EEPROM.h>
#include "secrets.h"
#define SS_PIN 21
#define RST_PIN 22
#define mqtt_subscribe_topic "smartlock/set"
#define uid_size 7 // Usually uid is either 4 or 7 bytes
#define rfid_timout 10 // Seconds
byte storedCard[uid_size];
String set_option;
unsigned long rfid_start_timer;
MFRC522 mfrc522(SS_PIN, RST_PIN); // Create MFRC522 instance.
WiFiClient espClient;
PubSubClient client;
void setup()
{
rfid_start_timer = millis();
EEPROM.begin(500);
Serial.begin(115200); // Initiate a serial communication
Serial.println("Booting");
// NFC init
SPI.begin(); // Initiate SPI bus
mfrc522.PCD_Init(); // Initiate MFRC522
Serial.println("Approximate your card to the reader...");
Serial.println();
// WiFi init
WiFi.begin(ssid, password);
delay(10);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("WiFi connected");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
// MQTT init
client.setClient(espClient);
client.setServer(mqtt_server, mqtt_port);
client.setCallback(mqtt_callback);
if (client.connect("arduinoClient", mqtt_user, mqtt_pass)) {
client.publish("smartlock/status", "connected");
client.subscribe(mqtt_subscribe_topic);
}
// OTA init
// Port defaults to 3232
// ArduinoOTA.setPort(3232);
// Hostname defaults to esp3232-[MAC]
ArduinoOTA.setHostname("smartlock");
// No authentication by default
// ArduinoOTA.setPassword("admin");
// Password can be set with it's md5 value as well
// MD5(admin) = 21232f297a57a5a743894a0e4a801fc3
// ArduinoOTA.setPasswordHash("21232f297a57a5a743894a0e4a801fc3");
ArduinoOTA
.onStart([]() {
String type;
if (ArduinoOTA.getCommand() == U_FLASH)
type = "sketch";
else // U_SPIFFS
type = "filesystem";
// NOTE: if updating SPIFFS this would be the place to unmount SPIFFS using SPIFFS.end()
Serial.println("Start updating " + type);
})
.onEnd([]() {
Serial.println("\nEnd");
})
.onProgress([](unsigned int progress, unsigned int total) {
Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
})
.onError([](ota_error_t error) {
Serial.printf("Error[%u]: ", error);
if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed");
else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed");
else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed");
else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed");
else if (error == OTA_END_ERROR) Serial.println("End Failed");
});
ArduinoOTA.begin();
}
void loop()
{
if (millis() - rfid_start_timer >= rfid_timout * 1000 && set_option != ""){
set_option = "";
Serial.println("----------> time is up......");
client.publish("smartlock/rfid_timer", "ended");
}
client.loop();
if (!client.connected()) {
mqtt_reconnect();
}
ArduinoOTA.handle();
readRFID();
}
void mqtt_reconnect() {
// Loop until we're reconnected
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
// Attempt to connect
if (client.connect("arduinoClient")) {
Serial.println("connected");
client.publish("smartlock/status","connected");
client.subscribe(mqtt_subscribe_topic);
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
// Wait 5 seconds before retrying
delay(5000);
}
}
}
void mqtt_callback(char* topic, byte* payload, unsigned int length) {
// client.publish("smartlock/mqtt_callback", "received message");
payload[length] = '\0';
String message = (char*)payload;
Serial.print(topic);
Serial.print(": ");
Serial.println(message);
if (message == "deleteall") {
Serial.println("Delete all RFIDs from the EEPROM.");
deleteAll();
} else if (message == "getids"){
getIDs();
} else if (message == "add_rfid"){
Serial.println("Add a new RFID on the EEPROM.");
set_option = message;
client.publish("smartlock/rfid_timer", "started");
rfid_start_timer = millis();
} else if (message == "del_rfid"){
Serial.println("Delete a RFID from the EEPROM.");
set_option = message;
client.publish("smartlock/rfid_timer", "started");
rfid_start_timer = millis();
}
}
void readRFID(){
// Look for new cards
if ( ! mfrc522.PICC_IsNewCardPresent()){return;}
// Select one of the cards
if ( ! mfrc522.PICC_ReadCardSerial()) {return;}
String uid_str = "";
byte uid_byte[uid_size];
char uid_char[mfrc522.uid.size];
for (byte i = 0; i < mfrc522.uid.size; i++)
{
uid_str.concat(String(mfrc522.uid.uidByte[i] < 0x10 ? "0" : ":"));
uid_str.concat(String(mfrc522.uid.uidByte[i], HEX));
uid_byte[i] = mfrc522.uid.uidByte[i];
}
uid_str.toUpperCase();
uid_str.toCharArray(uid_char, 50);
uid_str = uid_str.substring(1); // Get access denied if I remove this... :(
client.publish("smartlock/rfid_uid", uid_char);
Serial.print("UID tag: ");
Serial.println(uid_char);
Serial.print("Access: ");
if (set_option == "add_rfid") {
writeID(uid_byte);
set_option = "";
} else if (set_option == "del_rfid") {
deleteID(uid_byte);
set_option = "";
} else if ( findID(uid_byte) ) {
Serial.println("Authorized");
client.publish("smartlock/access", "authorized");
} else {
Serial.println(" Denied");
client.publish("smartlock/access", "denied");
}
Serial.println();
delay(1000);
}
//////////////////////////////////////// Read an ID from EEPROM //////////////////////////////
void readID( int number ) {
int start = (number * uid_size ) + 2; // Figure out starting position
for ( int i = 0; i < uid_size; i++ ) { // Loop 4 times to get the 4 Bytes
storedCard[i] = EEPROM.read(start + i); // Assign values read from EEPROM to array
}
}
void getIDs() {
int count = EEPROM.read(0);
Serial.print(F("I have "));
Serial.print(count);
Serial.print(F(" record(s) on EEPROM"));
Serial.println("");
for ( int i = 1; i <= count; i++ ) {
String uid_str = "";
int start = (i * uid_size ) + 2;
for ( int j = 0; j < uid_size; j++ ) {
storedCard[i] = EEPROM.read(start + j);
uid_str.concat(String(storedCard[i] < 0x10 ? "0" : ":"));
uid_str.concat(String(storedCard[i], HEX));
}
uid_str.toUpperCase();
Serial.print(i+1);
Serial.print(") UID: ");
Serial.println(uid_str);
char uid_char[mfrc522.uid.size];
uid_str.toCharArray(uid_char, 50);
client.publish("smartlock/saved_uid", uid_char);
}
Serial.println();
}
///////////////////////////////////////// Add ID to EEPROM ///////////////////////////////////
void writeID( byte a[] ) {
if ( !findID( a ) ) { // Before we write to the EEPROM, check to see if we have seen this card before!
int num = EEPROM.read(0); // Get the numer of used spaces, position 0 stores the number of ID cards
int start = ( num * uid_size ) + uid_size + 2; // Figure out where the next slot starts
num++; // Increment the counter by one
EEPROM.write( 0, num ); // Write the new count to the counter
for ( int j = 0; j < uid_size; j++ ) { // Loop 4 times
EEPROM.write( start + j, a[j] ); // Write the array values to EEPROM in the right position
}
EEPROM.commit();
Serial.println(F("Succesfully added ID record to EEPROM"));
}
else {
Serial.println(F("Failed! There is something wrong with ID or bad EEPROM, or already exists"));
}
}
///////////////////////////////////////// Remove ID from EEPROM ///////////////////////////////////
void deleteID( byte a[] ) {
if ( !findID( a ) ) { // Before we delete from the EEPROM, check to see if we have this card!
Serial.println(F("Failed! There is something wrong with ID or bad EEPROM"));
}
else {
int num = EEPROM.read(0); // Get the numer of used spaces, position 0 stores the number of ID cards
int slot; // Figure out the slot number of the card
int start; // = ( num * uid_size ) + uid_size + 2; // Figure out where the next slot starts
int looping; // The number of times the loop repeats
int j;
int count = EEPROM.read(0); // Read the first Byte of EEPROM that stores number of cards
slot = findIDSLOT( a ); // Figure out the slot number of the card to delete
start = (slot * uid_size) + 2;
looping = ((num - slot) * uid_size);
num--; // Decrement the counter by one
EEPROM.write( 0, num ); // Write the new count to the counter
for ( j = 0; j < looping; j++ ) { // Loop the card shift times
EEPROM.write( start + j, EEPROM.read(start + uid_size + j)); // Shift the array values to 4 places earlier in the EEPROM
}
for ( int k = 0; k < uid_size; k++ ) { // Shifting loop
EEPROM.write( start + j + k, 0);
}
EEPROM.commit();
Serial.println(F("Succesfully removed ID record from EEPROM"));
}
}
void deleteAll() {
int count = EEPROM.read(0);
EEPROM.write( 0, 0 );
for ( int i = 1; i <= count; i++ ) {
int start = (i * uid_size ) + 2;
for ( int j = 0; j < uid_size; j++ ) {
EEPROM.write(start + j, 0);
}
}
}
///////////////////////////////////////// Check Bytes ///////////////////////////////////
boolean checkTwo ( byte a[], byte b[] ) {
boolean match = false;
if ( a[0] != NULL ) // Make sure there is something in the array first
match = true; // Assume they match at first
for ( int k = 0; k < uid_size; k++ ) { // Loop 4 times
if ( a[k] != b[k] ) // IF a != b then set match = false, one fails, all fail
match = false;
}
if ( match ) { // Check to see if if match is still true
return true; // Return true
}
else {
return false; // Return false
}
}
///////////////////////////////////////// Find Slot ///////////////////////////////////
int findIDSLOT( byte find[] ) {
int count = EEPROM.read(0); // Read the first Byte of EEPROM that
for ( int i = 1; i <= count; i++ ) { // Loop once for each EEPROM entry
readID(i); // Read an ID from EEPROM, it is stored in storedCard[4]
if ( checkTwo( find, storedCard ) ) { // Check to see if the storedCard read from EEPROM
// is the same as the find[] ID card passed
return i; // The slot number of the card
break; // Stop looking we found it
}
}
}
///////////////////////////////////////// Find ID From EEPROM ///////////////////////////////////
boolean findID( byte find[] ) {
int count = EEPROM.read(0); // Read the first Byte of EEPROM that
for ( int i = 1; i <= count; i++ ) { // Loop once for each EEPROM entry
readID(i); // Read an ID from EEPROM, it is stored in storedCard[4]
if ( checkTwo( find, storedCard ) ) { // Check to see if the storedCard read from EEPROM
return true;
break; // Stop looking we found it
}
else { // If not, return false
}
}
return false;
}
#define ssid "ssid"
#define password "password"
#define mqtt_server "mqtt_ip"
#define mqtt_port 1883
#define mqtt_user "user"
#define mqtt_pass "pass"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment