<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[two uart.readline() statements give interchanged data in threaded function]]></title><description><![CDATA[<p dir="auto">I have shown at the end of this post a code excerpt that shows the function I am asking about. The global variables have already been defined somewhere above, I just removed them to shorten it.<br />
This is a LoPy4 communicating with an STM32 microcontroller in a power electronics application.<br />
The line</p>
<pre><code>uart.write(&quot;rim_?\r&quot;)
</code></pre>
<p dir="auto">returns a string of this form</p>
<pre><code>5: 0d00h45m03.424s,5, 413,9928,0,0x000394000000, 755,9922,0,0x0003B6000000, 1058,9934,0,0x00038B000000, 3047,9929,0,0x000375000002, 3646,9947,2,0x0003A1000742
</code></pre>
<p dir="auto">This command runs once and  is necessary to get the id of the box which is previously unknown. I then split the string and extract the &quot;5&quot; which is an id of the microcontroller, after which I construct two further strings/commands using this id. These constructed commands are necessary because exactly the same commands are sent over the air from another LoPy4 and the receiving LoPy4 only responds if received command is the same as the constructed expected command. There are 2 lines that cause the STM32 to return data over the serial port.</p>
<p dir="auto">The line</p>
<pre><code>uart.write(exp_dmp_cmd)
</code></pre>
<p dir="auto">when called ALONE returns a string with 47 parts, separated by a comma, such as</p>
<pre><code>5: 0d00h45m03.394s,4,0,35.5, 14.617,3.605,3.616,3.601,3.782,9.16,27.2, 0,-0.278,-0.15,nan, 1,12.51,133.9, 0,nan,nan, 0,nan,nan,nan,nan,nan,0.000,0,0, 0,0,0,nan,nan,nan,nan, +0x22E844DBF,+0x1C12333835CB, +0x6E011DF,-0xB875CA77, -0x23066,-0x13497C4D, -0x18AAB4,-0x14E8E0D2E, +0x23CA6,+0x1DF7E31F
</code></pre>
<p dir="auto">and</p>
<pre><code>uart.write(exp_rim_cmd)
</code></pre>
<p dir="auto">WHEN CALLED ALONE (i.e with the uart.write(exp_dmp_cmd) commented out) returns the same string I showed earlier with 22 parts.</p>
<p dir="auto">My issue is:<br />
with both these lines in the function, the responses to these write statements are interchanged over 90% of the time! The read operation after the first write statement uart.write(exp_dmp_cmd) largely gives the 22 part response and the response after uart.write(exp_rim_cmd) largely gives the 47 part response. Sometimes, the responses are as expected but this happens randomly. I am 100% sure the issue is <em>not</em> with the STM32, which responds the expected way always using other platforms (e.g. PuTTY over a USB-serial connection). Moreover, it responds the expected way when we call only one of these write commands without calling the other.</p>
<p dir="auto">You will see a work around in the code. Because I must store a response in the proper variable, dmp_resp or rim_resp, what I currently doing is to count how may parts the response I got back (either 47 or 22) and then save that response in the proper variable.<br />
But the code defeats all logic. Not sure if it being in a threaded function has something to do with it.<br />
I am looking forward to possible reasons why this is happening.</p>
<pre><code>def uart_tx_rx():
    global dmp_resp, rim_resp,exp_dmp_cmd,exp_rim_cmd,id, new_dmp_data, new_rim_data
    dmp_resp, rim_resp, exp_dmp_cmd, exp_rim_cmd,id=&quot;&quot;,&quot;&quot;,&quot;&quot;,&quot;&quot;,&quot;&quot;
    new_dmp_data,new_dmp_data=False,False
    led_count=0;
    id_obtained=False

    while True:
        try:
            if not uart_locked:  #only run code inside when this flag is true

                while id==&quot;&quot;: #box has not yet been identified
                    uart.write(&quot;rim_?\r&quot;) #this returns an id in the first 1 or 2 bytes followed by a &quot;:&quot;
                    if(uart.any()&gt;0):
                        resp=uart.readline().decode('ascii','ignore')
                        id=resp.split(':')[0]
                    exp_dmp_cmd = &quot;dmp_?&quot;+id+&quot;\r&quot;
                    exp_rim_cmd = &quot;rim_?&quot;+id+&quot;\r&quot;
                    id_obtained=True
                    time.sleep(1)

                if id_obtained:
                    led_count+=1
                    if led_count%2==0:
                        toggleRGB(5,0xFF69B4,1) #led flash means we got a homebox id
                        led_count=0;

                res1,res2=&quot;&quot;,&quot;&quot;
                uart.write(exp_dmp_cmd)
                if (uart.any()&gt;0):
                    res1=uart.readline().decode('ascii','ignore')
                uart.write(exp_rim_cmd)
                if (uart.any()&gt;0):
                    res2=uart.readline().decode('ascii','ignore')

                col_cnt1=len(res1.split(','))
                col_cnt2=len(res2.split(','))
                if col_cnt1==47: #this is a dmp response
                    dmp_resp=res1
                if col_cnt1==22:
                    rim_resp=res1
                if col_cnt2==47:
                    dmp_resp=res2
                if col_cnt2==22:
                    rim_resp=res2

                if dmp_resp:
                    new_dmp_data=True
                if rim_resp:
                    new_rim_data=True
        except:
            pass
        time.sleep_ms(2000)

_thread.start_new_thread(uart_tx_rx, ())

</code></pre>
]]></description><link>https://forum.pycom.io/topic/6973/two-uart-readline-statements-give-interchanged-data-in-threaded-function</link><generator>RSS for Node</generator><lastBuildDate>Tue, 12 May 2026 18:19:47 GMT</lastBuildDate><atom:link href="https://forum.pycom.io/topic/6973.rss" rel="self" type="application/rss+xml"/><pubDate>Wed, 14 Apr 2021 19:13:36 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to two uart.readline() statements give interchanged data in threaded function on Wed, 14 Apr 2021 19:18:26 GMT]]></title><description><![CDATA[<p dir="auto">I have shown at the end of this post a code excerpt that shows the function I am asking about. The global variables have already been defined somewhere above, I just removed them to shorten it.<br />
This is a LoPy4 communicating with an STM32 microcontroller in a power electronics application.<br />
The line</p>
<pre><code>uart.write(&quot;rim_?\r&quot;)
</code></pre>
<p dir="auto">returns a string of this form</p>
<pre><code>5: 0d00h45m03.424s,5, 413,9928,0,0x000394000000, 755,9922,0,0x0003B6000000, 1058,9934,0,0x00038B000000, 3047,9929,0,0x000375000002, 3646,9947,2,0x0003A1000742
</code></pre>
<p dir="auto">This command runs once and  is necessary to get the id of the box which is previously unknown. I then split the string and extract the &quot;5&quot; which is an id of the microcontroller, after which I construct two further strings/commands using this id. These constructed commands are necessary because exactly the same commands are sent over the air from another LoPy4 and the receiving LoPy4 only responds if received command is the same as the constructed expected command. There are 2 lines that cause the STM32 to return data over the serial port.</p>
<p dir="auto">The line</p>
<pre><code>uart.write(exp_dmp_cmd)
</code></pre>
<p dir="auto">when called ALONE returns a string with 47 parts, separated by a comma, such as</p>
<pre><code>5: 0d00h45m03.394s,4,0,35.5, 14.617,3.605,3.616,3.601,3.782,9.16,27.2, 0,-0.278,-0.15,nan, 1,12.51,133.9, 0,nan,nan, 0,nan,nan,nan,nan,nan,0.000,0,0, 0,0,0,nan,nan,nan,nan, +0x22E844DBF,+0x1C12333835CB, +0x6E011DF,-0xB875CA77, -0x23066,-0x13497C4D, -0x18AAB4,-0x14E8E0D2E, +0x23CA6,+0x1DF7E31F
</code></pre>
<p dir="auto">and</p>
<pre><code>uart.write(exp_rim_cmd)
</code></pre>
<p dir="auto">WHEN CALLED ALONE (i.e with the uart.write(exp_dmp_cmd) commented out) returns the same string I showed earlier with 22 parts.</p>
<p dir="auto">My issue is:<br />
with both these lines in the function, the responses to these write statements are interchanged over 90% of the time! The read operation after the first write statement uart.write(exp_dmp_cmd) largely gives the 22 part response and the response after uart.write(exp_rim_cmd) largely gives the 47 part response. Sometimes, the responses are as expected but this happens randomly. I am 100% sure the issue is <em>not</em> with the STM32, which responds the expected way always using other platforms (e.g. PuTTY over a USB-serial connection). Moreover, it responds the expected way when we call only one of these write commands without calling the other.</p>
<p dir="auto">You will see a work around in the code. Because I must store a response in the proper variable, dmp_resp or rim_resp, what I currently doing is to count how may parts the response I got back (either 47 or 22) and then save that response in the proper variable.<br />
But the code defeats all logic. Not sure if it being in a threaded function has something to do with it.<br />
I am looking forward to possible reasons why this is happening.</p>
<pre><code>def uart_tx_rx():
    global dmp_resp, rim_resp,exp_dmp_cmd,exp_rim_cmd,id, new_dmp_data, new_rim_data
    dmp_resp, rim_resp, exp_dmp_cmd, exp_rim_cmd,id=&quot;&quot;,&quot;&quot;,&quot;&quot;,&quot;&quot;,&quot;&quot;
    new_dmp_data,new_dmp_data=False,False
    led_count=0;
    id_obtained=False

    while True:
        try:
            if not uart_locked:  #only run code inside when this flag is true

                while id==&quot;&quot;: #box has not yet been identified
                    uart.write(&quot;rim_?\r&quot;) #this returns an id in the first 1 or 2 bytes followed by a &quot;:&quot;
                    if(uart.any()&gt;0):
                        resp=uart.readline().decode('ascii','ignore')
                        id=resp.split(':')[0]
                    exp_dmp_cmd = &quot;dmp_?&quot;+id+&quot;\r&quot;
                    exp_rim_cmd = &quot;rim_?&quot;+id+&quot;\r&quot;
                    id_obtained=True
                    time.sleep(1)

                if id_obtained:
                    led_count+=1
                    if led_count%2==0:
                        toggleRGB(5,0xFF69B4,1) #led flash means we got a homebox id
                        led_count=0;

                res1,res2=&quot;&quot;,&quot;&quot;
                uart.write(exp_dmp_cmd)
                if (uart.any()&gt;0):
                    res1=uart.readline().decode('ascii','ignore')
                uart.write(exp_rim_cmd)
                if (uart.any()&gt;0):
                    res2=uart.readline().decode('ascii','ignore')

                col_cnt1=len(res1.split(','))
                col_cnt2=len(res2.split(','))
                if col_cnt1==47: #this is a dmp response
                    dmp_resp=res1
                if col_cnt1==22:
                    rim_resp=res1
                if col_cnt2==47:
                    dmp_resp=res2
                if col_cnt2==22:
                    rim_resp=res2

                if dmp_resp:
                    new_dmp_data=True
                if rim_resp:
                    new_rim_data=True
        except:
            pass
        time.sleep_ms(2000)

