Simultaneous RFID lap timer

Hi all. It has been a while since I have been able to experiment with Arduino. My last project was accomplished by the help from everyone on this forum. Life got in the way since my last project but am trying to get back into it.
Last time you all helped me with building an IR lap timer to communicate with Zround lap timing software. That has been great and have been using it for years now. I think I have hit the limit to what IR can do for me. I just purchased the new Sparkfun Simultaneous RFID reader and some tags. I am hoping to adapt the code/sketch to make this work with little changes. I have played with the reader a bit to get an idea on how things work, but I am now back in over my head with trying to rewrite the code (I am great with hardware, crap with code). Here is the original IR lap timer code, written by someone on Github and adapted for 4 IR zones by myself and another member.

#include <IRremote.h>

int m, s, mu=0, md=0, su=0, sd=0, l=0, lu=0, ld=0, lc=0, redLed=5, gate=6, reset=7, greenLed=4, zround=0, tx=0, timer=0, connect=1, led_status = 1;
const int RECV_PIN = 9;
const int RECV_PIN2 = 10;
const int RECV_PIN3 = 11;
const int RECV_PIN4 = 12;

long int time, timeStart;
IRrecv irrecv(RECV_PIN);
IRrecv irrecv2(RECV_PIN2);
IRrecv irrecv3(RECV_PIN3);
IRrecv irrecv4(RECV_PIN4);

decode_results results;
decode_results results2;
decode_results results3;
decode_results results4;

char message[3];

// **********************************************************************************

void setup() {
    Serial.begin(19200);
    pinMode(redLed,OUTPUT);
    pinMode(greenLed,OUTPUT);
    pinMode(gate, OUTPUT);
    pinMode(reset, OUTPUT);
    irrecv.enableIRIn();
    irrecv2.enableIRIn();
    irrecv3.enableIRIn();
    irrecv4.enableIRIn();
    connect_Zround();
}

void loop() {
  
}

// **********************************************************************************

void connect_Zround() {

    int flash = 0;
    while (connect == 1) {

        led_indicators();

        // Read Message from Serial Port
        while (Serial.available() > 0) {
            for (int i = 0; i < 3; i++) {
                message[i] = Serial.read();
                delay(50);
            }
        }

        // Message: Connection from Zround "%C&"
        if (message[0] == '%') {
            if (message[1] == 'C') {
                if (message[2] == '&') {

                    int count = 0;
                    while (count <= 20) {
                        // Message: Confirmation "%A&"
                        Serial.write("%A&");
                        delay(100);
                        count++;
                    }

                    led_status = 2;

                    message[0] = ('0');
                }
            }
        }

        // Start Practice or Race
        if (message[0] == '%') {
            if (message[1] == 'I') {
                if (message[2] == '&') {

                    timeStart = millis();
                    connect = 0;
                    timer = 1;
                    zround = 1;
                    initiate_timer();
                }
            }
        }

        delay(50);

    }

}

// **********************************************************************************

void initiate_timer() {

    while (zround == 1) {
        while (Serial.available() > 0) {
            for (int i = 0; i < 3; i++) {
                message[i] = Serial.read();
                delay(50);
            }
        }

        led_status = 4;
        led_indicators();

        timeStart = millis();
        timer = 1;

        while (timer == 1) {

            time = millis() - timeStart;
            m = time / 60000;
            mu = m % 10;
            md = (m-mu) / 10;
            s = (time/1000) - (m*60);
            su = s % 10;
            sd = (s-su) / 10;
            l = time - (s*1000) - (m*60000);
            lu = l % 10;
            ld = ((l-lu) / 10) % 10;
            lc = (l - (ld*10) - lu) / 100;


            if ( su == 0) {

                if (lu == 0 && ld == 0 && lc == 0) {
                    Serial.print("%T");
                    Serial.print(time,HEX);
                    Serial.println("&");
                }

            }

            if (su == 5) {

                if (lu == 0 && ld == 0 && lc == 0) {
                    Serial.print("%T");
                    Serial.print(time,HEX);
                    Serial.println("&");
                }

            }

            if (irrecv.decode(&results)) {
                tx = results.value;
                lap_counter();
                irrecv.resume();
            }

            if (irrecv2.decode(&results2)) {
                tx = results2.value;
                lap_counter();
                irrecv2.resume();
            }

            if (irrecv3.decode(&results3)) {
                tx = results3.value;
                lap_counter();
                irrecv3.resume();
            }

            if (irrecv4.decode(&results4)) {
                tx = results4.value;
                lap_counter();
                irrecv4.resume();
            }

            while (Serial.available() > 0) {

                for (int i = 0; i < 3; i++) {
                    message[i] = Serial.read();
                    delay(50);
                }

            }

            // Check if Practice or Race has Ended
            if (message[0] == '%') {

                if (message[1] == 'F') {

                    if (message[2] == '&') {
                        timer = 0;
                        digitalWrite(redLed,LOW);
                        digitalWrite(greenLed,LOW);
                        connect = 1;
                        zround = 0;

                        led_status = 3;

                        connect_Zround();
                    }
                }
            }

        }

        delay(10);

    }
}

