Refactor wiegand rfid reader

This commit is contained in:
Theo Arends 2021-01-21 16:12:44 +01:00
parent 195a7754c6
commit 4de6648cd7
2 changed files with 77 additions and 81 deletions

View File

@ -156,6 +156,7 @@
#define D_JSON_SERIALRECEIVED "SerialReceived" #define D_JSON_SERIALRECEIVED "SerialReceived"
#define D_JSON_SET "Set" #define D_JSON_SET "Set"
#define D_JSON_SIGNAL "Signal" #define D_JSON_SIGNAL "Signal"
#define D_JSON_SIZE "Size"
#define D_JSON_SPEED "Speed" #define D_JSON_SPEED "Speed"
#define D_JSON_SPEED_UNIT "SpeedUnit" #define D_JSON_SPEED_UNIT "SpeedUnit"
#define D_JSON_SSID "SSId" #define D_JSON_SSID "SSId"
@ -180,6 +181,7 @@
#define D_JSON_TOTAL_START_TIME "TotalStartTime" #define D_JSON_TOTAL_START_TIME "TotalStartTime"
#define D_JSON_TVOC "TVOC" #define D_JSON_TVOC "TVOC"
#define D_JSON_TYPE "Type" #define D_JSON_TYPE "Type"
#define D_JSON_UID "UID"
#define D_JSON_UPTIME "Uptime" #define D_JSON_UPTIME "Uptime"
#define D_JSON_UTC_TIME "UTC" #define D_JSON_UTC_TIME "UTC"
#define D_JSON_UV_INDEX "UvIndex" #define D_JSON_UV_INDEX "UvIndex"

View File

