Update for consistency with the other docs

This commit is contained in:
Marcel Stör 2016-01-10 21:39:02 +01:00
parent 7eba3cbcf3
commit 7d1d10dc46
4 changed files with 220 additions and 222 deletions

View File

@ -1,34 +1,103 @@
# rtcfifo Module
The rtcfifo module implements a first-in,first-out storage intended for sensor readings. As the name suggests, it is backed by the RTC 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.
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:
!!! 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()` is called.
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
- rtcmem module
- rtctime module
[`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()` unconditionally re-initializes the storage - any samples stored are discarded.
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()` function, this field sets the sample interval (in microseconds) to use. It is effectively the first argument of `rtctime.dsleep_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.
- `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
@ -36,37 +105,20 @@ This function takes an optional configuration table as an argument. The followin
####Example
```lua
rtcfifo.prepare() -- Initialize with default values
-- Initialize with default values
rtcfifo.prepare()
```
```lua
rtcfifo.prepare({storage_begin=21, storage_end=128}) -- Use RTC slots 19 and up for variable storage
-- Use RTC slots 19 and up for variable storage
rtcfifo.prepare({storage_begin=21, storage_end=128})
```
####See also
- `rtcfifo.ready()`
[`rtcfifo.ready()`](#rtcfifoready)
___
## rtcfifo.ready()
Returns non-zero if the rtcfifo has been prepared and is ready for use, zero if not.
####Syntax:
`rtcfifo.ready()`
####Parameters
`nil`
####Returns
Non-zero if the rtcfifo has been prepared and is ready for use, zero if not.
####Example
if not rtcfifo.ready() then -- Prepare the rtcfifo if not already done
rtcfifo.prepare()
end
```
####See also
- `rtcfifo.prepare()`
[`rtcfifo.prepare()`](#rtcfifoprepare)
___
## rtcfifo.put()
Puts a sample into the rtcfifo.
@ -77,86 +129,41 @@ If the rtcfifo has not been prepared, this function does nothing.
`rtcfifo.put(timestamp, value, neg_e, name)`
####Parameters
- `timestamp`: Timestamp in seconds. The timestamp would typically come from `rtctime.get()`.
- `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.
- `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()`) names in use, the rtcfifo evicts all earlier samples.
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
local sample = ... -- Obtain a sample value from somewhere
rtcfifo.put(rtctime.get(), sample, 0, "foo") -- Store sample with no scaling, under the name "foo"
-- 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.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).
## rtcfifo.ready()
Returns non-zero if the rtcfifo has been prepared and is ready for use, zero if not.
####Syntax:
`rtcfifo.peek([offset])`
`rtcfifo.ready()`
####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.
none
####Returns
The values returned match the input arguments used to `rtcfifo.put()`.
- `timestamp`: Timestamp in seconds.
- `value`: The value.
- `neg_e`: Scaling factor.
- `name`: The sensor name.
If no sample is available (at the specified offset), nothing is returned.
Non-zero if the rtcfifo has been prepared and is ready for use, zero if not.
####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
`nil`
####Returns
The values returned match the input arguments used to `rtcfifo.put()`.
- `timestamp`: Timestamp in seconds.
- `value`: The value.
- `neg_e`: Scaling factor.
- `name`: The 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
-- Prepare the rtcfifo if not already done
if not rtcfifo.ready() then
rtcfifo.prepare()
end
```
___
## 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)` where `interval_us` is what was given to `rtcfifo.prepare()`.
####Syntax
`rtcfifo.dsleep_until_sample(minsleep_us)`
####Parameter
- minsleep_us: minimum sleep time, in microseconds.
####Example
```lua
rtcfifo.dsleep_until_sample(0) -- deep sleep until it's time to take the next sample
```
####See also
- `rtctime.dsleep_aligned()`
___

View File

