AlarmClock with sensor http posting

Hello!

Got my first imp couple of days ago and I must say it’s amazing. Been working with arduino for some years now.

Anyways. I’m trying to create a simple project right now to get started, where the imp should put a LED pin high at a given time and turn off again at another given time (alarmclock-ish). But at the same time I want to read a DHT11 sensor (doing that through arduino now, as I plan to do some OneWire communication later with DS18 temp sensors).

Is there a smart way to get the agent checking the time and send a message to the device when it should light up the LED, and at the same time have the imp posting sensors to the server every 10th second or so, like two wakeup threads?

I realize that it’s possible to check the time in the agent and act on it when I receive sensor data, but it would be nice to do that check in the agent, as I would like to increase the interval of sensor readings in the future :slight_smile:

Thanks in advance, and happy hacking :wink:

You could do this all in the imp, but since you asked, I threw together a contrived example which has the Agent setting the LED on the device. Also since I know how far in advance I want to set the LED, it’s not neccessary to check the time every one second since you could simply do an imp.wakeup() for the future delay time. This code matches your requirements:

Agent Code
`
timeToTrigger <- time() + 5;

function checkTime() {

if( time() >= timeToTrigger ) {
device.send(“setLED”, 1 );
timeToTrigger = time() + 5;
}

imp.wakeup( 1, checkTime ) ;

} checkTime();

device.on(“sensorUpdate”, function(sensor){

server.log("Received sensor data from Imp: " + sensor);

});

`

Device Code
`
sensorData <- 8;

agent.on(“setLED”, function( data ){

server.log("LED Set By Agent " + data );

hardware.pin1.write( data );

});

hardware.pin1.configure(DIGITAL_OUT);

function checkSensors(){

// Some code here to check on the sensors and then
// back to sleep until next time
agent.send(“sensorUpdate”, sensorData );
imp.wakeup(0.1, checkSensors);

}

// Start the checkSensors routine when the Imp starts up
checkSensors();
`

Okay cool thanks alot! So, if I understand it correctly, the 1 second wakeup you make in the agent have nothing to do with the 0.1 second wakeup in the device code? So I could actually define multiple wakeups in my code and they would act like independent events? :slight_smile:

That’s correct. The call to imp.wakeup is not blocking so you can run multiple. The return value is a handle to the specific timer which you could later use to cancel a timer if necessary. Here’s the link to the API doc for imp.wakeup https://electricimp.com/docs/api/imp/wakeup/

Here’s an example of running both your LED and sensor update timers on the device side. The values get passed back to the agent so that you could, for example, query the current values from an HTML app.

Agent Code
`

device.on(“sensorUpdate”, function(sensor){

server.log("Received sensor data from Imp: " + sensor);

});

device.on(“timerAlarm”, function( time ){

server.log("timer Alarm at : " + time );
});

`

Device Code
`
ledStatus <- 0;
timeToTrigger <- time() + 5;
sensorData <- 8;

function checkTime() {

if( time() >= timeToTrigger ) {
agent.send(“timerAlarm”, time() );
timeToTrigger = time() + 5;
// toggle the LED
ledStatus = ledStatus ? 0 : 1;
hardware.pin1.write( ledStatus );
}

imp.wakeup( 1, checkTime ) ;

}

function checkSensors(){

// SOme code here to check on the sensors and then
// back to sleep until next time
agent.send(“sensorUpdate”, sensorData );
imp.wakeup(1, checkSensors);
}

// Configure pin 1 as LED output
hardware.pin1.configure(DIGITAL_OUT);
// Start the checkSensors and checkTime routines when the Imp starts up
checkSensors();
checkTime();

`

Wow! Thanks a lot, wish I could give you some karma points for such comprehensive feedback!

Not that I expect you to answer such nested question, but you mentioned not checking the time every second - I dont suppose that server.sleepuntil() will in this case, so how would you trigger the time at a given timestamp? Say 15:13 e.g? Calculate time() and seconds seems like such an intricate operation. Now I’m storing variables for offMinute, onMinute, offHour and onHour, and comparing them to an updating date variable in the same 1 second check you so kindly provided me :slight_smile:

Like this:

`function checkTime() {

local d = date(time(), "l");

//server.log("agent time: " + d.hour + ":" + d.min + " - configured time: " + LightOnHour + ":" + LightOnMin) 

if(d.hour == LightOnHour.tointeger() && d.min == LightOnMin.tointeger()) {
    
    device.send("led", 1);
    
}

if(d.hour == LightOffHour.tointeger() && d.min == LightOffMin.tointeger()) {
    
    device.send("led", 0);
    
}

imp.wakeup(1, checkTime);

}

checkTime();`

What you have now is okay. Saves having to do the calculation of how many seconds to pass to the wakeup function. Also has the benefit of you not having to worry about the day or year values. Not as efficient as doing the calculation though. With calculation you could only wakeup once, but that’s not a minor…imho… this is easier :slight_smile:
THe sleepuntil function will block and put the imp into deep sleep so if there was other processing required on a different time interval, you would not want to use sleepuntil. When on battery, sleepuntil will be your friend and you will want to devise a strategy for using it.

Yeah, will do that if I ever run my application on batteries :slight_smile: Thanks again!