Go Down

Topic: Arduino pro mini + wiegand26 RFID reader + strike (Read 12551 times) previous topic - next topic

bolsontanker

Hello all, I'm trying to create a setup with the following:

http://www.sparkfun.com/commerce/product_info.php?products_id=9218
and
http://cgi.ebay.com/Mini-Wiegand26-Weatherproof-RFID-Reader-125KHz_W0QQitemZ260495497267QQcmdZViewItemQQptZLH_DefaultDomain_0?hash=item3ca6bdd833

http://cgi.ebay.com/Door-Fail-Secure-access-control-Electric-Strike-v5-NO_W0QQitemZ350230332833QQcmdZViewItemQQptZLH_DefaultDomain_0?hash=item518b5ac5a1


Here is the code which I have found which outputs a consistent RFID read (though quite different from the phidgets output).  Can someone help me with the following finishing touches-1- get the code to a point that it will take it's reading and compare it to a pre-defined list on the Arduino and grant access only to those in that list {I have no issues with having to open the setup to add RFID codes}
and 2- how do I set the 12v strike lock so that the output from the arduino is able to trigger the lock using the ground {with the 12v + for the strike plate coming from the breadboard power supply, and the negative going to ? (relay, transformer, ?)}
Code: [Select]
/* Crazy People
* By Mike Cook April 2009
* Three RFID readers outputing 26 bit Wiegand code to pins:-
* Reader A (Head) Pins 2 & 3
* Interrupt service routine gathers Wiegand pulses (zero or one) until 26 have been recieved
* Then a sting is sent to processing
*/

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

void reader1One(void) {
 reader1Count++;
 reader1 = reader1 << 1;
 reader1 |= 1;
}

void reader1Zero(void) {
 reader1Count++;
 reader1 = reader1 << 1;
}

void setup()
{
 Serial.begin(9600);
 // Attach pin change interrupt service routines from the Wiegand RFID readers
 attachInterrupt(0, reader1Zero, RISING);//DATA0 to pin 2
 attachInterrupt(1, reader1One, RISING); //DATA1 to pin 3
 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 = 2; i<4; 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);
int serialNumber=(reader1 >> 1) & 0x3fff;
int siteCode= (reader1 >> 17) & 0x3ff;

Serial.print(siteCode);
Serial.print("  ");
Serial.println(serialNumber);
 reader1 = 0;
 reader1Count = 0;
 digitalWrite(13,HIGH);
 delay(2000);
 digitalWrite(13,LOW);
    }
}



This is a visual representation of what I currently have setup:



With this setup the wiegand26 reader has an Arduino serial output of:
example:
Tag 1- 196-15809
Tag 2- 452-3285

- whereas my Phidgets reader has a serial output of:
Tag 1- 2800c4bdc1
Tag 2- 2800c4ccd5

using those tags as examples how would I set the code up for the wiegand tags up as verified tags which would trigger an output to trigger the strike lock?

PaulS

The variables siteCode and serialNumber are read from the card. Create two arrays:

Code: [Select]
int validSiteCodes[] = {196, 452};
int validSerialNumbers[] = {15809, 3285};


Then, create a function:

Code: [Select]
boolean IsTagValid(int siteCode, int serialNumber)
{
  boolean valid = false;

  // Determine how many valid tags there are
  int validTagCount = sizeof(validSiteCodes)/sizeof(int);

  // Loop through the arrays to see if siteCode
  // and serialNumber are present

  for(int t=0; t<validTagCount; t++)
  {
     if(validSiteCode[t] == siteCode &&
        validSerialNumber == serialNumber)
     {
         valid = true;
         break;
     }
  }

  return valid;
}


Where you print the serialNumber and siteCode, call this function:

