FEZ Cerberus with RFID

Hi,
I was able to get the FEZ Cerberus working with no issues with the RFID reader module.
I started this project so I could use my work badge to help log some things however I can not get my badge to read at all.

My work badge is a IDentiPROX card: IDentiPROX™ PVC Proximity Card | IDenticard.com

I was told this is a 125 kHz card… and thus I figured it should work the the 125 kHz GHI RFID Reader Module.

Since I haven’t been able to get my work badge to work with the GHI RFID module, I was wonder if someone could please help me hook up a reader my work currently uses in their security system.

I have attached the image of the ProxPoint Plus reader as well.

Thanks in advance

Take a look at the Gadgeteer source for the RFID reader. I looked at it once, and I believe it was coded to expect the message length to be that of the cards that came with the reader. Get the source and use the debugger to see if anything is being read.

*** I just checked the code. It expects a 13 byte message. *****

hi there,

as you found, HID cards are not standard RFID cards readable with a standard reader, they have proprietary encryption and require a specific reader.

As for interfacing the HID reader, that might be a little more work :slight_smile: The regular reader is a UART based device, but the connections on that HID card are not UART based. And you’ll need to find out what the actual protocol is that they use on those pins. So it’s time for you to start digging out any internet references you might find, and I am not sure how easy that will be.

Hey Mike,

I’ve tried the following and it didn’t work either.

public class IdentiProxReader: Module
    {
        private byte[] buffer;
        private int checksum;
        private const int MESSAGE_LENGTH = 13;
        private IdReceivedEventHandler onIdReceived;
        private MalformedIdReceivedEventHandler onMalformedIdReceived;
        private Serial port;
        private int read;
        private Timer timer;

        public event IdReceivedEventHandler IdReceived;

        public event MalformedIdReceivedEventHandler MalformedIdReceived;

        public IdentiProxReader(int socketNumber)
        {
            Socket socket = Socket.GetSocket(socketNumber, true, this, null);
            socket.EnsureTypeIsSupported('U', this);
            this.buffer = new byte[13];
            this.read = 0;
            this.checksum = 0;
            this.port = SerialFactory.Create(socket, 0x2580, SerialParity.None, SerialStopBits.One, 8, HardwareFlowControl.NotRequired, this);
            //this.port = SerialFactory.Create(socket, 0x2580, SerialParity.None, SerialStopBits.Two, 8, HardwareFlowControl.NotRequired, this);
            this.port.ReadTimeout = 10;
            this.port.Open();
            this.timer = new Timer(100);
            this.timer.Tick += new Timer.TickEventHandler(this.DoWork);
            this.timer.Start();
        }

        private int ASCIIToNumber(byte upper, byte lower)
        {
            int num = (upper - 0x30) - ((upper >= 0x41) ? 7 : 0);
            int num2 = (lower - 0x30) - ((lower >= 0x41) ? 7 : 0);
            return ((num << 4) | num2);
        }

        private void DoWork(object o)
        {

            if (this.port.BytesToRead > 0)
            {
                byte[] myBuffer = new byte[this.port.BytesToRead];
                this.port.Read(myBuffer, 0, myBuffer.Length);
                Debug.Print("Read: " + myBuffer.Length + " bytes");
            }
            /*
            this.read += this.port.Read(this.buffer, this.read, 13 - this.read);
            Debug.Print(read.ToString());
            if (this.read == 13)
            {
                for (int i = 1; i < 10; i += 2)
                {
                    this.checksum ^= this.ASCIIToNumber(this.buffer[i], this.buffer[i + 1]);
                }
                if (((this.buffer[0] == 2) && (this.buffer[12] == 3)) && (this.checksum == this.buffer[11]))
                {
                    this.OnIdReceived(this, new string(Encoding.UTF8.GetChars(this.buffer, 1, 10)));
                }
                else
                {
                    this.port.DiscardInBuffer();
                    this.OnMalformedIdReceived(this, null);
                }
                this.read = 0;
                this.checksum = 0;
            } */
        }

        private void OnIdReceived(IdentiProxReader sender, string e)
        {
            if (this.onIdReceived == null)
            {
                this.onIdReceived = new IdReceivedEventHandler(this.OnIdReceived);
            }
            if (Program.CheckAndInvoke(this.IdReceived, this.onIdReceived, new object[] { sender, e }))
            {
                this.IdReceived(sender, e);
            }
        }

        private void OnMalformedIdReceived(IdentiProxReader sender, Microsoft.SPOT.EventArgs e)
        {
            if (this.onMalformedIdReceived == null)
            {
                this.onMalformedIdReceived = new MalformedIdReceivedEventHandler(this.OnMalformedIdReceived);
            }
            if (Program.CheckAndInvoke(this.MalformedIdReceived, this.onMalformedIdReceived, new object[] { sender, e }))
            {
                this.MalformedIdReceived(sender, e);
            }
        }

        public delegate void IdReceivedEventHandler(IdentiProxReader sender, string e);

        public delegate void MalformedIdReceivedEventHandler(IdentiProxReader sender, Microsoft.SPOT.EventArgs e);
    }

