Hi everyone,
I've been trying to read RC receiver values using interrupts.
Here is the code I'm working on. For now it just prints the values in ms to serial monitor.
//Adding requied libraries
#include <Servo.h>
#include <NewPing.h>
#include <Wire.h>
#define fromLow 900
#define fromHigh 1900
#define toLow 1000
#define toHigh 2000
#define esc_pin 6
#define servo_pin 5
byte last_channel_1, last_channel_2, last_channel_3, last_channel_4, last_channel_5, last_channel_6;
int receiver_input_channel_1, receiver_input_channel_2, receiver_input_channel_3, receiver_input_channel_4, receiver_input_channel_5, receiver_input_channel_6;
int channel_1, channel_2, channel_3, channel_4, channel_5, channel_6;
int esc, servo;
unsigned long timer_channel_1, timer_channel_2, timer_channel_3, timer_channel_4, timer_channel_5, timer_channel_6;
unsigned long timer_1, timer_2, timer_3, timer_4, timer_5, timer_6, current_time;
void setup ()
{
pinMode(esc_pin, OUTPUT);
pinMode(servo_pin, OUTPUT);
//Set PCIE0 to enable PCMSK0 scan.
PCICR |= (1 << PCIE0);
PCMSK0 |= (1 << PCINT0); //Set PCINT0 (digital input 8) to trigger an interrupt on state change.
PCMSK0 |= (1 << PCINT1); //Set PCINT0 (digital input 9) to trigger an interrupt on state change.
PCMSK0 |= (1 << PCINT2); //Set PCINT0 (digital input 10) to trigger an interrupt on state change.
PCMSK0 |= (1 << PCINT3); //Set PCINT0 (digital input 11) to trigger an interrupt on state change.
PCMSK0 |= (1 << PCINT4); //Set PCINT0 (digital input 12) to trigger an interrupt on state change.
PCMSK0 |= (1 << PCINT5); //Set PCINT0 (digital input 13) to trigger an interrupt on state change.
Serial.begin(115200);
}
void loop ()
{
channel_1 = map(receiver_input_channel_1, fromLow, fromHigh, toLow, toHigh);
channel_2 = map(receiver_input_channel_2, fromLow, fromHigh, toLow, toHigh);
channel_3 = map(receiver_input_channel_3, fromLow, fromHigh, toLow, toHigh);
channel_4 = map(receiver_input_channel_4, fromLow, fromHigh, toLow, toHigh);
channel_5 = map(receiver_input_channel_5, fromLow, fromHigh, toLow, toHigh);
channel_6 = map(receiver_input_channel_6, fromLow, fromHigh, toLow, toHigh);
// debug
Serial.print("Channel 1 = ");
Serial.print(channel_1);
Serial.print('\t');
Serial.print("Channel 2 = ");
Serial.print(channel_2);
Serial.print('\t');
Serial.print("Channel 3 = ");
Serial.print(channel_3);
Serial.print('\t');
Serial.print("Channel 4 = ");
Serial.print(channel_4);
Serial.print('\t');
Serial.print("Channel 5 = ");
Serial.print(channel_5);
Serial.print('\t');
Serial.print("Channel 6 = ");
Serial.print(channel_6);
Serial.print('\n');
}
ISR(PCINT0_vect)
{
current_time = micros();
//Channel 1=========================================
if(PINB & B00000001)
{ //Is input 8 high?
if(last_channel_1 == 0)
{ //Input 8 changed from 0 to 1
last_channel_1 = 1; //Remember current input state
timer_1 = current_time; //Set timer_1 to current_time
}
}
else if(last_channel_1 == 1)
{ //Input 8 is not high and changed from 1 to 0
last_channel_1 = 0; //Remember current input state
receiver_input_channel_1 = current_time - timer_1; //Channel 1 is current_time - timer_1
}
//Channel 2=========================================
if(PINB & B00000010 )
{ //Is input 9 high?
if(last_channel_2 == 0)
{ //Input 9 changed from 0 to 1
last_channel_2 = 1; //Remember current input state
timer_2 = current_time; //Set timer_2 to current_time
}
}
else if(last_channel_2 == 1)
{ //Input 9 is not high and changed from 1 to 0
last_channel_2 = 0; //Remember current input state
receiver_input_channel_2 = current_time - timer_2; //Channel 2 is current_time - timer_2
}
//Channel 3=========================================
if(PINB & B00000100 )
{ //Is input 10 high?
if(last_channel_3 == 0)
{ //Input 10 changed from 0 to 1
last_channel_3 = 1; //Remember current input state
timer_3 = current_time; //Set timer_3 to current_time
}
}
else if(last_channel_3 == 1)
{ //Input 10 is not high and changed from 1 to 0
last_channel_3 = 0; //Remember current input state
receiver_input_channel_3 = current_time - timer_3; //Channel 3 is current_time - timer_3
}
//Channel 4=========================================
if(PINB & B00001000 )
{ //Is input 11 high?
if(last_channel_4 == 0)
{ //Input 11 changed from 0 to 1
last_channel_4 = 1; //Remember current input state
timer_4 = current_time; //Set timer_4 to current_time
}
}
else if(last_channel_4 == 1)
{ //Input 11 is not high and changed from 1 to 0
last_channel_4 = 0; //Remember current input state
receiver_input_channel_4 = current_time - timer_4; //Channel 4 is current_time - timer_4
}
//Channel 5=========================================
if(PINB & B00010000)
{
if(last_channel_5 == 0)
{
last_channel_5 = 1;
timer_5 = current_time;
}
}
else if(last_channel_5 == 1)
{
last_channel_5 = 0;
receiver_input_channel_5 = current_time - timer_5;
}
//Channel 6=========================================
if(PINB & B00100000)
{
if(last_channel_6 == 0)
{
last_channel_6 = 1;
timer_6 = current_time;
}
}
else if(last_channel_6 == 1)
{
last_channel_6 = 0;
receiver_input_channel_6 = current_time - timer_6;
}
}
The code works fine on Arduino UNO, but it has a difficult time when I upload it on Arduino Mega 2560.
I believe the problem is somewhere is these lines but I'm unable to identify the source.
//Set PCIE0 to enable PCMSK0 scan.
PCICR |= (1 << PCIE0);
//Set PCINT0 (digital input 8) to trigger an interrupt on state change.
PCMSK0 |= (1 << PCINT0); //Set PCINT0 (digital input 8) to trigger an interrupt on state change.
PCMSK0 |= (1 << PCINT1); //Set PCINT0 (digital input 9) to trigger an interrupt on state change.
PCMSK0 |= (1 << PCINT2); //Set PCINT0 (digital input 10) to trigger an interrupt on state change.
PCMSK0 |= (1 << PCINT3); //Set PCINT0 (digital input 11) to trigger an interrupt on state change.
PCMSK0 |= (1 << PCINT4); //Set PCINT0 (digital input 12) to trigger an interrupt on state change.
PCMSK0 |= (1 << PCINT5); //Set PCINT0 (digital input 13) to trigger an interrupt on state change.