Dick Cappels' project pages http://www.projects.cappels.org

return to HOME

Minimum Mass Waveform Capture
Capturing repetitive waveforms at 1 million samples per second using PWM and a comparator.
Described are the waveform capture method, example firmware and hardware designs. This material formed the basis of an article that was first published in the October, 2003 issue of Circuit Cellar magazine.

The only components added to the operating Atmel AT90S2313 circuit
(one capacitor and two resistors) to allow  waveform sampling with < 1 microsecond
resolution at 1 volt full scale, are inside the black outline.

Download AVR Studio Source wfcao 030326 .asm

The impetus for developing this technique came from my own need to capture repetitive waveforms using the least expensive and lowest part-count means possible. I wanted to be able to view the waveforms on either a liquid crystal display dedicated to the purpose or upload the waveform to a computer to manipulation on a spreadsheet.

The approaches using on-chip A-to-D converters on AVR, PIC, and Cypress controllers reached sample rates of up to about 60 kHz. Not really very useful for the sort of thing I was thinking about using this for: encoded data, radio control signals, A-to-D converter waveforms, checking the dynamic range of amplifiers and capturing audio waveforms for filtering and power calculations. I realized that the comparators in AVR devices were pretty fast with a response time of several hundred nanoseconds, and that the PWM (pulse width modulation) circuit could be made fairly responsive. If there was just some way to combine these to sample analog values quickly...

Eventually it became apparent that repetitive sampling was the only way to get high enough voltage and temporal sampling resolution using these on-chip components. Rather trying to sample and digitize the waveform as is comes in, this method finds out a little bit about the waveform using the relatively high speed comparator every time the waveform is repeated, building up a more and more detailed picture with each repetition by changing the relatively low speed PWM voltage each time.


It's all in the timing. Firmware timing loops set the interval between
samples in a burst of waveform samplings that starts with a trigger signal.
The Green dots represent voltage levels of the sampled signal at the time of sampling.

To capture a waveform, the Pulse Width Modulation D-to-A converter (PWM DAC) is set to its maximum output voltage. Then, using timing loops, the microcontroller looks at the voltage comparator output to determine whether the incoming voltage is higher than the PWM voltage at regularly spaced sampling times (1 microsecond in the illustration).

At each sampling time, if the incoming waveform is at a higher voltage than the PWM voltage, the PWM voltage is stored in a RAM array location corresponding to that sampling time relative to the start of the waveform. After all of the sample times have been tested against the PWM voltage , the PWM voltage is decrement and all of the sample times are compared with the PWM voltage again. This is repeated until the PWM voltage has been reduced to its minimum value, and each scan of the sample times starts by a trigger signal that is derived or in some way related to the incoming waveform.

The finer the voltage resolution, the longer the waveform capture takes. As my initial use of this is with an LCD display with 64 rows, the waveform capture circuit senses 64 different levels. To capture 100 points at 64 different levels, the total capture time is:

