Any clues on why would the impee disconnect and stay offline?

Hello folks!

I am starting to toy with my imp and so far it has been a great fun. I have noticed, however, that my impee disconnects after awhile ( a variable amount of hours - say 1 to 9) and just stay offline. I was wondering if I did something in the code that might be causing that.
The code is as follows:

`// Variable to represent numbers received
tempDesejada <- 25;
tempLocal <- 25;

local out = OutputPort(“out”,“number”);
local out2 = OutputPort(“TempLocal”,“number”);

// function to measure the temperature of the surroundings

function MeasureTemp()
{
local coded = 0;
local internal_voltage= 0;
local step = 0;
local voltage_read =0;
local sampling_size = 100;

// we need to measure a lot of times for better stability
for (local i=0;i<sampling_size;i+=1)
{
    imp.sleep(1/(sampling_size*2));
    coded += hardware.pin2.read()/sampling_size;

}

internal_voltage = hardware.voltage();
step= internal_voltage/(math.pow(2,16)-1);
voltage_read = (coded*step);
tempLocal = voltage_read*100;

}

// input class for LED control channel
class input extends InputPort
{
name = “LED control”
type = “number”

function set(value)
{
if(value == 0)
{
// 0 = Inhibit LED operation
inhibit = 1;
hardware.pin9.write(0);
hardware.pin7.write(1);

      MeasureTemp();
      out.set(tempLocal);

  }
  else
  {
      // 1 = Enable LED operation
      inhibit = 0;
      
      hardware.pin9.write(1);
      hardware.pin7.write(0);
  }

}
}

class input2 extends InputPort
{
name = “TempDesejada”
type = “number”

function set(value)
{
local tmp = 0;

  tmp = value.tofloat();
  out2.set(tmp);
  tempDesejada = tmp;
  server.show(tempDesejada*10);

}
}

// Register with the server
imp.configure(“Blinker5i2”, [input() input2()], [out out2]);

// Configure pin 9 as an open drain output with internal pull up
hardware.pin9.configure(DIGITAL_OUT_OD_PULLUP);
hardware.pin7.configure(DIGITAL_OUT_OD_PULLUP);
hardware.pin2.configure(ANALOG_IN);

hardware.pin9.write(1);

MeasureTemp();
// End of code.`

The planner looks like the following:

So, I use an external clock to activate periodical temperature measurements, that will be sent to COSM. So far I do nothing with the HTTP input that I receive, other than displaying it.

It would be fantastic if any fo you could give me hints on why is the impee disconnecting. As a second question, is there a way to make the impee keep trying to reconnect until it suceeds?

Thanks a lot!

Best,

Pedro

I’m not particularly fond of the use of imp.sleep; I realize your sleeps are short, but no traffic is processed during the sampling loop.

It would be much better to use imp.wakeup to sample the temperature constantly and keep a moving average at all times, so that when you get the incoming request you can just read the current moving average.

It’s possible that during the period you’re looping that the server is pinging and you are not responding in time, so the server drops the connection to you; currently, client side pings don’t exist and hence with no outbound traffic your imp will never realize it’s been disconnected. This will be fixed at some point, but until then adding a watchdog that generates output regularly will help, eg:

function watchdog() {
imp.wakeup(5*60, “watchdog”);
server.log(“watchdog”);
}

watchdog();

Hey Hugo, thanks a lot for looking at my problem and suggesting the changes. I have changed the imp.sleep to imp.wakeup and implemented a watchdog just like the one you’ve suggested.
So far, so good. Im going to sleep and I"ll post later if it worked. Anyhow, thanks a lot, you are doing a great job, guys.

Well, so far the imp has stayed connected all night. What is interesting is that every 5 min it restarts.

Thursday, November 15, 2012 07:45:17: watchdog Thursday, November 15, 2012 07:48:42: Device booting Thursday, November 15, 2012 07:48:42: Device configured to be "Blinker7c" Thursday, November 15, 2012 07:48:42: watchdog Thursday, November 15, 2012 07:52:06: Device booting Thursday, November 15, 2012 07:52:06: Device configured to be "Blinker7c" Thursday, November 15, 2012 07:52:06: watchdog Thursday, November 15, 2012 07:55:31: Device booting Thursday, November 15, 2012 07:55:31: Device configured to be "Blinker7c"

I wonder what might be causing that… the used code is the following:

// Blink-O-Matic example code with remote control

// Variables to define minimum and maximum time of powering up the AC
minimumOn <- 20;
minimumOff <- 0;

// Variable to represent LED inhibit state
inhibit <- 0;

// Variable to represent number received
tempDesejada <- 25;
tempLocal <- 25;

local out = OutputPort(“out”,“number”);
local out2 = OutputPort(“TempLocal”,“number”);

// function to measure the temperature of the surroundings

