Dragon12
Posts: 129
Joined: Thu Jul 18, 2013 10:33 am

Pico serial communication via USB

Sun Dec 10, 2023 4:00 am

I have written python code that reads and writes a byte via serial to a pico w.

This is the pico code that reads a byte sent from the python code and it works perfectly the first time. The second call to the read_char function returns "'\x04Traceback (most recent call last):'".

I've spent days trying to solve the problem but without success. Any suggestions will be greatly appreciated.

By the way, the same python code works perfectly with an old arduino board so I know for certain that the problem is multiple reads in the pico code.

I'm wondering if what I'm tying to is not possible via the board's USB socket and if I need to attach some sort of hardware to pins 1 and 2 to achieve real serial communication?

Code: Select all

def read_char():
    poll_obj = uselect.poll()
    poll_obj.register(sys.stdin,1)
    
    if poll_obj.poll(0):
        #read one character
        ch = sys.stdin.read(1)
    else:
        ch = None
    return ch



User avatar
neilgl
Posts: 7574
Joined: Sun Jan 26, 2014 8:36 pm
Location: Near The National Museum of Computing

Re: Pico serial communication via USB

Sun Dec 10, 2023 11:31 am

Am I correct in assuming you have a pico W running micropython and a script on that to read/write data over USB (serial)
And the python code you posted is running on some other device?

Dragon12
Posts: 129
Joined: Thu Jul 18, 2013 10:33 am

Re: Pico serial communication via USB

Sun Dec 10, 2023 8:39 pm

Thank you for your reply.

No, the code I posted runs on the pico. Just be clear, these are the instructions sent from the PC:
1. Send a byte to the pico. The pico reads this correctly and then sends an acknowledgement to the PC.
2. The PC then sends another byte to the pico. This second byte is not read.

I cannot see how to debug the pico code, print statements are of no value in this case.

The same PC code controls an arduino board correctly. If I omit the second write from the PC code, then the PC code will control the pico without any problems.

User avatar
neilgl
Posts: 7574
Joined: Sun Jan 26, 2014 8:36 pm
Location: Near The National Museum of Computing

Re: Pico serial communication via USB

Sun Dec 10, 2023 11:34 pm

Ok, can you post the complete pico code, and whatever code (python?) is running on the PC so we can look at it / test it?

ame
Posts: 8756
Joined: Sat Aug 18, 2012 1:21 am
Location: New Zealand

Re: Pico serial communication via USB

Mon Dec 11, 2023 12:33 am

And the complete error message.
Oh no, not again.

Dragon12
Posts: 129
Joined: Thu Jul 18, 2013 10:33 am

Re: Pico serial communication via USB

Mon Dec 11, 2023 2:06 am

The text that I quoted in my first plea for help is what was returned from the pico. I think it relates to an end of file error.

Anyway the cause of the problem was the read function which is non blocking. I needed the pico to wait until a byte was received from the PC. The problem is now solved, with the help of Bard, I have a read function that blocks for 1 second.

I'm still a little confused because the arduino serial.read function is non blocking and that code works perfectly. I need to think about this some more.

Thank you for taking the time to reply to my messages.

ghp
Posts: 3676
Joined: Wed Jun 12, 2013 12:41 pm
Location: Stuttgart Germany

Re: Pico serial communication via USB

Mon Dec 11, 2023 7:48 am

Some remarks:
- do not instantiate the polling objects each time you want to read a byte from serial

Code: Select all

# instantiate poll object here
poll_obj = uselect.poll()
poll_obj.register(sys.stdin,1)
def read_char():
    # do not re-instantiate the poll object each time when a byte is read
    # poll_obj = uselect.poll()
    # poll_obj.register(sys.stdin,1)
    
    if poll_obj.poll(0):
        #read one character
        ch = sys.stdin.read(1)
    else:
        ch = None
    return ch
- when you send bytes from host computer by USB serial to a micropython program, keep in mind that the micropython "repl" code is always running and might catch some data. One example: when I have micropython programs running and I by accident use ctrl-c in a serial console window (I use putty usually for this) then "repl" tells me that program has terminated. So a good idea to keep the data in the ascii character range between 0x20(blank) and 0x7d(tilde) and avoid control chars.

- analyzing problems in micropython is difficult when USB serial is used for data transfer. Solutions are to use a UART-to-USB adapter and write log messages and exception traces to UART. An example for such a device is https://shop.pimoroni.com/products/usb- ... =288389664 (look for 3.3V compatibility). Remove this adapter when program is stable and perfect.
Or write log messages to a file in the system (flash memory) and check content of file from time to time. Of course you need to ensure that the file is not filling up the available flash space

hippy
Posts: 15877
Joined: Fri Sep 09, 2011 10:34 pm
Location: UK

Re: Pico serial communication via USB

Mon Dec 11, 2023 3:49 pm

ghp wrote:
Mon Dec 11, 2023 7:48 am
analyzing problems in micropython is difficult when USB serial is used for data transfer.
I consider it not practical for all but the most simplistic of programs, and even those can be difficult enough.

The only sensible solution I believe is to implement additional USB virtual serial ports so you have access to the REPL on '/dev/ttyACM0' while having a data channel on '/dev/ttyACM1'. That is supported by CircuitPython but not by MicroPython and, due to refactoring, is nowhere near as easy as it used to be to implement it your self.

Dragon12
Posts: 129
Joined: Thu Jul 18, 2013 10:33 am

Re: Pico serial communication via USB

Mon Dec 11, 2023 8:43 pm

- do not instantiate the polling objects each time you want to read a byte from serial
I now have everything working correctly, however, I will take your advice.

Regarding debugging serial code. It's been like working with a black box; data goes in and something comes out. Solving problems inside the box has involved a lot of trial and error. Anyway I now know that there is a technique available although it seems a little complicated. I'll research this further.

Thank you everyone for your replies.

Return to “MicroPython”