The Netduino forums have been replaced by new forums at community.wildernesslabs.co.
This site has been preserved for archival purposes only
and the ability to make new accounts or posts has been turned off.
I have a new contribution to the community and a feedback request... This is a simple encapsulation class for the ID-2/ID-12/ID-20 RFID Card Reader modules.
It is also my first attempt at using callbacks and my first use of the class Destructor routine. Could someone look at both of these and let me know if they are implemented properly?
Thanks in advance, and enjoy!
Actual reader class:
using System;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using System.IO.Ports;
using System.Threading;
namespace IDx2Reader
{
// Callback function delegate.
delegate void onCardReadCallback(string str);
class idReader
{
private SerialPort rfidPort; // Serial port the reader is connected on.
private SerialDataReceivedEventHandler _serialReadEvent; // Serial event handler.
private OutputPort rfidResetPort; // Digital port the reader's reset pin is connected to.
private onCardReadCallback onCardRead; // Storage for the callback function.
private int readDelay; // How long to wait between card reads.
private bool _readerRunning = false; // State of the reader.
// Buffers for incoming card data.
byte[] rawData = new byte[16]; // Incoming raw bytes from the serial connection.
char[] idStringData = new char[12]; // ID String data.
public idReader(string _rfidSerialPort, Cpu.Pin _rfidResetPin, onCardReadCallback _onCardRead, int _readDelay = 500)
{
// Set up the ports as necessary.
rfidPort = new SerialPort(_rfidSerialPort, 9600, Parity.None, 8, StopBits.One);
rfidResetPort = new OutputPort(_rfidResetPin, false);
// Store the callback function.
onCardRead = _onCardRead;
// Set up the event handler.
_serialReadEvent = new SerialDataReceivedEventHandler(_rfidCardDataReceived);
// Open the port and set an event handler to receive incoming serial data.
rfidPort.Open();
rfidPort.DataReceived += _serialReadEvent;
// Store other passed parameters.
readDelay = _readDelay;
}
~idReader()
{
// Disable the reader.
if (_readerRunning) rfidResetPort.Write(false);
// Close the serial port.
rfidPort.Close();
// Detach the event handler.
rfidPort.DataReceived -= _serialReadEvent;
// GC will do the rest. (???)
}
// Start watching for a card.
public void start()
{
// Do nothing if the reader is already running.
if (_readerRunning) return;
// Release the reader from the reset state.
rfidResetPort.Write(true);
// Open the callback function to receive data and handle it.
_readerRunning = true;
}
// Stop watching for a card.
public void stop()
{
// Do nothing if the reader is already stopped.
if (!_readerRunning) return;
// Lock the reader to the reset state.
rfidResetPort.Write(false);
// Close the callback function.
_readerRunning = false;
}
// Property to determine the reader's state.
public bool isRunning
{
get { return _readerRunning; }
}
/* This method receives card data from the RFID reader via serial callback. */
private void _rfidCardDataReceived(object _cardPort, SerialDataReceivedEventArgs unused)
{
// Do nothing if the reader is not supposed to be running.
if (!_readerRunning) return;
// Capture the port that the data was received on.
SerialPort cardPort = (SerialPort)_cardPort;
// Read the ID string.
cardPort.Read(rawData, 0, rawData.Length);
// Isolate the actual ID string.
for (int i = 0; i < idStringData.Length; i++)
{
idStringData[i] = (char)rawData[i + 1];
}
// Convert the ID character array to a proper string.
String finishedID = new String(idStringData);
// Wipe the receive buffer for next time.
for (int i = 0; i < rawData.Length; i++)
{
rawData[i] = 0;
}
// Send the received card ID to the approprate callback function.
onCardRead(finishedID);
}
}
}
And how to use it:
using System;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using SecretLabs.NETMF.Hardware;
using SecretLabs.NETMF.Hardware.Netduino;
using IDx2Reader;
namespace IdReaderDemo
{
public class HardwareAbstraction
{
// Hardware device class instance.
private idReader rfidReader;
// Callback function prototype for the hardware device class.
private onCardReadCallback rfidCall;
/* This method is called when a card is read by the RFID reader. */
private void _rfidCardRead(string _cardID)
{
Debug.Print("Card scanned: " + _cardID);
}
public HardwareAbstraction()
{
// Set up the callback function for the ID reader.
rfidCall = new onCardReadCallback(_rfidCardRead);
// Set up the reader itself.
rfidReader = new idReader(SerialPorts.COM1, Pins.GPIO_PIN_D4, rfidCall);
// Start listening for RFID cards.
rfidReader.start();
}
}
public class Program
{
public static void Main()
{
HardwareAbstraction IDtest = new HardwareAbstraction();
// You can do something else useful here.
}
}
}
Thanks works great!
Why need I use GPIO_PIN_D4 to RST? I see some example where RST is direct to 5+ (and that also works with your code) I'm using ID-12 reader.
/Ken
I did a few small changes on the callback for easier use on "main class".
using System;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using System.IO.Ports;
using System.Threading;
namespace IDx2Reader
{
public class idReader
{
//(** new **)
#region Public Event
public delegate void RfidEventDelegate(object sender, RfidEventArgs e);
public event RfidEventDelegate RfidEvent;
public class RfidEventArgs : EventArgs
{
private string _RFID;
private DateTime _ReadTime;
public string RFID
{
get { return _RFID; }
set { _RFID = value; }
}
public DateTime ReadTime
{
get { return _ReadTime; }
set { _ReadTime = value; }
}
}
private void OnRfidEvent(RfidEventArgs e)
{
if (RfidEvent != null)
{
RfidEvent(this, e);
}
}
#endregion
private SerialPort rfidPort; // Serial port the reader is connected on.
private SerialDataReceivedEventHandler _serialReadEvent; // Serial event handler.
private OutputPort rfidResetPort; // Digital port the reader's reset pin is connected to.
private int readDelay; // How long to wait between card reads.
private bool _readerRunning = false; // State of the reader.
// Buffers for incoming card data.
byte[] rawData = new byte[16]; // Incoming raw bytes from the serial connection.
char[] idStringData = new char[12]; // ID String data.
public idReader(string _rfidSerialPort, Cpu.Pin _rfidResetPin, int _readDelay = 500)
{
// Set up the ports as necessary.
rfidPort = new SerialPort(_rfidSerialPort, 9600, Parity.None, 8, StopBits.One);
rfidResetPort = new OutputPort(_rfidResetPin, false);
// Set up the event handler.
_serialReadEvent = new SerialDataReceivedEventHandler(_rfidCardDataReceived);
// Open the port and set an event handler to receive incoming serial data.
rfidPort.Open();
rfidPort.DataReceived += _serialReadEvent;
// Store other passed parameters.
readDelay = _readDelay;
}
~idReader()
{
// Disable the reader.
if (_readerRunning) rfidResetPort.Write(false);
// Close the serial port.
rfidPort.Close();
// Detach the event handler.
rfidPort.DataReceived -= _serialReadEvent;
// GC will do the rest. (???)
}
// Start watching for a card.
public void Start()
{
// Do nothing if the reader is already running.
if (_readerRunning) return;
// Release the reader from the reset state.
rfidResetPort.Write(true);
// Open the callback function to receive data and handle it.
_readerRunning = true;
}
// Stop watching for a card.
public void stop()
{
// Do nothing if the reader is already stopped.
if (!_readerRunning) return;
// Lock the reader to the reset state.
rfidResetPort.Write(false);
// Close the callback function.
_readerRunning = false;
}
// Property to determine the reader's state.
public bool isRunning
{
get { return _readerRunning; }
}
/* This method receives card data from the RFID reader via serial callback. */
private void _rfidCardDataReceived(object _cardPort, SerialDataReceivedEventArgs unused)
{
// Do nothing if the reader is not supposed to be running.
if (!_readerRunning) return;
// Capture the port that the data was received on.
SerialPort cardPort = (SerialPort)_cardPort;
// Read the ID string.
cardPort.Read(rawData, 0, rawData.Length);
// Isolate the actual ID string.
for (int i = 0; i < idStringData.Length; i++)
{
idStringData[i] = (char)rawData[i + 1];
}
// Convert the ID character array to a proper string.
String finishedID = new String(idStringData);
// Wipe the receive buffer for next time.
for (int i = 0; i < rawData.Length; i++)
{
rawData[i] = 0;
}
// Send the received card ID to the approprate callback function.
//(** new **)
RfidEventArgs _args = new RfidEventArgs();
_args.RFID = finishedID;
_args.ReadTime = DateTime.Now;
OnRfidEvent(_args);
}
}
}
I use it like this:
using System;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using SecretLabs.NETMF.Hardware;
using SecretLabs.NETMF.Hardware.Netduino;
using System.IO.Ports;
using IDx2Reader;
namespace MyRFID
{
public class Program
{
private static idReader _idReader;
private static void StartRFID()
{
_idReader = new idReader(SerialPorts.COM1, Pins.GPIO_PIN_D4);
_idReader.RfidEvent += new idReader.RfidEventDelegate(_idReader_RfidEvent);
_idReader.Start();
}
static void _idReader_RfidEvent(object sender, idReader.RfidEventArgs e)
{
Debug.Print("Card scanned: " + e.RFID + ", time: " + e.ReadTime);
}
public static void Main()
{
// write your code here
StartRFID();
Thread.Sleep(Timeout.Infinite);
}
}
}
That you for sharing this class.
First time using the Netduino and loving it.
I'm having some problems getting it to work.
The card says it is reading data, but it is just returning all 255's.
Card scanned: ÿÿÿÿÿÿÿÿÿ, time: 01/01/2009 00:36:19
I have tried putting together just a simple serial reader and end up with the same output.
I can't seem to figure out why I'm not getting a valid RFID.
I have two cards and I'm pretty sure the code for both are not ÿÿÿÿÿÿÿÿÿ.
I'm pretty much using the class the same way you specify.
I coped the wiring from some other thread I found.
Pins:
11,2 = 5v
1,7 = gnd
10 = led
9 = Netduino pin 1
Hopefully I have something wired up wrong, I would hate to think i have a bad ID-20.
Thanks,
Trey Aughenbaugh
I'm having some problems getting it to work.
The card says it is reading data, but it is just returning all 255's.
Card scanned: ÿÿÿÿÿÿÿÿÿ, time: 01/01/2009 00:36:19
I have tried putting together just a simple serial reader and end up with the same output.
I can't seem to figure out why I'm not getting a valid RFID.
I have two cards and I'm pretty sure the code for both are not ÿÿÿÿÿÿÿÿÿ.
I'm pretty much using the class the same way you specify.
I coped the wiring from some other thread I found.
Pins:
11,2 = 5v
1,7 = gnd
10 = led
9 = Netduino pin 1
Hopefully I have something wired up wrong, I would hate to think i have a bad ID-20.
Trey, you do have it wired up correctly. Are you sure the cards you have are compatible with the ID-20? The ID-20 cannot read HID cards.
If you need cards, SparkFun sells compatible cards for $1.95 each.
Trey, you do have it wired up correctly. Are you sure the cards you have are compatible with the ID-20? The ID-20 cannot read HID cards.
If you need cards, SparkFun sells compatible cards for $1.95 each.
Dan,
Thanks for the response.
I'm using these cards. http://www.sparkfun.com/products/10169
I stated how I have them wired in the previous post.
I'm assuming that is correct.
I have an LED on pin 10. It turns on when I scan a card.
Would it turn on for an invalid card?
Again, I get data, but it sure does not look like a proper card ID.
I stated how I have them wired in the previous post.
I'm assuming that is correct.
I have an LED on pin 10. It turns on when I scan a card.
Would it turn on for an invalid card?
Again, I get data, but it sure does not look like a proper card ID.
The LED only turns on for a valid card so its kind of puzzling that your getting invalid data. I just re-read your first post, you have pin 9 from the ID-20 hooked up to pin 1 of the Netduino? If so, thats the transmit pin. It should be hooked up to pin 0, the receive pin.
The LED only turns on for a valid card so its kind of puzzling that your getting invalid data. I just re-read your first post, you have pin 9 from the ID-20 hooked up to pin 1 of the Netduino? If so, thats the transmit pin. It should be hooked up to pin 0, the receive pin.
OK, so I unplugged the ID-20 to make sure I had it wired up correctly and when I plugged in back in, it seemed to be showing numbers now instead of odd data.
Which is odd since I have done the same thing several times checking my wiring.
I guess it is possible my bread board has some issues.
Dan thanks for you help. One other note, I set the time as well. I can't believe that would make a difference.
Now that I'm getting data, the cards from sparkfun don't tell you what your ID should be.
I'm getting 12 characters out.
My understanding is I should only have 10 characters.
Any ideas why I'm seeing 12 characters.
Here is an example :450052C2FE2B.
Both cards start with 450052.
I guess I don't even know if this is the correct ID I should see.
Anyone know where I can get a card with the ID printed in it or at least it labeled somewhere?
Thanks again,
Trey
I think what I am seeing is the Check sum.
450052C2FE is the code and 2B is the check sum.
The 1byte (2 ASCII characters) Check sum is the “Exclusive OR” of the 5 hex bytes (10 ASCII) Data characters.
-trey
Why is chk[0] and chk[1] not getting used?
Based on your code, 450052C2FE2B is turned into 5423870.
Sorry if I'm not understanding something simple here.
I can see how << must be shifting the bits 8 times but why only starting at chk[2]?
I think the first two characters of the RFID code read a reference to the manufacturer.
In the next two characters were to me always 0 hence omitted.
In my program I had _args.RFID defined as integer but now as a string
The read code rfidtag is the same as the number which is printed on the tag.