How to read string using UART ?

Discussion about programs, libraries and tools that work with MicroPython. Mostly these are provided by a third party.
Target audience: All users and developers of MicroPython.
Post Reply
nikhiledutech
Posts: 118
Joined: Wed Dec 27, 2017 8:52 am

How to read string using UART ?

Post by nikhiledutech » Thu Mar 01, 2018 10:19 am

Hello,

I am currently working with GNSS Sensor(GPS). It outputs raw data from which we have to parse the required data for latitude, longitude etc. So i am reading data from sensor using UART4.

The desired output should be line of strings of raw data. But what i am getting is an hex value. Something like this.
Here i have used a byrterarray of 255 size.
uart.readinto(buffer) O/P
\x02\xc5\xcd\xa1\x03 A\x83M\xf9\x08\xf7\xd5\xc7\x0f\x1c\xc3\x10\xa7\x1c\xe0\xc1\x87\xe1\x91\x85\xd0\xfdV\x08\x91\x8c\xc3\x84P C\r\x93\xf4CV\xffV\x0e\xb1\x94\xc5\x8d\xa1\x03 C\r\x97R\xc3\xe7\xf0\xd5\xda\x1f\x94\xc5-C\x1cW\x88\xc1,\xf3\x00\xd3\xe5\xeb@\x08\xdc\xf2\x13\x87\x9f\x84\xc1\x9b,\x89\x04\x93\xe1E\xab\xf0\x96f\xf0%8\x91\x1c\xc5/\xc5\x82\x04C\r\x97R\xc3\xe7\xf0\x03\x1b\xe5\x12\xc5m\xa1\x82CB\x83M\xb4\xc3\xc6\xfc\x15\x9a\x95\x10\xc3\x84\x80\xc3A\x83M\xfd\x81\xd4\xff\x15\x8a\xa7!\xc1b\xcb@\x19!\x87\x11v\x13\x93,\x88\x14\xc5T\x01EY\x87\xe5\x05\xc7\xc6\xfcV\x08\x15\x85\xc1\x80\x05\xedC\rM\xf9\x90\xc6\xfc\x07\x88\xe5&\x8f\xc5\x0c\x10E\xdb\xe6C\xe7\xec\x85\xd0\xffU\xc7\xcbq\xc5/\xc5\x82\xc2A\r\x93@\x08\xdc\xf2\x07\xac\x11#\xc3H\x10 \xc3\x8f\xd0\x91\x85\xd4\xffC\x8e\x8d\x1c\xc5\x84\x01\x00\x93\xe5\xea@\x08\xdc\xffU\n\xaf1')
So how to read values inform of strings using uart ?

I have used uart.readline() function but it also give same sort of O/p.
uart.readline() output
b'a\x1d\xeb\x07\xe9\x03\x0e\xaf1\xc1\x80L\x96\x11J\x9a\xe2%L\xd6g\xffS\xa1\x10C\x84E\xf6\xf3\xc6V`N\xeb\x07\xf3\xa5\x89\xa1\x10A\x80E\xe6\xf3\x8cV`N\xd6\x07\xf3\x03\x12\x88\x14\xc5TB\x18R\xc3F\x90\xd5*\x11\x19\xc3b\xcb\x96\xa8\xe3\x85hL\xd6\x07\xf3T\n'

