How to connect a Parallax 125KHz RFID reader to a FEZ Cobra board

I need some help in figuring out the correct wiring between a Parallax RFID reader and a Cobra board. Apparently it’s all too simple, but I’m failing somewhere, since I can’t get it to output any data:

Parallax’s pin-out:

pin 1: System power (+5V DC input)
pin 2: Module enable (active LOW digital input… setting this to LOW enables the reader)
pin 3: Serial output to host (TTL-level interface, 2400 bps, 8 data bits, no parity, 1 stop bit)
pin 4: System ground

I’m using a very simple driver that I ported from a Netduino example that I found over at the Netduino forums (which I know it works, for I have tested on the Netduino myself), but something is not right for it’s not working on the Cobra / EMX Dev Board.

Maybe you guys scan shed some light on this.

If it works on any NETMF board then it should simply work on FEZ Cobra. Check your connections please.

Pin 1, tie to a 5v rail on Cobra.
Pin 2, tie to a general IO pin, and set high when your app starts.
Pin 3, tie to the Rx pin on one of the serial UART ports. That’s what you’ll do serial.read() from.
Pin 4, GND, tie to GND on cobra.

Should be simple.

What doesn’t work? Do you have any serial data coming in? Does the RFID reader have a power LED that you can see that is lit?

Thanks, Brett! I guess I was mistakenly setting the pin 2 to “t\rue” upon app start, which as it appears to be actually disables the reader. I’m setting it now to “false”, thus enabling it. By doing this, the LED on the reader turns to red and the cards are then properly detected. When setting the output pin to “true”, the LED turns green and then no card is read. Go figure. Thanks again.

ah, the magic “bar” or “bang” input. That’s often all it takes, a logic level shift :wink: :wink:

Now something totally new to me is happening. The RFID reader is working fine, the serial port’s DataReceived event is firing properly and I’m getting the card IDs back as expected. But what is stumping me is that this only works in “debug mode”, that is, if the board is connected to the PC and the app is running directly from Visual Studio in debug mode (F5). If I disconnect the board from the PC and reboot it (by unplugging the power adapter and plugging it back in), nothing works. I mean, the reader seems to be in an On state (its LED is indeed red), but nothing happens when I swipe a card in front of it. I know that it is not working because the driver turns the reader Off and then On back again between reads, and whenever the reader is Off its LED is green. This is all too strange. I have deployed other NETMF apps before to these boards and I have never seen this sort of behavior. Any ideas?

Without seeing your code, it will be hard to give you advice.

Sure… what would be the best way to submit this code? The whole app is comprised of two files:

  • Program.cs
  • ParallaxRFID.cs

Inside Program.cs I instantiate a ParallaxRFID object and then create a couple of event handlers for the “card read” and “status change” events. The bulk of the logic is kept inside the other file.

If the code is not to big, you can post here (use code tags), if it is, use http://pastebin.com and post the link here.

Greetings

Thanks, Eric… it’s not that big, so I guess I’ll just paste it here.

Program.cs


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

namespace MFConsoleApplication1
{
    public class Program
    {
        static ParallaxRFID rfidReader;

        public static void Main()
        {
            rfidReader = new ParallaxRFID("COM3", (Cpu.Pin)18);
            
            rfidReader.OnCardRead += rfidReader_OnCardRead;
            rfidReader.OnStatusChanged += rfidReader_OnStatusChanged;
            
            Thread.Sleep(Timeout.Infinite);
        }

        static void rfidReader_OnStatusChanged(ParallaxRFID sender, bool readerEnabled)
        {
            Debug.Print("Reader enabled: " + readerEnabled);
        }

        static void rfidReader_OnCardRead(ParallaxRFID sender, string cardID)
        {
            Debug.Print("Card ID: " + cardID);
        }
    }
}

ParallaxRFID.cs


using System;
using System.IO.Ports;
using Microsoft.SPOT.Hardware;
using System.Threading;

namespace MFConsoleApplication1
{
    class ParallaxRFID
    {
        const int WRITE_TIMEOUT = 1000;

        int _readDelay = 1500;
        bool _readerEnabled = false;

        byte[] _messageBuffer = new byte[10];
        int _messageCounter = -1; 
        // -1 = waiting for start char 
        //  0 or more = reading message

        public delegate void CardReadEventHandler(ParallaxRFID sender, string cardID);
        public delegate void StatusChangedEventHandler(ParallaxRFID sender, bool readerEnabled);

        public event CardReadEventHandler OnCardRead;
        public event StatusChangedEventHandler OnStatusChanged;

        public SerialPort SerialPort { get; set; }
        public OutputPort RfidControl { get; set; }

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

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

        public ParallaxRFID(string portName, Cpu.Pin controlPin, bool autoEnable = true)
            : this(new SerialPort(portName, 2400, Parity.None, 8, StopBits.One), new OutputPort(controlPin, true), autoEnable)
        {

        }

        public ParallaxRFID(SerialPort serialPort, OutputPort rfidControl, bool autoEnable = true)
        {
            SerialPort = serialPort;
            RfidControl = rfidControl;

            SerialPort.WriteTimeout = WRITE_TIMEOUT;

            SerialPort.DataReceived += SerialPort_DataReceived;
            SerialPort.Open();

            if (autoEnable)
            {
                EnableReader();
            }
        }

