RFID Project: Advice needed

Greetings,

I am building an RFID based Lap Counter for my base (USAF). The premise is using RFID to get accurate lap counts and times for each runner completing his/her annual assessment. I have several Photons and several Electrons at my disposal. More on this in a second…

I purchased a Simultaneous RFID Tag Reader from Sparkfun and some tags and have been experimenting with it. A Windows based software is available to use called Universal Reader Assistant. The software is a little on the cheezy side. I can read tons of tags at once but during each read cycle 1 single tag might have a read count of say 20 times and the latest read is what gets timestamped. Clearly this software won’t help me accomplish my goal. So on to exploring my options.

I started to think, what I used a Particle Device! I have built some web based application with Electrons to activate/deactivate lights. So the first problem is I don’t think I can get away with the Photons as they need a form of WiFi nearby to reach the cloud. Some of the annual assessments are outside and some are inside. The Mesh devices would be super cool because I could put a single Electron in between the two testing locations and let the Mesh device collect the data and call home with the Electron. Downside is the Mesh devices don’t ship until July and I have a project deadline of 4 weeks! So an Electron it is…

**Problem/Question #1 **
The RFID reader is 5V. Will the Electron play nice on the TX/RX lines with this or is a Logic Level Shift required?

Problem/Question #2
The is a shield for the Photon to handle Arduino Shields. Is there any plans to release one for the Electron?

Problem/Question #3
The Run track might have anywhere between 8 and 15 runners going around at the same time. Clearly not every single runner will travel at the same pace. But what if I have 4 guys cross the line at the same exact time? I know the ready will handle fine. But what about the Electron? How in code, could I be certain that all 4 runner’s lap times are successfully published to the cloud? I would be essentially grabbing these events and letting the Web Based Application gather the data and store via Firebase.

Side Question 3A
Can Particle Developers look into a Firebase integration?

Problem/Question #4
As mentioned before, the read will literally read the same tag like 22 times in one read cycle. If I were to count that runners would complete there test in a matter of seconds! Great for them/Bad for me :frowning: How would one take all the tag reads that occured in that very short period of time (500ms) and only take the earliest read from each runners tag and send each to the cloud?

I know my question is fairly long and complex, I would really just like to confer with others on how this might be done. Or at least find something I haven’t thought of.

_Cheers, _

Coach Allen

P/Q 1: The Electron shouldn’t be the issue, as it accepts 5V on the RX line, the question is, does the RFID reader see the 3.3V TX data from the Electron as sufficient. The datasheet should provide this info.
But, how do you intend to power the RFID reader? Will you have a 5V source available?

P/Q 2: You can use the Photon Shield Shield with the Electron just having it’s extra pins overhang. Other then that I doubt there will be an Electron Shield Shield - the Photon Shield Shield already has some issues with several Arduino shields, so I’d rather think Particle will focus on the Adafruit Feather Wings.

P/Q 3: For good practice you’d need to timestamp each RFID event on arrival and then can do what you like with it. You could pack multiple events into one publish (e.g. via JSON arrays) or queue them and send them at a 1 per second rate.

P/Q 4: That’s a similar issue as button debounce. The strategies used for that should apply here too.
e.g. First event for ID gets the timestamp, subsequent triggers for same ID will be discarded till currentTime - timestamp > minimumTrackTime.

Additinal question is: How fast does the RFID reader need to be serviced to provide the parallel events? Does it queue the events or only provide the RFIDs in sight at the moment? The speed of the Electron may or may not play a role here.
Tests required.

The reader needs a 5V source capable of 2A

Really not sure... Will look into this.

Bummer! Good to know for future projects though. Perhaps I will have make a PCB and work out the power to feed both safley. and include the lines for RX and TX between the two.

Not a super programmer yet. What does a queue snippet for 1/s look like?

Good point! I have yet to see a runner go round faster than 15 seconds. So I will need to take those instantaneous reads and just trash any that aren't unique I suppose.

By the way here is the reader for your situational awareness.
RFID Reader at Sparkfun

There are a few threads going in this direction
e.g.
Circular Buffer For Handling Rapid Particle Events
New library to delay Publish to cloud: PublishQueue

But I'd actually go for the multi-trigger-one-event path.

So as it turns out The Photon RedBoard has the power needed to supply the reader. Awesome!

After reading the datasheeet the RFID reader communicates on 3.3v so no LLC needed. Splendid!

So here is an update:

I could not seem to get the RFID reader to work directly as a shield on top of the Sparkfun Photon based RedBoard. They didn’t seem to like each other.