Also same result with uart.readchar()
bytearray(b"c\x07\xef!\xc1B\xcb\x921\x8a\xe1\xe2%L\xd6\x82\xf4\xd5\x8a\x01\x94\xc5/,C\xcc\x8a\xed\x85h\x0c\xc6\xe7L\xff#2\x12\xc5m\xa1B\x18=\xf3\xa1F\x90G\xb6\xff\x95\x8a\xad1\xc5\x80,\xb3\xcc\x88\xed\x85hL%\x89\xa1\x85\xc1\x80A\xf7\xf7C\x8fc!\xcb\xe7\x06'c\xae\xb1\x1c\xc1\x80@\x08\x16\xf1\xc3*OG\xe3'\x15\x12\xaf1\xc5\x80,\xb3\xcc\xa8\xcd\xc9c\x1a\xeaC\xf3\xf3A\x12\xc3\x84A\x8cg\xa8Mc%\x08\xe8\x84\xf7U\x8a\x13\x1d\xc1',J\xcc\x8a\xcd\x85hL\xd4\x07\xf3U\x9a\x13\x19\xc1\x84\xe7\xc5\x8c\x9f\xc3*\xcb\xe7\x06'c\tE!\xc5\x0cC\x98\x1d\xe5\xa5\x0f\xa1\x19c\xff%\x91\x19\xc1\x80,\xa3\xcc\x88\xcd\x85hL\xd4C\xf3\xf3X\x91#\xc1\x80,\xa3\xcc\x88\xcd\x85jN\xe3\x04\xf3\xff\x07X\xa1\x10A\x80E\xf6\xf3\xc6c\xcdc\x1c\xeb\x07\xf3T\x8b\x01\x90\x03\x0cT\xee\x19\xe1\xe2%N\xd6\xe3\xf2V\x14\x05\x90\xc3\x10\xc7e")

So can anyone tell how to read the whole string of rawdata using UART?

User avatar
pythoncoder
Posts: 5956
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: How to read string using UART ?

Post by pythoncoder » Thu Mar 01, 2018 5:07 pm

Are you sure the UART is set up correctly (especially baudrate)?
Peter Hinch
Index to my micropython libraries.

nikhiledutech
Posts: 118
Joined: Wed Dec 27, 2017 8:52 am

Re: How to read string using UART ?

Post by nikhiledutech » Mon Mar 05, 2018 5:22 am

:oops: baudrate was not correct. Sorry.

nikhiledutech
Posts: 118
Joined: Wed Dec 27, 2017 8:52 am

Re: How to read string using UART ?

Post by nikhiledutech » Mon Mar 05, 2018 5:41 am

Hello ,
So i am extracting data from GPS raw data. Below is my code.
uart = pyb.UART(4, 115200)

def main():

Rx = bytearray(255)
i=0

while True:
Data = bytearray(255)
j=0

uart.readinto(Rx)



# /* Extract the $GPGGA string */
for i in range(255):
if(Rx[i-5]=='$' & Rx[i-4]=='G' & Rx[i-3]=='P' & Rx[i-2] =='G' & Rx[i-1] =='G' & Rx == 'A'):
break





And i am facing this issue " TypeError: can't convert 'int' object to str implicitly" .

I tried to convert Rx[i-5] etc. elements to string , but it give me error of unsupported type for and operation as string string can't be anded.

How to solve this error ?

User avatar
pythoncoder
Posts: 5956
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: How to read string using UART ?

Post by pythoncoder » Mon Mar 05, 2018 5:58 am

There are so many things wrong with that line of code that I can only assume you're new to Python and possibly to programming. I suggest that you should learn the language on a PC from a book or online course. Specific topics are the difference between bitwise logical operators like & and normal logical operators like and, and the way to index into lists such as text strings - hint: negative indices access the end rather than the start of the string.

As a more general point I'd consider learning about the Python re module (ure in MicroPython) as this can help in parsing strings.
Peter Hinch
Index to my micropython libraries.

nikhiledutech
Posts: 118
Joined: Wed Dec 27, 2017 8:52 am

Re: How to read string using UART ?

Post by nikhiledutech » Mon Mar 05, 2018 6:49 am

Yes i know that negative index will read the data from end not from start. i was using negative index because all the string start from gps raw data string starts from "GP". So thought to better start from the ending point.

Actually my problem i didn't gave full code.
#******************************************************************//**
# @brief Write a Program to interface GNSS click with stm32f4
# @version v1.0
# @author Nikhil Komalan
#*********************************************************************/"""

import pyb
from pyb import Pin, delay,UART

uart = pyb.UART(4, 115200)

def main():

Rx = bytearray(255)
i=0

while True:
Data = bytearray(255)
j=0

uart.readinto(Rx)
print(Rx)



