Wixel SDK
Macros | Functions
servo.h File Reference
#include <cc2511_map.h>
#include <cc2511_types.h>

Go to the source code of this file.

Macros

#define SERVO_MAX_TARGET_MICROSECONDS   2500
 
#define SERVO_TICKS_PER_MICROSECOND   24
 

Functions

void servosStart (uint8 XDATA *pins, uint8 numPins)
 
void servosStop (void)
 
BIT servosStarted (void)
 
BIT servosMoving (void)
 
void servoSetTarget (uint8 servoNum, uint16 targetMicroseconds)
 
uint16 servoGetTarget (uint8 servoNum)
 
void servoSetSpeed (uint8 servoNum, uint16 speed)
 
uint16 servoGetSpeed (uint8 servoNum)
 
uint16 servoGetPosition (uint8 servoNum)
 
void servoSetTargetHighRes (uint8 servoNum, uint16 target)
 
uint16 servoGetTargetHighRes (uint8 servoNum)
 
uint16 servoGetPositionHighRes (uint8 servoNum)
 
 ISR (T1, 0)
 

Detailed Description

The servo.lib library provides the ability to control up to 6 RC servos by generating digital pulses directly from your Wixel without the need for a separate servo controller.

This library uses Timer 1, so it will conflict with any other library that uses Timer 1.

With the exception of servosStop(), the functions in this library are non-blocking. Pulses are generated in the background by Timer 1 and its interrupt service routine (ISR).

This library uses hardware PWM from Timer 1 to generate the servo pulses, so it can only generate servo pulses on the following pins:

The period of the servo signals generated by this library is approximately 19.11 ms (0x70000 clock cycles). The allowed pulse widths range from one 24th of a microsecond to 2500 microseconds, and the resolution available is one 24th of a microsecond.

For example code that uses this library, please see the example_servo_sequence app in the Wixel SDK's apps directory.

Wiring servos

To control servos from your Wixel, you will need to wire them properly.

Most standard radio control servos have three wires, each a different color. Usually, they are either black, red, and white, or they are brown, red, and orange/yellow:

The ground and power wires of the servo will need to be connected to a power supply that provides a voltage the servo can tolerate and which provides enough current for the servo.

The ground wire of the servo also needs to be connected to one of the Wixel's GND pins. If you are powering the Wixel from the same power supply as the servos, then you have already made this connection.

The signal wire of the servo needs to connect to an I/O pin of the Wixel that will be outputting servo pulses. These pins are specified by the parameters to servosStart().

More information about servos

For more information about servos and how to control them, we recommend reading this series of blog posts by Pololu president Jan Malasek:

  1. Introduction to an introduction to servos
  2. Introduction to servos
  3. Gettin' all up in your servos
  4. Servo, servo motor, servomotor (definitely not server)
  5. Electrical characteristics of servos and introduction to the servo control interface
  6. Servo control interface in detail
  7. Simple hardware approach to controlling a servo
  8. Simple microcontroller approach to controlling a servo
  9. Advanced hobby servo control pulse generation using hardware PWM
  10. Advanced hobby servo control using only a timer and interrupts
  11. RC servo speed control
  12. Continuous-rotation servos and multi-turn servos

Definition in file servo.h.

Macro Definition Documentation

#define SERVO_MAX_TARGET_MICROSECONDS   2500

The maximum allowed target of a servo, in microseconds.

Definition at line 82 of file servo.h.

#define SERVO_TICKS_PER_MICROSECOND   24

This defines the units used by the high resolution functions in this library to represent positions and targets.

Definition at line 86 of file servo.h.

Function Documentation

ISR ( T1  ,
 
)

Timer 1 interrupt.

Definition at line 59 of file servo.c.

uint16 servoGetPosition ( uint8  servoNum)
Parameters
servoNumA servo number between 0 and 5. This number should be less than the associated numPins parameter used in the last call to servosStart().
Returns
The current width in microseconds of pulses being sent to the specified servo. This will be equal to the last target set by servoSetTarget() unless there is a speed limit enabled for the servo.

