Radio Controller Input -> Servo Output

Hi everyone,

I don't have an Arduino yet or any real electronics experience (I'm a programmer and mechanic). I'm building a radio controlled "robot" of sorts. I've read up on controlling servos with Arduino. I'd like to use Arduino as a sophisticated "mixer" for the servos. Since servos are controlled with PWM signals, the R/C controller must output that (so obvious, but it's the intro to the question...). The question is, can I read the PWM from the R/C receiver? I understand the Arduino has 6 analog inputs and PWM is used to "simulate" analog output, so do the analog inputs sort of electrically average the PWM signal into a voltage, then convert to a number? Would this be the approach to take?

Feel free to point me to existing resources if this is a common issue.

Thanks for your patience with the newbie!

-Daryl

I don't think you would get good results treating the PWM inputs as analog values. You could put a low pass filter on it and probably make it work, but it would probably be noisy. You would be better off processing them digitally by using pulseIn() to measure the length of the pulse and working from that. For N channels of input you could probably manage about 20/N updates per second with that scheme but it would be very accurate.

Thanks, Jim. I should have figured if the digital pins can send PWM they ought to be able to read it.

It seems pulseIn() blocks until the pulse is read. If the R/C receiver sends a pulse every (a little less) than 50 millis, we could lose a lot of time. Could one write an object wrapper like the Servo library to read and time the pulse input (refreshing as often as possible rather than every 50 millis or so)? BTW, about how many instructions per second does the Arduino execute?

Thanks.

Most instructions take 1 clock cycles, things that access memory or branch take 2 more or less, there are some that take a few more. So figure nearly 16 million instructions per second.

It would be possible to make a multiple pin pulseIn type call that would watch all of the pins you cared about for pulse start and end. It gets tricky to tune because you end up with a bunch of code paths to be timed and corrected.

If you can live with 64 microsecond accuracy, which gives you about 20 distinct positions for an input, then it can be done fairly well by watching all the inputs and one of the PWM counters (which tick every 64 microseconds). Record when a pin goes high, record when it goes low, subtract to get the length. If you get a negative value, you rolled over the counter... add a counter's worth to it.

You may be able to use an electronic speed controller as an analog output from the receiver, although that'll increase your cost quite a bit for lots of channels...

-Z-

It would be possible to make a multiple pin pulseIn type call ...

Ok, great tips, Jim. I write web applications all day, so this real-time coding should be interesting...

It would be possible to make a multiple pin pulseIn type call ... If you can live with 64 microsecond accuracy, which gives you about 20 distinct positions for an input, then it can be done fairly well by watching all the inputs and one of the PWM counters (which tick every 64 microseconds).

Pardon my ignorance, but it seems that reading multiple PWM inputs should be fairly common, I've seen some projects doing just the thing I want to do (though not Arduino). Does anyone have any examples, references to existing projects, etc. that I can look at to understand the obstacles?

It seems the way to go is to have one timer control loop that services a number of objects on a reasonably tight schedule. How does one "watch" a timer or trigger a regularly scheduled block of code?

Thanks.

Any update on this? Im also interested in the same application. Thanks!

I haven't seen any examples but I had an idea.

Suppose you had a service function to call every 100 microseconds. We don't have a function to read micro seconds elapsed and milliseconds elapsed is too coarse. It's clear that counting loops is not practical - or is it? Assume the service function took roughly the same amount of time to run each call - maybe 5-10% variation. You could call the service function, then loop X number of times. If you do this 1000 times (call service() then loop X times), 100 milliseconds should have passed. We can measure this. If only 80 milliseconds passed, we know we need to increase X by 25%. We end up with a high resolution, self correcting control loop. This concept can be mocked up in any language with a millisecond timer without an Arduino. You could use a PWM counter instead of the milliseconds, but I'm not sure it matters much - it would correct more often but after the first few corrections, it shouldn't need much correction given the assumption above.

Greetings, It would be good to recall that a radio control receiver is actually a receiver/decoder. The format of the radio signal is:

  • Channel 1 pulse width - Channel 2 pulse width - Channel 3 pulse width - - - Channel n pulse width - Extra long pulse for Reset to Channel 1.

By hacking the receiver/decoder and finding the input to the decoder chip you could get all the channels on one Arduino input. Then you could output the channels to individual Arduino outputs or combine them in a pulse stream back to the decoder chip, or write the positions to another external board.

You may need to check out the timer tutorials on avrfreaks.net. Then you would need to either hack the Arduino libraries (which I have not done) or program using WinAVR (similar to Arduino but not as easy) then you can get full access to the timers

Most instructions take 1 clock cycles, It would be possible to make a multiple pin pulseIn type call that would watch all of the pins you cared about for pulse start and end. It gets tricky to tune because you end up with a bunch of code paths to be timed and corrected.

Something which is not clear to me is whether or not the program will be stuck in the pulsein instruction (as it does with a while) all the time the pin is, let say, HIGH. The reason why this is important to me is that I need to measure simultaneously the reception times of 4 ultrasonic transducers. Can I have 4 different pulseIn instructions corresponding to the 4 pins where the signals of the us transducers input to the board? And then the times I will get do they correspond to the individual times during which each pin has been HIGH or should I have to substract something?