<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="https://devzone.nordicsemi.com/cfs-file/__key/system/syndication/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Reliability of the BLE UART example</title><link>https://devzone.nordicsemi.com/f/nordic-q-a/87541/reliability-of-the-ble-uart-example</link><description>In my application I need a reliable BLE link between peripheral (in this case based on a nRF52840) and a PC / Laptop. I need to stream data at a rate of 200kbps with a very high reliability. i.e loss of more than 0.0001% of the data is unacceptable. </description><dc:language>en-US</dc:language><generator>Telligent Community 13</generator><lastBuildDate>Wed, 04 May 2022 14:22:34 GMT</lastBuildDate><atom:link rel="self" type="application/rss+xml" href="https://devzone.nordicsemi.com/f/nordic-q-a/87541/reliability-of-the-ble-uart-example" /><item><title>RE: Reliability of the BLE UART example</title><link>https://devzone.nordicsemi.com/thread/366294?ContentTypeID=1</link><pubDate>Wed, 04 May 2022 14:22:34 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:ac56fe1e-e486-47a8-8983-bbda6e756688</guid><dc:creator>jmoraal</dc:creator><description>&lt;p&gt;I made the following changes to the example and SDK to change the TX characteristic from notify to indicate:&lt;/p&gt;
&lt;p&gt;UART example:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="diff"&gt;diff --git a/ble_peripheral/ble_app_uart/main.c b/ble_peripheral/ble_app_uart/main.c
index 36d1a82..e60d938 100644
--- a/ble_peripheral/ble_app_uart/main.c
+++ b/ble_peripheral/ble_app_uart/main.c
@@ -91,8 +91,8 @@

 #define APP_ADV_DURATION                18000                                       /**&amp;lt; The advertising duration (180 seconds) in units of 10 milliseconds. */

-#define MIN_CONN_INTERVAL               MSEC_TO_UNITS(20, UNIT_1_25_MS)             /**&amp;lt; Minimum acceptable connection interval (20 ms), Connection interval uses 1.25 ms units. */
-#define MAX_CONN_INTERVAL               MSEC_TO_UNITS(75, UNIT_1_25_MS)             /**&amp;lt; Maximum acceptable connection interval (75 ms), Connection interval uses 1.25 ms units. */
+#define MIN_CONN_INTERVAL               MSEC_TO_UNITS(8, UNIT_1_25_MS)             /**&amp;lt; Minimum acceptable connection interval (20 ms), Connection interval uses 1.25 ms units. */^M
+#define MAX_CONN_INTERVAL               MSEC_TO_UNITS(8, UNIT_1_25_MS)             /**&amp;lt; Maximum acceptable connection interval (75 ms), Connection interval uses 1.25 ms units. */^M
 #define SLAVE_LATENCY                   0                                           /**&amp;lt; Slave latency. */
 #define CONN_SUP_TIMEOUT                MSEC_TO_UNITS(4000, UNIT_10_MS)             /**&amp;lt; Connection supervisory timeout (4 seconds), Supervision Timeout uses 10 ms units. */
 #define FIRST_CONN_PARAMS_UPDATE_DELAY  APP_TIMER_TICKS(5000)                       /**&amp;lt; Time from initiating event (connect or start of notification) to first time sd_ble_gap_conn_param_update is called (5 seconds). */
@@ -412,6 +412,10 @@ static void ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context)
                                              BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
             APP_ERROR_CHECK(err_code);
             break;
+        case BLE_GATTS_EVT_HVC:^M
+            //NRF_LOG_INFO(&amp;quot;Handle Value Confirmation.&amp;quot;);^M
+            APP_ERROR_CHECK(err_code);^M
+            break;^M

         default:
             // No implementation needed.
@@ -545,11 +549,12 @@ void uart_event_handle(app_uart_evt_t * p_event)
                         err_code = ble_nus_data_send(&amp;amp;m_nus, data_array, &amp;amp;length, m_conn_handle);
                         if ((err_code != NRF_ERROR_INVALID_STATE) &amp;amp;&amp;amp;
                             (err_code != NRF_ERROR_RESOURCES) &amp;amp;&amp;amp;
-                            (err_code != NRF_ERROR_NOT_FOUND))
+                            (err_code != NRF_ERROR_NOT_FOUND) &amp;amp;&amp;amp;^M
+                            (err_code != NRF_ERROR_BUSY))^M
                         {
                             APP_ERROR_CHECK(err_code);
                         }
-                    } while (err_code == NRF_ERROR_RESOURCES);
+                    } while ((err_code == NRF_ERROR_RESOURCES) || (err_code == NRF_ERROR_BUSY));^M
                 }

                 index = 0;
@@ -583,10 +588,10 @@ static void uart_init(void)
         .tx_pin_no    = TX_PIN_NUMBER,
         .rts_pin_no   = RTS_PIN_NUMBER,
         .cts_pin_no   = CTS_PIN_NUMBER,
-        .flow_control = APP_UART_FLOW_CONTROL_DISABLED,
+        .flow_control = APP_UART_FLOW_CONTROL_ENABLED,^M
         .use_parity   = false,
 #if defined (UART_PRESENT)
-        .baud_rate    = NRF_UART_BAUDRATE_115200
+        .baud_rate    = NRF_UARTE_BAUDRATE_230400^M
 #else
         .baud_rate    = NRF_UARTE_BAUDRATE_115200
 #endif
