ESP32-C3 not receiving data with ESP-NOW after initialising NimBLE

GabrieleCano
Posts: 1
Joined: Tue Jan 28, 2025 11:20 am

ESP32-C3 not receiving data with ESP-NOW after initialising NimBLE

Postby GabrieleCano » 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
  1. #include <NimBLEDevice.h>
  2. #include "ESP32_NOW.h"
  3. #include "WiFi.h"
  4. #include "structs.cpp"
  5.  
  6. #include <esp_mac.h>  // For the MAC2STR and MACSTR macros
  7.  
  8. /* Definitions */
  9.  
  10. #define ESPNOW_WIFI_CHANNEL 6
  11. #define BATTERY_PIN 3
  12.  
  13.  
  14. /* Global Variables */
  15.  
  16. uint32_t msg_count = 0;
  17. bool inGroup = false;
  18. bool isMaster = false;
  19. long startupTime, lastBatteryCheckSent, lastACKSent, lastAliveCheck;
  20. bool connectedBLE = false;
  21.  
  22.  
  23. /* Functions */
  24.  
  25. int getCurrentBatterySOT() {
  26.   int batteria = map(analogReadMilliVolts(BATTERY_PIN) * 2, 3150, 4150, 0, 100);
  27.   batteria = max(1, min(batteria, 100));
  28.   return batteria;
  29. }
  30.  
  31. /* Classes */
  32.  
  33. // Creating a new class that inherits from the ESP_NOW_Peer class is required.
  34. class ESP_NOW_Broadcast_Peer : public ESP_NOW_Peer {
  35. public:
  36.   // Constructor of the class using the broadcast address
  37.   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) {}
  38.  
  39.   // Destructor of the class
  40.   ~ESP_NOW_Broadcast_Peer() {
  41.     remove();
  42.   }
  43.  
  44.   // Function to properly initialize the ESP-NOW and register the broadcast peer
  45.   bool begin() {
  46.     if (!ESP_NOW.begin() || !add()) {
  47.       log_e("Failed to initialize ESP-NOW or register the broadcast peer");
  48.       return false;
  49.     }
  50.     return true;
  51.   }
  52.  
  53.   // Function to send a message to all devices within the network
  54.   bool send_message(const uint8_t *data, size_t len) {
  55.     if (!send(data, len)) {
  56.       log_e("Failed to broadcast message");
  57.       return false;
  58.     }
  59.     return true;
  60.   }
  61. };
  62.  
  63. class ESP_NOW_Peer_Class : public ESP_NOW_Peer {
  64. public:
  65.   // Constructor of the class
  66.   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) {}
  67.  
  68.   // Destructor of the class
  69.   ~ESP_NOW_Peer_Class() {}
  70.  
  71.   // Function to register the master peer
  72.   bool add_peer() {
  73.     if (!add()) {
  74.       log_e("Failed to register the peer");
  75.       return false;
  76.     }
  77.     return true;
  78.   }
  79.  
  80.   // Function to print the received messages from the master
  81.   void onReceive(const uint8_t *data, size_t len, bool broadcast) {
  82.     Serial.println("The peer received a packet");
  83.     if (*data == ACK_PACK_TYPE) return;
  84.     if (*data == BATTERY_PACK_TYPE) {
  85.       Serial.println("Sending battery information to the master");
  86.       BATTERY response = BATTERY(getCurrentBatterySOT());
  87.       send_message((uint8_t *)&response, sizeof(BATTERY));
  88.     }
  89.     Serial.printf("Received a message from master " MACSTR " (%s)\n", MAC2STR(addr()), broadcast ? "broadcast" : "unicast");
  90.     Serial.printf("  Message: %s\n", (char *)data);
  91.   }
  92.  
  93.     // Function to send a message to the peer
  94.   bool send_message(const uint8_t *data, size_t len) {
  95.     if (!send(data, len)) {
  96.       log_e("Failed to send message to peer %s", MAC2STR(addr()));
  97.       return false;
  98.     }
  99.     return true;
  100.   }
  101. };
  102.  
  103.  
  104. class ESP_NOW_Slave_Class : public ESP_NOW_Peer {
  105. public:
  106.   bool isAlive = true;
  107.   int battery = 0;
  108.   // Constructor of the class
  109.   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) {}
  110.  
  111.   // Destructor of the class
  112.   ~ESP_NOW_Slave_Class() {}
  113.  
  114.   // Function to register the master peer
  115.   bool add_peer() {
  116.     if (!add()) {
  117.       log_e("Failed to register the peer");
  118.       return false;
  119.     }
  120.     return true;
  121.   }
  122.  
  123.   // Function to print the received messages from the master
  124.   void onReceive(const uint8_t *data, size_t len, bool broadcast) {
  125.     isAlive = true;
  126.     //Serial.printf("Received message from: (%s), data*: %d\n", MAC2STR(addr()), *data);
  127.     if (*data == ACK_PACK_TYPE) return;
  128.     if (*data == BATTERY_PACK_TYPE) {
  129.       BATTERY *packet = (BATTERY *) data;
  130.       battery = packet->batt;
  131.     }
  132.   }
  133.  
  134.   void onSent(bool success) {
  135.     isAlive = success;
  136.     Serial.printf("onSent(), %d\n\n", isAlive);
  137.   }
  138.  
  139.   bool deinitialise() {
  140.     Serial.printf("I'm removing the peer\n");
  141.     return remove();
  142.   }
  143.  
  144.     // Function to send a message to the peer
  145.   bool send_message(const uint8_t *data, size_t len) {
  146.     if (!send(data, len)) {
  147.       log_e("Failed to broadcast message");
  148.       return false;
  149.     }
  150.     return true;
  151.   }
  152. };
  153.  
  154. // Create a broadcast peer object
  155. ESP_NOW_Broadcast_Peer broadcast_peer(ESPNOW_WIFI_CHANNEL, WIFI_IF_STA, NULL);
  156. std::vector<ESP_NOW_Slave_Class> devices;
  157. ESP_NOW_Peer_Class* master = NULL;
  158.  
  159. // Callback called when an unknown peer sends a message
  160. void register_new_master(const esp_now_recv_info_t *info, const uint8_t *data, int len, void *arg) {
  161.  
  162.   if (memcmp(info->des_addr, ESP_NOW.BROADCAST_ADDR, 6) == 0) {
  163.     Serial.printf("Unknown peer " MACSTR " sent a broadcast message\n", MAC2STR(info->src_addr));
  164.  
  165.     if (*data == ACK_PACK_TYPE && !inGroup) {
  166.       inGroup = true;
  167.       Serial.println("Registering the peer as a master");
  168.       master = new ESP_NOW_Peer_Class(info->src_addr, ESPNOW_WIFI_CHANNEL, WIFI_IF_STA, NULL);
  169.       if (!master->add_peer()) {
  170.         Serial.println("Failed to register the new master");
  171.         return;
  172.       }
  173.       OK_PACK okPack = OK_PACK();
  174.       master->send_message((uint8_t *)&okPack, sizeof(OK_PACK));
  175.     }
  176.   } else {
  177.     if (isMaster) {
  178.       log_v("Received a unicast message from " MACSTR, MAC2STR(info->src_addr));
  179.       Serial.printf("%d\n", *data);
  180.       if (*data == OK_PACK_TYPE) {
  181.         ESP_NOW_Slave_Class new_device(info->src_addr, ESPNOW_WIFI_CHANNEL, WIFI_IF_STA, NULL);
  182.         devices.push_back(new_device);
  183.         if(!devices.back().add_peer()){
  184.           Serial.println("\n\nFailed to add the new peer to the device list\n\n");
  185.         }
  186.       }
  187.     } else {
  188.       // The slave will only receive broadcast messages
  189.       log_v("Received a unicast message from " MACSTR, MAC2STR(info->src_addr));
  190.       log_v("Igorning the message");
  191.     }
  192.   }
  193. }
  194.  
  195.  
  196.  
  197. NimBLEServer* pServer = NULL;
  198. NimBLEService *serviceBattery = NULL;
  199. NimBLECharacteristic *batteryLevelChar = NULL;
  200.  
  201.  
  202. #define SERVICE_BATTERY_UUID "180f"                                                           //batteria
  203. #define BATTERY_LEVEL_CHARACTERISTIC_UUID "492c2d04-f173-4814-9630-e12aedc4f7f6"              
  204. //livello batteria tutti i sensori, 1byte per sensore, max 10 sensori, se sensore non connesso: 0xFF
  205.  
  206.  
  207. class ServerCallbacks: public NimBLEServerCallbacks {
  208.   void onConnect(NimBLEServer* pServer) {
  209.     Serial.println("Device connected");
  210.     connectedBLE = true;
  211.   };
  212.  
  213.   void onDisconnect(NimBLEServer* pServer) {
  214.     Serial.println("Device disconnected");
  215.     connectedBLE = false;
  216.     //resart the advertising
  217.     BLEDevice::startAdvertising();
  218.   }
  219. };
  220.  
  221.  
  222. void initBLE() {
  223.   NimBLEDevice::init("B_Rainbow");
  224.   pServer = NimBLEDevice::createServer();
  225.   pServer->setCallbacks(new ServerCallbacks());
  226.  
  227.   serviceBattery = pServer->createService(SERVICE_BATTERY_UUID);
  228.  
  229.   batteryLevelChar = serviceBattery->createCharacteristic(
  230.     BATTERY_LEVEL_CHARACTERISTIC_UUID,
  231.      NIMBLE_PROPERTY::NOTIFY | NIMBLE_PROPERTY::READ
  232.   );
  233.  
  234.   serviceBattery->start();
  235.  
  236.   BLEAdvertising *pAdvertising = NimBLEDevice::getAdvertising();
  237.   pAdvertising->addServiceUUID(SERVICE_BATTERY_UUID);
  238. //  pAdvertising->setScanResponse(true);
  239.   pAdvertising->setPreferredParams(0x06, 0x12);
  240.   NimBLEDevice::startAdvertising();
  241.  
  242.   Serial.println("Finished BLE init");
  243. }
  244.  
  245.  
  246.  
  247. void updateBLEData() {
  248.   uint8_t *data = (uint8_t*) malloc(devices.size() + 1);
  249.   data[0] = devices.size()+1;
  250.   for (int i = 0; i < devices.size(); i++) {
  251.     data[i] = devices[i].battery;
  252.   }
  253.   batteryLevelChar->setValue(data, devices.size()+1);
  254.   batteryLevelChar->notify();
  255.   free(data);
  256.   data = NULL;
  257. }
  258.  
  259. /* Main */
  260.  
  261. void setup() {
  262.   Serial.begin(115200);
  263.  
  264.   // Initialize the Wi-Fi module
  265.   WiFi.mode(WIFI_STA);
  266.   WiFi.setChannel(ESPNOW_WIFI_CHANNEL);
  267.   while (!WiFi.STA.started()) {
  268.     delay(100);
  269.   }
  270.  
  271.   // Register the broadcast peer
  272.   if (!broadcast_peer.begin()) {
  273.     Serial.println("Failed to initialize broadcast peer");
  274.     Serial.println("Reebooting in 5 seconds...");
  275.     delay(5000);
  276.     ESP.restart();
  277.   }
  278.  
  279.   ESP_NOW.onNewPeer(register_new_master, NULL);
  280.  
  281.   startupTime = millis();
  282. }
  283.  
  284. void loop() {
  285.   // Broadcast a message to all devices within the network
  286.  
  287.   if (!inGroup && startupTime + 3000 < millis() && !isMaster) {
  288.     //diventa il master
  289.     isMaster = true;
  290.     Serial.println("\n\n\nIM THE MASTER \n\n\n");
  291.     initBLE();
  292.   }
  293.  
  294.  
  295.   if (isMaster && lastACKSent + 1000 < millis()) {
  296.     ACK pack = ACK();
  297.     broadcast_peer.send_message((uint8_t *)&pack, sizeof(ACK));
  298.     lastACKSent = millis();
  299.   }
  300.  
  301.   if (isMaster && lastBatteryCheckSent + 2000 < millis()) {
  302.     BATTERY pack = BATTERY(255);
  303.     for (int i = devices.size() - 1; i >= 0; i--) {
  304.       devices[i].send_message((uint8_t *)&pack, sizeof(BATTERY));
  305.     }
  306.     lastBatteryCheckSent = millis();
  307.   }
  308.  
  309.  
  310.   if (isMaster && lastAliveCheck + 1000 < millis()) {
  311.     for (int i = devices.size() - 1; i >= 0; i--) {
  312.       if (!devices[i].isAlive) {
  313.         devices[i].deinitialise();
  314.         devices.erase(devices.begin() + i);
  315.       }
  316.     }
  317.     lastAliveCheck = millis();
  318.   }
  319.  
  320.   delay(100);
  321. }



