NANO BLE freezing

Hi to all,

Recently I finished my project of meteorogical station with NANO BLE SENSE (peripheral device) and NANO BLE (central device) which shows data through OLED display. I got connection between them and I see data via OLED display but around 5 minutes after starting devices (peripheral and central), OLED display show same data (do not change anymore) even when I heated up temperature sensor.

Both devices switched on green LED status.

Has anyone same issue like NANO BLE device?
Is it related with watchdog?

NANO BLE SENSE code:

#include <ArduinoBLE.h> //libreria Bluetooth
#include <Arduino_LPS22HB.h>  //libreria presion
#include <Arduino_HTS221.h> //libreria temperatura-humedad

BLEService MeteoExterior("0x181A"); //declaramos el servicio MeteoExterior 'org.bluetooth.service.environmental_sensing' 0x181A

BLEUnsignedShortCharacteristic Presion("0x2A6D", BLERead | BLENotify);  //declaramos caracteristica presion al servicio MeteoExterior 'org.bluetooth.characteristic.pressure' 0x2A6D
BLEShortCharacteristic Temperatura("0x2A6E", BLERead | BLENotify);  //declaramos caracteristica temperatura al servicio MeteoExterior 'org.bluetooth.characteristic.temperature' 0x2A6E
BLEByteCharacteristic Humedad("0x2A6F", BLERead | BLENotify);  //declaramos caracteristica humedad al servicio MeteoExterior 'org.bluetooth.characteristic.humidity' 0x2A6F

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600); //inicializamos la comunicacion monitor serie

  if (!BLE.begin()) { //inicializamos Bluetooth
    while (1);
  }

  BLE.setLocalName("Exterior");  //set nombre local

  BLE.setAdvertisedService(MeteoExterior);  //indicamos que el servicio tambien se publicite

  MeteoExterior.addCharacteristic(Presion);  //añadimos caracteristica presion al servicio MeteoExterior
  MeteoExterior.addCharacteristic(Temperatura);  //añadimos caracteristica temperatura al servicio MeteoExterior
  MeteoExterior.addCharacteristic(Humedad);  //añadimos caracteristica humedad al servicio MeteoExterior

  BLE.addService(MeteoExterior); //añadimos el servicio MeteoPresion

  BLE.setConnectable(true); //el periferico es conectable después de publicitarlo

  BARO.begin(); //inicializo sensor de presion
  HTS.begin();  //inicializo sensores de temperatura y humedad

  BLE.advertise(); //publicitando periferico

}

void loop() {

  BLEDevice central = BLE.central(); //preguntamos si central se ha conectado

  if (central) {  //si central esta disponible

    while (central.connected()) {  //y mientras central permanezca conectado
      uint16_t pressure = round(BARO.readPressure() * 100.0);
      Presion.writeValue(pressure);  //escribo el valor de presion del sensor en la caracteristica Presion del servicio MeteoExterior
      Serial.print(pressure);
      Serial.println(" kpa");
      int16_t temperature = round(HTS.readTemperature() * 100.0);
      Temperatura.writeValue(temperature);  //escribo el valor de temperatura del sensor en la caracteristica Temperatura del servicio MeteoExterior
      Serial.print(temperature);
      Serial.println(" ºC");
      int16_t humidity = round(HTS.readHumidity() * 100.0);
      Humedad.writeValue(humidity); //escribo el valor de humedad del sensor en la caracteristica Humedad del servicio MeteoExterior
      Serial.print(humidity);
      Serial.println(" %");
    }

  }

}

Yes, the issue is when the Arduino Nano 33 BLE loses the connection you can no longer recover. You simplified my code example which was written to make the connection more robust. See reply #3.

The if( central.rssi() != 0 ) is there for a reason.

But even with the code, there is an issue. When you lose the BLE connection completely without properly closing it you need a reset (button or maybe watchdog). You can test this with a smartphone and an app like BLE Scanner. I used the green LED as indicators for the connection.

Hi to all,

I checked your code and modified my code in peripheral device. I used orange LED to check when peripheral device connects with central device (ON connected, OFF disconnected) and green LED to check RSSI level (ON RSSI = 0, OFF RSSI != 0). But the problem persists on BLE devices (NANO BLE, central device).