Please note that this function does not return the actual physical position of the specified servo. This function returns the width of the pulses that are currently being sent to the servo, which is entirely determined by previous calls to servoSetTarget() and servoSetSpeed(). The standard RC servo interface provides no way to query a servo for its current position.

Definition at line 327 of file servo.c.

uint16 servoGetPositionHighRes ( uint8  servoNum)

This is the high resolution version of servoGetPosition(). The units of the returned position are 24ths of a microsecond, so a value of 24000 corresponds to 1000 microseconds.

Definition at line 337 of file servo.c.

uint16 servoGetSpeed ( uint8  servoNum)
Returns
The speed of the specified servo.

See servoSetSpeed() for more information.

Definition at line 353 of file servo.c.

uint16 servoGetTarget ( uint8  servoNum)
Parameters
servoNumA servo number between 0 and 5. This number should be less than the associated numPins parameter used in the last call to servosStart().
Returns
The target position of the specified servo, in units of microseconds.

Definition at line 322 of file servo.c.

uint16 servoGetTargetHighRes ( uint8  servoNum)

This is the high resolution version of servoGetTarget(). The units of the returned target position are 24ths of a microsecond, so a value of 24000 corresponds to 1000 microseconds.

Definition at line 332 of file servo.c.

void servoSetSpeed ( uint8  servoNum,
uint16  speed 
)

Sets the speed limit of the specified servo.

Parameters
servoNumA servo number between 0 and 5. This number should be less than the associated numPins parameter used in the last call to servosStart().
speedThe speed limit of the servo, or 0 for no speed limit. The valid values for this parameter are 0-65535.

The speed limit is in units of 24ths of a microsecond per servo period, or 2.18 microseconds per second.

At a speed limit of 1, the servo output would take 459 seconds to move from 1 ms to 2 ms. More examples are shown in the table below:

Speed limit examples
Speed limitTime to change output from 1 to 2 ms (s)
1458.75
765.54
4510.19
915.04
2292.00
4581.00
9170.50
S458752 / (1000*S)

Definition at line 346 of file servo.c.

void servoSetTarget ( uint8  servoNum,
uint16  targetMicroseconds 
)

Sets the specified servo's target position in units of microseconds.

Parameters
servoNumA servo number between 0 and 5. This number should be less than the associated numPins parameter used in the last call to servosStart().
targetMicrosecondsThe target position of the servo in units of microseconds. A typical servo responds to pulse widths between 1000 and 2000 microseconds, so appropriate values for this parameter would be between 1000 and 2000. The full range of allowed values for this parameter is 0-2500. A value of 0 means to stop sending pulses, and takes effect immediately regardless of the speed limit for the servo.

This is a non-blocking function that only takes a few microseconds to execute. Servos require much more time that that to actually reach the commanded position (on the order of hundreds of milliseconds).

Here is some example code:

1 servoSetTarget(0, 1000); // Start sending servo 0 to the 1000us position.
2 servoSetTarget(1, 1500); // Start sending servo 1 to the 1500us position.
3 servoSetTarget(2, 2000); // Start sending servo 2 to the 2000us position.

If the speed limit of the servo is 0 (no speed limit), or the current target is 0, or the targetMicroseconds parameter is 0, then this function will have an immediate effect on the variable that represents the position of the servo (which is returned by servoGetPosition()). This allows you to perform sequences of commands like:

1 servoSetSpeed(0, 0);
2 servoSetTarget(0, 1000); // Immediately sets position variable to 1000.
3 servoSetSpeed(0, 200);
4 servoSetTarget(2000); // Starts the position variable slowly changing from 1000 to 2000.

or

