How to activate LongRange using PlatformIO/Arduino/Bluefruit

I would really like to use Bluefruit and make a Long Range connection between Servers and my Central. I know that it is not build in Bluefruit by default, but there must be a way to get that done. Who can help me what to change to get Long Range to work?

I first try to update the coding to BLE_GAP_PHY_CODED right after a connect. I do that by calling set_coded_phy from the connect_event routine. The conn_handle is available there. I use the routine below, bu I keep getting error 19. I cannot change sdk_config.h because it is not the SDK but Adafruit lib in Android. I burned the bootloader: feather_nrf52840_sense_bootloader-0.9.2_s140_6.1.1.hex

void set_coded_phy(uint16_t conn_handle)
{
    ble_gap_phys_t phys;
    phys.tx_phys = BLE_GAP_PHY_CODED; // Gebruik Coded PHY voor transmissie
    phys.rx_phys = BLE_GAP_PHY_CODED; // Gebruik Coded PHY voor ontvangst

    // Stuur een PHY update request
    uint32_t err_code = sd_ble_gap_phy_update(conn_handle, &phys);
    if (err_code == NRF_SUCCESS) {
        log_p("Request PHY-update send.");
    } else if (err_code == NRF_ERROR_RESOURCES) {
        log_p("Too few resources (Error 19). try again later.");
    } else {
        log_p("Error LongRange PHY: %d", err_code);
    }
}

Does anyone have a tip for me how to make this work?
Many thanks in advance.

Parents
  • Hi Dirk, 
    I'm not so familiar with the Bluefruit board and the Adafruit ecosystem. But can you tell which SDK you are developing on ? 
    From what you provided in the code, it seems it's NRF5 SDK? 
    Note that when you call sd_ble_gap_phy_update() as a peripheral, it can only request the central to switch PHY. If the central doesn't want to switch PHY you will not be able to update to CODED PHY. 
    Please try using a nRF sniffer to check if the request is actually sent. 

Reply
  • Hi Dirk, 
    I'm not so familiar with the Bluefruit board and the Adafruit ecosystem. But can you tell which SDK you are developing on ? 
    From what you provided in the code, it seems it's NRF5 SDK? 
    Note that when you call sd_ble_gap_phy_update() as a peripheral, it can only request the central to switch PHY. If the central doesn't want to switch PHY you will not be able to update to CODED PHY. 
    Please try using a nRF sniffer to check if the request is actually sent. 

