feat(esp_now): Add support for ESP NOW V2 (#11524)
* feat(esp_now): Add support for ESP NOW V2 * fix(esp_now): Return -1 on error
This commit is contained in:
parent
9a35d9455f
commit
6754b1962c
7 changed files with 98 additions and 15 deletions
|
|
@ -86,6 +86,8 @@ void setup() {
|
|||
ESP.restart();
|
||||
}
|
||||
|
||||
Serial.printf("ESP-NOW version: %d, max data length: %d\n", ESP_NOW.getVersion(), ESP_NOW.getMaxDataLen());
|
||||
|
||||
Serial.println("Setup complete. Broadcasting messages every 5 seconds.");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -104,6 +104,8 @@ void setup() {
|
|||
ESP.restart();
|
||||
}
|
||||
|
||||
Serial.printf("ESP-NOW version: %d, max data length: %d\n", ESP_NOW.getVersion(), ESP_NOW.getMaxDataLen());
|
||||
|
||||
// Register the new peer callback
|
||||
ESP_NOW.onNewPeer(register_new_master, nullptr);
|
||||
|
||||
|
|
|
|||
|
|
@ -75,7 +75,12 @@
|
|||
// The following struct is used to send data to the peer device.
|
||||
// We use the attribute "packed" to ensure that the struct is not padded (all data
|
||||
// is contiguous in the memory and without gaps).
|
||||
// The maximum size of the complete message is 250 bytes (ESP_NOW_MAX_DATA_LEN).
|
||||
// The maximum size of the payload is 250 bytes (ESP_NOW_MAX_DATA_LEN) for ESP-NOW v1.0.
|
||||
// For ESP-NOW v2.0, the maximum size of the payload is 1470 bytes (ESP_NOW_MAX_DATA_LEN_V2).
|
||||
// You can use ESP_NOW.getMaxDataLen() after calling ESP_NOW.begin() to get the maximum size
|
||||
// of the data that can be sent.
|
||||
// Read about the compatibility between ESP-NOW v1.0 and v2.0 in the ESP-IDF documentation:
|
||||
// https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/network/esp_now.html#frame-format
|
||||
|
||||
typedef struct {
|
||||
uint32_t count;
|
||||
|
|
@ -276,6 +281,8 @@ void setup() {
|
|||
fail_reboot();
|
||||
}
|
||||
|
||||
Serial.printf("ESP-NOW version: %d, max data length: %d\n", ESP_NOW.getVersion(), ESP_NOW.getMaxDataLen());
|
||||
|
||||
if (!broadcast_peer.begin()) {
|
||||
Serial.println("Failed to initialize broadcast peer");
|
||||
fail_reboot();
|
||||
|
|
|
|||
|
|
@ -64,6 +64,7 @@ void setup() {
|
|||
// Start the ESP-NOW communication
|
||||
Serial.println("ESP-NOW communication starting...");
|
||||
NowSerial.begin(115200);
|
||||
Serial.printf("ESP-NOW version: %d, max data length: %d\n", ESP_NOW.getVersion(), ESP_NOW.getMaxDataLen());
|
||||
Serial.println("You can now send data to the peer device using the Serial Monitor.\n");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -140,7 +140,10 @@ static void _esp_now_tx_cb(const uint8_t *mac_addr, esp_now_send_status_t status
|
|||
}
|
||||
}
|
||||
|
||||
ESP_NOW_Class::ESP_NOW_Class() {}
|
||||
ESP_NOW_Class::ESP_NOW_Class() {
|
||||
max_data_len = 0;
|
||||
version = 0;
|
||||
}
|
||||
|
||||
ESP_NOW_Class::~ESP_NOW_Class() {}
|
||||
|
||||
|
|
@ -155,6 +158,23 @@ bool ESP_NOW_Class::begin(const uint8_t *pmk) {
|
|||
return false;
|
||||
}
|
||||
|
||||
// Unfortunately we can't get the ESP-NOW version before initializing the Wi-Fi
|
||||
uint32_t esp_now_version;
|
||||
err = esp_now_get_version(&esp_now_version);
|
||||
if (err != ESP_OK) {
|
||||
log_w("esp_now_get_version failed! Assuming ESP-NOW v1.0");
|
||||
esp_now_version = 1;
|
||||
}
|
||||
|
||||
if (esp_now_version == 1) {
|
||||
max_data_len = ESP_NOW_MAX_DATA_LEN;
|
||||
} else {
|
||||
max_data_len = ESP_NOW_MAX_DATA_LEN_V2;
|
||||
}
|
||||
|
||||
version = esp_now_version;
|
||||
log_i("ESP-NOW version: %lu, max_data_len: %lu", version, max_data_len);
|
||||
|
||||
_esp_now_has_begun = true;
|
||||
|
||||
memset(_esp_now_peers, 0, sizeof(ESP_NOW_Peer *) * ESP_NOW_MAX_TOTAL_PEER_NUM);
|
||||
|
|
@ -212,7 +232,7 @@ bool ESP_NOW_Class::end() {
|
|||
return true;
|
||||
}
|
||||
|
||||
int ESP_NOW_Class::getTotalPeerCount() {
|
||||
int ESP_NOW_Class::getTotalPeerCount() const {
|
||||
if (!_esp_now_has_begun) {
|
||||
return -1;
|
||||
}
|
||||
|
|
@ -225,7 +245,7 @@ int ESP_NOW_Class::getTotalPeerCount() {
|
|||
return num.total_num;
|
||||
}
|
||||
|
||||
int ESP_NOW_Class::getEncryptedPeerCount() {
|
||||
int ESP_NOW_Class::getEncryptedPeerCount() const {
|
||||
if (!_esp_now_has_begun) {
|
||||
return -1;
|
||||
}
|
||||
|
|
@ -238,16 +258,38 @@ int ESP_NOW_Class::getEncryptedPeerCount() {
|
|||
return num.encrypt_num;
|
||||
}
|
||||
|
||||
int ESP_NOW_Class::getMaxDataLen() const {
|
||||
if (max_data_len == 0) {
|
||||
log_e("ESP-NOW not initialized. Please call begin() first to get the max data length.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return max_data_len;
|
||||
}
|
||||
|
||||
int ESP_NOW_Class::getVersion() const {
|
||||
if (version == 0) {
|
||||
log_e("ESP-NOW not initialized. Please call begin() first to get the version.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return version;
|
||||
}
|
||||
|
||||
int ESP_NOW_Class::availableForWrite() {
|
||||
return ESP_NOW_MAX_DATA_LEN;
|
||||
int available = getMaxDataLen();
|
||||
if (available < 0) {
|
||||
return 0;
|
||||
}
|
||||
return available;
|
||||
}
|
||||
|
||||
size_t ESP_NOW_Class::write(const uint8_t *data, size_t len) {
|
||||
if (!_esp_now_has_begun) {
|
||||
return 0;
|
||||
}
|
||||
if (len > ESP_NOW_MAX_DATA_LEN) {
|
||||
len = ESP_NOW_MAX_DATA_LEN;
|
||||
if (len > max_data_len) {
|
||||
len = max_data_len;
|
||||
}
|
||||
esp_err_t result = esp_now_send(nullptr, data, len);
|
||||
if (result == ESP_OK) {
|
||||
|
|
@ -386,8 +428,15 @@ size_t ESP_NOW_Peer::send(const uint8_t *data, int len) {
|
|||
log_e("Peer not added.");
|
||||
return 0;
|
||||
}
|
||||
if (len > ESP_NOW_MAX_DATA_LEN) {
|
||||
len = ESP_NOW_MAX_DATA_LEN;
|
||||
|
||||
int max_data_len = ESP_NOW.getMaxDataLen();
|
||||
if (max_data_len < 0) {
|
||||
log_e("Error getting max data length.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (len > max_data_len) {
|
||||
len = max_data_len;
|
||||
}
|
||||
esp_err_t result = esp_now_send(mac, data, len);
|
||||
if (result == ESP_OK) {
|
||||
|
|
|
|||
|
|
@ -23,8 +23,10 @@ public:
|
|||
bool begin(const uint8_t *pmk = nullptr /* 16 bytes */);
|
||||
bool end();
|
||||
|
||||
int getTotalPeerCount();
|
||||
int getEncryptedPeerCount();
|
||||
int getTotalPeerCount() const;
|
||||
int getEncryptedPeerCount() const;
|
||||
int getMaxDataLen() const;
|
||||
int getVersion() const;
|
||||
|
||||
int availableForWrite();
|
||||
size_t write(const uint8_t *data, size_t len);
|
||||
|
|
@ -34,6 +36,10 @@ public:
|
|||
|
||||
void onNewPeer(void (*cb)(const esp_now_recv_info_t *info, const uint8_t *data, int len, void *arg), void *arg);
|
||||
bool removePeer(ESP_NOW_Peer &peer);
|
||||
|
||||
protected:
|
||||
size_t max_data_len;
|
||||
uint32_t version;
|
||||
};
|
||||
|
||||
class ESP_NOW_Peer {
|
||||
|
|
|
|||
|
|
@ -70,8 +70,25 @@ bool ESP_NOW_Serial_Class::begin(unsigned long baud) {
|
|||
//xSemaphoreTake(tx_sem, 0);
|
||||
xSemaphoreGive(tx_sem);
|
||||
}
|
||||
setRxBufferSize(1024); //default if not preset
|
||||
setTxBufferSize(1024); //default if not preset
|
||||
|
||||
size_t buf_size = 0;
|
||||
if (ESP_NOW.getVersion() == 2) {
|
||||
// ESP-NOW v2.0 has a larger maximum data length, so we need to increase the buffer sizes
|
||||
// to hold around 3-4 packets
|
||||
buf_size = setRxBufferSize(4096);
|
||||
buf_size &= setTxBufferSize(4096);
|
||||
} else {
|
||||
// ESP-NOW v1.0 has a smaller maximum data length, so we can use the default buffer sizes
|
||||
// to hold around 3-4 packets
|
||||
buf_size = setRxBufferSize(1024);
|
||||
buf_size &= setTxBufferSize(1024);
|
||||
}
|
||||
|
||||
if (buf_size == 0) {
|
||||
log_e("Failed to set buffer size");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -164,7 +181,6 @@ void ESP_NOW_Serial_Class::onReceive(const uint8_t *data, size_t len, bool broad
|
|||
|
||||
//Print
|
||||
int ESP_NOW_Serial_Class::availableForWrite() {
|
||||
//return ESP_NOW_MAX_DATA_LEN;
|
||||
if (tx_ring_buf == nullptr) {
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -189,7 +205,7 @@ bool ESP_NOW_Serial_Class::checkForTxData() {
|
|||
//do we have something that failed the last time?
|
||||
resend_count = 0;
|
||||
if (queued_buff == nullptr) {
|
||||
queued_buff = (uint8_t *)xRingbufferReceiveUpTo(tx_ring_buf, &queued_size, 0, ESP_NOW_MAX_DATA_LEN);
|
||||
queued_buff = (uint8_t *)xRingbufferReceiveUpTo(tx_ring_buf, &queued_size, 0, ESP_NOW.getMaxDataLen());
|
||||
} else {
|
||||
log_d(MACSTR " : PREVIOUS", MAC2STR(addr()));
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue