Notes About Working with Various Arduino & Netduino Microcontroller Boards

Sunday, June 10, 2012

C# Code for Using Parallax RFID Reader with Netduino

The following event-driven code for using the Parallax RFID reader is taken from posts in the Netduino Community Forum. The code is only slightly modified from the the code posted there by afulki.

Be sure to add the reference to Microsoft.SPOT.Hardware.SerialPort.dll.


using System;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using SecretLabs.NETMF.Hardware;

/* Change next line to end in Netduino or NetduionoPlus
 * as appropriate */
using SecretLabs.NETMF.Hardware.NetduinoPlus;

using System.IO.Ports;

public class RFID
{
    private int readDelay = 1500;
    private bool readerEnabled = false;

    public SerialPort Serial { get; set; }
    public OutputPort RfidCtrl { get; set; }

    public delegate void CardReadEventHandler(RFID sender, string cardID);
    public event CardReadEventHandler OnCardRead;

    public delegate void StatusChangedEventHandler(RFID sender, bool readerEnabled);
    public event StatusChangedEventHandler OnStatusChanged;

    private byte[] msgBuffer = new byte[10];

    // -1 = waiting for start char, 0 or more means reading message
    private int msgCounter = -1; 

    public int ReadDelay
    {
        get { return readDelay; }
        set { readDelay = value; }
    }

    public bool ReaderEnabled
    {
        get { return readerEnabled; }
        private set
        {
            readerEnabled = value;
            if (OnStatusChanged != null)
            {
                OnStatusChanged(this, value);
            }
        }
    }

    public RFID(string port, Cpu.Pin ctrlPin, bool autoEnable = true)
        : this(new SerialPort(port, 2400, Parity.None, 8, StopBits.One), new OutputPort(ctrlPin, false), autoEnable)
    {
    }

    public RFID(SerialPort sPort, OutputPort rfidCtrl, bool autoEnable = true)
    {
        this.Serial = sPort;
        this.RfidCtrl = rfidCtrl;

        Serial.WriteTimeout = 1000;

        Serial.Open();
        Serial.DataReceived += new SerialDataReceivedEventHandler(SerialPort_DataReceived);

        if (autoEnable) EnableReader();
    }

    public void DisableReader()
    {
        RfidCtrl.Write(true);
        if (Serial.IsOpen) Serial.Close();
        ReaderEnabled = false;
    }

    public void EnableReader()
    {
        if (!Serial.IsOpen) Serial.Open();
        RfidCtrl.Write(false);
        ReaderEnabled = true;
    }

    private void DoReadDelay()
    {
        if (ReaderEnabled)
        {
            DisableReader();
            Thread.Sleep(ReadDelay);
            EnableReader();
        }
    }


    void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
    {
        SerialPort sp = (SerialPort)sender;

        while (sp.BytesToRead > 0)
        {
            // temp buff to hold message,
            byte[] buf = new byte[1];

            // Read a single byte from the recv buffer,
            if (sp.Read(buf, 0, 1) > 0)
            {
                // Start of Message?
                if (buf[0] == '\n')
                {
                    msgCounter = 0;
                }
                // End of message?
                else if (buf[0] == '\r')
                {
                    if (msgCounter > 9)
                    {
                        String cardID = String.Empty;
                        for (int i = 0; i < 10; i++)
                        {
                            cardID += (char)msgBuffer[i];
                        }

                        if (OnCardRead != null)
                        {
                            OnCardRead(this, cardID);
                        }
                    }

                    msgCounter = -1;
                    DoReadDelay();
                }
                else // Store it in the global buffer, 
                {
                    if (msgCounter < 10)
                    {
                        msgBuffer[msgCounter++] = buf[0];
                    }
                    else
                        msgCounter = -1;
                }
            }
        }
    }

    // Added Main for quick test of code 
    public static void Main()
    {
        // /Enable connected to pin D2
        RFID rfid = new RFID(SerialPorts.COM1, Pins.GPIO_PIN_D2);
        rfid.OnCardRead += new RFID.CardReadEventHandler(rfid_OnCardRead);

        Thread.Sleep(Timeout.Infinite);
    }

    static void rfid_OnCardRead(RFID sender, string cardID)
    {
        Debug.Print("CardID: " + cardID);
    }
}

No comments:

Post a Comment