BLE reconnect after lost connection

I have read a few posts about how the nano 33 BLE has had issues with reconnecting after a lost connection. It seems like at some point they released a fix for it and others have just simply used a watchdog timer to reset the Arduino. The watchdog timer would not exactly work in my situation.

I am sort of having this issue but not consistently. My situation is I have a HC-19 BLE module connected to a battery and the Nano is scanning for the HC-19. When it finds it, it connects and then waits for the device to not be connected anymore. Then it scans again and the process repeats. For testing, I am just disconnecting the battery from the HC-19 to simulate it going away.

This works pretty well for a handful of connects/disconnects then I either get one of 2 issues

  1. The Arduino crashes (blinking orange LED), seems to occur possibly when I execute the scan function.
  2. The Arduino never finds the device again. Just continuously scans supposedly, I have no way to verify it is actually scanning I just know the call to start scanning is successful. And I know the HC-19 is available still because I can connect to it from my phone.

The timing of the connects/disconnects seems to make the issue happen quicker. If I reconnect more rapidly the issue seems to present itself quicker.

So it seems like I’m having some sort of reconnecting issue, it just doesn’t seem like it’s exactly the same as the rest of the posts I have seen on the topic.

I did read somewhere that the Nano 33 IOT does not have similar BT issues because it doesn’t use mbed OS. I would be fine switching to the IOT if that would fix the issue but I would like to see if I can get the BLE device I currently have working.

Which version of the board support and ArduinoBLE library are you using?

I just recently found the new* version 2.0.0. It is a package for the “Arduino Mbed OS Nano Boards”. * I am not sure when it was released.

A few things seem to be better with the latest version.

Can you post your code? I have both (Nano 33 BLE and IoT) boards and can try to replicate the test. I do not have a HC-19 but could use another board.

Where are you seeing the 2.0.0 version of the ArduinoBLE library? I am using version 1.2.0 which seems to be the latest as far as I can tell.

Ahh maybe you are talking about this?

This should work. I had to cut out some unrelated stuff but this is essentially what I am trying to do. Tried to comment it as best I could. Just need to set a device name to scan for. And I’m sure there is a better way to code this but this is just where I am at currently.

#include <ArduinoBLE.h>

String Device = ""; // Whatever device you want to look for

void setup() {
  Serial.begin(115200);

  pinMode(LED_BUILTIN, OUTPUT);
  pinMode(LED_PWR, OUTPUT);

  if (!BLE.begin()) {
    Serial.println("starting BLE failed!");
    while (1);
  }

  Serial.println("starting BLE success!");
  BLE.scanForName(Device);
}

bool enableStatusTimer = false;
int startStatusTimer = 0;
int endStatusTimer = 0;

int state = 0; // Begin by searching for device

BLEDevice peripheral;

void btConnect(){
  if (peripheral.connect()){ // When device is connected
    Serial.println("Connected");
  } else { // If a connection could not be established try to connect again
      Serial.println("Failed to Connect");
      btConnect(); // Try again
    }
}

void loop() {
  
  if (enableStatusTimer == false){
    startStatusTimer = millis();
    enableStatusTimer = true;
  }

  switch(state){

    case 0 : // Searching
      endStatusTimer = millis();
      if ((endStatusTimer - startStatusTimer)*.001 > .5){ // Indicates module is searching
        digitalWrite(LED_PWR,!digitalRead(LED_PWR));
        startStatusTimer = millis();
      }

      peripheral = BLE.available();

      if (peripheral) { // Upon finding the device
        BLE.stopScan(); // Stop scanning
        Serial.println("Found");

        btConnect(); // Recursively tries to connect to device

        digitalWrite(LED_BUILTIN,HIGH); // Connected
        startStatusTimer = millis();
        state = 1; // Connected
      }

      break;

    case 1 : // Disconnect
      endStatusTimer = millis();
      if ((endStatusTimer - startStatusTimer)*.001 > 1){ // Indicates Device is connected
        digitalWrite(LED_PWR,!digitalRead(LED_PWR));
        startStatusTimer = millis();
      }   

      if (!peripheral.connected()){
        Serial.println("Device not connected");
        digitalWrite(LED_BUILTIN,LOW);
        BLE.scanForName(Device); // turn BT back on
        state = 0;
      }
      break;  
  }
}

Calling a function ( btConnect() ) recursively is a good way to crash any computer. You do not have a operating system with memory management to save the day. Extend you state machine with a state fot connecting. loop() will do the rest.

That is the version of the board support. See Tools → Boards → Boards Manager. The board support contains all the other stuff (mbedOS, standard libraries, even part of the BLE stack).

A few other things I noted about your code:

  • The words enableStatusTimer and startStatusTimer have the same meaning. You use them for two quite different things. You need to look up the definition to find out what they are. Maybe you can find better names.

  • if ( enableStatusTimer == false ) → startStatusTimer = millis(); // this feels wrong

  • if ( ( endStatusTimer - startStatusTimer )*.001 > 1 ) // avoid floating point operations if you can, they are expensive, even if you have a Cortex-M4 with FPU.

  • You have a state machine for your BLE stuff, you might as well move all BLE code into it. e.g., remove it from setup. That will make it easier to read your code and move to another project. You can still have BLE functions called from the state machine, but you know BLE code is only called from one place.

  • I would recommend redefining your LEDs. That can make the code clear. e.g.

#define BLE_CONNECT_LED LED_BUILTIN

This also allows you to use other pins on another board that might not have a power led.

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