This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Scanning of Phy Coded advertising data on Android

Hello

I have a problem with the scanning of ble phy coded in Android, I need it to be continuous (or almost) but it seems that for coded it is not possible unlike with legacy.

First of all, I would like to explain briefly what the project is about.There are some nodes located in different areas called sensors nodes that read in real time the value of an oxygen sensor by saadc and the temperature and humidity. These values with the area and battery charge are coded in 6 bytes along with 32 bytes of a sha-256 hash, all of these is in the advertising (so I also use extended advertising) In addition, as this is a very noisy industrial environment I have used the lowest coding rate with fast advertising to ensure better reception with poor RSSI.

On the other hand a bridge node that reads the data encoded in the advertising (working on scan mode) processes it and generates a command to forward it through LoRaWAN (via uart). With a smartphone that supports long range it is possible to read the advertising data too, whit some fancy graphics and dashboards to display data

The point is that our client wants fast update times and since they will also be able to receive from different nodes depending on your location, I decided that the best thing to do is to advertise from the sensors by updating the advertising data every second.  The optimal when dealing with a data flow that changes so fast is to establish a connection but as there are different nodes it would have to connect separately to each one of them which I don't think is efficient so I opted to advertise the sensor nodes.

So on one hand there are the sensor nodes doing advertisement of the sensor values changing every second and on the other hand a scanner is receiving this data on the bridge node or on the smartphone. The boards I used as sensor and bridge nodes are nrf52840. The scanner mode in the bridge node works perfectly for each second shows me about 4 or 5 advertising and is a constant flow, then I have a timer to take one per second and process it.

The problem comes with android, I tried to make a continuous scan with the following parameters that are the most aggressive.

        scanSettings = new ScanSettings.Builder().setScanMode(this.scanMode)
                .setLegacy(false)
                .setPhy(ScanSettings.PHY_LE_ALL_SUPPORTED)
                .setNumOfMatches(ScanSettings.MATCH_NUM_MAX_ADVERTISEMENT)
                .setCallbackType(ScanSettings.CALLBACK_TYPE_ALL_MATCHES)
                .setMatchMode(ScanSettings.MATCH_MODE_AGGRESSIVE).build();


This is more or less continuous with legacy but not with phy coded, I have tried changing the fast advertising and raising the times but it seems that what it does is stops of about 15 or 20 seconds, putting CALLBACK_TYPE_ALL_MATCHES I receive all the advertisements, if I increase the advertisement time a little I can see for 2 or 3 seconds, with fast advertisiment only one second, 2 at most, I could attach some logs of a test application that I did only for the scanning part, but I think it is more informative this nRF connect capture where you can see this same behavior. In options I put continuous scanning with low latency and also it's possible to see that big whit some fancy graphics and dashboard to display datagap for coded that is tiny in legacy.



The part of the code related to the advertising on the sensor node is the following.

void advertising_init(void)
{
    uint32_t      err_code;
    ble_advdata_t advdata;
    uint8_t       flags = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE;

    ble_advdata_manuf_data_t manuf_specific_data;

    sd_ble_gap_adv_stop(m_adv_handle);

    manuf_specific_data.company_identifier = APP_COMPANY_IDENTIFIER;

    manuf_specific_data.data.p_data = (uint8_t *) data_and_hash;
    manuf_specific_data.data.size   = 35;

    // Build and set advertising data.
    memset(&advdata, 0, sizeof(advdata));

    advdata.name_type             = BLE_ADVDATA_NO_NAME;
    // beacons has no flags
    advdata.p_manuf_specific_data = &manuf_specific_data; // all data here
    advdata.include_appearance    = false;

    // Initialize advertising parameters (used when starting advertising).
    memset(&m_adv_params, 0, sizeof(m_adv_params));

    m_adv_params.properties.type = BLE_GAP_ADV_TYPE_EXTENDED_NONCONNECTABLE_NONSCANNABLE_UNDIRECTED; // lowest bitrate 125kbps
    m_adv_params.p_peer_addr     = NULL;    // Undirected advertisement.
    m_adv_params.filter_policy   = BLE_GAP_ADV_FP_ANY;
    m_adv_params.interval        = APP_ADV_INTERVAL;
    m_adv_params.duration        = 0;       // Never time out.
    m_adv_params.primary_phy     = BLE_GAP_PHY_CODED; // for coded advertisement
    m_adv_params.secondary_phy   = BLE_GAP_PHY_CODED; // for coded advertisement
    m_adv_params.filter_policy   = BLE_GAP_ADV_FP_ANY;

    err_code = ble_advdata_encode(&advdata, m_adv_data.adv_data.p_data, &m_adv_data.adv_data.len);
    APP_ERROR_CHECK(err_code);

    err_code = sd_ble_gap_adv_set_configure(&m_adv_handle, &m_adv_data, &m_adv_params);
    APP_ERROR_CHECK(err_code);

    // set 8 dbm of tx_power (max)
    err_code = sd_ble_gap_tx_power_set(BLE_GAP_TX_POWER_ROLE_ADV, m_adv_handle, 8);
    APP_ERROR_CHECK(err_code);
}


