set DS1307 time using an sd file

Hello.

I'm trying to read a line in a file located in an sd file and use that line to set my ds1307.

I'm having troble with this part of the code

myFile = SD.open("TimeDate.cfg");
    // read from the file until there's nothing else in it:
    while (myFile.available()) {
      inputChar = myFile.read();
      inputString[stringIndex] = inputChar; // Store it
      stringIndex++;
    }
    // close the file:
    myFile.close();

RTC.adjust(DateTime(inputString));

This returns the error:

snapshot4c.ino: In function 'void setDateTime()':
snapshot4c:352: error: invalid conversion from 'char*' to 'uint32_t {aka long unsigned int}' [-fpermissive]
invalid conversion from 'char*' to 'uint32_t {aka long unsigned int}' [-fpermissive]

I understad i'm using the wrong type of variable on "RTC.adjust(DateTime(inputString));". Can someone help me use the contents of inputString to adjust the DS1703 time?

What library are you using for the DS1307? Is it RTCLib.h with the DS1307 implementation.

#include "RTClib.h"
RTC_DS1307 rtc;

What do you have as the inputString when it is read from the SD card? Please provide the exact output. What is the declaration of inputString?

Edit: Where does the stored Date Time come from, and what format is it in at the original source?

Sorry, I just have to ask, why?

cattledog: What library are you using for the DS1307? Is it RTCLib.h with the DS1307 implementation.

#include "RTClib.h"
RTC_DS1307 rtc;

Yes, thats it.

cattledog: What do you have as the inputString when it is read from the SD card? Please provide the exact output. What is the declaration of inputString?

Edit: Where does the stored Date Time come from, and what format is it in at the original source?

The inputString will be the date and time i'm going to set on a file called DateTime.cfg in the sd card with this format: 2016, 3, 22, 21, 48, 0 But I haven't read the file yet. I get this error while compiling.

aarg:
Sorry, I just have to ask, why?

I assume you are asking why am I seting date and time using an sd card.
My project is a camera that’s triggered by a PIR sensor. Since the project won’t have ftdi to connect to a pc, i need a way to configure stuff, like time, date, picture size, time between shots, etc.

Why not store and retrieve the time on the card as a Unix time? It's a single integer value. Much easier to parse, and you really only need to set the time once.

vander: I assume you are asking why am I seting date and time using an sd card. My project is a camera that's triggered by a PIR sensor. Since the project won't have ftdi to connect to a pc, i need a way to configure stuff, like time, date, picture size, time between shots, etc.

I don't think you have answered the question, and I'm curious too. It sounds like you will need to know the time in order to set the time.

Since the project won't have ftdi to connect to a pc, i need a way to configure stuff, like time, date, picture size, time between shots, etc.

That's why you have the RTC. You will want to read the RTC and add a time stamp to the other data stored in the SD card. Why will you need to adjust the RTC based on previously stored data?

I would suggest a DS3231 RTC module instead of the DS1307 as they keep much better time.

It's not clear to me why you would want to take a value stored on the SD card and use it to update the RTC, but if you really want to do that, then you will need to get the DateTime.cfg ascii string into a format expected by DateTime in the RTC.adjust function.

The library gives you the options, and I think the closest for you is either

DateTime (uint32_t t =0);

//or

 DateTime (uint16_t year, uint8_t month, uint8_t day,uint8_t hour =0, uint8_t min =0, uint8_t sec =0);

So, as aarg suggests, store the time as the uint32_t "Unix Time", and reset the RTC with that, or else, parse and convert the ascii string into the numerical values expected by the function.

Nick_Pyner: I don't think you have answered the question, and I'm curious too. It sounds like you will need to know the time in order to set the time.

My project will be placed on a remote place in the middle of nowhere. I get there and my camera is dead. I replace the battery but the coin cell is also dead. I also replace it but now i can't set date or time because I dont have a computer or ftdi connection. I take the sd card out, pop it on my phone, create a file with the current date and time. My code detects the presence of a config file, sets the parameters I choose, deletes the file and reboots. Problem solved.

