Servo cannot move full range

Hi,

I have a problem with my servo controller. My servo only moves for about 45 degrees. Can anyone help me figure out what is wrong with my code?

This is my hardware setup:
Windows PC -> USB -> Pololu MICRO servo board -> Servo (channel 0)
Power supply (6.8V, 5A) -> Pololu MICRO servo board
I have set the settings to “Dual Port”

I am sure power supply is not a problem since I have more than enough power for my servo. The servo works perfectly when I try using the Maestro control center.

This is the code that I am using (python 2.7, all libraries installed - no error messages):

import serial
import time
import math
from Tkinter import *

master = Tk()

w = Scale(master, from_=0, to=180, orient=HORIZONTAL, length=180, label='Angle')
w.pack()

speed = 100

class ServoController():
    def __init__(self):
        self.sc = serial.Serial('COM3', 115200)
    def closeServo(self):
        self.sc.close()

    # Define the set angle function
    def setAngle(self, n, angle):
        # Define byteone variable as the percentage of 254
        byteone=int(254*angle/180)
        # chr(i, /) = Return a Unicode string of one character with ordinal i; 0 <= i <= 0x10ffff.
        # Define the bud variable as:
        # chr(0xFF) = command bytes (most significant bits set (pg. 49 manual)
        # chr (byteone) = data bytes
        # The pololu servo protocol is always command bytes followed by data bytes
        bud=chr(0xFF)+chr(n)+chr(byteone)
        # Write the data to the serial port
        self.sc.write(bud)
        
    # Define the servo speed function
    def setSpeed(self, channel, speed):
        # This is the set Speed compact protocol (pg. 55 manual)
        # Compact protocol: 0x87, channel number, speed low bits, speed high bits
        commandByte = chr(0x87)
        channelByte = chr(channel)
        lowTargetByte = chr(speed & 0x7F)
        highTargetByte = chr((speed >> 7) & 0x7F)
        command = commandByte + channelByte + lowTargetByte + highTargetByte
        self.sc.write(command)
    
Maestro = ServoController()

def controller():
    global speed
    Maestro.setSpeed(0, speed)
    angle_dest = w.get()
    try:
        Maestro.setAngle(0, angle_dest)
        time.sleep(.05)  
    except:
        Maestro.setAngle(0, angle_dest)
        time.sleep(.05)

    w.after(1,controller)
w.after(1,controller)
w.mainloop()

basically what the code does is it displays a slide bar for controlling angle (0-180). But, what I actually got is if I move from 0-90, the servo does not move, and from 90-180 the servo moves 45 degrees.

Can anyone help please? It’s urgent :frowning:

Thank you so much!

Hello.

It sounds like you are able to get the full range (180 degrees) from your servo using the Maestro Control Center, is that correct? From your code, it looks like you are using the Mini SSC protocol of the Set Target command. What did you set the 8-bit neutral and range settings to for that servo channel (0)?

By the way, if you do not already know, one of the members on our forum shared their Python class for Maestro, called maestro.py. It might be easier to use that code instead of writing from scratch. You can find that link under the “Related Resources” section of the Maestro user’s guide. Please note that the library does not have a function for setting the target in degrees, so you probably will need to write your own or modify the setTarget function to convert the value to Maestro units (which are in quarter-microseconds).

- Amanda