// **********************************************************************************

void lap_counter() {
  
    check_transponder();
    if (tx!=0) {
        digitalWrite(redLed, HIGH);
        Serial.print("%L");
        Serial.print(tx, HEX);
        Serial.print(",");
        Serial.print(time, HEX);
        Serial.print("&");
        Serial.println();
        digitalWrite(redLed, LOW);
        tx=0;
    }
}

// **********************************************************************************

void led_indicators() {

    switch (led_status) {

        case 1: // Standby
            digitalWrite(redLed,HIGH);
            digitalWrite(reset,HIGH);
            digitalWrite(gate,LOW);
            digitalWrite(greenLed,LOW);
            delay(200);
            digitalWrite(redLed,LOW);
            digitalWrite(greenLed,LOW);
            delay(700);
            break;
        case 2: { // Connecting
                int blink = 0;
                while (blink <= 5) {
                    digitalWrite(redLed,HIGH);
                    delay(200);
                    digitalWrite(redLed,LOW);
                    delay(200);
                    blink++;
                }
                digitalWrite(redLed,HIGH);
                digitalWrite(greenLed,LOW);
                led_status = 3;
                break;
            }
        case 3: // Connected
            digitalWrite(redLed,HIGH);
            digitalWrite(greenLed,LOW);
            break;
        case 4: // Race
            digitalWrite(redLed,LOW);
            digitalWrite(greenLed,HIGH);
            digitalWrite(gate,HIGH);
            delay(2000);
            digitalWrite(gate,LOW);
            break;
    }

}

// **********************************************************************************

void check_transponder() {

    // Backward compatibility
    // Keeping this here in case you don't want to re flash your existing transponder.
    
    //if (results.value >= 0xFFFF01 && results.value <= 0xFFFF12) {
     if (tx >= 0x0 && tx <= 0xFF) {
      
    }
    else {
      tx = 0; 
    } 

}
   

I guess for starters I am asking if this can easily be done with just a few tweaks? I can write the same HEX code the IR transponders use to the RFID tags, so I assumed if I can get the code to interpret the RFID tag and make it think it is the same transponder(HEX) number than it should work the same way, correct? Or am I going about this all wrong and should start over? Since the simultaneous reader is fairly new there is not a whole lot out there as far as references to use on it. I have searched this and several other forums with no luck, yet I don't really know where to begin, so there could be a lot of info and I just don't know it. The hardware is working fine, so no problems there, this is all about code. The RFID reader is great and can't wait to get it fully functional for real world testing. Any help would be great guys, again, I am as close to a beginner in code as it gets. I learned a lot on my last project, but the last 2 years of my life has set me waaaay back in skills and I am basically starting over. Thanks all.

Hi all, my original post apparently hasn't sparked anyone's interest yet, but I have been plugging away at the programming side of my project and made some good headway with it through a lot of reading and trial and error. I feel like I am getting a little better at understanding things. If I should have created a whole other topic I apologize, but all my questions have to deal with the same end result, so here we go....

I was able to take my original receiver code and adapt it to work with the new RFID timing system and appears like my proof of concept may actually work without too much alteration. I will start with one of the examples that came with the RFID reader/writer. I purchased the Sparkfun simultaneous RFID reader. I downloaded the library from that page and am using it as a shield for the Sparkfun Redboard. All is working. Here is my question. Using the "ReadEPC" example I can read my RFID tags just fine. Here is where I am lost at the moment. when I am done with this whole sketch I am wanting to basically build a "database" of RFID tags within the code. If I purchase 50 RFID tags I want to be able to specify which tag is which specific "transponder" number. The Zround software is looking for either a 2 digit Hexidecimal transponder or a variable length Hexidecimal transponder number. I got lucky and one of the tags I have will pop up in Zround as transponder #154 so I know it is working and will count the laps just like my original IR transponders would. My problem is knowing what to enter into the code to translate from whatever the RFID code is to a transponder number. Below is the "ReadEPC" example from Sparkfun.

