Time and TimeAlarms Libraries – Ask here for help or suggestions

Yes how stupid thanks may be back later if i can't get my head around the alarms, thanks again keith

Keith, don't beat yourself up. I can see why it seemed logical to include the TimeAlarm library within the Time folder. Unfortunately, Arduino does not currently handle library installation or inter-library dependencies very well, which is why I chose to have TimeAlarms as a separate library. Perhaps when Arduino support a simple mechanism for installing libraries, problems such as yours will go away.

Michael

How is "adjustTime(adjustment);" command used ?

I want to send a command to my program ,so an hour or a day is added to timer.
Later those commands will be sent by the press of a button

Is this command ok ? adjustTime(hour()++);

#include <Time.h>  


void setup()  {
  Serial.begin(9600);
 
  Serial.println("sending time to arduino");
  setTime(0,0,0,1,1,2000);
}

void loop(){
digitalClockDisplay();
delay(1000);
}

void digitalClockDisplay(){
 
  Serial.print(day());
  Serial.print(" ");
  Serial.print(hour());
  printDigits(minute());
  printDigits(second());
  Serial.print(" ");
  Serial.print(day());
  Serial.print(" ");
  Serial.print(month());
  Serial.print(" ");
  Serial.print(year()); 
  Serial.println(); 
}

void printDigits(int digits){
   Serial.print(":");
  if(digits < 10)
    Serial.print('0');
  Serial.print(digits);
}

I want to send a command to my program ,so an hour or a day is added to timer.

When you detect the command you can use the following:

time_t t = now();
setTime(t + X ); //X would be 3600 for 1 hour or 86400 for 1 day

OR

adjustTime(X) ; //X is + or - moves the time ahead or back X seconds ex: +3600 or -3600

DS1302

Hello Michael,
I placed this code in a class: Arduino Playground - HomePage
And I could add the 'get', 'set', 'read' and 'write' functions.

But I don't understand the difference between the 'sysTime' and the time in the RTC.
Are they synchronized with the 'syncInterval' ?
If the Arduino is running a little slow, it is no problem.
If the Arduino is running a little faster, it could cause a glitch for the number of seconds.

How is this handled ?
I do not know how this is done in a PC or other embedded system. I was just wondering what would happen.

I'm attempting to use the Time.h library in a program, but the program won't compile due to an issue in the .cpp file:

/Users/.../libraries/Time/Time.cpp: In function 'time_t now()':
/Users/.../libraries/Time/Time.cpp:240: error: 'millis' was not declared in this scope
/Users/.../libraries/Time/Time.cpp: In function 'void setTime(time_t)':
/Users/.../libraries/Time/Time.cpp:268: error: 'millis' was not declared in this scope

I'm not an expert, so I'd rather not go digging in the library files. I just updated to 1.0.3 from what I assume was the beta version.

I just updated to 1.0.3

Have you updated the Time library, too? Change WProgram.h to Arduino.h in the header and/or source file(s).

Thank you very much.

Hello everyone, I'm trying to use the Arduino time library at Arduino Playground - Time in my code, but the download link brings me to a page that says "The page "Time/Zip" doesn't exist."

Anyone know where I can download this library?

Thanks.
David

djlamm:
Anyone know where I can download this library?

Looks like the problem is fixed as of this morning. Thanks.

I just downloaded new update of Time library. When I try to compile it gives me an error:
sketchbook/libraries/Time/DateStrings.cpp:41:56: error: variable 'monthNames_P' must be const in order to be put into read-only section by means of 'attribute((progmem))'
sketchbook/libraries/Time/DateStrings.cpp:58:54: error: variable 'dayNames_P' must be const in order to be put into read-only section by means of 'attribute((progmem))'
sketchbook/libraries/Time/DateStrings.cpp:59:51: error: variable 'dayShortNames_P' must be const in order to be put into read-only section by means of 'attribute((progmem))'

It is due to new gcc-avr version 4.7.1

Three lines of code in DateStrings.cpp in library should be replaced by:
line 41: PGM_P PROGMEM monthNames_P[] =
line 58: PGM_P PROGMEM dayNames_P[] = { dayStr0,dayStr1,dayStr2,dayStr3,dayStr4,dayStr5,dayStr6,dayStr7};
line 59: const char dayShortNames_P[] PROGMEM = "ErrSunMonTueWedThrFriSat";

It, at least, compiles fine. There is no need to downgrade gcc-avr as suggested in several posts.

