我正在尝试使用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),它会在该100欧姆电阻和复位引脚上抛出5V,防止DTR将其拉低并重置芯片:) 然后我离开串行模式时调用setResetDisable(false),这样可以正常编程芯片。
答案 0 :(得分:11)
你应该能够在打开端口之前禁用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上打开之前允许setRTS,setDTR(设置初始状态),doc update
看起来它可能刚刚错过了2.6版本(2011年11月2日上传,请参阅:https://pypi.python.org/pypi/pyserial)。
此外,查看POSIX的setDTR()
的当前实现(在serialposix.py中),看起来此错误未修复,如果端口是,则抛出异常不开放,所以跨平台解决方案看起来不太可能。
答案 1 :(得分:2)
禁用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()
我发现它here。
答案 2 :(得分:1)
您描述的方法似乎是我见过的最常见的解决方案 - 所以我怀疑没有更简单的基于软件的解决方案。您当然可以使用ser.setDTR(level)
手动更改DTR行的状态 - 但是我没有在Arduino自动复位的情况下专门尝试这个,我怀疑在打开串口后立即切换线路可能不够快,以防止重置。
我可以看到你可以使用的其他选项是防止Arduino在硬件中自动复制(see here),或者稍微更改你的代码,以便在最初制作之后允许Arduino重启串行连接,然后当您手动触发串行接收模式时,从Arduino发送一个初始信号,表明它现在已准备好接收数据。或者,您可以在脚本中包含pySerial库的修改版本。
答案 3 :(得分:-2)
这是一个软件解决方案,我一直在使用它一段时间,它就像一个魅力:
ser = serial.Serial("/dev/ttyUSB0", 115200, timeout=1)
ser.setDTR(False)
time.sleep(0.5)
请注意,睡眠是棘手的部分,没有它就无法工作