Eightlines Creations

Experiments in Physical Computing

DLP-RFID1 for Processing

I recently had to set up a Processing application to monitor 15 RFID readers. The source was in C++ so I made a quick port to Processing. I’m adding it here in case it’s of use to anyone using a DLP-RFID1 device. Is there a better way of doing it? I’m open to suggestions!

(Hat-tip to ElectricRock for setting me on the right track.)

 
import processing.serial.*;
 
static final String RFID_PING = "0108000304FF0000";
static final String RFID_AGC = "0109000304F0000000";
static final String RFID_AMPM = "0109000304F1FF0000";
static final String RFID_PASS = "010900030419F00000";
static final String RFID_FAIL = "010900030420F00000";
static final String RFID_INVENTORY = "010B000304140601000000";
static final String RFID_SID = "010B000304340050000000";
static final String RFID_MODE_READ = "010C00030410002101000000";
static final String RFID_MODE_UID = "010C00030410002101020000";
static final String RFID_MODE_TAGIT = "010C00030410002101130000";
 
Serial rfidPort;
int rfidStep = 0;
boolean rfidRunning = false;
 
String uidValue = "";
float uidStrength = 0.0f;
 
int startTime;
 
void setup() 
{
  //DLP-RFID1 Device requires FTDI VCP Drivers
  rfidPort = new Serial(this, Serial.list()[0], 115200); //Set to active Serial Port
  rfidPort.bufferUntil(10); //LineFeed
 
  size(400, 300);
}
 
void draw()
{
  background(50);
 
  if (!rfidRunning)
  {
    rfidRunning = true;
 
    // Sequence PING | AMPM Toggle | UID MODE | INVENTORY is necessary to read RFID Tag.
    // Wait for an echo and response (if there is a response) before proceeding.
    switch (rfidStep)
    {
      case 0: 
        startTime = millis(); //Measure time between poll
        rfidPort.write(RFID_PING);
      break;
      case 1: rfidPort.write(RFID_AGC); break;
      case 2: rfidPort.write(RFID_AMPM); break;
      case 3: rfidPort.write(RFID_MODE_UID); break;
      case 4: rfidPort.write(RFID_INVENTORY); break;
    }
  }
}
 
void serialEvent(Serial port)
{
  String rfidVal = port.readString();
 
  switch (rfidStep)
  {
    case 0: if (rfidVal.toLowerCase().indexOf("dela") > -1) rfidStep = 1; break; //Response "dela"
    case 1: if (rfidVal.indexOf(RFID_AGC.toString()) > -1) rfidStep = 2; break; //Response echo
    case 2: if (rfidVal.indexOf(RFID_AMPM.toString()) > -1) rfidStep = 3; break; //Response echo
    case 3: if (rfidVal.indexOf(RFID_MODE_UID.toString()) > -1) rfidStep = 4; break; //Response echo
    case 4: //Suggest echoing back the entire Inventory Request packet before isolating for the value you want.
      if (rfidVal.indexOf(",40") == -1 &&  //Ignore < ,40> (empty RFID Register)
          rfidVal.indexOf(">") == -1 && //Ignore line feed
          rfidVal.toLowerCase().indexOf("iso 15693 inventory request.") == -1 && //Ignore packet header
          rfidVal.toLowerCase().indexOf("register write request.") == -1 && //Ignore packet header
          rfidVal.toLowerCase().indexOf("interrupt error.") == -1) //Ignore error
      {
        String uid = rfidVal.substring(1, rfidVal.length() - 6); //All I'm looking for is the UID of the RFID tag.
 
        float signalStrength = 0.0f; //Signal strength is passed with the UID. Hardly useful at 4cm though.
        if (rfidVal.indexOf("[,00]") == -1)
          signalStrength = map(unhex(rfidVal.substring(rfidVal.length() - 5, rfidVal.length() - 3)), 72, 109, 0, 100);
 
        uidValue = uid;
        uidStrength = signalStrength;
 
        float elapsedTime = millis() - startTime;
 
        println(uid + ", " + signalStrength + ", " + elapsedTime + "ms"); //Echo the result to the Serial Monitor
        rfidStep = 0; //Start the poll over again.
      }
    break;
  }
 
  rfidRunning = false; //Start the poll over again.
}
 

Next up, I’m pulling the device apart to add a visual indicator to the PASS/FAIL speaker. In noisy environments you can’t hear these devices fire.

Search

The archives run deep. Feel free to search older content using topic keywords.