If someone come across the same problem, I hope it will helps.

Hello,
I'm sorry if this has been covered but I couldn't find it.
I modified the 'TimeSerialDateStrings' to include a 16x2 I²C LCD Display.
It seems to display okay for a minute, but then seems to get erroneous data causing it to display incorrect information.

It would start off displaying:
10:38:16 Mon
Apr 08, 2013

but after a minute it would change to something seemingly random like:
21:11:26 Fri
Aug 29, 2104

and it doesn't do this once. I haven't been able to get a time interval of when these errors occur, but if I could get some help fixing them, it would be appreciated. I have also seen it display years that contain 5 digits. That may have been an alignment issue tho.

/* 
 * TimeSerialDateStrings.pde
 * example code illustrating Time library date strings
 *
 * This sketch adds date string functionality to TimeSerial.pde
 * 
 */ 
 
#include <Time.h>  
#include <Wire.h>
#include <LiquidCrystal.h>
LiquidCrystal lcd(0); //I²C

#define TIME_MSG_LEN  11   // time sync to PC is HEADER followed by unix time_t as ten ascii digits
#define TIME_HEADER  'T'   // Header tag for serial time sync message
#define TIME_REQUEST  7    // ASCII bell character requests a time sync message 

void setup()  {
  lcd.begin(16,2);lcd.setBacklight(HIGH);
  Serial.begin(9600);
  setSyncProvider( requestSync);  //set function to call when sync required
  Serial.println("Waiting for sync message");
}

void loop(){    
  if(Serial.available() ) 
  {
    processSyncMessage();
  }
  if(timeStatus()!= timeNotSet) 
  {
    digitalClockDisplay();  
  }
  //delay(1000); //Disabled because I am not sending time to the Serial Monitor.
                 //I'm sending it to an LCD and the 1 second delay causes it to apear like it skips 1 second every 11 seconds even tho it really doesn't.
}

void digitalClockDisplay(){
  // digital clock display of the time
  lcd.setCursor(2,0);
  printDigits(hour());
  lcd.setCursor(4,0);
  lcd.print(":");
  lcd.setCursor(5,0);
  printDigits(minute());
  lcd.setCursor(7,0);
  lcd.print(":");
  lcd.setCursor(8,0);
  printDigits(second());
  lcd.print(" ");
  lcd.print(dayShortStr(weekday()));
  lcd.print(" ");
  lcd.setCursor(2,1);
  lcd.print(monthShortStr(month()));
  lcd.print(" ");
  printDigits(day());
  lcd.print(", ");
  lcd.print(year()); 
}

void printDigits(int digits){
  // utility function for digital clock display: prints preceding colon and leading 0
  //lcd.print(":"); //seemed to be getting in the way, nut I may be wrong
  if(digits < 10)
    lcd.print('0');
  lcd.print(digits);
}

void processSyncMessage() {
  // if time sync available from serial port, update time and return true
  while(Serial.available() >=  TIME_MSG_LEN ){  // time message consists of a header and ten ascii digits
    char c = Serial.read() ; 
    lcd.clear();
    Serial.print(c);  
    if( c == TIME_HEADER ) {       
      time_t pctime = 0;
      for(int i=0; i < TIME_MSG_LEN -1; i++){   
        c = Serial.read();          
        if( c >= '0' && c <= '9'){   
          pctime = (10 * pctime) + (c - '0') ; // convert digits to a number    
        }
      }   
      setTime(pctime);   // Sync Arduino clock to the time received on the serial port
    }  
  }
}

time_t requestSync()
{
  //Serial.print(TIME_REQUEST,BYTE);  
  //return 0; // the time will be sent later in response to serial mesg
}
time_t requestSync()
{
  //Serial.print(TIME_REQUEST,BYTE);  
  //return 0; // the time will be sent later in response to serial mesg
}

A non-void function MUST return a value. Since this is your sync function, the fact that it doesn't return anything is what is screwing up your clock.

Last night, I got this message. I re-enabled the two lines in question then resent the time code.
I then applied external power and removed the Serial Line and shut down my computer to leave it running without the computer.
It ran all night. I just got home from work and turned on my computer. The Arduino Clock is still in perfect sync with my PC.
It is displaying all the correct information.

Thank you for your help!

