Go Down

Topic: SD card - Setting different file names  (Read 1 time) previous topic - next topic

datalog

Hello all!

I am trying to get my Arduino to write my datalog files one after another, but I have problems...
How can I make an Arduino write a file name with a date ?
something like "datalog_25_01_2017.txt"

All the tutorials and help files on SD card libraries just show the same piece of code:
Code: [Select]
myFile = SD.open("test.txt", FILE_WRITE);
Which, clever as it is, just makes the arduino write one file, and append to it. No matter if the device has been turned off or not.
I would like to get it to write a new file each time it was turned on, but I cannot figure out how to make it define the file name in the setup, rather than the loop, much less get the filename to include the date from my RTC.

Nick_Pyner

#1
Jan 25, 2017, 01:49 am Last Edit: Jan 25, 2017, 01:54 am by Nick_Pyner
Below changes the filename at midnight, using data from RTC. It also enables download on demand.
Code: [Select]

#include <OneWire.h>
#include <DallasTemperature.h>
#include <PCD8544.h>             
#include "Wire.h"               
#include <SD.h>
#include <SPI.h>                 

#define DS1307_ADDRESS 0x68

char filename[] = "00000000.CSV";
File myFile;
char dumpName[] = "00000000.CSV";
File dumpFile;

static PCD8544 lcd;

// Custom symbols
static const byte DEGREES_CHAR = 1;
static const byte degrees_glyph[] = { 0x00, 0x07, 0x05, 0x07, 0x00 };
static const byte SLASH_CHAR = 2;
static const byte slash_glyph[] = {0x00,0x20,0x10,0x08};

// Green group Dee Why SERVICE
byte InThermo[8] =  {0x28, 0x69, 0xC2, 0xB0, 0x03, 0x00, 0x00, 0x9F };
byte OutThermo[8] = {0x28, 0x7A, 0x8B, 0xC0, 0x03, 0x00, 0x00, 0x2F};
byte DrainThermo[8] = {0x28, 0x54, 0xF7, 0x2D, 0x04, 0x00, 0x00, 0x68};
byte ShrThermo[8] = {0x28, 0x09, 0xA9, 0xC0, 0x03, 0x00, 0x00, 0x95}; 

byte sensorInterrupt = 0;  // 0 = pin 2; 1 = pin 3
byte sensorPin       = 2; //

const int chipSelect = 4;

volatile byte pulseCount;

float calibrationFactor = 4.28;    //5.04;
float flowRate;
float kW, kWh;
float flowMilliLitres;   //QUANTITY
int totalLitres;
unsigned long oldTime;

#define ONE_WIRE_BUS 3
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
 
byte  second, minute, hour, weekDay, day, month, year, today;
int k=0;
int p=0;

float tempC, InTemp, OutTemp, DrainTemp, ShrTemp, Rise, Fall, supply, maxOut, maxkW;

// Define the strings for our datastream IDs
char sensorId0[] = "InThermo";
char sensorId1[] = "OutThermo";
char sensorId2[] = "DrainThermo";
char sensorId3[] = "ShrThermo";

char strIn[8];
char strOut[8];
char strDrain[8];
char strRise[8];
char strFall[8];
char charBuf [15];

String readString;
String str1, str2, str3, str4;
String stringFive, stringSix;

//_________________________________________

void setup() {
  lcd.begin(84, 48);
     // Register the custom symbols...
  lcd.createChar(DEGREES_CHAR, degrees_glyph);
  lcd.createChar(SLASH_CHAR, slash_glyph);
 
  Wire.begin();
  Serial.begin(9600);
  Serial2.begin(115200);
 
  delay(300);//Wait for newly restarted system to stabilize

  pinMode(0, INPUT_PULLUP);   // just a precaution for bluetooth 
  pinMode(53, OUTPUT);//MEGA

  lcd.setCursor (0,0);
  lcd.println("Init SD CARD");
   
  // see if the card is present and can be initialized:
  if (!SD.begin(chipSelect))
  {
    lcd.println("Card failed");
    return;
  }
  lcd.println("CARD OK");
  delay(2000);
    GetClock();
    today = day; // flag for later midnight check
    getFileName();
      lcd.setCursor(0,3);
      lcd.println(filename);
        delay(2000);
      lcd.clear();
        myFile = SD.open(filename, FILE_WRITE);//<<<<<<<<<<<<< OPEN     
          myFile.println(",");
        myFile.close();//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>CLOSE   
       
  //Sequence for bluetooth
  // "E256,-321,982\n"
  //so insert three variable between four strings, two are the same twice,
  //to make a fourth string
 
  str1 = "E";
  str2 = ",";
  str3 = "\n";

    running();

  pulseCount          = 0;
  flowRate            = 0.0;
  flowMilliLitres     = 0.0; //QUANTITY
  totalLitres         = 0;
  oldTime             = 0;

  attachInterrupt(sensorInterrupt, pulseCounter, FALLING);     
  }
//________________________________________________________________