@ -1,64 +1,59 @@
# rtcmem Module
The rtcmem module provides basic access to the RTC (Real Time Clock) memory.
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.
####See also
- rtctime module
- rtcfifo module
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
#### Syntax
`rtcmem.read32(idx [, num])`
####Parameters
- `idx`: The index to start reading from. Zero-based.
- `num`: Number of slots to read (default 1).
#### Parameters
- `idx` zero-based index to start reading from
- `num` number of slots to read (default 1)
####Returns
#### 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
#### 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()`
#### 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
#### Syntax
`rtcmem.write32(idx, val [, val2, ...])`
####Parameters
- `idx`: Index to start writing to. Auto-increments if multiple values are given. Zero-based.
- `val`: The (32bit) value to store.
- `val2...`: Additional values to store. Optional.
#### 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
#### Returns
`nil`
####Example
#### 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()`
___
#### See also
[`rtcmem.read32()`](#rtcmemread32)

View File

@ -1,114 +1,114 @@
# rtctime Module
The rtctime module provides advanced timekeeping support for NodeMCU, including keeping time across deep sleep cycles (provided rtctime.dsleep() is used instead of node.dsleep()). 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.
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 (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).
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, 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.
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()`). For best accuracy it is recommended to provide a reference time twice, with the second time being after a deep sleep.
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:
!!! note "Important:"
This module uses RTC memory slots 0-9, inclusive. As soon as `rtctime.set()` (or `sntp.sync()`) has been called these RTC memory slots will be used.
This module uses RTC memory slots 0-9, inclusive. As soon as [`rtctime.set()`](#rtctimeset) (or [`sntp.sync()`](sntp.md#sntpsync)) has been called these RTC memory slots will be used.
####See also
- rtcmem module
- sntp module
This is a companion module to the [rtcmem](rtcmem.md) and [SNTP](sntp.md) modules.
## 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()` *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, 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
rtctime.set(1436430589, 0) -- Set time to 2015 July 9, 18:29:49
```
####See also
- `sntp.sync()`
___
## rtctime.get()
Returns the current time. If current time is not available, zero is returned.
####Syntax
`rtctime.get()`
####Parameters
`nil`
####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()`
___
## rtctime.dsleep()
Puts the ESP8266 into deep sleep mode, like `node.dsleep()`. It differs from `node.dsleep()` in the following ways:
- Time is kept across the deep sleep. I.e. `rtctime.get()` 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()`.
- A sleep time of zero does not mean indefinite sleep, it is interpreted as a zero length sleep instead.
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
#### Syntax
`rtctime.dsleep(microseconds [, option])`
####Parameters
- `microseconds`: The number of microseconds to sleep for. Maxmium value is 4294967295us, or ~71 minutes.
- `option`: The sleep option. See `node.dsleep()` for specifics.
#### 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
#### Returns
This function does not return.
####Example
#### Example
```lua
rtctime.dsleep(60*1000000) -- sleep for a minute
-- sleep for a minute
rtctime.dsleep(60*1000000)
```
```lua
rtctime.dsleep(5000000, 4) -- sleep for 5 seconds, do not start RF on wakeup
-- 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
#### Syntax
`rtctime.dsleep(aligned_us, minsleep_us [, option])`
####Parameters
- `aligned_us`: specifies the 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.
#### 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
#### Example
```lua
rtctime.dsleep_aligned(5*1000000, 3*1000000) -- sleep at least 3 seconds, then wake up on the next 5-second boundary
-- 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)

View File

@ -1,28 +1,26 @@
# sntp Module
# SNTP Module
The SNTP module implements a Simple Network Time Procotol client. This includes support for the "anycast" NTP 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.
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 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.
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.
####See also
- rtctime module
## sntp.sync()
Attempts to obtain time synchronization.
####Syntax
#### Syntax
`sntp.sync([server_ip], [callback], [errcallback])`
####Parameters
- `server_ip`: If the `server_ip` argument is 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`: If the `callback` argument is provided it will be invoked on a successful synchronization, with three parameters: seconds, microseconds, and server. Note that when the rtctime module is available, there is no need to explicitly call `rtctime.set()` - this module takes care of doing so internally automatically, for best accuracy.
- `errcallback`: On failure, the `errcallback` will be invoked, if provided. The sntp module automatically performs a number of retries before giving up and reporting the error. This callback receives no parameters.
#### 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 no parameters. The module automatically performs a number of retries before giving up and reporting the error.
####Returns
#### Returns
`nil`
####Example
#### Example
```lua
-- Best effort, use the last known NTP server (or the NTP "anycast" address 224.0.1.1 initially)
sntp.sync()
@ -38,7 +36,5 @@ sntp.sync('192.168.0.1',
end
)
```
####See also
- `rtctime.set()`
___
#### See also
[`rtctime.set()`](rtctime.md#rtctimeset)