Skip to content

Commit db935ae

Browse files
DilmiWickramanayakeDilmi Wickramanayake
andauthored
Added NIScope EX Fetch Forever (#99)
* Analog Input - Voltage and Thermocouple Single Task * add niscope Signed-off-by: Dilmi Wickramanayake <[email protected]> * Rename Signed-off-by: Dilmi Wickramanayake <[email protected]> --------- Signed-off-by: Dilmi Wickramanayake <[email protected]> Co-authored-by: Dilmi Wickramanayake <[email protected]>
1 parent 16d0a0b commit db935ae

File tree

5 files changed

+128
-2
lines changed

5 files changed

+128
-2
lines changed

examples/nidaqmx/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,5 @@ This is a nipanel example that displays an interactive Streamlit app and updates
1616

1717
### Usage
1818

19-
Run `poetry run examples/nidaqmx_continuous_analog_input/nidaqmx_continuous_analog_input.py`
19+
Run `poetry run examples/nidaqmx/nidaqmx_continuous_analog_input.py`
2020

examples/niscope/README.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
Prerequisites
2+
===============
3+
Requires a Physical or Simulated Device. Refer to the [Getting Started Section](https://github.com/ni/nidaqmx-python/blob/master/README.rst) to learn how to create a simulated device. This example uses NI oscilloscopes/digitizers, which have the module numbering pattern _51xx_. One example is NI PXIe-5114.
4+
## Sample
5+
6+
This is a nipanel example that displays an interactive Streamlit app and updates and fetches data from device.
7+
8+
### Feature
9+
10+
Script demonstrates NIScope waveform data getting continuously acquired.
11+
- Supports various data types
12+
13+
### Required Software
14+
15+
- Python 3.9 or later
16+
17+
### Usage
18+
19+
Run `poetry run examples/niscope/niscope_ex_fetch_forever.py`
20+
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
"""Continuously acquires waveforms from NI-SCOPE, processes/scales them."""
2+
3+
import time
4+
from pathlib import Path
5+
from typing import Any
6+
7+
import hightime
8+
import niscope
9+
import numpy as np
10+
11+
import nipanel
12+
13+
panel_script_path = Path(__file__).with_name("niscope_ex_fetch_forever_panel.py")
14+
panel = nipanel.create_panel(panel_script_path)
15+
16+
print(f"Panel URL: {panel.panel_url}")
17+
18+
resource_name = "Dev1"
19+
channels = 0
20+
options = ""
21+
length = 1000
22+
samples_per_fetch = 1000
23+
24+
"""Example fetch data from device (Dev1)."""
25+
with niscope.Session(resource_name=resource_name, options=options) as session:
26+
session.configure_vertical(range=2, coupling=niscope.VerticalCoupling.DC, enabled=True)
27+
session.configure_horizontal_timing(
28+
min_sample_rate=100000000,
29+
min_num_pts=1000,
30+
ref_position=50.0,
31+
num_records=1000,
32+
enforce_realtime=True,
33+
)
34+
session.configure_trigger_software()
35+
36+
with session.initiate():
37+
wfm: np.ndarray[Any, np.dtype[np.int8]] = np.ndarray(
38+
length * samples_per_fetch, dtype=np.int8
39+
)
40+
waveforms = session.channels[channels].fetch_into(
41+
relative_to=niscope.FetchRelativeTo.READ_POINTER,
42+
offset=0,
43+
timeout=hightime.timedelta(seconds=5.0),
44+
waveform=wfm,
45+
)
46+
try:
47+
print(f"Press Ctrl + C to stop")
48+
while True:
49+
offset = session.meas_array_offset
50+
gain = session.meas_array_gain
51+
for i in range(len(waveforms)):
52+
time.sleep(0.2)
53+
amplitude_list = []
54+
total_data = waveforms[i].samples.tolist()
55+
for amplitude in total_data:
56+
amplitude = (amplitude * 10) * gain + offset
57+
amplitude_list.append(amplitude)
58+
panel.set_value("Waveform", amplitude_list)
59+
60+
except KeyboardInterrupt:
61+
pass
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
"""Streamlit dashboard for visualizing NI-SCOPE waveform data in real time."""
2+
3+
import streamlit as st
4+
from streamlit_echarts import st_echarts
5+
6+
import nipanel
7+
8+
st.set_page_config(page_title="NI-SCOPE Example", page_icon="📈", layout="wide")
9+
st.title("NIScope EX Fetch Forever")
10+
11+
panel = nipanel.get_panel_accessor()
12+
13+
waveform = panel.get_value("Waveform", [0])
14+
15+
graph = {
16+
"animation": False,
17+
"tooltip": {"trigger": "axis"},
18+
"legend": {"data": ["Amplitude (V)"]},
19+
"xAxis": {
20+
"type": "category",
21+
"data": list(range(len(waveform))),
22+
"name": "Samples",
23+
"nameLocation": "center",
24+
"nameGap": 40,
25+
},
26+
"yAxis": {
27+
"type": "value",
28+
"name": "Amplitude(V)",
29+
"nameRotate": 90,
30+
"nameLocation": "center",
31+
"nameGap": 40,
32+
},
33+
"series": [
34+
{
35+
"name": "niscope data",
36+
"type": "line",
37+
"data": waveform,
38+
"emphasis": {"focus": "series"},
39+
"smooth": True,
40+
"seriesLayoutBy": "row",
41+
},
42+
],
43+
}
44+
st_echarts(options=graph, height="400px", width="75%", key="graph")

pyproject.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ module = [
8989
"streamlit_echarts.*",
9090
# https://github.com/ni/nidaqmx-python/issues/209 - Support type annotations
9191
"nidaqmx.*",
92+
"niscope.*",
9293
]
9394
ignore_missing_imports = true
9495

@@ -103,4 +104,4 @@ testpaths = ["src/nipanel", "tests"]
103104

104105
[tool.pyright]
105106
include = ["examples/", "src/", "tests/"]
106-
exclude = ["src/ni/protobuf/types/", "src/ni/pythonpanel/v1/","examples/nidaqmx/nidaqmx_continuous_analog_input.py"]
107+
exclude = ["src/ni/protobuf/types/", "src/ni/pythonpanel/v1/","examples/nidaqmx/nidaqmx_continuous_analog_input.py","examples/niscope/niscope_ex_fetch_forever.py"]

0 commit comments

Comments
 (0)