Hi all...I'm working at my first project using Arduino and it's IDE and I want to use a macro which is inside the Time.h..For example,after a reset or a power supply fault to the board, I want to calculate the second of the day when the board recovers, therefore to find in which cycle of a finite state machine the program is..For this I want to use the elapsedSecsToday, but I'm far from knowing how to use it, efectivelly...Here is my code,until now, and I want to run this macro in the set-up sequence..Can you give me a clue how to do it?

// GPS + RTC  FSM clock
//
#include "Wire.h"
#include <DS1307RTC.h>
#include <Time.h>       
#include <Timezone.h> //Jack Christensen's Timezone  
#include <TinyGPS.h>//GPS and NewSoftSerial libraries are the work of Mikal Hart
#define DS1307_ADDRESS 0x68
 

//Timezone settings..=============================.

TimeChangeRule myDST = {
  "ROM", Last, Sun, Mar, 3, +180};    //Daylight time = UTC - 4 hours
TimeChangeRule mySTD = {
  "ROM", First, Sun, Nov, 3, +120};     //Standard time = UTC - 5 hours
Timezone myTZ(myDST, mySTD);
TimeChangeRule *tcr;        //pointer to the time change rule, use to get TZ abbrev
time_t utc, local,t;//var that must be seen by others functions

//Tiny GPS====================================

TinyGPS gps;
boolean valid = false;

//***interrupt*********************
volatile boolean interruptComplete = false;
volatile boolean rtcisrunning = false;


//=========GPS checking=============================================
time_t gpsTimeSync()
{ 
  unsigned long age = 0 ;   
  unsigned long date, time;
  gps.get_datetime(NULL, NULL, &age);

  //No time update to DS1307 if GPS signal is lost....
  if (age == TinyGPS::GPS_INVALID_AGE || age >1500 ){
    //Serial.println("GPS lost..");
    valid = false;
  }
  else{
    valid = true ;
    gpsToArduino();
  }
}

//  GPS to DS1307 local time =====================================   
time_t gpsToArduino(){
  tmElements_t tm;
  int year;
  gps.crack_datetime(&year, &tm.Month, &tm.Day, &tm.Hour, &tm.Minute, &tm.Second, NULL, NULL);
  tm.Year = year-1970 ; 
  time_t time = makeTime(tm);//GPS data--> time_t....
  utc = time;// time from GPS....
  local = myTZ.toLocal(utc, &tcr);
  //RTC.set(local);// moved from here to the loop...

}
// read  a register from DS1307....

void readreg() {
  byte reg;
  Wire.beginTransmission(0x68);              // write the control register
  Wire.write(0x00);                           // register address 07H)
  Wire.endTransmission();

  Wire.requestFrom(0x68, 1);
  reg=Wire.read();
  Serial.println (reg,HEX);
  //delay(1000);
}

//Debug on serial monitor..=================================================
void monitor_out(){
  char dateTime[20];
  sprintf(dateTime, "%4d-%02d-%02d %02d:%02d:%02d", year(),
  month(), day(), hour(),minute(), second()) ;
  Serial.print(dateTime);
  Serial.print(" - day of week: ");
  Serial.println(dayStr(weekday()));
}


//======================================

void getGPS(){
  bool newdata = false;
  //unsigned long start = millis();
  // Every second we print an update
  //while (millis() - start < 1000)
  //{
  if (feedgps()) newdata = true;
  gpsTimeSync();
  //}
}

// ***********************************************
// read GPS serial data and send to tinyGPS
// ***********************************************
static bool feedgps() {
  while (Serial1.available()) {
    if (gps.encode(Serial1.read())) {
      return true;
    }
  }
  return false;
}

//=================================
void setup()
{
  Serial.begin(19200);//monitor
  Serial1.begin(19200); // for GPS
  Serial1.println ("$PMTK314,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*28");//RMC only...
  Serial1.println ("$PMTK220,1000*1F");//fix at 1000 ms
  attachInterrupt(0, interruptHandler, FALLING);
  Wire.begin();
  delay(1000);//debug only..
  
      
      while ( ! valid ){
        getGPS();
      }
         if (valid){
      RTC.set(local);// DS1307 set to the local time from timezone..
      Serial.println ( "DS set");//debug only
      delay(1000);//debug only
      }
    //Serial.println (elapsedSecsToday());
   
  
  setSyncProvider(RTC.get);   // the function to get the time from the RTC
  if(timeStatus()!= timeSet) 
    Serial.println("Unable to sync with the RTC");
  else
    Serial.println("RTC has set the system time");
    delay(500);//debug only

    

}
void loop()
{

  if (interruptComplete){

    if (valid){  // If GPS sentence is valid,write the time, if not, skip..

      RTC.set(local);// DS1307 set to the local time from timezone..
      Serial.println ( "beep");//debug only
    }
    if (! valid){
      Serial.println ("No GPS");// Serial2---->Ethernet...
    }
    RTC.get();// time from DS1307...
    monitor_out();   //print it...
    //readreg();
    interruptComplete = false;
  }
  getGPS();// get data from GPS
}


