/* * Created on Mar 2, 2005 */ import Phidgets.*; import java.util.Timer; import java.util.TimerTask; /** * This class handles the detection of RFID-tags on a PhidgetRFID. The class * is used first to set up a PhidgetRFID and then, when a tag is detected, to * call appropriate listener methods. *
* The problem with the original PhidgetRFID is that there only exists one * event, which is a onTag-event that is thrown continuously as long as a * tag is present. The solution taken here is to start a timer when a tag * is detected. The timer detects when a tag is removed by detecting the * absence of onTag-events. */ public class RFID extends _IPhidgetRFIDEventsAdapter { private PhidgetRFID rfid; private RFIDEventListener RFIDListener; private Timer timer; public final int TIMER_PERIOD = 300; private String[] tags = new String[10]; private boolean[] active = new boolean[10]; private int counter = 0; /* (non-Javadoc) * Convert onTag events into tagDetected and tagDetached events. */ public void OnTag(_IPhidgetRFIDEvents_OnTagEvent e) { int pos = 0; // If the tag is new, call tagEntered and start a timer // to detected when the tag is removed. if ((pos = inArray(tags, e.get_TagNumber())) == -1) { counter = (counter + 1) % active.length; active[counter] = true; tags[counter] = e.get_TagNumber(); RFIDListener.tagEntered(e.get_TagNumber()); timer.schedule(new TagRemoved(counter), 0, TIMER_PERIOD); } else { // A timer is already active for this tag, therefore // set its read-value to true. active[pos] = true; } } /** * Check if a string is stored in a string array. * @param array the string array * @param needle the search string * @return If found, the index of the string, otherwise -1. */ private int inArray(String[] array, String needle) { for (int i = 0; i < array.length; i++) { if (array[i] != null && array[i].equals(needle)) { return i; } } return -1; } /** * Detect when a RFID-reader is detached. * @param e detach event */ public void OnDetach(_IPhidgetRFIDEvents_OnDetachEvent e) { System.err.println("PhidgetRFID was detached!"); } /** * Setup any connected RFID-reader. */ public RFID() { init(0); } /** * Setup a specific RFID-reader. * @param serial the serial number of the RFID-reader */ public RFID(int serial) { init(serial); } /** * Initiate the PhidgetRFID hardware. If no Phidget is found * a RuntimeException is thrown. * @param serial the serial number of the RFID-reader * to be initiated. If set to 0 (zero) any * detected phidget is attached. */ private void init(int serial) { rfid = new PhidgetRFID(); rfid.add_IPhidgetRFIDEventsListener(this); if (serial > 0) { if (rfid.Open(true, serial) == false) { throw new RuntimeException("Could not find the PhidgetRFID" + "with serial: " + serial); } } else { if (rfid.Open(true) == false) { throw new RuntimeException("Could not find a PhidgetRFID"); } } rfid.SetOutputState(3, true); timer = new Timer(); } /** * Begin listening for RFID-tags in a seperate thread. */ public void start() { rfid.start(); } /** * Begin listening in the calling thread, blocking mode. */ public void run() { rfid.run(); } /** * Add a listener which handles the events that * are thrown when a Tag is detected. * @param listener a listener for RFIDEvents */ public void addEventListener(RFIDEventListener listener) { RFIDListener = listener; } /** * Privat klass som används för att känna av när en tag avlägsnas * från läsaren. Klassen startas med en Timer och nollställer * den inlästa taggen 5 ggr per sekund. Om ingen ny tag läses av * på 1 sekund innebär det att taggen avlägsnats och då skickas * ett event till lyssnaren. */ private class TagRemoved extends TimerTask { private int absence = 0; private int pos; /** * Create a new Timer for each tag * @param pos index of the tag */ public TagRemoved(int pos) { this.pos = pos; this.absence = 0; } /* (non-Javadoc) * @see java.lang.Runnable#run() */ public void run() { if (active[pos]) { absence = 0; } // Check if tag has been absent 10 times the // timer period. if (absence++ > ((TIMER_PERIOD * 10) / TIMER_PERIOD)) { RFIDListener.tagRemoved(tags[pos]); tags[pos] = null; cancel(); } active[pos] = false; } } }