# Getting the PWM working The Raspberry Pi zero (1 and 2) have 2 PWM peripherals, allowing you to pulse pins without the CPU doing any additional work. This is particuarly useful for controlling motor speeds when connected to a motor driver/H-bridge chip. # References - [CircuitPython Libraries on Linux and Raspberry Pi](https://learn.adafruit.com/circuitpython-on-raspberrypi-linux/installing-circuitpython-on-raspberry-pi) - [Raspberry Pi Official Overlays information (github)](https://github.com/raspberrypi/firmware/blob/master/boot/overlays/README) - Line 4235 starts the description of the "pwm" overlay configuration - [Adding Basic Audio Ouput to Raspberry Pi Zero](https://learn.adafruit.com/adding-basic-audio-ouput-to-raspberry-pi-zero/pi-zero-pwm-audio) - [CircuitPython pwmio documentation](https://docs.circuitpython.org/en/latest/shared-bindings/pwmio/index.html) # Important Points 1. The `gpio` program is no longer available. It has been replaced with `pinctrl` which works a little differently. 1. The Blinka/CircuitPython interface uses `lgpio` to do hardware PWM on the pins. This requires the `pwm-2chan` overlay to be setup correctly, which it's documented procedure does. Details on relevant pins on line 4267 of the [overleays README](https://github.com/raspberrypi/firmware/blob/master/boot/overlays/README) # Discussion My raspberry pi zero W 2 wasn't working reliably with the PWM. The `gpio` command has been depricated and is now replaced by the `pinctrl` commend. Running it did not list any PWM0 on any of the pins, which was concerning. [This forum post](https://forums.raspberrypi.com/viewtopic.php?t=388352) indicated the need for a `pwm-2chan` device tree overlay to get it to show up. After adding `dtoverlay=pwm-2chan` to the `config.txt`: ``` $ pinctrl 0: ip -- | hi // ID_SDA/GPIO0 = input 1: ip -- | hi // ID_SCL/GPIO1 = input 2: a0 -- | hi // GPIO2 = SDA1 3: a0 -- | hi // GPIO3 = SCL1 4: op -- -- | hi // GPIO4 = output 5: ip -- | hi // GPIO5 = input 6: ip -- | hi // GPIO6 = input 7: op -- -- | hi // GPIO7 = output 8: op -- -- | hi // GPIO8 = output 9: a0 -- | lo // GPIO9 = SPI0_MISO 10: a0 -- | lo // GPIO10 = SPI0_MOSI 11: a0 -- | lo // GPIO11 = SPI0_SCLK 12: ip -- | lo // GPIO12 = input 13: ip -- | lo // GPIO13 = input 14: ip -- | lo // GPIO14 = input 15: ip -- | hi // GPIO15 = input 16: ip -- | lo // GPIO16 = input 17: ip -- | lo // GPIO17 = input 18: a5 -- | lo // GPIO18 = PWM0 19: a5 -- | lo // GPIO19 = PWM1 ``` Which looks much better. There is a pwm chip `in /sys/class/pwm` After running the `lgpio/pwm-test.py` the pin is back to being listed as an input, so I'm confused. The PWM pin (under load) did the right values. Without a load on the Analog Discovery 2, I just saw noise. I commented out `dtoverlay=pwm-2chan` and `lgpio/pwm-test.py` worked. The pwm chip is missing from `/sys/class/pwm` so I'm guess that's not needed.