9b56774d43cd12978138860529999ffeed638779
MicroPython Wiegand Driver
A lightweight, event-driven Wiegand protocol driver for MicroPython.
Supports 26-bit Wiegand, 34-bit Wiegand, and 8-bit keypad input.
No polling, no debouncing – just pure interrupt-driven collection with a one-shot timeout.
Features
- Fully interrupt-driven – Records bits on both DATA0/DATA1 falling edges.
- One‑shot timer – 80 ms timeout started only on the first bit; zero CPU overhead when idle.
- No software debouncing – Relies on frame length and parity checks to reject noise.
- Multi‑format support – Automatically detects 26‑bit, 34‑bit, and 8‑bit keypad frames.
- Raw payload output – Returns the data bits without parity bits (24 bits for WG26, 32 bits for WG34), giving the application full control over facility code / card number extraction.
- Automatic parity validation – Standard Wiegand even/odd parity check.
- Keypad verification – For 8‑bit keypad frames, validates that the upper nibble is the bitwise complement of the lower nibble, then returns the key number (0–15).
- Safe for MicroPython – Uses a pre‑allocated
bytearraybuffer; no memory allocation inside interrupts.
Installation
Copy the file wiegand.py to your MicroPython device (e.g., into /lib/ or the root directory).
Usage
from machine import Pin
from wiegand import Wiegand
def on_wiegand(data_type, value):
if data_type == 'wg26':
facility = (value >> 16) & 0xFF
card = value & 0xFFFF
print("WG26 - Facility: {}, Card: {}".format(facility, card))
elif data_type == 'wg34':
print("WG34 raw payload: 0x{:08X}".format(value))
elif data_type == 'keypad':
print("Key pressed:", value)
# DATA0 on GPIO16, DATA1 on GPIO17
reader = Wiegand(pin0=16, pin1=17, callback=on_wiegand)
API
Wiegand(pin0, pin1, callback, buf_len=34)
pin0– GPIO number for the DATA0 (zero‑bit) line.pin1– GPIO number for the DATA1 (one‑bit) line.callback– Function called when a valid frame is received.
Signature:callback(data_type, value)data_type(str): one of'wg26','wg34','keypad'.value(int):'wg26': 24‑bit payload (bits 1–24 of the 26‑bit frame, parity bits removed).'wg34': 32‑bit payload (bits 1–32 of the 34‑bit frame).'keypad': integer 0–15, the key number.
buf_len– (optional) maximum buffer size, default34. Must be at least as large as the longest expected frame.
Supported Formats
| Format | Total bits | Payload bits returned | Parity check |
|---|---|---|---|
| WG26 | 26 | 24 | Even (first half) / Odd (second half) |
| WG34 | 34 | 32 | Even (first half) / Odd (second half) |
| Keypad | 8 | lower nibble (0–15) | Upper nibble must be ~lower nibble |
For WG26 and WG34 the leading and trailing parity bits are stripped. The user is responsible for extracting facility code and card number from the raw payload.
How It Works
- Pin setup – Both DATA0 and DATA1 pins are configured as inputs with internal pull‑ups and falling‑edge interrupts.
- Interrupt handler – On each falling edge, the handler reads the state of both pins and encodes it as
0b01(bit 0) or0b10(bit 1). Any other combination (e.g., both low) is ignored. - One‑shot timer – When the first valid bit is recorded, a hardware timer is started in
ONE_SHOTmode with an 80 ms period. - Timeout – When the timer fires, the collected bit array is copied, parsed, and the buffer is reset.
- If the frame length is 26 or 34 and parity checks pass, the callback is called with the raw payload.
- If the frame length is 8 and the keypad nibble inversion check passes, the key number is reported.
- Otherwise the frame is silently discarded.
- Ready for next read – The buffer index is set to zero immediately after the timeout, so a new card can be processed right away.
Notes
- The 80 ms timeout works for virtually all standard Wiegand readers. If you have an exceptionally slow reader, adjust the
periodvalue inself.timer.init(period=...)inside the source. - No debouncing is applied. If your hardware produces spurious edges, the parity or length checks will reject the frame, and no callback will fire. This keeps the interrupt handler extremely short.
- The driver uses a pre‑allocated
bytearray– it never allocates memory in the IRQ, making it safe for all MicroPython ports. - If your platform does not support
Timer.ONE_SHOT, you can replace it with a periodic timer that callsself.timer.deinit()on the first callback. - This library is not thread‑safe – it is designed for the single‑threaded MicroPython environment.
License
MIT License.
Description
A lightweight, event-driven Wiegand protocol driver for MicroPython.
Supports 26-bit Wiegand, 34-bit Wiegand, and 8-bit keypad input.
Languages
Python
100%