2

I have this if statement:

if (now.hour() == 5 && now.minute() == 10 && now.second() == 0 && now.dayOfTheWeek() != 1 && now.dayOfTheWeek() != 7){

Is there a way to condense that for the purposes of saving on some bytes?

Ultimately trying to say "At 5:10 every weekday do X"

  • If this is using too much space then it's not the condition responsible, it's now. – Ignacio Vazquez-Abrams May 21 '16 at 1:31
  • Well, I was fine (just barely under) until I added the && now.dayOfTheWeek() != 1 && now.dayOfTheWeek() != 7. – Shpigford May 21 '16 at 1:33
  • In most libraries now.dayOfTheWeek() will actually calculate the day of the week, where at the other functions just load their value straight from the RTC chip. Calculating the day of the week is quite a bit of work. That would explain the jump in code size. The weird thing is that the RTC chip will actually keep track of the day of the week. – Gerben May 21 '16 at 9:32
2

The following saves a couple of program bytes (but no RAM) when now is a structure with a byte called DayofWeek:

 if ((byte)(now.DayofWeek+249)>250) ...
   -vs-
 if ((now.DayofWeek != 1 && now.DayofWeek != 7)) ...

It might save slightly more than that in your case, where now.dayOfTheWeek() appears to be a function reference. This technique will work if function now.dayOfTheWeek() returns a byte, that is, an unsigned char. The technique depends on value 7+249 overflowing to zero in byte arithmetic when truncated to a byte, because 7+249 is 0 modulo 256.

The cast to byte [or uint8_t] of now.DayofWeek+249 is needed because of int promotion as Edgar Bonet pointed out.

  • This does not work. You have to cast the sum to uint8_t. Otherwise, per the rules of integral promotion, everything in the expression is evaluated as 16-bit signed ints. – Edgar Bonet May 21 '16 at 11:56
  • @EdgarBonet, it does work. Specifically, it gives correct results for now.DayofWeek values from 1 to 7. Note, now.DayofWeek is declared as a byte (which is equivalent to uint8_t except for being easier to pronounce) so byte, not int, arithmetic is used. – James Waldby - jwpat7 May 21 '16 at 23:31
  • No, it doesn't, and you obviously did not try. If DayofWeek is 7, then DayofWeek+249 is 256, and since 256>250, the test succeeds, while it shouldn't. Note: there is no such thing as “byte arithmetic” in C: the operation is done on ints. C.f. for example this CERT article on integer conversion rules and, more specifically, the section titled “Integer Promotions”. – Edgar Bonet May 22 '16 at 7:38
  • @EdgarBonet, unfortunately my test printed out the result of assigning now.DayofWeek+249 to a byte – hence the value I expected – rather than the result of the comparison :( , See edit – James Waldby - jwpat7 May 22 '16 at 16:21
1

Yes. The method now() Returns the current time as seconds since Jan 1 1970. Simply keep tract of all your time this way and you only need to test this one value.

The Arduino is not a good source of time over long periods. Consider using an RTC (Real Time Clock) chip. This Arduino page links to this page which talks about an RTC. (I will leave it up to you to research any compatibility issues.)

Many RTCs contain a register set specifically designed to handle tasks such as you outlined above. For example, setting alarms off on weekdays only or on specific days of the month.

If absolute time is not important in your application I would try the following code outline. Each test only has 2 operands:

// Turn on Arduino on Monday at the time task is to be performed.  Task
// should be performed at that time on Monday, Tuesday, ... Friday.
// Nothing should happen on Saturday & Sunday.  Then cycle repeats.

// Set time to zero.

// Count through days (0, 1, 2, ...).

// Wait each day until number-of-seconds is greater then seconds-in-a-day
// times the day number.

// If day number is 4 or less do activity.  Else skip activity.

// If day number is more than 6 set the day counter to 0 and set the time
// to zero.

If you want to start the Arduino at arbitrary times, set the initial Arduino clock value to the number of seconds from the time the activity would have been performed on Monday and initialize the day counter to the appropriate value. For example if you started the Arduino on Tuesday 23 hours after the time the activity should have happened on Monday set the Arduino clock to 23 * 60 * 60 seconds and initialize the day counter to 2. Of course you can calculate the initial day counter value using = initial_number_of_seconds / 60 * 60 * 24.

  • I'm trying to get it to be true at a specific time every weekday, so I'm not sure how what you've said applies here. – Shpigford May 21 '16 at 1:36
  • Answer has been changed. Consider an RTC. Most RTCs contain a hardware solution for your situation. If Arduino time drift is tolerable, use the code outline which only uses seconds in a week to drive events. – st2000 May 21 '16 at 14:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.