diff --git a/examples/analog_out/ao_voltage_hw_timed.py b/examples/analog_out/ao_voltage_hw_timed.py deleted file mode 100644 index 8955bf2a9..000000000 --- a/examples/analog_out/ao_voltage_hw_timed.py +++ /dev/null @@ -1,25 +0,0 @@ -"""Example of AO voltage hw operation.""" - -import nidaqmx - -with nidaqmx.Task() as task: - task.ao_channels.add_ao_voltage_chan("Dev1/ao0") - - task.timing.cfg_samp_clk_timing(1000) - - print("1 Channel N Samples Write: ") - print(task.write([1.1, 2.2, 3.3, 4.4, 5.5], auto_start=True)) - task.wait_until_done() - task.stop() - - task.ao_channels.add_ao_voltage_chan("Dev1/ao1:3") - - print("N Channel N Samples Write: ") - print( - task.write( - [[1.1, 2.2, 3.3], [1.1, 2.2, 4.4], [2.2, 3.3, 4.4], [2.2, 3.3, 4.4]], - auto_start=True, - ) - ) - task.wait_until_done() - task.stop() diff --git a/examples/analog_out/ao_voltage_sw_timed.py b/examples/analog_out/ao_voltage_sw_timed.py deleted file mode 100644 index 928436aa4..000000000 --- a/examples/analog_out/ao_voltage_sw_timed.py +++ /dev/null @@ -1,24 +0,0 @@ -"""Example of AO voltage sw operation.""" - -import nidaqmx - -with nidaqmx.Task() as task: - task.ao_channels.add_ao_voltage_chan("Dev1/ao0") - - print("1 Channel 1 Sample Write: ") - print(task.write(1.0)) - task.stop() - - print("1 Channel N Samples Write: ") - print(task.write([1.1, 2.2, 3.3, 4.4, 5.5], auto_start=True)) - task.stop() - - task.ao_channels.add_ao_voltage_chan("Dev1/ao1") - - print("N Channel 1 Sample Write: ") - print(task.write([1.1, 2.2])) - task.stop() - - print("N Channel N Samples Write: ") - print(task.write([[1.1, 2.2, 3.3], [1.1, 2.2, 4.4]], auto_start=True)) - task.stop() diff --git a/examples/analog_out/cont_gen_voltage_wfm_int_clk.py b/examples/analog_out/cont_gen_voltage_wfm_int_clk.py new file mode 100644 index 000000000..61555ef6f --- /dev/null +++ b/examples/analog_out/cont_gen_voltage_wfm_int_clk.py @@ -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() diff --git a/examples/analog_out/cont_gen_voltage_wfm_int_clk_every_n_samples_event.py b/examples/analog_out/cont_gen_voltage_wfm_int_clk_every_n_samples_event.py new file mode 100644 index 000000000..01d66fc78 --- /dev/null +++ b/examples/analog_out/cont_gen_voltage_wfm_int_clk_every_n_samples_event.py @@ -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() diff --git a/examples/analog_out/cont_gen_voltage_wfm_int_clk_non_regen.py b/examples/analog_out/cont_gen_voltage_wfm_int_clk_non_regen.py new file mode 100644 index 000000000..9c0be568a --- /dev/null +++ b/examples/analog_out/cont_gen_voltage_wfm_int_clk_non_regen.py @@ -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() diff --git a/examples/analog_out/gen_voltage_wfm_int_clk.py b/examples/analog_out/gen_voltage_wfm_int_clk.py new file mode 100644 index 000000000..f823c7408 --- /dev/null +++ b/examples/analog_out/gen_voltage_wfm_int_clk.py @@ -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() diff --git a/examples/analog_out/voltage_update.py b/examples/analog_out/voltage_update.py new file mode 100644 index 000000000..169ea8e33 --- /dev/null +++ b/examples/analog_out/voltage_update.py @@ -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.")