Program not yielding to new code

I am working on a new prototype and code for my thermocouple temperature monitor, and am having trouble with my running program yielding to building and running new code. It is running fine, but I have to reboot the device to update the code. Here is where the problem seem to be:

function runProgram() { server.disconnect(); probe1(); probe2(); local probetemps = {"probe1temp" : probe1temp , "probe1reftemp" : probe1reftemp, "probe2temp" : probe2temp, "probe2reftemp" : probe2reftemp}; agent.send("Xively", probetemps) imp.wakeup(10, runProgram); }
I have been doing a server.disconnect() before my SPI reads to ensure that I never get any interference, and that seems to work well. The Imp reconnects to log data and send it to Xively. If I remove the server.disconnect statement, it will yield to code updates, but this in place, no yielding. Any suggestions? This seemed to work ok previously.

I have similar when something is wrong in code, no agent but main.

Hmm. This should work ok, as the imp is online for 10 seconds after sending the temp readings. We’ll try to replicate here.

I would personally write it a bit differently, though:

`// always called when disconnected
function runProgram() {
probe1();
probe2();
local probetemps = {“probe1temp” : probe1temp , “probe1reftemp” : probe1reftemp, “probe2temp” : probe2temp, “probe2reftemp” : probe2reftemp};
agent.send(“Xively”, probetemps); // will bing link up

// after readings are sent, disconnect then re-queue wakeup (so imp idles offline)
imp.onidle(function() { server.disconnect(); imp.wakeup(10, runProgram); });

}

imp.onidle(function() { server.disconnect(); runProgram(); });
`

…as this way, it takes less power. It’ll only connect for long enough to send readings and then wait the 10 seconds whilst disconnected (ie in a low power mode).

Thanks! I’ve updated my code, but it still does not yield. If I watch the status of my device in the IDE, it appears to only go online long enough to send to the agent, so the status blips to online and right back to offline.

–Edit I take that back, it is showing various states now. The interesting thing is that while the Imp is still looking for blinkup, and the LEDs are flashing, initially I get a green connection code, but then a lot of alternating amber/red, with some other code that I am unsure of on occasion, but no more green. The Imp however is correctly sending data to the agent. Still no yielding though…

The red blink/amber blink indicates that the imp is disconnected (under program control), but blinkup is enabled.

The green may be so short that you miss it :slight_smile:

Looked a bit further and I can replicate the behavior you see, and will try and work out if it’s something that can be addressed server side. Generally, we see people sleeping the imp between readings, and the equivalent code here works well:

`// Disconnect before we take first reading on cold boot
if (server.isconnected()) {
server.expectonlinein(15);
}

// Take readings
probe1();
probe2();
local probetemps = {“probe1temp” : probe1temp , “probe1reftemp” : probe1reftemp, “probe2temp” : probe2temp, “probe2reftemp” : probe2reftemp};
agent.send(“Xively”, probetemps); // will bing link up

// after readings are sent, disconnect then re-queue wakeup (so imp idles offline)
imp.onidle(function() {
server.expectonlinein(15);
imp.deepsleepfor(10);
});`

…this is much lower power than keeping the imp awake between readings, and you can update the code without a problem (it’ll get picked up on the next wake). Note also the use of expectonlinein() which tells the server when the imp is expected to next come online, and this also does a clean disconnect.

Some more experimentation seems to place this on the server side. If the imp is online for 11 seconds, it’ll get new firmware but not 10 seconds. Think there’s a timer there somewhere :slight_smile:

Ahh. That explains why I just noticed it. Normally I have a 30 sec interval between reading my probes, but I had dropped it to 10 while testing some code changes. I’ll bump it up. Thanks for looking.

I implemented that code… it will be interesting to see what kind of battery life I get now. That project also has a constantly on LCD, which will be the main power drain. I need to implement a sleep timer for the LCD, but ultimately this project would be awesome with an epaper display. I am currently using a 2500mAh LiPo, but I could likely drop that significantly using epaper. I’ve got some Vanessas on order for testing.

I am now implementing this in my model:

`
//Initialize NON WAKEREASON_TIMER hardware settings
function initializeHardware() {
screen.set_contrast(200); //set LCD screen contrast
screen.clear_screen(); //clear LCD screen
}
//Disconnect before taking the first reading on cold boot - implicit server.disconnect()
if (server.isconnected()) {
server.expectonlinein(25);
}

screen <- Screen(port0); //instantiate a screen object

//Check WAKEREASON
if (hardware.wakereason() != WAKEREASON_TIMER) {
initializeHardware();
}

hardware.pin8.write(1); //set chip select pin high
hardware.pin2.write(1); //set chip select pin high

//Take first temperature readings
probe1();
probe2();
local probetemps = {“probe1temp” : probe1temp , “probe1reftemp” : probe1reftemp, “probe2temp” : probe2temp, “probe2reftemp” : probe2reftemp};
agent.send(“Xively”, probetemps)
server.log(“test”);
imp.onidle(function() {
server.expectonlinein(25);
imp.deepsleepfor(20);
})
`
And I get this on a cold boot log:

2014-01-01 12:10:41 UTC-5: [Status] Device booting; 14.04% program storage used
2014-01-01 12:10:41 UTC-5: [Device] ERROR: sleeping in main program not recommended, see imp.onidle
2014-01-01 12:10:41 UTC-5: [] sleeping until 1388596266000
2014-01-01 12:10:43 UTC-5: [Device] test
2014-01-01 12:10:43 UTC-5: [] sleeping until 1388596268000

Where is the first sleep coming from? No sleep() is called from server.expectonlinein(), right?

Ah, that message is sort-of right, but badly worded (we’re working on making error messages a bit more conformal). What it’s saying is that disconnecting from the server without waiting for idle is a bad thing, because the server might have data to send you that you’re not getting to see.

The problem here is that it’d make your flow a lot more complex. What I might do instead is make it take no readings the first time through, ie do:

if (!server.isconnected()) { probe1(); probe2(); local ... agent.send ... }

…so that on boot it takes no readings, it just sleeps. Then, when it wakes it does so without wifi on, takes a reading, connects & sends then sleeps again.

I’m ok with the error message… I understand that part… but then there is a sleep message that I am confused about. The first sleep shouldn’t get called until after I log “test”, right?

The misleading bit of the “sleeping until X” message is that it says “sleeping” when it really means “disconnected”. When that message was first introduced, the only way to disconnect was to sleep :slight_smile:

As the comment notes, the server.expectonlinein does an implicit disconnect, with the suggestion that it’ll be back (in your case) 25 seconds later. Then the server.log(“test”) brings the connection straight back up again (long before 25 seconds is up), then the onidle handler runs and a second server.expectonlinein runs, again for 25 seconds in the future. The difference between the two times in the “sleeping until” is about how long it took to re-establish the connection: 2000ms or two seconds, a time consistent with the timestamps of the messages.

Peter

Ahhh… got it. Thanks Peter. I think I finally have my brain remembering that I can’t just go tossing server.log statements in places where I want to be disconnected.