Click here to Skip to main content
15,881,027 members
Articles / Internet of Things / Arduino

Wieganduino - Generate Wiegand Codes with Arduino

Rate me:
Please Sign up or sign in to vote.
4.85/5 (6 votes)
3 Jul 2018CPOL3 min read 36.9K   1.5K   3   14
Generate 26-bit Wiegand codes with Arduino Nano

Wiegand D0 and D1 wires

The Wiegand data wires D0 and D1.

Introduction

This article shows Wiegand protocol implementation on the Arduino Nano.

The Wiegand Protocol

The Wiegand protocol, albeit elementary, is still widely used by keyboards (and keycard readers) in access control systems. A brief description follows.

The Physical Layer

It is a very simple matter:

  1. There are 3 physical wires, namely D0, D1 and GROUND.
  2. When there is no transmission, both D0 and D1 are tied to +5V.
  3. A logical 0 happens when D0 goes low (0V) while D1 remains high. On the other hand, a logical 1 happens when D1 goes low while D0 remains high (see the above picture).
  4. Each data bit (either 0 or 1) must be followed by a pause interval. There are timing requirements for both data pulses and pause intervals (for details and references, please see the Wiegand Wikipedia page).

In my arrangement, the physical layer is represented by the Nano digital pins 2 (D0), 3 (D1) and GROUND. I use it to implement the 26-bit protocol.

The 26-bit Protocol

The Wiegand 'message' is just a 24-bit numeric code framed by two parity bits:

PXXXXXXXXXXXXXXXXXXXXXXXXQ

The heading parity bit P is added to the leftmost group of 12 bits (MSB) in order to obtain even parity. In a similar way, the trailing parity bit Q is added to the rightmost group in order to obtain odd parity.

For instance, assume the numeric code is 16777215, i.e., 0xFFFFFF (all ones):

P111111111111111111111111Q

In order to give even parity to the leftmost group of bits, we have to set P=0. On the other hand, in order to obtain odd parity in the rightmost one, we have to set Q=1.

Hence the final 26-bit code is:

01111111111111111111111111

Using the Sketch

Open the Serial Monitor tool: Arduino waits for a numeric code followed by a newline (see the picture below).

Serial Monitor tool

The Serial Monitor Tool

On successful reception of the numeric code, the corresponding Wiegand message is produced on digital pins 2, 3.

Some patterns captured by my trustworthy RIGOL scope:

The 16777215 (0xFFFFFF) code

The 16777215 (0xFFFFFF) code: yellow channel is Wiegand D0, blue channel is D1

The 0 code

The 0 code: note the last bit set to 1 in order to obtain trailing odd parity.

The 11184810 (0xAAAAAA) code

The 11184810 (0xAAAAAA) code flips all the bits.

The idle-to-data transition

This is a particular of the 0xAAAAAA pattern, showing the idle-to-data transition of the communication line.

Timings

In order to fulfill Wiegand timing constraints, the Arduino delayMicroseconds function is used. While results are not brilliant, protocols requirements are met.

Data pulse timing

Data pulse timing.

Interval pulse timing

Interval pulse timing.

The Code

The code is simple and heavily commented. The workhorse functions are reported in the below snippets:

C
// outputs ONE Wiegand bit
void outwiegbit(unsigned int b)
{
  int sel = b == 0 ? W_D0 : W_D1;
  digitalWrite(sel, 0);
  delayMicroseconds(80);
  digitalWrite(sel, 1);
  delayMicroseconds(240);
}

The outwiegbit trivially outputs a bit on Wiegand outputs with proper timings:

C
// outputs a 26 bit Wiegand code
// u32 is actually the 24-bit numeric code
void outwieg26(uint32_t u32)
{
  uint32_t tmp = u32;
  unsigned int p_even = 0;
  unsigned int p_odd = 1;
  // compute parity on trailing group of bits 
  for (int n=0; n<12; ++n)
  {
    p_odd ^= (tmp & 1);
    tmp >>= 1;
  }
  // compute parity on heading group of bits
  for (int n=12; n<24; ++n)
  {
    p_even ^= (tmp & 1);
    tmp >>= 1;
  }
  // now output data bits framed by parity ones
  outwiegbit(p_even);
  for (int n=0; n<24; ++n)
  {
    outwiegbit((u32 >> (23-n)) & 1);
  }
  outwiegbit(p_odd);  
}

The outwieg26 outputs a 26-bit code. Heading (even) and trailing (odd) parity bits are first computed on the actual 24-bit code.

Points of Interest

Building a Wiegand code generator on Arduino was really quick.

Another step could be adding a keypad in order to create a real standalone control access device.

History

  • 2nd July, 2018 - First revision

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) Biotecnica Instruments S.p.A.
Italy Italy




Debugging? Klingons do not debug. Our software does not coddle the weak. Bugs are good for building character in the user.
-- The Klingon programmer



Beelzebub for his friends [^].





Comments and Discussions

 
QuestionKeypad? Pin
Member 145681967-May-23 10:26
Member 145681967-May-23 10:26 
Questioni need to output same card number every time we short analog pin Pin
Member 1539114414-Oct-21 12:49
Member 1539114414-Oct-21 12:49 
AnswerRe: i need to output same card number every time we short analog pin Pin
CPallini14-Oct-21 20:10
mveCPallini14-Oct-21 20:10 
QuestionThank!!! Pin
Rodolfo Barros10-Oct-21 6:08
Rodolfo Barros10-Oct-21 6:08 
AnswerRe: Thank!!! Pin
CPallini11-Oct-21 2:08
mveCPallini11-Oct-21 2:08 
GeneralRe: Thank!!! Pin
Rodolfo Barros11-Oct-21 4:36
Rodolfo Barros11-Oct-21 4:36 
GeneralRe: Thank!!! Pin
CPallini11-Oct-21 5:25
mveCPallini11-Oct-21 5:25 
QuestionConvert Pin
Nik00997-Apr-21 6:52
Nik00997-Apr-21 6:52 
QuestionThanks Pin
Member 1471808617-Jan-20 3:11
Member 1471808617-Jan-20 3:11 
Generalabout the timing Pin
gerard k8-Sep-19 12:22
gerard k8-Sep-19 12:22 
QuestionWeigand Output Pin
Member 1456138017-Aug-19 6:52
Member 1456138017-Aug-19 6:52 
Questionawesome Pin
jow88s2-Jan-19 23:59
jow88s2-Jan-19 23:59 
QuestionInteresting article Pin
Mike Hankey3-Jul-18 7:14
mveMike Hankey3-Jul-18 7:14 
AnswerRe: Interesting article Pin
CPallini3-Jul-18 7:32
mveCPallini3-Jul-18 7:32 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.