User avatar
joan
Posts: 14197
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: RPi.GPIO Wiegand capture speed?

Thu Jul 04, 2013 8:29 pm

That is well within the capabilities of a Pi. 50us pulse every ms shouldn't add any perceptible load.

I've been playing with using software RX to decode hardware TX of serial data at 115200 bps (8.7us per bit) and I'm getting something like a bit error every 20,000 bits.

kghunt
Posts: 383
Joined: Sun Mar 04, 2012 9:28 am

Re: RPi.GPIO Wiegand capture speed?

Thu Jul 04, 2013 8:32 pm

Stevebird - I work for such a company and I can tell you we charge more than you were quoted :-). How many readers have you connected to one atmel?

Joan - Those are the speeds set by the wiegand effect/protocol. Are you using C? Maybe I could use C to do the wiegand read then do the processing in python.

I would love to make a board up that is simply a plug in access board with 2 readers 2 relays and 3 inputs. Then get it properly designed and printed. Once that's done maybe even start a kickstarter to employ one of our developers to make a nice web based software for it.

User avatar
joan
Posts: 14197
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: RPi.GPIO Wiegand capture speed?

Thu Jul 04, 2013 9:14 pm

I use my own C library which is why I'm confident it would successfully read wiegand data. I'd have thought the other C libraries would do just as well.

http://www.raspberrypi.org/phpBB3/viewt ... 38#p355638 shows I2C data being captured (100 kHz).

kghunt
Posts: 383
Joined: Sun Mar 04, 2012 9:28 am

Re: RPi.GPIO Wiegand capture speed?

Thu Jul 04, 2013 9:20 pm

Is i2c data buffered like serial? Wiegand obviously is not and its easy to miss 1 bit that screws the whole thing up.

User avatar
joan
Posts: 14197
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: RPi.GPIO Wiegand capture speed?

Thu Jul 04, 2013 9:31 pm

I'm not sure, I guess the I2C driver might buffer the data.

That's not what I was doing though, I was just passively monitoring the gpio states and logging state changes in a form suitable for viewing with gtkwave. The point is the software captured the state changes completely independently of the sender or receiver.

User avatar
joan
Posts: 14197
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: RPi.GPIO Wiegand capture speed?

Fri Jul 05, 2013 9:21 am

I was sufficiently interested to come up with a C implementation of what I think wiegand data looks like.

Based on your Python code.

Code: Select all

/*
    #!/usr/bin/env python

    #green/data0 is pin 22
    #white/data1 is pin 7
    import time
    import RPi.GPIO as GPIO
    GPIO.setmode(GPIO.BOARD)
    GPIO.setup(7, GPIO.IN)
    GPIO.setup(22, GPIO.IN)

    bits = ''
    timeout = 5
    def one(channel):
        global bits
        bits = bits + '1'
        #timeout = 5
       
    def zero(channel):
        global bits
        bits = bits + '0'
        #timeout = 5

    GPIO.add_event_detect(7, GPIO.FALLING, callback=one)
    GPIO.add_event_detect(22, GPIO.FALLING, callback=zero)

    print "Present Card"
    while 1:
        if len(bits) == 32:
            print 25 * "-"
            print "32 Bit Mifare Card"
            print "Binary:",bits
            print "Decimal:",int(str(bits),2)
            print "Hex:",hex(int(str(bits),2))
            bits = '0'
            print 25 * "-"
            print
            print "Present Card"
*/
#include <stdio.h>

#include <pigpio.h>

#define DATA0 25 /* P1-22 */
#define DATA1  4 /* P1-7 */

void bit(int gpio, int level, uint32_t tick)
{
   static int bits = 0;
   static uint32_t code = 0;
   static int timeout = 0;

   if (level == 0) /* bit to zero, falling */
   {
      if (gpio == DATA0)
      {
         timeout &= 2; /* clear DATA0 time out */

         code = (code << 1) + 0;
      }
      else
      {
         timeout &= 1; /* clear DATA1 time out */

         code = (code << 1) + 1;
      }

      if (++bits == 32)
      {
         printf("wiegand code is %11o, %8X, %u\n", code, code, code);
         bits = 0;
         code = 0;
      }
   }
   else if ((level == 2) && bits) /* DATA0 or DATA1 timed out during rx */
   {
      if (gpio == DATA0) timeout |= 1;
      else               timeout |= 2;

      if (timeout == 3) /* both bits timed out */
      {
         printf("SHORT wiegand code is %11o, %8x, %u\n", code, code, code);
         bits = 0;
         code = 0;
      }
   }
   
}

