Page : | [ 1 ] | [ 2 ] | [ 3 ] | [ 4 ] | [ 5 ] | [ 6 ] |
Software on Pi
Will be needing some software for listing to the data sent from the card readers. Luckily the PIGPIO site has some excellent examples and just so happens to have some Wiegand examples!
Since I plan to interact with the GPIO wia the PIGPIOD daemon then I will need the correct examples and code considerations going forward.
cd ~/
mkdir wiegand
cd wiegand
wget http://abyz.co.uk/rpi/pigpio/code/WD.zip
unzip WD.zip
gcc -Wall -pthread -o WD test_WD.c WD.c -lpigpiod_if2
The wiring of the data wires from the card readers are as follows:
Door 1
======
D0 gpio 14
D1 gpio 15
Door 2
======
D0 gpio 24
D1 gpio 23
Test the code by running it like this. (e.g. for "Door 1") I had to add -m3500 because the default of -m2000 didn't seem to accumulate all the bits before sending them back. -m3500 gave the correct results of reading all the bits properly.
./WD -g14 -w15 -m3500
Now scan the card reader. You should see some output that shows the card number and how many bits.
Create a databse for the system to use. Login to MySQL and do the following:
create database rfid;
use rfid;
create table card(
cardId int unsigned not null primary key auto_increment,
facility int unsigned,
number int unsigned,
isMaster tinyint unsigned not null default 0,
label varchar(16),
person varchar(32),
isVisible tinyint unsigned not null default 1
);
create unique index ix_card_facility_num on card (facility, number);
create table location(
locationId int unsigned not null primary key auto_increment,
locationName varchar(32) unique
);
create table locationCard(
locationCardId int unsigned not null primary key auto_increment,
cardId int unsigned not null,
locationId int unsigned not null,
isVisible tinyint unsigned not null default 1
);
create unique index ix_locationcard_cid_lid on locationCard (cardId, locationId);
create table locationCardDayTime(
locationCardDayTimeId int unsigned not null primary key auto_increment,
locationCardId int unsigned,
day int,
begin varchar(8),
end varchar(8)
);
create table history(
historyId int unsigned not null primary key auto_increment,
locationCardId int unsigned,
inserted timestamp not null default now()
);
A little data populating for testing:
insert into location (locationName) values ('DOOR_01');
Modify the wiegand example a bit for my own use. just edited their example file "test_WD.c".
/*
TO BUILD
gcc -Wall -pthread -o WD test_WD.c WD.c -lpigpiod_if2
TO RUN
./WD -gGPIO -wGPIO
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <unistd.h>
#include <pigpiod_if2.h>
#include "WD.h"
#define false 0
#define true 1
typedef int bool;
void fatal(char *fmt, ...){
char buf[128];
va_list ap;
va_start(ap, fmt);
vsnprintf(buf, sizeof(buf), fmt, ap);
va_end(ap);
fprintf(stderr, "%s\n", buf);
fflush(stderr);
exit(EXIT_FAILURE);
}
void usage(){
fprintf(stderr, "\n" \
"Usage: WD [OPTION] ...\n" \
" -g value, gpio green (0), 0-31, default None\n" \
" -w value, gpio white (1), 0-31, default None\n" \
" -m value, message gap, 1000-65000 micros, default 2000\n" \
" -l string, location, default NULL\n" \
" -r value, relay, default none\n" \
"EXAMPLE\n" \
"WD -g10 -w12 -m3500 -r17 -lDOOR_01\n" \
" Read a Wiegand device connected to GPIO 10/12.\n\n");
}
int optGpioGreen = -1;
int optGpioWhite = -1;
int optGap = 3500;
int optRelay = -1;
char *optLocation = NULL;
bool masterMode = false; // if in master mode
double startMasterMode; // when master mode started
char outBuffer[512]; // bufferfor command to call php script
bool doorOpen = false; // should door be currently open
double startDoorOpen; // time door opened
static uint64_t getNum(char *str, int *err){
uint64_t val;
char *endptr;
*err = 0;
val = strtoll(str, &endptr, 0);
if (*endptr) {*err = 1; val = -1;}
return val;
}
static void initOpts(int argc, char *argv[]){
int opt, err, i;
while ((opt = getopt(argc, argv, "g:w:m:l:r:")) != -1){
switch (opt){
case 'g':
i = getNum(optarg, &err);
if ((i >= 0) && (i <= 31)) optGpioGreen = i;
else fatal("invalid -g option (%s)", optarg);
break;
case 'w':
i = getNum(optarg, &err);
if ((i >= 0) && (i <= 31)) optGpioWhite = i;
else fatal("invalid -w option (%s)", optarg);
break;
case 'm':
i = getNum(optarg, &err);
if ((i >= 1000) && (i <= 65000)) optGap = i;
else fatal("invalid -m option (%s)", optarg);
break;
case 'r':
i = getNum(optarg, &err);
if ((i >= 0) && (i <= 31)) optRelay = i;
else fatal("invalid -r option (%s)", optarg);
break;
case 'l':
optLocation = malloc(sizeof(optarg)+1);
if (optLocation) strcpy(optLocation, optarg);
break;
default: /* '?' */
usage();
exit(-1);
}
}
}
void cbf(WD_data_t w){
sprintf(outBuffer,"/usr/bin/php /var/www/html/wiegand.php \"%llu\" \"%d\" \"%s\" \"%d\" ", (long long)w.code, w.bits, optLocation, masterMode);
int i = system(outBuffer);
if (i == 1024){
if (!masterMode){
doorOpen = true;
startDoorOpen = time_time();
} else {
doorOpen = false;
}
} else if (i == 1280) {
doorOpen = false;
masterMode = true;
startMasterMode = time_time();
}
}
int main(int argc, char *argv[]){
int pi;
WD_t * w;
initOpts(argc, argv);
if ((optGpioGreen < 0) || (optGpioWhite < 0) || (optRelay < 0) || (optGpioGreen == optGpioWhite)){
fprintf(stderr, "You must specify the green and white and relay GPIO.\n");
exit(0);
}
if (optLocation == NULL){
fprintf(stderr, "You must specify a location. i.e. DOOR_01\n");
exit(0);
}
pi = pigpio_start(NULL, NULL); /* Connect to Pi. default host, port */
if (pi >= 0){
w = WD(pi, optGpioGreen, optGpioWhite, optGap, cbf);
while(1){
if (masterMode){
if ((time_time() - startMasterMode) < 10.0){
masterMode = true;
} else {
masterMode = false;
}
} else {
if (doorOpen){
if ((time_time() - startDoorOpen) < 5.0){
doorOpen = true;
gpio_write(pi,optRelay, 0);
} else {
doorOpen = false;
gpio_write(pi,optRelay, 1);
}
}
}
usleep(250000);
}
WD_cancel(w);
pigpio_stop(pi);
}
return 0;
}
Build it and copy it to an appropriate location:
gcc -Wall -pthread -o WD test_WD.c WD.c -lpigpiod_if2
sudo cp WD /usr/local/bin
Then add this to "/etc/rc.local" for it to run when the Pi boots and will "listen" to the card reader.
sudo pico -w /etc/rc.local
#add the following to /etc/rc.local
# in this example i have D0 and D1 of
# the card reader going to GPIO 14 and 15 of the Pi
# the signal GPIO for the relay in my setup is 17
# also i named this particular location "DOOR_01"
# which was previously inserted into the location
# table of the database
/usr/local/bin/WD -g14 -w15 -r17 -m5000 -lDOOR_01 > /dev/null &
(Page 5 of 6) | ||