Giter VIP home page Giter VIP logo

wiegand26's Introduction

Wiegand26

Receiving data from Wiegand26 card readers.

Image of Wiegand26

Card readers with Wiegand26 protocol are sending only first 3 Bytes from the card Serial number (first 16 Byte block for UID0-UID3 / MANUFACTURER).

Library is made for Arduino IDE and for Arduinos, ESP32 and ESP8266.

Features

  • Service is "waiting on backgroud" and it's fired by interupts
  • Data and Status are served by event (callback) function, it's not required function at loop
  • Key is formated as 1Byte number (unsigned short int / Byte)
  • Code and Data is formated as 3Byte number (unsigned long)
  • Status id formated as 1Byte number (unsigned short int / Byte)
  • Status data can be triggered manually

Change log

  • 1.0.0 - Initial release
  • 1.1.0 - Swapping read Bytes of serial number for correct show
  • 1.2.0 - Swapping readed Bytes is optional (non-swap data (125kH readers), swap data (some 13.56MHz readers))
  • 2.0.0 - Support for Wiegand keyboard with 8bits protocol

Using

Define

Include library, define status report and pins.

#include <Wiegand26.h>                            // Wiegand RFID

// Status report defines
#define       INICIALIZE      0
#define       DATA_SENDED     1
#define       CONNECTION      2
#define       LOGIC_FAULT     3
#define       RCV_TIMEOUT     4
#define       BITS_FAULTS     5
#define       PARITY_FRST     6
#define       PARITY_SCND     7

// Inicialize Wiegand26
Wiegand26 wiegand;
#define       wiegandD0       27                  // Pin for Data 0
#define       wiegandD1       26                  // Pin for Data 1

Setup

Setup pins and library.

void setup()
{

  // Serial line
  Serial.begin (115200, SERIAL_8N1);
  Serial.setTimeout (15);
  delay (1000);

  // Wiegand RFID
  wiegand.onKey (wiegandKey);                     // Function for handle with key
  wiegand.onCode (wiegandCode);                   // Function for handle with code
  wiegand.onData (wiegandData);                   // Function for handle with data
  wiegand.onState (wiegandState);                 // Function for handle with status
  wiegand.begin(wiegandD0, wiegandD1, true, false);
  //            Data0      Data1      false == Send state only on change
  //                                  true  == Send state on each data reading
  //                                        false == non-swap data (125kH readers)
  //                                        true  == swap data (some 13.56MHz readers)

  // Interrupt for Wiegand data pin
  attachInterrupt(digitalPinToInterrupt(wiegandD0), wiegandPinChanged, FALLING);
  attachInterrupt(digitalPinToInterrupt(wiegandD1), wiegandPinChanged, FALLING);

}

Supporting functions

Supporting function for reading pins, print status and data.

// Function for reading Wiegand data
void wiegandPinChanged () {
  wiegand.readData ();
}

// Print received Wiegand state
void wiegandState (uint8_t state) {
  if (bitRead (state, INICIALIZE)) {
    Serial.println ("Wiegand26 - Inicialized");
  }
  if (bitRead (state, DATA_SENDED)) {
    Serial.println ("Wiegand26 - Data sended");
  }
  if (bitRead (state, CONNECTION)) {
    Serial.println ("Wiegand26 - Disconnected");
  }
  if (bitRead (state, LOGIC_FAULT)) {
    Serial.println ("Wiegand26 - Wiring problem");
  }
  if (bitRead (state, RCV_TIMEOUT)) {
    Serial.println ("Wiegand26 - Time Out");
  }
  if (bitRead (state, BITS_FAULTS)) {
    Serial.println ("Wiegand26 - Buffer size fault");
  }
  if (bitRead (state, PARITY_FRST)) {
    Serial.println ("Wiegand26 - First parity fault");
  }
  if (bitRead (state, PARITY_SCND)) {
    Serial.println ("Wiegand26 - Second parity fault");
  }
  
}

// Print received Wiegand key
void wiegandKey (uint8_t value) {

  Serial.print ("Wiegand26 - Key: 0x");
  Serial.println (value, HEX);

  Serial.print ("Wiegand26 - Key: 0b");
  Serial.println (value, BIN);

  Serial.print ("Wiegand26 - Key: ");
  Serial.println (value, DEC);

  Serial.println ();

}

// Print received Wiegand code
void wiegandCode (unsigned long value) {

  Serial.print ("Wiegand26 - Code: 0x");
  Serial.println (value, HEX);

  Serial.print ("Wiegand26 - Code: 0b");
  Serial.println (value, BIN);

  Serial.print ("Wiegand26 - Code: ");
  Serial.println (value, DEC);

  Serial.println ();
}

