Go Down

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

PaulS

Code: [Select]
byte readEEPROM(int addr, unsigned int eeaddress)                //EEPROM read function
  {
  Wire.beginTransmission(addr);
  Wire.write((int)(eeaddress >> 8));
  Wire.write((int)(eeaddress & 0xFF));
  Wire.endTransmission();
  Wire.requestFrom(addr, 1);
  Wire.read();
  }

A function that is designed to return a byte, but that doesn't have a return statement is pretty useless.

byte readEEPROM(int addr, unsigned int eeaddress)                //EEPROM read function
  {
  Wire.beginTransmission(addr);
  Wire.write((int)(eeaddress >> 8));
  Wire.write((int)(eeaddress & 0xFF));
  Wire.endTransmission();
  Wire.requestFrom(addr, 1);
  return Wire.read();
  }

You need to actually return the value read.

3 of your if blocks involve flag being true. One involves flag being false. It would be better to have
Code: [Select]
if(flag)
{
   // Pick which case, based on time...
}
else
{
   // Deal with the one false case
}
The art of getting good answers lies in asking good questions.

Bob808

Yes, you are right.
Is this way better?
Is it bad if I insert that into loop?

Code: [Select]
if(on<off){
                 if(flag)
                {
                    if(time>on && time <off)                                        
                       {  LightsOn(); }
                   else if(time>on && time>off)                      
                       {writeEEPROM(addr,4,0);}
                   else if(time<on && time<off)
                     {writeEEPROM(addr,4,0);}
                }
                else
                {
                  if(time>on && time<off)
                       {LightsOn();
                        writeEEPROM(addr,4,1);}
                }
}

if(on>off){
                 if(flag)
                 {
                     if(time>on && time>off)
                     {LightsOn();}                    
             else if(time<on && time<off)
                     {LightsOn();}
             else if(time<on && time> off)
                     {writeEEPROM(addr,4,0);}
                 }
           else
               {
                if(time>on && time>off)
                     {LightsOn();
                     writeEEPROM(addr,4,1);}
               }
}


Also the read function now has return on the byte
Code: [Select]
byte readEEPROM(int addr, unsigned int eeaddress)                //EEPROM read function
 {
 Wire.beginTransmission(addr);
 Wire.write((int)(eeaddress >> 8));
 Wire.write((int)(eeaddress & 0xFF));
 Wire.endTransmission();
 Wire.requestFrom(addr, 1);
 return Wire.read();
 }

Vaclav

I hope these remarks will be taken in spirit intended. Suggestions as posted in the original title.
First of all - it is plain crazy to build on thread of this length and age, Why?
I did not follow the last discussion post by post , but from my recent exposure to time ( lower case) related issues I would suggest always use "long"  for  time variables,  using "int" can and will create bugs.
Library Time puts most of the variables in "long"  anyway.
I think, personal opinion, using variable names "on" and "off"  for anything but byte is very poor choice.
I am not total fan of Hungarian notation(s) and lousy typist to boot, but few more characters in descriptive name  is better in long run.
After all, C will take up to 32 characters ( at lest it used to) and the  variable names don't take memory.
Cheers
Vaclav

PaulS

You are turning the lights on if the time is right, regardless of the value of flag.

You are writing a value to EEPROM that depends on the value in flag, regardless of what time it is.

Trying to combine the two actions in one set of if statements is crazy.
The art of getting good answers lies in asking good questions.

Bob808

#319
Sep 19, 2014, 10:26 pm Last Edit: Sep 19, 2014, 10:29 pm by Bob808 Reason: 1
Quote
I hope these remarks will be taken in spirit intended. Suggestions as posted in the original title.
First of all - it is plain crazy to build on thread of this length and age, Why?
I did not follow the last discussion post by post , but from my recent exposure to time ( lower case) related issues I would suggest always use "long"  for  time variables,  using "int" can and will create bugs.
Library Time puts most of the variables in "long"  anyway.
I think, personal opinion, using variable names "on" and "off"  for anything but byte is very poor choice.
I am not total fan of Hungarian notation(s) and lousy typist to boot, but few more characters in descriptive name  is better in long run.
After all, C will take up to 32 characters ( at lest it used to) and the  variable names don't take memory.
Cheers
Vaclav


