I am using python through windows, and I am trying to read data from a NI 9234 using an accelerometer. I want this data to be remotely read and for that I am using Dash. While for the NI part, I was trying to use nidaqmx, using this example.
My dash program is easy right now and it was working without the nidaqmx part (doing something reaaaally easy), while the nidaqmx program was succesfully reading data from the sensor. If I try to merge them together, I get the following error:
Here is my script:
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)
I was thinking that maybe dash is not supporting nidaqmx, and if that's the case a possible solution would be using the two scripts: one for doing the sensor reading, and the main one in dash to display the info to the user... However, I was trying to have everything in one script for clarification purposes.
Searched everywhere, but can't find nidaqmx being implemented into dash. Any help is greatly appreciated.
Thanks, dm2! Like you said, I was not declaring the task, I also ran into a ctypes problem that I need to research further, but for now I will declare my values as int. I am posting the solution because I guess that the world is full of newbs as myself:
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)
The sensor is reading the data!!