# /* Extract the $GPGGA string */
for i in range(255):
if(Rx[i-5]== '$' and Rx[i-4]== 'G' and Rx[i-3]== 'P' and Rx[i-2] == 'G' and Rx[i-1] == 'G' and Rx == 'A'):
break


i = i - 5 # // set the value at the '$'
# /* Copy string to another array */

for i in range(255):
Data[j] = Rx
if(Rx=='\r' and Rx[i+1]=='\n'):
break
j+=1

# /* check gps status */
if(Data[17]==',' and Data[18]==',' and Data[19]==',' and Data[20]==',' and Data[21]==','):

print("No Fixed Position")
print("D7",Data[7], "D8", Data[8],"D9", Data[9],"D10", Data[10], "D11", Data[11],"D12", Data[12])

elif(Data[43]=='1'): #// Gps fixed data[43] = 1 otherwise 0
print("UTC Time:",Data[7],Data[8],Data[9],Data[10],Data[11],Data[12])




if(Data[28] =='S'):
print("Latitude:", Data[18],Data[19],Data[20],Data[21],Data[23],Data[24],Data[25],Data[28])

else:
print("Latitude:", Data[18],Data[19],Data[20],Data[21],Data[23],Data[24],Data[25],Data[28])




if(Data[41]=='W'):
print("Longitude:",Data[30],Data[31],Data[32],Data[33],Data[34],Data[36],Data[37],Data[38],Data[41])

else:
print("Longitude:",Data[30],Data[31],Data[32],Data[33],Data[34],Data[36],Data[37],Data[38],Data[41])

print("Satellites in view: ",Data[45])



while True:
main()




User avatar
pythoncoder
Posts: 5956
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: How to read string using UART ?

Post by pythoncoder » Mon Mar 05, 2018 7:16 am

OK, sorry if I misjudged your level of experience. The fact that you're having to search the string for '$GPGGA' suggests that you have synchronisation issues. Have you considered using uart.readline()? I would try that, discarding the first line read as it may be partial (if you started the program while a line was being transmitted). Subsequent lines should then have '$GPGGA' (or other phrase) at the start.

Have you considered using string.split?

Code: Select all

>>> s = '$GPGGA,123519,4807.038,N,01131.000,E,1,08,0.9,545.4,M,46.9,M,,*47'
>>> s.split(',')
['$GPGGA', '123519', '4807.038', 'N', '01131.000', 'E', '1', '08', '0.9', '545.4', 'M', '46.9', 'M', '', '*47']
>>> lst = s.split(',')
>>> lst[0] == '$GPGGA'
True
>>> float(lst[2])
4807.038
>>> 
Peter Hinch
Index to my micropython libraries.

nikhiledutech
Posts: 118
Joined: Wed Dec 27, 2017 8:52 am

Re: How to read string using UART ?

Post by nikhiledutech » Mon Mar 05, 2018 10:06 am

Thanks for the advice. using split i have succesfully extracted the data i needed.


import pyb
from pyb import Pin, delay,UART

uart = pyb.UART(4, 115200)

def main():

Rx = bytearray(255)
i=0

while True:
Data = bytearray(255)
j=0

Rx = str(uart.readline())
fetch = Rx.split(',')

#Extracting the CGPA String
if (fetch[0] == "b'$GPGGA"):
Data = fetch[0:15]

#Checking if the GPS position is fixed or not
if (Data[2]==0 and Data[3]==0 and Data[4]==0 and Data[5]==0):
print("No Fixed Position")

elif (Data[6] == 1):
print("GPS Locked")
print("UTC Time:", Data[1])

so here i am reading the string data in Rx. Than i have used if condition to extract GPGGA data in Data array. So whats happening is """No Fixed position""" is getting printed 5 times instead of one.


I know the Rx byte array will contain other raw data values too but in IF condition we are loading the Data bytearray only when fetch[0] === GPGGA.

So data should only contain that GGPGA string instead of (GPGGA + other raw data).

How to correct it ?

Thanks

Post Reply