PWM is a very powerful technique to simulate an analog output from a microcontroller, programmable logic or any other digital environment. This can be used to drive LEDs, motors and speakers, etc... without the need of an external DAC component (in some cases a low-pass filter is necessary).

A PWM is typically made by using a counter and a comparator. The counter constantly counts and rolls up, and when it is above a threshold value (the desired % of output voltage), then a '1' logic is send, when below a '0' logic is send.

The main problem of PWM is that there is a tradeoff between precision and frequency: If one more bit is needed for precision, it means that the counter will take twice as long before it rolls again, and as such the parasite frequencies that will have to be filtered off are lower in the spectrum, thus closer to the signal and harder to filter.

For these reasons, PWM is inapplicable for signals that should either

  1. Have high analogue frequencies
  2. Needs too many bits in the DAC

My idea is simple, instead of using a N bit counter, I use a random number generator, made by taking the high (or low ?) N bits of a M bit LFSR (for example, use the lowest 8 bits of a 16 bit LFSR). That way, instead of outputting a square wave with a variable pulse width, we output a steam of random pulses.

The probability that a pulse is '1' is equal to the ratio between the desired output voltage, and the maximum output voltage. As such, the result is exactly the same as PWM, exept that the parasite frequencies are now random, and such are much easier to filter. It is now possible to add as many bits as necessary for the ADC, and this won't cause any problems.

For example, it becomes possible and actually very simple to have 16-bit Audio output with a 1MHz clock. With traditional PWM this would never has been possible: Only a 5-bit audio signal would have been possible without either a hearable audio fuzz.

Will this work? Since this idea is so simple and improves the PWM technique so much, why is it not mentioned in anywhere?

  • 2
    \$\begingroup\$ "Random frequencies" won't be easier to filter. They will be harder. With PWM, you know the frequency beforehand and can build your low pass filter appropriately. With your random modulation, some of the randomness will land in the range of frequencies you are trying to generate - you will not be able to remove those. \$\endgroup\$ – JRE Mar 18 '16 at 11:04
  • \$\begingroup\$ The point is that there will be some white noise in all frequencies, instead of being strong parasites at some frequencies. In the case of audio at least, it will probably sound "nicer". \$\endgroup\$ – Bregalad Mar 18 '16 at 11:06
  • \$\begingroup\$ I'd be interested, though, in the results if you were to try simulating it. Maybe it has some use in special cases - and maybe there's something I've overseen that would make it useful in the general case. Probably not generally useful, though, else someone else would have done it already. There's a lot of smart people out there, and surely someone would be doing this if it presented some advantage. \$\endgroup\$ – JRE Mar 18 '16 at 11:07
  • \$\begingroup\$ Do you really want white noise in your audio? That's like static on an FM radio. \$\endgroup\$ – JRE Mar 18 '16 at 11:08
  • 1
    \$\begingroup\$ Assuming true white noise, then the random modulation will include frequencies evenly distributed from nearly zero up to your sampling rate. 44100Hz/1MHz is 4.41 percent or about -14dB. Changing to 22050 improves that by 3dB to -17dB. \$\endgroup\$ – JRE Mar 18 '16 at 11:32

I thought I'd sum up my comments in an answer - maybe it'll be of some use to somebody.

  1. Using white noise will make it harder to remove the modulation signal rather than easier. In the case of a normal PWM signal, you need a low pass and you are done. When using white noise to do the modulation you will cause noise in the same frequency range as the signal you are trying to create. This cannot easily be removed.
  2. The noise left in your generated signal will be about 14dB below the level of the white noise that you used as a modulator signal. Assuming true white noise up to 1MHz as in your example, then the amount of noise left is a simple proportion. 44100Hz/1MHz gives 4.41 percent or about -14dB.
  3. I verified my estimate above by generating a white noise signal with a 1MHz sampling rate then filtering and resampling down to 44100Hz. The resulting signal was indeed 14dB below the original white noise signal.
  4. Interestingly enough, 14dB is also about the dynamic range of the 5Bit sampling at 1MHz mentioned in the question. So, you don't really gain anything in the signal to noise department. You trade scratchy 5Bit quantized audio that is at least quiet when there's no signal to get a signal that is quantized at a much higher bit depth but has a constant white noise at -14dB - even when there's no actual signal present.

So, the idea does and doesn't work.

As you expected, you can use noise modulation to get a better bit depth and have less quantization error by spreading the modulation signal over the entire bandwidth.

