Unverified Commit 67027c0d authored by Marcel Stör's avatar Marcel Stör Committed by GitHub
Browse files

Merge pull request #2340 from nodemcu/dev

2.2 master snap
parents 5073c199 18f33f5f
# Bloom Module
| Since | Origin / Contributor | Maintainer | Source |
| :----- | :-------------------- | :---------- | :------ |
| 2017-11-13 | [Philip Gladstone](https://github.com/pjsg) | [Philip Gladstone](https://github.com/pjsg) | [bloom.c](../../../app/modules/bloom.c)|
This module implements a [Bloom filter](https://en.wikipedia.org/wiki/Bloom_filter). This is a probabilistic data structure that is used to test for set membership. There are two operations -- `add` and `check` that allow
arbitrary strings to be added to the set or tested for set membership. Since this is a probabilistic data structure, the answer returned can be incorrect. However,
if the string *is* a member of the set, then the `check` operation will always return `true`.
## bloom.create()
Create a filter object.
#### Syntax
`bloom.create(elements, errorrate)`
#### Parameters
- `elements` The largest number of elements to be added to the filter.
- `errorrate` The error rate (the false positive rate). This is represented as `n` where the false positive rate is `1 / n`. This is the maximum rate of `check` returning true when the string is *not* in the set.
#### Returns
A `filter` object.
#### Example
```
filter = bloom.create(10000, 100) -- this will use around 11kB of memory
```
## filter:add()
Adds a string to the set and returns an indication of whether the string was already present.
#### Syntax
`filter:add(string)`
#### Parameters
- `string` The string to be added to the filter set.
#### Returns
`true` if the string was already present in the filter. `false` otherwise.
#### Example
```
if filter:add("apple") then
print ("Seen an apple before!")
else
print ("Noted that the first apple has been seen")
end
```
## filter:check()
Checks to see if a string is present in the filter set.
#### Syntax
`present = filter:check(string)`
#### Parameters
- `string` The string to be checked for membership in the set.
#### Returns
`true` if the string was already present in the filter. `false` otherwise.
#### Example
```
if filter:check("apple") then
print ("Seen an apple before!")
end
```
## filter:reset()
Empties the filter.
#### Syntax
`filter:reset()`
#### Returns
Nothing
#### Example
```
filter:reset()
```
## filter:info()
Get some status information on the filter.
#### Syntax
`bits, fns, occupancy, fprate = filter:info()`
#### Returns
- `bits` The number of bits in the filter.
- `fns` The number of hash functions in use.
- `occupancy` The number of bits set in the filter.
- `fprate` The approximate chance that the next `check` will return `true` when it should return `false`. This is represented as the inverse of the probability -- i.e. as the n in 1-in-n chance. This value is limited to 1,000,000.
#### Example
```
bits, fns, occupancy, fprate = filter:info()
```
...@@ -68,21 +68,6 @@ none ...@@ -68,21 +68,6 @@ none
- `H` last relative humidity reading in % times 1000 - `H` last relative humidity reading in % times 1000
- `T` temperature in celsius as an integer multiplied with 100 - `T` temperature in celsius as an integer multiplied with 100
## bme280.init()
Initializes module. Initialization is mandatory before read values.
!!! attention
This function is deprecated and will be removed in upcoming releases. Use `bme280.setup()` instead.
#### Syntax
`bme280.init(sda, scl, [temp_oss, press_oss, humi_oss, power_mode, inactive_duration, IIR_filter])`
#### Parameters
See [`setup()`](#bme280setup).
## bme280.qfe2qnh() ## bme280.qfe2qnh()
For given altitude converts the air pressure to sea level air pressure. For given altitude converts the air pressure to sea level air pressure.
......
# BME680 module
| Since | Origin / Contributor | Maintainer | Source |
| :----- | :-------------------- | :---------- | :------ |
| 2017-10-28 | [vsky279](https://github.com/vsky279) | [vsky279](https://github.com/vsky279) | [bme680.c](../../../app/modules/bme680.c)|
This module provides a simple interface to [BME680](https://www.bosch-sensortec.com/bst/products/all_products/bme680) temperature/air presssure/humidity sensors/air quality sensor (Bosch Sensortec). Compared to the BME280 module the sensor does not support automatic mode which means that it can be setup to perform regular measurements. Every measurement has to be triggered manually.
In order to measure the air quality the sensor needs to be heated first. In the example provided by the manufacturer the sensor is heated to 300 degrees centigrade for a period of 200 ms and then the measurement is taken. These values are taken as default values in this implementation. I have not tested the impact of different temperatures and heating times on the measurement.
This module is able to measure the gas resistance (see Bosch's datasheet). The gas resistance is not the IAQ (Indoor Air Quality) Index. But apparently it can be used as some proxy. The value still should somehow reflect the air quality. It seems that the higher value the air quality is better.
The algorithm for IAQ calculation from the gas restistances (probably measured at different temperatures) is not publicly available. Bosch says that at this point of time the calculations for the Indoor Air Quality index are offered only as a pre-compiled library (see discussion here: [BoschSensortec/BME680_driver#6](https://github.com/BoschSensortec/BME680_driver/issues/6)). It is available as the [BSEC Library](https://www.bosch-sensortec.com/bst/products/all_products/bsec).
The algorithm is implemented in the library `bsec/algo/bin/ESP8266/libalgobsec.a`. Unfortunately I did not even manage to run the Bosch BSEC example on ESP8266 using this library.
## bme680.altitude()
For given air pressure and sea level air pressure returns the altitude in meters as an integer multiplied with 100, i.e. altimeter function.
#### Syntax
`bme680.altitude(P, QNH)`
#### Parameters
- `P` measured pressure
- `QNH` current sea level pressure
#### Returns
altitude in meters of measurement point
## bme680.dewpoint()
For given temperature and relative humidity returns the dew point in Celsius as an integer multiplied with 100.
#### Syntax
`bme680.dewpoint(H, T)`
#### Parameters
- `H` relative humidity in percent multiplied by 1000.
- `T` temperate in Celsius multiplied by 100.
#### Returns
dew point in Celsius
## bme680.qfe2qnh()
For given altitude converts the air pressure to sea level air pressure.
#### Syntax
`bme680.qfe2qnh(P, altitude)`
#### Parameters
- `P` measured pressure
- `altitude` altitude in meters of measurement point
#### Returns
sea level pressure
## bme680.read()
Reads the sensor and returns the temperature, the air pressure, the air relative humidity and
#### Syntax
`bme680.read([altitude])`
#### Parameters
- (optional) `altitude`- altitude in meters of measurement point. If provided also the air pressure converted to sea level air pressure is returned.
#### Returns
- `T` temperature in Celsius as an integer multiplied with 100
- `P` air pressure in hectopascals multiplied by 100
- `H` relative humidity in percent multiplied by 1000
- `G` gas resistance
- `QNH` air pressure in hectopascals multiplied by 100 converted to sea level
Any of these variables is `nil` if the readout of given measure was not successful.
The measured values can be read only once. Following attempts to read values will return nil. A new `startreadout()` needs to be called first before next `read()`.
## bme680.startreadout()
Starts readout (turns the sensor into forced mode). After the readout the sensor turns to sleep mode.
#### Syntax
`bme680.startreadout(delay, callback)`
#### Parameters
- `delay` sets sensor to forced mode and calls the `callback` (if provided) after given number of milliseconds. For 0 the default delay is calculated by the [formula provided by Bosch](https://github.com/BoschSensortec/BME680_driver/blob/2a51b9c0c1899f28e561e6701caa22cb23201cfc/bme680.c#L586). Apparently for certain combinations of oversamplings setup the the delay returned by the formula is not sufficient and the readout is not ready (make sure you are not reading the previous measurement). For default parameters (2x, 16x, 1x) the calculated delay is 121 ms while in reality 150 ms are needed to get the result.
- `callback` if provided it will be invoked after given `delay`. The sensor reading should be finalized by then so.
#### Returns
`nil`
## bme680.setup()
Initializes module. Initialization is mandatory before read values.
#### Syntax
`bme680.setup([temp_oss, press_oss, humi_oss, heater_temp, heater_duration, IIR_filter, cold_start])`
#### Parameters
- (optional) `temp_oss` - Controls oversampling of temperature data. Default oversampling is 2x.
- (optional) `press_oss` - Controls oversampling of pressure data. Default oversampling is 16x.
- (optional) `humi_oss` - Controls oversampling of humidity data. Default oversampling is 1x
- (optional) `heater_temp` -
- (optional) `heater_duration` -
- (optional) `IIR_filter` - Controls the time constant of the IIR filter. Default fitler coefficient is 31.
- (optional) `cold_start` - If 0 then the bme680 chip is not initialised. Usefull in a battery operated setup when the ESP deep sleeps and on wakeup needs to initialise the driver (the module) but not the chip itself. The chip was kept powered (sleeping too) and is holding the latest reading that should be fetched quickly before another reading starts (`bme680.startreadout()`). By default the chip is initialised.
|`temp_oss`, `press_oss`, `humi_oss`|Data oversampling|
|-----|-----------------|
|0|Skipped (output set to 0x80000)|
|1|oversampling ×1|
|2|oversampling ×2|
|3|oversampling ×4|
|4|oversampling ×8|
|5|oversampling ×16|
|`IIR_filter`|Filter coefficient |
|-----|-----------------|
|0|Filter off|
|1|1|
|2|3|
|3|7|
|4|15|
|5|31|
|6|63|
|7|127|
#### Returns
`nil` if initialization has failed (no sensor connected?)
#### Example
```lua
alt=320 -- altitude of the measurement place
sda, scl = 3, 4
i2c.setup(0, sda, scl, i2c.SLOW) -- call i2c.setup() only once
bme680.setup()
-- delay calculated by formula provided by Bosch: 121 ms, minimum working (empirical): 150 ms
bme680.startreadout(150, function ()
T, P, H, G, QNH = bme680.read(alt)
if T then
local Tsgn = (T < 0 and -1 or 1); T = Tsgn*T
print(string.format("T=%s%d.%02d", Tsgn<0 and "-" or "", T/100, T%100))
print(string.format("QFE=%d.%03d", P/100, P%100))
print(string.format("QNH=%d.%03d", QNH/100, QNH%100))
print(string.format("humidity=%d.%03d%%", H/1000, H%1000))
print(string.format("gas resistance=%d", G))
D = bme680.dewpoint(H, T)
local Dsgn = (D < 0 and -1 or 1); D = Dsgn*D
print(string.format("dew_point=%s%d.%02d", Dsgn<0 and "-" or "", D/100, D%100))
end
end)
```
...@@ -6,23 +6,6 @@ ...@@ -6,23 +6,6 @@
This module provides access to the [BMP085](https://www.sparkfun.com/tutorials/253) temperature and pressure sensor. The module also works with BMP180. This module provides access to the [BMP085](https://www.sparkfun.com/tutorials/253) temperature and pressure sensor. The module also works with BMP180.
## bmp085.init()
Initializes the module and sets the pin configuration.
!!! attention
This function is deprecated and will be removed in upcoming releases. Use `bmp085.setup()` instead.
#### Syntax
`bmp085.init(sda, scl)`
#### Parameters
- `sda` data pin
- `scl` clock pin
#### Returns
`nil`
## bmp085.setup() ## bmp085.setup()
Initializes the module. Initializes the module.
......
# color utils Module
| Since | Origin / Contributor | Maintainer | Source |
| :----- | :-------------------- | :---------- | :------ |
| 2017-12-30 | [Konrad Huebner](https://github.com/skycoders) | [Konrad Huebner](https://github.com/skycoders) | [color_utils.c](../../../app/modules/color_utils.c)|
This module provides basic color transformations useful for color LEDs.
## color_utils.hsv2grb()
Convert HSV color to GRB color.
#### Syntax
`color_utils.hsv2grb(hue, saturation, value)`
#### Parameters
- `hue` is the hue value, between 0 and 360
- `saturation` is the saturation value, between 0 and 255
- `value` is the value value, between 0 and 255
#### Returns
`green`, `red`, `blue` as values between 0 and 255
## color\_utils.hsv2grbw()
Convert HSV color to GRB color and explicitly return a white value. This can be useful for RGB+W LED strips. The white value is simply calculated as min(g, r, b) and then removed from the colors. This does NOT take into account if the white chip used later creates an appropriate color.
#### Syntax
`color_utils.hsv2grbw(hue, saturation, value)`
#### Parameters
- `hue` is the hue value, between 0 and 360
- `saturation` is the saturation value, between 0 and 255
- `value` is the value value, between 0 and 255
#### Returns
`green`, `red`, `blue`, `white` as values between 0 and 255
## color\_utils.grb2hsv()
Convert GRB color to HSV color.
#### Syntax
`color_utils.grb2hsv(green, red, blue)`
#### Parameters
- `green` is the green value, between 0 and 255
- `red` is the red value, between 0 and 255
- `blue` is the blue value, between 0 and 255
#### Returns
`hue`, `saturation`, `value` as values between 0 and 360, respective 0 and 255
## color\_utils.colorWheel()
The color wheel function makes use of the HSV color space and calculates colors based on the color circle. The colors are created with full saturation and value. This function is a convenience function of the hsv2grb function and can be used to create rainbow colors.
#### Syntax
`color_utils.colorWheel(angle)`
#### Parameters
- `angle` is the angle on the color circle, between 0 and 359
#### Returns
`green`, `red`, `blue` as values between 0 and 255
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
[Cron](https://en.wikipedia.org/wiki/Cron)-like scheduler module. [Cron](https://en.wikipedia.org/wiki/Cron)-like scheduler module.
!!! important !!! important
This module needs RTC time to operate correctly. Do not forget to include the [`rtctime`](rtctime.md) module. This module needs RTC time to operate correctly. Do not forget to include the [`rtctime`](rtctime.md) module **and** initialize it properly.
## cron.schedule() ## cron.schedule()
......
...@@ -150,7 +150,7 @@ Lists all files in the file system. ...@@ -150,7 +150,7 @@ Lists all files in the file system.
none none
#### Returns #### Returns
a lua table which contains the {file name: file size} pairs a Lua table which contains the {file name: file size} pairs
#### Example #### Example
```lua ```lua
......
...@@ -125,10 +125,15 @@ This function is not available if GPIO_INTERRUPT_ENABLE was undefined at compile ...@@ -125,10 +125,15 @@ This function is not available if GPIO_INTERRUPT_ENABLE was undefined at compile
- `type` "up", "down", "both", "low", "high", which represent *rising edge*, *falling edge*, *both - `type` "up", "down", "both", "low", "high", which represent *rising edge*, *falling edge*, *both
edges*, *low level*, and *high level* trigger modes respectivey. If the type is "none" or omitted edges*, *low level*, and *high level* trigger modes respectivey. If the type is "none" or omitted
then the callback function is removed and the interrupt is disabled. then the callback function is removed and the interrupt is disabled.
- `callback_function(level, when)` callback function when trigger occurs. The level of the specified pin - `callback_function(level, when, eventcount)` callback function when trigger occurs. The level of the specified pin
at the interrupt passed as the first parameter to the callback. The timestamp of the event is passed at the interrupt passed as the first parameter to the callback. The timestamp of the event is passed
as the second parameter. This is in microseconds and has the same base as for `tmr.now()`. This timestamp as the second parameter. This is in microseconds and has the same base as for `tmr.now()`. This timestamp
is grabbed at interrupt level and is more consistent than getting the time in the callback function. is grabbed at interrupt level and is more consistent than getting the time in the callback function.
This timestamp is normally of the first interrupt detected, but, under overload conditions, might be a later one.
The eventcount is the number of interrupts that were elided for this callback. This works best for edge triggered
interrupts and enables counting of edges. However, beware
of switch bounces -- you can get multiple pulses for a single switch closure. Counting
works best when the edges are digitally generated.
The previous callback function will be used if the function is omitted. The previous callback function will be used if the function is omitted.
#### Returns #### Returns
...@@ -177,3 +182,222 @@ gpio.write(pin, gpio.HIGH) ...@@ -177,3 +182,222 @@ gpio.write(pin, gpio.HIGH)
#### See also #### See also
- [`gpio.mode()`](#gpiomode) - [`gpio.mode()`](#gpiomode)
- [`gpio.read()`](#gpioread) - [`gpio.read()`](#gpioread)
## gpio.pulse
This covers a set of APIs that allow generation of pulse trains with accurate timing on
multiple pins. It is similar to the `serout` API, but can handle multiple pins and has better
timing control.
The basic idea is to build a `gpio.pulse` object and then control it with methods on that object. Only one `gpio.pulse`
object can be active at a time. The object is built from an array of tables where each inner table represents
an action to take and the time to delay before moving to the next action.
One of the uses for this is to generate bipolar impulse for driving clock movements where you want (say) a pulse on Pin 1 on the even
second, and a pulse on Pin 2 on the odd second. `:getstate` and `:adjust` can be used to keep the pulse synchronized to the
RTC clock (that is itself synchronized with NTP).
!!! Attention
This sub module is disabled by default. Uncomment `LUA_USE_MODULES_GPIO_PULSE` in `app/include/user_modules.h` before building the firmware to enable it.
To make use of this feature, decide on the sort of pulse train that you need to generate -- hopefully it repeats a number of times.
Decide on the number of GPIO pins that you will be using. Then draw up a chart of what you want to happen, and in what order. Then
you can construct the table struct that you pass into `gpio.pulse.build`. For example, for the two out of phase square waves, you might do:
Step | Pin 1 | Pin 2 | Duration (&#956;S) | Next Step
---:|---|---|---:| --:
1 | High | Low | 100,000 | 2
2 | Low | High | 100,000 | **1**
This would (when built and started) just runs step 1 (by setting the output pins as specified), and then after 100,000&#956;S, it changes to step 2i. This
alters the output pins
and then waits for 100,000&#956;S before going back to step 1. This has the effect of outputting to Pin 1 and Pin 2 a 5Hz square wave with the pins being out of phase. The frequency will be
slightly lower than 5Hz as this is software generated and interrupt masking can delay the move to the next step. To get much closer to 5Hz,
you want to allow the duration of each step to vary slightly. This will then adjust the length of each step so that, overall, the output is
at 5Hz.
Step | Pin 1 | Pin 2 | Duration (&#956;S) | Range | Next Step
---:|---|---|---:|:---:| --:
1 | High | Low | 100,000 | 90,000 - 110,000 | 2
2 | Low | High | 100,000 | 90,000 - 110,000 | **1**
When turning this into the table structure as described below, you don't need to specify anything
special when the number of the next step is one more than the current step. When specifying an out of order
step, you must specify how often you want this to be performed. A very large value can be used for roughly infinite.
## gpio.pulse.build
This builds the `gpio.pulse` object from the supplied argument (a table as described below).
#### Syntax
`gpio.pulse.build(table)`
#### Parameter
`table` this is view as an array of instructions. Each instruction is represented by a table as follows:
- All numeric keys are considered to be pin numbers. The values of each are the value to be set onto the respective GPIO line.
For example `{ [1] = gpio.HIGH }` would set pin 1 to be high.
Note this that is the NodeMCU pin number and *not* the ESP8266 GPIO number. Multiple pins can be
set at the same time. Note that any valid GPIO pin can be used, including pin 0.
- `delay` specifies the number of microseconds after setting the pin values to wait until moving to the next state. The actual delay may be longer than this value depending on whether interrupts are enabled at the end time. The maximum value is 64,000,000 -- i.e. a bit more than a minute.
- `min` and `max` can be used to specify (along with `delay`) that this time can be varied. If one time interval overruns, then the extra time will be deducted from a time period which has a `min` or `max` specified. The actual time can also be adjusted with the `:adjust` API below.
- `count` and `loop` allow simple looping. When a state with `count` and `loop` is completed, the next state is at `loop` (provided that `count` has not decremented to zero). The first state is state 1. The `loop` is rather like a goto instruction as it specifies the next instruction to be executed.
#### Returns
`gpio.pulse` object.
#### Example
```lua
gpio.mode(1, gpio.OUTPUT)
gpio.mode(2, gpio.OUTPUT)
pulser = gpio.pulse.build( {
{ [1] = gpio.HIGH, [2] = gpio.LOW, delay=250000 },
{ [1] = gpio.LOW, [2] = gpio.HIGH, delay=250000, loop=1, count=20, min=240000, max=260000 }
})
pulser:start(function() print ('done') end)
```
This will generate a square wave on pins 1 and 2, but they will be exactly out of phase. After 10 seconds, the sequence will end, with pin 2 being high.
Note that you *must* set the pins into output mode (either gpio.OUTPUT or gpio.OPENDRAIN) before starting the output sequence, otherwise
nothing will appear to happen.
## gpio.pulse:start
This starts the output operations.
#### Syntax
`pulser:start([adjust, ] callback)`
#### Parameter
- `adjust` This is the number of microseconds to add to the next adjustable period. If this value is so large that
it would push the delay past the `min` or `max`, then the remainder is held over until the next adjustable period.
- `callback` This callback is executed when the pulses are complete. The callback is invoked with the same four
parameters that are described as the return values of `gpio.pulse:getstate`.
#### Returns
`nil`
#### Example
```lua
pulser:start(function(pos, steps, offset, now)
print (pos, steps, offset, now)
end)
```
## gpio.pulse:getstate
This returns the current state. These four values are also passed into the callback functions.
#### Syntax
`pulser:getstate()`
#### Returns
- `position` is the index of the currently active state. The first state is state 1. This is `nil` if the output operation is complete.
- `steps` is the number of states that have been executed (including the current one). This allows monitoring of progress when there are
loops.
- `offset` is the time (in microseconds) until the next state transition. This will be negative once the output operation is complete.
- `now` is the value of the `tmr.now()` function at the instant when the `offset` was calculated.
#### Example
```lua
pos, steps, offset, now = pulser:getstate()
print (pos, steps, offset, now)
```
## gpio.pulse:stop
This stops the output operation at some future time.
#### Syntax
`pulser:stop([position ,] callback)`
#### Parameters
- `position` is the index to stop at. The stopping happens on entry to this state. If not specified, then stops on the next state transition.
- `callback` is invoked (with the same arguments as are returned by `:getstate`) when the operation has been stopped.
#### Returns
`true` if the stop will happen.
#### Example
```lua
pulser:stop(function(pos, steps, offset, now)
print (pos, steps, offset, now)
end)
```
## gpio.pulse:cancel
This stops the output operation immediately.
#### Syntax
`pulser:cancel()`
#### Returns
- `position` is the index of the currently active state. The first state is state 1. This is `nil` if the output operation is complete.
- `steps` is the number of states that have been executed (including the current one). This allows monitoring of progress when there are
loops.
- `offset` is the time (in microseconds) until the next state transition. This will be negative once the output operation is complete.
- `now` is the value of the `tmr.now()` function at the instant when the `offset` was calculated.
#### Example
```lua
pulser:cancel(function(pos, steps, offset, now)
print (pos, steps, offset, now)
end)
```
## gpio.pulse:adjust
This adds (or subtracts) time that will get used in the `min` / `max` delay case. This is useful if you are trying to
synchronize a particular state to a particular time or external event.
#### Syntax
`pulser:adjust(offset)`
#### Parameters
- `offset` is the number of microseconds to be used in subsequent `min` / `max` delays. This overwrites any pending offset.
#### Returns
- `position` is the index of the currently active state. The first state is state 1. This is `nil` if the output operation is complete.
- `steps` is the number of states that have been executed (including the current one). This allows monitoring of progress when there are
loops.
- `offset` is the time (in microseconds) until the next state transition. This will be negative once the output operation is complete.
- `now` is the value of the `tmr.now()` function at the instant when the `offset` was calculated.
#### Example
```lua
pulser:adjust(177)
```
## gpio.pulse:update
This can change the contents of a particular step in the output program. This can be used to adjust the delay times, or even the pin changes. This cannot
be used to remove entries or add new entries.
#### Syntax
`pulser:update(entrynum, entrytable)`
#### Parameters
- `entrynum` is the number of the entry in the original pulse sequence definition. The first entry is numbered 1.
- `entrytable` is a table containing the same keys as for `gpio.pulse.build`
#### Returns
Nothing
Example
```lua
pulser:update(1, { delay=1000 })
```
...@@ -36,21 +36,3 @@ Initializes the module. ...@@ -36,21 +36,3 @@ Initializes the module.
#### Returns #### Returns
`nil` `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`
...@@ -25,23 +25,6 @@ local x,y,z = hmc5883l.read() ...@@ -25,23 +25,6 @@ local x,y,z = hmc5883l.read()
print(string.format("x = %d, y = %d, z = %d", x, y, z)) print(string.format("x = %d, y = %d, z = %d", x, y, z))
``` ```
## hmc5883l.init()
Initializes the module and sets the pin configuration.
!!! attention
This function is deprecated and will be removed in upcoming releases. Use `hmc5883l.setup()` instead.
#### Syntax
`hmc5883l.init(sda, scl)`
#### Parameters
- `sda` data pin
- `scl` clock pin
#### Returns
`nil`
## hmc5883l.setup() ## hmc5883l.setup()
Initializes the module. Initializes the module.
......
...@@ -112,14 +112,14 @@ Send an I²C stop condition. ...@@ -112,14 +112,14 @@ Send an I²C stop condition.
[i2c.read()](#i2cread) [i2c.read()](#i2cread)
## i2c.write() ## i2c.write()
Write data to I²C bus. Data items can be multiple numbers, strings or lua tables. Write data to I²C bus. Data items can be multiple numbers, strings or Lua tables.
####Syntax ####Syntax
`i2c.write(id, data1[, data2[, ..., datan]])` `i2c.write(id, data1[, data2[, ..., datan]])`
####Parameters ####Parameters
- `id` always 0 - `id` always 0
- `data` data can be numbers, string or lua table. - `data` data can be numbers, string or Lua table.
#### Returns #### Returns
`number` number of bytes written `number` number of bytes written
......
...@@ -24,23 +24,6 @@ local x,y,z = l3g4200d.read() ...@@ -24,23 +24,6 @@ local x,y,z = l3g4200d.read()
print(string.format("X = %d, Y = %d, Z = %d", x, y, z) print(string.format("X = %d, Y = %d, Z = %d", x, y, z)
``` ```
## l3g4200d.init()
Initializes the module and sets the pin configuration.
!!! attention
This function is deprecated and will be removed in upcoming releases. Use `l3g4200d.setup()` instead.
#### Syntax
`l3g4200d.init(sda, scl)`
#### Parameters
- `sda` data pin
- `scl` clock pin
#### Returns
`nil`
## l3g4200d.setup() ## l3g4200d.setup()
Initializes the module. Initializes the module.
......
...@@ -151,6 +151,15 @@ This is the description of how the `autoreconnect` functionality may (or may not ...@@ -151,6 +151,15 @@ This is the description of how the `autoreconnect` functionality may (or may not
Setup [Last Will and Testament](http://www.hivemq.com/blog/mqtt-essentials-part-9-last-will-and-testament) (optional). A broker will publish a message with qos = 0, retain = 0, data = "offline" to topic "/lwt" if client does not send keepalive packet. Setup [Last Will and Testament](http://www.hivemq.com/blog/mqtt-essentials-part-9-last-will-and-testament) (optional). A broker will publish a message with qos = 0, retain = 0, data = "offline" to topic "/lwt" if client does not send keepalive packet.
As the last will is sent to the broker when connecting, `lwt()` must be called BEFORE calling `connect()`.  
The broker will publish a client's last will message once he NOTICES that the connection to the client is broken. The broker will notice this when:
 - The client fails to send a keepalive packet for as long as specified in `mqtt.Client()`
 - The tcp-connection is properly closed (without closing the mqtt-connection before)
- The broker tries to send data to the client and fails to do so, because the tcp-connection is not longer open.
This means if you specified 120 as keepalive timer, just turn off the client device and the broker does not send any data to the client, the last will message will be published 120s after turning off the device.
#### Syntax #### Syntax
`mqtt:lwt(topic, message[, qos[, retain]])` `mqtt:lwt(topic, message[, qos[, retain]])`
......
...@@ -28,7 +28,7 @@ The second value returned is the extended reset cause. Values are: ...@@ -28,7 +28,7 @@ The second value returned is the extended reset cause. Values are:
In general, the extended reset cause supercedes the raw code. The raw code is kept for backwards compatibility only. For new applications it is highly recommended to use the extended reset cause instead. In general, the extended reset cause supercedes the raw code. The raw code is kept for backwards compatibility only. For new applications it is highly recommended to use the extended reset cause instead.
In case of extended reset cause 3 (exception reset), additional values are returned containing the crash information. These are, in order, EXCCAUSE, EPC1, EPC2, EPC3, EXCVADDR, and DEPC. In case of extended reset cause 3 (exception reset), additional values are returned containing the crash information. These are, in order, [EXCCAUSE](https://arduino-esp8266.readthedocs.io/en/latest/exception_causes.html), EPC1, EPC2, EPC3, EXCVADDR, and DEPC.
#### Syntax #### Syntax
`node.bootreason()` `node.bootreason()`
...@@ -245,7 +245,7 @@ Redirects the Lua interpreter output to a callback function. Optionally also pri ...@@ -245,7 +245,7 @@ Redirects the Lua interpreter output to a callback function. Optionally also pri
function tonet(str) function tonet(str)
sk:send(str) sk:send(str)
end end
node.output(tonet, 1) -- serial also get the lua output. node.output(tonet, 1) -- serial also get the Lua output.
``` ```
```lua ```lua
...@@ -335,6 +335,9 @@ Put NodeMCU in light sleep mode to reduce current consumption. ...@@ -335,6 +335,9 @@ Put NodeMCU in light sleep mode to reduce current consumption.
* All active timers will be suspended and then resumed when NodeMCU wakes from sleep. * 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. * Any previously suspended timers will be resumed when NodeMCU wakes from sleep.
!!! attention
This is disabled by default. Modify `PMSLEEP_ENABLE` in `app/include/user_config.h` to enable it.
#### Syntax #### Syntax
`node.sleep({wake_gpio[, duration, int_type, resume_cb, preserve_mode]})` `node.sleep({wake_gpio[, duration, int_type, resume_cb, preserve_mode]})`
......
...@@ -62,7 +62,7 @@ then call it asynchronously a few more times (e.g. using [node.task.post](../mod ...@@ -62,7 +62,7 @@ then call it asynchronously a few more times (e.g. using [node.task.post](../mod
#### Example #### Example
```lua ```lua
-- lua transmit radio code using protocol #1 -- Lua transmit radio code using protocol #1
-- pulse_length 300 microseconds -- pulse_length 300 microseconds
-- repeat 5 times -- repeat 5 times
-- use pin #7 (GPIO13) -- use pin #7 (GPIO13)
......
...@@ -26,7 +26,7 @@ time tracking is somewhat worse, but normally within 10ms. ...@@ -26,7 +26,7 @@ time tracking is somewhat worse, but normally within 10ms.
!!! important !!! important
This module uses RTC memory slots 0-9, inclusive. As soon as [`rtctime.set()`](#rtctimeset) (or [`sntp.sync()`](sntp.md#sntpsync)) has been called these RTC memory slots will be used. This module uses RTC memory slots 0-9, inclusive. As soon as [`rtctime.set()`](#rtctimeset) (or [`sntp.sync()`](sntp.md#sntpsync)) has been called these RTC memory slots will be used.
This is a companion module to the [rtcmem](rtcmem.md) and [SNTP](sntp.md) modules. This is a companion module to the [rtcmem](rtcmem.md) and [SNTP](sntp.md) modules.
...@@ -39,7 +39,7 @@ Puts the ESP8266 into deep sleep mode, like [`node.dsleep()`](node.md#nodedsleep ...@@ -39,7 +39,7 @@ Puts the ESP8266 into deep sleep mode, like [`node.dsleep()`](node.md#nodedsleep
- The time slept will generally be considerably more accurate than with [`node.dsleep()`](node.md#nodedsleep). - The time slept will generally be considerably more accurate than with [`node.dsleep()`](node.md#nodedsleep).
- A sleep time of zero does not mean indefinite sleep, it is interpreted as a zero length sleep instead. - A sleep time of zero does not mean indefinite sleep, it is interpreted as a zero length sleep instead.
When the sleep timer expires, the platform is rebooted and the lua code is started with the `init.lua` file. The clock is set reasonably accurately. When the sleep timer expires, the platform is rebooted and the Lua code is started with the `init.lua` file. The clock is set reasonably accurately.
#### Syntax #### Syntax
`rtctime.dsleep(microseconds [, option])` `rtctime.dsleep(microseconds [, option])`
...@@ -157,3 +157,30 @@ rtctime.set(1436430589, 0) ...@@ -157,3 +157,30 @@ rtctime.set(1436430589, 0)
``` ```
#### See also #### See also
[`sntp.sync()`](sntp.md#sntpsync) [`sntp.sync()`](sntp.md#sntpsync)
## rtctime.adjust_delta()
This takes a time interval in 'system clock microseconds' based on the timestamps returned by `tmr.now` and returns
an adjusted time interval in 'wall clock microseconds'. The size of the adjustment is typically pretty small as it (roughly) the error in the
crystal clock rate. This function is useful in some precision timing applications.
#### Syntax
`rtctime.adjust_delta(microseconds)`
#### Parameters
- `microseconds` a time interval measured in system clock microseconds.
#### Returns
The same interval but measured in wall clock microseconds
#### Example
```lua
local start = tmr.now()
-- do something
local end = tmr.now()
print ('Duration', rtctime.adjust_delta(end - start))
-- You can also go in the other direction (roughly)
local one_second = 1000000
local ticks_in_one_second = one_second - (rtctime.adjust_delta(one_second) - one_second)
```
...@@ -19,11 +19,15 @@ The handling of json null is as follows: ...@@ -19,11 +19,15 @@ The handling of json null is as follows:
- 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 - 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"`. 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. 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.
!!! note
All examples below use in-memory JSON or content read from the SPIFFS file system. However, where a streaming implementation really shines is in fetching large JSON structures from the remote resources and extracting values on-the-fly. An elaborate streaming example can be found in the [`/lua_examples`](../../../lua_examples/sjson-streaming.lua) folder.
## sjson.encoder() ## sjson.encoder()
This creates an encoder object that can convert a LUA object into a JSON encoded string. This creates an encoder object that can convert a Lua object into a JSON encoded string.
####Syntax ####Syntax
`sjson.encoder(table [, opts])` `sjson.encoder(table [, opts])`
...@@ -53,7 +57,8 @@ A string of up to `size` bytes, or `nil` if the encoding is complete and all dat ...@@ -53,7 +57,8 @@ A string of up to `size` bytes, or `nil` if the encoding is complete and all dat
#### Example #### 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 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. can be bigger than the total amount of memory on the NodeMCU.
```
```lua
function files() function files()
result = {} result = {}
for k,v in pairs(file.list()) do for k,v in pairs(file.list()) do
...@@ -101,7 +106,7 @@ end ...@@ -101,7 +106,7 @@ end
## sjson.decoder() ## 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 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). you to handle each value as it is inserted into each table (by implementing the `__newindex` method).
####Syntax ####Syntax
...@@ -149,7 +154,7 @@ you only need the `download_url` keys, then the total size is around 600B. This ...@@ -149,7 +154,7 @@ you only need the `download_url` keys, then the total size is around 600B. This
## sjson.decoder:write ## sjson.decoder:write
This provides more data to be parsed into the lua object. This provides more data to be parsed into the Lua object.
####Syntax ####Syntax
`decoder:write(string)` `decoder:write(string)`
...@@ -159,7 +164,7 @@ This provides more data to be parsed into the lua object. ...@@ -159,7 +164,7 @@ This provides more data to be parsed into the lua object.
- `string` the next piece of JSON encoded data - `string` the next piece of JSON encoded data
####Returns ####Returns
The constructed lua object or `nil` if the decode is not yet complete. The constructed Lua object or `nil` if the decode is not yet complete.
####Errors ####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. If a parse error occurrs during this decode, then an error is thrown and the parse is aborted. The object cannot be used again.
...@@ -167,7 +172,7 @@ If a parse error occurrs during this decode, then an error is thrown and the par ...@@ -167,7 +172,7 @@ If a parse error occurrs during this decode, then an error is thrown and the par
## sjson.decoder:result ## 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 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. same object each time.
####Syntax ####Syntax
...@@ -230,5 +235,5 @@ for k,v in pairs(t) do print(k,v) end ...@@ -230,5 +235,5 @@ for k,v in pairs(t) do print(k,v) end
##Constants ##Constants
There is one constant -- `sjson.NULL` -- which is used in lua structures to represent the presence of a JSON null. There is one constant, `sjson.NULL`, which is used in Lua structures to represent the presence of a JSON null.
...@@ -16,6 +16,11 @@ Attempts to obtain time synchronization. ...@@ -16,6 +16,11 @@ Attempts to obtain time synchronization.
For best results you may want to to call this periodically in order to compensate for internal clock drift. As stated in the [rtctime](rtctime.md) module documentation it's advisable to sync time after deep sleep and it's necessary to sync after module reset (add it to [`init.lua`](../upload.md#initlua) after WiFi initialization). For best results you may want to to call this periodically in order to compensate for internal clock drift. As stated in the [rtctime](rtctime.md) module documentation it's advisable to sync time after deep sleep and it's necessary to sync after module reset (add it to [`init.lua`](../upload.md#initlua) after WiFi initialization).
Note that either a single server can be provided as an argument (name or address), or a list (table) of servers can be provided. Note that either a single server can be provided as an argument (name or address), or a list (table) of servers can be provided.
If *all* of the supplied host names/addresses are invalid, then the error callback will be called with argument type 1. Otherwise, if
there is at least one valid name/address, then then sync will be performed.
If any sync operation fails (maybe the device is disconnected from the internet), then all the names will be looked up again.
#### Syntax #### Syntax
`sntp.sync([server_ip], [callback], [errcallback], [autorepeat])` `sntp.sync([server_ip], [callback], [errcallback], [autorepeat])`
`sntp.sync({ server1, server2, .. }, [callback], [errcallback], [autorepeat])` `sntp.sync({ server1, server2, .. }, [callback], [errcallback], [autorepeat])`
......
# sqlite3 Module
| Since | Origin / Contributor | Maintainer | Source |
| :----- | :-------------------- | :---------- | :------ |
| 2017-06-20 | [Luiz Felipe Silva](https://github.com/luizfeliperj) | [Luiz Felipe Silva](https://github.com/luizfeliperj) | [sqlite3.c](../../../app/modules/sqlite3.c)|
This module is based on [LuaSQLite3](http://lua.sqlite.org/index.cgi/index) module developed by Tiago Dionizio and Doug Currie with contributions from Thomas Lauer, Michael Roth, and Wolfgang Oertl.
This module depens on [SQLite3](http://www.sqlite.org/) library developed by Dwayne Richard Hipp.
For instruction on how to use this module or further documentation, please, refer to [LuaSQLite3 Documentation](http://lua.sqlite.org/index.cgi/doc/tip/doc/lsqlite3.wiki).
This module is a stripped down version of SQLite, with every possible OMIT_\* configuration enable. The enabled OMIT_\* directives are available in the module's [Makefile](../../../app/sqlite3/Makefile).
The SQLite3 module vfs layer integration with NodeMCU was developed by me.
**Simple example**
```lua
db = sqlite3.open_memory()
db:exec[[
CREATE TABLE test (id INTEGER PRIMARY KEY, content);
INSERT INTO test VALUES (NULL, 'Hello, World');
INSERT INTO test VALUES (NULL, 'Hello, Lua');
INSERT INTO test VALUES (NULL, 'Hello, Sqlite3')
]]
for row in db:nrows("SELECT * FROM test") do
print(row.id, row.content)
end
```
\ No newline at end of file
...@@ -291,3 +291,10 @@ firmware image. ...@@ -291,3 +291,10 @@ firmware image.
The alternative approach is easier for development, and that is to supply the PEM data as a string value to `tls.cert.verify`. This The alternative approach is easier for development, and that is to supply the PEM data as a string value to `tls.cert.verify`. This
will store the certificate into the flash chip and turn on verification for that certificate. Subsequent boots of the nodemcu can then will store the certificate into the flash chip and turn on verification for that certificate. Subsequent boots of the nodemcu can then
use `tls.cert.verify(true)` and use the stored certificate. use `tls.cert.verify(true)` and use the stored certificate.
# tls.setDebug function
mbedTLS can be compiled with debug support. If so, the tls.setDebug
function is mapped to the `mbedtls_debug_set_threshold` function and
can be used to enable or disable debugging spew to the console.
See mbedTLS's documentation for more details.
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