<?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>Unexpected empty PDU</title><link>https://devzone.nordicsemi.com/f/nordic-q-a/110688/unexpected-empty-pdu</link><description>Hello, 
 I&amp;#39;m trying to transfer data from peripheral to Central (based on Central Uart and Peripheral Uart samples) continuously with a delay between each packet of about 450us. 
 
 Bluetooth LE parameters are accordingly 
 Central device 
 
 peripheral</description><dc:language>en-US</dc:language><generator>Telligent Community 13</generator><lastBuildDate>Fri, 03 May 2024 08:16:44 GMT</lastBuildDate><atom:link rel="self" type="application/rss+xml" href="https://devzone.nordicsemi.com/f/nordic-q-a/110688/unexpected-empty-pdu" /><item><title>RE: Unexpected empty PDU</title><link>https://devzone.nordicsemi.com/thread/481711?ContentTypeID=1</link><pubDate>Fri, 03 May 2024 08:16:44 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:83239b98-5561-400d-842e-09286dfcb855</guid><dc:creator>ovrebekk</dc:creator><description>&lt;p&gt;Glad I could help Mustafa &lt;span class="emoticon" data-url="https://devzone.nordicsemi.com/cfs-file/__key/system/emoji/1f642.svg" title="Slight smile"&gt;&amp;#x1f642;&lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Unexpected empty PDU</title><link>https://devzone.nordicsemi.com/thread/481614?ContentTypeID=1</link><pubDate>Thu, 02 May 2024 15:39:37 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:fd8e5455-22e1-4cfb-8b61-314654f7126d</guid><dc:creator>Mustafa</dc:creator><description>&lt;p&gt;Great! thanks&amp;nbsp;&lt;span&gt;Torbj&amp;oslash;rn for your time!&lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Unexpected empty PDU</title><link>https://devzone.nordicsemi.com/thread/481487?ContentTypeID=1</link><pubDate>Thu, 02 May 2024 10:02:04 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:451f52f8-2abc-4c54-9b06-86d35048160e</guid><dc:creator>ovrebekk</dc:creator><description>&lt;p&gt;Hi Mustafa&lt;/p&gt;
&lt;p&gt;I think what you are seeing here is just the end of the connection event. Typically the SoftDevice controller will reserve around 2ms at the end of each event for post processing etc.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;If you try with a longer connection interval (try somewhere around 15-30ms for instance) you might get longer bursts of packets without delay.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Please note that if the link quality is poor, and you drop one of the packets in the sequence, the rest of the connection event will be lost and you won&amp;#39;t be able to transmit anything else until the next connection event. So in poor RF conditions a shorter connection interval might be better.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;And if high throughput is the overall goal I would recommend combining multiple packets into one, in order to more efficiently use the radio. The ideal situation is to negotiate 251 byte data length and send 244 byte packets (leaving 7 bytes for the ATT and L2CAP headers).&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Best regards&lt;br /&gt;Torbjørn&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Unexpected empty PDU</title><link>https://devzone.nordicsemi.com/thread/481180?ContentTypeID=1</link><pubDate>Mon, 29 Apr 2024 20:39:13 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:cdda5667-3f64-4415-a310-b1bda76ee56f</guid><dc:creator>Mustafa</dc:creator><description>&lt;p&gt;Thank&amp;nbsp;&lt;span&gt;Torbj&amp;oslash;rn&amp;nbsp;&lt;/span&gt;for your reply.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Indeed the delay is not the best way to get a very accurate delay but this is only for demonstration purpose. I don&amp;#39;t think that those empty PDUs occur bc of this delay, this delay is only in microseconds and I have max connection event extension of 4 ms and a connection interval of 7.5 ms, so theoretically the PDU should be applied only if there is no communication within&amp;nbsp;4 ms right? but now the empty pdu is&amp;nbsp;transmitted by Master each 150us right after the notify events by&amp;nbsp;the slave and each 8 empty pdu packets a big delay of around 1736us appears.&amp;nbsp;This&amp;nbsp;delay happens consistently (not randomly seems like).&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Anyway I implemented your advice by using a timer and semaphore where 16 packets are sent without delay and after that wait 50ms again before sending the next 16 packets without any delay but unfortunately, the problem is still there.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;img style="max-height:240px;max-width:320px;" src="https://devzone.nordicsemi.com/resized-image/__size/640x480/__key/communityserver-discussions-components-files/4/pastedimage1714422313958v1.png" alt=" " /&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;static void connected(struct bt_conn *conn, uint8_t err)
{
	char addr[BT_ADDR_LE_STR_LEN];

	if (err) {
		LOG_ERR(&amp;quot;Connection failed (err %u)&amp;quot;, err);
		return;
	}

	bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
	LOG_INF(&amp;quot;Connected %s&amp;quot;, addr);

	current_conn = bt_conn_ref(conn);

	dk_set_led_on(CON_STATUS_LED);
	printk(&amp;quot;Resuming measure thread.\n&amp;quot;);
	k_timer_start(&amp;amp;sensor_timer, K_MSEC(50), K_MSEC(50));
}

