Servo motor overheating

Hi everyone, I’m new to the whole Raspberry Pi scene and only started a couple of months ago. I’m attempting to build an RC car with the Raspberry Pi Camera Module v2, that I can control from my smartphone regardless of distance (e.g. 40-50km) for agricultural monitoring.

I’ve connected a Servo Hat to my pi, and have attached a servo motor to the Hat (for the camera). When i ran the script my servo started vibrating loudly and after about a minute started to overheat (burns my finger after a few seconds of contact). Since then the servo continues to vibrate and overheat as long as it’s plugged in - even after the Pi is shutdown or as it’s booting up. The only way i can get it to stop is to unplug the power completely.

I ran a second test script to try and reset the position, but the buzzing continued. After a while the servo stopped responding altogether to the script.

Does anyone know what might be causing the buzzing, and what is the normal operating temperature for a servo?

The script I ran initially was:

#! /usr/bin/python

import os.path
import tornado.httpserver
import tornado.websocket
import tornado.ioloop
import tornado.web
import RPi.GPIO as GPIO
import smbus, time
from numpy import interp

#Configure the servo hat for use
bus = smbus.SMBus(1) # the chip is on bus 1 of the available I2C buses
addr = 0x40 # I2C address of the PWM chip.
bus.write_byte_data(addr, 0, 0x20) # enable the chip
bus.write_byte_data(addr, 0xfe, 0x1e) # configure the chip for multi-byte write

directionPin = 18
enablePin = 16
pwmPin = 12

#start address for servo
panServoStartAddress = 0x06
tiltServoStartAddress = 0x0A
steerServStartAddress = 0x0E

#stop address for servo
panServoStopAddress = 0x08
tiltServoStopAddress = 0x0C
steerServStopAddress = 0x10

#Initialize Raspberry PI GPIO
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BOARD) #use gpio numbers as shown on board
GPIO.setup(pwmPin, GPIO.OUT) #gpio pin for motor pwm
GPIO.setup(enablePin, GPIO.OUT) #gpio pin for motor enable
GPIO.setup(directionPin, GPIO.OUT) #gpio pin for motor direction

#Initialise servo positions (start time, then centre servos)
bus.write_word_data(addr, panServoStartAddress , 0)
bus.write_word_data(addr, tiltServoStartAddress, 0)
bus.write_word_data(addr, steerServStartAddress, 0)
bus.write_word_data(addr, panServoStopAddress , 1250)
bus.write_word_data(addr, tiltServoStopAddress, 1250)
bus.write_word_data(addr, steerServStopAddress, 1250)

#initialise motor settings
frequency = 20000 #(PWM frequency) Max is 20KHz for motor driver
speed = 50 # this is the duty cycle of the PWM output (100 is max speed)

#initialise PWM signal
pulseWidth = GPIO.PWM(pwmPin,frequency) #pwmPin as PWM output, with set frequency
pulseWidth.start(speed) #start PWM at set speed

#initial servo settings
panAngle = 0 #centre pan servo
tiltAngle = 0 #centre tilt servo
SteerAngle = 0 #centre steer servo

#Tornado Folder Paths
settings = dict(
template_path = os.path.join(os.path.dirname(file), “templates”),
static_path = os.path.join(os.path.dirname(file), “static”)
)

#Tornado server port
PORT = 8080

def setSpeed(speed):
#set the vehicle speed
pulseWidth.ChangeDutyCycle(speed)

def forward():
#move the vehicle forward
GPIO.output(enablePin,GPIO.HIGH) #enable the motor driver
GPIO.output(directionPin,GPIO.HIGH)#set direction of movement

def backward():
#move the vehicle backwards
GPIO.output(enablePin,GPIO.HIGH) #enable the motor driver
GPIO.output(directionPin,GPIO.LOW)#set direction of movemet