Children
  • Hi Hung,

    Thanks for your reply. It looks indeed like the Bluefruit API is build on NRF5 SDK, but in the Bluefruit sources I cannot find the SDK headers (only few I can find). In above example, the central is requesting to switch to CODED PHY. Is that wrong, should the peripheral request CODED PHY? 

    I am not using a default Bluefruit device, I am using an EBYTE E73-2G4M08S1CX (with the nRF52840 inside), have added a crystal and load bootloader Bluefruit + Softdevice   feather_nrf52840_sense_bootloader-0.9.2_s140_6.1.1.hex. That works fine on all examples with Bluefruit. 

    I will try the sniffer, good idea!

  • Hi, 

    I'm sorry I didn't notice that you receive error 19 ( NRF_ERROR_RESOURCES) when calling sd_ble_gap_phy_update()
    I checked the function and don't see that error in the possible list of error when calling that function: 

    /**@brief Initiate or respond to a PHY Update Procedure
     *
     * @details   This function is used to initiate or respond to a PHY Update Procedure. It will always
     *            generate a @ref BLE_GAP_EVT_PHY_UPDATE event if successfully executed.
     *            If this function is used to initiate a PHY Update procedure and the only option
     *            provided in @ref ble_gap_phys_t::tx_phys and @ref ble_gap_phys_t::rx_phys is the
     *            currently active PHYs in the respective directions, the SoftDevice will generate a
     *            @ref BLE_GAP_EVT_PHY_UPDATE with the current PHYs set and will not initiate the
     *            procedure in the Link Layer.
     *
     *            If @ref ble_gap_phys_t::tx_phys or @ref ble_gap_phys_t::rx_phys is @ref BLE_GAP_PHY_AUTO,
     *            then the stack will select PHYs based on the peer's PHY preferences and the local link
     *            configuration. The PHY Update procedure will for this case result in a PHY combination
     *            that respects the time constraints configured with @ref sd_ble_cfg_set and the current
     *            link layer data length.
     *
     *            When acting as a central, the SoftDevice will select the fastest common PHY in each direction.
     *
     *            If the peer does not support the PHY Update Procedure, then the resulting
     *            @ref BLE_GAP_EVT_PHY_UPDATE event will have a status set to
     *            @ref BLE_HCI_UNSUPPORTED_REMOTE_FEATURE.
     *
     *            If the PHY Update procedure was rejected by the peer due to a procedure collision, the status
     *            will be @ref BLE_HCI_STATUS_CODE_LMP_ERROR_TRANSACTION_COLLISION or
     *            @ref BLE_HCI_DIFFERENT_TRANSACTION_COLLISION.
     *            If the peer responds to the PHY Update procedure with invalid parameters, the status
     *            will be @ref BLE_HCI_STATUS_CODE_INVALID_LMP_PARAMETERS.
     *            If the PHY Update procedure was rejected by the peer for a different reason, the status will
     *            contain the reason as specified by the peer.
     *
     * @events
     * @event{@ref BLE_GAP_EVT_PHY_UPDATE, Result of the PHY Update Procedure.}
     * @endevents
     *
     * @mscs
     * @mmsc{@ref BLE_GAP_CENTRAL_PHY_UPDATE}
     * @mmsc{@ref BLE_GAP_PERIPHERAL_PHY_UPDATE}
     * @endmscs
     *
     * @param[in] conn_handle   Connection handle to indicate the connection for which the PHY Update is requested.
     * @param[in] p_gap_phys    Pointer to PHY structure.
     *
     * @retval ::NRF_SUCCESS Successfully requested a PHY Update.
     * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
     * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied.
     * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
     * @retval ::NRF_ERROR_NOT_SUPPORTED Unsupported PHYs supplied to the call.
     * @retval ::NRF_ERROR_INVALID_STATE No link has been established.
     * @retval ::NRF_ERROR_BUSY Procedure is already in progress or not allowed at this time. Process pending events and wait for the pending procedure to complete and retry.
     *
     */
    SVCALL(SD_BLE_GAP_PHY_UPDATE, uint32_t, sd_ble_gap_phy_update(uint16_t conn_handle, ble_gap_phys_t const *p_gap_phys));

    So it's quite strange that you are seeing that. Have you tried to change to request 1Mbps instead of Coded PHY to see if you get the same error. 


    I don't see a problem if the peripheral send the request to switch to CODED PHY. The question is if the central support CODED PHY and accept switching to CODED PHY. 
    But you first need to check why error 19 is returned. 

    My suggestion is to get started with a DK and you can start with nRF Connect SDK . It 's a much updated platform and from my point of view much easier to get started with. 

    We have this Dev Academy here that you can follow along: academy.nordicsemi.com/

  • Thanks for the update. I succeeded in setting CODED PHY after a connection is set up. If you try too early, it raises an error. Also you must change the 2 len parameters in bluefruit.h:

    in bluefruit.cpp
      _sd_cfg.prph.mtu_max     = BLE_GATT_ATT_MTU_DEFAULT;
      _sd_cfg.prph.event_len   = BLE_GAP_EVENT_LENGTH_CODED_PHY_MIN; //BLE_GAP_EVENT_LENGTH_DEFAULT;
      _sd_cfg.prph.hvn_qsize   = BLE_GATTS_HVN_TX_QUEUE_SIZE_DEFAULT;
      _sd_cfg.prph.wrcmd_qsize = BLE_GATTC_WRITE_CMD_TX_QUEUE_SIZE_DEFAULT;
    
      _sd_cfg.central.mtu_max     = BLE_GATT_ATT_MTU_DEFAULT;
      _sd_cfg.central.event_len   = BLE_GAP_EVENT_LENGTH_CODED_PHY_MIN; //BLE_GAP_EVENT_LENGTH_DEFAULT;
      _sd_cfg.central.hvn_qsize   = BLE_GATTS_HVN_TX_QUEUE_SIZE_DEFAULT;
      _sd_cfg.central.wrcmd_qsize = BLE_GATTC_WRITE_CMD_TX_QUEUE_SIZE_DEFAULT;

    I am not able to have devices advertise, scan or connect in CODED PHY using Bluefruit lib, unfortunately. I tried the academy, but that is based on the Zephyr SDK, and that is all all new. And buggy (got strange errors compiling samples). Too complex for now. 

Related