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

I can't add more than 4 characteristics

Hi everyone !

I have 3 services and 13 characteristics in my project. Until today, 3 characteristics were working fine. But i added rest of the characteristics and my project stop working. (There is no build error). I tried to set breakpoint on sd_ble_gatts_characteristic_add function but i couldn't take any return value. I used nRF52810. When i add other characteristics, the relays in my circuit and my sensors are not working properly. I searched  about this problem and tried most of the solutions but nothing change. 

SoftDevice s112 6.0.0

Here is my Section Placement Macros :

FLASH_PH_START=0x0
FLASH_PH_SIZE=0x30000
RAM_PH_START=0x20000000
RAM_PH_SIZE=0x6000
FLASH_START=0x19000
FLASH_SIZE=0xda000
RAM_START=0x20001c18
RAM_SIZE=0x3dd50

I have three questions:

  1. Why i couldn't take any return value from this function ? (I can see other function's return value in debug mode)
  2. Do i need to add 16 bit ram size per UUID ? How to calculate it ?

I made "#define NRF_SDH_BLE_GATTS_ATTR_TAB_SIZE 1408" and "#define NRF_SDH_BLE_VS_UUID_COUNT 13"

Here is our_service.h :

#ifndef OUR_SERVICE_H__
#define OUR_SERVICE_H__

#include <stdint.h>
#include "ble.h"
#include "ble_srv_common.h"

// FROM_SERVICE_TUTORIAL: Defining 16-bit service and 128-bit base UUIDs
//#define BLE_UUID_OUR_BASE_UUID              {{0x33, 0xD1, 0x13, 0xEF, 0x5F, 0x78, 0x63, 0x15, 0xDE, 0xEF, 0x12, 0x12, 0x00, 0x00, 0x00, 0x00}}
#define BLE_UUID_OUR_BASE_UUID              {{0x64, 0x4F, 0x76, 0xF7, 0xA6, 0x52, 0x42, 0xBC, 0xE9, 0x11, 0xD2, 0x91, 0xDA, 0x10, 0xE4, 0xAE}} // 128-bit base UUID
#define BLE_UUID_OUR_SERVICE_UUID                  0xF00D // Maintenance Service
#define BLE_UUID_OUR_SERVICE_UUID_2                0xF00E // Setting Service 
#define BLE_UUID_OUR_SERVICE_UUID_3                0xF00F // Custom Setting Service

// ALREADY_DONE_FOR_YOU: Defining 16-bit characteristic UUID
#define BLE_UUID_OUR_CHARACTERISTC_UUID          0xBEEA // Sensor Characteristic
#define BLE_UUID_OUR_CHARACTERISTC_UUID_2        0xBEEB // Transmitter Characteristic
#define BLE_UUID_OUR_CHARACTERISTC_UUID_3        0xBEEC // Motor Delay Characteristic
#define BLE_UUID_OUR_CHARACTERISTC_UUID_4        0xBEED // Custom Setting Characteristic  

#define BLE_UUID_OUR_CHARACTERISTC_UUID_5        0xBEAA // Device Configuration Characteristic
#define BLE_UUID_OUR_CHARACTERISTC_UUID_6        0xBEAB // Light 1 Configuration Register Characteristic
#define BLE_UUID_OUR_CHARACTERISTC_UUID_7        0xBEAC // Light 2 Configuration Register Characteristic
#define BLE_UUID_OUR_CHARACTERISTC_UUID_8        0xBEAD // Motor 1 Configuration Register Characteristic
#define BLE_UUID_OUR_CHARACTERISTC_UUID_9        0xBEAE // Motor 2 Configuration Register Characteristic


// This structure contains various status information for our service. 
// The name is based on the naming convention used in Nordics SDKs. 
// 'ble? indicates that it is a Bluetooth Low Energy relevant structure and 
// ?os? is short for Our Service). 
typedef struct
{
    uint16_t                    conn_handle;    /**< Handle of the current connection (as provided by the BLE stack, is BLE_CONN_HANDLE_INVALID if not in a connection).*/
    uint16_t                    service_handle; /**< Handle of Our Service (as provided by the BLE stack). */
    uint16_t                    service_handle_2;
    uint16_t                    service_handle_3;
  
    // OUR_JOB: Step 2.D, Add handles for the characteristic attributes to our struct
    ble_gatts_char_handles_t    char_handles;
    ble_gatts_char_handles_t    char_handles_2;
    ble_gatts_char_handles_t    char_handles_3; //Motor Delay Char. Handle
    ble_gatts_char_handles_t    char_handles_4; //Custom Setting Char. Handle

    ble_gatts_char_handles_t    char_handles_5; // DCR Char.Handle
    ble_gatts_char_handles_t    char_handles_6; // L1CON Char. Handle
    ble_gatts_char_handles_t    char_handles_7; // L2CON Char. Handle
    ble_gatts_char_handles_t    char_handles_8; // M1CON Char. Handle
    ble_gatts_char_handles_t    char_handles_9; // M2CON Char. Handle
}ble_os_t;






