0

Sorry that I repeat my question, I can't enter to my user...

In the project I'm doing, I connect an arduino mega with ethernet and Post some Strings to the server. The arduino mega has a receiver(315MHz). I have some arduinos nano connected with PIR sensors that sends a some int with transmitters (315MHz). What I want to do is a list in my arduino mega that stores the values sent by the arduinos nanos to use them to my server (using POST). my question is the following:

If I had an empty array, what I would like to do is

listOfSensors[]={}

void funtion (String sensor){
    if (sensor is inside listOfSensors){
         //dont do anything
    }
    else {
         add sensor to listOfSensors
    }

I have been looking for hours, but I haven't found anything so far... Anyone has any idea? Thanks!!

  • 1
    Don't just double-post. Work out how to log into your earlier user. I'm sure StackExchange has ways of retrieving your password, or whatever-it-is that went wrong. – Nick Gammon Sep 11 '15 at 6:20
  • I registered with my mail but I didn't confirmed, then I accesed with my facebook, wich is related with my mail, so when I try to access the other account it says I'm already registered...I know I shouldn't but I really can't acces to my account – Alvaro Sep 11 '15 at 6:25
0

In C there is no such thing as an "empty array". All arrays have a finite pre-defined size.

String sensors[10]; // Room for up to 10 sensors

The usual way of storing an unknown number of entries that will be added to "as and when" is to use a linked list or doubly-linked list.

A linked list is a list of items where each item also contains a pointer to say where the next item in the list is located.

Also you shouldn't use the String class as it is not good when working with linked lists (or in general - stick to C strings).

Warning: linked lists aren't for the faint of heart.

First you would define a struct to store the data you want in the linked list:

struct sensor {
    char *name;
    int currentValue;
    struct sensor *next;
};

That would store the name of the sensor ("name"), the current value from the sensor ("currentValue") and also contains a pointer ("*next") to the next entry in the list. That last bit is the most important.

Now you create a "head" pointer variable to start your list off:

struct sensor *mySensors = NULL;

That starts out as NULL to say "This variable has nothing in it at the moment".

Now that was the easy part. The hard part is adding entries to the list...

A couple of helper functions can be of use here. Let's start by defining a function that will look for a specific entry by name in the list:

struct sensor *findSensor(const char *name) {
    for (struct sensor *scan = mySensors; *scan; scan = scan->next) {
        if (strcmp(scan->name , name) == 0) {
            return scan;
        }
    }
    return NULL;
}

That will start off with a pointer variable scan pointing to the first entry in the linked list (mySensors). While it's pointing to a valid entry (not NULL) compare the name to the given string and if they match then return the entry we are pointing to. Next point to whatever the "next" pointer is pointing to, so you move down the list.

Now to add a sensor:

struct sensor *addSensor(const char *name, int value) {
    // First look to see if it exists:
    struct sensor existing = findSensor(name);
    if (existing != NULL) { // We found it
        existing->currentValue = value; // Update the value
        return existing;
    }
    // We haven't got it in our list, so create a new entry:
    struct sensor newsensor = (struct sensor *)malloc(sizeof(struct sensor));
    // And fill in the data:
    newsensor->name = strdup(name); // Create a COPY of the string
    newsensor->currentValue = value; // Store the value
    newsensor->next = NULL; 
    // IMPORTANT: The new entry must point to NULL to mark the end of the list:
    newsensor->next = NULL; 

    // Now where to add it in the list? Is there even a list?
    if (mySensors == NULL) {
        // No? Then we just make our new entry the head of the list:
        mySensors = newsensor;
        return newsensor;
    }
    // Otherwise we need to scan through the whole list to find
    // where the tail of the list is:

    struct sensor *scan = mySensors;
    // While the current entry points to a valid next entry
    while (scan->next) {
        // move on to that next entry
        scan = scan->next;
    }
    // There must be no valid next entry now (scan->next == NULL), so
    //  add our new sensor as the next valid entry:
    scan->next = newsensor;
    return newsensor;
}

Removing a sensor from the list is a much more involved process (even more than adding a sensor). You need to "splice" the list around the deleted entry. I'll add detail on that if you need it, but by the sound of things you won't be removing entries, only adding them.

The routines shown there (I haven't actually tested them, but it is standard code I write all the time) aren't as efficient as they could be. If you are adding and removing entries all the time and you end up with quite a large list it can take longer and longer to scan right through the list to find the last entry to add to. If that is the case you can maintain a "tail" pointer that you always update to point to the last added entry whenever you add one. That can then be used to rapidly add to the end of the list without having to scan through the whole list every time.

Another optimisation if you do a lot of scanning around within a list is to make a doubly linked list. This is just like the linked list above except it works in both directions. Not only do you store a next pointer, you also store a previous pointer. You can now scan in either direction - from head to tail or from tail to head, or hopping around at will inside the list. That is especially useful if you want to do things like ordering the list alphabetically.

| improve this answer | |
0

If you only need to add items of a fixed size to your sensor list (i.e. you don't need to delete items or sort them), you can use an uninitialized array large enough for the maximum number of items it will need to hold:

#define MAXSENSORS 30               // max sensor count
#define SNAMELEN 12                 // max sensor name length

struct sensorData {
    char sname[SNAMELEN+1];
    uint16_t svalue;
};                                  // defines data for 1 sensor

uint8_t sensorCount = 0;
struct sensorData listOfSensors[MAXSENSORS]={0}; // array of sensor data, initialized to 0, 0, ...

You'll also need an unsigned int (perhaps only a byte) to keep track of the count of items in the array, which you'll increment every time you add another sensor (up to the maximum number).

I think this is what you meant by "empty array". You would add your next sensor data at listOfSensors[i], then increment i. Likewise, you would search for a sensor in the array from listOfSensors[0] to listOfSensors[i-1].

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.