在代码中禁用pyserial的DTR
我正在尝试使用pyserial库向Arduino发送数据。但是,当我打开COM端口时,它会将DTR信号拉低,从而重置了板子。不过,我的Arduino代码设置是需要按住两个按钮1秒钟才能进入串口接收模式。如果可以的话,我不想在Arduino启动时就进行串口输入。
显然,你可以修改serialWin32.py文件,改变其中一行代码:
self._dtrState = win32.DTR_CONTROL_ENABLE
改成:
self._dtrState = win32.DTR_CONTROL_DISABLE
但是,有没有办法直接在我的Python脚本中禁用这个功能呢?我还需要在所有系统上都能这样做。我不想强迫别人为了使用这个脚本而去更改他们的基本串口配置。
打开串口的方式如下:
com = serial.Serial(port, baud, timeout=1);
更新:最后我找到了一种适合我设置的解决方案。因为我并不需要一直进行串口数据传输,只有在我把设备放入串口接收模式时,我找到了一种方法可以从Arduino本身禁用串口连接时的重置。
很多帖子提到可以通过在5V和重置引脚之间放一个大约100欧姆的电阻来禁用DTR重置。但我不想让这个变成永久性的。所以,我选择在PD5和重置引脚之间放一个电阻。然后,在软件中:
void setup() {
//.......
DDRD &= ~(_BV(PD5)); //Set PD5 as input initially
PORTD |= (_BV(PD5)); //Set high
//.......
}
inline void setResetDisable(bool state)
{
if(state)
DDRD |= (_BV(PD5)); //Set PD5 as output to put 5V on reset line
else
DDRD &= ~(_BV(PD5)); //set back to input mode
}
所以现在,当我想进入串口模式时,我调用setResetDisable(true),这会让5V通过那个100欧姆的电阻和重置引脚,从而防止DTR将其拉低并重置芯片 :) 当我离开串口模式时,我只需调用setResetDisable(false),这样芯片就可以正常编程了。
5 个回答
你提到的方法似乎是我见过的最常见的解决这个问题的办法,所以我觉得可能没有更简单的软件解决方案。当然,你可以手动改变DTR线的状态,使用ser.setDTR(level)
这个命令。不过,我没有专门在Arduino自动重置的情况下尝试过这个方法,我觉得即使在打开串口后立刻切换这个线的状态,也可能来不及,还是会导致重置。
你还有其他的选择,比如在硬件上防止Arduino自动重置(可以查看这里),或者稍微修改一下你的代码,让Arduino在最初建立串口连接后重启,然后在你手动触发串口接收模式时,从Arduino发送一个初始信号,表示它现在准备好接收数据。或者,你也可以在你的脚本中包含一个修改过的pySerial库版本。
关闭DTR对我来说没用:
ser.dtr = None
(Linux 4.4.0 x86_64 / Python 2.7.12 / PySerial 3.4)
但是这个方法有效:
import serial
import termios
port = '/dev/ttyACM0'
f = open(port)
attrs = termios.tcgetattr(f)
attrs[2] = attrs[2] & ~termios.HUPCL
termios.tcsetattr(f, termios.TCSAFLUSH, attrs)
f.close()
se = serial.Serial()
se.baudrate = 115200
se.port = port
print 'dtr =', se.dtr
se.open()
我在这里找到了这个信息。
你应该可以在打开端口之前禁用DTR,像这样:
com = serial.Serial()
com.port = port
com.baudrate = baud
com.timeout = 1
com.setDTR(False)
com.open()
不过,在Windows上使用当前版本的pyserial(2.6)时,执行这个操作会出现以下错误:
..., line 315, in setDTR
ValueError: Attempting to use a port that is already open
这似乎是一个错误,但在2011年12月29日的最新版本中已经修复了(SVN修订版445),你可以查看这个链接了解更多信息:http://pyserial.svn.sourceforge.net/viewvc/pyserial/trunk/pyserial/serial/serialwin32.py?view=log,里面有这样的说明:
允许在Win32上打开之前设置RTS和DTR(以设置初始状态),文档更新
看起来这个修复可能刚好错过了2.6版本的发布(这个版本是在2011年11月2日上传的,详情见:https://pypi.python.org/pypi/pyserial)。
此外,查看当前的setDTR()
在POSIX系统中的实现(在serialposix.py中),似乎这个错误没有被修复,如果端口没有打开,就会抛出异常,所以跨平台的解决方案看起来不太可能。