Increase BLE Strength/ Connection reliability of Xiao nRF52

Hi guys, i am having trouble to get a stable ble connection for my Xiao Ble.
the signal strength is around -75 to -80 db in idle when devices are really close but within a few metres i quickly becomes -100db which is equal to a disconnect command.

It is even worse, when there is multiple devices around, of course.

I have to say my uC is in a SLA Printed Housing and there is a battery packed on top of it.

I have read that you can increase the tx power of the nrf52. Can i do it within arduino to make my connetion more stable?

Hi there,
You got a picture of it? How big is the Battery?
GL :slight_smile: PJ

It is 3,50 × 3,00 × 0,50 cm. However. I cannot change the configuration right now for all my devices. That is why i want to the tx power to be increased. There must be a solution for the Xiao ble as it must be set inside the init somehow.

There is a similar question for the esp32. I would need the adaptation for the Xiao.

Hi there,
Which Libs are you using, Post up some code and we can see , YES the Xiao is able to go up to 8dB.
HTH
GL :slight_smile: PJ

Here is my github repo:

Love any advice :slight_smile:

Thanks for your effort in trying to help me, btw. I appreciate it :slight_smile:

Hi there , shure. Glad to try and help.
SO I look at this repo and to me at first glance, it’s basically a BLE central waiting on a connection to a tag with a weight as the data? Close ?
What is this dev ESP-IDF?
anyway from what I know , are these two things and you can try this.
In the radio’s it only works BEST if both sender and receiver are set. or simply the Peripheral and the Central have max power set. You can try the Central only side and may get a tiny improvement YMMV. If it’s a proprietary pc board and layout, BE aware of the antenna area and placement matters.
in your repo file
eW_BLE.cpp , you’ll see this.

#include "eW_BLE.h"

BLEDevice central;
BLEService eWeightService("49cc6a9e-0fa3-493b-b290-e1ac59909dec");


