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

Disconnected: 0 BLEHci.remote_user_terminated_connection [using pc_ble_driver_py]

Hello,

I am using the nordic nRF52840-DK and trying to connect to a nRF52840-Dongle and sending/receiving data to custom services and characteristics using pc_ble_driver_py. I modified the heart rate collector.

But the problem is that when I am connected to the Dongle the connection last 25 to 30 secondes and I receive a message : "Disconnected: 0 BLEHci.remote_user_terminated_connection" and the error message is : "line 477, in write_req attr_handle = self.db_conns[conn_handle].get_char_value_handle(uuid) KeyError: 0". However, when I use the nRF connect mobile/PC version I don't have this problem so I think it is a problem with my code. I check it out if there is some time out equal to like 25_30 secondes but I didn't find any solution.

Could someone help me please to find some solution.

Thanks in advance.

Cordially

Joe

  • Hello,

    I edited the function connect() and I added a tag = 1 = CFG_TAG (the macro in the line number 33), I don't have anymore the problem BLEHci.remote_user_terminated_connection neither the errors.

    However, after like 250~253 secondes the connection will stop and I receive the message below :

    ---> Disconnected: 0 BLEHci.conn_interval_unacceptable

    Does anyone have any solution?

    Thanks in advance.

    Joe

  • Again, it should be possible to find where you are calling sd_ble_gap_disconnect() in your project, you can search for it in your project. I would assume it called in ble_conn_params.c, where you can find sd_ble_gap_disconnect(conn_handle, BLE_HCI_CONN_INTERVAL_UNACCEPTABLE);.

    Typically setting cp_init.disconnect_on_fail             = false; when calling ble_conn_params_init() in main.c can remedy this.

    Kenneth

  • Hello,

    I misunderstood previous messages, I guess when you told me to check the sd_ble_gap_disconnect you meant on the C embedded code of the nRF device. I will double check that with the engineer who developped the embedded code.
    We also tried MIN_CONNECTION_INTERVAL and MAX_CONNECTION_INTERVAL timing modification (400ms and 650ms) as mentioned in https://devzone.nordicsemi.com/f/nordic-q-a/51542/pca10059-pca10056-pc-ble-driver-py-hrcollector-example , but we still have the disconnection issue after about 250s.

    However, the nRF firmware works well with our smartphone application and also with nRF connect on Android, iOS and windows.
    I also tried Bleak library with python that uses the PC bluetooth LE <Microsoft Bluetooth LE Enumerator> from intel(R) wireless Bluetooth(R), and it worked well.
    However using the nRF52840-DK with pc-ble-driver-py or blatann which is based on pc-ble-driver-py, I still face the disconnecting problem.

    So it seems more probable that the issue come from the BLE connection function in the python code and not from the nRF firmware itself.
    PS---> I will leave a code in attachements.
    To run the code you have to modify:
    • the mac adress at the line 26 respecting the spécific format as showed in the comment. To get the mac adress you can use the nrf connect BLE application.
    • the serial communication port at the line 110

    from time import sleep
    from queue import Queue, Empty
    from pc_ble_driver_py.observers import *
    
    global config, BLEDriver, BLEAdvData, BLEEvtID, BLEAdapter, BLEEnableParams, BLEGapTimeoutSrc, BLEUUID, BLEUUIDBase, BLEConfigCommon, BLEConfig, BLEConfigConnGatt, BLEGapScanParams
    from pc_ble_driver_py import config
    
    config.__conn_ic_id__ = "NRF52"
    
    from pc_ble_driver_py.ble_driver import (
        BLEDriver,
        BLEAdvData,
        BLEEvtID,
        BLEEnableParams,
        BLEGapTimeoutSrc,
        BLEUUID,
        BLEUUIDBase,
        BLEGapScanParams,
        BLEConfigCommon,
        BLEConfig,
        BLEConfigConnGatt,
    )
    # noinspection PyUnresolvedReferences
    from pc_ble_driver_py.ble_adapter import BLEAdapter
    
    TARGET_PEER_ADDR = [111, 222, 333, 444, 555, 666]  # <-- here you put your target address in this format
    CONNECTIONS = 1
    CFG_TAG = 1
    nrf_sd_ble_api_ver = config.sd_api_ver_get()
    
    
    class HR(BLEDriverObserver, BLEAdapterObserver):
    
        def __init__(self, adapter):
            super(HR, self).__init__()
            self.adapter = adapter
            self.conn_q = Queue()
            self.adapter.observer_register(self)
            self.adapter.driver.observer_register(self)
            self.adapter.default_mtu = 250
    
        def open(self):
            self.adapter.driver.open()
            gatt_cfg = BLEConfigConnGatt()
            gatt_cfg.att_mtu = self.adapter.default_mtu
            gatt_cfg.tag = CFG_TAG
            self.adapter.driver.ble_cfg_set(BLEConfig.conn_gatt, gatt_cfg)
            self.adapter.driver.ble_enable()
    
        def close(self):
            self.adapter.driver.close()
    
        def connect_and_discover(self):
            scan_duration = 180
            params = BLEGapScanParams(interval_ms=200, window_ms=150, timeout_s=scan_duration)
    
            self.adapter.driver.ble_gap_scan_start(scan_params=params)
    
            try:
                new_conn = self.conn_q.get(timeout=scan_duration)
                self.adapter.service_discovery(new_conn)
    
                return new_conn
            except Empty:
                return None
    
        def on_gap_evt_connected(self, ble_driver, conn_handle, peer_addr, role, conn_params):
            print("New connection: {}".format(conn_handle))
            self.conn_q.put(conn_handle)
    
        def on_gap_evt_disconnected(self, ble_driver, conn_handle, reason):
            print("Disconnected: {} {}".format(conn_handle, reason))
    
        def on_gap_evt_adv_report(self, ble_driver, conn_handle, peer_addr, rssi, adv_type, adv_data):
            if BLEAdvData.Types.complete_local_name in adv_data.records:
                dev_name_list = adv_data.records[BLEAdvData.Types.complete_local_name]
    
            elif BLEAdvData.Types.short_local_name in adv_data.records:
                dev_name_list = adv_data.records[BLEAdvData.Types.short_local_name]
    
            else:
                return
            dev_name = "".join(chr(e) for e in dev_name_list)
            address_string = ":".join("{0:02X}".format(b) for b in peer_addr.addr)
            if peer_addr.addr == TARGET_PEER_ADDR:
                self.adapter.connect(peer_addr, tag=1)
    
        def on_notification(self, ble_adapter, conn_handle, uuid, data):
            if len(data) > 32:
                data = "({}...)".format(data[0:10])
            print("Connection: {}, {} = {}".format(conn_handle, uuid, data))
    
    
    def main(selected_serial_port):
        print("Serial port used: {}".format(selected_serial_port))
        driver = BLEDriver(serial_port=selected_serial_port, auto_flash=False, baud_rate=1000000, log_severity_level="info")
        adapter = BLEAdapter(driver)
        collector = HR(adapter)
        collector.open()
        conn = collector.connect_and_discover()
    
        if conn is not None:
            while True:
                pass
    
        collector.close()
    
    
    if __name__ == "__main__":
        main("COM9")  # <-- here you put your serial communication "COM" number
    
  • I can only assume that the dongle (operating in the central role) will be receiving an BLE_GAP_EVT_CONN_PARAM_UPDATE request from the peer device (operating in peripheral device). See here for an example:

    https://infocenter.nordicsemi.com/topic/com.nordic.infocenter.s140.api.v6.1.1/group___b_l_e___g_a_p___c_e_n_t_r_a_l___c_p_u___m_s_c.html

    If this event is unhandled or not accepted, it is likely that the peer device may disconnect based on the configuration set during ble_conn_params_init().

  • Hello,

    I tested the blinky example in the SDK on the dongle :

    • nRF5_SDK_17.0.2_d674dde\examples\ble_peripheral\ble_app_blinky\hex\pca10059\hex\ble_app_blinky_pca10059_s140.hex

    I can send data to the dongle from nrfconnect PC app, and it still connected to it as long as you don’t disconnect it. However, when using the python library, I will receive the same error and the connection will lost.

    Could you please try to run the last python script modifying the adress mac corresponding to the dongle with the blinky firmware and the serial communication port corresponding to the nrf52840-DK board.

    thanks

    Joe

Related