Pantilthat - rotation range

Just got my new PanTilt Hat setup and working. There appears to be a limit of 180 degrees on the pan servo. I am using it on a ‘tank chassis’ where for space reasons it is mounted '‘facing’ one side. I was expecting the pan range to be around 300 degrees which would give decent view when moving forward. The documentation does refer to serverpulse min and max but changing them doesn’t appear to change the rotation range.

So to questions:

  1. Can the pan servo be enabled to travel further than 180 degrees or can its start and end points be moved 90 degrees anti-clockwise.
  2. How/where do I change the settings and can I add additional ones if the range is extended beyond 180 degrees e.g. 45 degrees.


They are 180 degree servos, they can move a little further, but tend to jitter a lot at the extreme ends of their range.

Thanks for the quick reply, I’ll have a look in my ‘stock’ as I may have some that will go almost 360 which for my purpose would be better and avoid having to look at some surgery to turn the whole pantilt unit through 90. Assuming I have will the software allow me to adjust for the greater range?

Lots of how to’s on how to make them rotate 360 degrees.

Assuming you don’t have any wires etc that will get damaged if you do it.

Yes, the PanTilt HAT software lets you set an upper/lower range in milliseconds for the pulse.

At the moment, however, the servo range that the pan and tilt understand is fixed at 0-180, so if you configure the min and max pulse times to suit 360 degrees you’ll have to divide your desired rotation by 2.

IE: If you want to rotate to 360 you would need to send 180, which would be mapped to the maximum pulse time.

You can use servo_pulse_min(servo_index, value_in_ms) and servo_pulse_max(servo_index, value_in_ms) to adjust the min/max pulse times- where servo_index is either 1 or 2.

Great, thanks for your help. I am going to use a web page front end so I will be able to set the relevant range for each direction there once I’ve worked out where the start pint should be.

…and it looked as though it was going to be install and go!!

Replacement servo (fitec fs90r) installed. Now working on a python app which will be integrated into a cambot control script.
I have encountered a couple of difficulties:

  1. on the tilt servo (unchanged) a postive value for n between 40 and 140 to pantilthat.tilt(n) works with 40 looking up and 140 down. I had expected the range to be something like -45 to 45.
  2. and more important is sending any value for n to pantilthat.pan(n) results in the unit spinning until the camera ribbon cable runs out. This seems odd the first go used n=5 and a second n=2… I found a datasheet for the servo which says required pulse between 900 to 2100 mu sec. I tried n=0. 000015 but same result unit spins.
    I’m a novice with all of this whilst one isn’t a problem 2 is and I’m not sure how to solve it - any help would be appreciated.

Since Python gives you access to tweak/overwrite almost anything you could try replacing the min/max values for servos, like so:

pantilthat.pantilthat._servo_min = [900, 2100]
pantilthat.pantilthat._servo_max = [900,2100]

hello rjhazzeld:

I had to replace my pan servo and they sent me the fitec fs90r. I am still using the original towerpro SG90 for the tilt servo.

Did you figure out the settings you need for precise angle changes?
spec states: Operating Angle : 360degree
Required Pulse : 900us-2100us

I have tried

but pantilthat.pan(0) still results in spin until ribbon runs out

here is the program:
import time
import pantilthat
cnt1 = 1
while cnt1 == 1:
angl = input(’ angle = ')
angle = int(angl)
if angle > 180:
pan_angle = pantilthat.get_pan()
print (pan_angle)

I did succeed in getting it working although I have forgotten the detail as it is integrated into a cambot control web interface. Looking at the pantilt driver code I have amended it to servo_min=575 and servo_max=2325. The web interface feeds values between -89 and +89 i.e. almost 180 degree arc which is what I needed. There are button delivering values for these and mid position and a slider for ad-hoc movement. As far as I recall I had to do a fair amount of trial and error to get the range right.

If you are struggling let me know and I’ll get the code out and go through it so that I can be more specific.

This is even more strange. The following code causes the pan to rotate CW until it runs out of ribbon

import time
import pantilthat

I am no expert but there doesn’t appear to be a command telling the servo how far to turn in this code. The the servo_pulse_min and max are set in the driver script in my installation thus when the driver initialises the values are set. I then use a variable pmove to set the angle -pantithat.servo_one(pmove). In my case I have a condition to stop a value beyond -89 to 89 being passed. The value in this case must be an integer.
I’d be inclined to start by reinstalling the primoroni supplied software. Then change the values for servo_pulse_min and max. restart then try running the example code which should result in the servo moving 90 each way.
Hope that helps you although how I have got it to work may not be technically the desirable way of doing it. I found the example code and readme files helped immensely as did gadgetoids posts.

With the stock servos and the pan tilt hat its pretty easy to pan to a specific spot.
pantilthat.pan(+90) is fully left and pantilthat.pan(-90) is fully right for 180 degrees of movement. and pan(0) is centered. tilt - is up and tilt + is down.
Swap in different servos with a wider range and you get to play with all that PWM stuff, that can make your head hurt. It is very interesting to follow what you people are doing though. Best of luck. =)

I only just got my first full pan tilt kit last week. It worked like a charm in Raspbian with python. I was days getting it sorted out and working in Motion Eye though.

Slightly off topic. My next project will involve building a surveillance camera. It would use the pantilt hat. There appear to be two options:

  1. motioneyeos (buildroot, motion, motioneye)
  2. raspian buster, motion, motioneye


Also look at PiKrellCam. It has motion detection with recording. It’s similar to Motioneyesos.

I tried at least once to install Motion Eye on top of Raspbian but could not get it to work. Motion Eye OS is restrictive in what you can add to it and do to it. I had to remount as read write from terminal via putty just to edit some of the config files. But from what I’ve read thats because of builroot, and making it more robust so it doesn’t fail on you.

I’ve heard PiKrellCam mentioned before, haven’t tried it myself though

My personal main criteria was I didn’t want to have to stream my feed to the Internet and or a Web Site to view it. If you want to view it from work etc thats great. I only ever watch mine from a PC in the house. Motion Eye lets me do it all over my LAN, nothing goes to the WAN side of my router.

I use which works well for my purpose. It has motion detection capability but I haven’t tested it (Look at the pages on the RPi forum there is good discussion of capabilities. My application is streaming images from a cambot. I can control the vehicle, pantilthat and lights from a web page that has the image embedded with a link to open the RPi-Cam-Web-Interface. I only use the cambot and camera across my home Lan.
Hope this helps.

PiKrellCam is also a web server type interface so it can run as a background process.I like MotionEyesOS because putting multiple cameras on is a snap.

thanx for all the comments.
I do want to be able to access the camera when I am away, over the internet.
I created a subdomain on my web site, and setup port forwarding on my router.
Unfortunately the dynamic-dns software that my hosting site wants me to install on the RPI, only runs on python3.

It appears that motioneyeos only has python2 and no pip nor install software.

You could try installing Motion Eye into Raspbian. That “should” get you python 3 and the ability to install other software. I tried it once before and couldn’t get it to work. I don’t think it was these instructions though?