//interrupt vector=============================
void interruptHandler()
{
  rtcisrunning = true;
  interruptComplete = true;

}

JuraKa:
It is due to new gcc-avr version 4.7.1

Three lines of code in DateStrings.cpp in library should be replaced by:
line 41: PGM_P PROGMEM monthNames_P[] =
line 58: PGM_P PROGMEM dayNames_P[] = { dayStr0,dayStr1,dayStr2,dayStr3,dayStr4,dayStr5,dayStr6,dayStr7};
line 59: const char dayShortNames_P[] PROGMEM = "ErrSunMonTueWedThrFriSat";

Please email me directly, paul at pjrc dot com. I will apply this fix, but only if you (or someone) using avr gcc 4.7.1 will work with me by email to help with testing.

I do not plan to work on Time or other libraries until after Arduino 1.0.5 releases.

Hi..Any help for me? Post#164... :slight_smile:

I'm new to Arduino. I'm actually using a Seeeduino Stalker v2.3 for a project that monitors the output from a tipping water gauge. I've put the Time and Time Alarm libraries into the project which was already logging to a text file on an SD card, so far so good. What I noticed immediately on adding the timers and alarms in is that in testing at least that the logging was no longer triggering every time the gauge, which is a reed switch, was tripped. When I comment out the 'Alarm.delay(1000)' and reload the project to the device the logging works fine. With the alarm on, the logging is sporadic at best.

Looking for some help and a little insight on how I might do this better. Maybe the reed switch / logging method needs to be interrupt driven? Appreciative of help and suggestions.

James

code:

#include <Wire.h>
#include <SD.h>
#include "DS3231.h"
#include "DS1307RTC.h"
#include "Time.h"
#include "TimeAlarms.h"

  const int chipSelect = 10;

  int Led_Pin = 13;   // choose the pin for the LED
  int Sensor_Pin = 6; // choose the Sensor_Pin
  int val = 0;        // variable for reading the Sensor_Pin status
  String logData[] = ""; //empty string for log data
  DS3231 RTC2; //Create the R8025 object

void setup()
{
	Serial.begin(9600);
	Wire.begin();
	setTime(12,39,45,21,04,2013);
	Alarm.alarmRepeat(12,41,0, DailyLog);
	Alarm.timerRepeat(15, Repeater);

	pinMode(Led_Pin, OUTPUT);
	pinMode(Sensor_Pin, INPUT);
  /* add setup code here */
	setupsdcard();
	initializelogfile();
	

}


void loop()
{
	Alarm.delay(1000);
	logging();
}

void Repeater(){
  Serial.println("15 second timer test");         
}

void DailyLog(){
  Serial.println("Alarm: - sending log file");    
}

void setupsdcard(){
  pinMode(10, OUTPUT);
  if (!SD.begin(chipSelect)) {
    return;
  }
}


void logging(){
  
   val = digitalRead(Sensor_Pin);  // read Sensor_Pin
  if (val == HIGH) {         
    digitalWrite(Led_Pin, LOW);
  } else {
    digitalWrite(Led_Pin, HIGH);  //Set Led high
      logdata();
  } 
}

void initializelogfile(){
     char* filename = "datalog.txt";
     if(!SD.exists(filename)){
        Serial.println("Creating new datalog.txt...");
        File NewdataFile = SD.open(filename, FILE_WRITE);
        NewdataFile.close();
     }
}

void logdata(){
  
    File myFile = SD.open("datalog.txt", FILE_WRITE);
    if (myFile) {
      time_t t = now();
	  int32_t temp = RTC2.getTemperature();
	  String aDate = String(year(t), DEC) + "/" + String(month(t), DEC) + "/" + String(day(t), DEC) + ":" + String(hour(t),DEC) + ":" + String(minute(t), DEC) + ":"+ String(second(t),DEC) + " temp:" + temp + "'C";
      myFile.println(aDate);
      myFile.close();
      Serial.println(aDate);
      delay(500); } else {
    }
}

