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

Regarding Python Scripts for nrf52840 to connect and transfer data.

Hi ,

What I am trying:- 

-connect the custom board with nrf52840 chip using nrf52 dongle on pc with python.

-Already set some commands on custom board so when my pc (via dongle) connects to custom board, I want to send some commands and accordingly receive the response.

For this I got my hands-on nrf dongle to give my laptop a BLE access.

And I am trying to access the board using dongle (using python script) and I am getting below error,


raise NordicSemiException('Failed to {}. Error code: {}'.format(wrapped.__name__, err_code))
pc_ble_driver_py.exceptions.NordicSemiException: Failed to open. Error code: 13.

Would anyone able to tell me how do i resolve this. 

I want to have python code that can connect and do some data transfer over BLE using Dongle connected to my pc and I have tried with hart_rate_monitor unsuccessfully. 

EDIT 1:- I am able to scan and connect my board using the nRF Connect windows app. Same I wanted to implement over python.

Thanks,

Hinesh

Parents
  • Hi,

    Can you provide the full command that you run (for starting the python script) and all output to the command line afterwards? (Both what parameters you send to the script, any debug output, and the full traceback may give clues as to what is the problem.)

    Regards,
    Terje

  • HI

    Actually I have resolved the above error.

    By going through various questions and answers here I came to know some tools.

    So When I was opening 'nrf connect' windows app , it was flashing firmware and I was having impression that this will be samefirmware will be used for scanning and connect via python. But It was not working.

    And the I have installed windows command line tools and format the board using 'nrfproject' command. And Let the python  application 'Hear rate monitor' do the flashing. Then it started working.

    It seems the mismatch on the firmware version on nrf52840 PDK Board (that I am using as dongle to connect to custom board via my pc).

    So To come on another query I have,

    Can you point me any example or script that can do the same work as 'nrf connect' does?

    Scan, connect (to particular given mac id) and explore services of connected device.


    Basically I am trying what I have explained on above question.

    This would be very help full for us as we are already on advance stage for development.

    Thanks,

    Hinesh

  • Hi  

    Thank you for the response.

    You are correct the code on the other end will not change.

    however the code which I am using to connect also I keeping same, except checking with UUID's. A trial and error to remove the ': CCCD not found' by debugging. 

    inserting code which is right now, but not working

    import Queue
    
    import json
    import time
    import sys
    
    from datetime import datetime, timedelta
    from bitstruct import *
    from pprint import pformat
    import binascii
    from pc_ble_driver_py.observers import *
    from nordicsemi.ble_adapter import *
    
    try:
        with open("Config_Files/Connection_Settings.json")as conn:
            config = json.load(conn)
    except Exception as e:
        print str(e)
        print 'Could not open settings file'
        raw_input("Press ENTER to exit...")
        quit()
    
    
    
    
    ##### NRF PART ################
    CCCD_UUID = '00002902-0000-1000-8000-00805f9b34fb'
    
    DC_SERVICE_BASE_UUID = BLEUUIDBase([0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x10, 0x00,
                                        0x80, 0x00, 0x00, 0x80, 0x5f, 0x9b, 0x34, 0xfb])
    
    DATA_CHAR_UUID  = BLEUUID(0x2222, DC_SERVICE_BASE_UUID)
    DATA2_CHAR_UUID = BLEUUID(0x3333, DC_SERVICE_BASE_UUID)
    
    
    # BASE_UUID = BLEUUIDBase([0x8E, 0xC9, 0x00, 0x00, 0xF3, 0x15, 0x4F, 0x60,
    #                          0x9F, 0xB8, 0x83, 0x88, 0x30, 0xDA, 0xEA, 0x50])
    # DC_SERVICE_BASE_UUID = BLEUUIDBase([0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x10, 0x00,
    #                                     0x80, 0x00, 0x00, 0x80, 0x5f, 0x9b, 0x34, 0xfb])
    
    CCCD_BASE_UUID = BLEUUIDBase([0x00, 0x00, 0x29, 0x02, 0x00, 0x00, 0x10, 0x00,
                                  0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB])
    # Buttonless characteristics
    BLE_DFU_BUTTONLESS_CHAR_UUID = BLEUUID(0x2902, CCCD_BASE_UUID)
    BLE_DFU_BUTTONLESS_BONDED_CHAR_UUID = BLEUUID(0x2902, CCCD_BASE_UUID)
    SERVICE_CHANGED_UUID = BLEUUID(0x2A05)
    
    
    def init(conn_ic_id):
        global BLEDriver, BLEAdvData, BLEEvtID, BLEAdapter, BLEEnableParams, BLEGapTimeoutSrc, BLEUUID
        from pc_ble_driver_py import config
        config.__conn_ic_id__ = conn_ic_id
        from pc_ble_driver_py.ble_driver import BLEDriver, BLEAdvData, BLEEvtID, BLEEnableParams, BLEGapTimeoutSrc, BLEUUID
        from pc_ble_driver_py.ble_adapter import BLEAdapter
        global nrf_sd_ble_api_ver
        nrf_sd_ble_api_ver = config.sd_api_ver_get()
    
    
    class HRCollector(BLEDriverObserver, BLEAdapterObserver):
        def __init__(self, adapter):
            super(HRCollector, self).__init__()
            self.adapter = adapter
            self.conn_q = Queue.Queue()
            self.adapter.observer_register(self)
            self.adapter.driver.observer_register(self)
    
        def open(self):
            self.adapter.driver.open()
    
            ble_enable_params = BLEEnableParams(vs_uuid_count=1,
                                                service_changed=False,
                                                periph_conn_count=0,
                                                central_conn_count=CONNECTIONS,
                                                central_sec_count=CONNECTIONS)
            if nrf_sd_ble_api_ver >= 3:
                print("Enabling larger ATT MTUs")
                ble_enable_params.att_mtu = 50
    
            self.adapter.driver.ble_enable(ble_enable_params)
    
        def close(self):
            self.adapter.driver.close()
    
        @property
        def connect_and_discover(self):
            self.adapter.driver.ble_gap_scan_start()
            new_conn = self.conn_q.get(timeout=60)
    
            if nrf_sd_ble_api_ver >= 3:
                att_mtu = self.adapter.att_mtu_exchange(new_conn)
    
            self.adapter.service_discovery(new_conn)
            self.adapter.enable_notification(new_conn,BLEUUID(0x2902, CCCD_BASE_UUID))#BLEUUID(0x2902, DC_SERVICE_BASE_UUID))  # BLEUUID(BLEUUID.Standard.battery_level))
            # self.adapter.enable_notification(new_conn, BLEUUID(BLEUUID.Standard.heart_rate))
            return new_conn
    
        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_timeout(self, ble_driver, conn_handle, src):
            if src == BLEGapTimeoutSrc.scan:
                ble_driver.ble_gap_scan_start()
    
        def on_gap_evt_adv_report(self, ble_driver, conn_handle, peer_addr, rssi, adv_type, adv_data):
            dev_name_list = None
            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)
            print('Received advertisment report, address: 0x{}, device_name: {}'.format(address_string,
                                                                                        dev_name))
    
            if (dev_name == TARGET_DEV_NAME):
                self.adapter.connect(peer_addr)
    
        def on_notification(self, ble_adapter, conn_handle, uuid, data):
            print('Connection: {}, {} = {}'.format(conn_handle, uuid, data))
    
        def on_att_mtu_exchanged(self, ble_driver, conn_handle, att_mtu):
            print('ATT MTU exchanged: conn_handle={} att_mtu={}'.format(conn_handle, att_mtu))
    
        def on_gattc_evt_exchange_mtu_rsp(self, ble_driver, conn_handle, **kwargs):
            print('ATT MTU exchange response: conn_handle={}'.format(conn_handle))
    
    
    def main(serial_port):
        print('Serial port used: {}'.format(serial_port))
        driver = BLEDriver(serial_port=serial_port, auto_flash=True)
        adapter = BLEAdapter(driver)
        collector = HRCollector(adapter)
        collector.open()
        conn_handle = collector.connect_and_discover()
        adapter.write_req(conn_handle, CCCD_UUID, [3])#RAW_TYPE)
        # collector.connect_and_discover()
        # collector.wri
    
    
    if __name__ == "__main__":
        serial_port = None
        # if len(sys.argv) < 2:
        #     print("Please specify connectivity IC identifier (NRF51, NRF52)")
        #     exit(1)
        init("NRF52")
        if len(sys.argv) == 3:
            serial_port = sys.argv[2]
        else:
            descs = BLEDriver.enum_serial_ports()
            choices = ['{}: {}'.format(d.port, d.serial_number) for d in descs]
            choice = '0'  # item_choose(choices)
            serial_port = port_enter  # "COM12" #descs[choice].port
            main(serial_port)
            quit()
    
    ##### NRF PART ####### HINESH ############## NRF PART ###### #########
    

    Thanks,

  • Hi  

    Do you able to find out the error?

    Is there any other input require from my side?

    Thanks

  • Hi,

    Sorry for the delay, I have been out-of-office.

    It should work if you use the line:

    self.adapter.enable_notification(new_conn, DATA_CHAR_UUID)

    Regards,
    Terje

  • Hi

    I have tried the change you have suggested but still getting below error.

    ATT MTU exchange response: conn_handle=0
    Traceback (most recent call last):
      File "C:/My_Projects/CoMo_Docs/BLE_DOCS/Cassia_Data_Collection_Scripts-BLE_Range/Cassia_Data_Collection_Scripts/Range_Test.py", line 274, in <module>
        main(serial_port)
      File "C:/My_Projects/CoMo_Docs/BLE_DOCS/Cassia_Data_Collection_Scripts-BLE_Range/Cassia_Data_Collection_Scripts/Range_Test.py", line 255, in main
        conn_handle = collector.connect_and_discover()
      File "C:/My_Projects/CoMo_Docs/BLE_DOCS/Cassia_Data_Collection_Scripts-BLE_Range/Cassia_Data_Collection_Scripts/Range_Test.py", line 204, in connect_and_discover
        self.adapter.enable_notification(new_conn,  DATA_CHAR_UUID)
      File "C:\Python27\lib\site-packages\pc_ble_driver_py\ble_driver.py", line 125, in wrapper
        err_code = wrapped(*args, **kwargs)
      File "C:\Python27\lib\site-packages\pc_ble_driver_py\ble_adapter.py", line 254, in enable_notification
        raise NordicSemiException('CCCD not found')
    pc_ble_driver_py.exceptions.NordicSemiException: CCCD not found
    
    Process finished with exit code 1

  • Hi,

    I am sorry, but I cannot think of much more that might be the issue. Make sure that you have gotten the endianness correct (i.e. byte order in the UUIDs) and that you are using the correct UUIDs. Other than that, there is no reason left why it should not work...

    Regards,
    Terje

