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

How do I get my DK to Read character values

Hi, i am having some trouble getting my nRF52 DK (S132) to read a value provided by the nRF51 dongle(S130). First of all, i am very new to this whole Bluetooth thing so i've done all the tutorials, tried some things and had fun - so far. But now im stuck: I used the mulitlink_peripheral example on the dongle, set up the characteristics and values which i can read from the smartphone MCP. So all UUIDs and values und stuff are known and appear in MCP. This is where i figured out, i have to make changes to costumize the service i copied from multilink peripheral

static void services_init(void)   {
uint32_t            err_code;
ble_uuid_t          uuid;
ble_gatts_char_md_t char_md;
ble_gatts_attr_t    attr;
ble_gatts_attr_md_t attr_md;
ble_gatts_attr_md_t cccd_md;
ble_gatts_attr_md_t char_ud_md;
uint16_t            svc_test;


ble_uuid128_t base_uuid = MULTILINK_PERIPHERAL_BASE_UUID;

err_code = sd_ble_uuid_vs_add(&base_uuid, &m_base_uuid_type);
APP_ERROR_CHECK(err_code);

uuid.type = m_base_uuid_type;
uuid.uuid = MULTILINK_PERIPHERAL_SERVICE_UUID;

err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY, &uuid, &svc_test);  /**< Service will be added */
APP_ERROR_CHECK(err_code);

//////////

static uint8_t multilink_peripheral_data = 101;	/**< Actual Value of Characteristic, range 0-255, changing to uint16_t seems to stop functionality */
static uint8_t multilink_peripheral_ud[] = "Keycode Hex 1";			/**< Descriptor of Characteristic Value */

uuid.uuid = MULTILINK_PERIPHERAL_CHAR1_UUID;								/**< Set Characteristic UUID from #define */

memset(&attr, 0, sizeof(ble_gatts_attr_t));									/**< write 0 to ble_gatts_attr_t attr to make sure attr is not on random values */
attr.p_uuid    = &uuid;
attr.p_attr_md = &attr_md;
attr.max_len   = 1;
attr.p_value   = &multilink_peripheral_data;
attr.init_len  = sizeof(multilink_peripheral_data);

memset(&attr_md, 0, sizeof(ble_gatts_attr_md_t));
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.read_perm);
BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&attr_md.write_perm);
attr_md.vloc = BLE_GATTS_VLOC_STACK;
attr_md.vlen = 0;

memset(&cccd_md, 0, sizeof(ble_gatts_attr_md_t));
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm);
BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&cccd_md.write_perm);
cccd_md.vloc = BLE_GATTS_VLOC_STACK;

memset(&char_md, 0, sizeof(ble_gatts_char_md_t));
char_md.p_cccd_md               = &cccd_md;
char_md.char_props.notify       = 1;									/**< comment / uncomment to set permissions */
char_md.char_props.indicate     = 1;
char_md.char_props.read         = 1;
char_md.char_props.write        = 1;
char_md.char_ext_props.wr_aux   = 1;										/**< needs to stay 1 */
char_md.p_user_desc_md          = &char_ud_md;
char_md.p_char_user_desc        = multilink_peripheral_ud;
char_md.char_user_desc_size     = (uint8_t)strlen((char *)multilink_peripheral_ud);
char_md.char_user_desc_max_size = (uint8_t)strlen((char *)multilink_peripheral_ud);

memset(&char_ud_md, 0, sizeof(ble_gatts_attr_md_t));
char_ud_md.vloc = BLE_GATTS_VLOC_STACK;
char_ud_md.vlen = 1;
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&char_ud_md.read_perm);
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&char_ud_md.write_perm);

err_code = sd_ble_gatts_characteristic_add(BLE_GATT_HANDLE_INVALID,
                                           &char_md,
                                           &attr,
                                           &m_char_handles);
APP_ERROR_CHECK(err_code);

