Hello,
I am trying to log flowmeter data on a SD card with Arduino Uno and Adafruit
RTC SD shield.
In order to reduce the number of write cycles to the SD card I am using circular
buffer to store values.
Unfortunately there is no circular buffer for strings (date-time string), so I am
using a string array.
The output on the serial monitor looks ok, but as soon as I uncomment the
// write_data(); //Write value and Time to SD
command the output on the serial monitor produces blank lines and skips
output. Also the date-time string DT[i] cannot be written to the SD card.
output is e.g.
;9.68;94
;17.20;111
Any ideas?
Thanks
Michael
#include <SPI.h>
#include <SD.h>
#include <Wire.h>
#include "RTClib.h"
#include <CircularBuffer.h>
// RTC
RTC_PCF8523 rtc;
const int chipSelect = 10; //10 is default by shield, but normally on Pin 4
int interval = 1; //Log to SD Card every 1 seconds
long timer;
String timestring;
String mvalue;
// flowmeter measured 0.103 ml/pulse
float cfactor = 0.103;
byte interrupt = 0;
byte sensorPin = 2;
byte pulseCount;
float flowRate;
float f_ml;
long t_ml;
CircularBuffer<float, 10> buf_f_ml;
CircularBuffer<long, 10> buf_t_ml;
String DT[10];
int i = 0;
unsigned long oldTime;
void setup()
{
Serial.begin(9600);
delay(2000);
//SD Card
Serial.println("Initializing SD card...");
if (!SD.begin(chipSelect)) {
Serial.println("SD Card error");
return;
}
Serial.println("card initialized");
//RTC startup
if (! rtc.begin()) {
Serial.println("No RTC found");
} else {
Serial.println("RTC clock found");
}
if (! rtc.isrunning()) {
Serial.println("RTC is not configured");
}
// flowmeter
pinMode(sensorPin, INPUT);
digitalWrite(sensorPin, HIGH);
attachInterrupt(interrupt, pulseCounter, FALLING);
//initialize timestring-array
for(int j = 0; j < 11; j++) {
DT[j] = "99-99-99 99:99:99";
}
buf_f_ml.clear();
buf_t_ml.clear();
timer = millis();
}
void loop() {
// push each interval one dataset to queue
if ((timer + interval * 2000) < millis()) {
timer = millis();
get_logvalue(); //Get your value
get_time(); //Get time from RTC
i++;
if(buf_f_ml.isFull()) {
// as soon as I uncomment the follwing line the output
// on the serial monitor gets screwed up
// write_data(); //Write value and Time to SD
buf_f_ml.clear();
buf_t_ml.clear();
i = 0;
}
}
}
void pulseCounter()
{
pulseCount++;
}
void get_logvalue() {
int semic;
detachInterrupt(interrupt);
f_ml = pulseCount * cfactor;
flowRate = (1000.0 / (millis() - oldTime)) * f_ml;
oldTime = millis();
t_ml += f_ml;
// buffer data to reduce number of write cycles to SD Card
buf_f_ml.push(f_ml);
buf_t_ml.push(t_ml);
Serial.print(String(i) + ": ");
Serial.print("Current flow: ");
Serial.print(int(flowRate));
Serial.print(".");
semic = (flowRate - int(flowRate)) * 10;
Serial.print(semic, DEC) ;
Serial.print("L/min");
Serial.print(" Total: ");
Serial.print(t_ml);
Serial.println("mL");
pulseCount = 0;
attachInterrupt(interrupt, pulseCounter, FALLING);
}
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();
DT[i] = timestring;
Serial.println("i: " + String(i) + " DT: " + DT[i]);
Serial.println("TS: " + timestring);
}
void write_data() { //Write to SD card
File dataFile = SD.open("datalog3.txt", FILE_WRITE);
int j = 0;
if (dataFile) {
while(!buf_f_ml.isEmpty()) {
String dataString = DT[j] + ";" + String(buf_f_ml.shift()) + ";" + String(buf_t_ml.shift());
dataFile.println(dataString);
Serial.println(dataString);
j++;
}
dataFile.close();
}
else {
Serial.println("error writing datalog.txt");
}
Serial.println("write end");
}