#python #windows #plotly-dash #nidaqmx
Вопрос:
Я использую python через Windows и пытаюсь считывать данные с NI 9234 с помощью акселерометра. Я хочу, чтобы эти данные считывались удаленно, и для этого я использую Dash. В то время как по части NI я пытался использовать nidaqmx, используя этот пример.
Моя программа dash сейчас проста, и она работала без части nidaqmx (делала что-то действительно простое), в то время как программа nidaqmx успешно считывала данные с датчика. Если я попытаюсь объединить их вместе, я получу следующую ошибку:
Вот мой сценарий:
import dash
import dash_daq as daq
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
import plotly.graph_objects as go
from dash.exceptions import PreventUpdate
import nidaqmx
from nidaqmx.constants import AcquisitionType
import numpy as np
external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']
app = dash.Dash(__name__, external_stylesheets=external_stylesheets)
# some color to this
colors = {
'background': '#111111',
'text': '#7FDBFF'
}
#Initial conditions to have something in the graph
trace_1 = go.Scatter(
x = [],
y = []
)
layout = go.Layout(title = 'Título de gráfica')
fig = go.Figure(data = [trace_1], layout = layout)
app.layout = html.Div(style = {'backgroundColor': colors['background']},
children = [
# H3 es para marcar el título, es el mediano que los demás, H1 es súper grande.
html.H3(
children = 'Ejemplo fácil para chequear botones-gráficas-menus',
style = {
'textAlign': 'center',
'color': colors['text']
}
),
# Div parece que divide éste párrafo abajo de lo anterior
html.Div(
id= 'respuesta',
children= 'Clickea el botón',
style = {
'textAlign': 'center',
'color': colors['text']
}
),
# Se define el botón:
daq.BooleanSwitch(
id = 'Swtc_1',
label = 'Capturar',
on = False
),
html.Div(
[
html.Br(),
html.Br(),
html.Label(
['Elija algo'],
style = {
'font-weight': 'bold',
'text-align': 'center',
'color': colors['text']
}
),
dcc.Dropdown(
id = 'f_muestreo',
options = [
{'label' : '2048', 'value':'2048'},
{'label' : '2560', 'value':'2560'},
{'label' : '3200', 'value':'3200'},
{'label' : '5120', 'value':'5120'},
{'label' : '6400', 'value':'6400'},
{'label' : '10240', 'value':'10240'},
{'label' : '12800', 'value':'12800'},
{'label' : '25600', 'value':'25600'}
],
value = '2048',
multi = False,
disabled = False,
persistence = 'string',
persistence_type = 'session'
),
html.Br(),
dcc.Dropdown(
id = 'muestras',
options = [
{'label' : '2048', 'value':'2048'},
{'label' : '4096', 'value':'4096'},
{'label' : '8192', 'value':'8192'},
{'label' : '16384', 'value':'16384'},
{'label' : '32768', 'value':'32768'},
{'label' : '65536', 'value':'65536'},
{'label' : '131072', 'value':'131072'}
],
value = '2048',
multi = False,
disabled = False,
persistence = 'string',
persistence_type = 'session'
)
],className = 'three columns'
),
# graph
html.Div(
[
dcc.Graph(id = 'plot_id', figure = fig)
],className = 'eight columns'
)
]
)
# interaction
@app.callback(
Output('plot_id', 'figure'),
[Input('Swtc_1', 'on'),
Input('f_muestreo', 'value'),
Input('muestras', 'value')]
)
def update_output(on, value_1, value_2):
if on is True:
sample_rate = float(value_1)
samples_to_acq = float(value_2)
wait_time = samples_to_acq/sample_rate
#Name and channel of my NI 9234
channel_name = 'cDAQBAYO1Mod1/ai0'
#Not using the trig yet
#trig_name = 'cDAQBAYO1Mod1/ai1'
cont_mode = AcquisitionType.CONTINUOUS
units_g = nidaqmx.constants.AccelUnits.G
# Create accelerometer channel and configure sample clock and trigger specs
task.ai_channels.add_ai_accel_chan(channel_name, units = units_g)
task.timing.cfg_samp_clk_timing(sample_rate, sample_mode = cont_mode, samps_per_chan=samples_to_acq)
#task.triggers.start_trigger.cfg_dig_edge_start_trig(trigger_source = trig_name)
# Reading data from sensor and generating time data with numpy
ydata = task.read(number_of_samples_per_channel=samples_to_acq)
xdata = np.linspace(0, wait_time,samples_to_acq)
trace_1 = go.Scatter(
x = list(xdata),
y = list(ydata)
)
layout = go.Layout(title = 'Oscilograma')
fig = go.Figure(data = [trace_1], layout = layout)
return (fig)
else:
raise PreventUpdate
if __name__ == '__main__':
app.run_server(port=3040, debug=True)
Я подумал, что, возможно, dash не поддерживает nidaqmx, и в этом случае возможным решением было бы использовать два сценария: один для считывания показаний датчика и основной в dash для отображения информации пользователю… Тем не менее, я пытался собрать все в одном сценарии для целей разъяснения.
Искали везде, но не смогли найти nidaqmx, реализуемый в dash. Мы будем очень признательны за любую помощь.
Комментарии:
1. В соответствии с ошибкой,
task
не определено. Вы используете егоtask.ai_channels.add_ai_accel_chan()
, никогда не импортируя и не определяя, чтоtask
это такое.2. Привет, dm22, я получил эту строку из примера выше, из NI ( forums.ni.com/t5/Example-Code/… ) Они также не определяют его, и в этом сценарии он работал нормально. Нужно ли мне определять его в тире? и если да, то как? Я должен добавить, что я в этом деле полный новичок.
3. Но да, они определяют его , используя этот оператор контекста:
with nidaqmx.Task() as task
, который эквивалентен (с точки зрения определения переменной задачи)task = nidaqmx.Task()
. Я не знаком с модулем nidaqmx, поэтому лучшее, что я мог бы предложить, — это следовать коду, приведенному в примере, и попытаться добавить аналогичный контекстный оператор, чтобы определить, чтоtask
это такое.4. Редактировать… Вы правы, dm22, они заявляют об этом. Я думаю, что пропустил эту реплику. Я еще раз проверю свой сценарий.
Ответ №1:
Спасибо, dm2! Как вы сказали, я не объявлял задачу, я также столкнулся с проблемой типов, которую мне нужно исследовать дальше, но сейчас я объявлю свои значения как int. Я публикую решение, потому что я предполагаю, что мир полон новичков, как и я сам:
import dash
import dash_daq as daq
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
import plotly.graph_objects as go
from dash.exceptions import PreventUpdate
import nidaqmx
from nidaqmx.constants import AcquisitionType
import numpy as np
external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']
app = dash.Dash(__name__, external_stylesheets=external_stylesheets)
# some color to this
colors = {
'background': '#111111',
'text': '#7FDBFF'
}
#Initial conditions to have something in the graph
trace_1 = go.Scatter(
x = [],
y = []
)
layout = go.Layout(title = 'Título de gráfica')
fig = go.Figure(data = [trace_1], layout = layout)
app.layout = html.Div(style = {'backgroundColor': colors['background']},
children = [
# H3 es para marcar el título, es el mediano que los demás, H1 es súper grande.
html.H3(
children = 'Ejemplo fácil para chequear botones-gráficas-menus',
style = {
'textAlign': 'center',
'color': colors['text']
}
),
# Div parece que divide éste párrafo abajo de lo anterior
html.Div(
id= 'respuesta',
children= 'Clickea el botón',
style = {
'textAlign': 'center',
'color': colors['text']
}
),
# Se define el botón:
daq.BooleanSwitch(
id = 'Swtc_1',
label = 'Capturar',
on = False
),
html.Div(
[
html.Br(),
html.Br(),
html.Label(
['Elija algo'],
style = {
'font-weight': 'bold',
'text-align': 'center',
'color': colors['text']
}
),
dcc.Dropdown(
id = 'f_muestreo',
options = [
{'label' : '2048', 'value':'2048'},
{'label' : '2560', 'value':'2560'},
{'label' : '3200', 'value':'3200'},
{'label' : '5120', 'value':'5120'},
{'label' : '6400', 'value':'6400'},
{'label' : '10240', 'value':'10240'},
{'label' : '12800', 'value':'12800'},
{'label' : '25600', 'value':'25600'}
],
value = '2048',
multi = False,
disabled = False,
persistence = 'string',
persistence_type = 'session'
),
html.Br(),
dcc.Dropdown(
id = 'muestras',
options = [
{'label' : '2048', 'value':'2048'},
{'label' : '4096', 'value':'4096'},
{'label' : '8192', 'value':'8192'},
{'label' : '16384', 'value':'16384'},
{'label' : '32768', 'value':'32768'},
{'label' : '65536', 'value':'65536'},
{'label' : '131072', 'value':'131072'}
],
value = '2048',
multi = False,
disabled = False,
persistence = 'string',
persistence_type = 'session'
)
],className = 'three columns'
),
# graph
html.Div(
[
dcc.Graph(id = 'plot_id', figure = fig)
],className = 'eight columns'
)
]
)
# interaction
@app.callback(
Output('plot_id', 'figure'),
[Input('Swtc_1', 'on'),
Input('f_muestreo', 'value'),
Input('muestras', 'value')]
)
def update_output(on, value_1, value_2):
if on is True:
sample_rate = int(value_1)
samples_to_acq = int(value_2)
wait_time = samples_to_acq/sample_rate
#Name and channel of my NI 9234
channel_name = 'cDAQBAYO1Mod1/ai0'
#Not using the trig yet
#trig_name = 'cDAQBAYO1Mod1/ai1'
cont_mode = AcquisitionType.CONTINUOUS
units_g = nidaqmx.constants.AccelUnits.G
with nidaqmx.Task() as task:
# Create accelerometer channel and configure sample clock and trigger specs
task.ai_channels.add_ai_accel_chan(channel_name, units = units_g)
task.timing.cfg_samp_clk_timing(sample_rate, sample_mode = cont_mode, samps_per_chan=samples_to_acq)
#task.triggers.start_trigger.cfg_dig_edge_start_trig(trigger_source = trig_name)
# Reading data from sensor and generating time data with numpy
ydata = task.read(number_of_samples_per_channel=samples_to_acq)
xdata = np.linspace(0, wait_time,samples_to_acq)
trace_1 = go.Scatter(
x = list(xdata),
y = list(ydata)
)
layout = go.Layout(title = 'Oscilograma')
fig = go.Figure(data = [trace_1], layout = layout)
return (fig)
else:
raise PreventUpdate
if __name__ == '__main__':
app.run_server(port=3040, debug=True)
Датчик считывает данные!!