Nano 33 ble nRF52840 - BLE long range/pairing ? Mbed BLE API ? Adafruit Lib?

Hello everyone,

Someone has been able to reach 200m with the right code to use long range that says Colas71? I have achieved some improvement but not so much, with ble legacy around 20 or 22m as someone said in the post and with LE_Coded between 55 or 60m, better but still far from the 200m. By the way I think that it is not commented in the post but I suppose that apart from using a smartphone that supports Ble 5 long range you are using the app "nRF connect" to establish the connection, in my case if in connect I set LE Coded in "Set initial preferred PHY" it works but only occasionally, the thing is that I don't care about the connection because what I need is to generate beacons where the information is coded in the uuid so I adapted the code of Colas71 to generate an ibeacon.

/*--------INCLUDES--------*/
#include "ble/BLE.h"
/*------------------------*/

using namespace mbed;       // Enable us to call mbed functions without "mbed::"

/*------------GLOBAL VARIABLES-------------*/
const static char DEVICE_NAME[] = "LR Beacon";                    // Device name when detected on Bluetooth
static events::EventQueue event_queue(/* event count */ 16 * EVENTS_EVENT_SIZE);
static const uint16_t MAX_ADVERTISING_PAYLOAD_SIZE = 59;        // Advertising payload parameter
const ble::phy_set_t CodedPHY(ble::phy_t::LE_CODED);            // Creating a Coded Phy set
/*-----------------------------------------*/


/*------------------------------Bluetooth Device class------------------------------*/

class BeaconDemo : ble::Gap::EventHandler {
public:
    BeaconDemo(BLE &ble, events::EventQueue &event_queue) :
        _ble(ble),
        _event_queue(event_queue),
        _adv_data_builder(_adv_buffer) { }

    void start() {
        _ble.gap().setEventHandler(this);

        _ble.init(this, &BeaconDemo::on_init_complete);

        _event_queue.dispatch_forever();
    }

private:

    /** Callback triggered when the ble initialization process has finished */
    void on_init_complete(BLE::InitializationCompleteCallbackContext *params) {
        if (params->error != BLE_ERROR_NONE) {
            Serial.println("Ble initialization failed.");
            return;
        }

        Serial.println("Ble initialized.");

        start_advertising();
    }

    void start_advertising() {
        /* Create advertising parameters and payload */

        ble::AdvertisingParameters adv_parameters(
            //ble::advertising_type_t::CONNECTABLE_UNDIRECTED,
            ble::advertising_type_t::CONNECTABLE_NON_SCANNABLE_UNDIRECTED,
            ble::adv_interval_t(ble::millisecond_t(500)),  
            ble::adv_interval_t(ble::millisecond_t(1000)),
            false
        );

        adv_parameters.setPhy(ble::phy_t::LE_CODED, ble::phy_t::LE_CODED);  // Set Advertising radio modulation to LE_CODED Phy (=Long Range)
        adv_parameters.setTxPower(8);                                       // Set radio output power to 8dbm (max)
        _ble.gap().setPreferredPhys(&CodedPHY, &CodedPHY);                  // Set preferred connection phy to LE_CODED (=long range)

        _adv_data_builder.setFlags();

        static const uint8_t ibeacon_raw[] = {0x00, 0x4C, 0x02, 0x15, 0xE2, 0x0A, 0x39, 0xF4, 0x73, 0xF5, 0x4B, 0xC4, 0xA1, 0x2F, 0x17, 0xD1, 0xAD, 0x07, 0xA9, 0x61, 0x11, 0x22, 0x33, 0x44, 0xC8};
        
        _adv_data_builder.setManufacturerSpecificData(ibeacon_raw);


        /* Setup advertising */

        ble_error_t error = _ble.gap().setAdvertisingParameters(
            ble::LEGACY_ADVERTISING_HANDLE,
            adv_parameters
        );

        if (error) {
            Serial.println("_ble.gap().setAdvertisingParameters() failed");
            return;
        }

        error = _ble.gap().setAdvertisingPayload(
            ble::LEGACY_ADVERTISING_HANDLE,
            _adv_data_builder.getAdvertisingData()
        );

        if (error) {
            Serial.println("_ble.gap().setAdvertisingPayload() failed");
            return;
        }

        /* Start advertising */

        error = _ble.gap().startAdvertising(ble::LEGACY_ADVERTISING_HANDLE);

        if (error) {
            Serial.println("_ble.gap().startAdvertising() failed");
            return;
        }
    }

private:
    /* Event handler */

    void onDisconnectionComplete(const ble::DisconnectionCompleteEvent&) {
        _ble.gap().startAdvertising(ble::LEGACY_ADVERTISING_HANDLE);
    }

private:
    BLE &_ble;
    events::EventQueue &_event_queue;

    uint8_t _adv_buffer[ble::LEGACY_ADVERTISING_MAX_SIZE];
    ble::AdvertisingDataBuilder _adv_data_builder;
};

/** Schedule processing of events from the BLE middleware in the event queue. */
void schedule_ble_events(BLE::OnEventsToProcessCallbackContext *context) {
    event_queue.call(Callback<void()>(&context->ble, &BLE::processEvents));
}

/*====================== MAIN CODE ======================*/

void setup(){
    /* Setup Debugging */
    Serial.begin(9600);
    while(!Serial);

    /* Low Power */
    digitalWrite(LED_PWR, LOW);                 // Turn off power LED
    digitalWrite(PIN_ENABLE_SENSORS_3V3, LOW);  // Turn off sensors
    NRF_POWER->DCDCEN = 0x00000001;             // Enable DCDC
    /*           */

    BLE &ble = BLE::Instance();                 // Create the BLE object in order to use BLE_API function
    ble.onEventsToProcess(schedule_ble_events); // Set event schedule

    BeaconDemo demo(ble, event_queue);
    demo.start();                               // Start Bluetooth Long Range
}

void loop(){}

Basically is to add the CONNECTABLE_NON_SCANNABLE_UNDIRECTED option to the advertisement and set phy to LE_Coded and tx power to 8 dBi, then generate the ibeacon

I am using a One Plus 6T that as it shows the capture has all the options for Ble 5, in addition I attach the captures of the beacons one with legacy beacon to around 22m and the other with long range beacon to around 60m, both with a rssi near the limit of range.