Strategies for driving servos with Raspberry Pi
28 September 2012
The naive thing to do would be to wire them to the GPIO pins on the Raspberry Pi and Google up some open source software that knows how to talk to servos. Unfortunately it’s a bit more complicated than that.
How servos work
In an ordinary RC setup, servos are connected to a unit called a receiver, which maintains a radio link to the handheld transmitter. Servos have a three-lead connector of +5v, PWM signal, and low level. The servo’s position is controlled with the PWM signal. The servo’s arms are connected to your model’s control surfaces. When you move the stick on your transmitter, the servo draws power from the reciever sufficient to generate torque to deflect the control surfaces.
Constraints
Smoothly driving a servo requires a relatively high degree of temporal resolution in the PWM signal. One would need a real-time kernel to generate a good PWM signal in software—vanilla Linux will tend to generate sloppy PWM resulting in jittery, inaccurate servo movements, and the effect would be compounded under heavier CPU load.
Additionally, a single small servo can consume 3-5 watts under load, which is well beyond what the Raspberry Pi can supply. I’m going to have to research how I can obtain or create a dedicated power supply unit for the servos, and still connect their PWM leads to the Arduino or Raspberry Pi.
Approaches to generating PWM signals
We have two options with respect to generating PWM signals. Implement it in software using a real-time Linux kernel, or do it with dedicated hardware.
Most avionics software runs on hard real-time systems. This means that flight software will never interrupted by the OS, but also means that every task the software performs must be completed within a set amount of time. Real-time computers can generate a good PWM signal because the software implementing PWM will never be pre-empted by the operation system—a situation which could cause a too short or too long cycle, or off-phase signal.
Arduino boards are pretty good at generating PWM. The Digispark has hardware PWM on 3 pins. This would be sufficient for a three-channel airframe, but I will probably want 4 or more channels. I am also considering connecting the IMU unit to an Arduino, so availability of of IO pins on the Arduinos and Raspberry Pi might be tight.
Thoughts and feelings
My gut tells me I don’t immediately want to dive into a compiling a real-time kernel for Raspberry Pi just yet. Maybe I need to work on my beard first? Really I just don’t want to risk finding myself in a deep, strange, Linux kernel rabbit hole if I can avoid it.
Having a bunch of Arduino dongles to talk to servos seems a little less elegant than having it all integrated on the Raspberry Pi. And, I suspect I’ll have to use a real-time kernel at some point anyway.
On the other hand, it may be nice from a architecture standpoint to be able to strategically offload some tasks from the Raspberry Pi and onto the Arduinos.
I may end up buying a couple of Digispark boards just because they’re so cheap and rad. If that ends up happening I may use them to control the servos as an excuse to get my hands dirty with Arduino. It seems like a potentially faster way to get some servos moving with minimal effort.
Research items
- Learn how to obtain or create a servo power supply. Power source should be main flight battery. May be possible to use a BEC unit?
- Investigate real-time Linux on Raspberry Pi. What patches/configurations/distros are people using and is it painful?
- Is doing PWM in software a bad idea?
- How does real-time inform the virtualization layer?
- Learn about the interface of an IMU. Should the IMU be connected to the Raspberry Pi or the Arduinos? How many pins will I need for IMU and servos? This will inform which, if any, Arduino boards are used.
Tweet Follow @bvanderveen