Acquire and Analyze Noisy Clock Signals

This example shows how to acquire clock signals and analyze transitions, pulses, and compute metrics including rise time, fall time, slew rate, overshoot, undershoot, pulse width, and duty cycle. This example uses Data Acquisition Toolbox™ in conjunction with the Signal Processing Toolbox™.

Use the session-based interface in Data Acquisition Toolbox to configure the acquisition. Use the statistics and measurement functions in Signal Processing Toolbox to analyze the data signal.

Create an Acquisition Session and Acquire a Clock Signal

Use daq.createSession to create an acquisition session and add channel 0 from the National Instruments® NI-9205 with ID of 'cDAQ1Mod1'.

s = daq.createSession('ni');
addAnalogInputChannel(s,'cDAQ1Mod1', 0, 'Voltage');

By default the session is configured to run for 1000 scans/second.

Change the scan rate to 250000 scans/second, and set the duration to 2 ms.

s.Rate = 250000;
s.DurationInSeconds = 0.002;

Use startForeground to acquire multiple scans.

[data, time] = s.startForeground;
whos data time
  Name        Size            Bytes  Class     Attributes

  data      500x1              4000  double              
  time      500x1              4000  double              

The acquired data is returned in TIME-DATA pairs. TIME is an m x 1 matrix, where m is the number of scans. DATA is an m x n matrix where m is the number of scans and n is the number of analog input channels in the session.

Plot the overdamped clock signal you just acquired.

plot(time, data);
xlabel('Time (secs)'), ylabel('Voltage');

Estimate State Levels

Use statelevels with no output argument to visualize the state levels in a histogram.

ans =

    0.0138    5.1848

The computed histogram is divided into two equal sized regions between the first and last bin. The mode of each region of the histogram is returned as an estimated state level value in the command window.

Use optional input arguments to specify the number of histogram bins, histogram bounds, and the state level estimation method.

Measure Rise Time, Fall Time and Slew Rate

Use risetime with no output argument to visualize the rise time of positive edges.

ans =

   1.0e-04 *


The default reference levels for computing rise time and fall time are set at 10% and 90% of the waveform amplitude.

Measure fall time by specifying custom reference and state levels.

falltime(data,time,'PercentReferenceLevels',[20 80],'StateLevels',[0 5])
ans =

   1.0e-04 *


Obtain measurements programmatically by calling functions with one or more output arguments. For uniformly sampled data, you can provide a sample rate in place of the time vector. Use slewrate to measure the slope of each positive or negative edge.

sr = slewrate(data(1:100), s.Rate)
sr =


Analyze Overshoot and Undershoot

Change your acquisition session duration and acquire a new underdamped clock signal.

s.DurationInSeconds = 0.004;
[data, time] = s.startForeground;
plot(time, data);
xlabel('Time (secs)'), ylabel('Voltage');

Underdamped clock signals have overshoots. Overshoots are expressed as a percentage of the difference between state levels. Overshoots can occur just after an edge, at the start of the post-transition aberration region. These are called postshoot overshoots. Measure the overshoot using overshoot.

ans =


Overshoots can also occur just before an edge, at the end of the pre-transition aberration region. These are called preshoot overshoots.

Undershoots can occur in the pre and post-aberration regions and are expressed as a percentage of the difference between the state levels. Measure the undershoot with optional input arguments specifying the region to measure aberrations.

ans =


Measure Pulse Width and Duty Cycle

Use pulsewidth with no output argument to visualize highlighted pulse widths.

pulsewidth(data, time, 'Polarity', 'Positive');

This displays pulses of positive polarity. Select negative polarity to see the widths of negative polarity pulses.

Use dutycycle to compute the ratio of the pulse width to the pulse period for each positive-polarity or negative-polarity pulse. Duty cycles are expressed as a percentage of the pulse period.

d = dutycycle(data,time,'Polarity','negative')
d =


Use pulseperiod to obtain the periods of each cycle of the waveform. Use this information to compute other metrics like the average frequency of the waveform or the total observed jitter.

pp = pulseperiod(data, time);

avgFreq = 1./mean(pp)
totalJitter = std(pp)
avgFreq =


totalJitter =