Arduino stops BLE Transmissions

Hello my fellow arduino enthusiasts,

Ive just started using these miraculous machines and love everything so far.
I have a project, in which a arduino nano ble sense reads out its 8 analog inputs, its temperature sensor and its acceleration sensors, than writes them each to a characteristic.

A pi 3 b then accesses those on a regular basis and writes them to a .txt

After some time (inconsistent, one time after 14 minues, on time after 17, one time after 15 …), the arduino refuses connecting and the orange LED starts flashing 3 times slow, 5 times fast, on repeat.

I am new to all of this and maybe I made a mistake by trying jumping from making an LED flash to sensor data BLE transmission :wink: but since this is important for my studies, I would extremely appreciate any help.

Here is one version of my code on the arduino (i cut out some stuff due to character restrictions of the board):

#include <ArduinoBLE.h>
#include <Arduino_HTS221.h>
#include <Arduino_LSM9DS1.h>

BLEService guardService("1101");
BLEIntCharacteristic t0("2100", BLERead | BLENotify);
.
.
.
BLEIntCharacteristic t6("2106", BLERead | BLENotify);
BLEIntCharacteristic t7("2107", BLERead | BLENotify);
BLEIntCharacteristic ta("2108", BLERead | BLENotify);
BLEIntCharacteristic ax("2109", BLERead | BLENotify);
BLEIntCharacteristic ay("2110", BLERead | BLENotify);
BLEIntCharacteristic az("2111", BLERead | BLENotify);

//int m = 0;
//float xxx=0.0;
//float yyy=0.0;
//float zzz=0.0;

void setup() {
//#Serial.begin(9600);
//#while (!Serial);

//#pinMode(LED_BUILTIN, OUTPUT);
if (!BLE.begin()) 
{
//#Serial.println("starting BLE failed!");
while (1);
}

BLE.setLocalName("guArdian");
BLE.setAdvertisedService(guardService);
guardService.addCharacteristic(t0);
.
.
.
guardService.addCharacteristic(t7);
guardService.addCharacteristic(ta);
guardService.addCharacteristic(ax);
guardService.addCharacteristic(ay);
guardService.addCharacteristic(az);
BLE.addService(guardService);

BLE.advertise();
//#Serial.println("Bluetooth device active, waiting for connections...");
}

void loop() 
{
BLEDevice central = BLE.central();

if (central) 
{
//#Serial.print("Connected to central: ");
//#Serial.println(central.address());
digitalWrite(LED_BUILTIN, HIGH);

while (central.connected()) {

      int battery = analogRead(A0);
      //int batteryLevel = map(battery, 0, 1023, 0, 100);
      int vt0 = analogRead(A0);
.
.
.
      int vt7 = analogRead(A7);
      HTS.begin();
      int vta= HTS.readTemperature(CELSIUS);
//#      Serial.print("Battery Level % is now: ");
//#      Serial.print(vt0);
//#      Serial.println(vt1);
      t0.writeValue(vt0);
//t1-t6 same way, cut out due to character restrictions of the board
      t7.writeValue(vt7);
      ta.writeValue(vta);
//      IMU.begin();
//      float x, y, z;
//      float x0 = 0;
//      float y0 = 0;
//      float z0 = 0;
//      int n = 0;
//      while (n < 5) {
//        if (IMU.accelerationAvailable()) {
//              IMU.readAcceleration(x, y, z);
//              if (abs(x)>abs(x0)) {
//                  x0=abs(x);
//              }
//              if (abs(y)>abs(y0)) {
//                  y0=abs(y);
//              }
//              if (abs(z)>abs(z0)) {
//                  z0=abs(z);
//              }
//             delay(100);
//        n = n+1;
//        }
//      }
//      IMU.end();
//      
//
//      m=m+1;
//      if (m>20){
//        m=0;
//        xxx=0.0;
//        yyy=0.0;
//        zzz=0.0;
//      }else{
//        m=m+1;
//        if (abs(x0)>abs(xxx)) {
//                  xxx=abs(x0);
//              }
//        if (abs(y0)>abs(yyy)) {
//                  yyy=abs(y0);
//              }
//        if (abs(z0)>abs(zzz)) {
//                  zzz=abs(z0);
//              }
//      }
//      int vax = (int) (xxx*100);
//      int vay = (int) (yyy*100);
//      int vaz = (int) (zzz*100);
      ax.writeValue(0);
      ay.writeValue(0);
      az.writeValue(0);

      delay(2000);

}
}
digitalWrite(LED_BUILTIN, LOW);
//# Serial.print("Disconnected from central: ");
//# Serial.println(central.address());
}

