Clear array of struct

Hi! I recently built a chip timing system using RFID, and I use an array of structs to sort the data. When a chip's data is read, it is printed to the serial monitor with a time and written to an array so that it isn't printed hundreds of times, only once. What I want to do is when a race is ended, simply reset the array so that I don't have to reset the Arduino to be able to read the same chips for the next race.
My timing code:

#include <SoftwareSerial.h>
SoftwareSerial softSerial(2, 3);
#include "SparkFun_UHF_RFID_Reader.h"
RFID nano;
#define buzzer 9
#define buzzergnd 10

//place variables - data placement
int place = 1;
float seconds;
float personTime;
unsigned long currentMillis = 0;
unsigned long prevMillis = millis;
unsigned long minutes = 0;
int heat = 1;

//LEDs
int blue = 7;
int red = 9;
int green = 5;
int rfidcounter = 1;


//switches and such
const int buttonPin = 6;
int buttonPushCounter = 1;
int buttonState = 0;
int lastButtonState = 0;
int rfidbtn = 8;

// create structure to filter
struct DubFilter {
  uint8_t EPC[12];
  //unsigned long LastTime;     // optionally you could add data to capture
};

// maximum number of unique EPC
#define MaxEPC 15
struct DubFilter dub[MaxEPC];


void setup() {
//RFID 
pinMode(rfidbtn, INPUT);
pinMode(red, OUTPUT);
pinMode(green, OUTPUT);
pinMode(blue, OUTPUT);
pinMode(buzzer, OUTPUT);
pinMode(buzzergnd, OUTPUT);
digitalWrite(buzzergnd, LOW);
Serial.begin(115200);
while(! Serial);
digitalWrite(blue, HIGH);
if(setupNano(38400) == false){
  Serial.println("Module failed to respond");
  while (1);
}
nano.setRegion(REGION_NORTHAMERICA);
nano.setReadPower(1500);

// init de-dub
for (uint8_t i=0 ; i < MaxEPC ; i++)
  dub[i].EPC[0] = 0;

Serial.println("Ready");
Serial.println("Turn on switch to begin race");
/*while(!Serial.available());
  Serial.read();
    nano.startReading();
    digitalWrite(12, HIGH);
    Serial.println("RFID Reader active. Ready to begin race");
*/
//timing
pinMode(buttonPin, INPUT);

}

void startRace(){
    digitalWrite(red, HIGH);
  digitalWrite(blue, LOW);
  digitalWrite(green, LOW);

  Serial.print("Race ");
  Serial.print(heat);
  Serial.println(" started");
  heat++;
  flash();
}

//where the magic happens
void runTimer(){
  digitalWrite(red, HIGH);
  currentMillis = millis();
  seconds = currentMillis - prevMillis;
  float personTime = seconds/1000;

  if(seconds < 100){
    startRace();
  }

  //data - THIS IS WHERE IT ALL GOES DOWN
  if(nano.check() == true){
    byte responseType = nano.parseResponse();
    
    if(responseType == RESPONSE_IS_TAGFOUND){

      // it is already in the list
      if ( DeDub() ) return ;
      
      Serial.print(place);
        Serial.print(" ");
      byte tagEPCBytes = nano.getTagEPCBytes();
      for(byte x = 0 ; x< tagEPCBytes ; x++){
        if(nano.msg[31 + x] < 0x10) Serial.print("0");
        
        Serial.print(char(nano.msg[31 + x]));
        Serial.print((""));
      }
      unsigned minutes = (personTime + .0005) /60;
      personTime -= minutes * 60;
      Serial.print(" ");
      Serial.print(minutes);
      Serial.print(':');
      if ((personTime + 0.0005) < 10)
    Serial.print('0');
      Serial.println(personTime, 2);
      place++;
     // flash();
     // delay(10);
    }
  }
}

/**
 * This routine will check against the table
 * If EPC is already in the table true will be returned.
 * if NOT EPC will be added to the list and false is turned
 */
bool DeDub()  {
  uint8_t i,x;
  bool MissMatch = false; 
  
  // get the num EPC bytes 
  uint8_t tagEPCBytes = 12;

  // check each entry in the table
  for (i = 0 ; i < MaxEPC; i++){
 
    // if empty entry
    if (dub[i].EPC[0] == 0)  break;

    MissMatch = false; 
    for(x = 0 ; x< tagEPCBytes ; x++){

      // check for miss match
      if(nano.msg[31 + x]  != dub[i].EPC[x] ){
        MissMatch = true;
        break;
      }
    }

    // A this point we check for MisMatch (false means we have a Match)
    if (! MissMatch)  return true;

  }

  // EPC was not in the list already
  if (i == MaxEPC) {
    Serial.println("Table is full\nCan NOT add more");
  }
  else {
    // add to the list
    for(x = 0 ; x< tagEPCBytes ; x++){
      // Add to the list
      dub[i].EPC[x] = nano.msg[31 + x];
    }
  }
  return(false);
}

void flash(){
  tone(buzzer, 2349);
  delay(150);
  noTone(buzzer);
}

void stopTimer(){
  digitalWrite(blue, HIGH);
  digitalWrite(green, LOW);
  digitalWrite(red, LOW);
  seconds = 0;
  place = 1;
  minutes = 0;
  prevMillis = millis();
  
}

void loop() {
  // put your main code here, to run repeatedly:
buttonState = digitalRead(buttonPin);
  if(buttonState == HIGH){
    runTimer();  }
  else{
   stopTimer();
  }

int rfidbtnstate = digitalRead(rfidbtn);
if (rfidbtnstate == HIGH){
  rfidcounter++;
    if(rfidcounter %2 == 0){
      nano.startReading();
     digitalWrite(green, HIGH);
      digitalWrite(red, LOW);
      Serial.println("RFID reader activated");
      }
    else if(rfidcounter %2 != 0){
      nano.stopReading();
        digitalWrite(green, LOW);
        digitalWrite(red, HIGH);
        Serial.println("RFID Reader deactivated");
  } 
  
  delay(200);
}
//end loop
}
  


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.isListening() == false); //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

    delay(250);
  }

  //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
}

To clarify: I haven't written the function to clear the array, I am asking what it is. Any help is appreciated. Thank you!

Why do you need to "clear" it? Couldn't you just use a bool variable to tell if it contains valid data or not?

Wouldn't this code do it? You already have it in setup().

  // init de-dub
  for (uint8_t i = 0 ; i < MaxEPC ; i++)
    dub[i].EPC[0] = 0;

Yes it would! Thank you!

Your for loop only resets the first entry in the structure

you basically have a 2D array of bytes

#define MaxEPC 15
uint8_t dub[MaxEPC][12];

so one easy way to reset the whole thing to 0 is to use memset()

memset(dub, 0, sizeof dub);

otherwise you need 2 loops

for (auto &d : dub)
  for (auto &epc : d) 
    epc = 0;

or the version with indexes

for (uint8_t i = 0 ; i < MaxEPC ; i++)
  for (uint8_t j = 0 ; i < 12 ; j++)
    dub[i].EPC[j] = 0;
1 Like

Yes but OP is only using the first entry to check for empty. That is why I suggested what I did.

    // if empty entry
    if (dub[i].EPC[0] == 0)  break;

right - thx, makes sense then !

1 Like

Oh cool, this thread helped me in some way too. Thank you.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.