1+ """Streamlit visualization script to display data acquired by nidaqmx_continuous_analog_input.py."""
2+
3+ import streamlit as st
4+ from nidaqmx .constants import (
5+ TerminalConfiguration ,
6+ CJCSource ,
7+ TemperatureUnits ,
8+ ThermocoupleType ,
9+ LoggingMode ,
10+ )
11+ from streamlit_echarts import st_echarts
12+
13+ import nipanel
14+ from nipanel .controls import enum_selectbox
15+
16+
17+ st .set_page_config (page_title = "NI-DAQmx Example" , page_icon = "📈" , layout = "wide" )
18+ st .title ("Analog Input - Voltage and Thermocouple in a Single Task" )
19+
20+ st .markdown (
21+ """
22+ <style>
23+ div[data-baseweb="select"] {
24+ max-width: 250px !important;
25+ }
26+ div.stNumberInput {
27+ max-width: 250px !important;
28+ }
29+ div.stTextInput {
30+ max-width: 250px !important;
31+ }
32+ </style>
33+ """ ,
34+ unsafe_allow_html = True ,
35+ )
36+
37+ panel = nipanel .get_streamlit_panel_accessor ()
38+ is_running = panel .get_value ("is_running" , False )
39+
40+ if is_running :
41+ st .button (r"⏹️ Stop" , key = "stop_button" )
42+ else :
43+ st .button (r"▶️ Run" , key = "run_button" )
44+
45+ thermocouple_data = panel .get_value ("thermocouple_data" , [0.0 ])
46+ voltage_data = panel .get_value ("voltage_data" , [0.0 ])
47+ sample_rate = panel .get_value ("sample_rate" , 0.0 )
48+
49+ # Create two-column layout for the entire interface
50+ left_column , right_column = st .columns ([1 , 1 ])
51+
52+ # Left column - Channel tabs and Timing Settings
53+ with left_column :
54+ # Channel Settings tabs
55+ with st .container (border = True ):
56+ st .header ("Channel Settings" )
57+ voltage_tab , thermocouple_tab = st .tabs (["Voltage" , "Thermocouple" ])
58+
59+ voltage_tab .header ("Voltage" )
60+ with voltage_tab :
61+ channel_left_column , channel_right_column = st .columns (2 )
62+ with channel_left_column :
63+ st .selectbox (options = ["Dev1/ai0" ], label = "Physical Channels" , disabled = True )
64+ st .number_input (
65+ "Min Value" ,
66+ value = - 5.0 ,
67+ step = 0.1 ,
68+ disabled = panel .get_value ("is_running" , False ),
69+ key = "voltage_min_value" ,
70+ )
71+ st .number_input (
72+ "Max Value" ,
73+ value = 5.0 ,
74+ step = 0.1 ,
75+ disabled = panel .get_value ("is_running" , False ),
76+ key = "voltage_max_value" ,
77+ )
78+ with channel_right_column :
79+ enum_selectbox (
80+ panel ,
81+ label = "Terminal Configuration" ,
82+ value = TerminalConfiguration .DEFAULT ,
83+ disabled = panel .get_value ("is_running" , False ),
84+ key = "terminal_configuration" ,
85+ )
86+
87+ thermocouple_tab .header ("Thermocouple" )
88+ with thermocouple_tab :
89+ channel_left_column , channel_middle_column , channel_right_column = st .columns (3 )
90+ with channel_left_column :
91+ st .selectbox (options = ["Dev1/ai1" ], label = "Physical Channel" , disabled = True )
92+ st .number_input (
93+ "Min Value" ,
94+ value = 0.0 ,
95+ step = 1.0 ,
96+ disabled = panel .get_value ("is_running" , False ),
97+ key = "thermocouple_min_value" ,
98+ )
99+ st .number_input (
100+ "Max Value" ,
101+ value = 100.0 ,
102+ step = 1.0 ,
103+ disabled = panel .get_value ("is_running" , False ),
104+ key = "thermocouple_max_value" ,
105+ )
106+ with channel_middle_column :
107+ enum_selectbox (
108+ panel ,
109+ label = "Units" ,
110+ value = TemperatureUnits .DEG_C ,
111+ disabled = panel .get_value ("is_running" , False ),
112+ key = "thermocouple_units" ,
113+ )
114+ enum_selectbox (
115+ panel ,
116+ label = "Thermocouple Type" ,
117+ value = ThermocoupleType .K ,
118+ disabled = panel .get_value ("is_running" , False ),
119+ key = "thermocouple_type" ,
120+ )
121+ with channel_right_column :
122+ enum_selectbox (
123+ panel ,
124+ label = "CJC Source" ,
125+ value = CJCSource .CONSTANT_USER_VALUE ,
126+ disabled = panel .get_value ("is_running" , False ),
127+ key = "thermocouple_cjc_source" ,
128+ )
129+ st .number_input (
130+ "CJC Value" ,
131+ value = 25.0 ,
132+ step = 1.0 ,
133+ disabled = panel .get_value ("is_running" , False ),
134+ key = "thermocouple_cjc_val" ,
135+ )
136+
137+ # Timing Settings section in left column
138+ with st .container (border = True ):
139+ st .header ("Timing Settings" )
140+ timing_left_column , timing_right_column = st .columns (2 )
141+ with timing_left_column :
142+ st .selectbox (
143+ options = ["OnboardClock" ],
144+ label = "Sample Clock Source" ,
145+ disabled = True ,
146+ )
147+ st .number_input (
148+ "Sample Rate" ,
149+ value = 1000.0 ,
150+ step = 100.0 ,
151+ min_value = 1.0 ,
152+ disabled = panel .get_value ("is_running" , False ),
153+ key = "sample_rate_input" ,
154+ )
155+ with timing_right_column :
156+ st .number_input (
157+ "Samples per Loop" ,
158+ value = 3000 ,
159+ step = 100 ,
160+ min_value = 10 ,
161+ disabled = panel .get_value ("is_running" , False ),
162+ key = "samples_per_channel" ,
163+ )
164+ st .text_input (
165+ label = "Actual Sample Rate" ,
166+ value = str (sample_rate ) if sample_rate else "" ,
167+ key = "actual_sample_rate_display" ,
168+ )
169+
170+ # Right column - Graph and Logging Settings
171+ with right_column :
172+ with st .container (border = True ):
173+ # Graph section
174+ st .header ("Voltage & Thermocouple" )
175+ voltage_therm_graph = {
176+ "animation" : False ,
177+ "tooltip" : {"trigger" : "axis" },
178+ "legend" : {"data" : ["Voltage (V)" , "Temperature (C)" ]},
179+ "xAxis" : {
180+ "type" : "category" ,
181+ "data" : [
182+ x / sample_rate if sample_rate > 0.001 else x for x in range (len (voltage_data ))
183+ ],
184+ "name" : "Time" ,
185+ "nameLocation" : "center" ,
186+ "nameGap" : 40 ,
187+ },
188+ "yAxis" : {
189+ "type" : "value" ,
190+ "name" : "Measurement" ,
191+ "nameRotate" : 90 ,
192+ "nameLocation" : "center" ,
193+ "nameGap" : 40 ,
194+ },
195+ "series" : [
196+ {
197+ "name" : "voltage_amplitude" ,
198+ "type" : "line" ,
199+ "data" : voltage_data ,
200+ "emphasis" : {"focus" : "series" },
201+ "smooth" : True ,
202+ "seriesLayoutBy" : "row" ,
203+ },
204+ {
205+ "name" : "thermocouple_amplitude" ,
206+ "type" : "line" ,
207+ "data" : thermocouple_data ,
208+ "color" : "red" ,
209+ "emphasis" : {"focus" : "series" },
210+ "smooth" : True ,
211+ "seriesLayoutBy" : "row" ,
212+ },
213+ ],
214+ }
215+ st_echarts (options = voltage_therm_graph , height = "446px" , key = "voltage_therm_graph" )
216+
217+ # Logging Settings section in right column
218+ with st .container (border = True ):
219+ st .header ("Logging Settings" )
220+ logging_left_column , logging_right_column = st .columns (2 )
221+ with logging_left_column :
222+ enum_selectbox (
223+ panel ,
224+ label = "Logging Mode" ,
225+ value = LoggingMode .OFF ,
226+ disabled = panel .get_value ("is_running" , False ),
227+ key = "logging_mode" ,
228+ )
229+ with logging_right_column :
230+ left_sub_column , right_sub_column = st .columns ([3 , 1 ])
231+ with left_sub_column :
232+ tdms_file_path = st .text_input (
233+ label = "TDMS File Path" ,
234+ disabled = panel .get_value ("is_running" , False ),
235+ value = "data.tdms" ,
236+ key = "tdms_file_path" ,
237+ )
0 commit comments