Problem with using String array for RFID inventory

Hi! I am trying to make a simple inventory system for keeping track of RFID tags that will be entering and exiting a particular scan area. I'm sure this has been done a trillion times before, but I was unable to find any examples after an extended search. So, I decided to take a crack at writing it myself.

For the record, I am using windows 7, a Mega 2560, Tagsense Nano UHF Module, and Adafruit 2.8" TFT.

First off, I can read and write to/from the tag IDs just fine. For easier debugging, I have renumbered the EPC IDs to be '123456......', '22222....', and '33333.....'.

GOAL: I want to scan an area for RFID tags at approx 1Hz. If a tag is in the scan area, I want to identify it and compare it to the items already in inventory. IF it is a new tag, I want to add it to the current inventory, and continue scanning for new tags.

I am having trouble with identifying the newcomers, particularly at the array address Compare[3]. . I've attached the relevant code below.

// Trying to get inventory comparison feature to work. Needs to detect when tags enter and leave the field.
// 1_13_16
// Ryan 


String Current_Invent[4] = {};
String Last_Invent[4] = {};

void setup(void) {  
  
  Serial.begin(4800);      
                                                                                 
}

void loop() {

InventScan();
CompareInvent();

    
}
 

void InventScan(){

   Last_Invent[1] = Current_Invent[1];
   Last_Invent[2] = Current_Invent[2];
   Last_Invent[3] = Current_Invent[3];
  
  String buffer;
  char char1[25];
  char char2[25];
  char char3[25];  
  
  mySerial.print('Z');                          // This set of commands the TagSense Module to take a single inventory of all available tags.
  mySerial.print('\r');

  Serial.println(F("Single Inventory Scan Completed"));

  while (mySerial.available() > 0 ) {
    buffer = mySerial.readString();
    //Serial.println("myserial is available!");
  }
    //Serial.print("buffer ="); Serial.println(buffer);
    
    int stringlength = buffer.length();
   
   //Serial.print(F("Stringlength is:")); Serial.println(stringlength);

    delay(2000);

   if (stringlength >= 33) {

     switch (stringlength) {

      case 36:                                     // It just so happens that with one tag, the incoming serial stream is 36 characters long
                      
        buffer.substring(7,31).toCharArray(char1, 25);   //This pulls out the EPC ID from the serial string for each case and converts it to char array
        Current_Invent[1] = char1;
        Current_Invent[2] = {"empty"};
        Current_Invent[3] = {"empty"};
        
        itemsInBag = 1;
        break;
      
      case 63:                                                // It just so happens that with two tags, the incoming serial stream is 63 characters long
                          
        buffer.substring(7,31).toCharArray(char1, 25);        
        Current_Invent[1] = char1;

                  
        buffer.substring(34,58).toCharArray(char2, 25);         //TODO clean this up so it doesnt require individual global 'buffer' array for each case
        Current_Invent[2] = char2;
        Current_Invent[3] = {"empty"};
        
        itemsInBag = 2;
        break;

       case 90:                                         // It just so happens that with three tags, the incoming serial stream is 90 characters long
       
        buffer.substring(7,31).toCharArray(char1, 25);
        Current_Invent[1] = char1;
                                 
        buffer.substring(34,58).toCharArray(char2, 25);
        Current_Invent[2] = char2;

        buffer.substring(61,85).toCharArray(char3, 25);
        Current_Invent[3] = char3;
        
        itemsInBag = 3;
        
        break;
        
      }

   }
      else
      itemsInBag = 0;

}
             


void CompareInvent () {

  Serial.println("Last Inventory:");
  Serial.println(Last_Invent[1]);
  Serial.println(Last_Invent[2]);
  Serial.println(Last_Invent[3]);    
    
  Serial.println("Current Inventory:");
  Serial.println(Current_Invent[1]);
  Serial.println(Current_Invent[2]);
  Serial.println(Current_Invent[3]);

  char Compare[3];

  Compare[1]='N';                   // initialize all values to zero in the array. TODO is there a smaller/faster way to do this?
  Compare[2]='N';
  Compare[3]='N';

  //Serial.print("Items in bag:"); Serial.println(itemsInBag);
  
  for (int i = 1; i <= 3; i++) {

    for (int j = 1; j <= 3; j++) {
        Serial.print("(i,j)="); Serial.print(i); Serial.print(","); Serial.println(j);       
        
        if (Current_Invent[i] == Last_Invent[j]) {
          
          Compare[i] = 'Y';                                   // 'Y' means the current item in inventory matches an item from the last inventory; therefore, no action needed. 'N' means that there is an open spot in the location Current_Invent[i]
          delay(100);
          Serial.print("Compare["); Serial.print(i);Serial.print("]="); 
          Serial.println(Compare[i]);
          Serial.print("Compare[3]="); Serial.println(Compare[3]);
          
          delay(2000);
        }
    }
    
  }


Serial.println("Comparison Array:");                  //TODO get comparison array to work...
Serial.println(Compare[1]);
Serial.println(Compare[2]);
Serial.println(Compare[3]);

delay(3000);
  
}