def steerLeft():
#steer the vehicle left
SteerAngle-=1
if SteerAngle < -90:
SteerAngle = -90
count = mapServoAngle(SteerAngle)
setServoAngle(steerServStopAddress,count)

def steerRight():
#steer the vehicle right
SteerAngle+=1
if SteerAngle > 90:
SteerAngle = 90
count = mapServoAngle(SteerAngle)
setServoAngle(steerServStopAddress,count)

def centreSteer():
#centre the steer servo
SteerAngle = 0
count = mapServoAngle(SteerAngle)
setServoAngle(steerServStopAddress,count)

def stop():
#stop the vehicle
GPIO.output(enablePin,GPIO.LOW)

def panleft():
#pan the camera left
panAngle-=1
if panAngle < -90:
panAngle = -90
count = mapServoAngle(panAngle)
setServoAngle(panServoStopAddress,count)

def panRight():
#pan the camera right
panAngle+=1
if panAngle > 90:
panAngle = 90
count = mapServoAngle(panAngle)
setServoAngle(panServoStopAddress,count)

def tiltUp():
#tilt the camera up
tiltAngle+=1
if tiltAngle > 90:
tiltAngle = 90
count = mapServoAngle(tiltAngle)
setServoAngle(tiltServoStopAddress,count)

def tiltDown():
#tilt the camera down
tiltAngle-=1
if tiltAngle < -90:
tiltAngle = -90
count = mapServoAngle(tiltAngle)
setServoAngle(tiltServoStopAddress,count)

def mapServoAngle(angle):
#function to map the desired angle to servo count
#it calculates and returns the count for angles in the range -90<angle<90
count = interp(angle,[-90,90],[836,1664]) #4.6 counts per degree
return int(count)

def setServoAngle(address,count)
#sets the servo at the given address to the specified angle
bus.write_word_data(address, count)

class MainHandler(tornado.web.RequestHandler):
def get(self):
print “HTTP User Connected.”
self.render(“index.html”)

class WSHandler(tornado.websocket.WebSocketHandler):
def open(self):
print ‘[WS] Connection was opened.’

def on_message(self, message):
print ‘[WS] Incoming message:’, message
if message == “m-forward”:
forward()
if message == “m-backward”:
backward()
if message == “m-left”:
steerLeft()
if message == “m-right”:
steerRight()
if message == “m-up-off”:
stop()
if message == “m-down-off”:
stop()
if message == “m-left-off”:
centreSteer()
if message == “m-right-off”:
centreSteer()
if message == “pt-up”:
tiltUp()
if message == “pt-down”:
tiltDown()
if message == “pt-left”:
panleft()
if message == “pt-right”:
panRight()
if message == “speed-25”:
setSpeed(25) #allow the speed to be set
if message == “speed-50”:
setSpeed(50) #allow the speed to be set
if message == “speed-75”:
setSpeed(75) #allow the speed to be set
if message == “speed-100”:
setSpeed(100) #allow the speed to be set

def on_close(self):
stop() #stop vehicle movement if connection is lost
print ‘[WS] Connection was closed.’

application = tornado.web.Application([
(r’/’, MainHandler),
(r’/ws’, WSHandler),
], **settings)

if name == “main”:
try:
http_server = tornado.httpserver.HTTPServer(application)
http_server.listen(PORT)
main_loop = tornado.ioloop.IOLoop.instance()

    print "Tornado Server started"
    main_loop.start()

except:
    print "Exception triggered - Tornado Server stopped."
    GPIO.cleanup()

#End of Program

Hey Brian,

Servos should not be getting hot enough to burn your hands. I have a feeling something has gone a bit funny somewhere. Are you about to tell me what Servo Hat and servo you are using and how you have wired them together so i can compare what the code is doing to what the hardware is doing?

Hey Clinton,

I’m using the sparkfun pi servo hat (link here) and a this is the sub-micro servo im using (link)

I’ve also attached a photo of how it’s wired up (hooked up to #0 on the servo hat).