cattledog: That's why you have the RTC. You will want to read the RTC and add a time stamp to the other data stored in the SD card. Why will you need to adjust the RTC based on previously stored data?

I would suggest a DS3231 RTC module instead of the DS1307 as they keep much better time.

It's not clear to me why you would want to take a value stored on the SD card and use it to update the RTC, but if you really want to do that, then you will need to get the DateTime.cfg ascii string into a format expected by DateTime in the RTC.adjust function.

The library gives you the options, and I think the closest for you is either

DateTime (uint32_t t =0);

//or

DateTime (uint16_t year, uint8_t month, uint8_t day,uint8_t hour =0, uint8_t min =0, uint8_t sec =0);




So, as aarg suggests, store the time as the uint32_t "Unix Time", and reset the RTC with that, or else, parse and convert the ascii string into the numerical values expected by the function.

I could store date and time in the file as unix time, if I knew how to... I'll have to check that out because it would be simpler to have a long integer to use in rtc.adjust (DateTime(longinthere)). I'll have it a go. Thanks!

You will basically be storing now.unixtime() read from the RTC in the SD card as a uint32_t time stamp. Be sure to store the numerical value (4 bytes) and not the ascii characters.

DateTime now = rtc.now();
 TimeStamp = now.unixtime();

//or

TimeStamp = rtc.now().unixtime();

To set the rtc to a Unix time stamp you will use

rtc.adjust(DateTime(xxxxxxxxxx)); //input 10 digit unix time stamp value

I take the sd card out, pop it on my phone, create a file with the current date and time. My code detects the presence of a config file, sets the parameters I choose, deletes the file and reboots. Problem solved.

What is the format of the data you get from the phone? If you can get a uint32_t timestamp from the phone you are good, other wise you still have the issue of getting from an ascii string to something that rtc.adjust and DateTime will accept.

cattledog: You will basically be storing now.unixtime() read from the RTC in the SD card as a uint32_t time stamp. Be sure to store the numerical value (4 bytes) and not the ascii characters.

DateTime now = rtc.now();
 TimeStamp = now.unixtime();

//or

TimeStamp = rtc.now().unixtime();




To set the rtc to a Unix time stamp you will use


rtc.adjust(DateTime(xxxxxxxxxx)); //input 10 digit unix time stamp value ```

What is the format of the data you get from the phone? If you can get a uint32_t timestamp from the phone you are good, otherwise you still have the issue of getting from an ascii string to something that rtc.adjust and DateTime will accept.

No, you don't understand. That would mean creating the file and inserting the time and date using my project. That's not the objective. Let's forget the "why?".

I have a file named "TimeDate.cfg" in an SD card. The contents of that file are the following text in one line:

2016, 3, 22, 21, 48, 0

This is what I need to set time on my DS1703. The command I use is:

RTC.adjust(DateTime(2016, 3, 22, 21, 48, 0))

This sets the time on my DS1703 RTC and it works because I tried it.

My problem is when I try to retrieve the contents of the file.

My code is as follows:

myFile = SD.open("TimeDate.cfg");
    // read from the file until there's nothing else in it:
    while (myFile.available()) {
      inputChar = myFile.read();
      inputString[stringIndex] = inputChar; // Store it
      stringIndex++;
    }
    // close the file:
    myFile.close();

RTC.adjust(DateTime(inputString));

The error is in this line: RTC.adjust(DateTime(inputString));

The error message:

snapshot4c.ino: In function 'void setDateTime()':
snapshot4c:352: error: invalid conversion from 'char*' to 'uint32_t {aka long unsigned int}' [-fpermissive]
invalid conversion from 'char*' to 'uint32_t {aka long unsigned int}' [-fpermissive]

How do I create a type uint32_t variable named "inputString" and fill it with myFile.read();?

I appreciate any help you can offer.

With a file named TimeDate.cfg containing 2016,3,22,21,48,0 as characters, the following sketch will read them out, and convert to numerical values, and load into the rtc. It uses the .parseInt() function.

