I am in the process of capturing 6 PWM inputs from an RF receiver for my studies.
I am referring to the AT Mega 2560 datasheet for using the correct registers to generate an interrupt on pin change for pins 10 to 13. That works well.
I am not adding CH4 and CH5 but cannot get things to work using the same principle.
As soon as PCICR |= (1 << PCIE2) serial communication starts giving garbage, and arduino keeps looping in the setup loop. Switching off the register by PCICR &= ~(1 << PCIE2); returns all to normal. Code below
#include <Wire.h>
#include <Servo.h>
//#include <MPU6050_6Axis_MotionApps20.h>
//pin out assignment--------------------------------------------------------------------------------------
//pin 20 SDA MPU Module Comm
//pin 21 SCL
//pin 18 TX1 Bluetooth Module Comm
//pin 19 RX1
#define COGservopin 2 //COG Servo
#define TILTLservopin 3 //Left tilt servo
#define TILTRservopin 4 //Right tilt servo
#define PROPLpin 5 //Left prop motor
#define PROPRpin 6 //Right prop motor
#define MPUint 23 //MPU interrup pin
#define CH1 10 //CH1 PWM i/p port B B00010000 //datasheet ATMEGA2560 par 13.4.7
#define CH2 11 //CH2 PWM i/p port B B00100000
#define CH3 12 //CH3 PWM i/p port B B01000000
#define CH4 13 //CH5 PWM i/p port B B10000000
#define CH5 14 //CH4 PWM i/p port K B01000000
#define CH6 15 //CH6 PWM i/p port K B10000000
//PWM capture input----------------------------------------------------------------------------------------
unsigned long current_count, counter_1, counter_2, counter_3, counter_4, counter_5, counter_6; //PWMwidth timercount
bool last_CH1_state, last_CH2_state, last_CH3_state, last_CH4_state, last_CH5_state, last_CH6_state; //Previous value of the input signal
int input_YAW; //CH1, D10 input
int input_PITCH; //CH2, D11 input
int input_ROLL; //CH3, D12 input
int input_THROTTLE; //CH4, D13 input
int input_CH5; //CH5, A14 input
int input_CH6; //CH6, A15 input
#define CH1min 1020 //Scaling and contsraining limits
#define CH1max 1940 //Scaling and contsraining limits
#define CH2min 1100 //Scaling and contsraining limits
#define CH2max 1920 //Scaling and contsraining limits
#define CH3min 1100 //Scaling and contsraining limits
#define CH3max 1890 //Scaling and contsraining limits
#define CH4min 1020 //Scaling and contsraining limits
#define CH4max 1930 //Scaling and contsraining limits
#define CH5min 1000 //Scaling and contsraining limits
#define CH5max 2000 //Scaling and contsraining limits
#define CH6min 1000 //Scaling and contsraining limits
#define CH6max 2000 //Scaling and contsraining limits
//void setup - single initial run -------------------------------------------------------------------------------
void setup()
{
//IO pins
pinMode(COGservopin, OUTPUT); //COGservo pin configured as output
pinMode(MPUint, INPUT); //MPU interrupt pin
//PortB registers as Interupt sources for capture input of PWM
PCICR |= (1 << PCIE0); //enable PCMSK0 scan ATMEGA Datasheet 15.2.5
PCMSK0 |= (1 << PCINT4); //Set pin Pin10, PB4 trigger an interrupt on state change.
PCMSK0 |= (1 << PCINT5); //Set pin Pin11, PB5 trigger an interrupt on state change.
PCMSK0 |= (1 << PCINT6); //Set pin Pin12, PB6 trigger an interrupt on state change.
PCMSK0 |= (1 << PCINT7); //Set pin Pin13, PB7 trigger an interrupt on state change.
//PortK registers as Interupt sources for capture input of PWM
PCICR |= (1 << PCIE2); //enable PCMSK2 scan ATMEGA Datasheet 15.2.5
PCMSK2 |= (1 << PCINT22); //Set pin Pin14, PK6 trigger an interrupt on state change.
PCMSK2 |= (1 << PCINT23); //Set pin Pin15, PK7 trigger an interrupt on state change.
//PCICR &= ~(1 << PCIE2); // Disable PCINT2 interruptfreaking issue**********************************************************************************************************************************
//Initialise Serial
Serial.begin(57600, SERIAL_8N1); // Initialise serial port (USB & pins 0 1), baud 57600 8 bit no paity
Serial1.begin(9600, SERIAL_8N1); // Initialise serial 1 port (pins 18,19), baud 9600 8 bit no paity
Serial.println("Starting up");
Serial1.println("Starting up");
}
//void main - main program---------------------------------------------------------------------------------------
void loop()
{
Serial.print("CH1: "); Serial.print(input_YAW);
Serial.print("\tCH2: "); Serial.print(input_PITCH);
Serial.print("\tCH3: "); Serial.print(input_THROTTLE);
Serial.print("\tCH4: "); Serial.print(input_ROLL);
Serial.print("\tCH5: "); Serial.print(input_CH5);
Serial.print("\tCH6: "); Serial.println(input_CH6);
}
//Capture input interrupt service routine------------------------------------------------------------------------
ISR(PCINT0_vect)
{
current_count = micros();
//CH1
if(PINB & B00010000) //pin 10 B00010000
{ //AND with the pin state register check if pin is 1
if(last_CH1_state == 0) //from 0 to 1 transition
{
last_CH1_state = 1; //Store the current state into the last state for the next loop
counter_1 = current_count; //Set counter_1 to current value.
}
}
else if(last_CH1_state == 1) // from 1 to 0 transition
{
last_CH1_state = 0; //Store the current state into the last state for the next loop
input_YAW = current_count - counter_1; //CH 1 is current_time - counter_1.
input_YAW = constrain(input_YAW,CH1min,CH1max); //constarin and scale
input_YAW = (int)map(input_YAW,CH1min,CH1max,-100,100);
}
//CH2
if(PINB & B00100000) //pin 11 B00100000
{
if(last_CH2_state == 0)
{
last_CH2_state = 1;
counter_2 = current_count;
}
}
else if(last_CH2_state == 1)
{
last_CH2_state = 0;
input_PITCH = current_count - counter_2;
input_PITCH = constrain(input_PITCH,CH2min,CH2max); //constarin and scale
input_PITCH = (int)map(input_PITCH,CH2min,CH2max,-100,100);
}
//CH 3
if(PINB & B01000000) //pin 12 B01000000
{
if(last_CH3_state == 0)
{
last_CH3_state = 1;
counter_3 = current_count;
}
}
else if(last_CH3_state == 1)
{
last_CH3_state = 0;
input_THROTTLE = current_count - counter_3;
input_THROTTLE = constrain(input_THROTTLE,CH3min,CH3max); //constarin and scale
input_THROTTLE = (int)map(input_THROTTLE,CH3min,CH3max,0,100);
}
//CH 4
if(PINB & B10000000) //pin 13 B10000000
{
if(last_CH4_state == 0)
{
last_CH4_state = 1;
counter_4 = current_count;
}
}
else if(last_CH4_state == 1)
{
last_CH4_state = 0;
input_ROLL = current_count - counter_4;
input_ROLL = constrain(input_ROLL,CH4min,CH4max); //constarin and scale
input_ROLL = (int)map(input_ROLL,CH4min,CH4max,-100,100);
}
//CH 5
if(PINK & B01000000) //pin 14 B01000000
{
if(last_CH5_state == 0)
{
last_CH5_state = 1;
counter_5 = current_count;
}
}
else if(last_CH5_state == 1)
{
last_CH5_state = 0;
input_CH5 = current_count - counter_5;
//input_CH5 = constrain(input_CH5,CH5min,CH5max); //constarin and scale
//input_CH5 = (int)map(input_CH5,CH5min,CH5max,0,100);
}
//CH 6
if(PINK & B1000000) //pin 15 B10000000
{
if(last_CH6_state == 0)
{
last_CH6_state = 1;
counter_6 = current_count;
}
}
else if(last_CH6_state == 1)
{
last_CH6_state = 0;
input_CH6 = current_count - counter_6;
//input_CH6 = constrain(input_CH6,CH6min,CH6max); //constarin and scale
//input_CH6 = (int)map(input_CH6,CH6min,CH6max,0,100);
}
}