int main(int argc, char *argv[])
{
   if (gpioInitialise()<0) return 1; /* initialisation failed */

   gpioSetMode(DATA0, PI_INPUT);
   gpioSetMode(DATA1, PI_INPUT);

   gpioSetAlertFunc(DATA0, bit); /* call bit when DATA0 changes */
   gpioSetAlertFunc(DATA1, bit); /* call bit when DATA1 changes */

   gpioSetWatchdog(DATA0, 5); /* timeout DATA0 after 5ms */
   gpioSetWatchdog(DATA1, 5); /* timeout DATA1 after 5ms */

   while (1) sleep (1); /* spin forever */

   gpioTerminate(); /* never reaches here, just for completeness */
}
I used a TI to send a series of 32 bit and (short) 30 bit codes. I assume the pulses are active low of 50us duration with 1ms between each pulse. I used an arbitrary delay of 20ms between the end of one code and the start of the next.

Code: Select all

wiegand code is     4447600,   124F80, 1200000
wiegand code is     4753040,   13D620, 1300000
wiegand code is     5256300,   155CC0, 1400000
wiegand code is     5561540,   16E360, 1500000
wiegand code is     6065000,   186A00, 1600000
wiegand code is     6370240,   19F0A0, 1700000
wiegand code is     6673500,   1B7740, 1800000
wiegand code is     7176740,   1CFDE0, 1900000
SHORT wiegand code is     2670660,    b71b0, 750000
SHORT wiegand code is     2751530,    bd358, 775000
SHORT wiegand code is     3032400,    c3500, 800000
SHORT wiegand code is     3113250,    c96a8, 825000
SHORT wiegand code is     3174120,    cf850, 850000
SHORT wiegand code is     3254770,    d59f8, 875000
SHORT wiegand code is     3335640,    dbba0, 900000
SHORT wiegand code is     3416510,    e1d48, 925000
SHORT wiegand code is     3477360,    e7ef0, 950000
SHORT wiegand code is     3560230,    ee098, 975000
wiegand code is     3641100,    F4240, 1000000
wiegand code is     4144340,   10C8E0, 1100000
wiegand code is     4447600,   124F80, 1200000
wiegand code is     4753040,   13D620, 1300000
wiegand code is     5256300,   155CC0, 1400000
wiegand code is     5561540,   16E360, 1500000
wiegand code is     6065000,   186A00, 1600000
wiegand code is     6370240,   19F0A0, 1700000
wiegand code is     6673500,   1B7740, 1800000
wiegand code is     7176740,   1CFDE0, 1900000
SHORT wiegand code is     2670660,    b71b0, 750000
SHORT wiegand code is     2751530,    bd358, 775000
SHORT wiegand code is     3032400,    c3500, 800000
SHORT wiegand code is     3113250,    c96a8, 825000
SHORT wiegand code is     3174120,    cf850, 850000
SHORT wiegand code is     3254770,    d59f8, 875000
SHORT wiegand code is     3335640,    dbba0, 900000
SHORT wiegand code is     3416510,    e1d48, 925000
SHORT wiegand code is     3477360,    e7ef0, 950000
SHORT wiegand code is     3560230,    ee098, 975000
wiegand code is     3641100,    F4240, 1000000
wiegand code is     4144340,   10C8E0, 1100000
wiegand code is     4447600,   124F80, 1200000
wiegand code is     4753040,   13D620, 1300000
wiegand code is     5256300,   155CC0, 1400000
wiegand code is     5561540,   16E360, 1500000
wiegand code is     6065000,   186A00, 1600000
wiegand code is     6370240,   19F0A0, 1700000
wiegand code is     6673500,   1B7740, 1800000
wiegand code is     7176740,   1CFDE0, 1900000
SHORT wiegand code is     2670660,    b71b0, 750000
SHORT wiegand code is     2751530,    bd358, 775000
SHORT wiegand code is     3032400,    c3500, 800000
SHORT wiegand code is     3113250,    c96a8, 825000
SHORT wiegand code is     3174120,    cf850, 850000
SHORT wiegand code is     3254770,    d59f8, 875000
SHORT wiegand code is     3335640,    dbba0, 900000
SHORT wiegand code is     3416510,    e1d48, 925000
SHORT wiegand code is     3477360,    e7ef0, 950000
SHORT wiegand code is     3560230,    ee098, 975000
wiegand code is     3641100,    F4240, 1000000
wiegand code is     4144340,   10C8E0, 1100000
wiegand code is     4447600,   124F80, 1200000
wiegand code is     4753040,   13D620, 1300000
wiegand code is     5256300,   155CC0, 1400000
wiegand code is     5561540,   16E360, 1500000
wiegand code is     6065000,   186A00, 1600000
wiegand code is     6370240,   19F0A0, 1700000
wiegand code is     6673500,   1B7740, 1800000
wiegand code is     7176740,   1CFDE0, 1900000
wiegand-1.png
Overview
wiegand-1.png (7.11 KiB) Viewed 7369 times
wiegand-2.png
Several codes
wiegand-2.png (5.74 KiB) Viewed 7369 times
wiegand-3.png
Detail of one code
wiegand-3.png (6.39 KiB) Viewed 7369 times

