How can I alter my program to read PWM signals from Arduino Mega?
It looks like the code in the ISR is slow and it may compute incorrect results.

It is slow because of using floating point arithmetic in throttle_pwm and aileron_pwm calculations.  It may be so slow that the trailing edge of a PWM pulse occurs while the leading edge still is being processed.  This will delay trailing edge processing, and mis-measurement of pulse lengths.

The main thing to do to reduce the amount of code executed in the ISR is separate the input measuring phase from the output actuating phase.  You could compute pulse widths and store them in volatile variables for a loop in main to pick up and use in analogWrite() statements there.



Note, in 16-bit int arithmetic, the value of expression (t-1500)/1000 is 0 for 500 &lt; t &lt; 2500.   Because throttle and aileron are supposed to be RC pulse lengths in the range 1000 to 2000 μs, your  throttle_pwm and aileron_pwm will be zero.  That means you can replace the following code,

int throttle_pwm = (throttle - 1500) / 1000;
int aileron_pwm = (aileron - 1500) / 1000;
int v = (0.5 - abs(aileron_pwm)) * (throttle_pwm / 0.5) + throttle_pwm;
int w = (0.5 - abs(throttle_pwm)) * (aileron_pwm / 0.5) + aileron_pwm;
int lm = v + (w/2) * 255;
int rm = v - (w/2) * 255;


with this code:

int throttle_pwm=0, aileron_pwm=0, v=0, w=0, lm=0, rm=0;


which should save you several milliseconds of computation!  Also, having lm and rm as constant zeroes means that you don't need all those lengthy and laborious if and else blocks.   You can replace those 24 lines of stuff with just the following:

analogWrite(8,0);
analogWrite(9,0);
analogWrite(10,0);
analogWrite(11,0);




Slightly more seriously, it looks like you intended for your arithmetic like (throttle - 1500) / 1000, etc. to determine whether to raise or lower the throttle, etc.   Instead of doing that time-consuming division, just say:

int throttle_pwm = throttle &gt; 1500 ? 1 : -1;  // or whatever values you meant to have
int aileron_pwm = aileron &gt; 1500 ? 1 : -1;    // ditto


Instead of all those 24 lines of stuff, just say:

analogWrite(8,  (rm&gt;0) * Level);
analogWrite(9,  (rm&lt;=0)* Level);
analogWrite(10, (lm&gt;0) * Level);
analogWrite(11, (lm&lt;=0)* Level);


where Level is some level you want to set the control to.  Note, an expression like (rm&gt;0) has a value 1 when it is true and and 0 when it is false.  So when rm&gt;0, you have, in effect, analogWrite(8,Level); and analogWrite(9,0);.

If instead you end up with a calculation where lm and rm are actually usable PWM levels, ie numbers from 0 to 255, you could instead say:

analogWrite(8,   (rm&gt;0) * rm);
analogWrite(9,  -(rm&lt;=0)* rm);
analogWrite(10,  (lm&gt;0) * lm);
analogWrite(11, -(lm&lt;=0)* lm);


or could say:

analogWrite(8,  rm&gt;0  ?  rm : 0);
analogWrite(9,  rm&lt;=0 ? -rm : 0);
analogWrite(10, lm&gt;0  ?  lm : 0);
analogWrite(11, lm&lt;=0 ? -lm : 0);




Also see my answer to the question  Read RC receiver channels using Interrupt instead of PulseIn and see my answer to the question  Arduino read PWM duty cycle value with input (analog / digital).