Skip to Content

PWM Generation Code

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!