diff --git a/examples/nidaqmx/README.md b/examples/nidaqmx/README.md index 0969d0d..5e80d97 100644 --- a/examples/nidaqmx/README.md +++ b/examples/nidaqmx/README.md @@ -16,5 +16,5 @@ This is a nipanel example that displays an interactive Streamlit app and updates ### Usage -Run `poetry run examples/nidaqmx_continuous_analog_input/nidaqmx_continuous_analog_input.py` +Run `poetry run examples/nidaqmx/nidaqmx_continuous_analog_input.py` diff --git a/examples/niscope/README.md b/examples/niscope/README.md new file mode 100644 index 0000000..83e8f6e --- /dev/null +++ b/examples/niscope/README.md @@ -0,0 +1,20 @@ +Prerequisites +=============== +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. +## Sample + +This is a nipanel example that displays an interactive Streamlit app and updates and fetches data from device. + +### Feature + +Script demonstrates NIScope waveform data getting continuously acquired. +- Supports various data types + +### Required Software + +- Python 3.9 or later + +### Usage + +Run `poetry run examples/niscope/niscope_ex_fetch_forever.py` + diff --git a/examples/niscope/niscope_ex_fetch_forever.py b/examples/niscope/niscope_ex_fetch_forever.py new file mode 100644 index 0000000..68d7316 --- /dev/null +++ b/examples/niscope/niscope_ex_fetch_forever.py @@ -0,0 +1,61 @@ +"""Continuously acquires waveforms from NI-SCOPE, processes/scales them.""" + +import time +from pathlib import Path +from typing import Any + +import hightime +import niscope +import numpy as np + +import nipanel + +panel_script_path = Path(__file__).with_name("niscope_ex_fetch_forever_panel.py") +panel = nipanel.create_panel(panel_script_path) + +print(f"Panel URL: {panel.panel_url}") + +resource_name = "Dev1" +channels = 0 +options = "" +length = 1000 +samples_per_fetch = 1000 + +"""Example fetch data from device (Dev1).""" +with niscope.Session(resource_name=resource_name, options=options) as session: + session.configure_vertical(range=2, coupling=niscope.VerticalCoupling.DC, enabled=True) + session.configure_horizontal_timing( + min_sample_rate=100000000, + min_num_pts=1000, + ref_position=50.0, + num_records=1000, + enforce_realtime=True, + ) + session.configure_trigger_software() + + with session.initiate(): + wfm: np.ndarray[Any, np.dtype[np.int8]] = np.ndarray( + length * samples_per_fetch, dtype=np.int8 + ) + waveforms = session.channels[channels].fetch_into( + relative_to=niscope.FetchRelativeTo.READ_POINTER, + offset=0, + timeout=hightime.timedelta(seconds=5.0), + waveform=wfm, + ) + try: + print(f"Press Ctrl + C to stop") + while True: + offset = session.meas_array_offset + gain = session.meas_array_gain + for i in range(len(waveforms)): + time.sleep(0.2) + amplitude_list = [] + total_data = waveforms[i].samples.tolist() + for amplitude in total_data: + amplitude = (amplitude * 10) * gain + offset + amplitude_list.append(amplitude) + panel.set_value("Waveform", amplitude_list) + + except KeyboardInterrupt: + pass diff --git a/examples/niscope/niscope_ex_fetch_forever_panel.py b/examples/niscope/niscope_ex_fetch_forever_panel.py new file mode 100644 index 0000000..3c2d1b0 --- /dev/null +++ b/examples/niscope/niscope_ex_fetch_forever_panel.py @@ -0,0 +1,44 @@ +"""Streamlit dashboard for visualizing NI-SCOPE waveform data in real time.""" + +import streamlit as st +from streamlit_echarts import st_echarts + +import nipanel + +st.set_page_config(page_title="NI-SCOPE Example", page_icon="📈", layout="wide") +st.title("NIScope EX Fetch Forever") + +panel = nipanel.get_panel_accessor() + +waveform = panel.get_value("Waveform", [0]) + +graph = { + "animation": False, + "tooltip": {"trigger": "axis"}, + "legend": {"data": ["Amplitude (V)"]}, + "xAxis": { + "type": "category", + "data": list(range(len(waveform))), + "name": "Samples", + "nameLocation": "center", + "nameGap": 40, + }, + "yAxis": { + "type": "value", + "name": "Amplitude(V)", + "nameRotate": 90, + "nameLocation": "center", + "nameGap": 40, + }, + "series": [ + { + "name": "niscope data", + "type": "line", + "data": waveform, + "emphasis": {"focus": "series"}, + "smooth": True, + "seriesLayoutBy": "row", + }, + ], +} +st_echarts(options=graph, height="400px", width="75%", key="graph") diff --git a/pyproject.toml b/pyproject.toml index 25d10f4..ba3985c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -89,6 +89,7 @@ module = [ "streamlit_echarts.*", # https://github.com/ni/nidaqmx-python/issues/209 - Support type annotations "nidaqmx.*", + "niscope.*", ] ignore_missing_imports = true @@ -103,4 +104,4 @@ testpaths = ["src/nipanel", "tests"] [tool.pyright] include = ["examples/", "src/", "tests/"] -exclude = ["src/ni/protobuf/types/", "src/ni/pythonpanel/v1/","examples/nidaqmx/nidaqmx_continuous_analog_input.py"] \ No newline at end of file +exclude = ["src/ni/protobuf/types/", "src/ni/pythonpanel/v1/","examples/nidaqmx/nidaqmx_continuous_analog_input.py","examples/niscope/niscope_ex_fetch_forever.py"] \ No newline at end of file