_thread.start_new_thread(uart_tx_rx, ())

</code></pre>
]]></description><link>https://forum.pycom.io/post/37879</link><guid isPermaLink="true">https://forum.pycom.io/post/37879</guid><dc:creator><![CDATA[mbyamukama]]></dc:creator><pubDate>Wed, 14 Apr 2021 19:18:26 GMT</pubDate></item><item><title><![CDATA[Reply to two uart.readline() statements give interchanged data in threaded function on Wed, 14 Apr 2021 20:50:45 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="https://forum.pycom.io/uid/6154">@mbyamukama</a> add traces (logs) to your code. You’ll find out it’s not doing what you expect it to do in the order you want.</p>
<p dir="auto">The root cause is the <code>any</code> test. It probably comes too early (the STM32 hasn’t had time to answer yet, or not enough). The you send the other command and by then you get the response to the first command. And then you loop back and get the answer to the second command after sending (again) the first command.</p>
<p dir="auto">Since you are running on a thread the <code>any</code> is probably not needed anyway. If you want or need to keep it you will probably need a state machine.</p>
]]></description><link>https://forum.pycom.io/post/37880</link><guid isPermaLink="true">https://forum.pycom.io/post/37880</guid><dc:creator><![CDATA[jcaron]]></dc:creator><pubDate>Wed, 14 Apr 2021 20:50:45 GMT</pubDate></item><item><title><![CDATA[Reply to two uart.readline() statements give interchanged data in threaded function on Thu, 29 Apr 2021 12:26:00 GMT]]></title><description><![CDATA[<p dir="auto">Thank you for your help. I will come back after trying this.</p>
]]></description><link>https://forum.pycom.io/post/38059</link><guid isPermaLink="true">https://forum.pycom.io/post/38059</guid><dc:creator><![CDATA[mbyamukama]]></dc:creator><pubDate>Thu, 29 Apr 2021 12:26:00 GMT</pubDate></item></channel></rss>