I would like to "perform a given operation only while there is an interrupt, and not when there is no interrupt"

I would like to "perform a given operation only while there is an interrupt, and not when there is no interrupt".

(1) Each time there is an interrupt, pulse++ is executed and stored in now1.
(2) Compare the value of now1 with the last time, judge that there is an interrupt if there is a change, and perform the prescribed operation in a loop. (In this case, the LED is blinked.)

#define LED1 (13)
  
  /*pulsecounter*/
  volatile unsigned int pulse1 = 0;        
  volatile unsigned int now ;
  volatile unsigned int now0 ;
  volatile unsigned int now1 ;         
  volatile unsigned int old ;                   

void setup(){
             DDRB &= ~_BV(0); //interrupt_port     
                         
             }

 
void loop(){
  
            now0 = now1;
             
            if(old ! = pulse1){
                              PORTB ^= _BV(5);  
                              }                            
                               old = pulse1;   
                                                                  
            if (old == now0){
                            PORTB &= ~_BV(5) ;
                            }
}
 

ISR (PCINT0_vect){                 
                  old = now0;
                   
                   pulse1++;

                  now1 = pulse1;
                 }

Q1) The prescribed operation is successful when there is an interrupt. However, the operation cannot be stopped when there is no interrupt. (will not the LED is turned off.)

Q2) I tried to get the value of pulse at regular intervals by millis or Timer2 and compare them, but the acquired value is kept and the comparison does not work.

Q3) I would like to know how to determine in real time whether there is or is not an interruption.

Thank you all in advance!

Why use an interrupt at all? Why not just scan the inputs and use millis() to see when an input changes and compare with old value to see changes?

Thanks for the reply.

It is detecting a high speed pulse, so it had to be an interrupt to detect it.

so you're worried that simply polling may miss the pulse, right?

have the interrupt set a flag which is monitored within loop() and that code clears the flag after it performs some processing

1 Like

Thanks for the reply.

so you're worried that simply polling may miss the pulse, right?
→That is correct.

I used FLAG as you suggested.
However, it seems that state=1; from the beginning. I am unable to set it back to 0 even when there are no interrupts.

Could you please give me a hint?

#define LED1  (13)
  
/*FLAG*/
volatile int state = 0 ;             

void setup(){
             DDRB &= ~_BV(0);    //interrupt_port   

             /*interrupt*/
             PCICR |= B00000111;     //PCIE0
             PCMSK0 |= B00011001;      
             }

 
void loop(){

  /*FLAG*/
  state = 0 ; 
             
            if(state=1){ PORTB ^= _BV(5);}                            
                                                                  
            else if (state=0){ PORTB &= ~_BV(5);}
                                        
}