void loop() {
      if((millis() - oldTime) > 1000)    // Only process counters once per second
      {
   oldTime = millis();
   detachInterrupt(sensorInterrupt);
   
    flowRate = ((1000.0 / (millis() - oldTime)) * pulseCount) / calibrationFactor;
    flowMilliLitres = (flowRate / 60) * 1000;  // L/min IN ONE SECOND X 1000
    totalLitres += (flowRate / 60); //   totalLitres += (flowMilliLitres / 1000.0);

   GetClock();
  if (today != day)
  {
   today = day;
   minmax();
   getFileName();
  }
 
    while (Serial2.available())
  {
    delay(3); 
    char c = Serial2.read();
    readString += c;
  }// end while

  if (readString.length() >0)
  { 
    getDump();   
   readString=""; 
   } // end if
 
  sensors.requestTemperatures();

  InTemp = sensorValue(InThermo);
  OutTemp = sensorValue(OutThermo); 
  DrainTemp = sensorValue(DrainThermo);
  ShrTemp = sensorValue(ShrThermo);

  Rise = OutTemp - InTemp;
  Fall = ShrTemp - DrainTemp;
/*Serial.print("    ");
Serial.print(Rise);
Serial.print("    ");
*/

power();
  StringOut();
  LCDdata();

  k=k+1; 
  if ((k>9 ) && flowRate > 1)
  {   
    WriteSD();
    k=0;

    p=p+1; 
  if (p>90)
     {
       supply = InTemp;
       p=0;
     }
     
  if (OutTemp>maxOut)
     {
        maxOut = OutTemp;
     }
  }     
   pulseCount=0;
   attachInterrupt(sensorInterrupt, pulseCounter, FALLING);
  }
}  // loop ends here

float sensorValue (byte deviceAddress[])
{
  tempC = sensors.getTempC (deviceAddress);
  return tempC;
}

byte bcdToDec(byte val)  {
  // Convert binary coded decimal to normal decimal numbers
  return ( (val/16*10) + (val%16) );
}

void running(){
        lcd.clear();
  lcd.setCursor(7,0);
  lcd.print("In");
  lcd.setCursor(7,1);
  lcd.print("Out");
  lcd.setCursor(7,2);
  lcd.print("Flow");
  lcd.setCursor(7,3);
  lcd.print("Total");
  lcd.setCursor(7,4);
  lcd.print("kW"); 
  lcd.setCursor(7,5);
  lcd.print("kWh");
  }

void getFileName(){
sprintf(filename, "%02d%02d%02d.csv", year, month, day);
}

void GetClock(){
  // Reset the register pointer
  Wire.beginTransmission(DS1307_ADDRESS);
  byte zero = 0x00;
  Wire.write(zero);
  Wire.endTransmission();
  Wire.requestFrom(DS1307_ADDRESS, 7);

  second = bcdToDec(Wire.read());
  minute = bcdToDec(Wire.read());
  hour = bcdToDec(Wire.read() & 0b111111); //24 hour time
  weekDay = bcdToDec(Wire.read()); //0-6 -> sunday - Saturday
  day = bcdToDec(Wire.read());
  month = bcdToDec(Wire.read());
  year = bcdToDec(Wire.read());
}

void getDump() {
   stringSix = "16" + readString + ".csv";
   stringSix.toCharArray(charBuf, 15); 
     Serial2.println("");
     Serial2.println(charBuf);
  File dumpFile = SD.open(charBuf);
  if (dumpFile)
  {
    lcd.clear();
      lcd.setCursor (0,1);
      lcd.println("DUMP FROM ");
      lcd.setCursor (0,2);
      lcd.println(charBuf);
    while (dumpFile.available())
    {
      Serial2.write(dumpFile.read());
    }
    dumpFile.close();
      running();
  } 
  else {
    Serial2.println("error opening file");
       }
}

void pulseCounter()
{
  pulseCount++;
}

void WriteSD()

           myFile = SD.open(filename, FILE_WRITE);//<<<<<<<<<<<<< OPEN
  myFile.print(hour);
  myFile.print(":");
  myFile.print(minute);
  myFile.print(":");
  myFile.print(second);
  myFile.print(",");

  myFile.print(InTemp);
  myFile.print(",");
  myFile.print(OutTemp);
  myFile.print(",");
  myFile.print(DrainTemp);
  myFile.print(",");
  myFile.println(ShrTemp);
       myFile.close();//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>CLOSE     
      k=0;
}   

void LCDdata(){
  lcd.setCursor(49,0);
  lcd.print(InTemp);
  lcd.setCursor(49,1);
  lcd.print (OutTemp);
  lcd.setCursor(49,2);
  lcd.print(flowRate,1);
  lcd.setCursor(49,3);
  lcd.print(totalLitres); 
  lcd.setCursor(49,4);\
  lcd.print (kW); 
  lcd.print(" ");//suppress trailing fig > 9.99
  lcd.setCursor(49,5);
  lcd.print (kWh);
//  lcd.print(" ");//suppress trailing fig > 9.99
}

void StringOut()
   {
dtostrf(InTemp,4, 2, strIn);
dtostrf(OutTemp,4, 2, strOut);
dtostrf(Rise,4, 2, strRise);
dtostrf(Fall,4, 2, strFall);

str4 = str1 + strIn + str2 + strOut + str2 + strRise + str3;

  Serial2.println(str4);
   }
   
void minmax()
  {
    myFile = SD.open(filename, FILE_WRITE);//<<<<<<<<<<<<< OPEN
  myFile.print(supply);
  myFile.print(",");
  myFile.print(maxOut);
  myFile.print(",");
  myFile.println(maxkW);
    myFile.close();//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>CLOSE 
   
  maxOut = 0.0;   
  }
 
 void power()
 {

kW = flowMilliLitres * Rise / 239.0;
kWh = kWh + kW/3600.0;
 
  if (kW > maxkW)
    {
      maxkW = kW;
    }
 }
}


The vital bit is
Code: [Select]
void getFileName(){
sprintf(filename, "%02d%02d%02d.csv", year, month, day);
}
Strip out what you don't need....


datalog

Thanks guys!

Nick_Pyner, that did the trick!

I have set my code to write the file name as per:
Code: [Select]
sprintf(filename, "%02d%02d%02d%02d.csv", month, day, hour, minute);

Which works great!
Happy days

Go Up