Pin change Interrupt Problem 2 - Mega 2560

Hi

So I have got the pin change interrupt working when reading one digital input on pin D10 using the following

//Original code from Tutorial: Pin Change Interrupts on the Arduino
//https://www.youtube.com/watch?v=-rvaUgYVNuI
//Modified to work with arduino Mega 2650 on pin D7


#define Rx_Cooling1 10 //D10 corrisponds to PCINT4 (PCMSK0 / PCIF0 / PCIE0)
boolean Rx_Cooling;
unsigned long Cooling_SignalTime;
unsigned long Cooling_Sig;
unsigned long Cooling_SignalStartTime;

#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))

volatile byte portBstatus;
volatile int eventFlag;
 
int RxUpperSignalLimit = 2100;
int RxLowerSignalLimit = 1000;

void setup() {
Serial.begin(19200);

//define the pins
pinMode(Rx_Cooling1, INPUT);
digitalWrite(Rx_Cooling1, HIGH);

sbi (PCICR, PCIE0);  //Enable interupt PCI2
sbi (PCMSK0, PCINT4);  //Set the interupt control bits for Digital input 10
}

void loop() {
   if(eventFlag == 1){  
     Rx_Cooling = bitRead(portBstatus, 4); //Read bit of digital input 10
     //Cooling
     if(Rx_Cooling == HIGH){
       Cooling_SignalStartTime = micros();
     }
     if(Rx_Cooling == LOW){
       Cooling_SignalTime = (micros() - Cooling_SignalStartTime);
     }     
     if(Cooling_SignalTime > RxLowerSignalLimit && Cooling_SignalTime < RxUpperSignalLimit) Cooling_Sig = Cooling_SignalTime;       
       Serial.print("Wing Fold Signal Time ");
       Serial.println(Cooling_Sig);
   }
   eventFlag = 0;  //Reset event flag
}

//Get binary of Port B whenever D10, D11, D12, D13, D50, D51, D52 or D53 change state
ISR (PCINT0_vect){  
  portBstatus = PINB;
  eventFlag = 1; //Update event flag so that signal time can be calculated
}

How ever when I try and add the same to pin 11 as well as pin 10 using the following it is very slow to update the Cooling_Sig and wings_Sig as Cooling_SignalTime and Wings_SignalTime are way out like 24000, 36000 etc.

//Original code from Tutorial: Pin Change Interrupts on the Arduino
//https://www.youtube.com/watch?v=-rvaUgYVNuI
//Modified to work with arduino Mega 2650 on pin D7


#define Rx_Cooling1 11 //D11 corrisponds to PCINT5 (PCMSK0 / PCIF0 / PCIE0)
boolean Rx_Cooling;
unsigned long Cooling_SignalTime;
unsigned long Cooling_Sig;
unsigned long Cooling_SignalStartTime;

#define Rx_Wings1 10 //D10 corrisponds to PCINT4 (PCMSK0 / PCIF0 / PCIE0)
boolean Rx_Wings;
unsigned long Wings_SignalTime;
unsigned long Wings_Sig;
unsigned long Wings_SignalStartTime;

#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))

volatile byte portBstatus;
volatile int eventFlag;
 
int RxUpperSignalLimit = 2100;
int RxLowerSignalLimit = 1000;

void setup() {
Serial.begin(19200);

//define the pins
pinMode(Rx_Cooling1, INPUT);
digitalWrite(Rx_Cooling1, HIGH);
pinMode(Rx_Wings1, INPUT);
digitalWrite(Rx_Wings1, HIGH);

sbi (PCICR, PCIE0);  //Enable interupt PCI2
sbi (PCMSK0, PCINT4);  //Set the interupt control bits for Digital input 10
sbi (PCMSK0, PCINT5);  //Set the interupt control bits for Digital input 10
}

