如何在 python dash 应用程序中绘制来自传感器的串行信号?
Posted
技术标签:
【中文标题】如何在 python dash 应用程序中绘制来自传感器的串行信号?【英文标题】:How to plot serial signal from a sensor in a python dash app? 【发布时间】:2020-11-15 21:25:23 【问题描述】:我正在尝试从 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() 不断地或多或少地输出相同的值
【问题讨论】:
【参考方案1】:由于我特别不熟悉 Dash,因此很难准确诊断出这里出了什么问题。但是,我在 Python 和 Arduinos 方面的其他经验提出了一些故障排除建议,按照我建议的尝试顺序:
-
尝试拔下和插入您的 Arduino,并关闭其他可能试图使用 COM 端口的程序。通常(总是?)一次只有一个程序可以打开给定的 COM 端口。第二个程序将收到权限被拒绝错误。
尝试在回调函数之外初始化串行端口。即,在脚本的早期打开 com 端口,将其“ser”对象保留为全局变量。
也许 Dash 窗口没有自动授予管理员权限。尝试以管理员身份显式运行 Python 提示符。 (当您尝试打开命令行、终端、Python IDE 或您正在使用的任何东西时,右键单击应用程序图标。)
您猜测波特率或超时设置通常可能是一个问题是正确的,但是您的两个示例代码中的串行初始化行是相同的,所以我怀疑这是这里的问题。
【讨论】:
以上是关于如何在 python dash 应用程序中绘制来自传感器的串行信号?的主要内容,如果未能解决你的问题,请参考以下文章
Plotly Dash:在 Python 中绘制 networkx
使用 Plotly 生成有角度的条形图(来自 Dash 的风险分析)