Setting the Duty Cycle of a Counter Output Using NI-DAQmx for Python

Updated Dec 1, 2020

A Pulse Width Modulation (PWM) signal is a technique for generating digital pulses to control an analog circuit. This article will go through the steps to create a counter output and set or change the duty cycle of the square wave while the task is running using the Python NI-DAQmx API. You will need to have the NI-DAQmx driver and support for Python API installed.

You can configure the frequency and duty cycle of a counter output task by using the counter writer class which is part of the stream writers. The counter writer is going to write samples to a counter output channel in the DAQ-mx task. One way to do it is using the write_one_sample_pulse_frequency method. To do this, follow these steps while writing your script:
 
  • Import the following classes:
    import nidaqmx
    from nidaqmx.stream_writers import CounterWriter
    from nidaqmx.constants import *

  • Create your task and add a counter output channels to it. 
    with nidaqmx.Task() as task: 
        task.co_channels.add_co_pulse_chan_time(counter = "cDAQ1Mod1/ctr1")

  • Set the acquisition mode:
    task.timing.cfg_implicit_timing(sample_mode=AcquisitionType.CONTINUOUS)

  • Set the counter writer and start the task:
    cw = CounterWriter(task.out_stream, True)
    task.start()

  • Set the duty cycle and frequency:
    cw.write_one_sample_pulse_frequency(100, 0.1, 10)

The parameters for this method are the following:
  • frequency (float) – Specifies at what frequency to generate pulses.
  • duty_cycle (float) – Specifies the width of the pulse divided by the pulse period. NI-DAQmx uses this ratio combined with frequency to determine pulse width and the interval between pulses.
  • auto_start (Optional[bool]) – Specifies if this method automatically starts the task if you did not explicitly start it with the DAQmx Start Task method. 
  • timeout (Optional[float]) – Specifies the amount of time in seconds to wait for the method to write all samples. NI-DAQmx performs a timeout check only if the method must wait before it writes data. This method returns an error if the time elapses. The default timeout is 10 seconds. If you set timeout to nidaqmx.constants.WAIT_INFINITELY, the method waits indefinitely. If you set timeout to 0, the method tries once to write the submitted samples. If the method could not write all the submitted samples, it returns an error and the number of samples successfully written.

The resulting code should be similar to this:
 
import nidaqmx
from nidaqmx.stream_writers import CounterWriter
from nidaqmx.constants import *

with nidaqmx.Task() as task:
    task.co_channels.add_co_pulse_chan_time(counter = "cDAQ1Mod1/ctr1")
    task.timing.cfg_implicit_timing(sample_mode=AcquisitionType.CONTINUOUS)
    cw = CounterWriter(task.out_stream, True)
    task.start()
    cw.write_one_sample_pulse_frequency(100, 0.1, 10)