Reply Children
  • Hi ,

    I have took the endianness correctly that I have checked. But not able to success. If there is no other reason left then I have to take another approach here.

    I have took windows native ble libs for connecting to nrf board. As of now I am able to connect and explore services UUID's from board (pairing is also done). For this I am using the same UUID's as above for reading characteristics. ( If you have experience in that you can point to me correct way if I am wrong. I am coding in C# and open for java as well for example code).

    But While sending read command I am not able to receive data. To debug this issue,I request to point me for any example that utilizes the same libs(windows app for BLE libs) for communication. so that I can compare and make changes accordingly in my application.

    Thanks,

    Hinesh

  • Hi,

    I am sorry for the delays, I have been out-of-office for the holidays and returned today.

    We do not have anything in C# or Java. What we do have is pc-ble-driver-py and pc-ble-driver-js, which is Python and JavaScript respectively. For pc-ble-driver-py we do not have any example that does what you want, so I still refer to what I have written previously in this thread. We also have the base pc-ble-driver, which is written in c/c++.

    Regards,
    Terje

  • Hi

    Is there any update on the python version for scripts which you have mentioned in the thread here?

    Thanks,

  • Hi,

    Nothing new, I am afraid, apart from that the team is working on pc-ble-driver-py now and there will be a release some time in the future. I do not know how much time it will take, and what changes they will do other than implement support for pc-ble-driver v4.

    Regards,
    Terje

  • Hi ,

    Thank you very much for the quick response and I agree with your point as well.

    I was digging a bit and found that., 

    In order to receive the data using above UUID, I need to select the service UUID and then Characteristics UUID (might be the normal communication) .

    here the characteristics have their own handles or descriptors ( which I am not able to write or I am not doing in code ).

    From the descriptors or handles I need to choose one and then I need to write (0x0100) to enable notification. Once the notification is  enabled the board (slave )will start transmitting data which I wanted to read. 

    Now slave has number of descriptors that I need to read and select first and according to need I will write data and enable notification. 

    This is the flow which I confirmed with other device.

    May be in python example above you can point out edits so that I can check once.

    Thanks,

Related