next thing i want to do is to read the value stored in

static uint8_t multilink_peripheral_data = 101;

from my nrf52 DK which then lights up a LED when compared the 101 to another value stored on the nrf52 DK. In the infocenter I found this flowchart: GATTC Read Characteristic Value by UUID

but somehow i cannot figure out how to make this function work. e.g. i don't know where the conn_handle comes from. Infocenter just tells me: this is the connection handle, which i already figured out from the name...

do i have to call some other functions first, or set up some structs to make this work? thanks for the help so far. I'm trying to be precise, but as i am new to this, it's a bit difficult. And thanks for recommending the app_hrs and battery service, but since i set up my peripheral device and it appears in MCP as I wish, i'd rather like to stick with this code, than getting to know a new one which wasn't very familiar looking.

best regards selle

  • I recommend you to start off with ble_app_uart and ble_app_uart_c, or ble_app_hrs and ble_app_hrs_c. It is also difficult to determine if what you are doing is correct or not, since you haven't included what you are actually doing. You general approach seems correct though. Maybe you can edit your question, and add some more information?

  • well you have all the peripheral stuff done on one board, now you need to implement the other side of it, the central side, on the DK board. For that you should look at some of the central examples.

    You say you don't know where the connection handle comes from, well you get that after you connect, have you connected, I"d guess you haven't else you'd have seen the conn_handle come flying past.

    So for peripherals you

    1. Set up the GATT database
    2. Set the GAP options
    3. Start advertising
    4. (optionally) handle read and write requests if your GATT database is dynamic and requires that

    on the central side you

    1. Set the GAP options
    2. Start scanning for advertisers until you find one you want
    3. Connect to it (you can actually skip 2 and go right to 3. if you know what you want to connect to)
    4. Query the GATT database on the peripheral to find the handles
    5. Send read and write requests.

    It sounds like you've skipped straight to 5 without doing 1-4. That message sequence chart you refer to, that's one of the correct ones, by UUID works ok (also getting the handle first and then reading by handle works). Note the very top of it, the big rounded box says 'connection established'. Now if you look in the GAP message sequences you'll see the charts for how a central scans for and connect to the peripheral it wants to talk to.

  • Thanks for the quick answer. My boards do connect, as i get a BLE_GAP_EVT_CONNECTED. Both Boards also indicate this by lighting up LED1. I think my problem is step 4, central side. When calling the sd_ble_gatts_char_value_by_uuid_read i guess the argument uuid is the uuid from my character i want to read, but what about the handle range?

  • ok well if you're connected then there's your conn_handle, just hold onto it, so you have that.

    For handle range just give it 0-65535 and it will return the first however many values with entries matching the UUID, which will probably be one I expect. You can have multiple of the same UUID in the database so you send in 0-65535 and then, after you get your reply, whatever the last handle was you add 1 to it, and ask again. When you get no more back, you have all of them. In your case you'll likely get one reply with one handle as you only have one value.

    However it's usually better to use one of the service discovery procedures to find the service you want, the characteristics it has and hold onto the handles, then you just read the value by handle. But what you're doing is ok. It will also return you the handle so you can cache it there and use it next time.

  • ok, i now set up this:

    #define READ_CHAR1_UUID 								 0x900A                                  
    

    const ble_uuid_t CHAR1 = {READ_CHAR1_UUID, BLE_UUID_CHARACTERISTIC}; const ble_gattc_handle_range_t CHAR1_RANGE = {0,65535};

    with that, i can call

    sd_ble_gattc_char_value_by_uuid_read(p_ble_evt->evt.gap_evt.conn_handle,&CHAR1,&CHAR1_RANGE);
    

    inside the static void on_ble_evt() in main.c without getting compilation error, but i had to change the variable type for the uuid type from uint8 to uint16.... so im not sure if that's correct XD. I then stumbled across this Read Value I tried to use this, but i could need a bit more details.

Related