User avatar
ibshar
Posts: 22
Joined: Sun Jul 31, 2016 3:00 pm

Servo control using PWM

Thu Mar 28, 2019 3:27 pm

Hi,

I have a servo motor connected to my Raspberry Pi 2 and use PWM to control it. It works fine using the below code:

Code: Select all

import RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BCM)
GPIO.setup(21, GPIO.OUT)
p = GPIO.PWM(21, 50)
p.start(7.5)

try:
    while True:
        p.ChangeDutyCycle(7.5)  # turn towards 90 degree
        time.sleep(1) # sleep 1 second
        p.ChangeDutyCycle(2.5)  # turn towards 0 degree
        time.sleep(1) # sleep 1 second
        p.ChangeDutyCycle(12.5) # turn towards 180 degree
        time.sleep(1) # sleep 1 second 
except KeyboardInterrupt:
    p.stop()
    GPIO.cleanup()
Now I am trying to build a control program for the servo that would run all the time (24x7) so I was thinking that I would give a button to start the PWM then stop it when done. And this can be done any number of times. But i'm facing the issue that, once I call the p.stop, after that when i again call the p.start, then the rotation does not work for any value of p.ChangeDutyCycle. Am i missing something?

EG:

Code: Select all

def Start(self):
		self.p.start(7.5)
	
	
	def Stop(self):
		self.p.stop()
		
	def Turn(self, val):
		if (val >= self.Min and val <= self.Max):
			print val
			self.p.ChangeDutyCycle(val)
			self.CurrentPos = val
			time.sleep(self.holdtime)

pcmanbob
Posts: 6256
Joined: Fri May 31, 2013 9:28 pm
Location: Mansfield UK

Re: Servo control using PWM

Thu Mar 28, 2019 4:10 pm

May be if you showed us all of your program we could help just showing part of it does not allow use to see how and when you are calling the functions.
We want information… information… information........................no information no help
The use of crystal balls & mind reading are not supported

User avatar
ibshar
Posts: 22
Joined: Sun Jul 31, 2016 3:00 pm

Re: Servo control using PWM

Tue Apr 02, 2019 11:38 am

Hi,
Heres the full code:
Servo Class:

Code: Select all

import RPi.GPIO as GPIO
import time

class ServoControl:

	servoPin = 21
	frequency = 50
	Neutral = 7.5
	Min = 2.5
	Max = 12.5
	CurrentPos = 7.5
	TurnDistance = 1	
	holdtime = 0.02
	GPIO.setmode(GPIO.BCM)
	GPIO.setup(servoPin,GPIO.OUT)
	p = None

	def __init__( self):
		self.p = GPIO.PWM(self.servoPin,self.frequency)
	
	
	def Start(self):
		self.p.start(self.Neutral)
	
	
	def Stop(self):
		self.p.stop()
		
	
	def TurnLeft(self):
		val = self.CurrentPos + self.TurnDistance
		self.Turn(val)
	
	
	def TurnRight(self):
		val = self.CurrentPos - self.TurnDistance
		self.Turn(val)
		
	
	def Turn(self, val):
		if (val >= self.Min and val <= self.Max):
			print val
			self.p.ChangeDutyCycle(val)
			self.CurrentPos = val
			time.sleep(self.holdtime)
			

	def CleanUp(self):
		#self.p.stop()
		GPIO.cleanup()
And then i test the servo using this simple script:

Code: Select all

#!/usr/bin/python
import sys
import time
sys.path.insert(0, '/home/pi/Programs/PythonLibz')
from zServoControl import ServoControl

try:
	s = ServoControl()
	s.Start()
	s.TurnLeft()
	time.sleep(0.5)
	s.TurnLeft()
	time.sleep(0.5)
	s.TurnLeft()
	time.sleep(0.5)
	s.TurnLeft()
	time.sleep(1)
	s.TurnRight()
	time.sleep(0.5)
	s.Stop      # ISSUE here, servo stops working after this stop.
	print "round 2"
	time.sleep(3)
	s.Start()
	s.TurnLeft()
	time.sleep(0.5)
	s.TurnLeft()
	time.sleep(0.5)
	s.TurnLeft()
	time.sleep(0.5)
	s.TurnLeft()
	time.sleep(1)
	s.TurnRight()
	time.sleep(0.5)
	s.Stop
except Exception as error:
	print error
finally:
	s.CleanUp()

My main doubt is, can we call the start method on PWM after calling its stop method? Or does it dispose the object after the stop method is called?

