adafruit / circuitpython

CircuitPython - a Python implementation for teaching coding with microcontrollers
https://circuitpython.org
Other
4.11k stars 1.22k forks source link

Problems when transmitting ndarray via UART #8384

Closed Flashton91 closed 1 year ago

Flashton91 commented 1 year ago

CircuitPython version

I use latest version (8.2)

Code/REPL

# microcontroller - sender
import sys
import time
from ulab import numpy as np
import board
import busio

uart = busio.UART(board.GP4, board.GP5, baudrate=2000, timeout=0)

def sending(data):

    uart.reset_input_buffer()
    time.sleep(0.001)
    uart.write(data)
    time.sleep(0.001)
    return print(data)

k = 1
while k < 50:

    data = np.zeros((3, 3), dtype=np.uint8)
    data[0,0] = k
    time.sleep(10)

    sending(data)
    if k == 49:
        k = 0
        time.sleep(20)

    time.sleep(0.1)

    k = k + 1

# microcontroller - receiver
import time
import board
import busio
import digitalio
from ulab import numpy as np

#uart = busio.UART(board.TX, board.RX, baudrate=9600)
uart = busio.UART(board.GP4, board.GP5, baudrate=2000, timeout=0)
uart.reset_input_buffer()

bf = np.zeros((3, 3), dtype=np.uint8)

while True:
    if uart.in_waiting:

        uart.readinto(bf)
        print(bf)

Behavior

Hello. I use latest version (8.2) I have connected two Raspberry Pi Pico and am trying to transfer ndarray (ulab.numpy) between them using UART.

I noticed several problems:

  1. The microcontroller - receiver reads messages not in the order in which they are sent by the microcontroller - sender. For example, "array 3" comes, then "array 1", and "then 2". I may be talking nonsense, but it would be cool to add an option to control the reading order so messages can be read in the order they were sent.

  2. Many arrays containing only zeros arrive. This is weird because when I sending bytearrays rather than ndarray, I don't see any corruption. I can't figure out where these null ndarrays come from that I'm not sending. For some reason _uart.inwaiting: misses such messages.

Description

No response

Additional information

No response

dhalbert commented 1 year ago

The baud rate is very low and is also non-standard. Did you try, say 1200, and 9600?

If you set the timeout to 0, then .readinto() will only read as many characters as are available. It will not wait for the whole array to fill. It returns how many bytes it actually read. Add print statemtns to see what .in_waiting and .readinto() return.

Are the two boards connected to have a common ground?

Flashton91 commented 1 year ago

Thank you, you are right - apparently the problem was timeout=0. With this configuration, everything is transferred correctly: uart = busio.UART(board.GP4, board.GP5, baudrate=9600, timeout=5)

I receive messages in the correct order and without distortion:

array([[1, 0, 0],
       [0, 0, 0],
       [0, 0, 0]], dtype=uint8)

array([[2, 0, 0],
       [0, 0, 0],
       [0, 0, 0]], dtype=uint8)
dhalbert commented 1 year ago

Glad you got it working!