/*
  Reading multiple RFID tags, simultaneously!
  By: Nathan Seidle @ SparkFun Electronics
  Date: October 3rd, 2016
  https://github.com/sparkfun/Simultaneous_RFID_Tag_Reader

  Single shot read - Ask the reader to tell us what tags it currently sees. And it beeps!

  If using the Simultaneous RFID Tag Reader (SRTR) shield, make sure the serial slide
  switch is in the 'SW-UART' position.
*/

#include <SoftwareSerial.h> //Used for transmitting to the device

SoftwareSerial softSerial(2, 3); //RX, TX

#include "SparkFun_UHF_RFID_Reader.h" //Library for controlling the M6E Nano module
RFID nano; //Create instance

#define BUZZER1 9
//#define BUZZER1 0 //For testing quietly
#define BUZZER2 10

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

  pinMode(BUZZER1, OUTPUT);
  pinMode(BUZZER2, OUTPUT);

  digitalWrite(BUZZER2, LOW); //Pull half the buzzer to ground and drive the other half.

  while (!Serial);
  Serial.println();
  Serial.println("Initializing...");

  if (setupNano(38400) == false) //Configure nano to run at 38400bps
  {
    Serial.println("Module failed to respond. Please check wiring.");
    while (1); //Freeze!
  }

  nano.setRegion(REGION_NORTHAMERICA); //Set to North America

  nano.setReadPower(500); //5.00 dBm. Higher values may cause USB port to brown out
  //Max Read TX Power is 27.00 dBm and may cause temperature-limit throttling
}

void loop()
{
  Serial.println(F("Press a key to scan for a tag"));
  while (!Serial.available()); //Wait for user to send a character
  Serial.read(); //Throw away the user's character

  byte myEPC[12]; //Most EPCs are 12 bytes
  byte myEPClength;
  byte responseType = 0;

  while (responseType != RESPONSE_SUCCESS)//RESPONSE_IS_TAGFOUND)
  {
    myEPClength = sizeof(myEPC); //Length of EPC is modified each time .readTagEPC is called

    responseType = nano.readTagEPC(myEPC, myEPClength, 500); //Scan for a new tag up to 500ms
    Serial.println(F("Searching for tag"));
  }

  //Beep! Piano keys to frequencies: http://www.sengpielaudio.com/KeyboardAndFrequencies.gif
  tone(BUZZER1, 2093, 150); //C
  delay(150);
  tone(BUZZER1, 2349, 150); //D
  delay(150);
  tone(BUZZER1, 2637, 150); //E
  delay(150);

  //Print EPC
  Serial.print(F(" epc["));
  for (byte x = 0 ; x < myEPClength ; x++)
  {
    if (myEPC[x] < 0x10) Serial.print(F("0"));
    Serial.print(myEPC[x], HEX);
    Serial.print(F(" "));
  }
  Serial.println(F("]"));
}

//Gracefully handles a reader that is already configured and already reading continuously
//Because Stream does not have a .begin() we have to do this outside the library
boolean setupNano(long baudRate)
{
  nano.begin(softSerial); //Tell the library to communicate over software serial port

  //Test to see if we are already connected to a module
  //This would be the case if the Arduino has been reprogrammed and the module has stayed powered
  softSerial.begin(baudRate); //For this test, assume module is already at our desired baud rate
  while(!softSerial); //Wait for port to open

  //About 200ms from power on the module will send its firmware version at 115200. We need to ignore this.
  while(softSerial.available()) softSerial.read();
  
  nano.getVersion();

  if (nano.msg[0] == ERROR_WRONG_OPCODE_RESPONSE)
  {
    //This happens if the baud rate is correct but the module is doing a ccontinuous read
    nano.stopReading();

    Serial.println(F("Module continuously reading. Asking it to stop..."));

    delay(1500);
  }
  else
  {
    //The module did not respond so assume it's just been powered on and communicating at 115200bps
    softSerial.begin(115200); //Start software serial at 115200

    nano.setBaud(baudRate); //Tell the module to go to the chosen baud rate. Ignore the response msg

    softSerial.begin(baudRate); //Start the software serial port, this time at user's chosen baud rate
  }

  //Test the connection
  nano.getVersion();
  if (nano.msg[0] != ALL_GOOD) return (false); //Something is not right

  //The M6E has these settings no matter what
  nano.setTagProtocol(); //Set protocol to GEN2

  nano.setAntennaPort(); //Set TX/RX antenna ports to 1

  return (true); //We are ready to rock
}

When I run the sketch and read my tag it comes back like this. From the serial monitor.

Searching for tag
Searching for tag
Searching for tag
Searching for tag
Searching for tag
epc[02 00 00 00 4C C0 60 17 06 8E 01 D4 ]
Press a key to scan for a tag