@ -21,27 +21,31 @@
/*********************************************************************************************\ /*********************************************************************************************\
* Wiegand 24, 26, 32, 34 bit Rfid reader 125 kHz * Wiegand 24, 26, 32, 34 bit Rfid reader 125 kHz
* *
* Wire connections: * Wire connections for https://www.benselectronics.nl/wiegand-2634-bit-rfid-reader-125khze248d29925d602d.html
* Red Vdc * Red Vdc
* Black Gnd * Black Gnd
* Green D0 * Green D0
* White D1 * White D1
* Yellow Buzzer * Yellow/Grey Sound Buzzer if connected to Gnd
* Blue Led * Blue Light Led if connected to Gnd
* Grey 34-bit if connected to Gnd * Grey/Purple 34-bit if connected to Gnd
* *
* MQTT: * MQTT:
* %prefix%/%topic%/SENSOR = {"Time":"2021-01-13T12:30:38","Wiegand":{"UID":"rfid tag"}} * %prefix%/%topic%/SENSOR = {"Time":"2021-01-21T16:04:12","Wiegand":{"UID":7748328,"Size":26}}
* %prefix%/%topic%/SENSOR = {"Time":"2021-01-21T15:48:49","Wiegand":{"UID":4302741608,"Size":34}}
*
* Rule:
* on wiegand#uid=4302741608 do publish cmnd/ailight/power 2 endon
\*********************************************************************************************/ \*********************************************************************************************/
#warning **** Wiegand interface enabled **** #warning **** Wiegand interface enabled ****
#define XSNS_82 82 #define XSNS_82 82
#define WIEGAND_BIT_TIMEOUT 25 //time to be wait after last bit detected. #define WIEGAND_BIT_TIMEOUT 25 // Time in mSec to be wait after last bit detected.
// Use only a randomly generate RFID for testing. using #define will save some space in the final code // Use only a randomly generate RFID for testing. using #define will save some space in the final code
// DEV_WIEGAND_TEST_MODE 1 : testing with random rfid without hardware connected, but GPIOs set correctly // DEV_WIEGAND_TEST_MODE 1 : testing with random rfid without hardware connected, but GPIOs set correctly
// DEV_WIEGAND_TEST_MODE 2 : testing with hardware corretly connected. // DEV_WIEGAND_TEST_MODE 2 : testing with hardware correctly connected.
#define DEV_WIEGAND_TEST_MODE 0 #define DEV_WIEGAND_TEST_MODE 0
#ifdef DEV_WIEGAND_TEST_MODE #ifdef DEV_WIEGAND_TEST_MODE
@ -63,7 +67,10 @@ class Wiegand {
void ScanForTag(void); void ScanForTag(void);
#ifdef USE_WEBSERVER #ifdef USE_WEBSERVER
void Show(void); void Show(void);
#endif #endif // USE_WEBSERVER
bool isInit = false;
uint8_t scanDelay;
private: private:
@ -82,15 +89,13 @@ class Wiegand {
static volatile uint16_t bitCount; static volatile uint16_t bitCount;
static volatile uint32_t lastFoundTime; static volatile uint32_t lastFoundTime;
static volatile uint8_t timeOut; static volatile uint8_t timeOut;
bool isInit = false;
#if (DEV_WIEGAND_TEST_MODE)==1 #if (DEV_WIEGAND_TEST_MODE)==1
uint64_t GetRandomRfid(uint8_t); uint64_t GetRandomRfid(uint8_t);
#endif #endif // DEV_WIEGAND_TEST_MODE==1
}; };
Wiegand* oWiegand = new Wiegand(); Wiegand* oWiegand = new Wiegand();
uint8_t scanDelay;
volatile uint64_t Wiegand::rfidBuffer; volatile uint64_t Wiegand::rfidBuffer;
volatile uint16_t Wiegand::bitCount; volatile uint16_t Wiegand::bitCount;
@ -105,6 +110,7 @@ Wiegand::Wiegand() {
bitCount = 0 ; bitCount = 0 ;
timeOut = 0; timeOut = 0;
isInit = false; isInit = false;
scanDelay = 1;
} }
#if (DEV_WIEGAND_TEST_MODE)==1 #if (DEV_WIEGAND_TEST_MODE)==1
@ -157,7 +163,7 @@ uint64_t Wiegand::GetRandomRfid(uint8_t tag_size=34) {
return result; return result;
} }
#endif #endif // DEV_WIEGAND_TEST_MODE==1
void ICACHE_RAM_ATTR Wiegand::handleD1Interrupt() { // Receive a 1 bit. (D0=high & D1=low) void ICACHE_RAM_ATTR Wiegand::handleD1Interrupt() { // Receive a 1 bit. (D0=high & D1=low)
rfidBuffer = (rfidBuffer << 1) | 1; // Leftshift + 1 bit rfidBuffer = (rfidBuffer << 1) | 1; // Leftshift + 1 bit
@ -173,28 +179,26 @@ void ICACHE_RAM_ATTR Wiegand::handleD0Interrupt() { // Receive a 0 bit. (D0=low
void Wiegand::Init() { void Wiegand::Init() {
isInit = false; isInit = false;
if (PinUsed(GPIO_WIEGAND_D0) && PinUsed(GPIO_WIEGAND_D1)) { // Only start, if the Wiegang pins are if (PinUsed(GPIO_WIEGAND_D0) && PinUsed(GPIO_WIEGAND_D1)) { // Only start, if the Wiegang pins are selected
#if (DEV_WIEGAND_TEST_MODE)>0 #if (DEV_WIEGAND_TEST_MODE)>0
AddLog_P(LOG_LEVEL_INFO, PSTR("WIE: Init()")); AddLog_P(LOG_LEVEL_INFO, PSTR("WIE: Init()"));
#endif #endif // DEV_WIEGAND_TEST_MODE>0
pinMode(Pin(GPIO_WIEGAND_D0), INPUT_PULLUP); pinMode(Pin(GPIO_WIEGAND_D0), INPUT_PULLUP);
pinMode(Pin(GPIO_WIEGAND_D1), INPUT_PULLUP); pinMode(Pin(GPIO_WIEGAND_D1), INPUT_PULLUP);
attachInterrupt(Pin(GPIO_WIEGAND_D0), handleD0Interrupt, FALLING); attachInterrupt(Pin(GPIO_WIEGAND_D0), handleD0Interrupt, FALLING);
attachInterrupt(Pin(GPIO_WIEGAND_D1), handleD1Interrupt, FALLING); attachInterrupt(Pin(GPIO_WIEGAND_D1), handleD1Interrupt, FALLING);
isInit = true; // Helps to run only if correctly setup isInit = true; // Helps to run only if correctly setup
#if (DEV_WIEGAND_TEST_MODE)>0 #if (DEV_WIEGAND_TEST_MODE)>0
AddLog_P(LOG_LEVEL_INFO, PSTR("WIE: Testmode")); // For tests without reader attaiched AddLog_P(LOG_LEVEL_INFO, PSTR("WIE: Testmode, D0:%u, D1:%u"), Pin(GPIO_WIEGAND_D0), Pin(GPIO_WIEGAND_D1)); // For tests without reader attaiched
AddLog_P(LOG_LEVEL_INFO, PSTR("WIE: D0:%u"),Pin(GPIO_WIEGAND_D0));
AddLog_P(LOG_LEVEL_INFO, PSTR("WIE: D1:%u"),Pin(GPIO_WIEGAND_D1));
#else #else
AddLog_P(LOG_LEVEL_INFO, PSTR("WIE: D0=%u, D1=%u"),Pin(GPIO_WIEGAND_D0), Pin(GPIO_WIEGAND_D1)); AddLog_P(LOG_LEVEL_INFO, PSTR("WIE: Wiegand Rfid Reader detected"));
#endif #endif // DEV_WIEGAND_TEST_MODE>0
} }
#if (DEV_WIEGAND_TEST_MODE)>0 #if (DEV_WIEGAND_TEST_MODE)>0
else { else {
AddLog_P(LOG_LEVEL_INFO, PSTR("WIE: no GPIOs.")); AddLog_P(LOG_LEVEL_INFO, PSTR("WIE: no GPIOs."));
} }
#endif #endif // DEV_WIEGAND_TEST_MODE>0
} }
uint64_t Wiegand::CheckAndConvertRfid(uint64_t rfidIn, uint16_t bitcount) { uint64_t Wiegand::CheckAndConvertRfid(uint64_t rfidIn, uint16_t bitcount) {
@ -225,17 +229,17 @@ uint64_t Wiegand::CheckAndConvertRfid(uint64_t rfidIn, uint16_t bitcount) {
default: default:
break; break;
} }
calcParity = CalculateParities(rfidIn, bitCount); // check result on http://www.ccdesignworks.com/wiegand_calc.htm with raw tag as input calcParity = CalculateParities(rfidIn, bitCount); // Check result on http://www.ccdesignworks.com/wiegand_calc.htm with raw tag as input
if (calcParity != (evenParityBit | oddParityBit)) { // Parity bit is wrong if (calcParity != (evenParityBit | oddParityBit)) { // Parity bit is wrong
rfidIn=0; rfidIn=0;
AddLog_P(LOG_LEVEL_INFO, PSTR("WIE: %llu parity error"), rfidIn); AddLog_P(LOG_LEVEL_DEBUG, PSTR("WIE: %llu parity error"), rfidIn);
} }
#if (DEV_WIEGAND_TEST_MODE)>0 #if (DEV_WIEGAND_TEST_MODE)>0
AddLog_P(LOG_LEVEL_INFO, PSTR("WIE: even (left) parity: %u "), (evenParityBit>>7)); AddLog_P(LOG_LEVEL_INFO, PSTR("WIE: even (left) parity: %u "), (evenParityBit>>7));
AddLog_P(LOG_LEVEL_INFO, PSTR("WIE: even (calc) parity: %u "), (calcParity & 0x80)>>7); AddLog_P(LOG_LEVEL_INFO, PSTR("WIE: even (calc) parity: %u "), (calcParity & 0x80)>>7);
AddLog_P(LOG_LEVEL_INFO, PSTR("WIE: odd (right) parity: %u "), oddParityBit); AddLog_P(LOG_LEVEL_INFO, PSTR("WIE: odd (right) parity: %u "), oddParityBit);
AddLog_P(LOG_LEVEL_INFO, PSTR("WIE: odd (calc) parity: %u "), (calcParity & 0x01)); AddLog_P(LOG_LEVEL_INFO, PSTR("WIE: odd (calc) parity: %u "), (calcParity & 0x01));
#endif #endif // DEV_WIEGAND_TEST_MODE>0
return rfidIn; return rfidIn;
} }
@ -292,21 +296,17 @@ bool Wiegand::WiegandConversion () {
if (diffTicks > WIEGAND_BIT_TIMEOUT) { // Last bit found is WIEGAND_BIT_TIMEOUT ms ago if (diffTicks > WIEGAND_BIT_TIMEOUT) { // Last bit found is WIEGAND_BIT_TIMEOUT ms ago
#if (DEV_WIEGAND_TEST_MODE)>0 #if (DEV_WIEGAND_TEST_MODE)>0
AddLog_P(LOG_LEVEL_INFO, PSTR("WIE: Raw tag %llu, Bit count %u"), rfidBuffer, bitCount); AddLog_P(LOG_LEVEL_INFO, PSTR("WIE: Raw tag %llu, Bit count %u"), rfidBuffer, bitCount);
#endif #endif // DEV_WIEGAND_TEST_MODE>0
if ((24 == bitCount) || (26 == bitCount) || (32 == bitCount) || (34 == bitCount)) { if ((24 == bitCount) || (26 == bitCount) || (32 == bitCount) || (34 == bitCount)) {
// 24, 26, 32, 34-bit Wiegand codes // 24, 26, 32, 34-bit Wiegand codes
rfid = CheckAndConvertRfid(rfidBuffer, bitCount); rfid = CheckAndConvertRfid(rfidBuffer, bitCount);
tagSize = bitCount; tagSize = bitCount;
bitCount = 0;
rfidBuffer = 0;
bRet = true; bRet = true;
} }
else if (4 == bitCount) { else if (4 == bitCount) {
// 4-bit Wiegand codes for keypads // 4-bit Wiegand codes for keypads
rfid = (int)translateEnterEscapeKeyPress(rfidBuffer & 0x0000000F); rfid = (int)translateEnterEscapeKeyPress(rfidBuffer & 0x0000000F);
tagSize = bitCount; tagSize = bitCount;
bitCount = 0;
rfidBuffer = 0;
bRet = true; bRet = true;
} }
else if (8 == bitCount) { else if (8 == bitCount) {
@ -323,26 +323,23 @@ bool Wiegand::WiegandConversion () {
bRet = false; bRet = false;
} }
tagSize = bitCount; tagSize = bitCount;
bitCount = 0;
rfidBuffer = 0;
} else { } else {
// Time reached but unknown bitCount, clear and start again // Time reached but unknown bitCount, clear and start again
lastFoundTime = nowTick; lastFoundTime = nowTick;
bitCount = 0;
rfidBuffer = 0;
bRet = false; bRet = false;
} }
bitCount = 0;
rfidBuffer = 0;
} else { } else {
bRet = false; // watching time not finished bRet = false; // Watching time not finished
} }
#if (DEV_WIEGAND_TEST_MODE)>0 #if (DEV_WIEGAND_TEST_MODE)>0
AddLog_P(LOG_LEVEL_INFO, PSTR("WIE: tag out %llu, tag size %u "), rfid, tagSize); AddLog_P(LOG_LEVEL_INFO, PSTR("WIE: Tag out %llu, tag size %u "), rfid, tagSize);
#endif #endif // DEV_WIEGAND_TEST_MODE>0
return bRet; return bRet;
} }
void Wiegand::ScanForTag() { void Wiegand::ScanForTag() {
if (!isInit) { return;}
#if (DEV_WIEGAND_TEST_MODE)>0 #if (DEV_WIEGAND_TEST_MODE)>0
AddLog_P(LOG_LEVEL_INFO, PSTR("WIE: ScanForTag().")); AddLog_P(LOG_LEVEL_INFO, PSTR("WIE: ScanForTag()."));
#if (DEV_WIEGAND_TEST_MODE==1) #if (DEV_WIEGAND_TEST_MODE==1)
@ -363,21 +360,20 @@ void Wiegand::ScanForTag() {
rfidBuffer = GetRandomRfid(34); rfidBuffer = GetRandomRfid(34);
break; break;
} }
AddLog_P(LOG_LEVEL_INFO, PSTR("WIE: raw generated: %lX"), rfidBuffer); // for tests without reader attaiched AddLog_P(LOG_LEVEL_INFO, PSTR("WIE: Raw generated %lX"), rfidBuffer); // For tests without reader attaiched
#endif #endif // DEV_WIEGAND_TEST_MODE==1
#endif #endif // DEV_WIEGAND_TEST_MODE>0
if (bitCount > 0) { if (bitCount > 0) {
uint64_t oldTag = rfid; uint64_t oldTag = rfid;
bool validKey = WiegandConversion(); bool validKey = WiegandConversion();
#if (DEV_WIEGAND_TEST_MODE)>0 #if (DEV_WIEGAND_TEST_MODE)>0
AddLog_P(LOG_LEVEL_INFO, PSTR("WIE: previous tag: %llu"), oldTag); AddLog_P(LOG_LEVEL_INFO, PSTR("WIE: Previous tag %llu"), oldTag);
#endif #endif // DEV_WIEGAND_TEST_MODE>0
// only in case of valid key do action. Issue#10585 if (validKey) { // Only in case of valid key do action. Issue#10585
if (validKey) { if (oldTag == rfid) {
if (oldTag != rfid) { AddLog_P(LOG_LEVEL_INFO, PSTR("WIE: new= %llu"), rfid); } AddLog_P(LOG_LEVEL_DEBUG, PSTR("WIE: Old tag"));
else { AddLog_P(LOG_LEVEL_INFO, PSTR("WIE: prev= %llu"), rfid); } }
AddLog_P(LOG_LEVEL_INFO, PSTR("WIE: bits= %u"), tagSize); ResponseTime_P(PSTR(",\"Wiegand\":{\"UID\":%0llu,\"" D_JSON_SIZE "\":%u}}"), rfid, tagSize);
ResponseTime_P(PSTR(",\"Wiegand\":{\"UID\":\"%0llu\"}}"), rfid);
MqttPublishTeleSensor(); MqttPublishTeleSensor();
} }
} }
@ -385,12 +381,10 @@ void Wiegand::ScanForTag() {
#ifdef USE_WEBSERVER #ifdef USE_WEBSERVER
void Wiegand::Show(void) { void Wiegand::Show(void) {
if (!isInit) { return; }
WSContentSend_PD(PSTR("{s}Wiegand UID{m}%llu {e}"), rfid); WSContentSend_PD(PSTR("{s}Wiegand UID{m}%llu {e}"), rfid);
#if (DEV_WIEGAND_TEST_MODE)>0 #if (DEV_WIEGAND_TEST_MODE)>0
AddLog_P(LOG_LEVEL_INFO,PSTR("WIE: Tag: %llu"), rfid); AddLog_P(LOG_LEVEL_INFO, PSTR("WIE: Tag %llu, Bits %u"), rfid, bitCount);
AddLog_P(LOG_LEVEL_INFO, PSTR("WIE: %u bits"), bitCount); #endif // DEV_WIEGAND_TEST_MODE>0
#endif
} }
#endif // USE_WEBSERVER #endif // USE_WEBSERVER
@ -401,23 +395,22 @@ void Wiegand::Show(void) {
bool Xsns82(byte function) { bool Xsns82(byte function) {
bool result = false; bool result = false;
switch (function) { if (FUNC_INIT == function) {
case FUNC_INIT:
oWiegand->Init(); oWiegand->Init();
scanDelay = 1; }
break; else if (oWiegand->isInit) {
switch (function) {
case FUNC_EVERY_250_MSECOND: // Some tags need more time, don't try shorter period case FUNC_EVERY_250_MSECOND: // Some tags need more time, don't try shorter period
#if (DEV_WIEGAND_TEST_MODE)==1 #if (DEV_WIEGAND_TEST_MODE)==1
if (scanDelay >= 4) // Give a second because of the log entries to be send. if (oWiegand->scanDelay >= 4) // Give a second because of the log entries to be send.
#else #else
if (scanDelay >= 2) // Only run every (delay * 250 ms) (every 250ms is too fast for some tags) if (oWiegand->scanDelay >= 2) // Only run every (delay * 250 ms) (every 250ms is too fast for some tags)
#endif #endif
{ {
oWiegand->ScanForTag(); oWiegand->ScanForTag();
scanDelay = 1; oWiegand->scanDelay = 1;
} else { } else {
scanDelay++; oWiegand->scanDelay++;
} }
break; break;
#ifdef USE_WEBSERVER #ifdef USE_WEBSERVER
@ -426,6 +419,7 @@ bool Xsns82(byte function) {
break; break;
#endif // USE_WEBSERVER #endif // USE_WEBSERVER
} }
}
return result; return result;
} }