kghunt
Posts: 383
Joined: Sun Mar 04, 2012 9:28 am

Re: RPi.GPIO Wiegand capture speed?

Fri Jul 05, 2013 9:53 am

That is amazing. I am not going to pretend to understand everything that is going on here my knowledge of c is based on what I have done with my arduinos.

When trying to compile your code I get

Code: Select all

fatal error: pigpio.h: No such file or directory
I assume I am missing the library you used for gpio. I was Just setting out porting my Arduino wiegand sketch to c using wiringPi this is as far as I got.

Code: Select all

#include <wiringPi.h>
#include <stdio.h>

int data0 = 2;
int data1 = 3;
int timeout = 0;
char bits[32];
volatile int bit_count = 0;


char zero(){
  bit_count ++; bits = (bits + 0);
}

char one(){
  bit_count ++; bits = (bits + 1);
}


int main()
{

    printf(bits,"\n");
    //printf("\n");
    return 0;
}
But I am doing something wrong with the bits variable and I get this error.

Code: Select all

error: incompatible types when assigning to type 'char[32]' from type 'char *'
How reliable was your test? It is funny because I was going to program an atmel chip to send a 32bit number every x seconds to my pi and log the number of failures over a several hour period. But then I just decided to give C a try.

User avatar
joan
Posts: 14197
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: RPi.GPIO Wiegand capture speed?

Fri Jul 05, 2013 10:25 am

For pigpio, assuming a hard float distribution, to download and build the library

Code: Select all

wget abyz.co.uk/rpi/pigpio/pigpio.tar
tar xvf pigpio.tar
cd PIGPIO
cp libpigpio.a-hard libpigpio.a
make
make install
To compile/link the example

cc -o wiegand wiegand.c -lpigpio -lrt -lpthread

I only ran the script for a few minutes once I got it working (TI is very fussy about longs). It seemed reliable. The first few readings came across as short codes as they caught a TI transmission in the middle when the program started.

C doesn't have strings a la Python.

char zero(){
bit_count ++; bits = (bits + 0);
}

would need to be rewritten as

char zero(){
bits[bit_count ++] = 0;
}

That would accumulate the bits into separate bytes of bits (back to front to the way you do it though, bits[0] would be the first bit, bit[1] the second etc.).

User avatar
joan
Posts: 14197
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: RPi.GPIO Wiegand capture speed?

Fri Jul 05, 2013 12:56 pm

kghunt wrote: ...
How reliable was your test?
...
I have just had it running for two hours. Apart from the expected spurious short codes at start-up it has been faultless.