No data arrives when trying to use my card.
The RFID Module doesn’t even appear to be detecting the card(no lights flicker)

@ Brett - As Brett mentioned these are a different beast and as a starting point http://www.hidglobal.com/sites/hidglobal.com/files/hid-understanding_card_data_formats-wp-en.pdf

@ Michael Kaufman - You can’t use GHI reader. You need to interface with the HID reader in your last picture. Most likely Wiegand interface.

@ Architect - You are correct. I just found out this uses Wiegand.
I did a quick search on the forums and it doesn’t appear anyone has implemented the Wiegand protocol in .NET?

@ Michael Kaufman

The old legacy devices were not fast enough to do required bit banging via managed code.
I haven’t tried since then.

RLP if needed :slight_smile:

@ Architect - I can try to use the current Cerberus to see if it will process it.
Would the following be the concept you would use?

Take two ports on the board and set both of their Pin 3 to be an interrupt pin.
Capture and process the interrupts.

@ Brett - RLP… I’m a big noob… mind linking? :slight_smile:

@ Michael Kaufman - You can try use both data lines as interrupts. You also have violet wire which is “card present” signal. If interrupt approach wouldn’t work I would try RLP as @ Brett suggested. I would call it when “card present” signal is asserted.

Yeah I totally agree with architect, go and use the RLP

So using RLP would the approach be to do the following:

In managed code create an interrupt on pin 3 and tie that to the “card present” signal.

Create a native code RLP that monitors 2 digital input signals (D0/D1) in a while loop, recording the signals?

Then call a PostManagedEvent inside the native code passing this data back to the managed code?

Yes, something like that.

Im an RLP-wuss, so I just use a $5 ebay-china-duino-nano as a bitbang-aggregator for these sorts of things…

I should figure out RLP someday, given the awesome tutorials I’ve seen on here.

Yes, that what we ended up doing. POE arduinos.

So I want to go ahead and attempt to use RLP.
First, since we only want RLP running when its required… I want to catch when a card present signal is triggered.

For this example I’m using Port 6 on the Cerberus board.
I have a Breakout board attached to Port 6 with the following pins connected to the ProxPoint plus reader

PIN 2 = Red (5V)
PIN 3 = Violet (Card Present)
PIN 4 = Green (DATA0/DATA)
PIN 5 = White (DATA1/CLOCK)
PIN 10 = Black (GND)

The following software is currently not working… but what I’m wanting to do is create a interrupt on Port 6 Pin 3 and detect when a card is present.

I’ve measure the voltage between PIN 3 and PIN 10 and it is 4.56V.
When scanning my badge the interrupt is not triggered.
However, If I disconnect PIN 3 from the breakout board during operation the interrupt is triggered.

    public partial class Program
    {
        private InterruptInput cardPresent;

        // This method is run when the mainboard is powered up or reset.   
        void ProgramStarted()
        {
            characterDisplay.BacklightEnabled = true;
            characterDisplay.Clear();

            cardPresent = breakoutPort6.CreateInterruptInput(GT.Socket.Pin.Three, GlitchFilterMode.Off, ResistorMode.Disabled,
                InterruptMode.FallingEdge);

            cardPresent.Interrupt += CardPresentOnInterrupt;
            characterDisplay.Print("Ready...");
        }

        private void CardPresentOnInterrupt(InterruptInput sender, bool value)
        {
            // Launch RLP Code
            Debug.Print("Launch RLP");
        }
    }

@ Michael Kaufman - I would check with logic analyser or oscilloscope that the line is actually working before connecting it to Gadgeteer.

@ Architect - I don’t have one unfortunately. Anything else I can do?