python - 如何在 python dash 应用程序中绘制来自传感器的串行信号?
问题描述
我正在尝试从 arduino uno 读取模拟输入,并在破折号 GUI 中不断显示新输入。使用 pyserial 包从 arduino 读取 USB 串行信号非常简单。
但是,我还不能在 Dash 中实现读数。
到目前为止,我得到的是这段代码,其中每 1000 毫秒触发一次间隔事件,并将生成的数据添加到绘图中(更新):
import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
import os
import plotly.graph_objects as go
import serial
import time, datetime
os.system("start \"\" http://127.0.0.1:8050/") # necessary since dash does not automatically open browser
# readout function for analog signal reading
def readAO():
ser = serial.Serial('COM3', baudrate=9600, timeout=10)
dat = ser.readline().decode('ascii')
ser.close()
return dat
# arrays for saving data points
X = [0]
Y = [0]
# GUI layout/design
app = dash.Dash()
app.layout = html.Div(
children=[
html.H1('Datenauswertung '),
dcc.Graph(id='live-graph'),
dcc.Interval(id='update_graph', interval=1000),
html.Button(id='textout', children='text')
]
)
# update part where data is read and the plot and data arrays are updated
@app.callback(Output('live-graph', 'figure'),
[Input('update_graph', 'n_intervals')])
def update(i_input):
# this is where the Error happens
dat = readAO()
if(dat > 100 | dat < 600):
Y.append(float(1))
X.append(datetime.datetime.now().strftime('%H:%M:%S'))
if len(X) > 50:
del(X[0])
del(Y[0])
plot = go.Figure(go.Scatter(x=X, y=Y, mode='markers+lines'))
return plot
if __name__ == '__main__':
app.run_server()
我得到的是这个错误:
serial.serialutil.SerialException: could not open port 'COM3': PermissionError(13, 'Permission denied', None, 5)
我不明白。我是 PC 的唯一用户,因此授予管理员权限。以下也执行得很好:
while(True):
ser = serial.Serial('COM3', baudrate=9600, timeout=10)
dat = ser.readline().decode('ascii')
print(dat)
ser.close()
让我恼火的一件事是,当我在 while 循环中执行代码时,有时会得到错误的结果(没有错误)。
这可能是串行连接配置的问题,即超时设置不匹配或类似情况?
感谢大家的帮助和见解!
编辑:好的,我进一步本地化了问题。似乎 readline() 时不时地会出错,因此将串行读取封装在 try except 中会捕获到这一点。Dash 和 pyserial 似乎也不能很好地协同工作。我坚持的是 readline() 或多或少地不断输出相同的值
解决方案
由于我特别不熟悉 Dash,因此很难准确诊断出这里出了什么问题。但是,我在 Python 和 Arduinos 方面的其他经验提出了一些故障排除建议,按照我建议尝试的顺序:
- 尝试拔下和插入您的 Arduino,并关闭其他可能试图使用 COM 端口的程序。通常(总是?)一次只有一个程序可以打开给定的 COM 端口。第二个程序将得到一个权限被拒绝的错误。
- 尝试在回调函数之外初始化串行端口。即,在脚本的早期打开 com 端口,将其“ser”对象作为全局变量。
- 也许 Dash 窗口不会自动获得管理员权限。尝试以管理员身份显式运行 Python 提示符。(当您尝试打开命令行、终端、Python IDE 或您正在使用的任何东西时,通过右键单击应用程序图标。)
您猜测波特率或超时设置通常可能是一个问题是正确的,但是您的两个示例代码中的串行初始化行是相同的,所以我怀疑这是这里的问题。
推荐阅读
- python - GCP AI 平台统一:使用解析器/命令行参数时找不到存储桶
- ios - 状态栏上方的导航栏
- javascript - 我在遵循教程后得到的 Javascript 项目中出现“TypeError:无法读取未定义的属性‘长度’”错误。如何修复错误?
- r - 在 tidyverse 中使用 ifelse 更改多个值
- c - 执行整个代码之前的函数返回
- svg - 如何使用带有 document.evaluate 的 xpath 单击 svg 元素
- javascript - 此条件将始终返回 false,因为 Light 和 Dark 类型没有重叠
- python - Python Ray:固定在内存中的对象无法驱逐
- php - Woocommerce 和发票系统中的价格舍入问题
- facebook - 当 fbq('track') 也适用于自定义事件时,Facebook fbq('trackCustom') 是否必要?