3

I've been working on a project using the Pi ... I need to give PWM output but every one says that only one GPIO pin is compartible with PWM but i need 4 is there any way to give PWM output using 4 GPIO pins...

Plese help

5 Answers 5

2

An alternative way is to add hardware that can do the PWM, example PCA9685.

1

I for myself have made bad experiences using the pi and python for pwm. The software pwm the RPi.GPIO library provides is very prone to 'hick-ups' when ever any additional workload appears. In my case for example opening a ssh connection immediately caused an irregular flicker. It will work with any gpio the way Deepesh descibed. But you must not be sensitive to occasional failures in your motor speed/light intensity/what ever. Python on the raspberry pi will not do its purpose in case of pwm if you want to achieve good results! When using the Raspberry for pwm I would highly recommend using C for coding (if you are able to do so, use assembler. It's not so hard to implement pwm with assembler ;). Then using 4 or 5 pins for seperate pwm funktions should not be a problem, I guess. But - believe me - no python

1

Here is a pigpio version to send PWM at one frequency but with selected phase and duty cycle.

It may use as many GPIO as are available on the expansion header and should be glitch free. Since this way is based on pigpio class, you need to run the pigpio daemon before executing the following code.

sudo pigpiod 

By starting pigpio daemon, a number of setings are determined e.g. sample rate (1, 2, , 4, 5, 8, or 10 us, default 5 us).

#!/usr/bin/env python import time import pigpio # http://abyz.me.uk/rpi/pigpio/ import wavePWM # http://abyz.me.uk/rpi/pigpio/code/wavePWM_py.zip GPIO=[5, 6, 7, 8, 9, 10] pi = pigpio.pi() if not pi.connected: exit() pwm = wavePWM.PWM(pi) pwm.set_frequency(100) for g in range(len(GPIO)): pwm.set_pulse_start_in_fraction(GPIO[g], g/6.0) while True: try: for i in range(51): for g in range(len(GPIO)): pwm.set_pulse_length_in_fraction(GPIO[g], i/100.0) pwm.update() # apply the changes time.sleep(0.1) for i in range(51): for g in range(len(GPIO)): pwm.set_pulse_length_in_fraction(GPIO[g], (100-i)/100.0) pwm.update() # apply the changes time.sleep(0.1) except KeyboardInterrupt: break pwm.cancel() pi.stop() 

enter image description here

0

Never mind, I found a way
Have a look at this:

import time import RPi.GPIO as GPIO GPIO.setmode(GPIO.BCM) GPIO.setup(4,GPIO.OUT) while True: GPIO.output(4,True) time.sleep(0.00001)#1 GPIO.output(4,False) time.sleep(0.02)#2 #This is how PWM works 

Just increase the number of zeres after '.' in 1 to make the LED or whatever glow dimmer

12
  • 1
    Could we see the code you use for four LEDs with different brightness? Commented Aug 18, 2016 at 10:10
  • 1
    This will work to do a relatively crude form of PWM that's effective to control the brightness of an LED -- but anything with a granularity finer than 10 ms will probably be visibly inconsistent, and rack up processor time (i.e. waste system resources). It will never work to do the more precise sort of PWM required for servos, etc. If you have a 26 pin model and you want to do PWM on more than pin 18 you should probably look into the pigpio python bindings. The 40-pin models do have 4 PWM pins. Commented Aug 18, 2016 at 12:44
  • @goldilocks I can't find any info that the 40-pin model has 4 PWM pins... Commented Aug 18, 2016 at 14:26
  • See here; the pins crossed out are only on 40-pin models. The only one that isn't crossed out which has a "PWM" function (they're light blue) is pin 18, but there are three more that are crossed out: 12, 13, and 19. I'm not a python user so I can't say how to use RPi.GPIO for this, but it involves setting the mode of the pin to something other than input or output, then configuring a PWM clock. There are potentially other ways to create a PWM pulse, but they require some more complex low level hacking which is why I recommended you try pigpio. Commented Aug 18, 2016 at 14:34
  • 1
    @goldilocks Re PWM pins. GPIO 12/13/18/19 (and others on the compute module) may be set to PWM mode. However there are only two PWM channels. 12 and 18 share a channel so have exactly the same PWM settings, similarly 13 and 19 share a channel. Commented Aug 18, 2016 at 16:53
0

If you need to get a six step pwm for three phase inverter using Python, you can use the following code which creates six commutation signals. Each output has 60 degrees lag with the previous one (p1, p2, p3, p4, p5, p6). The firing signals are issued over GPIO2, GPIO3, GPIO4, GPIO17, GPIO27 and GPIO 22 which are the first lower left pins of the second row of raspberry pi IO pins.