Master's Logs
  1. ============ Before Setup End ============
  2. [   484][I][esp32-hal-periman.c:141] perimanSetPinBus(): Pin 18 already has type USB_DM (38) with bus 0x3fc98ed0
  3. [   485][I][esp32-hal-periman.c:141] perimanSetPinBus(): Pin 19 already has type USB_DP (39) with bus 0x3fc98ed0
  4. I NimBLEDevice: BLE Host Task Started
  5. I NimBLEDevice: NimBle host synced.
  6. D NimBLEService: >> start(): Starting service: UUID: 0x180f, handle: 0x0000
  7. D NimBLEService: Adding 1 characteristics for service UUID: 0x180f, handle: 0x0000
  8. D NimBLEService: << start()
  9. Finished BLE init
  10. [   577][V][NetworkEvents.cpp:113] _checkForEvent(): Network Event: 101 - WIFI_READY
  11. [   581][V][STA.cpp:186] _onStaEvent(): STA Started
  12. [   581][V][NetworkEvents.cpp:113] _checkForEvent(): Network Event: 110 - STA_START
  13. [   582][V][STA.cpp:110] _onStaArduinoEvent(): Arduino STA Event: 110 - STA_START
  14. [   584][V][ESP32_NOW.cpp:18] _esp_now_add_peer(): ff:ff:ff:ff:ff:ff
  15. [   585][V][ESP32_NOW.cpp:311] add(): Peer added - ff:ff:ff:ff:ff:ff
  16. =========== After Setup Start ============
  17.  
  18.  
  19. IM THE MASTER
  20. D NimBLEAdvertising: >> Advertising start: duration=0, dirAddr=NULL
  21. primary service
  22.            uuid 0x1800
  23.          handle 1
  24.      end_handle 5
  25. characteristic
  26.            uuid 0x2a00
  27.      def_handle 2
  28.      val_handle 3
  29.    min_key_size 0
  30.           flags [READ]
  31. characteristic
  32.            uuid 0x2a01
  33.      def_handle 4
  34.      val_handle 5
  35.    min_key_size 0
  36.           flags [READ]
  37. primary service
  38.            uuid 0x1801
  39.          handle 6
  40.      end_handle 13
  41. characteristic
  42.            uuid 0x2a05
  43.      def_handle 7
  44.      val_handle 8
  45.    min_key_size 0
  46.           flags [INDICATE]
  47. ccc descriptor
  48.            uuid 0x2902
  49.          handle 9
  50.    min_key_size 0
  51.           flags [READ|WRITE]
  52. characteristic
  53.            uuid 0x2b3a
  54.      def_handle 10
  55.      val_handle 11
  56.    min_key_size 0
  57.           flags [READ]
  58. characteristic
  59.            uuid 0x2b29
  60.      def_handle 12
  61.      val_handle 13
  62.    min_key_size 0
  63.           flags [READ|WRITE]
  64. primary service
  65.            uuid 0x180f
  66.          handle 14
  67.      end_handle 17
  68. characteristic
  69.            uuid 492c2d04-f173-4814-9630-e12aedc4f7f6
  70.      def_handle 15
  71.      val_handle 16
  72.    min_key_size 0
  73.           flags [READ|NOTIFY]
  74. ccc descriptor
  75.            uuid 0x2902
  76.          handle 17
  77.    min_key_size 0
  78.           flags [READ|WRITE]
  79. D NimBLEAdvertising: setAdvertisementData: 02 01 06 03 03 0f 18 05 12 06 00 12 00
  80. D NimBLEAdvertising: << Advertising start
  81. Started Advertising
  82.  
  83.  
  84. [  3727][V][ESP32_NOW.cpp:384] send(): ff:ff:ff:ff:ff:ff, data length 1
  85. [  3829][V][ESP32_NOW.cpp:133] _esp_now_tx_cb(): ff:ff:ff:ff:ff:ff : SUCCESS
  86. [  3830][I][ESP32_NOW.h:78] onSent(): Message transmission to peer ff:ff:ff:ff:ff:ff successful
  87. .....
  88.  