I guess this is my 3rd of 4th arduino project, and certainly my most complex one. I really don't know how things are usually done in programming, I'm just getting my feet wet.
Also, the whole thing started as this was the place I found to be related to my earlier problems with timealarms library.

Code: [Select]
 
  onH= readEEPROM(addr,0);            
  onM= readEEPROM(addr,1);              
  offH= readEEPROM(addr,2);    
   offM= readEEPROM(addr,3);
   flag= readEEPROM(addr,4);

long  time = hour()*10000UL + minute()*100+second();
long on = onH*10000UL + onM*100;
long off = offH*10000UL + offM*100;


Quote
You are turning the lights on if the time is right, regardless of the value of flag.


Code: [Select]
if (time == on)
{
if(!flag)
 {
LightsOn();
flag=true;
writeEEPROM(addr,4,1);
 }
}

The lights go on only if the time is right and flag is 0. Same, the lights go off at a certain hour if time is right and flag is 1. If the flag is 1, the lights won't come on. Right?

PaulS

Quote
The lights go on only if the time is right and flag is 0. Same, the lights go off at a certain hour if time is right and flag is 1. If the flag is 1, the lights won't come on. Right?

flag is a boolean. It is true or false, not 0 or 1.
The art of getting good answers lies in asking good questions.

Bob808

Yes I know that, it's quicker to type, I guess you get the idea. In program indeed it's better to write true or false always.

joe4444

Hi again

Please could someone help me with just setting an alarm for a specific date and time.

I did ask this question a few weeks ago and thanks Pauls for the clock tip ..I did manage to trigger an event with the time library and the DS1307 library.
however I would like to use the timealarms library because it seems perfect for what I would like to do.
It seems like what Bob808 is chatting about and getting help with is similar to what I would like to achive with one exception and that's setting the trigger times for HMS (hour minute second) and DMY(day month year)

The timealarms library works great for HMS but how do you set an alarm for a specific date ?

At the moment I am just trying to get a few lights switching on and off at specific dates and times for example 2014/9/25 @ 01:38 AM.
Does a basic example for this specific request above exist ?

