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

Sending string data over NUS

Hello,

I am trying to modify the ble_app_uart code so that my peripheral can send data automatically to the central, which in turn can print it on a computer through UART. What I mean is that instead of the ble_nus_string_send() command being called when I press enter, I want the peripheral to send a number automatically from the main.

This is the code I'm using for sending the number in the peripheral, which prints the value of number correct starting at 1:

    uint8_t number = 0;
    uint8_t data[20]; 

    for (;;)
    {

        number = number + 1;

        sprintf((char *)data, "%d", number); 

        ble_nus_string_send(&m_nus, data, sizeof(data));
    }

This is the code in the central, in the case that BLE_NUS_C_EVT_NUS_TX_EVT happens it calls this function:

static void ble_nus_chars_received_uart_print(uint8_t * p_data, uint16_t data_len)
{
    ret_code_t ret_val;

    NRF_LOG_DEBUG("Receiving data.");
    NRF_LOG_HEXDUMP_DEBUG(p_data, data_len);

    for (uint32_t i = 0; i < data_len; i++)
    {
        do
        {
            ret_val = app_uart_put(p_data[i]);
            if ((ret_val != NRF_SUCCESS) && (ret_val != NRF_ERROR_BUSY))
            {
                NRF_LOG_ERROR("app_uart_put failed for index 0x%04x.", i);
                APP_ERROR_CHECK(ret_val);
            }
        } while (ret_val == NRF_ERROR_BUSY);
    }
    if (p_data[data_len-1] == '\r')
    {
        while (app_uart_put('\n') == NRF_ERROR_BUSY);
    }
}

As far as I know, with the ble_nus_string_send the central should receive and print the number on the other PC. From what I know, the central enters ble_nus_c_evt_handler to establish connection but the NUS_TX_EVT is not being called.

How can I fix this? Or is there a better way to send a number from the peripheral and have the central simply print it to UART?

I'm using NRF52832 and S132.

Parents Reply Children
  • I'll try.  My project uses different UUIDs but mostly unmolested NUS inside.

    This screencap shows the button on you need to select to turn notifications on:

    The periph won't send anything until you turn notifications on that way.  

    If successful you'll be rewarded with soemthing like this:

    And the data will refresh as often as received until you toggle notifications off.

  • Thanks! Its quite clear now. Sadly, what I'm trying to transmit over BLE is sensor data, and I need a continuous stream of data that I can accumulate. For example, if I send the data over UART to PuTTY I can copy all the data I send over long periods of time for processing. I'm afraid I can't do that with the method you showed me, that's why I'm trying to send it on BLE NUS packets to another board that are then sent over UART to PuTTY in order to accumulate all that data. I need to send about 70 bytes every 20 ms.
    Could you help me solve my initial question or could you propose another method?

  • I understand. The point of the nrf connection is to get the sensor side working  Is it working? With nrfconnect are you seeing the data from your sensor-connected peripheral after clicking notify?

    If you're not seeing your sensor's data with the nrf connect PC app then I think you need to start at the peripheral.  Log what's going on between the sensor's uart and the example/ble_peripheral/ble_app_uart main.c's call to ble_nus_data_send().

    If you are seeing your sensor data then your central running something like examples/ble_central/ble_app_uart_c can almost drop-in and replace the PC.  You could set up the central to scan for and autoconnect to your peripheral. Then you'll turn tx_notifs on from the central, enlarge the MTU (see this thread devzone.nordicsemi.com/.../158918, and the example's ble_nus_chars_received_uart_print() will emit the sensor data on the pin defined for SER_APP_TX_PIN  .

    3500 bytes every second is very do-able.

  • Data packets are indeed being received by nrf connect. I can see them when I click notify.

    The boards automatically connect when I turn on the peripheral and stay connected. I increased the MTU in both to 100. Baudrate in both is 57600.

    I am using the examples/ble_central/ble_app_uart_c.

    When they connect it is turning on the tx_notifs, it prints "connected" and "disconnected" no problem but "data recieved" is never printed and no data is being printed either. Here is my ble_nus_c_evt_handler in case it helps:

    switch (p_ble_nus_evt->evt_type)
        {
            case BLE_NUS_C_EVT_DISCOVERY_COMPLETE:
                NRF_LOG_INFO("Discovery complete.");
                err_code = ble_nus_c_handles_assign(p_ble_nus_c, p_ble_nus_evt->conn_handle, &p_ble_nus_evt->handles);
                APP_ERROR_CHECK(err_code);
    
                err_code = ble_nus_c_tx_notif_enable(p_ble_nus_c);
                APP_ERROR_CHECK(err_code);
                NRF_LOG_INFO("Connected to device with Nordic UART Service.");
                printf("Connected\r\n");
                break;
    
            case BLE_NUS_C_EVT_NUS_TX_EVT:
                printf("Data received\r\n");
                ble_nus_chars_received_uart_print(p_ble_nus_evt->p_data, p_ble_nus_evt->data_len);
                break;
    
            case BLE_NUS_C_EVT_DISCONNECTED:
                NRF_LOG_INFO("Disconnected.");
                printf("Disconnected\r\n");
                scan_start();
                break;
        }

  • I'm stumped and would need your code to figure out what's wrong, and that's not appropriate (we hardly know each other! :-) 

    Hopefully others with better ideas than I have will chime in. FWIW it sounds like you're very close. Final tips would be to make sure there's nothing untoward in the peripheral side's logs (but you have good results with nrf connect......)  

Related