Revert back to Coded PHY connection when 2M is not possible because of distance.

Hi,

I have 2 nrf52840 DK boards advertising on coded PHY mode. Once connected the connection is updated (using sd_ble_gap_phy_update()) to use 2M mode. No problem in doing so.

However, I have a situation or use case where after the successful update to 2M mode, but because of the distance between the 2 boards is too far for 2M mode to continue, I would like the connection to revert back down to coded PHY. Is that even possible in the first place? If it is possible, what are steps required to revert back to coded PHY.

In my testing,

I tried walking around to find the distance that is too far for 2M communication but still possible with Coded PHY. 

What I find is that they always connect on coded and then updated to 2M. When the distance is too far apart, there is no connection at all even on coded PHY. 

I can't find a distance/case where they connect on coded PHY but fail to update to 2M because of distance.

Some may say why not just connect on coded PHY and forget about 2M. My case is we want to use 2M whenever possilbe and auto revert down to coded PHY when physical distance does not allow 2M mode.

Your help is very much appreciated.

Parents
  • Hi again

    What is the distance you're seeing between the two devices exactly? Are you able to see the MTU/PHY update in logging or something to make sure you actually move to the 2MBPS PHY? Your advertising parameters seem to be correct, so I would think it advertises on the Coded PHY at least.

    Best regards,

    Simon

  • Hi Simon,

    The distance is approximately 100 metres. Note that this is conducted on a noisy street with buildings on either sides of the road. One of the board is laying flat on the walk steps hence the reception might not be that great.

    Yes, I saw from the logging that PHY is updated to 2MBPS.

    Thanks for the confirmation on the code.

    Correct me if I am wrong, but I think the "handshake" between central and peripheral is still taking place on Coded PHY when sd_ble_gap_phy_update() is taking place and when they are both updated to 2M, because of the distance is too far for 2M to support, the devices would disconnect after a short interval, say between 1 to 5 seconds? Shoudl this be the expected observation?

    Can you help to confirm if this is the case?

    You can make the central device check the RSSI (Received Signal Strength Indicator) of the peripheral and when it's under a certain value you can trig a PHY update to switch to the Coded PHY.

    I think for my use case, it would be more of always connect in Coded PHY and if RSSI value is strong (which means devices are close to each other) trigger a PHY update to switch to 2M. Will that work?

Reply
  • Hi Simon,

    The distance is approximately 100 metres. Note that this is conducted on a noisy street with buildings on either sides of the road. One of the board is laying flat on the walk steps hence the reception might not be that great.

    Yes, I saw from the logging that PHY is updated to 2MBPS.

    Thanks for the confirmation on the code.

    Correct me if I am wrong, but I think the "handshake" between central and peripheral is still taking place on Coded PHY when sd_ble_gap_phy_update() is taking place and when they are both updated to 2M, because of the distance is too far for 2M to support, the devices would disconnect after a short interval, say between 1 to 5 seconds? Shoudl this be the expected observation?

    Can you help to confirm if this is the case?

    You can make the central device check the RSSI (Received Signal Strength Indicator) of the peripheral and when it's under a certain value you can trig a PHY update to switch to the Coded PHY.

    I think for my use case, it would be more of always connect in Coded PHY and if RSSI value is strong (which means devices are close to each other) trigger a PHY update to switch to 2M. Will that work?

Children
  • Hi

    100 meters in a noisy environment as you describe, does indeed sound like too far away for a 2MBPS PHY connection, I would think you need to get as close as 20 meters to get a good connection on the 2MBPS PHY. sd_ble_gap_phy_update() is used to initiate or respond to a PHY update procedure. It will always generate a BLE_GAP_EVT_PHY_UPDATE event if executed successfully. Yes, it will stay on the current PHY within this function, then generate a PHY_UPDATE event (if successful) which will cause the devices to move to the new PHY.
    /**@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 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 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));
    JasonGeo said:
    always connect in Coded PHY and if RSSI value is strong (which means devices are close to each other) trigger a PHY update to switch to 2M

    Yes, that should work as well.

    Best regards,

    Simon

  • Thanks Simon,

    Will try to do some more testing with the distance as suggested.

    I am abit concern now if I did indeed connect on 2MBPS at 100 metres. Maybe it was still on Coded PHY!

    A side note, we have the Tx power set to 8dBm, a high one. Not sure if it says something.

    Just to confirm if the Central initiate the PHY update, do we have to confirm on BOTH the peripheral and central side that they both received the BLE_GAP_EVT_PHY_UPDATE event before we can be sure that the connection link is indeed updated to 2 MBPS?

    Any other means to check for current PHY status?

    Because currently, I only handle that event in the peripheral, not the central.

    Is it still possible that we connect on 2MBPS only to disconnect almost instantaneously because of poor reception or interference?

  • Hi

    I think the easiest way to make sure what PHY is used is to either print in a log what PHY is currently used, or to use a sniffer device to catch the packets on the air and see what PHY it is sent over. I'm only aware of the Ellisys sniffers that support sniffing over the Coded PHY, but you could use the nRF Sniffer to detect any activity on the 2MBPS PHY at least. You can also choose the advertising device so you don't catch a lot of random BLE activity as well.

    You can also only use 2MBPS to connect and check what range you are able to achieve, as I don't know how noisy your test environment is. Even though I don't think you'll be able to reach 100m in a noisy environment even with 8dBm TX power.

    Best regards,

    Simon

  • Hi Simon,

    I've setup the nRF Sniffer in the office and verified that we are advertising in coded PHY and then successfully updated the PHY mode to 2Mbps on connection. All subsequent transactions are in 2Mbps.

    I do noticed too as the distance increases while connected on 2M, I saw a lot more L2CAP Fragment with the CRC Error flag set. Does that mean something I need to take note of?

    Thereafter I went and do more range testing this time in an open area. Same setup as before, advertising in Coded PHY, on succesful connection update PHY to 2Mbps.

    Findings,

    I am able to connect on coded PHY and update to 2Mbps every single time up to a distance of around 200 metres. As I then walked further, the boards disconnected and I am not able to reconnect again until I walked back into range i.e. 200 metres.

    I then modified my code to only adv and connect on Coded PHY, NO UPDATE of PHY to 2 Mbps. I observed the same results as before! I thought I will be able to get couple of hundreds metres more than 2 Mbps but No.

    Can you please help me with this last question. If we can connect on Coded PHY adv, we can always update to 2Mbps regardless of the distance (say 1 Km) since we both agree sd_ble_gap_phy_update() function takes place in the current PHY which is Coded yes? And if on successful update to 2Mbps (PHY PHY_UPDATE event trig), because the distance is now too great for 2Mbps to support, a disconnection will result instaneously? or will it not?

    Thanks Simon.

Related