XIAO nrf52840 ArduinoBLE 1 central, 2 peripherals

I just removed everything out of the main loop apart from a single

Serial.println(millis());

so I can see it’s still running on the Serial monitor, and guess what, it crashed after about 3 minutes…

I hope I do not write this too early, but the board is running perfectly fine since I connected it to a power source instead of having it attached on my MacBook Pro 16" (2019)
No crash since at least 10 minutes now, never ran for so long before.

ok, so it crashed anyway, but after a much longer time then when connected to serial… which I find strange myself but it’s my observation.

@msfujino sorry for the many messages, but I spent the whole day debugging the issue and still did not find it. I had to wait for minutes each time only to see it’s still not stable :smiley:
Anyway, one question: in the peripheral code, you wrote

while(central.connect())

shouldn’t that be

while(central.connected())

I mean it didn’t change my problem, but anyway, just as a question.

biggest difference I’m seeing is in the peripheral code.
Since you transmit accelerometer-data and I need to transmit temperature and humidity, we have differences there.

You did:

do {        
        myIMU.readRegister(&readData, LSM6DS3_ACC_GYRO_STATUS_REG);   //0,0,0,0,0,TDA,GDA,XLDA
      } while ((readData & 0x07) != 0x07);   
...
ud.dataBuff32[0] = roll; 
      ud.dataBuff32[1] = pitch; 
      ud.dataBuff32[2] = yaw;       
      ud.dataBuff32[3] = Vbatt;

I removed the loop and replaced the lower with:

if(sht.readSample()){
  ud.dataBuff32[1] = sht.getHumidity(), 2; 
  ud.dataBuff32[2] = sht.getTemperature(), 2;        
  ud.dataBuff32[3] = Vbatt * 1000;
}

I thought this would be the same in the end… readSample should return true as soon as data is ready?
But when I use your code and transmit accelerometer-data, nothing is crashing ever.

This is the library I use: GitHub - Sensirion/arduino-sht: Repository for Sensirion humidity and temperature sensor support on Arduino

seems like everytime I write here to say it’s probably solved, it’s going to crash within 60 seconds.

So even your code is crashing here after some time.

Did you let your code run for several minutes?

I am experimenting with moving Peripherals away from Central until -70dBm. Your -50 dBm is sufficient signal strength.

Once connected, I confirmed that communication was maintained for at least half a day.

Peripheral : XIAO_nRF52840 Sense
Central : XIAO_nRF52840
Board Library : Seeed nRF52 mbed-enabled Borads 2.8.1
ArduinoBLE 1.3.1

Thanks for finding the bug. Maybe you are right.
I rewrote connect() with connected() and started it working. So far it is working fine. However, it doesn’t seem to solve the disconnect detection and reconnect problems I am having.

1 Like

we have the absolut same setup. What a coincidende!

I started again with your code, I’m not sure if my display-code is slowing things down too much.
I use this code / libraries for my display:

#include <Adafruit_SH110X.h>
#include <Adafruit_GFX.h> 

in loop

displayData();

definition

void displayData(){
  display.clearDisplay();
  display.setTextSize(2);
  drawGraph(temperatureDiff, 'C', temperatureScale, 2); //unit, real value to show, scale (f.e. display 10% as 1, where +/-1 is the max. value the graph can show), top position
  drawGraph(humidityDiff, '%', humidityScale, 45);
  display.setTextSize(1);
  display.setCursor(1, 110);
  display.print(sd_1.ss);
  display.print('s');
  display.setCursor(30 + display.width()/2, 110);
  display.print(sd_2.ss);
  display.print('s');
  display.setCursor(1, 120);
  display.print(sd_1.Vbatt);
  display.print('V');
  display.setCursor(24 + display.width()/2, 120);
  display.print(sd_2.Vbatt);
  display.print('V');
  display.display();
}

void drawGraph(float val, char unit, float scale, int marginTop) {
  int16_t x1, y1;
  uint16_t w, h;
  int x = 1;
  int y = marginTop;
  display.getTextBounds(String(val)+unit, x, y, &x1, &y1, &w, &h); //calc width of new string
  display.setCursor(x - w/2 + display.width()/2, y);
  display.print(val);
  display.print(unit);
  display.drawFastVLine(display.width()/2, marginTop+23, 10, SH110X_WHITE);
  display.drawRect(display.width()/2, marginTop+26, ((display.width()-2)*val/scale*0.5), 5, SH110X_WHITE);
}

and it seems to make a massive difference in the loop time. Could it be that I “overload” the system and therefor it’s crashing?
I thought the nrf52840 has plenty of power?

Data transfer to the I2C display unit requires a great deal of time. This has nothing to do with the performance of the nRF52840. Why not make the loop 1000mS instead of 80mS?

What happens if readSample()=false?
If you are sending Vbatt as a float, you don’t need “*1000”.

I will look into readSample().

I first wrote a small “UI”-test which only outputs cyclic data with the same functions, it works “fluid” to the eye.
I need to redraw the display way more often than 1Hz, because I need to display real time data (therefor also the use of the expensive Sensirion SHT40 sensors).

I’ll attach my current code incl. the UI-testcode if you want to take a look.
Archiv.zip (12,1 KB)

I am using SSD1306(128*64) with I2C interface and it takes about 50mS for data transfer even with 400kHz clock. 10mS loop time is too short. Especially when drawing graphs, the I2C interface is too slow to be useful. I use a display with SPI interface when drawing graphs.

oh really? I can change to SPI if that helps!
Thought of changing from clearing the whole display to only a canvas-part of it, but using SPI might be easier.
Could this cause the crash?

Does it crash if you increase the 10mS loop time?

Right now, your UI.ino is running on my SSD1306 with I2C interface. I think it is usable enough if the display content is small enough.
If you use SPI display, the drawing speed will be many times faster.

[edit]
The IMU sends data every 80mS, but I thought SHT40 would send data more frequently and overload the BLE. How about you try to transmit every 80mS to test it out!

Yes.

Just trying this out, 100ms loop timer on the peripherals. It has not crashed yet (and I’m writing this on purpose because if it does not crash within 1 minute after posting I’m probably fine :laughing:)

(and I’m writing this on purpose because if it does not crash within 1 minute after posting I’m probably fine :laughing:)

What was the effect of 100mS loop time?

After fixing the “while(central.connected())” you found, I was checking “reset-disconnect-reconnect”. Peripherals are now able to reconnect, although it takes a long time. However, sometimes it is not possible to reconnect.

1 Like

I’m very happy I could at least also help a little bit :slight_smile:

I am currently running it with 100ms loop time since 8 hours and it did not crash. Happy! And thank you so much for all your efforts.

1 Like

Hello friends. I’m currently working on a project. I’m using Seeed Studio XIAO nRF52840 Sense with the nRF52840 chip. I need to establish a connection with 2 or more Android/iOS devices using a single Seeed Studio XIAO nRF52840 module (via BLE). This way, I’ll be able to send data to the phones. Currently, I can only connect to a single phone. How can I achieve multiple phone connections using BLE? I’m developing the project with Arduino.

Hi melik,
This topic is about communication between XIAO and XIAO, and I have little experience with BLE communication between phones and XIAO.
I think you would get more direct and useful advice about connecting multiple phones to XIAO if you posted a topic separate from this one.