Testing for file existence

Hello all

My Question:
I am wanting to test for the existence of a file on power up. The data file called datalog.txt. If the file does exist then run, which appends data to the file. If the file doesn’t exists then create it and write a header.

Extra Info:
This is for a data logger for my offline power system that I am working on.

Hardware list:
Uno R3
Data logger shield for Uno
16x2 LCD (not I2C)

#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include "RTClib.h"
#include <SoftI2C.h>
#include <LiquidCrystal.h>

RTC_DS1307 RTC;

LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

SoftI2C i2c(A4, A5);

float SensorVoltage = 5000;
float VoltsPerAmp = 0.040;
float IntSensorVolts = 2.500;

int Res = 1023;

int chipSelect = 10;

File dataFile;

const int VoltInputPin = A1;
float VoltIn = 0;
float VoltInValue = 0;
float VoltsIn = 0;
const float R1 = 30000;
const float R2 = 7500;

int AmpInputPin = A2;
float AmpIn = 0;
float AmpInValue = 0;
float AmpsIn = 0;

int AmpOutPin = A3;
float AmpOut = 0;
float AmpOutValue = 0;
float AmpsOut = 0;

long readVcc() {
  long result;
  // Read 1.1V reference against AVcc
  ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
  delay(2);
  ADCSRA |= _BV(ADSC);
  while (bit_is_set(ADCSRA, ADSC));
  result = ADCL;
  result |= ADCH << 8;
  result = 1125300L / result;
  return result;
}

void setup() {
  Serial.begin(9600);
  analogReference(DEFAULT);
  Wire.begin();
  RTC.begin();
  Serial.println();
  while (!Serial) {
    ;
  }

  Serial.print("Initializing SD card...");
  pinMode(SS, OUTPUT);
  if (!SD.begin(chipSelect)) {
    Serial.println("Card failed, or not present");
    while (1) ;
  }
  Serial.println("card initialized.");
  dataFile = SD.open("datalog.txt", FILE_WRITE);
  if (dataFile) {
    Serial.print("Writing to datalog.txt...");
    dataFile.println("Date, Time, Battery Volts, Amps IN, Amps OUT");
  } else {
    // if the file didn't open, print an error:
    Serial.println("error opening datalog.txt");
  }

  pinMode(VoltInputPin, INPUT);
  pinMode(AmpInputPin, INPUT);
  pinMode(AmpOutPin, INPUT);
  lcd.begin(16, 2);
}

void loop() {

  DateTime now = RTC.now();

  unsigned int ADCValue;
  double Voltage;
  double Vcc;

  Vcc = readVcc() / 1000.0;
  ADCValue = analogRead(0);
  Voltage = (ADCValue / Res) * Vcc;

  {
    VoltInValue = analogRead(VoltInputPin);
    VoltIn = (VoltInValue * Vcc) / Res;
    VoltsIn = VoltIn / (R2 / (R1 + R2));
  }

  AmpInValue = analogRead(AmpInputPin);
  AmpsIn = (AmpInValue - (Vcc / 2)) * Vcc / Res / 0.04 - 0.34;

  AmpOutValue = analogRead(AmpOutPin);
  if (AmpOutValue < (Res / 2))
  {
    AmpOut = IntSensorVolts - (AmpOutValue / Res);
  }
  else
  {
    AmpOut = IntSensorVolts + (AmpOutValue / Res);
  }

  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Volts: ");
  if (VoltsIn < 10) {
    lcd.print(0);
  }
  lcd.print(VoltsIn);

  lcd.setCursor(0, 1);
  if (now.day() < 10) {
    lcd.print("0");
  }
  lcd.print(now.day(), DEC);
  lcd.print('-');
  if (now.month() < 10) {
    lcd.print("0");
  }
  lcd.print(now.month(), DEC);
  lcd.print('-');
  lcd.print(now.year(), DEC);
  lcd.print(" ");
  if (now.hour() < 10) {
    lcd.print("0");
  }
  lcd.print(now.hour(), DEC);
  lcd.print(':');
  if (now.minute() < 10) {
    lcd.print("0");
  }
  lcd.print(now.minute(), DEC);

  dataFile.println();
  if (now.day() < 10) {
    dataFile.print("0");
  }
  dataFile.print(now.day(), DEC);
  dataFile.print("/");
  if (now.month() < 10) {
    dataFile.print("0");
  }
  dataFile.print(now.month(), DEC);
  dataFile.print("/");
  dataFile.print(now.year(), DEC);
  dataFile.print(", ");
  if (now.hour() < 10) {
    dataFile.print("0");
  }
  dataFile.print(now.hour(), DEC);
  dataFile.print(":");
  if (now.minute() < 10) {
    dataFile.print("0");
  }
  dataFile.print(now.minute(), DEC);
  dataFile.print(", ");
  dataFile.print(VoltsIn);
  dataFile.print(", ");
  dataFile.print(AmpsIn);
  dataFile.print(", ");
  dataFile.print(AmpsOut);

  dataFile.flush();

  Serial.print(VoltsIn);
  Serial.print(", ");
  Serial.print(AmpsIn);
  Serial.print(", ");
  Serial.print(AmpsOut);
  Serial.print(", ");
  Serial.print(Vcc);
  Serial.println();

  delay(500);
}