Both devices connect and peripheral send information to central (orange LED blink every connection like programm indicates and green LED is always OFF, sometimes blink less than 1 second) and minutes later peripheral device show orange LED ON, that means connection established, and green LED OFF, that means RSSI != 0. Central device displays last values that received and Serial monitor is block too, in this instrucion:

    if (Conectado) {  //Conectamos al dispositivo BLE encontrado
      Serial.println("Conectado");

I added “goto” instruction in central code and it runs right few minutes more, but it stops always at the same instruction that you can see above.

I checked serial monitor of peripheral device and it runs when central “stops”.

In my opinion, the problem is not related with Bluetooth, because both devices site in the same place, central device stop/block always around same time and at the same instruction; but I have not got idea where issue comes from.

Serial monitor where central device stops:

18:09:24.278 -> 1
18:09:24.278 -> Exterior
18:09:24.278 -> Local name: Exterior
18:09:24.278 -> Service UUIds: 00000000-0000-0000-0000-00000000181a 
18:09:24.278 -> Connectando...
18:09:24.358 -> Conectado

Peripheral code:

#include <ArduinoBLE.h> //libreria Bluetooth
#include <Arduino_LPS22HB.h>  //libreria presion
#include <Arduino_HTS221.h> //libreria temperatura-humedad

BLEService MeteoExterior("0x181A"); //declaramos el servicio MeteoExterior 'org.bluetooth.service.environmental_sensing' 0x181A

BLEUnsignedShortCharacteristic Presion("0x2A6D", BLERead | BLENotify);  //declaramos caracteristica presion al servicio MeteoExterior 'org.bluetooth.characteristic.pressure' 0x2A6D
BLEShortCharacteristic Temperatura("0x2A6E", BLERead | BLENotify);  //declaramos caracteristica temperatura al servicio MeteoExterior 'org.bluetooth.characteristic.temperature' 0x2A6E
BLEShortCharacteristic Humedad("0x2A6F", BLERead | BLENotify);  //declaramos caracteristica humedad al servicio MeteoExterior 'org.bluetooth.characteristic.humidity' 0x2A6F

const int BLE_LED_PIN = LED_BUILTIN;
const int RSSI_LED_PIN = LED_PWR;


void setup() {
  // put your setup code here, to run once:
  pinMode(BLE_LED_PIN, OUTPUT);
  pinMode(RSSI_LED_PIN, OUTPUT);

  Serial.begin(9600); //inicializamos la comunicacion monitor serie

  if (!BLE.begin()) { //inicializamos Bluetooth
    while (1);
  }

  BLE.setLocalName("Exterior");  //set nombre local

  BLE.setAdvertisedService(MeteoExterior);  //indicamos que el servicio tambien se publicite

  MeteoExterior.addCharacteristic(Presion);  //añadimos caracteristica presion al servicio MeteoExterior
  MeteoExterior.addCharacteristic(Temperatura);  //añadimos caracteristica temperatura al servicio MeteoExterior
  MeteoExterior.addCharacteristic(Humedad);  //añadimos caracteristica humedad al servicio MeteoExterior

  BLE.addService(MeteoExterior); //añadimos el servicio MeteoPresion

  BLE.setConnectable(true); //el periferico es conectable después de publicitarlo

  BARO.begin(); //inicializo sensor de presion
  HTS.begin();  //inicializo sensores de temperatura y humedad

  BLE.advertise(); //publicitando periferico

}

void loop() {

  static long anteriorMillis = 0;
#define INTERVALO_ACTUALIZA_SENSOR 5000

  BLEDevice central = BLE.central(); //preguntamos si central se ha conectado

  if (central) {  //si central esta disponible

    while (central.connected()) {  //y mientras central permanezca conectado

      digitalWrite(BLE_LED_PIN, HIGH);

      unsigned long actualMillis = millis();
      if (actualMillis - anteriorMillis > INTERVALO_ACTUALIZA_SENSOR) {
        anteriorMillis = actualMillis;

        Serial.print("Central RSSI: ");
        Serial.println(central.rssi());

        if (central.rssi() != 0) {  //señal por encima de 0
          digitalWrite( RSSI_LED_PIN, LOW );
          uint16_t pressure = round(BARO.readPressure() * 100.0);
          Presion.writeValue(pressure);  //escribo el valor de presion del sensor en la caracteristica Presion del servicio MeteoExterior
          Serial.print(pressure);
          Serial.println(" kpa");
          int16_t temperature = round(HTS.readTemperature() * 100.0);
          Temperatura.writeValue(temperature);  //escribo el valor de temperatura del sensor en la caracteristica Temperatura del servicio MeteoExterior
          Serial.print(temperature);
          Serial.println(" ºC");
          int16_t humidity = round(HTS.readHumidity() * 100.0);
          Humedad.writeValue(humidity); //escribo el valor de humedad del sensor en la caracteristica Humedad del servicio MeteoExterior
          Serial.print(humidity);
          Serial.println(" %");
        }

        else {
          digitalWrite( RSSI_LED_PIN, HIGH );
        }
      }
    }
    digitalWrite(BLE_LED_PIN, LOW);
  }
}

Here post Central code, that I could not posted before:

#include <ArduinoBLE.h> //libreria Bluetooth
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

//Constantes
#define ANCHO_PANTALLA 128
#define ALTO_PANTALLA 64

Adafruit_SSD1306 myDisplay(ANCHO_PANTALLA, ALTO_PANTALLA, &Wire, -1);

//Variables
byte Int_Ext;
uint16_t presion_Exterior;
int16_t temperatura_Exterior;
int16_t humedad_Exterior;
uint16_t presion_Interior;
int16_t temperatura_Interior;
int16_t humedad_Interior;


void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600); //inicializamos la comunicacion monitor serie

  if (!BLE.begin()) { //inicializamos Bluetooth
    Serial.println("fallo al inicializar BLE");
    while (1);
  }

  Serial.println("Inicializamos el dispositivo BlueTooth central");

  BLE.setLocalName("LectorMeteos");  //set nombre local

  BLE.scan(); //dispositivo BLE escaneando perifericos
  Serial.println("Escaneamos en busca de dispositivo BLE periferico");

  myDisplay.begin(SSD1306_SWITCHCAPVCC, 0x3C);
}

