在Windows或Ubuntu VBox上通过Python与Arduino通信的串口

4 投票
4 回答
10214 浏览
提问于 2025-04-16 12:52

我有一个Arduino微控制器,正在COM3端口上监听。使用Arduino IDE和串口监视器发送和接收数据都很顺利。

我想用Python来发送和接收数据,但这并不是很明显怎么做。(如果用C#更简单,我也可以用C#。)

我找到了一些资料,比如arduino_serial.py,但这个只适用于Unix系统。幸运的是,我有一个设置好的Ubuntu 10.10虚拟机。不过,我不知道这个虚拟机能否访问串口,或者是否需要特别的步骤。

我还发现了pySerial,看起来很靠谱。但是,我也不太确定怎么使用它。它需要串口的名称。我该怎么找到这些有效的值呢?

举个例子,pySerial提到可以用以下命令“以‘19200,8,N,1’打开命名端口,超时1秒”:

>>> ser = serial.Serial('/dev/ttyS1', 19200, timeout=1)

但我不知道怎么知道/dev/ttyS1是一个有效的端口名称。

有没有好的文档可以帮助我入门呢?

更新:我在使用Ubuntu和arduino_serial,但仍然遇到问题。

这个程序在Arduino上运行:

void setup() { 
  Serial.begin(9600);
}

void loop() { 
  if (Serial.available()) {
    Serial.print((char)Serial.read());
  }
}

我看到有一个叫tty0的端口可用:

foo@bar:~/baz$ dmesg | grep tty
[    0.000000] console [tty0] enabled

然后我尝试用arduino_serial连接:

foo@bar:~/baz$ sudo python
[sudo] password for foo: 
Python 2.6.6 (r266:84292, Sep 15 2010, 15:52:39) 
[GCC 4.4.5] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import arduino_serial
>>> sp = arduino_serial.SerialPort("/dev/tty0", 9600)
>>> sp.write("foo")
>>> sp.read_until("\n")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "arduino_serial.py", line 107, in read_until
    n = os.read(self.fd, 1)
OSError: [Errno 11] Resource temporarily unavailable

为什么我会收到这个错误?我哪里做错了?

4 个回答

2

在Windows系统中,串口的名称是从COM1开始的,比如COM1、COM2等等,而在Linux系统中,串口的名称是/dev/ttyS0对应COM1。我写了一些Python代码,用于我们的四旋翼无人机控制器,这段代码可以在Windows和Linux上运行(只要你正确提供端口名称),使用的是Pyserial库。

在Windows上,可以尝试把COM3传给Pyserial。在虚拟机中,你需要先把USB转串口适配器连接到虚拟机,或者设置一下串口部分(我使用的是VirtualBox)。如果你选择使用USB的方式,串口设备会显示为/dev/ttyUSBxx

4

pySerial 这个库可能已经包含在你的Python里,也可能没有。如果没有的话,你需要下载并安装pySerial这个库。

而且你已经知道Arduino在COM3端口上,只需使用以下代码:

import serial
ser = serial.Serial("COM3", 19200, timeout=1)
ser.write("Whatever")

如果你是在Linux系统上,找出Arduino使用哪个串口是相对简单的:

dmesg | grep tty

这会给你一些类似这样的输出:[ 7.944654] usb 1-1.6: FTDI USB Serial Device converter now attached to ttyUSB0

所以我的Arduino在ttyUSB0上。这意味着你可以用下面的代码在Linux系统上和Arduino进行通信:

import serial
ser = serial.Serial("/dev/ttyUSB0", 19200, timeout=1)
ser.write("Whatever")

注意:如果你在Arduino上使用9600的波特率(大多数人都是这样),你可以直接使用serial.Serial("COM3")或者serial.Serial("/dev/ttyUSB0"),不需要其他参数。

补充说明: 你还需要记住,在实际操作中,打开端口并准备好传输数据可能需要一秒钟的时间。这意味着在调用serial.Serial()之后立即进行写操作可能不会有任何效果。所以我会使用以下代码:

import serial
import time
ser = serial.Serial("/dev/ttyUSB0", 19200, timeout=1)
time.sleep(1.5)
ser.write("Whatever")

这有点像是个小技巧,但这是我知道的在我的系统上让它工作的方法。

0

我有一个项目叫做 Yaam on CodePlex,它使用C#通过串口发送数据。你可以去看看这个项目作为例子。在C#这边(查看Yaam\Yaam.xaml.cs),你只需要使用 SerialPort 类,这个类在 System.IO.Ports 这个命名空间里。一旦你创建了这个对象并设置好一些属性(比如波特率、串口等),你只需要调用 .Open() 方法就可以了。网上还有很多其他的例子,你可以看看这些:

撰写回答