Sending and decoding data over UART

General discussions and questions abound development of code with MicroPython that is not hardware specific.
Target audience: MicroPython Users.
Post Reply
psereni
Posts: 5
Joined: Wed Sep 11, 2019 8:06 am

Sending and decoding data over UART

Post by psereni » Thu Feb 27, 2020 12:21 pm

Hello,

I'm pretty new here with micropython and I'm facing a problem that I can not solve.
Basically, I use the Pyboard to read a Pentiometer on Input X19 and I wanto to send the read value via UART to a Host (PC, or, later a Raspberry PI) where a Python script is polling the serial interface.

PyBoard Code is:

Code: Select all

# main.py -- put your code here!
from pyb import Pin, ADC, UART, LED
import time 
led = LED(4)
adc = ADC(Pin("X19"))
uart = UART(1,9600)
uart.init(9600, bits=8,parity=None, stop=1)

while True:
    a=adc.read()
    uart.write(str(a))
    print(a)
    pyb.delay(250)
    led.toggle()
-------
This code woks fine. When I use Putty to open a REPL on pyboard I see the correct values (from 0 to 4095, depending on the Potentiometer setting). E.g. the output is:
385
385
386
...
....
-----
I use the following code to open the corresponding COM port on the PC:

Code: Select all

#!/usr/bin/python3

import serial

sp=serial.Serial("COM8", 9600, timeout=1)

while True:
    data=sp.read()
#    print(data)
#    print(data.decode())
    print ((data.decode().strip()))
-------
The point is, that I found no way of reading a correct string on the PC. I mean that I was not able to find a way of the reading the "right" numbers of bytes...
In the specific case the result will be:
3
8
5
3
8
5
3
8
6
.
.
-------------
The python routine on the PC should be able to understand that the measurement could vary from "0" to "4095". How??

Any help will be greatly appreciated.

doublevee
Posts: 75
Joined: Mon Jul 02, 2018 11:09 pm

Re: Sending and decoding data over UART

Post by doublevee » Thu Feb 27, 2020 12:49 pm

A simple solution might be to transmit a newline character after your uart.write() on the PyBoard. This way, you can read the serial bytes and split them using this character.

I also think there is a command in PySerial that reads until a newline is received.

User avatar
jimmo
Posts: 2754
Joined: Tue Aug 08, 2017 1:57 am
Location: Sydney, Australia
Contact:

Re: Sending and decoding data over UART

Post by jimmo » Thu Feb 27, 2020 1:06 pm

Yup, exactly what doublevee said -- you probably want to use the readline() method in pyserial rather than read(1), and ensure that you append a newline to the end of each uart.write() that you do on the pyboard.

The more complicated answer is that writing serial protocols is complicated and coming up with a reliable and robust way to frame your messages is important, and often you'll end up having to read a byte at a time and implement some sort of state machine to track where in the frame you are.

In this case it's pretty straightforward -- keep appending characters to a buffer until you see a newline. (But that's what pyserial.readline() does).

psereni
Posts: 5
Joined: Wed Sep 11, 2019 8:06 am

Re: Sending and decoding data over UART

Post by psereni » Thu Feb 27, 2020 1:32 pm

Thank you so much, it works perfectly.
I added uart.write("\n") after uar.write(str(data)) on the pyboard code and used data=sp.readline() on the PC.
Thanks again

Post Reply