Search code examples
c++arraysstructarduinoplatformio

Access to struct property while looping array in C++


I've occured problem looping through array of structs.

I've got this struct:

struct sensor
{
  float data = 0;
  bool status = false;
  Idx idx; //enum
  SensorType type; //enum
};

It contains some sensors for my arduino.

So to send data, that I've recieved from them I want to use array of sensors in loop.

This is my array definition:

sensor sensors[] = {light, pressure, pressureHpa, temperature, humidity, temperatureOut, humidityOut};

Finally, I want to loop through this array and call some methods, but when I try to access any sensor by index I get zero values for all properties.

  for (unsigned int i = 0; i < sizeof(sensors) / sizeof(sensor); i++)
  {
    Serial.print("type:");
    Serial.print(sensors[i].type);
    Serial.print(" sens.idx:");
    Serial.print(sensors[i].idx);
    Serial.print(" sens.data:");
    Serial.print(sensors[i].data);
    Serial.print(" sens.status:");
    Serial.print(sensors[i].status);
    Serial.println();
  }

In this loop I've got output like:

type:0 sens.idx:0 sens.data:0.00 sens.status:0
type:0 sens.idx:0 sens.data:0.00 sens.status:0
type:0 sens.idx:0 sens.data:0.00 sens.status:0
type:0 sens.idx:0 sens.data:0.00 sens.status:0
type:0 sens.idx:0 sens.data:0.00 sens.status:0
type:0 sens.idx:0 sens.data:0.00 sens.status:0
type:0 sens.idx:0 sens.data:0.00 sens.status:0

But, when I access any of my structs directly like:

Serial.print("type:");
Serial.print(pressure.type);
Serial.print(" pressure.idx:");
Serial.print(pressure.idx);
Serial.print(" pressure.data:");
Serial.print(pressure.data);
Serial.print(" sens.status:");
Serial.print(pressure.status);
Serial.println();

I get:

type:3 pressure.idx:13 pressure.data:0.00 sens.status:1

Solution

  • light is defined and left at its default values.

    sensor sensors[] = {light, pressure, pressureHpa, temperature, humidity, temperatureOut, humidityOut};
    

    copies light into sensors[0]. This means sensors[0] contains the same data as light, but is not the same thing as light. Later when the code assigns values to light, sensors[0]'s copy is left untouched.

    Option 1

    Discard light and friends. Add an enumerated type that names the sensors

    enum sensor_names
    {
        LIGHT, // will be 0
        PRESSURE, //will be 1
        ...
        NR_SENSORS // must be last. Used to size the array and for loop terminators
    };
    

    And make sensors a simple array of the correct size

    sensor sensors[NR_SENSORS];
    

    Feel free to use std::array and the smarter enums of modern C++ if they are available. I'm weak on what is and isn't available to Arduino, so I've stuck to basic C-Style arrays and enums. If you have better tools, use them.

    Then access that which was light as sensors[LIGHT];

    Option 2

    Make sensors store pointers and change the accessing accordingly.

    sensor * sensors[] = {&light, &pressure,  .... };
    

    I prefer the first option. No duplication and a lower chance of placing an item in the wrong place in the array making a difference.