Trouble connecting to specific BLE address

I have a code that reads the power from my cycling power meter and changes the color of some LED lights accordingly. It connects to the device by matching the ServiceUUID and Characteristic UUID. The problem is that I have 4 devices in my garage that all have the same UUIDs as my target device, so it often connects to the wrong one. The code works just fine when connected to the right device. How do I get it to connect to my device with the BLE address?

class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks {
    /**
        Called for each advertising BLE server.
    */
    void onResult(BLEAdvertisedDevice advertisedDevice) {
      Serial.print("BLE Advertised Device found: ");
      Serial.println(advertisedDevice.toString().c_str());

      // We have found a device, let us now see if it contains the service we are looking for.
      if (advertisedDevice.haveServiceUUID() && advertisedDevice.isAdvertisingService(serviceUUID)) {

        BLEDevice::getScan()->stop();                   // stop scanning when device is found
        myDevice = new BLEAdvertisedDevice(advertisedDevice);
        doConnect = true;
        doScan = true;

      } // Found our server
    } // onResult
}; // MyAdvertisedDeviceCallbacks

This section of code is where it checks the UUIDs. I have tried pasting in the following snippet instead of that if statement, but when I run the code it goes in an endless loop and never works (I did add the DEF_BLE_ADDR with the target address at the top of my code):