The serial monitor in the Arduino IDE displays this:

Single Inventory Scan Completed
Last Inventory:
222222222222222222222222
333333333333333333333333
123456789012345678901234
Current Inventory:
333333333333333333333333
222222222222222222222222
123456789012345678901234
(i,j)=1,1
(i,j)=1,2
Compare[1]=Y
Compare[3]=N
(i,j)=1,3
(i,j)=2,1
Compare[2]=Y
Compare[3]=N
(i,j)=2,2
(i,j)=2,3
(i,j)=3,1
(i,j)=3,2
(i,j)=3,3
Compare[3]=Y
Compare[3]=N
Comparison Array:
Y
Y
N

What I anticipate would happen is if the tag IDs from Last_Invent match up 1-to-1 with the Current_Invent, then the 'Comparison Array' would be: 'Y,Y,Y', but for some reason, it outputs: 'Y,Y,N'.

I am writing the value of Compare[3] every time because that is the only array location that is giving me grief.

What am I doing wrong?

Thanks in advance,

Ryan

It just so happensThis seems to me to be a very unreliable way to write a program

Array indexes start at 0, not 1.

  while (mySerial.available() > 0 )

Do you REALLY have a mySerial connected to the pins? I didn't think so. So, what's with the meaningless name? Wouldn't while(rfid.available()) convey a LOT more information about where the data was coming from?

    delay(2000);

Now, this is absolutely stupid. How the f**k do you expect to deal with one tag per second while stuffing your head in the sand for two seconds after reading a tag?

UKHeliBob:
It just so happensThis seems to me to be a very unreliable way to write a program

You are correct, this is not the best way to write a program. One thing on my todo list is to detect the start character of the EPC ID, and then read the fixed-length EPC ID string to the array. However, that is a lower priority at the moment and should not affect how the other parts of the code operate.

Do you have any advice on how I can solve the strange array behavior I have been seeing?

rmckay2307:
Do you have any advice on how I can solve the strange array behavior I have been seeing?

start with understanding arrays:

  char Compare[3];

  Compare[1]='N';                   // initialize all values to zero in the array. TODO is there a smaller/faster way to do this?
  Compare[2]='N';
  Compare[3]='N';

arrays of size == 3 have three elements starting with zero

  char Compare[3];

  Compare[0]='N';
  Compare[1]='N';
  Compare[2]='N';

PaulS:
Array indexes start at 0, not 1.

  while (mySerial.available() > 0 )

Do you REALLY have a mySerial connected to the pins? I didn't think so. So, what's with the meaningless name? Wouldn't while(rfid.available()) convey a LOT more information about where the data was coming from?

I agree. That is a much better way to describe where the data is coming from. I have made the change accordingly. Thanks!

    delay(2000);

Now, this is absolutely stupid. How the f**k do you expect to deal with one tag per second while stuffing your head in the sand for two seconds after reading a tag?

I agree that the delay() function is horrible and should be avoided at all costs. I put the delay(2000) in there so I could read the output of the serial monitor before it moved on to the next operation. Once the code is functional, i will search for all delays and remove them.

I realize I am not the most elegant coder, but I am trying to constantly improve. Thanks for the input. Back to the question at hand: Why I have been seeing the strange behavior with the Compare[3]?

Why I have been seeing the strange behavior with the Compare[3]?

Because you are using array (indices) incorrectly. Until you change that, nothing is going to work the way you expect, because your expectations are wrong.

OK, I will change the array indices to run 0, 1, 2. I will try that tonight and let you know how it goes. Thanks for your help!