READ 6 RC PWM CHANNELS USING TIMERS IN ARDUINO MEGA 2560 R3

Hi,

My project is an indoor navigation control of an hexacopter using the Arduino MEGA 2560 R3 and some ultrasound sensors.

I am trying now to read 6 RC PWM channels from a receiver into the arduino, and I have been struggling for some weeks now:

  • I tried the pulseIn() function, which is ok for 1 channel, but very slow when trying to read 6 channels.

  • The functions delay() and micros() use the same Timer, and this leads to wrong PWM readings. Therefore I am trying to use Timers 3,4 & 5.

  • Then I realized there is already a code for this purpose: (Arduino Playground - ReadReceiver); and I found some more, but they were written for other arduino boards and they don´t work in the MEGA straight away.

Since my programming skills are basic, I was doing a lot of reading the past weeks on ATTACHINTERRUPTS and TIMERS and I came up with the following:

  • I have 6 channels and therefore 6 attachInterrupts connected to pins 2,3,21,20,19,28 which are the ones supporting attachments in the MEGA 2560 R3.

  • TIMER5 is set up with no pre-scaling, for which I estimate 16 clicks per micro seconds. Using OCR5A = 16 it should call the ISR(TIMER5_COMPA_vect) every micro second, and run ++counter.

  • For each channel there is an attachInterrupt and 2 functions risex() and fallx(), being x the number of the channel. When the PWM rises, the attachIterrupt(pinx,risex,RISING) activates, and the function risex() sets the counter=0 and modifies the attachInterrupt to (pinx,fallx,FALLING). When the PWM falls the function fallx() counter value is stored.

This is the best I could do so far; it is reading 6 channels at a good sampling time. But there are some problems for which I would thank any helpful comment:

  • Using OCR5A = 16 is not giving the results I expected. I had to scale up the counter value by 4, in order to obtain something between 1000-2000 microseconds.

  • When I plot the signals they are noisy (+- 10 microseconds), I could live with it using an alpha-beta filter. The main problem here is, that when I move the transmitter controls and the PWM of any of the channels changes, the value of the other signals drops some microseconds. It is like the TIMER 5 was busy, and it accumulated delays.

  • I tried to set up TIMER 4 together with TIMER5, but I could not make it work. Only the first one runs, the second is ignored.

That is it. I would thank you a lot any help that you could provide me.

I have attached the code and some pictures.

Best regards

6_Chan_RC_Input.txt (5.58 KB)

20170224_145617.jpg

You can use a Pin Change Interrupt on every pin. Read micros() in the ISR, this should be precise enough. In a RC application the signals don't change really fast, so that you also can poll one input after another, using pulseIn() or your own code.