Skip to content

Commit 018faef

Browse files
committed
feat(esp_now): Add support for ESP NOW V2
1 parent 21640ac commit 018faef

File tree

7 files changed

+98
-15
lines changed

7 files changed

+98
-15
lines changed

libraries/ESP_NOW/examples/ESP_NOW_Broadcast_Master/ESP_NOW_Broadcast_Master.ino

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,8 @@ void setup() {
8686
ESP.restart();
8787
}
8888

89+
Serial.printf("ESP-NOW version: %d, max data length: %d\n", ESP_NOW.getVersion(), ESP_NOW.getMaxDataLen());
90+
8991
Serial.println("Setup complete. Broadcasting messages every 5 seconds.");
9092
}
9193

libraries/ESP_NOW/examples/ESP_NOW_Broadcast_Slave/ESP_NOW_Broadcast_Slave.ino

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,8 @@ void setup() {
104104
ESP.restart();
105105
}
106106

107+
Serial.printf("ESP-NOW version: %d, max data length: %d\n", ESP_NOW.getVersion(), ESP_NOW.getMaxDataLen());
108+
107109
// Register the new peer callback
108110
ESP_NOW.onNewPeer(register_new_master, nullptr);
109111

libraries/ESP_NOW/examples/ESP_NOW_Network/ESP_NOW_Network.ino

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,12 @@
7575
// The following struct is used to send data to the peer device.
7676
// We use the attribute "packed" to ensure that the struct is not padded (all data
7777
// is contiguous in the memory and without gaps).
78-
// The maximum size of the complete message is 250 bytes (ESP_NOW_MAX_DATA_LEN).
78+
// The maximum size of the payload is 250 bytes (ESP_NOW_MAX_DATA_LEN) for ESP-NOW v1.0.
79+
// For ESP-NOW v2.0, the maximum size of the payload is 1470 bytes (ESP_NOW_MAX_DATA_LEN_V2).
80+
// You can use ESP_NOW.getMaxDataLen() after calling ESP_NOW.begin() to get the maximum size
81+
// of the data that can be sent.
82+
// Read about the compatibility between ESP-NOW v1.0 and v2.0 in the ESP-IDF documentation:
83+
// https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/network/esp_now.html#frame-format
7984

