I am currently working on a project that requires using 2 sensors(both I2C devices) to measure temperature and pressure and having that data saved onto an SD card as a .csv file. The requirement is to have them sample at a rate of 50Hz+. Currently they are only sampling at 10Hz which is far below the requirement.
-What can I do to increase sampling rate?
-Is the problem with the sensors I have chosen? Is the maximum they can sample just 10Hz?
-Is the problem with my code?
#include <Wire.h>
#include <SD.h>
#include "TSYS01.h"
#include "MS5837.h"
#include <RTClib.h>
#define cardSelect 4
MS5837 pressuresensor; //Initializing global variables
TSYS01 tempsensor;
RTC_DS3231 rtc;
File datafile;
char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"}; //Creating array for the days of the week
char filename[15]; //Creates an array of size 15 filled with elements of type 'char'
void dateTime(uint16_t* date, uint16_t* time) { //Void function for timestamp of .csv file
DateTime now = rtc.now();
*date = FAT_DATE(now.year(), now.month(), now.day());
*time = FAT_TIME(now.hour(), now.minute(), now.second());
}
void error (uint8_t errno) { //This will trigger the LED on pin 13 to blink a certain number of times. This is used to troubleshoot the code.
while (1) {
uint8_t i;
for (i = 0; i < errno; i++) {
digitalWrite(13, HIGH);
delay(100);
digitalWrite(13, LOW);
delay(100);
}
for (i = errno; i < 10; i++) {
delay(200);
}
}
}
void setup() {
pinMode(13, OUTPUT); //This activates the red LED on pin 13
pinMode(8, OUTPUT); //This activates the green LED on pin 8
#ifndef ESP8266 //This is required for the RTC
while (!Serial);
#endif
Serial.begin(9600);
Serial.println("Starting!");
Wire.begin();
rtc.begin();
tempsensor.init();
pressuresensor.init();
pressuresensor.setFluidDensity(997); //Freshwater density = 997 kg/m^3 , Seawater density = 1029 kg/m^3
Serial.print("Initializing SD card...");
if (!SD.begin(cardSelect)) { //If sd card is not present then this if statement will be triggered
Serial.println("Card Failed, or Not Present");
error(1);
return;
}
Serial.println("Card Initialized.");
strcpy(filename, "LOG00.CSV");
for (uint8_t i = 0; i < 100; i++) { //This for loop is used to create a new .csv file everytime the sd card is pulled out of card holder
filename[3] = '0' + i / 10;
filename[4] = '0' + i % 10;
if (! SD.exists(filename)) {
break;
}
}
SdFile::dateTimeCallback(dateTime); //This uses the void function that timestamps the .csv file
datafile = SD.open(filename, FILE_WRITE); //Opens .csv file
if (datafile) {
datafile.print("\"Temp_TSYS01 [deg C]\",\"Temp_BAR30 [deg C]\",\"Pressure [mbar]\",\"Depth [m]\",\"Altitude [m]\",Timestamp");
datafile.println();
Serial.println("Header logged");
} else {
Serial.println("error opening datalog-case1");
error(5);
}
datafile.close();
Serial.println("READY!");
delay(500);
Serial.println("Datalogging!");
}
void loop() {
DateTime now = rtc.now();
tempsensor.read();
pressuresensor.read();
float temp = tempsensor.temperature();
float temp2 = pressuresensor.temperature();
float pres = pressuresensor.pressure();
float depth = pressuresensor.depth();
float alt = pressuresensor.altitude();
Serial.print("TYSYS01: ");
Serial.print(temp);
Serial.print(" deg C ");
Serial.print("MS5837: ");
Serial.print(temp2);
Serial.print(" deg C ");
Serial.print(pres);
Serial.print(" mbar ");
Serial.print(depth);
Serial.print(" m(depth) ");
Serial.print(alt);
Serial.print(" m(above mean sea level) ");
Serial.print(now.year(), DEC);
Serial.print('/');
Serial.print(now.month(), DEC);
Serial.print('/');
Serial.print(now.day(), DEC);
Serial.print(" (");
Serial.print(daysOfTheWeek[now.dayOfTheWeek()]);
Serial.print(") ");
Serial.print(now.hour(), DEC);
Serial.print(':');
Serial.print(now.minute(), DEC);
Serial.print(':');
Serial.print(now.second(), DEC);
Serial.println();
digitalWrite(8, HIGH); //Turns on green LED light to ensure that code has processed through to this point.
datafile = SD.open(filename, FILE_WRITE);
if (datafile) { // open the file. note that only one file can be open at a time,
//datafile.println();
datafile.print(temp);
datafile.print(",");
datafile.print(temp2);
datafile.print(",");
datafile.print(pres);
datafile.print(",");
datafile.print(depth);
datafile.print(",");
datafile.print(alt);
datafile.print(",");
datafile.print(now.year(), DEC);
datafile.print('/');
datafile.print(now.month(), DEC);
datafile.print('/');
datafile.print(now.day(), DEC);
datafile.print(" (");
datafile.print(daysOfTheWeek[now.dayOfTheWeek()]);
datafile.print(") ");
datafile.print(now.hour(), DEC);
datafile.print(':');
datafile.print(now.minute(), DEC);
datafile.print(':');
datafile.print(now.second(), DEC);
datafile.println();
Serial.println("LOGGED IN SD CARD");
datafile.close();
}
}
The temperature sensor has a time constant of 1 second, so sampling at 50Hz doesn't make sense. You'll just have lots of nearly identical readings.
You can further reduce the amount of data by only saving values that are some minimum value above or below the last saved reading. For slowly changing values your data set will shrink down to almost nothing.
So you're saying with sampling rates I need to consider the time constant/response time of the device? Also since the time constant of my temp sensor is only 1 second, the sample rate I have (10hz) is too fast giving sample points that are redundant?
jpasion22:
So you're saying with sampling rates I need to consider the time constant/response time of the device? Also since the time constant of my temp sensor is only 1 second, the sample rate I have (10hz) is too fast giving sample points that are redundant?
Yes.
If you are doing depth/temperature profiles then you'll also need to move the sensor at a speed slow enough so that it keeps up with the temperature changes otherwise you'll get average instead of spot readings.