How to remote set any value (e.g. TimeAlarm)?

I am trying to use the TimeAlarms library to make a schedule to turn things on and off. Here is the example code

#include "TimeAlarms/TimeAlarms.h"

int myTime;
int deviceA = D1;


void setup()
	{
	pinMode(deviceA,OUTPUT};
	digitalWrite(deviceA,LOW);
	Time.zone(-8);
	Time.setFormat("%I:%M%p %d/%m/%Y");
	Alarm.alarmRepeat(myTime, scheduleA);
	} 
 
 void loop()
	{
	  void scheduleA()
		  {
		  Serial.println("print something");
		  digitalWrite(deviceA,LOW);
		  digitalWrite(deviceA,HIGH);
		  delay(15000);
		  
		  if (deviceA == HIGH)
		  {
			  Particle.publish("print something");
		  }
		  else
		  {
			   Particle.publish("print something");
		  }
		}
	}

How do i set “myTime” over the web?

You need to have a web app that can either call a Particle.function (which would set the value of myTime), or publish from the web app, and have your device subscribe to that event, and set myTime in the handler.

I found this code @ScruffR wrote in this post. Can i set values for hh and mm through a webapp. If you can site any examples where this has been done i could learn from that code.

You might look at the “Control LEDs over the 'net” example code in the Particle docs for an example of how to call a function with a web app. Instead of sending “on” or “off” as the arguments to the function, you would need to send something like “10:45”, and parse that in your device code to get the hour and minute values. I can’t offer much more advice, since I’m not a web programmer (I interact with my devices through native iOS apps).

Thank you for your help Ric. I have looked at the LED tutorials and even modified an app in angular for that purpose to call functions. I was looking for an example where this had been done so i could actually copy paste the code and play around with it until i figured out how to use it for my purpose.

In the code you posted above, you have the scheduleA function inside of loop() – it should be moved outside of loop. If you’re going to be setting the firing time for the alarm via a web call of a function, it would be better to setup the alarm in the callback to that function, rather than in setup(). Something like this,

int deviceA = D1;

void setup() {
    pinMode(deviceA,OUTPUT);
    digitalWrite(deviceA,LOW);
    Time.zone(-8);
    Time.setFormat("%I:%M%p %d/%m/%Y");
    Particle.function("setAlarm", setupAlarm);
}

void loop() {

}


int setupAlarm(String cmd) {
    char* stringArgs = strdup(cmd.c_str());
    char* s = strtok(stringArgs, ":");
    int hour = atoi (s);
    int minute = atoi (strtok(NULL, ":"));
    Alarm.alarmRepeat(hour, minute, 0, scheduleA); // use the hour, minute, second version of the repeating timer
    return 1;
}

void scheduleA() {
    Serial.println("print something");
    digitalWrite(deviceA,LOW);
    digitalWrite(deviceA,HIGH);
    delay(15000);
		  
    if (deviceA == HIGH) {
	Particle.publish("print something");
    }else{
	Particle.publish("print something");
    }
}

The code in setupAlarm will parse a string like “10:45” into its two numeric parts and pass them to the alarmRepeat function. So, as long as you can figure out how to send a string like “10:45” via your web app you should be OK. If you’re still having problems with the web part, you should post that code, and someone with web programming experience should be able to help you out.

Thank you very much. I will try this out and let you know how it went. In any case I will post all the relevant code here once it’s working for anyone else out there who would want to do something similar.

One thing you definetly are missing in order to have TimeAlarm work is the regular call to Alarm.delay(); in loop() (as shown in the linked code).

What device is deviceA?
Since the LOW/HIGH transition in your scheduleA() will be rather short, you need a quite speedy device to catch that.

The delay(15000) on the other hand should be avoided in there, rather use Alarm.delay(15000); in loop().

How would “if (deviceA == HIGH)” ever be not true, with the preceeding digitalWrite(deviceA, HIGH);?
(and I guess you actually mean digitalRead(deviceA) since deviceA == D1 == 1 == HIGH will also never change - usually).

I’d not use strdup() as it does dynamic memory allocation (which I try to avoid where possible on embedded devices) but you already know the expected max length of your data, so I’d rather go for

char stringArgs[8];
strncpy(stringArgs, cmd.c_str(), 7);
...
return hour*100 + minute; // give the return value a useful meaning and report back what was set 

To test your code you can always use this
http://suda.github.io/particle-web-interface/

BTW: Looking at the thread title, this seems to be a totally unrelated question.
Could you please open a new thread when duscussing other issues. This also makes it easier and more valuable for users with similar problems and might even save us some time by avoiding to answer similar questions over and over again.

Having said this, I’ll split this question off into a new thread (have done)

2 Likes

Hi @Ali

When you use the TimeAlarms library, you don’t call regular delay if you want the alarm to fire–you have to call Alarm.delay(15000); instead to give the library a chance to figure out if it time for the alarm to fire.

2 Likes

actually i’m using all of this code for the same project that is why i post in that thread.

Thank you everyone for the ideas though. I cant wait to try them all out!!

1 Like

got it!

Here’s another hurdle i have hit with calling variables

int static setHour = 8;
int static setMinute = 0;
void setup() 
    {
        Serial.println("Device Online");
        Time.zone(-8);
        Time.setFormat("%I:%M%p %d/%m/%Y");
        Particle.function("setTime",setTime);
		Particle.variable("getTime",setHour);
		
void loop() {}
int setTime(String cmd) 
    {
        char stringArgs[8];
        strncpy(stringArgs, cmd.c_str(), 7);
        char* s = strtok(stringArgs, ":");
        setHour = atoi (s);
        Serial.println(setHour);
        setMinute = atoi (strtok(NULL, ":"));
        Serial.println(setMinute);
        return (setHour*100 + setMinute);
	}

I’m trying to display the value of setTime through a variable. How can i display the values of 2 ints with a “:” in between.

You can use Serial.printf, or Serial.printlnf for that.

Serial.printlnf("%d:%d", setHour, setMinute);

got it!! thank you sir.

how do i write that in the variable though. What i was thinking on making a separate function

int displaySetTime()
    {
        Serial.printlnf("%d:%d", setHour, setMinute);
    }

and then calling it like this

Particle.variable("getTime",displaySetTime());

that did not work

You’re getting pretty off-topic here, as these are really C questions, not Particle ones. Google sprintf, that’s what you need.

2 Likes

ok! just learning Java. Have not got around to C yet. But i will look it up and try to make sense of it.

I might suggest storing alarm settings in the EEPROM emulator so the setting doesn’t go away even after power cycle or OTA updates. It was handy in certain applications.

Actually this also is Particle specific, as Particle.variable() has to be passed a variable and not a function.

So you can do this

char timeVar[8];

void setup()
{
  Particle.variable("getTime",timeVar);
}

void displaySetTime()
{
  sprintf(timeVar, "%02d:%02d", setHour, setMinute);
  Serial.println(timeVar);
}

But some of these infos have already been presented to you in other threads. So please try to understand and remember them!

Yes I have been looking at example codes with EEPROM storage. I have a total of about 10 variables that need to be stored to EEPROM.