0

I have two RP2040 devices, one a Raspberry Pi Pico W(H), and one a Waveshare RP2040 LCD 1.28 device. I am trying to send data from the Waveshare to the Pico through a USB cable (USB-C on the Waveshare, micro USB on the Pico) and miserably failing ...

I'm using micropython. The setup works when I connect either device to my PC, but just not when I connect ghem together. So I suspect there's something about how the Pico expects data to be encoded that the PC is doing without me noticing.

Hence posting here, as I hope that someone who knows about the Pico will know that crucial bit of information.

Here's a bit more detail.

The code on the Waveshare device is:

import sys
import time
import random
from RP2040-LCD-1.28 import LCD_1inch28

LCD = LCD_1inch28()
LCD.set_bl_pwm(65535)

colours = [LCD.blue, LCD.red]
i = 0

while(True):
    LCD.fill(colours[i])
    i = 1 - i
    LCD.show()
        
    msg = f'Messge {random.randint(1,6)}\n'.encode()
    sys.stdout.write(msg)
    
    time.sleep(1)

This needs the LCD controller code from the Demo section of their site. The required file is RP2040-LCD-1.28.py (a useful page for this device is on the PiHut). This is just to control the display which (as can be seen from the code) is used as an indicator that the code is running. Removing that code leaves just:

import sys
import time
import random

while(True):        
    msg = f'Messge {random.randint(1,6)}\n'.encode()
    sys.stdout.write(msg)
    
    time.sleep(1)

On the Pico, I have the following code:

import sys
import time
from machine import Pin,Timer

led = Pin("LED", Pin.OUT)

while True:
    # get the next message
    led.toggle()
    sys.stdin.readline()

    time.sleep(1)

So the Waveshare sends a message and the Pico is supposed to read it. As each does that, it blinks either the screen or the LED.

Except it doesn't.

I can check that both sets of code work by connecting them to a PC.

This code listens to the Waveshare:

import serial
import serial.tools.list_ports

# I presume that the serial number is fixed ...
watch_sn = "e6614c309392962d"
watch_port = None

ports = list(serial.tools.list_ports.comports())
for port, desc, opts in ports:
    print(port, desc, opts)
    if 'SER=' in opts:
        s = opts.find('SER=') + 4
        e = opts.find(' ',s)
        ser = opts[s:e]
        if ser == watch_sn:
            watch_port = port

watch = serial.Serial(watch_port)

while True:
    msg = watch.readline()
    print(msg)

The output looks a bit like:

/dev/ttyACM0 Board in FS mode - Board CDC USB VID:PID=2E8A:0005 SER=e6614c309392962d LOCATION=1-2.4:1.0
b'Messge 6\r\n'
b'Messge 2\r\n'
b'Messge 2\r\n'
b'Messge 2\r\n'
b'Messge 2\r\n'
b'Messge 3\r\n'
b'Messge 4\r\n'
b'Messge 6\r\n'
b'Messge 5\r\n'
b'Messge 6\r\n'

I can send data to the Pico from the PC, using:

import serial
import serial.tools.list_ports
import random
from time import sleep

pico_sn = "e6626005a757702b"

ports = list(serial.tools.list_ports.comports())
for port, desc, opts in ports:
    print(port, desc, opts)
    if 'SER=' in opts:
        s = opts.find('SER=') + 4
        e = opts.find(' ',s)
        ser = opts[s:e]
        if ser == pico_sn:
            pico_port = port

print(pico_port)
pico = serial.Serial(pico_port)

while True:
    msg = f'Message {random.randint(1,6)}'.encode()
    print(msg.decode())
    pico.write(msg + b'\n')
    sleep(1)

and the LED flashes.

But when I connect the Waveshare to the Pico ... nothing.

I have tried changing from bytearray to string, and changing readline to read(1), and changing the newline character. All to no avail.

It feels like something very simple, such as line endings, but I'm flailing about in the dark trying to figure it out and ... just hope! ... that someone might have a good idea that I can try.

Incidentally, the cable is a USB-C to micro USB cable and I've used it to connect two other devices and read data from the one device on the other, so it is a data cable.

5
  • I suspect not many will have the same setup as me, so testing it might be tricky for others, but I'm really just looking for suggestions to try. Then I'll test and report back. Commented Mar 20 at 0:02
  • Most of this question is about some other device (to which you haven't provided a link) and is not on topic for this site (unless it is about the RP2040 chip). You seem to be assuming that you can join 2 devices with a USB cable and it will magically work. I suggest you connect the serial devices (with a crossover) and see if that works.
    – Milliways
    Commented Mar 20 at 1:44
  • @Milliways the word "Waveshare" is hyperlinked to a page about the other RP2040 device. By "serial cable" I mean a USB cable, as explained in the last paragraph. I had hoped that it would "magically work" because, as I explain, it does magically work when I connect either device to a PC. So if someone can explain why the RP2040 chip works differently when connected to another RP2040 as opposed to a PC then that would be an answer. Commented Mar 20 at 6:53
  • I'd also say that this requires knowledge about the pico to answer, because I need to know what data format it is expecting so that sys.stdin.read[line] works. I can modify the code on the waveshare to match, but if I don't know what the pico wants then I'm flailing about in the dark. Commented Mar 20 at 7:02
  • "It works with the computer" means that when I connect the PC to the Pico then I can send data to the Pico through the USB cable and the Pico receives that data. The Pico doesn't know that the data is coming from a PC or other device, so there should be no difference in connecting a different device and sending data through the cable. Commented Mar 20 at 7:59

1 Answer 1

0

USB devices are not symmetrical and operate in either Host or Device mode, with all connections initiated by the Host.
Some devices (including some Pi models) can operate as Host or Device but mode need to be configured (either in software or by hardware).

AFAIK the RP2040 does not support Host, certainly not by default, so you can not communicate between 2 devices.

While these can not communicate over USB the RP2040 has 2 UART which can be used for serial communication over GPIO pins.
Using the python serial module it is simple to configure the UART for practically any common serial format/speed.

1
  • Thank you. I had not been aware of the Host/Device nature of USB and so hadn't understood why USB wouldn't work. I've now refactored it to use UART and it's working fine. Commented Mar 21 at 20:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.