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

nRF51: writing to a characteristic

Hello,

I am using SD 130 on nRF5 with SDK V12.1.0.

I want to write to a characteristic using the android debug app (nrf connect).

This is my code for the characteristic:

  ble_uuid_t          char_uuid;
  char_uuid.uuid      = BLE_UUID_MY_CHARACTERISTC_UUID;
  err_code = sd_ble_uuid_vs_add(&base_uuid, &char_uuid.type);
  APP_ERROR_CHECK(err_code);



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

  /* 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;                     /* assign attribute metadata to characteristic value attribute */
  attr_char_value.max_len     = 1;                            /* max value length */
  attr_char_value.init_len    = 1;                            /* initial value length */
  attr_char_value.p_value = (uint8_t*)&MyVar;                            /* ptr to actual value */


  ble_gatts_char_md_t char_md;
  memset(&char_md, 0, sizeof(char_md));
  char_md.char_props.read = 1;                                /* set read property */
  char_md.char_props.write = 1;                               /* set write proper */
  

  err_code = sd_ble_gatts_characteristic_add(p_our_service->service_handle,
                                     &char_md,
                                     &attr_char_value,
                                     &p_our_service->char_handles_dry);
  APP_ERROR_CHECK(err_code);

What is happening: I can write a value to the characteristic. When I read it afterwards, it is correct. BUT: The debugger shows me, that MyVar did not change.

Question 1: Where is the new value saved? It's obviously not in MyVar as I assumed.

Question 2: How can I update MyVar with the correct value?

Thank you very much in advance!

Regards

Parents
  • Thank you very much for your answer. I made the mentioned changes and it works so far:

    static void on_write(ble_soil_t * p_bas, ble_evt_t * p_ble_evt)
    {
      ble_gatts_evt_write_t * p_evt_write = &p_ble_evt->evt.gatts_evt.params.write;
      
      if (p_evt_write->handle == p_bas->char_handles_dry.value_handle)
      {  
        
        if(CALIB_TRIGGER == *p_evt_write->data)
        {
          SoilMoistureThresholdDry = SoilMoistureValue;
        }
      }
               
      
    }
    void ble_soil_on_ble_evt(ble_soil_t * p_our_service, ble_evt_t * p_ble_evt)
    {
      /* Connection status handle updaten*/
      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:
            on_write(p_our_service, p_ble_evt);
            break;
        default:
            // No implementation needed.
            break;
      }
    
    }
    

    1. Question As you can see, I want the characteristic variable to be updated when a special number is written to it (calibration trigger, e.g. "1"). It works fine in the debugger, the variable is updated correctly (SoilMoistureThresholdDry is also the variable connected to the characteristic I have written to, it should work like this: write CALIB_TRIGGER to characteristic, but don't update the connected variable with this value but update it with another value). But when I read the value again in NRF connect, it stills shows the value I have written before and not the updated value. I assume this has also todo with the stack. How can I tell the Softdevice to update the stack with the new value?

    2. Question When searching the forum I often found solutions which implemented a write_handler, e.g.

    static void on_write(ble_dls_t * p_dls, ble_evt_t * p_ble_evt)
    {
        ble_gatts_evt_write_t * p_evt_write = &p_ble_evt->evt.gatts_evt.params.write;
            uint32_t temp_val = 0;
    
        if ((p_evt_write->handle == p_dls->dl_char_handles.value_handle) &&
            (p_evt_write->len == 4) &&
            (p_dls->dl_write_handler != NULL))
        {
                    p_dls->dl_write_handler(p_dls, p_evt_write);
        }
    
    }
    

    Can you tell me how to implement such a write handler?

    Thank you very much for your support!

    Regards

Reply
  • Thank you very much for your answer. I made the mentioned changes and it works so far:

    static void on_write(ble_soil_t * p_bas, ble_evt_t * p_ble_evt)
    {
      ble_gatts_evt_write_t * p_evt_write = &p_ble_evt->evt.gatts_evt.params.write;
      
      if (p_evt_write->handle == p_bas->char_handles_dry.value_handle)
      {  
        
        if(CALIB_TRIGGER == *p_evt_write->data)
        {
          SoilMoistureThresholdDry = SoilMoistureValue;
        }
      }
               
      
    }
    void ble_soil_on_ble_evt(ble_soil_t * p_our_service, ble_evt_t * p_ble_evt)
    {
      /* Connection status handle updaten*/
      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:
            on_write(p_our_service, p_ble_evt);
            break;
        default:
            // No implementation needed.
            break;
      }
    
    }
    

    1. Question As you can see, I want the characteristic variable to be updated when a special number is written to it (calibration trigger, e.g. "1"). It works fine in the debugger, the variable is updated correctly (SoilMoistureThresholdDry is also the variable connected to the characteristic I have written to, it should work like this: write CALIB_TRIGGER to characteristic, but don't update the connected variable with this value but update it with another value). But when I read the value again in NRF connect, it stills shows the value I have written before and not the updated value. I assume this has also todo with the stack. How can I tell the Softdevice to update the stack with the new value?

    2. Question When searching the forum I often found solutions which implemented a write_handler, e.g.

    static void on_write(ble_dls_t * p_dls, ble_evt_t * p_ble_evt)
    {
        ble_gatts_evt_write_t * p_evt_write = &p_ble_evt->evt.gatts_evt.params.write;
            uint32_t temp_val = 0;
    
        if ((p_evt_write->handle == p_dls->dl_char_handles.value_handle) &&
            (p_evt_write->len == 4) &&
            (p_dls->dl_write_handler != NULL))
        {
                    p_dls->dl_write_handler(p_dls, p_evt_write);
        }
    
    }
    

    Can you tell me how to implement such a write handler?

    Thank you very much for your support!

    Regards

Children
No Data
Related