Race Check-in System: Creating RFID tags in real-time at registration
Post date: Apr 1, 2014 1:38:39 PM
I finally got to debugging the part of the application that write tags during the check-in process.
It now works - the system can use each of the 4 antenna ports to write chip tags, in real-time, as part of the check-in process.
The idea behind race check-in is address the "empty space" between on-line race registration and results. It was motivated by the observation that CrossMgr had greatly reduced the errors at the finish line, and provides graphic user interfaces to fix remaining problems quickly. The main source of results errors were from riders getting the wrong bib, duplicate bibs in the same race, managing day-of riders, and delays from information from registration getting to the results system in time for the race start.
The race check-in system is a web-based database that enables rider confirmation (name, team, category), payment verification, bib and chip distribution to quickly and error-free by novice volunteers via a web browser interface.
A few minutes before the race start, it generates a "perfect" file for CrossMgr to get results (all rider information, all categories, etc.). Unlike a manual system, the check-in system allows riders to confirm for any race at any time - not just the next event. This reduces bottlenecks further as riders can get their bib numbers at any time for any race.
The system already supports barcode readers and an electronic signature pad for a paperless process. Duplicate bib numbers and chips are relics of the past - bib numbers do not need to be assigned before they are distributed - the database ensures that it is impossible to assign duplicates.
To write tags, near-field antennas are connected to the rfid-reader, which is connected to the web server machine.
Web browsers accessing the server (LAN or wireless) send write requests (they specify the tag and the antenna in the request).
This causes the server to trigger the rfid-reader to write that tag id at that antenna in a synchronous call (i.e. the web client thread waits).
If successful (as verified by reading the tag after writing it), the browser shows the result on the web page. Otherwise the browser displays the error.
I am testing with one of the R1000's to check performance - about 0.4 seconds to write a tag - not bad considering what it actually has to do to pull this off (see below).
With 4 tag-writing stations, if each station requested a tag write at exactly the same time, the requests would be queued, and the last request would be finished in about 2 seconds.
This behavior required a surprising number of moving parts.
The web server is multi-threaded (each client is processed in its own thread), however, the rfid-reader supports one connection at a time.
The solution was to write a single-threaded non-blocking rfid-server to queue up the write requests, send them to the rfid-read in sequence (specifying the tag to write and the antenna), and make sure the success/fail response gets back to the correct client through the socket.
So, the web server opens a socket for HTTP requests, and the rfid-server opens a socket on localhost to process rfid commands coming from clients managed in the web server.
Launching the application actually launches two servers - the web server, and the rfid-server.
The rfid-server runs in its own thread. It also requires another thread to monitor it in case it loses the connection to the rfid-reader and dies. When this happens, the monitor starts a loop trying to reconnect every 3 seconds.
While this is going on, the web server/database is still functional - it will just fail to write tags.
All the magic happens under the covers when the application is started.
Whew! Time to go build a space shuttle - it has got to be easier...
If anyone has a simpler suggestion, let me know.
Lots of documentation to write now...