diff --git a/tasmota/xsns_51_rdm6300.ino b/tasmota/xsns_51_rdm6300.ino
index de2714cb2..ebc9ab175 100644
--- a/tasmota/xsns_51_rdm6300.ino
+++ b/tasmota/xsns_51_rdm6300.ino
@@ -1,5 +1,5 @@
/*
- xsns_51_rdm6300.ino - Support for RDM6300 NFC Tag Reader on Tasmota
+ xsns_51_rdm6300.ino - Support for RDM630(0) 125kHz NFC Tag Reader on Tasmota
Copyright (C) 2020 Gerhard Mutz and Theo Arends
@@ -17,136 +17,127 @@
along with this program. If not, see .
*/
-
#ifdef USE_RDM6300
+/*********************************************************************************************\
+ * Seeed studio Grove / RDM630 / RDM6300 125kHz rfid reader
+ *
+ * Expected 14 byte data:
+ * 0 1 2 3 4 5 6 7 8 9 10 11 12 13
+ * Hd ------ ASCII characters ----- Chksm Tl
+ * 02 31 34 30 30 38 45 43 37 39 33 43 45 03 = 02-14-008EC793-CE-03
+ * Versn --------- Tag ---------
+\*********************************************************************************************/
-#define XSNS_51 51
+#define XSNS_51 51
-#define RDM6300_BAUDRATE 9600
+#define RDM6300_BAUDRATE 9600
+#define RDM_TIMEOUT 100
+#define RDM6300_BLOCK 2 * 10 // 2 seconds block time
#include
+TasmotaSerial *RDM6300Serial = nullptr;
-#define RDM_TIMEOUT 100
-char rdm_uid_str[10];
+struct {
+ uint32_t uid = 0;
+ uint8_t block_time = 0;
+} Rdm;
-// 2 seconds block time
-#define RDM6300_BLOCK 2*10
+/********************************************************************************************/
-uint8_t rdm_blcnt;
-TasmotaSerial *RDM6300_Serial = nullptr;
+uint8_t RDM6300HexNibble(char chr) {
+ uint8_t rVal = 0;
+ if (isdigit(chr)) { rVal = chr - '0'; }
+ else if (chr >= 'A' && chr <= 'F') { rVal = chr + 10 - 'A'; }
+ else if (chr >= 'a' && chr <= 'f') { rVal = chr + 10 - 'a'; }
+ return rVal;
+}
-void RDM6300_Init() {
+// Convert hex string to int array
+void RDM6300HexStringToArray(uint8_t array[], uint8_t len, char buffer[]) {
+ char *cp = buffer;
+ for (uint32_t i = 0; i < len; i++) {
+ uint8_t val = RDM6300HexNibble(*cp++) << 4;
+ array[i] = val | RDM6300HexNibble(*cp++);
+ }
+}
+
+/********************************************************************************************/
+
+void RDM6300Init() {
if (PinUsed(GPIO_RDM6300_RX)) {
- RDM6300_Serial = new TasmotaSerial(Pin(GPIO_RDM6300_RX),-1,1);
- if (RDM6300_Serial->begin(RDM6300_BAUDRATE)) {
- if (RDM6300_Serial->hardwareSerial()) {
+ RDM6300Serial = new TasmotaSerial(Pin(GPIO_RDM6300_RX), -1, 1);
+ if (RDM6300Serial->begin(RDM6300_BAUDRATE)) {
+ if (RDM6300Serial->hardwareSerial()) {
ClaimSerial();
}
}
}
- rdm_blcnt=0;
}
-// 14 bytes payload; // RFID DATA FRAME FORMAT: 1byte head (value: 2), 10byte data (2byte version + 8byte tag), 2byte checksum, 1byte tail (value: 3)
-void RDM6300_ScanForTag() {
- char rdm_buffer[14];
- uint8_t rdm_index;
- uint8_t rdm_array[6];
+void RDM6300ScanForTag() {
+ if (!RDM6300Serial) { return; }
- if (!RDM6300_Serial) return;
-
- if (rdm_blcnt>0) {
- rdm_blcnt--;
- while (RDM6300_Serial->available()) RDM6300_Serial->read();
+ if (Rdm.block_time > 0) {
+ Rdm.block_time--;
+ while (RDM6300Serial->available()) {
+ RDM6300Serial->read(); // Flush serial buffer
+ }
return;
}
- if (RDM6300_Serial->available()) {
+ if (RDM6300Serial->available()) {
+
+ char c = RDM6300Serial->read();
+ if (c != 2) { return; } // Head marker
- char c=RDM6300_Serial->read();
- if (c!=2) return;
- // head detected
// read rest of message 11 more bytes
- rdm_index=0;
- uint32_t cmillis=millis();
+ char rdm_buffer[14];
+ uint8_t rdm_index = 0;
+
+ rdm_buffer[rdm_index++] = c;
+
+ uint32_t cmillis = millis();
while (1) {
- if (RDM6300_Serial->available()) {
- char c=RDM6300_Serial->read();
- if (c==3) {
- // tail marker
- break;
- }
- rdm_buffer[rdm_index++]=c;
- if (rdm_index>13) {
- // illegal message
- return;
- }
+ if (RDM6300Serial->available()) {
+ c = RDM6300Serial->read();
+ rdm_buffer[rdm_index++] = c;
+
+ if (3 == c) { break; } // Tail marker
+ if (rdm_index > 14) { break; } // Illegal message
}
- if ((millis()-cmillis)>RDM_TIMEOUT) {
- // timeout
- return;
+ if ((millis() - cmillis) > RDM_TIMEOUT) {
+ return; // Timeout
}
}
- // block for 2 seconds
- rdm_blcnt=RDM6300_BLOCK;
+ AddLogBuffer(LOG_LEVEL_DEBUG, (uint8_t*)rdm_buffer, sizeof(rdm_buffer));
- // calc checksum,
- rm6300_hstring_to_array(rdm_array,sizeof(rdm_array),rdm_buffer);
- uint8_t accu=0;
- for (uint8_t count=0;count<5;count++) {
- accu^=rdm_array[count];
+ if (rdm_buffer[13] != 3) { return; } // Tail marker
+
+ Rdm.block_time = RDM6300_BLOCK; // Block for 2 seconds
+
+ uint8_t rdm_array[6];
+ RDM6300HexStringToArray(rdm_array, sizeof(rdm_array), (char*)rdm_buffer +1);
+ uint8_t accu = 0;
+ for (uint32_t count = 0; count < 5; count++) {
+ accu ^= rdm_array[count]; // Calc checksum,
}
- if (accu!=rdm_array[5]) {
- // checksum error
- return;
+ if (accu != rdm_array[5]) { return; } // Checksum error
+
+ rdm_buffer[11] = '\0';
+ uint32_t uid = strtoul(rdm_buffer +3, nullptr, 16);
+ if (uid > 0) { // Ignore false positive all zeros
+ Rdm.uid = uid;
+ ResponseTime_P(PSTR(",\"RDM6300\":{\"UID\":\"%08X\"}}"), Rdm.uid);
+ MqttPublishTeleSensor();
}
-
- // copy 4 hex bytes
- memcpy(rdm_uid_str,&rdm_buffer[2],8);
- rdm_uid_str[9]=0;
-
- ResponseTime_P(PSTR(",\"RDM6300\":{\"UID\":\"%s\"}}"), rdm_uid_str);
- MqttPublishTeleSensor();
-/*
- char command[24];
- sprintf(command,"event RDM6300=%s",rdm_uid_str);
- ExecuteCommand(command, SRC_RULE);
- */
- }
-
-
-}
-
-uint8_t rm6300_hexnibble(char chr) {
- uint8_t rVal = 0;
- if (isdigit(chr)) {
- rVal = chr - '0';
- } else {
- if (chr >= 'A' && chr <= 'F') rVal = chr + 10 - 'A';
- if (chr >= 'a' && chr <= 'f') rVal = chr + 10 - 'a';
- }
- return rVal;
-}
-
-// convert hex string to int array
-void rm6300_hstring_to_array(uint8_t array[], uint8_t len, char buffer[])
-{
- char *cp=buffer;
- for (uint8_t i = 0; i < len; i++) {
- uint8_t val = rm6300_hexnibble(*cp++) << 4;
- array[i]= val | rm6300_hexnibble(*cp++);
}
}
#ifdef USE_WEBSERVER
-const char HTTP_RDM6300[] PROGMEM =
- "{s}RDM6300 " "UID" "{m}%s" "{e}";
-
-void RDM6300_Show(void) {
- if (!RDM6300_Serial) return;
- if (!rdm_uid_str[0]) strcpy(rdm_uid_str,"????");
- WSContentSend_PD(HTTP_RDM6300,rdm_uid_str);
+void RDM6300Show(void) {
+ if (!RDM6300Serial) { return; }
+ WSContentSend_PD(PSTR("{s}RDM6300 UID{m}%08X {e}"), Rdm.uid);
}
#endif // USE_WEBSERVER
@@ -154,24 +145,23 @@ void RDM6300_Show(void) {
* Interface
\*********************************************************************************************/
-bool Xsns51(byte function)
-{
+bool Xsns51(byte function) {
bool result = false;
- switch (function) {
- case FUNC_INIT:
- RDM6300_Init();
- break;
- case FUNC_EVERY_100_MSECOND:
- RDM6300_ScanForTag();
- break;
+ switch (function) {
+ case FUNC_INIT:
+ RDM6300Init();
+ break;
+ case FUNC_EVERY_100_MSECOND:
+ RDM6300ScanForTag();
+ break;
#ifdef USE_WEBSERVER
- case FUNC_WEB_SENSOR:
- RDM6300_Show();
- break;
+ case FUNC_WEB_SENSOR:
+ RDM6300Show();
+ break;
#endif // USE_WEBSERVER
- }
- return result;
+ }
+ return result;
}
#endif // USE_RDM6300