/**@brief Function for handling BLE Stack events related to our service and characteristic.
 *
 * @details Handles all events from the BLE stack of interest to Our Service.
 *
 * @param[in]   p_our_service       Our Service structure.
 * @param[in]   p_ble_evt  Event received from the BLE stack.
 */
void ble_our_service_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context);

/**@brief Function for initializing our new service.
 *
 * @param[in]   p_our_service       Pointer to Our Service structure.
 */
void our_service_init(ble_os_t * p_our_service);

/**@brief Function for updating and sending new characteristic values
 *
 * @details The application calls this function whenever our timer_timeout_handler triggers
 *
 * @param[in]   p_our_service                     Our Service structure.
 * @param[in]   characteristic_value     New characteristic value.
 */
void our_sensor_characteristic_update(ble_os_t *p_our_service, int32_t *voltage);

/**@brief Function for updating and sending new characteristic values
 *
 * @details The application calls this function whenever our timer_timeout_handler triggers
 *
 * @param[in]   p_our_service                     Our Service structure.
 * @param[in]   characteristic_value     New characteristic value.
 */
void our_trm_error_characteristic_update_2(ble_os_t *p_our_service, int32_t *TRM_Signal);

#endif  /* _ OUR_SERVICE_H__ */

Here is our_service.c :

#include <stdint.h>
#include <string.h>
#include "nrf_gpio.h"
#include "our_service.h"
#include "ble_srv_common.h"
#include "app_error.h"

extern uint8_t setup_register[4];
extern int motor_delay;
extern bool ble_motor_stop_flag;
extern uint8_t MCON,L2CON,L1CON,M2CON;
int16_t data;
// Declaration of a function that will take care of some housekeeping of ble connections related to our service and characteristic
void ble_our_service_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context)
{       
        ble_gatts_evt_write_t * p_evt_write;
  	ble_os_t * p_our_service =(ble_os_t *) p_context;  
		//Implement switch case handling BLE events related to our service. 
                switch (p_ble_evt->header.evt_id)
                {
                    case BLE_GAP_EVT_CONNECTED:
                        p_our_service->conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
                        break;
                    case BLE_GAP_EVT_DISCONNECTED:
                        p_our_service->conn_handle = BLE_CONN_HANDLE_INVALID;
                        break;
                    case  BLE_GATTS_EVT_WRITE:
                        p_evt_write = &p_ble_evt->evt.gatts_evt.params.write;
                        nrf_gpio_pin_clear(28);
                        //setup_register[4]=NULL;
                        if(p_evt_write->handle == p_our_service->char_handles_3.value_handle) //If the write event come from characteristic 3 // write i?lemi ger?ekle?en characteristic 3. ise
                        { 
                          if(*p_evt_write->data == 0x10)
                            {                             
                              motor_delay = 10;
                              
                            }
                          else if(*p_evt_write->data == 0x15)
                            { 
                              motor_delay = 50;                             
                            }
                          else if (*p_evt_write->data == 0x20)      
                            {
                              motor_delay = 100;
                            }
                          else if (*p_evt_write->data == 0x00)
                            {
                              motor_delay = 0;
                            }                             
                        }else if (p_evt_write->handle == p_our_service->char_handles_4.value_handle)
                        {
                          
                          
//                          setup_register[0] = (int*)p_evt_write->data[0];
//                          setup_register[1] = (int*)p_evt_write->data[1];
//                          setup_register[2] = (int*)p_evt_write->data[2];
//                          setup_register[3] = (int*)p_evt_write->data[3];

                          M2CON = p_evt_write->data[0];
                          L1CON = p_evt_write->data[1];
                          L2CON = p_evt_write->data[2];
                          MCON = p_evt_write->data[3];
                          
                          
                        }

                        
                        break;
                    default:
                        // No implementation needed.
                        break;
                }
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


/**@brief Function for adding our new characterstic to "Our service" that we initiated in the previous tutorial. 
 *
 * @param[in]   p_our_service        Our Service structure.
 *
 */
static uint32_t sensor_char_add(ble_os_t * p_our_service)
{
    //Add a custom characteristic UUID
    uint32_t      err_code;
    ble_uuid_t    char_uuid;
    ble_uuid128_t base_uuid = BLE_UUID_OUR_BASE_UUID;
    char_uuid.uuid          = BLE_UUID_OUR_CHARACTERISTC_UUID;
    err_code = sd_ble_uuid_vs_add(&base_uuid, &char_uuid.type);
    APP_ERROR_CHECK(err_code);

    


    //Add read/write properties to our characteristic
    ble_gatts_char_md_t char_md;
    memset(&char_md, 0, sizeof(char_md));
    char_md.char_props.read = 1;
    char_md.char_props.write = 0;



    
    //Configuring Client Characteristic Configuration Descriptor metadata and add to char_md structure
    ble_gatts_attr_md_t cccd_md;
    memset(&cccd_md, 0, sizeof(cccd_md));
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm);
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.write_perm);
    cccd_md.vloc                = BLE_GATTS_VLOC_STACK;    
    char_md.p_cccd_md           = &cccd_md;
    char_md.char_props.notify   = 1;

   
    
    //Configure the attribute metadata
    ble_gatts_attr_md_t attr_md;
    memset(&attr_md, 0, sizeof(attr_md));
    attr_md.vloc = BLE_GATTS_VLOC_STACK; //Store the attributes in stack(softdevice)

	
    
    
    //Set read/write security levels to our characteristic
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.read_perm);
//    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.write_perm);
    
    //Configure the characteristic value attribute
    ble_gatts_attr_t    attr_char_value;
    memset(&attr_char_value, 0, sizeof(attr_char_value));
    attr_char_value.p_uuid  = &char_uuid;
    attr_char_value.p_attr_md = &attr_md;



    
    //Set characteristic length in number of bytes
    attr_char_value.max_len     = 2;
    attr_char_value.init_len    = 2;
    uint8_t value[2]            = {0xFF,0xFF};
    attr_char_value.p_value     = value;


    // Add our new characteristic to the service
    err_code = sd_ble_gatts_characteristic_add(p_our_service->service_handle,
                                   &char_md,
                                   &attr_char_value,
                                   &p_our_service->char_handles);
    APP_ERROR_CHECK(err_code);

    return NRF_SUCCESS;
}