void loop() {
   if(eventFlag == 1){  
     Rx_Cooling = bitRead(portBstatus, 5); //Read bit of digital input 10
     //Cooling
     if(Rx_Cooling == HIGH){
       Cooling_SignalStartTime = micros();
     }
     if(Rx_Cooling == LOW){
       Cooling_SignalTime = (micros() - Cooling_SignalStartTime);
     } 
     Rx_Wings = bitRead(portBstatus, 4); //Read bit of digital input 10
     //Cooling
     if(Rx_Wings == HIGH){
       Wings_SignalStartTime = micros();
     }
     if(Rx_Wings == LOW){
       Wings_SignalTime = (micros() - Wings_SignalStartTime);
     }     
     if(Cooling_SignalTime > RxLowerSignalLimit && Cooling_SignalTime < RxUpperSignalLimit) Cooling_Sig = Cooling_SignalTime;       
     if(Wings_SignalTime > RxLowerSignalLimit && Wings_SignalTime < RxUpperSignalLimit) Wings_Sig = Wings_SignalTime;       
       Serial.print("Cooling Signal Time ");
       Serial.print(Cooling_Sig);
       Serial.print("\t");
       Serial.print("Wing Fold Signal Time ");
       Serial.println(Wings_Sig);
   }
   eventFlag = 0;  //Reset event flag
}

//Get binary of Port B whenever D10, D11, D12, D13, D50, D51, D52 or D53 change state
ISR (PCINT0_vect){  
  portBstatus = PINB;
  eventFlag = 1; //Update event flag so that signal time can be calculated
}

Update times of Cooling_Sig and Wings_Sig with the above are around half a second, I am after less than 200ms at the most. Cooling_SignalTime and Wings_SignalTime update very fast I would say around 100ms without timing it.
Once again if anyone could help with this that would be great.

sbi (PCMSK0, PCINT4);  //Set the interupt control bits for Digital input 10
sbi (PCMSK0, PCINT5);  //Set the interupt control bits for Digital input 10

Those two comments can't both be right.

Are you using the external interrupt pins for something else? Why not use them instead of pin change interrupts?

sbi (PCMSK0, PCINT4);  //Set the interupt control bits for Digital input 10

sbi (PCMSK0, PCINT5);  //Set the interupt control bits for Digital input 10


Those two comments can't both be right.

Yes you are correct

sbi (PCMSK0, PCINT5);  //Set the interupt control bits for Digital input 10

should be

sbi (PCMSK0, PCINT5);  //Set the interupt control bits for Digital input 11

Are you using the external interrupt pins for something else? Why not use them instead of pin change interrupts?

I am not using external interrupt pins as yes they are being used for something else. I understand that the mega has 6 external interrupt pins on pins 2,3,18,19,20,21. 20 and 21 are used for I2C coms and that only leaves 4 pins available. In total I will want to read 6 rx signals and maybe add more later on. This is why I have gone to Pin change Interrupts.

Anyone have an idea of why this is not working?

Anyone have an idea of why this is not working?

When you have two active pins, your current algorithm does not detect which one has changed and which direction it went so your timings are not correct.

A simple implementation on detecting the pin that caused the interrupt is as follows:

in the isr you define a static variable last_state

when isr is called, one of the 2 pins (10 or 11) has changed, so you read those two values from the port register and xor to last_state. the xor operation will leave the bit set to 1 on any bit that is a different state than the last state. 0 xor 0 = 0, 1 xor 1 = 0, 1 xor 0 = 1, 0 xor 1 =1

ISR (PCINT0_vect){ 
static uint8_t last_state=0;//starting state all low
uint8_t state = PINB & B00110000; //read PINB masked to read only bit 5(pin11) and bit 4 (pin10)
uint8_t value = (state^last_state); // value will be 16 if pin 10 changed or 32 if pin 11 changed 
//you could bitshift >>4 to bring the active bits to the end and value will be 1 or 2
last_state=state;
eventFlag = 1;
}

You can pull the xor value out of the ISR into your loop with the flag like you do, and then from what pin has changed, you can determine if that particular pin is now high or low then do whatever you need to select start and end times for that pin.

Hi cattledog

Thank you for your reply. I have implemented your sugestions as below. Not sure if this is correct or not. Once again it works great while just reading one pin and is much faster than before. However if I try and do it with both pins I run into timing issues again.

#define Rx_Cooling1 11 //D11 corrisponds to PCINT5 (PCMSK0 / PCIF0 / PCIE0)
boolean Rx_Cooling;
unsigned long Cooling_SignalTime;
unsigned long Cooling_Sig;
unsigned long Cooling_SignalStartTime;

#define Rx_Wings1 10 //D10 corrisponds to PCINT4 (PCMSK0 / PCIF0 / PCIE0)
boolean Rx_Wings;
unsigned long Wings_SignalTime;
unsigned long Wings_Sig;
unsigned long Wings_SignalStartTime;

