When working (ok, avoiding working) on my thesis, I realized I needed to generate some pulse width modulation graphs. For those who don’t know, it’s a way of taking a low-frequency, high-resolution signal and converting it to a high-frequency, low-resolution signal. This technique is very popular in analog design, especially audio amplifiers, where you can easily get enormous over-sampling ratios due to the low signal bandwidth. Just making the one-bit graph is pretty easy, but it took me a bit to think of a good way of making the multi-bit ones, especially in a dynamic way (read: not 100
if x > y statements). Throwing it here for now, hoping to come back and comment/explain the tuning knobs at the top a bit better once my thesis is done.
import numpy as np import matplotlib.pyplot as plt StepsPerCycle = 30 # PWM resolution NumCycles = 30 # number of PWM cycles in the signal NumPoints = StepsPerCycle * NumCycles NumThresholds = 3 # number of PWM trigger thresholds thresholds = np.arange(0, 1, step=1/NumThresholds) time = np.linspace(0, 1, num=NumPoints) vsin = 0.5*np.sin(2*np.pi*time) + 0.5 vout = np.copy(vsin) for n in range(NumCycles): error = vsin[StepsPerCycle * n] - thresholds thresh = np.argmin(error[error >= 0]) high = int(np.floor(error[thresh] * StepsPerCycle)) vout[n*StepsPerCycle : n*StepsPerCycle + high] = (thresh+1)/NumThresholds vout[n*StepsPerCycle + high : (n+1)*StepsPerCycle] = thresh/NumThresholds plt.close('all') plt.plot(time, vout) plt.plot(time, vsin) plt.show()
Some quick output examples:
Hope this is useful to someone else!