Replace old tmr API in docs with OO API (#1695)
This commit is contained in:
parent
61d20a75e2
commit
a89b008087
|
@ -70,7 +70,7 @@ node.restart(); for i = 1, 20 do print("not quite yet -- ",i); end
|
|||
* Whilst the SDK provides a number of interrupt driven device drivers, the hardware architecture severely limits the memory available for these drivers, so writing new device drivers is not a viable options for most developers
|
||||
* The SDK interfaces internally with hardware and device drivers to queue pending events.
|
||||
* The registered callback routines are invoked sequentially with the associated C task running to completion uninterrupted.
|
||||
* In the case of Lua, these C tasks are typically functions within the Lua runtime library code and these typically act as C wrappers around the corresponding developer-provided Lua callback functions. An example here is the Lua `tmr.alarm(id, interval, repeat, callback)` function. The calls a function in the `tmr` library which registers a C function for this alarm using the SDK, and when this C function is called it then invokes the Lua callback.
|
||||
* In the case of Lua, these C tasks are typically functions within the Lua runtime library code and these typically act as C wrappers around the corresponding developer-provided Lua callback functions. An example here is the Lua [`mytimer:alarm(interval, repeat, callback)`](modules/tmr.md#tmralarm) function. The calls a function in the `tmr` library which registers a C function for this alarm using the SDK, and when this C function is called it then invokes the Lua callback.
|
||||
|
||||
The NodeMCU firmware simply mirrors this structure at a Lua scripting level:
|
||||
|
||||
|
@ -185,7 +185,7 @@ status = mail.send(to, subject, body)
|
|||
|
||||
### When and why should I avoid using tmr.delay()?
|
||||
|
||||
If you are used coding in a procedural paradigm then it is understandable that you consider using `tmr.delay()` to time sequence your application. However as discussed in the previous section, with NodeMCU Lua you are coding in an event-driven paradigm.
|
||||
If you are used coding in a procedural paradigm then it is understandable that you consider using [`tmr.delay()`](modules/tmr.md#tmrdelay) to time sequence your application. However as discussed in the previous section, with NodeMCU Lua you are coding in an event-driven paradigm.
|
||||
|
||||
If you look at the `app/modules/tmr.c` code for this function, then you will see that it executes a low level `ets_delay_us(delay)`. This function isn't part of the NodeMCU code or the SDK; it's actually part of the xtensa-lx106 boot ROM, and is a simple timing loop which polls against the internal CPU clock. It does this with interrupts disabled, because if they are enabled then there is no guarantee that the delay will be as requested.
|
||||
|
||||
|
@ -197,9 +197,12 @@ The latest SDK includes a caution that if any (callback) task runs for more than
|
|||
### How do I avoid a PANIC loop in init.lua?
|
||||
|
||||
Most of us have fallen into the trap of creating an `init.lua` that has a bug in it, which then causes the system to reboot and hence gets stuck in a reboot loop. If you haven't then you probably will do so at least once.
|
||||
* When this happens, the only robust solution is to reflash the firmware.
|
||||
* The simplest way to avoid having to do this is to keep the `init.lua` as simple as possible -- say configure the wifi and then start your app using a one-time `tmr.alarm()` after a 2-3 sec delay. This delay is long enough to issue a `file.remove("init.lua")` through the serial port and recover control that way.
|
||||
* Also it is always best to test any new `init.lua` by creating it as `init_test.lua`, say, and manually issuing a `dofile("init_test.lua")` through the serial port, and then only rename it when you are certain it is working as you require.
|
||||
|
||||
- When this happens, the only robust solution is to reflash the firmware.
|
||||
- The simplest way to avoid having to do this is to keep the `init.lua` as simple as possible -- say configure the wifi and then start your app using a one-time `tmr.alarm()` after a 2-3 sec delay. This delay is long enough to issue a `file.remove("init.lua")` through the serial port and recover control that way.
|
||||
- Also it is always best to test any new `init.lua` by creating it as `init_test.lua`, say, and manually issuing a `dofile("init_test.lua")` through the serial port, and then only rename it when you are certain it is working as you require.
|
||||
|
||||
See ["Uploading code" → init.lua](upload.md#initlua) for an example.
|
||||
|
||||
## Techniques for Reducing RAM and SPIFFS footprint
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ NodeMCU provides 7 static timers, numbered 0-6, and dynamic timer creation funct
|
|||
|
||||
!!! attention
|
||||
|
||||
Static timers are deprecated and will be removed later.
|
||||
Static timers are deprecated and will be removed later. Use the OO API initiated with [`tmr.create()`](#tmrcreate).
|
||||
|
||||
## tmr.alarm()
|
||||
|
||||
|
@ -21,20 +21,29 @@ This is a convenience function combining [`tmr.register()`](#tmrregister) and [`
|
|||
|
||||
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.
|
||||
|
||||
#### Syntax
|
||||
`tmr.register([id/ref], interval_ms, mode, func())`
|
||||
|
||||
#### Parameters
|
||||
- `id`/`ref` timer id (0-6) or object
|
||||
- `id`/`ref` timer id (0-6) or object, obsolete for OO API (→ [`tmr.create()`](#tmrcreate))
|
||||
- `interval_ms` timer interval in milliseconds. Maximum value is 6870947 (1:54:30.947).
|
||||
- `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
|
||||
- `func(timer)` callback function which is invoked with the timer object as an argument
|
||||
|
||||
#### Returns
|
||||
`true` if the timer was started, `false` on error
|
||||
|
||||
#### Example
|
||||
```lua
|
||||
if not tmr.alarm(0, 5000, tmr.ALARM_SINGLE, function() print("hey there") end) then print("whoopsie") end
|
||||
if not tmr.create():alarm(5000, tmr.ALARM_SINGLE, function()
|
||||
print("hey there")
|
||||
end)
|
||||
then
|
||||
print("whoopsie")
|
||||
end
|
||||
```
|
||||
#### See also
|
||||
- [`tmr.create()`](#tmrcreate)
|
||||
|
@ -51,12 +60,12 @@ Dynamic timer can be used instead of numeric ID in control functions. Also can b
|
|||
Functions supported in timer object:
|
||||
|
||||
- [`t:alarm()`](#tmralarm)
|
||||
- [`t:interval()`](#tmrinterval)
|
||||
- [`t:register()`](#tmrregister)
|
||||
- [`t:start()`](#tmrstart)
|
||||
- [`t:state()`](#tmrstate)
|
||||
- [`t:stop()`](#tmrstop)
|
||||
- [`t:unregister()`](#tmrunregister)
|
||||
- [`t:state()`](#tmrstate)
|
||||
- [`t:interval()`](#tmrinterval)
|
||||
|
||||
#### Parameters
|
||||
none
|
||||
|
@ -104,10 +113,10 @@ tmr.delay(100)
|
|||
Changes a registered timer's expiry interval.
|
||||
|
||||
#### Syntax
|
||||
`tmr.interval(id/ref, interval_ms)`
|
||||
`tmr.interval([id/ref], interval_ms)`
|
||||
|
||||
#### Parameters
|
||||
- `id`/`ref` timer id (0-6) or object
|
||||
- `id`/`ref` timer id (0-6) or object, obsolete for OO API (→ [`tmr.create()`](#tmrcreate))
|
||||
- `interval_ms` new timer interval in milliseconds. Maximum value is 6870947 (1:54:30.947).
|
||||
|
||||
#### Returns
|
||||
|
@ -115,8 +124,10 @@ Changes a registered timer's expiry interval.
|
|||
|
||||
#### Example
|
||||
```lua
|
||||
tmr.register(0, 5000, tmr.ALARM_SINGLE, function() print("hey there") end)
|
||||
tmr.interval(0, 3000) -- actually, 3 seconds is better!
|
||||
mytimer = tmr.create()
|
||||
mytimer:register(10000, tmr.ALARM_AUTO, function() print("hey there") end)
|
||||
mytimer:interval(3000) -- actually, 3 seconds is better!
|
||||
mytimer:start()
|
||||
```
|
||||
|
||||
## tmr.now()
|
||||
|
@ -145,15 +156,16 @@ Configures a timer and registers the callback function to call on expiry.
|
|||
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.
|
||||
|
||||
#### Syntax
|
||||
`tmr.register(id/ref, interval_ms, mode, func)`
|
||||
`tmr.register([id/ref], interval_ms, mode, func())`
|
||||
|
||||
#### Parameters
|
||||
- `id`/`ref` timer id (0-6) or object
|
||||
- `id`/`ref` timer id (0-6) or object, obsolete for OO API (→ [`tmr.create()`](#tmrcreate))
|
||||
- `interval_ms` timer interval in milliseconds. Maximum value is 6870947 (1:54:30.947).
|
||||
- `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
|
||||
- `func(timer)` callback function which is invoked with the timer object as an argument
|
||||
|
||||
Note that registering does *not* start the alarm.
|
||||
|
||||
|
@ -162,8 +174,9 @@ Note that registering does *not* start the alarm.
|
|||
|
||||
#### Example
|
||||
```lua
|
||||
tmr.register(0, 5000, tmr.ALARM_SINGLE, function() print("hey there") end)
|
||||
tmr.start(0)
|
||||
mytimer = tmr.create()
|
||||
mytimer:register(5000, tmr.ALARM_SINGLE, function() print("hey there") end)
|
||||
mytimer:start()
|
||||
```
|
||||
#### See also
|
||||
- [`tmr.create()`](#tmrcreate)
|
||||
|
@ -199,18 +212,19 @@ complex_stuff_which_might_never_call_the_callback(on_success_callback)
|
|||
Starts or restarts a previously configured timer.
|
||||
|
||||
#### Syntax
|
||||
`tmr.start(id/ref)`
|
||||
`tmr.start([id/ref])`
|
||||
|
||||
#### Parameters
|
||||
`id`/`ref` timer id (0-6) or object
|
||||
`id`/`ref` timer id (0-6) or object, obsolete for OO API (→ [`tmr.create()`](#tmrcreate))
|
||||
|
||||
#### Returns
|
||||
`true` if the timer was started, `false` on error
|
||||
|
||||
#### Example
|
||||
```lua
|
||||
tmr.register(0, 5000, tmr.ALARM_SINGLE, function() print("hey there") end)
|
||||
if not tmr.start(0) then print("uh oh") end
|
||||
mytimer = tmr.create()
|
||||
mytimer:register(5000, tmr.ALARM_SINGLE, function() print("hey there") end)
|
||||
if not mytimer:start() then print("uh oh") end
|
||||
```
|
||||
#### See also
|
||||
- [`tmr.create()`](#tmrcreate)
|
||||
|
@ -223,10 +237,10 @@ if not tmr.start(0) then print("uh oh") end
|
|||
Checks the state of a timer.
|
||||
|
||||
#### Syntax
|
||||
`tmr.state(id/ref)`
|
||||
`tmr.state([id/ref])`
|
||||
|
||||
#### Parameters
|
||||
`id`/`ref` timer id (0-6) or object
|
||||
`id`/`ref` timer id (0-6) or object, obsolete for OO API (→ [`tmr.create()`](#tmrcreate))
|
||||
|
||||
#### Returns
|
||||
(bool, int) or `nil`
|
||||
|
@ -235,7 +249,11 @@ If the specified timer is registered, returns whether it is currently started an
|
|||
|
||||
#### Example
|
||||
```lua
|
||||
running, mode = tmr.state(0)
|
||||
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
|
||||
```
|
||||
|
||||
## tmr.stop()
|
||||
|
@ -243,17 +261,18 @@ running, mode = tmr.state(0)
|
|||
Stops a running timer, but does *not* unregister it. A stopped timer can be restarted with [`tmr.start()`](#tmrstart).
|
||||
|
||||
#### Syntax
|
||||
`tmr.stop(id/ref)`
|
||||
`tmr.stop([id/ref])`
|
||||
|
||||
#### Parameters
|
||||
`id`/`ref` timer id (0-6) or object
|
||||
`id`/`ref` timer id (0-6) or object, obsolete for OO API (→ [`tmr.create()`](#tmrcreate))
|
||||
|
||||
#### Returns
|
||||
`true` if the timer was stopped, `false` on error
|
||||
|
||||
#### Example
|
||||
```lua
|
||||
if not tmr.stop(2) then print("timer 2 not stopped, not registered?") end
|
||||
mytimer = tmr.create()
|
||||
if not mytimer:stop() then print("timer not stopped, not registered?") end
|
||||
```
|
||||
#### See also
|
||||
- [`tmr.register()`](#tmrregister)
|
||||
|
@ -285,10 +304,10 @@ Stops the timer (if running) and unregisters the associated callback.
|
|||
This isn't necessary for one-shot timers (`tmr.ALARM_SINGLE`), as those automatically unregister themselves when fired.
|
||||
|
||||
#### Syntax
|
||||
`tmr.unregister(id/ref)`
|
||||
`tmr.unregister([id/ref])`
|
||||
|
||||
#### Parameters
|
||||
`id`/`ref` timer id (0-6) or object
|
||||
`id`/`ref` timer id (0-6) or object, obsolete for OO API (→ [`tmr.create()`](#tmrcreate))
|
||||
|
||||
#### Returns
|
||||
`nil`
|
||||
|
|
|
@ -77,11 +77,11 @@ For this purpose, the ws2812 library offers a read/write buffer. This buffer has
|
|||
Led chaser with a RGBW strip
|
||||
```lua
|
||||
ws2812.init()
|
||||
local i, buffer = 0, ws2812.newBuffer(300, 4); buffer:fill(0, 0, 0, 0); tmr.alarm(0, 50, 1, function()
|
||||
i=i+1
|
||||
buffer:fade(2)
|
||||
buffer:set(i%buffer:size()+1, 0, 0, 0, 255)
|
||||
ws2812.write(buffer)
|
||||
local i, buffer = 0, ws2812.newBuffer(300, 4); buffer:fill(0, 0, 0, 0); tmr.create():alarm(50, 1, function()
|
||||
i = i + 1
|
||||
buffer:fade(2)
|
||||
buffer:set(i % buffer:size() + 1, 0, 0, 0, 255)
|
||||
ws2812.write(buffer)
|
||||
end)
|
||||
```
|
||||
|
||||
|
|
|
@ -62,11 +62,11 @@ print("Connecting to WiFi access point...")
|
|||
wifi.setmode(wifi.STATION)
|
||||
wifi.sta.config(SSID, PASSWORD)
|
||||
-- wifi.sta.connect() not necessary because config() uses auto-connect=true by default
|
||||
tmr.alarm(1, 1000, 1, function()
|
||||
tmr.create():alarm(1000, tmr.ALARM_AUTO, function(cb_timer)
|
||||
if wifi.sta.getip() == nil then
|
||||
print("Waiting for IP address...")
|
||||
else
|
||||
tmr.stop(1)
|
||||
cb_timer:unregister()
|
||||
print("WiFi connection established, IP address: " .. wifi.sta.getip())
|
||||
print("You have 3 seconds to abort")
|
||||
print("Waiting...")
|
||||
|
|
Loading…
Reference in New Issue