#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))

volatile byte portBstatus;
volatile int eventFlag;
volatile uint8_t PortB_Dec;
 
int RxUpperSignalLimit = 2100;
int RxLowerSignalLimit = 1000;

void setup() {
Serial.begin(19200);

//define the pins
pinMode(Rx_Cooling1, INPUT);
digitalWrite(Rx_Cooling1, HIGH);
pinMode(Rx_Wings1, INPUT);
digitalWrite(Rx_Wings1, HIGH);

sbi (PCICR, PCIE0);  //Enable interupt PCI2
sbi (PCMSK0, PCINT4);  //Set the interupt control bits for Digital input 10
sbi (PCMSK0, PCINT5);  //Set the interupt control bits for Digital input 11
}

void loop() {
  
    //Pin 10 changed
    if(PortB_Dec == 16 && eventFlag == 1){
      //Pin 10 Changed from low to high
      if(bitRead(portBstatus, 4) == HIGH){
        Cooling_SignalStartTime = micros();  //Set the time at which the pin went high
        eventFlag = 0;       
      }
      //Pin 10 Changed from high to low
      if(bitRead(portBstatus, 4) == LOW){
        Cooling_SignalTime = (micros() - Cooling_SignalStartTime);  //Calculate the time that the pin was high for         
        eventFlag = 0;
      }
      if(Cooling_SignalTime > RxLowerSignalLimit && Cooling_SignalTime < RxUpperSignalLimit) Cooling_Sig = Cooling_SignalTime;  //Filter out the crap.
    }
    
    //Pin 11 changed
    if(PortB_Dec == 32 && eventFlag == 1){
      //Pin 10 Changed from low to high
      if(bitRead(portBstatus, 5) == HIGH){
        Wings_SignalStartTime = micros();  //Set the time at which the pin went high
        eventFlag = 0;
      }
      //Pin 10 Changed from high to low
      if(bitRead(portBstatus, 5) == LOW){
        Wings_SignalTime = (micros() - Wings_SignalStartTime);  //Calculate the time that the pin was high for
        eventFlag = 0; 
      }
      if(Wings_SignalTime > RxLowerSignalLimit && Wings_SignalTime < RxUpperSignalLimit) Wings_Sig = Wings_SignalTime;  //Filter out the crap.
    }
    Serial.print("Wings Sig: "); Serial.print(Wings_Sig); Serial.print(", "); Serial.print(Wings_SignalTime); Serial.print("\t");
    Serial.print(" Cooling Sig: "); Serial.print(Cooling_Sig); Serial.print(", "); Serial.println(Cooling_SignalTime);
}


ISR (PCINT0_vect){ 
  static uint8_t last_state=0;//starting state all low  ***Should this be set outside the ISR Routine?? ***
  uint8_t state = PINB & B00110000; //read PINB masked to read only bit 5(pin11) and bit 4 (pin10)
  portBstatus = PINB;
  //             00110000^00100000 = 00010000 = Pin10 has changed - decimal value of 00010000 is 16
  //             00000000^00100000 = 00100000 = Pin11 has changed - decimal value of 00100000 is 32
  PortB_Dec = (state^last_state); // value will be 16 if pin 10 changed or 32 if pin 11 changed 
  //you could bitshift >>4 to bring the active bits to the end and value will be 1 or 2
  last_state=state;  
  eventFlag = 1;
}

Couldnt get this line to compile when I used value outside the ISR so I modified as above.

uint8_t value = (state^last_state); // value will be 16 if pin 10 changed or 32 if pin 11 changed

I’m not seeing anything obviously wrong in the code, and I will try to set up some test signals to run it.

I have moved the debug print outs to what I think are more appropriate locations, and have taken out the range filter. Can you tell me what you see for serial output?

#define Rx_Cooling1 11 //D11 corrisponds to PCINT5 (PCMSK0 / PCIF0 / PCIE0)
boolean Rx_Cooling;
unsigned long Cooling_SignalTime;
unsigned long Cooling_Sig;
unsigned long Cooling_SignalStartTime;