void loop() {
  // put your main code here, to run repeatedly:
puntoReset:
  BLEDevice perifericoExterior = BLE.available();  //dispositivo periferico disponible
  Serial.println(perifericoExterior);

  if (perifericoExterior) { //el dispositivo BLE esta disponible
    Serial.println(perifericoExterior.localName());

    if (perifericoExterior.hasLocalName()) { //dispone de localName?
      Serial.print("Local name: ");
      Serial.println(perifericoExterior.localName());
    }
    else Serial.println("Local name: no encontrado");

    if (perifericoExterior.hasAdvertisedServiceUuid()) { //dispone de Servicios?
      Serial.print("Service UUIds: ");
      for (int i = 0; i < perifericoExterior.advertisedServiceUuidCount(); i++) {
        Serial.print(perifericoExterior.advertisedServiceUuid(i));
        Serial.print(" ");
      }
      Serial.println();
    }
    else Serial.println("Service UUIDs: no encontrados");

    Int_Ext = 0;

    funcionDisponibilidadDispositivo(perifericoExterior, Int_Ext);

  }
  else {
    Serial.println("Dispositivo BLE periferico no esta disponible");
    Serial.println(perifericoExterior);
  }

  //  BLEDevice perifericoInterior = BLE.available();  //dispositivo periferico disponible
  //  Serial.println(perifericoInterior);
  //
  //  if (perifericoInterior) { //el dispositivo BLE esta disponible
  //    Serial.println("Dispositivo BLE periferico esta disponible");
  //
  //    if (perifericoInterior.hasLocalName()) { //dispone de localName?
  //      Serial.print("Local name: ");
  //      Serial.println(perifericoInterior.localName());
  //    }
  //    else Serial.println("Local name: no encontrado");
  //
  //    if (perifericoInterior.hasAdvertisedServiceUuid()) { //dispone de Servicios?
  //      Serial.print("Service UUIds: ");
  //      for (int i = 0; i < perifericoInterior.advertisedServiceUuidCount(); i++) {
  //        Serial.print(perifericoInterior.advertisedServiceUuid(i));
  //        Serial.print(" ");
  //      }
  //      Serial.println();
  //    }
  //    else Serial.println("Service UUIDs: no encontrados");

  //  Int_Ext=1;

  //  funcionDisponibilidadDispositivo(perifericoInterior);

  //  }
  //  else {
  //    Serial.println("Dispositivo BLE periferico no esta disponible");
  //    Serial.println(perifericoInterior);
  //  }

  myDisplay.clearDisplay();

  myDisplay.setTextSize(1);

  myDisplay.setTextColor(SSD1306_WHITE);

  myDisplay.setCursor(0, 0);

  myDisplay.print("P: ");
  myDisplay.print(presion_Exterior);
  myDisplay.println(" kPa");

  myDisplay.print("HR: ");
  myDisplay.print(humedad_Exterior);
  myDisplay.println(" %");

  myDisplay.print("T: ");
  myDisplay.print(temperatura_Exterior);
  myDisplay.println(" C");

  myDisplay.display();

  goto puntoReset;  //prueba de "reset"

}

