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
89 extern "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  */
111 int rc_servo_init(void);
112 
113 /**
114  * @brief Cleans up servo functionality and turns off the power rail.
115  *
116  * @return 0 on success, -1 on failure
117  */
118 void rc_servo_cleanup(void);
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  */
138 int rc_servo_power_rail_en(int en);
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  */
165 int 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  */
189 int 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  */
206 int 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  */
232 int 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  */
257 int rc_servo_send_oneshot_pulse_normalized(int ch, double input);
258 
259 
260 #ifdef __cplusplus
261 }
262 #endif
263 
264 #endif // RC_SERVO_H
265 
266 /** @} end group Servo */
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.
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...
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_power_rail_en(int en)
enables or disables the 6V power rail to drive servos.
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...
void rc_servo_cleanup(void)
Cleans up servo functionality and turns off the power rail.
#define min(a, b)
Definition: rc_usefulincludes.h:73