You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Several users have asked for time reporting that's more precise than the millisecond ticks provided by time.monotonic(). Use cases and proposals welcome here.
I was attempting to work with a 433Mhz radio transmitter which required writing to a pin at 200 microsecond intervals. Even if a function similar to the Arduino micros() had less than 1 microsecond resolution this would allow time calculations that are not possible with the time.monotonic() function.
@CameronDevine Interesting! How much data do you know you need to write ahead of time? Something like PulseOut might be adequate. It looks like it requires a carrier PWM signal though it could just be constant.
I too would like to see something better than monotonic, since it's not stable and loses precision as time goes on. Or maybe I just need to learn the CircuitPython way to do longer term ramping up/down of a NeoPixel, while not doing a busy wait, so I can handle other inputs that come in.
Right now I just try to do:
timetofire = timer.Monotonic() + delay
while True:
now= timer.Monotonic()
if (now > timetofire):
timetofire = now + delay
# do NeoPixel incremental update here
continue on looking for keyboard input, etc.
Does this make sense? I also wish it was more clearly documented what resolution monotonic is counting in, since it's not quite seconds, but maybe milliseconds?
I'm still unsure we want to provide precise timing because we pause the VM from time to time to do other things. I'm worried about making timing promises we don't always keep. If we did, I think we could introduce a precisetime module for it.
@l8gravely also follow #619 for a different way to do things concurrently.
Would it be possible to have a variable which states the approximate interval at which time.monotonic() is increased? This would save people form having to write code to guess what the interval is, since it appears to change based on which board is being used.
like @l8gravely I want a monotonic time source which doesn't lose precision. In my project, I want to show the seconds and fractions of seconds based on NTP time, but it starts to lose precision as the monotonic() value gets large.
For me, directly exposing common_hal_time_monotonic(), possibly via the microcontroller module, seems like a good first step. I'm not sure whether exposing it as a 64-bit value (restricting it to devices with support for longs) is better, or exposing it as unix-style (seconds,microseconds} is better. The latter is sure less convenient for doing math on, and forces the choice of a fractional second size of microseconds or coarser (rather than nanoseconds or 2^-32s) in order to avoid overflows while doing arithmetic (+, -) on timestamps with limited integer precision available.
I'm trying to sample a 1kHz modulated light beam at 100µs intervals. About every 1/32 sec I go into a coma for almost 1/32 sec while the system does its other things. More precise timing would not help unless we also had a "suspend the other system things for a mo while I do this time-critical thing" function...
As time.monotonic() becomes less precise over time I support having a precise_time module with a custom timer with millisecond precision. It would be very useful if the module had a resettable timer that is independent of the changing precision provided by time.monotonic(). A precise_time module could provide something like this to allow timing of events with higher precision:
precise_time.reset()
# do processing
process_time = precise_time.time()
Hi all,
I'm also interested in a better timer. I'm more interested in knowing how long it takes to execute stuff. So, a read-only timer, to the usec would be very useful.
I've been playing with this and just realized that time.monotonic() is only good to 1 decimal. But, learned that is dependent on time since last restarted or reset(?)
Just wanted to chime in to say that I am also looking for the feature.
I'll chime in on this too, since I recently ran into this limitation after switching a project from Arduino to CircuitPython. The project requires events triggered with at least 0.1 second resolution, but using monotonic() begins to fail. The only fix is to have the device reset as the resolution limit approaches. This is insufficient for my use case. I can't think of another way around it.
Even a rollover counter like millis() is preferable to monotonic(), as at least I can keep track of the rollovers and manage my own counter. Helping people port from Arduino also would argue for a millis()-like function, even if such does not exist in CPython.
We're only enabling time.monotonic_ns() on the Express builds. We need Python long integers for monotonic_ns() or else the values will wrap around after a few seconds. Unfortunately there's not enough room in the Trinket or Gemma builds for long integers (longints).
Dan> We're only enabling time.monotonic_ns() on the Express builds. We
Dan> need Python long integers for monotonic_ns() or else the values
Dan> will wrap around after a few seconds. Unfortunately there's not
Dan> enough room in the Trinket or Gemma builds for long integers
Dan> (longints).
How about time.monotonic_ms() on the Gemmas, with a lower resolution?
I don't even care too much if it wraps, because if I know to check for
that, it's not too bad.
John
Hello, I am totally new to this circuitpython stuff.
What I am looking for, is a timer-callback, that will be executed repeatedly after a certain period of time (something like setInterval(callback, period) in JavaScript).
This should run asynchronous, that means, that my program is not sleeping, but could do other stuff meanwhile.
Is that possible with circuitpython? If so, is there any example?
@framlin - sorry, we don't have callbacks or other asynchronous features right now (they are in MicroPython but we're not using them). We're working on coming up with simpler concurrency mechanisms that are easy to understand, e.g. #1380.
I was able to get this running on my Metro M0 Express, but it looks like time.monotonic_ns() still only returns a value with a resolution of milliseconds.
Is there an equivalent to the micros() call available on the Arduino platform?
@dhalbert Why does it make the builds bigger, is this just because literal ints end up with a larger representation in mpy files? Would having yet another function to return (seconds, milliseconds) as an (int,int) tuple be another option to support all boards?
Activity
CameronDevine commentedon Jan 10, 2018
I was attempting to work with a 433Mhz radio transmitter which required writing to a pin at 200 microsecond intervals. Even if a function similar to the Arduino
micros()had less than 1 microsecond resolution this would allow time calculations that are not possible with thetime.monotonic()function.tannewt commentedon Jan 10, 2018
@CameronDevine Interesting! How much data do you know you need to write ahead of time? Something like PulseOut might be adequate. It looks like it requires a carrier PWM signal though it could just be constant.
dhalbert commentedon Jan 10, 2018
came from here: asking there as well: https://forums.adafruit.com/viewtopic.php?f=60&t=129222
l8gravely commentedon Mar 1, 2018
I too would like to see something better than monotonic, since it's not stable and loses precision as time goes on. Or maybe I just need to learn the CircuitPython way to do longer term ramping up/down of a NeoPixel, while not doing a busy wait, so I can handle other inputs that come in.
Right now I just try to do:
timetofire = timer.Monotonic() + delay
while True:
now= timer.Monotonic()
if (now > timetofire):
timetofire = now + delay
# do NeoPixel incremental update here
continue on looking for keyboard input, etc.
Does this make sense? I also wish it was more clearly documented what resolution monotonic is counting in, since it's not quite seconds, but maybe milliseconds?
tannewt commentedon Mar 5, 2018
@l8gravely On the SAMD21 it is millisecond.
I'm still unsure we want to provide precise timing because we pause the VM from time to time to do other things. I'm worried about making timing promises we don't always keep. If we did, I think we could introduce a
precisetimemodule for it.@l8gravely also follow #619 for a different way to do things concurrently.
CameronDevine commentedon Mar 6, 2018
Would it be possible to have a variable which states the approximate interval at which
time.monotonic()is increased? This would save people form having to write code to guess what the interval is, since it appears to change based on which board is being used.jepler commentedon Apr 9, 2018
like @l8gravely I want a monotonic time source which doesn't lose precision. In my project, I want to show the seconds and fractions of seconds based on NTP time, but it starts to lose precision as the
monotonic()value gets large.For me, directly exposing
common_hal_time_monotonic(), possibly via themicrocontrollermodule, seems like a good first step. I'm not sure whether exposing it as a 64-bit value (restricting it to devices with support for longs) is better, or exposing it as unix-style (seconds,microseconds} is better. The latter is sure less convenient for doing math on, and forces the choice of a fractional second size of microseconds or coarser (rather than nanoseconds or 2^-32s) in order to avoid overflows while doing arithmetic (+, -) on timestamps with limited integer precision available.tannewt commentedon Apr 9, 2018
I was thinking we could add a
precise_timemodule too.margaret commentedon May 14, 2018
I'm going to take a stab at this (pycon sprints)
CBMalloch commentedon Sep 10, 2018
I'm trying to sample a 1kHz modulated light beam at 100µs intervals. About every 1/32 sec I go into a coma for almost 1/32 sec while the system does its other things. More precise timing would not help unless we also had a "suspend the other system things for a mo while I do this time-critical thing" function...
tannewt commentedon Sep 11, 2018
@CBMalloch how is the light beam being interfaced to the microcontroller? We may be able to add a C helper for it.
It's highly unlikely we'll ever allow for predictable timing in Python execution. There are too many critical things happening around the VM to do it.
jak3kay commentedon Oct 8, 2018
As
time.monotonic()becomes less precise over time I support having aprecise_timemodule with a custom timer with millisecond precision. It would be very useful if the module had a resettable timer that is independent of the changing precision provided bytime.monotonic(). Aprecise_timemodule could provide something like this to allow timing of events with higher precision:parsko41 commentedon Oct 22, 2018
Hi all,
I'm also interested in a better timer. I'm more interested in knowing how long it takes to execute stuff. So, a read-only timer, to the usec would be very useful.
I've been playing with this and just realized that time.monotonic() is only good to 1 decimal. But, learned that is dependent on time since last restarted or reset(?)
Just wanted to chime in to say that I am also looking for the feature.
Thanks,
-Parsko
gmparis commentedon Nov 3, 2018
I'll chime in on this too, since I recently ran into this limitation after switching a project from Arduino to CircuitPython. The project requires events triggered with at least 0.1 second resolution, but using monotonic() begins to fail. The only fix is to have the device reset as the resolution limit approaches. This is insufficient for my use case. I can't think of another way around it.
Even a rollover counter like millis() is preferable to monotonic(), as at least I can keep track of the rollovers and manage my own counter. Helping people port from Arduino also would argue for a millis()-like function, even if such does not exist in CPython.
Thanks for listening!
Greg
tannewt commentedon Nov 4, 2018
@gmparis
time.monotonic_ns()will be released with the next 4.x alpha. Feel free to try a test build from here until then.tballas commentedon Dec 13, 2018
So, I just put 4.0.0 alpha 5 on my Trinket M0 expecting to be able to use time.monotonic_ns() This is what I get in REPL:
I wonder why it's not enabled?
dhalbert commentedon Dec 13, 2018
We're only enabling
time.monotonic_ns()on the Express builds. We need Python long integers formonotonic_ns()or else the values will wrap around after a few seconds. Unfortunately there's not enough room in the Trinket or Gemma builds for long integers (longints).tballas commentedon Dec 13, 2018
Ah, that's unfortunate to hear. Thank you for explaining.
l8gravely commentedon Dec 13, 2018
framlin commentedon Dec 19, 2018
Hello, I am totally new to this circuitpython stuff.
What I am looking for, is a timer-callback, that will be executed repeatedly after a certain period of time (something like setInterval(callback, period) in JavaScript).
This should run asynchronous, that means, that my program is not sleeping, but could do other stuff meanwhile.
Is that possible with circuitpython? If so, is there any example?
dhalbert commentedon Dec 19, 2018
@framlin - sorry, we don't have callbacks or other asynchronous features right now (they are in MicroPython but we're not using them). We're working on coming up with simpler concurrency mechanisms that are easy to understand, e.g. #1380.
zamfi commentedon Mar 14, 2019
I was able to get this running on my Metro M0 Express, but it looks like
time.monotonic_ns()still only returns a value with a resolution of milliseconds.Is there an equivalent to the
micros()call available on the Arduino platform?kevinjwalters commentedon Nov 11, 2019
@dhalbert Why does it make the builds bigger, is this just because literal ints end up with a larger representation in mpy files? Would having yet another function to return (seconds, milliseconds) as an (int,int) tuple be another option to support all boards?
(Discussion/issue in https://forums.adafruit.com/viewtopic.php?f=60&t=158501 reminded me of this)
dhalbert commentedon Nov 11, 2019
@kevinjwalters The builds are bigger because we need longints to support
time.monotonic_ns()values, which are larger than regular ints.We have talked about adding another function, but it would not be in
time, because we don't want to add new functionality to a standard module.