Code: [Select]
if(IsTagValid(siteCode, serialNumber)
{
  // Open the door. It's cold out here!
}

bolsontanker

#2
Feb 27, 2010, 11:14 pm Last Edit: Feb 27, 2010, 11:16 pm by bolsontanker Reason: 1
Thank you very much for your reply.  As I'm completely new to all of this is there any chance that you would be willing to show me how that code fits into the code I have (thanks a ton for using the example tags in your code).   :o  I still have the rest of the schematic to figure out as well- I assume I can't just run the ground from let's say pin 13 out to the ground of the 12v strike plate (I assume that would create a problem of too much voltage running through the arduino? - would a TIP31A work for this input- from pin 13 of arduino, ground to well.. ground, and then output to the ground for the strike plate..... ?

bolsontanker

I might add- I'm a complete noob to both electronics and coding.  I saw the arduino about a month ago, ordered one and have been trying to learn everything I can- this is my first project (other than pin 13 blinking  ;) )

PaulS

#4
Feb 28, 2010, 01:58 am Last Edit: Feb 28, 2010, 02:03 am by PaulS Reason: 1
Your loop function with my additions:
Code: [Select]
void loop() {
 if(reader1Count >=26){
//Serial.print(" Reader 1 ");
//Serial.println(reader1,HEX);
// Serial.println("A");
//Serial.println(reader1& 0xfffffff);
int serialNumber=(reader1 >> 1) & 0x3fff;
int siteCode= (reader1 >> 17) & 0x3ff;

Serial.print(siteCode);
Serial.print("  ");
Serial.println(serialNumber);
 reader1 = 0;
 reader1Count = 0;
 digitalWrite(13,HIGH);
 delay(2000);
 digitalWrite(13,LOW);
[glow]if(IsTagValid(siteCode, serialNumber)
{
  // Open the door. It's cold out here!
} [/glow]
    }
}


The IsTagValid function would go after the last } above.

Quote
I can't just run the ground from let's say pin 13 out to the ground of the 12v strike plate (I assume that would create a problem of too much voltage running through the arduino? - would a TIP31A work for this input- from pin 13 of arduino, ground to well.. ground, and then output to the ground for the strike plate..... ?


Pin 13 is not ground. If you turn pin 13 on, using digitalWrite(13, HIGH);, pin 13 will measure 5V, but can only safely supply 20 mA of current.

Pin 13 should be connected to some leg of a transistor of some sort. Which one, and which leg? I don't know, I'm a software guy; that's a hardware question.

bolsontanker

Okay so I included the code (where I believe you were referring to) and I'm getting an error :question -

In function 'void loop()':
error: 'IsTagValid' was not declared in this scope

Here is the code:

Code: [Select]
/* Crazy People
* By Mike Cook April 2009
* Three RFID readers outputing 26 bit Wiegand code to pins:-
* Reader A (Head) Pins 2 & 3
* Interrupt service routine gathers Wiegand pulses (zero or one) until 26 have been recieved
* Then a sting is sent to processing
*/

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

void reader1One(void) {
 reader1Count++;
 reader1 = reader1 << 1;
 reader1 |= 1;
}

void reader1Zero(void) {
 reader1Count++;
 reader1 = reader1 << 1;
}

void setup()
{
 Serial.begin(9600);
 // Attach pin change interrupt service routines from the Wiegand RFID readers
 attachInterrupt(0, reader1Zero, RISING);//DATA0 to pin 2
 attachInterrupt(1, reader1One, RISING); //DATA1 to pin 3
 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 = 2; i<4; 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);
int serialNumber=(reader1 >> 1) & 0x3fff;
int siteCode= (reader1 >> 17) & 0x3ff;

Serial.print(siteCode);
Serial.print("  ");
Serial.println(serialNumber);
 reader1 = 0;
 reader1Count = 0;
 digitalWrite(13,HIGH);
 delay(2000);
 digitalWrite(13,LOW);
 
if (IsTagValid)(siteCode, serialNumber)
{
int validSiteCodes[] = {196, 452};
int validSerialNumbers[] = {15809, 3285};
  // Open the door. It's cold out here!
}
    }
}

bolsontanker

oops what I meant was the output from pin 13 to the ground of the 12v strike lock.  Thanks for your help on this it's very much appreciated.  ;D

PaulS

The first block of code in Reply #1 goes before setup, not in the if block.

The second block of code (the function IsTagValid) can go after loop.

