ESP32-C3 not receiving data with ESP-NOW after initialising NimBLE
Posted: Tue Jan 28, 2025 11:56 am
Hi,
I'm using two ESP32-C3, the first one to turn on is the one who becomes the master after 3 seconds. The master should initialise NimBLE and then broadcast every second or so a packet called ACK for other ESP32s with esp now. The problem is that when the slave device receives the packet it tries to reply back to the master but the attempt fails. I know for sure that this kind of communication works because I tried it without initialising NimBLE.
(Note: after initialising NimBLE the master ESP is correctly seen by the phone)
(I already tried to ask on Arduino-ESP32 core but didn't replied and I need to finish this code before friday)
I can't figure out what's the problem.
This is the code
Master's Logs
Slave's Logs
I'm using two ESP32-C3, the first one to turn on is the one who becomes the master after 3 seconds. The master should initialise NimBLE and then broadcast every second or so a packet called ACK for other ESP32s with esp now. The problem is that when the slave device receives the packet it tries to reply back to the master but the attempt fails. I know for sure that this kind of communication works because I tried it without initialising NimBLE.
(Note: after initialising NimBLE the master ESP is correctly seen by the phone)
(I already tried to ask on Arduino-ESP32 core but didn't replied and I need to finish this code before friday)
I can't figure out what's the problem.
This is the code
- #include <NimBLEDevice.h>
- #include "ESP32_NOW.h"
- #include "WiFi.h"
- #include "structs.cpp"
- #include <esp_mac.h> // For the MAC2STR and MACSTR macros
- /* Definitions */
- #define ESPNOW_WIFI_CHANNEL 6
- #define BATTERY_PIN 3
- /* Global Variables */
- uint32_t msg_count = 0;
- bool inGroup = false;
- bool isMaster = false;
- long startupTime, lastBatteryCheckSent, lastACKSent, lastAliveCheck;
- bool connectedBLE = false;
- /* Functions */
- int getCurrentBatterySOT() {
- int batteria = map(analogReadMilliVolts(BATTERY_PIN) * 2, 3150, 4150, 0, 100);
- batteria = max(1, min(batteria, 100));
- return batteria;
- }
- /* Classes */
- // Creating a new class that inherits from the ESP_NOW_Peer class is required.
- class ESP_NOW_Broadcast_Peer : public ESP_NOW_Peer {
- public:
- // Constructor of the class using the broadcast address
- ESP_NOW_Broadcast_Peer(uint8_t channel, wifi_interface_t iface, const uint8_t *lmk) : ESP_NOW_Peer(ESP_NOW.BROADCAST_ADDR, channel, iface, lmk) {}
- // Destructor of the class
- ~ESP_NOW_Broadcast_Peer() {
- remove();
- }
- // Function to properly initialize the ESP-NOW and register the broadcast peer
- bool begin() {
- if (!ESP_NOW.begin() || !add()) {
- log_e("Failed to initialize ESP-NOW or register the broadcast peer");
- return false;
- }
- return true;
- }
- // Function to send a message to all devices within the network
- bool send_message(const uint8_t *data, size_t len) {
- if (!send(data, len)) {
- log_e("Failed to broadcast message");
- return false;
- }
- return true;
- }
- };
- class ESP_NOW_Peer_Class : public ESP_NOW_Peer {
- public:
- // Constructor of the class
- ESP_NOW_Peer_Class(const uint8_t *mac_addr, uint8_t channel, wifi_interface_t iface, const uint8_t *lmk) : ESP_NOW_Peer(mac_addr, channel, iface, lmk) {}
- // Destructor of the class
- ~ESP_NOW_Peer_Class() {}
- // Function to register the master peer
- bool add_peer() {
- if (!add()) {
- log_e("Failed to register the peer");
- return false;
- }
- return true;
- }
- // Function to print the received messages from the master
- void onReceive(const uint8_t *data, size_t len, bool broadcast) {
- Serial.println("The peer received a packet");
- if (*data == ACK_PACK_TYPE) return;
- if (*data == BATTERY_PACK_TYPE) {
- Serial.println("Sending battery information to the master");
- BATTERY response = BATTERY(getCurrentBatterySOT());
- send_message((uint8_t *)&response, sizeof(BATTERY));
- }
- Serial.printf("Received a message from master " MACSTR " (%s)\n", MAC2STR(addr()), broadcast ? "broadcast" : "unicast");
- Serial.printf(" Message: %s\n", (char *)data);
- }
- // Function to send a message to the peer
- bool send_message(const uint8_t *data, size_t len) {
- if (!send(data, len)) {
- log_e("Failed to send message to peer %s", MAC2STR(addr()));
- return false;
- }
- return true;
- }
- };
- class ESP_NOW_Slave_Class : public ESP_NOW_Peer {
- public:
- bool isAlive = true;
- int battery = 0;
- // Constructor of the class
- ESP_NOW_Slave_Class(const uint8_t *mac_addr, uint8_t channel, wifi_interface_t iface, const uint8_t *lmk) : ESP_NOW_Peer(mac_addr, channel, iface, lmk) {}
- // Destructor of the class
- ~ESP_NOW_Slave_Class() {}
- // Function to register the master peer
- bool add_peer() {
- if (!add()) {
- log_e("Failed to register the peer");
- return false;
- }
- return true;
- }
- // Function to print the received messages from the master
- void onReceive(const uint8_t *data, size_t len, bool broadcast) {
- isAlive = true;
- //Serial.printf("Received message from: (%s), data*: %d\n", MAC2STR(addr()), *data);
- if (*data == ACK_PACK_TYPE) return;
- if (*data == BATTERY_PACK_TYPE) {
- BATTERY *packet = (BATTERY *) data;
- battery = packet->batt;
- }
- }
- void onSent(bool success) {
- isAlive = success;
- Serial.printf("onSent(), %d\n\n", isAlive);
- }
- bool deinitialise() {
- Serial.printf("I'm removing the peer\n");
- return remove();
- }
- // Function to send a message to the peer
- bool send_message(const uint8_t *data, size_t len) {
- if (!send(data, len)) {
- log_e("Failed to broadcast message");
- return false;
- }
- return true;
- }
- };
- // Create a broadcast peer object
- ESP_NOW_Broadcast_Peer broadcast_peer(ESPNOW_WIFI_CHANNEL, WIFI_IF_STA, NULL);
- std::vector<ESP_NOW_Slave_Class> devices;
- ESP_NOW_Peer_Class* master = NULL;
- // Callback called when an unknown peer sends a message
- void register_new_master(const esp_now_recv_info_t *info, const uint8_t *data, int len, void *arg) {
- if (memcmp(info->des_addr, ESP_NOW.BROADCAST_ADDR, 6) == 0) {
- Serial.printf("Unknown peer " MACSTR " sent a broadcast message\n", MAC2STR(info->src_addr));
- if (*data == ACK_PACK_TYPE && !inGroup) {
- inGroup = true;
- Serial.println("Registering the peer as a master");
- master = new ESP_NOW_Peer_Class(info->src_addr, ESPNOW_WIFI_CHANNEL, WIFI_IF_STA, NULL);
- if (!master->add_peer()) {
- Serial.println("Failed to register the new master");
- return;
- }
- OK_PACK okPack = OK_PACK();
- master->send_message((uint8_t *)&okPack, sizeof(OK_PACK));
- }
- } else {
- if (isMaster) {
- log_v("Received a unicast message from " MACSTR, MAC2STR(info->src_addr));
- Serial.printf("%d\n", *data);
- if (*data == OK_PACK_TYPE) {
- ESP_NOW_Slave_Class new_device(info->src_addr, ESPNOW_WIFI_CHANNEL, WIFI_IF_STA, NULL);
- devices.push_back(new_device);
- if(!devices.back().add_peer()){
- Serial.println("\n\nFailed to add the new peer to the device list\n\n");
- }
- }
- } else {
- // The slave will only receive broadcast messages
- log_v("Received a unicast message from " MACSTR, MAC2STR(info->src_addr));
- log_v("Igorning the message");
- }
- }
- }
- NimBLEServer* pServer = NULL;
- NimBLEService *serviceBattery = NULL;
- NimBLECharacteristic *batteryLevelChar = NULL;
- #define SERVICE_BATTERY_UUID "180f" //batteria
- #define BATTERY_LEVEL_CHARACTERISTIC_UUID "492c2d04-f173-4814-9630-e12aedc4f7f6"
- //livello batteria tutti i sensori, 1byte per sensore, max 10 sensori, se sensore non connesso: 0xFF
- class ServerCallbacks: public NimBLEServerCallbacks {
- void onConnect(NimBLEServer* pServer) {
- Serial.println("Device connected");
- connectedBLE = true;
- };
- void onDisconnect(NimBLEServer* pServer) {
- Serial.println("Device disconnected");
- connectedBLE = false;
- //resart the advertising
- BLEDevice::startAdvertising();
- }
- };
- void initBLE() {
- NimBLEDevice::init("B_Rainbow");
- pServer = NimBLEDevice::createServer();
- pServer->setCallbacks(new ServerCallbacks());
- serviceBattery = pServer->createService(SERVICE_BATTERY_UUID);
- batteryLevelChar = serviceBattery->createCharacteristic(
- BATTERY_LEVEL_CHARACTERISTIC_UUID,
- NIMBLE_PROPERTY::NOTIFY | NIMBLE_PROPERTY::READ
- );
- serviceBattery->start();
- BLEAdvertising *pAdvertising = NimBLEDevice::getAdvertising();
- pAdvertising->addServiceUUID(SERVICE_BATTERY_UUID);
- // pAdvertising->setScanResponse(true);
- pAdvertising->setPreferredParams(0x06, 0x12);
- NimBLEDevice::startAdvertising();
- Serial.println("Finished BLE init");
- }
- void updateBLEData() {
- uint8_t *data = (uint8_t*) malloc(devices.size() + 1);
- data[0] = devices.size()+1;
- for (int i = 0; i < devices.size(); i++) {
- data[i] = devices[i].battery;
- }
- batteryLevelChar->setValue(data, devices.size()+1);
- batteryLevelChar->notify();
- free(data);
- data = NULL;
- }
- /* Main */
- void setup() {
- Serial.begin(115200);
- // Initialize the Wi-Fi module
- WiFi.mode(WIFI_STA);
- WiFi.setChannel(ESPNOW_WIFI_CHANNEL);
- while (!WiFi.STA.started()) {
- delay(100);
- }
- // Register the broadcast peer
- if (!broadcast_peer.begin()) {
- Serial.println("Failed to initialize broadcast peer");
- Serial.println("Reebooting in 5 seconds...");
- delay(5000);
- ESP.restart();
- }
- ESP_NOW.onNewPeer(register_new_master, NULL);
- startupTime = millis();
- }
- void loop() {
- // Broadcast a message to all devices within the network
- if (!inGroup && startupTime + 3000 < millis() && !isMaster) {
- //diventa il master
- isMaster = true;
- Serial.println("\n\n\nIM THE MASTER \n\n\n");
- initBLE();
- }
- if (isMaster && lastACKSent + 1000 < millis()) {
- ACK pack = ACK();
- broadcast_peer.send_message((uint8_t *)&pack, sizeof(ACK));
- lastACKSent = millis();
- }
- if (isMaster && lastBatteryCheckSent + 2000 < millis()) {
- BATTERY pack = BATTERY(255);
- for (int i = devices.size() - 1; i >= 0; i--) {
- devices[i].send_message((uint8_t *)&pack, sizeof(BATTERY));
- }
- lastBatteryCheckSent = millis();
- }
- if (isMaster && lastAliveCheck + 1000 < millis()) {
- for (int i = devices.size() - 1; i >= 0; i--) {
- if (!devices[i].isAlive) {
- devices[i].deinitialise();
- devices.erase(devices.begin() + i);
- }
- }
- lastAliveCheck = millis();
- }
- delay(100);
- }
Master's Logs
- ============ Before Setup End ============
- [ 484][I][esp32-hal-periman.c:141] perimanSetPinBus(): Pin 18 already has type USB_DM (38) with bus 0x3fc98ed0
- [ 485][I][esp32-hal-periman.c:141] perimanSetPinBus(): Pin 19 already has type USB_DP (39) with bus 0x3fc98ed0
- I NimBLEDevice: BLE Host Task Started
- I NimBLEDevice: NimBle host synced.
- D NimBLEService: >> start(): Starting service: UUID: 0x180f, handle: 0x0000
- D NimBLEService: Adding 1 characteristics for service UUID: 0x180f, handle: 0x0000
- D NimBLEService: << start()
- Finished BLE init
- [ 577][V][NetworkEvents.cpp:113] _checkForEvent(): Network Event: 101 - WIFI_READY
- [ 581][V][STA.cpp:186] _onStaEvent(): STA Started
- [ 581][V][NetworkEvents.cpp:113] _checkForEvent(): Network Event: 110 - STA_START
- [ 582][V][STA.cpp:110] _onStaArduinoEvent(): Arduino STA Event: 110 - STA_START
- [ 584][V][ESP32_NOW.cpp:18] _esp_now_add_peer(): ff:ff:ff:ff:ff:ff
- [ 585][V][ESP32_NOW.cpp:311] add(): Peer added - ff:ff:ff:ff:ff:ff
- =========== After Setup Start ============
- IM THE MASTER
- D NimBLEAdvertising: >> Advertising start: duration=0, dirAddr=NULL
- primary service
- uuid 0x1800
- handle 1
- end_handle 5
- characteristic
- uuid 0x2a00
- def_handle 2
- val_handle 3
- min_key_size 0
- flags [READ]
- characteristic
- uuid 0x2a01
- def_handle 4
- val_handle 5
- min_key_size 0
- flags [READ]
- primary service
- uuid 0x1801
- handle 6
- end_handle 13
- characteristic
- uuid 0x2a05
- def_handle 7
- val_handle 8
- min_key_size 0
- flags [INDICATE]
- ccc descriptor
- uuid 0x2902
- handle 9
- min_key_size 0
- flags [READ|WRITE]
- characteristic
- uuid 0x2b3a
- def_handle 10
- val_handle 11
- min_key_size 0
- flags [READ]
- characteristic
- uuid 0x2b29
- def_handle 12
- val_handle 13
- min_key_size 0
- flags [READ|WRITE]
- primary service
- uuid 0x180f
- handle 14
- end_handle 17
- characteristic
- uuid 492c2d04-f173-4814-9630-e12aedc4f7f6
- def_handle 15
- val_handle 16
- min_key_size 0
- flags [READ|NOTIFY]
- ccc descriptor
- uuid 0x2902
- handle 17
- min_key_size 0
- flags [READ|WRITE]
- D NimBLEAdvertising: setAdvertisementData: 02 01 06 03 03 0f 18 05 12 06 00 12 00
- D NimBLEAdvertising: << Advertising start
- Started Advertising
- [ 3727][V][ESP32_NOW.cpp:384] send(): ff:ff:ff:ff:ff:ff, data length 1
- [ 3829][V][ESP32_NOW.cpp:133] _esp_now_tx_cb(): ff:ff:ff:ff:ff:ff : SUCCESS
- [ 3830][I][ESP32_NOW.h:78] onSent(): Message transmission to peer ff:ff:ff:ff:ff:ff successful
- .....
Slave's Logs
- 00:00:27.572 ============ Before Setup End ============
- 00:00:27.676 [ 2279][I][esp32-hal-periman.c:141] perimanSetPinBus(): Pin 18 already has type USB_DM (38) with bus 0x3fc98ed0
- 00:00:27.676 [ 2280][I][esp32-hal-periman.c:141] perimanSetPinBus(): Pin 19 already has type USB_DP (39) with bus 0x3fc98ed0
- 00:00:27.725 I NimBLEDevice: BLE Host Task Started
- 00:00:27.728 I NimBLEDevice: NimBle host synced.
- 00:00:27.730 D NimBLEService: >> start(): Starting service: UUID: 0x180f, handle: 0x0000
- 00:00:27.735 D NimBLEService: Adding 1 characteristics for service UUID: 0x180f, handle: 0x0000
- 00:00:27.737 D NimBLEService: << start()
- 00:00:27.739 Finished BLE init
- 00:00:27.749 [ 2352][V][NetworkEvents.cpp:113] _checkForEvent(): Network Event: 101 - WIFI_READY
- 00:00:27.749 [ 2356][V][STA.cpp:186] _onStaEvent(): STA Started
- 00:00:27.750 [ 2356][V][NetworkEvents.cpp:113] _checkForEvent(): Network Event: 110 - STA_START
- 00:00:27.750 [ 2357][V][STA.cpp:110] _onStaArduinoEvent(): Arduino STA Event: 110 - STA_START
- 00:00:27.753 [ 2359][V][ESP32_NOW.cpp:18] _esp_now_add_peer(): ff:ff:ff:ff:ff:ff
- 00:00:27.754 [ 2359][V][ESP32_NOW.cpp:311] add(): Peer added - ff:ff:ff:ff:ff:ff
- 00:00:27.754 =========== After Setup Start ============
- 00:00:27.754 INTERNAL Memory Info:
- 00:00:27.755 ------------------------------------------
- 00:00:27.755 Total Size : 272580 B ( 266.2 KB)
- 00:00:27.755 Free Bytes : 131276 B ( 128.2 KB)
- 00:00:27.755 Allocated Bytes : 133592 B ( 130.5 KB)
- 00:00:27.755 Minimum Free Bytes: 131172 B ( 128.1 KB)
- 00:00:27.755 Largest Free Block: 110580 B ( 108.0 KB)
- 00:00:27.755 ------------------------------------------
- 00:00:27.755 GPIO Info:
- 00:00:27.755 ------------------------------------------
- 00:00:27.755 GPIO : BUS_TYPE[bus/unit][chan]
- 00:00:27.755 --------------------------------------
- 00:00:27.755 18 : USB_DM
- 00:00:27.755 19 : USB_DP
- 00:00:27.755 20 : UART_RX[0]
- 00:00:27.756 21 : UART_TX[0]
- 00:00:27.756 ============ After Setup End =============
- 00:00:28.247 [ 2850][V][ESP32_NOW.cpp:112] _esp_now_rx_cb(): Broadcast from d8:3b:da:e3:1c:cc, data length : 1
- 00:00:28.248 0x00, // .
- 00:00:28.248 [ 2850][V][ESP32_NOW.cpp:115] _esp_now_rx_cb(): Calling new_cb, peer not found.
- 00:00:28.248 Unknown peer d8:3b:da:e3:1c:cc sent a broadcast message
- 00:00:28.248 Registering the peer as a master
- 00:00:28.248 [ 2853][V][ESP32_NOW.cpp:18] _esp_now_add_peer(): d8:3b:da:e3:1c:cc
- 00:00:28.248 [ 2856][V][ESP32_NOW.cpp:311] add(): Peer added - d8:3b:da:e3:1c:cc
- 00:00:28.248 [ 2856][V][ESP32_NOW.cpp:384] send(): d8:3b:da:e3:1c:cc, data length 1
- 00:00:28.288 [ 2894][V][ESP32_NOW.cpp:133] _esp_now_tx_cb(): d8:3b:da:e3:1c:cc : FAILED
- 00:00:28.289 [ 2895][I][ESP32_NOW.h:78] onSent(): Message transmission to peer d8:3b:da:e3:1c:cc failed
- 00:00:29.245 [ 3850][V][ESP32_NOW.cpp:112] _esp_now_rx_cb(): Broadcast from d8:3b:da:e3:1c:cc, data length : 1
- 00:00:29.245 0x00, // .
- 00:00:29.245 [ 3851][V][ESP32_NOW.cpp:122] _esp_now_rx_cb(): Checking peer ff:ff:ff:ff:ff:ff
- 00:00:29.246 [ 3851][V][ESP32_NOW.cpp:122] _esp_now_rx_cb(): Checking peer d8:3b:da:e3:1c:cc
- 00:00:29.246 [ 3851][V][ESP32_NOW.cpp:125] _esp_now_rx_cb(): Calling onReceive
- 00:00:29.246 The peer received a packet
- 00:00:30.345 [ 4950][V][ESP32_NOW.cpp:112] _esp_now_rx_cb(): Broadcast from d8:3b:da:e3:1c:cc, data length : 1
- 00:00:30.346 0x00, // .
- 00:00:30.346 [ 4951][V][ESP32_NOW.cpp:122] _esp_now_rx_cb(): Checking peer ff:ff:ff:ff:ff:ff
- 00:00:30.346 [ 4951][V][ESP32_NOW.cpp:122] _esp_now_rx_cb(): Checking peer d8:3b:da:e3:1c:cc
- 00:00:30.346 [ 4952][V][ESP32_NOW.cpp:125] _esp_now_rx_cb(): Calling onReceive
- 00:00:30.346 The peer received a packet