SOLVED: accuracy of imp.wakeup timer; 35% error?


EDIT: upon solving.
99% my own error of having a really noisy signal on pin 1 - just plain messed things up
also needed this line:
imp.enableblinkup(true);

in the current release as a workaround for some timer issue - according to Hugo.

I have a function that sets a new wakeup each 20 seconds. I ran the imp overnight and checked it in the morning - the planner log shows the wakeups occurring each 13 or 14 seconds for an average of 13.35 seconds.

What is the reason for the difference?

`
function setforReading(){

//each 20 seconds, change the interrupt so that
//when a pin is read, the power is calculated at that moment
//Then the function is set back to the normal counter

count = CalculatePower;

imp.wakeup(20.0,setforReading);

}

`

and this code might be pertinent. The function ‘count’ is normally just indexing a counter when the pin is high but each 20 seconds I change the function count to be one that gives me a power reading upon the interrupt before setting it back to a normal counter.

hardware.pin1.configure(DIGITAL_IN_PULLUP,function() {count();});

I am making a watt meter using a chip that puts out pulses at a frequency corresponding to instantaneous power. I have just realized it may not be trivial to get a time base against which to calculate the power.

will hardware.micros() be more accurate and will that be repeatable?

Will I need to perform periodic calibrations of hardware.micros by checking against the time function?

Naturally, i will be trying to figure this out but any help to speed up my tests will be most appreciated.

thanks!

Hardware.millis() appears to be off by 7% if I’m not mistaken.

I ran the program for a while having the value of micros() returned. It shows about 12.5 seconds-worth of micro ticks at the same time as the planner log shows about 13.5 seconds passing. That would be in the neighborhood of 7% under-counting.

Maybe this is a matter of the timers in the imp not being perfectly divisible into real time - and I can deal with that easily.

However there is still the odd matter of 20 second wakeup calls returning in 13.5 seconds. I may also have to test the timers for drift with temperature or create a self-calibration scheme using the web.

I will work with Hugo and let you know.

cool. thank you!

I made a separate copy of my code, simplified it to the basics and pasted it below. It does the same thing. - the return log is below

** One thing I learned - the code did not work at first as the wakeup did not ever seem to fire. on hunch I added the pin setup back into the code and it started working! It seems to require the line that configures pin 1. I can make the code not run by commenting out that line. I do have a signal being applied to pin 1.

`
//Time Checker, mjkuwp94

BatteryVoltage <- OutputPort(“Battery Voltage”,“number”);
Watts <- OutputPort(“Power Watts”,“number”);

imp.configure(“Time Checker”, [], [BatteryVoltage, Watts]);

lasttime<-0;
nowtime<-0;

function ReportTheTime(){

//each 20 seconds, display some time stuff

nowtime = hardware.micros();
server.log(nowtime);

local SecondsDifference = 1.0*(nowtime-lasttime)/1000000;

lasttime=nowtime;

Watts.set(SecondsDifference);

local d = date(time()-(5*60*60)); //puts us into our timezone

//server.log (d.hour);
//server.log (d.min);
server.log (d.sec);

imp.wakeup(20.0,ReportTheTime);

}

function donothing(){

}
//*************************************
//If I omit this single line, the program will not run
//the wakeup appears to not function
hardware.pin1.configure(DIGITAL_IN_PULLUP,donothing);
//

imp.wakeup(3.0,ReportTheTime);

lasttime = hardware.micros();

server.log(":");

`

The server logs are an average of 13.3 seconds apart
the value returned by micros are an average of 12.5 seconds

4/5/2013 12:29:26 PM: Downloading new code
4/5/2013 12:29:26 PM: Device configured to be "Time Checker"
4/5/2013 12:29:26 PM: :
4/5/2013 12:29:28 PM: -742189184
4/5/2013 12:29:28 PM: 28
4/5/2013 12:29:41 PM: -729708501
4/5/2013 12:29:41 PM: 41
4/5/2013 12:29:55 PM: -717231821
4/5/2013 12:29:55 PM: 54
4/5/2013 12:30:08 PM: -704759381
4/5/2013 12:30:08 PM: 8
4/5/2013 12:30:21 PM: -692275013
4/5/2013 12:30:21 PM: 21
4/5/2013 12:30:35 PM: -679801873
4/5/2013 12:30:35 PM: 34
4/5/2013 12:30:48 PM: -667336221
4/5/2013 12:30:48 PM: 48
4/5/2013 12:31:01 PM: -654855838
4/5/2013 12:31:01 PM: 1

Hmm, I don’t see this behavior myself. Have you tried after a power cycle?

Wondering if there’s a bug where using certain peripherals, eg the sampler, is affecting the system time.

