8.0 KiB
ESP-NOW Module
Since | Origin / Contributor | Maintainer | Source |
---|---|---|---|
2024-03-07 | DiUS Jade Mattsson | Jade Mattsson | espnow.c |
The espnow
module provides an interface to Espressif's ESP-NOW functionality. To quote their documentation directly:
"ESP-NOW is a kind of connectionless Wi-Fi communication protocol that is defined by Espressif. In ESP-NOW, application data is encapsulated in a vendor-specific action frame and then transmitted from one Wi-Fi device to another without connection."
Packets can be sent to either individual peers, the whole list of defined peers, or broadcast to everyone in range. For non-broadcast packets, ESP-NOW provides optional encryption support to prevent eavesdropping. To use encryption, a "Primary Master Key" (PMK) should first be set. When registering a peer, a peer-specific "Local Master Key" (LMK) is then given, which is further encrypted by the PMK. All packets sent to that peer will be encrypted with the resulting key.
To broadcast packets, a peer with address 'ff:ff:ff:ff:ff:ff' must first be registered. Broadcast packets do not support encryption, and attempting to enable encrypting when registering the broadcast peer will result in an error.
ESP-NOW uses a WiFi vendor-specific action frame to transmit data, and as such it requires the WiFi stack to have been started before ESP-NOW packets can be sent and received.
espnow.start
Starts the ESP-NOW stack. While this may be called prior to wifi.start()
, packet transmission and reception will not be possible until after the WiFi stack has been started.
Syntax
espnow.start()
Parameters
None.
Returns
nil
An error will be raised if the ESP-NOW stack cannot be started.
espnow.stop
Stops the ESP-NOW stack.
Syntax
espnow.stop()
Parameters
None.
Returns
nil
An error will be raised if the ESP-NOW stack cannot be stopped.
espnow.getversion
Returns the raw version number enum value. Currently, it is 1
. Might be useful for checking version compatibility in the future.
Syntax
ver = espnow.getversion()
Parameters
None.
Returns
An integer representing the ESP-NOW version.
espnow.setpmk
Sets the Primary Master Key (PMK). When using security, this should be done prior to adding any peers, as their LMKs will be encrypted by the current PMK.
Syntax
espnow.setpmk(pmk)
Parameters
pmk
The Primary Master Key, given as a hex-encoding of a 16-byte key (i.e. the pmk
should consist of 32 hex digits.
Returns
nil
An error will be raised if the PMK cannot be set.
Example
espnow.setpmk('00112233445566778899aabbccddeeff')
espnow.setwakewindow
Controls the wake window during which ESP-NOW listens. In most cases this should never need to be changed from the default. Refer to the Espressif documentation for further details.
Syntax
espnow.setwakewindow(window)
Parameters
window
An integer between 0 and 65535.
Returns
nil
espnow.addpeer
Registers a peer MAC address. Optionally parameters for the peer may be included, such as encryption key.
Syntax
espnow.addpeer(mac, options)
Parameters
mac
The peer mac address, given as a string in00:11:22:33:44:55
format (colons optional, and may also be replaced by '-' or ' ').options
A table with with following entries:channel
An integer indicating the WiFi channel to be used. The default is0
, indicating that the current WiFi channel should be used. If non-zero, must match the current WiFi channel.lmk
The LMK for the peer, if encryption is to be used.encrypt
A non-zero integer to indicate encryption should be enabled. When set, makeslmk
a required field.
Returns
nil
An error will be raised if a peer cannot be added, such as if the peer list if full, or the peer has already been added.
Examples
Adding a peer without encryption enabled.
espnow.addpeer('7c:df:a1:c1:4c:71')
Adding a peer with encryption enabled. Please use randomly generated keys instead of these easily guessable placeholders.
espnow.setpmk('ffeeddccbbaa99887766554433221100')
espnow.addpeer('7c:df:a1:c1:4c:71', { encrypt = 1, lmk = '00112233445566778899aabbccddeeff' })
espnow.delpeer
Deletes a previously added peer from the internal peer list.
Syntax
espnow.delpeer(mac)
Parameters
mac
The MAC address of the peer to delete.
Returns
nil
Returns an error if the peer cannot be deleted.
espnow.on
Registers or unregisters callback handlers for the ESP-NOW events.
There are two events available, sent
which is issued in response to a packet send request and which reports the status of the send attempt, and 'receive' which is issued when an ESP-NOW packet is successfully received.
Only a single callback function can be registered for each event.
The callback function for the sent
event is invoked with two parameters, the destination MAC address, and a 1
/nil
to indicate whether the send was believed to be successful or not.
The callback function for the receive
event is invoked with a single parameter, a table with the following keys:
src
The sender MAC addressdst
The destination MAC address (likely either the local MAC of the receiver, or the broadcast address)rssi
The RSSI value from the packet, indicating signal strength between the two devicesdata
The actual payload data, as a string. The string may contain binary data.
Syntax
espnow.on(event, callbackfn)
Parameters
event
The event name, one ofsent
orreceive
.callbackfn
The callback function to register, ornil
to unregister the previously set callback function for the event.
Returns
nil
Raises an error if invalid arguments are given.
Example
Registering callback handlers.
espnow.on('sent',
function(mac, success) print(mac, success and 'Yay!' or 'Noooo') end)
espnow.on('receive',
function(t) print(t.src, '->', t.dst, '@', t.rssi, ':', t.data) end)
Unregistering callback handlers.
espnow.on('sent') -- implicit nil
espnow.on('receive', nil)
espnow.send
Attempts to send an ESP-NOW packet to one or more peers.
In general it is strongly recommended to use the encryption functionality, as this ensures not only secrecy but also prevent unintentional interference between different users of ESP-NOW.
If you do need to use broadcasts or multicasts, you should make sure to have a unique, recognisable marker at the start of the payload to make filtering out unwanted messages easy, both for you and other ESP-NOW users.
Syntax
espnow.send(peer, data)
Parameters
peer
The peer MAC address to send to. Must have previously been added viaespnow.addpeer()
. Ifpeer
is given asnil
, the packet is sent to all registered non-broadcast/multicast peers, and thesent
callback is invoked for each of those peers.data
A string of data to send. May contain binary bytes. Maximum supported length at the time of writing is 250 bytes.
Returns
nil
, but the sent
callback is invoked with the status afterwards.
Raises an error if the peer is not valid, or other fatal errors preventing a send attempt from even being made. The sent
callback will not be invoked in this case.
Example
Broadcasting a message to every single ESP-NOW device in range.
bcast='ff:ff:ff:ff:ff:ff'
espnow.addpeer(bcast)
espnow.send(bcast, '[NodeMCU] Hello, world!')
Sending a directed message to one specific ESP-NOW device.
peer='7c:df:a1:c1:4c:71'
espnow.addpeer(peer)
espnow.send(peer, 'Hello, you!')
Sending a message to all registered peers.
espnow.addpeer('7c:df:a1:c1:4c:71')
espnow.addpeer('7c:df:a1:c1:4c:47')
espnow.addpeer('7c:df:a1:c1:4f:12')
espnow.send(nil, 'Hello, peers!')