It is a behavior similar to the one of a beacon but changing the data every second

In a nutshell, I think that the option to make advertisement with new values every second is the most viable for this use case but the problem is that it doesn't seem to work well for android scanning, at least not like in the dongle. The phone I am using is a oneplus 6T and according to the nordic app it supports all bluetooth 5 features. I'm aware that Android doesnt like scanning intensive modes (plus these drain your battery) but is there any chance to get the scanning of ble coded as fast as the one of legacy on Android? If this is not possible I guess I'll choose to establish a connection with the phone to the bridge node and send the data stream directly to the phone, as a bridge node is in range with several sensors it's possible to see the data from them on the phone, so if you are moving from zone to zone just connect to the bridge node of the zone, it's not as fast as moving and directly read the sensor that is in range but it's better than connecting to each one separately.

Thanks in advance

  • Hi

    The nRFConnect screenshot is reminiscent of an Android phone not supporting Coded PHY fully. Multiple phones state that they support Coded PHY in the app because the app checks this by checking the Android stack if it supports BLE 5.0, where Coded PHY is an optional feature.

    The reason you're able to see these short periods of advertisements is because this is the amount of time the devces are advertising on the primary advertising channels (37, 38, & 39). The rest of the advertisement in Coded PHY advertising is done on secondary channels, which a phone not supporting Coded PHY will not be able to "see".

    If you use a phone supporting Coded PHY you should be able to see a "complete" scan of Coded PHY advertisements as well.

    Is there a specific reason you're using Coded PHY for these advertisement? I don't see how it's well suited here, as Coded PHY advertisements take ~8 times longer to do than on the Uncoded PHYs (1MBPS and 2MBPS). Are these sensor nodes located too far away from the scanning module(s)? 

    Best regards,

    Simon

  • Hi Simon

    Tanks for the replay, I understand that the problem is whit my phone that cannot support the secondary PHY as coded and for that reason I cannot see the advertisement done in the secondary PHY, I guess I'll do the other approach that commented before. But we'll developing more Bluetooth 5 related projects in a near future, I have some nrf dongles with Bluetooth 5.2 that probably test for some precise indoor location project. It's possible to get a list of android devices (smartphone/tablet) that fully support all Bluetooth 5 features?

    Is there a specific reason you're using Coded PHY for these advertisement? I don't see how it's well suited here, as Coded PHY advertisements take ~8 times longer to do than on the Uncoded PHYs (1MBPS and 2MBPS). Are these sensor nodes located too far away from the scanning module(s)? 

    Maybe not in the line of sight but keep in mind that it is a very noisy environment. Inside it's impossible to get GSM/GPS coverage, it's like a Faraday cage, that's why we use LoRa to communicate with the outside but even to communicate on the inside the noise are also quite big. The reason why we do not use LoRa for indoor communication is because of the low bandwidth, the communication with the outside does not matter if it is delayed but the indoor one has to be fast. We have tried Ble legacy and it did not offer as good coverage as Phy Coded, at this moment I have code it for the most extreme case, I know that with the lowest coding rate in the device and extended advertising I have the potential to cause the three advertising channels to become congested and with fast advertisement the 650mA node batteries are drained in 17 hours but it would be a question of adjusting it to find a good balance between coverage and transmission speed.

    Regards

  • Hi

    I'm sorry, but we have no such list, as the sheer number of phones that would require testing is too large to make a comprehensive list of this. Most of the latest high-end phones and flagship models the last couple of years. For example, the later OnePlus models, the Samsung S10 and newer, etc. It is in our backlog (for the nRFConnect app that is) to check whether the phone supports Coded PHY "correctly" or not, but this is not in place as of yet. Please look out for it in future updates.

    Thank you for explaining your predicament, I think I understand, but I think you have a lot of trial and error in front of you to find this balance.

    Best regards,

    Simon

Related