129990 reads (18 reads per second).

Log sorted, then uniq -c to give

Code: Select all

   6500 SHORT wiegand code is     2670660,    b71b0, 750000
   6500 SHORT wiegand code is     2751530,    bd358, 775000
   6500 SHORT wiegand code is     3032400,    c3500, 800000
   6500 SHORT wiegand code is     3113250,    c96a8, 825000
   6500 SHORT wiegand code is     3174120,    cf850, 850000
   6500 SHORT wiegand code is     3254770,    d59f8, 875000
   6500 SHORT wiegand code is     3335640,    dbba0, 900000
   6500 SHORT wiegand code is     3416510,    e1d48, 925000
   6500 SHORT wiegand code is     3477360,    e7ef0, 950000
   6500 SHORT wiegand code is     3560230,    ee098, 975000
   6499 wiegand code is     3641100,    F4240, 1000000
   6499 wiegand code is     4144340,   10C8E0, 1100000
   6499 wiegand code is     4447600,   124F80, 1200000
   6499 wiegand code is     4753040,   13D620, 1300000
   6499 wiegand code is     5256300,   155CC0, 1400000
   6499 wiegand code is     5561540,   16E360, 1500000
   6499 wiegand code is     6065000,   186A00, 1600000
   6499 wiegand code is     6370240,   19F0A0, 1700000
   6499 wiegand code is     6673500,   1B7740, 1800000
   6499 wiegand code is     7176740,   1CFDE0, 1900000
For one hour the program was mostly running by itself. For the second hour it was stressed with

stress --cpu 5 --io 5 --vm 5 --vm-bytes 10M --timeout 3600s &

Code: Select all

top - 13:00:50 up  3:39,  3 users,  load average: 15.31, 15.30, 12.85
Tasks: 104 total,  16 running,  88 sleeping,   0 stopped,   0 zombie
%Cpu(s): 35.0 us, 64.8 sy,  0.0 ni,  0.0 id,  0.0 wa,  0.0 hi,  0.3 si,  0.0 st
KiB Mem:    448776 total,   408264 used,    40512 free,    14108 buffers
KiB Swap:        0 total,        0 used,        0 free,   310172 cached

  PID USER      PR  NI  VIRT  RES  SHR S  %CPU %MEM    TIME+  COMMAND                 
 2322 root      20   0  6980 4948  576 S  10.9  1.1   6:40.13 wiegand                 
 2936 joan      20   0  2168  200  124 R   6.0  0.0   1:34.68 stress                  
 2937 joan      20   0 12412 6460  196 R   6.0  1.4   1:34.68 stress                  
 2938 joan      20   0  2168  204  128 R   6.0  0.0   1:34.68 stress                  
 2940 joan      20   0 12412 3964  196 R   6.0  0.9   1:34.68 stress                  
 2926 joan      20   0  2168  204  128 R   5.7  0.0   1:34.67 stress                  
 2927 joan      20   0  2168  200  124 R   5.7  0.0   1:34.67 stress                  
 2928 joan      20   0 12412  272  196 R   5.7  0.1   1:34.67 stress                  
 2929 joan      20   0  2168  204  128 R   5.7  0.0   1:34.67 stress                  
 2930 joan      20   0  2168  200  124 R   5.7  0.0   1:34.67 stress                  
 2931 joan      20   0 12412  272  196 R   5.7  0.1   1:34.67 stress                  
 2932 joan      20   0  2168  204  128 R   5.7  0.0   1:34.67 stress                  
 2933 joan      20   0  2168  200  124 R   5.7  0.0   1:34.67 stress                  
 2934 joan      20   0 12412 9464  196 R   5.7  2.1   1:34.67 stress                  
 2935 joan      20   0  2168  204  128 R   5.7  0.0   1:34.67 stress                  
 2939 joan      20   0  2168  200  124 R   5.7  0.0   1:34.67 stress                  
 2941 joan      20   0  4664 1380 1024 R   1.3  0.3   0:20.93 top

kghunt
Posts: 383
Joined: Sun Mar 04, 2012 9:28 am