&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;SDK:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="diff"&gt;diff --git a/ble/ble_services/ble_nus/ble_nus.c b/ble/ble_services/ble_nus/ble_nus.c
index ca77de6..c629401 100644
--- a/ble/ble_services/ble_nus/ble_nus.c
+++ b/ble/ble_services/ble_nus/ble_nus.c
@@ -98,11 +98,13 @@ static void on_connect(ble_nus_t * p_nus, ble_evt_t const * p_ble_evt)
 
     if ((err_code == NRF_SUCCESS)     &amp;amp;&amp;amp;
         (p_nus-&amp;gt;data_handler != NULL) &amp;amp;&amp;amp;
-        ble_srv_is_notification_enabled(gatts_val.p_value))
+        /*ble_srv_is_notification_enabled(gatts_val.p_value))*/
+        ble_srv_is_indication_enabled(gatts_val.p_value))
     {
         if (p_client != NULL)
         {
-            p_client-&amp;gt;is_notification_enabled = true;
+            //p_client-&amp;gt;is_notification_enabled = true;
+            p_client-&amp;gt;is_indication_enabled = true;
         }
 
         memset(&amp;amp;evt, 0, sizeof(ble_nus_evt_t));
@@ -147,9 +149,11 @@ static void on_write(ble_nus_t * p_nus, ble_evt_t const * p_ble_evt)
     {
         if (p_client != NULL)
         {
-            if (ble_srv_is_notification_enabled(p_evt_write-&amp;gt;data))
+            /*if (ble_srv_is_notification_enabled(p_evt_write-&amp;gt;data))*/
+            if (ble_srv_is_indication_enabled(p_evt_write-&amp;gt;data))
             {
-                p_client-&amp;gt;is_notification_enabled = true;
+                //p_client-&amp;gt;is_notification_enabled = true;
+                p_client-&amp;gt;is_indication_enabled = true;
                 evt.type                          = BLE_NUS_EVT_COMM_STARTED;
             }
             else
@@ -300,7 +304,8 @@ uint32_t ble_nus_init(ble_nus_t * p_nus, ble_nus_init_t const * p_nus_init)
     add_char_params.max_len           = BLE_NUS_MAX_TX_CHAR_LEN;
     add_char_params.init_len          = sizeof(uint8_t);
     add_char_params.is_var_len        = true;
-    add_char_params.char_props.notify = 1;
+    //add_char_params.char_props.notify = 1;
+    add_char_params.char_props.indicate = 1;
 
     add_char_params.read_access       = SEC_OPEN;
     add_char_params.write_access      = SEC_OPEN;
@@ -330,7 +335,8 @@ uint32_t ble_nus_data_send(ble_nus_t * p_nus,
         return NRF_ERROR_NOT_FOUND;
     }
 
-    if (!p_client-&amp;gt;is_notification_enabled)
+    //if (!p_client-&amp;gt;is_notification_enabled)
+    if (!p_client-&amp;gt;is_indication_enabled)
     {
         return NRF_ERROR_INVALID_STATE;
     }
@@ -345,7 +351,8 @@ uint32_t ble_nus_data_send(ble_nus_t * p_nus,
     hvx_params.handle = p_nus-&amp;gt;tx_handles.value_handle;
     hvx_params.p_data = p_data;
     hvx_params.p_len  = p_length;
-    hvx_params.type   = BLE_GATT_HVX_NOTIFICATION;
+    //hvx_params.type   = BLE_GATT_HVX_NOTIFICATION;
+    hvx_params.type   = BLE_GATT_HVX_INDICATION;
 
     return sd_ble_gatts_hvx(conn_handle, &amp;amp;hvx_params);
 }
diff --git a/ble/ble_services/ble_nus/ble_nus.h b/ble/ble_services/ble_nus/ble_nus.h
index 8c5e977..62b4dbe 100644
--- a/ble/ble_services/ble_nus/ble_nus.h
+++ b/ble/ble_services/ble_nus/ble_nus.h
@@ -140,6 +140,7 @@ typedef struct
 typedef struct
 {
     bool is_notification_enabled; /**&amp;lt; Variable to indicate if the peer has enabled notification of the RX characteristic.*/
+    bool is_indication_enabled;
 } ble_nus_client_context_t;
 
 
&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;Credit:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://devzone.nordicsemi.com/f/nordic-q-a/37951/how-to-change-the-characteristic-property-from-notify-to-indicate"&gt;https://devzone.nordicsemi.com/f/nordic-q-a/37951/how-to-change-the-characteristic-property-from-notify-to-indicate&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;However the results do not improve dramatically.&lt;/p&gt;
&lt;p&gt;I &lt;em&gt;think &lt;/em&gt;the problem is that the characteristic is sometimes overwritten by the peripheral before the python script can read it, and therefore it seems that the data is lost.&lt;/p&gt;
&lt;p&gt;The only way I can think of is to implement another characteristic that can function as an ACK channel where the laptop can acknowledge receipt of a packet. Only when the peripheral receives the ACK does it write new data to the TX characteristic&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Reliability of the BLE UART example</title><link>https://devzone.nordicsemi.com/thread/366287?ContentTypeID=1</link><pubDate>Wed, 04 May 2022 14:08:46 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:d8665167-f679-4d6a-affe-a60368787dc7</guid><dc:creator>jmoraal</dc:creator><description>&lt;p&gt;Thanks. Enabling flow control also solves another problem with the example: If you send over the UART fast enough, an unhandled UART overflow error will occur. After enabling flow control the UART overflow never occurs&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Reliability of the BLE UART example</title><link>https://devzone.nordicsemi.com/thread/366199?ContentTypeID=1</link><pubDate>Wed, 04 May 2022 11:35:10 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:5a8a596a-29ce-4ba9-acf6-919aeb0634aa</guid><dc:creator>Susheel Nuguru</dc:creator><description>&lt;p&gt;Not sure if the flow control is enabled at both ends of the communication. If one end enable flowcontrol and the other end just pull the rtscts active, then it is in effect no flow control. 5-10% of data loss seems very high with flow control.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item></channel></rss>