// Print received Wiegand data
void wiegandData (unsigned long value) {

  Serial.print ("Wiegand26 - Data: 0x");
  Serial.println (value, HEX);

  Serial.print ("Wiegand26 - Data: 0b");
  Serial.println (value, BIN);

  Serial.print ("Wiegand26 - Data: ");
  Serial.println (value, DEC);

  Serial.println ();
}

Main loog

If manually invoking status is required.

void loop() {
  
  // Manually invoke Wiegand state
  // wiegand.readState ();
  
  delay (250);

}

Example

./examples/wiegand26/wiegand26.ino

Wiegand

The Wiegand interface is a de facto wiring standard which arose from the popularity of Wiegand effect card readers in the 1980s. It is commonly used to connect a card swipe mechanism to the rest of an access control system. The sensor in such a system is often a "Wiegand wire", based on the Wiegand effect, discovered by John R. Wiegand. A Wiegand-compatible reader is normally connected to a Wiegand-compatible security panel.

Physical layer

The Wiegand interface uses three wires, one of which is a common ground and two of which are data transmission wires usually called DATA0 and DATA1, alternately labeled "D0" and "D1" or "Data Low" and "Data High". When no data is being sent, both DATA0 and DATA1 are pulled up to the "high" voltage level — usually +5 VDC. When a 0 is sent the DATA0 wire is pulled to a low voltage while the DATA1 wire stays at a high voltage. When a 1 is sent the DATA1 wire is pulled to a low voltage while DATA0 stays at a high voltage.

Wiegand26 Data Logic

Pulse for valid data is around 100 µs long.

Wiegand26 Data Pulse

Gap between pulses is around 1ms.

Wiegand26 Gap delay

The high signaling level of 5 VDC is used to accommodate long cable runs from card readers to the associated access control panel, typically located in a secure closet. Most card reader manufacturers publish a maximum cable run of 500 feet (150 m). An advantage of the Wiegand signaling format is that it allows very long cable runs, far longer than other interface standards of its day allowed.

Protocol

The communications protocol used on a Wiegand interface is known as the Wiegand protocol. The original Wiegand format had one parity bit, 8 bits of facility code, 16 bits of ID code, and a trailing parity bit for a total of 26 bits. The first parity bit is calculated from the first 12 bits of the code and the trailing parity bit from the last 12 bits. However, many inconsistent implementations and extensions to the basic format exist.

Many access control system manufacturers adopted Wiegand technology, but were unhappy with the limitations of only 8 bits for site codes (0-255) and 16 bits for card numbers (0-65535), so they designed their own formats with varying complexity of field numbers and lengths and parity checking.

The physical size limitations of the card dictated that a maximum of 37 Wiegand wire filaments could be placed in a standard credit card, as dictated by CR80 or ISO/IEC 7810 standards, before misreads would affect reliability. Therefore, most Wiegand formats used in physical access control are less than 37 bits in length.

wiegand26's People

Contributors

jvondrus avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

Forkers

nunut

wiegand26's Issues

Guru Meditation error on both cores using ESP32

I am trying to read some Wiegand card using the Bosch ARD-AYK12 - RFID Proximity Reader, but I get the following errors:

