【arduino学习笔记】通过批处理向串口发送数据到arduino的坑
需求
现有编程为需要从串口接收数据进行处理的arduino主板,每次传输内容为3位数字;arduino处理方法为先读取为字符串,再转换为整型变量进行处理。
每次从串口接收到有效数据时,arduino需要打开一个LED灯;若后续5秒内没有接收到串口数据,则关闭LED。
在实际使用时,需要使用批处理先从powershell执行一条命令,将其结果写入文本文件,随后将文件第四行的内容发送到串口上。
初步方法
询问bing chat和网上搜索,开始编写脚本:
1 |
|
这里的mode COM3 BAUD=96 PARITY=n DATA=8
就是用于设置串口通信参数的命令,而>COM3
是将内容发送到COM3串口上。
问题
该方法存在一个缺陷,arduino的串口通信模式与这里设定的可能不同(尤其是与IDE的默认模式),导致LED灯无法正常打开。
这里还有一个奇怪的地方,不知道是不是我代码有问题,每次重新上传烧录代码到arduino之后LED就能正常被批处理打开,但如果断电重连则不行;此外,断电后如果先用IDE通信则LED正常打开,再用批处理发送不能打开,LED保持熄灭;而如果先用批处理发送,则后续再用IDE发送也无法打开LED。
推测与解决方案
由于我没有仔细阅读arduino官方reference文档,不是非常了解Serial.available()函数具体是如何动作的;但我的推测是,这个函数在等待串口数据的时候会暂时阻塞机器,这也是半双工串口通信的一个问题。
至于它如何影响arduino以至于出现这些奇怪的问题?我也不是很清楚,但我找到了解决方案。
微软官方文档:https://learn.microsoft.com/zh-cn/windows-server/administration/windows-commands/mode
在仔细阅读了批处理中mode指令控制串口参数的用法后,我进行了一些尝试,并成功解决了问题。
只需要在mode
这一行后面加入DTR=OFF RTS=OFF
即可:
1 |
|
这是什么原因呢?我猜测批处理默认情况下会通过DTR和RTS信号来决定何时发送数据。这两个信号是串行通信中的控制信号,前者用于计算机向arduino发出信号,让arduino准备好接收;后者用于arduino向计算机回馈信号,允许计算机发送串口数据。
但这样的过程会浪费很多等待时间,相当于双方要完成握手才能发送数据(类比TCP连接);而整个握手和等待的时间内arduino都处于阻塞状态,LED就处于熄灭状态。
因此,在手动关闭了DTR和RTS信号后,计算机便无需等待arduino响应即可发送数据,arduino也无需等待连接建立,计算机可随时向arduino发送数据(类比UDP包),进而大幅节约了进程时间,使得arduino不再一直处于阻塞状态,LED可以正常点亮。