Capture time = 100 x [sample interval] x 64 (+ 64 X ([ trigger latency]) + 68 ms ,

where is " trigger latency" is the average time the controller waits for the trigger edge after the last sample, and the 68 milliseconds comes from 1 millisecond settling time of the PWM circuit after each step, plus 5 milliseconds for initial settling.

When capturing waveforms with long periods, the total time needed to capture the waveform is dominated by the time it takes the waveform to make the requisite number of repetitions. For shorter periods, the total time is dominated by the settling times for the PWM. For example, for the example design to capture a waveform with 64 level resolution over a 100 microsecond interval, sampling at 1 microsecond intervals, it takes a little over 72 milliseconds. To capture a 1 second waveform at the same resolution, it takes a little over a minute.

The preceding suggests that the higher the sampling rate, the greater the possible reduction in sampling time by speeding up the DAC. A resistor network connected to some port pins could suffice for low resolution (6 bit) waveform capture. An integrated circuit DAC would probably be much better for higher resolution measurements.

  The symbolic illustration above helps visualize the waveform capture method.
The delay is implemented by firmware timing loops,
and the latch and gate are also functions of firmware.

The quality of the trigger signal is very important. The trigger signal must consistently appear at the same time with respect to the captured signal otherwise sever distortion will result . This means that a noisy trigger signal directly derived from the incoming waveform will give poor results . You'll get the best results with a digital trigger signal taken directly from the source of the signal if such a trigger source is available.

Unsynchronized signals, such as noise will not be represented accurately and be underrepresented in the captured waveform. This quality, which results from synchronous sampling, is sometimes a good thing in that it can effectively pull a signal out of the noise, an important property in applications such as ultra wideband and spread spectrum signal decoding.

Another aspect of sampled data systems, it susceptibility to aliasing. Aliasing is a phenomenon in which a signal appears to occur at a frequency other than that at which it actually occurs. For example, when a 250 kHz square wave is views with a 1 microsecond sampling interval it shows up as properly as two high samples followed by two low samples, but when captured at a 100 microsecond sampling interval, it appears as 625 Hz signal, or 1/400 the actual frequency. The way to prevent aliasing is to insert an analog filter in the signal path before the sampling point, in this case the comparator's input.

In the example circuit discussed here, the AT90S2313 samples the signal at 1 megasample per second. The on-chip comparator has a propagation delay of 500ns to 700 ns, providing inherent filtering for components of signals above about 800 kHz, thus restricting the range of frequencies that can be aliased from above the sampling rate down into those below the sampling rate. To reduce aliasing of signal components lower in frequency than the sampling rate, an additional external would need to be used.

An Implementation


With a bare minimum of parts, this circuit is the same basic configuration used
for successive approximation A-to-D conversion, only the firmware is different.

This circuit includes a resistive divider to reduce the full scale voltage from the PWM output (PIN 15) to 1 volt, thus making it 1 volt full scale. In some applications, one might want to replace the 39k resistor with a fixed resistor in series with a variable resistor so that the full scale voltage can be adjusted for calibration.

An even simpler implementation would eliminate the 39K resistor and only write PWM values up to a maximum of 6 bits, but that would result in a slight reduction in noise immuity. Using a voltage divider gives a slightly improved immunity to noise in that ripple on the power supply pin of the AT90S2313 is divided by the divider ratio. This is important for ripple voltage fequency components well below the PWM frequency because at higher frequencies the PWM low pass filter would attenuate the ripple voltage sufficently.

If the 39k resistor was elimiated to increase the full scale voltage to 5 volts, note that this results in the equivalent resistance of the PWM low pass filter increasing by a factor of five (160k/31k), and this means that the capacitor should be reduced to .0068 uf so that the PWM voltage will settle in the expected time yet filter the 20 kHz PWM signal such that the ripple will be less than 1/2 lsb.

More About the Firmware

When capturing a waveform, the PWM circuit generates the maximum output voltage (here, corresponding to a decimal value of 63) and samples all time intervals starting from a trigger signal, taking care to keep the time between samples constant. Whenever a voltage at a sampled time exceeds the PWM voltage, the PWM voltage is stored in the RAM array location corresponding to that sample. In this way, the peak sampled at each time is stored in the RAM array.
The code below is the heart of the waveform capture firmware.

nextydelay:                  ;When not storing, branch here.
    inc     YL              ;Inc YL and see if array boundary has been exceeded.
    cpi     YL,arrayend+1
    breq    decpwm          ;If at end of RAM array, decrement PWM value
    nop                      Equalize time between samples for pwmval saved and not saved.
    ijmp                  ;Indirect jump to delay routine
    rjmp    nextydelay         
    st       Y+,pwmval      ;Store and inc YL and see if array boundary has been exceeded.
    cpi     YL,arrayend+1
    breq    deccpwm        ;If end of RAM array, decrement the PWM value
    rjmp    nexty         

The sampling loop, shown above, is the essence of the method. It requires 10 cycles per sample. Two clock cycles are taken up by the "ijmp" indirect jump instruction, which either jumps to the next byte or to a delay routine that returns to the next byte. Elimination of the ijmp (indirect jump) instruction would decrease the sampling interval to 8 cycles. Straight line coding, which would be quite a chore to write, take a lot of program memory, and be inflexible, could reduce the sampling interval to as little as 3 cycles (for a 5.333 million sample per second rate with a 16 Mhz clock) if storing the waveform in RAM, or just two 2 cycles (for a 8 million sample per second rate with a 16 MHz clock) if storing in registers, though only using registers would allow a very small number of samples before having to dump the contents.

After the actual waveform capture is completed, any RAM array locations with the value $FF remaining can be assumed to be above full scale, and treated accordingly. In the sample application, that of an waveform capture and display system, values of $FF and $00 are not transmitted, and if the count of either $FF or $00 exceeds some preset limit, out of range indicators for the signal being too high or two low are set in the LCD display.

Prior to the sampling loop being called, the program sits in a wait loop, waiting for a low-to-high or high-to-low transistion on the trigger input. Once the triggering event is detected, the sampling loop is called, and then decrements the PWM value, waits for the PWM low pass filter value to settle and then returns to wait for the next triggering event. This process continues until the lowest possible PWM value is tested.

Continued on the NEXT PAGE.

 Use of information presented on this page is for personal, nonprofit educational and noncommercial use only. This material (including object files) is copyrighted by Richard Cappels and may not be republished or used directly for commercial purposes without explicit authorization from Richard Cappels. For commercial license, click HERE.


Please see the liability disclaimer on the HOME page.
Contents ©2003 Richard Cappels All Rights Reserved. http://www.projects.cappels.org/
Dick Cappel's web version firstt posted in November, 2003