Arduino Mega 2560 reading from RC-receiver

Hello everyone!

Last few days I’m trying to read signals from 6ch RC-receiver. I used this code for Arduino UNO and it works perfectly:

//This is the full code for RC
//By: Shantanu Sharma
//Date: 23/10/2013.
//contact me at : shantanu.785@gmail.com
#include <PinChangeInt.h>
#include <PinChangeIntConfig.h>
 
int led = 13;
int ch6_pin=11;
int ch5_pin=10;
int ch4_pin=9;
int ch3_pin=8;
int ch2_pin=7;
int ch1_pin=6;
// global values for all the channels
volatile uint16_t ch6_start=0, ch6_global_count=0;
volatile uint16_t ch5_start=0, ch5_global_count=0;
volatile uint16_t ch4_start=0, ch4_global_count=0;
volatile uint16_t ch3_start=0, ch3_global_count=0;
volatile uint16_t ch2_start=0, ch2_global_count=0;
volatile uint16_t ch1_start=0, ch1_global_count=0;
 
volatile uint8_t flag=LOW;//global flag
 
volatile uint8_t ch6_global_flag=LOW;//global flag
volatile uint8_t ch5_global_flag=LOW;//global flag
volatile uint8_t ch4_global_flag=LOW;//global flag
volatile uint8_t ch3_global_flag=LOW;//global flag
volatile uint8_t ch2_global_flag=LOW;//global flag
volatile uint8_t ch1_global_flag=LOW;//global flag
 
// the setup routine runs once when you press reset:
void setup()
{
// initialize the digital pin as an output.
pinMode(led, OUTPUT);
Serial.begin(9600);
// ISR for all channels
PCintPort::attachInterrupt(ch6_pin,ch6_count,CHANGE);
PCintPort::attachInterrupt(ch5_pin,ch5_count,CHANGE);
PCintPort::attachInterrupt(ch4_pin,ch4_count,CHANGE);
PCintPort::attachInterrupt(ch3_pin,ch3_count,CHANGE);
PCintPort::attachInterrupt(ch2_pin,ch2_count,CHANGE);
PCintPort::attachInterrupt(ch1_pin,ch1_count,CHANGE);
Serial.println("press the button");
}
 
// the loop routine runs over and over again forever:
void loop() {
volatile static uint16_t ch6_static_count;//local count
volatile static uint16_t ch5_static_count;//local count
volatile static uint16_t ch4_static_count;//local count
volatile static uint16_t ch3_static_count;//local count
volatile static uint16_t ch2_static_count;//local count
volatile static uint16_t ch1_static_count;//local count
 
volatile static uint8_t updateflags;//lcoal flag
volatile static uint8_t ch6_update_flag;//lcoal flag
volatile static uint8_t ch5_update_flag;//lcoal flag
volatile static uint8_t ch4_update_flag;//lcoal flag
volatile static uint8_t ch3_update_flag;//lcoal flag
volatile static uint8_t ch2_update_flag;//lcoal flag
volatile static uint8_t ch1_update_flag;//lcoal flag
 
if(flag)
{
noInterrupts();
updateflags=flag;
ch6_update_flag=ch6_global_flag;
ch5_update_flag=ch5_global_flag;
ch4_update_flag=ch4_global_flag;
ch3_update_flag=ch3_global_flag;
ch2_update_flag=ch2_global_flag;
ch1_update_flag=ch1_global_flag;
 
if(ch6_update_flag)
{
ch6_static_count=ch6_global_count;
}
if(ch5_update_flag)
{
ch5_static_count=ch5_global_count;
}
if(ch4_update_flag)
{
ch4_static_count=ch4_global_count;
}
if(ch3_update_flag)
{
ch3_static_count=ch3_global_count;
}
if(ch2_update_flag)
{
ch2_static_count=ch2_global_count;
}
if(ch1_update_flag)
{
ch1_static_count=ch1_global_count;
}
// Serial.print("ch6: ");
Serial.println(ch6_static_count);
// Serial.print("\t");
 
// Serial.print("ch5: ");
Serial.println(ch5_static_count);
// Serial.print("\t");
 
// Serial.print("ch4: ");
Serial.println(ch4_static_count);
// Serial.print("\t");
 
// Serial.print("ch3: ");
Serial.println(ch3_static_count);
// Serial.print("\t");
 
// Serial.print("ch2: ");
Serial.println(ch2_static_count);
// Serial.print("\t");
 
// Serial.print("ch1: ");
Serial.println(ch1_static_count);
Serial.print("\n");
 
ch6_global_count=0;
ch6_global_flag=0;
ch6_update_flag=0;
 
ch5_global_count=0;
ch5_global_flag=0;
ch5_update_flag=0;
 
ch4_global_count=0;
ch4_global_flag=0;
ch4_update_flag=0;
 
ch3_global_count=0;
ch3_global_flag=0;
ch3_update_flag=0;
 
ch2_global_count=0;
ch2_global_flag=0;
ch2_update_flag=0;
 
ch1_global_count=0;
ch1_global_flag=0;
ch1_update_flag=0;
flag=0;
interrupts();
 
//use all the ch*_static_count for computation here.
}
digitalWrite(led, HIGH); // turn the LED on (HIGH is the voltage level)
delay(200); // wait for a second
digitalWrite(led, LOW); // turn the LED off by making the voltage LOW
delay(200);
}
void ch6_count()
{
//Serial.println(millis());
if(digitalRead(ch6_pin)==HIGH)
{
ch6_start= micros();
}
else
{
ch6_global_count=(uint16_t)(micros()-ch6_start);
flag=HIGH;
ch6_global_flag=HIGH;
}
}
void ch5_count()
{
//Serial.println(millis());
if(digitalRead(ch5_pin)==HIGH)
{
ch5_start= micros();
}
else
{
ch5_global_count=(uint16_t)(micros()-ch5_start);
flag=HIGH;
ch5_global_flag=HIGH;
}
}
void ch4_count()
{
//Serial.println(millis());
if(digitalRead(ch4_pin)==HIGH)
{
ch4_start= micros();
}
else
{
ch4_global_count=(uint16_t)(micros()-ch4_start);
flag=HIGH;
ch4_global_flag=HIGH;
}
}
void ch3_count()
{
//Serial.println(millis());
if(digitalRead(ch3_pin)==HIGH)
{
ch3_start= micros();
}
else
{
ch3_global_count=(uint16_t)(micros()-ch3_start);
flag=HIGH;
ch3_global_flag=HIGH;
}
}
void ch2_count()
{
//Serial.println(millis());
if(digitalRead(ch2_pin)==HIGH)
{
ch2_start= micros();
}
else
{
ch2_global_count=(uint16_t)(micros()-ch2_start);
flag=HIGH;
ch2_global_flag=HIGH;
}
}
void ch1_count()
{
//Serial.println(millis());
if(digitalRead(ch1_pin)==HIGH)
{
ch1_start= micros();
}
else
{
ch1_global_count=(uint16_t)(micros()-ch1_start);
flag=HIGH;
ch1_global_flag=HIGH;
}
}

But for Mega it doesn’t work: it only prints “Press the button” and doesn’t get impulses from receiver (or doesn’t print the results, but i doubt it).
So the question is: what’s wrong with this code for Mega? “PinChangeInt” library allows interrupts for every pin, as I understood, so I don’t know what causes trouble.

Thank you for you help.

From the playground page on pinChangeInt
"Beginning Version 1.81beta, the library contains MEGA support, although there are some gotchas. Read the release notes and wiki for more info."

How about using hardware interrupts, of which the Mega has 6, instead of pin change interrupts ?

I tried hardware interrupts and it works for me, but if I'll use 6ch transmitter I'll be out of interrupt pins. Now I use 4 channels to transmit impulses (hardware interrupts with pins 2,3,18,19) and pins 20,21 to get data from IMU-sensor. So in case of 6ch transmitter there is no more pins to read data from IMU, for example.

Besides, I'm going to use a lot of sensors and servos with Mega.

That's why I would like to use program interrupts for multiple pins, not only hardware interrupts.

Did you follow up the possible problems with pin change interrupts on the Mega ?

Maybe this is the problem? I use SoftwareSerial as a test on my Mega 2560 just to insure it works. Here is the limitation you will experience on the Mega. This is from the SoftwareSerial page.

Not all pins on the Mega and Mega 2560 support change interrupts, so only the following can be used for RX: 10, 11, 12, 13, 14, 15, 50, 51, 52, 53, A8 (62), A9 (63), A10 (64), A11 (65), A12 (66), A13 (67), A14 (68), A15 (69).

Thank you all very much for your replies!

I tried pins 50-53 and A9-A12 and it works! So issue is solved)