Re: RPi.GPIO Wiegand capture speed?

Fri Jul 05, 2013 4:14 pm

I take it that test was run on the pi? Well I cannot get your code to fail at all apart from the hand full of reads at the start. I'm not sure why it is doing that it must be weirdness with the gpio floating when it's called or something as the reader I'm using is held high.

The code works great and even under load I can't get it to fail.

It has 6% cpu usage too.

My python code has 90% cpu to do the same task and fails 1 in 20.

Now I can see (almost) what your code does but I would never have got that far by myself.

Next question is do I try do do the rest in python which is mostly called when needed and not looping or try and do it all in C.

Also what do you use pi-gpio? Git says this is not maintained have you used wiringpi?.

User avatar
joan
Posts: 14197
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: RPi.GPIO Wiegand capture speed?

Fri Jul 05, 2013 4:36 pm

Yes, my tests were run on the Pi.

I can understand why I get one short read at the start, but not the others. You shouldn't get any. Probably some faulty logic on my part, probably to do with the way I timeout DATA0 and DATA1. I'll think about it.

It can be tricky to get your head around this sort of code. It's event driven so you have to maintain a sort of state machine. I don't use interrupts, but I expect an interrupt driven approach would work in a similar fashion.

As to how you implement your solution - personal choice.

User avatar
joan
Posts: 14197
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: RPi.GPIO Wiegand capture speed?

Fri Jul 05, 2013 4:46 pm

kghunt wrote:...
Also what do you use pi-gpio? Git says this is not maintained have you used wiringpi?.
Pigpio is my own library, written to meet my interests and needs. I haven't published the source. I probably will if I can complete one major area of functionality I'm currently working on.

stevebird
Posts: 8
Joined: Fri Mar 01, 2013 8:46 pm

Re: RPi.GPIO Wiegand capture speed?

Fri Jul 05, 2013 6:04 pm

kghunt wrote:Stevebird - I work for such a company and I can tell you we charge more than you were quoted :-).

Exactly, I don't know why they are so much, the component parts are relatively inexpensive, install of the locks by a good chippy can be done reasonably quick. It shouldn't be expensive.
kghunt wrote: How many readers have you connected to one atmel?
I have one reader per atmel, not component efficient perhaps, but for our functionality exactly what we wanted.

I wanted the access database stored locally on each door, just in case it lost contact with the back end for some reason.

We have a really awful sabre system at work, when it works its great, but.... the doors are chained together so if there's a break in the cable or door power goes off, all those down stream cease to function. I'm sure not all systems are like this.

I've designed the back end door system to integrate with the bookings system, which then pushes the changes to each door and since they are stored locally it doesn't matter if the network should fail or the back end stop for some reason, as long as a change doesn't need to be pushed out and the door its self hasn't got a problem then it should be fine.

I've got some prototypes here at the office and apart from a little coding error defining the wrong type of variable which should have been an unsigned long, the reader software so far in the atmel has been very stable.

kghunt
Posts: 383
Joined: Sun Mar 04, 2012 9:28 am

Re: RPi.GPIO Wiegand capture speed?

Fri Jul 05, 2013 8:35 pm

Yeah 2 readers a controller a break glass and a lock probably cost £500 retail obviously less to a partner like us. But You pay for the software. Our system is all written in house and all controllers are stand alone ip based and work online/offline. Plus our system works with biometrics and clocking machines and people like to use the same data for both access and Time and attendance.

The 328p only has 2 external interrupts but each port also has an interupt so it is possible although not as straight forward to have up to 3 readers on one 328p. Although Joan's code above is pretty much flawless and every pi supports interupt so I can easily have 2 readers 2 relays 2 push button inputs 2 door monitors and a fire alarm input and an RTC without any atmel chips. Ideally I would prefer this.

Did you program your atmel using arduino? There's an easy way to upload sketches to an arduino via the pis serial port using arduino-core and a make file.

kghunt
Posts: 383
Joined: Sun Mar 04, 2012 9:28 am

Re: RPi.GPIO Wiegand capture speed?

Mon Jul 08, 2013 4:33 pm

