I'm able to write to GPIO pins with sysfs with the standard commands like echo "1" > /sys/class/gpio/gpio6/value, but that only turns the pin on or off.

I tried echo "0.5" > /sys/class/gpio/gpio6/value and echo "50%" > /sys/class/gpio/gpio6/value but those give an Invalid argument error.

I tried looking it up, but couldn't find any examples of sysfs PWM usage for the GPIO interface. 😒

How can I use PWM with sysfs?

(I put together a fan module a couple of years ago and wrote some software to control it as well as to automate it whenever the board gets hot, and that worked fine. But I want to make it so that it's not always blasting 100% when it turns on, I want it to blow according to the temperature. I switched the (two-wire) fan to a PWM pin and can turn it on and off as before, but I need to control its duty-cycle. This is technically an XY-problem for me, so any solution would be great, but one answering this specific question would also help others wondering this for other applications.)


4 Answers 4


To use pwm, you need to use the pwm interface at /sys/class/pwm, not the gpio interface.

Here is the relevant documentation. The startup would be something like export 1 > /sys/class/pwm/pwmchip0/0/export.

  • Thank you. That's exactly what I was looking for. 👍 I did manage to find a page that mentioned it, but /sys/class/pwm empty on my SBC because I had removed the PWM overlay (because enabling it disables the TTY interface). I've re-enabled it and I can now access pwmchip0. Now I just need to figure out good values to set.
    – Synetech
    Oct 22, 2021 at 0:32

I have done this before but I would not recommend doing it this way. sys/class/gpio doesn't support PWM on it's own, you can only write 1 or 0, ie "on" or "off" to a gpio pin using the sysfs gpio interface. PWM means writing on for a certain duration and then off for a certain duration and then repeating. You can implement this yourself with sysfs in software, but there are other more industry standard ways to accomplish this, look into hardware timed pwm interfaces

  • Thanks, but the reason I'm using sysfs is because of the simplicity, I want to avoid all those extra complications. PMF's answer pointed me in the right direction; I just need to figure out what values to use for period and duty_cycle.
    – Synetech
    Oct 22, 2021 at 0:34
  • ahh okay. In that case then I think that is part specific, check the datasheet for your fan if you can
    – Dyskord
    Oct 22, 2021 at 0:38
  • also do you understand the pwm protocol? I apologize that my answer wasn't helpful to you but I can tell you more about how pwm works if you need, as well as point you to some resources
    – Dyskord
    Oct 22, 2021 at 0:40
  • Yes, I'm quite familiar with PWM. (I've been programming computers for over 30 years, dabbling in electronics and building computer peripherals for over 20, and working with Arduinos and other microcontrollers for 5.) I'm just not familiar with how it's implemented in *PIs. There is a pin on the GPIO which is specifically designated as a PWM pin so I assume the logic is integrated into the SBC (hence why I was hoping to handle it with a bit of code instead of instead messing with drivers or circuits).
    – Synetech
    Oct 22, 2021 at 2:42
  • Understood. In that case, yeah I think your fan probably has specific pwm values that lead to specific settings. You might have to do some math to convert the values in the data sheet to the ones that you want, but I think that's how you would go about it
    – Dyskord
    Oct 22, 2021 at 3:59

There is some real paths for work with Pi PWM0 output:


But I think that for to generate PWM by Pi is better to be independent on only 2 PWM predefined ports, especially when multiple different devices are connected to the one Pi bus. There is commented Python code for to use any GPIO port as PWM output and set frequency and duty cycle:

import RPi.GPIO as GPIO     #import the RPi.GPIO library
from time import sleep      #import the sleep from time library
GPIO.setmode(GPIO.BOARD)    #set GPIO PIN number on Pi board
GPIO.setup(7, GPIO.OUT)     #set PIN 7 as Output PIN
pwm_obj = GPIO.PWM(7, 400)  #create object pwm_obj (PinNumber, Frequency)
while True:
    pwm_obj.start(40)   #start generating signal(Duty cycle = 0-100)
    pwm_obj.ChangeDutyCycle(10) #change Duty cycle
    time.sleep(1)       #leave the same setting (eg. for 1sec.)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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