<?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>How to subscribe/read a characteristic over BLE?</title><link>https://devzone.nordicsemi.com/f/nordic-q-a/96246/how-to-subscribe-read-a-characteristic-over-ble</link><description>Hello! I&amp;#39;m trying to figure out how to program a nRF52832 to subscribe and read from a TX or custom characteristic on another nRF52832. My environment: 
 
 NRF Connect SDK in VSCode - Version 2.1.1 
 Zephyr v3.1.99 
 
 What I&amp;#39;ve done so far: 
 
 I&amp;#39;ve</description><dc:language>en-US</dc:language><generator>Telligent Community 13</generator><lastBuildDate>Tue, 07 Feb 2023 09:43:45 GMT</lastBuildDate><atom:link rel="self" type="application/rss+xml" href="https://devzone.nordicsemi.com/f/nordic-q-a/96246/how-to-subscribe-read-a-characteristic-over-ble" /><item><title>RE: How to subscribe/read a characteristic over BLE?</title><link>https://devzone.nordicsemi.com/thread/408483?ContentTypeID=1</link><pubDate>Tue, 07 Feb 2023 09:43:45 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:07180485-ce15-4a80-acf4-5f6906c77a0f</guid><dc:creator>ovrebekk</dc:creator><description>&lt;p&gt;Hi&lt;/p&gt;
[quote user="jksu"]This would return 49 for 1, 50 for 2, etc.[/quote]
&lt;p&gt;Yes, 49 is the ASCII Code for &amp;#39;1&amp;#39;, 50 for &amp;#39;2 and so on.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;There is another trick to print non null terminated strings, as explained &lt;a href="https://embeddedartistry.com/blog/2017/07/05/printf-a-limited-number-of-characters-from-a-string/"&gt;here&lt;/a&gt;.&amp;nbsp;&lt;br /&gt;I don&amp;#39;t remember if I tested this with printk(..), but you could always give this a go. In the ble_data_received callback it should look something like this:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;printk(&amp;quot;Received string: %*.s\n&amp;quot;, len, data);&lt;/pre&gt;&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: How to subscribe/read a characteristic over BLE?</title><link>https://devzone.nordicsemi.com/thread/408104?ContentTypeID=1</link><pubDate>Fri, 03 Feb 2023 23:37:54 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:d84d6c19-8ca8-4b10-8366-dda1e1aca47d</guid><dc:creator>jksu</dc:creator><description>&lt;p&gt;Hello!&lt;/p&gt;
&lt;p&gt;Once again, I appreciate the detailed answer! If there will be a simpler example in the future,&amp;nbsp;I would definitely be interested in reading through it&lt;/p&gt;
&lt;p&gt;As for my original question, your answer worked for me! I originally tried&amp;nbsp;printing&amp;nbsp;the data you mentioned in your answer above, but I ended up getting weirdly interpreted values, as I was printing with a PRId8 type specifier. This would return 49 for 1, 50 for 2, etc. I changed the format specifier to a char, and the answer came as expected!&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;static uint8_t ble_data_received(struct bt_nus_client *nus,
								 const uint8_t *data, uint16_t len)
{
    ...
        for (int i=0;i&amp;lt;len;i++){
    		printk(&amp;quot;%c&amp;quot;, data[i]);
    	}
    	printk(&amp;quot;\n&amp;quot;);
    }
	
	return BT_GATT_ITER_CONTINUE;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;I hope it seems that I&amp;#39;ve implemented this properly, but as you mentioned, there&amp;#39;s likely a cleaner way to handle the data.&amp;nbsp;&lt;br /&gt;&lt;br /&gt;Anyways, thank you again for answering my questions!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: How to subscribe/read a characteristic over BLE?</title><link>https://devzone.nordicsemi.com/thread/407926?ContentTypeID=1</link><pubDate>Fri, 03 Feb 2023 09:11:04 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:fbdb35a3-6cb8-4dbe-be7a-5cfb47064ec6</guid><dc:creator>ovrebekk</dc:creator><description>&lt;p&gt;Hi&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The data is actually provided directly in the arguments of the ble_data_received function:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;static uint8_t ble_data_received(struct bt_nus_client *nus, const uint8_t *data, uint16_t len)&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;The second argument points to the data buffer, and the third argument provides the length.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;In theory you could delete more or less the entire implementation of this function, with the exception of the return call at the end, and just process the data in some other way.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;(The standard example is not the best IMO as it uses dynamic memory allocation, and makes the flow of the code pretty hard to follow, and I have it on my todo list to try and provide a simpler example.)&lt;/p&gt;
