Wednesday, 19 March 2014

Testing RFID door entry system for BuildBrighton

Next Thursday night is BuildBrighton Open Evening, and we'd promised to have the new door entry system working. In principle, it's a fairly straight-forward idea, but - as with most software (and hardware) development - most of the effort seems to be going into the "fail-safe": what happens if, for example, the internet connection goes down?

Firstly, here's the theory of how it works:
We have a members website for BuildBrighton, and our key-issuing members can access an admin screen, which allows them to issue keyfob numbers to members, and to activate certain "flags" on the keys (so the same keyfob could, in future, be used to access lots of different pieces of equipment - for now, we're concentrating on opening the door).


Each member has an RFID keyfob number against them, and a number of flags to say what that keyfob can do. This can be administered by anyone with admin access to the BuildBrighton members website.

For testing, we've removed the ethernet-to-UART module, and have plugged in our PICKit2 Programmer, which has a simple UART interface, so we can emulate sending data backwards and forwards between the RFID reader and the website (it can be difficult, during testing, to force a network error - or diagnose an error reported on the hardware, when everything looks like it should be working, and there's fault on the web server!)


We've also added in loads of logging into the microcontroller handling the data between the RFID reader and the web server, so that we can see how different conditions are being handled.

The first thing to do is present a keyfob/rfid card (the reader works with any 125khz RFID tag) to the reader. The hardware displays the number read from the fob on the character LCD (the reason for this will be explained in a moment) and then tries to contact the web server.


As we're using an ENC28J60 ethernet modules with another microcontroller attached (it'll be an ATMega328 but we're prototyping on a full Arduino) to do all the talking over the internet, we can simply send this ID number over serial/UART. The ethernet module will post this ID number to a URL and await a response from the remote web server. Any data sent back from the web server appears on our hardware here as a serial string of data.



We're emulating this by simply typing data into our PICKit2 UART module.
When a correctly formatted response is received on our hardware, it displays the name of the keyholder for confirmation:


So far, so simple.
The bulk of the work in this project, however, has gone into making sure the device works when there's a network error. So, each time valid data is received from the internet, we store it in some local eeprom (that's what the 24C256 eeprom chip is doing there). That way, if ever we don't get the expected response from our web server, we can compare the keyfob ID against a known "database" of valid fob numbers. If there's a match, we use the credentials stored in eeprom, rather than over the 'net.
The next time the same keyfob is presented to the hardware, it checks against the web server first - so any updated credentials get downloaded to local eeprom, once the internet connection is back up and running.

Here it is in action:



And here's the massive data logging output.


Starting keyfob reader
Flushing buffer 176 96 193 131
Keyfob reading complete
Sending data to ethernet
176096193131:0100:0
Data received: OK:8761:Chris Holden

Reading eeprom address 0
Data from eeprom: 255 255 255 255
Keyfob serial: 176 96 193 131
Writing new record at 0
End writing eeprom

Starting keyfob reader
Flushing buffer 35 70 141 26
Keyfob reading complete
Sending data to ethernet
035070141026:0100:0
Data received: OK:8761:Steve Carpenter

Reading eeprom address 0
Data from eeprom: 176 96 193 131
Keyfob serial: 35 70 141 26
Reading eeprom address 32
Data from eeprom: 255 255 255 255
Keyfob serial: 35 70 141 26
Writing new record at 32
End writing eeprom

Starting keyfob reader
Flushing buffer 35 70 141 26
Keyfob reading complete
Sending data to ethernet
035070141026:0100:0
Data received: ERROR

Reading eeprom from 0
Data from eeprom: 17696193131
Keyfob serial: 35 70 141 26
Reading eeprom from 32
Data from eeprom: 357014126
Keyfob serial: 35 70 141 26
Record foundData received: OK:8761:Steve Carpenter


Starting keyfob reader
Flushing buffer 176 96 193 131
Keyfob reading complete
Sending data to ethernet
176096193131:0100:0
Data received: OK:0000:Chris Holden

Reading eeprom address 0
Data from eeprom: 176 96 193 131
Keyfob serial: 176 96 193 131
Data found at address0
Updating record
End writing eeprom

Starting keyfob reader


So what's happening in the video?
To begin with, we presented a new card to the system. It queried the remote server (sending the key ID 176096193131) and we emulated a valid response. The response "OK:8761:Chris Holden" tells the hardware who the key belongs to, and which flags are set for that person (effectively, which bits of equipment this keyfob is valid for, so they can be compared to the flags in the hardware device).

This activity is reflected in the log above.
After receiving the data, the hardware then looks through the eeprom chip, reading 4 bytes at a time and comparing them to the 4 bytes read from the RFID tag. If it finds a match, it will update the following "record" in eeprom. If it finds a series of four 0xff bytes, this indicates a blank bit of eeprom memory (where we've reached the end of all the records) and so writes a new record at this address.

We can see this happening, in the log above.
At address zero, there are four lots of 0xff (since the eeprom chip at this point is completely empty). So a new record is written, starting at address zero.

Then, in the video, we pick up the blue keyfob and present this to the reader.
The results of this can be seen in the log above - the web server responds with an OK message and identifies the keyfob as belonging to Laser-Robot-Steve. If you read through the log, after this, you can see that the previous record is found in eeprom, at address zero, so it skips forwards 32 bytes, and reads another 4 bytes back. This time, four sets of 0xff are found (blank data) so it knows it's reached the end of the data in the eeprom chip, and adds another new record.

So what if we present a keyfob but the internet connection is down?
We simulated this by having the serial response from the ethernet module read "ERROR"
And you can see in the video, the hardware identifies the error, but then after querying the eeprom chip, validates the keyfob as belonging to Steve - and so activates the door lock and lets him in, even though the internet connection was down.

By reading through the log above, we can see that after receiving an ERROR response, the hardware queries the eeprom chip. At address zero it finds four bytes, but these do not match the ID from the keyfob, so it jumps forward 32 bytes and tries again. This time, it does find a match, and so validates the user as Robot Steve, and opens the door.

Now Steve's been let into the 'space, he can reboot the router and get the internet connection working for anyone else who needs to access the space using their RFID tag. Without this safety net, there's a good chance that we'd end up with a queue of people all on the outside, not able to get in, to sort out the problem causing the internet connection failure that was keeping everyone out!


The last bit of logging (not shown in the video) shows how keyfob credentials are updated by the members-only website. In the last example, the flags for Chris Holden have been reset to zero on the website (as if the keyfob has been revoked). When the revoked keyfob is presented to the RFID reader, the new credentials are downloaded from the web server, the appropriate record is found in eeprom, and is updated/overwritten. So in the event of another internet failure, the key remains revoked once contact has been made with the web site (and doesn't let Nasty Chris in, if he's cut the cables to the phone lines on a future visit, for example!)

Hopefully we don't have to worry about revoking access with BuildBrighton members.
But exactly the same principle can be used to grant additional access to tools, equipment etc. to users in future. So once a user is issued with their own RFID tag, they could use this to, say, activate the laser cutter and log time used on it, or power up the CNC with their RFID tag.
We're a long way from it, but the principle could be extended by other people using this system for things like snack purchases and donating for hardware use, even if the member doesn't have any cash on them at the time.

Hopefully we'll have more ideas on Thursday evening, when the new system "goes live".