Skip to content

Commit

Permalink
updated sine wave generation function with phase
Browse files Browse the repository at this point in the history
  • Loading branch information
WayneDroid committed May 27, 2024
1 parent 97d6644 commit f990e99
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 25 deletions.
43 changes: 35 additions & 8 deletions examples/analog_out/cont_gen_voltage_wfm_int_clk.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,34 +4,61 @@
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 create_sine_wave(
frequency: float, amplitude: float, sampling_rate: float, duration: float
) -> numpy.typing.NDArray[numpy.double]:
"""Generate a sine wave."""
t = np.arange(0, duration, 1 / sampling_rate)
def generate_sine_wave(
frequency: float,
amplitude: float,
sampling_rate: float,
phase_in: float,
number_of_samples: int,
) -> Tuple[numpy.typing.NDArray[numpy.double], float]:
"""Generates a sine wave with a specified phase.
Args:
frequency (float): Specifies the frequency of the sine wave.
amplitude (float): Specifies the amplitude of the sine wave.
sampling_rate (float): Specifies the sampling rate of the sine wave.
phase_in (float): Specifies the phase of the sine wave in radians.
number_of_samples (int): Specifies the number of samples to generate.
Returns:
Tuple[numpy.typing.NDArray[numpy.double], float]: 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(2 * np.pi * frequency * t)
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
phase = 0.0
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 = create_sine_wave(
frequency=10.0, amplitude=1.0, sampling_rate=actual_sampling_rate, duration=1.0
data, phase = generate_sine_wave(
frequency=10.0,
amplitude=1.0,
sampling_rate=actual_sampling_rate,
phase_in=phase,
number_of_samples=number_of_samples,
)
task.write(data)
task.start()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,27 +6,50 @@
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 create_sine_wave(
frequency: float, amplitude: float, sampling_rate: float, duration: float
) -> numpy.typing.NDArray[numpy.double]:
"""Generate a sine wave."""
t = np.arange(0, duration, 1 / sampling_rate)
def generate_sine_wave(
frequency: float,
amplitude: float,
sampling_rate: float,
phase_in: float,
number_of_samples: int,
) -> Tuple[numpy.typing.NDArray[numpy.double], float]:
"""Generates a sine wave with a specified phase.
Args:
frequency (float): Specifies the frequency of the sine wave.
amplitude (float): Specifies the amplitude of the sine wave.
sampling_rate (float): Specifies the sampling rate of the sine wave.
phase_in (float): Specifies the phase of the sine wave in radians.
number_of_samples (int): Specifies the number of samples to generate.
Returns:
Tuple[numpy.typing.NDArray[numpy.double], float]: 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(2 * np.pi * frequency * t)
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
phase = 0.0

def callback(task_handle, every_n_samples_event_type, number_of_samples, callback_data):
"""Callback function for Transferred N samples."""
Expand All @@ -43,8 +66,12 @@ def callback(task_handle, every_n_samples_event_type, number_of_samples, callbac
actual_sampling_rate = task.timing.samp_clk_rate
print(f"Actual sampling rate: {actual_sampling_rate:g} S/s")

data = create_sine_wave(
frequency=10.0, amplitude=1.0, sampling_rate=sampling_rate, duration=1.0
data, phase = generate_sine_wave(
frequency=10.0,
amplitude=1.0,
sampling_rate=actual_sampling_rate,
phase_in=phase,
number_of_samples=number_of_samples,
)
task.write(data)
task.start()
Expand Down
15 changes: 6 additions & 9 deletions examples/analog_out/cont_gen_voltage_wfm_int_clk_non_regen.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
from nidaqmx.constants import AcquisitionType, RegenerationMode


def create_sine_wave_with_phase(
def generate_sine_wave(
frequency: float,
amplitude: float,
sampling_rate: float,
Expand All @@ -42,9 +42,9 @@ def create_sine_wave_with_phase(
containing the generated data and the phase of the sine wave after generation.
"""
duration_time = number_of_samples / sampling_rate
duration_radians = (duration_time / frequency) * 2 * np.pi
duration_radians = duration_time * 2 * np.pi
phase_out = (phase_in + duration_radians) % (2 * np.pi)
t = np.linspace(phase_in, phase_out, number_of_samples)
t = np.linspace(phase_in, phase_in + duration_radians, number_of_samples, endpoint=False)

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

Expand Down Expand Up @@ -77,23 +77,20 @@ def main():
print(f"Actual sampling rate: {actual_sampling_rate:g} S/s")

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

phase_in = phase_out
except KeyboardInterrupt:
pass
finally:
Expand Down

0 comments on commit f990e99

Please sign in to comment.