The output of pin 13 goes to the gate (I think) of a transistor. One of the other legs goes to ground. The other goes to the ground side of the door lock. The other side of the door lock goes to the plus side of the power supply. The other ground side of the power supply, the ground side of the transistor, and the Arduino ground all get connected.

bolsontanker

#8
Feb 28, 2010, 05:38 am Last Edit: Feb 28, 2010, 06:15 am by bolsontanker Reason: 1
Thank you for your patience I'm sure I probably seem like an idiot :-P (and code wise I clearly am)
So I modified the code in the manner which I believe you were stating.  Now I'm getting this error while trying to compile:



In function 'void setup()':
error: expected initializer before 'boolean'

Code: [Select]
/* Crazy People
* By Mike Cook April 2009
* Three RFID readers outputing 26 bit Wiegand code to pins:-
* Reader A (Head) Pins 2 & 3
* Interrupt service routine gathers Wiegand pulses (zero or one) until 26 have been recieved
* Then a sting is sent to processing
*/
int validSiteCodes[] = {196, 452};
int validSerialNumbers[] = {15809, 3285};

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

void reader1One(void) {
 reader1Count++;
 reader1 = reader1 << 1;
 reader1 |= 1;
}

void reader1Zero(void) {
 reader1Count++;
 reader1 = reader1 << 1;
}