And here is the python code on the pi, which was shamelessly stolen from the hexiwear guide and adapted for my needs. It is run on a 10 second basis via cronjobmanagerthingy:

#! /usr/bin/python3

import pexpect
import time
import sys
import os
import binascii
# ---------------------------------------------------------------------
# transforms the crazy hex bits to a normal number (int)
# ---------------------------------------------------------------------
def hexStrToInt(hexstr):
    #val = int(hexstr[0:2],16) + (int(hexstr[3:5],16)<<8)
    #val = int(hexstr[0:2],16) + int(hexstr[3:5],16) + int(hexstr[6:8],16) + int(hexstr[9:11],16)
    #if ((val&0x8000)==0x8000): # treat signed 16bits
    #    val = -((val^0xffff)+1)
    val = int(str(int(bin(int(hexstr[3:5]))[2:])*(100000000)),2) + int(hexstr[0:2],16)
    return val
# ---------------------------------------------------------------------
DEVICE = "F5:A5:37:66:E9:A2"   # Arduino Mac Adress
if len(sys.argv) == 2:
    DEVICE = str(sys.argv[1])
#   Run gatttool interactively.
child = pexpect.spawn("gatttool -I")
#   Connect to the device.
print("Connecting to:"),
print(DEVICE)
NOF_REMAINING_RETRY = 3
while True:
    try:
        child.sendline("connect {0}".format(DEVICE))
        child.expect("Connection successful", timeout=5)
    except pexpect.TIMEOUT:
        NOF_REMAINING_RETRY = NOF_REMAINING_RETRY-1
        if (NOF_REMAINING_RETRY>0):
            print ("timeout, retry...")
            continue
        else:
            print ("timeout, giving up.")
            break
    else:
        print("Connected!")
        break
if NOF_REMAINING_RETRY>0:
    unixTime = int(time.time())
    unixTime += 60*60 # GMT+1
    unixTime += 60*60 # added daylight saving time of one hour
  # open file
    file = open("ledger.txt", "a")
    if (os.path.getsize("ledger.txt")==0):
        file.write("Device;Time;T0;T1;T2;T3;T4;T5;T6;T7;TA;AX;AY;AZ\n")
    file.write(DEVICE)
    file.write(";")
    file.write(str(unixTime)) # Unix timestamp in seconds 
    file.write(";")
#   # App mode
#     child.sendline("char-read-hnd 0x6d")
#     child.expect("Characteristic value/descriptor: ", timeout=5)
#     child.expect("\r\n", timeout=5)
#     print("AppMode:  "),
#     print(child.before),
#     print(str(int(child.before[0:2],16)))
#     file.write(str(int(child.before[0:2],16)))
#     file.write("\t")
  # T0
    child.sendline("char-read-uuid 00002100-0000-1000-8000-00805f9b34fb")
    child.expect("handle: 0x000b value: ", timeout=5)
    child.expect("\r\n", timeout=5)
    print("T0:  " + str(hexStrToInt(child.before)))
    file.write(str(hexStrToInt(child.before)))
    file.write(";")   
    

    file.write(";")   
    
   