static uint32_t transmitter_char_add(ble_os_t * p_our_service)
{
    //Add a custom characteristic UUID
    uint32_t      err_code;
    ble_uuid_t    char_uuid_2;
    ble_uuid128_t base_uuid = BLE_UUID_OUR_BASE_UUID;
    char_uuid_2.uuid          = BLE_UUID_OUR_CHARACTERISTC_UUID_2;
    err_code = sd_ble_uuid_vs_add(&base_uuid, &char_uuid_2.type);
    APP_ERROR_CHECK(err_code);

    


    //Add read/write properties to our characteristic
    ble_gatts_char_md_t char_md_2;
    memset(&char_md_2, 0, sizeof(char_md_2));
    char_md_2.char_props.read = 1;
    char_md_2.char_props.write = 0;



    
    //Configuring Client Characteristic Configuration Descriptor metadata and add to char_md structure
    ble_gatts_attr_md_t cccd_md_2;
    memset(&cccd_md_2, 0, sizeof(cccd_md_2));
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md_2.read_perm);
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md_2.write_perm);
    cccd_md_2.vloc                = BLE_GATTS_VLOC_STACK;    
    char_md_2.p_cccd_md           = &cccd_md_2;
    char_md_2.char_props.notify   = 1;

   
    
    //Configure the attribute metadata
    ble_gatts_attr_md_t attr_md_2;
    memset(&attr_md_2, 0, sizeof(attr_md_2));
    attr_md_2.vloc = BLE_GATTS_VLOC_STACK; //Store the attributes in stack(softdevice)

	
    
    
    //Set read/write security levels to our characteristic
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md_2.read_perm);
//    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md_2.write_perm);
    
    //Configure the characteristic value attribute
    ble_gatts_attr_t    attr_char_value_2;
    memset(&attr_char_value_2, 0, sizeof(attr_char_value_2));
    attr_char_value_2.p_uuid  = &char_uuid_2;
    attr_char_value_2.p_attr_md = &attr_md_2;



    
    //Set characteristic length in number of bytes
    attr_char_value_2.max_len     = 2;
    attr_char_value_2.init_len    = 2;
    uint8_t value[2]              = {0xFF,0xFF};
    attr_char_value_2.p_value     = value;


    //Add our new characteristic to the service
    err_code = sd_ble_gatts_characteristic_add(p_our_service->service_handle,
                                   &char_md_2,
                                   &attr_char_value_2,
                                   &p_our_service->char_handles_2);
    APP_ERROR_CHECK(err_code);

    return NRF_SUCCESS;
}

