<?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>Algorithm of work with GNSS via UART</title><link>https://devzone.nordicsemi.com/f/nordic-q-a/106722/algorithm-of-work-with-gnss-via-uart</link><description>Good Day. 
 I am using a custom board based on an nRF52840 microcontroller and a RYS8830 GNSS receiver connected to it via UART0. 
 SDK v2.5.99 (Toolchain v2.5.0). 
 I want to get the coordinates of the board location (via asynchronous UART0) and output</description><dc:language>en-US</dc:language><generator>Telligent Community 13</generator><lastBuildDate>Wed, 07 Feb 2024 15:23:47 GMT</lastBuildDate><atom:link rel="self" type="application/rss+xml" href="https://devzone.nordicsemi.com/f/nordic-q-a/106722/algorithm-of-work-with-gnss-via-uart" /><item><title>RE: Algorithm of work with GNSS via UART</title><link>https://devzone.nordicsemi.com/thread/467957?ContentTypeID=1</link><pubDate>Wed, 07 Feb 2024 15:23:47 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:b0a66926-9ee6-43e8-90f4-0a641ecf9803</guid><dc:creator>Einar Thorsrud</dc:creator><description>&lt;p&gt;I see. If you receive data rapitly, it is not viable to receive single bytes at a time. I would use a larger receive buffer, so that data is received directly with DMA, without the CPU needing to handle it continiously. You can still set a timeout if you want to handle the data withing reasonable time. The &lt;a href="https://developer.nordicsemi.com/nRF_Connect_SDK/doc/2.2.0/zephyr/hardware/peripherals/uart.html#uart-async-api"&gt;Async UART API&lt;/a&gt; is probably what you want to use for this. (This API can be a bit confusing, but &lt;a href="https://www.youtube.com/watch?v=ikRS9XXZGGA"&gt;this video&lt;/a&gt; explains it in a good way).&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Algorithm of work with GNSS via UART</title><link>https://devzone.nordicsemi.com/thread/467814?ContentTypeID=1</link><pubDate>Tue, 06 Feb 2024 20:28:33 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:14db4272-f0e0-4936-98ae-ae5ab9b939aa</guid><dc:creator>backstreet.devisor</dc:creator><description>&lt;p&gt;Hi, Einar.&lt;/p&gt;
