http://www.dattalo.com/technical/theory/sqwave.html Theoretical stuff on how harmonics may be suppressed in a stream of pulses. Referring to the section: 011 Harmonic Content of a Periodic Pulse Train from that page, Scott Dattalo says,

If you don't feel like wading through the gory details, here's the conclusion reached:
   +-------------------------------------+
   |  0 = (-m1 + m2 + (M/2)*n) % (M/n)   |
   +-------------------------------------+

If you have a periodic pulse stream of period T, then M is the number of possible positions at which a pulse may appear. Each pulse is the same width, T/M. 'm1' and 'm2' are two integers between 0 and M-1 describing the positions of two pulses. Finally, n is the harmonic number that is suppressed.

There are are two conditions that need to be satisfied before this equation can be used:

a)   0 = M % 2
b)   0 = (M/2) % n

The first says that M must be even. The second says that the n'th harmonic must evenly divide half of M.

The example on the web page is for M = 12. For M=12, it's only possible to simultaneously suppress the 2nd and 3rd harmonic. If you want to suppress the 4th harmonic, then M has to be increased to 24. I haven't analyzed the requirements beyond n=5. However, the other day I claimed that M had to be on the order of n! to suppress the 2nd through n'th harmonic. That doesn't appear to be true. A casual examination for the 6th harmonic shows that it's possible to satisfy the equation for M=120. However, I don't if it's possible to cancel the 2nd through 6th harmonics with M=120. In other words, the equation is known to be necessary, but I don't know if it's sufficient.

[ed: and previously]

It finally dawned on me yesterday how magic sine waves can be sythesized. What's frustrating, is that the answer is so simple that it's obvious; so obvious that it's been overlooked in the discussions we had off and on for the last couple of years (at least by me). Lancaster is probably a chuckling lurker :). [Don Lancaster's Magic Sin Waves]

There are probably a few ways to go about it, but this is the one I tried. Imagine how you'd go about synthesizing a sine wave if you had an A/D converter. The most common way is to produce `N' samples for one sine wave cycle and repeatedly write these to an A/D converter. The sine wave frequency is determined by the rate at which the samples are written to the A/D converter.

Now imagine replacing the A/D converter with a PWM generator that has the same resolution. So for example, if you had a 12-bit A/D converter the PWM generator would be capable of producing 4095 (2^12 - 1) different duty cycles. Theoretically, the low-pass filtered output of the A/D converter and the PWM are the same. Practically however, it's difficult to design a filter that would have the proper cut-off characteristics. So to ease the filter requirements, the PWM synthesized sine wave is usually made to be a much higher frequency than the frequency at which samples are written to the A/D converter.

Now when we, or at least I, begin to think about `magic sine waves' the idea that the pwm frequency can be reduced is forgotten. Furthermore, we constrain ourselves to the low-resolution 8 or 10 bit pwm generators that are available in the various pic's. What the magic sine wave algorithm does, AFAICT, is find a suitable time discretization for a high resolution PWM synthesized sine wave.

So, there are two parts to the synthesis. Part 1 invovles finding the high resolution PWM representation of the sine wave. Part 2 involves finding an optimum way to make time discrete. The first part is easy and the attached octave (or matlab) program will do this. The second part can be determined using brute force search techniques. I don't have an elegant solution though, but hopefully some others have some insight.

PS, this octave program is meant to be tool and otherwise not too useful (in other words, I don't bother to explain hardly anything...)

% `magic'sine wave synthesis
%   The purpose of this program is to find an optimum pulse stream
% that when low pass filtered will produce a sine wave. The optimization
% criterion is to minimize the harmonics for a given number of pulses.


% by  T. Scott Dattalo 04MAR00
clear;
clg;
pulses = 32;

T = 1;              % Period
f = 1/T;            % fundamental frequency

tp = T/pulses;      % Time window for each pulse

t = [0:(pulses-1)]/pulses;
sine_samples = sin(2*pi*f * t);

ts = zeros(1,4*(pulses-1));
p = ts;

% create a pwm sine wave with edges based on floating point
% numbers:

for i=1:pulses

  ts(4*i) = t(i);
  ts(4*i+1) = t(i);
  ts(4*i+2) = t(i) + (1 + sine_samples(i))/2 * tp + 1000*eps;
  ts(4*i+3) = ts(4*i+2);
  p(4*i+0) = 0;
  p(4*i+1) = 1;
  p(4*i+2) = 1;
  p(4*i+3) = 0;

end

% Now calculate the harmonic content
harmonics = 20*pulses;
mag = zeros(1:harmonics);
ph  = zeros(1:harmonics);
phase = [0:(pulses-1)] * T/(pulses);
N = 1000;                 %Number of samples
sqwave = zeros(1:N);
u = [1:N]/N * T;          %Time vector

for n=1:harmonics
  w = n*2*pi/T;

  m=2;
  for m=1:(pulses)
    tau = (1 + sine_samples(m))/2*tp;
    d = tau/T;
    sqwave = sqwave + 2*sin(n*pi*d)/(n*pi)*cos(w*(u-tau/2-phase(m)));
    mag(n) = mag(n) + 2*sin(n*pi*d)/(n*pi)*cos(w*phase(m));
    ph(n) = ph(n) + cos(w*phase(m));
  end

end

sqwave = sqwave + 0.5 + 2;
dc = sum(sine_samples);
mag(2) = 0;
ti = sprintf('PWM Synthesis');
title(ti)
subplot(111)
%plot(t,sine_samples)
%subplot(212)
% plot the harmonics:
plot([0:harmonics-1]/pulses,abs(mag))
% uncomment to plot the square wave train re-synthesized from its
% harmonics
%plot(ts,p,u,sqwave)

If you had a square wave with a 50% duty cycle, there are no even harmonics. Furthermore, the relative magnitude of the harmonics are inversely proportional to their harmonic numbers. If you vary the duty cycle to say 33%, you'll have no 3rd,6th, 9th harmonic, but some of the evens will pop up. I don't think there's a way to arbitrarily kill the odd harmonics. But you can do (at least) two things: vary the pulse width of individual pulses and vary the number of pulses. The plot:

http://www.dattalo.com/ms1.gif

cancels the 2nd and 3rd harmonics. You could say that it consists of three pulses; one twice as wide as the other. (But the program generating it had 4 bits for those 3 pulses...).

I don't have time right now to explain, but as I mentioned earlier, it's possible to exactly cancel the first N harmonics. However, the number of 'time slots' or quantized positions at which the pulse edges may occur is of the order of N! (factorial). There is technique that involves examining the phases of the harmonics of the individual pulses. I found that pulses can be collected into groups that totally cancel one another at a given harmonic number. The smallest group I experimented with is just a pair. For example, for the second harmonic, the pulses are grouped in pairs. One pulse is 180 degrees out of phase with the other. The pairs for the second harmonic are two pulses separated by one pulse. For the third harmonic, the pulses are separated by two pulses.

2nd harmonic suppressed:
010100000000
000010100000

3rd harmonic suppressed:
010010000000
000100100000

Total pulse stream:
010110100000

So the objective is to discover the pairs that cancel at a given harmonic and then to find a set of pulses that will have complete coverage for each harmonic. I've done this for 24 pulses, but beyond that it gets pretty hairy...

See also:

Comments: