Time Alarm Not Working (With NTP)

Hello everyone,

I'm trying to use the Time Alarm library (TimeAlarms Library, Run Functions At Specific Times), I tryed the library example and it works normaly, but with my skecth (that uses NTP) it just don't trigger the alarm.

if (alarm == false) {
    Alarm.alarmRepeat(19, 35, 0, MorningAlarm);
    alarm = true;
    Serial.println("alarm set");
 }
void MorningAlarm(){
  Serial.println("Alarm: - turn lights off");
  alarm = false;
}

Serial Monitor

Waiting for time sync
19:33:24 12 9 2014
Web Server Initializing
alarm set

Thanks in advance.

Any help, or improvements suggestions are welcome!!

            char *filename = HTTP + 5;
            (strstr(filename, " "))[0] = 0;

Where did you put the NULL if filename doesn't contain a space?

          if (webFile) { // send web page to client
            while(webFile.available()) {
              client.write(webFile.read());
            }
            webFile.close();
          }

This is a pretty poor way to send data to the client. Each client.write() call sends a packet of 512 bytes, containing one byte of payload. Read more than one byte from the file, and send the array of bytes with a client.write() call.

Which Arduino are you using? How much free memory do you have?
http://playground.arduino.cc/Code/AvailableMemory

Whatever else may or may not be wrong your alarms will not work because you have not taken note of this from the TimeAlarms readme and/or the TimeAlarms examples.

Your sketch should call the Alarm.delay() function instead of the Arduino delay() function when
using the Alarms library. The timeliness of triggers depends on sketch delays using this function.

Hi PaulS, thanks for your reply.

Where did you put the NULL if filename doesn't contain a space?

Actually I'm using page names without space, so that space detects the end of the page name.
Pages examples: index.htm, 1andar.htm, 2andar.htm, 3andar.htm...

GET /1Andar.htm HTTP/1.1

I could use the " HTTP" on the end of the header request (example above), from my tests both works, the only difference is if the page as a space the filename will not be read correctely and the page will not open, and acctually I did that on purpose. :stuck_out_tongue:

Read more than one byte from the file, and send the array of bytes with a client.write() call.

About this, can you be more specific on how should I do that?

It should be something like this?

            while(myFile.available())
            {
              clientBuf[clientCount] = myFile.read();
              clientCount++;

              if(clientCount > 63)
              {
                // Serial.println("Packet");
                client.write(clientBuf,64);
                clientCount = 0;
              }
            }
            //final <64 byte cleanup packet
            if(clientCount > 0) client.write(clientBuf,clientCount);            
            // close the file:
            myFile.close();
          }

I'm using a Arduino Uno, it's with 565 kb free memory while using this sketch.

Ohhh, UKHeliBob, thanks very much, I acctually saw that, but my english isn't very good, and I thougth that was some kind of delay only for the alarms. I already changed all the delay's to Alarm.delay's, but the alarm still not triggering...

Do you have anything else in mind?

Actually I'm using page names without space, so that space detects the end of the page name.

Nonsense. Unless you are explicitly setting the array to all spaces before you overwrite part of it, which you can't do using pointers, you haven't a clue where strstr is finding a space.

About this, can you be more specific on how should I do that?

It was a clue to go look at the documentation. Both the read() and the write() methods are well documented.

No, that is not the way to do it. The read() method is overloaded to take an array to write to and a length, and to return the amount of data actually read.

Thanks PaulS, I'm going to study it...

Do you, or anyone else have any clue about the alarms?
Why the alarms set by Time Alarms library don't trigger?

Did I made something wrong? (Other than the Alarm.delay) :cold_sweat:

  if (alarm == false) 
  {
    Alarm.alarmRepeat(19, 35, 0, MorningAlarm);
    alarm = true;
    Serial.println("alarm set");
  }

Do you get the message printed indicating that the alarm is set when you expect it ? I hope it is obvious that an alarm set for a time of 19:35:00 will not be triggered in the morning despite the name of the function.

Sure, if you see my first post:

Serial Monitor

Code:
Waiting for time sync
19:33:24 12 9 2014
Web Server Initializing
alarm set

It was 19:33 so I set it to 19:35 to test...

I made some tests and if I remove all my void loop and change to the library example it works perfectly, so I think there is something in my skecth that conflicts with the alarms.
I don't know if it's a library limitation, or a bug. My programming skills are quite basic, and I can't figure out what, or how to fix it.

If someone could have a look and help me.

Here is the code I'm trying to use:

  Alarm.alarmRepeat(8,30,0, MorningAlarm);
  Alarm.alarmRepeat(17,45,0,EveningAlarm);
  Alarm.alarmRepeat(dowSaturday,8,30,30,WeeklyAlarm);
  Alarm.timerRepeat(15, Repeats);
  Alarm.timerOnce(10, OnceOnly);
  Serial.println(F("Web Server Initializing"));
}
void MorningAlarm(){
  Serial.println("Alarm: - turn lights off");    
}
void EveningAlarm(){
  Serial.println("Alarm: - turn lights on");           
}
void WeeklyAlarm(){
  Serial.println("Alarm: - its Monday Morning");      
}
void ExplicitAlarm(){
  Serial.println("Alarm: - this triggers only at the given date and time");       
}
void Repeats(){
  Serial.println("15 second timer");         
}
void OnceOnly(){
  Serial.println("This timer only triggers once");  
}

Here is the code I'm trying to use:

Which is WAY too complicated to illustrate the problem. Ditch 90% of that crap.

There is no need to read from an SD card to illustrate that there is some issue with TimeAlarm and an NTP time working together. So, get rid of anything dealing with the SD card.

There is no need to diddle with an RF transmitter to illustrate the problem. So, get rid of anything dealing with Livolo.

There is no reason to deal with authenticated users. So, get rid of everything that distinguishes authenticated users from non-authenticated users.

Post the simplest code possible that illustrates the problem. My guess is that in getting rid of a lot of this code, you'll quit running out of memory, and the problem will go away.

I also believe that you need an alarm.delay(0) in your main loop in addition, to ensure that timealarms executes continuously.
Can't remember where I read that though, but I do use it that way and have no problems.

I also believe that you need an alarm.delay(0) in your main loop in addition, to ensure that timealarms executes continuously.
Can't remember where I read that though, but I do use it that way and have no problems.

Thanks very much pinsull, I haven't notice that my main loop haven't any delay, I added a Alarm.delay(0) on the end of it has you suggested and the alarms now is triggering normally!

I'm sorry PaulS, I only posted the full code because I saw a Nick Gammon's post saying that it's better to always post the full code, otherwise people can't see the full picture.

This is a pretty poor way to send data to the client. Each client.write() call sends a packet of 512 bytes, containing one byte of payload. Read more than one byte from the file, and send the array of bytes with a client.write() call.

About this, I understand that each packet has 512 bytes and it's sending just 1 byte from my html file, so the best way is to create a char array with 512 "positions" to read and store each char from my html file and then send it all together?

Thanks very much!

I'm sorry PaulS, I only posted the full code because I saw a Nick Gammon's post saying that it's better to always post the full code, otherwise people can't see the full picture.

The full code THAT ILLUSTRATES THE PROBLEM is needed. But, generally that means AND ONLY THE MINIMUM code to illustrate the problem.

We need to know just WHY the code is failing. As is, there are approximately 14 bazillion possibilities. You need to eliminate a few of them before expecting us to wade through the rest.

About this, I understand that each packet has 512 bytes and it's sending just 1 byte from my html file

Correct. Some of that packet is routing information - where is the packet going, where did it come from, etc. So, the usable payload is much smaller than that.

so the best way is to create a char array with 512 "positions" to read and store each char from my html file and then send it all together?

An array, yes. But 64 elements would be a better size.

Then, use the webFile.read() method that takes an array and size, and returns the number of bytes read. Then, use the client.write() method that takes an array and a size (the number of bytes read, not the size of the array) to populate the packet that is sent with 64 bytes (or less, in the last packet) of data.

Hi PaulS, thanks again.

Then, use the webFile.read() method that takes an array and size, and returns the number of bytes read. Then, use the client.write() method that takes an array and a size (the number of bytes read, not the size of the array) to populate the packet that is sent with 64 bytes (or less, in the last packet) of data.

I think I got what you mean. I didn't try it yet, because I'm working right now, but I think that should be this:

#define HTML_BUF_SZ 64 // buffer size to handle webFile
char HTML [HTML_BUF_SZ] = {0}; // buffer HTML stored as null terminated string

         if (webFile) { // send web page to client
            while (webFile.available()) {
              int bytesRead = webFile.readBytes(HTML, HTML_BUF_SZ);
              client.write((const uint8_t *)HTML, bytesRead);
            }
            webFile.close();

Right?
It seens a nice piece of code, thanks for the help.

Right?

Yes, except that HTML is never NULL terminated (and doesn't need to be), so the comment is wrong.