Commit c8ac5cfb authored by Arnim Läuger's avatar Arnim Läuger Committed by GitHub
Browse files

Merge pull request #1980 from nodemcu/dev

2.1.0 master drop
parents 22e1adc4 787379f0
# CJSON Module
| Since | Origin / Contributor | Maintainer | Source |
| :----- | :-------------------- | :---------- | :------ |
| 2015-03-16 | [Mark Pulford](http://kyne.com.au/~mark/software/lua-cjson.php), [Zeroday](https://github.com/funshine) | [Zeroday](https://github.com/funshine) | [cjson](../../../app/modules/cjson.c) |
The JSON support module. Allows encoding and decoding to/from JSON.
This module has been replaced by [sjson](sjson.md). It provides a superset of functionality. All references to `cjson` can be replaced by `sjson`.
Please note that nested tables can require a lot of memory to encode. To catch out-of-memory errors, use `pcall()`.
## cjson.encode()
Encode a Lua table to a JSON string. For details see the [documentation of the original Lua library](http://kyne.com.au/~mark/software/lua-cjson-manual.html#encode).
####Syntax
`cjson.encode(table)`
####Parameters
`table` data to encode
While it also is possible to encode plain strings and numbers rather than a table, it is not particularly useful to do so.
####Returns
JSON string
####Example
```lua
ok, json = pcall(cjson.encode, {key="value"})
if ok then
print(json)
else
print("failed to encode!")
end
```
## cjson.decode()
Decode a JSON string to a Lua table. For details see the [documentation of the original Lua library](http://kyne.com.au/~mark/software/lua-cjson-manual.html#_decode).
####Syntax
`cjson.decode(str)`
####Parameters
`str` JSON string to decode
####Returns
Lua table representation of the JSON data
####Example
```lua
t = cjson.decode('{"key":"value"}')
for k,v in pairs(t) do print(k,v) end
```
......@@ -7,7 +7,7 @@ The file module provides access to the file system and its individual files.
The file system is a flat file system, with no notion of subdirectories/folders.
Besides the SPIFFS file system on internal flash, this module can also access FAT partitions on an external SD card is [FatFS is enabled](../sdcard.md).
Besides the SPIFFS file system on internal flash, this module can also access FAT partitions on an external SD card if [FatFS is enabled](../sdcard.md).
```lua
-- open file in flash:
......@@ -32,6 +32,10 @@ Change current directory (and drive). This will be used when no drive/directory
Current directory defaults to the root of internal SPIFFS (`/FLASH`) after system start.
!!! note
Function is only available when [FatFS support](../sdcard.md#enabling-fatfs) is compiled into the firmware.
#### Syntax
`file.chdir(dir)`
......@@ -73,7 +77,9 @@ end
Format the file system. Completely erases any existing file system and writes a new one. Depending on the size of the flash chip in the ESP, this may take several seconds.
Not supported for SD cards.
!!! note
Function is not supported for SD cards.
#### Syntax
`file.format()`
......@@ -91,7 +97,9 @@ none
Returns the flash address and physical size of the file system area, in bytes.
Not supported for SD cards.
!!! note
Function is not supported for SD cards.
#### Syntax
`file.fscfg()`
......@@ -156,7 +164,9 @@ end
Mounts a FatFs volume on SD card.
Not supported for internal flash.
!!! note
Function is only available when [FatFS support](../sdcard.md#enabling-fatfs) is compiled into the firmware and it is not supported for internal flash.
#### Syntax
`file.mount(ldrv[, pin])`
......@@ -217,7 +227,7 @@ When done with the file, it must be closed using `file.close()`.
`file.open(filename, mode)`
#### Parameters
- `filename` file to be opened, directories are not supported
- `filename` file to be opened
- `mode`:
- "r": read mode (the default)
- "w": write mode
......@@ -248,8 +258,8 @@ end
```
#### See also
- [`file.close()`](#fileclose)
- [`file.readline()`](#filereadline)
- [`file.close()`](#fileclose-fileobjclose)
- [`file.readline()`](#filereadline-fileobjreadline)
## file.remove()
......@@ -296,17 +306,19 @@ file.rename("temp.lua","init.lua")
## file.stat()
Get attribtues of a file or directory in a table:
Get attribtues of a file or directory in a table. Elements of the table are:
- `size` file size in bytes
- `name` file name
- `time` table with time stamp information. Default is 1970-01-01 00:00:00 in case time stamps are not supported (on SPIFFS).
- `year`
- `mon`
- `day`
- `hour`
- `min`
- `sec`
- `is_dir` flag `true` if item is a directory, otherwise `false`
- `is_rdonly` flag `true` if item is read-only, otherwise `false`
- `is_hidden` flag `true` if item is hidden, otherwise `false`
......@@ -387,8 +399,7 @@ end
The maximum number of open files on SPIFFS is determined at compile time by `SPIFFS_MAX_OPEN_FILES` in `user_config.h`.
## file.close()
## file.obj:close()
## file.close(), file.obj:close()
Closes the open file, if any.
......@@ -406,10 +417,9 @@ none
#### See also
[`file.open()`](#fileopen)
## file.flush()
## file.obj:flush()
## file.flush(), file.obj:flush()
Flushes any pending writes to the file system, ensuring no data is lost on a restart. Closing the open file using [`file.close()` / `fd:close()`](#fileclose) performs an implicit flush as well.
Flushes any pending writes to the file system, ensuring no data is lost on a restart. Closing the open file using [`file.close()` / `fd:close()`](#fileclose-fileobjclose) performs an implicit flush as well.
#### Syntax
`file.flush()`
......@@ -436,10 +446,9 @@ end
```
#### See also
[`file.close()` / `file.obj:close()`](#fileclose)
[`file.close()` / `file.obj:close()`](#fileclose-fileobjclose)
## file.read()
## file.obj:read()
## file.read(), file.obj:read()
Read content from the open file.
......@@ -482,10 +491,9 @@ end
#### See also
- [`file.open()`](#fileopen)
- [`file.readline()` / `file.obj:readline()`](#filereadline)
- [`file.readline()` / `file.obj:readline()`](#filereadline-fileobjreadline)
## file.readline()
## file.obj:readline()
## file.readline(), file.obj:readline()
Read the next line from the open file. Lines are defined as zero or more bytes ending with a EOL ('\n') byte. If the next line is longer than 1024, this function only returns the first 1024 bytes.
......@@ -511,12 +519,11 @@ end
#### See also
- [`file.open()`](#fileopen)
- [`file.close()` / `file.obj:close()`](#fileclose)
- [`file.read()` / `file.obj:read()`](#fileread)
- [`file.close()` / `file.obj:close()`](#fileclose-fileobjclose)
- [`file.read()` / `file.obj:read()`](#fileread-fileobjread)
## file.seek()
## file.obj:seek()
## file.seek(), file.obj:seek()
Sets and gets the file position, measured from the beginning of the file, to the position given by offset plus a base specified by the string whence.
......@@ -549,8 +556,7 @@ end
#### See also
[`file.open()`](#fileopen)
## file.write()
## file.obj:write()
## file.write(), file.obj:write()
Write a string to the open file.
......@@ -588,10 +594,9 @@ end
#### See also
- [`file.open()`](#fileopen)
- [`file.writeline()` / `file.obj:writeline()`](#filewriteline)
- [`file.writeline()` / `file.obj:writeline()`](#filewriteline-fileobjwriteline)
## file.writeline()
## file.obj:writeline()
## file.writeline(), file.obj:writeline()
Write a string to the open file and append '\n' at the end.
......@@ -618,4 +623,4 @@ end
#### See also
- [`file.open()`](#fileopen)
- [`file.readline()` / `file.obj:readline()`](#filereadline)
- [`file.readline()` / `file.obj:readline()`](#filereadline-fileobjreadline)
# HDC1080 Module
| Since | Origin / Contributor | Maintainer | Source |
| :----- | :-------------------- | :---------- | :------ |
| 2017-04-01 | [Metin KOC](https://github.com/saucompeng) | [Metin KOC](https://github.com/saucompeng) | [hdc1080.c](../../../app/modules/hdc1080.c)|
This module provides access to the [HDC1080](http://www.ti.com/product/HDC1080) low power, high accuracy digital humidity sensor with temperature sensor.
## hdc1080.read()
Samples the sensor then returns temperature and humidity value.
#### Syntax
`hdc1080.read()`
#### Returns
Temperature data in centigrade and humidity data in percentage (0-100) (integer/float)
#### Example
```lua
local sda, scl = 1, 2
i2c.setup(0, sda, scl, i2c.SLOW) -- call i2c.setup() only once
hdc1080.setup()
local temperature,humidity = hdc1080.read()
print(temperature)
print(humidity)
```
## hdc1080.setup()
Initializes the module.
#### Syntax
`hdc1080.setup()`
#### Parameters
- None
#### Returns
`nil`
## hdc1080.init(sda,scl)
Initializes the module and sets the pin configuration.
!!! attention
This function is deprecated and will be removed in upcoming releases. Use `hdc1080.setup()` instead.
#### Syntax
`hdc1080.init(sda, scl)`
#### Parameters
- `sda` data pin
- `scl` clock pin
#### Returns
`nil`
......@@ -11,7 +11,7 @@ Setup I²C address and read/write mode for the next transfer.
#### Parameters
- `id` always 0
- `device_addr` device address
- `device_addr` 7-bit device address, remember that [in I²C `device_addr` represents the upper 7 bits](http://www.nxp.com/documents/user_manual/UM10204.pdf#page=13) followed by a single `direction` bit
- `direction` `i2c.TRANSMITTER` for writing mode , `i2c. RECEIVER` for reading mode
#### Returns
......
......@@ -18,7 +18,7 @@ Creates a MQTT client.
- `keepalive` keepalive seconds
- `username` user name
- `password` user password
- `cleansession` 0/1 for `false`/`true`
- `cleansession` 0/1 for `false`/`true`. Default is 1 (`true`).
#### Returns
MQTT client
......@@ -48,18 +48,22 @@ m:on("message", function(client, topic, data)
end)
-- for TLS: m:connect("192.168.11.118", secure-port, 1)
m:connect("192.168.11.118", 1883, 0, function(client) print("connected") end,
function(client, reason) print("failed reason: "..reason) end)
-- Calling subscribe/publish only makes sense once the connection
-- was successfully established. In a real-world application you want
-- move those into the 'connect' callback or make otherwise sure the
-- connection was established.
-- subscribe topic with qos = 0
m:subscribe("/topic",0, function(client) print("subscribe success") end)
-- publish a message with data = hello, QoS = 0, retain = 0
m:publish("/topic","hello",0,0, function(client) print("sent") end)
m:connect("192.168.11.118", 1883, 0, function(client)
print("connected")
-- Calling subscribe/publish only makes sense once the connection
-- was successfully established. You can do that either here in the
-- 'connect' callback or you need to otherwise make sure the
-- connection was established (e.g. tracking connection status or in
-- m:on("connect", function)).
-- subscribe topic with qos = 0
client:subscribe("/topic", 0, function(client) print("subscribe success") end)
-- publish a message with data = hello, QoS = 0, retain = 0
client:publish("/topic", "hello", 0, 0, function(client) print("sent") end)
end,
function(client, reason)
print("failed reason: " .. reason)
end)
m:close();
-- you can call m:connect again
......@@ -92,13 +96,41 @@ Connects to the broker specified by the given host, port, and secure options.
- `host` host, domain or IP (string)
- `port` broker port (number), default 1883
- `secure` 0/1 for `false`/`true`, default 0. Take note of constraints documented in the [net module](net.md).
- `autoreconnect` 0/1 for `false`/`true`, default 0
- `autoreconnect` 0/1 for `false`/`true`, default 0. This option is *deprecated*.
- `function(client)` callback function for when the connection was established
- `function(client, reason)` callback function for when the connection could not be established
- `function(client, reason)` callback function for when the connection could not be established. No further callbacks should be called.
#### Returns
`true` on success, `false` otherwise
#### Notes
Don't use `autoreconnect`. Let me repeat that, don't use `autoreconnect`. You should handle the errors explicitly and appropriately for
your application. In particular, the default for `cleansession` above is `true`, so all subscriptions are destroyed when the connection
is lost for any reason.
In order to acheive a consistent connection, handle errors in the error callback. For example:
```
function handle_mqtt_error(client, reason)
tmr.create():alarm(10 * 1000, tmr.ALARM_SINGLE, do_mqtt_connect)
end
function do_mqtt_connect()
mqtt:connect("server", function(client) print("connected") end, handle_mqtt_error)
end
```
In reality, the connected function should do something useful!
This is the description of how the `autoreconnect` functionality may (or may not) work.
> When `autoreconnect` is set, then the connection will be re-established when it breaks. No error indication will be given (but all the
> subscriptions may be lost if `cleansession` is true). However, if the
> very first connection fails, then no reconnect attempt is made, and the error is signalled through the callback (if any). The first connection
> is considered a success if the client connects to a server and gets back a good response packet in response to its MQTT connection request.
> This implies (for example) that the username and password are correct.
#### Connection failure callback reason codes:
| Constant | Value | Description |
......
......@@ -13,11 +13,11 @@ Constants to be used in other functions: `net.TCP`, `net.UDP`
Creates a client.
#### Syntax
`net.createConnection(type, secure)`
`net.createConnection([type[, secure]])`
#### Parameters
- `type` `net.TCP` or `net.UDP`. UDP connections chained to [net.createUDPSocket()](#netcreateudpsocket)
- `secure` 1 for encrypted, 0 for plain. Secure connections chained to [tls.createConnection()](tls.md#tlscreateconnection)
- `type` `net.TCP` (default) or `net.UDP`
- `secure` 1 for encrypted, 0 for plain (default)
!!! attention
This will change in upcoming releases so that `net.createConnection` will always create an unencrypted TCP connection.
......@@ -44,11 +44,11 @@ net.createConnection(net.TCP, 0)
Creates a server.
#### Syntax
`net.createServer(type, timeout)`
`net.createServer([type[, timeout]])`
#### Parameters
- `type` `net.TCP` or `net.UDP`. UDP connections chained to [net.createUDPSocket()](#netcreateudpsocket)
- `timeout` for a TCP server timeout is 1~28'800 seconds (for an inactive client to be disconnected)
- `type` `net.TCP` (default) or `net.UDP`
- `timeout` for a TCP server timeout is 1~28'800 seconds, 30 sec by default (for an inactive client to be disconnected)
!!! attention
The `type` parameter will be removed in upcoming releases so that `net.createServer` will always create a TCP-based server. For UDP use [net.createUDPSocket()](#netcreateudpsocket) instead.
......@@ -318,12 +318,31 @@ Otherwise, all connection errors (with normal close) passed to disconnection eve
```lua
srv = net.createConnection(net.TCP, 0)
srv:on("receive", function(sck, c) print(c) end)
-- Wait for connection before sending.
srv:on("connection", function(sck, c)
-- Wait for connection before sending.
sck:send("GET /get HTTP/1.1\r\nHost: httpbin.org\r\nConnection: keep-alive\r\nAccept: */*\r\n\r\n")
-- 'Connection: close' rather than 'Connection: keep-alive' to have server
-- initiate a close of the connection after final response (frees memory
-- earlier here), https://tools.ietf.org/html/rfc7230#section-6.6
sck:send("GET /get HTTP/1.1\r\nHost: httpbin.org\r\nConnection: close\r\nAccept: */*\r\n\r\n")
end)
srv:connect(80,"httpbin.org")
```
!!! note
The `receive` event is fired for every network frame! Hence, if the data sent to the device exceeds 1460 bytes (derived from [Ethernet frame size](https://en.wikipedia.org/wiki/Ethernet_frame)) it will fire more than once. There may be other situations where incoming data is split across multiple frames (e.g. HTTP POST with `multipart/form-data`). You need to manually buffer the data and find means to determine if all data was received.
```lua
local buffer = nil
srv:on("receive", function(sck, c)
if buffer == nil then
buffer = c
else
buffer = buffer .. c
end
end)
-- throttling could be implemented using socket:hold()
-- example: https://github.com/nodemcu/nodemcu-firmware/blob/master/lua_examples/pcm/play_network.lua#L83
```
#### See also
- [`net.createServer()`](#netcreateserver)
......@@ -400,6 +419,29 @@ end)
#### See also
[`net.socket:on()`](#netsocketon)
## net.socket:ttl()
Changes or retrieves Time-To-Live value on socket.
#### Syntax
`ttl([ttl])`
#### Parameters
- `ttl` (optional) new time-to-live value
#### Returns
current / new ttl value
#### Example
```lua
sk = net.createConnection(net.TCP, 0)
sk:connect(80, '192.168.1.1')
sk:ttl(1) -- restrict frames to single subnet
```
#### See also
[`net.createConnection()`](#netcreateconnection)
## net.socket:unhold()
Unblock TCP receiving data by revocation of a preceding `hold()`.
......@@ -492,6 +534,12 @@ Retrieve local port and ip of socket.
The syntax and functional identical to [`net.socket:getaddr()`](#netsocketgetaddr).
## net.udpsocket:ttl()
Changes or retrieves Time-To-Live value on socket.
The syntax and functional identical to [`net.socket:ttl()`](#netsocketttl).
# net.dns Module
## net.dns.getdnsserver()
......
......@@ -95,7 +95,7 @@ Firmware from before 05 Jan 2016 have a maximum sleeptime of ~35 minutes.
This function can only be used in the condition that esp8266 PIN32(RST) and PIN8(XPD_DCDC aka GPIO16) are connected together. Using sleep(0) will set no wake up timer, connect a GPIO to pin RST, the chip will wake up by a falling-edge on pin RST.
#### Syntax
`node.dsleep(us, option)`
`node.dsleep(us, option, instant)`
#### Parameters
- `us` number (integer) or `nil`, sleep time in micro second. If `us == 0`, it will sleep forever. If `us == nil`, will not set sleep time.
......@@ -107,6 +107,10 @@ Firmware from before 05 Jan 2016 have a maximum sleeptime of ~35 minutes.
- 1, RF_CAL after deep-sleep wake up, there will be large current
- 2, no RF_CAL after deep-sleep wake up, there will only be small current
- 4, disable RF after deep-sleep wake up, just like modem sleep, there will be the smallest current
- `instant` number (integer) or `nil`. If present and non-zero, do not use
the normal grace time before entering deep sleep. This is a largely
undocumented feature, and is only briefly mentioned in Espressif's
[low power solutions](https://espressif.com/sites/default/files/documentation/9b-esp8266_low_power_solutions_en.pdf#page=10) document (chapter 4.5).
#### Returns
`nil`
......@@ -123,6 +127,11 @@ node.dsleep(1000000, 4)
node.dsleep(nil,4)
```
#### See also
- [`wifi.suspend()`](wifi.md#wifisuspend)
- [`wifi.resume()`](wifi.md#wifiresume)
- [`node.sleep()`](#nodesleep)
## node.flashid()
Returns the flash chip ID.
......@@ -280,7 +289,9 @@ none
## node.restore()
Restores system configuration to defaults using the SDK function `system_restore()`, which doesn't document precisely what it erases/restores.
Restores system configuration to defaults using the SDK function `system_restore()`, which is described in the documentation as:
> Reset default settings of following APIs: `wifi_station_set_auto_connect`, `wifi_set_phy_mode`, `wifi_softap_set_config` related, `wifi_station_set_config` related, `wifi_set_opmode`, and APs’ information recorded by `#define AP_CACHE`.
#### Syntax
`node.restore()`
......@@ -315,6 +326,71 @@ target CPU frequency (number)
node.setcpufreq(node.CPU80MHZ)
```
## node.sleep()
Put NodeMCU in light sleep mode to reduce current consumption.
* NodeMCU can not enter light sleep mode if wifi is suspended.
* All active timers will be suspended and then resumed when NodeMCU wakes from sleep.
* Any previously suspended timers will be resumed when NodeMCU wakes from sleep.
#### Syntax
`node.sleep({wake_gpio[, duration, int_type, resume_cb, preserve_mode]})`
#### Parameters
- `duration` Sleep duration in microseconds(μs). If a sleep duration of `0` is specified, suspension will be indefinite (Range: 0 or 50000 - 268435454 μs (0:4:28.000454))
- `wake_pin` 1-12, pin to attach wake interrupt to. Note that pin 0(GPIO 16) does not support interrupts.
- If sleep duration is indefinite, `wake_pin` must be specified
- Please refer to the [`GPIO module`](gpio.md) for more info on the pin map.
- `int_type` type of interrupt that you would like to wake on. (Optional, Default: `node.INT_LOW`)
- valid interrupt modes:
- `node.INT_UP` Rising edge
- `node.INT_DOWN` Falling edge
- `node.INT_BOTH` Both edges
- `node.INT_LOW` Low level
- `node.INT_HIGH` High level
- `resume_cb` Callback to execute when WiFi wakes from suspension. (Optional)
- `preserve_mode` preserve current WiFi mode through node sleep. (Optional, Default: true)
- If true, Station and StationAP modes will automatically reconnect to previously configured Access Point when NodeMCU resumes.
- If false, discard WiFi mode and leave NodeMCU in `wifi.NULL_MODE`. WiFi mode will be restored to original mode on restart.
#### Returns
- `nil`
#### Example
```lua
--Put NodeMCU in light sleep mode indefinitely with resume callback and wake interrupt
cfg={}
cfg.wake_pin=3
cfg.resume_cb=function() print("WiFi resume") end
node.sleep(cfg)
--Put NodeMCU in light sleep mode with interrupt, resume callback and discard WiFi mode
cfg={}
cfg.wake_pin=3 --GPIO0
cfg.resume_cb=function() print("WiFi resume") end
cfg.preserve_mode=false
node.sleep(cfg)
--Put NodeMCU in light sleep mode for 10 seconds with resume callback
cfg={}
cfg.duration=10*1000*1000
cfg.resume_cb=function() print("WiFi resume") end
node.sleep(cfg)
```
#### See also
- [`wifi.suspend()`](wifi.md#wifisuspend)
- [`wifi.resume()`](wifi.md#wifiresume)
- [`node.dsleep()`](#nodedsleep)
## node.stripdebug()
Controls the amount of debug information kept during [`node.compile()`](#nodecompile), and allows removal of debug information from already compiled Lua code.
......
......@@ -137,7 +137,7 @@ Issues a 1-Wire rom select command. Make sure you do the `ow.reset(pin)` first.
#### Parameters
- `pin` 1~12, I/O index
- `rom` string value, len 8, rom code of the salve device
- `rom` string value, len 8, rom code of the slave device
#### Returns
`nil`
......@@ -247,7 +247,7 @@ Writes a byte. If `power` is 1 then the wire is held high at the end for parasit
#### Parameters
- `pin` 1~12, I/O index
- `v` byte to be written to salve device
- `v` byte to be written to slave device
- `power` 1 for wire being held high for parasitically powered devices
#### Returns
......
......@@ -4,6 +4,7 @@
| 2015-06-26 | [DiUS](https://github.com/DiUS), [Johny Mattsson](https://github.com/jmattsson), Bernd Meyer <bmeyer@dius.com.au> | [Johny Mattsson](https://github.com/jmattsson) | [rtcfifo.c](../../../app/modules/rtcfifo.c)|
The rtcfifo module implements a first-in,first-out storage intended for sensor readings. As the name suggests, it is backed by the [RTC](https://en.wikipedia.org/wiki/Real-time_clock) user memory and as such survives deep sleep cycles. Conceptually it can be thought of as a cyclic array of `{ timestamp, name, value }` tuples. Internally it uses a space-optimized storage format to allow the greatest number of samples to be kept. This comes with several trade-offs, and as such is not a one-solution-fits-all. Notably:
- Timestamps are stored with second-precision.
- Sample frequency must be at least once every 8.5 minutes. This is a side-effect of delta-compression being used for the time stamps.
- Values are limited to 16 bits of precision, but have a separate field for storing an E<sup>-n</sup> multiplier. This allows for high fidelity even when working with very small values. The effective range is thus 1E<sup>-7</sup> to 65535.
......@@ -110,17 +111,13 @@ This function takes an optional configuration table as an argument. The followin
```lua
-- Initialize with default values
rtcfifo.prepare()
```
```lua
-- Use RTC slots 19 and up for variable storage
rtcfifo.prepare({storage_begin=21, storage_end=128})
```
####See also
[`rtcfifo.ready()`](#rtcfifoready)
####See also
[`rtcfifo.prepare()`](#rtcfifoprepare)
- [`rtcfifo.ready()`](#rtcfifoready)
- [`rtcfifo.prepare()`](#rtcfifoprepare)
## rtcfifo.put()
......
# Si7021 Module
| Since | Origin / Contributor | Maintainer | Source |
| :----- | :-------------------- | :---------- | :------ |
| 2017-04-19 | [fetchbot](https://github.com/fetchbot) | [fetchbot](https://github.com/fetchbot) | [si7021.c](../../../app/modules/si7021.c)|
This module provides access to the Si7021 humidity and temperature sensor.
## si7021.firmware()
Read the internal firmware revision of the Si7021 sensor.
#### Syntax
`si7021.firmware()`
#### Parameters
none
#### Returns
`fwrev` Firmware version
* `0xFF` Firmware version 1.0
* `0x20` Firmware version 2.0
#### Example
```lua
local sda, scl = 6, 5
i2c.setup(0, sda, scl, i2c.SLOW) -- call i2c.setup() only once
si7021.setup()
fwrev = si7021.firmware()
print(string.format("FW: %X\r\n", fwrev))
```
## si7021.read()
#### Syntax
`si7021.read()`
#### Parameters
none
#### Returns
- `hum` humidity (see note below)
- `temp` temperature (see note below)
- `hum_dec` humidity decimal
- `temp_dec` temperature decimal
!!! note
If using float firmware then `hum` and `temp` are floating point numbers. On an integer firmware, the final values have to be concatenated from `hum` and `hum_dec` / `temp` and `temp_dec`.
#### Example
```lua
local sda, scl = 6, 5
i2c.setup(0, sda, scl, i2c.SLOW) -- call i2c.setup() only once
si7021.setup()
hum, temp, hum_dec, temp_dec = si7021.read()
-- Integer firmware using this example
print(string.format("Humidity:\t\t%d.%03d\nTemperature:\t%d.%03d\n", hum, hum_dec, temp, temp_dec))
-- Float firmware using this example
print("Humidity: "..hum.."\n".."Temperature: "..temp)
```
## si7021.serial()
Read the individualized 64-bit electronic serial number of the Si7021 sensor.
#### Syntax
`si7021.serial()`
#### Parameters
none
#### Returns
- `sna` 32-bit serial number part a
- `snb` 32-bit serial number part b, upper byte contains the device identification
* `0x00` or `0xFF` engineering samples
* `0x0D` `13` Si7013
* `0x14` `20` Si7020
* `0x15` `21` Si7021
#### Example
```lua
local sda, scl = 6, 5
i2c.setup(0, sda, scl, i2c.SLOW) -- call i2c.setup() only once
si7021.setup()
sna, snb = si7021.serial()
print(string.format("SN:\t\t%X%X\nDevice:\tSi70%d", sna, snb, bit.rshift(snb,24)))
```
## si7021.setting()
Settings for the sensors configuration register to adjust measurement resolution, on-chip heater and read the supply voltage status.
#### Syntax
`si7021.setting(RESOLUTION[, HEATER, HEATER_SETTING])`
#### Parameters
- `RESOLUTION`
* `si7021.RH12_TEMP14` Relative Humidity 12 bit - Temperature 14 bit (default)
* `si7021.RH08_TEMP12` Relative Humidity 8 bit - Temperature 12 bit
* `si7021.RH10_TEMP13` Relative Humidity 10 bit - Temperature 13 bit
* `si7021.RH11_TEMP11` Relative Humidity 11 bit - Temperature 11 bit
- `HEATER` optional
* `si7021.HEATER_ENABLE` On-chip Heater Enable
* `si7021.HEATER_DISABLE` On-chip Heater Disable (default)
- `HEATER_SETTING` optional
* `0x00` - `0x0F` 3.09 mA - 94.20 mA
#### Returns
- `resolution`
* `0` Relative Humidity 12 bit - Temperature 14 bit
* `1` Relative Humidity 8 bit - Temperature 12 bit
* `2` Relative Humidity 10 bit - Temperature 13 bit
* `3` Relative Humidity 11 bit - Temperature 11 bit
- `vdds`
* `0` VDD OK (1.9V - 3.6V)
* `1` VDD LOW (1.8V - 1.9V)
- `heater`
* `0` Disabled
* `1` Enabled
- `heater_setting`
* `0` - `15`
#### Example
```lua
local id, sda, scl = 0, 6, 5
i2c.setup(id, sda, scl, i2c.SLOW) -- call i2c.setup() only once
si7021.setup()
res, vdds, heater, heater_set = si7021.setting(si7021.RH12_TEMP14)
res, vdds, heater, heater_set = si7021.setting(si7021.RH12_TEMP14, si7021.HEATER_ENABLE, 0x01)
```
## si7021.setup()
Initializes the device on fixed I²C device address (0x40).
#### Syntax
`si7021.setup()`
#### Parameters
none
#### Returns
`nil`
#### Example
```lua
local sda, scl = 6, 5
i2c.setup(0, sda, scl, i2c.SLOW) -- call i2c.setup() only once
si7021.setup()
```
# SJSON Module
| Since | Origin / Contributor | Maintainer | Source |
| :----- | :-------------------- | :---------- | :------ |
| 2017-02-01 | [Philip Gladstone](https://github.com/pjsg) | [Philip Gladstone](https://github.com/pjsg) | [sjson](../../../app/modules/sjson.c) |
The JSON support module. Allows encoding and decoding to/from JSON.
Please note that nested tables can require a lot of memory to encode. To catch out-of-memory errors, use `pcall()`.
This code using the streaming json library [jsonsl](https://github.com/mnunberg/jsonsl) to do the parsing of the string.
This module can be used in two ways. The simpler way is to use it as a direct drop-in for cjson (you can just do `_G.cjson = sjson`).
The more advanced approach is to use the streaming interface. This allows encoding and decoding of significantly larger objects.
The handling of json null is as follows:
- By default, the decoder represents null as sjson.NULL (which is a userdata object). This is the behavior of cjson.
- The encoder always converts any userdata object into null.
- Optionally, a single string can be specified in both the encoder and decoder. This string will be used in encoding/decoding to represent json null values. This string should not be used
anywhere else in your data structures. A suitable value might be `"\0"`.
When encoding a lua object, if a function is found, then it is invoked (with no arguments) and the (single) returned value is encoded in the place of the function.
## sjson.encoder()
This creates an encoder object that can convert a LUA object into a JSON encoded string.
####Syntax
`sjson.encoder(table [, opts])`
####Parameters
- `table` data to encode
- `opts` an optional table of options. The possible entries are:
- `depth` the maximum encoding depth needed to encode the table. The default is 20 which should be enough for nearly all situations.
- `null` the string value to treat as null.
####Returns
A `sjson.encoder` object.
## sjson.encoder:read
This gets a chunk of JSON encoded data.
####Syntax
`encoder:read([size])`
####Parameters
- `size` an optional value for the number of bytes to return. The default is 1024.
####Returns
A string of up to `size` bytes, or `nil` if the encoding is complete and all data has been returned.
#### Example
The following example prints out (in 64 byte chunks) a JSON encoded string containing the first 4k of every file in the file system. The total string
can be bigger than the total amount of memory on the NodeMCU.
```
function files()
result = {}
for k,v in pairs(file.list()) do
result[k] = function() return file.open(k):read(4096) end
end
return result
end
local encoder = sjson.encoder(files())
while true do
data = encoder:read(64)
if not data then
break
end
print(data)
end
```
## sjson.encode()
Encode a Lua table to a JSON string. This is a convenience method provided for backwards compatibility with `cjson`.
####Syntax
`sjson.encode(table [, opts])`
####Parameters
- `table` data to encode
- `opts` an optional table of options. The possible entries are:
- `depth` the maximum encoding depth needed to encode the table. The default is 20 which should be enough for nearly all situations.
- `null` the string value to treat as null.
####Returns
JSON string
####Example
```lua
ok, json = pcall(sjson.encode, {key="value"})
if ok then
print(json)
else
print("failed to encode!")
end
```
## sjson.decoder()
This makes a decoder object that can parse a JSON encoded string into a lua object. A metatable can be specified for all the newly created lua tables. This allows
you to handle each value as it is inserted into each table (by implementing the `__newindex` method).
####Syntax
`sjson.decoder([opts])`
#### Parameters
- `opts` an optional table of options. The possible entries are:
- `depth` the maximum encoding depth needed to encode the table. The default is 20 which should be enough for nearly all situations.
- `null` the string value to treat as null.
- `metatable` a table to use as the metatable for all the new tables in the returned object.
#### Returns
A `sjson.decoder` object
####Metatable
There are two principal methods that are invoked in the metatable (if it is present).
- `__newindex` this is the standard method invoked whenever a new table element is created.
- `checkpath` this is invoked (if defined) whenever a new table is created. It is invoked with two arguments:
- `table` this is the newly created table
- `path` this is a list of the keys from the root.
It must return `true` if this object is wanted in the result, or `false` otherwise.
For example, when decoding `{ "foo": [1, 2, []] }` the checkpath will be invoked as follows:
- `checkpath({}, {})` the `table` argument is the object that will correspond with the value of the JSON object.
- `checkpath({}, {"foo"})` the `table` argument is the object that will correspond with the value of the outer JSON array.
- `checkpath({}, {"foo", 3})` the `table` argument is the object that will correspond to the empty inner JSON array.
When the `checkpath` method is called, the metatable has already be associated with the new table. Thus the `checkpath` method can replace it
if desired. For example, if you are decoding `{ "foo": { "bar": [1,2,3,4], "cat": [5] } }` and, for some reason, you did not want to capture the
value of the `"bar"` key, then there are various ways to do this:
* In the `__newindex` metamethod, just check for the value of the key and skip the `rawset` if the key is `"bar"`. This only works if you want to skip all the
`"bar"` keys.
* In the `checkpath` method, if the path is `["foo"]`, then return `false`.
* Use the following `checkpath`: `checkpath=function(tab, path) tab['__json_path'] = path return true end` This will save the path in each constructed object. Now the `__newindex` method can perform more sophisticated filtering.
The reason for being able to filter is that it enables processing of very large JSON responses on a memory constrained platform. Many APIs return lots of information
which would exceed the memory budget of the platform. For example, `https://api.github.com/repos/nodemcu/nodemcu-firmware/contents` is over 13kB, and yet, if
you only need the `download_url` keys, then the total size is around 600B. This can be handled with a simple `__newindex` method.
## sjson.decoder:write
This provides more data to be parsed into the lua object.
####Syntax
`decoder:write(string)`
####Parameters
- `string` the next piece of JSON encoded data
####Returns
The constructed lua object or `nil` if the decode is not yet complete.
####Errors
If a parse error occurrs during this decode, then an error is thrown and the parse is aborted. The object cannot be used again.
## sjson.decoder:result
This gets the decoded lua object, or raises an error if the decode is not yet complete. This can be called multiple times and will return the
same object each time.
####Syntax
`decoder:result()`
####Errors
If the decode is not complete, then an error is thrown.
####Example
```
local decoder = sjson.decoder()
decoder:write("[10, 1")
decoder:write("1")
decoder:write(", \"foo\"]")
for k,v in pairs(decoder:result()) do
print (k, v)
end
```
The next example demonstrates the use of the metatable argument. In this case it just prints out the operations, but it could suppress the assignment
altogether if desired.
```
local decoder = sjson.decoder({metatable=
{__newindex=function(t,k,v) print("Setting '" .. k .. "' = '" .. tostring(v) .."'")
rawset(t,k,v) end}})
decoder:write('[1, 2, {"foo":"bar"}]')
```
## sjson.decode()
Decode a JSON string to a Lua table. This is a convenience method provided for backwards compatibility with `cjson`.
####Syntax
`sjson.decode(str[, opts])`
####Parameters
- `str` JSON string to decode
- `opts` an optional table of options. The possible entries are:
- `depth` the maximum encoding depth needed to encode the table. The default is 20 which should be enough for nearly all situations.
- `null` the string value to treat as null.
- `metatable` a table to use as the metatable for all the new tables in the returned object. See the metatable section in the description of `sjson.decoder()` above.
####Returns
Lua table representation of the JSON data
####Errors
If the string is not valid JSON, then an error is thrown.
####Example
```lua
t = sjson.decode('{"key":"value"}')
for k,v in pairs(t) do print(k,v) end
```
##Constants
There is one constant -- `sjson.NULL` -- which is used in lua structures to represent the presence of a JSON null.
......@@ -10,6 +10,17 @@ For technical details of the underlying hardware refer to [metalphreak's ESP8266
The ESP hardware provides two SPI busses, with IDs 0, and 1, which map to pins generally labelled SPI and HSPI. If you are using any kind of development board which provides flash, then bus ID 0 (SPI) is almost certainly used for communicating with the flash chip. You probably want to choose bus ID 1 (HSPI) for your communication, as you will have uncontended use of it.
HSPI signals are fixed to the following IO indices and GPIO pins:
| Signal | IO index | ESP8266 pin |
|-----------|----------|-------------|
| HSPI CLK | 5 | GPIO14 |
| HSPI /CS | 8 | GPIO15 |
| HSPI MOSI | 7 | GPIO13 |
| HSPI MISO | 6 | GPIO12 |
See also [spi.setup()](#spisetup).
## High Level Functions
The high level functions provide a send & receive API for half- and
full-duplex mode. Sent and received data items are restricted to 1 - 32 bit
......@@ -86,6 +97,8 @@ _, _, x = spi.send(1, 0, {255, 255, 255})
Set up the SPI configuration.
Refer to [Serial Peripheral Interface Bus](https://en.wikipedia.org/wiki/Serial_Peripheral_Interface_Bus#Clock_polarity_and_phase) for details regarding the clock polarity and phase definition.
Calling `spi.setup()` will route the HSPI signals to the related pins, overriding previous configuration and control by the `gpio` module. It is possible to revert any pin back to gpio control if its HSPI functionality is not needed, just set the desired `gpio.mode()` for it. This is recommended especially for the HSPI /CS pin function in case that SPI slave-select is driven from a different pin by `gpio.write()` - the SPI engine would toggle pin 8 otherwise.
#### Syntax
`spi.setup(id, mode, cpol, cpha, databits, clock_div[, duplex_mode])`
......@@ -109,6 +122,13 @@ Refer to [Serial Peripheral Interface Bus](https://en.wikipedia.org/wiki/Serial_
#### Returns
Number: 1
#### Example
```lua
spi.setup(1, spi.MASTER, spi.CPOL_LOW, spi.CPHA_LOW, 8, 8)
-- we won't be using the HSPI /CS line, so disable it again
gpio.mode(8, gpio.INPUT, gpio.PULLUP)
```
## Low Level Hardware Functions
The low level functions provide a hardware-centric API for application
scenarios that need to excercise more complex SPI transactions. The
......@@ -119,7 +139,10 @@ transactions are initiated with full control over the hardware features.
Extract data items from MISO buffer after `spi.transaction()`.
#### Syntax
`data1[, data2[, ..., datan]] = spi.get_miso(id, offset, bitlen, num)`
```lua
data1[, data2[, ..., datan]] = spi.get_miso(id, offset, bitlen, num)
string = spi.get_miso(id, num)
```
#### Parameters
- `id` SPI ID number: 0 for SPI, 1 for HSPI
......@@ -128,7 +151,7 @@ Extract data items from MISO buffer after `spi.transaction()`.
- `num` number of data items to retrieve
####Returns
`num` data items
`num` data items or `string`
#### See also
[spi.transaction()](#spitransaction)
......@@ -137,13 +160,17 @@ Extract data items from MISO buffer after `spi.transaction()`.
Insert data items into MOSI buffer for `spi.transaction()`.
#### Syntax
`spi.set_mosi(id, offset, bitlen, data1[, data2[, ..., datan]])`
```lua
spi.set_mosi(id, offset, bitlen, data1[, data2[, ..., datan]])
spi.set_mosi(id, string)
```
####Parameters
- `id` SPI ID number: 0 for SPI, 1 for HSPI
- `offset` bit offset into MOSI buffer for inserting data1 and subsequent items
- `bitlen` bit length of data1, data2, ...
- `data` data items where `bitlen` number of bits are considered for the transaction.
- `string` send data to be copied into MOSI buffer at offset 0, bit length 8
#### Returns
`nil`
......
# TCS34725 module
| Since | Origin / Contributor | Maintainer | Source |
| :----- | :-------------------- | :---------- | :------ |
| 2017-04-02 | [tjhowse](https://github.com/tjhowse) | [tjhowse](https://github.com/tjhowse) | [tcs34725.c](../../../app/modules/tcs34725.c)|
This module provides a simple interface to [TCS34725 colour/light sensors](https://www.adafruit.com/product/1334) (Adafruit).
Note that you must call [`setup()`](#tcs34725setup) before you can start reading values!
## tcs34725.setup()
setupializes module. setupialization is mandatory before values can be read.
#### Syntax
`tcs34725.setup()`
#### Returns
`0` if setup has failed (no sensor connected?), `1` if sensor is TCS34725
#### Example
```lua
tcs34725.setup()
tcs34725.enable(function()
print("TCS34275 Enabled")
clear,red,green,blue=tcs34725.raw()
end)
```
## tcs34725.enable(function())
Enables the sensor. Can be used to wake up after a disable.
#### Syntax
```lua
tcs34725.enable(function()
print("TCS34275 Enabled")
clear,red,green,blue=tcs34725.raw()
end)
```
#### Parameters
A function called when the sensor has finished initialising.
#### Returns
0
## tcs34725.disable()
Disables the sensor. Enables a low-power sleep mode.
#### Syntax
`tcs34725.disable()`
#### Returns
0
## tcs34725.raw()
Reads the clear, red, green and blue values from the sensor.
#### Syntax
`clear,red,green,blue=tcs34725.raw()`
#### Returns
clear, red, green, blue in uint16_t.
## tcs34725.setGain()
Sets the gain of the sensor. Must be called after the sensor is enabled.
#### Syntax
`tcs34725.setGain(gain)`
#### Parameters
|gain|Gain|
|-----|-----------------|
|0x00|TCS34725_GAIN_1X|
|0x01|TCS34725_GAIN_4X|
|0x02|TCS34725_GAIN_16X|
|0x03|TCS34725_GAIN_60X|
#### Returns
0
## tcs34725.setIntegrationTime()
Sets the integration time of the sensor. Must be called after the sensor is enabled.
#### Syntax
`tcs34725.setIntegrationTime(time)`
#### Parameters
|time|Gain|
|-----|-----------------|
|0xFF|TCS34725_INTEGRATIONTIME_2_4MS|
|0xF6|TCS34725_INTEGRATIONTIME_24MS|
|0xD5|TCS34725_INTEGRATIONTIME_101MS|
|0xC0|TCS34725_INTEGRATIONTIME_154MS|
|0x00|TCS34725_INTEGRATIONTIME_700MS|
#### Returns
0
......@@ -148,6 +148,8 @@ srv:on("connection", function(sck, c)
end)
srv:connect(443,"google.com")
```
!!! note
The `receive` event is fired for every network frame! See details at [net.socket:on()](net.md#netsocketon).
#### See also
- [`tls.createConnection()`](#tlscreateconnection)
......
......@@ -62,9 +62,11 @@ Functions supported in timer object:
- [`t:alarm()`](#tmralarm)
- [`t:interval()`](#tmrinterval)
- [`t:register()`](#tmrregister)
- [`t:resume()`](#tmrresume)
- [`t:start()`](#tmrstart)
- [`t:state()`](#tmrstate)
- [`t:stop()`](#tmrstop)
- [`t:suspend()`](#tmrsuspend)
- [`t:unregister()`](#tmrunregister)
#### Parameters
......@@ -182,6 +184,61 @@ mytimer:start()
- [`tmr.create()`](#tmrcreate)
- [`tmr.alarm()`](#tmralarm)
## 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
- [`tmr.suspend()`](#tmrsuspend)
- [`tmr.suspend_all()`](#tmrsuspendall)
- [`tmr.resume_all()`](#tmrresumeall)
## 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
- [`tmr.suspend()`](#tmrsuspend)
- [`tmr.suspend_all()`](#tmrsuspendall)
- [`tmr.resume()`](#tmrresume)
## tmr.softwd()
Provides a simple software watchdog, which needs to be re-armed or disabled before it expires, or the system will be restarted.
......@@ -279,6 +336,67 @@ if not mytimer:stop() then print("timer not stopped, not registered?") end
- [`tmr.stop()`](#tmrstop)
- [`tmr.unregister()`](#tmrunregister)
## tmr.suspend()
Suspend an armed timer.
* 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
- [`tmr.suspend_all()`](#tmrsuspendall)
- [`tmr.resume()`](#tmrresume)
- [`tmr.resume_all()`](#tmrresumeall)
## tmr.suspend_all()
Suspend all currently armed timers.
!!! 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
- [`tmr.suspendl()`](#tmrsuspend)
- [`tmr.resume()`](#tmrresume)
- [`tmr.resume_all()`](#tmrresumeall)
## tmr.time()
Returns the system uptime, in seconds. Limited to 31 bits, after that it wraps around back to zero.
......
......@@ -7,6 +7,10 @@ The [UART](https://en.wikipedia.org/wiki/Universal_asynchronous_receiver/transmi
The default setup for the uart is controlled by build-time settings. The default rate is 115,200 bps. In addition, auto-baudrate detection is enabled for the first two minutes
after platform boot. This will cause a switch to the correct baud rate once a few characters are received. Auto-baudrate detection is disabled when `uart.setup` is called.
!!! important
Although there are two UARTs(0 and 1) available to NodeMCU, **UART 1 is not capable of receiving data and is therefore transmit only**.
## uart.alt()
Change UART pin assignment.
......@@ -28,6 +32,9 @@ Sets the callback function to handle UART events.
Currently only the "data" event is supported.
!!! note
Due to limitations of the ESP8266, only UART 0 is capable of receiving data.
#### Syntax
`uart.on(method, [number/end_char], [function], [run_input])`
......@@ -69,16 +76,20 @@ end, 0)
(Re-)configures the communication parameters of the UART.
!!! note
Bytes sent to the UART can get lost if this function re-configures the UART while reception is in progress.
#### Syntax
`uart.setup(id, baud, databits, parity, stopbits, echo)`
`uart.setup(id, baud, databits, parity, stopbits[, echo])`
#### Parameters
- `id` always zero, only one uart supported
- `id` UART id (0 or 1).
- `baud` one of 300, 600, 1200, 2400, 4800, 9600, 19200, 31250, 38400, 57600, 74880, 115200, 230400, 256000, 460800, 921600, 1843200, 3686400
- `databits` one of 5, 6, 7, 8
- `parity` `uart.PARITY_NONE`, `uart.PARITY_ODD`, or `uart.PARITY_EVEN`
- `stopbits` `uart.STOPBITS_1`, `uart.STOPBITS_1_5`, or `uart.STOPBITS_2`
- `echo` if 0, disable echo, otherwise enable echo
- `echo` if 0, disable echo, otherwise enable echo (default if omitted)
#### Returns
configured baud rate (number)
......@@ -97,7 +108,7 @@ Returns the current configuration parameters of the UART.
`uart.getconfig(id)`
#### Parameters
- `id` always zero, only one uart supported
- `id` UART id (0 or 1).
#### Returns
Four values as follows:
......@@ -123,7 +134,7 @@ Write string or byte to the UART.
`uart.write(id, data1 [, data2, ...])`
#### Parameters
- `id` always 0, only one UART supported
- `id` UART id (0 or 1).
- `data1`... string or byte to send via UART
#### Returns
......
......@@ -3,6 +3,10 @@
| :----- | :-------------------- | :---------- | :------ |
| 2015-05-12 | [Zeroday](https://github.com/funshine) | [dnc40085](https://github.com/dnc40085) | [wifi.c](../../../app/modules/wifi.c)|
!!! important
The WiFi subsystem is maintained by background tasks that must run periodically. Any function or task that takes longer than 15ms (milliseconds) may cause the WiFi subsystem to crash. To avoid these potential crashes, it is advised that the WiFi subsystem be suspended with [wifi.suspend()](#wifisuspend) prior to the execution of any tasks or functions that exceed this 15ms guideline.
The NodeMCU WiFi control is spread across several tables:
- `wifi` for overall WiFi configuration
......@@ -74,6 +78,60 @@ The current physical mode as one of `wifi.PHYMODE_B`, `wifi.PHYMODE_G` or `wifi.
#### See also
[`wifi.setphymode()`](#wifisetphymode)
## wifi.nullmodesleep()
Configures whether or not WiFi automatically goes to sleep in NULL_MODE. Enabled by default.
!!! note
This function **does not** store it's setting in flash, if auto sleep in NULL_MODE is not desired, `wifi.nullmodesleep(false)` must be called after power-up, restart, or wake from deep sleep.
#### Syntax
`wifi.nullmodesleep([enable])`
#### Parameters
- `enable`
- `true` Enable WiFi auto sleep in NULL_MODE. (Default setting)
- `false` Disable WiFi auto sleep in NULL_MODE.
#### Returns
- `sleep_enabled` Current/New NULL_MODE sleep setting
- If `wifi.nullmodesleep()` is called with no arguments, current setting is returned.
- If `wifi.nullmodesleep()` is called with `enable` argument, confirmation of new setting is returned.
## wifi.resume()
Wake up WiFi from suspended state or cancel pending wifi suspension.
!!! note
Wifi resume occurs asynchronously, this means that the resume request will only be processed when control of the processor is passed back to the SDK (after MyResumeFunction() has completed). The resume callback also executes asynchronously and will only execute after wifi has resumed normal operation.
#### Syntax
`wifi.resume([resume_cb])`
#### Parameters
- `resume_cb` Callback to execute when WiFi wakes from suspension.
!!! note "Note:"
Any previously provided callbacks will be replaced!
#### Returns
`nil`
#### Example
```lua
--Resume wifi from timed or indefinite sleep
wifi.resume()
--Resume wifi from timed or indefinite sleep w/ resume callback
wifi.resume(function() print("WiFi resume") end)
```
#### See also
- [`wifi.suspend()`](#wifisuspend)
- [`node.sleep()`](node.md#nodesleep)
- [`node.dsleep()`](node.md#nodedsleep)
## wifi.setmode()
Configures the WiFi mode to use. NodeMCU can run in one of four WiFi modes:
......@@ -85,7 +143,8 @@ Configures the WiFi mode to use. NodeMCU can run in one of four WiFi modes:
When using the combined Station + AP mode, the same channel will be used for both networks as the radio can only listen on a single channel.
NOTE: WiFi Mode configuration will be retained until changed even if device is turned off.
!!! note
WiFi configuration will be retained until changed even if device is turned off.
#### Syntax
`wifi.setmode(mode[, save])`
......@@ -149,26 +208,6 @@ physical mode after setup
#### See also
[`wifi.getphymode()`](#wifigetphymode)
## wifi.nullmodesleep()
Configures whether or not WiFi automatically goes to sleep in NULL_MODE. Enabled by default.
!!! note
This function **does not** store it's setting in flash, if auto sleep in NULL_MODE is not desired, `wifi.nullmodesleep(false)` must be called after power-up, restart, or wake from deep sleep.
#### Syntax
`wifi.nullmodesleep([enable])`
#### Parameters
- `enable`
- `true` Enable WiFi auto sleep in NULL_MODE. (Default setting)
- `false` Disable WiFi auto sleep in NULL_MODE.
#### Returns
- `sleep_enabled` Current/New NULL_MODE sleep setting
- If `wifi.nullmodesleep()` is called with no arguments, current setting is returned.
- If `wifi.nullmodesleep()` is called with `enable` argument, confirmation of new setting is returned.
## wifi.startsmart()
Starts to auto configuration, if success set up SSID and password automatically.
......@@ -221,6 +260,62 @@ none
#### See also
[`wifi.startsmart()`](#wifistartsmart)
## wifi.suspend()
Suspend Wifi to reduce current consumption.
!!! note
Wifi suspension occurs asynchronously, this means that the suspend request will only be processed when control of the processor is passed back to the SDK (after MySuspendFunction() has completed). The suspend callback also executes asynchronously and will only execute after wifi has been successfully been suspended.
#### Syntax
`wifi.suspend({duration[, suspend_cb, resume_cb, preserve_mode]})`
#### Parameters
- `duration` Suspend duration in microseconds(μs). If a suspend duration of `0` is specified, suspension will be indefinite (Range: 0 or 50000 - 268435454 μs (0:4:28.000454))
- `suspend_cb` Callback to execute when WiFi is suspended. (Optional)
- `resume_cb` Callback to execute when WiFi wakes from suspension. (Optional)
- `preserve_mode` preserve current WiFi mode through node sleep. (Optional, Default: true)
- If true, Station and StationAP modes will automatically reconnect to previously configured Access Point when NodeMCU resumes.
- If false, discard WiFi mode and leave NodeMCU in [`wifi.NULL_MODE`](#wifigetmode). WiFi mode will be restored to original mode on restart.
#### Returns
- `suspend_state` if no parameters are provided, current WiFi suspension state will be returned
- States:
- `0` WiFi is awake.
- `1` WiFi suspension is pending. (Waiting for idle task)
- `2` WiFi is suspended.
#### Example
```lua
--get current wifi suspension state
print(wifi.suspend())
--Suspend WiFi for 10 seconds with suspend/resume callbacks
cfg={}
cfg.duration=10*1000*1000
cfg.resume_cb=function() print("WiFi resume") end
cfg.suspend_cb=function() print("WiFi suspended") end
wifi.suspend(cfg)
--Suspend WiFi for 10 seconds with suspend/resume callbacks and discard WiFi mode
cfg={}
cfg.duration=10*1000*1000
cfg.resume_cb=function() print("WiFi resume") end
cfg.suspend_cb=function() print("WiFfi suspended") end
cfg.preserve_mode=false
wifi.suspend(cfg)
```
#### See also
- [`wifi.resume()`](#wifiresume)
- [`node.sleep()`](node.md#nodesleep)
- [`node.dsleep()`](node.md#nodedsleep)
# wifi.sta Module
## wifi.sta.autoconnect()
......@@ -270,6 +365,26 @@ wifi.sta.changeap(4)
- [`wifi.sta.getapinfo()`](#wifistagetapinfo)
- [`wifi.sta.getapindex()`](#wifistagetapindex)
## wifi.sta.clearconfig()
Clears the currently saved WiFi station configuration, erasing it from the flash. May be useful for certain factory-reset
scenarios when a full [`node.restore()`](node.md#noderestore) is not desired, or to prepare for using
[End-User Setup](enduser-setup) so that the SoftAP is able to lock onto a single hardware radio channel.
#### Syntax
`wifi.sta.clearconfig()`
#### Parameters
none
#### Returns
- `true` Success
- `false` Failure
#### See also
- [`wifi.sta.config()`](#wifistaconfig)
- [`node.restore()`](node.md#noderestore)
## wifi.sta.config()
Sets the WiFi station configuration.
......@@ -280,7 +395,7 @@ Sets the WiFi station configuration.
#### Parameters
- `station_config` table containing configuration data for station
- `ssid` string which is less than 32 bytes.
- `pwd` string which is 8-64 or 0 bytes. Empty string indicates an open WiFi access point.
- `pwd` string which is 0-64. Empty string indicates an open WiFi access point. _Note: WPA requires a minimum of 8-characters, but the ESP8266 can also connect to a WEP access point (a 40-bit WEP key can be provided as its corresponding 5-character ASCII string)._
- `auto` defaults to true
- `true` to enable auto connect and connect to access point, hence with `auto=true` there's no need to call [`wifi.sta.connect()`](#wifistaconnect)
- `false` to disable auto connect and remain disconnected from access point
......@@ -332,6 +447,7 @@ wifi.sta.config(station_cfg)
```
#### See also
- [`wifi.sta.clearconfig()`](#wifistaclearconfig)
- [`wifi.sta.connect()`](#wifistaconnect)
- [`wifi.sta.disconnect()`](#wifistadisconnect)
- [`wifi.sta.apinfo()`](#wifistaapinfo)
......@@ -377,6 +493,9 @@ none
Registers callbacks for WiFi station status events.
!!! note
Please update your program to use the [`wifi.eventmon`](#wifieventmon-module) API, as the `wifi.sta.eventmon___()` API is deprecated.
#### Syntax
- `wifi.sta.eventMonReg(wifi_status[, function([previous_state])])`
......@@ -972,20 +1091,20 @@ Gets the current status in station mode.
`nil`
#### Returns
number: 0~5
The current state which can be one of the following:
- 0: STA_IDLE,
- 1: STA_CONNECTING,
- 2: STA_WRONGPWD,
- 3: STA_APNOTFOUND,
- 4: STA_FAIL,
- 5: STA_GOTIP.
- `wifi.STA_IDLE`
- `wifi.STA_CONNECTING`
- `wifi.STA_WRONGPWD`
- `wifi.STA_APNOTFOUND`
- `wifi.STA_FAIL`
- `wifi.STA_GOTIP`
# wifi.ap Module
## wifi.ap.config()
Sets SSID and password in AP mode. Be sure to make the password at least 8 characters long! If you don't it will default to *no* password and not set the SSID! It will still work as an access point but use a default SSID like e.g. NODE-9997C3.
Sets SSID and password in AP mode. Be sure to make the password at least 8 characters long! If you don't it will default to *no* password and not set the SSID! It will still work as an access point but use a default SSID like e.g. NODE_9997C3.
#### Syntax
`wifi.ap.config(cfg)`
......@@ -1350,6 +1469,10 @@ Note: The functions `wifi.sta.eventMon___()` and `wifi.eventmon.___()` are compl
## wifi.eventmon.register()
Register/unregister callbacks for WiFi event monitor.
- After a callback is registered, this function may be called to update a callback's function at any time
!!! note
To ensure all WiFi events are caught, the Wifi event monitor callbacks should be registered as early as possible in `init.lua`. Any events that occur before callbacks are registered will be discarded!
#### Syntax
wifi.eventmon.register(Event[, function(T)])
......@@ -1381,7 +1504,7 @@ T: Table returned by event.
- `wifi.eventmon.STA_DISCONNECTED`: Station was disconnected from access point.
- `SSID`: SSID of access point.
- `BSSID`: BSSID of access point.
- `REASON`: See [wifi.eventmon.reason](#wifieventmonreason) below.
- `reason`: See [wifi.eventmon.reason](#wifieventmonreason) below.
- `wifi.eventmon.STA_AUTHMODE_CHANGE`: Access point has changed authorization mode.
- `old_auth_mode`: Old wifi authorization mode.
- `new_auth_mode`: New wifi authorization mode.
......@@ -1400,6 +1523,9 @@ T: Table returned by event.
- `wifi.eventmon.AP_PROBEREQRECVED`: A probe request was received.
- `MAC`: MAC address of the client that is probing the access point.
- `RSSI`: Received Signal Strength Indicator of client.
- `wifi.eventmon.WIFI_MODE_CHANGE`: WiFi mode has changed.
- `old_auth_mode`: Old WiFi mode.
- `new_auth_mode`: New WiFi mode.
#### Example
......@@ -1414,7 +1540,7 @@ T: Table returned by event.
T.BSSID.."\n\treason: "..T.reason)
end)
wifi.eventmon.register(wifi.eventmon.STA_AUTHMODE_CHANGE, Function(T)
wifi.eventmon.register(wifi.eventmon.STA_AUTHMODE_CHANGE, function(T)
print("\n\tSTA - AUTHMODE CHANGE".."\n\told_auth_mode: "..
T.old_auth_mode.."\n\tnew_auth_mode: "..T.new_auth_mode)
end)
......@@ -1437,7 +1563,12 @@ T: Table returned by event.
end)
wifi.eventmon.register(wifi.eventmon.AP_PROBEREQRECVED, function(T)
print("\n\tAP - STATION DISCONNECTED".."\n\tMAC: ".. T.MAC.."\n\tRSSI: "..T.RSSI)
print("\n\tAP - PROBE REQUEST RECEIVED".."\n\tMAC: ".. T.MAC.."\n\tRSSI: "..T.RSSI)
end)
wifi.eventmon.register(wifi.eventmon.WIFI_MODE_CHANGED, function(T)
print("\n\tSTA - WIFI MODE CHANGED".."\n\told_mode: "..
T.old_mode.."\n\tnew_mode: "..T.new_mode)
end)
```
#### See also
......@@ -1465,6 +1596,7 @@ Event: WiFi event you would like to set a callback for.
- wifi.eventmon.AP_STACONNECTED
- wifi.eventmon.AP_STADISCONNECTED
- wifi.eventmon.AP_PROBEREQRECVED
- wifi.eventmon.WIFI_MODE_CHANGED
#### Returns
`nil`
......
......@@ -34,6 +34,9 @@ none
## wps.start()
Start WiFi WPS function. WPS must be enabled prior calling this function.
!!! note
This function only configures the station with the AP's info, it does not connect to AP automatically.
#### Syntax
`wps.start([function(status)])`
......@@ -45,21 +48,95 @@ Start WiFi WPS function. WPS must be enabled prior calling this function.
#### Example
```lua
wps.enable()
wps.start(function(status)
--Basic example
wifi.setmode(wifi.STATION)
wps.enable()
wps.start(function(status)
if status == wps.SUCCESS then
wps.disable()
print("WPS: Success, connecting to AP...")
wifi.sta.connect()
return
elseif status == wps.FAILED then
print("WPS: Failed")
elseif status == wps.TIMEOUT then
print("WPS: Timeout")
elseif status == wps.WEP then
print("WPS: WEP not supported")
elseif status == wps.SCAN_ERR then
print("WPS: AP not found")
else
print(status)
end
wps.disable()
end)
--Full example
do
-- Register wifi station event callbacks
wifi.eventmon.register(wifi.eventmon.STA_CONNECTED, function(T)
print("\n\tSTA - CONNECTED".."\n\tSSID: "..T.SSID.."\n\tBSSID: "..
T.BSSID.."\n\tChannel: "..T.channel)
end)
wifi.eventmon.register(wifi.eventmon.STA_GOT_IP, function(T)
print("\n\tSTA - GOT IP".."\n\tStation IP: "..T.IP.."\n\tSubnet mask: "..
T.netmask.."\n\tGateway IP: "..T.gateway)
end)
wifi.setmode(wifi.STATION)
wps_retry_func = function()
if wps_retry_count == nil then wps_retry_count = 0 end
if wps_retry_count < 3 then
wps.disable()
wps.enable()
wps_retry_count = wps_retry_count + 1
wps_retry_timer = tmr.create()
wps_retry_timer:alarm(3000, tmr.ALARM_SINGLE, function() wps.start(wps_cb) end)
print("retry #"..wps_retry_count)
else
wps_retry_count = nil
wps_retry_timer = nil
wps_retry_func = nil
wps_cb = nil
end
end
wps_cb = function(status)
if status == wps.SUCCESS then
print("SUCCESS!")
wps.disable()
print("WPS: success, connecting to AP...")
wifi.sta.connect()
wps_retry_count = nil
wps_retry_timer = nil
wps_retry_func = nil
wps_cb = nil
return
elseif status == wps.FAILED then
print("Failed")
print("WPS: Failed")
wps_retry_func()
return
elseif status == wps.TIMEOUT then
print("Timeout")
print("WPS: Timeout")
wps_retry_func()
return
elseif status == wps.WEP then
print("WEP not supported")
print("WPS: WEP not supported")
elseif status == wps.SCAN_ERR then
print("WPS AP not found")
print("WPS: AP not found")
wps_retry_func()
return
else
print(status)
end
wps.disable()
end)
wps_retry_count = nil
wps_retry_timer = nil
wps_retry_func = nil
wps_cb = nil
end
wps.enable()
wps.start(wps_cb)
end
```
......@@ -13,16 +13,19 @@ handle two led strips at the same time.
**WARNING**: In dual mode, you will loose access to the Lua's console
through the serial port (it will be reconfigured to support WS2812-like
protocol). If you want to keep access to Lua's console, you will have to
use an other input channel like a TCP server (see [example](https://github.com/nodemcu/nodemcu-firmware/blob/master/examples/telnet.lua))
use an other input channel like a TCP server (see [example](https://github.com/nodemcu/nodemcu-firmware/blob/master/lua_examples/telnet.lua))
## ws2812.init(mode)
## ws2812.init()
Initialize UART1 and GPIO2, should be called once and before write().
Initialize UART0 (TXD0) too if `ws2812.MODE_DUAL` is set.
#### Syntax
`ws2812.init([mode])`
#### Parameters
- `mode` (optional) either `ws2812.MODE_SINGLE` (default if omitted) or `ws2812.MODE_DUAL`.
In `ws2812.MODE_DUAL` mode you will be able to handle two strips in parallel but will lose access
to Lua's serial console as it shares the same UART and PIN.
- `mode` (optional) either `ws2812.MODE_SINGLE` (default if omitted) or `ws2812.MODE_DUAL`
In `ws2812.MODE_DUAL` mode you will be able to handle two strips in parallel but will lose access to Lua's serial console as it shares the same UART and PIN.
#### Returns
`nil`
......
# XPT2046 Module
| Since | Origin / Contributor | Maintainer | Source |
| :----- | :-------------------- | :---------- | :------ |
| 2017-03-09| [Starofall](https://github.com/nodemcu/nodemcu-firmware/pull/1242)/[Frank Exoo](https://github.com/FrankX0) | [Frank Exoo](https://github.com/FrankX0) | [xpt2046.c](../../../app/modules/xpt2046.c)|
XPT2046 is a touch controller used by several cheap displays - often in combination with the ILI9341 display controller.
The module is built based on the libraries of [spapadim](https://github.com/spapadim/XPT2046/) and [PaulStoffregen](https://github.com/PaulStoffregen/XPT2046_Touchscreen).
## xpt2046.init()
Initiates the XPT2046 module to read touch values from the display. It is required to call [`spi.setup()`](spi.md#spisetup) before calling `xpt2046.init` (see example).
As the ucg lib also requires [`spi.setup()`](spi.md#spisetup) to be called before it is important to only call it once in total and to activate `spi.FULLDUPLEX`.
The `clock_div` used in [`spi.setup()`](spi.md#spisetup) should be 16 or higher, as lower values might produces inaccurate results.
#### Syntax
`xpt2046.init(cs_pin, irq_pin, height, width)`
#### Parameters
- `cs_pin` GPIO pin for cs
- `irq_pin` GPIO pin for irq
- `height` display height in pixel
- `width` display width in pixel
#### Returns
`nil`
#### Example
```lua
-- Setup spi with `clock_div` of 16 and spi.FULLDUPLEX
spi.setup(1, spi.MASTER, spi.CPOL_LOW, spi.CPHA_LOW, 8, 16,spi.FULLDUPLEX)
-- SETTING UP DISPLAY (using ucg module)
local disp = ucg.ili9341_18x240x320_hw_spi(8, 4, 0)
disp:begin(0)
-- SETTING UP TOUCH
xpt2046.init(2,1,320,240)
xpt2046.setCalibration(198, 1776, 1762, 273)
```
## xpt2046.setCalibration()
Sets the calibration of the display. Calibration values can be optained by using [`xpt2046.getRaw()`](#xpt2046getraw) and read the values in the edges.
#### Syntax
`xpt2046.setCalibration(x1, y1, x2, y2)`
#### Parameters
- `x1` raw x value at top left
- `y1` raw y value at top left
- `x2` raw x value at bottom right
- `y2` raw y value at bottom right
#### Returns
`nil`
## xpt2046.isTouched()
Checks if the touch panel is touched.
#### Syntax
`xpt2046.isTouched()`
#### Returns
`true` if the display is touched, else `false`
#### Example
```lua
if(xpt2046.isTouched()) then
local x, y = xpt2046.getPosition()
print(x .. "-" .. y)
end
```
## xpt2046.getPosition()
Returns the position the display is touched using the calibration values and given width and height.
Can be used in an interrupt pin callback to return the coordinates when the touch screen is touched.
#### Syntax
`xpt2046.getPosition()`
#### Returns
returns both the x and the y position.
#### Example
```lua
-- Setup spi with `clock_div` of 16 and spi.FULLDUPLEX
spi.setup(1, spi.MASTER, spi.CPOL_LOW, spi.CPHA_LOW, 8, 16,spi.FULLDUPLEX)
-- SETTING UP TOUCH
cs_pin = 2 -- GPIO4
irq_pin = 3 -- GPIO0
height = 240
width = 320
xpt2046.init(cs_pin, irq_pin, width, height)
xpt2046.setCalibration(198, 1776, 1762, 273)
gpio.mode(irq_pin,gpio.INT,gpio.PULLUP)
gpio.trig(irq_pin, "down", function()
print(xpt2046.getPosition())
end)
```
## xpt2046.getPositionAvg()
To create better measurements this function reads the position three times and averages the two positions with the least distance.
#### Syntax
`xpt2046.getPositionAvg()`
#### Returns
returns both the x and the y position.
#### Example
```lua
local x, y = xpt2046.getPositionAvg()
print(x .. "-" .. y)
```
## xpt2046.getRaw()
Reads the raw value from the display. Useful for debugging and custom conversions.
#### Syntax
`xpt2046.getRaw()`
#### Returns
returns both the x and the y position as a raw value.
#### Example
```lua
local rawX, rawY = xpt2046.getRaw()
print(rawX .. "-" .. rawY)
```
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment