Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add and update AO examples #570

Merged
merged 13 commits into from
May 31, 2024
25 changes: 0 additions & 25 deletions examples/analog_out/ao_voltage_hw_timed.py

This file was deleted.

24 changes: 0 additions & 24 deletions examples/analog_out/ao_voltage_sw_timed.py

This file was deleted.

70 changes: 70 additions & 0 deletions examples/analog_out/cont_gen_voltage_wfm_int_clk.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
"""Example of analog output voltage generation.

This example demonstrates how to output a continuous periodic
waveform using an internal sample clock.
"""

from typing import Tuple

import numpy as np
import numpy.typing

import nidaqmx
from nidaqmx.constants import AcquisitionType


def generate_sine_wave(
frequency: float,
amplitude: float,
sampling_rate: float,
number_of_samples: int,
phase_in: float = 0.0,
) -> Tuple[numpy.typing.NDArray[numpy.double], float]:
"""Generates a sine wave with a specified phase.

Args:
frequency: Specifies the frequency of the sine wave.
amplitude: Specifies the amplitude of the sine wave.
sampling_rate: Specifies the sampling rate of the sine wave.
number_of_samples: Specifies the number of samples to generate.
phase_in: Specifies the phase of the sine wave in radians.

Returns:
Indicates a tuple containing the generated data and the phase
of the sine wave after generation.
"""
duration_time = number_of_samples / sampling_rate
duration_radians = duration_time * 2 * np.pi
phase_out = (phase_in + duration_radians) % (2 * np.pi)
t = np.linspace(phase_in, phase_in + duration_radians, number_of_samples, endpoint=False)

return (amplitude * np.sin(frequency * t), phase_out)


def main():
"""Continuously generates a sine wave."""
with nidaqmx.Task() as task:
sampling_rate = 1000.0
number_of_samples = 1000
task.ao_channels.add_ao_voltage_chan("Dev1/ao0")
task.timing.cfg_samp_clk_timing(sampling_rate, sample_mode=AcquisitionType.CONTINUOUS)

actual_sampling_rate = task.timing.samp_clk_rate
print(f"Actual sampling rate: {actual_sampling_rate:g} S/s")

data, _ = generate_sine_wave(
frequency=10.0,
amplitude=1.0,
sampling_rate=actual_sampling_rate,
number_of_samples=number_of_samples,
)
task.write(data)
task.start()

input("Generating voltage continuously. Press Enter to stop.\n")

task.stop()


if __name__ == "__main__":
main()
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
"""Example of analog output voltage generation with events.

This example demonstrates how to use a Every N Samples events to output a
continuous periodic waveform to an Analog Output Channel
using an internal sample clock. The Every N Samples events indicate when
the specified number of samples generation is complete.
"""

from typing import Tuple

import numpy as np
import numpy.typing

import nidaqmx
from nidaqmx.constants import AcquisitionType


def generate_sine_wave(
frequency: float,
amplitude: float,
sampling_rate: float,
number_of_samples: int,
phase_in: float = 0.0,
) -> Tuple[numpy.typing.NDArray[numpy.double], float]:
"""Generates a sine wave with a specified phase.

Args:
frequency: Specifies the frequency of the sine wave.
amplitude: Specifies the amplitude of the sine wave.
sampling_rate: Specifies the sampling rate of the sine wave.
number_of_samples: Specifies the number of samples to generate.
phase_in: Specifies the phase of the sine wave in radians.

Returns:
Indicates a tuple containing the generated data and the phase
of the sine wave after generation.
"""
duration_time = number_of_samples / sampling_rate
duration_radians = duration_time * 2 * np.pi
phase_out = (phase_in + duration_radians) % (2 * np.pi)
t = np.linspace(phase_in, phase_in + duration_radians, number_of_samples, endpoint=False)

return (amplitude * np.sin(frequency * t), phase_out)


def main():
"""Continuously generates a sine wave using an Every N Samples event."""
total_write = 0
with nidaqmx.Task() as task:
sampling_rate = 1000.0
number_of_samples = 1000

def callback(task_handle, every_n_samples_event_type, number_of_samples, callback_data):
"""Callback function for Transferred N samples."""
nonlocal total_write
total_write += number_of_samples
print(f"Transferred data: {number_of_samples} samples. Total {total_write}.", end="\r")

return 0

task.ao_channels.add_ao_voltage_chan("Dev1/ao0")
task.timing.cfg_samp_clk_timing(sampling_rate, sample_mode=AcquisitionType.CONTINUOUS)
task.register_every_n_samples_transferred_from_buffer_event(1000, callback)

actual_sampling_rate = task.timing.samp_clk_rate
print(f"Actual sampling rate: {actual_sampling_rate:g} S/s")

data, _ = generate_sine_wave(
frequency=10.0,
amplitude=1.0,
sampling_rate=actual_sampling_rate,
number_of_samples=number_of_samples,
)
task.write(data)
task.start()

input("Generating voltage continuously. Press Enter to stop.\n")

task.stop()
print(f"\nTransferred {total_write} total samples.")


if __name__ == "__main__":
main()
101 changes: 101 additions & 0 deletions examples/analog_out/cont_gen_voltage_wfm_int_clk_non_regen.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
"""Example of analog output voltage generation.

This example demonstrates how to continuously generate an
analog output waveform by providing new data to the output buffer
as the task is running.

This example is useful if you want to generate a non-repeating waveform,
make updates on-the-fly, or generate a frequency that is not an
even divide-down of your sample clock. In this example,
the default frequency value is 17.0 to demonstrate that non-regenerative output
can be used to create a signal with a frequency that is not an even divide-down
of your sample clock.
"""

from typing import Tuple

import numpy as np
import numpy.typing

import nidaqmx
from nidaqmx.constants import AcquisitionType, RegenerationMode


def generate_sine_wave(
frequency: float,
amplitude: float,
sampling_rate: float,
number_of_samples: int,
phase_in: float = 0.0,
) -> Tuple[numpy.typing.NDArray[numpy.double], float]:
"""Generates a sine wave with a specified phase.

Args:
frequency: Specifies the frequency of the sine wave.
amplitude: Specifies the amplitude of the sine wave.
sampling_rate: Specifies the sampling rate of the sine wave.
number_of_samples: Specifies the number of samples to generate.
phase_in: Specifies the phase of the sine wave in radians.

Returns:
Indicates a tuple containing the generated data and the phase
of the sine wave after generation.
"""
duration_time = number_of_samples / sampling_rate
duration_radians = duration_time * 2 * np.pi
phase_out = (phase_in + duration_radians) % (2 * np.pi)
t = np.linspace(phase_in, phase_in + duration_radians, number_of_samples, endpoint=False)

return (amplitude * np.sin(frequency * t), phase_out)


def main():
"""Generate a continuous voltage waveform using an analog output channel of a NI-DAQmx device.

This function sets up a task to generate a continuous voltage waveform using the specified
analog output channel of a NI-DAQmx device. It configures the sampling rate, number of samples,
and regeneration mode of the task. It then enters a loop where it continuously generates a
sine wave with a specified frequency, amplitude, and phase, and writes the waveform to the
analog output channel.
The loop continues until the user interrupts the program by pressing Ctrl+C.

Args:
None

Returns:
None
"""
with nidaqmx.Task() as task:
is_first_run = True
sampling_rate = 1000.0
number_of_samples = 1000
task.ao_channels.add_ao_voltage_chan("Dev1/ao0")
task.out_stream.regen_mode = RegenerationMode.DONT_ALLOW_REGENERATION
task.timing.cfg_samp_clk_timing(sampling_rate, sample_mode=AcquisitionType.CONTINUOUS)

actual_sampling_rate = task.timing.samp_clk_rate
print(f"Actual sampling rate: {actual_sampling_rate:g} S/s")

try:
phase = 0.0
print("Generating voltage continuously. Press Ctrl+C to stop.")
while True:
data, phase = generate_sine_wave(
frequency=17.0,
amplitude=1.0,
sampling_rate=actual_sampling_rate,
number_of_samples=number_of_samples,
phase_in=phase,
)
task.write(data)
if is_first_run:
is_first_run = False
task.start()
except KeyboardInterrupt:
pass
finally:
task.stop()


if __name__ == "__main__":
main()
23 changes: 23 additions & 0 deletions examples/analog_out/gen_voltage_wfm_int_clk.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
"""Example of analog output voltage generation.

This example demonstrates how to output a finite number of
voltage samples to an Analog Output Channel using an internal
sample clock.
"""

import nidaqmx
from nidaqmx.constants import AcquisitionType

with nidaqmx.Task() as task:
data = []
total_samples = 1000
task.ao_channels.add_ao_voltage_chan("Dev1/ao0")
task.timing.cfg_samp_clk_timing(
1000.0, sample_mode=AcquisitionType.FINITE, samps_per_chan=total_samples
)

data = [5.0 * i / total_samples for i in range(total_samples)]
number_of_samples_written = task.write(data, auto_start=True)
print(f"Generating {number_of_samples_written} voltage samples.")
task.wait_until_done()
task.stop()
13 changes: 13 additions & 0 deletions examples/analog_out/voltage_update.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
"""Example of analog output voltage generation.

This example demonstrates how to output a single Voltage Update
(Sample) to an Analog Output Channel.
"""

import nidaqmx

with nidaqmx.Task() as task:
task.ao_channels.add_ao_voltage_chan("Dev1/ao0")

number_of_samples_written = task.write(1.1)
print(f"Generated {number_of_samples_written} voltage sample.")
Loading