void BLEinit(const char* deviceID, BLECharacteristic charIMU, int bufferSize, BLECharacteristic charWeight, int valueSizeWeight,BLECharacteristic charButton, int valueSizeButton)
{ 

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

   //byte data[5] = { 0x0e, 0x0e, 0x0e}; //doesnt work from arduino side right now
 // BLE.setManufacturerData(data, 3);
  BLE.setAdvertisedService(eWeightService); // add the service UUID
  eWeightService.addCharacteristic(charIMU); // 
  eWeightService.addCharacteristic(charWeight);
  eWeightService.addCharacteristic(charButton);

According to the To set the BLE transmitter power level to the maximum (8 dBm) on the nRF52840 using the ArduinoBLE library, you can use the setTxPower() function provided by the ArduinoBLE library. The transmitter power level is set in dBm, and the valid values depend on your specific hardware capabilities.

I have mostly seen it used just after the Device ID call if that matters.
so the edit would be like this below;

 if (!BLE.begin()) {
    Serial.println("starting BLE failed!");
    while (1);
  }
  
  BLE.setDeviceName(deviceID);
  BLE.setLocalName(deviceID);
// Set the transmitter power level to the maximum (8 dBm)
 "color:>BLE.setTxPower(8)"
   //byte data[5] = { 0x0e, 0x0e, 0x0e}; //doesnt work from arduino side right now
 // BLE.setManufacturerData(data, 3);
  BLE.setAdvertisedService(eWeightService); // add the service UUID

In the BLEinit function,(line 7) I added the line BLE.setTxPower(8); to set the transmitter power level to 8 dBm. Adjust the value if your hardware supports different power levels.
HTH
GL :slight_smile: PJ

P.s.
The default TX power with the softdevice is 0dbm. You can change the TX power using the softdevice function sd_ble_gap_tx_power_set().

Hi PJ, almost. its a sensor module sending data to a phone, so it is a Peripheral in that case. Part of it is scanning NFC Tags and the weight they save.
The ESP-IDF link is only a similar problem where someone found a solution on the esp. I need the same solution but for the Xiao.

You say that my radios, so peripheral and central, do need the same transmission power to have the best connection? Why do you think that is. I am studying electronics and this is indeed my master thesis, eventhough my specialization is not in high frequency nor radio transmission. Still from my basic lectures i would not necessarily expect that to be true unless we are talking about impedance matching, but that is a nother story.

You are correct, i should have spend more thought about the antenna surrounding. The Xiao is placed on top of my very own designed pcb but i didnt take into account the antenna clearance areas of the xiao. So it is placed on top of a gnd plane. That is not ideal. That beeing said. Without my PCB, housing, and battery on top. The transmission power is around 5dbm better. Something but i hope to be compensated by transmission power.

Now to your solution:

BLE.setTxPower(8)

Unfortunately this is not part of the ArduinoBLE library and therefore cannot be used. I think you referred to the solution using the Adafruit Bluefruit library. I am unsure if it is possible to easily use with the Xiao. However in the context there is a function called : Bluefruit.setTxPower(txValue);.

Compilation Error: class BLEDevice' has no member named 'setPower' BLE.setPower(8);

Your second solution is really interesting though: sd_ble_gap_tx_power_set()

I just need to know how i’d be able to execute the function within my code. I tried to find the setting of the default power inside the core libraries but wouldnt find it.

Just thought another time about the power levels and wanted to make that clear. The BLE communication is bidirectional, ofc. So either side could be the bottleneck. That is probably what you talk about. I doubt that the phones are the bottlenecks in my usecase after all. That leads me to expect a raise in connection stability when only increasing the Xiao Tx Power.

FYI
On nRF52-based boards, such as the nRF52840, you can use the setTxPower function from the nRF5 SDK. To access this functionality, you may need to use the NRF52832_XXAA variant, as the NRF52840_XXAA variant may not provide direct access to some nRF5 SDK features.

Radio current
consumption DC-DC at 3v
13.6mA - TX at +8dBm output power
8.7mA – TX at +4dBm output power
5.3mA – TX at 0dBm output power
6.4mA - RX at 1Mbs

You might try this, via the soft device with the SDK libraries (it’s for S132) but supposed to be compatible if not try the second library method.

#include <ArduinoBLE.h>
#include <nRF5SDK\components\softdevice\s132\headers\nrf_soc.h>
BLEDevice central;
BLEService eWeightService("49cc6a9e-0fa3-493b-b290-e1ac59909dec");

void BLEinit(const char* deviceID, BLECharacteristic charIMU, int bufferSize, BLECharacteristic charWeight, int valueSizeWeight, BLECharacteristic charButton, int valueSizeButton)
{
  if (!BLE.begin())
  {
    Serial.println("starting BLE failed!");
    while (1)
      ;
  }

  BLE.setDeviceName(deviceID);
  BLE.setLocalName(deviceID);

  // Set the transmitter power level to the maximum (8 dBm)
  sd_ble_gap_tx_power_set(BLE_GAP_TX_POWER_ROLE_CONN, BLE_CONN_HANDLE_INVALID, 8);
 }

Make sure to include the correct paths to the nRF5 SDK headers. Note that this example assumes a simplified scenario
you’re using the S140 SoftDevice on the Xiao nRF52840, you can set the transmitter power using the sd_ble_gap_tx_power_set function as well , same way.

#include <ArduinoBLE.h>
#include <ble.h>

try those HTH
GL :slight_smile: PJ

i found the function to set the txPower. Important here is that i am using the mbed core 2.9.2 from seeeduino!

#include <AdvertisingParameters.h>
using namespace ble;

AdvertisingParameters advParams;

...
BLE.begin();
advertising_power_t tx_power = 4; // dBm // maybe not set, but doesnt affect rssi 
advParams.setTxPower(tx_power);

But as in the commentary i am not sure if it affects the hardware after all. Function returns 0 and i can use the getTxPower() function to get the correct setted value. However when i am reading the value before setting it it is constantly set to 127. That is a “wildcard” value as called in the library. It just mean that a device doesnt have preferences and is unrelated to the real txPower.

Also the RSSI wouldnt change, anyway.
I found that most smartphone manufacturers wont allow manipulation of txPower for BLE so i am trying to find another solution.

I just found that my IMU Characteristic notifies with 430 Hz for some reason. I will try to reduce that drastically as i sample my data with only 50Hz. That might affect the BER (Bit Error Rate). I read that a BER = 0.1% causes a disconnect. If i sample with lower frequency the connection might get more stable.

PJ thanks for your help. You helped me to get into the right direction!
Much appreciated :slight_smile:

1 Like