7 years, 8 months ago.

How to write data with different data types to a single buffer and print them exactly

I would like to store data from sensors to a buffer first and then to a SD card.

My data is:

float temperature,humidity,light;
double barometer;
int16_t accelerometer;
time_t realtime;

Using inturrtps i will store each sensor data @1HZ to a buffer.

void onTempTick() {
 float temperature = sht.readTemp();
// writing to buffer
}
void onHumidityTick(void) {
float humidity = sht.readHumidity();
// writing to buffer
}

At the end I will check regularly in while loop whether buffer is full. If yes then write whole buffer to SD card.

Whic way would be best?.

2 Answers

7 years, 8 months ago.

Or store all the data with the maximal precision, ie. double, which means you'll only have to do a basic conversion to double.

uint8_t counter;
double barometer, temperature, humidity, light, accelerometer, buffer[100];
void onTempTick() {
temperature = (double)sht.readTemp();
buffer[counter] = temperature;
counter ++;
}
void onHumidityTick(void) {
humidity = (double)sht.readHumidity();
buffer[counter] = humidity;
counter ++;
}

And so on.

Qucik question : If your data are refreshed every second, why not write immediately to the SD card ? It would save some time and coding efforts. Plus SD works as SPI, so it's rather fast compared to flash or RAM, and doesn't need to be written to as blocks of data.

Accepted Answer

Actually SD cards do need to be written as blocks (of 512B) and are relative slow, especially over SPI ;).

posted by Erik - 07 Jul 2016

Ok, my bad then. Seems like I don't know SD cards well enough '

posted by Pierre David 08 Jul 2016

Hi Pierre, Thank you for your answer. For your question. If your data are refreshed every second, why not write immediately to the SD card ? Initially I was doing that. After few writes system hangs up. Then I got to know that placing printf or fprintf in a ticker is not a good idea. Hence I thought of storing in to a buffer first then my while loop will check regularly for buffer full. If yes buffer will be written to SD card. That is my plan.

posted by Mohan gandhi Vinnakota 08 Jul 2016

I just gave a small test with above code.

#define bufferSize 256
double LUX;
double sensorReading[bufferSize];

void onluxTick(void)
{
   LUX = max44009.getLUXReading();  
    sensorReading[writePointer++] = LUX; 
    if (writePointer == bufferSize)
        writePointer = 0;
    if (writePointer == readPointer) {
    }
}


// in while loop
 while (true) {
 
        while (writePointer != readPointer) { 
              fprintf(myLogFile,"\r\n %f ",sensorReading[readPointer++]);
            
            if (readPointer == bufferSize)
                readPointer = 0;
        }

My output in .csv file: 973.440.002

979.200.012

979.200.012

979.200.012

1.036.800.049

1.105.920.044

1.111.680.054

1.094.400.024

1.094.400.024

1.088.640.015

1.088.640.015

output in .txt file is fine

posted by Mohan gandhi Vinnakota 08 Jul 2016
7 years, 8 months ago.

I would start by converting the temperature, humidity, barometer and light to int16_t or uint16_t instead of floats and doubles. Both of those types use 64 bits, and I doubt that you need that kind of accuraccy. One byte for full digits and another for two decimal points. Conversion to float may be needed when reading the values again.

The conversion could look something like this:

Code

uint16_t Float_To_uint16(float input, uint8_t out_int, uint8_t out_dec)
{
out_int = input;
out_dec = (input - out_int)*100;

//Combine the two to a single variable
uint16_t ret = 0x0000;
ret |= out_int << 8;
ret |= out_dec;

return ret;
}

Floats use 32 bits.

posted by Andy A 08 Jul 2016

Ah, so they do, I'll correct it.

posted by Jyri Lehtinen 08 Jul 2016