Sorry, not sure if that was the proper way to post text from the serial monitor. every time I try to add changes to the code, whether it be "if" statements, or "switch/case" statements it doesn't work. Almost as if I am not entering the tags EPC number correctly. in other words something similar to this (a quick "cut and paste" not direct from sketch).

//Print EPC
  //Serial.print(F(" epc["));
  for (byte x = 0 ; x < myEPClength ; x++)
  {
    if (myEPC[x] < 0x10 == 0x02,0x00,0x00,0x00,0x4C,0xC0,0x60,0x17,0x06,0x8E,0x01,0xD4){
    tx = 01;
    Serial.print(tx);
    }
    else{
    tx = 0;
    Serial.print(tx);
    }
    //Serial.print(F("0"));
    //Serial.print(myEPC[x], HEX);
    //Serial.print(F(" "));
  }
  //Serial.println(F("]"));
}

I end up with this in the serial monitor

"Initializing...
Press a key to scan for a tag
Searching for tag
111111111111Press a key to scan for a tag"

I am a little lost with the best way to go about the translation from what is being read from the tag to what I want the transponder number of that tag to be. I can write to the tag just fine as well. I am open to another suggested way to do this. If there was a way to write 0x01, or 0x02 to the tag and have a way to only read the 01, or 02 from the tag and forget about all the other digits, then I wouldn't have to worry about building a database, but again, I am lost on where to go from here. Am I overthinking this? This is my first go around with RFID, so I am pretty confused and during my searches it appears this reader is fairly new so I am having a hard time finding anyone with information on this board. Everyone was wonderful with my last go around on here, but my original post didn't seem to catch anyone's attention. I am not asking for someone to write the code for me, just help me figure out where to go from here and what your thoughts are on how to approach the read/writing of tag to transponder. Thanks guys, I hope I posted enough information here, let me know if I missed something. Thanks.

you could put all your valid tags in an array.
if you read a tag, compare against the values stored in the array.
each index of the array gives you an ID of the tag.

see this

/ compare an array against a set of valid values
//
// https://forum.arduino.cc/t/simultaneous-rfid-lap-timer/1024145/5
// noiasca 2022-08-30
// will be deleted after 2022-09-01

byte myEPC[12]; //Most EPCs are 12 bytes
byte myEPClength;

struct ValidTag
{
  const byte uid[12];
};

ValidTag validTag[]
{
  {0x02, 0x00, 0x00, 0x00, 0x4C, 0xC0, 0x60, 0x17, 0x06, 0x8E, 0x01, 0x00}, // 0
  {0x02, 0x00, 0x00, 0x00, 0x4C, 0xC0, 0x60, 0x17, 0x06, 0x8E, 0x01, 0xD4}, // 1
  {0x02, 0x00, 0x00, 0x00, 0x4C, 0xC0, 0x60, 0x17, 0x06, 0x8E, 0x01, 0x02}, // 2
  {0x02, 0x00, 0x00, 0x00, 0x4C, 0xC0, 0x60, 0x17, 0x06, 0x8E, 0x01, 0x03}  // 3
};

void simulateRead()
{
  myEPC[0] = 0x02;
  myEPC[1] = 0x00;
  myEPC[2] = 0x00;
  myEPC[3] = 0x00;
  myEPC[4] = 0x4C;
  myEPC[5] = 0xC0;
  myEPC[6] = 0x60;
  myEPC[7] = 0x17;
  myEPC[8] = 0x06;
  myEPC[9] = 0x8E;
  myEPC[10] = 0x01;
  myEPC[11] = 0xD4;
  myEPClength = 12;
}

// return ID (= index within valid UIDs) or -1 if unknown
int getId()
{
  int index = 0;
  for (auto &i : validTag)
  {
     if (memcmp(i.uid, myEPC, 12) == 0) return index;
     index++;
  }
  return -1;
}

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

  int result;
  result = getId();             // if we have only garbish in the variable, we should get -1
  Serial.print(F("result A:")); 
  Serial.println(result);       // print the result of the search

  simulateRead();               // now we read the tag
  result = getId();             // try to find it as one of  validTag
  Serial.print(F("result B:")); 
  Serial.println(result);       // print the result of the search
}

void loop() {
  // put your main code here, to run repeatedly:

}

should work with several tags with 12byte UIDs.

if you want "real names" you can expand the structure ValidTag with a name (or any other attribute) for your tags. Also if your tags have UIDs with different sizes, you must adopt the sketch.

Thanks for the reply noiasca, much appreciated. I understand the idea of the arrays, but I guess to start this off I need to get the translation figured out first. In my last post I showed what information I was getting from the serial monitor on what the tags EPC code is, but I can't seem to figure out how to take the tags EPC and get it to understand what to look for to translate it to a transponder number. Almost as if what the reader is reading isn't the same as what is being printed to the serial monitor. Once I can get that figured out I think I can make an array work. Does this make sense?

