(I'm waiting on an RTC to include a real world time stamp but for the time being/testing I am brute forcing a timer.)
I'm writing three analog inputs (temp, pH & OD) to an SD card. I want a time stamp, the data type and the sensor reading all on the same line but what I'm getting is ": :" then the data type & reading.
I came across the following code that isn't just converting millis() into MM/DD/HH/MM but rather has an actual time stamp. I'd prefer to stick to this method since it'll make data analysis a little less tedious once I'm utilizing a RTC.
#include "wiring.c"
const int Adjust = 8;
void SetMillis () {
char T[] = __TIME__;
uint8_t oldSREG = SREG;
cli();
unsigned long temp = (unsigned long)((T[0]*10+T[1]-528)*60+T[3]*10+T[4]-528)*60
+T[6]*10+T[7]-528+Adjust;
timer0_millis = (unsigned long)temp*1000;
SREG = oldSREG;
}
void setup() {
SetMillis();
// initialize serial communication
Serial.begin(9600);
}
// Add a leading zero when necessary
void Print2 (int n) {
if (n<10) Serial.print('0');
Serial.print(n);
}
void loop() {
// Demonstrate clock
unsigned long Now = millis()/1000;
int Seconds = Now%60;
int Minutes = (Now/60)%60;
int Hours = (Now/3600)%24;
Print2(Hours); Serial.print(':');
Print2(Minutes); Serial.print(':');
Print2(Seconds); Serial.println();
delay(1000);
}
My code (with the above code included) is as follows:
#include <SPI.h>
#include <SD.h>
File myFile;
#define TEMP_INTERVAL 18000ul // 30min
#define OD_INTERVAL 18000ul // 30min
#define PH_INTERVAL 12000ul // 20min
#define PH_CO2_ADD_INTERVAL 60000ul // 1min
#define PH_CO2_CHECK_INTERVAL 600000ul // 10min
// * * * * pH ADDED * * * *
unsigned long int avgValue; //Store the average value of the sensor feedback
float b;
int buf[10], temp;
// Optical Density Sensor
const byte OD_Probe = A5; //
const byte Temp_Probe = A0; //
const byte pH_Probe = A4; //
const byte CO2_GateValve = 3;
const byte pH_HIGH_THRESHOLD = 16.00;
unsigned long timeOD;
unsigned long timepH;
unsigned long timeTemp;
unsigned long timeCo2Add;
unsigned long timeCo2Chk;
unsigned long timeNow;
enum { ST_INIT, ST_ADD, ST_CHK };
int state;
#include "wiring.c"
const int Adjust = 8;
void SetMillis () {
char T[] = __TIME__;
uint8_t oldSREG = SREG;
cli();
unsigned long temp = (unsigned long)((T[0] * 10 + T[1] - 528) * 60 + T[3] * 10 + T[4] - 528) * 60
+ T[6] * 10 + T[7] - 528 + Adjust;
timer0_millis = (unsigned long)temp * 1000;
SREG = oldSREG;
}
// -----------------------------------------------------------------------------
void setup () {
Serial.begin (9600);
Serial.print("Initializing SD card...");
pinMode(10, OUTPUT);
if (!SD.begin(4)) {
Serial.println("Initialization failed!");
return;
}
Serial.println("Initialization done.");
myFile = SD.open("08112020.txt", FILE_WRITE);
if (myFile) {
Serial.print("Writing to 08112020.txt...");
// myFile.println("testing 1, 2, 3.");
myFile.close();
Serial.println("done.");
} else {
Serial.println("error opening 08112020.txt");
}
myFile = SD.open("08112020.txt");
if (myFile) {
Serial.println("08112020.txt");
while (myFile.available()) {
Serial.write(myFile.read());
}
myFile.close();
} else {
Serial.println("error opening 08112020.txt");
}
pinMode (OD_Probe, INPUT);
pinMode (CO2_GateValve, OUTPUT);
pinMode (Temp_Probe, INPUT);
pinMode (pH_Probe, INPUT);
timeNow = millis ();
timeOD = timeNow;
timepH = timeNow;
timeTemp = timeNow;
SetMillis();
}
// Add a leading zero when necessary
void Print2 (int n) {
if (n < 10) Serial.print('0');
Serial.print(n);
}
void loop ()
{
timeNow = millis ();
unsigned long Now = millis()/1000;
// -----------------------------------------------------------------------------
// * * * * * Temp INTERVAL * * * * *
if ((timeNow - timeTemp) >= TEMP_INTERVAL)
{
timeTemp = timeNow;
int temp_Val = analogRead (Temp_Probe);
myFile = SD.open("08112020.txt", FILE_WRITE);
unsigned long Now = millis() / 1000;
int Seconds = Now % 60;
int Minutes = (Now / 60) % 60;
int Hours = (Now / 3600) % 24;
Print2(Hours); myFile.print(":");
Print2(Minutes); myFile.print(":");
Print2(Seconds); myFile.println();
myFile.print(" Temp: ");
myFile.println(((temp_Val) - 500) / 10);
Serial.print("Temp: ");
Serial.println(((temp_Val) - 500) / 10);
myFile.close();
}
// -----------------------------------------------------------------------------
// * * * * * OD INTERVAL * * * * *
if ((timeNow - timeOD) >= OD_INTERVAL)
{
timeOD = timeNow;
int od_Val = analogRead (OD_Probe);
myFile = SD.open("08112020.txt", FILE_WRITE);
unsigned long Now = millis() / 1000;
int Seconds = Now % 60;
int Minutes = (Now / 60) % 60;
int Hours = (Now / 3600) % 24;
Print2(Hours); myFile.print(":");
Print2(Minutes); myFile.print(":");
Print2(Seconds); myFile.println();
myFile.print(" OD: ");
myFile.println(od_Val);
Serial.print("OD: ");
Serial.println(od_Val);
myFile.close();
}
// -----------------------------------------------------------------------------
// * * * * * pH INTERVAL * * * * *
if ((timeNow - timepH) >= PH_INTERVAL)
{
int pH_Val;
switch (state) {
case ST_INIT:
for (int i = 0; i < 10; i++) //Get 10 sample value from the sensor for smooth the value
{
buf[i] = analogRead(pH_Probe);
delay(10);
}
for (int i = 0; i < 9; i++) //sort the analog from small to large
{
for (int j = i + 1; j < 10; j++)
{
if (buf[i] > buf[j])
{
temp = buf[i];
buf[i] = buf[j];
buf[j] = temp;
}
}
}
avgValue = 0;
for (int i = 2; i < 8; i++) //take the average value of 6 center sample
avgValue += buf[i];
float pH_Val = (float)avgValue * 5.0 / 1024 / 6; //convert the analog into millivolt
pH_Val = 3.5 * pH_Val; //convert the millivolt into pH value
myFile = SD.open("08112020.txt", FILE_WRITE);
unsigned long Now = millis() / 1000;
int Seconds = Now % 60;
int Minutes = (Now / 60) % 60;
int Hours = (Now / 3600) % 24;
Print2(Hours); myFile.print(':');
Print2(Minutes); myFile.print(':');
Print2(Seconds); myFile.println();
myFile.print(" pH: ");
myFile.println(pH_Val);
Serial.print("pH: ");
Serial.println(pH_Val);
myFile.close();
if (pH_Val >= pH_HIGH_THRESHOLD) {
state = ST_ADD;
timeCo2Add = timeNow;
timeCo2Chk = timeNow;
digitalWrite (CO2_GateValve, LOW);
}
else
timepH = timeNow;
break;
case ST_ADD:
if ((timeNow - timeCo2Add) >= PH_CO2_ADD_INTERVAL) {
state = ST_CHK;
digitalWrite (CO2_GateValve, HIGH);
}
break;
case ST_CHK:
default:
if ((timeNow - timeCo2Chk) >= PH_CO2_CHECK_INTERVAL) {
state = ST_INIT;
timepH = timeNow;
}
break;
}
}
}
What is being written to the SD card is:
::
Temp: 52
::
OD: 480
::
pH: 15.10
I know there will be some drift in the timing but since this is only until I implement the RTC I don't see a need to worry about it. I'm hoping/guessing my mistake in including the timestamp code is a simply fix but that may be my naivety.