#define Rx_Wings1 10 //D10 corrisponds to PCINT4 (PCMSK0 / PCIF0 / PCIE0)
boolean Rx_Wings;
unsigned long Wings_SignalTime;
unsigned long Wings_Sig;
unsigned long Wings_SignalStartTime;

#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))

volatile byte portBstatus;
volatile int eventFlag;
volatile uint8_t PortB_Dec;
 
int RxUpperSignalLimit = 2100;
int RxLowerSignalLimit = 1000;

void setup() {
Serial.begin(19200);

//define the pins
pinMode(Rx_Cooling1, INPUT);
digitalWrite(Rx_Cooling1, HIGH);
pinMode(Rx_Wings1, INPUT);
digitalWrite(Rx_Wings1, HIGH);

sbi (PCICR, PCIE0);  //Enable interupt PCI2
sbi (PCMSK0, PCINT4);  //Set the interupt control bits for Digital input 10
sbi (PCMSK0, PCINT5);  //Set the interupt control bits for Digital input 11
}

void loop() {
  
    //Pin 10 changed
    if(PortB_Dec == 16 && eventFlag == 1){
      //Pin 10 Changed from low to high
      if(bitRead(portBstatus, 4) == HIGH){
        Cooling_SignalStartTime = micros();  //Set the time at which the pin went high
        eventFlag = 0;       
      }
      //Pin 10 Changed from high to low
      if(bitRead(portBstatus, 4) == LOW){
        Cooling_SignalTime = (micros() - Cooling_SignalStartTime);  //Calculate the time that the pin was high for         
        eventFlag = 0;
        Serial.print("Cooling Sig: "); Serial.print(Cooling_SignalTime); 
      }
     // if(Cooling_SignalTime > RxLowerSignalLimit && Cooling_SignalTime < RxUpperSignalLimit) Cooling_Sig = Cooling_SignalTime;  //Filter out the crap.
    }
    
    //Pin 11 changed
    if(PortB_Dec == 32 && eventFlag == 1){
      //Pin 11 Changed from low to high
      if(bitRead(portBstatus, 5) == HIGH){
        Wings_SignalStartTime = micros();  //Set the time at which the pin went high
        eventFlag = 0;
      }
      //Pin 11 Changed from high to low
      if(bitRead(portBstatus, 5) == LOW){
        Wings_SignalTime = (micros() - Wings_SignalStartTime);  //Calculate the time that the pin was high for
        eventFlag = 0; 
        Serial.print("Wings Sig: "); Serial.print(Wings_SignalTime);
      }
     // if(Wings_SignalTime > RxLowerSignalLimit && Wings_SignalTime < RxUpperSignalLimit) Wings_Sig = Wings_SignalTime;  //Filter out the crap.
    }
   // Serial.print("Wings Sig: "); Serial.print(Wings_Sig); Serial.print(", "); Serial.print(Wings_SignalTime); Serial.print("\t");
   // Serial.print(" Cooling Sig: "); Serial.print(Cooling_Sig); Serial.print(", "); Serial.println(Cooling_SignalTime);
}


ISR (PCINT0_vect){ 
  static uint8_t last_state=0;//starting state all low  ***Should this be set outside the ISR Routine?? ***
  uint8_t state = PINB & B00110000; //read PINB masked to read only bit 5(pin11) and bit 4 (pin10)
  portBstatus = PINB;
  //             00110000^00100000 = 00010000 = Pin10 has changed - decimal value of 00010000 is 16
  //             00000000^00100000 = 00100000 = Pin11 has changed - decimal value of 00100000 is 32
  PortB_Dec = (state^last_state); // value will be 16 if pin 10 changed or 32 if pin 11 changed 
  //you could bitshift >>4 to bring the active bits to the end and value will be 1 or 2
  last_state=state;  
  eventFlag = 1;
}

Can you provide some more information on the signals coming into pins 10 and 11. From your filter the pulses would appear to be 1000-2100 microseconds long.

Update times of Cooling_Sig and Wings_Sig with the above are around half a second, I am after less than 200ms at the most. Cooling_SignalTime and Wings_SignalTime update very fast I would say around 100ms without timing it.
Once again if anyone could help with this that would be great.

This is a little confusing to me. Why would a valid pulse length measurement be updating at a different rate than the measurement. Are only half the measurements valid?

I’m assuming that the incoming pulses of length 1-2.1 ms are coming in every 100 ms for my testing purposes. Is that correct?