not for me.
The code in #4 shows, that your UID is in myEPC[].

I took exactly the UID from your example serial monitor print out and placed it into a code.

My code shows you either -1 if the readed UID is not within an array of valid UIDs or return the index of a valid index.

please explain ... what is in your opinion a "transponder number" for the UID 02 00 00 00 4C C0 60 17 06 8E 01 D4 ?

currently Zround is looking for a 2 digit HEX "transponder" number, e.g. 01, or 02, or 03. in post #4 I show the code for an "if/else" statement just to try and get the serial monitor to print out my "tx" number 01. tx being the "transponder number". But I can never get the serial monitor to print out the corresponding "tx" number I am looking. The code in post 4 should print out "01" in the serial monitor, but it doesn't, it prints a line of "111111111111" no matter what tag I wave in front of the reader, this is why I say my code isn't "translating" the EPC from the tag correctly. I assume I am handling the "if EPC == ?????????" improperly? I am just not understanding how to handle what the reader is reading and turning the EPC into a "tx".

Also, do you think it is possible to just write a 2 digit EPC to the tag so I don't need to build an array of valid tags. If Zround sees a 2 digit hex it will automatically recognize it as a "transponder". Thanks again for the attention. I am still learning.

The information of the readed transponder is in the array myEPC[]
you can't compare an array with a simple ==.
You can compare an array either byte for byte or how I have shown with a memcmp (google for it!).

Have you even checked the linked code, did you ever press the play button?!?

Please answer:
what is in your opinion a "transponder number" for the UID 02 00 00 00 4C C0 60 17 06 8E 01 D4 ?

apologies noiasca, I have not ran the linked code yet, I am at work and will give it a go tonight for sure, I am anxious to try things. I did look at the linked code and understand the array. It now makes better sense knowing I am not handling the "compare" properly. Sorry again for my lack of understanding some of this.

I was saying the "transponder number" for that UID was in my example code and should have been tx (tx being the transponder code) of 01.

do you think the above idea would work better than an array? is it possible to accomplish this by writing a "01" to a tag and only reading a "01", or will it always read back up to 12 digits? Just want to keep things simple as a tag is just a sticker and I would image it would get wore out and would need to constantly update the array database as I get more tags, where just writing a 2 digit number to a tag would eliminate the need for a database.

so you tried to assign "01" just in code. That's not very different to the array index.
I don't know if you can store bytes on your tags because I don't know your tags, nor the library you are using.
If you want to read "01" from the tag, you should find ways to write (and read) that. I can't help you much to that.

I sincerely apologize noiasca, but I am struggling here. I have been tinkering with some ideas based on your suggestions and I just can't seem to get it to work. I guess I am just not understand the command I need to call up the proper tag information. by the end of the night I thought I would try and really simplify things (since I am an idiot) and go as basic as I could with very few alterations to the code and simply just try and get the EPC from the card to print in the serial monitor to make sure I am calling up the proper tag EPC number correctly. For example...

 for (byte x = 0 ; x < myEPClength ; x++)
  {
    if (myEPC[x] < 0x10) //Serial.print(F("0"));
    //Serial.print(myEPC[x], HEX);
    //Serial.print(F(" "));
    if (((myEPC[x],HEX)) == (0xE2, 0x00, 0x42, 0x00, 0x4D, 0x80, 0x60, 0x17, 0x06, 0x8E, 0x01, 0xE0)){
    Serial.println(F("transponder 01"));
  }
    else
    Serial.println(F("no transponder found"));

Apparently this isn't the proper way to enter the EPC of the tag. If I run the program I can wave the correct tag, or the incorrect tag in front of the reader and I always get "no transponder found". What am I doing wrong? the more I read and research arrays, structs, etc. the more lost I am getting as it doesn't seem as if the information is consistent that I am reading. I hate to ask for help with the basics, but I am really lost here.

I am hoping that once I can get the right information, even if it is just one tag, than I will start researching the library, tags, etc to see if I can program/write to the tags with a simple 2 digit HEX so I won't have to create an array or database of tags. Thanks.

nothin but apologies noiasca, it was late last night and my eyes were burning from staring at code all night. I tried to build a simple code using your memcmp and was still struggling to get the right results and what I copied and pasted in that last post was from the old code I tried, not my end test with your memcmp, my bad.

I tried to fiddle with writing and reading a 2 digit code to the tag after I got frustrated and had a little luck with that and am going to try to get more work done on that tonight and see if I have better luck with that. If I start to stumble more I will reach back out on here for help, but hopefully I can have better luck this way, but I'm definitely not as good at this as I would like to be. Thanks for your patience with me so far. Just out of curiosity, I couldn't find much information on why an array cannot be compared by a simple ==, seems like if I can print it, I should be able to compare it just as easily, but again, I am really out of touch with arrays. Thanks again for your help so far.

well, when you look at your code how you print the UID bytewise

//Print EPC
  Serial.print(F(" epc["));
  for (byte x = 0 ; x < myEPClength ; x++)
  {
    if (myEPC[x] < 0x10) Serial.print(F("0"));
    Serial.print(myEPC[x], HEX);
    Serial.print(F(" "));
  }
  Serial.println(F("]"));
}

