Skip to content

Commit 12c2a37

Browse files
author
Dilmi Wickramanayake
committed
Merge branch 'users/DilmiWickramanayake/Analog_Output_voltage' of https://github.com/ni/nipanel-python into users/DilmiWickramanayake/Analog_Output_voltage
2 parents dd9d95b + 126d3fb commit 12c2a37

File tree

2 files changed

+339
-0
lines changed

2 files changed

+339
-0
lines changed
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
"""Data acquisition script that continuously acquires analog input data."""
2+
3+
from pathlib import Path
4+
5+
import nidaqmx
6+
from nidaqmx.constants import (
7+
AcquisitionType,
8+
CurrentShuntResistorLocation,
9+
CurrentUnits,
10+
Edge,
11+
LoggingMode,
12+
LoggingOperation,
13+
Slope,
14+
)
15+
from settings import AnalogPause, PauseWhen
16+
17+
import nipanel
18+
19+
panel_script_path = Path(__file__).with_name("nidaqmx_current_panel.py")
20+
panel = nipanel.create_panel(panel_script_path)
21+
panel.set_value("is_running", False)
22+
try:
23+
print(f"Panel URL: {panel.panel_url}")
24+
print(f"Waiting for the 'Run' button to be pressed...")
25+
print(f"(Press Ctrl + C to quit)")
26+
while True:
27+
while not panel.get_value("run_button", False):
28+
panel.set_value("is_running", False)
29+
panel.set_value("is_running", True)
30+
panel.set_value("stop_button", False)
31+
32+
# How to use nidaqmx: https://nidaqmx-python.readthedocs.io/en/stable/
33+
with nidaqmx.Task() as task:
34+
35+
chan = task.ai_channels.add_ai_current_chan(
36+
"Mod3/ai10",
37+
max_val=panel.get_value("max_value_current", 0.01),
38+
min_val=panel.get_value("min_value_current", -0.01),
39+
ext_shunt_resistor_val=panel.get_value("shunt_resistor_value", 249.0),
40+
shunt_resistor_loc=panel.get_value(
41+
"shunt_location", CurrentShuntResistorLocation.EXTERNAL
42+
),
43+
)
44+
45+
task.timing.cfg_samp_clk_timing(
46+
rate=panel.get_value("rate", 1000.0),
47+
sample_mode=AcquisitionType.CONTINUOUS,
48+
samps_per_chan=panel.get_value("num_of_samps", 1000),
49+
)
50+
panel.set_value("sample_rate", task._timing.samp_clk_rate)
51+
52+
task.in_stream.configure_logging(
53+
file_path=panel.get_value("tdms_file_path", "data.tdms"),
54+
logging_mode=panel.get_value("logging_mode", LoggingMode.OFF),
55+
operation=LoggingOperation.OPEN_OR_CREATE,
56+
)
57+
trigger_type = panel.get_value("trigger_type")
58+
59+
if trigger_type == "5":
60+
task.triggers.start_trigger.cfg_anlg_edge_start_trig(
61+
trigger_source="APFI0",
62+
trigger_slope=panel.get_value("slope", Slope.FALLING),
63+
trigger_level=panel.get_value("level", 0.0),
64+
)
65+
66+
if trigger_type == "2":
67+
task.triggers.start_trigger.cfg_dig_edge_start_trig(
68+
trigger_source="/Dev2/PFI0", trigger_edge=panel.get_value("edge", Edge.FALLING)
69+
)
70+
task.triggers.start_trigger.anlg_edge_hyst = hysteresis = panel.get_value(
71+
"hysteresis", 0.0
72+
)
73+
74+
try:
75+
76+
task.start()
77+
78+
while not panel.get_value("stop_button", False):
79+
data = task.read(
80+
number_of_samples_per_channel=1000
81+
) # pyright: ignore[reportArgumentType]
82+
panel.set_value("voltage_data", data)
83+
panel.set_value("current_data", data)
84+
panel.set_value("strain_data", data)
85+
86+
except KeyboardInterrupt:
87+
pass
88+
finally:
89+
task.stop()
90+
panel.set_value("is_running", False)
91+
panel.set_value("run_button", False)
92+
93+
94+
except KeyboardInterrupt:
95+
pass
Lines changed: 244 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,244 @@
1+
"""Streamlit visualization script to display data acquired by nidaqmx_analog_input_filtering.py."""
2+
3+
import extra_streamlit_components as stx # type: ignore[import-untyped]
4+
import streamlit as st
5+
from nidaqmx.constants import (
6+
CurrentShuntResistorLocation,
7+
CurrentUnits,
8+
Edge,
9+
FilterResponse,
10+
LoggingMode,
11+
Slope,
12+
StrainGageBridgeType,
13+
TerminalConfiguration,
14+
)
15+
from settings import AnalogPause, PauseWhen
16+
from streamlit_echarts import st_echarts
17+
18+
import nipanel
19+
from nipanel.controls import enum_selectbox
20+
21+
st.set_page_config(page_title="Current - Continuous Input", page_icon="📈", layout="wide")
22+
st.title("Current - Continuous Input")
23+
panel = nipanel.get_panel_accessor()
24+
25+
left_col, right_col = st.columns(2)
26+
27+
28+
is_running = panel.get_value("is_running", True)
29+
with left_col:
30+
if is_running:
31+
st.button("Stop", key="stop_button")
32+
else:
33+
st.button("Run", key="run_button")
34+
35+
36+
st.markdown(
37+
"""
38+
<style>
39+
div[data-baseweb="select"] {
40+
width: 190px !important; /* Adjust the width as needed */
41+
}
42+
</style>
43+
""",
44+
unsafe_allow_html=True,
45+
)
46+
47+
streamlit_style = """
48+
<style>
49+
iframe[title="streamlit_echarts.st_echarts"]{ height: 400px; width:100%;}
50+
</style>
51+
"""
52+
st.markdown(streamlit_style, unsafe_allow_html=True)
53+
54+
55+
with left_col:
56+
with st.container(border=True):
57+
58+
st.title("Channel Settings")
59+
st.selectbox(options=["Mod3/ai10"], index=0, label="Physical Channels", disabled=True)
60+
61+
enum_selectbox(
62+
panel,
63+
label="Shunt Resistor",
64+
value=CurrentShuntResistorLocation.EXTERNAL,
65+
disabled=panel.get_value("is_running", False),
66+
key="shunt_location",
67+
)
68+
min_value_current = st.number_input(
69+
"Min Current (A)",
70+
value=0.0,
71+
step=0.001,
72+
disabled=panel.get_value("is_running", False),
73+
)
74+
panel.set_value("min_value_current", min_value_current)
75+
max_value_current = st.number_input(
76+
"Max Current (A)",
77+
value=0.02,
78+
step=1.0,
79+
key="max_value_current",
80+
disabled=panel.get_value("is_running", False),
81+
)
82+
current = panel.set_value("max_value_current", max_value_current) # type:ignore
83+
shunt_resistor_value = st.number_input(
84+
"Shunt Resistor Value (Ohm)",
85+
value=249.0,
86+
step=1.0,
87+
disabled=panel.get_value("is_running", False),
88+
)
89+
panel.set_value("shunt_resistor_value", shunt_resistor_value)
90+
91+
st.title("Timing Settings")
92+
93+
st.selectbox("Sample Clock Source", options=["Onboard Clock"], index=0, disabled=True)
94+
st.number_input(
95+
"Sample Rate",
96+
value=1000.0,
97+
min_value=1.0,
98+
step=1.0,
99+
disabled=panel.get_value("is_running", False),
100+
key="rate",
101+
)
102+
st.number_input(
103+
"Number of Samples",
104+
value=1000,
105+
min_value=1,
106+
step=1,
107+
disabled=panel.get_value("is_running", False),
108+
key="num_of_samps",
109+
)
110+
st.selectbox(
111+
"Actual Sample Rate", options=[panel.get_value("sample_rate", 100.0)], disabled=True
112+
)
113+
114+
st.title("Logging Settings")
115+
enum_selectbox(
116+
panel,
117+
label="Logging Mode",
118+
value=LoggingMode.OFF,
119+
disabled=panel.get_value("is_running", False),
120+
key="logging_mode",
121+
)
122+
tdms_file_path = st.text_input(
123+
label="TDMS File Path",
124+
disabled=panel.get_value("is_running", False),
125+
value="data.tdms",
126+
key="tdms_file_path",
127+
)
128+
129+
with right_col:
130+
with st.container(border=True):
131+
st.title("Trigger Settings")
132+
id = stx.tab_bar(
133+
data=[
134+
stx.TabBarItemData(id=1, title="No Trigger", description=""),
135+
stx.TabBarItemData(id=2, title="Digital Start", description=""),
136+
stx.TabBarItemData(id=3, title="Digital Pause", description=""),
137+
stx.TabBarItemData(id=4, title="Digital Reference", description=""),
138+
stx.TabBarItemData(id=5, title="Analog Start", description=""),
139+
stx.TabBarItemData(id=6, title="Analog Pause", description=""),
140+
stx.TabBarItemData(id=7, title="Analog Reference", description=""),
141+
],
142+
default=1,
143+
)
144+
trigger_type = id
145+
panel.set_value("trigger_type", trigger_type)
146+
tab1, tab2, tab3, tab4, tab5, tab6, tab7 = st.tabs(
147+
[
148+
"No Trigger",
149+
"Digital Start",
150+
"Digital Pause",
151+
"Digital Reference",
152+
"Analog Start",
153+
"Analog Pause",
154+
"Analog Reference",
155+
]
156+
)
157+
with tab1:
158+
st.write(
159+
"To enable triggers, select a tab above, and configure the settings. \n Not all hardware supports all trigger types. Refer to your device documentation for more information."
160+
)
161+
with tab2:
162+
st.selectbox("Source->", " /Dev1/PFI0")
163+
enum_selectbox(
164+
panel,
165+
label="Edge",
166+
value=Edge.FALLING,
167+
disabled=panel.get_value("is_running", False),
168+
key="edge",
169+
)
170+
with tab3:
171+
st.write(
172+
"This trigger type is not supported in continuous sample timing. Refer to your device documentation for more information on which triggers are supported."
173+
)
174+
175+
pause_when = PauseWhen[pause_when[0]] # type: ignore
176+
panel.set_value("pause_when", pause_when)
177+
with tab4:
178+
st.write(
179+
"This trigger type is not supported in continuous sample timing. Refer to your device documentation for more information on which triggers are supported"
180+
)
181+
with tab5:
182+
st.selectbox("Source:", "APFI0")
183+
enum_selectbox(
184+
panel,
185+
label="Slope",
186+
value=Slope.FALLING,
187+
disabled=panel.get_value("is_running", False),
188+
key="slope",
189+
)
190+
191+
level = st.number_input("Level")
192+
panel.set_value("level", level)
193+
hysteriesis = st.number_input(
194+
"Hysteriesis", disabled=panel.get_value("is_running", False)
195+
)
196+
panel.set_value("hysteriesis", hysteriesis)
197+
198+
with tab6:
199+
st.write(
200+
"This trigger type is not supported in continuous sample timing. Refer to your device documentation for more information on which triggers are supported."
201+
)
202+
203+
204+
with tab7:
205+
st.write(
206+
"This trigger type is not supported in continuous sample timing. Refer to your device documentation for more information on which triggers are supported."
207+
)
208+
209+
210+
with right_col:
211+
current_data = panel.get_value("current_data", [1.0])
212+
sample_rate = panel.get_value("sample_rate", 0.0)
213+
with right_col:
214+
with st.container(border=True):
215+
graph = {
216+
"animation": False,
217+
"tooltip": {"trigger": "axis"},
218+
"legend": {"data": ["Current Data"]},
219+
"xAxis": {
220+
"type": "category",
221+
"data": [x / sample_rate for x in range(len(current_data))],
222+
"name": "Time",
223+
"nameLocation": "center",
224+
"nameGap": 40,
225+
},
226+
"yAxis": {
227+
"type": "value",
228+
"name": "Amps",
229+
"nameRotate": 90,
230+
"nameLocation": "center",
231+
"nameGap": 40,
232+
},
233+
"series": [
234+
{
235+
"name": "voltage_amplitude",
236+
"type": "line",
237+
"data": current_data,
238+
"emphasis": {"focus": "series"},
239+
"smooth": True,
240+
"seriesLayoutBy": "row",
241+
},
242+
],
243+
}
244+
st_echarts(options=graph, height="400px", key="graph", width="100%")

0 commit comments

Comments
 (0)