Skip to main content
added 123 characters in body
Source Link
Alex
  • 181
  • 2
  • 3
  • 9

Edit2: Sample code which reproduces the problem when the simulator array is available here: http://1drv.ms/1TRwiIB

Edit2: Sample code which reproduces the problem when the simulator array is available here: http://1drv.ms/1TRwiIB

Explained that simulator class resides in seperate *.cpp/h files
Source Link
Alex
  • 181
  • 2
  • 3
  • 9

Edit: I should have mentioned that this simulator class and all it's member functions & variables reside in a seperate *.cpp and *.h file. I alreadt found out that since i'm initializing the SimulatorQueue array in the class itself, and not in the main *.ino file, I should do it like so:

constexpr static SimulatorRecord SimulatorQueue[28] PROGMEM = {<structs go in here>};

Edit: I should have mentioned that this simulator class and all it's member functions & variables reside in a seperate *.cpp and *.h file. I alreadt found out that since i'm initializing the SimulatorQueue array in the class itself, and not in the main *.ino file, I should do it like so:

constexpr static SimulatorRecord SimulatorQueue[28] PROGMEM = {<structs go in here>};
Source Link
Alex
  • 181
  • 2
  • 3
  • 9

Using PROGMEM to store array of structs

I am hitting the limits of my arduino's SRAM and found that SRAM usage can be reduced by storing static stuff in flash memory instead of SRAM.

My project can (optionally) be built with an included SimulatorClass. I use this to 'playback' data at home which I gathered during real-life testing of my project. My project is based on photoelectric sensors, and it's timing-critical, so all timekeeping is done using micros(), which returns unsigned long datatype.

To simulate these photoelectric sensor triggers, I need an array containing a struct of 3 variables each: unsigned int _iDataPos;

   struct SimulatorRecord
   {
      uint8_t iSensorNumber;
      unsigned long lTriggerTime;
      uint8_t iState;
   };

So one these structs is 6 bytes long in my counting (2x uint8_t = 2 bytes, unsigned long = 4 bytes). A typical set of simulator records I need to use is about 25-30 records long, so worst case scenario the simulator array is 180 bytes in size.

I initialize these arrays like so:

SimulatorRecord SimulatorQueue[28] = {
      { 1, 41708, 1 }
      , { 2, 60692, 1 }
      , { 1, 176848, 0 }
      , { 2, 197732, 0 }
      , { 1, 4675580, 1 }
      , { 2, 4692252, 1 }
      , { 2, 4830180, 0 }
      , { 1, 4849032, 0 }
      , { 2, 9058416, 1 }
      , { 1, 9074780, 1 }
      , { 1, 9215868, 0 }
      , { 2, 9234968, 0 }
      , { 2, 13497276, 1 }
      , { 2, 13500924, 0 }
      , { 2, 13502728, 1 }
      , { 1, 13514992, 1 }
      , { 1, 13668000, 0 }
      , { 1, 13669344, 1 }
      , { 1, 13681828, 0 }
      , { 2, 13701464, 0 }
      , { 2, 18028788, 1 }
      , { 2, 18034252, 0 }
      , { 2, 18036540, 1 }
      , { 1, 18046892, 1 }
      , { 2, 18160312, 0 }
      , { 1, 18178224, 0 }
      , { 1, 20454580, 1 }
      , { 1, 20456368, 0 }
   };

In my simulator code I then loop through these arrays like so:

   unsigned int _iDataPos = 0;
   SimulatorRecord PendingRecord = SimulatorQueue[_iDataPos];

   //main simulator loop
   if (PendingRecord.lTriggerTime <= lRaceElapsedTime)
   {
      //simulate signal
      digitalWrite(PendingRecord.iSensorNumber, PendingRecord.iState);

      //And increase pending record
      _iDataPos++;
      PendingRecord = SimulatorQueue[_iDataPos];
   }

Now I've been reading various PROGMEM tutorials, and storing the SimulatorQueue array in flash seems to be piece of cake, just change

SimulatorRecord SimulatorQueue[28]

to

const PROGMEM SimulatorRecord SimulatorQueue[28]

But for the life of me I can't find out how I should change the copying of each array item to the PendingRecord variable, as my iDataPos counter increases.