2016-03-05 10:47:01 +01:00
# Timer Module
| Since | Origin / Contributor | Maintainer | Source |
| :----- | :-------------------- | :---------- | :------ |
| 2014-12-12 | [Zeroday ](https://github.com/funshine ) | [dnc40085 ](https://github.com/dnc40085 ) | [tmr.c ](../../../app/modules/tmr.c )|
2016-01-06 03:06:00 +01:00
The tmr module allows access to simple timers, the system counter and uptime.
It is aimed at setting up regularly occurring tasks, timing out operations, and provide low-resolution deltas.
2016-01-10 16:04:23 +01:00
What the tmr module is *not* however, is a time keeping module. While most timeouts are expressed in milliseconds or even microseconds, the accuracy is limited and compounding errors would lead to rather inaccurate time keeping. Consider using the [rtctime ](rtctime.md ) module for "wall clock" time.
2016-01-06 03:06:00 +01:00
2016-08-02 22:35:53 +02:00
NodeMCU provides 7 static timers, numbered 0-6, and dynamic timer creation function [`tmr.create()` ](#tmrcreate ).
!!! attention
2017-01-03 21:50:56 +01:00
Static timers are deprecated and will be removed later. Use the OO API initiated with [`tmr.create()` ](#tmrcreate ).
2016-01-06 03:06:00 +01:00
2016-01-10 16:04:23 +01:00
## tmr.alarm()
2016-01-06 03:06:00 +01:00
2016-01-10 16:04:23 +01:00
This is a convenience function combining [`tmr.register()` ](#tmrregister ) and [`tmr.start()` ](#tmrstart ) into a single call.
2016-01-06 03:06:00 +01:00
2016-01-10 16:04:23 +01:00
To free up the resources with this timer when done using it, call [`tmr.unregister()` ](#tmrunregister ) on it. For one-shot timers this is not necessary, unless they were stopped before they expired.
2016-01-06 03:06:00 +01:00
2017-01-03 21:50:56 +01:00
#### Syntax
2017-01-04 10:32:55 +01:00
`tmr.alarm([id/ref], interval_ms, mode, func())`
2017-01-03 21:50:56 +01:00
2016-01-10 16:04:23 +01:00
#### Parameters
2017-01-03 21:50:56 +01:00
- `id` /`ref` timer id (0-6) or object, obsolete for OO API (→ [`tmr.create()` ](#tmrcreate ))
2016-05-07 11:30:04 +02:00
- `interval_ms` timer interval in milliseconds. Maximum value is 6870947 (1:54:30.947).
2016-01-10 16:04:23 +01:00
- `mode` timer mode:
- `tmr.ALARM_SINGLE` a one-shot alarm (and no need to call [`tmr.unregister()` ](#tmrunregister ))
- `tmr.ALARM_SEMI` manually repeating alarm (call [`tmr.start()` ](#tmrstart ) to restart)
- `tmr.ALARM_AUTO` automatically repeating alarm
2017-01-03 21:50:56 +01:00
- `func(timer)` callback function which is invoked with the timer object as an argument
2016-01-06 03:06:00 +01:00
2016-01-10 16:04:23 +01:00
#### Returns
`true` if the timer was started, `false` on error
2016-01-06 03:06:00 +01:00
2016-01-10 16:04:23 +01:00
#### Example
2016-01-06 03:06:00 +01:00
```lua
2017-01-03 21:50:56 +01:00
if not tmr.create():alarm(5000, tmr.ALARM_SINGLE, function()
print("hey there")
end)
then
print("whoopsie")
end
2016-01-06 03:06:00 +01:00
```
2016-01-10 16:04:23 +01:00
#### See also
2016-08-02 22:35:53 +02:00
- [`tmr.create()` ](#tmrcreate )
2016-01-10 16:04:23 +01:00
- [`tmr.register()` ](#tmrregister )
- [`tmr.start()` ](#tmrstart )
- [`tmr.unregister()` ](#tmrunregister )
2016-01-07 00:33:52 +01:00
2016-08-02 22:35:53 +02:00
## tmr.create()
Creates a dynamic timer object.
Dynamic timer can be used instead of numeric ID in control functions. Also can be controlled in object-oriented way.
Functions supported in timer object:
- [`t:alarm()` ](#tmralarm )
2017-01-03 21:50:56 +01:00
- [`t:interval()` ](#tmrinterval )
2016-08-02 22:35:53 +02:00
- [`t:register()` ](#tmrregister )
2017-04-04 21:31:06 +02:00
- [`t:resume()` ](#tmrresume )
2016-08-02 22:35:53 +02:00
- [`t:start()` ](#tmrstart )
2017-01-03 21:50:56 +01:00
- [`t:state()` ](#tmrstate )
2016-08-02 22:35:53 +02:00
- [`t:stop()` ](#tmrstop )
2017-04-04 21:31:06 +02:00
- [`t:suspend()` ](#tmrsuspend )
2016-08-02 22:35:53 +02:00
- [`t:unregister()` ](#tmrunregister )
#### Parameters
none
#### Returns
`timer` object
#### Example
```lua
local mytimer = tmr.create()
-- oo calling
mytimer:register(5000, tmr.ALARM_SINGLE, function (t) print("expired"); t:unregister() end)
mytimer:start()
-- with self parameter
tmr.register(mytimer, 5000, tmr.ALARM_SINGLE, function (t) print("expired"); tmr.unregister(t) end)
tmr.start(mytimer)
```
2016-01-10 16:04:23 +01:00
## tmr.delay()
2016-01-06 03:06:00 +01:00
2016-01-10 16:04:23 +01:00
Busyloops the processor for a specified number of microseconds.
2016-01-06 03:06:00 +01:00
2016-01-10 16:04:23 +01:00
This is in general a **bad** idea, because nothing else gets to run, and the networking stack (and other things) can fall over as a result. The only time `tmr.delay()` may be appropriate to use is if dealing with a peripheral device which needs a (very) brief delay between commands, or similar. *Use with caution!*
2016-01-06 03:06:00 +01:00
2016-01-10 16:04:23 +01:00
Also note that the actual amount of time delayed for may be noticeably greater, both as a result of timing inaccuracies as well as interrupts which may run during this time.
#### Syntax
`tmr.delay(us)`
2016-01-06 03:06:00 +01:00
2016-01-10 16:04:23 +01:00
#### Parameters
`us` microseconds to busyloop for
2016-01-06 03:06:00 +01:00
2016-01-10 16:04:23 +01:00
#### Returns
2016-01-06 03:06:00 +01:00
`nil`
2016-01-10 16:04:23 +01:00
#### Example
2016-01-06 03:06:00 +01:00
```lua
2016-01-10 16:04:23 +01:00
tmr.delay(100)
2016-01-06 03:06:00 +01:00
```
2016-01-07 00:33:52 +01:00
2016-01-10 16:04:23 +01:00
## tmr.interval()
2016-01-06 03:06:00 +01:00
2016-01-10 16:04:23 +01:00
Changes a registered timer's expiry interval.
2016-01-06 03:06:00 +01:00
2016-01-10 16:04:23 +01:00
#### Syntax
2017-01-03 21:50:56 +01:00
`tmr.interval([id/ref], interval_ms)`
2016-01-06 03:06:00 +01:00
2016-01-10 16:04:23 +01:00
#### Parameters
2017-01-03 21:50:56 +01:00
- `id` /`ref` timer id (0-6) or object, obsolete for OO API (→ [`tmr.create()` ](#tmrcreate ))
2016-05-07 11:30:04 +02:00
- `interval_ms` new timer interval in milliseconds. Maximum value is 6870947 (1:54:30.947).
2016-01-06 03:06:00 +01:00
2016-01-10 16:04:23 +01:00
#### Returns
`nil`
2016-01-06 03:06:00 +01:00
2016-01-10 16:04:23 +01:00
#### Example
2016-01-06 03:06:00 +01:00
```lua
2017-01-03 21:50:56 +01:00
mytimer = tmr.create()
mytimer:register(10000, tmr.ALARM_AUTO, function() print("hey there") end)
mytimer:interval(3000) -- actually, 3 seconds is better!
mytimer:start()
2016-01-06 03:06:00 +01:00
```
2016-01-07 00:33:52 +01:00
2016-01-10 16:04:23 +01:00
## tmr.now()
2016-01-06 03:06:00 +01:00
2016-01-10 16:04:23 +01:00
Returns the system counter, which counts in microseconds. Limited to 31 bits, after that it wraps around back to zero. That is essential if you use this function to [debounce or throttle GPIO input ](https://github.com/hackhitchin/esp8266-co-uk/issues/2 ).
2016-01-06 03:06:00 +01:00
2016-01-10 16:04:23 +01:00
#### Syntax
`tmr.now()`
2016-01-06 03:06:00 +01:00
2016-01-10 16:04:23 +01:00
#### Parameters
none
2016-01-06 03:06:00 +01:00
2016-01-10 16:04:23 +01:00
#### Returns
the current value of the system counter
2016-01-06 03:06:00 +01:00
2016-01-10 16:04:23 +01:00
#### Example
2016-01-06 03:06:00 +01:00
```lua
2016-01-10 16:04:23 +01:00
print(tmr.now())
print(tmr.now())
2016-01-06 03:06:00 +01:00
```
2016-01-07 00:33:52 +01:00
2016-01-10 16:04:23 +01:00
## tmr.register()
2016-01-06 03:06:00 +01:00
2016-01-10 16:04:23 +01:00
Configures a timer and registers the callback function to call on expiry.
2016-01-06 03:06:00 +01:00
2016-01-10 16:04:23 +01:00
To free up the resources with this timer when done using it, call [`tmr.unregister()` ](#tmrunregister ) on it. For one-shot timers this is not necessary, unless they were stopped before they expired.
2016-01-06 03:06:00 +01:00
2016-01-10 16:04:23 +01:00
#### Syntax
2017-01-03 21:50:56 +01:00
`tmr.register([id/ref], interval_ms, mode, func())`
2016-01-10 16:04:23 +01:00
#### Parameters
2017-01-03 21:50:56 +01:00
- `id` /`ref` timer id (0-6) or object, obsolete for OO API (→ [`tmr.create()` ](#tmrcreate ))
2016-05-07 11:30:04 +02:00
- `interval_ms` timer interval in milliseconds. Maximum value is 6870947 (1:54:30.947).
2016-01-10 16:04:23 +01:00
- `mode` timer mode:
- `tmr.ALARM_SINGLE` a one-shot alarm (and no need to call [`tmr.unregister()` ](#tmrunregister ))
- `tmr.ALARM_SEMI` manually repeating alarm (call [`tmr.start()` ](#tmrunregister ) to restart)
- `tmr.ALARM_AUTO` automatically repeating alarm
2017-01-03 21:50:56 +01:00
- `func(timer)` callback function which is invoked with the timer object as an argument
2016-01-10 16:04:23 +01:00
Note that registering does *not* start the alarm.
2016-01-06 03:06:00 +01:00
2016-01-10 16:04:23 +01:00
#### Returns
2016-01-06 03:06:00 +01:00
`nil`
2016-01-10 16:04:23 +01:00
#### Example
2016-01-06 03:06:00 +01:00
```lua
2017-01-03 21:50:56 +01:00
mytimer = tmr.create()
mytimer:register(5000, tmr.ALARM_SINGLE, function() print("hey there") end)
mytimer:start()
2016-01-06 03:06:00 +01:00
```
2016-01-10 16:04:23 +01:00
#### See also
2016-08-02 22:35:53 +02:00
- [`tmr.create()` ](#tmrcreate )
- [`tmr.alarm()` ](#tmralarm )
2016-01-06 03:06:00 +01:00
2017-04-04 21:31:06 +02:00
## tmr.resume()
Resume an individual timer.
Resumes a timer that has previously been suspended with either `tmr.suspend` or `tmr.suspend_all`
#### Syntax
`tmr.resume(id/ref)`
#### Parameters
`id/ref` timer id (0-6) or object, obsolete for OO API (→ [`tmr.create()` ](#tmrcreate ))
#### Returns
`true` if timer was resumed successfully
#### Example
```lua
--resume timer mytimer
mytimer:resume()
--alternate metod
tmr.resume(mytimer)
```
#### See also
2017-04-05 06:57:10 +02:00
- [`tmr.suspend()` ](#tmrsuspend )
- [`tmr.suspend_all()` ](#tmrsuspendall )
- [`tmr.resume_all()` ](#tmrresumeall )
2017-04-04 21:31:06 +02:00
## tmr.resume_all()
Resume all timers.
Resumes all timers including those previously been suspended with either `tmr.suspend` or `tmr.suspend_all`
#### Syntax
`tmr.resume_all()`
#### Parameters
none
#### Returns
`true` if timers were resumed successfully
#### Example
```lua
--resume all previously suspended timers
tmr.resume_all()
```
#### See also
2017-04-05 06:57:10 +02:00
- [`tmr.suspend()` ](#tmrsuspend )
- [`tmr.suspend_all()` ](#tmrsuspendall )
- [`tmr.resume()` ](#tmrresume )
2017-04-04 21:31:06 +02:00
2016-01-10 16:04:23 +01:00
## tmr.softwd()
2016-01-06 03:06:00 +01:00
2016-01-10 16:04:23 +01:00
Provides a simple software watchdog, which needs to be re-armed or disabled before it expires, or the system will be restarted.
2016-01-06 03:06:00 +01:00
2016-01-10 16:04:23 +01:00
#### Syntax
`tmr.softwd(timeout_s)`
2016-01-06 03:06:00 +01:00
2016-01-10 16:04:23 +01:00
#### Parameters
`timeout_s` watchdog timeout, in seconds. To disable the watchdog, use -1 (or any other negative value).
2016-01-06 03:06:00 +01:00
2016-01-10 16:04:23 +01:00
#### Returns
`nil`
2016-01-06 03:06:00 +01:00
2016-01-10 16:04:23 +01:00
#### Example
2016-01-06 03:06:00 +01:00
```lua
2016-01-10 16:04:23 +01:00
function on_success_callback()
tmr.softwd(-1)
print("Complex task done, soft watchdog disabled!")
end
tmr.softwd(5)
-- go off and attempt to do whatever might need a restart to recover from
complex_stuff_which_might_never_call_the_callback(on_success_callback)
2016-01-06 03:06:00 +01:00
```
2016-01-10 16:04:23 +01:00
## tmr.start()
Starts or restarts a previously configured timer.
2016-01-06 03:06:00 +01:00
2016-01-10 16:04:23 +01:00
#### Syntax
2017-01-03 21:50:56 +01:00
`tmr.start([id/ref])`
2016-01-06 03:06:00 +01:00
2016-01-10 16:04:23 +01:00
#### Parameters
2017-01-03 21:50:56 +01:00
`id` /`ref` timer id (0-6) or object, obsolete for OO API (→ [`tmr.create()` ](#tmrcreate ))
2016-01-06 03:06:00 +01:00
2016-01-10 16:04:23 +01:00
#### Returns
`true` if the timer was started, `false` on error
2016-01-06 03:06:00 +01:00
2016-01-10 16:04:23 +01:00
#### Example
2016-01-06 03:06:00 +01:00
```lua
2017-01-03 21:50:56 +01:00
mytimer = tmr.create()
mytimer:register(5000, tmr.ALARM_SINGLE, function() print("hey there") end)
if not mytimer:start() then print("uh oh") end
2016-01-06 03:06:00 +01:00
```
2016-01-10 16:04:23 +01:00
#### See also
2016-08-02 22:35:53 +02:00
- [`tmr.create()` ](#tmrcreate )
2016-01-10 16:04:23 +01:00
- [`tmr.register()` ](#tmrregister )
- [`tmr.stop()` ](#tmrstop )
- [`tmr.unregister()` ](#tmrunregister )
2016-01-07 00:33:52 +01:00
2016-01-10 16:04:23 +01:00
## tmr.state()
2016-01-06 03:06:00 +01:00
2016-01-10 16:04:23 +01:00
Checks the state of a timer.
2016-01-06 03:06:00 +01:00
2016-01-10 16:04:23 +01:00
#### Syntax
2017-01-03 21:50:56 +01:00
`tmr.state([id/ref])`
2016-01-06 03:06:00 +01:00
2016-01-10 16:04:23 +01:00
#### Parameters
2017-01-03 21:50:56 +01:00
`id` /`ref` timer id (0-6) or object, obsolete for OO API (→ [`tmr.create()` ](#tmrcreate ))
2016-01-10 16:04:23 +01:00
#### Returns
(bool, int) or `nil`
2016-01-06 03:06:00 +01:00
2016-01-10 16:04:23 +01:00
If the specified timer is registered, returns whether it is currently started and its mode. If the timer is not registered, `nil` is returned.
2016-01-06 03:06:00 +01:00
2016-01-10 16:04:23 +01:00
#### Example
2016-01-06 03:06:00 +01:00
```lua
2017-01-03 21:50:56 +01:00
mytimer = tmr.create()
print(mytimer:state()) -- nil
mytimer:register(5000, tmr.ALARM_SINGLE, function() print("hey there") end)
running, mode = mytimer:state()
print("running: " .. tostring(running) .. ", mode: " .. mode) -- running: false, mode: 0
2016-01-06 03:06:00 +01:00
```
2016-01-10 16:04:23 +01:00
## tmr.stop()
2016-01-06 03:06:00 +01:00
2016-01-10 16:04:23 +01:00
Stops a running timer, but does *not* unregister it. A stopped timer can be restarted with [`tmr.start()` ](#tmrstart ).
2016-01-06 03:06:00 +01:00
2016-01-10 16:04:23 +01:00
#### Syntax
2017-01-03 21:50:56 +01:00
`tmr.stop([id/ref])`
2016-01-06 03:06:00 +01:00
2016-01-10 16:04:23 +01:00
#### Parameters
2017-01-03 21:50:56 +01:00
`id` /`ref` timer id (0-6) or object, obsolete for OO API (→ [`tmr.create()` ](#tmrcreate ))
2016-01-06 03:06:00 +01:00
2016-01-10 16:04:23 +01:00
#### Returns
`true` if the timer was stopped, `false` on error
#### Example
2016-01-06 03:06:00 +01:00
```lua
2017-01-03 21:50:56 +01:00
mytimer = tmr.create()
if not mytimer:stop() then print("timer not stopped, not registered?") end
2016-01-06 03:06:00 +01:00
```
2016-01-10 16:04:23 +01:00
#### See also
- [`tmr.register()` ](#tmrregister )
- [`tmr.stop()` ](#tmrstop )
- [`tmr.unregister()` ](#tmrunregister )
2016-01-06 03:06:00 +01:00
2017-04-04 21:31:06 +02:00
## tmr.suspend()
Suspend an armed timer.
2017-10-19 10:00:41 +02:00
!!! attention
This is disabled by default. Modify `ENABLE_TIMER_SUSPEND` in `app/include/user_config.h` to enable it.
2017-04-04 21:31:06 +02:00
* Timers can be suspended at any time after they are armed.
* If a timer is rearmed with `tmr.start` or `tmr.alarm` any matching suspended timers will be discarded.
#### Syntax
`tmr.suspend(id/ref)`
#### Parameters
`id/ref` timer id (0-6) or object, obsolete for OO API (→ [`tmr.create()` ](#tmrcreate ))
#### Returns
`true` if timer was resumed successfully
#### Example
```lua
--suspend timer mytimer
mytimer:suspend()
--alternate metod
tmr.suspend(mytimer)
```
#### See also
2017-04-05 06:57:10 +02:00
- [`tmr.suspend_all()` ](#tmrsuspendall )
- [`tmr.resume()` ](#tmrresume )
- [`tmr.resume_all()` ](#tmrresumeall )
2017-04-04 21:31:06 +02:00
## tmr.suspend_all()
Suspend all currently armed timers.
2017-10-19 10:00:41 +02:00
!!! attention
This is disabled by default. Modify `ENABLE_TIMER_SUSPEND` in `app/include/user_config.h` to enable it.
2017-04-04 21:31:06 +02:00
!!! Warning
This function suspends ALL active timers, including any active timers started by the NodeMCU subsystem or other modules. this may cause parts of your program to stop functioning properly.
USE THIS FUNCTION AT YOUR OWN RISK!
#### Syntax
`tmr.suspend_all()`
#### Parameters
none
#### Returns
`true` if timers were suspended successfully
#### Example
```lua
--suspend timer mytimer
tmr.suspend_all()
```
#### See also
2017-04-05 06:57:10 +02:00
- [`tmr.suspendl()` ](#tmrsuspend )
- [`tmr.resume()` ](#tmrresume )
- [`tmr.resume_all()` ](#tmrresumeall )
2017-04-04 21:31:06 +02:00
2016-01-10 16:04:23 +01:00
## tmr.time()
2016-01-06 03:06:00 +01:00
2016-01-10 16:04:23 +01:00
Returns the system uptime, in seconds. Limited to 31 bits, after that it wraps around back to zero.
2016-01-06 03:06:00 +01:00
2016-01-10 16:04:23 +01:00
#### Syntax
`tmr.time()`
2016-01-06 03:06:00 +01:00
2016-01-10 16:04:23 +01:00
#### Parameters
none
2016-01-06 03:06:00 +01:00
2016-01-10 16:04:23 +01:00
#### Returns
the system uptime, in seconds, possibly wrapped around
2016-01-06 03:06:00 +01:00
2016-01-10 16:04:23 +01:00
#### Example
```lua
print("Uptime (probably):", tmr.time())
2016-01-06 03:06:00 +01:00
```
2016-01-10 16:04:23 +01:00
## tmr.unregister()
2016-01-06 03:06:00 +01:00
2016-01-10 16:04:23 +01:00
Stops the timer (if running) and unregisters the associated callback.
2016-01-06 03:06:00 +01:00
2016-01-10 16:04:23 +01:00
This isn't necessary for one-shot timers (`tmr.ALARM_SINGLE`), as those automatically unregister themselves when fired.
2016-01-06 03:06:00 +01:00
2016-01-10 16:04:23 +01:00
#### Syntax
2017-01-03 21:50:56 +01:00
`tmr.unregister([id/ref])`
2016-01-06 03:06:00 +01:00
2016-01-10 16:04:23 +01:00
#### Parameters
2017-01-03 21:50:56 +01:00
`id` /`ref` timer id (0-6) or object, obsolete for OO API (→ [`tmr.create()` ](#tmrcreate ))
2016-01-06 03:06:00 +01:00
2016-01-10 16:04:23 +01:00
#### Returns
2016-01-06 03:06:00 +01:00
`nil`
2016-01-10 16:04:23 +01:00
#### Example
2016-01-06 03:06:00 +01:00
```lua
2016-01-10 16:04:23 +01:00
tmr.unregister(0)
2016-01-06 03:06:00 +01:00
```
2016-01-10 16:04:23 +01:00
#### See also
[`tmr.register()` ](#tmrregister )
2016-01-06 03:06:00 +01:00
## tmr.wdclr()
Feed the system watchdog.
*In general, if you ever need to use this function, you are doing it wrong.*
The event-driven model of NodeMCU means that there is no need to be sitting in hard loops waiting for things to occur. Rather, simply use the callbacks to get notified when somethings happens. With this approach, there should never be a need to manually feed the system watchdog.
2016-01-10 16:04:23 +01:00
#### Syntax
2016-01-06 03:06:00 +01:00
`tmr.wdclr()`
2016-01-10 16:04:23 +01:00
#### Parameters
none
2016-01-06 03:06:00 +01:00
2016-01-10 16:04:23 +01:00
#### Returns
2016-05-07 11:30:04 +02:00
`nil`