# ...T1 - T7 i cut out now due to character restrictions of the board here

    
#    # T7
    child.sendline("char-read-uuid 00002107-0000-1000-8000-00805f9b34fb")
    child.expect("handle: 0x0020 value: ", timeout=5)
    child.expect("\r\n", timeout=5)
    print("T7:  " + str(hexStrToInt(child.before)))
    file.write(str(hexStrToInt(child.before)))
    file.write(";") 
#     
#    # TA
    child.sendline("char-read-uuid 00002108-0000-1000-8000-00805f9b34fb")
    child.expect("handle: 0x0023 value: ", timeout=5)
    child.expect("\r\n", timeout=5)
    print("TA:  " + str(hexStrToInt(child.before)))
    file.write(str(hexStrToInt(child.before)))
    file.write(";")   
#     
#    # AX (same way AY and AZ, again cut due to character restrictions)
    child.sendline("char-read-uuid 00002109-0000-1000-8000-00805f9b34fb")
    child.expect("handle: 0x0026 value: ", timeout=5)
    child.expect("\r\n", timeout=5)
    print("AX:  " + str(hexStrToInt(child.before)))
    file.write(str(hexStrToInt(child.before)))
    file.write(";") 
#     

    
    file.close()
    print("done!")
    child.sendline("disconnect")
    sys.exit(0)
else:
    print("FAILED!")
    sys.exit(-1)

I have tried not disconnecting from it every time from the pi, but same, i have tried not sending as many values, no success, i am at my witts end. HELP me mario!

Purely a wild guess, but you might try the new beta platform for the Nano 33 BLE to see if you get different results:

  • Tools > Board > Boards Manager
  • Wait for the downloads to finish
  • Click on "Arduino mbed-enabled Boards".
  • Click the "Install" button.
  • Wait for the installation to finish.
  • Click the "Close" button.

You will now find that you have two entries for Arduino Nano 33 BLE under the Arduino IDE's Tools > Board menu. The original is under the "Arduino nRF528x Boards (Mbed OS)" section, while the beta version is under the "Arduino Mbed OS Boards (nRF52840 / STM32H747)" section. If you select the Arduino Nano 33 BLE board selection from under the "Arduino Mbed OS Boards (nRF52840 / STM32H747)" section, then upload the sketch to your Nano 33 BLE again, the new boards platform's code will be used. I know there have been some improvements in the beta platform, but I don't know whether any of them are relevant to the problem you're having.

Hello pert,

thanks for that rapid response. Also two thumbs up for the foolproof step by step explanation.

Still i seem to have screwed up, i get a few errors:

C:\Users\MasterThesis\Documents\Arduino\libraries\ArduinoBLE\src\utility\HCICordioTransport.cpp: In function 'void bleLoop()':

C:\Users\MasterThesis\Documents\Arduino\libraries\ArduinoBLE\src\utility\HCICordioTransport.cpp:112:11: error: 'LowPowerTimer' is not a member of 'mbed'

mbed::LowPowerTimer timer;

^~~~~~~~~~~~~

C:\Users\MasterThesis\Documents\Arduino\libraries\ArduinoBLE\src\utility\HCICordioTransport.cpp:115:38: error: 'timer' was not declared in this scope

last_update_us += (uint64_t) timer.read_high_resolution_us();

^~~~~

C:\Users\MasterThesis\Documents\Arduino\libraries\ArduinoBLE\src\utility\HCICordioTransport.cpp:115:38: note: suggested alternative: 'time'

last_update_us += (uint64_t) timer.read_high_resolution_us();

^~~~~

time

C:\Users\MasterThesis\Documents\Arduino\libraries\ArduinoBLE\src\utility\HCICordioTransport.cpp:131:19: error: 'CriticalSectionLock' is not a member of 'mbed'

mbed::CriticalSectionLock critical_section;

^~~~~~~~~~~~~~~~~~~

C:\Users\MasterThesis\Documents\Arduino\libraries\ArduinoBLE\src\utility\HCICordioTransport.cpp:148:55: warning: 'void rtos::ThisThread::sleep_for(uint32_t)' is deprecated: Pass a chrono duration, not an integer millisecond count. For example use 5s rather than 5000. [since mbed-os-6.0.0] [-Wdeprecated-declarations]

