From 5892cffbdae2f8a4a31fc6664a535771ceee739e Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Mon, 30 Nov 2020 17:54:40 +0100
Subject: [PATCH] Prep RC522 rfid reader pt2
---
tasmota/my_user_config.h | 21 ++---
tasmota/support_features.ino | 4 +-
tasmota/tasmota.ino | 3 +-
tasmota/tasmota_configurations.h | 3 +
tasmota/xsns_80_mfrc522.ino | 136 +++++++++++++++++++++++++++++++
tools/decode-status.py | 4 +-
6 files changed, 155 insertions(+), 16 deletions(-)
create mode 100644 tasmota/xsns_80_mfrc522.ino
diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h
index 45cbb25da..0908fae79 100644
--- a/tasmota/my_user_config.h
+++ b/tasmota/my_user_config.h
@@ -613,21 +613,18 @@
// -- SPI sensors ---------------------------------
//#define USE_SPI // Hardware SPI using GPIO12(MISO), GPIO13(MOSI) and GPIO14(CLK) in addition to two user selectable GPIOs(CS and DC)
+
#ifdef USE_SPI
// #define USE_NRF24 // Add SPI support for NRF24L01(+) (+2k6 code)
- #ifdef USE_NRF24
#define USE_MIBLE // BLE-bridge for some Mijia-BLE-sensors (+4k7 code)
- #else
- #ifndef USE_DISPLAY
- #define USE_DISPLAY // Add SPI Display support for 320x240 and 480x320 TFT
- #endif
- #define USE_DISPLAY_ILI9341 // [DisplayModel 4] Enable ILI9341 Tft 480x320 display (+19k code)
-// #define USE_DISPLAY_EPAPER_29 // [DisplayModel 5] Enable e-paper 2.9 inch display (+19k code)
-// #define USE_DISPLAY_EPAPER_42 // [DisplayModel 6] Enable e-paper 4.2 inch display
-// #define USE_DISPLAY_ILI9488 // [DisplayModel 8] [I2cDriver38] (Touch)
-// #define USE_DISPLAY_SSD1351 // [DisplayModel 9]
-// #define USE_DISPLAY_RA8876 // [DisplayModel 10] [I2cDriver39] (Touch)
- #endif // USE_NRF24
+// #define USE_DISPLAY // Add SPI Display support for 320x240 and 480x320 TFT
+ #define USE_DISPLAY_ILI9341 // [DisplayModel 4] Enable ILI9341 Tft 480x320 display (+19k code)
+// #define USE_DISPLAY_EPAPER_29 // [DisplayModel 5] Enable e-paper 2.9 inch display (+19k code)
+// #define USE_DISPLAY_EPAPER_42 // [DisplayModel 6] Enable e-paper 4.2 inch display
+// #define USE_DISPLAY_ILI9488 // [DisplayModel 8] [I2cDriver38] (Touch)
+// #define USE_DISPLAY_SSD1351 // [DisplayModel 9]
+// #define USE_DISPLAY_RA8876 // [DisplayModel 10] [I2cDriver39] (Touch)
+// #define USE_RC522 // Add support for MFRC522 13.56Mhz Rfid reader (+6k code)
#endif // USE_SPI
// -- Serial sensors ------------------------------
diff --git a/tasmota/support_features.ino b/tasmota/support_features.ino
index 64155e324..f6995f0ee 100644
--- a/tasmota/support_features.ino
+++ b/tasmota/support_features.ino
@@ -665,7 +665,9 @@ void ResponseAppendFeatures(void)
#if defined(USE_SHELLY_DIMMER)
feature7 |= 0x00001000; // xdrv_45_shelly_dimmer.ino
#endif
-// feature7 |= 0x00002000;
+#ifdef USE_RC522
+ feature7 |= 0x00002000; // xsns_80_mfrc522.ino
+#endif
// feature7 |= 0x00004000;
// feature7 |= 0x00008000;
diff --git a/tasmota/tasmota.ino b/tasmota/tasmota.ino
index d89e2c22c..0af214158 100644
--- a/tasmota/tasmota.ino
+++ b/tasmota/tasmota.ino
@@ -299,7 +299,8 @@ void setup(void) {
SetPowerOnState();
- AddLog_P(LOG_LEVEL_INFO, PSTR(D_PROJECT " %s %s " D_VERSION " %s%s-" ARDUINO_CORE_RELEASE), PROJECT, SettingsText(SET_DEVICENAME), TasmotaGlobal.version, TasmotaGlobal.image_name);
+ AddLog_P(LOG_LEVEL_INFO, PSTR(D_PROJECT " %s %s " D_VERSION " %s%s-" ARDUINO_CORE_RELEASE "(%s)"),
+ PROJECT, SettingsText(SET_DEVICENAME), TasmotaGlobal.version, TasmotaGlobal.image_name, GetBuildDateAndTime().c_str());
#ifdef FIRMWARE_MINIMAL
AddLog_P(LOG_LEVEL_INFO, PSTR(D_WARNING_MINIMAL_VERSION));
#endif // FIRMWARE_MINIMAL
diff --git a/tasmota/tasmota_configurations.h b/tasmota/tasmota_configurations.h
index 6acddadd5..da400cea3 100644
--- a/tasmota/tasmota_configurations.h
+++ b/tasmota/tasmota_configurations.h
@@ -141,6 +141,9 @@
//#define USE_EZORGB // [I2cDriver55] Enable support for EZO's RGB sensor (+0k5 code) - Shared EZO code required for any EZO device (+1k2 code)
//#define USE_EZOPMP // [I2cDriver55] Enable support for EZO's PMP sensor (+0k3 code) - Shared EZO code required for any EZO device (+1k2 code)
+//#define USE_SPI // Hardware SPI using GPIO12(MISO), GPIO13(MOSI) and GPIO14(CLK) in addition to two user selectable GPIOs(CS and DC)
+//#define USE_RC522 // Add support for MFRC522 13.56Mhz Rfid reader (+6k code)
+
#define USE_MHZ19 // Add support for MH-Z19 CO2 sensor (+2k code)
#define USE_SENSEAIR // Add support for SenseAir K30, K70 and S8 CO2 sensor (+2k3 code)
#ifndef CO2_LOW
diff --git a/tasmota/xsns_80_mfrc522.ino b/tasmota/xsns_80_mfrc522.ino
new file mode 100644
index 000000000..9754bf963
--- /dev/null
+++ b/tasmota/xsns_80_mfrc522.ino
@@ -0,0 +1,136 @@
+/*
+ xsns_80_mfrc522.ino - Support for MFRC522 (SPI) NFC Tag Reader on Tasmota
+
+ Copyright (C) 2020 Theo Arends
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+#ifdef USE_RC522
+/*********************************************************************************************\
+ * MFRC522 - 13.56 MHz RFID reader
+\*********************************************************************************************/
+
+#define XSNS_80 80
+
+#define USE_RC522_DATA_FUNCTION
+
+#include
+MFRC522 *Mfrc522;
+
+struct RC522 {
+ bool present = false;
+ uint8_t scantimer = 0;
+} Rc522;
+
+void RC522ScanForTag(void) {
+ // Reset the loop if no new card present on the sensor/reader. This saves the entire process when idle. And if present, select one.
+ if (!Mfrc522->PICC_IsNewCardPresent() || !Mfrc522->PICC_ReadCardSerial()) { return; }
+
+ MFRC522::PICC_Type piccType = Mfrc522->PICC_GetType(Mfrc522->uid.sak);
+ AddLog_P(LOG_LEVEL_DEBUG, PSTR("MFR: Type %s"), Mfrc522->PICC_GetTypeName(piccType));
+
+ char uids[21]; // Number of bytes in the UID. 4, 7 or 10
+ ToHex_P((unsigned char*)Mfrc522->uid.uidByte, Mfrc522->uid.size, uids, sizeof(uids));
+
+#ifdef USE_RC522_DATA_FUNCTION
+ bool didit = false;
+ if ( piccType == MFRC522::PICC_TYPE_MIFARE_MINI
+ || piccType == MFRC522::PICC_TYPE_MIFARE_1K
+ || piccType == MFRC522::PICC_TYPE_MIFARE_4K) {
+
+ uint8_t trailerBlock = 7;
+ MFRC522::MIFARE_Key key;
+ for (uint32_t i = 0; i < 6; i++) {
+ key.keyByte[i] = 0xFF;
+ }
+ MFRC522::StatusCode status = Mfrc522->PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, trailerBlock, &key, &(Mfrc522->uid));
+ if (status == MFRC522::STATUS_OK) {
+ uint8_t buffer[18]; // The buffer must be at least 18 bytes because a CRC_A is also returned
+ uint8_t size = sizeof(buffer);
+ status = (MFRC522::StatusCode) Mfrc522->MIFARE_Read(1, buffer, &size);
+ if (status == MFRC522::STATUS_OK) {
+ char card_datas[34];
+ for (uint32_t i = 0; i < size -2; i++) {
+ if ((isalpha(buffer[i])) || ((isdigit(buffer[i])))) {
+ card_datas[i] = char(buffer[i]);
+ } else {
+ card_datas[i] = '\0';
+ }
+ }
+ didit = true;
+ ResponseTime_P(PSTR(",\"MFRC522\":{\"UID\":\"%s\",\"" D_JSON_DATA "\":\"%s\"}}"), uids, card_datas);
+ }
+ }
+ }
+ if (!didit) {
+ ResponseTime_P(PSTR(",\"MFRC522\":{\"UID\":\"%s\"}}"), uids);
+ }
+#else
+ ResponseTime_P(PSTR(",\"MFRC522\":{\"UID\":\"%s\"}}"), uids);
+#endif
+ MqttPublishTeleSensor();
+
+ // Halt PICC
+ Mfrc522->PICC_HaltA();
+
+ Rc522.scantimer = 7; // Ignore tags found for two seconds
+}
+
+void RC522Init(void) {
+ if (PinUsed(GPIO_SPI_CS) && PinUsed(GPIO_RC522_RST)) {
+ Mfrc522 = new MFRC522(Pin(GPIO_SPI_CS), Pin(GPIO_RC522_RST));
+ SPI.begin();
+ Mfrc522->PCD_Init();
+ if (Mfrc522->PCD_PerformSelfTest()) {
+ uint8_t v = Mfrc522->PCD_ReadRegister(Mfrc522->VersionReg);
+ char ver[8] = { 0 };
+ switch (v) {
+ case 0x92: strcpy_P(ver, PSTR("v2.0")); break;
+ case 0x91: strcpy_P(ver, PSTR("v1.0")); break;
+ case 0x88: strcpy_P(ver, PSTR("clone")); break;
+ case 0x00: case 0xFF: strcpy_P(ver, PSTR("fail")); break;
+ }
+ AddLog_P(LOG_LEVEL_INFO, PSTR("MFR: MFRC522 Rfid reader %s"), ver);
+ Rc522.present = true;
+ }
+ }
+}
+
+/*********************************************************************************************\
+ * Interface
+\*********************************************************************************************/
+
+bool Xsns80(uint8_t function)
+{
+ bool result = false;
+
+ if (FUNC_INIT == function) {
+ RC522Init();
+ }
+ else if (Rc522.present) {
+ switch (function) {
+ case FUNC_EVERY_250_MSECOND:
+ if (Rc522.scantimer) {
+ Rc522.scantimer--;
+ } else {
+ RC522ScanForTag();
+ }
+ break;
+ }
+ }
+ return result;
+}
+
+#endif // USE_RC522
diff --git a/tools/decode-status.py b/tools/decode-status.py
index 07896559d..829e84e32 100755
--- a/tools/decode-status.py
+++ b/tools/decode-status.py
@@ -239,7 +239,7 @@ a_features = [[
"USE_EZOORP","USE_EZORTD","USE_EZOHUM","USE_EZOEC",
"USE_EZOCO2","USE_EZOO2","USE_EZOPRS","USE_EZOFLO",
"USE_EZODO","USE_EZORGB","USE_EZOPMP","USE_AS608",
- "USE_SHELLY_DIMMER","","","",
+ "USE_SHELLY_DIMMER","USE_RC522","","",
"","","","",
"","","","",
"","","","",
@@ -271,7 +271,7 @@ else:
obj = json.load(fp)
def StartDecode():
- print ("\n*** decode-status.py v20201129 by Theo Arends and Jacek Ziolkowski ***")
+ print ("\n*** decode-status.py v20201130 by Theo Arends and Jacek Ziolkowski ***")
# print("Decoding\n{}".format(obj))