static uint32_t motor_delay_char_add(ble_os_t * p_our_service)
{
    // Add a custom characteristic UUID
    uint32_t      err_code;
    ble_uuid_t    char_uuid_3;
    ble_uuid128_t base_uuid = BLE_UUID_OUR_BASE_UUID;
    char_uuid_3.uuid          = BLE_UUID_OUR_CHARACTERISTC_UUID_3;
    err_code = sd_ble_uuid_vs_add(&base_uuid, &char_uuid_3.type);
    APP_ERROR_CHECK(err_code);

    


    //Add read/write properties to our characteristic
    ble_gatts_char_md_t char_md_3;
    memset(&char_md_3, 0, sizeof(char_md_3));
    char_md_3.char_props.read = 1;
    char_md_3.char_props.write = 1;



    
    //Configuring Client Characteristic Configuration Descriptor metadata and add to char_md structure
    ble_gatts_attr_md_t cccd_md_3;
    memset(&cccd_md_3, 0, sizeof(cccd_md_3));
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md_3.read_perm);
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md_3.write_perm);
    cccd_md_3.vloc                = BLE_GATTS_VLOC_STACK;    
    char_md_3.p_cccd_md           = &cccd_md_3;
    char_md_3.char_props.notify   = 1;
    char_md_3.char_props.write_wo_resp = 1;

   
    
    //Configure the attribute metadata
    ble_gatts_attr_md_t attr_md_3;
    memset(&attr_md_3, 0, sizeof(attr_md_3));
    attr_md_3.vloc = BLE_GATTS_VLOC_STACK; //Store the attributes in stack(softdevice)

    //Set read/write security levels to our characteristic
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md_3.read_perm);
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md_3.write_perm);
    
    //Configure the characteristic value attribute
    ble_gatts_attr_t    attr_char_value_3;
    memset(&attr_char_value_3, 0, sizeof(attr_char_value_3));
    attr_char_value_3.p_uuid  = &char_uuid_3;
    attr_char_value_3.p_attr_md = &attr_md_3;
    
    //Set characteristic length in number of bytes
    attr_char_value_3.max_len     = 4;
    attr_char_value_3.init_len    = 1;
    uint8_t value[1]              = {0x00};
    attr_char_value_3.p_value     = value;


    // Add our new characteristic to the service
    err_code = sd_ble_gatts_characteristic_add(p_our_service->service_handle_2,
                                   &char_md_3,
                                   &attr_char_value_3,
                                   &p_our_service->char_handles_3);
    APP_ERROR_CHECK(err_code);

    return NRF_SUCCESS;
}

static uint32_t custom_setting_char_add (ble_os_t * p_our_service)
{
    // Add a custom characteristic UUID
    uint32_t err_code;
    ble_uuid_t char_uuid_4; //char characteristic uuid handle
    ble_uuid128_t base_uuid = BLE_UUID_OUR_BASE_UUID; //base uuid
    char_uuid_4.uuid = BLE_UUID_OUR_CHARACTERISTC_UUID_4; //Assign our char uuid to char handle
    err_code = sd_ble_uuid_vs_add(&base_uuid,&char_uuid_4.type);// add our uuid to softdevice
    APP_ERROR_CHECK(err_code);

    //Add read/write properties to our characteristic
    ble_gatts_char_md_t char_md_4;
    memset(&char_md_4,0,sizeof(char_md_4));
    char_md_4.char_props.read = 1;
    char_md_4.char_props.write = 1;

    //Configuring Client Characteristic Configuration Descriptor metadata and add to char_md structure
    ble_gatts_attr_md_t cccd_md_4;
    memset(&cccd_md_4,0,sizeof(cccd_md_4));
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md_4.read_perm);
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md_4.write_perm);
    cccd_md_4.vloc = BLE_GATTS_VLOC_STACK;
    char_md_4.p_cccd_md = &cccd_md_4;
    char_md_4.char_props.notify         = 1;
    char_md_4.char_props.write_wo_resp  = 1;

    //Configure attribute metadata
    ble_gatts_attr_md_t attr_md_4;
    memset(&attr_md_4,0,sizeof(attr_md_4));
    attr_md_4.vloc = BLE_GATTS_VLOC_STACK;

    //Set read/write security level of our characteristics
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md_4.read_perm);
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md_4.write_perm);

    //Configure the characteristic value attribute
    ble_gatts_attr_t  attr_char_value_4;
    memset(&attr_char_value_4,0,sizeof(attr_char_value_4));
    attr_char_value_4.p_uuid = &char_uuid_4;
    attr_char_value_4.p_attr_md = &attr_md_4;
    
    //Set characteristic length in number of bytes
    attr_char_value_4.max_len     = 4;
    attr_char_value_4.init_len    = 1;
    uint8_t value[1]              = {0x00};
    attr_char_value_4.p_value     = value;

    //Add our new characteristic to service
    err_code = sd_ble_gatts_characteristic_add(p_our_service->service_handle_3,
                                                &char_md_4,
                                                &attr_char_value_4,
                                                &p_our_service->char_handles_4);

    APP_ERROR_CHECK(err_code);

    return  NRF_SUCCESS;


}