&lt;p&gt;It is important to note that this callback function is running in an interrupt context, which means it is very limited what you are allowed to do in the callback directly.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The normal way to handle this is to move the data into a separate buffer, and set a flag or a semaphore that allows you to process the data from the thread context rather than in the interrupt.&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: How to subscribe/read a characteristic over BLE?</title><link>https://devzone.nordicsemi.com/thread/407863?ContentTypeID=1</link><pubDate>Thu, 02 Feb 2023 23:40:27 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:abc3b979-a920-4694-8849-49ec9c37b82f</guid><dc:creator>jksu</dc:creator><description>&lt;p&gt;Hello&amp;nbsp;&lt;span&gt;Torbj&amp;oslash;rn,&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Thank you for such a quick reply! Upon messing around with my code a little bit, I ended up getting the TX characteristic to print out via Serial on the Central device, so the code does work as expected. I think there was an issue caused by having CONFIG_ASSERT=y on the peripheral prj.conf.&amp;nbsp;&lt;br /&gt;&lt;br /&gt;Your answer makes a lot of sense, and I took a look at the parts of the code you referenced, and the flow is more apparent to me now. One more thing that might be helpful for me is how to extract or store the TX characteristic data. I see in the nus_client.c file, the TX data is returned on line 44 by this snippet:&lt;br /&gt;&lt;br /&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;if (nus-&amp;gt;cb.received) {
	return nus-&amp;gt;cb.received(nus, data, length);
}&lt;/pre&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;I&amp;#39;m having a bit of trouble tracing the value down in main(), but I suspect it may be somewhere near ble_data_received() and tx-&amp;gt;data, but I haven&amp;#39;t been fruitful in my attempts to track down where the data is being put. Any clarification would be appreciated!&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: How to subscribe/read a characteristic over BLE?</title><link>https://devzone.nordicsemi.com/thread/407820?ContentTypeID=1</link><pubDate>Thu, 02 Feb 2023 14:47:42 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:11b10ea4-dd9d-4a24-85c3-d8a3778b6e25</guid><dc:creator>ovrebekk</dc:creator><description>&lt;p&gt;Hi&lt;/p&gt;
&lt;p&gt;The central_uart should subscribe to the RX characteristic out of the box. Are you not able to get this to work?&amp;nbsp;&lt;/p&gt;
&lt;p&gt;If you look inside the discovery_complete(..) callback on line 293 of main.c you will notice it calls the&amp;nbsp;bt_nus_subscribe_receive(..) function, the implementation of which can be found on line 172 of nus_client.c.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Here you can see how it calls bt_gatt_subscribe(..), after checking that notifications are not enabled already. It also sets a callback function called on_received which will be used to process incoming data from the connected peripheral. The on_received(..) callback function will in turn call the received callback, which triggers&amp;nbsp;ble_data_received(..) in main.c.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;If you want to make your own proprietary characteristic then a good way to do this is simply to copy the existing nus implementation, give it a different name (replacing all instance of &amp;quot;nus&amp;quot; or &amp;quot;NUS&amp;quot; with your own name), and then modifying it as you see fit.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;You should also give it a different 128-bit UUID to ensure you don&amp;#39;t get your device mixed up with all the devices using NUS.&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>