ISR (PCINT0_vect){   
                  /*FLAG*/
                   state=1;                
                 }  `
``整形済みテキスト

only set state back to zero when it is set.
not sure what you need to do when it is not set

void loop()
{
    if (state == 1)  {
        state = 0 ;
        PORTB ^= _BV(5);
    }
}

Thank you very much.
I have tried it.

The LED now responds when there is an initial interrupt.

However, it is lit very dimly.
Is the operation not catching up?

By the way.
PORTB ^= _BV(5); //inverted
↓ ↓
PORTB |= _BV(5); //lighted

I tried to change the value , but it remained the same.

Also, it seems that state=0; is not set when there is no interrupt.
I cannot go back after the light is turned on.

Translated with DeepL

Post your complete current code.

OK.
LED is lit when there is an interrupt.
When there is no interrupt, LED is off.

#define LED1  (13)
  
/*FLAG*/
volatile int state  ;             

void setup(){
             DDRB &= ~_BV(0);    //interrupt_port   

             /*interrupt*/
             PCICR |= B00000111;     //PCIE0
             PCMSK0 |= B00111111;   
  
//             Serial.begin(2000000);
             }

 
void loop(){

   if(state == 1){   
                  state = 0 ;
                  PORTB |= _BV(5);       
                  }

//                  Serial.print(" state : ");
//                  Serial.println( state);                                       
}

ISR (PCINT0_vect){   
                  /*FLAG*/
                   state=1;                
                 }

And once the interrupt occurs, the LED will remain ON forever as you never shut it off. Is that your intention?

BTW, your indenting is atrocious. Please hit 'ctrl-t' in the Arduino IDE to auto-format it:

#define LED1  (13)
/*FLAG*/
volatile int state  ;

void setup() {
  DDRB &= ~_BV(0);    //interrupt_port

  /*interrupt*/
  PCICR |= B00000111;     //PCIE0
  PCMSK0 |= B00111111;

  //             Serial.begin(2000000);
}


void loop() {

  if (state == 1) {
    state = 0 ;
    PORTB |= _BV(5);
  }

  //                  Serial.print(" state : ");
  //                  Serial.println( state);
}

ISR (PCINT0_vect) {
  /*FLAG*/
  state = 1;
}

where do you turn the LED off?

if the interrupt is too fast to detect using polling, then it certainly doesn't make sense to only have the LED on when the interrupt occurs.

if you're just trying to detect a pulse, you might try toggling the LED each interrupt event so that it turns off or on each event

this means the the pulse is HIGH for a very short time possibly < usec

'state' is an int, which is two bytes. That makes it a critical section which you have provided no protection for. You have to disable interrupts, make a copy, and enable interrupts again. It's also an obscure name, doesn't tell you what it is, like for example 'pulseReceived'.

  noInterrupts();
  int state = pulseReceived;
  interrupts();
  if (state == 1) {

Otherwise, you should use a bool type which uses only one byte. It's what you should use for a flag anyway.

#define LED1  (13)
/*FLAG*/
volatile bool pulseReceived = false;

void setup() {
  DDRB &= ~_BV(0);    //interrupt_port

  /*interrupt*/
  PCICR |= B00000111;     //PCIE0
  PCMSK0 |= B00111111;

  //             Serial.begin(2000000);
}

void loop() {
  if (pulseReceived) {
    pulseReceived = false;
    PORTB |= _BV(5);
  }

  //                  Serial.print("pulseReceived state : ");
  //                  Serial.println( pulseReceived);
}

ISR (PCINT0_vect) {
  /*FLAG*/
  pulseReceived = true;
}

On a more obscure point, it's not a good idea to use /* */ for one line comments because those kind of comments don't nest. If you have to comment out multiple lines and one includes this, you have a problem.

If you want to toggle the LED, use '^' not '|'. It's probably dim because the ISR is being called rapidly by the unknown device you have connected to it.

Only by telling us what your "high speed pulse" is, can we help you with that aspect of your problem.

It is detecting a high speed pulse, so it had to be an interrupt to detect it.

Probably not. On an AVR based processor, this polling loop has a much faster response than an interrupt, but the processor can't do anything else while waiting:

while ( (PIND&(1<<2)) == 0); //wait for high on PortD, pin 2

i doubt that.
isn't the interrupt triggered by hardware?

Feel free to do so, but the response lag of that wait loop is 1 to 3 machine cycles (62.5 ns on a 16 MHz Arduino).

Machine code (from Compiler Explorer AVR-gcc):

.L2:
        sbis 0x9,2
        rjmp .L2

The interrupt has an unpredictable latency, depending on what instruction is currently being executed, then calls the ISR, which must save all registers potentially affected by the ISR, before anything else can be accomplished. Many machine cycles.

Look up "interrupt response latency" to learn more.

thanks, that make sense
because your loop is so tight

#include <PinChangeInterrupt.h>

const byte LEDPin = LED_BUILTIN;
const byte InterruptPin = 8;

volatile boolean ThereIsAnInterrupt = false;

void setup()
{
  pinMode(LEDPin, OUTPUT);
  pinMode(InterruptPin, INPUT);

  attachPinChangeInterrupt(InterruptPin, InterruptHandler, CHANGE);
}

void InterruptHandler()
{

  ThereIsAnInterrupt = true;
}

void loop()
{
  noInterrupts();
  boolean local_TIAI = ThereIsAnInterrupt;
  ThereIsAnInterrupt = false;
  interrupts();

  if (local_TIAI)
  {
    // An interrupt occurred so blink the LED
    digitalWrite(LEDPin, HIGH);
    delay(250);
    digitalWrite(LEDPin, LOW);
    delay(250);
  }
}

Yes, it's better to protect all ISR variables regardless of type. Then nothing will break if you change them, and it won't be vulnerable to compiler implementation details.

Thank you all.

→The high speed pulse is 1~2us per pulse and is received every 25us.

→I found out that I should do an interrupt disable in the loop and hold the value once.
By holding, state=1 was achieved when the interrupt occurred.
However, it did not return to state=0 when there was no interrupt and I am trying to figure out how to do that again.

→The interrupt operation did not work.
But very interesting about PinChangeInterrupt.h. Thank you very much.

It's not only what @jremington describes in post #15.

When the interrupt occurs, registers are saved; from memory, there are around 60 to 80 machine cycles (I might be totally wrong though with that number) to achieve that. And at the end of the ISR, they need to be restored as well.

In assembly you are free to do what you want, in C/C++ the compiler decides.