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

Can't receive bytes sent via ByteArray in nRFConnect App

I created a custom BLE service following this tutorial and I am able to connect to the BLE service and write data to it, but ideally, I want to send character bytes as opposed to just decimal values. 

In the nRFConnect app, seemingly ByteArray is a field to enter character bytes but when I enter a character, on_write is invoked and p_evt_write->len remains 0, and so is p_evt_write->data
But when I send in an Unsigned field, I receive the expected data and so does the length.

Also can we not send multiple bytes at once? because otherwise p_evt_write->len would always remain 1 hence no actual use.


Am I using the ByteArray field correctly? 

Parents
  • Hi,

    Can you say more about the characteristic you write to? What is the maximum length? I ask because referring to this snippet from the tutorial, the max length is set to sizeof(uint8_t), which is 1:

        /* This code belongs in custom_value_char_add() in ble_cus.c*/
    
        memset(&attr_char_value, 0, sizeof(attr_char_value));
    
        attr_char_value.p_uuid    = &ble_uuid;
        attr_char_value.p_attr_md = &attr_md;
        attr_char_value.init_len  = sizeof(uint8_t);
        attr_char_value.init_offs = 0;
        attr_char_value.max_len   = sizeof(uint8_t);

    If you want to write more than one byte at a time, you must set a higher value for max_len.

  • max_len indicates the max number of bytes that could be sent before the application starts processing/interrupt is triggered then?  because currently, every byte I send, on_write is invoked through the ble event handler call.

    Also now the RX characteristics button doesn't seem to recognize the tap to bring up the options for the data. do you see what's happening now?

  • Okay, so I tried again and despite having max_len at sizeof(uint8_t) * 5, I can send/receive < 5 bytes. Do you see why would that be? (p_evt_write->len < 5)

    Secondly, there's no way for you to send string bytes? Would you have to consult to the ASCII table to make sure you're sending the expected chars?

  • Hi,

    morpho said:
    Okay, so I tried again and despite having max_len at sizeof(uint8_t) * 5, I can send/receive < 5 bytes. Do you see why would that be? (p_evt_write->len < 5)

    Can you share your code so that I can see?

    morpho said:
    Secondly, there's no way for you to send string bytes?

    When you have selected ByteArray, then yes. If you select UTF8, you can enter a string and it will be automatically converted to ASCII for you.

  • static uint32_t custom_value_char_add(BleCust * p_cus, const BleCustInit_t * p_cus_init)
    {
        uint32_t            err_code;
        ble_gatts_char_md_t char_md;
        ble_gatts_attr_md_t cccd_md;
        ble_gatts_attr_t    attr_char_value;
        ble_uuid_t          ble_uuid;
        ble_gatts_attr_md_t attr_md;
    
        memset(&char_md, 0, sizeof(char_md));
    
        char_md.char_props.read   = 1;
        char_md.char_props.write  = 1;
        char_md.char_props.notify = 0; 
        char_md.p_char_user_desc  = NULL;
        char_md.p_char_pf         = NULL;
        char_md.p_user_desc_md    = NULL;
        char_md.p_cccd_md         = NULL; 
        char_md.p_sccd_md         = NULL;
    		
        memset(&attr_md, 0, sizeof(attr_md));
    
        attr_md.read_perm  = p_cus_init->customCharAttr.read_perm;
        attr_md.write_perm = p_cus_init->customCharAttr.write_perm;
        attr_md.vloc       = BLE_GATTS_VLOC_STACK;
        attr_md.rd_auth    = 0;
        attr_md.wr_auth    = 0;
        attr_md.vlen       = 0;
    
        ble_uuid.type = p_cus->uuidType;
        ble_uuid.uuid = CUSTOM_VALUE_CHAR_UUID;
    
        memset(&attr_char_value, 0, sizeof(attr_char_value));
    
        attr_char_value.p_uuid    = &ble_uuid;
        attr_char_value.p_attr_md = &attr_md;
        attr_char_value.init_len  = sizeof(uint8_t);
        attr_char_value.init_offs = 0;
        attr_char_value.max_len   = sizeof(uint8_t) * 5;
    
        err_code = sd_ble_gatts_characteristic_add(p_cus->serviceHandle, &char_md,
                                                   &attr_char_value,
                                                   &p_cus->customValueHandle);
        if (err_code != NRF_SUCCESS)
        {
            return err_code;
        }
    
        return NRF_SUCCESS;
    }

  • This looks OK for writing up to 5 bytes. Does it not work if you use ByteArray with hex or UTF8 with characters?

  • is it UP TO or neither more nor less which you indicated earlier? Unless I'm misinterpreting

Reply Children
  • The max_len field indicates the maximum length, so it is up to. You can always write a smaller value, the point is that it cannot be larger than the specified maximum.

    (I see now that my statement "The max_len here dictates the maximum length of the value, neither more or less" can be confusing. The point was that max_len does not do anything other than limiting the maximum length. So, it does not say anything about number of writes before you get an interrupt or similar as you asked about before I answered that).

Related