What is generating the pulses? Is INPUT_PULLUP (i.e. digitalWrite(pin,HIGH) which you are using, the correct mode for the pins?

Do you have any idea of the separation of the two signals. Is one finished before the other arrives? Or, are the start and stop times overlapped-i.e. both signals are high at some time during the period.

Can you provide some more information on the signals coming into pins 10 and 11. From your filter the pulses would appear to be 1000-2100 microseconds long.
Do you have any idea of the separation of the two signals. Is one finished before the other arrives? Or, are the start and stop times overlapped-i.e. both signals are high at some time during the period.

The signal is from a Rc reciever. It is between 1000 and 2100 microseconds long and has a gap of 20 milliseconds between pulses. The signals can overlap as well.

and have taken out the range filter

No need to take that out as in the debug prints I am printing both the filtered and non filtered value.

This is a little confusing to me. Why would a valid pulse length measurement be updating at a different rate than the measurement. Are only half the measurements valid?

Yes less than half were in the specified range and the ones that were out are around 72000 microsecond so way out. Note that now when using just one input or reading one signal with the new code this problem does not exist at all only 1 in around 100 are invalid which is alright.

Can you tell me what you see for serial output?

Using the code you gave me I get the following. I did change print to println in a few locations. As you can see sometimes Wings_Sig is valid but cooling_Sig is only valid once below.

Cooling Sig: 113360
Wings Sig: 18716
Cooling Sig: 133640
Wings Sig: 38996
Cooling Sig: 436
Wings Sig: 57716
Wings Sig: 67080
Wings Sig: 552
Wings Sig: 1516
Cooling Sig: 45240
Wings Sig: 17528
Wings Sig: 26892
Wings Sig: 36252
Wings Sig: 45612
Wings Sig: 1512
Wings Sig: 1516
Cooling Sig: 110760
Wings Sig: 17612
Cooling Sig: 1316
Wings Sig: 36852
Wings Sig: 46216
Wings Sig: 940
Wings Sig: 1504
Cooling Sig: 45760
Wings Sig: 17164
Wings Sig: 26528
Wings Sig: 35888

The signal is from a Rc reciever. It is between 1000 and 2100 microseconds long and has a gap of 20 milliseconds between pulses. The signals can overlap as well.

To get the program to run reliably I had to structure it for either separated signals or overlapping signals. I could not figure out a version which handled both cases. EDIT: I may be confused about this point, as both versions of the sketch appear to read either overlapping or separated signals. With mismatch they may read every other pulse. I would use the code for separated signals as the control logic is may be easier to understand.

As far as I know, which may not be very far :), your RC signals should be one scheme or the other in order to decode multiple signals in a 20 ms frame.

I set up two simple pulse generation programs on another Arduino and brought the signals to the input pins for Wings and Cooling. One program generated overlapping pulses, and the other separated ones.

//overlapping pulses
void setup() {
  pinMode(3, OUTPUT);//jumper to pin 10 Wings
  pinMode(4, OUTPUT);//jumper to pin 11 Cooling
}
void loop() {
  digitalWrite(3, HIGH);
  delayMicroseconds(400);
  digitalWrite(4, HIGH);
  delayMicroseconds(1000);
  digitalWrite(3, LOW);//wings pulse length 1400
  delayMicroseconds(600);
  digitalWrite(4, LOW);//cooling pulse length 1600
  delay(18);
}
//separated pulses
void setup() {
  pinMode(3, OUTPUT);//jumper to pin 10 Wings
  pinMode(4, OUTPUT);//jumper to pin 11 Cooling
}
void loop() {
  digitalWrite(3, HIGH);
  delayMicroseconds(1400);
  digitalWrite(3, LOW); //wings pulse length 1400
  delayMicroseconds(400);
  digitalWrite(4, HIGH);
  delayMicroseconds(1600);
  digitalWrite(4, LOW);//cooling pulse length 1600
  delay(16);
}

To reliably measure the pulse lengths I added sequence control flags to the edge detection in order to keep the start and stop timings for each pulse aligned. The logic differences between the two cases are subtle. I made some other small changes to the code. 1)made all the isr variables global 2)revised the error detection and print out. Things were running error free.

Here is the sketch for overlapping pulses

