Hi all, as it says in the title i am struggling to detect which pin has triggered my pin change interrupt and to work out how to read the register correctly. My project is going to eventually use 5 infrared sensors to receive a signal and decode so that it can perform various functions dependent upon what triggered it (imagine a infrared target board) the issue i am having is that although i can measure the pulse lengths and decode the infrared i am unable to get this to work with more than a single sensor or work reliably.
The code uses an interrupt to detect a change on any of the pins 2-7 then checks micros, the PIND register and sets a flag so that we can process the pulse into an array before the 600 microseconds gap ends between pulses to only get the pulses i have an if statement to ignore anything that doesn't match with the register B11011 (I think that is pin 3 low) however this seems to be slightly buggy it did work fine and then on attaching another sensor even if its not used and covered up it can cause it all to go to hell.
The goal is to have the header pulse detected and then turn off all other interrupts until i have decoded that code from that sensor but to get that far i need to detect what pin i need to turn the interrupt off, i have attached my code below and a serial printout of what i get when it works correctly using 1 sensor the reason i am using an interrupt is because i will also be using other modules such as RF an LCD screen and i need to ensure that its highest priority is receiving the infrared signal.
/* Infrared Reciever using pin change interrupts for multiple sensors.
* C. Shand
* Created 2018
*/
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) //Clear bit in byte at sfr address.
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit)) //Set bit in byte at sfr address.
volatile long unsigned PrevMicros; //sStore time of last pulse.
volatile long unsigned eventTime; //Store current time.
volatile long unsigned timeSinceLastEvent; //Length of Pulses.
int Pulse = 0; //Keep track of how many pulse lengths we record.
unsigned long bits[15]; //Store lengths here.
byte bin[15]; //store register.
volatile byte portDstatus; //For the regist status to be stored.
volatile byte eventFlag; //Set an even flag.
void setup() {
Serial.begin(57600); //Begin serial communication.
pinMode(3, INPUT); //Setup pin 3 as input.
digitalWrite(3, HIGH); //Pullup pin 3 to high (IR reciever goes low on recieving a signal.)
pinMode(4, INPUT); //Setup pin 4 as input.
digitalWrite(4, HIGH); //Pullup pin 4 to high (IR reciever goes low on recieving a signal.)
Serial.println("Reciever Started..."); //Let us know its ready.
sbi (PCICR, PCIE2); //enable interrupt on PCI2
sbi (PCMSK2, PCINT23); //pins 7.
sbi (PCMSK2, PCINT22); //Pin 6
sbi (PCMSK2, PCINT21); //Pin 5.
sbi (PCMSK2, PCINT20); //Pin 4.
sbi (PCMSK2, PCINT19); //Pin 3.
}
void loop() {
Get_IR(); //Process any IR.
if(Pulse >= 7 && eventFlag == 0){ //If there are no events and we have collected all our data.
for(int i; i < 7; i++){ //Loop through the stored data and display it to the user.
Serial.print("Pulse length: ");
Serial.print(bits[i]);
Serial.print(" - Register: ");
Serial.println(bin[i], BIN);
}
Pulse = 0; //Reset the pulse count.
}
}
int Get_IR(){
if(eventFlag == 1 && (eventTime - PrevMicros > 300)){ //Only process pulses longer than 300 (Would be classed as error or noise) and only run if event flag is 1.
timeSinceLastEvent = eventTime - PrevMicros; //Calculate time ISR has been running.
PrevMicros = eventTime; //Remember the time now.
if(portDstatus == B11011){ //Only add pulses that are from the pin going low.
bits[Pulse] = timeSinceLastEvent; //Store the pulse lengths in array.
bin[Pulse] = portDstatus; //Store the register status in array.
Pulse++; //Increment to next part of array.
}
eventFlag = 0; //Reset the event flag.
}
}
ISR (PCINT2_vect){
portDstatus = PIND; //Record the register status.
eventTime = micros(); //Note time of ISR.
eventFlag = 1; //Set the event flag.
}
Any help would be much appreciated their doesn't seem to be much information "that i can find" about using pin change interrupts without a library to detect the pin with the exception of a few videos saying "now if you want to detect pins you just compare the register status" yes easier said then done apparently.