&lt;p&gt;When I start GNSS I get a data packet like the one below once per second. And as time passes, the amount of data (number of characters) increases.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;$GNRMC,,V,,,,,,,,,,N*4D&lt;br /&gt;$GNVTG,,,,,,,,,N*2E&lt;br /&gt;$GNGGA,,,,,,0,00,99.99,,,,,,*56&lt;br /&gt;$GNGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*2E&lt;br /&gt;$GNGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*2E&lt;br /&gt;$GPGSV,1,1,00*79&lt;br /&gt;$GLGSV,1,1,00*65&lt;br /&gt;$GNGLL,,,,,,V,N*7A&lt;/p&gt;
&lt;p&gt;The result is that the interrupt from the UART is triggered as many times as there are characters in the packet, which is several hundred times per second.&amp;nbsp;The time between UART interrupts is not enough time for gnss_work_cb to execute.&amp;nbsp;This can be seen on the screenshot (underlined with a red line), the thread does not have time to print the copied character in the sentence array.&lt;/p&gt;
&lt;p&gt;&lt;img style="max-height:240px;max-width:320px;" alt=" " src="https://devzone.nordicsemi.com/resized-image/__size/640x480/__key/communityserver-discussions-components-files/4/2308.GNNS-connected.jpg" /&gt;&lt;/p&gt;
&lt;p&gt;I don&amp;#39;t have any other tasks in my program at the moment. I only need to parsing the string $GNRMC, but so far I can&amp;#39;t do it.&lt;/p&gt;
&lt;p&gt;What can you advise me based on your experience?&lt;/p&gt;
&lt;p&gt;Thank you.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Algorithm of work with GNSS via UART</title><link>https://devzone.nordicsemi.com/thread/467769?ContentTypeID=1</link><pubDate>Tue, 06 Feb 2024 14:42:11 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:10231cd5-aa6b-40a1-ad83-d4ba2ed52a45</guid><dc:creator>Einar Thorsrud</dc:creator><description>&lt;p&gt;Hi,&lt;/p&gt;
&lt;p&gt;In the original post you wrote that one character is recevied every second. If that is the case, then you should have ample time to receive and process one character at a time as you describe. Why did you conclude that CPU is a limiting factor here? Do you do a lot of other work every time a character is received?&lt;/p&gt;
&lt;p&gt;If it is so that this casue a lot of CPU activity, then I would start to figure out what parts of the handling contribute to the CPU usage, as that is not obvious to me.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Algorithm of work with GNSS via UART</title><link>https://devzone.nordicsemi.com/thread/467656?ContentTypeID=1</link><pubDate>Mon, 05 Feb 2024 19:43:11 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:bbbce177-fdfb-44fe-91f1-ee2875ebdb93</guid><dc:creator>backstreet.devisor</dc:creator><description>&lt;p&gt;Any idea how to implement this, assuming that the interrupt from the UART consumes almost all of the CPU time because the data from GNSS is coming almost continuously?&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Algorithm of work with GNSS via UART</title><link>https://devzone.nordicsemi.com/thread/467479?ContentTypeID=1</link><pubDate>Sun, 04 Feb 2024 19:50:24 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:9096e805-9526-40f7-aead-9c5f14d92d5b</guid><dc:creator>backstreet.devisor</dc:creator><description>&lt;p&gt;Hi. At the moment I have the following problem.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;I want to receive one symbol at a time from GNSS (rx_buf size = 1) and pass it immediately to the queue for further processing.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;static void uart_cb(const struct device *dev, struct uart_event *evt, void *user_data)
{
	switch (evt-&amp;gt;type) {

	case UART_RX_RDY:
		LOG_DBG(&amp;quot;rx_buf[0] = %c \n&amp;quot;, rx_buf[0]);
			k_work_submit_to_queue(&amp;amp;gnss_work_q, &amp;amp;gnss_work);
		break;

	case UART_RX_DISABLED:
		uart_rx_enable(dev, rx_buf, sizeof(rx_buf), RECEIVE_TIMEOUT);
		break;

	default:
		break;
	}
}&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;In the thread, I write the received characters to the &amp;quot;sentence&amp;quot; array until the end of line character is received.&lt;br /&gt;Then the parser decodes the sentence array.&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;int i = 0;