//pulse length of overlapping pulses
#define Rx_Cooling1 11 //D11 corrisponds to PCINT5 (PCMSK0 / PCIF0 / PCIE0)
boolean Rx_Cooling;
unsigned long Cooling_SignalTime;
unsigned long Cooling_Sig;
unsigned long Cooling_SignalStartTime;

#define Rx_Wings1 10 //D10 corrisponds to PCINT4 (PCMSK0 / PCIF0 / PCIE0)
boolean Rx_Wings;
unsigned long Wings_SignalTime;
unsigned long Wings_Sig;
unsigned long Wings_SignalStartTime;

#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))

//all ISR variables volatile and global
volatile byte portBstatus;
volatile byte eventFlag;
volatile byte PortB_Dec;
volatile byte last_state;
volatile byte state;

//pin change sequence control flags
byte startWingsFlag;
byte endWingsFlag = 1;//allows first read
byte startCoolingFlag;
byte endCoolingFlag = 1;//allows first read

int RxUpperSignalLimit = 2100;
int RxLowerSignalLimit = 1000;

void setup() {
  Serial.begin(115200);
  //define the pins
  pinMode(Rx_Cooling1, INPUT);
  digitalWrite(Rx_Cooling1, HIGH);//INPUT_PULLUP
  pinMode(Rx_Wings1, INPUT);
  digitalWrite(Rx_Wings1, HIGH);//INPUT_PULLUP

  sbi (PCICR, PCIE0);  //Enable interupt group
  sbi (PCMSK0, PCINT4);  //Set the interupt control bits for Digital input 10
  sbi (PCMSK0, PCINT5);  //Set the interupt control bits for Digital input 11

}

void loop() {

  //Pin 10(Wings)changed
  if (PortB_Dec == 16 && eventFlag == 1) {
    //Pin 10 Changed from low to high
    if (endCoolingFlag && (bitRead(portBstatus, 4)) == HIGH) {
      Wings_SignalStartTime = micros();  //Set the time at which the pin went high
      eventFlag = 0;
      endCoolingFlag = 0;
      startWingsFlag = 1;
    }
    //Pin 10 (Wings) Changed from high to low
    if (startCoolingFlag && (bitRead(portBstatus, 4) == LOW)) {
      Wings_SignalTime = (micros() - Wings_SignalStartTime);  //Calculate the time that the pin was high for
      eventFlag = 0;
      startCoolingFlag = 0;
      endWingsFlag = 1;
      Serial.print("Wings Sig: "); Serial.println(Wings_SignalTime);
      if (Wings_SignalTime < RxLowerSignalLimit || Wings_SignalTime > RxUpperSignalLimit)
        Serial.println("ERROR WINGS!!!!!!!!!!ERROR WINGS");
    }
  }

  //Pin 11(Cooling) changed
  if (PortB_Dec == 32 && eventFlag == 1) {
    //Pin 11 Changed from low to high
    if (startWingsFlag && (bitRead(portBstatus, 5)) == HIGH) {
      Cooling_SignalStartTime = micros();  //Set the time at which the pin went high
      eventFlag = 0;
      startWingsFlag = 0;
      startCoolingFlag = 1;
    }
    //Pin 11(Cooling) Changed from high to low
    if (endWingsFlag && (bitRead(portBstatus, 5) == LOW)) {
      Cooling_SignalTime = (micros() - Cooling_SignalStartTime);  //Calculate the time that the pin was high for
      eventFlag = 0;
      endWingsFlag = 0;
      endCoolingFlag = 1;
      Serial.print("Cooling Sig: "); Serial.println(Cooling_SignalTime);
      if (Cooling_SignalTime < RxLowerSignalLimit || Cooling_SignalTime > RxUpperSignalLimit)
        Serial.println("ERROR COOLING!!!!!!!!!!ERROR COOLING");  //Filter out the crap.
    }
  }
}

ISR (PCINT0_vect) {
  portBstatus = PINB; //read full register
  state = portBstatus & B00110000;//select pins of interest
  PortB_Dec = (state ^ last_state); //XOR value will be 16 if pin 10 changed or 32 if pin 11 changed
  last_state = state;
  eventFlag = 1;
}

Here is the code for separated pulses