static uint32_t device_configuration_char_add(ble_os_t * p_our_service)
{
  
  // Add a custom characteristic UUID
    uint32_t err_code;
    ble_uuid_t char_uuid_5; //char characteristic uuid handle
    ble_uuid128_t base_uuid = BLE_UUID_OUR_BASE_UUID; //base uuid
    char_uuid_5.uuid = BLE_UUID_OUR_CHARACTERISTC_UUID_5; //Assign our char uuid to char handle
    err_code = sd_ble_uuid_vs_add(&base_uuid,&char_uuid_5.type);// add our uuid to softdevice
    APP_ERROR_CHECK(err_code);

    //Add read/write properties to our characteristic
    ble_gatts_char_md_t char_md_5;
    memset(&char_md_5,0,sizeof(char_md_5));
    char_md_5.char_props.read = 1;
    char_md_5.char_props.write = 1;

    //Configuring Client Characteristic Configuration Descriptor metadata and add to char_md structure
    ble_gatts_attr_md_t cccd_md_5;
    memset(&cccd_md_5,0,sizeof(cccd_md_5));
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md_5.read_perm);
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md_5.write_perm);
    cccd_md_5.vloc = BLE_GATTS_VLOC_STACK;
    char_md_5.p_cccd_md = &cccd_md_5;
    char_md_5.char_props.notify         = 1;
    char_md_5.char_props.write_wo_resp  = 1;

    //Configure attribute metadata
    ble_gatts_attr_md_t attr_md_5;
    memset(&attr_md_5,0,sizeof(attr_md_5));
    attr_md_5.vloc = BLE_GATTS_VLOC_STACK;

    //Set read/write security level of our characteristics
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md_5.read_perm);
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md_5.write_perm);

    //Configure the characteristic value attribute
    ble_gatts_attr_t  attr_char_value_5;
    memset(&attr_char_value_5,0,sizeof(attr_char_value_5));
    attr_char_value_5.p_uuid = &char_uuid_5;
    attr_char_value_5.p_attr_md = &attr_md_5;
    
    //Set characteristic length in number of bytes
    attr_char_value_5.max_len     = 4;
    attr_char_value_5.init_len    = 1;
    uint8_t value[1]              = {0x00};
    attr_char_value_5.p_value     = value;

    //Add our new characteristic to service
    ret_code_t ret_code = sd_ble_gatts_characteristic_add(p_our_service->service_handle_3,
                                                &char_md_5,
                                                &attr_char_value_5,
                                                &p_our_service->char_handles_5);

    APP_ERROR_CHECK(ret_code);

    return  NRF_SUCCESS;
}

static uint32_t ligth1_control_register_char_add(ble_os_t * p_our_service)
{
  
    // Add a custom characteristic UUID
    uint32_t err_code;
    ble_uuid_t char_uuid_6;
    ble_uuid128_t base_uuid = BLE_UUID_OUR_BASE_UUID;
    char_uuid_6.uuid        = BLE_UUID_OUR_CHARACTERISTC_UUID_6;
    err_code = sd_ble_uuid_vs_add(&base_uuid, &char_uuid_6.type);  
    APP_ERROR_CHECK(err_code);

    //Add read/write properties to our characteristic
    ble_gatts_char_md_t char_md_6;
    memset(&char_md_6, 0, sizeof(char_md_6));
    char_md_6.char_props.read = 1;
    char_md_6.char_props.write = 1;

    //Configuring Client Characteristic Configuration Descriptor metadata and add to char_md structure
    ble_gatts_attr_md_t cccd_md_6;
    memset(&cccd_md_6, 0, sizeof(cccd_md_6));
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md_6.read_perm);
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md_6.write_perm);
    cccd_md_6.vloc = BLE_GATTS_VLOC_STACK;
    char_md_6.p_cccd_md = &cccd_md_6;
    char_md_6.char_props.notify = 0;
    char_md_6.char_props.write_wo_resp = 1;
  

    //Configure attribute metadata
    ble_gatts_attr_md_t attr_md_6;
    memset(&attr_md_6, 0, sizeof(attr_md_6));
    attr_md_6.vloc = BLE_GATTS_VLOC_STACK;

    //Set read/write security level of our characteristics
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md_6.read_perm);
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md_6.write_perm);


    //Configure the characteristic value attribute
    ble_gatts_attr_t attr_char_value_6;
    memset(&attr_char_value_6, 0, sizeof(attr_char_value_6));
    attr_char_value_6.p_uuid = &char_uuid_6;
    attr_char_value_6.p_attr_md = &attr_md_6;
    
  
    //Set characteristic length in number of bytes
    attr_char_value_6.max_len = 2;
    attr_char_value_6.init_len = 2;
    uint8_t value[2] = {0x00,0x00};
    attr_char_value_6.p_value = value;
  
    //Add our new characteristic to service
    err_code = sd_ble_gatts_characteristic_add(p_our_service->service_handle_3, 
                                    &char_md_6, &attr_char_value_6, 
                                    &p_our_service->char_handles_6);

    APP_ERROR_CHECK(err_code);

    return NRF_SUCCESS;
}

