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.
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.