it's apparently not a "simple print", so you shouldn't expect to have a "simple ==" neither.
Just saying...

another curiosity, is there any such command that allows you to take what is serial.print(ed) and turn that into a value? e.g. "tx = serial.print(blah blah blah)?" wouldn't that be nice!!!

not a command but a kind of implementation which can do something like that. But please forget that at the moment. Currently you need to solve the comparison. Do the comparison.

thanks again noiasca, I got a lot done last night on my program. I was able to figure out the "writeEPC" code to make the 2 digit HEX work and auto detect without having to build a database, which makes having the array and struct unnecessary at the moment as the Zround software already has 01 - 99 available for transponders. I was having a little instability within my program that I am going to try and figure out next. If I don't get that figured out by the end of the night tonight I may post my whole program to see if you can help me figure out where the problem might be. After I can get this operational for real world testing I am going to sit back down and see if I can get the array and database punched in and working to better understand what I am doing. It was nice to finally get some results that was moving me forward instead of a standstill. Thanks again for the all the help and patience thus far.

I now I know, not again. I am really wanting to have a better understanding of the "read" and "write" code I am working with and I am hoping you can help. I am just using the example code for the library that goes with the reader. Here are the 2 codes that allows me to write and read a single digit. I was able to adapt my receiver code to communicate with the Zround lap timing software, but once I get into the 2 digit tags it will not work. For example, tags numbered 1 through 9 work fine, but when going to tag 10, the numbers go crazy, so I am obviously not doing this right I am just not understanding what needs to be done to correct this problem.

write code

#include <SoftwareSerial.h> //Used for transmitting to the device

SoftwareSerial softSerial(2, 3); //RX, TX

#include "SparkFun_UHF_RFID_Reader.h" //Library for controlling the M6E Nano module
RFID nano; //Create instance

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

  while (!Serial);
  Serial.println();
  Serial.println("Initializing...");

  if (setupNano(38400) == false) //Configure nano to run at 38400bps
  {
    Serial.println("Module failed to respond. Please check wiring.");
    while (1); //Freeze!
  }

  nano.setRegion(REGION_NORTHAMERICA); //Set to North America

  nano.setReadPower(500); //5.00 dBm. Higher values may cause USB port to brown out
  //Max Read TX Power is 27.00 dBm and may cause temperature-limit throttling

  nano.setWritePower(500); //5.00 dBm. Higher values may cause USB port to brown out
  //Max Write TX Power is 27.00 dBm and may cause temperature-limit throttling
}

void loop()
{
  Serial.println(F("Get all tags out of the area. Press a key to write EPC to first detected tag."));
  if (Serial.available()) Serial.read(); //Clear any chars in the incoming buffer (like a newline char)
  while (!Serial.available()); //Wait for user to send a character
  Serial.read(); //Throw away the user's character

  //"Hello" Does not work. "Hell" will be recorded. You can only write even number of bytes
  //char stringEPC[] = "Hello!"; //You can only write even number of bytes
  //byte responseType = nano.writeTagEPC(stringEPC, sizeof(stringEPC) - 1); //The -1 shaves off the \0 found at the end of string

  char hexEPC[] = {0x10, 0x00}; //You can only write even number of bytes
  byte responseType = nano.writeTagEPC(hexEPC, sizeof(hexEPC));

  if (responseType == RESPONSE_SUCCESS)
    Serial.println("New EPC Written!");
  else
    Serial.println("Failed write");
}