static uint32_t ligth2_control_register_char_add(ble_os_t * p_our_service)
{
  
    // Add a custom characteristic UUID
    uint32_t err_code;
    ble_uuid_t char_uuid_7;
    ble_uuid128_t base_uuid = BLE_UUID_OUR_BASE_UUID;
    char_uuid_7.uuid        = BLE_UUID_OUR_CHARACTERISTC_UUID_7;
    err_code = sd_ble_uuid_vs_add(&base_uuid, &char_uuid_7.type);  
    APP_ERROR_CHECK(err_code);

    //Add read/write properties to our characteristic
    ble_gatts_char_md_t char_md_7;
    memset(&char_md_7, 0, sizeof(char_md_7));
    char_md_7.char_props.read = 1;
    char_md_7.char_props.write = 1;

    //Configuring Client Characteristic Configuration Descriptor metadata and add to char_md structure
    ble_gatts_attr_md_t cccd_md_7;
    memset(&cccd_md_7, 0, sizeof(cccd_md_7));
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md_7.read_perm);
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md_7.write_perm);
    char_md_7.p_cccd_md = &cccd_md_7;
    char_md_7.char_props.notify = 1;
    char_md_7.char_props.write_wo_resp = 1;
  

    //Configure attribute metadata
    ble_gatts_attr_md_t attr_md_7;
    memset(&attr_md_7, 0, sizeof(attr_md_7));
    attr_md_7.vloc = BLE_GATTS_VLOC_STACK;

    //Set read/write security level of our characteristics
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md_7.read_perm);
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md_7.write_perm);


    //Configure the characteristic value attribute
    ble_gatts_attr_t attr_char_value_7;
    memset(&attr_char_value_7, 0, sizeof(attr_char_value_7));
    attr_char_value_7.p_uuid = &char_uuid_7;
    attr_char_value_7.p_attr_md = &attr_md_7;
  
    //Set characteristic length in number of bytes
    attr_char_value_7.max_len = 2;
    attr_char_value_7.init_len = 1;
    uint8_t value[1] = {0x00};
    attr_char_value_7.p_value = value;
  
    //Add our new characteristic to service
    err_code = sd_ble_gatts_characteristic_add(p_our_service->service_handle_3, 
                                    &char_md_7, &attr_char_value_7, 
                                    &p_our_service->char_handles_7);

    APP_ERROR_CHECK(err_code);

    return NRF_SUCCESS;
}


static uint32_t motor1_control_register_char_add(ble_os_t * p_our_service)
{
  
    // Add a custom characteristic UUID
    uint32_t err_code;
    ble_uuid_t char_uuid_8;
    ble_uuid128_t base_uuid = BLE_UUID_OUR_BASE_UUID;
    char_uuid_8.uuid        = BLE_UUID_OUR_CHARACTERISTC_UUID_8;
    err_code = sd_ble_uuid_vs_add(&base_uuid, &char_uuid_8.type);  
    APP_ERROR_CHECK(err_code);

    //Add read/write properties to our characteristic
    ble_gatts_char_md_t char_md_8;
    memset(&char_md_8, 0, sizeof(char_md_8));
    char_md_8.char_props.read = 1;
    char_md_8.char_props.write = 1;

    //Configuring Client Characteristic Configuration Descriptor metadata and add to char_md structure
    ble_gatts_attr_md_t cccd_md_8;
    memset(&cccd_md_8, 0, sizeof(cccd_md_8));
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md_8.read_perm);
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md_8.write_perm);
    char_md_8.p_cccd_md = &cccd_md_8;
    char_md_8.char_props.notify = 1;
    char_md_8.char_props.write_wo_resp = 1;
  

    //Configure attribute metadata
    ble_gatts_attr_md_t attr_md_8;
    memset(&attr_md_8, 0, sizeof(attr_md_8));
    attr_md_8.vloc = BLE_GATTS_VLOC_STACK;

    //Set read/write security level of our characteristics
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md_8.read_perm);
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md_8.write_perm);


    //Configure the characteristic value attribute
    ble_gatts_attr_t attr_char_value_8;
    memset(&attr_char_value_8, 0, sizeof(attr_char_value_8));
    attr_char_value_8.p_uuid = &char_uuid_8;
    attr_char_value_8.p_attr_md = &attr_md_8;
  
    //Set characteristic length in number of bytes
    attr_char_value_8.max_len = 1;
    attr_char_value_8.init_len = 1;
    uint8_t value[1] = {0x00};
    attr_char_value_8.p_value = value;
  
    //Add our new characteristic to service
    err_code = sd_ble_gatts_characteristic_add(p_our_service->service_handle_3, 
                                    &char_md_8, &attr_char_value_8, 
                                    &p_our_service->char_handles_8);

    APP_ERROR_CHECK(err_code);

    return NRF_SUCCESS;
}