Many thanks in advance for any input offered.

Regards

Fred

So what is the problem ?

The SD library has an exists() method and the SD Files example shows how it is used.

I think that SD.exists() will provide the functionality that you're looking for.

My problem is that I'm not a programmer. And I have read SD.exist() but I can't work out how to implement it correctly.

I'm an electronics (hardware) engineer not a programmer.

Regards

Fred

I can't work out how to implement it correctly.

Look at the SD examples, give it a go and post your code and any problems here and you will get plenty of help.

Hi All

I have managed to resolve my problem. I rang a programmer friend and he gave me a few tips. I then researched the information he gave me and the result is shown.

It sure isn't pretty, but as I have said, I'm not a programmer. And as easy as this project may sound, I have been working on the software for almost 8 months now. A really steep learning curve for me.

I have tested this code and does what I want it to do. It's only taken me 3 days to work this out. But I did it.

Serial.print("Initializing SD card...");                // make sure that the default chip select pin is set to
  // output, even if you don't use it:
  pinMode(SS, OUTPUT);

  // see if the card is present and can be initialized:
  if (!SD.begin(chipSelect)) {
    Serial.println("Card failed, or not present");
    // don't do anything more:
    while (1) ;
  }
  Serial.println("card initialized.");

  if (SD.exists("datalog.txt")) {
    goto NoHeader;
  }
  else {
    goto Header;
  }
  
Header:
  // if the file opened okay, write to it:
  dataFile = SD.open("datalog.txt", FILE_WRITE);
  if (dataFile) {
    Serial.print("Writing to datalog.txt...");
    dataFile.print("Date, Time, Battery Volts, Amps IN, Amps OUT");
    // close the file:
    //    dataFile.close();
    //    Serial.println("done.");
  } else {
    // if the file didn't open, print an error:
    Serial.println("error opening datalog.txt");
  }
goto Program;

NoHeader:
  dataFile = SD.open("datalog.txt", FILE_WRITE);
  if (dataFile) {
    Serial.print("Writing to datalog.txt...");
  } else {
    // if the file didn't open, print an error:
    Serial.println("error opening datalog.txt");
  }

Program:
  pinMode(VoltInputPin, INPUT);                           // Set the mode of the pin used to measure battery voltage
  pinMode(AmpInputPin, INPUT);                            // Set the mode of the pin used to measure wind turbine charge current
  pinMode(AmpOutPin, INPUT);                              // Set the mode of the pin used to measure the current drawn for the inverter
  lcd.begin(16, 2);                                       // Define number of characters and rows for the LCD
}

Regards

Fred

goto Program;Did you use goto at the suggestion of your programmer friend ? What programming language does he use and when was the last time he used it ?

