Help Reading PWM with Baby-O 328


I have search all over, and I cannot seem to find what I need.
I am trying to basically use a typical RC controller and reciever to send commands to my Baby-O, and then have the Baby-O control the motors, sensors, servos etc based on that input.

My problem is reading the PWM from the RC reciever. From what I can tell, this will basically output a 1-2ms pulse every 20ms. How do I read this with the Baby-O?

does anyone have a C++ or C example of this?

Thanks for any help!


We have a project where we show how to make a radio-controlled 3pi. The code should work on your Baby-O (you should probably change the includes at the top). I think it may already do what you want. If you have any questions about the code, please ask them here.

- Ryan

Thanks, that code is almost perfect for me.

The only thing I need some assistance on is the very end of the code. It is set up to be a tank steer type code, but I need the two values (forward/reverse & Left/Right) to be independant.

“(int)ch[0].pulse” is my forward/reverse
“(int)ch[1].pulse” is my left/right

how would I re-code this calculation to give me usable values for each channel? Channel [0] output from -255 to 255, and channel [1] output to be from 0 to 200 (this is the range my servo controller needs).

* Mix calculation
* This calculation mixes the pulses from the two channels
* to make control intuitive. Channel 0 controls foward and
* reverse. When the pulse is longer than neutralPulseTime it
* adds to m1 and m2; when the pulse is shorter than nuetralPulseTime
* it subtracts from m1 and m2. Channel 1 controls rotation. When the
* pulse is longer than neutralPulseTime it subtracts from m1 and adds
* to m2; when the pulse is shorter than neutralPulseTime it adds to m1
* and subtracts from m2. m1 and m2 are then scaled so they fit within
* -255 to 255 range.
* Calibration
Sample Project: RC 3pi © 2001–2009 Pololu Corporation
4. Software Page 8 of 11
* Your transmitter/receiver might treat channels 0 and 1 differently
* than the receiver this code was developed for. If your 3pi turns
* when you expect it to go straight or vice versa, you may need to flip
* a sign in the calculation below or swap the connections at the receiver.
long m1 = (neutralPulseTime - (int)ch[0].pulse) +
((int)ch[1].pulse - neutralPulseTime);
long m2 = (neutralPulseTime - (int)ch[0].pulse) -
((int)ch[1].pulse - neutralPulseTime);
m1 = m1 * 255 / minPulseTime;
m2 = m2 * 255 / minPulseTime;
set_motors(m1, m2);

Also, since it’s kind of related.
For my motor I wanted to use the 30:1 MicroMetal Gear Motor. It’s 1000rpm which is what I need, but the Stall current @ 6V: 1600 mA .

Is this too much to put on the Baby-O? I will only be running 1 motor.


The most recently received pulse durations for each channel are stored in the variables ch[0].pulse and ch[1].pulse. If you don’t want to mix them, then just skip the mixing code and scale them appropriately for your application. How you scale them will depend on the range of pulses output by your RC receiver and how you want those pulses to map to servo positions or motor speed. In the end your task will be something like figuring out how to convert a pulse duration number between 300 and 600 into a motor speed between -255 and 255, where 300 corresponds to -255 and 600 corresponds to 255. A simple mapping like this just requires a scale factor and an offset.

The 30:1 micro metal gearmotor HP is slightly above what we would generally recommend for the Baby Orangutan , but it should work okay if you keep the motor from stalling and keep the operating voltage low (maybe under 7 volts). The Baby Orangutan can deliver a continuous 1 A and handle 3 A peaks, so as long as you aren’t repeatedly stalling the motor or alternating between full-speed forward and full-speed reverse, you should be fine.

- Ben