static uint32_t motor2_control_register_char_add(ble_os_t * p_our_service)
{
  
    // Add a custom characteristic UUID
    uint32_t err_code;
    ble_uuid_t char_uuid_9;
    ble_uuid128_t base_uuid = BLE_UUID_OUR_BASE_UUID;
    char_uuid_9.uuid        = BLE_UUID_OUR_CHARACTERISTC_UUID_9;
    err_code = sd_ble_uuid_vs_add(&base_uuid, &char_uuid_9.type);  
    APP_ERROR_CHECK(err_code);

    //Add read/write properties to our characteristic
    ble_gatts_char_md_t char_md_9;
    memset(&char_md_9, 0, sizeof(char_md_9));
    char_md_9.char_props.read = 1;
    char_md_9.char_props.write = 1;

    //Configuring Client Characteristic Configuration Descriptor metadata and add to char_md structure
    ble_gatts_attr_md_t cccd_md_9;
    memset(&cccd_md_9, 0, sizeof(cccd_md_9));
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md_9.read_perm);
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md_9.write_perm);
    char_md_9.p_cccd_md = &cccd_md_9;
    char_md_9.char_props.notify = 1;
    char_md_9.char_props.write_wo_resp = 1;
  

    //Configure attribute metadata
    ble_gatts_attr_md_t attr_md_9;
    memset(&attr_md_9, 0, sizeof(attr_md_9));
    attr_md_9.vloc = BLE_GATTS_VLOC_STACK;

    //Set read/write security level of our characteristics
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md_9.read_perm);
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md_9.write_perm);


    //Configure the characteristic value attribute
    ble_gatts_attr_t attr_char_value_9;
    memset(&attr_char_value_9, 0, sizeof(attr_char_value_9));
    attr_char_value_9.p_uuid = &char_uuid_9;
    attr_char_value_9.p_attr_md = &attr_md_9;
  
    //Set characteristic length in number of bytes
    attr_char_value_9.max_len = 2;
    attr_char_value_9.init_len = 2;
    uint8_t value[1] = {0x00};
    attr_char_value_9.p_value = value;
  
    //Add our new characteristic to service
    err_code = sd_ble_gatts_characteristic_add(p_our_service->service_handle_3, 
                                    &char_md_9, &attr_char_value_9, 
                                    &p_our_service->char_handles_9);

    APP_ERROR_CHECK(err_code);

    return NRF_SUCCESS;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


/**@brief Function for initiating our new service.
 *
 * @param[in]   p_our_service        Our Service structure.c
 */
void our_service_init(ble_os_t * p_our_service)
{
    uint32_t   err_code; // Variable to hold return codes from library and softdevice functions

    //Declare 16-bit service and 128-bit base UUIDs and add them to the BLE stack
    ble_uuid_t        service_uuid;
    ble_uuid_t        service_uuid_2;
    ble_uuid_t        service_uuid_3;
    ble_uuid128_t     base_uuid = BLE_UUID_OUR_BASE_UUID;
    
     
    service_uuid.uuid = BLE_UUID_OUR_SERVICE_UUID;      //Sensor Service
    service_uuid_2.uuid = BLE_UUID_OUR_SERVICE_UUID_2;  //Transmitter Service    
    service_uuid_3.uuid = BLE_UUID_OUR_SERVICE_UUID_3;  //Custom Setting Register

    err_code = sd_ble_uuid_vs_add(&base_uuid, &service_uuid.type);
    APP_ERROR_CHECK(err_code);  
    err_code = sd_ble_uuid_vs_add(&base_uuid, &service_uuid_2.type);
    APP_ERROR_CHECK(err_code);
    err_code = sd_ble_uuid_vs_add(&base_uuid, &service_uuid_3.type);
    APP_ERROR_CHECK(err_code);
    
    // Set our service connection handle to default value. I.e. an invalid handle since we are not yet in a connection.
    p_our_service->conn_handle = BLE_CONN_HANDLE_INVALID;

    // Add our service
		err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY,
                                        &service_uuid,
                                        &p_our_service->service_handle);
                APP_ERROR_CHECK(err_code);
    //Call the function our_char_add() to add our new characteristic to the service. 
    sensor_char_add(p_our_service);
    transmitter_char_add(p_our_service);
    
    //custom_setting_char_add(p_our_service);
      
    //Add our service
		err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY,
                                        &service_uuid_2,
                                        &p_our_service->service_handle_2);
                APP_ERROR_CHECK(err_code);
    motor_delay_char_add(p_our_service);

    //Add our service
                err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY,
                                        &service_uuid_3,
                                        &p_our_service->service_handle_3);
                APP_ERROR_CHECK(err_code);
    //Call the function our_char_add() to add our new characteristic to the service. 
    
    custom_setting_char_add(p_our_service);
 //   device_configuration_char_add(p_our_service);  //when i remove comment my app stop working.
    
 //   ligth1_control_register_char_add(p_our_service);

