Ok, I am losing my mind...

Why is this so damn difficult?

Current situation:
- 12V Access control device that is connected like this i.e. Wiegand D0 to Tx and D1 to Rx, with voltage dividers.
- Raspberry Pi 3 with Raspbian Lite OS.
- Configured the GPIO serial port i.e. enabling uart and disabling the console.

The following Python script runs:

import serial

ser = serial.Serial(port='/dev/serial0', baudrate = 9600)

while 1:
        print ser.readline()

I swipe the 125KHZ cards, the device beeps, and nothing happens...

I tried reading from /dev/serial1, /dev/ttyAMA0, /dev/ttyS0... Still nothing.

What am I missing?

  • (1) Your reader is 12V, and may be noisy long distance, suggest CD4050 to buffer and convert 12V to 3V3, (2) Your linked tutorial is rubbish. Google harder. (3) WieGand has no timing standard, you need a scope to display timing, before starting any programming, (3) Vendor provides RS232 option. You might like to ask them for more details. Good luck. :)
    – tlfong01
    Jul 1, 2019 at 4:18
  • In case your have no luck asking vendor for RS232 version of reader, you might like to read my draft program just added in the appendix of my answer, to see how "simple" is the program! :)
    – tlfong01
    Jul 1, 2019 at 7:02

3 Answers 3



How to use Rpi UART to read Wiegand data?


No you can't. Wiegand and UART are different animals. They don't talk to each other.

But you can use two Rpi GPIO pins and write a simple python program instead. See details below.

Wiegand format summary

(1) has two output signal wires, one carrying Bit 1 signal, the other Bit 0 signal,

(2) uses 26 bits format (16 bit for card number),

(3) has no clock.

wiegand format

Rpi GPIO reading Wiegand

To use Rpi to read Wiegand, you can use a HC00 Quad NAND to preprocess the two signals, then use two input mode GPIO pins to read the processed data. It might take an average Rpi python hobbyist programmer one or two days to write a program (Of course you can borrow C++ code from the Arduino guys! :)). See Reference 2 below for more details.

Converting 5V/12V Input Signals to 3.3V for Rpi

Only hobbyists use resistor voltage dividers. The EE guys usually use CMOS CD4050 (Note 1), which is low side single supply (3V3 in this case) and specially designed for high to low level conversion. All theses years I have been using CD4050 to convert 5V to 3V for Rpi, and so far so good.

Note 1 - Of course hex converter CD4050 is not the only choice. For stepping down just one or two 5V signals to 3V3 say, EE guys usually prefer to use one small signal diode to do the step down (5V - diode drop at cutoff is "usually" safe for high impedance 3V3 logic CMOS input - but no guarantee!)

CD4050B CMOS Hex Buffer and Converter (5V (max 20V) Logic to 3V3, Vcc = 3V3) - TI


  1. Understanding Wiegand Format

  2. Wiegand Serial Format

  3. AliExpress DC12V Access Control 26/34 Wiegand Reader

  4. Raspberry Pi and Wiegand: Step by Step (Useless!)

  5. CD4050B CMOS Hex Buffer and Converter (5V Logic to 3V3, Vcc = 3V3) - TI


Appendix A - Quick and dirty buggy WieGand reader program draft V0.1

# *** Initialiation ***
Note - GPIO pinA reads Bit 0, GPIO pinB reads Bit 0

import GPIO module
set GPIO pinA and pinB to input mode
declare 16 elements dataBitList to store card number

# *** Read a pulse from either pinA or PinB ***
Note - wait for pulse coming at PinA or pinB

while (pinA OR pinB) NOT Low 
  sleep 100uS

read pinA         
  if pinA Low
    return 0
    return 1               

# *** Main program ***
Note - just read one card number, no parity checked.

initialize pinA, pinB, dataBitList
loop 26 times
  read start pulse
  loop to read  8 factory data bits and discard
  loop to read 16 card number bits and store in dataBitlist
  read partity pulse
  sleep 100mS

print card number in the dataBitList 

Wiegand devices do not generally talk via a serial interface. They typically provide a Wiegand output on two data lines (typically a green wire and a white wire).

Before connecting any device to a Pi GPIO you need to ensure its outputs are 3V3 or less.

Here is an example Python script to read Wiegand codes.


It requires the pigpio daemon to be running (sudo pigpiod).

  • Thanks for the answer. I assumed Rx/Tx is serial and that I can read it directly. As for the 3.3V, yes, I used a voltage divider to step down from 5V. Why is a library required to read the signal? Isn't the socket file enough?
    – Ivan
    Jun 30, 2019 at 22:11
  • RX/TX is serial. Wiegand is not. Perhaps look at a Wiki for both. Not sure where socket file comes into this at all.
    – joan
    Jun 30, 2019 at 22:24

Here's my complete code for checking a 26bit rfid card to grant or deny access for a control access system.

var rpio = require('rpio');
rpio.init({mapping: 'gpio'});
var exec = require('child_process').exec;
rpio.open(17, rpio.INPUT, rpio.PULL_DOWN);
rpio.open(18, rpio.INPUT, rpio.PULL_DOWN);

var z = "";
var xTime;
function y(pin)


if (pin == 17) {
    z = z + "0";
    if (pin == 18) {
        z = z + "1";
xTime = setTimeout(CheckAccessMain,1000)

rpio.poll(17, y, rpio.POLL_LOW);
rpio.poll(18, y, rpio.POLL_LOW);

function CheckAccessMain() {
if (z.length != 26) {
if (z == "10111011000000110010001111") { //check if access card is correct
console.log("access granted!");
exec('omxplayer /root/rfid_make_sound/LOZ_Secret.wav', function callback(error, stdout, stderr){})

rpio.mode(21, rpio.OUTPUT);  //open lock

setTimeout(function() {
rpio.mode(21, rpio.INPUT); //close lock after 3 seconds
    }, 3000);

} else {
console.log("Access Denied!");
exec('omxplayer /root/rfid_make_sound/jurass01.mp3', function callback(error, stdout, stderr){})

z = "";
  • Please add some text explaining why this works...
    – NomadMaker
    Aug 9, 2022 at 11:39

This site is temporarily in read-only mode and not accepting new answers.

Not the answer you're looking for? Browse other questions tagged .