Storing array of structs

I use an ESP32 to scan RFID cards and would like create a timeout per card.
My idea is to store the UID of the card (String value) with the current time in millis.

When i scan a card it needs to check if the array has a value with the UID and if not, add the UID with the current millis + timout.

After the timout (say 30 seconds) it could remove the value from the array to keep it small.

In pseudo it would look like this:

list = {
'1425342': 38289,
'1883028': 40192,
'8382917': 42148,
}

...

I would also need to be able to see if card UID 1883028 already is in the list and if the millis for that value is smaller than current millis + timeout.

Is this possible?

surely
Did you try to code? Please show your efforts

I am not sure which is the best approach, but i thought something like a struct:

    typedef struct
    {
        String cardUid;
        unsigned long time;
    } registrationHistory;

But i need to define an array of "registrationHistory" with a certain length. In my case the length needs to be variable and i need to be able to search in the array, so i am not sure if this is the way i should go

Do some research on 'linked list' to further your knowledge.

That's OK.

That's not.

You could make a simple linked list instead, or simply make the array as big as it could ever be.

Your cardUid has fixed length, so do not use the Strings. Use the char array instead:

typedef struct
    {
        char cardUid[UID_LENGTH};
        unsigned long time;
    } registrationHistory;

But better do not save UID as text at all, use the byte array

I will search for linked list, but wouldn't an array as big as it ever could be not give me problems in the end?

The device will "never" turn off and the number of cards that are scanned are increasing every day.
I assume a huge array will take RAM? (sorry if i am wrong)

Thanks for the tip!

consider

struct REGHISTORY
{
  String cardUiD;
  unsigned long timeReg;
}regHistorys[]
{
  {"1425342",38289},
  {"1883028",40192},
  {"8382917",42148},
};

Not sure if i understand but i would need to add records "on the fly", i have no values in the beginning.

Plus i would need to be able to search if a UID exists, so i need to search for value "1883028" (for example) in the list

Here i can add a value on index x
Would it be a bad idea to convert the UID (6 in length) to int and use that as the index?

I would also be able to get the value by: myList.get(x);

Yes.

There are two addtional functions needed:

  1. push event: parameter {cardUiD, timeReg}
  2. search event: parameter{cardUiD} return{timeReg}

I wouldn't recommend a linked list on a memory-constrained AVR unit, but you're on an ESP32. Memory management is much less constrained.
However, the array option also works, as long as you limit the number of active cards, which is effectively your 30-second boundary. Just set your IDs to a known flag, like 0, when they're freed up, and can be used. It matters little in this case, but in the more general case a linked list would be the design preference.
If you need to keep the IDs around(for example, you're maintaining a list for future reference, or have a list of allowed visitors), then making your struct a little more complex is an option, too.

You can use std::vector on an ESP32.

BTW:

You don't need 'typedef' in C++. That's a C thing. The C++ way:

#include <vector>

struct Registration {
  String cardUid;
  unsigned long time;
};

std::vector<Registration> registrationHistory;
1 Like

Thanks, but i still don't get how i can do this the most efficient way
I cannot see a lot of information how to create a "2d array" out of a vector and be able to search in it

Why do you need a 2D array instead of 1D?

I do a lot of programming in PHP and there a 2d array (or object) is a list of key, value combination.

There i can find a pair via the key or value so a thought it could be the same here.
In this case i don't know how to link the card UID with the time in millis

For key / value, use std::map.

But than i need a β€œlist” of keys/values.
I cannot see how to do that.

Also be able to search for a key in the list

Read up on std::map, it does that.