//    ligth2_control_register_char_add(p_our_service);
//    motor1_control_register_char_add(p_our_service);
//    motor2_control_register_char_add(p_our_service);
 

}






/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

//Function to be called when updating characteristic value
void our_sensor_characteristic_update(ble_os_t *p_our_service, int32_t *voltage)
{
    // Update characteristic value
    if (p_our_service->conn_handle != BLE_CONN_HANDLE_INVALID)//ba?lant? varm? diye kontorl ediyor. ba?lant? yoksa soft device hata verir
    {
      uint16_t               len = 2;
      ble_gatts_hvx_params_t hvx_params;
      memset(&hvx_params, 0, sizeof(hvx_params));

      hvx_params.handle = p_our_service->char_handles.value_handle;
      hvx_params.type   = BLE_GATT_HVX_NOTIFICATION;
      hvx_params.offset = 0;
      hvx_params.p_len  = &len;
      hvx_params.p_data = (uint8_t*)voltage;  

      sd_ble_gatts_hvx(p_our_service->conn_handle, &hvx_params);
    }

}

// Function to be called when updating characteristic value
void our_trm_error_characteristic_update_2(ble_os_t *p_our_service, int32_t *TRM_Signal)
{
    // Update characteristic value
    if (p_our_service->conn_handle != BLE_CONN_HANDLE_INVALID)//Checking the connection status, SoftDevice occurs error if there is no connection
    {
      uint16_t               len = 2;
      ble_gatts_hvx_params_t hvx_params;
      memset(&hvx_params, 0, sizeof(hvx_params));

      hvx_params.handle = p_our_service->char_handles_2.value_handle; //char_handles_2 oldu?u i?in 2.karakteristi?i g?ncelliyor
      hvx_params.type   = BLE_GATT_HVX_NOTIFICATION;
      hvx_params.offset = 0;
      hvx_params.p_len  = &len;
      hvx_params.p_data = (uint8_t*)TRM_Signal;  

      sd_ble_gatts_hvx(p_our_service->conn_handle, &hvx_params);
    }

}

Parents
  • Hi,

    How does your nrf_log output look like, any errors printed ? (either via UART or Segger RTT backend) 

    If you are not getting any RTT logs, you might need to set NRF_FPRINTF_FLAG_AUTOMATIC_CR_ON_LF_ENABLED to 0 in sdk_config.h

    Your RAM_START value seems a bit low, but nrf_log should output the correct value for you in case it's not correct.

  • Hi Sigurd,

    When i works with 4 characteristics the output is :

    <debug> nrf_sdh: State request: 0x00000000
    <debug> nrf_sdh: Notify observer 0x0001FA74 => ready
    <debug> nrf_sdh: State change: 0x00000000
    <debug> nrf_sdh: State change: 0x00000001
    <debug> nrf_sdh_ble: RAM starts at 0x20001C18
    <debug> nrf_sdh_ble: RAM start location can be adjusted to 0x20001BD8.
    <debug> nrf_sdh_ble: RAM size for application can be adjusted to 0x4428.

    There is no output if  i open other characteristics. I changed the ram start 0x20001C18 to 0x20001BD8 and ram size to 0x4428. Nothing change.

    Edit : If i do like this, my 3 services and 4 characteristics work fine.

    static ble_uuid_t m_adv_uuids[] =                                               /**< Universally unique service identifiers. */
    {
        {BLE_UUID_OUR_SERVICE_UUID, BLE_UUID_TYPE_VENDOR_BEGIN}
    //    {BLE_UUID_OUR_SERVICE_UUID_2,BLE_UUID_TYPE_VENDOR_BEGIN},
    //    {BLE_UUID_OUR_SERVICE_UUID_3, BLE_UUID_TYPE_VENDOR_BEGIN}
    };

    When i uncomment other two services, i got fatal error.

  • Hi,

    Likely because there is not enough room in the advertising packet to advertise the UUID of all services. But you don't really need to put all UUIDs in the advertising packet anyway, the central will discover them when it connects.

    Caner Celiktas said:
    i got fatal error.

     You should then use the Debug configuration, the error-code should then be printed:

    If you don't have a Debug configuration, then add DEBUG as a Preprocessor define in the project settings.

Reply Children
Related