Before I begin, I am a fellow programmer who learnt how to program by myself and it just started 2 months ago.
I am glad this forum exists to help fellow Arduino lovers and right now I do need some guidances about WIEGAND 26bits format device to communicate with ARDUINO UNO board.
So, from there I have a few problems that are too complicated to solve on my own, so I seek some pointers from readers here.
To begin,
I am using ARDUINO UNO board shown in the link.
And this is my fingerprint device whose communications are RS232 to PC and WIEGAND to ARDUINO.
http://www.futronic-tech.com/product_fs20.html
Lastly, this is my 2 relays board circuit connection.
The purpose of all these shown above is to get a fingerprint device to transmit signals of 26bits to Arduino UNO and then UNO will operate either relay depends on the user selection from the fingerprint device.
Which means UNO will have to operate as a "Converter or Middleman" between the fingerprint device and the 2 relays.
And so, problems surface as I edit Crazy People's arduino sketch from Crazy People
/* Crazy People
* By Mike Cook April 2009
* One Fingerprint Reader outputing 26 bit Wiegand code to pins:-
* Reader A (Head) Pins 4 & 5
* Interrupt service routine gathers Wiegand pulses (zero or one) until 26 have been recieved
* Then a sting is sent to processing
*/
#include "pins_arduino.h"
/*
* an extension to the interrupt support for arduino.
* add pin change interrupts to the external interrupts, giving a way
* for users to have interrupts drive off of any pin.
*/
/*
* Theory: all IO pins on Atmega168 are covered by Pin Change Interrupts.
* The PCINT corresponding to the pin must be enabled and masked, and
* an ISR routine provided. Since PCINTs are per port, not per pin, the ISR
* must use some logic to actually implement a per-pin interrupt service.
*/
/* Pin to interrupt map:
* D0-D7 = PCINT 16-23 = PCIR2 = PD = PCIE2 = pcmsk2
* D8-D13 = PCINT 0-5 = PCIR0 = PB = PCIE0 = pcmsk0
* A0-A5 (D14-D19) = PCINT 8-13 = PCIR1 = PC = PCIE1 = pcmsk1
*/
volatile uint8_t *port_to_pcmask[] = {
&PCMSK0,
&PCMSK1,
&PCMSK2
};
typedef void (*voidFuncPtr)(void);
volatile static voidFuncPtr PCintFunc[24] = {
NULL };
volatile static uint8_t PCintLast[3];
/*
* attach an interrupt to a specific pin using pin change interrupts.
* First version only supports CHANGE mode.
*/
void PCattachInterrupt(uint8_t pin, void (*userFunc)(void), int mode) {
uint8_t bit = digitalPinToBitMask(pin);
uint8_t port = digitalPinToPort(pin);
uint8_t slot;
volatile uint8_t *pcmask;
if (mode != CHANGE) {
return;
}
// map pin to PCIR register
if (port == NOT_A_PORT) {
return;
}
else {
port -= 2;
pcmask = port_to_pcmask[port];
}
slot = port * 8 + (pin % 8);
PCintFunc[slot] = userFunc;
// set the mask
*pcmask |= bit;
// enable the interrupt
PCICR |= 0x01 << port;
}
void PCdetachInterrupt(uint8_t pin) {
uint8_t bit = digitalPinToBitMask(pin);
uint8_t port = digitalPinToPort(pin);
volatile uint8_t *pcmask;
// map pin to PCIR register
if (port == NOT_A_PORT) {
return;
}
else {
port -= 2;
pcmask = port_to_pcmask[port];
}
// disable the mask.
*pcmask &= ~bit;
// if that's the last one, disable the interrupt.
if (*pcmask == 0) {
PCICR &= ~(0x01 << port);
}
}
// common code for isr handler. "port" is the PCINT number.
// there isn't really a good way to back-map ports and masks to pins.
static void PCint(uint8_t port) {
uint8_t bit;
uint8_t curr;
uint8_t mask;
uint8_t pin;
// get the pin states for the indicated port.
curr = *portInputRegister(port+2);
mask = curr ^ PCintLast[port];
PCintLast[port] = curr;
// mask is pins that have changed. screen out non pcint pins.
if ((mask &= *port_to_pcmask[port]) == 0) {
return;
}
// mask is pcint pins that have changed.
for (uint8_t i=0; i < 8; i++) {
bit = 0x01 << i;
if (bit & mask) {
pin = port * 8 + i;
if (PCintFunc[pin] != NULL) {
PCintFunc[pin]();
}
}
}
}
SIGNAL(PCINT0_vect) {
PCint(0);
}
SIGNAL(PCINT1_vect) {
PCint(1);
}
SIGNAL(PCINT2_vect) {
PCint(2);
}
// End of interrupts code and start of the reader code
volatile long reader1 = 0;
volatile int reader1Count = 0;
void reader1One(void) {
if(digitalRead(4) == LOW){
reader1Count++;
reader1 = reader1 << 1;
reader1 |= 1;
}
}
void reader1Zero(void) {
if(digitalRead(5) == LOW){
reader1Count++;
reader1 = reader1 << 1;
}
}
void setup()
{
Serial.begin(57000);
// Attach pin change interrupt service routines from the Wiegand Fingerprint reader
PCattachInterrupt(4, reader1One, CHANGE);
PCattachInterrupt(5, reader1Zero, CHANGE);
delay(10);
// the interrupt in the Atmel processor misses out the first negative pulse as the inputs are already high,
// so this gives a pulse to each reader input line to get the interrupts working properly.
// Then clear out the reader variables.
// The readers are open collector sitting normally at a one so this is OK
for(int i = 4; i<10; i++){
pinMode(i, OUTPUT);
digitalWrite(i, HIGH); // enable internal pull up causing a one
digitalWrite(i, LOW); // disable internal pull up causing zero and thus an interrupt
pinMode(i, INPUT);
digitalWrite(i, HIGH); // enable internal pull up
}
delay(10);
// put the reader input variables to zero
reader1 = 0;
reader1Count = 0;
digitalWrite(13, HIGH); // show Arduino has finished initialization
}
void loop() {
if(reader1Count >= 26){
// Serial.print(" Reader 1 ");Serial.println(reader1,HEX);
Serial.println("A");Serial.println(reader1 & 0xfffffff);
reader1 = 0;
reader1Count = 0;
}
}
According to this sketch above, it is supposed to transmit 26bits signals over to arduino UNO in the form of 32bits, right?
From the picture above, HOW do I make the UNO to read only the USER CODE from WIEGAND so that I can get my fingerprint to match with the USER CODE and then I can choose to select which RELAY LED to activate? It's the even parity bit that is in the way...
Problem 1: Removing the parity bit and get only the USER CODE so that I can get my fingerprint ID to match with it.
Problem 2: How do I get PIN 10 or PIN 11 to activate when I have successfully match my fingerprint ID with the USER CODE and I have to select relay?
I seek your expertise in this area, readers!