Using interrupts to interpret number of pulses and control flow

Hello

I'm new to interrupts and require some guidance please. I hooked up a Leonardo (Atmel 32u4) to an external system that sends the following pulses:

Active HIGH

No. of Pulses State
1 ON
2 OFF
3 Error

The period between the pulses is 1 second. My program detects the pulse and the interrupt is trigged accordingly. I am struggling to get the logic correct to interpret the pulses and record the state. So for 1 pulse it determines it correctly. However for 2 pulses, it detects the second pulse as an individual pulse which is incorrect. I think I need to record the time of the pulses somehow, but I'm unclear on how to achieve this.

I have o scope readings if required..

My program is below:

volatile int IRQcount;
 int result=0;
  unsigned long time1,time2;
  
void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  Serial.println("Testing Interrupt v1.0");
  pinMode(7, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(7), IRQcounter, FALLING);
 
  
}

void loop() {
  // put your main code here, to run repeatedly:
  //IRQcount=-1;
  

  delay(100);

  cli();//disable interrupts
  //result = IRQcount;
  sei();//enable interrupts
 
  if (result ==1) {
    Serial.println("ON");
    
   result=0;
  }
  
  if (result==2) {
    Serial.println("OFF");
    result =0;
  }

  
 // Serial.print(F("Counted = "));
  //Serial.println(result);
}

void IRQcounter() {
  Serial.println("BEEP");
  

  IRQcount++;
    result=1;
  

    if(IRQcount ==2) {
       IRQcount = 0;
       result =2;
    }
}

Sample output

BEEP
ON   (correct)
BEEP
OFF
BEEP
ON     (incorrect)
BEEP
OFF
BEEP
ON
BEEP
OFF
BEEP
ON
BEEP
OFF
BEEP
ON
void IRQcounter() {
  Serial.println("BEEP");

avoid putting Serial read/write in your ISR.

volatile int IRQcount;
//int result = 0;
//unsigned long time1, time2;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  Serial.println("Testing Interrupt v1.0");
  pinMode(7, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(7), IRQcounter, FALLING);
}

void loop() {
  if (IRQcount) {
    Serial.println(F("Beep"));
    IRQcount--;
  }
}

void IRQcounter() {
  IRQcount++;
}

I think I need to record the time of the pulses somehow

The millis() function sounds what you are looking for.

Yes thank you, if I include this in the ISR, then it would be reset each time, so I need to store it outside of the ISR right ?

Thanks ! I never thought of that :frowning:

I'll give it a shot.