#include <Wire.h>
#include "RTClib.h"
RTC_DS1307 rtc;

#include <SPI.h>
#include <SD.h>

int year;
int month;
int day;
int hour;
int minute;
int second;

void setup()
{ 
  Serial.begin(9600);
  SD.begin(10);
  rtc.begin();
  
  File myFile = SD.open("TimeDate.cfg");
  if (myFile) {
    Serial.println("TimeDate.cfg");
    while (myFile.available()) {
      year = myFile.parseInt();
      month = myFile.parseInt();
      day = myFile.parseInt();
      hour = myFile.parseInt();
      minute = myFile.parseInt();
      second = myFile.parseInt();
      myFile.close();
    }
  }
  else {
    // if the file didn't open, print an error:
    Serial.println("error opening TimeDate.cfg");
  }

  Serial.print("cfg file read from sd card  ");
  Serial.print(year);
  Serial.print("/");
  Serial.print(month);
  Serial.print("/");
  Serial.print(day);
  Serial.print("  ");
  Serial.print(hour);
  Serial.print(":");
  Serial.print(minute);
  Serial.print(":");
  Serial.println(second);

rtc.adjust(DateTime(year,month,day,hour,minute,second));
Serial.println("cfg data loaded into rtc  ");
}

void loop() {
  DateTime now = rtc.now();
    Serial.print(now.year());
    Serial.print('/');
    Serial.print(now.month());
    Serial.print('/');
    Serial.print(now.day());
    Serial.print("   ");
    Serial.print(now.hour());
    Serial.print(':');
    Serial.print(now.minute());
    Serial.print(':');
    Serial.print(now.second());
    Serial.println();
    
    Serial.print("Since midnight 1/1/1970 = ");
    Serial.print(now.unixtime());
    Serial.println("  unix timestamp");
    
    delay(5000);
    }

cattledog:
With a file named TimeDate.cfg containing 2016,3,22,21,48,0 as characters, the following sketch will read them out, and convert to numerical values, and load into the rtc. It uses the .parseInt() function.

#include <Wire.h>

#include “RTClib.h”
RTC_DS1307 rtc;

#include <SPI.h>
#include <SD.h>

int year;
int month;
int day;
int hour;
int minute;
int second;

void setup()
{
  Serial.begin(9600);
  SD.begin(10);
  rtc.begin();
 
  File myFile = SD.open(“TimeDate.cfg”);
  if (myFile) {
    Serial.println(“TimeDate.cfg”);
    while (myFile.available()) {
      year = myFile.parseInt();
      month = myFile.parseInt();
      day = myFile.parseInt();
      hour = myFile.parseInt();
      minute = myFile.parseInt();
      second = myFile.parseInt();
      myFile.close();
    }
  }
  else {
    // if the file didn’t open, print an error:
    Serial.println(“error opening TimeDate.cfg”);
  }

Serial.print(“cfg file read from sd card  “);
  Serial.print(year);
  Serial.print(”/”);
  Serial.print(month);
  Serial.print("/");
  Serial.print(day);
  Serial.print("  “);
  Serial.print(hour);
  Serial.print(”:");
  Serial.print(minute);
  Serial.print(":");
  Serial.println(second);

rtc.adjust(DateTime(year,month,day,hour,minute,second));
Serial.println("cfg data loaded into rtc  ");
}

void loop() {
  DateTime now = rtc.now();
    Serial.print(now.year());
    Serial.print(’/’);
    Serial.print(now.month());
    Serial.print(’/’);
    Serial.print(now.day());
    Serial.print("  ");
    Serial.print(now.hour());
    Serial.print(’:’);
    Serial.print(now.minute());
    Serial.print(’:’);
    Serial.print(now.second());
    Serial.println();
   
    Serial.print(“Since midnight 1/1/1970 = “);
    Serial.print(now.unixtime());
    Serial.println(”  unix timestamp”);
   
    delay(5000);
    }

That seems so simple that I feel genuinely bad for not coming up with that code…
I will try it as soon as I get home. I’ll post if it works or not.

Cheers, mate!

it worked. thanks!