Testing Servos

The servos were just the cheapest heavy-duty ones from the local model shop, but even so I may need larger to move the huge wheels. As this a rock-crawler model, both the axles are identical with a separate motor and steering servo. The advantage for this setup is that we have 4 wheel drive and 4 wheel steering. The modes for the steering maybe:

  • Normal front wheel steering
  • Rear wheel steer like a forklift truck
  • Crab steer where the vehicle moves sideways with both axles turned in the same direction
  • Opposite steer for a quick turn with axles in different directions
  • Random steer of both axles

Both axles are the same with the execution of the motor turns in the opposite direction on the rear.


Rear axle showing servo and steering.


Rear axle showing motor location.

add pics of modes

We have 4 wheel drive and 4 wheel steering.

To control the servos (and ultimately the speed controller) the Adafruit’s 16-channel 12-bit PWM/Servo Driver was selected with the idea of using as many standard RC bits as possible, hence using a standard speed controller not a RPi specific one; whether this is a good idea remains to be seen! setting up the driver board went pretty smoothly using the directions on Adafruit’s site; front servo was connected to channel 0 and rear to channel 2.

The code for testing the servo was copied (and slightly modified) and did move the servos back & forth as expected like a wiper blade.

# Simple demo of of the PCA9685 PWM servo/LED controller library.
# This will move channel 0 from min to max position repeatedly.
# Author: Tony DiCola
# License: Public Domain
from __future__ import division
import time

# Import the PCA9685 module.
import Adafruit_PCA9685

# Uncomment to enable debug output.
#import logging

# Initialise the PCA9685 using the default address (0x40).
pwm = Adafruit_PCA9685.PCA9685()

# Alternatively specify a different address and/or bus:
#pwm = Adafruit_PCA9685.PCA9685(address=0x41, busnum=2)

# Configure min and max servo pulse lengths
servo_min = 150 # Min pulse length out of 4096
servo_max = 600 # Max pulse length out of 4096

# Helper function to make setting a servo pulse width simpler.
def set_servo_pulse(channel, pulse):
 pulse_length = 1000000 # 1,000,000 us per second
 pulse_length //= 60 # 60 Hz
 print('{0}us per period'.format(pulse_length))
 pulse_length //= 4096 # 12 bits of resolution
 print('{0}us per bit'.format(pulse_length))
 pulse *= 1000
 pulse //= pulse_length
 pwm.set_pwm(channel, 0, pulse)

# Set frequency to 60hz, good for servos.

print('Moving servo on channel 0, press Ctrl-C to quit...')
while True:
 # Move servo on channel O between extremes.
 pwm.set_pwm(0, 0, servo_min)
 pwm.set_pwm(0, 0, servo_max)

There is a good explanation of PWM & Servos here. The important lines of code to note (taken from the Adafruit instructions) are:

  • pwm.set_pwm_freq(60)

    Where the argument is (freq) between 40 and 1000.

    pwm.set_pwm(0, 0, servo_min)

    The arguments are (channel, on, off). The module is 12 bit and so pulse is divided into 4096 “ticks”. For our purposes we need pulse widths from 1mS (minimum) to 2mS (maximum), about 150..600 (centre is about 375) & all starting at 0, the start of the pulse.


Leave a Reply

Your e-mail address will not be published. Required fields are marked *