查看: 225|回复: 1

[Arduino] ESP32 / ESP8266 Arduino教程:与Python的串行通信

[复制链接]
本教程的目的是解释如何在运行在esp8266esp32 上的Python程序和Arduino程序之间建立串行连接。
对ESP32的测试是使用集成在ESP32开发板中的DFRobot的ESP-WROOM-32设备进行的。


简介
此文章旨在解释如何在Python程序之间建立串行连接。Arduino程序将扮演echo程序的角色,返回通过串行接收的字节。
在Python程序中,我们将使用PySerial模块建立串行连接。安装PySerial最简单的方法是使用Python包安装程序pip。为此,我们只需要在Windows命令行中输入以下命令:

[AppleScript] 纯文本查看 复制代码
pip install pyserial

ESP32 的测试是使用DFRobot的ESP-WROOM-32设备集成在ESP32 FireBeetle板上进行的。

Arduino代码
本教程的Arduino代码非常简单。在Arduino设置函数中,我们将通过调用Serial对象的begin方法打开一个串行通信。请注意,Serial对象属于HardwareSerial类。
begin方法接收波特率,以每秒位数为单位[1]。我们将使用值115200,稍后我们还需要在Python程序中使用到它。
[AppleScript] 纯文本查看 复制代码
void setup() {

  Serial.begin(115200);

}

 
现在我们将继续讨论Arduino循环函数,通过它我们可以处理收到的数据。在那里,我们将通过调用Serial对象的可用方法检查是否存在可供读取的字节。
此方法不接收任何参数,并返回可读取的字节数[2]。因此,我们可以编写一个循环,它将继续读取串行端口的字节,而可用方法意味着字节是可用的。
[AppleScript] 纯文本查看 复制代码
while(Serial.available()){

// Handle bytes reception

}

 
如需通过串行端口读取一个字节,我们只需在Serial对象上调用read方法,该方法将返回下一个可用字节。
由于我们的应用程序将回收发送给发送方的内容,因此我们希望通过调用Serial对象的write方法将其写回。该方法接收我们希望发送的字节作为输入内容[4]。
[AppleScript] 纯文本查看 复制代码
while(Serial.available()){

   Serial.write(Serial.read());

}

 
最终Arduino代码如下所示。请注意,我们在主循环每次迭代之间添加了一个小的延迟。
[AppleScript] 纯文本查看 复制代码
void setup() {

  Serial.begin(115200);

}

 

void loop() {

 

  while(Serial.available()){

    Serial.write(Serial.read());

  }

  delay(10);

}


Python代码
我们将通过导入串行模块启动Python代码,这将是我们与ESP板建立串行连接所需的内容。
[AppleScript] 纯文本查看 复制代码
import serial
接下来,我们将创建一个Serial类对象。我们将使用无任何参数的默认构造函数,然后再对连接参数进行设置。
[AppleScript] 纯文本查看 复制代码
ser = serial.Serial()
接下来我们需要配置我们的串行连接参数。因此,我们需要设置波特率以匹配ESP所用的波特率。为此,我们将值115200分配给Serial类对象的波特率数据成员。
[AppleScript] 纯文本查看 复制代码
ser.baudrate = 115200
我们还需要指定ESP的COM端口。请注意,这与我们在Arduino IDE上用于将程序上载到ESP开发板的COM端口相同。就我而言,它是COM5,但是您的端口很可能不是它。请注意,这里设置类型为字符串。
[AppleScript] 纯文本查看 复制代码
ser.port = 'COM5'
现在我们已经配置了所需的全部内容,我们只需通过调用Serial对象的open方法即可打开串口。
[AppleScript] 纯文本查看 复制代码
ser.open()
由于连接已经打开,我们可以开始向ESP发送部分字节。我们通过调用write方法实现此过程。我们将发送一些任意数组的字节,这些字节我们将使用bytearray函数进行创建。
[AppleScript] 纯文本查看 复制代码
values = bytearray([4, 9, 62, 144, 56, 30, 147, 3, 210, 89, 111, 78, 184, 151, 17, 129])

ser.write(values)

 
由于我们的ESP程序将所有字节回送到Python程序,我们将创建一个while循环,它将逐字节通过串行端口进行读取,直到返回等于发送数组大小的字节数。
如需从串行端口读取一个字节,我们需要调用Serial对象的read方法。此方法接收每次调用需要读取的字节数作为输入,因此我们将传递1这个数值,以逐字节进行读取。
请注意,如果未设置超时,则此调用过程将会中止,直到返回指定的字节数[5]。
值得一提的是,在某些Python版本中,针对read方法的调用将返回字符串而非字节[5]的实例,我们可以通过调用ord函数将其转换回字节。
[AppleScript] 纯文本查看 复制代码
total = 0

 

while total < len(values):

    print(ord(ser.read(1)))

    total=total+1

最终Python完整代码如下所示,这些代码包含了此函数的调用过程。

[AppleScript] 纯文本查看 复制代码
total = 0

 

while total < len(values):

    print(ord(ser.read(1)))

    total=total+1

 


代码测试
如需测试整个系统,首先使用Arduino IDE编译并将代码上传到ESP开发板。
请注意,在两块ESP开发板中,当Arduino程序启动时,部分字符会被打印到串行监视器上。因此,如果我们立即运行Python程序,我们将不会收到我们发送的字节。预防此种情况的最简单方法是首先打开串行监视器以获取这些字符,然后将其关闭。
之后,我们可以启动Python脚本。您应该在你正在使用的环境的Python提示符上得到与图1类似的东西,它显示了我们在正在打印的数组上定义的字节。就我而言,我正在使用IDLE,即Python IDE。


esp32-esp8266-arduino-serial-communication-with-python.png
图1  - 程序输出。

注:本文作者是Nuno Santos,他是一位和蔼可亲的电子和计算机工程师,住在葡萄牙里斯本 (Lisbon)。
他写了200多篇有关ESP32、ESP8266的有用的教程和项目。

查看更多ESP32/ESP8266教程和项目:
中文版教程 : ESP32教程 合集
英文版教程 : ESP32 tutorial 合集

gada888  版主

发表于 2019-5-11 10:10:19

很实用
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

为本项目制作心愿单
购买心愿单
心愿单 编辑
wifi气象站

硬件清单

btnicon
我也要做!
点击进入购买页面
上海智位机器人股份有限公司 沪ICP备09038501号-4

© 2013-2019 Comsenz Inc. Powered by Discuz! X3.4 Licensed

mail