【发布时间】:2021-03-24 21:07:43
【问题描述】:
我只是想在一个值表示开始后从 QtSerialPort 连接读取值到 arduino。我可以在 python 代码中有一个最大计数,但这并不会改变它在多次运行 python 脚本后没有从 arduino 读取 println 的结果。起初它会打印出“开始”、“阅读”和“V”,如果我很快再次运行它,可能会再次打印出来。但在那之后,它在打印出“开始”后停止阅读。这是python代码。
from PyQt5 import QtCore, QtSerialPort
import sys
app = QtCore.QCoreApplication([])
serial_port = QtSerialPort.QSerialPort('COM3')
serial_port.open(QtCore.QIODevice.ReadWrite)
def handle_ready_read():
print('to read')
while serial_port.canReadLine():
serialrd = serial_port.readLine().data().decode().strip()
print(serialrd)
serial_port.close()
app.quit()
serial_port.readyRead.connect(handle_ready_read)
serial_port.write(bytes([100]))
print('start')
sys.exit(app.exec_())
这是arduino代码。
int measured;
int counter = 0;
int maxnum = 10;
void setup()
{
Serial.begin(9600);
}
void loop()
{
if(Serial.available() > 0)
{
while(counter < maxnum)
{
Serial.println("V");
counter++;
delay(100);
}
}
}
任何可以解释为什么它不会再次阅读的想法都会很有用。我每次都必须拔下并重新插入 arduino 才能读取它,但最好避免这样做。我还注意到我无法在 pyserial 连接之后运行 PyQt5 串行端口连接,首先断开 arduino,但我可以在 PyQt5 串行端口连接之后运行 pyserial,尽管我不知道该问题是否与某种相关。
编辑:我在handle_ready_read中添加了'to read'打印语句,第一次运行时有时会打印两次,所以虽然有要读取的内容,但readline并不总是可以读取,所以我添加了到最后去handle_ready_read吧,
while serial_port.bytesAvailable():
dataByte = serial_port.readLineData(1)
print(dataByte)
serial_port.close()
app.quit()
因此有时会在读取时打印出b'V',而不仅仅是V。但一两次尝试后仍然无法读取。
编辑 2:我添加了一个计时器和函数来检查字节是否被写入,
attempts = []
def check_bytes_written():
print('bytes to write' , serial_port.bytesToWrite())
attempts.append(1)
if len(attempts) > 10:
serial_port.close()
timer.stop()
app.quit()
timer = QtCore.QTimer()
timer.setInterval(50)
timer.timeout.connect(check_bytes_written)
timer.start()
这不会在第一次或第二次尝试时打印出任何内容,然后在以后的尝试中说“要写入 0 的字节”,即使端口和应用程序已结束,仍然没有打印出任何形式的“V”,除非我仍然断开 arduino 并将其重新插入(至少现在不需要每次都重新启动内核)。我还在 arduino 中添加了代码,以检查写入的值是否可用于更改输出引脚的电压,它可以工作并且每次运行 python 脚本时都会更改输出电压,是否读取了“V” .所以我稍微改变了问题标题和之前的文字,因为它并没有真正崩溃或冻结,它只是没有阅读 arduino 正在打印的内容。
编辑 3:我将if(Serial.available() > 0) { int counter = 0; 放在 arduino 代码中,而不是在开始时初始化计数器,python 代码将在重新运行脚本时从 arduino 读取(尽管 V 周围有一堆空格,或者只是从 readlineData 部分打印 b'\x00',但这可能是另一个问题,可以通过在 readyRead 之前放置 serial_port.clear() 来清除它,但是仍然会打印 V 或 b'V')。所以看起来python脚本没有重新启动arduino代码,也许这是qserialport如何关闭或打开的问题(如DTR或RTS),不像pyserial那样?更多讨论here。
编辑 4:如果我添加(在 arduino 代码的开头初始化计数器时,如最初所示,撤消最后一次编辑)
serial_port.setDataTerminalReady(1)
serial_port.setDataTerminalReady(0)
serial_port.setDataTerminalReady(1)
在serial_port.open 语句并运行它之后,它仍然不会从串行读取中打印(没有断开arduino 并首先重新连接它),但是如果我评论DTR 设置,那么V 是再次运行时按预期打印,无需断开连接,但随后又回到不打印V。仅使用 serial_port.setDataTerminalReady(1) 也会产生相同的效果,每隔一段时间将其评论输入/输出。
编辑 5:我发现(一旦它至少正常运行一次,首先拔掉插头或使用编辑 4 中的方法),如果我放了
serial_port.setDataTerminalReady(0)
serial_port.setDataTerminalReady(1)
serial_port.setDataTerminalReady(0)
就在serial_port.close() 之前,它可以再次运行多次并打印出“V”。我猜它正在将 DTR 重置为 0。如果有解释为什么需要发生这种情况,那就太好了。
【问题讨论】:
标签: python arduino pyqt5 qtserialport