mcilveen1
Posts: 1
Joined: Sat Apr 28, 2018 2:09 pm

Servo motors freeze after exactly 250 initializations

Sun Apr 29, 2018 5:44 pm

Hi all,

I am currently working on a project the uses 2 servo motors for a pan and tilt camera system, while developing my code i noticed that the servos suffer from a jitter due to the OS interrupting th PWM signal to the servos. As a solution to this I decided to only move them in small increments by switching the servos on moving them and then off again using the .start(pos) and .stop() methods. I then noticed that after around 250 individual moves of the servos both will cease to move from that point on. the program does not crash and no warning or errors are thrown. after resetting the environment they will work again for another 250 moves. is there a limit to the amount of times a servo can have the .start() called on it?

i created my own modules for initializing a servo object which i will post below

As far as i can tell there is no issue with the standard generic servo motors which were purchased on eBay.

i have wrote a few simple test that use the servo module and freeze the servos after 250 moves.
using the repos method.

The objects coord value continues to be updated even though the servo does not move.

Code: Select all

## servo motor moduule
import RPi.GPIO as GPIO
from time import sleep
import sys

#GPIO.setwarnings(False)

class ServoMotor:
    def __init__(self, pinNo, type):        
        self.pinNo = pinNo
        self.type = type
        GPIO.setmode(GPIO.BCM)
        GPIO.setup(self.pinNo,GPIO.OUT)
        self.pos = GPIO.PWM(self.pinNo,50)
        self.coord = 7.5
        self.pos.start(self.coord)
        sleep(0.5)
        self.pos.stop()
        self.posMax = 0.0
        self.posMin = 0.0
        
        if(self.type == "H"):
            self.posMax = 12.5
            self.posMin = 2.8
        else:
            self.posMax = 11
            self.posMin = 4
    
    
    
    def repos(self, state):
        changeUnit = 0.06
        try:
            GPIO.setmode(GPIO.BCM)
            self.pos = GPIO.PWM(self.pinNo,50)
            if(state == "pos"):
                if(self.coord + changeUnit < self.posMax):
                    self.coord = self.coord + changeUnit
                    self.pos.start(self.coord)
                    sleep(0.1)
                    self.pos.stop()
                else:
                    self.pos.start(self.posMax)
            elif(state == "neg"):
                if(self.coord - changeUnit > self.posMin):
                    self.coord = self.coord - changeUnit
                    self.pos.start(self.coord)
                    sleep(0.1)
                    self.pos.stop()
                else:
                    self.pos.start(self.posMin)
            else:
                print("unknown state: " + str(state))
                quit()
                 
        except Exception as e: 
            print("Error while repositioning in the servo module: " + str(e))
            quit()
            
            
            
    def reposition(self, position):
        self.pos = GPIO.PWM(self.pinNo,50)
        if(self.type == "H"):
            if(position == "Front"):
                self.coord = 7.5
                self.pos.start(self.coord)
                sleep(0.5)
                #print("Front")
            elif(position == "Left"):
                self.coord = 12.5
                self.pos.start(self.coord)
                sleep(1)
                #print("Left")
            elif(position == "Right"):
                self.coord = 2.8
                self.pos.start(self.coord)
                sleep(1)
                #print("Right")
            else:
                try:
                    self.pos.start(position)
                    sleep(0.2)
                except:
                    self.pos.stop()
        else:
            try:
                self.pos.start(position)
                sleep(0.2)
            except:
                print("ERROR: invalid position")
               
        self.pos.stop()
        
    
    
    def getInfo(self):
        print("=========" + str(self.type) + "=========")
        print("Current coords:" + str(self.coord))        
        print("max coord:" + str(self.posMax))
        print("min coord:" + str(self.posMin))
        print("pin no.:" + str(self.pinNo))
        print("===================")
        

User avatar
joan
Posts: 14960
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: Servo motors freeze after exactly 250 initializations

Sun Apr 29, 2018 10:20 pm

That is a known issue with RPi.GPIO.

If you want jitter free operation use something like servoblaster or my pigpio (e.g. http://abyz.me.uk/rpi/pigpio/examples.h ... vo_demo_py )

ghp
Posts: 1517
Joined: Wed Jun 12, 2013 12:41 pm
Location: Stuttgart Germany
Contact: Website

Re: Servo motors freeze after exactly 250 initializations

Mon Apr 30, 2018 6:08 pm

Hello,
there are some things I would propose to change:
- use the " GPIO.setmode(GPIO.BCM) " only once, either in the __init__() or perhaps after the #GPIO.setwarnings(False).
- in your code, the PWM object is created many times. " self.pos = GPIO.PWM(self.pinNo,50) ". IHHO this is needed only once in __init__(). You can start and stop as often you need later.
Hope this helps
Gerhard

Return to “Python”