So I planted the RFID shield right on top of a Sparkfun RedBoard and provided the RedBoard the following code:

#include "SparkFun_UHF_RFID_Reader.h"
#include <SoftwareSerial.h>

SoftwareSerial rfSerial(2,3);
SoftwareSerial ptSerial(8,9);

RFID rfid;

void setup()
{
  Serial.begin(115200);
  ptSerial.begin(115200);

  Serial.println("Initializing...");
  ptSerial.println("Initializing...");

  if (setupNano(38400) == false)
  {
    Serial.println("Check Wiring");
    ptSerial.println("Check Wiring");
    while (1);
  }

  rfid.setRegion(REGION_NORTHAMERICA);
  rfid.setReadPower(500); // 5.00 dBm

  Serial.println("Starting Scan...");
  ptSerial.println("Starting Scan");

  rfid.startReading();
}

void loop()
{
  if (rfid.check() == true)
  {
     byte responseType = rfid.parseResponse();

     if (responseType == RESPONSE_IS_KEEPALIVE)
     {
        Serial.println(F("Scanning"));
        ptSerial.println(F("Scanning"));
     }
    else if (responseType == RESPONSE_IS_TAGFOUND)
    {
       int rssi = rfid.getTagRSSI(); //Get the RSSI for this tag read
       long freq = rfid.getTagFreq(); //Get the frequency this tag was detected at
       long timeStamp = rfid.getTagTimestamp();
       byte tagEPCBytes = rfid.getTagEPCBytes(); 
       
       Serial.print(F(" rssi["));
       Serial.print(rssi);
       Serial.print(F("]"));

       Serial.print(F(" freq["));
       Serial.print(freq);
       Serial.print(F("]"));

       Serial.print(F(" time["));
       Serial.print(timeStamp);
       Serial.print(F("]"));

       ptSerial.print(F("RSSI: "));
       ptSerial.print(rssi);
       ptSerial.print(F(" "));

       ptSerial.print(F("Freq: "));
       ptSerial.print(freq);
       ptSerial.print(F(" "));

       Serial.print(F("Tag: "));
       ptSerial.print(F("Tag: "));
       for (byte x = 0 ; x < tagEPCBytes ; x++)
       {
          if (rfid.msg[31 + x] < 0x10) Serial.print(F("0"));//Pretty print
          Serial.print((char) rfid.msg[31 + x]);
          ptSerial.print((char) rfid.msg[31 + x]);
        }
       Serial.print(F(" "));
       Serial.println();
       ptSerial.println();
   }
  else if (responseType == ERROR_CORRUPT_RESPONSE)
  {
    Serial.println(F("Bad CRC"));
    ptSerial.println(F("Bad CRC"));
  }
  else
  {
     Serial.println(F("Unknown Error"));
    ptSerial.println(F("Unknown Error"));
   }
  }
}

boolean setupNano(long baudRate)
{
  rfid.begin(rfSerial);
  rfSerial.begin(baudRate);

while (!rfSerial);
while (rfSerial.available()) rfSerial.read();

 rfid.getVersion();

 if (rfid.msg[0] == ERROR_WRONG_OPCODE_RESPONSE)
 {
  rfid.stopReading();
  delay(1500);
 }
else
{
  rfSerial.begin(115200);
  rfid.setBaud(baudRate);
  rfSerial.begin(baudRate);
 }

 rfid.getVersion();

 if (rfid.msg[0] != ALL_GOOD) return (false);
 rfid.setTagProtocol();
 rfid.setAntennaPort();
 return true;
}

Anything that says:

ptSerial is for the Photon RedBoard hooked up via Serial1
rfSerial is for the RFID reader built into the shield

I then read this arbitrarily like this on the Photon RedBoard:

void setup(){
   Serial1.begin(115200);
}

void loop(){
  if(Serial1.available()){
      String s = Serial1.readStringUntil('\n');
      Serial.printlnf("Recieved: %s", s.c_str());
  }  
}

Which will output this in the Particle CLI in terminal:

Recieved: RSSI: -46 Freq: 925200 Tag: TestTrackTag03

Dozens of times during a tag read. Now I need to read though how only really care about unique hits by each tag as there could possibly be 3-5 tags crossing the lap line at a time. Then publishing those in a queue.

Cheers,

Clayton Allen

1 Like

Clayton,

Any updates here? Working on something similar. You couldn’t just connect the SparkFun simultaneous RFID reader straight to the electron, correct?

