Go Down

Topic: Time and TimeAlarms Libraries – Ask here for help or suggestions (Read 79 times) previous topic - next topic

Paul Stoffregen


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.



JamesBee

#167
Apr 21, 2013, 07:20 pm Last Edit: Apr 27, 2013, 02:58 pm by JamesBee Reason: 1
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:  

Code: [Select]

#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");
 }
 
}

PaulS

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.

Code: [Select]
    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.

JamesBee

#169
Apr 22, 2013, 12:01 am Last Edit: Apr 27, 2013, 02:57 pm by JamesBee Reason: 1
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.

===
Code: [Select]

#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();
    }
}

PaulS

Quote
SoftwareSerial mySerial(7, 8);     

Ah, yes, the infamous smiley face pin. I wish my Arduino had one.

JamesBee

Ah yes, the smiley. Where would we be without it? Likely living in caves and chipping pointy stones... no, wait a minute, forget that.


biggosh


iwilllearn

adjustTime(adjustment); // Adjust system time by adding
                         //  the adjustment value
help
how do i use this function?
what is the adjustment value?
thank you

kgarner

Hi.. new with Arduino R3 and official Ethernet shield I was very pleased to use the TimeNTP Example and have it work first time. That is when I - Ethernet.begin(mac) - address only and connect to my network using DHCP. However, when I specify the IP address it fails each time with "No NTP Response :-(".

I really need to be able to specific a static address but even when I also supply the gateway address and subnet mask - Ethernet.begin(mac, IP, Gateway, Subnet); - it never works. How can I fix this please?

Docedison

While the Time Library is ok... it really doesn't work like it had been tested... The TimeGPS code is completely non functional. No surprise, it was written on 1/6/2010 and never tested. Ever.

Doc
--> WA7EMS <--
"The solution of every problem is another problem." -Johann Wolfgang von Goethe
I do answer technical questions PM'd to me with whatever is in my clipboard

Elektrix

I have gcc-avr 4.7.2 on Debian Wheezy and tried the Time library. I got the same errors as already mentioned. Then I changed DateStrings.cpp as shown above. Still got the same errors. Now I take the original version from the playground, works ok.

Elektrix
My blog about arduino and Linux themes:
http://heliosoph.mit-links.info/

Paul Stoffregen

Download Arduino from www.arduino.cc and use it, instead of the one provided by your distro.

PedroS23

The results appear in Serial.Monitor this:




I wonder if it is possible to set the date and time displayed for the Date and Current Time????

example:

17/07/2013 17:10:00


I'm printing that results in the void loop () (as shown in the code previously published) and was taken from a line of code that I took from the window where I downloaded the library team, and this is the code I'm using:

Code: [Select]

*
* TimeSerial.pde
* example code illustrating Time library set through serial port messages.
*
* Messages consist of the letter T followed by ten digit time (as seconds since Jan 1 1970)
* you can send the text on the next line using Serial Monitor to set the clock to noon Jan 1 2013
T1357041600 
*
* A Processing example sketch to automatically send the messages is inclided in the download
* On Linux, you can use "date +T%s > /dev/ttyACM0" (UTC time zone)
*/

#include <Time.h> 

#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()  {
  Serial.begin(9600);
  while (!Serial) ; // Needed for Leonardo only
  pinMode(13, OUTPUT);
  setSyncProvider( requestSync);  //set function to call when sync required
// Serial.println("Waiting for sync message"); [i][b]it's necessary???[/b][/i]
time_t t = now(); // Store the current time in time
                    //  variable t
now();
}


void digitalClockDisplay(){
  // digital clock display of the time
  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){
  // utility function for digital clock display: prints preceding colon and leading 0
  Serial.print(":");
  if(digits < 10)
    Serial.print('0');
  Serial.print(digits);
}


void processSyncMessage() {
  unsigned long pctime;
  const unsigned long DEFAULT_TIME = 1357041600; // Jan 1 2013

  if(Serial.find(TIME_HEADER)) {
     pctime = Serial.parseInt();
     if( pctime >= DEFAULT_TIME) { // check the integer is a valid time (greater than Jan 1 2013)
       setTime(pctime); // Sync Arduino clock to the time received on the serial port
     }
  }
}

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

void loop(){   
  if (Serial.available()) {
    processSyncMessage();
  }
  if (timeStatus()!= timeNotSet) {
    digitalClockDisplay(); 
  }
  if (timeStatus() == timeSet) {
    digitalWrite(13, HIGH); // LED on if synced
  } else {
    digitalWrite(13, LOW);  // LED off if needs refresh
  }
  delay(1000);
 
  time_t t = now(); // Store the current time in time
                    //  variable t
                   
  hour(t);          // Returns the hour for the given
                    //  time t
  minute(t);        // Returns the minute for the given
                    //  time t
  second(t);        // Returns the second for the given
                    //  time t
  day(t);           // The day for the given time t

  weekday(t);       // Day of the week for the given
                    //  time t 
  month(t);         // The month for the given time t

  year(t);          // The year for the given time t
 
 

  Serial.print(year(t));
  Serial.print("/");
  Serial.print(month(t));
  Serial.print("/");
  Serial.print(day(t));
  Serial.print(" ");

  Serial.print(hour(t));
  printDigits(minute(t));
  printDigits(second(t));
  Serial.println("");
}



I am using the tab class TIME.H


Thanks!!!!!!!
regards,

Pedro, from Portugal!!!!!

calim

#179
Aug 29, 2013, 03:26 pm Last Edit: Aug 31, 2013, 05:03 pm by calim Reason: 1
Hello,

I'm currently working on a sketch witch will use several (may be 9+) changeable repeated alarms and I'm expecting difficulties with my ram usage (Arduino Nano v3).
As I understand, I can get the alarm id by "AlarmId   myTimer = Alarm.alarmRepeat(15, 00, 00, Repeats); " and delete the alarm by "Alarm.free(id);" if I want to set a new alarm.

Is there also a way to read the current alarm values?

This way I could save the currently used variables for hour and minute of each alarm so I can display them on lcd each time I want to change the alarm time.

Thanks
calim

edit: The timers do not seem to work at all. I checked using serial.print in all funktions of the sketch. I use three "Alarm.timerRepeat(10, Function);" in the setup-section and two "Alarm.timerOnce" in the sketch right now and the functions never start. I used only alarm.delay delays in the sketch. ->???
~~User of the mighty Arduino Nano v3.0~~

Go Up