//pulse length for separated pulses
#define Rx_Cooling1 11 //D11 corrisponds to PCINT5 (PCMSK0 / PCIF0 / PCIE0)
boolean Rx_Cooling;
unsigned long Cooling_SignalTime;
unsigned long Cooling_Sig;
unsigned long Cooling_SignalStartTime;

#define Rx_Wings1 10 //D10 corrisponds to PCINT4 (PCMSK0 / PCIF0 / PCIE0)
boolean Rx_Wings;
unsigned long Wings_SignalTime;
unsigned long Wings_Sig;
unsigned long Wings_SignalStartTime;

#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))

//all ISR variables volatile and global
volatile byte portBstatus;
volatile byte eventFlag;
volatile byte PortB_Dec;
volatile byte last_state;
volatile byte state;

//pin change sequence control flags
byte startWingsFlag;
byte endWingsFlag = 1;//allows first read
byte startCoolingFlag;
byte endCoolingFlag = 1;//allows first read

int RxUpperSignalLimit = 2100;
int RxLowerSignalLimit = 1000;

void setup() {
  Serial.begin(115200);
  //define the pins
  pinMode(Rx_Cooling1, INPUT);
  digitalWrite(Rx_Cooling1, HIGH);//INPUT_PULLUP
  pinMode(Rx_Wings1, INPUT);
  digitalWrite(Rx_Wings1, HIGH);//INPUT_PULLUP

  sbi (PCICR, PCIE0);  //Enable interupt group
  sbi (PCMSK0, PCINT4);  //Set the interupt control bits for Digital input 10
  sbi (PCMSK0, PCINT5);  //Set the interupt control bits for Digital input 11

}

void loop() {

  //Pin 10 (Wings)changed
  if (PortB_Dec == 16 && eventFlag == 1) {
    //Pin 10 Changed from low to high
    if (endCoolingFlag && (bitRead(portBstatus, 4)) == HIGH) {
      Wings_SignalStartTime = micros();  //Set the time at which the pin went high
      eventFlag = 0;
      endCoolingFlag = 0;
      startWingsFlag = 1;
      
    }
    //Pin 10 (Wings) Changed from high to low
    if (startWingsFlag && (bitRead(portBstatus, 4) == LOW)) {
      Wings_SignalTime = (micros() - Wings_SignalStartTime);  //Calculate the time that the pin was high for
      eventFlag = 0;
      startWingsFlag = 0;
      endWingsFlag = 1;
      Serial.print("Wings Sig: "); Serial.println(Wings_SignalTime);
      if (Wings_SignalTime < RxLowerSignalLimit || Wings_SignalTime > RxUpperSignalLimit)
        Serial.println("ERROR WINGS!!!!!!!!!!ERROR WINGS");
    }
  }

  //Pin 11(Cooling)changed
  if (PortB_Dec == 32 && eventFlag == 1) {
    //Pin 11 Changed from low to high
    if (endWingsFlag && (bitRead(portBstatus, 5)) == HIGH) {
      Cooling_SignalStartTime = micros();  //Set the time at which the pin went high
      eventFlag = 0;
      endWingsFlag = 0;
      startCoolingFlag = 1;
    }
    //Pin 11 (Cooling) Changed from high to low
    if (startCoolingFlag && (bitRead(portBstatus, 5) == LOW)) {
      Cooling_SignalTime = (micros() - Cooling_SignalStartTime);  //Calculate the time that the pin was high for
      eventFlag = 0;
      startCoolingFlag = 0;
      endCoolingFlag = 1;
      Serial.print("Cooling Sig: "); Serial.println(Cooling_SignalTime);
      if (Cooling_SignalTime < RxLowerSignalLimit || Cooling_SignalTime > RxUpperSignalLimit)
        Serial.println("ERROR COOLING!!!!!!!!!!ERROR COOLING");
    }
  }
}

ISR (PCINT0_vect) {
  portBstatus = PINB; //read full register
  state = portBstatus & B00110000;//select pins of interest
  PortB_Dec = (state ^ last_state); //XOR value will be 16 if pin 10 changed or 32 if pin 11 changed
  last_state = state;
  eventFlag = 1;
}

cattledog you sir are a legand.

The sketch for overlapping signals works great :slight_smile: now to nut it out with 6 signals. I am on the right track now though. I will add one signal at a time and adjust the start and end flags to suit.
I thank you for your time. Karma coming your way :slight_smile:

Cheers
Grant