I do apologize for the super late response KWL. The reader is in the form of an Arduino Shield. Thus that is the first hurdle to making it fit up to the Electron. I would like to mention @BulldogLowell really helped get this off the ground I still have to make some tweaks to his code though as he gave some recommendations that I have yet to implement. I have been really busy at work for the last week or so. I am back at it now. Please let us know how you get on with it.

I am no coding expert as you might have gathered from the thread but I sure would like to try helping if I can.

Cheers,

1 Like

Here is the enclosure I designed for the box 3D printed last night. Now I am off to build a PCB for the buttons which will be connected to the Sparkfun RedBoard through the RFID shield.

3 Likes

Thanks for the update. I read through the other threads and am reading to take a dive. From what I understand…You have the Arduino & Simultaneous RFID Reader communicating back to the electron and then sending that data via cellular up to Firebase?

I’m trying to work on a slightly different project. One where I can trigger a read and then stamp a GPS read on as well.

Exactly! Once the data is in Firebase I will work out how to associate the Tag EPC to the runners and save their lap times and overall run time.

I don't think it should be too difficult to accomplish you could send a Serial message back the Arduino saying "ScanTags" and once the tag is found you can report back to the electron with the GPS attached with the tag EPC bytes and send to wherever you need that data to live.

Cheers,

Awesome, thanks for the help. Tremendous head start.

How are you handling power? Is the Electron & Arduino/RFID Module powered separately? I’ll keep you posted on my progress.

I have a 5V 2A wall wart on hand. So Intend to have the lipo battery attached to the Electron whilst feeding it 5V from the Arduino. I don't think this is optimum by any means but it will have to do for now until I find a wall wart that can supply more amps.

Callen,

Do you mind sharing a picture of your setup? Just want to make sure I’m not screwing anything up? Or a rough schematic?

Yes once I get it all working with the Electron I will certainly share.

@BulldogLowell I am having some difficulty with the firmware using the Electron. I am having to read from Serial4 and:

if (Serial4.available()) {
    if (Serial4.peek() == '\r') { // ditch the <CR>
      Serial4.read();
      return nullptr;
    }
    incomingMessage[idx] = Serial4.read();
    if (incomingMessage[idx] == endMarker) {
      incomingMessage[idx] = '\0';
      idx = 0;
      return incomingMessage;
    } else {
      idx++;
      if (idx > MAX_MESSAGE_LENGTH - 1) {
        //stream.print(F("{\"error\":\"message too long\"}\n"));  //you can send an error to sender here
        idx = 0;
        incomingMessage[idx] = '\0';
      }
    }
  } 

Is not reading anything at all.

Which function does that belong.

If you keep your interface variable you can easily check the code with any of the other available serial interfaces without any further change.
This keeps you from needing to scratch your head whether or not this is related to the actual interface or not - just swap the interface, rewire and test again.

One way to do that is via

USARTSerial &rfidSerial = Serial4; // or Serial1 or any other you like (just not Serial or ParticleSoftSerial ;-)

and replace all the instances of your hardcoded interface with your reference variable and you’re good to test.
If you want to keep things so flexible to even target Serial or ParticleSoftSerial you could use Stream as common base class (instead of USARTSerial).

Just as a shot in the blue: Have you double checked the wiring C2/RX4 connected to TX and C3/TX4 connected to RX on the reader.

1 Like

Sorry about the confusion. I got it working again. It was an error in code from the Arduino side of the project.

So as usual, fixing one issue leads to 10 new ones.

Now it’s mainly power. The Electron only likes a maximum of 12v and my Arduino can handle up to 15v. The Arduino running a RFID scanner needs at least 2A to be happy. The Electron needs at least a 1.5A source to be happy.

The first uneducated thing I tried was to feed the Electron from the Arduino 5V pin. Which can only source 800mA. So I hooked up a 12V 29A Chinese Meanwell power supply. But I think the EMI from that is affecting the components around it. For example the Serial LCD screen goes nuts around it. Now the screen is a brick.

So I have a power supply from an old Nintendo Wii capable of 15V 5A that I will hack to feed a circuit that will feature a couple of voltage regulators the feed each system.

Are you saying that because that's what Particle recommends or from experience?

The PMIC can accept 15v; Particle only recommends 12v to be on the super safe side. The Electron will get warmer when charging the battery at full power when the input voltage is in the higher ranges.

If you're not charging the battery then feeding the Electron 15v on the VIN pin should be fine and heating should be minimum.

Does that Meanwell power supply have a built-in fan?

I have found Meanwell equipment to well built and reliable.

This is a Chinese knock-off so I doubt it’s as good as the legit ones.