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
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
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() 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
pigpio python bindings. The 40-pin models do have 4 PWM pins. 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. 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)