function MeasureTemp()
{
local coded = 0;
local internal_voltage= 0;
local step = 0;
local voltage_read =0;
local running_avg_size = 15000;
local time_to_sleep = 0.001;//seconds

// we need to measure a lot of times for better stability

imp.wakeup(time_to_sleep, MeasureTemp);
coded = hardware.pin2.read();
internal_voltage = hardware.voltage();
step= internal_voltage/(math.pow(2,16)-1);

voltage_read = coded*step*100;
tempLocal =((running_avg_size-1)*tempLocal + voltage_read)/running_avg_size;

}

// input class for LED control channel
class input extends InputPort
{
name = “LED control”
type = “number”

function set(value)
{
if(value == 0)
{
// 0 = Inhibit LED operation
inhibit = 1;
out.set(tempLocal);

  }
  else
  {
      // 1 = Enable LED operation    
      if (tempLocal > tempDesejada)
      {
           hardware.pin9.write(1);
      }
      if (tempLocal < tempDesejada -2)
      {
          hardware.pin9.write(0);
      }

  }

}
}

class input2 extends InputPort
{
name = “TempDesejada”
type = “number”

function set(value)
{
local tmp = 0;

  tmp = value.tofloat();
  out2.set(tmp);
  tempDesejada = tmp;
  server.show(tempDesejada*10);
  if (tmp == 99) 
  {
    server.show(tempDesejada+5);
    hardware.pin9.write(1);
  }
   if (tmp == 299) 
  {
    hardware.pin9.write(0);
    server.show(tempDesejada+5);
  }

}
}

function watchdog() {
imp.wakeup(5*60, “watchdog”);
server.log(“watchdog”);
}

// Register with the server
imp.configure(“Blinker7c”, [input() input2()], [out out2]);

// Configure pin 9 as an open drain output with internal pull up
hardware.pin9.configure(DIGITAL_OUT_OD_PULLUP);
hardware.pin7.configure(DIGITAL_OUT_OD_PULLUP);
hardware.pin2.configure(ANALOG_IN);

hardware.pin9.write(0);

MeasureTemp();
watchdog();
// End of code.

What I get from COSM is the following:

https://api.cosm.com/v2/feeds/86156/datastreams/temp.png?width=730&height=250&colour=%23f15a24&duration=1hour&show_axis_labels=true&detailed_grid=true&scale=manual&min=22&max=26&timezone=Brasilia

Any ideas on what might be causing it? Thanks a lot!

Best,

Pedro

I had random power downs - make sure the imp is properly in the socket! I had just pushed it in and it was not properly clipped in.
Probably not the answer to your problem but …

Regards
Peter

The reason it’s rebooting every 5 minutes is this:

function watchdog() {
imp.wakeup(5*60, “watchdog”);
server.log(“watchdog”);
}

…the imp.wakeup should have the function name of the watchdog, ie imp.wakeup(5*60, watchdog) … NOT in quotes! See my original post :slight_smile:

You should be seeing an error in the log for this, but we close the connection too fast after an error and hence you don’t see it. This bug is fixed in release-11.

Really that should be an error at imp.wakeup() time, not when the wakeup fires. Which also means that the errors-in-main bug already fixed in release-11 would not help here.

Peter

On this topic, what can an impee do if it has used imp.sleep() and wants to ensure it’s still connected? In your above example it looked like a periodic server.log() was sufficient, although could still result in odd log events. I seem to have found a more pathological case: the imp running the code below consistently disappears after 548 seconds.

`
local startTime = time(); // this is unix time

while (true)
{
hardware.pin9.write(0);
hardware.pin8.write(1);

imp.sleep(0.15);

hardware.pin9.write(1);
hardware.pin8.write(0);

imp.sleep(0.85);

server.show(format("Uptime: %d s",time()-startTime))

local vBatt = (2.0*3.3/0xFFFF)*hardware.pin1.read();
VbattOut.set(vBatt);

if (vBatt < 3.35)
{
    server.show("Dying battery, goodnight!")
    imp.sleepfor(60*60*24); // sleep for a whole day
}

}`

Now this pushes me to a funny hypothesis: server.log() works, but server.show() doesn’t and neither does updating an output port??

The server periodically sends “ping”-like messages to the imp to check it’s still there: if there are no ping replies for long enough, the server assumes the imp has gone away. Your code contains an infinite loop, the while(true), meaning that it never returns to the event loop, and never receives any server messages. So no pings, so no ping replies, so eventually a disappeared imp. (You’ll also find that the “play” button in our code editor doesn’t work: the “reload your squirrel” message which it sends, would also never be received.)

The way to write long-running periodic things is with imp.wakeup(), not imp.sleep(). That way Squirrel keeps dropping out to the event loop in-between wakeups, and messages will continue to be processed.

http://devwiki.electricimp.com/doku.php?id=basiccodestructure#code_data_flow

Peter

Got it, thanks!

The watchdog worked but I lowered the time to 1 min. Strangely, I have two impee’s but only one have a problem with going off line. Still I added the watchdog to both.