Wixel SDK
|
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) | |
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.
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().
For more information about servos and how to control them, we recommend reading this series of blog posts by Pololu president Jan Malasek:
Definition in file servo.h.
#define SERVO_MAX_TARGET_MICROSECONDS 2500 |
#define SERVO_TICKS_PER_MICROSECOND 24 |
servoNum | A servo number between 0 and 5. This number should be less than the associated numPins parameter used in the last call to servosStart(). |
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.
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.
See servoSetSpeed() for more information.
servoNum | A servo number between 0 and 5. This number should be less than the associated numPins parameter used in the last call to servosStart(). |
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.
Sets the speed limit of the specified servo.
servoNum | A servo number between 0 and 5. This number should be less than the associated numPins parameter used in the last call to servosStart(). |
speed | The 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 | Time to change output from 1 to 2 ms (s) |
---|---|
1 | 458.75 |
7 | 65.54 |
45 | 10.19 |
91 | 5.04 |
229 | 2.00 |
458 | 1.00 |
917 | 0.50 |
S | 458752 / (1000*S) |
Sets the specified servo's target position in units of microseconds.
servoNum | A servo number between 0 and 5. This number should be less than the associated numPins parameter used in the last call to servosStart(). |
targetMicroseconds | The 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:
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:
or
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().
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.
BIT servosMoving | ( | void | ) |
This function is equivalent to, but much faster than:
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.
pins | A 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:
|
numPins | The 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:
BIT servosStarted | ( | void | ) |
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.
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.