[solved]Flowmeter Datalogger sdcard

please help, I created a datalogger project from a flowmeter with an RS485 output. Using the rs485 to TTL (max485) module.
My problem is that the data is written on the SDcard only once, it doesn't continue. It looks like the serial software is in conflict or doesn't work
this is my code


#include <ModbusMaster.h>
#include <SoftwareSerial.h>
#include <RTClib.h>
#include <SPI.h>
#include <SD.h>
/*
#define MAX485_RE_NEG  6
#define MAX485_DE      7
#define SSERIAL_RX_PIN 8
#define SSERIAL_TX_PIN 9
*/
RTC_DS1307 rtc;
//const int chipSelect = 10;
ModbusMaster node;
SoftwareSerial RS485Serial(8, 9);
File dataFile;
void preTransmission() {
  digitalWrite(6, 1);
  digitalWrite(7, 1);
}

void postTransmission() {
  digitalWrite(6, 0);
  digitalWrite(7, 0);
}

void setup() {
  pinMode(6, OUTPUT);
  pinMode(7, OUTPUT);
  digitalWrite(6, 1);
  digitalWrite(7, 1);
  Serial.begin(9600);
  RS485Serial.begin(9600);
 
  node.begin(8, RS485Serial);
  node.preTransmission(preTransmission);
  node.postTransmission(postTransmission);
 SD.begin(10);
 if (! rtc.begin()) {
    Serial.flush();
    while (1) delay(10);
  }
if (! rtc.isrunning()) {
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
  }    
}

void loop() {

 
  readSensor();
   
  delay(10000); //read every 10 second
}

void writeToSD(DateTime vData,int vVol1, int vVol2, int Rate) { 
  File dataFile = SD.open("datalog.csv",FILE_WRITE);  

  if (dataFile) {
    dataFile.println(print_data(vData,vVol1,vVol2,Rate));
  }
   else
  {
    Serial.println("error opening datalog.csv");
  }
  dataFile.close();
}


String print_data(DateTime timestamp, int vVolTot, int vVolDec, int Rate) {
  char message[120];

  int Year = timestamp.year();
  int Month = timestamp.month();
  int Day = timestamp.day();
  int Hour = timestamp.twelveHour();
  int Minute = timestamp.minute();
  int Second= timestamp.second();
  float VolDec = vVolTot+(float)vVolDec/1000;
  char sVol[8];
  dtostrf(VolDec, String(VolDec).length(), 3, sVol);
  
  sprintf(message, "%02d-%02d-%d,%02d:%02d:%02d,%s,%d", Day,Month,Year,Hour,Minute,Second,sVol,Rate);
  
  return message;
}

void readSensor() {
  
  DateTime now = rtc.now(); 
  uint8_t result = node.readHoldingRegisters(99,13);
  if (result == node.ku8MBSuccess) {
    writeToSD(now,node.getResponseBuffer(8),node.getResponseBuffer(10),node.getResponseBuffer(1));
    Serial.println(print_data(now,node.getResponseBuffer(8),node.getResponseBuffer(10),node.getResponseBuffer(1)));    
  }
 else {
    Serial.println("Waiting");
  }
}

Hi @pedet_10k,

just a question:

 if (result == node.ku8MBSuccess) {
    writeToSD(now,node.getResponseBuffer(8),node.getResponseBuffer(10),node.getResponseBuffer(1));
    Serial.println(print_data(now,node.getResponseBuffer(8),node.getResponseBuffer(10),node.getResponseBuffer(1)));    
  }

I assume that the Serial.println() statement in the above function prints the actual data but you cannot find them on SD card ... Okay?

If yes, are the data on the SD card from the first write access or the last?

