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

How to send gyro sensor data through bluetooth(ble)?

Hi, all.

I want data read from gyro sensor through i2c, and then send it through bluetooth equipment.(PC or iPhone and so on) But i don'k know how to send gyro sensor data through bluetooth.

I tried to send gyro sensor data transmitted through "on_hids_evt()" and "on_hids_evt()" and "bsp_event_handler()" functions. But it did not fit.

I would like to transmit the gyro sensor data via the BLE continuously. In other words, I would like to express the mouse cursor through the sensor value. (Not use button triggering like "ble_app_hids_mouse" original example.)

My development environment is like below.

  • chip : nRf51822
  • example : ble_app_hids_mouse(s130) in nRF_Example 10.0.0

Please kindly comment guide or relevant Q&A issue. (I can't found relevant this issue in "Questions" tab, yet.)

  • FormerMember
    0 FormerMember

    In your case, the BLE device will be a peripheral/slave device. In order to transmit data continuously, I would recommend you to use notification. This message sequence chart shows the flow for transmitting a notification. As you can see, sd_ble_gatts_hvx(..) transmits notifications.

    The functions "on_hids_evt()" and "on_hids_evt()" and "bsp_event_handler()" handle received events.

    In order for the peripheral to transmit notifications, the central/master device will have to enable notifications. The central enables notifications by writing to the CCCD (Client Characteristic Configuration Descriptor) for the gyro characteristic.

    I will try to make it clearer with an example, using ble_app_uart :

    The peripheral side:

    The UART RX characteristic is set up the following way, with the notification property set. The UART RX characteristic transmits data from the peripheral to the central.

    static uint32_t rx_char_add(ble_nus_t * p_nus, const ble_nus_init_t * p_nus_init)
    {
    /**@snippet [Adding proprietary characteristic to S110 SoftDevice] */
    ...
    ...    
    memset(&char_md, 0, sizeof(char_md));
    
    char_md.char_props.notify = 1;  // Notification property set
    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         = &cccd_md;
    char_md.p_sccd_md         = NULL;
    
    ...
    ...
    return sd_ble_gatts_characteristic_add(p_nus->service_handle,
                                           &char_md,
                                           &attr_char_value,
                                           &p_nus->rx_handles);
    /**@snippet [Adding proprietary characteristic to S110 SoftDevice] */
    }
    

    The transfer of the notifications happen in ble_nus_string_send(..) if notification has been enabled.

    As mentioned above, notifications are being enabled by writing to the CCCD for the characteristic in question. In ble_app_uart, a write event to the RX characteristic CCCD is handled in on_write(..):

      static void on_write(ble_nus_t * p_nus, ble_evt_t * p_ble_evt)
      {
      ble_gatts_evt_write_t * p_evt_write = &p_ble_evt->evt.gatts_evt.params.write;
    
    // Check if the write event is addressed to the RX characteristic CCCD handle:
    if (
        (p_evt_write->handle == p_nus->rx_handles.cccd_handle)  /
        &&
        (p_evt_write->len == 2)
       )
    {
        // Check if the write event enables notifications:
        if (ble_srv_is_notification_enabled(p_evt_write->data))
        {
            p_nus->is_notification_enabled = true;
        }
        else
        {
            p_nus->is_notification_enabled = false;
        }
    }
    ...
    ...
    }
    

    The central side: The central side enables notifications when the RX characteristic has been found:

    static void ble_nus_c_evt_handler(ble_nus_c_t * p_ble_nus_c, const ble_nus_c_evt_t * p_ble_nus_evt)
    {
        uint32_t err_code;
        switch (p_ble_nus_evt->evt_type)
       {
        ...
        ...
        
        case BLE_NUS_C_EVT_FOUND_NUS_RX_CHARACTERISTIC:
            err_code = ble_nus_c_rx_notif_enable(p_ble_nus_c);
            APP_ERROR_CHECK(err_code);
            APPL_LOG("The device has the device RX characteristic\r\n");
            break;
    ...
    ...
    }
    

    I hope this gives you an idea of how to implement update of the gyro data.

    Update 04.03.16: It should be possible to update the data fast enough. There are several parameters that affect the throughput:

    1. Connection interval: A shorter connection interval will allow the peripheral to send notifications more often, at least every connection interval.
    2. Multiple packets per connection interval: When using notification, it is also possible to transmit multiple packets per connection interval.

    How often do you want to transmit the gyro data?

    For a continuous data update every given interval, you can use a timer. The example ble_app_hrs uses a timer to update the heart rate value at a given interval.

    In order to check what is being transferred over the air, you can use the sniffer to track the BLE link.The sniffer download contains among others a sniffer firmware that you program to either the nRF51-DK or the nRF51-Dongle, and the nRF51-DK/nRF51-Dongle will be the sniffing device. Using the sniffer is very easy. It can be downloaded from the nRF51822 webpage --> "downloads" tab.

    The sniffer should be used with Wireshark, and it works best with version 1.10, not one of the newer versions. Wireshark can be downloaded here:

  • Hi, Kristin. Thanks for your kindly guide. :)

    Example was run "ble_app_uart", refer to this link.(does not changed source code) However, when i transfer a character from one board to another one on the board, the speed was too slow.

    It seems difficult to move the mouse cursor in real time. It wants to transfer the gyro sensor values that occur continuously in real time.

    Thank you and best regards, GON.

  • FormerMember
    0 FormerMember in reply to FormerMember

    I have updated my answer to answer your questions.

  • Hi, Kristin. Thank you updated comment.

    How can i using shorter connection interval? Is that right refers to the "MIN_CONNECTION_INTERVAL" in "ble_app_uart_c_s130_pca10028"?

    I hope to give me the guide based on the current example.

    Thank you and best regards, GON.

  • Hi, Kristin.

    I tried to test changed connect interval in source code like below.

    a. UNIT_1_25_MS -> UNIT_10_MS : both board were not connected.

    b. MSEC_TO_UNITS(10, UNIT_1_25_MS), MSEC_TO_UNITS(35, UNIT_1_25_MS) : both board were connect success, but too slow still.

    c. MSEC_TO_UNITS(5, UNIT_1_25_MS), MSEC_TO_UNITS(18, UNIT_1_25_MS) : both board were not connected.

    If my test is wrong, please let me know correct guide.

Related