Read RC Channels from RC receiver from 1 to 8 channels:
Read single RC channel on Pin 8 using Input Capture of 16bit Timer1 with precaler.
Read single RC channel on Pin 2 to 7 using Pin Change Interrupt and 16bit Timer1 with precaler.
Read single RC channel on Pin 2 to 7 using Pin Change Interrupt and 8bit Timer2 with precaler.
Read 6 RC channels on Pin 2 to 7 using Pin Change Interrupt and 8bit Timer2 with precaler.
Hi everyone!
This is my first post I hope you will see some interest in it.
I have a main project that involves reading of a single RC channel but this is not the core of my project. Willing to gain some time I have designed and ordered and received a PCB in order to have a tidy result. Not worried about the way to read PWM signal from any receiver I put this input on Pin 4 of ATMega328 based MCU. I was sure enough that it will be “finger in the nose” operation to find some piece of code on the net to do the job. But it was not…
When I start looking for the “easy to get” piece of code I quickly realize that it was more difficult than expected and by far. I end up in the infamous world of Interrupts, Timers, Prescalers and Bitwise operation! If you look for such code you will find some good tutorials about interrupts but without associated code. It is the same for timers. There are some long pages talking about registers. You will find some pieces of code but not what fulfill your needs.
You may use some good libraries around but not easy to use and most of the time difficult to adapt if needed because the code is a bit “dark”. By the way I recommend the reading (max you can digest) of http://rcarduino.blogspot.fr/. It covers most of what you need to understand this strange world and you can try the library developed by the author (who seems to be a French compatriot).
I join a helpful pdf table made by myself about Timers and Prescaler Calculations.
Ok…So What now!
I decided to make my own code exploring different ways to read PWM signal from RC receiver. I spend a lot of time doing this but at least I’m now much more comfortable with those tricky stuffs. I also realize that it is not based on how smart you are. But much more on how much time you can spend experiencing and by the way understanding. I forgot to mention that after two years “pumping” code lines from every source I could it was time for me to contribute. So here is the result of my contribution. All code is based and tested on Arduino Uno SMD edition R3.
1 Reading single RC channel on Pin 8 using Input Capture of 16bit Timer1 with precaler.
2 Reading single RC channel on Pin 2 to 7 using Pin Change Interrupt and 16bit Timer1 with precaler.
3 Reading single RC channel on Pin 2 to 7 using Pin Change Interrupt and 8bit Timer2 with precaler.
And finaly “la cerise sur le gateau”.
4 Reading 6 RC channels on Pin 2 to 7 using Pin Change Interrupt and 8bit Timer2 with precaler.
NOTE: I made my test with a Futaba 9Channels Rx R149DP PCM1024 and a Futaba 6Channels Rx R156F (PPM). The main problem when it comes to read multi-channel input is that you end up with a single interrupt triggered by one rising plus one falling edge. It don’t makes things easy to put together…
NOTE: There is two ways not covered by this post. The first one is the pulseIn() function because it is a code “holding” function and it makes it useless when it comes to get fast and low time consumption code. The second one is build in External Interrupts mainly because only Pins 2 and 3 can do it and those pins where not available on my project (my mistake). External Interrupts are useful if you need only one or two channels. The following code shall be easy to adapt if you want use this feature.
I hope my code is easy to understand and easy to modify to fit your needs. I’ll surely take any improvement proposal as I’m not a C++ or Java doctor. I’m also interested in performance testing. So if you are willing to torture this code please give some feedback.
Hope my English is still correct.
Enjoy.
I will answer myself to post de code:
Cheers.
Timer Calculation.pdf (45.4 KB)