8085
typedef struct {
8186
uint32_t count;
@@ -276,6 +281,8 @@ void setup() {
276281
fail_reboot();
277282
}
278283

284+
Serial.printf("ESP-NOW version: %d, max data length: %d\n", ESP_NOW.getVersion(), ESP_NOW.getMaxDataLen());
285+
279286
if (!broadcast_peer.begin()) {
280287
Serial.println("Failed to initialize broadcast peer");
281288
fail_reboot();

libraries/ESP_NOW/examples/ESP_NOW_Serial/ESP_NOW_Serial.ino

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ void setup() {
6464
// Start the ESP-NOW communication
6565
Serial.println("ESP-NOW communication starting...");
6666
NowSerial.begin(115200);
67+
Serial.printf("ESP-NOW version: %d, max data length: %d\n", ESP_NOW.getVersion(), ESP_NOW.getMaxDataLen());
6768
Serial.println("You can now send data to the peer device using the Serial Monitor.\n");
6869
}
6970

libraries/ESP_NOW/src/ESP32_NOW.cpp

Lines changed: 57 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,10 @@ static void _esp_now_tx_cb(const uint8_t *mac_addr, esp_now_send_status_t status
140140
}
141141
}
142142

143-
ESP_NOW_Class::ESP_NOW_Class() {}
143+
ESP_NOW_Class::ESP_NOW_Class() {
144+
max_data_len = 0;
145+
version = 0;
146+
}
144147

145148
ESP_NOW_Class::~ESP_NOW_Class() {}
146149

@@ -155,6 +158,23 @@ bool ESP_NOW_Class::begin(const uint8_t *pmk) {
155158
return false;
156159
}
157160

161+
// Unfortunately we can't get the ESP-NOW version before initializing the Wi-Fi
162+
uint32_t esp_now_version;
163+
err = esp_now_get_version(&esp_now_version);
164+
if (err != ESP_OK) {
165+
log_w("esp_now_get_version failed! Assuming ESP-NOW v1.0");
166+
esp_now_version = 1;
167+
}
168+
169+
if (esp_now_version == 1) {
170+
max_data_len = ESP_NOW_MAX_DATA_LEN;
171+
} else {
172+
max_data_len = ESP_NOW_MAX_DATA_LEN_V2;
173+
}
174+
175+
version = esp_now_version;
176+
log_i("ESP-NOW version: %lu, max_data_len: %lu", version, max_data_len);
177+
158178
_esp_now_has_begun = true;
159179

160180
memset(_esp_now_peers, 0, sizeof(ESP_NOW_Peer *) * ESP_NOW_MAX_TOTAL_PEER_NUM);
@@ -212,7 +232,7 @@ bool ESP_NOW_Class::end() {
212232
return true;
213233
}
214234

215-
int ESP_NOW_Class::getTotalPeerCount() {
235+
int ESP_NOW_Class::getTotalPeerCount() const {
216236
if (!_esp_now_has_begun) {
217237
return -1;
218238
}
@@ -225,7 +245,7 @@ int ESP_NOW_Class::getTotalPeerCount() {
225245
return num.total_num;
226246
}
227247

228-
int ESP_NOW_Class::getEncryptedPeerCount() {
248+
int ESP_NOW_Class::getEncryptedPeerCount() const {
229249
if (!_esp_now_has_begun) {
230250
return -1;
231251
}
@@ -238,16 +258,38 @@ int ESP_NOW_Class::getEncryptedPeerCount() {
238258
return num.encrypt_num;
239259
}
240260

261+
int ESP_NOW_Class::getMaxDataLen() const {
262+
if (max_data_len == 0) {
263+
log_e("ESP-NOW not initialized. Please call begin() first to get the max data length.");
264+
return -ESP_ERR_ESPNOW_NOT_INIT;
265+
}
266+
267+
return max_data_len;
268+
}
269+
270+
int ESP_NOW_Class::getVersion() const {
271+
if (version == 0) {
272+
log_e("ESP-NOW not initialized. Please call begin() first to get the version.");
273+
return -ESP_ERR_ESPNOW_NOT_INIT;
274+
}
275+
276+
return version;
277+
}
278+
241279
int ESP_NOW_Class::availableForWrite() {
242-
return ESP_NOW_MAX_DATA_LEN;
280+
int available = getMaxDataLen();
281+
if (available < 0) {
282+
return 0;
283+
}
284+
return available;
243285
}
244286

245287
size_t ESP_NOW_Class::write(const uint8_t *data, size_t len) {
246288
if (!_esp_now_has_begun) {
247289
return 0;
248290
}
249-
if (len > ESP_NOW_MAX_DATA_LEN) {
250-
len = ESP_NOW_MAX_DATA_LEN;
291+
if (len > max_data_len) {
292+
len = max_data_len;
251293
}
252294
esp_err_t result = esp_now_send(nullptr, data, len);
253295
if (result == ESP_OK) {
@@ -386,8 +428,15 @@ size_t ESP_NOW_Peer::send(const uint8_t *data, int len) {
386428
log_e("Peer not added.");
387429
return 0;
388430
}
389-
if (len > ESP_NOW_MAX_DATA_LEN) {
390-
len = ESP_NOW_MAX_DATA_LEN;
431+
432+
int max_data_len = ESP_NOW.getMaxDataLen();
433+
if (max_data_len < 0) {
434+
log_e("Error getting max data length.");
435+
return 0;
436+
}
437+
438+
if (len > max_data_len) {
439+
len = max_data_len;
391440
}
392441
esp_err_t result = esp_now_send(mac, data, len);
393442
if (result == ESP_OK) {

libraries/ESP_NOW/src/ESP32_NOW.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,10 @@ class ESP_NOW_Class : public Print {
2323
bool begin(const uint8_t *pmk = nullptr /* 16 bytes */);
2424
bool end();
2525

26-
int getTotalPeerCount();
27-
int getEncryptedPeerCount();
26+
int getTotalPeerCount() const;
27+
int getEncryptedPeerCount() const;
28+
int getMaxDataLen() const;
29+
int getVersion() const;
2830

2931
int availableForWrite();
3032
size_t write(const uint8_t *data, size_t len);
@@ -34,6 +36,10 @@ class ESP_NOW_Class : public Print {
3436

3537
void onNewPeer(void (*cb)(const esp_now_recv_info_t *info, const uint8_t *data, int len, void *arg), void *arg);
3638
bool removePeer(ESP_NOW_Peer &peer);
39+
40+
protected:
41+
size_t max_data_len;
42+
uint32_t version;
3743
};
3844

3945
class ESP_NOW_Peer {

libraries/ESP_NOW/src/ESP32_NOW_Serial.cpp

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,25 @@ bool ESP_NOW_Serial_Class::begin(unsigned long baud) {
7070
//xSemaphoreTake(tx_sem, 0);
7171
xSemaphoreGive(tx_sem);
7272
}
73-
setRxBufferSize(1024); //default if not preset
74-
setTxBufferSize(1024); //default if not preset
73+
74+
size_t buf_size = 0;
75+
if (ESP_NOW.getVersion() == 2) {
76+
// ESP-NOW v2.0 has a larger maximum data length, so we need to increase the buffer sizes
77+
// to hold around 3-4 packets
78+
buf_size = setRxBufferSize(4096);
79+
buf_size &= setTxBufferSize(4096);
80+
} else {
81+
// ESP-NOW v1.0 has a smaller maximum data length, so we can use the default buffer sizes
82+
// to hold around 3-4 packets
83+
buf_size = setRxBufferSize(1024);
84+
buf_size &= setTxBufferSize(1024);
85+
}
86+
87+
if (buf_size == 0) {
88+
log_e("Failed to set buffer size");
89+
return false;
90+
}
91+
7592
return true;
7693
}
7794

@@ -164,7 +181,6 @@ void ESP_NOW_Serial_Class::onReceive(const uint8_t *data, size_t len, bool broad
164181

165182
//Print
166183
int ESP_NOW_Serial_Class::availableForWrite() {
167-
//return ESP_NOW_MAX_DATA_LEN;
168184
if (tx_ring_buf == nullptr) {
169185
return 0;
170186
}
@@ -189,7 +205,7 @@ bool ESP_NOW_Serial_Class::checkForTxData() {
189205
//do we have something that failed the last time?
190206
resend_count = 0;
191207
if (queued_buff == nullptr) {
192-
queued_buff = (uint8_t *)xRingbufferReceiveUpTo(tx_ring_buf, &queued_size, 0, ESP_NOW_MAX_DATA_LEN);
208+
queued_buff = (uint8_t *)xRingbufferReceiveUpTo(tx_ring_buf, &queued_size, 0, ESP_NOW.getMaxDataLen());
193209
} else {
194210
log_d(MACSTR " : PREVIOUS", MAC2STR(addr()));
195211
}

0 commit comments

Comments
 (0)