rst:0x1 (POWERON_RESET),boot:0x1b (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0030,len:1184
load:0x40078000,len:12784
load:0x40080400,len:3032
entry 0x400805e4
[��mum����2-hal-cpu.c:214] setCpuFrequencyMhz(): PLL: 480 / 2 = 240 Mhz, APB: 80000000 Hz
Wiegand26 - Inicialized
Wiegand26 - Data: 0xE28244
Wiegand26 - Data: 0b111000101000001001000100
Wiegand26 - Data: 14844484

Wiegand26 - Inicialized
WieGuru Meditation Error: Core  1 panic'ed (Interrupt wdt timeout on CPU1). 

Core  1 register dump:
PC      : 0x4008c8c8  PS      : 0x00060d35  A0      : 0x8008bb1a  A1      : 0x3ffbec2c
A2      : 0x3ffb9068  A3      : 0x3ffc68c8  A4      : 0x00000004  A5      : 0x00060d23  
A6      : 0x00060d23  A7      : 0x00000001  A8      : 0x3ffc68c8  A9      : 0x00000019
A10     : 0x3ffc68c8  A11     : 0x00000019  A12     : 0x3ffc380c  A13     : 0x00060d23  
A14     : 0x007beeb8  A15     : 0x003fffff  SAR     : 0x00000009  EXCCAUSE: 0x00000006
EXCVADDR: 0x00000000  LBEG    : 0x4008841d  LEND    : 0x4008842d  LCOUNT  : 0xfffffff9  
Core  1 was running in ISR context:
EPC1    : 0x400e842b  EPC2    : 0x00000000  EPC3    : 0x00000000  EPC4    : 0x00000000


Backtrace:0x4008c8c5:0x3ffbec2c |<-CORRUPTED

  #0  0x4008c8c5:0x3ffbec2c in vListInsert at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/list.c:166 (discriminator 1)


Core  0 register dump:
PC      : 0x4008ca49  PS      : 0x00060035  A0      : 0x8008b743  A1      : 0x3ffbe80c
A2      : 0x3ffbeeb8  A3      : 0xb33fffff  A4      : 0x0000abab  A5      : 0x00060023
A6      : 0x00060021  A7      : 0x0000cdcd  A8      : 0x0000abab  A9      : 0xffffffff
A10     : 0x00000000  A11     : 0x00000000  A12     : 0x3ffc28d8  A13     : 0x00000007
A14     : 0x007beeb8  A15     : 0x003fffff  SAR     : 0x0000001a  EXCCAUSE: 0x00000006  
EXCVADDR: 0x00000000  LBEG    : 0x00000000  LEND    : 0x00000000  LCOUNT  : 0x00000000


Backtrace:0x4008ca46:0x3ffbe80c |<-CORRUPTED

  #0  0x4008ca46:0x3ffbe80c in compare_and_set_native at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/esp_hw_support/include/soc/compare_set.h:25
      (inlined by) spinlock_acquire at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/esp_hw_support/include/soc/spinlock.h:103
      (inlined by) xPortEnterCriticalTimeout at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/port/xtensa/port.c:288




ELF file SHA256: 0000000000000000

Rebooting...

This is the sketch:

/*
 *  Wiegand26 - https://github.com/jvondrus/Wiegand26
 *  by Jiri Vondrus (https://github.com/jvondrus)
 *  Version 1.1.0 06-2020
 */
#include <Arduino.h>
#include <Wiegand26.h> // Wiegand RFID

// Status report defines
#define INICIALIZE 0
#define DATA_SENDED 1
#define CONNECTION 2
#define LOGIC_FAULT 3
#define RCV_TIMEOUT 4
#define BITS_FAULTS 5
#define PARITY_FRST 6
#define PARITY_SCND 7

// Inicialize Wiegand26
Wiegand26 wiegand;

#define wiegandD0 14 // Pin for Data 0
#define wiegandD1 13 // Pin for Data 1

// Function for reading Wiegand data
void wiegandPinChanged()
{
  wiegand.readData();
}

// Print received Wiegand state
void wiegandState(uint8_t state)
{
  if (bitRead(state, INICIALIZE))
  {
    Serial.println("Wiegand26 - Inicialized");
  }
  if (bitRead(state, DATA_SENDED))
  {
    Serial.println("Wiegand26 - Data sended");
  }
  if (bitRead(state, CONNECTION))
  {
    Serial.println("Wiegand26 - Disconnected");
  }
  if (bitRead(state, LOGIC_FAULT))
  {
    Serial.println("Wiegand26 - Wiring problem");
  }
  if (bitRead(state, RCV_TIMEOUT))
  {
    Serial.println("Wiegand26 - Time Out");
  }
  if (bitRead(state, BITS_FAULTS))
  {
    Serial.println("Wiegand26 - Buffer size fault");
  }
  if (bitRead(state, PARITY_FRST))
  {
    Serial.println("Wiegand26 - First parity fault");
  }
  if (bitRead(state, PARITY_SCND))
  {
    Serial.println("Wiegand26 - Second parity fault");
  }
}

// Print received Wiegand key
void wiegandKey(uint8_t value)
{
  Serial.print("Wiegand26 - Key: 0x");
  Serial.println(value, HEX);

  Serial.print("Wiegand26 - Key: 0b");
  Serial.println(value, BIN);

  Serial.print("Wiegand26 - Key: ");
  Serial.println(value, DEC);

  Serial.println();
}

// Print received Wiegand code
void wiegandCode(unsigned long value)
{
  Serial.print("Wiegand26 - Code: 0x");
  Serial.println(value, HEX);

  Serial.print("Wiegand26 - Code: 0b");
  Serial.println(value, BIN);

  Serial.print("Wiegand26 - Code: ");
  Serial.println(value, DEC);

  Serial.println();
}

// Print received Wiegand data
void wiegandData(unsigned long value)
{
  Serial.print("Wiegand26 - Data: 0x");
  Serial.println(value, HEX);

  Serial.print("Wiegand26 - Data: 0b");
  Serial.println(value, BIN);

  Serial.print("Wiegand26 - Data: ");
  Serial.println(value, DEC);

  Serial.println();
}

// Setup
void setup()
{
  // Serial line
  Serial.begin(115200, SERIAL_8N1);
  Serial.setTimeout(15);
  delay(1000);

  // Wiegand RFID
  wiegand.onKey(wiegandKey);
  wiegand.onCode(wiegandCode);
  wiegand.onData(wiegandData);
  wiegand.onState(wiegandState);
  wiegand.begin(wiegandD0, wiegandD1, true, false);
  //            Data0      Data1      false == Send state only on change
  //                                  true  == Send state on each data reading
  //                                        false == non-swap data (125kH readers)
  //                                        true  == swap data (some 13.56MHz readers)

  // Interrupt for Wiegand data pin
  attachInterrupt(digitalPinToInterrupt(wiegandD0), wiegandPinChanged, FALLING);
  attachInterrupt(digitalPinToInterrupt(wiegandD1), wiegandPinChanged, FALLING);
}

// Main loop
void loop()
{

  // Manually invoke Wiegand state
  // wiegand.readState ();

  delay(250);
}

Do you have any ideas ? Do I need to use level shifters ?

Bootloop while testing the example file

Hi, I am trying to get the example working with a Wiegand26 reader. I have D0 connected to P13 and D1 to P12. I am getting a bootloop. Here is the log:

19:36:57.651 -> ets Jun 8 2016 00:22:57
19:36:57.651 ->
19:36:57.651 -> rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
19:36:57.651 -> configsip: 0, SPIWP:0xee
19:36:57.651 -> clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
19:36:57.699 -> mode:DIO, clock div:1
19:36:57.699 -> load:0x3fff0030,len:1184
19:36:57.699 -> load:0x40078000,len:13260
19:36:57.699 -> load:0x40080400,len:3028
19:36:57.699 -> entry 0x400805e4
19:36:58.818 -> Wiegand26 - Inicialized
19:36:58.818 -> Wiegand26 - Disconnected
19:36:58.818 -> Wiegand26 - Inicialized
19:36:58.867 -> Wiegand26 - Disconnected
19:36:58.867 -> Wiegand26 - Wiring problem
19:36:58.867 -> Wiegand2Guru Meditation Error: Core 1 panic'ed (Interrupt wdt timeout on CPU1).
19:36:59.150 ->
19:36:59.150 -> Core 1 register dump:
19:36:59.150 -> PC : 0x4008ab56 PS : 0x00060135 A0 : 0x80089ace A1 : 0x3ffbf06c
19:36:59.150 -> A2 : 0x3ffc57d0 A3 : 0x3ffbce0c A4 : 0x00000004 A5 : 0x00060123
19:36:59.150 -> A6 : 0x00060123 A7 : 0x00000001 A8 : 0x3ffbce0c A9 : 0x00000019
19:36:59.150 -> A10 : 0x3ffbce0c A11 : 0x00000019 A12 : 0x3ffc2334 A13 : 0x00060123
19:36:59.191 -> A14 : 0x007bf2f8 A15 : 0x003fffff SAR : 0x0000000a EXCCAUSE: 0x00000006
19:36:59.191 -> EXCVADDR: 0x00000000 LBEG : 0x400863c9 LEND : 0x400863d9 LCOUNT : 0xfffffff8
19:36:59.191 -> Core 1 was running in ISR context:
19:36:59.191 -> EPC1 : 0x400dab4f EPC2 : 0x00000000 EPC3 : 0x00000000 EPC4 : 0x00000000
19:36:59.191 ->
19:36:59.191 ->
19:36:59.191 -> Backtrace: 0x4008ab53:0x3ffbf06c |<-CORRUPTED
19:36:59.191 ->
19:36:59.191 ->
19:36:59.191 -> Core 0 register dump:
19:36:59.191 -> PC : 0x4008aceb PS : 0x00060035 A0 : 0x800896f7 A1 : 0x3ffbea1c
19:36:59.238 -> A2 : 0x3ffbf2f8 A3 : 0xb33fffff A4 : 0x0000abab A5 : 0x00060023
19:36:59.238 -> A6 : 0x00060021 A7 : 0x0000cdcd A8 : 0x0000abab A9 : 0xffffffff
19:36:59.238 -> A10 : 0x00000000 A11 : 0x00000000 A12 : 0x3ffc214c A13 : 0x00000007
19:36:59.238 -> A14 : 0x007bf2f8 A15 : 0x003fffff SAR : 0x0000001d EXCCAUSE: 0x00000006
19:36:59.238 -> EXCVADDR: 0x00000000 LBEG : 0x00000000 LEND : 0x00000000 LCOUNT : 0x00000000
19:36:59.238 ->
19:36:59.238 ->
19:36:59.238 -> Backtrace: 0x4008ace8:0x3ffbea1c |<-CORRUPTED
19:36:59.238 ->
19:36:59.238 ->
19:36:59.285 ->
19:36:59.285 ->
19:36:59.285 -> ELF file SHA256: 8c79d0b6d79a0e87
19:36:59.285 ->
19:36:59.380 -> Rebooting...

I'd appreciate any help.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.