Also the reason I need to Start and Stop multiple times, is because I will be using the ServoClass in a flask web app which would run 24x7 so I want to enable the servo only when I want to move it.

PiGraham
Posts: 3559
Joined: Fri Jun 07, 2013 12:37 pm
Location: Waterlooville

Re: Servo control using PWM

Tue Apr 02, 2019 12:26 pm

Maybe this helps:
4


I am fairly sure it is a bug in the RPi.GPIO module.
Look through https://sourceforge.net/p/raspberry-gpi ... n/tickets/
As a workaround I suggest you do not use the start() and stop() methods in a loop, use the ChangeDutyCycle() method instead to set the duty cycle to zero to stop PWM.

https://raspberrypi.stackexchange.com/q ... start-stop

PiGraham
Posts: 3559
Joined: Fri Jun 07, 2013 12:37 pm
Location: Waterlooville

Re: Servo control using PWM

Tue Apr 02, 2019 12:29 pm

ibshar wrote:
Tue Apr 02, 2019 11:38 am

Also the reason I need to Start and Stop multiple times, is because I will be using the ServoClass in a flask web app which would run 24x7 so I want to enable the servo only when I want to move it.
Check how your servo handles no PWM. It will still draw power and may still move a bit. If you want to shut it off completely until needed you may have to add a power switching device on another gpio.

MarkR
Posts: 154
Joined: Fri Jan 25, 2013 1:55 pm

Re: Servo control using PWM

Tue Apr 02, 2019 6:04 pm

If you're using a web app, then probably your program / script won't keep running once the web request is finished. This is probably not what you want, if the servo motor is still trying to move to its position.

Personally, I like the pigpio library / daemon, so I'd install that, and have your web app send commands to the daemon. You can do that either by calling the "pigs" program (e.g. pigs s 24 1500).

As it's a "daemon" process which runs in the background, pigpio will just keep sending the pulses until you tell it to stop. This is good because it means the servo will try to hold its position.

If you want to save a bit of power or wear on the servo, then you'll need to write your own thing to turn the servo off (send 0 pulses) if it hasn't been used for a while.

PiGraham
Posts: 3559
Joined: Fri Jun 07, 2013 12:37 pm
Location: Waterlooville

Re: Servo control using PWM

Wed Apr 03, 2019 6:29 am

MarkR wrote:
Tue Apr 02, 2019 6:04 pm

If you want to save a bit of power or wear on the servo, then you'll need to write your own thing to turn the servo off (send 0 pulses) if it hasn't been used for a while.
Your pigpiod suggestion is good.

Do you know how most servos behave without a PWM signal? I note that just applying power typically causes the output to twitch and it becomes hard to turn the shaft by hand. This is on the cheap Tower 9g servos I've played with. That suggests to me that servos are either powered or not and are active when powered whatever the PWM signal state.

It is possible that some servos enter a sleep state when there is no PWM but do you know that to be the case in general or for specific servo models?

User avatar
ibshar
Posts: 22
Joined: Sun Jul 31, 2016 3:00 pm

Re: Servo control using PWM

Sat Jun 22, 2019 2:50 pm

Thanks for the suggestions guys.

Sorry for the long delay in response, I was out travelling so couldn't work for some time. Finally I got back with the project today and fixed it myself.

The solution for me was to Create the Servo class Object only when the user clicks the start button, then I can turn the motor, left/right etc, then click the Stop button where I call the Sop on the servo and del the Servo object. This puts the servo in a nice sleep state and wakes it only when Start is pressed. :mrgreen:

peterm2
Posts: 39
Joined: Wed Jun 27, 2012 7:46 pm
Location: Dorset

Re: Servo control using PWM

Thu Jun 27, 2019 12:54 pm

Thanks, This has sorted my problem. I have been using a flask App with python code and different buttons to move servo in different positions, but it only worked for the first button push and then played stupid. This suggestion sorted it.

PeterM.

PiGraham wrote:
Tue Apr 02, 2019 12:26 pm
Maybe this helps:
4


I am fairly sure it is a bug in the RPi.GPIO module.
Look through https://sourceforge.net/p/raspberry-gpi ... n/tickets/
As a workaround I suggest you do not use the start() and stop() methods in a loop, use the ChangeDutyCycle() method instead to set the duty cycle to zero to stop PWM.

https://raspberrypi.stackexchange.com/q ... start-stop

Return to “Automation, sensing and robotics”