I would like to be able to :
1. Set a given device (assuming I assign each infrared light a device ID) for on and off at a specific time.
(this done by perhaps applying an alarm ID to match the device ID when the alarm is created.
2.Be able to delete/disable/reset and alarm once set.
(this would be grabbed from a list or possibly from EEPROM if stored there)
3. If the list of alarms is stored in EEPROM (assuming this is possible for multiple alarms, ow many can be stored in the arduino EEPROM.
Please forgive any coding issues or misconceptions as I am fairly new to Arduino's and was used to programming PIC's in basic as a hobbyist.
I have been reading through snippets of code and these forums and googling for weeks now and don't seem to be making much headway with this.

I hope some kind soul can help or guide me as I really would like to build on my successes with the Arduino and also be able to give back to the forum somehow.
I am sure that if I could get a basic example I would be able to make some headway albeit fumbling around in the dark.

Regards
joe444

UKHeliBob

Quote
At the moment I am just trying to get a few lights switching on and off at specific dates and times for example 2014/9/25 @ 01:38 AM.
Does a basic example for this specific request above exist ?

From the TimeAlarms readme
Quote
If you want to trigger once at a specified date and time you can use the trigger Once() method:
  Alarm. triggerOnce(time_t value,  explicitAlarm); // value specifies a date and time
(See the makeTime() method in the Time library to convert dates and times into time_t)




Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

joe4444

Hi all

Thanks UKHeliBob

This is exactly where I am battling
Quote
See the makeTime() method in the Time library to convert dates and times into time_t

I keep reading over the time library info and trying to find a clear simple example of create the time_t from the method mentioned.
I have have been reading over the the code in the forums for days now since my last posting :-(

Quote
void localTime(time_t *timep,byte *psec,byte *pmin,byte *phour,byte *pday,byte *pwday,byte *pmonth,byte *pyear);
    extracts time components from time_t. Note that year here is the desired year minus 1900
time_t sTime makeTime(byte sec, byte min, byte hour, byte day, byte month, int year );
    returns time_t from time components, note that year here is full four digit year.


My question/confusion so far:
1.How do I correctly initially set/assign the variables in order to  return the time_t from the time components?
In my code if I want to create a startTime is it a case of assigning each variable a value like this :
Code: [Select]
byte sec = 33;
byte min = 20;
byte hour = 13;
byte day = 26;
byte month = 09;
int year = 2014 

then
Code: [Select]
time_t makeTime(byte sec, byte min, byte hour, byte day, byte month, int year );

OR is it like this

Code: [Select]
tmElements_t stm;
  stm.Year = 2014 - 1970; 
  stm.Month = 09;
  stm.Day = 26;
  stm.Hour = 02;
  stm.Minute = 01;
  stm.Second = 00;
  Alarm.triggerOnce(makeTime(stm), OnceOnly) ;


Please excuse NOOB confusion.

I really am battling to make light of this and a little guidance please.

As always I look forward to any replies..

Regards
Joe

joe4444

#325
Sep 26, 2014, 03:28 am Last Edit: Sep 26, 2014, 03:39 am by joe4444 Reason: 1
YAY
I decided to bash around a bit more and ...
It looks like it's working :-)
Would still love some answers if possible on the last post though ;-)

Here's the code for anyone battling to create a ONCE-OFF alarm in other words with a specific date and time to start and a specific end time.
The most difficult hurdle for me was just to see how the time_t object is created and excatly where it slots in, and that took me two weeks of searching after my initial post here.
So I really do hope this helps some people.

I now have a few more questions:

1.
I would like to assign a start and end time to each device using its deviceID.
What would be the correct(or a nice)  way to assign both an start and end time to each single deviceID.
For example if I enter 465 into the serial monitor as the device ID and then run through collecting the start and end times for the device.
Since I am creating two time_t  object stm (start time) and etm (end time) , I was wondering how to have the device ID attach to each time_t object.
Some form of concatenation perhaps or is there a better/different method ?
I think something like stm465 and etm465 would be awesome ... ?
Any tips or comments please?

2.
How does once store the alarm ID's so yo can reference them later. (I remember seeing a post answered by PaulS somewhere in the last few days/weeks about this very same question but for the life of me I can't remember the topic to search on.

3.
If each alarm is stored in the Arduino UNO eeprom, how many alarms could be created and what byte size is taken up by each alarm ?

4.
From what I have been reading through the posts, is it correct to summize that each is destroyed after triggering ?

5.
Could or would somebody suggest some re-useable routine/code or steps to create a start and end alarm for each deviceID ?

Thanks a million for this library and to those people who have replied to my posts , I definitely found every single reply useful.

Kind regards

Joe

Code: [Select]
#include <Time.h>
#include <TimeAlarms.h>

void setup()
{
 Serial.begin(9600);
 setTime(2,38,30,26,9,14); // set time to Saturday 2:38:30am September 26 2014

tmElements_t stm; // start time values go here
 stm.Year = 2014 -1970;
 stm.Month = 9;
 stm.Day = 26;
 stm.Hour = 2;
 stm.Minute = 39;
 stm.Second = 0;
 Alarm.triggerOnce(makeTime(stm), OnceOnly) ;

tmElements_t etm; // end time values go here
 etm.Year = 2014 -1970;
 etm.Month = 9;
 etm.Day = 26;
 etm.Hour = 2;
 etm.Minute = 39;
 etm.Second = 30;
 Alarm.triggerOnce(makeTime(etm), OnceOnly) ;

}

void  loop(){  
 digitalClockDisplay();
 Alarm.delay(1000); // wait one second between clock display
}

// functions to be called when an alarm triggers:

void OnceOnly(){
 Serial.println("This timer only triggers once");  
}

void digitalClockDisplay()
{
 // digital clock display of the time
 Serial.print(hour());
 printDigits(minute());
 printDigits(second());
 Serial.println();
}

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



PaulS

Quote
1.
I would like to assign a start and end time to each device using its deviceID.
What would be the correct(or a nice)  way to assign both an start and end time to each single deviceID.
For example if I enter 465 into the serial monitor as the device ID and then run through collecting the start and end times for the device.

What device(s) are you referring to? The TimeAlarms class creates objects that are meant to model real alarm clocks. The ID of an alarm is assigned by the TimeAlarms class, not by you.

Quote
Since I am creating two time_t  object stm (start time) and etm (end time) , I was wondering how to have the device ID attach to each time_t object.

This question does not make sense without knowing what device(s) you are talking about.

Quote
2.
How does once store the alarm ID's so yo can reference them later. (I remember seeing a post answered by PaulS somewhere in the last few days/weeks about this very same question but for the life of me I can't remember the topic to search on.

In a variable (or array) of the proper type. Look at the TimeAlarms class to see what that type is.

Quote
3.
If each alarm is stored in the Arduino UNO eeprom, how many alarms could be created and what byte size is taken up by each alarm ?

They are not. You can experiment to determine how much your code size changes when you allow for more than the pre-defined number of alarms.

Quote
4.
From what I have been reading through the posts, is it correct to summize that each is destroyed after triggering ?

I don't think so. The source code is the definitive answer, though.

Quote
5.
Could or would somebody suggest some re-useable routine/code or steps to create a start and end alarm for each deviceID ?

Not until you explain what you mean by device ID.
The art of getting good answers lies in asking good questions.

joe4444

#327
Sep 26, 2014, 08:15 pm Last Edit: Sep 26, 2014, 11:51 pm by joe4444 Reason: 1
Hi all

@PaulS thanks a million for the reply

With regard to this question 3 in my earlier post concerning the EEPROM:
Quote
If each alarm is stored in the Arduino UNO eeprom, how many alarms could be created and what byte size is taken up by each alarm ?
.
I see the possible confusion there ..let me clear that up
I realize that each alarm is not strored in the EEPROM of the Arduino UNO , is it possible that they may be stored there ?
And thank you for the tip ....I will check how many bytes the code increases by after compiling with the addition of each new alarm. I just thought someone (like the creator of the library) might already know this.

Oh I see the possible confusion in terms of DEVICE ID as well .
DEVICE ID is a number attached to a light. So for example , light number 465 becomes DEVICE ID 465 and in code I guess would be
Code: [Select]
int DEVID
So if one wanted DEVID 465 to be on @ a fixed date and time
you could key in (via serial maybe) the DEVID (in this case 465) and then you could set the start time and end times and the necessary alarms(Start and End) would be created and eventually triggered.
Basically I would like to attach a single DEVID to a start and end time.
For example:
DEVID 465
start @ date/time
end @ date/time
DEVID 466
start@ date/time
end@ date/time
etc..

So to clear up the question,

How do I go about matching the DEVID to the alarmID or maybe assigning the DEVID as the alarmID ? OR get this to work.

As always any help and tips are hugely appreciated

Regards

Joe4444


UKHeliBob

Quote
I will check how many bytes the code increases by after compiling with the addition of each new alarm. I just thought someone (like the creator of the library) might already know this.

From the TimeAlarms readme
Quote
Q: How many alarms can be created?
A: Up to six alarms can be scheduled. 
The number of alarms can be changed in the TimeAlarms header file (set by the constant dtNBR_ALARMS,
note that the RAM used equals dtNBR_ALARMS  * 11)
Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

joe4444

@ UKHeliBob

Thanks for the valuable tip.
I did see that in the readme and other several other posts and it seems many overlook it and I believe the max is 255 :-)

Kind regards
Joe4444

Go Up