if( DEF_BLE_ADDR == advertisedDevice.getAddress().toString() ){

Thanks

How are the four devices different from each other? do they have different names? different addresses?

What do you see for each device when this prints out

Serial.print("BLE Advertised Device found: ");
Serial.println(advertisedDevice.toString().c_str());

They are four different power meters (three for cycling, one for running). I need it to connect to the one I use that is on my bike that I ride on the trainer. They all have different addresses, but the UUIDs are the same. When the program runs, it lists the device name and the UUID and address and seemingly connects to whichever one has the strongest signal (or whichever it finds first, not sure).

Here is what I get on the serial monitor. In this case it connected to a device called 'Tacx Flux' which is one of my power meters, but not the one I need.

19:06:31.671 -> Starting Arduino BLE Client application...
19:06:32.386 -> BLE Advertised Device found: Name: 221S001637006250, Address: e0:e2:e6:a1:20:ce, serviceUUID: 0000fef1-0000-1000-8000-00805f9b34fb, txPower: 3
19:06:32.421 -> BLE Advertised Device found: Name: , Address: 19:22:9c:13:a0:29, manufacturer data: 4c0002152686f39cbada4658854aa62e7e5e8b8d00010000c9
19:06:32.491 -> BLE Advertised Device found: Name: , Address: 65:5e:43:be:91:1f, manufacturer data: 4c001005491c15333b
19:06:32.562 -> BLE Advertised Device found: Name: , Address: 52:81:40:c6:85:41, manufacturer data: 650001c905, serviceUUID: 0000fe78-0000-1000-8000-00805f9b34fb
19:06:32.632 -> BLE Advertised Device found: Name: , Address: 57:fa:b0:70:68:3c, manufacturer data: 4c0010062a1e7ebce274, txPower: 8
19:06:32.906 -> BLE Advertised Device found: Name: , Address: 3d:89:f5:88:4a:e0, serviceUUID: 0000fd6f-0000-1000-8000-00805f9b34fb
19:06:34.259 -> BLE Advertised Device found: Name: , Address: d6:a2:43:03:f4:38, manufacturer data: 4c0012020001
19:06:34.808 -> BLE Advertised Device found: Name: , Address: 6e:3c:d6:65:bb:86, manufacturer data: 060001092002b75dd6d8d25e62dad79632e214a3fc487588b073f712d6
19:06:35.117 -> BLE Advertised Device found: Name: Tacx Flux 10881, Address: d2:44:d7:f6:2f:2f, manufacturer data: 89062900, serviceUUID: 00001826-0000-1000-8000-00805f9b34fb
19:06:35.152 -> Forming a connection to d2:44:d7:f6:2f:2f
19:06:35.152 ->  - Created client

When I look at your data I see 4 different Service UUIDs

  1. serviceUUID: 0000fef1-0000-1000-8000-00805f9b34fb
  2. serviceUUID: 0000fe78-0000-1000-8000-00805f9b34fb
  3. serviceUUID: 0000fd6f-0000-1000-8000-00805f9b34fb
  4. serviceUUID: 00001826-0000-1000-8000-00805f9b34fb

I have not seen your complete code, but it looks like you may be specifying a shortened version of the ServiceUUID.

I think you need to define the ServiceUUID in the client code as the full 128 bit (16 bytes) number of the device you want to connect.

Here is the complete code.

#include "BLEDevice.h"
#include "Arduino.h"
#include "FastLED.h"
#include <BLEScan.h>
#include <BLEAdvertisedDevice.h>

#define NUM_LEDS 150         
#define LED_PIN 4   
#define CHIPSET WS2812B
#define COLOR_ORDER GRB
CRGB led[NUM_LEDS];         

#define DEF_BLE_ADDR "eb:56:d2:fb:28:ec"
// The remote service we wish to connect to.
static BLEUUID serviceUUID("00001818-0000-1000-8000-00805f9b34fb");  //powermeter
// The characteristic of the remote service we are interested in.
static BLEUUID    charUUID("00002a63-0000-1000-8000-00805f9b34fb");  // Cycling power measurement
// 2A63: Cycling power measurement



static bool doConnect = false;
static bool connected = false;
static bool doScan = false;
static BLERemoteCharacteristic* pRemoteCharacteristic;
static BLEAdvertisedDevice* myDevice;
bool success;

static void notifyCallback(BLERemoteCharacteristic* pBLERemoteCharacteristic,
                           uint8_t* pData,
                           size_t length,
                           bool isNotify) {

  Serial.print("Power: ");
  int Power = pData[3]*256 + pData[2];              //pData[2] = instantaneous power LSB, GATT_Specification_Supplement_v5.pdf 3.59.2
                                                    // pData[3] = instantaneous power MSB, GATT_Specification_Supplement_v5.pdf 3.59.2
  Serial.print(Power);                              // prints to serial port
  Serial.println(" W");


// Determine power zone and set color
int zone;
int FTP = 331;   // FTP value as entered/measured in Zwift
int startLed = 1;  // LED 0 is used as status light (blue = connected, red = not connected) 


if (Power < 10){                                                        // LEDs off below 10 W
  zone = 0;
  for (int i = startLed; i < NUM_LEDS; i++)  {
    led[i] = CRGB(0,0,0);
  }
}
else if (Power >= 10 && Power <= FTP * 0.6) {                           // Zone 1 (Grey, Recovery): 10 W to 60% FTP
  zone = 1;
  for (int i = startLed; i < NUM_LEDS; i++)  {
    led[i] = CRGB(100,100,100);
  }
}
else if (Power > FTP * 0.60 && Power <= FTP * 0.75){                    // Zone 2 (Blue, Endurance): 60-75%
  zone = 2;
     for (int i = startLed; i < NUM_LEDS; i++)  {
    led[i] = CRGB(0,0,255);
  }
}
else if (Power > FTP * 0.75 && Power <= FTP * 0.89){                   // Zone 3 (Green, Tempo): 76-89%
  zone = 3;
for (int i = startLed; i < NUM_LEDS; i++)  {
    led[i] = CRGB(0,255,0);
  }
}
else if (Power > FTP * 0.89 && Power <= FTP * 1.04){                   // Zone 4 (Yellow, Threshold): 90-104%
  zone = 4;
  for (int i = startLed; i < NUM_LEDS; i++)  {
    led[i] = CRGB(255,255,0);
  }
}
else if (Power > FTP * 1.04 && Power <= FTP * 1.18){                   // Zone 5 (Orange, VO2 Max): 105-118%
  zone = 5;
  for (int i = startLed; i < NUM_LEDS; i++)  {
    led[i] = CRGB(255,40,0);
  }
}
else if (Power > FTP * 1.18){                                           // Zone 6 (Red, Anaerobic): above 118%
  zone = 6;
  for (int i = startLed; i < NUM_LEDS; i++)  {
    led[i] = CRGB(255,0,0);
  }
}
else{                                                                   // if not in range but this basically is not possible
  zone = 0;
  for (int i = startLed; i < NUM_LEDS; i++)  {
    led[i] = CRGB(255,0,255);
  }
  Serial.println("Error: This zone should not be possible.");
}
                       
Serial.print("zone: ");
Serial.println(zone);
FastLED.show();

delay(500);        //Delay otherwise too many updates and color changes (drives me mad!). So update every 500 ms

}

class MyClientCallback : public BLEClientCallbacks {
    void onConnect(BLEClient* pclient) {
    }

    void onDisconnect(BLEClient* pclient) {
      connected = false;
      Serial.println("onDisconnect");
    }
};

// Start connection to the BLE Server
bool connectToServer() {
  Serial.print("Forming a connection to ");
  Serial.println(myDevice->getAddress().toString().c_str());

  BLEClient*  pClient  = BLEDevice::createClient();
  Serial.println(" - Created client");

  pClient->setClientCallbacks(new MyClientCallback());

  // Connect to the remove BLE Server.
  pClient->connect(myDevice);  // if you pass BLEAdvertisedDevice instead of address, it will be recognized type of peer device address (public or private)
  Serial.println(" - Connected to server");

  // Obtain a reference to the service we are after in the remote BLE server.
  BLERemoteService* pRemoteService = pClient->getService(serviceUUID);
  if (pRemoteService == nullptr) {
    Serial.print("Failed to find our service UUID: ");
    Serial.println(serviceUUID.toString().c_str());
    pClient->disconnect();
    return false;
  }
  Serial.println(" - Found our service");


  // Obtain a reference to the characteristic in the service of the remote BLE server.
  pRemoteCharacteristic = pRemoteService->getCharacteristic(charUUID);
  if (pRemoteCharacteristic == nullptr) {
    Serial.print("Failed to find our characteristic UUID: ");
    Serial.println(charUUID.toString().c_str());
    pClient->disconnect();
    return false;
  }
  Serial.println(" - Found our characteristic");

  // Read the value of the characteristic.
  if (pRemoteCharacteristic->canRead()) {
    std::string value = pRemoteCharacteristic->readValue();
    Serial.print("The characteristic value was: ");
    Serial.println(value.c_str());
  }

  if (pRemoteCharacteristic->canNotify())
    pRemoteCharacteristic->registerForNotify(notifyCallback);

  connected = true;
  return true;
}
/**
   Scan for BLE servers and find the first one that advertises the service we are looking for.
*/
class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks {
    /**
        Called for each advertising BLE server.
    */
    void onResult(BLEAdvertisedDevice advertisedDevice) {
      Serial.print("BLE Advertised Device found: ");
      Serial.println(advertisedDevice.toString().c_str());

      // We have found a device, let us now see if it contains the service we are looking for.
      if (advertisedDevice.haveServiceUUID() && advertisedDevice.isAdvertisingService(serviceUUID)) {

        BLEDevice::getScan()->stop();                   // stop scanning when device is found
        myDevice = new BLEAdvertisedDevice(advertisedDevice);
        doConnect = true;
        doScan = true;

      } // Found our server
    } // onResult
}; // MyAdvertisedDeviceCallbacks



void setup() {
  Serial.begin(115200);
  Serial.println("Starting Arduino BLE Client application...");
  BLEDevice::init("");

  // Retrieve a Scanner and set the callback we want to use to be informed when we
  // have detected a new device.  Specify that we want active scanning and start the
  // scan to run for 5 seconds.
  BLEScan* pBLEScan = BLEDevice::getScan();
  pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
  pBLEScan->setInterval(1349);
  pBLEScan->setWindow(449);
  pBLEScan->setActiveScan(true);
  pBLEScan->start(5, false);                    //scan for 5 seconds

  // voor LEDS
  FastLED.addLeds<WS2812B, LED_PIN, GRB > (led, NUM_LEDS);      
  //FastLED.setMaxPowerInVoltsAndMilliamps(5, 500);    // maximize current
  // turn all LEDS off              
  FastLED.clear(true);  // clear all pixel data and push to strip

 
  } // End of setup.


// This is the Arduino main loop function.
void loop() {

  // If the flag "doConnect" is true then we have scanned for and found the desired
  // BLE Server with which we wish to connect.  Now we connect to it.  Once we are
  // connected we set the connected flag to be true.
  if (doConnect == true) {
    if (connectToServer()) {
      Serial.println("We are now connected to the BLE Server.");
    } else {
      Serial.println("We have failed to connect to the server; there is nothing more we will do.");
      led[0] = CRGB::Red;    // not connected, statuslight (LED 0) red
      FastLED.show();
      
    }
    doConnect = false;
  }

  // If we are connected to a peer BLE Server, update the characteristic each time we are reached
  // with the current time since boot.
  if (connected) {
    
    led[0] = CRGB(0,0,150);  //Connected, status light (LED 0) blue
    FastLED.show();

  } else if (doScan) {
    BLEDevice::getScan()->start(0);  // this is just example to start scan after disconnect, most likely there is better way to do it in arduino
  }

} // End of loop

Interesting theory, worth checking out.

@kevina654, try adding to setup():

Serial.println(serviceUUID.toString().c_str());

What does it print?

"eb:56:d2:fb:28:ec"

If you know the specific address of the server you want to connect with, the I think you should be using it in this section

/**
   Scan for BLE servers and find the first one that advertises the service we are looking for.
*/
class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks
{
    /**
        Called for each advertising BLE server.
    */
    void onResult(BLEAdvertisedDevice advertisedDevice)
    {
      Serial.print("BLE Advertised Device found: ");
      Serial.println(advertisedDevice.toString().c_str());

      if (advertisedDevice.getAddress() == "eb:56:d2:fb:28:ec")
      {

        // We have found a device, let us now see if it contains the service we are looking for.
        if (advertisedDevice.haveServiceUUID() && advertisedDevice.isAdvertisingService(serviceUUID))
        {

          BLEDevice::getScan()->stop();                   // stop scanning when device is found
          myDevice = new BLEAdvertisedDevice(advertisedDevice);
          doConnect = true;
          doScan = true;

        } // Found our service
      } //found our server address
    } // onResult
}; // MyAdvertisedDeviceCallbacks
1 Like

I pasted in this code and get this error message:

Arduino: 1.8.19 (Mac OS X), Board: "ESP32 Dev Module, Disabled, Default 4MB with spiffs (1.2MB APP/1.5MB SPIFFS), 240MHz (WiFi/BT), QIO, 80MHz, 4MB (32Mb), 921600, None"

In file included from /Users/kevinadams/Documents/Arduino/libraries/FastLED/src/FastLED.h:67:0,
                 from /Users/kevinadams/Documents/Arduino/Rockerplate_LED/Rockerplate_LED.ino:10:
/Users/kevinadams/Documents/Arduino/libraries/FastLED/src/fastspi.h:145:23: note: #pragma message: No hardware SPI pins defined.  All SPI access will default to bitbanged output
 #      pragma message "No hardware SPI pins defined.  All SPI access will default to bitbanged output"
                       ^
/Users/kevinadams/Documents/Arduino/Rockerplate_LED/Rockerplate_LED.ino: In member function 'virtual void MyAdvertisedDeviceCallbacks::onResult(BLEAdvertisedDevice)':
Rockerplate_LED:181:41: error: no match for 'operator==' (operand types are 'BLEAddress' and 'const char [18]')
       if (advertisedDevice.getAddress() == "eb:56:d2:fb:28:ec") {
                                         ^
In file included from /Users/kevinadams/Documents/Arduino/libraries/FastLED/src/controller.h:9:0,
                 from /Users/kevinadams/Documents/Arduino/libraries/FastLED/src/FastLED.h:49,
                 from /Users/kevinadams/Documents/Arduino/Rockerplate_LED/Rockerplate_LED.ino:10:
/Users/kevinadams/Documents/Arduino/libraries/FastLED/src/pixeltypes.h:749:44: note: candidate: bool operator==(const CRGB&, const CRGB&)
 inline __attribute__((always_inline)) bool operator== (const CRGB& lhs, const CRGB& rhs)
                                            ^
/Users/kevinadams/Documents/Arduino/libraries/FastLED/src/pixeltypes.h:749:44: note:   no known conversion for argument 1 from 'BLEAddress' to 'const CRGB&'
Multiple libraries were found for "BLEDevice.h"
 Used: /Users/kevinadams/Documents/Arduino/libraries/ESP32_BLE_Arduino
 Not used: /Users/kevinadams/Library/Arduino15/packages/esp32/hardware/esp32/1.0.6/libraries/BLE
exit status 1
no match for 'operator==' (operand types are 'BLEAddress' and 'const char [18]')

This compiles, so try

/**
   Scan for BLE servers and find the first one that advertises the service we are looking for.
*/
class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks {
    /**
        Called for each advertising BLE server.
    */
    void onResult(BLEAdvertisedDevice advertisedDevice) {
      Serial.print("BLE Advertised Device found: ");
      Serial.println(advertisedDevice.toString().c_str());
 // if (advertisedDevice.getAddress() == "eb:56:d2:fb:28:ec")
   //   {

      if (strcmp(advertisedDevice.getAddress().toString().c_str(), "eb:56:d2:fb:28:ec") == 0) {

        // We have found a device, let us now see if it contains the service we are looking for.
        if (advertisedDevice.haveServiceUUID() && advertisedDevice.isAdvertisingService(serviceUUID)) {

          BLEDevice::getScan()->stop();                   // stop scanning when device is found
          myDevice = new BLEAdvertisedDevice(advertisedDevice);
          doConnect = true;
          doScan = true;

        } // Found our server
      } //if(strcmp
    }// onResult
}; // MyAdvertisedDeviceCallbacks

Okay, so that does indeed compile and upload. However it still keeps rebooting when the program is run. Here is what is happening on the serial monitor:

18:48:57.434 -> Starting Arduino BLE Client application...
18:48:58.122 -> BLE Advertised Device found: Name: , Address: 44:c5:ba:ae:af:fa, manufacturer data: 4c001005471c259a17
18:48:58.122 -> BLE Advertised Device found: Name: , Address: 52:81:40:c6:85:41, manufacturer data: 650001c905, serviceUUID: 0000fe78-0000-1000-8000-00805f9b34fb
18:48:58.197 -> BLE Advertised Device found: Name: , Address: 37:88:aa:b0:02:3c, serviceUUID: 0000fd6f-0000-1000-8000-00805f9b34fb
18:48:58.299 -> BLE Advertised Device found: Name: , Address: 12:83:04:c4:44:44, manufacturer data: 4c0002152686f39cbada4658854aa62e7e5e8b8d00010000c9
18:48:58.439 -> BLE Advertised Device found: Name: Tacx Flux 10881, Address: d2:44:d7:f6:2f:2f, manufacturer data: 89062900, serviceUUID: 00001826-0000-1000-8000-00805f9b34fb
18:48:58.476 -> BLE Advertised Device found: Name: , Address: 4c:cf:35:3a:f6:e9, manufacturer data: 4c000c0e001f512946378abe05be008054a110056b1c557433
18:48:59.499 -> BLE Advertised Device found: Name: 221S001637006250, Address: e0:e2:e6:a1:20:ce, serviceUUID: 0000fef1-0000-1000-8000-00805f9b34fb, txPower: 3
18:49:00.038 -> BLE Advertised Device found: Name: iFit HRM 6720, Address: f8:1f:7e:c5:20:67, appearance: 833, serviceUUID: 0000180d-0000-1000-8000-00805f9b34fb
18:49:03.023 -> BLE Advertised Device found: Name: Stages 41069, Address: eb:56:d2:fb:28:ec, serviceUUID: 00001818-0000-1000-8000-00805f9b34fb
18:49:03.023 -> Forming a connection to eb:56:d2:fb:28:ec
18:49:03.023 ->  - Created client
18:49:04.372 ->  - Connected to server
18:49:05.714 ->  - Found our service
18:49:05.714 ->  - Found our characteristic
18:49:05.714 -> Guru Meditation Error: Core  1 panic'ed (IllegalInstruction). Exception was unhandled.
18:49:05.714 -> Memory dump at 0x400d1e24: 3aa0ffcd f87da120 b1008316
18:49:05.714 -> Core 1 register dump:
18:49:05.714 -> PC      : 0x400d1e2a  PS      : 0x00060330  A0      : 0x800d7d43  A1      : 0x3ffc84c0  
18:49:05.714 -> A2      : 0x3ffc3cce  A3      : 0x00000001  A4      : 0x3ffc3cce  A5      : 0x3f4003d8  
18:49:05.748 -> A6      : 0x00000003  A7      : 0x00060a23  A8      : 0x800d1e2a  A9      : 0x3ffc8470  
18:49:05.748 -> A10     : 0x00000001  A11     : 0xdd022b08  A12     : 0xdd022b08  A13     : 0x3ffc4654  
18:49:05.748 -> A14     : 0x3ffe0d70  A15     : 0x00fb0010  SAR     : 0x00000018  EXCCAUSE: 0x00000000  
18:49:05.748 -> EXCVADDR: 0x00000000  LBEG    : 0x4000c2e0  LEND    : 0x4000c2f6  LCOUNT  : 0x00000000  
18:49:05.784 -> 
18:49:05.784 -> ELF file SHA256: 0000000000000000
18:49:05.784 -> 
18:49:05.784 -> Backtrace: 0x400d1e2a:0x3ffc84c0 0x400d7d40:0x3ffc8500 0x400902da:0x3ffc8520
18:49:05.784 -> 
18:49:05.784 -> Rebooting...
18:49:05.784 -> ets Jun  8 2016 00:22:57
18:49:05.784 -> 
18:49:05.784 -> rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
18:49:05.784 -> configsip: 0, SPIWP:0xee
18:49:05.784 -> clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
18:49:05.784 -> mode:DIO, clock div:1
18:49:05.784 -> load:0x3fff0018,len:4
18:49:05.784 -> load:0x3fff001c,len:1216
18:49:05.818 -> ho 0 tail 12 room 4
18:49:05.818 -> load:0x40078000,len:10944
18:49:05.818 -> load:0x40080400,len:6388
18:49:05.818 -> entry 0x400806b4

Run that through the ESP Exception Decoder.

Okay, I ran the Decoder, though I'm not exactly sure how it is supposed to work. I pasted the exception text and got a 'Decode Success' message, but not sure what to do from this point.

I don't understand, but when I paste the backtrace you posted in the Exception decoder I have installed in my IDE, I see more detail.

PC: 0x400d1e2a: CPixelLEDController(EOrder)66, 1, 4294967295u>::show(CRGB const*, int, CRGB) at C:\Users\cattledog\Documents\Arduino\libraries\FastLED/controller.h line 229
EXCVADDR: 0x00000000

Decoding stack results
0x400d1e2a: CPixelLEDController(EOrder)66, 1, 4294967295u>::show(CRGB const*, int, CRGB) at C:\Users\cattledog\Documents\Arduino\libraries\FastLED/controller.h line 229
0x400d7d40: BLERemoteService::retrieveCharacteristics() at c:\users\cattledog\appdata\local\arduino15\packages\esp32\tools\xtensa-esp32-elf-gcc\gcc8_4_0-esp-2021r1\xtensa-esp32-elf\include\c++\8.4.0\bits/stl_tree.h line 2320
0x400902da: _ungetc_r at /builds/idf/crosstool-NG/.build/HOST-i686-w64-mingw32/xtensa-esp32-elf/src/newlib/newlib/libc/stdio/ungetc.c line 203

I don't really understand, but its possible that you are seeing the crash from something related to FastLED and not BLE. I do see many warnings related to FastLED when I compile.

You did say all was working correctly except for the connection, so I'm confused. Perhaps you can write a simplified sketch which just connects and prints the characteristic without the FastED display.

Without a power meter, it's really difficult for me to help debug this. :frowning_face:
I think at this point, you are connecting with the correct address, but there may be an issue with either the characteristic or the Fast LED display, but I'm not clear how this would be related to the connection.

I believe that indicates an attempt to de-reference the NULL pointer. Could be caused by an overflow of the process's stack. Or something completely unrelated. Since ESP32 has built-in FreeRTOS, I prefer not to follow the Arduino 'loop()' paradigm for this processor but use the muti-tasking capabilities of the OS. That helps in debugging when things go wrong and it's using the processor / OS combination as intended.

Absolutely. I think it's time to start from scratch and build up the functionality piece-by-piece ... starting with the BLE stuff.

1 Like

Here's the link to the ESP reference which documents the Exception Decoder.

https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/fatal-errors.html

Guru Meditation Error: Core 1 panic'ed (IllegalInstruction). Exception was unhandled.

Given that IllegalInstruction cause then I think this is particularly relevant

IllegalInstruction

This CPU exception indicates that the instruction which was executed was not a valid instruction. Most common reasons for this error include:

  • FreeRTOS task function has returned. In FreeRTOS, if a task function needs to terminate, it should call vTaskDelete() and delete itself, instead of returning.
  • Failure to read next instruction from SPI flash. This usually happens if:
    • Application has reconfigured the SPI flash pins as some other function (GPIO, UART, etc.). Consult the Hardware Design Guidelines and the datasheet for the chip or module for details about the SPI flash pins.
    • Some external device has accidentally been connected to the SPI flash pins, and has interfered with communication between ESP32 and SPI flash.
  • In C++ code, exiting from a non-void function without returning a value is considered to be an undefined behavior. When optimizations are enabled, the compiler will often omit the epilogue in such functions. This most often results in an IllegalInstruction exception. By default, ESP-IDF build system enables -Werror=return-type which means that missing return statements are treated as compile time errors. However if the application project disables compiler warnings, this issue might go undetected and the IllegalInstruction exception will occur at run time.

I believe that indicates an attempt to de-reference the NULL pointer.

Yes, this is true, but I would have thought that the error would have been Load/Store Prohibited and not Illegal Instruction. But I am not very experienced with ESP fatal error debugging.

LoadProhibited, StoreProhibited

These CPU exceptions happen when an application attempts to read from or write to an invalid memory location. The address which has been written/read is found in the EXCVADDR register in the register dump. If this address is zero, it usually means that the application has attempted to dereference a NULL pointer. If this address is close to zero, it usually means that the application has attempted to access a member of a structure, but the pointer to the structure is NULL. If this address is something else (garbage value, not in 0x3fxxxxxx - 0x6xxxxxxx range), it likely means that the pointer used to access the data is either not initialized or has been corrupted.

This seems to be getting quite complicated. I'm in a little over my head with these programming issues (I have a little experience with Visual Basic, but none with C++) and I might just need spend some time playing around with the code.

In the meantime, I will try using a different power meter (the bike trainer itself) for the LEDs, which seems to have a stronger signal in general and should work better. I was trying to avoid this because it can only connect to two devices and I've been connecting it to my phone and computer during workouts, so now it will be LEDs and phone or computer. I'll just keep messing around with the code when I can.

I truly appreciate all of the help you guys have provided, it is greatly appreciated. Thanks!

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.