//Gracefully handles a reader that is already configured and already reading continuously
//Because Stream does not have a .begin() we have to do this outside the library
boolean setupNano(long baudRate)
{
  nano.begin(softSerial); //Tell the library to communicate over software serial port

  //Test to see if we are already connected to a module
  //This would be the case if the Arduino has been reprogrammed and the module has stayed powered
  softSerial.begin(baudRate); //For this test, assume module is already at our desired baud rate
  while (!softSerial); //Wait for port to open

  //About 200ms from power on the module will send its firmware version at 115200. We need to ignore this.
  while (softSerial.available()) softSerial.read();

  nano.getVersion();

  if (nano.msg[0] == ERROR_WRONG_OPCODE_RESPONSE)
  {
    //This happens if the baud rate is correct but the module is doing a ccontinuous read
    nano.stopReading();

    Serial.println(F("Module continuously reading. Asking it to stop..."));

    delay(1500);
  }
  else
  {
    //The module did not respond so assume it's just been powered on and communicating at 115200bps
    softSerial.begin(115200); //Start software serial at 115200

    nano.setBaud(baudRate); //Tell the module to go to the chosen baud rate. Ignore the response msg

    softSerial.begin(baudRate); //Start the software serial port, this time at user's chosen baud rate
  }

  //Test the connection
  nano.getVersion();
  if (nano.msg[0] != ALL_GOOD) return (false); //Something is not right

  //The M6E has these settings no matter what
  nano.setTagProtocol(); //Set protocol to GEN2

  nano.setAntennaPort(); //Set TX/RX antenna ports to 1

  return (true); //We are ready to rock
}

read code

#include <SoftwareSerial.h> //Used for transmitting to the device

SoftwareSerial softSerial(2, 3); //RX, TX

#include "SparkFun_UHF_RFID_Reader.h" //Library for controlling the M6E Nano module
RFID nano; //Create instance

#define BUZZER1 9
//#define BUZZER1 0 //For testing quietly
#define BUZZER2 10

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

  pinMode(BUZZER1, OUTPUT);
  pinMode(BUZZER2, OUTPUT);

  digitalWrite(BUZZER2, LOW); //Pull half the buzzer to ground and drive the other half.

  while (!Serial);
  Serial.println();
  Serial.println("Initializing...");

  if (setupNano(38400) == false) //Configure nano to run at 38400bps
  {
    Serial.println("Module failed to respond. Please check wiring.");
    while (1); //Freeze!
  }

  nano.setRegion(REGION_NORTHAMERICA); //Set to North America

  nano.setReadPower(500); //5.00 dBm. Higher values may cause USB port to brown out
  //Max Read TX Power is 27.00 dBm and may cause temperature-limit throttling
}

void loop()
{
  Serial.println(F("Press a key to scan for a tag"));
  while (!Serial.available()); //Wait for user to send a character
  Serial.read(); //Throw away the user's character

  byte myEPC[2]; //Most EPCs are 12 bytes
  byte myEPClength;
  byte responseType = 0;
  byte tx = 0;
  while (responseType != RESPONSE_SUCCESS)//RESPONSE_IS_TAGFOUND)
  {
    myEPClength = sizeof(myEPC); //Length of EPC is modified each time .readTagEPC is called

    responseType = nano.readTagEPC(myEPC, myEPClength, 500); //Scan for a new tag up to 500ms
    Serial.println(F("Searching for tag"));
  }

  //Beep! Piano keys to frequencies: http://www.sengpielaudio.com/KeyboardAndFrequencies.gif
  tone(BUZZER1, 2093, 150); //C
  delay(150);
  tone(BUZZER1, 2349, 150); //D
  delay(150);
  tone(BUZZER1, 2637, 150); //E
  delay(150);

  //Print EPC
  //Serial.print(F(" epc["));
  for (byte x = 0 ; x < myEPClength ; x++)
  {
    if (myEPC[x] < 0x10) //Serial.print(F("0"));
    //Serial.print(myEPC[x], HEX);
    //Serial.print(F(" "));
    tx = (myEPC, HEX);
    Serial.print(tx);
  }
  //Serial.println(F("]"));
}

//Gracefully handles a reader that is already configured and already reading continuously
//Because Stream does not have a .begin() we have to do this outside the library
boolean setupNano(long baudRate)
{
  nano.begin(softSerial); //Tell the library to communicate over software serial port

  //Test to see if we are already connected to a module
  //This would be the case if the Arduino has been reprogrammed and the module has stayed powered
  softSerial.begin(baudRate); //For this test, assume module is already at our desired baud rate
  while(!softSerial); //Wait for port to open

  //About 200ms from power on the module will send its firmware version at 115200. We need to ignore this.
  while(softSerial.available()) softSerial.read();
  
  nano.getVersion();

  if (nano.msg[0] == ERROR_WRONG_OPCODE_RESPONSE)
  {
    //This happens if the baud rate is correct but the module is doing a ccontinuous read
    nano.stopReading();

    Serial.println(F("Module continuously reading. Asking it to stop..."));

    delay(1500);
  }
  else
  {
    //The module did not respond so assume it's just been powered on and communicating at 115200bps
    softSerial.begin(115200); //Start software serial at 115200

    nano.setBaud(baudRate); //Tell the module to go to the chosen baud rate. Ignore the response msg

    softSerial.begin(baudRate); //Start the software serial port, this time at user's chosen baud rate
  }

  //Test the connection
  nano.getVersion();
  if (nano.msg[0] != ALL_GOOD) return (false); //Something is not right

  //The M6E has these settings no matter what
  nano.setTagProtocol(); //Set protocol to GEN2

  nano.setAntennaPort(); //Set TX/RX antenna ports to 1

  return (true); //We are ready to rock
}

