Wiegand reader with keypad (detect end of transmission algorithm problem)

Hi Arduino Enthusiasts!

I have Arduino Duemilanove + Wiegand26 reader Smartec ST-PR160EK (pic above) and my task is to write sketch which is able to distinguish key press from card touch. Result must be sended in com port like "button: 5" or "card: 123456". For working with Wiegand I use this library.

When card is presented you got 26 bytes. E.g. when you got tag id #7357893 it means that there was such sequence of bytes: 111000001000101110001011. Example sketch here.

When button is touched you got 7 or 8 bytes:

0 - 11110000 (240)
1 - 11100001 (225)
2 - 11010010 (210)
3 - 11000011 (195)
4 - 10110100 (180)
5 - 10100101 (165)
6 - 10010110 (150)
7 - 10000111 (135)
8 - 1111000 (120)
9 - 1101001 (105)
esc - 1011010 (90)
enter - 1001011 (75)

Example sketch of decode buttons at my Wiegand reader.

At particular reader model frequency of data is 416 Hz (T~2.59 ms):

Empirically I find out that minimum delay between pressing two buttons is 300 ms (let's call it "interframe delay")

Difficulties are:

  • All data is sending by same wire at same port. So now way to combine two example sketches listed below - anyway it will trigger if(reader2Count>=8) condition at loop().
  • Card number and facility code can be any number so there is no signature which can help
  • button code can be either 7 or 8 bit

At now I think the most perspective and universal solution is to use timer and check is reader2Count variable changed during 3 ms (not necessarily 3ms - any time that is > T and < "interframe delay" is ok). If no change - start to process collected bites. I wrote a working sketch but I have no idea why it's working only once (for next time use need to reset controller).

Any suggestion is much appreciated :slight_smile:

Broken link.

You use the millis() timer to recover the current time count and store that when ever something is received by the Weagand interface. Then you need to look at this and see if a time has elapsed before you decide if it is a card or a digit.

button code can be either 7 or 8 bit

I doubt it, I think there might be a leading zero suppression that is causing you to think that.

Grumpy_Mike:
Broken link.

Link fixed, please take a look. I saw that immediately after posting, but was able to correct only after 5 min cause I'm newbie at this forum.

Grumpy_Mike:
You use the millis() timer to recover the current time count and store that when ever something is received by the Weagand interface. Then you need to look at this and see if a time has elapsed before you decide if it is a card or a digit.

You mean that timer was overflow? I don't think so. I use this library for setting timer and as I understood it use millis(). This number will overflow (go back to zero) after approximately 50 days.

Grumpy_Mike:
I doubt it, I think there might be a leading zero suppression that is causing you to think that.

I'm sure in it, there is no leading zero at protocol. Wiegand26 lib that I use collects data this way (when no data pin is HIGH):

void  WIEGAND26::reader2One() {
  if(digitalRead(reader2Pins[1]) == LOW){
    reader2Count++;
    reader2 = reader2 << 1;
    reader2 |= 1;
  }
}

void  WIEGAND26::reader2Zero(void) {
  if(digitalRead(reader2Pins[0]) == LOW){
    reader2Count++;
    reader2 = reader2 << 1;  
  }
}

You mean that timer was overflow?

No I never said that at all. I suggested using the millis() NOT the timer library.

I'm sure in it, there is no leading zero at protocol.

Sorry that makes no sense. I talked about leading zero suppression.

However I have looked at your code but can not understand what the timer library is doing. Have you read this How to use this forum
It asks you to post links to any library you use so that others can reproduce what you have done.

Dear Mike, seems like you missed something. I posted links to all libraries that I use. For your convenience I can do it once again:
http://playground.arduino.cc/Code/Timer

Thank you for looking at my code.

Solved the problem, now sketch works fine. I just forgot to reset the variable: reader2Count_real = 0

Here is a full listing of working code.