Fri Apr 05 2013 11:39:09 GMT-0700 (PDT): Device configured to be "Time Checker"
Fri Apr 05 2013 11:39:09 GMT-0700 (PDT): :
Fri Apr 05 2013 11:39:12 GMT-0700 (PDT): 45759826
Fri Apr 05 2013 11:39:12 GMT-0700 (PDT): 11
Fri Apr 05 2013 11:39:32 GMT-0700 (PDT): 65759823
Fri Apr 05 2013 11:39:32 GMT-0700 (PDT): 31
Fri Apr 05 2013 11:39:52 GMT-0700 (PDT): 85759821
Fri Apr 05 2013 11:39:52 GMT-0700 (PDT): 51
Fri Apr 05 2013 11:40:12 GMT-0700 (PDT): 105759819
Fri Apr 05 2013 11:40:12 GMT-0700 (PDT): 11

Indeed, yours looks really good. It is also counting micros with incredible accuracy rather than 7% low.

i have not tried a power cycle - it has been constantly up since the start. I’ll try that later.

You can do a power cycle remotely inserting a server.sleepfor() then removing it after it’s rebooted :slight_smile:

But yes, if that does fix it then the steps to replicate would be most useful.

ok; I didn’t know that trick. I did that and got the same result. I must have a 2nd imp at home. I’ll try it later. There is no trick for doing that remotely.

4/5/2013 3:09:52 PM: sleeping until 1365192616000
4/5/2013 3:09:52 PM: Power state: online=>asleep
4/5/2013 3:10:20 PM: Power state: asleep=>online
4/5/2013 3:10:20 PM: Downloading new code
4/5/2013 3:10:20 PM: Downloading new code
4/5/2013 3:10:20 PM: Device configured to be "Time Checker2"
4/5/2013 3:10:20 PM: :
4/5/2013 3:11:40 PM: Downloading new code
4/5/2013 3:11:40 PM: Device configured to be "Time Checker2"
4/5/2013 3:11:40 PM: :
4/5/2013 3:11:42 PM: 84249434
4/5/2013 3:11:42 PM: 42
4/5/2013 3:11:56 PM: 96673183
4/5/2013 3:11:56 PM: 55
4/5/2013 3:12:09 PM: 109120907
4/5/2013 3:12:09 PM: 8
4/5/2013 3:12:22 PM: 121561253
4/5/2013 3:12:22 PM: 21
4/5/2013 3:12:36 PM: 133997342
4/5/2013 3:12:36 PM: 35
4/5/2013 3:12:49 PM: 146443926
4/5/2013 3:12:49 PM: 48
4/5/2013 3:13:02 PM: 158884971
4/5/2013 3:13:02 PM: 1
4/5/2013 3:13:16 PM: 171331339
4/5/2013 3:13:16 PM: 15
4/5/2013 3:13:29 PM: 183786061
4/5/2013 3:13:29 PM: 28
4/5/2013 3:13:42 PM: 196225924
4/5/2013 3:13:42 PM: 41

Since you need to measure frequency, have you tried using:

hardware.pin1.configure(PULSE_COUNTER, duration, divider); local count = hardware.pin1.read();

which will return the number of pulses counted during ‘duration’. I suspect this will work a lot nicer than triggering a callback via an interrupt to increment a counter and manually timing the whole operation.

the pulse counter is what I originally planned on… its why my pulses go to pin 1. However, I found that the call is blocking so I cannot do anything in the meanwhile. I need to count power continuously so my only chance was to catch a pulse quickly and do other calculations in the meantime.

The timing problem is occurring even in a simple program (the example pasted above) that has nothing much to do.

I’ll have an update later today with any luck.

ok, think I’ve got it. I disconnected my signal source and turned off power supply, restarted it and ran the simple time reporting code.

Average wakup 21.5 seconds (when called for 20.0)
Average seconds reported each interval (from hardware.micros) = 20.0

so this is probably in spec?

I put my signal back on the pin - feeding the base of a transistor and then noticed my “C1” was missing to filter the incoming signal to the transistor - I forgot/neglected to solder it on.

so… my function generator is possibly/likely passing some high frequency noise into pin 1 through a transistor with a 100k pullup on it. I will try adding the capacitor first and also consider changing the value of the pullup.

I don’t understand how that affects the time counting but it does appear to be near the root cause.

sorry for bothering you with my silly hardware error…

My 7% problem was fixed with imp.enableblinkup(). If you also see 7% error, then I bet it’s your problem too?

Well, I first have to get a filter on my input and while I’m at it I will scope around for other errant signals though there really isn’t much to my device.

I’ll check that out if I come across the 7% thing but for right now it is ok.

@mjkuw94 a 21.5 second wakeup when asked for 20 would be the interrupt issue - the workaround is the imp.enableblinkup(true) as sbright33 says.

If there was high freq noise on a pin configured for interrupts, that would drive a lot of clock state switches which could affect the timer - on the current release, with the aforementioned bug.

thanks All!

It is working now with perfect timing. I found I can run at least 400Hz pulses and catch them continuously on the interrupt for pin 1. There is time for calculating the power out and doing just a couple other minor things.

I also tested the pulsecounter input as sjm had suggested; this was used just to confirm the pulse count and it worked as long as I used the .enableblinkup() line.