Commit 4911d2db authored by Arnim Läuger's avatar Arnim Läuger
Browse files

Merge pull request #1336 from nodemcu/dev

1.5.1 master drop
parents c8037568 2e109686
# perf Module
| Since | Origin / Contributor | Maintainer | Source |
| :----- | :-------------------- | :---------- | :------ |
| 2016-02-26 | [Philip Gladstone](https://github.com/pjsg) | [Philip Gladstone](https://github.com/pjsg) | [perf.c](../../../app/modules/perf.c)|
This module provides simple performance measurement for an application. It samples the program counter roughly every 50 microseconds and builds a histogram of the values that it finds. Since there is only a small amount
of memory to store the histogram, the user can specify which area of code is of interest. The default is the entire flash which contains code. Once the hotspots are identified, then the run can then be repeated with different areas and at different resolutions to get as much information as required.
## perf.start()
Starts a performance monitoring session.
#### Syntax
`perf.start([start[, end[, nbins[, offset]]]])`
#### Parameters
- `start` (optional) The lowest PC address for the histogram. Default is 0x40000000.
- `end` (optional) The highest address for the histogram. Default is the end of the used space in the flash memory.
- `nbins` (optional) The number of bins in the histogram. Keep this reasonable otherwise
you will run out of memory. Default is 1024.
- `offset` (Very optional) This specifies the offset of the saved PC value
on the interrupt stack. It appears that 20 is the correct value.
Note that the number of bins is an upper limit. The size of each bin is set to be the smallest power of two
such that the number of bins required is less than or equal to the provided number of bins.
#### Returns
Nothing
## perf.stop()
Terminates a performance monitoring session and returns the histogram.
#### Syntax
`total, outside, histogram, binsize = perf.stop()`
#### Returns
- `total` The total number of samples captured in this run
- `outside` The number of samples that were outside the histogram range
- `histogram` The histogram represented as a table indexed by address where the value is the number of samples. The address is the lowest address for the bin.
- `binsize` The number of bytes per histogram bin.
### Example
perf.start()
for j = 0, 100 do
str = "str"..j
end
tot, out, tbl, binsize = perf.stop()
print(tot, out)
local keyset = {}
local n = 0
for k,v in pairs(tbl) do
n=n+1
keyset[n]=k
end
table.sort(keyset)
for kk,k in ipairs(keyset) do print(string.format("%x - %x",k, k + binsize - 1),tbl[k]) end
This runs a loop creating strings 100 times and then prints out the histogram (after sorting it).
This takes around 2,500 samples and provides a good indication of where all the CPU time is
being spent.
# PWM Module
| Since | Origin / Contributor | Maintainer | Source |
| :----- | :-------------------- | :---------- | :------ |
| 2014-12-22 | [Zeroday](https://github.com/funshine) | [Zeroday](https://github.com/funshine) | [pwm.c](../../../app/modules/pwm.c)|
## pwm.close()
Quit PWM mode for the specified GPIO pin.
#### Syntax
`pwm.close(pin)`
#### Parameters
`pin` 1~12, IO index
#### Returns
`nil`
#### See also
[pwm.start()](#pwmstart)
## pwm.getclock()
Get selected PWM frequency of pin.
#### Syntax
`pwm.getclock(pin)`
#### Parameters
`pin` 1~12, IO index
#### Returns
`number` PWM frequency of pin
#### See also
[pwm.setclock()](#pwmsetclock)
#### See also
[pwm.getduty()](#pwmgetduty)
## pwm.getduty()
Get selected duty cycle of pin.
#### Syntax
`pwm.getduty(pin)`
#### Parameters
`pin` 1~12, IO index
#### Returns
`number` duty cycle, max 1023
#### See also
[pwm.setduty()](#pwmsetduty)
## pwm.setclock()
Set PWM frequency.
**Note:** Setup of the PWM frequency will synchronously change other setups as well if there are any. Only one PWM frequency can be allowed for the system.
#### Syntax
`pwm.setclock(pin, clock)`
#### Parameters
- `pin` 1~12, IO index
- `clock` 1~1000, PWM frequency
#### Returns
`nil`
#### See also
[pwm.getclock()](#pwmgetclock)
## pwm.setduty()
Set duty cycle for a pin.
#### Syntax
`pwm.setduty(pin, duty)`
#### Parameters
- `pin` 1~12, IO index
- `duty` 0~1023, pwm duty cycle, max 1023 (10bit)
#### Returns
`nil`
#### Example
```lua
-- D1 is connected to green led
-- D2 is connected to blue led
-- D3 is connected to red led
pwm.setup(1, 500, 512)
pwm.setup(2, 500, 512)
pwm.setup(3, 500, 512)
pwm.start(1)
pwm.start(2)
pwm.start(3)
function led(r, g, b)
pwm.setduty(1, g)
pwm.setduty(2, b)
pwm.setduty(3, r)
end
led(512, 0, 0) -- set led to red
led(0, 0, 512) -- set led to blue.
```
## pwm.setup()
Set pin to PWM mode. Only 6 pins can be set to PWM mode at the most.
#### Syntax
`pwm.setup(pin, clock, duty)`
#### Parameters
- `pin` 1~12, IO index
- `clock` 1~1000, pwm frequency
- `duty` 0~1023, pwm duty cycle, max 1023 (10bit)
#### Returns
`nil`
#### Example
```lua
-- set pin index 1 as pwm output, frequency is 100Hz, duty cycle is half.
pwm.setup(1, 100, 512)
```
#### See also
[pwm.start()](#pwmstart)
## pwm.start()
PWM starts, the waveform is applied to the GPIO pin.
#### Syntax
`pwm.start(pin)`
####Parameters
`pin` 1~12, IO index
#### Returns
`nil`
#### See also
[pwm.stop()](#pwmstop)
## pwm.stop()
Pause the output of the PWM waveform.
#### Syntax
`pwm.stop(pin)`
#### Parameters
`pin` 1~12, IO index
#### Returns
`nil`
#### See also
[pwm.start()](#pwmstart)
# RC Module
| Since | Origin / Contributor | Maintainer | Source |
| :----- | :-------------------- | :---------- | :------ |
| 2015-06-12 | [Mike Wen](https://github.com/mikewen) | - | [rc.c](../../../app/modules/rc.c)|
# rotary Module
| Since | Origin / Contributor | Maintainer | Source |
| :----- | :-------------------- | :---------- | :------ |
| 2016-03-01 | [Philip Gladstone](https://github.com/pjsg) | [Philip Gladstone](https://github.com/pjsg) | [rotary.c](../../../app/modules/rotary.c)|
This module can read the state of cheap rotary encoder switches. These are available at all the standard places for a dollar or two. They are five pin devices where three are used for a gray code encoder for rotation, and two are used for the push switch. These switches are commonly used in car audio systems.
These switches do not have absolute positioning, but only encode the number of positions rotated clockwise / anti-clockwise. To make use of this module, connect the common pin on the quadrature encoder to ground and the A and B phases to the NodeMCU. One pin of the push switch should also be grounded and the other pin connected to the NodeMCU.
## Sources for parts
- Amazon: This [search](http://www.amazon.com/s/ref=nb_sb_noss_1?url=search-alias%3Dindustrial&field-keywords=rotary+encoder+push+button&rh=n%3A16310091%2Ck%3Arotary+encoder+push+button) shows a variety.
- Ebay: Somewhat cheaper in this [search](http://www.ebay.com/sch/i.html?_from=R40&_trksid=p2050601.m570.l1313.TR0.TRC0.H0.Xrotary+encoder+push+button.TRS0&_nkw=rotary+encoder+push+button&_sacat=0)
- Adafruit: [rotary encoder](https://www.adafruit.com/products/377)
- Aliexpress: This [search](http://www.aliexpress.com/wholesale?catId=0&initiative_id=SB_20160217173657&SearchText=rotary+encoder+push+button) reveals all sorts of shapes and sizes.
There is also a switch mounted on a board with standard 0.1" pins.
This is the KY-040, and can also be found at [lots of places](https://www.google.com/webhp?sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8#q=ky-040%20rotary%20encoder).
Note that the pins are named somewhat eccentrically, and I suspect that it really does need the VCC connected.
## Constants
- `rotary.PRESS = 1` The eventtype for the switch press.
- `rotary.LONGPRESS = 2` The eventtype for a long press.
- `rotary.RELEASE = 4` The eventtype for the switch release.
- `rotary.TURN = 8` The eventtype for the switch rotation.
- `rotary.CLICK = 16` The eventtype for a single click (after release)
- `rotary.DBLCLICK = 32` The eventtype for a double click (after second release)
- `rotary.ALL = 63` All event types.
## rotary.setup()
Initialize the nodemcu to talk to a rotary encoder switch.
#### Syntax
`rotary.setup(channel, pina, pinb[, pinpress[, longpress_time_ms[, dblclick_time_ms]]])`
#### Parameters
- `channel` The rotary module supports three switches. The channel is either 0, 1 or 2.
- `pina` This is a GPIO number (excluding 0) and connects to pin phase A on the rotary switch.
- `pinb` This is a GPIO number (excluding 0) and connects to pin phase B on the rotary switch.
- `pinpress` (optional) This is a GPIO number (excluding 0) and connects to the press switch.
- `longpress_time_ms` (optional) The number of milliseconds (default 500) of press to be considered a long press.
- `dblclick_time_ms` (optional) The number of milliseconds (default 500) between a release and a press for the next release to be considered a double click.
#### Returns
Nothing. If the arguments are in error, or the operation cannot be completed, then an error is thrown.
For all API calls, if the channel number is out of range, then an error will be thrown.
#### Example
rotary.setup(0, 5,6, 7)
## rotary.on()
Sets a callback on specific events.
#### Syntax
`rotary.on(channel, eventtype[, callback])`
#### Parameters
- `channel` The rotary module supports three switches. The channel is either 0, 1 or 2.
- `eventtype` This defines the type of event being registered. This is the logical or of one or more of `PRESS`, `LONGPRESS`, `RELEASE`, `TURN`, `CLICK` or `DBLCLICK`.
- `callback` This is a function that will be invoked when the specified event happens.
If the callback is None or omitted, then the registration is cancelled.
The callback will be invoked with three arguments when the event happens. The first argument is the eventtype,
the second is the current position of the rotary switch, and the third is the time when the event happened.
The position is tracked
and is represented as a signed 32-bit integer. Increasing values indicate clockwise motion. The time is the number of microseconds represented
in a 32-bit integer. Note that this wraps every hour or so.
#### Example
rotary.on(0, rotary.ALL, function (type, pos, when)
print "Position=" .. pos .. " event type=" .. type .. " time=" .. when
end)
#### Notes
Events will be delivered in order, but there may be missing TURN events. If there is a long
queue of events, then PRESS and RELEASE events may also be missed. Multiple pending TURN events
are typically dispatched as one TURN callback with the final position as its parameter.
Some switches have 4 steps per detent. This means that, in practice, the application
should divide the position by 4 and use that to determine the number of clicks. It is
unlikely that a switch will ever reach 30 bits of rotation in either direction -- some
are rated for under 50,000 revolutions.
The `CLICK` and `LONGPRESS` events are delivered on a timeout. The `DBLCLICK` event is delivered after a `PRESS`, `RELEASE`, `PRESS`, `RELEASE` sequence
where this is a short time gap between the middle `RELEASE` and `PRESS`.
#### Errors
If an invalid `eventtype` is supplied, then an error will be thrown.
## rotary.getpos()
Gets the current position and press status of the switch
#### Syntax
`pos, press, queue = rotary.getpos(channel)`
#### Parameters
- `channel` The rotary module supports three switches. The channel is either 0, 1 or 2.
#### Returns
- `pos` The current position of the switch.
- `press` A boolean indicating if the switch is currently pressed.
- `queue` The number of undelivered callbacks (normally 0).
#### Example
print rotary.getpos(0)
## rotary.close()
Releases the resources associated with the rotary switch.
#### Syntax
`rotary.close(channel)`
#### Parameters
- `channel` The rotary module supports three switches. The channel is either 0, 1 or 2.
#### Example
rotary.close(0)
# RTC FIFO Module
| Since | Origin / Contributor | Maintainer | Source |
| :----- | :-------------------- | :---------- | :------ |
| 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.
- Sensor names are limited to a maximum of 4 characters.
!!! note "Important:"
This module uses two sets of RTC memory slots, 10-20 for its control block, and a variable number of slots for samples and sensor names. By default these span 32-127, but this is configurable. Slots are claimed when [`rtcfifo.prepare()`](#rtcfifoprepare) is called.
This is a companion module to the [rtcmem](rtcmem.md) and [rtctime](rtctime.md) modules.
## rtcfifo.dsleep_until_sample()
When the rtcfifo module is compiled in together with the rtctime module, this convenience function is available. It allows for some measure of separation of concerns, enabling writing of modularized Lua code where a sensor reading abstraction may not need to be aware of the sample frequency (which is largely a policy decision, rather than an intrinsic of the sensor). Use of this function is effectively equivalent to [`rtctime.dsleep_aligned(interval_us, minsleep_us)`](rtctime.md#rtctimedsleep_aligned) where `interval_us` is what was given to [`rtcfifo.prepare()`](#rtcfifoprepare).
####Syntax
`rtcfifo.dsleep_until_sample(minsleep_us)`
####Parameter
`minsleep_us` minimum sleep time, in microseconds
####Example
```lua
-- deep sleep until it's time to take the next sample
rtcfifo.dsleep_until_sample(0)
```
####See also
[`rtctime.dsleep_aligned()`](rtctime.md#rtctimedsleep_aligned)
## rtcfifo.peek()
Reads a sample from the rtcfifo. An offset into the rtcfifo may be specified, but by default it reads the first sample (offset 0).
####Syntax:
`rtcfifo.peek([offset])`
####Parameters
`offset` Peek at sample at position `offset` in the fifo. This is a relative offset, from the current head. Zero-based. Default value is 0.
####Returns
The values returned match the input arguments used to [`rtcfifo.put()`](#rtcfifoput).
- `timestamp` timestamp in seconds
- `value` the value
- `neg_e` scaling factor
- `name` sensor name
If no sample is available (at the specified offset), nothing is returned.
####Example
```lua
local timestamp, value, neg_e, name = rtcfifo.peek()
```
## rtcfifo.pop()
Reads the first sample from the rtcfifo, and removes it from there.
####Syntax:
`rtcfifo.pop()`
####Parameters
none
####Returns
The values returned match the input arguments used to [`rtcfifo.put()`](#rtcfifoput).
- `timestamp` timestamp in seconds
- `value` the value
- `neg_e` scaling factor
- `name` sensor name
####Example
```lua
while rtcfifo.count() > 0 do
local timestamp, value, neg_e, name = rtcfifo.pop()
-- do something with the sample, e.g. upload to somewhere
end
```
## rtcfifo.prepare()
Initializes the rtcfifo module for use.
Calling [`rtcfifo.prepare()`](#rtcfifoprepare) unconditionally re-initializes the storage - any samples stored are discarded.
####Syntax
`rtcfifo.prepare([table])`
####Parameters
This function takes an optional configuration table as an argument. The following items may be configured:
- `interval_us` If wanting to make use of the [`rtcfifo.sleep_until_sample()`](#rtcfifosleep_until_sample) function, this field sets the sample interval (in microseconds) to use. It is effectively the first argument of [`rtctime.dsleep_aligned()`](rtctime.md#rtctimedsleep_aligned).
- `sensor_count` Specifies the number of different sensors to allocate name space for. This directly corresponds to a number of slots reserved for names in the variable block. The default value is 5, minimum is 1, and maximum is 16.
- `storage_begin` Specifies the first RTC user memory slot to use for the variable block. Default is 32. Only takes effect if `storage_end` is also specified.
- `storage_end` Specified the end of the RTC user memory slots. This slot number will *not* be touched. Default is 128. Only takes effect if `storage_begin` is also specified.
####Returns
`nil`
####Example
```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.put()
Puts a sample into the rtcfifo.
If the rtcfifo has not been prepared, this function does nothing.
####Syntax
`rtcfifo.put(timestamp, value, neg_e, name)`
####Parameters
- `timestamp` Timestamp in seconds. The timestamp would typically come from [`rtctime.get()`](rtctime.md#rtctimeget).
- `value` The value to store.
- `neg_e` The effective value stored is valueE<sup>neg_e</sup>.
- `name` Name of the sensor. Only the first four (ASCII) characters of `name` are used.
Note that if the timestamp delta is too large compared to the previous sample stored, the rtcfifo evicts all earlier samples to store this one. Likewise, if `name` would mean there are more than the `sensor_count` (as specified to [`rtcfifo.prepare()`](#rtcfifoprepare)) names in use, the rtcfifo evicts all earlier samples.
####Returns
`nil`
####Example
```lua
-- Obtain a sample value from somewhere
local sample = ...
-- Store sample with no scaling, under the name "foo"
rtcfifo.put(rtctime.get(), sample, 0, "foo")
```
## rtcfifo.ready()
Returns non-zero if the rtcfifo has been prepared and is ready for use, zero if not.
####Syntax:
`rtcfifo.ready()`
####Parameters
none
####Returns
Non-zero if the rtcfifo has been prepared and is ready for use, zero if not.
####Example
```lua
-- Prepare the rtcfifo if not already done
if not rtcfifo.ready() then
rtcfifo.prepare()
end
```
\ No newline at end of file
# RTC User Memory Module
| Since | Origin / Contributor | Maintainer | Source |
| :----- | :-------------------- | :---------- | :------ |
| 2015-06-25 | [DiUS](https://github.com/DiUS), [Johny Mattsson](https://github.com/jmattsson) | [Johny Mattsson](https://github.com/jmattsson) | [rtcmem.c](../../../app/modules/rtcmem.c)|
The rtcmem module provides basic access to the [RTC](https://en.wikipedia.org/wiki/Real-time_clock) (Real Time Clock) memory.
The RTC in the ESP8266 contains memory registers which survive a deep sleep, making them highly useful for keeping state across sleep cycles. Some of this memory is reserved for system use, but 128 slots (each 32bit wide) are available for application use. This module provides read and write access to these.
Due to the very limited amount of memory available, there is no mechanism for arbitrating use of particular slots. It is up to the end user to be aware of which memory is used for what, and avoid conflicts. Note that some Lua modules lay claim to certain slots.
This is a companion module to the [rtctime](rtctime.md) and [rtcfifo](rtcfifo.md) modules.
## rtcmem.read32()
Reads one or more 32bit values from RTC user memory.
#### Syntax
`rtcmem.read32(idx [, num])`
#### Parameters
- `idx` zero-based index to start reading from
- `num` number of slots to read (default 1)
#### Returns
The value(s) read from RTC user memory.
If `idx` is outside the valid range [0,127] this function returns nothing.
If `num` results in overstepping the end of available memory, the function only returns the data from the valid slots.
#### Example
```lua
val = rtcmem.read32(0) -- Read the value in slot 0
val1, val2 = rtcmem.read32(42, 2) -- Read the values in slots 42 and 43
```
#### See also
[`rtcmem.write32()`](#rtcmemwrite32)
## rtcmem.write32()
Writes one or more values to RTC user memory, starting at index `idx`.
Writing to indices outside the valid range [0,127] has no effect.
#### Syntax
`rtcmem.write32(idx, val [, val2, ...])`
#### Parameters
- `idx` zero-based index to start writing to. Auto-increments if multiple values are given.
- `val` value to store (32bit)
- `val2...` additional values to store (optional)
#### Returns
`nil`
#### Example
```lua
rtcmem.write32(0, 53) -- Store the value 53 in slot 0
rtcmem.write32(42, 2, 5, 7) -- Store the values 2, 5 and 7 into slots 42, 43 and 44, respectively.
```
#### See also
[`rtcmem.read32()`](#rtcmemread32)
\ No newline at end of file
# RTC Time Module
| Since | Origin / Contributor | Maintainer | Source |
| :----- | :-------------------- | :---------- | :------ |
| 2015-06-25 | [DiUS](https://github.com/DiUS), [Johny Mattsson](https://github.com/jmattsson), Bernd Meyer <bmeyer@dius.com.au> | [Johny Mattsson](https://github.com/jmattsson) | [rtctime.c](../../../app/modules/rtctime.c)|
The rtctime module provides advanced timekeeping support for NodeMCU, including keeping time across deep sleep cycles (provided [`rtctime.dsleep()`](#rtctimedsleep) is used instead of [`node.dsleep()`](node.md#nodedsleep)). This can be used to significantly extend battery life on battery powered sensor nodes, as it is no longer necessary to fire up the RF module each wake-up in order to obtain an accurate timestamp.
This module is intended for use together with [NTP](https://en.wikipedia.org/wiki/Network_Time_Protocol) (Network Time Protocol) for keeping highly accurate real time at all times. Timestamps are available with microsecond precision, based on the Unix Epoch (1970/01/01 00:00:00).
Time keeping on the ESP8266 is technically quite challenging. Despite being named [RTC](https://en.wikipedia.org/wiki/Real-time_clock), the RTC is not really a Real Time Clock in the normal sense of the word. While it does keep a counter ticking while the module is sleeping, the accuracy with which it does so is *highly* dependent on the temperature of the chip. Said temperature changes significantly between when the chip is running and when it is sleeping, meaning that any calibration performed while the chip is active becomes useless mere moments after the chip has gone to sleep. As such, calibration values need to be deduced across sleep cycles in order to enable accurate time keeping. This is one of the things this module does.
Further complicating the matter of time keeping is that the ESP8266 operates on three different clock frequencies - 52MHz right at boot, 80MHz during regular operation, and 160MHz if boosted. This module goes to considerable length to take all of this into account to properly keep the time.
To enable this module, it needs to be given a reference time at least once (via [`rtctime.set()`](#rtctimeset)). For best accuracy it is recommended to provide a reference time twice, with the second time being after a deep sleep.
Note that while the rtctime module can keep time across deep sleeps, it *will* lose the time if the module is unexpectedly reset.
!!! note "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 is a companion module to the [rtcmem](rtcmem.md) and [SNTP](sntp.md) modules.
## rtctime.dsleep()
Puts the ESP8266 into deep sleep mode, like [`node.dsleep()`](node.md#nodedsleep). It differs from [`node.dsleep()`](node.md#nodedsleep) in the following ways:
- Time is kept across the deep sleep. I.e. [`rtctime.get()`](#rtctimeget) will keep working (provided time was available before the sleep).
- This call never returns. The module is put to sleep immediately. This is both to support accurate time keeping and to reduce power consumption.
- 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.
#### Syntax
`rtctime.dsleep(microseconds [, option])`
#### Parameters
- `microseconds` number of microseconds to sleep for. Maxmium value is 4294967295us, or ~71 minutes.
- `option` sleep option, see [`node.dsleep()`](node.md#nodedsleep) for specifics.
#### Returns
This function does not return.
#### Example
```lua
-- sleep for a minute
rtctime.dsleep(60*1000000)
```
```lua
-- sleep for 5 seconds, do not start RF on wakeup
rtctime.dsleep(5000000, 4)
```
## rtctime.dsleep_aligned()
For applications where it is necessary to take samples with high regularity, this function is useful. It provides an easy way to implement a "wake up on the next 5-minute boundary" scheme, without having to explicitly take into account how long the module has been active for etc before going back to sleep.
#### Syntax
`rtctime.dsleep(aligned_us, minsleep_us [, option])`
#### Parameters
- `aligned_us` boundary interval in microseconds
- `minsleep_us` minimum time that will be slept, if necessary skipping an interval. This is intended for sensors where a sample reading is started before putting the ESP8266 to sleep, and then fetched upon wake-up. Here `minsleep_us` should be the minimum time required for the sensor to take the sample.
- `option` as with `dsleep()`, the `option` sets the sleep option, if specified.
#### Example
```lua
-- sleep at least 3 seconds, then wake up on the next 5-second boundary
rtctime.dsleep_aligned(5*1000000, 3*1000000)
```
## rtctime.get()
Returns the current time. If current time is not available, zero is returned.
#### Syntax
`rtctime.get()`
#### Parameters
none
#### Returns
A two-value timestamp containing:
- `sec` seconds since the Unix epoch
- `usec` the microseconds part
#### Example
```lua
sec, usec = rtctime.get()
```
#### See also
[`rtctime.set()`](#rtctimeset)
## rtctime.set()
Sets the rtctime to a given timestamp in the Unix epoch (i.e. seconds from midnight 1970/01/01). If the module is not already keeping time, it starts now. If the module was already keeping time, it uses this time to help adjust its internal calibration values. Care is taken that timestamps returned from [`rtctime.get()`](#rtctimeget) *never go backwards*. If necessary, time is slewed and gradually allowed to catch up.
It is highly recommended that the timestamp is obtained via NTP (see [SNTP module](sntp.md)), GPS, or other highly accurate time source.
Values very close to the epoch are not supported. This is a side effect of keeping the memory requirements as low as possible. Considering that it's no longer 1970, this is not considered a problem.
#### Syntax
`rtctime.set(seconds, microseconds)`
#### Parameters
- `seconds` the seconds part, counted from the Unix epoch
- `microseconds` the microseconds part
#### Returns
`nil`
#### Example
```lua
-- Set time to 2015 July 9, 18:29:49
rtctime.set(1436430589, 0)
```
#### See also
[`sntp.sync()`](sntp.md#sntpsync)
\ No newline at end of file
# Sigma-delta Module
| Since | Origin / Contributor | Maintainer | Source |
| :----- | :-------------------- | :---------- | :------ |
| 2016-02-20 | [Espressif example](http://bbs.espressif.com/viewtopic.php?t=49), [Arnim Läuger](https://github.com/devsaurus) | [Arnim Läuger](https://github.com/devsaurus) | [sigma_delta.c](../../../app/modules/sigma_delta.c)|
This module provides access to the [sigma-delta](https://en.wikipedia.org/wiki/Delta-sigma_modulation) component. It's a hardware signal generator that can be routed to any of the GPIOs except pin 0.
The signal generation is controlled by the [`setprescale()`](#sigma_deltasetprescale) and [`settarget()`](#sigma_deltasettarget) functions.
- 0 < target <= 128<br />
t<sub>high</sub> = (prescale + 1) / 80 µs<br />
t<sub>period</sub> = t<sub>high</sub> * 256 / target
- 128 < target < 256<br />
t<sub>low</sub> = (prescale + 1) / 80 µs<br />
t<sub>period</sub> = t<sub>low</sub> * 256 / (256 - target)
- target = 0<br />
signal stopped at low
Fixed frequency PWM at ~312.5&nbsp;kHz is availble with the [`setpwmduty()`](#sigma_deltasetpwmduty) function.
## sigma_delta.close()
Stops signal generation and reenables GPIO functionality at the specified pin.
#### Syntax
`sigma_delta.close(pin)`
#### Parameters
`pin` 1~12, IO index
#### Returns
`nil`
## sigma_delta.setprescale()
Sets the prescale value.
#### Syntax
`sigma_delta.setprescale(value)
#### Parameters
`value` prescale 1 to 255
#### Returns
`nil`
#### See also
[`sigma_delta.settarget()`](#sigma_deltasettarget)
## sigma_delta.setpwmduty()
Operate the sigma-delta module in PWM-like mode with fixed base frequency.
#### Syntax
`sigma_delta.setpwmduty(ratio)`
#### Parameters
`ratio` 0...255 for duty cycle 0...100%, 0 stops the signal at low
#### Returns
`nil`
#### Example
```lua
-- attach generator to pin 2
sigma_delta.setup(2)
-- set 50% duty cycle ratio (and implicitly start signal)
sigma_delta.setpwmduty(128)
-- stop
sigma_delta.setpwmduty(0)
-- resume with ~99.6% ratio
sigma_delta.setpwmduty(255)
-- stop and detach generator from pin 2
sigma_delta.close(2)
```
## sigma_delta.settarget()
Sets the target value.
#### Syntax
`sigma_delta.settarget(value)`
#### Parameters
`value` target 0 to 255
#### Returns
`nil`
#### See also
[`sigma_delta.setprescale()`](#sigma_deltasetprescale)
## sigma_delta.setup()
Stops the signal generator and routes it to the specified pin.
#### Syntax
`sigma_delta.setup(pin)`
#### Parameters
`pin` 1~12, IO index
#### Returns
`nil`
# SNTP Module
| Since | Origin / Contributor | Maintainer | Source |
| :----- | :-------------------- | :---------- | :------ |
| 2015-06-30 | [DiUS](https://github.com/DiUS), [Johny Mattsson](https://github.com/jmattsson) | [Johny Mattsson](https://github.com/jmattsson) | [sntp.c](../../../app/modules/sntp.c)|
The SNTP module implements a [Simple Network Time Procotol](https://en.wikipedia.org/wiki/Network_Time_Protocol#SNTP) client. This includes support for the "anycast" [NTP](https://en.wikipedia.org/wiki/Network_Time_Protocol) mode where, if supported by the NTP server(s) in your network, it is not necessary to even know the IP address of the NTP server.
When compiled together with the [rtctime](rtctime.md) module it also offers seamless integration with it, potentially reducing the process of obtaining NTP synchronization to a simple `sntp.sync()` call without any arguments.
## sntp.sync()
Attempts to obtain time synchronization.
#### Syntax
`sntp.sync([server_ip], [callback], [errcallback])`
#### Parameters
- `server_ip` if non-`nil`, that server is used. If `nil`, then the last contacted server is used. This ties in with the NTP anycast mode, where the first responding server is remembered for future synchronization requests. The easiest way to use anycast is to always pass nil for the server argument.
- `callback` Iif provided it will be invoked on a successful synchronization, with three parameters: seconds, microseconds, and server. Note that when the [rtctime](rtctime.md) module is available, there is no need to explicitly call [`rtctime.set()`](rtctime.md#rtctimeset) - this module takes care of doing so internally automatically, for best accuracy.
- `errcallback` failure callback with a single integer parameter describing the type of error. The module automatically performs a number of retries before giving up and reporting the error. Error codes:
- 1: DNS lookup failed
- 2: Memory allocation failure
- 3: UDP send failed
- 4: Timeout, no NTP response received
#### Returns
`nil`
#### Example
```lua
-- Best effort, use the last known NTP server (or the NTP "anycast" address 224.0.1.1 initially)
sntp.sync()
```
```lua
-- Sync time with 192.168.0.1 and print the result, or that it failed
sntp.sync('192.168.0.1',
function(sec,usec,server)
print('sync', sec, usec, server)
end,
function()
print('failed!')
end
)
```
#### See also
[`rtctime.set()`](rtctime.md#rtctimeset)
# SPI Module
| Since | Origin / Contributor | Maintainer | Source |
| :----- | :-------------------- | :---------- | :------ |
| 2015-01-16 | [Ibrahim Abd Elkader](https://github.com/iabdalkader) | [Arnim Läuger](https://github.com/devsaurus) | [spi.c](../../../app/modules/spi.c)|
All transactions for sending and receiving are most-significant-bit first and least-significant last.
For technical details of the underlying hardware refer to [metalphreak's ESP8266 HSPI articles](http://d.av.id.au/blog/tag/hspi/).
## 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
length and each data item is surrounded by (H)SPI CS inactive.
## spi.recv()
Receive data from SPI.
#### Syntax
`spi.recv(id, size[, default_data])`
#### Parameters
- `id` SPI ID number: 0 for SPI, 1 for HSPI
- `size` number of data items to be read
- `default_data` default data being sent on MOSI (all-1 if omitted)
#### Returns
String containing the bytes read from SPI.
####See also
[spi.send()](#spisend)
## spi.send()
Send data via SPI in half-duplex mode. Send & receive data in full-duplex mode.
#### Syntax
HALFDUPLEX:<br />
`wrote = spi.send(id, data1[, data2[, ..., datan]])`
FULLDUPLEX:<br />
`wrote[, rdata1[, ..., rdatan]] = spi.send(id, data1[, data2[, ..., datan]])`
#### Parameters
- `id` SPI ID number: 0 for SPI, 1 for HSPI
- `data` data can be either a string, a table or an integer number.<br/>Each data item is considered with `databits` number of bits.
#### Returns
- `wrote` number of written bytes
- `rdata` received data when configured with `spi.FULLDUPLEX`<br />Same data type as corresponding data parameter.
#### Example
```lua
=spi.send(1, 0, 255, 255, 255)
4 255 192 32 0
x = {spi.send(1, 0, 255, 255, 255)}
=x[1]
4
=x[2]
255
=x[3]
192
=x[4]
32
=x[5]
0
=x[6]
nil
=#x
5
_, _, x = spi.send(1, 0, {255, 255, 255})
=x[1]
192
=x[2]
32
=x[3]
0
```
#### See also
- [spi.setup()](#spisetup)
- [spi.recv()](#spirecv)
## spi.setup()
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.
#### Syntax
`spi.setup(id, mode, cpol, cpha, databits, clock_div[, duplex_mode])`
#### Parameters
- `id` SPI ID number: 0 for SPI, 1 for HSPI
- `mode` select master or slave mode
- `spi.MASTER`
- `spi.SLAVE` - **not supported currently**
- `cpol` clock polarity selection
- `spi.CPOL_LOW`
- `spi.CPOL_HIGH`
- `cpha` clock phase selection
- `spi.CPHA_LOW`
- `spi.CPHA_HIGH`
- `databits` number of bits per data item 1 - 32
- `clock_div` SPI clock divider, f(SPI) = f(CPU) / `clock_div`
- `duplex_mode` duplex mode
- `spi.HALFDUPLEX` (default when omitted)
- `spi.FULLDUPLEX`
#### Returns
Number: 1
## 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
programming model is built up around the HW send and receive buffers and SPI
transactions are initiated with full control over the hardware features.
## spi.get_miso()
Extract data items from MISO buffer after `spi.transaction()`.
#### Syntax
`data1[, data2[, ..., datan]] = spi.get_miso(id, offset, bitlen, num)`
#### Parameters
- `id` SPI ID number: 0 for SPI, 1 for HSPI
- `offset` bit offset into MISO buffer for first data item
- `bitlen` bit length of a single data item
- `num` number of data items to retrieve
####Returns
`num` data items
#### See also
[spi.transaction()](#spitransaction)
## spi.set_mosi()
Insert data items into MOSI buffer for `spi.transaction()`.
#### Syntax
`spi.set_mosi(id, offset, bitlen, data1[, data2[, ..., datan]])`
####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.
#### Returns
`nil`
#### See also
[spi.transaction()](#spitransaction)
## spi.transaction()
Start an SPI transaction, consisting of up to 5 phases:
1. Command
2. Address
3. MOSI
4. Dummy
5. MISO
#### Syntax
`spi.transaction(id, cmd_bitlen, cmd_data, addr_bitlen, addr_data, mosi_bitlen, dummy_bitlen, miso_bitlen)`
#### Parameters
- `id` SPI ID number: 0 for SPI, 1 for HSPI
- `cmd_bitlen` bit length of the command phase (0 - 16)
- `cmd_data` data for command phase
- `addr_bitlen` bit length for address phase (0 - 32)
- `addr_data` data for command phase
- `mosi_bitlen` bit length of the MOSI phase (0 - 512)
- `dummy_bitlen` bit length of the dummy phase (0 - 256)
- `miso_bitlen` bit length of the MISO phase (0 - 512) for half-duplex.<br />Full-duplex mode is activated with a negative value.
####Returns
`nil`
####See also
- [spi.set_mosi()](#spisetmosi)
- [spi.get_miso()](#spigetmiso)
# Struct Module
| Since | Origin / Contributor | Maintainer | Source |
| :----- | :-------------------- | :---------- | :------ |
| 2015-02-13 | [Roberto Ierusalimschy](http://www.inf.puc-rio.br/~roberto/struct/), [Philip Gladstone](https://github.com/pjsg) | [Philip Gladstone](https://github.com/pjsg) | [struct.c](../../../app/modules/struct.c)|
This module offers basic facilities to convert Lua values to and from C structs. Its main functions are `struct.pack`, which packs multiple Lua values into a struct-like string; and `struct.unpack`, which unpacks multiple Lua values from a given struct-like string.
The first argument to both functions is a *format string*, which describes the layout of the structure. The format string is a sequence of conversion elements, which respect the current endianess and the current alignment requirements. Initially, the current endianess is the machine's native endianness and the current alignment requirement is 1 (meaning no alignment at all). You can change these settings with appropriate directives in the format string.
Note that the float and double conversions are only available with a floating point NodeMCU build.
### Format String
The elements in the format string are as follows:
- `" "` (empty space) ignored.
- `"!n"` flag to set the current alignment requirement to *n*
(necessarily a power of 2); an absent *n* means the machine's native
alignment.
- `">"` flag to set mode to big endian.
- `"<"` flag to set mode to little endian.
- `"x"` a padding zero byte with no corresponding Lua value.
- `"b"` a signed `char`.
- `"B"` an unsigned `char`.
- `"h"` a signed `short` (native size).
- `"H"` an unsigned `short` (native size).
- `"l"` a signed `long` (native size).
- `"L"` an unsigned `long` (native size).
- `"T"` a `size_t` (native size).
- `"in"` a signed integer with *n* bytes. An absent *n* means the
native size of an `int`.
- `"In"` like `"in"` but unsigned.
- `"f"` a `float` (native size).
- `"d"` a `double` (native size).
- `"s"` a zero-terminated string.
- `"cn"` a sequence of exactly *n* chars corresponding to a single Lua
string. An absent *n* means 1. When packing, the given string must
have at least *n* characters (extra characters are discarded).
- `"c0"` this is like `"cn"`, except that the *n* is given by other
means: When packing, *n* is the length of the given string; when
unpacking, *n* is the value of the previous unpacked value (which
must be a number). In that case, this previous value is not
returned.
#### Examples
To pack and unpack the structure
struct Str {
char b;
int i[4];
};
you can use the string `"<!4biiii"`.
To pack a string with its length coded in its first byte, use the
following code:
x = struct.pack("Bc0", string.len(s), s)
To unpack that string, do as follows:
s = struct.unpack("Bc0", x)
Note that the length (read by the element `"B"`) is not returned.
To pack a string in a fixed-width field of 10 characters padded with
blanks, do as follows:
x = struct.pack("c10", s .. string.rep(" ", 10))
## struct.pack()
Returns a string containing the values `d1`, `d2`, etc. packed
according to the format string `fmt`.
#### Syntax
`struct.pack (fmt, d1, d2, ...)`
#### Parameters
- `fmt` The format string in the format above
- `d1` The first data item to be packed
- `d2` The second data item to be packed etc.
#### Returns
The packed string.
#### Example
```
s = struct.pack("I", 0x41424344)
print(s)
```
## struct.unpack()
Returns the values packed in string `s` according to the format
string `fmt`. An optional `i` marks where in `s` to start reading
(default is 1). After the read values, this function also returns
the index in `s` where it stopped reading, which is also where you
should start to read the rest of the string.
#### Syntax
`struct.unpack (fmt, s[, offset])`
#### Parameters
- `fmt` The format string in the format above
- `s` The string holding the data to be unpacked
- `offset` The position to start in the string (default is 1)
#### Returns
All the unpacked data.
#### Example
Suppose we have to decode a string `s` with an unknown number of
doubles; the end is marked by a zero value. We can use the following
code:
local a = {}
local i = 1 -- index where to read
while true do
local d
d, i = struct.unpack("d", s, i)
if d == 0 then break end
a[#a + 1] = d
end
## struct.size()
Returns the size of a string formatted according to the format
string `fmt`. The format string should contain neither the option
`s` nor the option `c0`.
#### Syntax
`struct.size (fmt)`
#### Parameters
- `fmt` The format string in the format above
#### Returns
The size of the string that would be output in a pack operation with this format string.
#### Example
```
print(struct.size("i"))
```
This prints the size of the native integer type.
### License
This package is distributed under the MIT license. See copyright notice
at the end of file `struct.c`.
# Timer Module
| Since | Origin / Contributor | Maintainer | Source |
| :----- | :-------------------- | :---------- | :------ |
| 2014-12-12 | [Zeroday](https://github.com/funshine) | [dnc40085](https://github.com/dnc40085) | [tmr.c](../../../app/modules/tmr.c)|
The tmr module allows access to simple timers, the system counter and uptime.
It is aimed at setting up regularly occurring tasks, timing out operations, and provide low-resolution deltas.
What the tmr module is *not* however, is a time keeping module. While most timeouts are expressed in milliseconds or even microseconds, the accuracy is limited and compounding errors would lead to rather inaccurate time keeping. Consider using the [rtctime](rtctime.md) module for "wall clock" time.
NodeMCU provides 7 timers, numbered 0-6. It is currently up to the user to keep track of which timers are used for what.
## tmr.alarm()
This is a convenience function combining [`tmr.register()`](#tmrregister) and [`tmr.start()`](#tmrstart) into a single call.
To free up the resources with this timer when done using it, call [`tmr.unregister()`](#tmrunregister) on it. For one-shot timers this is not necessary, unless they were stopped before they expired.
#### Parameters
- `id` timer id (0-6)
- `interval_ms` timer interval in milliseconds. Maximum value is 6870947 (1:54:30.947).
- `mode` timer mode:
- `tmr.ALARM_SINGLE` a one-shot alarm (and no need to call [`tmr.unregister()`](#tmrunregister))
- `tmr.ALARM_SEMI` manually repeating alarm (call [`tmr.start()`](#tmrstart) to restart)
- `tmr.ALARM_AUTO` automatically repeating alarm
#### Returns
`true` if the timer was started, `false` on error
#### Example
```lua
if not tmr.alarm(0, 5000, tmr.ALARM_SINGLE, function() print("hey there") end) then print("whoopsie") end
```
#### See also
- [`tmr.register()`](#tmrregister)
- [`tmr.start()`](#tmrstart)
- [`tmr.unregister()`](#tmrunregister)
## tmr.delay()
Busyloops the processor for a specified number of microseconds.
This is in general a **bad** idea, because nothing else gets to run, and the networking stack (and other things) can fall over as a result. The only time `tmr.delay()` may be appropriate to use is if dealing with a peripheral device which needs a (very) brief delay between commands, or similar. *Use with caution!*
Also note that the actual amount of time delayed for may be noticeably greater, both as a result of timing inaccuracies as well as interrupts which may run during this time.
#### Syntax
`tmr.delay(us)`
#### Parameters
`us` microseconds to busyloop for
#### Returns
`nil`
#### Example
```lua
tmr.delay(100)
```
## tmr.interval()
Changes a registered timer's expiry interval.
#### Syntax
`tmr.interval(id, interval_ms)`
#### Parameters
- `id` timer id (0-6)
- `interval_ms` new timer interval in milliseconds. Maximum value is 6870947 (1:54:30.947).
#### Returns
`nil`
#### Example
```lua
tmr.register(0, 5000, tmr.ALARM_SINGLE, function() print("hey there") end)
tmr.interval(0, 3000) -- actually, 3 seconds is better!
```
## tmr.now()
Returns the system counter, which counts in microseconds. Limited to 31 bits, after that it wraps around back to zero. That is essential if you use this function to [debounce or throttle GPIO input](https://github.com/hackhitchin/esp8266-co-uk/issues/2).
#### Syntax
`tmr.now()`
#### Parameters
none
#### Returns
the current value of the system counter
#### Example
```lua
print(tmr.now())
print(tmr.now())
```
## tmr.register()
Configures a timer and registers the callback function to call on expiry.
To free up the resources with this timer when done using it, call [`tmr.unregister()`](#tmrunregister) on it. For one-shot timers this is not necessary, unless they were stopped before they expired.
#### Syntax
`tmr.register(id, interval_ms, mode, func)`
#### Parameters
- `id` timer id (0-6)
- `interval_ms` timer interval in milliseconds. Maximum value is 6870947 (1:54:30.947).
- `mode` timer mode:
- `tmr.ALARM_SINGLE` a one-shot alarm (and no need to call [`tmr.unregister()`](#tmrunregister))
- `tmr.ALARM_SEMI` manually repeating alarm (call [`tmr.start()`](#tmrunregister) to restart)
- `tmr.ALARM_AUTO` automatically repeating alarm
Note that registering does *not* start the alarm.
#### Returns
`nil`
#### Example
```lua
tmr.register(0, 5000, tmr.ALARM_SINGLE, function() print("hey there") end)
tmr.start(0)
```
#### See also
[`tmr.alarm()`](#tmralarm)
## tmr.softwd()
Provides a simple software watchdog, which needs to be re-armed or disabled before it expires, or the system will be restarted.
#### Syntax
`tmr.softwd(timeout_s)`
#### Parameters
`timeout_s` watchdog timeout, in seconds. To disable the watchdog, use -1 (or any other negative value).
#### Returns
`nil`
#### Example
```lua
function on_success_callback()
tmr.softwd(-1)
print("Complex task done, soft watchdog disabled!")
end
tmr.softwd(5)
-- go off and attempt to do whatever might need a restart to recover from
complex_stuff_which_might_never_call_the_callback(on_success_callback)
```
## tmr.start()
Starts or restarts a previously configured timer.
#### Syntax
`tmr.start(id)`
#### Parameters
`id` timer id (0-6)
#### Returns
`true` if the timer was started, `false` on error
#### Example
```lua
tmr.register(0, 5000, tmr.ALARM_SINGLE, function() print("hey there") end)
if not tmr.start(0) then print("uh oh") end
```
#### See also
- [`tmr.register()`](#tmrregister)
- [`tmr.stop()`](#tmrstop)
- [`tmr.unregister()`](#tmrunregister)
## tmr.state()
Checks the state of a timer.
#### Syntax
`tmr.state(id)`
#### Parameters
`id` timer id (0-6)
#### Returns
(bool, int) or `nil`
If the specified timer is registered, returns whether it is currently started and its mode. If the timer is not registered, `nil` is returned.
#### Example
```lua
running, mode = tmr.state(0)
```
## tmr.stop()
Stops a running timer, but does *not* unregister it. A stopped timer can be restarted with [`tmr.start()`](#tmrstart).
#### Syntax
`tmr.stop(id)`
#### Parameters
`id` timer id (0-6)
#### Returns
`true` if the timer was stopped, `false` on error
#### Example
```lua
if not tmr.stop(2) then print("timer 2 not stopped, not registered?") end
```
#### See also
- [`tmr.register()`](#tmrregister)
- [`tmr.stop()`](#tmrstop)
- [`tmr.unregister()`](#tmrunregister)
## tmr.time()
Returns the system uptime, in seconds. Limited to 31 bits, after that it wraps around back to zero.
#### Syntax
`tmr.time()`
#### Parameters
none
#### Returns
the system uptime, in seconds, possibly wrapped around
#### Example
```lua
print("Uptime (probably):", tmr.time())
```
## tmr.unregister()
Stops the timer (if running) and unregisters the associated callback.
This isn't necessary for one-shot timers (`tmr.ALARM_SINGLE`), as those automatically unregister themselves when fired.
#### Syntax
`tmr.unregister(id)`
#### Parameters
`id` timer id (0-6)
#### Returns
`nil`
#### Example
```lua
tmr.unregister(0)
```
#### See also
[`tmr.register()`](#tmrregister)
## tmr.wdclr()
Feed the system watchdog.
*In general, if you ever need to use this function, you are doing it wrong.*
The event-driven model of NodeMCU means that there is no need to be sitting in hard loops waiting for things to occur. Rather, simply use the callbacks to get notified when somethings happens. With this approach, there should never be a need to manually feed the system watchdog.
#### Syntax
`tmr.wdclr()`
#### Parameters
none
#### Returns
`nil`
# TSL2561 Module
| Since | Origin / Contributor | Maintainer | Source |
| :----- | :-------------------- | :---------- | :------ |
| 2015-08-22 | [Michael Lucas](https://github.com/Aeprox) | [Michael Lucas](https://github.com/Aeprox) | [tsl2561.c](../../../app/modules/tsl2561.c)|
## tsl2561.getlux()
Reads sensor values from the device and returns calculated lux value.
#### Syntax
`tsl2561.getlux()`
#### Parameters
none
#### Returns
- `lux` the calculated illuminance in lux (lx)
- `status` value indicating success or failure as explained below:
* `tsl2561.TSL2561_OK`
* `tsl2561.TSL2561_ERROR_I2CINIT` can't initialize I²C bus
* `tsl2561.TSL2561_ERROR_I2CBUSY` I²C bus busy
* `tsl2561.TSL2561_ERROR_NOINIT` initialize I²C bus before calling function
* `tsl2561.TSL2561_ERROR_LAST`
#### Example
``` lua
status = tsl2561.init(5, 6, tsl2561.ADDRESS_FLOAT, tsl2561.PACKAGE_T_FN_CL)
if status == tsl2561.TSL2561_OK then
lux = tsl2561.getlux()
print("Illuminance: "..lux.." lx")
end
```
## tsl2561.getrawchannels()
Reads the device's 2 sensors and returns their values.
#### Syntax
`tsl2561.getrawchannels()`
#### Parameters
none
#### Returns
- `ch0` value of the broad spectrum sensor
- `ch1` value of the IR sensor
- `status` value indicating success or failure as explained below:
* `tsl2561.TSL2561_OK`
* `tsl2561.TSL2561_ERROR_I2CINIT` can't initialize I²C bus
* `tsl2561.TSL2561_ERROR_I2CBUSY` I²C bus busy
* `tsl2561.TSL2561_ERROR_NOINIT` initialize I²C bus before calling function
* `tsl2561.TSL2561_ERROR_LAST`
#### Example
``` lua
status = tsl2561.init(5, 6, tsl2561.ADDRESS_FLOAT, tsl2561.PACKAGE_T_FN_CL)
if status == tsl2561.TSL2561_OK then
ch0, ch1 = tsl2561.getrawchannels()
print("Raw values: "..ch0, ch1)
lux = tsl2561.getlux()
print("Illuminance: "..lux.." lx")
end
```
## tsl2561.init()
Initializes the device on pins sdapin & sclpin. Optionally also configures the devices address and package. Default: address pin floating (0x39) and FN package.
#### Syntax
` tsl2561.init(sdapin, sclpin[, address[, package]])`
#### Parameters
- `sdapin` pin number of the device's I²C sda connection
- `sclpin` pin number of the device's I²C scl connection
- `address` optional address of the device on the I²C bus
* `tsl2561.ADDRESS_GND`
* `tsl2561.ADDRESS_FLOAT` (default when omitted)
* `tsl2561.ADDRESS_VDD`
- `package` optional device's package type (slight difference in lux calculation)
* `tsl2561.PACKAGE_CS`
* `tsl2561.PACKAGE_T_FN_CL` (default when omitted)
#### Returns
`status` value indicating success or failure as explained below:
- `tsl2561.TSL2561_OK`
- `tsl2561.TSL2561_ERROR_I2CINIT` can't initialize I²C bus
- `tsl2561.TSL2561_ERROR_I2CBUSY` I²C bus busy
- `tsl2561.TSL2561_ERROR_NOINIT` Initialize I²C bus before calling function
- `tsl2561.TSL2561_ERROR_LAST`
#### Example
``` lua
status = tsl2561.init(5, 6, tsl2561.ADDRESS_FLOAT, tsl2561.PACKAGE_T_FN_CL)
if status == tsl2561.TSL2561_OK then
lux = tsl2561.getlux()
print("Illuminance: "..lux.." lx")
end
```
## tsl2561.settiming()
Sets the integration time and gain settings of the device. When `tls2561.init()` is called, these values default to 402 ms and no gain.
#### Syntax
`tsl2561.settiming(integration, gain)`
#### Parameters
- `integration` sets the device's integration period. Valid options are:
* `tsl2561.INTEGRATIONTIME_13MS`
* `tsl2561.INTEGRATIONTIME_101MS`
* `tsl2561.INTEGRATIONTIME_402MS` (default when omitted)
- `gain` sets the device's gain. Valid options are:
* `tsl2561.GAIN_1X` (default when omitted)
* `tsl2561.GAIN_16X`
#### Returns
`status` value indicating success or failure as explained below:
- `tsl2561.TSL2561_OK`
- `tsl2561.TSL2561_ERROR_I2CINIT` can't initialize I²C bus
- `tsl2561.TSL2561_ERROR_I2CBUSY` I²C bus busy
- `tsl2561.TSL2561_ERROR_NOINIT` initialize I²C bus before calling function
- `tsl2561.TSL2561_ERROR_LAST`
#### Example
``` lua
status = tsl2561.init(5, 6, tsl2561.ADDRESS_FLOAT, tsl2561.PACKAGE_T_FN_CL)
if status == tsl2561.TSL2561_OK then
status = tsl2561.settiming(tsl2561.INTEGRATIONTIME_101MS, tsl2561.GAIN_16X)
end
if status == tsl2561.TSL2561_OK then
lux = tsl2561.getlux()
print("Illuminance: "..lux.." lx")
end
```
# u8g Module
| Since | Origin / Contributor | Maintainer | Source |
| :----- | :-------------------- | :---------- | :------ |
| 2015-01-30 | [Oli Kraus](https://github.com/olikraus/u8glib), [Arnim Läuger](https://github.com/devsaurus) | [Arnim Läuger](https://github.com/devsaurus) | [u8glib](../../../app/u8glib/)|
U8glib is a graphics library developed at [olikraus/u8glib](https://github.com/olikraus/u8glib) with support for many different displays. The NodeMCU firmware supports a subset of these.
I²C and SPI mode:
- sh1106_128x64
- ssd1306 - 128x64 and 64x48 variants
- ssd1309_128x64
- ssd1327_96x96_gr
- uc1611 - dogm240 and dogxl240 variants
SPI only:
- ld7032_60x32
- pcd8544_84x48
- pcf8812_96x65
- ssd1322_nhd31oled - bw and gr variants
- ssd1325_nhd27oled - bw and gr variants
- ssd1351_128x128 - gh and hicolor variants
- st7565_64128n - variants 64128n, dogm128/132, lm6059/lm6063, c12832/c12864
- uc1601_c128032
- uc1608 - 240x128 and 240x64 variants
- uc1610_dogxl160 - bw and gr variants
- uc1611 - dogm240 and dogxl240 variants
- uc1701 - dogs102 and mini12864 variants
This integration is based on [v1.18.1](https://github.com/olikraus/U8glib_Arduino/releases/tag/1.18.1).
## Overview
### I²C Connection
Hook up SDA and SCL to any free GPIOs. Eg. [u8g_graphics_test.lua](https://github.com/nodemcu/nodemcu-firmware/blob/master/lua_examples/u8glib/u8g_graphics_test.lua) expects SDA=5 (GPIO14) and SCL=6 (GPIO12). They are used to set up nodemcu's I²C driver before accessing the display:
```lua
sda = 5
scl = 6
i2c.setup(0, sda, scl, i2c.SLOW)
```
### SPI connection
The HSPI module is used ([more information](http://d.av.id.au/blog/esp8266-hardware-spi-hspi-general-info-and-pinout/)), so certain pins are fixed:
- HSPI CLK = GPIO14
- HSPI MOSI = GPIO13
- HSPI MISO = GPIO12 (not used)
All other pins can be assigned to any available GPIO:
- CS
- D/C
- RES (optional for some displays)
Also refer to the initialization sequence eg in [u8g_graphics_test.lua](https://github.com/nodemcu/nodemcu-firmware/blob/master/lua_examples/u8glib/u8g_graphics_test.lua):
```lua
spi.setup(1, spi.MASTER, spi.CPOL_LOW, spi.CPHA_LOW, 8, 8)
```
### Library Usage
The Lua bindings for this library closely follow u8glib's object oriented C++ API. Based on the u8g class, you create an object for your display type.
SSD1306 via I²C:
```lua
sla = 0x3c
disp = u8g.ssd1306_128x64_i2c(sla)
```
SSD1306 via SPI:
```lua
cs = 8 -- GPIO15, pull-down 10k to GND
dc = 4 -- GPIO2
res = 0 -- GPIO16, RES is optional YMMV
disp = u8g.ssd1306_128x64_hw_spi(cs, dc, res)
```
This object provides all of u8glib's methods to control the display. Again, refer to [u8g_graphics_test.lua](https://github.com/nodemcu/nodemcu-firmware/blob/master/lua_examples/u8glib/u8g_graphics_test.lua) to get an impression how this is achieved with Lua code. Visit the [u8glib homepage](https://github.com/olikraus/u8glib) for technical details.
### Displays
I²C and HW SPI based displays with support in u8glib can be enabled. To get access to the respective constructors, add the desired entries to the I²C or SPI display tables in [app/include/u8g_config.h](https://github.com/nodemcu/nodemcu-firmware/blob/master/app/include/u8g_config.h):
```c
#define U8G_DISPLAY_TABLE_I2C \
U8G_DISPLAY_TABLE_ENTRY(ssd1306_128x64_i2c) \
#define U8G_DISPLAY_TABLE_SPI \
U8G_DISPLAY_TABLE_ENTRY(ssd1306_128x64_hw_spi) \
U8G_DISPLAY_TABLE_ENTRY(pcd8544_84x48_hw_spi) \
U8G_DISPLAY_TABLE_ENTRY(pcf8812_96x65_hw_spi) \
```
### Fonts
u8glib comes with a wide range of fonts for small displays. Since they need to be compiled into the firmware image, you'd need to include them in [app/include/u8g_config.h](https://github.com/nodemcu/nodemcu-firmware/blob/master/app/include/u8g_config.h) and recompile. Simply add the desired fonts to the font table:
```c
#define U8G_FONT_TABLE \
U8G_FONT_TABLE_ENTRY(font_6x10) \
U8G_FONT_TABLE_ENTRY(font_chikita)
```
They'll become available as `u8g.<font_name>` in Lua.
### Bitmaps
Bitmaps and XBMs are supplied as strings to `drawBitmap()` and `drawXBM()`. This off-loads all data handling from the u8g module to generic methods for binary files. See [u8g_bitmaps.lua](https://github.com/nodemcu/nodemcu-firmware/blob/master/lua_examples/u8glib/u8g_bitmaps.lua).
In contrast to the source code based inclusion of XBMs into u8glib, it's required to provide precompiled binary files. This can be performed online with [Online-Utility's Image Converter](http://www.online-utility.org/image_converter.jsp): Convert from XBM to MONO format and upload the binary result with [nodemcu-uploader.py](https://github.com/kmpm/nodemcu-uploader).
## I²C Display Drivers
Initialize a display via I²C.
The init sequence would insert delays to match the display specs. These can destabilize the overall system if wifi service is blocked for too long. It is therefore advisable to disable such delays unless the specific use case can exclude wifi traffic while initializing the display driver.
- `u8g.sh1106_128x64_i2c()`
- `u8g.ssd1306_128x64_i2c()`
- `u8g.ssd1306_64x48_i2c()`
- `u8g.ssd1309_128x64_i2c()`
- `u8g.ssd1327_96x96_gr_i2c()`
- `u8g.uc1611_dogm240_i2c()`
- `u8g.uc1611_dogxl240_i2c()`
####Syntax
`u8g.ssd1306_128x64_i2c(address[, use_delay])`
####Parameters
- `address` I²C slave address of display
- `use_delay` '1': use delays in init sequence, '0' if omitted
####Returns
u8g display object
####Example
```lua
sda = 5
scl = 6
i2c.setup(0, sda, scl, i2c.SLOW)
sla = 0x3c
disp = u8g.ssd1306_128x64_i2c(sla)
```
####See also
[SPI Display Drivers](#spi-display-drivers)
## SPI Display Drivers
Initialize a display via Hardware SPI.
The init sequence would insert delays to match the display specs. These can destabilize the overall system if wifi service is blocked for too long. It is therefore advisable to disable such delays unless the specific use case can exclude wifi traffic while initializing the display driver.
- `u8g.ld7032_60x32_hw_spi()`
- `u8g.pcd8544_84x48_hw_spi()`
- `u8g.pcf8812_96x65_hw_spi()`
- `u8g.sh1106_128x64_hw_spi()`
- `u8g.ssd1306_128x64_hw_spi()`
- `u8g.ssd1306_64x48_hw_spi()`
- `u8g.ssd1309_128x64_hw_spi()`
- `u8g.ssd1322_nhd31oled_bw_hw_spi()`
- `u8g.ssd1322_nhd31oled_gr_hw_spi()`
- `u8g.ssd1325_nhd27oled_bw_hw_spi()`
- `u8g.ssd1325_nhd27oled_gr_hw_spi()`
- `u8g.ssd1327_96x96_gr_hw_spi()`
- `u8g.ssd1351_128x128_332_hw_spi()`
- `u8g.ssd1351_128x128gh_332_hw_spi()`
- `u8g.ssd1351_128x128_hicolor_hw_spi()`
- `u8g.ssd1351_128x128gh_hicolor_hw_spi()`
- `u8g.ssd1353_160x128_332_hw_spi()`
- `u8g.ssd1353_160x128_hicolor_hw_spi()`
- `u8g.st7565_64128n_hw_spi()`
- `u8g.st7565_dogm128_hw_spi()`
- `u8g.st7565_dogm132_hw_spi()`
- `u8g.st7565_lm6059_hw_spi()`
- `u8g.st7565_lm6063_hw_spi()`
- `u8g.st7565_nhd_c12832_hw_spi()`
- `u8g.st7565_nhd_c12864_hw_spi()`
- `u8g.uc1601_c128032_hw_spi()`
- `u8g.uc1608_240x128_hw_spi()`
- `u8g.uc1608_240x64_hw_spi()`
- `u8g.uc1610_dogxl160_bw_hw_spi()`
- `u8g.uc1610_dogxl160_gr_hw_spi()`
- `u8g.uc1611_dogm240_hw_spi()`
- `u8g.uc1611_dogxl240_hw_spi()`
- `u8g.uc1701_dogs102_hw_spi()`
- `u8g.uc1701_mini12864_hw_spi()`
#### Syntax
`u8g.ssd1306_128x64_spi(cs, dc[, res[, use_delay]])`
#### Parameters
- `cs` GPIO pin for /CS
- `dc` GPIO pin for DC
- `res` GPIO pin for /RES, none if omitted
- `use_delay` '1': use delays in init sequence, '0' if omitted
#### Returns
u8g display object
#### Example
```lua
spi.setup(1, spi.MASTER, spi.CPOL_LOW, spi.CPHA_LOW, 8, 8)
cs = 8 -- GPIO15, pull-down 10k to GND
dc = 4 -- GPIO2
res = 0 -- GPIO16, RES is optional YMMV
disp = u8g.ssd1306_128x64_hw_spi(cs, dc, res)
```
#### See also
[I²C Display Drivers](#i2c-display-drivers)
___
## Constants
Constants for various functions.
`u8g.DRAW_UPPER_RIGHT`, `u8g.DRAW_UPPER_LEFT`, `u8g.DRAW_LOWER_RIGHT`, `u8g.DRAW_LOWER_LEFT`, `u8g.DRAW_ALL`,
`u8g.MODE_BW`, `u8g.MODE_GRAY2BIT`
`u8g.font_6x10`, ...
# u8g.disp Sub-Module
## u8g.disp:begin()
See [u8glib begin()](https://github.com/olikraus/u8glib/wiki/userreference#begin).
## u8g.disp:drawBitmap()
Draw a bitmap at the specified x/y position (upper left corner of the bitmap).
Parts of the bitmap may be outside the display boundaries. The bitmap is specified by the array bitmap. A cleared bit means: Do not draw a pixel. A set bit inside the array means: Write pixel with the current color index. For a monochrome display, the color index 0 will usually clear a pixel and the color index 1 will set a pixel.
#### Syntax
`disp:drawBitmap(x, y, cnt, h, bitmap)`
#### Parameters
- `x` X-position (left position of the bitmap)
- `y` Y-position (upper position of the bitmap)
- `cnt` number of bytes of the bitmap in horizontal direction. The width of the bitmap is cnt*8.
- `h` height of the bitmap
- `bitmap` bitmap data supplied as string
#### Returns
`nil`
#### See also
- [u8glib drawBitmap()](https://github.com/olikraus/u8glib/wiki/userreference#drawbitmap)
- [lua_examples/u8glib/u8g_bitmaps.lua](https://github.com/nodemcu/nodemcu-firmware/blob/master/lua_examples/u8glib/u8g_bitmaps.lua)
- [u8g.disp:drawXBM()](#u8gdispdrawxbm)
## u8g.disp:drawBox()
See [u8glib drawBox()](https://github.com/olikraus/u8glib/wiki/userreference#drawbox).
## u8g.disp:drawCircle()
See [u8glib drawCircle()](https://github.com/olikraus/u8glib/wiki/userreference#drawcircle).
## u8g.disp:drawDisc()
See [u8glib drawDisc()](https://github.com/olikraus/u8glib/wiki/userreference#drawdisc).
## u8g.disp:drawEllipse()
See [u8glib drawEllipse()](https://github.com/olikraus/u8glib/wiki/userreference#drawellipse).
## u8g.disp:drawFilledEllipse()
See [u8glib drawFilledEllipse](https://github.com/olikraus/u8glib/wiki/userreference#drawfilledellipse).
## u8g.disp:drawFrame()
See [u8glib drawFrame()](https://github.com/olikraus/u8glib/wiki/userreference#drawframe).
## u8g.disp:drawHLine()
See [u8glib drawHLine()](https://github.com/olikraus/u8glib/wiki/userreference#drawhline).
## u8g.disp:drawLine()
See [u8glib drawLine()](https://github.com/olikraus/u8glib/wiki/userreference#drawline).
## u8g.disp:drawPixel()
See [u8glib drawPixel()](https://github.com/olikraus/u8glib/wiki/userreference#drawpixel).
## u8g.disp:drawRBox()
See [u8glib drawRBox()](https://github.com/olikraus/u8glib/wiki/userreference#drawrbox).
## u8g.disp:drawRFrame()
See [u8glib drawRFrame()](https://github.com/olikraus/u8glib/wiki/userreference#drawrframe).
## u8g.disp:drawStr()
See [u8glib drawStr()](https://github.com/olikraus/u8glib/wiki/userreference#drawstr).
## u8g.disp:drawStr90()
See [u8glib drawStr90](https://github.com/olikraus/u8glib/wiki/userreference#drawstr90).
## u8g.disp:drawStr180()
See [u8glib drawStr180()](https://github.com/olikraus/u8glib/wiki/userreference#drawstr180).
## u8g.disp:drawStr270()
See [u8glib drawStr270()](https://github.com/olikraus/u8glib/wiki/userreference#drawstr270).
## u8g.disp:drawTriangle()
See [u8glib drawTriangle()](https://github.com/olikraus/u8glib/wiki/userreference#drawtriangle).
## u8g.disp:drawVLine()
See [u8glib drawVLine()](https://github.com/olikraus/u8glib/wiki/userreference#drawvline).
## u8g.disp:drawXBM()
Draw a XBM Bitmap. Position (x,y) is the upper left corner of the bitmap.
XBM contains monochrome, 1-bit bitmaps. This procedure only draws pixel values 1. The current color index is used for drawing (see setColorIndex). Pixel with value 0 are not drawn (transparent).
Bitmaps and XBMs are supplied as strings to `drawBitmap()` and `drawXBM()`. This off-loads all data handling from the u8g module to generic methods for binary files. In contrast to the source code based inclusion of XBMs into u8glib, it's required to provide precompiled binary files. This can be performed online with [Online-Utility's Image Converter](http://www.online-utility.org/image_converter.jsp): Convert from XBM to MONO format and upload the binary result with [nodemcu-uploader.py](https://github.com/kmpm/nodemcu-uploader) or [ESPlorer](http://esp8266.ru/esplorer/).
#### Syntax
`disp:drawXBM(x, y, w, h, bitmap)`
#### Parameters
- `x` X-position (left position of the bitmap)
- `y` Y-position (upper position of the bitmap)
- `w` width of the bitmap
- `h` height of the bitmap
- `bitmap` XBM data supplied as string
#### Returns
`nil`
#### See also
- [u8glib drawXBM()](https://github.com/olikraus/u8glib/wiki/userreference#drawxbm)
- [lua_examples/u8glib/u8g_bitmaps.lua](https://github.com/nodemcu/nodemcu-firmware/blob/master/lua_examples/u8glib/u8g_bitmaps.lua)
- [u8g.disp:drawBitmap()](#u8gdispdrawbitmap)
## u8g.disp:firstPage()
See [u8glib firstPage()](https://github.com/olikraus/u8glib/wiki/userreference#firstpage).
## u8g.disp:getColorIndex()
See [u8glib getColorIndex()](https://github.com/olikraus/u8glib/wiki/userreference#getcolorindex).
## u8g.disp:getFontAscent()
See [u8glib getFontAscent()](https://github.com/olikraus/u8glib/wiki/userreference#getfontascent).
## u8g.disp:getFontDescent()
See [u8glib getFontDescent()](https://github.com/olikraus/u8glib/wiki/userreference#getfontdescent).
## u8g.disp:getFontLineSpacing()
See [u8glib getFontLineSpacing()](https://github.com/olikraus/u8glib/wiki/userreference#getfontlinespacing).
## u8g.disp:getHeight()
See [u8glib getHeight()](https://github.com/olikraus/u8glib/wiki/userreference#getheight).
## u8g.disp:getMode()
See [u8glib getMode()](https://github.com/olikraus/u8glib/wiki/userreference#getmode).
## u8g.disp:getWidth()
See [u8glib getWidth()](https://github.com/olikraus/u8glib/wiki/userreference#getwidth).
## u8g.disp:getStrWidth()
See [u8glib getStrWidth](https://github.com/olikraus/u8glib/wiki/userreference#getstrwidth).
## u8g.disp:nextPage()
See [u8glib nextPage()](https://github.com/olikraus/u8glib/wiki/userreference#nextpage).
## u8g.disp:setColorIndex()
See [u8glib setColorIndex()](https://github.com/olikraus/u8glib/wiki/userreference#setcolortndex).
## u8g.disp:setDefaultBackgroundColor()
See [u8glib setDefaultBackgroundColor()](https://github.com/olikraus/u8glib/wiki/userreference#setdefaultbackgroundcolor).
## u8g.disp:setDefaultForegroundColor()
See [u8glib setDefaultForegroundColor()](https://github.com/olikraus/u8glib/wiki/userreference#setdefaultforegroundcolor).
## u8g.disp:setFont()
u8glib comes with a wide range of fonts for small displays.
Since they need to be compiled into the firmware image, you'd need to include them in `app/include/u8g_config.h` and recompile. Simply add the desired fonts to the font table:
```c
#define U8G_FONT_TABLE \
U8G_FONT_TABLE_ENTRY(font_6x10) \
U8G_FONT_TABLE_ENTRY(font_chikita)
```
They'll be available as `u8g.<font_name>` in Lua.
#### Syntax
`disp:setFont(font)`
#### Parameters
`font` Constant to indentify pre-compiled font
#### Returns
`nil`
#### Example
```lua
disp:setFont(u8g.font_6x10)
```
#### See also
- [u8glib setFont()](https://github.com/olikraus/u8glib/wiki/userreference#setfont)
## u8g.disp:setFontLineSpacingFactor()
See [u8glib setFontLineSpacingFactor()](https://github.com/olikraus/u8glib/wiki/userreference#setfontlinespacingfactor).
## u8g.disp:setFontPosBaseline()
See [u8glib setFontPosBaseline()](https://github.com/olikraus/u8glib/wiki/userreference#setfontposbaseline).
## u8g.disp:setFontPosBottom()
See [u8glib setFontPosBottom()](https://github.com/olikraus/u8glib/wiki/userreference#setfontposbottom).
## u8g.disp:setFontPosCenter()
See [u8glib setFontPosCenter()](https://github.com/olikraus/u8glib/wiki/userreference#setfontposcenter).
## u8g.disp:setFontPosTop()
See [u8glib setFontPosTop()](https://github.com/olikraus/u8glib/wiki/userreference#setfontpostop).
## u8g.disp:setFontRefHeightAll()
See [u8glib setFontRefHeightAll()](https://github.com/olikraus/u8glib/wiki/userreference#setfontrefheightall).
## u8g.disp:setFontRefHeightExtendedText()
See [u8glib setFontRefHeightExtendedText()](https://github.com/olikraus/u8glib/wiki/userreference#setfontrefheightextendedtext).
## u8g.disp:setFontRefHeightText()
See [u8glib setFontRefHeightText()](https://github.com/olikraus/u8glib/wiki/userreference#setfontrefheighttext).
## u8g.disp:setRot90()
See [u8glib setRot90()](https://github.com/olikraus/u8glib/wiki/userreference#setrot90).
## u8g.disp:setRot180()
See [u8glib setRot180()](https://github.com/olikraus/u8glib/wiki/userreference#setrot180).
## u8g.disp:setRot270()
See [u8glib setRot270()](https://github.com/olikraus/u8glib/wiki/userreference#setrot270).
## u8g.disp:setScale2x2()
See [u8glib setScale2x2()](https://github.com/olikraus/u8glib/wiki/userreference#setscale2x2).
## u8g.disp:sleepOn()
See [u8glib sleepOn()](https://github.com/olikraus/u8glib/wiki/userreference#sleepon).
## u8g.disp:sleepOff()
See [u8glib sleepOff()](https://github.com/olikraus/u8glib/wiki/userreference#sleepoff).
## u8g.disp:undoRotation()
See [u8glib undoRotation()](https://github.com/olikraus/u8glib/wiki/userreference#undorotation).
## u8g.disp:undoScale()
See [u8glib undoScale()](https://github.com/olikraus/u8glib/wiki/userreference#undoscale).
## Unimplemented Functions
- Cursor handling
- disableCursor()
- enableCursor()
- setCursorColor()
- setCursorFont()
- setCursorPos()
- setCursorStyle()
- General functions
- setContrast()
- setPrintPos()
- setHardwareBackup()
- setRGB()
- setDefaultMidColor()
# UART Module
| Since | Origin / Contributor | Maintainer | Source |
| :----- | :-------------------- | :---------- | :------ |
| 2014-12-22 | [Zeroday](https://github.com/funshine) | [Zeroday](https://github.com/funshine) | [uart.c](../../../app/modules/uart.c)|
The [UART](https://en.wikipedia.org/wiki/Universal_asynchronous_receiver/transmitter) (Universal asynchronous receiver/transmitter) module allows configuration of and communication over the UART serial port.
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.
## uart.alt()
Change UART pin assignment.
#### Syntax
`uart.alt(on)`
#### Parameters
`on`
- 0 for standard pins
- 1 to use alternate pins GPIO13 and GPIO15
#### Returns
`nil`
## uart.on()
Sets the callback function to handle UART events.
Currently only the "data" event is supported.
#### Syntax
`uart.on(method, [number/end_char], [function], [run_input])`
#### Parameters
- `method` "data", data has been received on the UART
- `number/end_char`
- if pass in a number n<255, the callback will called when n chars are received.
- if n=0, will receive every char in buffer.
- if pass in a one char string "c", the callback will called when "c" is encounterd, or max n=255 received.
- `function` callback function, event "data" has a callback like this: `function(data) end`
- `run_input` 0 or 1. If 0, input from UART will not go into Lua interpreter, can accept binary data. If 1, input from UART will go into Lua interpreter, and run.
To unregister the callback, provide only the "data" parameter.
#### Returns
`nil`
#### Example
```lua
-- when 4 chars is received.
uart.on("data", 4,
function(data)
print("receive from uart:", data)
if data=="quit" then
uart.on("data") -- unregister callback function
end
end, 0)
-- when '\r' is received.
uart.on("data", "\r",
function(data)
print("receive from uart:", data)
if data=="quit\r" then
uart.on("data") -- unregister callback function
end
end, 0)
```
## uart.setup()
(Re-)configures the communication parameters of the UART.
#### Syntax
`uart.setup(id, baud, databits, parity, stopbits, echo)`
#### Parameters
- `id` always zero, only one uart supported
- `baud` one of 300, 600, 1200, 2400, 4800, 9600, 19200, 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
#### Returns
configured baud rate (number)
#### Example
```lua
-- configure for 9600, 8N1, with echo
uart.setup(0, 9600, 8, uart.PARITY_NONE, uart.STOPBITS_1, 1)
```
## uart.write()
Write string or byte to the UART.
#### Syntax
`uart.write(id, data1 [, data2, ...])`
#### Parameters
- `id` always 0, only one UART supported
- `data1`... string or byte to send via UART
#### Returns
`nil`
#### Example
```lua
uart.write(0, "Hello, world\n")
```
# ucg Module
| Since | Origin / Contributor | Maintainer | Source |
| :----- | :-------------------- | :---------- | :------ |
| 2015-08-05 | [Oli Kraus](https://github.com/olikraus/ucglib), [Arnim Läuger](https://github.com/devsaurus) | [Arnim Läuger](https://github.com/devsaurus) | [ucglib](../../../app/ucglib/)|
Ucglib is a graphics library developed at [olikraus/ucglib](https://github.com/olikraus/ucglib) with support for color TFT displays. The NodeMCU firmware supports a subset of these:
- ILI9163
- ILI9341
- PCF8833
- SEPS225
- SSD1331
- SSD1351
- ST7735
This integration is based on [v1.3.3](https://github.com/olikraus/Ucglib_Arduino/releases/tag/v1.3.3).
## Overview
### SPI Connection
The HSPI module is used ([more information](http://d.av.id.au/blog/esp8266-hardware-spi-hspi-general-info-and-pinout/)), so certain pins are fixed:
* HSPI CLK = GPIO14
* HSPI MOSI = GPIO13
* HSPI MISO = GPIO12 (not used)
All other pins can be assigned to any available GPIO:
* CS
* D/C
* RES (optional for some displays)
Also refer to the initialization sequence eg in [GraphicsTest.lua](https://github.com/nodemcu/nodemcu-firmware/blob/master/lua_examples/ucglib/GraphicsTest.lua):
```lua
spi.setup(1, spi.MASTER, spi.CPOL_LOW, spi.CPHA_LOW, 8, 8)
```
### Library Usage
The Lua bindings for this library closely follow ucglib's object oriented C++ API. Based on the ucg class, you create an object for your display type.
ILI9341 via SPI:
```lua
cs = 8 -- GPIO15, pull-down 10k to GND
dc = 4 -- GPIO2
res = 0 -- GPIO16, RES is optional YMMV
disp = ucg.ili9341_18x240x320_hw_spi(cs, dc, res)
```
This object provides all of ucglib's methods to control the display.
Again, refer to [GraphicsTest.lua](https://github.com/nodemcu/nodemcu-firmware/blob/master/lua_examples/ucglib/GraphicsTest.lua) to get an impression how this is achieved with Lua code. Visit the [ucglib homepage](https://github.com/olikraus/ucglib) for technical details.
### Displays
To get access to the display constructors, add the desired entries to the display table in [app/include/ucg_config.h](https://github.com/nodemcu/nodemcu-firmware/blob/master/app/include/ucg_config.h):
```c
#define UCG_DISPLAY_TABLE \
UCG_DISPLAY_TABLE_ENTRY(ili9341_18x240x320_hw_spi, ucg_dev_ili9341_18x240x320, ucg_ext_ili9341_18) \
UCG_DISPLAY_TABLE_ENTRY(st7735_18x128x160_hw_spi, ucg_dev_st7735_18x128x160, ucg_ext_st7735_18) \
```
### Fonts
ucglib comes with a wide range of fonts for small displays. Since they need to be compiled into the firmware image, you'd need to include them in [app/include/ucg_config.h](https://github.com/nodemcu/nodemcu-firmware/blob/master/app/include/ucg_config.h) and recompile. Simply add the desired fonts to the font table:
```c
#define UCG_FONT_TABLE \
UCG_FONT_TABLE_ENTRY(font_7x13B_tr) \
UCG_FONT_TABLE_ENTRY(font_helvB12_hr) \
UCG_FONT_TABLE_ENTRY(font_helvB18_hr) \
UCG_FONT_TABLE_ENTRY(font_ncenR12_tr) \
UCG_FONT_TABLE_ENTRY(font_ncenR14_hr)
```
They'll be available as `ucg.<font_name>` in Lua.
## Display Drivers
Initialize a display via Hardware SPI.
- `ili9163_18x128x128_hw_spi()`
- `ili9341_18x240x320_hw_spi()`
- `pcf8833_16x132x132_hw_spi()`
- `seps225_16x128x128_uvis_hw_spi()`
- `ssd1351_18x128x128_hw_spi()`
- `ssd1351_18x128x128_ft_hw_spi()`
- `ssd1331_18x96x64_uvis_hw_spi()`
- `st7735_18x128x160_hw_spi()`
#### Syntax
`ucg.st7735_18x128x160_hw_spi(cs, dc[, res])`
#### Parameters
- `cs` GPIO pin for /CS
- `dc` GPIO pin for DC
- `res` GPIO pin for /RES (optional)
#### Returns
ucg display object
#### Example
```lua
spi.setup(1, spi.MASTER, spi.CPOL_LOW, spi.CPHA_LOW, spi.DATABITS_8, 0)
cs = 8 -- GPIO15, pull-down 10k to GND
dc = 4 -- GPIO2
res = 0 -- GPIO16, RES is optional YMMV
disp = ucg.st7735_18x128x160_hw_spi(cs, dc, res)
```
## Constants
Constants for various functions.
`ucg.FONT_MODE_TRANSPARENT`, `ucg.FONT_MODE_SOLID`, `ucg.DRAW_UPPER_RIGHT`,
`ucg.DRAW_UPPER_LEFT`, `ucg.DRAW_LOWER_RIGHT`, `ucg.DRAW_LOWER_LEFT`, `ucg.DRAW_ALL`
`ucg.font_7x13B_tr`, ...
# ucg.disp Sub-Module
## ucg.disp:begin()
See [ucglib begin()](https://github.com/olikraus/ucglib/wiki/reference#begin).
## ucg.disp:clearScreen()
See [ucglib clearScreen()](https://github.com/olikraus/ucglib/wiki/reference#clearscreen).
## ucg.disp:draw90Line()
See [ucglib draw90Line()](https://github.com/olikraus/ucglib/wiki/reference#draw90line).
## ucg.disp:drawBox()
See [ucglib drawBox()](https://github.com/olikraus/ucglib/wiki/reference#drawbox).
## ucg.disp:drawCircle()
See [ucglib drawCircle()](https://github.com/olikraus/ucglib/wiki/reference#drawcircle).
## ucg.disp:drawDisc()
See [ucglib drawDisc()](https://github.com/olikraus/ucglib/wiki/reference#drawdisc).
## ucg.disp:drawFrame()
See [ucglib drawFrame()](https://github.com/olikraus/ucglib/wiki/reference#drawframe).
## ucg.disp:drawGlyph()
See [ucglib drawGlyph()](https://github.com/olikraus/ucglib/wiki/reference#drawglyph).
## ucg.disp:drawGradientBox()
See [ucglib drawGradientBox()](https://github.com/olikraus/ucglib/wiki/reference#drawgradientbox).
## ucg.disp:drawGradientLine()
See [ucglib drawGradientLine()](https://github.com/olikraus/ucglib/wiki/reference#drawgradientline).
## ucg.disp:drawHLine()
See [ucglib drawHLine()](https://github.com/olikraus/ucglib/wiki/reference#drawhline).
## ucg.disp:drawLine()
See [ucglib drawLine()](https://github.com/olikraus/ucglib/wiki/reference#drawline).
## ucg.disp:drawPixel()
See [ucglib drawPixel()](https://github.com/olikraus/ucglib/wiki/reference#drawpixel).
## ucg.disp:drawRBox()
See [ucglib drawRBox()](https://github.com/olikraus/ucglib/wiki/reference#drawrbox).
## ucg.disp:drawRFrame()
See [ucglib drawRFrame()](https://github.com/olikraus/ucglib/wiki/reference#drawrframe).
## ucg.disp:drawString()
See [ucglib drawString()](https://github.com/olikraus/ucglib/wiki/reference#drawstring).
## ucg.disp:drawTetragon()
See [ucglib drawTetragon()](https://github.com/olikraus/ucglib/wiki/reference#drawtetragon).
## ucg.disp:drawTriangle()
See [ucglib drawTriangle()](https://github.com/olikraus/ucglib/wiki/reference#drawrtiangle).
## ucg.disp:drawVLine()
See [ucglib drawVline()](https://github.com/olikraus/ucglib/wiki/reference#drawvline).
## ucg.disp:getFontAscent()
See [ucglib getFontAscent()](https://github.com/olikraus/ucglib/wiki/reference#getfontascent).
## ucg.disp:getFontDescent()
See [ucglib getFontDescent()](https://github.com/olikraus/ucglib/wiki/reference#getfontdescent).
## ucg.disp:getHeight()
See [ucglib getHeight()](https://github.com/olikraus/ucglib/wiki/reference#getheight).
## ucg.disp:getStrWidth()
See [ucglib getStrWidth()](https://github.com/olikraus/ucglib/wiki/reference#getstrwidth).
## ucg.disp:getWidth()
See [ucglib getWidth()](https://github.com/olikraus/ucglib/wiki/reference#getwidth).
## ucg.disp:print()
See [ucglib print()](https://github.com/olikraus/ucglib/wiki/reference#print).
## ucg.disp:setClipRange()
See [ucglib setClipRange()](https://github.com/olikraus/ucglib/wiki/reference#setcliprange).
## ucg.disp:setColor()
See [ucglib setColor()](https://github.com/olikraus/ucglib/wiki/reference#setcolor).
## ucg.disp:setFont()
ucglib comes with a wide range of fonts for small displays. Since they need to be compiled into the firmware image, you'd need to include them in [app/include/ucg_config.h](https://github.com/nodemcu/nodemcu-firmware/blob/master/app/include/ucg_config.h) and recompile. Simply add the desired fonts to the font table:
```c
#define UCG_FONT_TABLE \
UCG_FONT_TABLE_ENTRY(font_7x13B_tr) \
UCG_FONT_TABLE_ENTRY(font_helvB12_hr) \
UCG_FONT_TABLE_ENTRY(font_helvB18_hr) \
UCG_FONT_TABLE_ENTRY(font_ncenR12_tr) \
UCG_FONT_TABLE_ENTRY(font_ncenR14_hr)
```
They'll be available as `ucg.<font_name>` in Lua.
#### Syntax
`disp:setFont(font)`
#### Parameters
`font` constant to identify pre-compiled font
#### Returns
`nil`
#### Example
```lua
disp:setFont(ucg.font_7x13B_tr)
```
#### See also
[ucglib setFont()](https://github.com/olikraus/ucglib/wiki/reference#setfont)
## ucg.disp:setFontMode()
See [ucglib setFontMode()](https://github.com/olikraus/ucglib/wiki/reference#setfontmode).
## ucg.disp:setFontPosBaseline()
See [ucglib setFontPosBaseline()](https://github.com/olikraus/ucglib/wiki/reference#setfontposbaseline).
## ucg.disp:setFontPosBottom()
See [ucglib setFontPosBottom()](https://github.com/olikraus/ucglib/wiki/reference#setfontposbottom).
## ucg.disp:setFontPosCenter()
See [ucglib setFontPosCenter()](https://github.com/olikraus/ucglib/wiki/reference#setfontposcenter).
## ucg.disp:setFontPosTop()
See [ucglib setFontPosTop()](https://github.com/olikraus/ucglib/wiki/reference#setfontpostop).
## ucg.disp:setMaxClipRange()
See [ucglib setMaxClipRange()](https://github.com/olikraus/ucglib/wiki/reference#setmaxcliprange).
## ucg.disp:setPrintDir()
See [ucglib setPrintDir()](https://github.com/olikraus/ucglib/wiki/reference#setprintdir).
## ucg.disp:setPrintPos()
See [ucglib setPrintPos()](https://github.com/olikraus/ucglib/wiki/reference#setprintpos).
## ucg.disp:setRotate90()
See [ucglib setRotate90()](https://github.com/olikraus/ucglib/wiki/reference#setrotate90).
## ucg.disp:setRotate180()
See [ucglib setRotate180()](https://github.com/olikraus/ucglib/wiki/reference#setrotate180).
## ucg.disp:setRotate270()
See [ucglib setRotate270()](https://github.com/olikraus/ucglib/wiki/reference#setrotate270).
## ucg.disp:setScale2x2()
See [ucglib setScale2x2()](https://github.com/olikraus/ucglib/wiki/reference#setscale2x2).
## ucg.disp:undoClipRange()
See [ucglib undoClipRange()](https://github.com/olikraus/ucglib/wiki/reference#undocliprange).
## ucg.disp:undoRotate()
See [ucglib undoRotate()](https://github.com/olikraus/ucglib/wiki/reference#undorotate).
## ucg.disp:undoScale()
See [ucglib undoScale()](https://github.com/olikraus/ucglib/wiki/reference#undoscale).
# WiFi Module
| Since | Origin / Contributor | Maintainer | Source |
| :----- | :-------------------- | :---------- | :------ |
| 2015-05-12 | [Zeroday](https://github.com/funshine) | [dnc40085](https://github.com/dnc40085) | [wifi.c](../../../app/modules/wifi.c)|
The NodeMCU WiFi control is spread across several tables:
- `wifi` for overall WiFi configuration
- [`wifi.sta`](#wifista-module) for station mode functions
- [`wifi.ap`](#wifiap-module) for wireless access point (WAP or simply AP) functions
- [`wifi.ap.dhcp`](#wifiapdhcp-module) for DHCP server control
- [`wifi.eventmon`](#wifieventmon-module) for wifi event monitor
## wifi.getchannel()
Gets the current WiFi channel.
#### Syntax
`wifi.getchannel()`
#### Parameters
`nil`
#### Returns
current WiFi channel
## wifi.getmode()
Gets WiFi operation mode.
#### Syntax
`wifi.getmode()`
#### Parameters
`nil`
#### Returns
The WiFi mode, as one of the `wifi.STATION`, `wifi.SOFTAP`, `wifi.STATIONAP` or `wifi.NULLMODE` constants.
#### See also
[`wifi.setmode()`](#wifisetmode)
## wifi.getphymode()
Gets WiFi physical mode.
#### Syntax
`wifi.getpymode()`
#### Parameters
none
#### Returns
The current physical mode as one of `wifi.PHYMODE_B`, `wifi.PHYMODE_G` or `wifi.PHYMODE_N`.
#### See also
[`wifi.setphymode()`](#wifisetphymode)
## wifi.setmode()
Configures the WiFi mode to use. NodeMCU can run in one of four WiFi modes:
- Station mode, where the NodeMCU device joins an existing network
- Access point (AP) mode, where it creates its own network that others can join
- Station + AP mode, where it both creates its own network while at the same time being joined to another existing network
- WiFi off
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.
#### Syntax
`wifi.setmode(mode)`
#### Parameters
`mode` value should be one of
- `wifi.STATION` for when the device is connected to a WiFi router. This is often done to give the device access to the Internet.
- `wifi.SOFTAP` for when the device is acting *only* as an access point. This will allow you to see the device in the list of WiFi networks (unless you hide the SSID, of course). In this mode your computer can connect to the device, creating a local area network. Unless you change the value, the NodeMCU device will be given a local IP address of 192.168.4.1 and assign your computer the next available IP address, such as 192.168.4.2.
- `wifi.STATIONAP` is the combination of `wifi.STATION` and `wifi.SOFTAP`. It allows you to create a local WiFi connection *and* connect to another WiFi router.
- `wifi.NULLMODE` to switch off WiFi
#### Returns
current mode after setup
#### Example
```lua
wifi.setmode(wifi.STATION)
```
#### See also
[`wifi.getmode()`](#wifigetmode)
## wifi.setphymode()
Sets WiFi physical mode.
- `wifi.PHYMODE_B`
802.11b, more range, low Transfer rate, more current draw
- `wifi.PHYMODE_G`
802.11g, medium range, medium transfer rate, medium current draw
- `wifi.PHYMODE_N`
802.11n, least range, fast transfer rate, least current draw (STATION ONLY)
Information from the Espressif datasheet v4.3
| Parameters |Typical Power Usage|
|---------------------------------------------|-------------------|
|Tx 802.11b, CCK 11Mbps, P OUT=+17dBm | 170 mA |
|Tx 802.11g, OFDM 54Mbps, P OUT =+15dBm | 140 mA |
|Tx 802.11n, MCS7 65Mbps, P OUT =+13dBm | 120 mA |
|Rx 802.11b, 1024 bytes packet length, -80dBm | 50 mA |
|Rx 802.11g, 1024 bytes packet length, -70dBm | 56 mA |
|Rx 802.11n, 1024 bytes packet length, -65dBm | 56 mA |
#### Syntax
`wifi.setphymode(mode)`
#### Parameters
`mode` one of the following
- `wifi.PHYMODE_B`
- `wifi.PHYMODE_G`
- `wifi.PHYMODE_N`
#### Returns
physical mode after setup
#### See also
[`wifi.getphymode()`](#wifigetphymode)
## wifi.sleeptype()
Configures the WiFi modem sleep type.
#### Syntax
`wifi.sleeptype(type_wanted)`
#### Parameters
`type_wanted` one of the following:
- `wifi.NONE_SLEEP` to keep the modem on at all times
- `wifi.LIGHT_SLEEP` to allow the modem to power down under some circumstances
- `wifi.MODEM_SLEEP` to power down the modem as much as possible
#### Returns
The actual sleep mode set, as one of `wifi.NONE_SLEEP`, `wifi.LIGHT_SLEEP` or `wifi.MODEM_SLEEP`.
#### See also
- [`node.dsleep()`](node.md#nodedsleep)
- [`rtctime.dsleep()`](rtctime.md#rtctimedsleep)
## wifi.startsmart()
Starts to auto configuration, if success set up SSID and password automatically.
Intended for use with SmartConfig apps, such as Espressif's [Android & iOS app](https://github.com/espressifapp).
Only usable in `wifi.STATION` mode.
!!! note "Note:"
SmartConfig is disabled by default and can be enabled by setting `WIFI_SMART_ENABLE` in [`user_config.h`](https://github.com/nodemcu/nodemcu-firmware/blob/dev/app/include/user_config.h#L96) before you build the firmware.
#### Syntax
`wifi.startsmart(type, callback)`
#### Parameters
- `type` 0 for ESP\_TOUCH, or 1 for AIR\_KISS.
- `callback` a callback function of the form `function(ssid, password) end` which gets called after configuration.
#### Returns
`nil`
#### Example
```lua
wifi.setmode(wifi.STATION)
wifi.startsmart(0,
function(ssid, password)
print(string.format("Success. SSID:%s ; PASSWORD:%s", ssid, password))
end
)
```
#### See also
[`wifi.stopsmart()`](#wifistopsmart)
## wifi.stopsmart()
Stops the smart configuring process.
#### Syntax
`wifi.stopsmart()`
#### Parameters
none
#### Returns
`nil`
#### See also
[`wifi.startsmart()`](#wifistartsmart)
# wifi.sta Module
## wifi.sta.autoconnect()
Auto connects to AP in station mode.
#### Syntax
`wifi.sta.autoconnect(auto)`
#### Parameters
`auto` 0 to disable auto connecting, 1 to enable auto connecting
#### Returns
`nil`
#### Example
```lua
wifi.sta.autoconnect(1)
```
#### See also
- [`wifi.sta.config()`](#wifistaconfig)
- [`wifi.sta.connect()`](#wifistaconnect)
- [`wifi.sta.disconnect()`](#wifistadisconnect)
## wifi.sta.config()
Sets the WiFi station configuration.
NOTE: Station configuration will be retained until changed even if device is turned off.
#### Syntax
`wifi.sta.config(ssid, password[, auto[, bssid]])`
#### Parameters
- `ssid` string which is less than 32 bytes.
- `password` string which is 8-64 or 0 bytes. Empty string indicates an open WiFi access point.
- `auto` defaults to 1
- 0 to disable auto connect and remain disconnected from access point
- 1 to enable auto connect and connect to access point, hence with `auto=1` there's no need to call [`wifi.sta.connect()`](#wifistaconnect) later
- `bssid` string that contains the MAC address of the access point (optional)
- You can set BSSID if you have multiple access points with the same SSID.
- Note: if you set BSSID for a specific SSID and would like to configure station to connect to the same SSID only without the BSSID requirement, you MUST first configure to station to a different SSID first, then connect to the desired SSID
- The following formats are valid:
- "DE-C1-A5-51-F1-ED"
- "AC-1D-1C-B1-0B-22"
- "DE AD BE EF 7A C0"
#### Returns
`nil`
#### Example
```lua
-- Connect to access point automatically when in range, `auto` defaults to 1
wifi.sta.config("myssid", "password")
-- Connect to Unsecured access point automatically when in range, `auto` defaults to 1
wifi.sta.config("myssid", "")
-- Connect to access point, User decides when to connect/disconnect to/from AP due to `auto=0`
wifi.sta.config("myssid", "mypassword", 0)
wifi.sta.connect()
-- ... do some WiFi stuff
wifi.sta.disconnect()
-- Connect to specific access point automatically when in range, `auto` defaults to 1
wifi.sta.config("myssid", "mypassword", "12:34:56:78:90:12")
-- Connect to specific access point, User decides when to connect/disconnect to/from AP due to `auto=0`
wifi.sta.config("myssid", "mypassword", 0, "12:34:56:78:90:12")
wifi.sta.connect()
-- ... do some WiFi stuff
wifi.sta.disconnect()
```
#### See also
- [`wifi.sta.connect()`](#wifistaconnect)
- [`wifi.sta.disconnect()`](#wifistadisconnect)
## wifi.sta.connect()
Connects to the configured AP in station mode. You only ever need to call this if auto-connect was disabled in [`wifi.sta.config()`](#wifistaconfig).
#### Syntax
`wifi.sta.connect()`
#### Parameters
none
#### Returns
`nil`
#### See also
- [`wifi.sta.disconnect()`](#wifistadisconnect)
- [`wifi.sta.config()`](#wifistaconfig)
## wifi.sta.disconnect()
Disconnects from AP in station mode.
#### Syntax
`wifi.sta.disconnect()`
#### Parameters
none
#### Returns
`nil`
#### See also
- [`wifi.sta.config()`](#wifistaconfig)
- [`wifi.sta.connect()`](#wifistaconnect)
## wifi.sta.eventMonReg()
Registers callbacks for WiFi station status events.
#### Syntax
- `wifi.sta.eventMonReg(wifi_status[, function([previous_state])])`
#### Parameters
- `wifi_status` WiFi status you would like to set a callback for:
- `wifi.STA_IDLE`
- `wifi.STA_CONNECTING`
- `wifi.STA_WRONGPWD`
- `wifi.STA_APNOTFOUND`
- `wifi.STA_FAIL`
- `wifi.STA_GOTIP`
- `function` callback function to perform when event occurs
- Note: leaving field blank unregisters callback.
- `previous_state` previous wifi_state(0 - 5)
#### Returns
`nil`
#### Example
```lua
--register callback
wifi.sta.eventMonReg(wifi.STA_IDLE, function() print("STATION_IDLE") end)
wifi.sta.eventMonReg(wifi.STA_CONNECTING, function() print("STATION_CONNECTING") end)
wifi.sta.eventMonReg(wifi.STA_WRONGPWD, function() print("STATION_WRONG_PASSWORD") end)
wifi.sta.eventMonReg(wifi.STA_APNOTFOUND, function() print("STATION_NO_AP_FOUND") end)
wifi.sta.eventMonReg(wifi.STA_FAIL, function() print("STATION_CONNECT_FAIL") end)
wifi.sta.eventMonReg(wifi.STA_GOTIP, function() print("STATION_GOT_IP") end)
--register callback: use previous state
wifi.sta.eventMonReg(wifi.STA_CONNECTING, function(previous_State)
if(previous_State==wifi.STA_GOTIP) then
print("Station lost connection with access point\n\tAttempting to reconnect...")
else
print("STATION_CONNECTING")
end
end)
--unregister callback
wifi.sta.eventMonReg(wifi.STA_IDLE)
```
#### See also
- [`wifi.sta.eventMonStart()`](#wifistaeventmonstart)
- [`wifi.sta.eventMonStop()`](#wifistaeventmonstop)
- [`wifi.eventmon.register()`](#wifieventmonregister)
- [`wifi.eventmon.unregister()`](#wifieventmonunregister)
## wifi.sta.eventMonStart()
Starts WiFi station event monitor.
#### Syntax
`wifi.sta.eventMonStart([ms])`
### Parameters
- `ms` interval between checks in milliseconds, defaults to 150ms if not provided.
#### Returns
`nil`
#### Example
```lua
--start WiFi event monitor with default interval
wifi.sta.eventMonStart()
--start WiFi event monitor with 100ms interval
wifi.sta.eventMonStart(100)
```
#### See also
- [`wifi.sta.eventMonReg()`](#wifistaeventmonreg)
- [`wifi.sta.eventMonStop()`](#wifistaeventmonstop)
- [`wifi.eventmon.register()`](#wifieventmonregister)
- [`wifi.eventmon.unregister()`](#wifieventmonunregister)
## wifi.sta.eventMonStop()
Stops WiFi station event monitor.
#### Syntax
`wifi.sta.eventMonStop([unregister_all])`
#### Parameters
- `unregister_all` enter 1 to unregister all previously registered functions.
- Note: leave blank to leave callbacks registered
#### Returns
`nil`
#### Example
```lua
--stop WiFi event monitor
wifi.sta.eventMonStop()
--stop WiFi event monitor and unregister all callbacks
wifi.sta.eventMonStop(1)
```
#### See also
- [`wifi.sta.eventMonReg()`](#wifistaeventmonreg)
- [`wifi.sta.eventMonStart()`](#wifistaeventmonstart)
- [`wifi.eventmon.register()`](#wifieventmonregister)
- [`wifi.eventmon.unregister()`](#wifieventmonunregister)
## wifi.sta.getap()
Scans AP list as a Lua table into callback function.
#### Syntax
`wifi.sta.getap([[cfg], format,] callback(table))`
#### Parameters
- `cfg` table that contains scan configuration
- `ssid` SSID == nil, don't filter SSID
- `bssid` BSSID == nil, don't filter BSSID
- `channel` channel == 0, scan all channels, otherwise scan set channel (default is 0)
- `show_hidden` show_hidden == 1, get info for router with hidden SSID (default is 0)
- `format` select output table format, defaults to 0
- 0: old format (SSID : Authmode, RSSI, BSSID, Channel), any duplicate SSIDs will be discarded
- 1: new format (BSSID : SSID, RSSI, auth mode, Channel)
- `callback(table)` a callback function to receive the AP table when the scan is done. This function receives a table, the key is the BSSID, the value is other info in format: SSID, RSSID, auth mode, channel.
#### Returns
`nil`
#### Example
```lua
-- print AP list in old format (format not defined)
function listap(t)
for k,v in pairs(t) do
print(k.." : "..v)
end
end
wifi.sta.getap(listap)
-- Print AP list that is easier to read
function listap(t) -- (SSID : Authmode, RSSI, BSSID, Channel)
print("\n"..string.format("%32s","SSID").."\tBSSID\t\t\t\t RSSI\t\tAUTHMODE\tCHANNEL")
for ssid,v in pairs(t) do
local authmode, rssi, bssid, channel = string.match(v, "([^,]+),([^,]+),([^,]+),([^,]+)")
print(string.format("%32s",ssid).."\t"..bssid.."\t "..rssi.."\t\t"..authmode.."\t\t\t"..channel)
end
end
wifi.sta.getap(listap)
-- print AP list in new format
function listap(t)
for k,v in pairs(t) do
print(k.." : "..v)
end
end
wifi.sta.getap(1, listap)
-- Print AP list that is easier to read
function listap(t) -- (SSID : Authmode, RSSI, BSSID, Channel)
print("\n\t\t\tSSID\t\t\t\t\tBSSID\t\t\t RSSI\t\tAUTHMODE\t\tCHANNEL")
for bssid,v in pairs(t) do
local ssid, rssi, authmode, channel = string.match(v, "([^,]+),([^,]+),([^,]+),([^,]*)")
print(string.format("%32s",ssid).."\t"..bssid.."\t "..rssi.."\t\t"..authmode.."\t\t\t"..channel)
end
end
wifi.sta.getap(1, listap)
--check for specific AP
function listap(t)
print("\n\t\t\tSSID\t\t\t\t\tBSSID\t\t\t RSSI\t\tAUTHMODE\t\tCHANNEL")
for bssid,v in pairs(t) do
local ssid, rssi, authmode, channel = string.match(v, "([^,]+),([^,]+),([^,]+),([^,]*)")
print(string.format("%32s",ssid).."\t"..bssid.."\t "..rssi.."\t\t"..authmode.."\t\t\t"..channel)
end
end
scan_cfg = {}
scan_cfg.ssid = "myssid"
scan_cfg.bssid = "AA:AA:AA:AA:AA:AA"
scan_cfg.channel = 0
scan_cfg.show_hidden = 1
wifi.sta.getap(scan_cfg, 1, listap)
--get RSSI for currently configured AP
function listap(t)
for bssid,v in pairs(t) do
local ssid, rssi, authmode, channel = string.match(v, "([^,]+),([^,]+),([^,]+),([^,]*)")
print("CURRENT RSSI IS: "..rssi)
end
end
ssid, tmp, bssid_set, bssid=wifi.sta.getconfig()
scan_cfg = {}
scan_cfg.ssid = ssid
if bssid_set == 1 then scan_cfg.bssid = bssid else scan_cfg.bssid = nil end
scan_cfg.channel = wifi.getchannel()
scan_cfg.show_hidden = 0
ssid, tmp, bssid_set, bssid=nil, nil, nil, nil
wifi.sta.getap(scan_cfg, 1, listap)
```
#### See also
[`wifi.sta.getip()`](#wifistagetip)
## wifi.sta.getbroadcast()
Gets the broadcast address in station mode.
#### Syntax
`wifi.sta.getbroadcast()`
#### Parameters
`nil`
#### Returns
broadcast address as string, for example "192.168.0.255",
returns `nil` if IP address = "0.0.0.0".
#### See also
[`wifi.sta.getip()`](#wifistagetip)
## wifi.sta.getconfig()
Gets the WiFi station configuration.
#### Syntax
`wifi.sta.getconfig()`
#### Parameters
none
#### Returns
ssid, password, bssid_set, bssid
Note: If bssid_set is equal to 0 then bssid is irrelevant
#### Example
```lua
--Get current Station configuration
ssid, password, bssid_set, bssid=wifi.sta.getconfig()
print("\nCurrent Station configuration:\nSSID : "..ssid
.."\nPassword : "..password
.."\nBSSID_set : "..bssid_set
.."\nBSSID: "..bssid.."\n")
ssid, password, bssid_set, bssid=nil, nil, nil, nil
```
#### See also
- [`wifi.sta.connect()`](#wifistaconnect)
- [`wifi.sta.disconnect()`](#wifistadisconnect)
## wifi.sta.gethostname()
Gets current station hostname.
#### Syntax
`wifi.sta.gethostname()`
#### Parameters
none
#### Returns
currently configured hostname
#### Example
```lua
print("Current hostname is: \""..wifi.sta.gethostname().."\"")
```
## wifi.sta.getip()
Gets IP address, netmask, and gateway address in station mode.
#### Syntax
`wifi.sta.getip()`
#### Parameters
none
#### Returns
IP address, netmask, gateway address as string, for example "192.168.0.111". Returns `nil` if IP = "0.0.0.0".
#### Example
```lua
-- print current IP address, netmask, gateway
print(wifi.sta.getip())
-- 192.168.0.111 255.255.255.0 192.168.0.1
ip = wifi.sta.getip()
print(ip)
-- 192.168.0.111
ip, nm = wifi.sta.getip()
print(nm)
-- 255.255.255.0
```
#### See also
[`wifi.sta.getmac()`](#wifistagetmac)
## wifi.sta.getmac()
Gets MAC address in station mode.
#### Syntax
`wifi.sta.getmac()`
#### Parameters
none
#### Returns
MAC address as string e.g. "18-33-44-FE-55-BB"
#### See also
[`wifi.sta.getip()`](#wifistagetip)
## wifi.sta.getrssi()
Get RSSI(Received Signal Strength Indicator) of the Access Point which ESP8266 station connected to.
#### Syntax
`wifi.sta.getrssi()`
#### Parameters
none
#### Returns
- If station is connected to an access point, `rssi` is returned.
- If station is not connected to an access point, `nil` is returned.
#### Example
```lua
RSSI=wifi.sta.getrssi()
print("RSSI is", RSSI)
```
## wifi.sta.sethostname()
Sets station hostname.
#### Syntax
`wifi.sta.sethostname(hostname)`
#### Parameters
`hostname` must only contain letters, numbers and hyphens('-') and be 32 characters or less with first and last character being alphanumeric
#### Returns
`nil`
#### Example
```lua
if (wifi.sta.sethostname("NodeMCU") == true) then
print("hostname was successfully changed")
else
print("hostname was not changed")
end
```
## wifi.sta.setip()
Sets IP address, netmask, gateway address in station mode.
#### Syntax
`wifi.sta.setip(cfg)`
#### Parameters
`cfg` table contain IP address, netmask, and gateway
```lua
{
ip = "192.168.0.111",
netmask = "255.255.255.0",
gateway = "192.168.0.1"
}
```
#### Returns
true if success, false otherwise
#### See also
[`wifi.sta.setmac()`](#wifistasetmac)
## wifi.sta.setmac()
Sets MAC address in station mode.
#### Syntax
`wifi.sta.setmac(mac)`
#### Parameters
MAC address in string e.g. "DE:AD:BE:EF:7A:C0"
#### Returns
true if success, false otherwise
#### Example
```lua
print(wifi.sta.setmac("DE:AD:BE:EF:7A:C0"))
```
#### See also
[`wifi.sta.setip()`](#wifistasetip)
## wifi.sta.status()
Gets the current status in station mode.
#### Syntax
`wifi.sta.status()`
#### Parameters
`nil`
#### Returns
number: 0~5
- 0: STA_IDLE,
- 1: STA_CONNECTING,
- 2: STA_WRONGPWD,
- 3: STA_APNOTFOUND,
- 4: STA_FAIL,
- 5: 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.
NOTE: SoftAP Configuration will be retained until changed even if device is turned off.
#### Syntax
`wifi.ap.config(cfg)`
#### Parameters
- `ssid` SSID chars 1-32
- `pwd` password chars 8-64
- `auth` authentication one of AUTH\_OPEN, AUTH\_WPA\_PSK, AUTH\_WPA2\_PSK, AUTH\_WPA\_WPA2\_PSK, default = AUTH\_OPEN
- `channel` channel number 1-14 default = 6
- `hidden` 0 = not hidden, 1 = hidden, default 0
- `max` maximal number of connections 1-4 default=4
- `beacon` beacon interval time in range 100-60000, default = 100
#### Returns
`nil`
#### Example:
```lua
cfg={}
cfg.ssid="myssid"
cfg.pwd="mypassword"
wifi.ap.config(cfg)
```
## wifi.ap.deauth()
Deauths (forcibly removes) a client from the ESP access point by sending a corresponding IEEE802.11 management packet (first) and removing the client from it's data structures (afterwards).
The IEEE802.11 reason code used is 2 for "Previous authentication no longer valid"(AUTH_EXPIRE).
#### Syntax
`wifi.ap.deauth([MAC])`
#### Parameters
- `MAC` address of station to be deauthed.
- Note: if this field is left blank, all currently connected stations will get deauthed.
#### Returns
Returns true unless called while the ESP is in the STATION opmode
#### Example
```lua
allowed_mac_list={"18:fe:34:00:00:00", "18:fe:34:00:00:01"}
wifi.eventmon.register(wifi.eventmon.AP_STACONNECTED, function(T)
print("\n\tAP - STATION CONNECTED".."\n\tMAC: "..T.MAC.."\n\tAID: "..T.AID)
if(allowed_mac_list~=nil) then
for _, v in pairs(allowed_mac_list) do
if(v == T.MAC) then return end
end
end
wifi.ap.deauth(T.MAC)
print("\tStation DeAuthed!")
end)
```
#### See also
[`wifi.eventmon.register()`](#wifieventmonregister)
[`wifi.eventmon.reason()`](#wifieventmonreason)
## wifi.ap.getbroadcast()
Gets broadcast address in AP mode.
#### Syntax
`wifi.ap.getbroadcast()`
#### Parameters
none
#### Returns
broadcast address in string, for example "192.168.0.255",
returns `nil` if IP address = "0.0.0.0".
#### Example
```lua
bc = wifi.ap.getbroadcast()
print(bc)
-- 192.168.0.255
```
#### See also
[`wifi.ap.getip()`](#wifiapgetip)
## wifi.ap.getclient()
Gets table of clients connected to device in AP mode.
#### Syntax
`wifi.ap.getclient()`
#### Parameters
none
#### Returns
table of connected clients
#### Example
```lua
table={}
table=wifi.ap.getclient()
for mac,ip in pairs(table) do
print(mac,ip)
end
-- or shorter
for mac,ip in pairs(wifi.ap.getclient()) do
print(mac,ip)
end
```
## wifi.ap.getip()
Gets IP address, netmask and gateway in AP mode.
#### Syntax
`wifi.ap.getip()`
#### Parameters
none
#### Returns
IP address, netmask, gateway address as string, for example "192.168.0.111", returns `nil` if IP address = "0.0.0.0".
#### Example
```lua
-- print current ip, netmask, gateway
print(wifi.ap.getip())
-- 192.168.4.1 255.255.255.0 192.168.4.1
ip = wifi.ap.getip()
print(ip)
-- 192.168.4.1
ip, nm = wifi.ap.getip()
print(nm)
-- 255.255.255.0
ip, nm, gw = wifi.ap.getip()
print(gw)
-- 192.168.4.1
```
#### See also
- [`wifi.ap.getmac()`](#wifiapgetmac)
## wifi.ap.getmac()
Gets MAC address in AP mode.
#### Syntax
`wifi.ap.getmac()`
#### Parameters
none
#### Returns
MAC address as string, for example "1A-33-44-FE-55-BB"
#### See also
[`wifi.ap.getip()`](#wifiapgetip)
## wifi.ap.setip()
Sets IP address, netmask and gateway address in AP mode.
#### Syntax
`wifi.ap.setip(cfg)`
#### Parameters
`cfg` table contain IP address, netmask, and gateway
#### Returns
true if successful, false otherwise
#### Example
```lua
cfg =
{
ip="192.168.1.1",
netmask="255.255.255.0",
gateway="192.168.1.1"
}
wifi.ap.setip(cfg)
```
#### See also
[`wifi.ap.setmac()`](#wifiapsetmac)
## wifi.ap.setmac()
Sets MAC address in AP mode.
#### Syntax
`wifi.ap.setmac(mac)`
#### Parameters
MAC address in byte string, for example "AC-1D-1C-B1-0B-22"
#### Returns
true if success, false otherwise
#### Example
```lua
print(wifi.ap.setmac("AC-1D-1C-B1-0B-22"))
```
#### See also
[`wifi.ap.setip()`](#wifiapsetip)
# wifi.ap.dhcp Module
## wifi.ap.dhcp.config()
Configure the dhcp service. Currently only supports setting the start address of the dhcp address pool.
#### Syntax
`wifi.ap.dhcp.config(dhcp_config)`
#### Parameters
`dhcp_config` table containing the start-IP of the DHCP address pool, eg. "192.168.1.100"
#### Returns
`pool_startip`, `pool_endip`
#### Example
```lua
dhcp_config ={}
dhcp_config.start = "192.168.1.100"
wifi.ap.dhcp.config(dhcp_config)
```
## wifi.ap.dhcp.start()
Starts the DHCP service.
#### Syntax
`wifi.ap.dhcp.start()`
#### Parameters
none
#### Returns
boolean indicating success
## wifi.ap.dhcp.stop()
Stops the DHCP service.
#### Syntax
`wifi.ap.dhcp.stop()`
#### Parameters
none
#### Returns
boolean indicating success
# wifi.eventmon Module
Note: The functions `wifi.sta.eventMon___()` and `wifi.eventmon.___()` are completely seperate and can be used independently of one another.
## wifi.eventmon.register()
Register/unregister callbacks for WiFi event monitor.
#### Syntax
wifi.eventmon.register(Event[, function(T)])
#### Parameters
Event: WiFi event you would like to set a callback for.
- Valid WiFi events:
- wifi.eventmon.STA_CONNECTED
- wifi.eventmon.STA_DISCONNECTED
- wifi.eventmon.STA_AUTHMODE_CHANGE
- wifi.eventmon.STA_GOT_IP
- wifi.eventmon.STA_DHCP_TIMEOUT
- wifi.eventmon.AP_STACONNECTED
- wifi.eventmon.AP_STADISCONNECTED
- wifi.eventmon.AP_PROBEREQRECVED
#### Returns
Function:
`nil`
Callback:
T: Table returned by event.
- `wifi.eventmon.STA_CONNECTED` Station is connected to access point.
- `SSID`: SSID of access point.
- `BSSID`: BSSID of access point.
- `channel`: The channel the access point is on.
- `wifi.eventmon.STA_DISCONNECT`: Station was disconnected from access point.
- `SSID`: SSID of access point.
- `BSSID`: BSSID of access point.
- `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.
- `wifi.eventmon.STA_GOT_IP`: Station got an IP address.
- `IP`: The IP address assigned to the station.
- `netmask`: Subnet mask.
- `gateway`: The IP address of the access point the station is connected to.
- `wifi.eventmon.STA_DHCP_TIMEOUT`: Station DHCP request has timed out.
- Blank table is returned.
- `wifi.eventmon.AP_STACONNECTED`: A new client has connected to the access point.
- `MAC`: MAC address of client that has connected.
- `AID`: SDK provides no details concerning this return value.
- `wifi.eventmon.AP_STADISCONNECTED`: A client has disconnected from the access point.
- `MAC`: MAC address of client that has disconnected.
- `AID`: SDK provides no details concerning this return value.
- `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.
#### Example
```lua
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_DISCONNECTED, function(T)
print("\n\tSTA - DISCONNECTED".."\n\tSSID: "..T.SSID.."\n\tBSSID: "..
T.BSSID.."\n\treason: "..T.reason)
end)
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)
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.eventmon.register(wifi.eventmon.STA_DHCP_TIMEOUT, function()
print("\n\tSTA - DHCP TIMEOUT")
end)
wifi.eventmon.register(wifi.eventmon.AP_STACONNECTED, function(T)
print("\n\tAP - STATION CONNECTED".."\n\tMAC: "..T.MAC.."\n\tAID: "..T.AID)
end)
wifi.eventmon.register(wifi.eventmon.AP_STADISCONNECTED, function(T)
print("\n\tAP - STATION DISCONNECTED".."\n\tMAC: "..T.MAC.."\n\tAID: "..T.AID)
end)
wifi.eventmon.register(wifi.eventmon.AP_PROBEREQRECVED, function(T)
print("\n\tAP - STATION DISCONNECTED".."\n\tMAC: ".. T.MAC.."\n\tRSSI: "..T.RSSI)
end)
```
#### See also
- [`wifi.eventmon.unregister()`](#wifieventmonunregister)
- [`wifi.sta.eventMonStart()`](#wifistaeventmonstart)
- [`wifi.sta.eventMonStop()`](#wifistaeventmonstop)
- [`wifi.sta.eventMonReg()`](#wifistaeventmonreg)
## wifi.eventmon.unregister()
Unregister callbacks for WiFi event monitor.
#### Syntax
wifi.eventmon.unregister(Event)
#### Parameters
Event: WiFi event you would like to set a callback for.
- Valid WiFi events:
- wifi.eventmon.STA_CONNECTED
- wifi.eventmon.STA_DISCONNECTED
- wifi.eventmon.STA_AUTHMODE_CHANGE
- wifi.eventmon.STA_GOT_IP
- wifi.eventmon.STA_DHCP_TIMEOUT
- wifi.eventmon.AP_STACONNECTED
- wifi.eventmon.AP_STADISCONNECTED
- wifi.eventmon.AP_PROBEREQRECVED
#### Returns
`nil`
#### Example
```lua
wifi.eventmon.unregister(wifi.eventmon.STA_CONNECTED)
```
#### See also
- [`wifi.eventmon.register()`](#wifieventmonregister)
- [`wifi.sta.eventMonStart()`](#wifistaeventmonstart)
- [`wifi.sta.eventMonStop()`](#wifistaeventmonstop)
## wifi.eventmon.reason
Table containing disconnect reasons.
| Disconnect reason | value |
|:--------------------|:-------:|
|wifi.eventmon.reason.UNSPECIFIED | 1 |
|wifi.eventmon.reason.AUTH_EXPIRE | 2 |
|wifi.eventmon.reason.AUTH_LEAVE | 3 |
|wifi.eventmon.reason.ASSOC_EXPIRE | 4 |
|wifi.eventmon.reason.ASSOC_TOOMANY | 5 |
|wifi.eventmon.reason.NOT_AUTHED | 6 |
|wifi.eventmon.reason.NOT_ASSOCED | 7 |
|wifi.eventmon.reason.ASSOC_LEAVE | 8 |
|wifi.eventmon.reason.ASSOC_NOT_AUTHED | 9 |
|wifi.eventmon.reason.DISASSOC_PWRCAP_BAD | 10 |
|wifi.eventmon.reason.DISASSOC_SUPCHAN_BAD | 11 |
|wifi.eventmon.reason.IE_INVALID | 13 |
|wifi.eventmon.reason.MIC_FAILURE | 14 |
|wifi.eventmon.reason.4WAY_HANDSHAKE_TIMEOUT | 15 |
|wifi.eventmon.reason.GROUP_KEY_UPDATE_TIMEOUT | 16 |
|wifi.eventmon.reason.IE_IN_4WAY_DIFFERS | 17 |
|wifi.eventmon.reason.GROUP_CIPHER_INVALID | 18 |
|wifi.eventmon.reason.PAIRWISE_CIPHER_INVALID | 19 |
|wifi.eventmon.reason.AKMP_INVALID | 20 |
|wifi.eventmon.reason.UNSUPP_RSN_IE_VERSION | 21 |
|wifi.eventmon.reason.INVALID_RSN_IE_CAP | 22 |
|wifi.eventmon.reason.802_1X_AUTH_FAILED | 23 |
|wifi.eventmon.reason.CIPHER_SUITE_REJECTED | 24 |
|wifi.eventmon.reason.BEACON_TIMEOUT | 200 |
|wifi.eventmon.reason.NO_AP_FOUND | 201 |
|wifi.eventmon.reason.AUTH_FAIL | 202 |
|wifi.eventmon.reason.ASSOC_FAIL | 203 |
|wifi.eventmon.reason.HANDSHAKE_TIMEOUT | 204 |
# WS2801 Module
| Since | Origin / Contributor | Maintainer | Source |
| :----- | :-------------------- | :---------- | :------ |
| 2015-07-12 | [Espressif example](https://github.com/CHERTS/esp8266-devkit/blob/master/Espressif/examples/EspLightNode/user/ws2801.c), [Konrad Beckmann](https://github.com/kbeckmann) | [Konrad Beckmann](https://github.com/kbeckmann) | [ws2801.c](../../../app/modules/ws2801.c)|
## ws2801.init()
Initializes the module and sets the pin configuration.
#### Syntax
`ws2801.init(pin_clk, pin_data)`
#### Parameters
- `pin_clk` pin for the clock. Supported are GPIO 0, 2, 4, 5.
- `pin_data` pin for the data. Supported are GPIO 0, 2, 4, 5.
#### Returns
`nil`
## ws2801.write()
Sends a string of RGB Data in 24 bits to WS2801. Don't forget to call `ws2801.init()` before.
#### Syntax
`ws2801.write(string)`
####Parameters
- `string` payload to be sent to one or more WS2801.
It should be composed from an RGB triplet per element.
- `R1` the first pixel's red channel value (0-255)
- `G1` the first pixel's green channel value (0-255)
- `B1` the first pixel's blue channel value (0-255)<br />
... You can connect a lot of WS2801...
- `R2`, `G2`, `B2` are the next WS2801's Red, Green, and Blue channel values
#### Returns
`nil`
#### Example
```lua
ws2801.write(string.char(255,0,0, 0,255,0, 0,0,255))
```
# WS2812 Module
| Since | Origin / Contributor | Maintainer | Source |
| :----- | :-------------------- | :---------- | :------ |
| 2015-02-05 | [Till Klocke](https://github.com/dereulenspiegel), [Thomas Soëte](https://github.com/Alkorin) | [Till Klocke](https://github.com/dereulenspiegel) | [ws2812.c](../../../app/modules/ws2812.c)|
ws2812 is a library to handle ws2812-like led strips.
It works at least on WS2812, WS2812b, APA104, SK6812 (RGB or RGBW).
The library uses UART1 routed on GPIO2 (Pin D4 on NodeMCU DEVKIT) to
generate the bitstream.
## ws2812.init()
Initialize UART1 and GPIO2, should be called once and before write()
#### Parameters
none
#### Returns
`nil`
## ws2812.write()
Send data to a led strip using its native format which is generally Green,Red,Blue for RGB strips
and Green,Red,Blue,White for RGBW strips.
#### Syntax
`ws2812.write(string)`
#### Parameters
- `string` payload to be sent to one or more WS2812 like leds.
#### Returns
`nil`
#### Example
```lua
ws2812.init()
ws2812.write(string.char(255,0,0,255,0,0) -- turn the two first RGB leds to green
```
```lua
ws2812.init()
ws2812.write(string.char(0,0,0,255,0,0,0,255) -- turn the two first RGBW leds to white
```
# Buffer module
For more advanced animations, it is useful to keep a "framebuffer" of the strip,
interact with it and flush it to the strip.
For this purpose, the ws2812 library offers a read/write buffer.
#### Example
Led chaser with a RGBW strip
```lua
local i, b = 0, ws2812.newBuffer(300, 4); b:fill(0,0,0,0); tmr.alarm(0, 50, 1, function()
i=i+1
b:fade(2)
b:set(i%b:size()+1, 0, 0, 0, 255)
b:write()
end)
```
## ws2812.newBuffer()
Allocate a new memory buffer to store led values.
#### Syntax
`ws2812.newBuffer(numberOfLeds, bytesPerLed)`
#### Parameters
- `numberOfLeds` length of the led strip
- `bytesPerLed` 3 for RGB strips and 4 for RGBW strips
#### Returns
`ws2812.buffer`
## ws2812.buffer:get()
Return the value at the given position
#### Syntax
`buffer:get(index)`
#### Parameters
- `index` position in the buffer (1 for first led)
#### Returns
`(color)`
#### Example
```lua
buffer:get(2) -- return the color of the second led
```
## ws2812.buffer:set()
Set the value at the given position
#### Syntax
`buffer:set(index, color)`
#### Parameters
- `index` position in the buffer (1 for the first led)
- `color` bytes of the color
#### Returns
`nil`
#### Example
```lua
buffer:set(1, 255, 0, 0) -- set the first led green for a RGB strip
```
## ws2812.buffer:size()
Return the size of the buffer in number of leds
#### Syntax
`buffer:size()`
#### Parameters
none
#### Returns
`int`
## ws2812.buffer:fill()
Fill the buffer with the given color.
The number of given bytes must match the number of bytesPerLed of the buffer
#### Syntax
`buffer:fill(color)`
#### Parameters
- `color` bytes of the color
#### Returns
`nil`
#### Example
```lua
buffer:fill(0, 0, 0) -- fill the buffer with black for a RGB strip
```
## ws2812.buffer:fade()
Divide each byte of each led by the given value. Useful for a fading effect
#### Syntax
`buffer:fade(value)`
#### Parameters
- `value` value by which divide each byte
#### Returns
`nil`
#### Example
```lua
buffer:fade(2)
```
## ws2812.buffer:write()
Output the buffer to the led strip
#### Syntax
`buffer:write()`
#### Parameters
none
#### Returns
`nil`
# Getting started
## Obtain the firmware
[Build the firmware](build.html) or download it from ?
## Flash the firmware
There are a number of tools for flashing the firmware.
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