the below code is where I am changing things around to get the different results, but not the exact results I am looking for.

//Print EPC
  //Serial.print(F(" epc["));
  for (byte x = 0 ; x < myEPClength ; x++)
  {
    if (myEPC[x] < 0x10) //Serial.print(F("0"));
    //Serial.print(myEPC[x], HEX);
    //Serial.print(F(" "));
    tx = (myEPC, HEX);
    Serial.print(tx);
  }
  //Serial.println(F("]"));
}

if I change the write code

char hexEPC[] = {0x10, 0x00}; //You can only write even number of bytes

to this

char hexEPC[] = {0x01, 0x00}; //You can only write even number of bytes

I can get "1" as my transponder("tx") to print and shows up in the Zround software as transponder 1, all is well, but as soon as I change it to 0x10, 0x00, I get the tag to come back as 0249. I have tried to change it to

tx = (myEPC[x], HEX);

I get 016, with that, if I change it to 0x02, 0x00, I get 016 as well, same with all numbers 1-9. where is the 16 coming from? Where should I go from here to write and read just 01 through 99 on my tags. I will never need more than 99 tags. And this would really be nice just to write to the tags instead of constantly update an array of tags. Suggestions? Again, apologies for all the rookie questions, but I really want to understand all of this as I am doing it, not just move things around until it kind of works.

a)
please activate all compiler Warnings (Menu File / Preferences / Compiler Warnings: All)

The Sketch MUST compiler without any red warnings.
Do you get warnings?

b)
what do you expect that this line should do?

c)
016 might come because you print a zero and you print 0x10 in decimal which is a 16.

d)
do yourself a favour and print the digits separates as long as you don't know if it is working.

try something like this to check if you can read back the correct numbers:
stay i one system. If you enter numbers in HEX, print them in HEX

  for (byte x = 0 ; x < myEPClength ; x++)
  {
    if (myEPC[x] < 0x10) Serial.print(F(" 0x0")); else Serial.print(F(" 0x"));
    Serial.print(myEPC[x], HEX);
  }
  Serial.println();

try with both tags and report what you get for each written tag.

Done, didn't realize that was there and don't recall it being in the earlier versions of IDE, sorry. Here is the only warning I get.

C:\Users\Jason\Desktop\New Timing system\working_RFID_read_test\working_RFID_read_test.ino: In function 'void loop()':
C:\Users\Jason\Desktop\New Timing system\working_RFID_read_test\working_RFID_read_test.ino:81:18: warning: left operand of comma operator has no effect [-Wunused-value]
     tx = (myEPC[x], HEX);

Interesting, so I assume that the way serial.print is using HEX is different than the way I need to store that info into byte "tx"? not sure where to go from here, do I convert to a string byte for byte?

well, I thought it would turn "tx" into 0x01, 0x00 that I was seeing in the serial monitor as my tag ID.

I get what I expect to see, the ID I have printed to the tags. My problem comes in when I try to , what I call, translate from the myEPC to "tx". I just have a hard time understanding what is happening when I can print the correct HEX, but I can't make "tx" equal the same thing. Where should I go from here.

what do you expect to get in tx when you have a tag like

char hexEPC[] = {0x10, 0x00}; //You can only write even number of bytes

what do you expect to get in tx when you have a tag like:

char hexEPC[] = {0x01, 0x00}; //You can only write even number of bytes

well, what I need to get is just a 2 digit number, anywhere from 01-99. I was hoping to get 10 and 01 from those results. In the "read" example If I change it to

byte myEPC[1]
tx = (myEPC[x])

I can get 1 - 9 to work, but cant get a second digit. I just need some way of reading the digits from the first 0x??. That way I can just write 0x01 up to 0x99 to the tags and have them read in Zround without a database to compare tags to. The write code will only allow me to write an even number of bytes, so no matter what I have to write 0x??, 0x?? to a tag, but I only want to read, and make "tx" the first 0x?? number. For starters I was just trying to make "tx" print the exact same number as myEPC[x], HEX