Skip to content

Commit

Permalink
Make it easier/possible to change channel for espnow. (#2156)
Browse files Browse the repository at this point in the history
We were seeing "Peer channel is not equal to the home channel" errors.

Also see https://esp32.com/viewtopic.php?t=18291
  • Loading branch information
floitsch authored Mar 20, 2024
1 parent f94a050 commit 7bc99a4
Show file tree
Hide file tree
Showing 6 changed files with 35 additions and 19 deletions.
6 changes: 2 additions & 4 deletions examples/espnow.toit
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,8 @@ import esp32.espnow
PMK ::= espnow.Key.from-string "pmk1234567890123"

main:
service := espnow.Service.station --key=PMK
service.add-peer
espnow.BROADCAST-ADDRESS
--channel=1
service := espnow.Service.station --key=PMK --channel=1
service.add-peer espnow.BROADCAST-ADDRESS
task:: send-task service
task:: receive-task service

Expand Down
27 changes: 22 additions & 5 deletions lib/esp32/espnow.toit
Original file line number Diff line number Diff line change
Expand Up @@ -107,18 +107,23 @@ class Service:
send-mutex_/monitor.Mutex ::= monitor.Mutex
resource_ := ?
state_ := ?
channel/int := ?

/**
Constructs a new ESP-Now service in station mode.
The $rate parameter, if provided, must be a valid ESP-Now rate constant. See
$RATE-1M-L for example. By default, the rate is set to 1Mbps.
The $channel parameter must be a valid Wi-Fi channel number.
*/
constructor.station --key/Key? --rate/int?=null:
constructor.station --key/Key? --rate/int?=null --.channel=6:
if not 0 < channel <= 14: throw "INVALID_ARGUMENT"

key-data := key ? key.data : #[]
if rate and rate < 0: throw "INVALID_ARGUMENT"
if not rate: rate = -1
resource_ = espnow-create_ resource-group_ STATION_ key-data rate
resource_ = espnow-create_ resource-group_ STATION_ key-data rate channel
state_ = ResourceState_ resource-group_ resource_

close -> none:
Expand All @@ -136,6 +141,9 @@ class Service:
/**
Sends the given $data to the given $address.
Unless the $address is a broadcast address, the $address must be a peer added
with $(add-peer address --key). The $address must be a valid MAC address.
The $data must be at most 250 bytes long.
Waits for the transmission to complete.
*/
Expand Down Expand Up @@ -166,10 +174,19 @@ class Service:
address := Address result[0]
return Datagram address result[1]

/**
Deprecated. Use $(add-peer address --key) without any channel. The channel is
now set during construction of the service (see $Service.station).
*/
add-peer address/Address --channel/int --key/Key?=null -> bool:
if not 0 <= channel <= 14:
throw "ESP-Now channel range must be 0-14"
return add-peer address --key=key

/**
Adds a peer with the given $address and $key.
The channel of the peer is set to the channel of the service.
*/
add-peer address/Address --key/Key?=null -> bool:
key-data := key ? key.data : #[]
return espnow-add-peer_ resource_ address.mac channel key-data

Expand All @@ -181,7 +198,7 @@ SEND-DONE-STATE_ ::= 1 << 1
espnow-init_:
#primitive.espnow.init

espnow-create_ group mode pmk rate:
espnow-create_ group mode pmk rate channel:
#primitive.espnow.create

espnow-close_ resource:
Expand Down
2 changes: 1 addition & 1 deletion src/primitive.h
Original file line number Diff line number Diff line change
Expand Up @@ -707,7 +707,7 @@ namespace toit {

#define MODULE_ESPNOW(PRIMITIVE) \
PRIMITIVE(init, 0) \
PRIMITIVE(create, 4) \
PRIMITIVE(create, 5) \
PRIMITIVE(close, 1) \
PRIMITIVE(send, 3) \
PRIMITIVE(send_succeeded, 1) \
Expand Down
7 changes: 6 additions & 1 deletion src/resources/espnow_esp32.cc
Original file line number Diff line number Diff line change
Expand Up @@ -403,7 +403,7 @@ PRIMITIVE(init) {
}

PRIMITIVE(create) {
ARGS(EspNowResourceGroup, group, int, mode, Blob, pmk, int, rate);
ARGS(EspNowResourceGroup, group, int, mode, Blob, pmk, int, rate, int, channel);

wifi_phy_rate_t phy_rate = WIFI_PHY_RATE_1M_L;
if (rate != -1) {
Expand Down Expand Up @@ -439,6 +439,11 @@ PRIMITIVE(create) {
group->register_resource(resource);
proxy->set_external_address(resource);

esp_err_t err = esp_wifi_set_channel(channel, WIFI_SECOND_CHAN_NONE);
if (err != ESP_OK) {
return Primitive::os_error(err, process);
}

return proxy;
}

Expand Down
6 changes: 2 additions & 4 deletions tests/esp32/espnow1-board1.toit
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,9 @@ import expect show *
import .espnow1-shared

main:
service ::= espnow.Service.station --key=PMK
service ::= espnow.Service.station --key=PMK --channel=CHANNEL

service.add-peer
espnow.BROADCAST-ADDRESS
--channel=CHANNEL
service.add-peer espnow.BROADCAST-ADDRESS

print "Listening for messages."
with-timeout --ms=10_000:
Expand Down
6 changes: 2 additions & 4 deletions tests/esp32/espnow1-board2.toit
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,9 @@ import esp32.espnow
import .espnow1-shared

main:
service ::= espnow.Service.station --key=PMK
service ::= espnow.Service.station --key=PMK --channel=CHANNEL

service.add-peer
espnow.BROADCAST-ADDRESS
--channel=CHANNEL
service.add-peer espnow.BROADCAST-ADDRESS

TEST-DATA.do:
service.send
Expand Down

0 comments on commit 7bc99a4

Please sign in to comment.