void getdata(){
  File myFile = SD.open("datalog.txt");
  
  if (myFile) {
    int counter = 0;
    while (myFile.available()) {
       logData[counter] = String(myFile.println());
       
	   Serial.write(sizeof(logData));
       counter++;
    }
    myFile.close();
  } else {
    Serial.println("error opening DATALOG.TXT");
  }
  
}

Why are you constructing and destructing so many String objects just to write the date to the file? Use sprintf() and a fixed buffer or 6 calls to File::print() and quit pissing memory away.

    while (myFile.available()) {
       logData[counter] = String(myFile.println());

This makes no sense whatsoever. Printing a blank line to the file, and then storing the number of characters printed to the file, wrapped in a String, in an array makes no sense.

Good point. I'm not entirely focused on performance just yet, more on getting it to work, which I just managed to do. The original intent of that method was to get the file content, read it line by line, get the first and last log entry, check the date difference to establish the time span and then based on that, process the file and send it as an SMS message. All that being said, it's no longer relevant.

Thanks for the pointers on memory and sprintf() etc. I'll keep it in mind as the project moves forward and I get into making better use of the limited resources on the device.

===

#include <Wire.h>
#include <SD.h>
#include "DS3231.h"
#include "DS1307RTC.h"
#include "Time.h"
#include "TimeAlarms.h"
#include <SoftwareSerial.h>
#include <String.h>

  SoftwareSerial mySerial(7, 8);		
  const int chipSelect = 10;
  int switchPin = 2; // choose the Sensor_Pin
  int counter0 = 0;
  long lastDebounce = 0;
  long debounceDelay = 500;
  int val = 0;        // variable for reading the Sensor_Pin status
  String logData[] = ""; //empty string for log data
  DS3231 RTC2; //Create the R8025 object
  int32_t temp = 0;

void setup()
{
	mySerial.begin(19200);
	Serial.begin(9600);
	Wire.begin();
	setTime(12,39,45,21,04,2013);
	Alarm.alarmRepeat(12,41,0, DailyLog);
	Alarm.timerRepeat(15, Repeater);
	pinMode(switchPin, INPUT);
	//digitalWrite(switchPin, HIGH);
	attachInterrupt(0, trigger0, FALLING);
  /* add setup code here */
	setupsdcard();
	initializelogfile();
	delay(500);
}

void loop()
{
	Alarm.delay(1000);
	temp = RTC2.getTemperature();
}

void trigger0(){
	if((millis() - lastDebounce) > debounceDelay){
		counter0++;
		File myFile = SD.open("datalog.txt", FILE_WRITE);
		if (myFile) {
		  time_t t = now();
		  String aDate = String(year(t), DEC) + "/" + String(month(t), DEC) + "/" + String(day(t), DEC) + ":" + String(hour(t),DEC) + ":" + String(minute(t), DEC) + ":"+ String(second(t),DEC)+ " " + temp + "'c";
		  myFile.println(aDate);
		  myFile.close();
		  Serial.println(aDate);
		  delay(200); 
		} else {
		}
		lastDebounce = millis();
	}
}

void Repeater(){
  Serial.println("15 second timer test");         
}

void DailyLog(){
  Serial.println("Alarm: - sending log file");  
    if (Serial.available())
    switch(Serial.read())
   {
     case 't':
       SendTextMessage();
       break;
   } 
  if (mySerial.available())
    Serial.write(mySerial.read());
}

///SendTextMessage()
///this function is to send a sms message
void SendTextMessage()
{
  mySerial.print("AT+CMGF=1\r");    //Because we want to send the SMS in text mode
  delay(100);
  mySerial.println("AT + CMGS = \"+86138xxxxx615\"");//send sms message, be careful need to add a country code before the cellphone number
  delay(100);
  mySerial.println("A test message!");//the content of the message
  delay(100);
  mySerial.println((char)26);//the ASCII code of the ctrl+z is 26
  delay(100);
  mySerial.println();
}
 
void setupsdcard(){
  pinMode(10, OUTPUT);
  if (!SD.begin(chipSelect)) {
    return;
  }
}

void initializelogfile(){
     char* filename = "datalog.txt";
     if(!SD.exists(filename)){
        Serial.println("Creating new datalog.txt...");
        File NewdataFile = SD.open(filename, FILE_WRITE);
        NewdataFile.close();
     }
}