Project 7.0 Working with Servomotors

Configuring a PWM signal to drive a servomotor



In this project you will control externally connected servomotors from the Blackboard. Servos are very common motors which have precise control over their range of motion. Similar to project 3, this project will use the triple timer counter module for timing. Unlike project 3, this project will introduce and use the waveform generating capabilities of the TTC module to control a servo.

Before you begin, you should:

  • Have a basic understanding of PWM signals;
  • Be able to write a C program to communicate with the PC using a UART;
  • Have access to a hobby servomotor
  • Download this module’s Submission Form: Submission Form 7

After you’re done, you should:

  • Understand how DC motors and servomotors operate
  • Know how to create a suitable PWM signal to drive a servo
  • Be able to contol a servmotor’s postion and speed



A servo motor is a rotary or linear actuator that is specifically designed to allow precise control of angular or linear postition. Servo motors are typically used to move a part of a machine to an exact postition, and then actively hold it there. Servo motors typically have a control interface that allows then to be moved at a given rate, and to be started and stopped with well-controlled acceleration. At the low-end of the market, “hobby servos” are small, inexpensive servo motors that used to control consumer products that don’t require exacting controls. Hobby servos are commonly used to control avionics on RC aircraft, or steering on RC cars.

Most hobby servos have a fixed range of rotation, most typically 0 to 180 degrees. Hobby servos use a single data input signal, and the servo’s angular position is controlled by sending a constant stream of periodic pulses on the input signal. About once every 20ms, a pulse ranging from 1ms to 2ms must be delivered to the servo to cause it to set and hold an angular position. A 1ms pulse every 20ms will rotate a servo to its clockwise limit. A 2ms wide pulse in this window will put it to the opposite limit. A 1.5ms pulse every 20ms will center the servo. The window width has some tolerance, but the width of the pulse will always control the servo’s angle.

Output Compare

Most microcontroller systems feature capability to drive periodic signals. This functionality is usually closely coupled with one of a microcontroller’s timer modules. Typically referred to as Output Compare, the output can be triggered by a specific timer value or other events. The Zynq’s TTC Module has a feature called ‘waveform generation’, which is essentially an output compare system. The TTC can be configured to drive a signal when a certain count value is reached and reset when the counter overflows or reaches a defined interval value.

Refer to the backgroud topics to learn more about motors, motor control systems, and servomotor.


1. Center the Servomotor

Configure TTC0 to generate a servo control waveform; Have the timer drive the servo signal high once every 20ms and leave the signal driven for 1.5ms (period of 20ms:1.5ms on, 18.5ms off). This should center the servo. If the servo is not centered when it is connected, it will center itself. if it is centered, it will resist if you try to rotate it to either side.

Before connecting a servo you can verify your signal is correct by looking at the output on an oscilliscope. Another way to verify is by using a multimeter that can do frequency and duty cycle measurements. You should have a frequency of 50Hz and a duty cycle of 7.5% high.

2. Move the servo back and forth over its full range

Have the servo continuously rotate from its minimum angle to its maximum angle and back. Have the servo take 5 seconds to go from one extreme to the other. If you just change the pulse length from 1ms to 2ms, the servo will rotate from one side to the other at it’s maximum speed. Thus, you need to control the speed of servo. An approach is suggested below, you may however design your own solution to the requirement.

One way to address the problem is to periodically change the angle of the servo. If the frequency the angle changes is fixed, then the size of the change will determine how fast the servo moves (how fast the angle changes). Setup the TTC0 to generate interval interrupts which should occur every 20ms (50Hz), this sets the frequency at which the angle is changed (and conveniently it’s the same frequency required to control the servo. When the interrupt occurs, you can change the pulse length by a set amount.

With the interrupt occuring at 50Hz, in 5 seconds there will be 250 interrupts and with a 1ms range of pulse length (from 1ms to 2ms) you will need to increase/decrease the pulse length by 0.004ms per interrupt (1ms /250 interrupts). Some math will required to calculate how much to modify the match value Hint: First find the correlation between the match value and pulse width.

3. Control the servo from a terminal

Use a terminal to control the servo. You should be able to move the servo clockwise a small amount with one command, and move it counter-clockwise with another.

4. Add more commands to the terminal interface

Add more functionality to your terminal UART controller. Have the Terminal be able to set the absolute position of the servo. You can have the pc send a percentage: 0 being the servo’s minimum angle, 50 being centered and 100 being at it’s maximum angle. If you know the range of motion of your servo, you can send an angle instead. Also add functionality that sets the speed the servo moves to a new angle. You can have the speed be set from a number sent from the terminal or you can choose from a number of predetermined speeds.


1. Read the on-board ADC, and position the servo based on the ADCs value

Assume you are making an older-style, analog-like voltmeter. A “needle” can be attached to a stationary servo held in place by a servo stand, and the assembly can be placed infront of a laser-printed voltmeter graphic. An example of how this may look is shown.

Write a program that changes the servo angle based on the position of the on-board potentiometer that is connected ZYNQ’s on-board ADC. When the potentiometer is at its max value, have the servo go to its maximum angle. When the pot is at its minimum value have the servo set to its minimum angle. Make sure the servo goes to in-between values as well.