All access is based on the I/O index number on the NodeMCU dev kits, not the internal GPIO pin. For example, the D0 pin on the dev kit is mapped to the internal GPIO pin 16.
Serialize output based on a sequence of delay-times in µs. After each delay, the pin is toggled. After the last cycle and last delay the pin is not toggled.
Whether the asynchronous mode is chosen is defined by presence of the `callback` parameter. If present and is of function type the function goes asynchronous and the callback function is invoked when sequence finishes. If the parameter is numeric the function still goes asynchronous but no callback is invoked when done.
For the asynchronous version, the minimum delay time should not be shorter than 50 μs and maximum delay time is 0x7fffff μs (~8.3 seconds).
In this mode the function does not block the stack and returns immediately before the output sequence is finalized. HW timer `FRC1_SOURCE` mode is used to change the states. As there is only a single hardware timer, there
are restrictions on which modules can be used at the same time. An error will be raised if the timer is already in use.
Note that the synchronous variant (no or nil `callback` parameter) function blocks the stack and as such any use of it must adhere to the SDK guidelines (also explained [here](../extn-developer-faq/#extension-developer-faq)). Failure to do so may lead to WiFi issues or outright to crashes/reboots. In short it means that the sum of all delay times multiplied by the number of cycles should not exceed 15 ms.
gpio.serout(1,gpio.HIGH,{30,30,60,60,30,30}) -- serial one byte, b10110010
gpio.serout(1,gpio.HIGH,{30,70},8) -- serial 30% pwm 10k, lasts 8 cycles
gpio.serout(1,gpio.HIGH,{3,7},8) -- serial 30% pwm 100k, lasts 8 cycles
gpio.serout(1,gpio.HIGH,{0,0},8) -- serial 50% pwm as fast as possible, lasts 8 cycles
gpio.serout(1,gpio.LOW,{20,10,10,20,10,10,10,100}) -- sim uart one byte 0x5A at about 100kbps
gpio.serout(1,gpio.HIGH,{8,18},8) -- serial 30% pwm 38k, lasts 8 cycles
gpio.serout(1,gpio.HIGH,{5000,995000},100, function() print("done") end) -- asynchronous 100 flashes 5 ms long every second with a callback function when done
gpio.serout(1,gpio.HIGH,{5000,995000},100, 1) -- asynchronous 100 flashes 5 ms long, no callback
This covers a set of APIs that allow generation of pulse trains with accurate timing on
multiple pins. It is similar to the `serout` API, but can handle multiple pins and has better
timing control.
The basic idea is to build a `gpio.pulse` object and then control it with methods on that object. Only one `gpio.pulse`
object can be active at a time. The object is built from an array of tables where each inner table represents
an action to take and the time to delay before moving to the next action.
One of the uses for this is to generate bipolar impulse for driving clock movements where you want (say) a pulse on Pin 1 on the even
second, and a pulse on Pin 2 on the odd second. `:getstate` and `:adjust` can be used to keep the pulse synchronized to the
RTC clock (that is itself synchronized with NTP).
!!! Configuration
This feature is only available if `LUA_USE_MODULES_GPIO_PULSE` is defined at build time.
## gpio.pulse.build
This builds the `gpio.pulse` object from the supplied argument -- which is a table as described below.
#### Syntax
`gpio.pulse.build(table)`
#### Parameter
`table` this is view as an array of instructions. Each instruction is represented by a table as follows:
- All numeric keys are considered to be pin numbers. The values of each are the value to be set onto the respective GPIO line. For example `{ [1] = gpio.HIGH }` would set pin 1 to be high. Note this that is the pin number and *not* the GPIO number. Multiple pins can be
set at the same time.
-`delay` specifies the number of microseconds after setting the pin values to wait until moving to the next state. The actual delay may be longer than this value depending on whether interrupts are enabled at the end time.
-`min` and `max` can be used to specify (along with `delay`) that this time can be varied. If one time interval overruns, then the extra time will be deducted from a time period which has a `min` or `max` specified. The actual time can also be adjusted with the `:adjust` API below.
-`count` and `loop` allow simple looping. When a state with `count` and `loop` is completed, the next state is at `loop` (provided that `count` has not decremented to zero). The first state is state 1.