WIEGAND 26bits format to Arduino UNO. Requesting guidances.

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 http://www.thebox.myzen.co.uk/Hardware/Crazy_People.html

/* 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!

did you try http://github.com/monkeyboard/Wiegand-Protocol-Library-for-Arduino ?

The standard Wiegand format had one parity bit, 8 bits of facility code, 16 bits of ID code, and a trailing parity bit for a total of 26 bits. The first parity bit is calculated from the first 12 bits of the code and the trailing parity bit from the last 12 bits. Yours is seem like standard.

sonnyyu, the link you provided is included with a library that is not working correctly on my sketch because Arduino is unable to import .cpp and .h from that file.

Yes, my sketch is standard. All I need to understand is how am I able to extract the USER CODE (16bits) from the 26bits WIEGAND so that I can bring it over to my LED RELAY CONTROL as a known variable.

From there, I am stuck.

Updated: alright, it is working now. from what I see from the link above, I don't think it is capable of storing 26 bits value to EEPROM since I need to store a 26bits WIEGAND value of which only 16bit out of 26bit is what I really need in order to do ID MATCHING.

Take the 26 bit Weagand code into a long int variable. Shift it to the right one place and mask out the lower 16 bits to just give you the user code.

user = ( weagand >> 1) & 0xffff;

Yes, I found how how to shift bits register to the right by 1 bit to "remove" the odd parity and mask out the other bits. THANK YOU!

Now, next to a bigger problem yet.

How do I convert the newly read bits onto EEPROM? I heard it uses 12 bits formats?

Sigh, converting bits formats are really troublesome.

updated:

according to http://forum.arduino.cc/index.php?topic=157574.0

I have to break down 26 bits WIEGAND format into separate byte on which I must get USERID bits to break down into 16 different bits. Am I correct on this?

It is much simpler and is just a variant on what you have done already. You have removed both parity bits so younare left with 24 bits or three bytes. Just convert them into bits by shift and mask and store the bits in EEPROM.

From what I see, I had only removed the even parity. I do not know how to remove the odd parity.

/* 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 & 0xffff;  // user = ( weagand >> 1) & 0xffff;
  reader1 |= 1;
  }
}

void reader1Zero(void) {
  if(digitalRead(5) == LOW){
  reader1Count++;
  reader1 = reader1 >> 1 & 0xffff;  // user = ( weagand >> 1) & 0xffff;
  }
}


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 mises out the first negitave 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 initilisation
}

void loop() {
  if(reader1Count >= 26){
//  Serial.print(" Reader 1 ");Serial.println(reader1,HEX);
  Serial.println("A");Serial.println(reader1 & 0xfffffff);
  reader1 = 0;
  reader1Count = 0;
     }
}

Your helpful code had been modified into my reader1One and reader1Zero

So by doing that I am left with 25 bit signal with only the userID bit not masked instead.

0xFFFF is 16 bit values of all 1, right? meaning the 16bit all 1 is on USERID code? Why is it masked? Can the arduino send the masked userID over to selection of LED 1 or LED 2 by using case select structure?

Another thing about EEPROM,

#include 

#define EEPROM_MAX 1024 // Maximum capacity of the EEPROM memory

void EEPROMClearMemory() {
  for (int addr=0;addr> 0) & 0xFF);
  byte Byte2 = ((p_value >> 8) & 0xFF);
  byte Byte3 = ((p_value >> 16) & 0xFF);
  byte Byte4 = ((p_value >> 24) & 0xFF);

  EEPROM.write(p_address, Byte1);
  EEPROM.write(p_address + 1, Byte2);
  EEPROM.write(p_address + 2, Byte3);
  EEPROM.write(p_address + 3, Byte4);
}

long EEPROMReadLong(int p_address)
{
  byte Byte1 = EEPROM.read(p_address);
  byte Byte2 = EEPROM.read(p_address + 1);
  byte Byte3 = EEPROM.read(p_address + 2);
  byte Byte4 = EEPROM.read(p_address + 3);

  long firstTwoBytes = ((Byte1 << 0) & 0xFF) + ((Byte2 << 8) & 0xFF00);
  long secondTwoBytes = (((Byte3 << 0) & 0xFF) + ((Byte4 << 8) & 0xFF00));
  secondTwoBytes *= 65536; // multiply by 2 to power 16 - bit shift 24 to the left

  return (firstTwoBytes + secondTwoBytes);
}

From the EEPROM sketch above, First the memory inside, the stored values will be cleared. 0 values all over. That is the purpose of EEPROMClearMemory.

Then, the program will start to write values from somewhere, assuming WIEGAND 26bit. From EEPROMWriteLong, I am unable to comprehend the functions operated. May I have your guidance to explain this to me?

Finally, in EEPROMReadLong, From what I see, it will call the EEPROMWriteLong void and get the 4 bytes over to, assuming LEDS as outputs. Am I right on this?

I do not know how to remove the odd parity.

 removed = number & 0xfffff;

That will take the top bit out and give you a variable of only 24 bits. This will need only 3 bytes of EEPROM to store the two numbers from the card.

0xFFFF is 16 bit values of all 1, right?

Yes

meaning the 16bit all 1 is on USERID code?

No. If you apply a mask to a variable using a a bitwise and operation & then all the bits in the variable with a corresponding bit of zero in the mask will give a zero in the result. All the bits in the variable with a corresponding bit of one in the mask will leave the bit in the result the same as it was in the original variable. So the bitwise and operation & selectively clears bits. So applying a mask of 0xffff will leave only the two least significant bytes of the three byte number.

I don't know what you mean by:-

assuming LEDS as outputs

Grumpy_Mike:

I do not know how to remove the odd parity.

 removed = number & 0xfffff;

That will take the top bit out and give you a variable of only 24 bits. This will need only 3 bytes of EEPROM to store the two numbers from the card.

volatile long reader1 = 0;
volatile int reader1Count = 0;

void reader1One(void) {   if(digitalRead(4) == LOW){   reader1Count++;   reader1 = reader1 >> 1 & 0xffff;   reader1 |= 1;   } }

void reader1Zero(void) {   if(digitalRead(5) == LOW){   reader1Count++;   reader1 = reader1 >> 1 & 0xffff;    } }



By putting this [ removed = number & 0xfffff; ] to the 2 voids above, this is puzzling me, if I want to remove the even parity bit, I should put the code that you gave me at AFTER the count++; or after the shift register;?

I don't know what you mean by:-


> assuming LEDS as outputs


For this EEPROM, what I meant was that is EEPROM capable of sending a 16 bit signal from the EEPROM memory over to the output pin where I write a program about ID MATCHING?

And by doing that, I must verify (match, I mean,) the EEPROM variable = USERID CODE from WIEGAND variable right? So if the EEPROM 16bits signal matches the USERID CODE from WIEGAND, the output pin which has a LED will light on.

So for this operation, is it possible? I just started learning C++ and I am getting the hang of it thank to you, Grumpy_Mike. I am surprised you have a high level of tolerance towards new comers like me. You make a great teacher. Thank you for the big help, again!! 

I still do not get the EEPROM operations of reading and writing at all.. Where are the stored values being called upon and stayed into? Especially the calling part, I need to call out the variable before I break it down into 4 bytes or call the byte 1 by 1? And by calling, it means by writing or reading?

By putting this removed = number & 0xfffff; to the 2 voids above, this is puzzling me,

No you do it after all 26 bits of the wiegand code has been inputted. So:-

void loop() {
  if(reader1Count >= 26){
 long int rawToken = (reader1 >> 1) & 0xffffff); // remove both parity bits
 int facilityCode = rawToken >> 16; // just get the top 8 bits
 int userID = rawToken & 0xffff; // bottom 16 bits are the user code
  Serial.print("Facility Code ");
  Serial.println(facilityCode); // use Serial.println(facilityCode, HEX); // to see the result in hex
  Serial.print("User ID ");
  Serial.println(userID);

  reader1 = 0;
  reader1Count = 0;
     }
}

Now you need to find a place in EEPROM to store it, you need only 3 bytes to store this so you invent a number called say slot which is the number which you use to identify what virtual slot you will store it in. The "real" point in the EEPROM is thus three times this slot number. So you can write a function that stores the token in a slot number:-

void storeToken(int slot, long int token){
 int byteAddress = slot * 3; // the start point of where you will store it in EEPROM
   EEPROM.write(byteAddress, token >> 16); // store facility code
   EEPROM.write(byteAddress + 1, (token >> 8) & 0xff); // store upper 8 bits of id
   EEPROM.write(byteAddress + 2,  token  & 0xff); // store lower 8 bits of id
}

and you can write the corresponding one that retrieves the token:-

long int getToken(int slot){
 long int recoverdToken;
 int byteAddress = slot * 3; // the start point of where you will store it in EEPROM
   recoverdToken = EEPROM.read(byteAddress) << 16;
   recoverdToken |= EEPROM.read(byteAddress + 1) << 8; // note the |= is an OR operation on the existing variable
   recoverdToken |= EEPROM.read(byteAddress + 2);
return recoverdToken;
}

So the whole of the token value minus parity bits is in a long int variable and you can use the normal if == to test it.

if(rawToken == getToken(0) ) { // do this if the value in rawToken matches what is in the first slot
// do stuff
}

This of course will be in a loop where getToken(0) is replaced by getToken(i) with i being the loop variable.

Grumpy_Mike, thank you so much for the teaching of EEPROM to me! Now that I have read all about EEPROM, I finally understand the operation of EEPROM. REALLY THANK YOU A LOT!

I had tested the WIEGANDtoARDUINO sketch and... I will show you the full sketch first.

And the serial monitor print out 4 times after scanning my fingerprint for 4 times.

Facility Code 0
User ID 0
Facility Code 0
User ID 0
Facility Code 0
User ID 0
Facility Code 0
User ID 0

Why are they zeroes? I removed the masked bits and the shift register and the serial monitor still shows 0 for userid and facility codes. I used the oscilloscope to test D1 and GND, D0 and GND. They showed the correct electrical format similarly shown in the wiegand format.

4 different fingerprint scans and they all yield 0 in both facility and userid.

Updated:

/* 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; // shift value right to remove odd parity in D1
    reader1 |= 1;

  }
}

void reader1Zero(void) {
  if(digitalRead(5) == LOW){
    reader1Count++;
    reader1 = reader1 << 1;  // shift value right to remove odd parity in D0
  }
}


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 mises out the first negitave 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 initilisation
}

void loop() {
  if(reader1Count >= 26){
    long int rawToken = ((reader1 >> 1) & 0xffffff); // remove both parity bits
    int facilityCode = rawToken >> 16; // just get the top 8 bits
    int userID = rawToken & 0xffff; // bottom 16 bits are the user code
    Serial.print("Facility Code ");
    Serial.println(facilityCode); // use Serial.println(facilityCode, HEX); // to see the result in hex
    Serial.print("User ID ");
    Serial.println(userID);

    reader1 = 0;
    reader1Count = 0;
  }
}

The facility code and userid have been set correctly. The bits register at the reader1zero/one void setup is wrong so I change from >> 1 to << 1.

Everything from wiegand to arduino has been setup correctly, mostly thank to you! Thank you! In my next post, I have a question about EEPROM.

According to;

/* Crazy People
 * By Mike Cook April 2009
 * One Fingerprint Reader outputing 26 bit Wiegand code to pins:-
 * Reader A (Head) Pins 4 & 5 (pin 4 = data1, pin 5 = data0)
 * 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; // shift value right to remove odd parity in D1
    reader1 |= 1;

  }
}

void reader1Zero(void) {
  if(digitalRead(5) == LOW){
    reader1Count++;
    reader1 = reader1 << 1;  // shift value right to remove odd parity in D0
  }
}


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 mises out the first negitave 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 initilisation
}

void loop() {
  if(reader1Count >= 26){
    long int rawToken = ((reader1 >> 1) & 0xffffff); // remove both parity bits
    int facilityCode = rawToken >> 16; // just get the top 8 bits
    int userID = rawToken & 0xffff; // bottom 16 bits are the user code
    Serial.print("Facility Code ");
    Serial.println(facilityCode); // use Serial.println(facilityCode, HEX); // to see the result in hex
    Serial.print("User ID ");
    Serial.println(userID);

    reader1 = 0;
    reader1Count = 0;
  }
}

Include EEPROM.H and the program will call the library, so..

void storeToken(int slot, long int token){
 int byteAddress = slot * 3; // the start point of where you will store it in EEPROM
   EEPROM.write(byteAddress, token >> 16); // store facility code
   EEPROM.write(byteAddress + 1, (token >> 8) & 0xff); // store upper 8 bits of id
   EEPROM.write(byteAddress + 2,  token  & 0xff); // store lower 8 bits of id
}

storeToken is a void function, with slot as integer and token as long integer. Under EEPROM.write, byteAddress integer is referring to the name of the variable for the starting point where I will start to store my USERID and facility code in. (16bits / 2 and the facility code 8bits) ??? Am I right?

So in other words, byteAddress is actually the combined of 24bits without the even and odd parity?

or

Is the byteAddress referring to the 16bits USERID that print out in serial monitor?

byteAddress+1 and +2 is to move to the next point, this I understand.

Now, my project only wants up to 15 people to use 2 lockers. So that means binary 1 1 1 1 = 15 in dec and F in hex. So in userid I will only take last 4 bits value since 1111max is 15 people

So I write only 1 bytes for 1 address, needing only the last 4 bits of userID. facility code does not matter. Hence,

//EEPROM
void storeToken(int slot, long int token){
 int byteAddress = slot * 1; // the start point of where you will store it in EEPROM
   EEPROM.write(byteAddress, (token <<20) & 0xff); // store last 4 bits of userID

Is the code above correct? I suck at shifting registers since I am new to binary registers in C++ Now I am not sure where to call the storeToken(int,long int). Is it inside the loop and inside the if loop? It shows up argument errors if I put that.

Now this is my draft sketch of ALL in 1 sketch, WIEGAND to ARDUINO to EEPROM

#include 

/* 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; // shift value left to remove even parity in D1
    reader1 |= 1;

  }
}

void reader1Zero(void) {
  if(digitalRead(5) == LOW){
    reader1Count++;
    reader1 = reader1 << 1;  // shift value left to remove even parity in D0
  }
}
//EEPROM
void storeToken(int slot, long int token){
  int byteAddress = slot * 1; // the start point of where you will store it in EEPROM
  EEPROM.write(byteAddress, (token <<20) & 0xff); // store last 4 bits of userID
}

long int getToken(int slot){
  long int recoverdToken;
  int byteAddress = slot * 1; // the start point of where you will store it in EEPROM
  recoverdToken = EEPROM.read(byteAddress) >> 20; // call out userid of last 4 bits from EEPR
  return recoverdToken;
}


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 mises out the first negitave 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 initilisation
}

void loop() {
  if(reader1Count >= 26){
    long int rawToken = ((reader1 >> 1) & 0xffffff); // remove both parity bits
    int facilityCode = rawToken >> 16; // just get the top 8 bits
    int userID = rawToken & 0xffff; // bottom 16 bits are the user code
    Serial.print("Facility Code ");
    Serial.println(facilityCode); // use Serial.println(facilityCode, HEX); // to see the result in hex
    Serial.print("User ID ");
    Serial.println(userID);
    reader1 = 0;
    reader1Count = 0;
    
 //calling out storeToken function... how??
   storeToken(userID,userID); // not sure what to call int and long int variables.
  Serial.print("16 bit is: ");
  Serial.println(userID,DEC); //not sure what int slot to call?
  Serial.print("userID is : ");
  Serial.println(userID,BIN); // not sure about this too
  
    if(rawToken == getToken(0) ) { // do this if the value in rawToken matches what is in the first slot
Serial.println(rawToken);
}
  }


}

I want serial monitor to tell me that I have successfully store my last(most right) 4bits of 16bits userID and call the bytes.

Please tell me what should I do next...

Do not put the store function inside the loop function. You only want to store stuff when you have new stuff to store, otherwise if you do it constantly you will damage the EEPROM it only has 10,000 write cycles and while that sounds a lot you can exceed it in a few minutes if you put it in the wrong place.

You basically have two modes of operation, new token enrolling and verifying tokens, make sure you have that distinction clear in your mind before writing code.

So in other words, byteAddress is actually the combined of 24bits without the even and odd parity?

No the variable called byteAddress points to the location where you will store your data,

Now, my project only wants up to 15 people to use 2 lockers.

So you need 15 slots, don't worry about the byteAddress that is low level stuff, as far as your code is concerned just use slots, one for each token you want to store. The fact that the function turns this into an address you can conveniently forget when writing the code.

So in userid I will only take last 4 bits value since 1111max is 15 people

No. I have no idea what you are thinking here.

Is the code above correct?

no

EEPROM.write(byteAddress, (token <<20) & 0x0f); // store last 4 bits of userID

It shows up argument errors if I put that.

No it only show up argument errors if you have an error in the arguments of the function, that is the numbers you are giving it when you call it.

Grumpy_Mike:

You basically have two modes of operation, new token enrolling and verifying tokens, make sure you have that distinction clear in your mind before writing code.

yeah. enrolling tokens means all the 15 slots inside EEPROM has the values from 0000 to 1111 stored. verifying means 15 users' fingerprint ID of last 4 bits must match with the 15 slots respectively.

No. I have no idea what you are thinking here.

My project is to get 15 users to register their fingerprint into wiegand (wiegand device can store fingerprint id). So after 15 users registered in WIEGAND, I also want the 15 users to register to EEPROM as well. EEPROM is to represent which 2 lockers for which of the 15 users are in use. Meaning if EEPROM store 0011 and the user which is 0011 scan via WIEGAND and prompt success with EEPROM, locker 2 which has been registered before will open ONLY TO 0011. (it's similar to one fingerprint device = one locker concept, but my concept is one fingerprint device, 15 fingerprint ids and 2 lockers concept.)

EEPROM.write(byteAddress, (token <<20) & 0x0f); // store last 4 bits of userID

alright, 0x0f is to write only the last 4 bits, not 0xff. Thanks!

No it only show up argument errors if you have an error in the arguments of the function, that is the numbers you are giving it when you call it.

So I must not put storeToken function inside the loop function?

This is my EEPROM part inside my main sketch, before the void setup() and the void loop() like you said.

 //EEPROM function begins
 void storeToken(int slot, long int token){
 int byteAddress = slot * 15; // the start point of where you will store it in EEPROM
 EEPROM.write(byteAddress, (token <<20) & 0x0f); // store last 4 bits of userID. (is this for userID 0000 to store in his fingerprint id? dec = 0
 EEPROM.write(byteAddress+1, (token <<20) & 0x0f); // userID 0001 to store in his fingerprint id. dec = 1
 EEPROM.write(byteAddress+2, (token <<20) & 0x0f); // userID 0010 to store in his fingerprint id. dec = 2
 EEPROM.write(byteAddress+3, (token <<20) & 0x0f); // userID 0011 to store in his fingerprint id. dec = 3
 EEPROM.write(byteAddress+4, (token <<20) & 0x0f); // userID 0100 to store in his fingerprint id. dec = 4
 EEPROM.write(byteAddress+5, (token <<20) & 0x0f); // userID 0101 to store in his fingerprint id. dec = 5
 EEPROM.write(byteAddress+6, (token <<20) & 0x0f); // userID 0110 to store in his fingerprint id. dec = 6
 EEPROM.write(byteAddress+7, (token <<20) & 0x0f); // userID 0111 to store in his fingerprint id. dec = 7
 EEPROM.write(byteAddress+8, (token <<20) & 0x0f); // userID 1000 to store in his fingerprint id. dec = 8
 EEPROM.write(byteAddress+9, (token <<20) & 0x0f); // userID 1001 to store in his fingerprint id. dec = 9
 EEPROM.write(byteAddress+10, (token <<20) & 0x0f); // userID 1010 to store in his fingerprint id. dec = 10
 EEPROM.write(byteAddress+11, (token <<20) & 0x0f); // userID 1011 to store in his fingerprint id. dec = 11
 EEPROM.write(byteAddress+12, (token <<20) & 0x0f); // userID 1101 to store in his fingerprint id. dec = 12
 EEPROM.write(byteAddress+13, (token <<20) & 0x0f); // userID 1110 to store in his fingerprint id. dec = 13
 EEPROM.write(byteAddress+14, (token <<20) & 0x0f); // userID 1111 to store in his fingerprint id. dec = 14
 } // end storing part of EEPROM

 //begin calling EEPROM
 long int getToken(int slot){
 long int recoverdToken;
 int byteAddress = slot * 15; // the start point of where you will store it in EEPROM
 recoverdToken |= EEPROM.read(byteAddress) >> 20; // call out userid of last 4 bits from EEPROM. (This token from user 0000, dec = 0, will match with the EEPROM value of 0000 stored in, by calling)
 recoverdToken |= EEPROM.read(byteAddress + 1) >> 20; // user 0001 dec=1
 recoverdToken |= EEPROM.read(byteAddress + 2) >> 20; // user 0010 dec=2
 recoverdToken |= EEPROM.read(byteAddress + 3) >> 20; // user 0011 dec=3
 recoverdToken |= EEPROM.read(byteAddress + 4) >> 20; // user 0100 dec=4
 recoverdToken |= EEPROM.read(byteAddress + 5) >> 20; // user 0101 dec=5
 recoverdToken |= EEPROM.read(byteAddress + 6) >> 20; // user 0110 dec=6
 recoverdToken |= EEPROM.read(byteAddress + 7) >> 20; // user 0111 dec=7
 recoverdToken |= EEPROM.read(byteAddress + 8) >> 20; // user 1000 dec=8
 recoverdToken |= EEPROM.read(byteAddress + 9) >> 20; // user 1001 dec=9
 recoverdToken |= EEPROM.read(byteAddress + 10) >> 20; // user 1010 dec=10
 recoverdToken |= EEPROM.read(byteAddress + 11) >> 20; // user 1011 dec=11
 recoverdToken |= EEPROM.read(byteAddress + 12) >> 20; // user 1100 dec=12
 recoverdToken |= EEPROM.read(byteAddress + 13) >> 20; // user 1101 dec=13
 recoverdToken |= EEPROM.read(byteAddress + 14) >> 20; // user 1111 dec=14
 return recoverdToken;
 } // end of EEPROM function

So basically, I am to write 15 IDs into 15 slots for 15 users to scan and match. Is it correct?

and in the void loop()

void loop() {
  if(reader1Count >= 26){
    long int rawToken = ((reader1 >> 1) & 0xffffff); // remove both parity bits
    int facilityCode = rawToken >> 16; // just get the top 8 bits
    int userID = rawToken & 0xffff; // bottom 16 bits are the user code
    Serial.print("Facility Code ");
    Serial.println(facilityCode); // use Serial.println(facilityCode, HEX); // to see the result in hex
    Serial.print("User ID ");
    Serial.println(userID);
    reader1 = 0;
    reader1Count = 0;
  } //end if
// grumpy_mike's code starts here for eeprom operation?
if(rawToken == getToken(0) ) { // do this if the value in rawToken matches what is in the first slot
// do stuff
}
//getToken(0) or getToken(i) where i is the loop variable <--- this code is to stop operating the loop?
}

Ok there are some serious missunderstanding going on here. What on earth are you trying to do, not only with that code but the whole project? That code just writes the same thing to 15 differant memory locations and the thing it is writing is just the top four bits of an ID code why? Assuming the ID codes are sequential that will only change every 16000 users. With RFID you normally use the whole of the number to identify some token, not a part of it. You normally have no idea what the token numbers are before you get them. If you have a fixed number of tokens you can put the numbers directly into and array to compair them there is no need for EEPROM storage. You only need to store the codes if you have a dynamic process where you enroll an unknown token in a list of valid tokens. That is a seprate process from the job of reading stored tokens and see if it matches something you have had before. Also you don't seem to know what a function is and how you call it. So let's start from the beginning by saying what you want to do before you get tangled up with how to do it.

I do have some serious issues which I acknowledge since I just started learning C++

Function is something that I will call when needed and they will only run once, except for loop.

The main idea of my budget project is to get any users up to 15 people to use one of the 2 lockers by means of RFID programming. (I am using fingerprint device in WIEGAND 26bits format)

When locker 1 or 2 is assigned to a user out of 15 people, only that user will open or lock the locker 1 or 2 when he signs in until he sign out, which allows other users to be able to use.

To do that, I need the userID set as token for people who has registered. And whenever their token is used(sign in), it will do the above operation. Here's my completed locker sketch which I need to use it to connect to EEPROM, ARDUINO and WIEGAND which I haven't start yet.

#include 
char lockerselect;
int locker1 = 10;
int locker2 = 11;
int i=0;


// the setup routine runs once when you press reset:
void setup() {                
  // initialize the digital pin as an output.
  pinMode(10, OUTPUT);     
  pinMode(11, OUTPUT);     

Serial.begin(9600);
  Serial.println("select your locker"); // prompt user to select locker via serial monitor
}

void serialEvent() {
    if (Serial.available() > 0) {
  lockerselect = Serial.read();
  i = 1;
  }
}

// the loop routine runs over and over again forever:
void loop() {
  if(i) {
  if (lockerselect == '1') {
    Serial.println("Locker 1 has been unlocked.");
    digitalWrite(10, HIGH);   // turn the LED on (HIGH is the voltage level)
    delay(5000);               // wait for a second
    digitalWrite(10, LOW);    // turn the LED off by making the voltage LOW
    delay(5000);               // wait for a second
    Serial.println("OFF 1");
    lockerselect=0; // it will be off forever until locker selection prompt appears.
  }
  if (lockerselect == '2')  {
    Serial.println("Locker 2  has been unlocked.");
    digitalWrite(11, HIGH);   // turn the LED on (HIGH is the voltage level)
    delay(5000);               // wait for a second
    digitalWrite(11, LOW);    // turn the LED off by making the voltage LOW
    delay(5000);               // wait for a second
    Serial.println("OFF 2");
    lockerselect=0; // it will be off forever until locker selection prompt appears.
  }
  i = 0;
  Serial.println("select your locker"); // go back to start of selection
  }
}

(I am using fingerprint device in WIEGAND 26bits format)

OK a fingerprint takes about 4K of data, where is this being stored? What number are you getting from the reader, that is have you assigned it during some fingerprint enrolling process?

The main idea of my budget project is to get any users up to 15 people to use one of the 2 lockers by means of RFID programming. (I am using fingerprint device in WIEGAND 26bits format)

You have not considered the enrolling process, how are the 26 bit numbers going to be associated with the user. This is a different phase to the operation process of placing your fingerprint on a reader and the appropriate locker opens. This is what I mean by you have not thought through exactly how you want it to operate. If your user ID is just a number from 1 to 15 then there is no need to store that in EEPROM at all. What you might want to store is the relationship between the user ID and the locker they have been allocated. If this could be any locker you need to include this in the enrolling process. So before you even think how you are going to implement it you have to know EXACTLY what you want your code to do and how the user and supervisor will interact with it. This is not a beginners project because there is a lot of other stuff apart from reading a token and doing something with the results. Until you figure out exactly what you want to do forget about any coding. You might think you know what you want it to do but you have not expressed that in enough detail to even begin to write a single line of code.

Grumpy_Mike:

OK a fingerprint takes about 4K of data, where is this being stored? What number are you getting from the reader, that is have you assigned it during some fingerprint enrolling process?

The reader shows facility code 111 in DEC and user id 0 to 15 in DEC when I setup facility code 111 in DEC using the fingerprint device and add users up to 15 in DEC.

You have not considered the enrolling process, how are the 26 bit numbers going to be associated with the user. This is a different phase to the operation process of placing your fingerprint on a reader and the appropriate locker opens. This is what I mean by you have not thought through exactly how you want it to operate. If your user ID is just a number from 1 to 15 then there is no need to store that in EEPROM at all. What you might want to store is the relationship between the user ID and the locker they have been allocated. If this could be any locker you need to include this in the enrolling process. So before you even think how you are going to implement it you have to know EXACTLY what you want your code to do and how the user and supervisor will interact with it. This is not a beginners project because there is a lot of other stuff apart from reading a token and doing something with the results. Until you figure out exactly what you want to do forget about any coding. You might think you know what you want it to do but you have not expressed that in enough detail to even begin to write a single line of code.

Your explanation has struck me with an alternative beginner friendly idea. I can use the if-elseif statement for 2 users 2 lockers since I am unable to do 15 users 2 lockers as it's too much for me to absorb given my limited knowledge of C++ right now. Since I had your help in WIEGAND to ARDUINO sketch, there's nothing else I can dare to ask for help from you. You have helped me for 3 weeks now. It's really admirable to have met nice people like you in the Internet. Really, I thank you very much for your teaching and sharing knowledge even though my project is limited to budgets where I can't just buy converter or stuffs. The next time I learn more about C++, I will eventually have to learn flash memory or RAM as well as EEPROM / AVR. Greatly appreciated for your tolerance towards new learners.

Successfully made 2 users 2 lockers sketch project. The only problem is that I am unable to tell the people who are not user1 or user2 when they scan their fingerprints (unknown users who have not registered) in serial monitor. I guess this is not much of an issue since fingerprint device can tell the people.

Overall, the software for my project is done, with the codes that you created for everyone to use. Credits are yours. I will show it in my powerpoint presentations! Thank you

The only problem is that I am unable to tell the people who are not user1 or user2 when they scan their fingerprints (unknown users who have not registered)

Is this because the fingerprint reader sends no Weagand code when nothing is recognised? Some readers can be configured to send a code for none recognised fingers, but that depends on the mode it is running in.