That comes at the cost of not being able to remove the modulation noise from the generated output signal so that you end up with the same signal to noise ratio.

All you've done is to change the cause of the poor signal to noise ratio.

  • \$\begingroup\$ I still believe the ratio should be about -17 dB since it would be filtered out after 20'000 Hz, but in any case it's still way too much noise to be acceptable. \$\endgroup\$ – Bregalad Mar 18 '16 at 22:06

An improvement certainly. But it does not improve it to the point where there are no signals at a frequency of f_clock/resolution, they are still present, reduced by the first order of the frequency ratio. If the small improvement is adequate for your application, then go for it. For typical audio application, the improvement would not be enough, neither would it be for generating DC calibration signals for instance.

You can achieve better suppression of f_clock/resolution frequencies by one of two techniques.

Noise-shaped sigma delta fractional N. There is much published matierial on this subject, much of it fairly opaque. I'm not going to do a literature review here. In this method there are still signals at fclk/resolution, but they are suppressed by the nth order of the ratio for an nth order modulator.

Chinese remainder theorem synthesis. This uses two (or more) conventional PWMs in parallel, each with a shorter accumulator. The two counters are of the form MN and MP, where M, N, and P are mutually prime, and M is a few more than the number of PWMs, say 5 for two PWMs. If N=63 and P=64, then the lowest repetition rate is 1/320th of fclock (1/5x64), but the resolution that can be achieved is 1/16128 (the 63 and 64 work together to create 1/4032ths, and there's an addition 1/4 from 1/(M-1)). In this method, there are truly no signals at fclk/resolution. The method is limited for monotonicity by the degree of analogue balance that can be obtained, but this equality should be easier to achieve than the ratio between a most significant and least significant PWM, if you tried to combine two that way. Why is it called Chinese Remainder Theorem Synthesis? That's what you use to determine the numbers to load into your PWMs, given the output fraction that needs to be achieved.


The problem is that you will still have low frequencies in the output. Even worse, there is no lower bound on the frequency content even if the intended signal is steady. At least with PWM you know all the noise will be at the PWM frequency and its harmonics.

You are essentially trading off noise at known frequencies with broad spectrum noise. In some cases that might be a desirable tradeoff. In other cases this is worse because now you can't separate noise from signal by frequency anymore.

Another common idea along this line is to use a DIV engine or something like a Bresenham algorithm. You track the accumulated error and make the output go high when the error is negative and low when the error is positive.

You can then play with different strategies of how each output slice is accumulated over time into the error. If it is just added without decay, then you have a pure DIV engine or Bresenham algorithm. This can produce infinitely low frequencies, but the long term average is within ± one slice high or low. With different decays, you can cause it to emit less lower frequencies at the expense of long term accuracy.

However, in no case do these methods have a higher guaranteed bound on the noise frequency than PWM has at the same slice frequency and ultimate resulting accuracy.

  • \$\begingroup\$ Actually the lower bound of the frequency is generated by the fact that the LFSR noise generator will eventually loop. (After 2^N cycles) But yeah other than that you're perfectly right. \$\endgroup\$ – Bregalad Mar 18 '16 at 20:16
  • \$\begingroup\$ @Breg: Yes, that's true for the digital technique you described. I was generalizing to true random numbers. \$\endgroup\$ – Olin Lathrop Mar 18 '16 at 21:16

It is used.

I believe you have described "pseudo random sequence" (PRS) generator PWM.

It is described in Cypress Semiconductor's application note "AN2246: PSoC® 1 – PWM Source – High Frequency, High Resolution" in document "AN2246_001-33721_0C_V" which you can download from Cypress Semi in document:

That application note also describes several alternatives.

  • 1
    \$\begingroup\$ That does use pseudo random numbers to improve accuracy, but it does so in combination with a PWM scheme. The combination avoids generating pulses below some minimum frequency so that filtering is still pretty straight forward. \$\endgroup\$ – JRE Mar 18 '16 at 11:28

A single or double order Delta-Sigma modulator (a.k.a. as MOD1 and MOD2) do an even better job at leveraging bandwidth, noise and resolution, and are even simpler to implement. And they are used a lot in various domains.

When you want to learn more about Delta-Sigma converters, I recommend: "Understanding Delta-Sigma Data Converters" by Schreier and Temes (ISBN 0-471-46585-2).


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.