|
| 1 | +:mod:`espnow` --- Support for the ESP-NOW protocol |
| 2 | +================================================== |
| 3 | + |
| 4 | +.. module:: espnow |
| 5 | + :synopsis: Low-level ESP-NOW wireless protocol support |
| 6 | + |
| 7 | +This module provides an interface to the ESP-NOW protocol provided by Espressif |
| 8 | +on ESP32 and ESP8266 devices. |
| 9 | + |
| 10 | +Load this module from the `esp` module:: |
| 11 | + |
| 12 | + from esp import espnow |
| 13 | + |
| 14 | + |
| 15 | + |
| 16 | +.. note:: This module is still under development and its classes, functions, |
| 17 | + methods and constants are subject to change. |
| 18 | + |
| 19 | +class ESPNow |
| 20 | +------------ |
| 21 | + |
| 22 | +Constructor |
| 23 | +----------- |
| 24 | + |
| 25 | +.. class:: ESPNow() |
| 26 | + |
| 27 | + Returns the singleton ESPNow object. |
| 28 | + |
| 29 | +Configuration |
| 30 | +------------- |
| 31 | + |
| 32 | +.. method:: ESPNow.init() |
| 33 | + |
| 34 | + Prepare the software and hardware for use of the ESPNow communication |
| 35 | + protocol, including: |
| 36 | + |
| 37 | + - initialise the ESPNow data structures, |
| 38 | + - allocate the send and recv data buffers, |
| 39 | + - invoke esp_now_init() and |
| 40 | + - register the send and recv callbacks. |
| 41 | + |
| 42 | +.. method:: ESPNow.deinit() |
| 43 | + |
| 44 | + De-initialise the Espressif ESPNow software stack (esp_now_deinit()), disable |
| 45 | + the interrupt callbacks and deallocate the send and recv data buffers. |
| 46 | + |
| 47 | + **Note**: `deinit()` will also deregister all peers which must be |
| 48 | + re-registered after `init()`. |
| 49 | + |
| 50 | +.. method:: ESPNow.config() |
| 51 | + ESPNow.config('param') |
| 52 | + ESPNow.config(param=value, ...) |
| 53 | + |
| 54 | + Get or set configuration values of the ESPNow interface. To get a value the |
| 55 | + parameter name should be quoted as a string, and just one parameter is |
| 56 | + queried at a time. To set values use the keyword syntax, and one or more |
| 57 | + parameters can be set at a time. Invocation with no arguments will return a |
| 58 | + dict of all parameter names and values. |
| 59 | + |
| 60 | + Currently supported values are: |
| 61 | + |
| 62 | + - ``'txbuf'``: *(default=200)* Get/set the size in bytes of the internal |
| 63 | + buffer used to store status data for the send callback functions |
| 64 | + (`send_cb()` - see below). This buffer is global to the entire ESPNow driver. |
| 65 | + Increasing this allows better handling of bursty outgoing/incoming data. |
| 66 | + |
| 67 | + - ``'rxbuf'``: *(default=534)* Get/set the size in bytes of the internal |
| 68 | + buffer used to store incoming ESPNow packet data. This buffer is global |
| 69 | + to the entire ESPNow driver. The default size is selected to fit two |
| 70 | + max-sized ESPNow packets (250 bytes) with associated mac_address (6 bytes) |
| 71 | + and a packet byte count (1 byte) plus buffer overhead. Increase this if |
| 72 | + you expect to receive a lot of large packets or expect bursty incoming |
| 73 | + traffic. |
| 74 | + |
| 75 | + **Note:** The send and recv buffers are only allocated/deallocated by the |
| 76 | + `init()/deinit()` methods. ie. changing these values will have no effect |
| 77 | + until the next call of `init()`. |
| 78 | + |
| 79 | + - ``'cb_repeat'``: *(default=20)* Get/set the GAP d
F438
evice "callback repeat" |
| 80 | + parameter. This parameter is used to set a cap on the number of packets |
| 81 | + which will be processed by each call of the soft interrupt callback |
| 82 | + function (see below). This can be set at any time and will take immediate |
| 83 | + effect. |
| 84 | + |
| 85 | +.. method:: ESPNow.set_pmk(pmk) |
| 86 | + |
| 87 | + Set the Primary Master Key (PMK) which is used to encrypt the Local Master |
| 88 | + Keys (LMK) for encrypting ESPNow data traffic. If this is not set, a default |
| 89 | + PMK is used by the underlying Espressif esp_now software stack. The ``pmk`` |
| 90 | + argument bust be a byte string of length `espnow.KEY_LEN` (16 bytes). |
| 91 | + |
| 92 | +Sending and Receiving Data |
| 93 | +-------------------------- |
| 94 | + |
| 95 | +The relevant wifi interface must be activated before messages can be sent or |
| 96 | +received via the ESPNow interface. For example:: |
| 97 | + |
| 98 | + import network |
| 99 | + |
| 100 | + w0 = network.WLAN(network.STA_IF) |
| 101 | + w0.active(True) |
| 102 | + |
| 103 | +The wifi interface (`network.STA_IF` or `network.AP_IF`) must be `active()` |
| 104 | +but it is not necessary to connect or configure the WLAN interface. |
| 105 | + |
| 106 | +.. method:: ESPNow.send(mac, msg) |
| 107 | + |
| 108 | + Send the data contained in ``msg`` to the peer with given network ``mac`` |
| 109 | + address. ``mac`` bust be a byte string exactly 6 bytes long and ``msg`` must |
| 110 | + be a string or byte-string at most `espnow.MAX_DATA_LEN` (250) bytes long. |
| 111 | + |
| 112 | + `ESPNow.send()` will return after the ``msg`` has been handed off to the |
| 113 | + esp_now software stack for transmitting. Success or failure of |
| 114 | + communication with the peer will be signalled through the *handler* |
| 115 | + registered with `ESPNow.on_send()`. |
| 116 | + |
| 117 | +.. method:: ESPNow.on_recv(recv_cb) |
| 118 | + |
| 119 | + Registers a callback for incoming ESPNow data packets. The *recv_cb* must |
| 120 | + have a call signature like:: |
| 121 | + |
| 122 | + def recv_cb(mac, msg): |
| 123 | + print("Recv:", mac, msg) |
| 124 | + if msg == b'ping': |
| 125 | + espnow.ESPNow.send(mac, b'pong') |
| 126 | + |
| 127 | + espnow.ESPNow.on_recv(recv_cb) |
| 128 | + |
| 129 | + Where: |
| 130 | + |
| 131 | + - ``mac`` is the mac address of the sending device (peer) and |
| 132 | + |
| 133 | + - ``msg`` is the message/data sent from the peer. |
| 134 | + |
| 135 | + To eliminate unnecessary allocation of heap memory the storage for ``mac`` |
| 136 | + and ``msg`` is statically allocated and will be overwritten each time |
| 137 | + `recv_cb()` or `send_cb()` is called. `recv_cb` and `send_cb` should take care |
| 138 | + to make a copy of the ``mac`` or ``msg`` byte-strings* if they need to be |
| 139 | + retained. |
| 140 | + |
| 141 | + The callback is run in a micropython `sched` context and should return |
| 142 | + as quickly as possible. |
| 143 | + |
| 144 | +.. method:: ESPNow.on_send(send_cb) |
| 145 | + |
| 146 | + Registers a callback for outgoing ESPNow data packets. ``send_cb`` will be |
| 147 | + called after an outgoing packet has been successfully (or unsuccessfully) |
| 148 | + sent and provides access to the success/fail status of the packet. |
| 149 | + The ``send_cb`` must be a python function which takes two arguments: |
| 150 | + |
| 151 | + - ``mac`` which is the mac address of the receiving device (peer) and |
| 152 | + |
| 153 | + - ``success`` which is ``True`` if the packet was received and ``False`` |
| 154 | + otherwise. |
| 155 | + |
| 156 | + See `ESPNow.on_recv()` for important considerations on static allocation |
| 157 | + of the ``mac`` argument. |
| 158 | + |
| 159 | +.. method:: ESPNow.stats() |
| 160 | + |
| 161 | + Return a 4-tuple containing the number of packets sent/received/lost: |
| 162 | + `(sent_packets, recv_packets, lost_tx_packets, lost_rx_packets)`. Packets |
| 163 | + are *lost* when the send/recv buffers are full. To reduce packet loss, |
| 164 | + increase the ``txbuf`` and ``rxbuf`` config parameters and ensure the |
| 165 | + *recv_cb* and *send_cb* callbacks complete as quickly as possible. |
| 166 | + |
| 167 | +Peer Management |
| 168 | +--------------- |
| 169 | + |
| 170 | +The ESPNow protocol requires that other devices (peers) must be *registered* |
| 171 | +before we can *send()* them data. |
| 172 | + |
| 173 | +.. method:: ESPNow.add_peer(mac, [lmk], [channel], [ifidx], [encrypt]) |
| 174 | + ESPNow.add_peer(mac, 'param'=value, ...) |
| 175 | + |
| 176 | + Add/register the provided ``mac`` address (a 6-byte byte-string) as a peer |
| 177 | + under the ESPNow protocol. The following "peer info" parameters may also be |
| 178 | + specified as positional or keyword arguments: |
| 179 | + |
| 180 | + - ``lmk`` The Local Master Key (LMK) key used to encrypt data transfers |
| 181 | + with this peer (if the *encrypt* parameter is set to *True*). Must be |
| 182 | + a byte-string of length `espnow.KEY_LEN` (16 bytes). |
| 183 | + (default=b'0000000000000000') |
| 184 | + |
| 185 | + - ``channel`` The wifi channel (2.4GHz) to communicate with this peer. Must |
| 186 | + be an integer from 0 to 14. If channel is set to 0 the current channel |
| 187 | + of the wifi device will be used. (default=0) |
| 188 | + |
| 189 | + - ``ifidx`` Index of the wifi interface which will be used to send data to |
| 190 | + this peer. Must be an integer set to `network.WLAN.STA_IF` (=0) or |
| 191 | + `network.WLAN.AP_IF` (=1). (default=0/`network.WLAN.STA_IF`). |
| 192 | + |
| 193 | + - ``encrypt`` If set to ``True`` data exchanged with this peer will be |
| 194 | + encrypted with the PMK and LMK. (default=False) |
| 195 | + |
| 196 | +.. method:: ESPNow.get_peer(mac) |
| 197 | + |
| 198 | + Return a 5-tuple of the "peer info" associated with the ``mac`` address:: |
| 199 | + |
| 200 | + (mac, lmk, channel, ifidx, encrypt) |
| 201 | + |
| 202 | +.. method:: ESPNow.peer_count() |
| 203 | + |
| 204 | + Return the number of peers which have been registered. |
| 205 | + |
| 206 | +.. method:: ESPNow.get_peers() |
| 207 | + |
| 208 | + Return the "peer info" parameters for all the registered peers (as a tuple |
| 209 | + of tuples). |
| 210 | + |
| 211 | +.. method:: ESPNow.mod_peer(mac, lmk, [channel], [ifidx], [encrypt]) |
| 212 | + ESPNow.mod_peer(mac, 'param'=value, ...) |
| 213 | + |
| 214 | + Modify the parameters of the peer associated with the provided ``mac`` |
| 215 | + address. Parameters may be provided as positional or keyword arguments. |
| 216 | + |
| 217 | +.. method:: ESPNow.del_peer(mac) |
| 218 | + |
| 219 | + Deregister the peer associated with the provided ``mac`` address. |
| 220 | + |
| 221 | +Constants |
| 222 | +--------- |
| 223 | + |
| 224 | +.. data:: espnow.MAX_DATA_LEN (=250) |
| 225 | + espnow.KEY_LEN (=16) |
| 226 | + espnow.MAX_TOTAL_PEER_NUM (=20) |
| 227 | + espnow.MAX_ENCRYPT_PEER_NUM (=6) |
0 commit comments