1 servoSetSpeed(0, 200);
2 servoSetTarget(0, 0); // Immediately sets position variable to 0 (pulses off).
3 servoSetTarget(0, 1000); // Immediately sets position variable to 1000.
4 servoSetTarget(0, 2000); // Starts the position variable slowly changing from 1000 to 2000.

These two sequences of commands each have the same effect, which is to immediately set the position variable for servo number 0 to 1000 microseconds and then slowly change it from 1000 to 2000 microseconds. Please note that the servo's actual physical position does not change immediately; it will lag behind the position variable. To make sure the servo actually reaches position 1000 before it starts moving towards 2000, you might want to add a delay after servoSetTarget(0, 1000);, but keep in mind that most other Wixel libraries require regular attention from the main loop.

If you need more than 1-microsecond resolution, see servoSetTargetHighRes().

Definition at line 292 of file servo.c.

void servoSetTargetHighRes ( uint8  servoNum,
uint16  target 
)

This is the high resolution version of servoSetTarget(). The units of target are 24ths of a microsecond, so a value of 24000 corresponds to 1000 microseconds.

Definition at line 298 of file servo.c.

BIT servosMoving ( void  )
Returns
1 if there are servos that are still moving towards their target position (limited by the speed limit), otherwise returns 0.

This function is equivalent to, but much faster than:

1 servoGetTarget(0) == servoGetPosition(0) &&
2 servoGetTarget(1) == servoGetPosition(1) &&
3 servoGetTarget(2) == servoGetPosition(2) &&
4 servoGetTarget(3) == servoGetPosition(3) &&
5 servoGetTarget(4) == servoGetPosition(4) &&
6 servoGetTarget(5) == servoGetPosition(5)

Definition at line 287 of file servo.c.

void servosStart ( uint8 XDATA pins,
uint8  numPins 
)

This function starts the library; it sets up the servo pins and the timer to be ready to send servo pulses. This function should be called before any other functions in the library.

Parameters
pinsA pointer to an array of pin numbers that specifies which pins will be used to generate servo pulses. The pin numbers used in this array are the same as the pin numbers used in the GPIO library (see gpio.h). There should be no repetitions in this array, and each entry must be one of:
  • 2 (for P0_2)
  • 3 (for P0_3)
  • 4 (for P0_4)
  • 10 (for P1_0)
  • 11 (for P1_1)
  • 12 (for P1_2)
numPinsThe size of the pin number array.

The pins specified in the pins array will be configured as digital outputs, their targets will be initialized to 0 (no pulses), and their speed limits will be initialized to 0 (no speed limit).

If the pins parameter is 0 (a null pointer), then this function skips the initialization of the pins and the internal data structures of the library. This means that the servo pin assignments, positions, targets, and speeds from before will be preserved.

The parameters to this function define the correspondence of servo numbers to pins. The servoNum parameter in the other library functions can be thought of as an index in the pins array. For example, a servoNumber of 0 corresponds to pins[0], the first pin in the array.

Example code:

1 uint8 CODE pins[] = {10, 12}; // Use P1_0 and P1_2 for servos.
2 servosStart((uint8 XDATA *)pins, sizeof(pins));
3 servoSetTarget(0, 1500); // Affects pin P1_0
4 servoSetTarget(1, 1500); // Affects pin P1_2

Definition at line 170 of file servo.c.

BIT servosStarted ( void  )
Returns
1 if the library is currently active and using Timer 1, or 0 if the library is stopped.

Calling servosStart() changes this value to 1. Calling servosStop() changes this value to 0.

Timer 1 can be used for other purposes while the servo library is stopped.

Definition at line 282 of file servo.c.

void servosStop ( void  )

Stops the library; stops sending servo pulses and turns off Timer 1. After this function runs, the pins that were used for servo pulses will all be configured as general-purpose digital outputs driving low.

You can later restart the servo pulses by calling servosStart().

This is a blocking function that can take up to 2.8 milliseconds to finish because it ensures that the pulses are shut off cleanly without any glitches.

Definition at line 256 of file servo.c.