static void gnss_work_cb (struct k_work *work){

if (rx_buf[0] != &amp;#39;\n&amp;#39;)
{
	sentence[i] = rx_buf[0];
	LOG_DBG(&amp;quot;sentence[%d] = %c \n&amp;quot;, i, sentence[i]);
	i++;
}
  else
 {
	LOG_DBG(&amp;quot;%s \r\n&amp;quot;, sentence);
	struct minmea_sentence_rmc frame;
	if(minmea_parse_rmc(&amp;amp;frame, sentence)){
                    LOG_DBG(INDENT_SPACES &amp;quot;$xxRMC floating point degree coordinates and speed: (%f,%f) %f\n&amp;quot;,
                            minmea_tocoord(&amp;amp;frame.latitude),
                            minmea_tocoord(&amp;amp;frame.longitude),
                            minmea_tofloat(&amp;amp;frame.speed));
                }
                else {
                    LOG_DBG(INDENT_SPACES &amp;quot;$xxRMC sentence is not parsed\n&amp;quot;);
                }
                
	memset(sentence, 0, sizeof(sentence));
	LOG_DBG(&amp;quot;i = %d \r\n&amp;quot;, i);
	i = 0;
}&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;When I connect GNSS and test the program I get the following results as on the screenshot&lt;/p&gt;
&lt;p&gt;&lt;img style="max-height:240px;max-width:320px;" alt=" " src="https://devzone.nordicsemi.com/resized-image/__size/640x480/__key/communityserver-discussions-components-files/4/GNNS-connected.jpg" /&gt;&lt;/p&gt;
&lt;p&gt;It seems that there is not enough CPU time for the workflow.&lt;/p&gt;
&lt;p&gt;How can this be fixed?&amp;nbsp; &amp;nbsp;&lt;/p&gt;
&lt;p&gt;If I disable GNSS and manually enter the NMEA string (simulating sending a message from GNSS), everything works correctly.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;img style="max-height:240px;max-width:320px;" alt=" " src="https://devzone.nordicsemi.com/resized-image/__size/640x480/__key/communityserver-discussions-components-files/4/manual-sentence.jpg" /&gt;&lt;/p&gt;
&lt;p&gt;Can you please tell me where I&amp;#39;m making a mistake? &lt;br /&gt;Thank you.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Algorithm of work with GNSS via UART</title><link>https://devzone.nordicsemi.com/thread/465224?ContentTypeID=1</link><pubDate>Mon, 22 Jan 2024 07:58:49 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:30e15142-70a5-40d4-8bdc-35fd1f782cd6</guid><dc:creator>Einar Thorsrud</dc:creator><description>&lt;p&gt;Hi,&lt;/p&gt;
&lt;p&gt;Logs are dropped, so you are logging faster than the logs can be processed output. If the logging is in bursts, you can solve this issue by increasing the log buffers like this (adjust the values as needed):&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;CONFIG_LOG_BUFFER_SIZE=15360
CONFIG_SEGGER_RTT_BUFFER_SIZE_UP=15360&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;You can also consider adding&amp;nbsp;&lt;code&gt;CONFIG_LOG_MODE_IMMEDIATE=y&lt;/code&gt; to process log, but this will impact the timing/performance more though, as logs are processed in place wherever you do any logging. (If you do this th einternal log buffer is not used, so there would be no point in increasing &lt;code&gt;CONFIG_LOG_BUFFER_SIZE&lt;/code&gt;.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Algorithm of work with GNSS via UART</title><link>https://devzone.nordicsemi.com/thread/465198?ContentTypeID=1</link><pubDate>Sun, 21 Jan 2024 21:03:17 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:ce042793-9735-43ad-9567-0b0e87443d2c</guid><dc:creator>backstreet.devisor</dc:creator><description>&lt;p&gt;Thanks.&lt;/p&gt;
&lt;p&gt;I would also like to ask why when I connect GNSS to my board (UART speed is 9600) and try to output incoming data via RTT Terminal, I see missing messages?&lt;/p&gt;
&lt;p&gt;&lt;img style="max-height:240px;max-width:320px;" alt=" " src="https://devzone.nordicsemi.com/resized-image/__size/640x480/__key/communityserver-discussions-components-files/4/dropped-messages.jpg" /&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Algorithm of work with GNSS via UART</title><link>https://devzone.nordicsemi.com/thread/465061?ContentTypeID=1</link><pubDate>Fri, 19 Jan 2024 13:40:21 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:8cb14120-3b2c-48d7-8a89-30f5949bc9f6</guid><dc:creator>Einar Thorsrud</dc:creator><description>&lt;p&gt;You can refer to how it is done in&amp;nbsp;nrf/manifest-tmp/lib/modem_slm/modem_slm.c.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Algorithm of work with GNSS via UART</title><link>https://devzone.nordicsemi.com/thread/465050?ContentTypeID=1</link><pubDate>Fri, 19 Jan 2024 13:05:04 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:12b3ad6b-2fb2-4ee7-8606-557011ceefdc</guid><dc:creator>backstreet.devisor</dc:creator><description>&lt;p&gt;I got you. Is there a code example of using two buffers?&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Algorithm of work with GNSS via UART</title><link>https://devzone.nordicsemi.com/thread/465048?ContentTypeID=1</link><pubDate>Fri, 19 Jan 2024 13:00:01 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:e9b8be0f-bf97-4a3e-9d30-48b714d88062</guid><dc:creator>Einar Thorsrud</dc:creator><description>&lt;p&gt;Not with async UART. But two buffers is enough, and then you can alternate between them (that is commonly done).&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Algorithm of work with GNSS via UART</title><link>https://devzone.nordicsemi.com/thread/465029?ContentTypeID=1</link><pubDate>Fri, 19 Jan 2024 12:06:00 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:08ea9558-46ab-4a04-beb7-8de39533472f</guid><dc:creator>backstreet.devisor</dc:creator><description>&lt;p&gt;So the only way out is to add an additional receive buffer? This problem cannot be solved with a single buffer?&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Algorithm of work with GNSS via UART</title><link>https://devzone.nordicsemi.com/thread/465020?ContentTypeID=1</link><pubDate>Fri, 19 Jan 2024 11:48:27 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:f1cc2667-8af5-4e0a-9cfc-ad901102b419</guid><dc:creator>Einar Thorsrud</dc:creator><description>&lt;p&gt;Hi,&lt;/p&gt;
&lt;p&gt;You do not need to clear the buffer with memset. And what you do here is not related to receiving new data. With asycn UART, you will get an evernt about providing a new buffer (UART_RX_BUF_REQUEST). You can read more about it in the &lt;a href="https://academy.nordicsemi.com/courses/nrf-connect-sdk-fundamentals/lessons/lesson-4-serial-communication-uart/topic/uart-driver/"&gt;UART Driver section&lt;/a&gt;&amp;nbsp;of the&amp;nbsp;nRF Connect SDK Fundamentals course. If you want a good overview of how to work with async UART, I would also recomend this video: &lt;a href="https://www.youtube.com/watch?v=ikRS9XXZGGA"&gt;Zephyr 101 - Async UART&lt;/a&gt;.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Algorithm of work with GNSS via UART</title><link>https://devzone.nordicsemi.com/thread/464901?ContentTypeID=1</link><pubDate>Thu, 18 Jan 2024 18:08:23 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:d664a08e-f696-4004-8f9e-c0dedddf69c4</guid><dc:creator>backstreet.devisor</dc:creator><description>&lt;p&gt;Thank you, Einar, for your reply.&lt;br /&gt;Can you please tell me how to properly clear the receive buffer (rx_buf) of the UART?&lt;/p&gt;
&lt;p&gt;My plan is as follows, I receive data (NMEA messages) from the GNSS receiver and write it to rx_buf (buffer size 83 bytes) until the newline character &amp;#39;\n&amp;#39; arrives.&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;/* Define the callback function for UART0 */
static void uart_cb(const struct device *dev, struct uart_event *evt, void *user_data)
{
	switch (evt-&amp;gt;type) {

	case UART_RX_RDY:
		if(evt-&amp;gt;data.rx.buf[evt-&amp;gt;data.rx.offset] == &amp;#39;\n&amp;#39;){
		    memcpy(rx_buf_cpy, rx_buf, sizeof(rx_buf));
			k_work_submit_to_queue(&amp;amp;gnss_work_q, &amp;amp;gnss_work);
			memset(rx_buf, 0, sizeof(rx_buf));
		}
		break;

	case UART_RX_DISABLED:
		uart_rx_enable(dev, rx_buf, sizeof rx_buf, RECEIVE_TIMEOUT);
		break;

	default:
		break;
	}
}&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;When a newline character is detected, I copy the contents of rx_buf to rx_buf_cpy using the memcpy function and send the data to the queue.&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;static void gnss_work_cb (struct k_work *work){

   // Parsing rx_buf_cpy array
}&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;I then clear the receive buffer rx_buf in the UART callback function using the memset function.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;But apparently my approach doesn&amp;#39;t work, because after the first clearing of rx_buf no further writes are made to the buffer and the buffer remains empty.&lt;/p&gt;
&lt;p&gt;Please tell me how to do it correctly in my case. I will be grateful for any help.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Algorithm of work with GNSS via UART</title><link>https://devzone.nordicsemi.com/thread/460828?ContentTypeID=1</link><pubDate>Mon, 18 Dec 2023 13:29:21 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:d4e722b9-25f2-4ebb-8006-e5c5e1e2507e</guid><dc:creator>Einar Thorsrud</dc:creator><description>&lt;p&gt;Hi,&lt;/p&gt;
&lt;p&gt;You should not process the data in an interrupt (like a UART callback), so I would suggest that you use&amp;nbsp;a&amp;nbsp;worqeueue for that. See &lt;a href="https://developer.nordicsemi.com/nRF_Connect_SDK/doc/2.5.0/zephyr/kernel/services/threads/workqueue.html"&gt;Workqueue Threads&lt;/a&gt;. You can refer to the &lt;a href="https://academy.nordicsemi.com/courses/nrf-connect-sdk-fundamentals/lessons/lesson-7-multithreaded-applications/topic/exercise-3-7/"&gt;Workqueue creation and work item submission&amp;nbsp;Exercise&lt;/a&gt;&amp;nbsp;for an eaxmple of using a workqueue.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item></channel></rss>