I'd use something like this
const char jsonTemplate[] = // string template for creating the JSON string
"{\"Timestamp_Device\":\"%d\""
",\"device_id\":\"%s \""
",\"temp\":\"%.1f\""
",\"flowshort\":\"%.1f\""
",\"flowacum\":\"%.1f\""
",\"vbat\":\"%.1f\""
",\"counterstatus\":\"%d\"}";
struct flowData_t {
int ts; // timestamp
float temp;
float total;
float accum;
float vbat;
int status;
};
const int maxBuf = 0x7F; // (127) (power of 2)-1 for easy roll-over
flowData_t flowBuf[maxBuf+1]; // allow for 0 .. maxBuf elements
int head, tail; // to use flowBuf as circular buffer
...
char msg[sizeof(jsonTemplate)+64]; // allow for up to 64 characters to be inserted into the template
while(tail != head) {
snprintf(msg, sizeof(msg), jsonTemplate
, flowBuf[tail].ts
, (const char*)id
, flowBuf[tail].temp
, flowBuf[tail].total
, flowBuf[tail].accum
, flowBuf[tail].vbat
, flowBuf[tail].status);
Serial.println(msg);
tail++; // advance tail as we already treated that element
tail &= maxBuf; // if tail reached end of array roll over when
}
This way you only store 24 bytes per set of data and create the actual string on the fly as automatic/local variable which will disappear as soon the function leaves.
When adding a new element to flowBuf[]
you should do this
head++; // advance head to next "free" position
head &= maxBuf; // when reaching the end of array roll over
if (head == tail) { // if the buffer is completely full overwrite oldest data
tail++; // advance tail one on as the previous entry will be overwritten
tail &= maxBuf; // roll over when needed
}
// fill data into flowBuf[head]
BTW, since it's not considered good style to put multiple instructions in one line you could rewrite this
as
Serial.printlnf("backup: %d saved: %s ", o, (const char*)backup[o]);
Also there are neater ways to format this
e.g. like this
if(config == 1)
backup[o] = payload;
...
if(o == ARRAYSIZE-3) { // if getting close to the limit delete everything . Id prefer to replace only the first..
cleanbackup(); // resets all to "x"
backupcounter = 0;
}
else
o = ARRAYSIZE+1;
Having conditional block of the same level also aligned on the same indent level makes code readability somewhat easier IMO.
Also adding some extra spaces adds readability - in exchange for the lost space the indentation depth could be reduced from 4 to 2 places.