void setup()
{
 Serial.begin(9600);
 // Attach pin change interrupt service routines from the Wiegand RFID readers
 attachInterrupt(0, reader1Zero, RISING);//DATA0 to pin 2
 attachInterrupt(1, reader1One, RISING); //DATA1 to pin 3
 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 = 2; i<4; 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

{
 boolean IsTagValid(int siteCode, int serialNumber)

  boolean valid = false;

  // Determine how many valid tags there are
  int validTagCount = sizeof(validSiteCodes)/sizeof(int);

  // Loop through the arrays to see if siteCode
  // and serialNumber are present

  for(int t=0; t<validTagCount; t++)
  {
     if(validSiteCode[t] == siteCode &&
        validSerialNumber == serialNumber)
     {
         valid = true;
         break;
     }
  }

  return valid;
}

void loop() {
 if(reader1Count >=26){
//Serial.print(" Reader 1 ");
//Serial.println(reader1,HEX);
// Serial.println("A");
//Serial.println(reader1& 0xfffffff);
int serialNumber=(reader1 >> 1) & 0x3fff;
int siteCode= (reader1 >> 17) & 0x3ff;

Serial.print(siteCode);
Serial.print("  ");
Serial.println(serialNumber);
 reader1 = 0;
 reader1Count = 0;
 digitalWrite(13,HIGH);
 delay(2000);
 digitalWrite(13,LOW);
if(IsTagValid(siteCode, serialNumber)
{
  // Open the door. It's cold out here!
}
    }
}

bolsontanker

#9
Feb 28, 2010, 06:08 am Last Edit: Feb 28, 2010, 06:15 am by bolsontanker Reason: 1
This is what I'm basing the idea off of -
http://www.instructables.com/id/Arduino-RFID-Door-Lock/?ALLSTEPS

his code is as follows, but does not use wiegand- :

http://www.instructables.com/files/orig/F3I/3G5E/G1YQE507/F3I3G5EG1YQE507.txt

had to hyperlink to a text document because it wouldn't let me C & P it - too many characters I guess.

PaulS

Now, you are trying to embed the function IN setup.

You should have:

Code: [Select]
void setup()
{
  // Do some stuff
}

void loop()
{
  // Do some stuff
  if(IsTagValid(siteCode, serialNumber)
  {
     // Open the door. I'm freezing my butt off out here
  }
}

boolean IsTagValid(int siteCode, int serialNumber)
{
  // see if site code and serial number are in the lists...
}

bolsontanker

#11
Feb 28, 2010, 08:45 pm Last Edit: Feb 28, 2010, 08:46 pm by bolsontanker Reason: 1
Well it compiles now :D now to see if it does what I want.  Thanks for the help!

Code: [Select]
/* Crazy People
* By Mike Cook April 2009
* Three RFID readers outputing 26 bit Wiegand code to pins:-
* Reader A (Head) Pins 2 & 3
* Interrupt service routine gathers Wiegand pulses (zero or one) until 26 have been recieved
* Then a sting is sent to processing
*/

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

void reader1One(void) {
 reader1Count++;
 reader1 = reader1 << 1;
 reader1 |= 1;
}

void reader1Zero(void) {
 reader1Count++;
 reader1 = reader1 << 1;
}

void setup()
{
 Serial.begin(9600);
 // Attach pin change interrupt service routines from the Wiegand RFID readers
 attachInterrupt(0, reader1Zero, RISING);//DATA0 to pin 2
 attachInterrupt(1, reader1One, RISING); //DATA1 to pin 3
 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 = 2; i<4; 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);
int serialNumber=(reader1 >> 1) & 0x3fff;
int siteCode= (reader1 >> 17) & 0x3ff;

Serial.print(siteCode);
Serial.print("  ");
Serial.println(serialNumber);
 reader1 = 0;
 reader1Count = 0;
 digitalWrite(13,HIGH);
 delay(2000);
 digitalWrite(13,LOW);
if(IsTagValid(siteCode, serialNumber)
){
  // Open the door. It's cold out here!
}
    }
}


boolean IsTagValid(int siteCode, int serialNumber)
{
  // see if site code and serial number are in the lists...
}

bolsontanker

Okay... well it works... kind of - all tags that are read open the lock.  I want it to work with only those tags that are stored.  How do I change the code to only open the tags that have been stored.  Using these tags as an example how would I do that? (did I screw up the code again? :-P):
Tag 1- 196-15809
Tag 2- 452-3285

PaulS

Code: [Select]
boolean IsTagValid(int siteCode, int serialNumber)
{
  // see if site code and serial number are in the lists...
}


You were supposed to put the code from Reply #1 here. This was a place holder to show you where to put the code.

Code: [Select]
if(IsTagValid(siteCode, serialNumber)
){
  // Open the door. It's cold out here!
}


There's an extra ) in there. I'm surprised that it compiled.

Also, you're supposed to put some code in there where the comment is, to actually do something...

bolsontanker

#14
Mar 01, 2010, 12:08 am Last Edit: Mar 01, 2010, 12:20 am by bolsontanker Reason: 1
Okay- so here is what I did- it still compiles without issue, but again it opens for all RFID tags, rather than just those 2 I'm using as examples.  What am I missing?  Thanks again for all your help.

Code: [Select]
/* Crazy People
* By Mike Cook April 2009
* Three RFID readers outputing 26 bit Wiegand code to pins:-
* Reader A (Head) Pins 2 & 3
* Interrupt service routine gathers Wiegand pulses (zero or one) until 26 have been recieved
* Then a sting is sent to processing
*/

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

void reader1One(void) {
 reader1Count++;
 reader1 = reader1 << 1;
 reader1 |= 1;
}

void reader1Zero(void) {
 reader1Count++;
 reader1 = reader1 << 1;
}

void setup()
{
 Serial.begin(9600);
 // Attach pin change interrupt service routines from the Wiegand RFID readers
 attachInterrupt(0, reader1Zero, RISING);//DATA0 to pin 2
 attachInterrupt(1, reader1One, RISING); //DATA1 to pin 3
 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 = 2; i<4; 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);
int serialNumber=(reader1 >> 1) & 0x3fff;
int siteCode= (reader1 >> 17) & 0x3ff;

Serial.print(siteCode);
Serial.print("  ");
Serial.println(serialNumber);
 reader1 = 0;
 reader1Count = 0;
 digitalWrite(13,HIGH);
 delay(2000);
 digitalWrite(13,LOW);
if(IsTagValid(siteCode, serialNumber)
){
 digitalWrite(13,HIGH);// Open the door. It's cold out here!
}
 else
   digitalWrite(13,LOW);   // release the hounds
}
    }

boolean IsTagValid(int siteCode, int serialNumber)
{
  int validSiteCodes[] = {196, 452};
  int validSerialNumbers[] = {15809, 3285};// see if site code and serial number are in the lists...
}


edit- when I monitor it on the serial connection the results are all the same for the tags as they are read (and they do not match the example codes).  :question

Go Up