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))