I have been attempting to go through some C++ turorials to hopefully move my IO to C and just do the processing in python. Meanwhile I optimized my python version so now it only uses 6% cpu versus 70% previously.

This means that the read rate is much higher probably 1 bad read in every 50 maybe higher. I also found a cool function that someone blogged about that lets you change the process name of a python script.

I think maybe with some more optimisation this python one could be a winner for hobby/home use I have even tested in with stress 3 cpus and 3 io's and it still worked! This is a vast improvement over last time.

Here is the code

Code: Select all

#!/usr/bin/env python

#green/data0 is pin 22
#white/data1 is pin 7
import time
import RPi.GPIO as GPIO

D0 = 22
D1 = 7
bits = ''
t = 15
timeout = t

GPIO.setmode(GPIO.BOARD)
GPIO.setup(D0, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(D1,GPIO.IN, pull_up_down=GPIO.PUD_UP)

def set_procname(newname):
    from ctypes import cdll, byref, create_string_buffer
    libc = cdll.LoadLibrary('libc.so.6')    #Loading a 3rd party library C
    buff = create_string_buffer(len(newname)+1) #Note: One larger than the name (man prctl says that)
    buff.value = newname                 #Null terminated string as it should be
    libc.prctl(15, byref(buff), 0, 0, 0) #Refer to "#define" of "/usr/include/linux/prctl.h" for the misterious value 16 & arg[3..5] are zero as the man page says.
    
def one(channel):
    global bits
    global timeout
    bits = bits + '1'
    timeout = t
    
def zero(channel):
    global bits
    global timeout
    bits = bits + '0'
    timeout = t



def main():
    set_procname("Wiegand Reader")
    global bits
    global timeout
    GPIO.add_event_detect(D0, GPIO.FALLING, callback=zero)
    GPIO.add_event_detect(D1, GPIO.FALLING, callback=one)
    while 1:
        if bits:
            timeout = timeout -1
            time.sleep(0.001)
            if len(bits) > 1 and timeout == 0:
                #print "Binary:",bits
                result = int(str(bits),2)
                if result == 2923229214: # the number of my test badge
                    bits = '0'
                    print result
                else:
                    bits = '0'
                    timeout = t
                    print "Bad Read"
        else:
            time.sleep(0.001)



if __name__ == '__main__':
    main()

kghunt
Posts: 383
Joined: Sun Mar 04, 2012 9:28 am

Solved using WiringPi..Re: RPi.GPIO Wiegand capture speed?

Thu Jul 11, 2013 3:15 pm

I have had a bash (pun intended) at writing my own C version of the Wiegand reader and I can report that the results are good! There are not missed bits ever (so far). I Still find it easier a quicker to do most of my processing in python but the more time critical stuff like input monitoring I will do in C then pass off to python.

This code grabs the wiegand bits then squirts them into a python program for later authentication/processing. It also does this on a new thread so as not to upset the delicate reading process.

Let me know what you think. Be gentle it is my first C program ever (besides hello world). This also has the benefit of no anomalous readings at start up that I was getting with Joans (although I think I know why Joans is doing that).

C Code (compiled with sudo gcc -Wall io.c -o io -lwiringPi -lpthread && sudo ./io)

Code: Select all

include <wiringPi.h>
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

int data0 = 6; /* P1-22 */
int data1 = 7; /* P1-7 */
int bits; // Collected bits storage area
int blank; //blank variable to reset bits
int bit_count = 0; //to measure the size of bits
int t = 5;
int timeout; //timout to return correct value
char command[40];
pthread_t thread0;

void python_thread(int val){
    //printf("%X\n", val); // test to see if val comes in
    sprintf(command,"python access.py %X",val); //build python command
    system(command); //run python command
 //return 0;   
}

void bit0(){ //adds a 0
        bit_count ++; //increase bit count
        bits = (bits << 1) + 0;
        timeout = t;   //reset timeout
}

void bit1(){ //adds a 1
        bit_count ++; 
        bits = (bits << 1) + 1;
        timeout = t;   
}

int main(){
    wiringPiSetup(); //initialise wiringPi
    pinMode (data0, INPUT); // set data0 as input
    pinMode (data1, INPUT); // set data1 as input
    
    wiringPiISR(data0, INT_EDGE_FALLING, bit0); // set interrupt on data 0 if it falls call bit0 function
    wiringPiISR(data1, INT_EDGE_FALLING, bit1); // set interrupt on data 1 if it falls call bit1 function
    while (1){ //loop
                if (bit_count > 0 ){ //if bits is not empty
                    timeout--; // reduce timeout by 1
                    if(timeout == 0){ //and it has timed out ie no more bits coming
            //printf("%X\n", bits); //for testing
            pthread_create(&thread0, NULL, python_thread,bits); //start new thread for python program
            bit_count = 0; //reset bit count
            bits = blank; //clear bits cariable
            timeout = t; //reset timeout
                    }
                }
     delay(1);
    }
    return 0;
}
Python Code (Not yet implemented this simply prints the badge number in binary hex and decimal.

Code: Select all

#!/usr/bin/env python
import sys

def set_procname(newname):
    from ctypes import cdll, byref, create_string_buffer
    libc = cdll.LoadLibrary('libc.so.6')    #Loading a 3rd party library C
    buff = create_string_buffer(len(newname)+1) #Note: One larger than the name (man prctl says that)
    buff.value = newname                 #Null terminated string as it should be
    libc.prctl(15, byref(buff), 0, 0, 0) #Refer to "#define" of "/usr/include/linux/prctl.h" for the misterious value 16 & arg[3..5] are zero as the man page says.
    
set_procname("pi access")
print "Hex", sys.argv[1]
dec = int(str(sys.argv[1]),16)
print "Dec",dec
print "Bin",bin(dec)[2:]

IrishHayZeus
Posts: 6
Joined: Tue May 07, 2013 6:35 pm

Re: RPi.GPIO Wiegand capture speed?

Wed Oct 30, 2013 11:02 pm

This is awesome! I had just ordered a Wiegand RFID/Keypad and door strike to do the same thing, and was debating a Pi for the smarts. Glad to know I wasn't about to reinvent the wheel. Would someone (Joan? kghunt?) mind posting a schematic of their interface? I'm concerned about the 3.3v/5v difference. I saw the circuit that was in the 2nd or 3rd post, but I couldn't see all the detail.

I would love to see this developed into a PCB, with a relay, buzzer/LED, and a door release button, that could be neatly packaged. Anyone have any expertise on that? (I'm mostly a C-coder). I'm looking for a similar setup as SteveBird, only I'm hoping to control access to a photo/video studio that I'll rent by the day. Since I'm dealing with some expensive equipment, I'm also hoping to utilize the Pi Camera to snapshot the person swiping the card/entering the access code, and storing it in the audit log.

Cheers!

kghunt
Posts: 383
Joined: Sun Mar 04, 2012 9:28 am

Re: RPi.GPIO Wiegand capture speed?

Thu Oct 31, 2013 7:14 am

I just use a voltage divider to drop the Wiegand output to 2.5v.

Its funny you should say that I have been trying to design a pub in fritzing with a reader interface an output relay and an rtc.

It's hard work. I have never designed a pcb like this before.
I originally started with 2 reader inputs and 2 relay outputs but It got a bit busy so I might have another go but with one reader interface and get that working first.

I was planning to power the board by 12v so I can use this for the readers and locks then step it down to 5v to power the pi itself.

kghunt
Posts: 383
Joined: Sun Mar 04, 2012 9:28 am

Re: RPi.GPIO Wiegand capture speed?

Thu Oct 31, 2013 4:54 pm

Not pretty but here is a jpeg of my PCB. They alignment could be better but I have everything on there except an RTC. I will add the RTC soon.

Image

User avatar
paddyg
Posts: 2340
Joined: Sat Jan 28, 2012 11:57 am
Location: UK

Re: RPi.GPIO Wiegand capture speed?

Fri Nov 01, 2013 11:12 am

As a bit of an aside, but related to occasionally needing high speed GPIO from python: I noticed a post by @Antares here asking for some general speeding up thoughts for his python. I ended up doing a couple of experiments using Cython, encapsulating Ben Croston's RPi.GPIO c code unaltered from here. Where I put the looping into a cython function I went from an average time per GPIO.output of 15 micro seconds to 0.05 micro seconds = 300 x faster! No understanding of or coding in C required.
also https://groups.google.com/forum/?hl=en-GB&fromgroups=#!forum/pi3d

IrishHayZeus
Posts: 6
Joined: Tue May 07, 2013 6:35 pm

Re: RPi.GPIO Wiegand capture speed?

Thu Nov 14, 2013 7:54 pm

Pi-Wiegand & Latch.png
Here is the start of my schematic. Component values are wrong.
Pi-Wiegand & Latch.png (55.75 KiB) Viewed 6713 times
I finally got my tags, strike and keypad/reader in. I've been poking around with it on an Arduino, but now I'm ready to start digging in with the Pi.

Kghunt, would you mind posting the schematic view of yours? My Strike is 300ma 12VDC, and so I'm considering using a 12VDC supply, and using a MOSFET to drive the strike. I still want to have a second output that I'm considering using as an illumination for the Pi Camera, and am debating between a second 12VDC LED driver, or a relay. The relay is more flexible.

Anyway, I'm thinking of doing the voltage divider as well to get the voltages down to Pi-levels. The schematic early on in this thread isn't really clear to me, and so I'm a little confused by it.

IrishHayZeus
Posts: 6
Joined: Tue May 07, 2013 6:35 pm

Re: RPi.GPIO Wiegand capture speed?

Tue Dec 03, 2013 12:31 am

I finally got all my components together to actually start working with my Wiegand reader on the Pi. I found the code from http://pidoorman.com as a starting point, but was disappointed with its reliability. So, I rewrote it. It's written to be used as a very, very lightweight, but hopefully robust API. It should be fairly self explanatory. I would be interested in hearing from others of successes of problems.

http://irishjesus.wordpress.com/2013/12 ... gand-rfid/

squiggleuk
Posts: 12
Joined: Wed Jun 05, 2013 12:37 pm

Re: RPi.GPIO Wiegand capture speed?

Sat Feb 15, 2014 7:06 pm

Hi guys,

A little late to the party, but just ordered another pi, piface, wiegand rfid reader, and door strike.

Plan is to make RIFD entry system, where the pi checks with against a Microsoft Active Directory server to find if the card is registered to anyone, check if their account is active, and opens the door if it is - the AD integration is the easy part for me!

Hoping to use the code that kghunt posted (Thu Jul 11, 2013 3:15 pm) - Not really used wiringpi libs before - nor the wiringpi piface extra bits - can anyone foresee any issues with doing this via the piface?

squiggleuk
Posts: 12
Joined: Wed Jun 05, 2013 12:37 pm

Re: RPi.GPIO Wiegand capture speed?

Wed Aug 27, 2014 2:53 pm

kghunt/irish...

Did either of you ever look into a PCB shield for the pi that would attach to the pi?

Using code from this thread, I managed to get the pi reading cards fine, then also integrated it with our active directory system at work (That's the system that manages usernames, passwords etc on corporate networks if you're not a sysadmin style geek!)

The nice thing here is that card numbers are centrally managed and entered as a field in each users account. When a user account is disabled or expires in active directory, the card automatically stops allowing access to doors.

An addon board that would allow connection of 2 wiegand readers (in/out) each with LED/Buzzer connections, door strike control, emergency exit button, with 12v power input that steps down to 5v to power the pi would be great. Although having had a bit of a try, it's looking like it is well beyond my electronics skills!!

IrishHayZeus
Posts: 6
Joined: Tue May 07, 2013 6:35 pm

Re: RPi.GPIO Wiegand capture speed?

Wed Aug 27, 2014 4:20 pm

I ended up prototyping my own... I used a proto board with the ribbon cable to connect to the Pi. I'm considering redesigning it around an Adafruit Pi Plate board ( http://www.adafruit.com/products/801 ) just to tighten up the foot print. The actual components to do the door strike were pretty minimal. A MOSFET and two or three support components.

Return to “Python”