uint16_t funcionLecturaPresion(BLECharacteristic Presion) {
  uint16_t pres;
  Presion.readValue(pres);
  Serial.print("Presion: ");
  Serial.print(pres / 100.0);
  Serial.println(" Kpa");
  return (pres / 100.0);
}

int16_t funcionLecturaTemperatura(BLECharacteristic Temperatura) {
  int16_t temp;
  Temperatura.readValue(temp);
  Serial.print("Temperatura: ");
  Serial.print(temp / 100.0);
  Serial.println(" ºC");
  return (temp / 100.0);
}

int16_t funcionLecturaHumedad(BLECharacteristic Humedad) {
  int16_t hum;
  Humedad.readValue(hum);
  Serial.print("Humedad: ");
  Serial.print(hum / 100.0);
  Serial.println(" %");
  return (hum / 100.0);
}

void funcionDisponibilidadDispositivo(BLEDevice dispositivo, byte selector) {
  if (dispositivo.localName() == "Exterior") { //encontramos el dispositivo BLE que buscamos
    BLE.stopScan(); //paramos el escaneo de dispositivos.
    Serial.println("Connectando...");

    bool Conectado = dispositivo.connect(); //conectamos con el periferico

    if (Conectado) {  //Conectamos al dispositivo BLE encontrado
      Serial.println("Conectado");

      if (dispositivo.discoverAttributes()) { //descubrimos los atributos del periferico
        Serial.println("Atributos descubiertos");
      }
      else Serial.println("No Atributos");

      Serial.print("Device name: ");
      Serial.println(dispositivo.deviceName());
      Serial.print("Local name: ");
      Serial.println(dispositivo.localName());

      BLEService MeteoService = dispositivo.service("00000000-0000-0000-0000-00000000181A");
      Serial.println(MeteoService);

      BLECharacteristic Presion = MeteoService.characteristic("00000000-0000-0000-0000-000000002A6D");
      if (Presion) {  //si caracteristica Presion esta disponible obtenemos el valor
        switch (selector) {
          case 0:
            presion_Exterior = funcionLecturaPresion(Presion);
            break;
          case 1:
            presion_Interior = funcionLecturaPresion(Presion);
            break;
        }
      }

      BLECharacteristic Temperatura = MeteoService.characteristic("00000000-0000-0000-0000-000000002A6E");
      if (Temperatura) {  //si caracteristica Temperatura esta disponible obtenemos el valor
        switch (selector) {
          case 0:
            temperatura_Exterior = funcionLecturaTemperatura(Temperatura);
            break;
          case 1:
            temperatura_Interior = funcionLecturaTemperatura(Temperatura);
            break;
        }
      }

      BLECharacteristic Humedad = MeteoService.characteristic("00000000-0000-0000-0000-000000002A6F");
      if (Humedad) {  //si caracteristica Humedad esta disponible obtenemos el valor
        switch (selector) {
          case 0:
            humedad_Exterior = funcionLecturaHumedad(Humedad);
            break;
          case 1:
            humedad_Interior = funcionLecturaHumedad(Humedad);
            break;
        }
      }

      dispositivo.disconnect();
      Serial.println("Desconectado");
      BLE.scan(); //dispositivo BLE escaneando perifericos

    }
    else {
      Serial.println("Fallo en la conexion");
      Serial.println("Desconectado");
      BLE.scan(); //dispositivo BLE escaneando perifericos

    }
  }
}