Slave's Logs
  1. 00:00:27.572 ============ Before Setup End ============
  2. 00:00:27.676 [  2279][I][esp32-hal-periman.c:141] perimanSetPinBus(): Pin 18 already has type USB_DM (38) with bus 0x3fc98ed0
  3. 00:00:27.676 [  2280][I][esp32-hal-periman.c:141] perimanSetPinBus(): Pin 19 already has type USB_DP (39) with bus 0x3fc98ed0
  4. 00:00:27.725 I NimBLEDevice: BLE Host Task Started
  5. 00:00:27.728 I NimBLEDevice: NimBle host synced.
  6. 00:00:27.730 D NimBLEService: >> start(): Starting service: UUID: 0x180f, handle: 0x0000
  7. 00:00:27.735 D NimBLEService: Adding 1 characteristics for service UUID: 0x180f, handle: 0x0000
  8. 00:00:27.737 D NimBLEService: << start()
  9. 00:00:27.739 Finished BLE init
  10. 00:00:27.749 [  2352][V][NetworkEvents.cpp:113] _checkForEvent(): Network Event: 101 - WIFI_READY
  11. 00:00:27.749 [  2356][V][STA.cpp:186] _onStaEvent(): STA Started
  12. 00:00:27.750 [  2356][V][NetworkEvents.cpp:113] _checkForEvent(): Network Event: 110 - STA_START
  13. 00:00:27.750 [  2357][V][STA.cpp:110] _onStaArduinoEvent(): Arduino STA Event: 110 - STA_START
  14. 00:00:27.753 [  2359][V][ESP32_NOW.cpp:18] _esp_now_add_peer(): ff:ff:ff:ff:ff:ff
  15. 00:00:27.754 [  2359][V][ESP32_NOW.cpp:311] add(): Peer added - ff:ff:ff:ff:ff:ff
  16. 00:00:27.754 =========== After Setup Start ============
  17. 00:00:27.754 INTERNAL Memory Info:
  18. 00:00:27.755 ------------------------------------------
  19. 00:00:27.755   Total Size        :   272580 B ( 266.2 KB)
  20. 00:00:27.755   Free Bytes        :   131276 B ( 128.2 KB)
  21. 00:00:27.755   Allocated Bytes   :   133592 B ( 130.5 KB)
  22. 00:00:27.755   Minimum Free Bytes:   131172 B ( 128.1 KB)
  23. 00:00:27.755   Largest Free Block:   110580 B ( 108.0 KB)
  24. 00:00:27.755 ------------------------------------------
  25. 00:00:27.755 GPIO Info:
  26. 00:00:27.755 ------------------------------------------
  27. 00:00:27.755   GPIO : BUS_TYPE[bus/unit][chan]
  28. 00:00:27.755   --------------------------------------  
  29. 00:00:27.755     18 : USB_DM
  30. 00:00:27.755     19 : USB_DP
  31. 00:00:27.755     20 : UART_RX[0]
  32. 00:00:27.756     21 : UART_TX[0]
  33. 00:00:27.756 ============ After Setup End =============
  34. 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
  35. 00:00:28.248 0x00, // .
  36. 00:00:28.248 [  2850][V][ESP32_NOW.cpp:115] _esp_now_rx_cb(): Calling new_cb, peer not found.
  37. 00:00:28.248 Unknown peer d8:3b:da:e3:1c:cc sent a broadcast message
  38. 00:00:28.248 Registering the peer as a master
  39. 00:00:28.248 [  2853][V][ESP32_NOW.cpp:18] _esp_now_add_peer(): d8:3b:da:e3:1c:cc
  40. 00:00:28.248 [  2856][V][ESP32_NOW.cpp:311] add(): Peer added - d8:3b:da:e3:1c:cc
  41. 00:00:28.248 [  2856][V][ESP32_NOW.cpp:384] send(): d8:3b:da:e3:1c:cc, data length 1
  42. 00:00:28.288 [  2894][V][ESP32_NOW.cpp:133] _esp_now_tx_cb(): d8:3b:da:e3:1c:cc : FAILED
  43. 00:00:28.289 [  2895][I][ESP32_NOW.h:78] onSent(): Message transmission to peer d8:3b:da:e3:1c:cc failed
  44. 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
  45. 00:00:29.245 0x00, // .
  46. 00:00:29.245 [  3851][V][ESP32_NOW.cpp:122] _esp_now_rx_cb(): Checking peer ff:ff:ff:ff:ff:ff
  47. 00:00:29.246 [  3851][V][ESP32_NOW.cpp:122] _esp_now_rx_cb(): Checking peer d8:3b:da:e3:1c:cc
  48. 00:00:29.246 [  3851][V][ESP32_NOW.cpp:125] _esp_now_rx_cb(): Calling onReceive
  49. 00:00:29.246 The peer received a packet
  50. 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
  51. 00:00:30.346 0x00, // .
  52. 00:00:30.346 [  4951][V][ESP32_NOW.cpp:122] _esp_now_rx_cb(): Checking peer ff:ff:ff:ff:ff:ff
  53. 00:00:30.346 [  4951][V][ESP32_NOW.cpp:122] _esp_now_rx_cb(): Checking peer d8:3b:da:e3:1c:cc
  54. 00:00:30.346 [  4952][V][ESP32_NOW.cpp:125] _esp_now_rx_cb(): Calling onReceive
  55. 00:00:30.346 The peer received a packet
  56.  
  57.  

ahsrabrifat
Posts: 23
Joined: Sat Jan 18, 2025 2:31 pm

Re: ESP32-C3 not receiving data with ESP-NOW after initialising NimBLE

Postby ahsrabrifat » Thu Jan 30, 2025 9:47 am

That are not much info about the conflict between these two protocols. Anyway, you can check these threads.

http://esp32.io/viewtopic.php?t=38709

https://esp32.com/viewtopic.php?t=23406

Who is online

Users browsing this forum: jblazeg and 50 guests