(Long, long time ago there was an issue with FILE_WRITE which did not include O_APPEND, just to make sure it's not the most simple reason ...)

P.S.: If you want to make a simple check you may replace

FILE_WRITE

by

(O_READ | O_WRITE | O_CREAT | O_APPEND)

ec2021

no, the data that I get on the SDcard only displays the data value once. like this pict.

Is this the last data set that you also saw on Serial?

(That would be good, because then it might just be a missing O_APPEND ...) :wink:

ec2021

yes,but i want record every 10 second ,its not happend ,sorry im nubby i dont understand about O_APPEND
:pray:

I just try to make sure that you do not have a very simple (and very old) issue ...

In this part of the sketch you write to the SD card:

void writeToSD(DateTime vData,int vVol1, int vVol2, int Rate) { 
  File dataFile = SD.open("datalog.csv",FILE_WRITE); 

  if (dataFile) {
    dataFile.println(print_data(vData,vVol1,vVol2,Rate));
  }
   else
  {
    Serial.println("error opening datalog.csv");
  }
  dataFile.close();
}

Where dataFile is opened you see the word FILE_WRITE which is defined as follows

#define FILE_WRITE (O_READ | O_WRITE | O_CREAT | O_APPEND)

in the Arduino SD lib on github (see https://github.com/arduino-libraries/SD/blob/master/src/SD.h)

It tells the SD lib that you want to open a file for Read and Write Access, which shall be created if not existing and to append new data at the end. If the option O_APPEND would be missing, it would start overwriting the content everytime you open and write to it.

It is not quite likely but to make sure that it is not so easy :wink: you can replace

File dataFile = SD.open("datalog.csv",FILE_WRITE); 

by

  File dataFile = SD.open("datalog.csv",(O_READ | O_WRITE | O_CREAT | O_APPEND)); 

Just a try ...
ec2021

1 Like

yesss its work thanks master :kissing_heart: oh ya one problem my serial monitor not show anything any sugestion :smile:

Serial.println(print_data(now,node.getResponseBuffer(8),node.getResponseBuffer(10),node.getResponseBuffer(1)));

Try this little change first:

#include <ModbusMaster.h>
#include <SoftwareSerial.h>
#include <RTClib.h>
#include <SPI.h>
#include <SD.h>
/*
#define MAX485_RE_NEG  6
#define MAX485_DE      7
#define SSERIAL_RX_PIN 8
#define SSERIAL_TX_PIN 9
*/
RTC_DS1307 rtc;
//const int chipSelect = 10;
ModbusMaster node;
SoftwareSerial RS485Serial(8, 9);
File dataFile;
void preTransmission() {
  digitalWrite(6, 1);
  digitalWrite(7, 1);
}

void postTransmission() {
  digitalWrite(6, 0);
  digitalWrite(7, 0);
}

void setup() {
  pinMode(6, OUTPUT);
  pinMode(7, OUTPUT);
  digitalWrite(6, 1);
  digitalWrite(7, 1);
  Serial.begin(9600);
  RS485Serial.begin(9600);
 
  node.begin(8, RS485Serial);
  node.preTransmission(preTransmission);
  node.postTransmission(postTransmission);
 SD.begin(10);
 if (! rtc.begin()) {
    Serial.flush();
    while (1) delay(10);
  }
if (! rtc.isrunning()) {
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
  }    
}

void loop() {

 
  readSensor();
   
  delay(10000); //read every 10 second
}

void writeToSD(DateTime vData,int vVol1, int vVol2, int Rate) { 
  File dataFile = SD.open("datalog.csv",FILE_WRITE);  
  String msg = print_data(vData,vVol1,vVol2,Rate);
  Serial.println(msg);

  if (dataFile) {
      dataFile.println(msg);
  }
   else
  {
    Serial.println("error opening datalog.csv");
  }
  dataFile.close();
}


String print_data(DateTime timestamp, int vVolTot, int vVolDec, int Rate) {
  char message[120];

  int Year = timestamp.year();
  int Month = timestamp.month();
  int Day = timestamp.day();
  int Hour = timestamp.twelveHour();
  int Minute = timestamp.minute();
  int Second= timestamp.second();
  float VolDec = vVolTot+(float)vVolDec/1000;
  char sVol[8];
  dtostrf(VolDec, String(VolDec).length(), 3, sVol);
  
  sprintf(message, "%02d-%02d-%d,%02d:%02d:%02d,%s,%d", Day,Month,Year,Hour,Minute,Second,sVol,Rate);
  
  return message;
}

void readSensor() {
  
  DateTime now = rtc.now(); 
  uint8_t result = node.readHoldingRegisters(99,13);
  if (result == node.ku8MBSuccess) {
    writeToSD(now,node.getResponseBuffer(8),node.getResponseBuffer(10),node.getResponseBuffer(1));
  }
 else {
    Serial.println("Waiting");
  }
}

Just moved the Serial.println() to the function void writeToSD() and removed this way the double call to print_data() ... This way exactly the same message should be written to Serial and to dataFile.

ec2021

1 Like

yess thank you very much master, I hope you are always healthy and have lots of fortune, greetings :pray:

Does it mean it works (or not?)?

its work

Great, you might mark this thread as solved so that others in the forum do know about it ...

Regards
ec2021

1 Like

ok

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.