IMP clock going crazy - bug or timer issue?

If I create a “fast” timer based on functioncallback (wanted to detect some zerocross) - 0.02sec - the IMP’s timer goes wild (starting to go faster). Can be reproduced with the april too - used a sparkfun one after I noticed the issue with my prototypes. It’s not permitted to use callbacks with periods <1sec?

The code to reproduce it:
// Clock test

imp.configure(“Clock tester”,[],[]);
server.log("=======>Clock tester starting …");
server.log(“IMPId:”+hardware.getimpeeid());

imp_sel1 <- hardware.pin1;
imp_sel1.configure(DIGITAL_OUT);
imp_sel2 <- hardware.pin8;
imp_sel2.configure(DIGITAL_OUT);

imp_sel1.write(1);imp_sel2.write(1);//backup
//imp_sel1.write(0);imp_sel2.write(0);//no backup

function upsZeroCrossChecker()
{
imp.wakeup(0.02, upsZeroCrossChecker);
}

function main()
{
imp.wakeup(5, main);
server.log(format(“MAIN mem=%d sec=%d”,imp.getmemoryfree(),clock()));
}
main();
upsZeroCrossChecker();

The result with and without the imp.wakeup(0.02, upsZeroCrossChecker); line is below. It can be clearly seen that the IMP counts 5 second in both cases but in the log in one case is coming in every 3 (sometimes 4) second and in the second case comes in every 5-6 second as it should. The result is the same with blinking a led but this version is easier to check for You guys. It’s understandable if that 3 second pops up rare because of net congestion but than it should be followed by longer times but it doesn’t - the 5 second becomes shorter for the imp if the 0.02sec timer is running …

With upsZeroCrossChecker
Tuesday, January 08, 2013 13:06:21: MAIN mem=61956 sec=439
Tuesday, January 08, 2013 13:06:24: MAIN mem=61956 sec=444
Tuesday, January 08, 2013 13:06:27: MAIN mem=61956 sec=449
Tuesday, January 08, 2013 13:06:30: MAIN mem=61956 sec=454
Tuesday, January 08, 2013 13:06:33: MAIN mem=61956 sec=459
Tuesday, January 08, 2013 13:06:36: MAIN mem=61956 sec=464
Tuesday, January 08, 2013 13:06:39: MAIN mem=61956 sec=469
Tuesday, January 08, 2013 13:06:42: MAIN mem=61956 sec=474
Tuesday, January 08, 2013 13:06:45: MAIN mem=61956 sec=479
Tuesday, January 08, 2013 13:06:48: MAIN mem=61956 sec=484
Tuesday, January 08, 2013 13:06:51: MAIN mem=61956 sec=489
Tuesday, January 08, 2013 13:06:54: MAIN mem=61956 sec=494
Tuesday, January 08, 2013 13:06:57: MAIN mem=61956 sec=499
Tuesday, January 08, 2013 13:07:00: MAIN mem=61956 sec=504

Without upsZeroCrossChecker
Tuesday, January 08, 2013 13:07:52: MAIN mem=62088 sec=567
Tuesday, January 08, 2013 13:07:58: MAIN mem=62088 sec=572
Tuesday, January 08, 2013 13:08:03: MAIN mem=62088 sec=577
Tuesday, January 08, 2013 13:08:09: MAIN mem=62088 sec=582
Tuesday, January 08, 2013 13:08:14: MAIN mem=62084 sec=587
Tuesday, January 08, 2013 13:08:19: MAIN mem=62088 sec=592
Tuesday, January 08, 2013 13:08:24: MAIN mem=62088 sec=597
Tuesday, January 08, 2013 13:08:30: MAIN mem=62088 sec=602
Tuesday, January 08, 2013 13:08:35: MAIN mem=62088 sec=607
Tuesday, January 08, 2013 13:08:40: MAIN mem=62088 sec=612
Tuesday, January 08, 2013 13:08:46: MAIN mem=62088 sec=617
Tuesday, January 08, 2013 13:08:51: MAIN mem=62088 sec=622
Tuesday, January 08, 2013 13:08:56: MAIN mem=62088 sec=627
Tuesday, January 08, 2013 13:09:02: MAIN mem=62088 sec=632
Tuesday, January 08, 2013 13:09:07: MAIN mem=62088 sec=637
Tuesday, January 08, 2013 13:09:12: MAIN mem=62088 sec=642
Tuesday, January 08, 2013 13:09:18: MAIN mem=62088 sec=647
Tuesday, January 08, 2013 13:09:23: MAIN mem=62088 sec=652
Tuesday, January 08, 2013 13:09:28: MAIN mem=62088 sec=657

This is true, but is surprisingly awkward to fix in the short term :(. One workaround is imp.enableblinkup(true), which keeps the flashing green light going after the 60s in which it would normally stop – but, as a side-effect, suppresses the “CPU underclocking on idle” which is causing centisecond time to drift. (It also suppresses the power-consumption benefits of “CPU underclocking on idle”, but if you’re interested in zero-crossing then I’m guessing your imp is mains-powered, not battery-powered, and thus you aren’t counting every millijoule?)

Peter

Oops, it looks like imp.enableblinkup() wasn’t on the devwiki – that’d be my fault, sorry. I’ve just added it.

Peter

This device has “dual” power - where I use zero cross it’s main powered, when the zero cross disappears I should change to low power mode, keep the IMP running on a small battery to not loose the clock and do some really low power stuff, keeping the rest of the equipment powered off. And in this mode every milijoule matters (the blinking led too so the enableblinkup is not as good as I would like it)…

I need the clock since the device has to do things periodically so this clock shitfing is close to be a showstopper … Will it be fixed in a month or two? I think it’s not good to have a bad clock which shifts so much (losing 2 seconds from 5 it is much) so I really hope it will be fixed …

One more thing: in my case it’s not underclock - it’s rather overclock - imp’s time is faster than the real time. Just to be more clear :slight_smile:

The effect of your 0.02s repeating timer is to repeatedly switch between “CPU fast” and “CPU slow”, and it’s the switching that makes the centisecond timer drift.

So what you do is, in “low-power mode”, you stop the 0.02s repeating timer, and time doesn’t drift, so you can imp.enableblinkup(false).

When you go back into “high-power mode” and enable the 0.02s repeating timer, also do imp.enableblinkup(true).

Peter

Strange enough I don’t have this timer drift in high power without the enableblinkup either but only on one of the prototypes (the rest is drifting, april too). The cause probably is that I have there both zero cross callback and this 0.01s/50Hz callback + the 0.02s timer keeps the IMP in CPU fast all the time …

but I’ll just use enableblinkup to be sure - tx for the solution and for long term hoping for a solution which does not need that led :slight_smile: