Robot Control Library
servo.h
Go to the documentation of this file.
1/**
2 * <rc/servo.h>
3 *
4 * @brief Control Servos and Brushless Motor Controllers.
5 *
6 * The Robotics Cape has 8 3-pin headers for connecting hobby servos and ESCs.
7 * These are driven by the PRU for extremely precise signaling with minimal CPU
8 * use. Standard 3-pin servo connectors are not polarized so pay close attention
9 * to the symbols printed in white silkscreen on the cape before plugging
10 * anything in. The black/brown ground wire should always be closest to the cape
11 * PCB. The pinnout for these standard 3 pin connectors is as follows.
12 *
13 * - 1 Ground
14 * - 2 6V Power
15 * - 3 Pulse width signal
16 *
17 * Both servos and Brushless ESCs expect pulse width signals corresponding to
18 * the desired output position or speed. These pulses normally range from 900us
19 * to 2100us which usually corresponds to +- 60 degrees of rotation from the
20 * neutral position. 1500us usually corresponds to the center position. Many
21 * servos work up to +- 90 degrees when given pulse widths in the extended range
22 * from 600us to 2400us. Test the limits of your servos very carefully to avoid
23 * stalling the servos motors.
24 *
25 * | Normalized Width | Pulse Width | Servo Angle |
26 * |:----------------:|:-------------:|:-------------:|
27 * | -1.5 | 600us | 90 deg ccw |
28 * | -1.0 | 900us | 60 deg ccw |
29 * | 0.0 | 1500us | centered |
30 * | 1.0 | 2100us | 60 deg cw |
31 * | 1.5 | 2400us | 90 deg cw |
32 *
33 * Unlike PWM which is concerned with the ratio of pulse width to pulse
34 * frequency, servos and ESCs are only concerned with the pulse width and can
35 * tolerate a wide range of update frequencies. Servos can typically tolerate
36 * update pulses from 5-50hz with more expensive digital models sometimes
37 * capable of higher update rates. Brushless ESCs are much more tolerant and
38 * typically accept update rates up to 200hz with some multirotor ESCs capable
39 * of 400hz when using sufficiently short pulse widths.
40 *
41 * Since ESCs drive motor unidirectionally, it makes more sense to think of
42 * their normalized throttle as ranging from 0.0 (stopped) to 1.0 (full power).
43 * Thus, these functions translate a normalized value from 0.0 to 1.0 to a pulse
44 * width between 1000us and 2000us which is a common factory-calibration range
45 * for many ESCs. We suggest using the rc_calibrate_escs example program on all
46 * ESCs used with the robotics cape to ensure they are calibrated to this exact
47 * pulse range.
48 *
49 * We HIGHLY recommend the use of ESCs which use the BLHeli firmware because
50 * this firmware allows the input pulse range to be programmed to exactly
51 * 1000-2000us and the old fashioned calibration mode to be disabled. This
52 * prevents accidental triggering of calibration mode during use and removes the
53 * need to run rc_calibrate_escs. BLHeli includes a plethora of configurable
54 * settings and features such as easily adjustable timing and sounds. More
55 * information on the BLHeli open source project here.
56 *
57 * Unless calibration mode is disabled, most ESCs will go into a failsafe or
58 * calibration mode if the first signals they receive when powered up are not
59 * their calibrated minimum pulse width corresponding to the throttle-off
60 * condition. Therefore it is necessary for your program to start sending pulses
61 * with a normalized value of 0.0 for a second or more before sending any other
62 * value to ensure expected operation.
63 *
64 * Some ESCs, including those running BLHeli firmware, will wake up but keep the
65 * motor idle when receiving pulses slightly below the minimum. This is largely
66 * undocumented but we call this "idle" mode. For this reason we allow inputs to
67 * rc_send_esc_pulse_normalized and rc_send_esc_pulse_normalized_all to range
68 * from -0.1 to 1.0 where 0.0 results in the lowest throttle the ESC allows and
69 * -0.1 can be used for idle where the motor is entirely powered off but the ESC
70 * is awake.
71 *
72 * A recent trend among ESCs is support of "One-Shot" mode which shrinks the
73 * pulse range down to 125-250us for reduced latency. Like
74 * rc_send_esc_pulse_normalized, these oneshot equivalents also take a range
75 * from -0.1 to 1.0 to allow for idle signals.
76 *
77 * @author James Strawson
78 * @date 3/7/2018
79 *
80 * @addtogroup Servo
81 * @{
82 */
83
84
85#ifndef RC_SERVO_H
86#define RC_SERVO_H
87
88#ifdef __cplusplus
89extern "C" {
90#endif
91
92#define RC_SERVO_CH_MIN 1 ///< servo channels range from 1-8
93#define RC_SERVO_CH_MAX 8 ///< servo channels range from 1-8
94#define RC_SERVO_CH_ALL 0 ///< providing this as an argument writes the same pulse to all channels
95
96
97
98#define RC_ESC_DEFAULT_MIN_US 1000
99#define RC_ESC_DEFAULT_MAX_US 2000
100#define RC_ESC_DJI_MIN_US 1120
101#define RC_ESC_DJI_MAX_US 1920
102
103/**
104 * @brief Configures the PRU to send servo pulses
105 *
106 * Also leaves the servo power rail OFF, turn back on with
107 * rc_servo_power_rail_en(1) if you need to power servos off of the board.
108 *
109 * @return 0 on success, -1 on failure
110 */
112
113/**
114 * @brief Cleans up servo functionality and turns off the power rail.
115 *
116 * @return 0 on success, -1 on failure
117 */
119
120/**
121 * @brief enables or disables the 6V power rail to drive servos.
122 *
123 * The Robotics Cape has a 6V 4A high-efficiency switching regulator to power
124 * servos from the 2 cell LiPo battery. DO NOT enable this when using
125 * BEC-enabled brushless ESCs as it may damage them. Since brushless ESCs only
126 * need the ground and signal pins, it is safest to simply cut or disconnect the
127 * middle power wire. This will allow the use of servos and ESCs at the same
128 * time. Use the enable and disable functions above to control the power rail in
129 * software.
130 *
131 * ALso use this to turn off power to the servos for example when the robot is
132 * in a paused state to save power or prevent noisy servos from buzzing.
133 *
134 * @param[in] en 0 to disable, non-zero to enable
135 *
136 * @return 0 on success, -1 on failure
137 */
139
140
141/**
142 * @brief Sets the pulse width range used by the
143 * rc_servo_esc_send_pulse_normalized() function.
144 *
145 * This function is not necessary when using the default range which is
146 * RC_ESC_DEFAULT_MIN_US (1000) to RC_ESC_DEFAULT_MAX_US (2000). This is only
147 * neccessary when using custom ranges. The most common need for this is when
148 * dealing with DJI motor drivers which cannot be calibrated. In this case use
149 * the line:
150 *
151 * rc_servo_set_esc_range(RC_ESC_DJI_MIN_US, RC_ESC_DJI_MAX_US);
152 *
153 * This will set the range to 1120-1920 for DJI motor drivers. Note that the
154 * minimum value is what is sent when calling rc_servo_usc_send_pulse_normalized
155 * with a desired motor control input of 0. A slightly negative value is still
156 * possible which will send a pulse width shorter than the minimum value given
157 * here. These negative values shoul dbe avoided with DJI motor drivers as they
158 * don't register.
159 *
160 * @param[in] min The minimum pulse width in microseconds
161 * @param[in] max The maximum pulse width in microseconds
162 *
163 * @return 0 on success, -1 on failure.
164 */
165int rc_servo_set_esc_range(int min, int max);
166
167
168/**
169 * @brief Sends a single pulse of desired width in microseconds to one or
170 * all channels.
171 *
172 * This function returns right away and the PRU manages the accurate timing of
173 * the pulse in the background. Therefore calling this function succesively for
174 * each channel will start the pulse for each channel at approximately the same
175 * time.
176 *
177 * As described above, servos and ESCs require regular pulses of at least 5hz to
178 * function. Since these pulses do not have to be accurate in frequency, the
179 * user can use these functions to start pulses from a userspace program at
180 * convenient locations in their program, such as immediately when new positions
181 * are calculated from sensor values.
182 *
183 * @param[in] ch Channel to send signal to (1-8) or 0 to send to all
184 * channels.
185 * @param[in] us Pulse Width in microseconds
186 *
187 * @return 0 on success, -1 on failure
188 */
189int rc_servo_send_pulse_us(int ch, int us);
190
191
192/**
193 * @brief Like rc_send_pulse_us but translates a desired servo position
194 * from -1.5 to 1.5 to a corresponding pulse width from 600 to 2400us.
195 *
196 * We cannot gurantee all servos will operate over the full range from -1.5 to
197 * 1.5 as that is normally considered the extended range. -1.0 to 1.0 is a more
198 * typical safe range but may not utilize the full range of all servos.
199 *
200 * @param[in] ch Channel to send signal to (1-8) or 0 to send to all
201 * channels.
202 * @param[in] input normalized position from -1.5 to 1.5
203 *
204 * @return 0 on success, -1 on failure
205 */
206int rc_servo_send_pulse_normalized(int ch, double input);
207
208
209/**
210 * @brief Like rc_send_pulse_normalized but translates a desired esc
211 * throttle position from 0 to 1.0 to a corresponding pulse width from 1000 to
212 * 2000us.
213 *
214 * This only works as expected if your ESCs are calibrated to accept pulse
215 * widths from 1000-2000us. This is best done with an ESC programming tool but
216 * can also be done with the rc_calibrate_escs example program that comes
217 * installed with this package.
218 *
219 * While the normal operating range for the normalized input is 0.0 to 1.0,
220 * inputs as low as -0.1 are allowed. This is because many ESC firmwares such as
221 * BLHeli will still turn or chirp the motors at 0.0 throttle, but will be
222 * stationary and still armed and awake with throttle values slightly lower. We
223 * suggest using a throttle of -0.1 for at least a second at the beginnig of
224 * your program to wake the ESCs up from sleep but still keep the motors still.
225 *
226 * @param[in] ch Channel to send signal to (1-8) or 0 to send to all
227 * channels.
228 * @param[in] input normalized position from -0.1 to 1.0
229 *
230 * @return 0 on success, -1 on failure
231 */
232int rc_servo_send_esc_pulse_normalized(int ch, double input);
233
234
235/**
236 * @brief Like rc_send_pulse_normalized but translates a desired esc
237 * throttle position from 0 to 1.0 to a corresponding pulse width from 125 to
238 * 250us.
239 *
240 * A recent trend among ESCs is support of "One-Shot" mode which shrinks the
241 * pulse range down to 125-250us for reduced latency. If you are sure your ESCs
242 * support this then you may try this function.
243 *
244 * While the normal operating range for the normalized input is 0.0 to 1.0,
245 * inputs as low as -0.1 are allowed. This is because many ESC firmwares such as
246 * BLHeli will still turn or chirp the motors at 0.0 throttle, but will be
247 * stationary and still armed and awake with throttle values slightly lower. We
248 * suggest using a throttle of -0.1 for at least a second at the beginnig of
249 * your program to wake the ESCs up from sleep but still keep the motors still.
250 *
251 * @param[in] ch Channel to send signal to (1-8) or 0 to send to all
252 * channels.
253 * @param[in] input normalized position from -0.1 to 1.0
254 *
255 * @return 0 on success, -1 on failure
256 */
258
259
260#ifdef __cplusplus
261}
262#endif
263
264#endif // RC_SERVO_H
265
266/** @} end group Servo */
int rc_servo_send_oneshot_pulse_normalized(int ch, double input)
Like rc_send_pulse_normalized but translates a desired esc throttle position from 0 to 1....
void rc_servo_cleanup(void)
Cleans up servo functionality and turns off the power rail.
int rc_servo_power_rail_en(int en)
enables or disables the 6V power rail to drive servos.
int rc_servo_send_esc_pulse_normalized(int ch, double input)
Like rc_send_pulse_normalized but translates a desired esc throttle position from 0 to 1....
int rc_servo_set_esc_range(int min, int max)
Sets the pulse width range used by the rc_servo_esc_send_pulse_normalized() function.
int rc_servo_send_pulse_normalized(int ch, double input)
Like rc_send_pulse_us but translates a desired servo position from -1.5 to 1.5 to a corresponding pul...
int rc_servo_init(void)
Configures the PRU to send servo pulses.
int rc_servo_send_pulse_us(int ch, int us)
Sends a single pulse of desired width in microseconds to one or all channels.
#define min(a, b)
Definition: rc_usefulincludes.h:73