He didn’t say to use goto. He suggested I use lables as a means of navigating the program. I simply googled lable examples and came up with what I have. And he only suggested lables because he knew of my very limited knowledge.

As I said, I’m no programmer. And I don’t necessarily want to be hand held. but some guidance/suggestion is often enough for me to cobble something together.

And for what it is worth. The documentation for Arduino isn’t any help at all for a guy like me who isn’t a programmer, and truth be known doesn’t really want to be. But does this out of necessity because I can’t afford to pay someone to do it properly for me. But I do have to say. The Arduino hardware is just great for what it is, so I persevere with it.

Sorry if I sound short. But I’m at the bottom of what seems to be a very tall ladder, and I sometimes get tired and cranky from looking up all the time. And I know that not really wanting to do this doesn’t help my situation. But I am where I am.

Regards

Fred

The documentation for Arduino isn’t any help at all for a guy like me who isn’t a programmer,

The Arduino documentation is mostly about the Arduino specific functions such as pinMode(), digitalRead() etc but the programming language used is C++ and there are plenty of tutorials online and plenty of help available here.

Instead of using 'goto', you could make 'Header' and 'NoHeader' into separate functions, called from the 'if' statement, especially since the code under 'Program' is executed in both cases.
ie

if (SD.exists("datalog.txt"))
    NoHeader();
else
    Header();

// *** Put code currently under 'Program' here.

Then, outside the loop function:-

void Header()
{
    // if the file opened okay, write to it:
    dataFile = SD.open("datalog.txt", FILE_WRITE);
    if (dataFile)
    {
        Serial.print("Writing to datalog.txt...");
        dataFile.print("Date, Time, Battery Volts, Amps IN, Amps OUT");
        // close the file:
        //    dataFile.close();
        //    Serial.println("done.");
    }
    else
    {
        // if the file didn't open, print an error:
        Serial.println("error opening datalog.txt");
    }
}

void NoHeader()
{
    dataFile = SD.open("datalog.txt", FILE_WRITE);
    if (dataFile)
    {
        Serial.print("Writing to datalog.txt...");
    }
    else
    {
        // if the file didn't open, print an error:
        Serial.println("error opening datalog.txt");
    }
}

'goto' is a thing of the past, (mainly a relic of other languages like Basic), and best avoided unless it's absolutely necessary.

You could even make the 'Header()' and 'NoHeader()' functions return a value, to indicate an error. Perhaps they could return 'true' if successful, 'false' if not, then that return value could determine whether or not to execute the code that's now under 'Program'.
ie
When calling 'Header()' or 'NoHeader()':-

retVal = Header();

if(retVal==true)
{
    // Put the code that's now under 'Program' here.
}

And the 'Header()' and 'NoHeader()' functions:-

boolean Header()
{
        // if the file opened okay, write to it:
    dataFile = SD.open("datalog.txt", FILE_WRITE);
    if (dataFile)
    {
        Serial.print("Writing to datalog.txt...");
        dataFile.print("Date, Time, Battery Volts, Amps IN, Amps OUT");
        // close the file:
        //    dataFile.close();
        //    Serial.println("done.");
        return true;
    }
    else
    {
        // if the file didn't open, print an error:
        Serial.println("error opening datalog.txt");
        return false;
    }
}

boolean NoHeader()
{
    dataFile = SD.open("datalog.txt", FILE_WRITE);
    if (dataFile)
    {
        Serial.print("Writing to datalog.txt...");
        return true;
    }
    else
    {
        // if the file didn't open, print an error:
        Serial.println("error opening datalog.txt");
        return false;
    }
}

Morning guys

Thanks heaps for the suggestions. Knowing the language is probably the biggest help. Now when I'm searching for examples I know what to look for.

I will test the example of function rather than goto example today.

I will also search for what the rest of the code that I have robbed actually does, and how it works so that I can annotate my code fully. This will ensure that once the project is complete, should I have to come back to it for any reason I have an understanding of what the program is doing and why. It also means that if someone else wants to use the code they can understand what I have done and why.

Regards

Fred