rtos::ThisThread::sleep_for(wait_time_ms);

^

In file included from C:\Users\MasterThesis\AppData\Local\Arduino15\packages\arduino-beta\hardware\mbed\1.2.0\cores\arduino/mbed/rtos/rtos.h:30:0,

from C:\Users\MasterThesis\AppData\Local\Arduino15\packages\arduino-beta\hardware\mbed\1.2.0\cores\arduino/USB/PluggableUSBSerial.h:24,

from C:\Users\MasterThesis\AppData\Local\Arduino15\packages\arduino-beta\hardware\mbed\1.2.0\cores\arduino/Arduino.h:127,

from C:\Users\MasterThesis\Documents\Arduino\libraries\ArduinoBLE\src\utility\HCITransport.h:23,

from C:\Users\MasterThesis\Documents\Arduino\libraries\ArduinoBLE\src\utility\HCICordioTransport.h:27,

from C:\Users\MasterThesis\Documents\Arduino\libraries\ArduinoBLE\src\utility\HCICordioTransport.cpp:42:

C:\Users\MasterThesis\AppData\Local\Arduino15\packages\arduino-beta\hardware\mbed\1.2.0\cores\arduino/mbed/rtos/ThisThread.h:216:6: note: declared here

void sleep_for(uint32_t millisec);

^~~~~~~~~

C:\Users\MasterThesis\Documents\Arduino\libraries\ArduinoBLE\src\utility\HCICordioTransport.cpp:152:15: error: 'wait_us' was not declared in this scope

wait_us(wait_time_us);

^~~~~~~

C:\Users\MasterThesis\Documents\Arduino\libraries\ArduinoBLE\src\utility\HCICordioTransport.cpp:152:15: note: suggested alternative: 'init_wsf'

wait_us(wait_time_us);

^~~~~~~

init_wsf

exit status 1
Fehler beim Kompilieren für das Board Arduino Nano 33 BLE.

(The last line translates to: An error occured during the compilation for the arduino board nano 33 ble)

when changing back to the other board, everything is fine

It seems that the release version of the ArduinoBLE library is not compatible with the beta Arduino mbed boards platform. It's necessary to use the beta test version of the ArduinoBLE library as well. You can do that by following these instructions:

  • Delete C:\Users\MasterThesis\Documents\Arduino\libraries\ArduinoBLE. Please be very careful when deleting things from your computer. When in doubt, back up!
  • Download the beta test version of the ArduinoBLE library: https://github.com/arduino-libraries/ArduinoBLE/archive/master.zip
  • (In the Arduino IDE) Sketch > Include Library > Add .ZIP Library
  • Select the downloaded file.
  • Click the "Open" button.

Now try uploading your sketch again.

Commenting to add a refence supporting my previous reply:

All right! I will give it a try on Monday!

I hope it will be helpful. Let me know how it goes.

Between changing to the beta platform and the development version of the library, you are definitely getting the advantage of a lot of new development work Arduino has done. I don’t necessarily recommend making a habit of using development versions of code for everyday use (it’s more intended to be used for beta testing), but if you find that the production release version of the software isn’t working and the development version is, then the best choice is clear enough.

Hello pert,

your guide helped me upload the skript! But unfortunately, it did not resolve my problem. I think it would suffice for me, to get a hang of watchdog. But i have read that i have to make the arduino nano ble sense think that its a arduino uno. will i still be able to use its bluetooth module and buildin sensors? I couldnt find any, but is there maybe a good guide how to do it for a beginner?

but thanks so far for the comprehensible suggestions :))

ive alreade researched it, but if anyone has a solution, rebooting the arduino with its software being an absolutely valid way at this point for me, i am really thankfull for any input :slight_smile:

In the end, this here did the trick for me. its not pretty, but it works, so i guess its pretty awesome :smiley: