TOP

Raspberry Pi 和 Raspberry Pico 之间的串行连接

Raspberry Pi 和 Raspberry Pico 之间的串行连接

本文作者:Sebastian  来源于medium.com

2021年初,我开始了我的机器人项目。 它的子项目之一是熟悉 Arduino 和 C 编程。 Arduino 在传感器和执行器库方面无可挑剔,在“连接并工作”体验方面无与伦比。 然而,在年中,我决定改用 Raspberry Pico 和 MicroPython 来实现我的机器人。 这种选择的动机是为机器人中间件、SBD 和微控制器使用一种且仅一种编程语言,以及利用 RealSense D435 相机提供的强大的 Python 库进行图像识别。

为此,我需要重新学习运行 MicroPython 的 Raspberry Pico 和运行 Python 的 Raspberry Pi 之间的串行连接的要点。 本文介绍了建立成功连接的基础知识。

这篇文章最初出现在我的博客 admantium.com

硬件连接选项

要从 Pi 连接到 Pico,有三个选项:

  • 直接 USB 转 USB
  • 直接 Tx/Rx 引脚
  • USB-TTL 到 Rx/Rx

由于 Raspberry Pico 还比较年轻,MicroPython 堆栈的技术成熟度会影响这些连接中的哪些可以使用。

当您使用选项 A 或 C 时,您可以跳转到示例。 如果要使用选项 B,则需要按照下一节中描述的步骤启用 Tx/Rx 引脚。

如何在 Raspberry Pi 上启用 Tx/Rx 引脚

在这篇 很棒的文章 ,您需要执行以下操作:

  • 通过 Raspi-Config 初始化串口
$> sudo raspi-config  => 3. Interface Option
  => P6. Serial Port
    =>  Would you like a login shell to be accessible over serial?
        Answer with 'No'
    =>  Would you like the serial port hardware to be enabled?
        Answer with 'Yes'
  • 禁用 /dev/ttyS0服务
$> sudo systemctl stop serial-getty@ttyS0.service
$> sudo systemctl disable serial-getty@ttyS0.service
  • 从引导中删除控制台
$> sudo nano /boot/cmdline.txt
    => Remove or comment out a line that says 'console=serial0,115200'
 

有趣的是,树莓派仍会通过 Tx/Rx 引脚发送系统消息——这可能是您一直在寻找的特定用例。 这是我关闭 Pi 时的示例输出。


>> [  OK  ] Stopped LSB: automatic crash report generation.
>> [  OK  ] Stopped User Manager for UID 1000.
>> [  OK  ] Stopped Login Service.
>> RPI 4 Model B (0xc03111)

将数据从 Pi 发送到 Pico

在所有示例中,从 Raspberry Pi 向 Pico 发送数据都是相同的代码,只是稍作修改:Pico 连接的端口。

使用这个样板代码:


 1 # sender.py
 2 import time
 3 import serial
 4 ser = serial.Serial(
 5   port='/dev/ttyS0', # Change this according to connection methods, e.g. /dev/ttyUSB0
 6   baudrate = 115200,
 7   parity=serial.PARITY_NONE,
 8   stopbits=serial.STOPBITS_ONE,
 9   bytesize=serial.EIGHTBITS,
10   timeout=1
11 )
12 
13 msg = ""
14 i = 0
15 
16 while True:
17     i+=1
18     print("Counter {} - Hello from Raspberry Pi".format(i))
19     ser.write('hello'.encode('utf-8'))
20     time.sleep(2)

解释:

  • 第 3 行:导入 serial启用串行连接的库
  • 第 4 行:创建一个与默认 Pico UART 配置完全相同的串行对象(波特率 115200,字节大小 8 位等)。 这 port部分需要根据连接方式定制 - 详情见下文
  • 第 19 行:要发送数据,您首先 encode字符串数据,然后 write它到串行对象

现在让我们检查接收方。

接收数据:USB 转 USB 连接

在撰写本文时,在 Pico 上运行的最新版本的 MicroPython 是 MicroPython v1.16 on 2021-06-18. 此版本没有用于通过 USB 进行串行通信的内置库。

然而,在这个 Pico 论坛线程 中,用户提供了一个纯 MicroPython 实现,它在第二个 Pico CPU 内核上生成一个线程,该线程主动侦听通过 USB 传入的字节。 我在我早期的机器人原型中尝试了这个代码,并且可以使用它通过 Pico 上的 USB 接收命令我的机器人移动的消息。

这是我的工作示例:


# receiver.py / USB => USB
import sys
sys.path.append('/radu')

import os
from bot import Bot
from rusb import USB

from _thread import start_new_thread
from time  import sleep_ms

radu = Bot('Radu MK1')
usb = USB()

input_msg = None
bufferSTDINthread = start_new_thread(usb.bufferSTDIN, ())

while True:
  input_msg = usb.getLineBuffer()
  if input_msg and 'ros_msg' in input_msg:
    obj = eval(input_msg)
    radu.notify(obj)  

sleep_ms(10)

接收数据:Tx/Rx 引脚连接

Tx/Rx 引脚之间的直接连接意味着:

  • 接地:Pi PIN 6 到 Pico Pin 3
  • 将 Tx 连接到 Rx:Pi PIN 8 (GPIO 14) 到 Pico Pin 1 (GPIO 0)
  • 将 Tx 连接到 Rx:Pi PIN 10 (GPIO 15) 到 Pico Pin 2 (GPIO 1)

如上所述,您还需要配置您的 Raspberry Pi 以启用这些引脚。 完成后,使用以下代码:


 1 # receiver.py / Tx/Rx => Tx/Rx
 2 import os
 3 import machine
 4 from time import sleep
 5 
 6 uart = machine.UART(0, 115200)
 7 print(uart)
 8 
 9 b = None
10 msg = ""
11 
12 while True:
13     sleep(1)
14     if uart.any():
15         b = uart.readline()
16         print(type(b))
17         print(b)
18         try:
19             msg = b.decode('utf-8')
20             print(type(msg))
21             print(">> " + msg)
22         except:
23             pass

在这个程序中:

  • 第 6 行:创建一个 uart实例通过访问 Pico 的内部 machine.UART实例。 这与配置发件人代码的值相同。 请注意, MicroPython 文档 还允许您创建不同配置的 UART 实例,例如使用较慢的波特率。
  • 第 14 行:条件 uart.any()当 UART 连接上至少有一个字符可用时,返回一个正整数。
  • 第 13 行:要读取数据,请使用 read(i)在哪里 i是字符数,或 readline()读取所有字符,直到到达换行符。 使用单个字符更高效、更快,如果您需要交换复杂的信息,使用完整的行更可靠。
  • 第 18 行:A try - except块开始于...
  • 第 20 行:……接收到的消息被解码然后打印。 如果有任何错误,程序将继续运行而不引发错误。

接收数据:USB-TTL 到 Tx/Rx 引脚连接

首先,你需要一个 USB-TTL 适配器,它至少有两种不同的芯片组:FT232RL 和 CH340g。

资料来源: Amazon.de Amazon.de

将适配器插入 Picos USB 端口,然后使用 dmesg查看此设备的配置方式。


326612.390873] usb 1-2: new full-speed USB device number 54 using xhci_hcd
[326612.543888] usb 1-2: New USB device found, idVendor=1a86, idProduct=7523, bcdDevice= 2.64
[326612.543893] usb 1-2: New USB device strings: Mfr=0, Product=2, SerialNumber=0
[326612.543895] usb 1-2: Product: USB Serial
[326612.546221] ch341 1-2:1.0: ch341-uart converter detected
[326612.549000] usb 1-2: ch341-uart converter now attached to ttyUSB0

最后一行说 ttyUSB0,所以发送者代码需要更改如下:


# sender.py / USB-TTL => Tx/Rx
# ...
ser = serial.Serial(
  port='/dev/USB0'
  # ...
)

接收数据的代码与直接 Tx/Rx 连接中的代码相同。

示例输出

现在让我们看看我们的代码在起作用。

执行 sender.py在 Raspberry Pi 上输出以下信息:


>>>
Counter 1 - Hello from Pi4
Counter 2 - Hello from Pi4
Counter 3 - Hello from Pi4
Counter 4 - Hello from Pi4
 

并运行 receiver.py在 Raspberry Pico 上显示:


%Run -c $EDITOR_CONTENT
(sysname='rp2', nodename='rp2', release='1.16.0', version='v1.16 on 2021-06-18 (GNU 10.2.0 MinSizeRel)', machine='Raspberry Pi Pico with RP2040')
UART(0, baudrate=115200, bits=8, parity=None, stop=1, tx=0, rx=1, txbuf=256, rxbuf=256, timeout=0, timeout_char=1, invert=None)
<class 'bytes'>
b'hello\n'
<class 'str'>
>> hello

结论

本文介绍了使用 (Micro)Python 将 Raspberry Pi 与 Raspberry Pico 连接的三个选项。 第一个选项是 USB 转 USB,需要外部 MicroPython 库来接收数据。 第二种选择是直接从两台机器连接 Rx/Tx。 在对 Pi 进行一些配置后,它可以稳定运行。 第三种选择是使用 USB-FTL 转 Tx/Rx。 无需配置,开箱即用。

考虑到源代码,在 Pi 上是 pyserial库:打开一个与 Pico 具有相同配置(波特率、停止位)的串行连接对象,并发送编码数据 serial.write(). 在 Pico 上,它的建筑 machine.UART访问内置 UART 或可配置的对象。 利用 uart.readline()接收字节,然后 decode()数据。

 
posted @ 2022-06-10 17:00  liqinsan  阅读(1321)  评论(0)    收藏  举报