static void disconnected(struct bt_conn *conn, uint8_t reason)
{
	char addr[BT_ADDR_LE_STR_LEN];

	bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));

	LOG_INF(&amp;quot;Disconnected: %s (reason %u)&amp;quot;, addr, reason);

	if (auth_conn) {
		bt_conn_unref(auth_conn);
		auth_conn = NULL;
	}

	if (current_conn) {
		bt_conn_unref(current_conn);
		current_conn = NULL;
		dk_set_led_off(CON_STATUS_LED);
		k_timer_stop(&amp;amp;sensor_timer);
	}

}
void send_sensor_data(struct k_timer *timer_id) {
	k_sem_give(&amp;amp;sensor_sema);
}

static void measure() {
        for (int i = 0; i &amp;lt; SAMPLES_PER_CYCLE; i++) {
            double sample = sin(theta);
            theta += theta_increment;

            // Scale the sample to fit within the range of 0 to 255
            int scaled_sample = (int)(sample * AMPLITUDE) + AMPLITUDE;

            // Ensure the sample is within the valid range
            if (scaled_sample &amp;lt; 0) 
                scaled_sample = 0;
            else if (scaled_sample &amp;gt; 255)
                scaled_sample = 255;
			for (uint8_t i = 0 ; i &amp;lt; CHUNK_NUMBER ; i++) {
				chunks[i].detial.sensor.data = (uint8_t)scaled_sample;

				if (i == 2) {// check chunk 3 (counting from 0)
					chunks[i].detial.reserved1.data += 1;
				}
				if (bt_nus_send(NULL, &amp;amp;chunks[i].data, sizeof(chunks[i].data))) {
					 LOG_WRN(&amp;quot;Failed to send data over BLE connection&amp;quot;);
				}
			}

        }
}

static void sensor_simulated_thread_fn(void)
{
	printk(&amp;quot;initialize measure thread.\n&amp;quot;);
	k_sem_init(&amp;amp;sensor_sema, 0, 1);
	while (true) {
		if (k_sem_take(&amp;amp;sensor_sema, K_FOREVER) == 0) {
			measure();
		}
	}
}&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Thanks again for your time!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Unexpected empty PDU</title><link>https://devzone.nordicsemi.com/thread/481092?ContentTypeID=1</link><pubDate>Mon, 29 Apr 2024 13:01:39 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:eb4a2059-a756-44f2-b8a5-06a440f2c61c</guid><dc:creator>ovrebekk</dc:creator><description>&lt;p&gt;Hi Mustafa&lt;/p&gt;
&lt;p&gt;I don&amp;#39;t think adding a delay like this is the best way to achieve a consistent rate,&amp;nbsp;since the delay doesn&amp;#39;t take into account the time spent by the bt_nus_send(..) function itself.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Could you try to run a &lt;a href="https://docs.zephyrproject.org/latest/kernel/services/timing/timers.html"&gt;Zephyr timer&lt;/a&gt;&amp;nbsp;instead, set (give) a semaphore in the timer callback, and wait for this semaphore (take) in the transmit loop?&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Then the timer will run at a consistent 450us, independent of how long the bt_nus_send(..) function might take.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Best regards&lt;br /&gt;Torbjørn&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item></channel></rss>