Note that in practice as mentioned before, there are “hick-ups” or irregular flickers in the output pulses. If you are not required to have the duty cycle changes every 100 ms, simply comment out lines under While loop.

Python time sleep function is used to add delay in the execution of a program. We can use python sleep function to halt the execution of the program for given time in seconds. Notice that python time sleep function actually stops the execution of current thread only, not the whole program. Python sleep() is a method of python time module. So, first we have to import the time module then we can use this method.

The code compilation will be fine using "python3" in command line or Thonny in Raspbian Stretch (2019-04-08) if the indentation in the following lines is messy, get the .py file from here:

# pwm for 6 step firing with 100 Hz frequency and changing duty cycle from 0 - 100% import RPi.GPIO as IO #calling header file which help us use GPIO'S of PI import time #calling time to provide delays in program IO.setwarnings(False) #don't show any warnings #setting 6 GPIO pins as output for 6 step commutation IO.setmode(IO.BCM) #WE ARE PROGRAMMING THE gpio BY BCN PIN NUMBERS. (PIN35 AS 'GPIO19') IO.setup(2,IO.OUT) #initialize GPIO2 as an output IO.setup(3,IO.OUT) #initialize GPIO3 as an output IO.setup(4,IO.OUT) #initialize GPIO4 as an output IO.setup(17,IO.OUT) #initialize GPIO17 as an output IO.setup(27,IO.OUT) #initialize GPIO27 as an output IO.setup(22,IO.OUT) #initialize GPIO22 as an output fr4pwm = 100 p1 = IO.PWM(2,fr4pwm) #GPIO2 as PWM output with 100 HZ frequency p2 = IO.PWM(3,fr4pwm) #GPIO3 as PWM output with 100 HZ frequency p3 = IO.PWM(4,fr4pwm) #GPIO4 as PWM output with 100 HZ frequency p4 = IO.PWM(17,fr4pwm) #GPIO17 as PWM output with 100 HZ frequency p5 = IO.PWM(27,fr4pwm) #GPIO27 as PWM output with 100 HZ frequency p6 = IO.PWM(22,fr4pwm) #GPIO22 as PWM output with 100 HZ frequency fireinterval = 1/(6*fr4pwm) print(fireinterval) p1.start(0) #generate PWM signal with 0% duty cycle on GPIO2 time.sleep(fireinterval); # interval bw firing pulses p2.start(0) #generate PWM signal with 0% duty cycle on GPIO3 time.sleep(fireinterval); # interval bw firing pulses p3.start(0) #generate PWM signal with 0% duty cycle on GPIO4 time.sleep(fireinterval); # interval bw firing pulses p4.start(0) #generate PWM signal with 0% duty cycle on GPIO17 time.sleep(fireinterval); # interval bw firing pulses p5.start(0) #generate PWM signal with 0% duty cycle on GPIO27 time.sleep(fireinterval); # interval bw firing pulses p6.start(0) #generate PWM signal with 0% duty cycle on GPIO22 try: while 1: #execute loop forever for x in range(50): #execute loop for 50 times, x being incremented from 0 to 49. p1.ChangeDutyCycle(x) # change duty cycle for varying the speed of ac motor. p2.ChangeDutyCycle(x) # change duty cycle for varying the speed of ac motor. p3.ChangeDutyCycle(x) # change duty cycle for varying the speed of ac motor. p4.ChangeDutyCycle(x) # change duty cycle for varying the speed of ac motor. p5.ChangeDutyCycle(x) # change duty cycle for varying the speed of ac motor. p6.ChangeDutyCycle(x) # change duty cycle for varying the speed of ac motor. time.sleep(0.1) #sleep for 100 milli seconds for x in range(50): #EXECUTE LOOP FOR 50 TIMES X BEING INCREMENTED FROM 0 TO 49 p1.ChangeDutyCycle(100-x) #change duty cycle for changing the speed of ac motor. p2.ChangeDutyCycle(100-x) #change duty cycle for changing the speed of ac motor. p3.ChangeDutyCycle(100-x) #change duty cycle for changing the speed of ac motor. p4.ChangeDutyCycle(100-x) #change duty cycle for changing the speed of ac motor. p5.ChangeDutyCycle(100-x) #change duty cycle for changing the speed of ac motor. p6.ChangeDutyCycle(100-x) #change duty cycle for changing the speed of ac motor. time.sleep(0.1) #sleep for 100 milli seconds except KeyboardInterrupt: # KeyboardInterrupt : user signal executed by user; by pressing Ctrl+C the following lines are executed p1.stop() # stop pwm 1 p2.stop() # stop pwm 2 p3.stop() # stop pwm 3 p4.stop() # stop pwm 4 p5.stop() # stop pwm 5 p6.stop() # stop pwm 6 IO.cleanup() # sets the GPIO's to inital states (some High some Low) 

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.