Hi all, Im new with Arduino and I would really appreciate your help to finish my project, thank you in advance.
I have an Arduino Uno, a data logger shield from Adafruit and an SCD30 sensor for temperature, Co2 and humidity. The data logger code from Adafruit opens a datalog.txt file, but I need to open another .txt file with manually user defined offset values so that the data logger stores the actual sensor value +- the offset values from the other .txt file.
Example: The temperature recorded by the sensor is 22 °C and the offset value from the other text file is 2 °C, then the data logger should write 20 °C to the datalog.txt file (22 °C - 2 °C from the offset file).
Here you can also see the Data Logger skript.
const int chipSelect = 10; //10 is default by shield, but normally on Pin 4
int interval = 5; //Log to SD Card every 5 seconds
long timer;
String timestring;
String mvalue;
RTC_PCF8523 rtc;
void setup() {
Serial.begin(9600);
delay(3000);
Serial.println("Initializing SD card...");
if (!SD.begin(chipSelect)) {
Serial.println("SD Card error");
return;
}
Serial.println("card initialized");
if (! rtc.begin()) {
Serial.println("No RTC found");
} else {
Serial.println("RTC clock found");
}
if (! rtc.isrunning()) {
Serial.println("RTC is not configured");
}
}
void loop() {
if ((timer + interval * 1000) < millis()) {
timer = millis();
get_logvalue(); //Get your value
get_time(); //Get time from RTC
write_data(); //Write value and Time to SD
}
}
void get_logvalue() {
mvalue = "My Value"; //mvalue is your log parameter eg. Temperature
}
void get_time(){ //Read Time from RTC
DateTime now = rtc.now();
timestring = now.day();
timestring += "-";
timestring += now.month();
timestring += "-";
timestring += now.year();
timestring += " ";
timestring += now.hour();
timestring += ":";
timestring += now.minute();
timestring += ":";
timestring += now.second();
Serial.println(timestring);
}
void write_data() { //Write to SD card
String dataString = mvalue + "," + timestring;
File dataFile = SD.open("datalog.txt", FILE_WRITE);
if (dataFile) {
dataFile.println(dataString);
dataFile.close();
Serial.println(dataString);
}
else {
Serial.println("error writing datalog.txt");
}
}
One argument against that is that it will require a recompile if you want to change something. EEPROM however can be a solution with some code to modify the value using e.g. serial.
Could you please write an code example or give me some more tips where i can look and learn about it. Im pretty new with coding aswell and would appreciate your help. Thanks
It compiles, but it doesnt write data yet because the values from the sensor are not included yet, I have not yet soldered the sensor, but i tried them seperately and the sensor aswell as the data logger work just fine. I've been searching and thinking about the problem I have, I dont have an Idea yet how to it.
You don't actually need the sensor to test the principle as you could generate random numbers in the right range and save them
In the simplest case your sketch would open and read the file containing the offsets giving 3 variables to be used in loop() to be used as offsets to the values read by the sensor
Some things to think about
is the offsets file going to be on the same SD card as the log file ?
what should the sketch do if the offsets file does not exist ?
the sketch could fall back to using values previously saved to EEPROM if the file does not exist
should the sketch test that the offsets are within reasonable ranges given that they will be entered by a user ?
will the offsets be integer or float values ?
will the offsets file contain binary data or characters representing the offset values ?
How is the offset.txt file going to get onto the SD card?
What will be the data format of the offset.txt file?
Would it be possible to take the SD card put a offset.txt file onto the SD card. Then in setup() read the offset.txt file, putting the offsets into an array or some other thingy and then use the offsets as per the OP thingy?
The offset is gonna be on the same SD card as the log file.
if the offset file doesnt exist than the sketch should write the values we got from the sensor.
YES, thats also another point i gotta also set some range of values so the user wont be able to write values outside the range.
Offset has to be float values.
Offset file will contain character values.
"In the simplest case your sketch would open and read the file containing the offsets giving 3 variables to be used in loop() to be used as offsets to the values read by the sensor" - do you have any example code or any other example whatsoever that you can share with me so I can get an better idea of it. Thank you very much.
Yes I did, i already know how to open and read the file but still dont know how to deduct the offset.
I was thinking to do it this way, but not sure if it works:
since i cant use the sensor and Datalogger shield together cuz i have not yet soldered the sensor I took the Data Logger code from the library and gave some values for CO2, Temperatur and Humidity, it works but when I try the as above than I get the error: Invalid types 'float[int]' for array subscript.
this is the code:
#include <SPI.h>
#include <SD.h>
#include <Wire.h>
#include "RTClib.h"
#include "SparkFun_SCD30_Arduino_Library.h"
SCD30 airSensor;
const byte pin_LED = 13;
const int chipSelect = 10; //10 is default by shield, but normally on Pin 4
int interval = 5; //Log to SD Card every 5 seconds
long timer;
String timestring;
String mvalue;
float Offsets;
float CO2ppm = 1.50;
float TempC = 1.50;
float HumidityPct = 1.50;
File sdfile;
RTC_PCF8523 rtc;
void setup() {
Serial.begin(9600);
delay(3000);
Serial.println("Initializing SD card...");
if (!SD.begin(chipSelect)) {
Serial.println("SD Card error");
return;
}
Serial.println("card initialized");
if (! rtc.begin()) {
Serial.println("No RTC found");
} else {
Serial.println("RTC clock found");
}
if (! rtc.isrunning()) {
Serial.println("RTC is not configured");
}
}
void loop() {
if ((timer + interval * 1000) < millis()) {
timer = millis();
get_logvalue(); //Get your value
get_time(); //Get time from RTC
write_data(); //Write value and Time to SD
}
}
void get_logvalue() {
//mvalue = "My Value"; //mvalue is your log parameter eg. Temperature
Serial.print(CO2ppm)- Offsets[0];
Serial.print(";");
Serial.print(TempC) - Offsets[1];
Serial.print(";");
Serial.println(HumidityPct) - Offsets[2];
// Write to the SD card..
//sdfile.print(isoDateTime); // 20200216T150644Z
//sdfile.print(";");
sdfile.print(CO2ppm) - Offsets[0];
sdfile.print(";");
sdfile.print(TempC) - Offsets[1];
sdfile.print(";");
sdfile.println(HumidityPct) - Offsets[2];
Serial.println(mvalue);
}
void get_time(){ //Read Time from RTC
DateTime now = rtc.now();
timestring = now.day();
timestring += "-";
timestring += now.month();
timestring += "-";
timestring += now.year();
timestring += " ";
timestring += now.hour();
timestring += ":";
timestring += now.minute();
timestring += ":";
timestring += now.second();
Serial.println(timestring);
}
myFile = SD.open("Offsets.txt");
if (myFile) {
Serial.println("checking the offsets values:");
// read from the file until there's nothing else in it:
while (myFile.available()) {
Serial.write(myFile.read());
}
// close the file:
myFile.close();
} else {
// if the file didn't open, print an error:
Serial.println("error opening Offsets.txt");
}
void write_data() { //Write to SD card
String dataString = mvalue + "," + timestring;
//String dataString = CO2ppm + "," TempC + "," Humidity + "," timestring;
File dataFile = SD.open("datalog.txt", FILE_WRITE);
if (dataFile) {
dataFile.println(dataString);
dataFile.close();
Serial.println(dataString);
}
else {
Serial.println("error writing datalog.txt");
}
}