Basic Electronics 10, Chapter 10: Challenge 2 solution (PWM and interrupts) Formulas: D = compare / top V(avg) = D x V steps = f(clk) / f(PWM) bits = floor(log2 steps) RC filter ripple dV = V D (1 - D) / (R C f) time constant tau = R C settling to 1/256: ln(256) tau = 5.55 tau pulse rate = rpm / 60 x pulses per rev CPU load = rate x ISR time one count = 60 / (pulses per rev x window) rpm (a) analogWrite(pin, 90) on an Uno D = 90 / 255 = 0.3529 = 35.3 % On a 5 V pin: V(avg) = 0.3529 x 5 = 1.765 V On a 6 V motor supply: V(avg) = 0.3529 x 6 = 2.118 V (through a driver, which also drops a little) (b) PWM at 25 kHz Pico (125 MHz): 125e6 / 25e3 = 5000 steps log2(5000) = 12.29 -> 12 bits ESP32 (80 MHz): 80e6 / 25e3 = 3200 steps log2(3200) = 11.64 -> 11 bits Uno Timer 1, 8-bit phase-correct, 16 MHz: 16e6 / 510 = 31 373 Hz = 31.4 kHz (255 levels) Doubling the frequency would halve the steps and cost one bit: 25 kHz is a good silent choice on all three. (c) RC filter, R = 4.7 k, C = 2.2 uF, 5 V, D = 0.5 (D(1 - D) = 0.25) Time constant: tau = 4700 x 2.2e-6 = 10.34 ms cut-off f(c) = 1 / (2 pi tau) = 15.4 Hz Ripple at 490 Hz: 5 x 0.25 / (4700 x 2.2e-6 x 490) = 1.25 / 5.067 = 0.247 V peak to peak Ripple at 31 372 Hz: 5 x 0.25 / (4700 x 2.2e-6 x 31372) = 1.25 / 324.4 = 3.85 mV peak to peak Settling to 1 part in 256: t = tau x ln(256) = 10.34 ms x 5.545 = 57.3 ms The fast PWM makes the ripple 64 times smaller (31 372 / 490), at no cost in settling time. (d) Encoder: 7 pulses per rev on the motor shaft, motor 9000 rpm, gearbox 30:1 Motor speed in rev/s: 9000 / 60 = 150 rev/s Pulse rate: 150 x 7 = 1050 interrupts per second CPU load of a 12 us ISR: 1050 x 12e-6 = 0.0126 = 1.26 % Counts in a 50 ms window: 1050 x 0.050 = 52.5 (so 52 or 53 counts per window) One count = 60 / (7 x 0.050) = 171.4 rpm of the motor, which is 171.4 / 30 = 5.71 rpm at the output shaft (a single count of error is 1 / 52.5 = 1.9 % of the reading: about right; a 100 ms window would halve it) Output shaft speed: 9000 / 30 = 300 rpm Motor rpm from counts: counts x 60 / (7 x 0.050) = 52.5 x 171.4 = 9000 rpm Expected readings (a) a meter on a PWM pin (DC range) averages to about 1.76 V; a scope shows 35 % high (c) a scope on the capacitor shows 2.5 V with 0.25 V of ripple at 490 Hz, and a flat line (4 mV) at 31.4 kHz (d) in the program the count in a 50 ms window is 52 or 53, alternating, as the window and the pulses do not line up Wiring and program checklist - PWM output: pin -> driver input, with a 100 k pull-down to GND at the driver so the motor is off while the board boots. - Encoder: sensor output to an interrupt-capable pin (Uno D2 or D3; any GPIO on a Pico or ESP32), with the sensor's own pull-up if it is open-collector. - ISR: count only, shared variable volatile, copy it with interrupts off on an 8-bit chip. - Filter test: measure the capacitor voltage with a meter; it should be D x 5 V once settled.