        private void DisableReader()
        {
            RfidControl.Write(true);
            if (SerialPort.IsOpen)
            {
                SerialPort.Close();
            }
            ReaderEnabled = false;
        }

        private void EnableReader()
        {
            if (!SerialPort.IsOpen)
            {
                SerialPort.Open();
            }
            RfidControl.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 buffer to hold the message (one char at a time)
                byte[] buf = new byte[1];

                // read a single byte from the serial port input buffer
                if (sp.Read(buf, 0, 1) > 0)
                {
                    // check if start of message
                    if (buf[0] == '\n')
                    {
                        _messageCounter = 0;
                    }
                    // check if end of message
                    else if (buf[0] == '\r')
                    {
                        if (_messageCounter > 9)
                        {
                            String cardID = String.Empty;
                            for (int i = 0; i < 10; i++)
                            {
                                cardID += (char)_messageBuffer[i];
                            }

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

                        _messageCounter = -1;
                        DoReadDelay();
                    }
                    // store data in our message buffer
                    else
                    {
                        if (_messageCounter < 10)
                        {
                            _messageBuffer[_messageCounter++] = buf[0];
                        }
                        else
                        {
                            _messageCounter = -1;
                        }
                    }
                }
            }
        }
    }
}

Step 1 when you have little or no debug capability to see what is going on: flash a LED ! Make it flash fast on startup (until after handlers are defined) then flash slower when it’s in steady state. Just use a timer to do that.

Edit: do you have a display on the Cobra? If so, print stuff on the screen !

Thanks, Brett. According to your suggestion, I added two LED blinking cycles inside Main(): one right at the top of the method, faster, and another one, slower, after both event handlers are defined. The blinking is working as expected, but once again if I disconnect the board and then reboot it, the same behavior persists. The LED blinks fast, then the card reader turns on and then LED blinks slower, but then if I swipe a card, nothing happens. This is really strange.

ok, so how are you powering this device? What options do you have on power?

I’m using a 6V DC power adapter connected to the dedicated power jack available on the board (EMX Dev Sys). When I first connected this board to the PC via USB it was quite clear that an external power adapter would be necessary, since the board didn’t boot properly (the LCD was having problems, not being properly lit and all).

OK, so you have EMX Dev Sys, not Cobra?

The power pack, what amp rating is it? I don’t know DevSys display requirements, but I’d suggest you want a 100mA capacity as a good starting point. The other issue with 6v is that you may not be getting 5v out of the regulator (again I haven’t looked at a DevSys so don’t know what it’s capable of) but that also may influence what you get.

Is the power pack a regulated one? Or just a “regular” not very stable one? Do you have a 7.5V 1A or greater power pack that you can try? or a 5v 1A one that you can input straight into the 5V side of the circuit?

The thinking here is that over USB you get a bit more current capability or at least a stable source, that is then enough to power the device and the RFID reader successfully.

Can you please put some debugging statements that just output to the LCD screen to see what is happening, to see if any serial data output from the RFID module.

What other diagnostic equipment do you have, such as a oscilloscope or even a bus pirate?

Does it work when connected with USB to the pc, but not debugging? (just connect to board to the pc with usb, and try to read a card) If that does work, i would say you have a power issue.

Eric, I did try with the board connected to both the power adapter and to the PC via USB but that doesn’t work either. What I have also noticed is that if I stop the debugging session from inside VS, the system continues to work properly, but once I boot the board it stops working.

Brett, the power adapter I’m using is rated at 6V DC 1.5A. I’m not an expert in this field, but I guess that 1.5A should be more than enough to deliver the amount of current required for this circuit. But again, I’m no hardware expert. Not sure if it’s a “regulated” one either - how can I check for that? At the moment I don’t have any other power adapters like the ones you suggested that I could test out. I have a version of this driver that uses the GLIDE library that outputs information to the LCD (card ID and state of the reader), but this version also behaves in the exact same way, that is, it works only if the app is in debug mode. For diagnostic equipment, I’m not sure if it counts as one, but what I do have is a multimeter. I haven’t gone that far into hardware tinkering that made me feel the need for an oscilloscope and I’m mot sure what a “bus pirate” is… if I had one I’d probably know it, so most certainly I don’t have one. :frowning: Besides this EMX Dev board that I’m using right now, I also have a Cobra board and an additional 3.5" display board. If you guys think it’s worth it, maybe we could use them for some A/B testing.

[quote] public ParallaxRFID(SerialPort serialPort, OutputPort rfidControl, bool autoEnable = true)
{
SerialPort = serialPort;
RfidControl = rfidControl;

        SerialPort.WriteTimeout = WRITE_TIMEOUT;

        SerialPort.DataReceived += SerialPort_DataReceived;
        SerialPort.Open();

        if (autoEnable)
        {
            EnableReader();
        }
    }[/quote]

Open the port before you set the events…enjoy :slight_smile:

Doh, that I didn’t noticed that one…shame shame :-[

Well, guys, that seems to have done the trick! Thanks, Gus. Would you mind explaining me why we shouldn’t set the event handler before opening the serial port?