Keep an attachInterrupt for determinate time

Hi, I want to know it is possible to keep an attachInterrupt for a specific period of time, for sample, press a button and keep the interruption until release the button, it that possible?

attachInterrupt()
detachInterrupt()

Google knows about these functions.

It is (arguably) better in most cases to use a boolean variable to create a software "mask" for the interrupt handler, that tells it whether to process or ignore the interrupt, rather than constantly attaching and detaching the interrupt handler.

Regards,
Ray L.

Yes, but why? What signals are you trying to capture with the interrupt? What are you trying to do?
How do you know your enabling routine will capture the interrupt. Interrupts are typically for events which occur very fast and at any time.

This sounds like an "X-Y" question.

Perhaps someone can confirm this. An interrupt that is pending when they are enabled will then be processed, even if the source of the interrupt happened some time before.

Paul

An interrupt that is pending when they are enabled will then be processed, even if the source of the interrupt happened some time before.

True.

From Nick Gammon Interrupts Gammon Forum : Electronics : Microprocessors : Interrupts

Something to be aware of is that these flags can be set before you attach the interrupt handler. For example, it is possible for a rising or falling level interrupt on pin D2 to be "flagged", and then as soon as you do an attachInterrupt the interrupt immediately fires, even if the event occurred an hour ago. To avoid this you can manually clear the flag. For example:

EIFR = 1; // clear flag for interrupt 0 (D2 on Uno)
EIFR = 2; // clear flag for interrupt 1 (D3 on Uno)

Or, for readability:

EIFR = bit (INTF0); // clear flag for interrupt 0
EIFR = bit (INTF1); // clear flag for interrupt 1

Paul_KD7HB:
Perhaps someone can confirm this. An interrupt that is pending when they are enabled will then be processed, even if the source of the interrupt happened some time before.

Paul

Which is one of the arguments for ALWAYS processing the interrupt, and using a software "mask" to allow the handler to simply return, without doing anything, when the interrupt function is not really needed.

Regards,
Ray L.

Thanks a lot for helping.

Well, I have a fuction that works with big numbers in loop, so I need to stop that function by specif time, for example by 1 or 2 seconds max. Due to stress with the big numbers function, others functions like delay() and millis() does not work properly to start and stop bigBumber function. So, I think that can use another Arduino to call an interruption that pause bignumber function for 1 or 2 seconds, then that another Arduino send some signal to stop their initial interruption, like if a person press a button for 1 ou 2 seconds. I need to be precise because I observe everything through an oscilloscope.

Maybe the method that I'm trying to do is so complicate, the ideia of RayLivingston to use a flag to change the operation of bigNumber function in the loop is maybe the best option.

Due to stress with the big numbers function, others functions like delay() and millis() does not work properly to start and stop bigBumber function.

It sounds like you have written some sort of blocking function. Sounds more like it is a bigBummer :slight_smile:

If you share this function with us and place it in the context of a minimal example program which demonstrates the issues with it you will get help.

Due to stress with the big numbers function, others functions like delay() and millis() does not work properly to start and stop bigBumber function.

That makes no sense. The BigNumber functions should have nothing to do with delay() and millis(). You really need to explain better exactly what it is you're really trying to do. It sounds like your code is likely not well structured...

Regards,
Ray L.

these are the sample code that I tryng to do, the device A is the Arduino with the bigNumber function, the device B is another arduino that start a interrupt

Device A

/*
 * Device A with the bigNumber function
 * Arduino Mega
 */

#include <BigNumber.h> 

const int intPin = 2;


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

  attachInterrupt(digitalPinToInterrupt(intPin), fooInte, CHANGE);

}
void BibNumberTest(){
  
  BigNumber a;
  
  BigNumber::setScale (100);

   a = 2;
   int i =1800; // with 2940 value the Arduino Mega Stop!!

  while(i < 2000){ //set value that  dont stop Arduino execution
    BigNumber p = a.pow (i);
    Serial.println(p);
    i+=1;  
  }
}
void loop() {
  Serial.println( ".........Start execution.............");

  BibNumberTest();
  
}

void fooInte(){
  //Do something NOPs, it just waiting for a signal or pulse to stop this interruption and back to the normal program execution
}

Device 2 code

/*
 * Device B
 * Start interruptions
 */

//Pin to activate interruption
const int emuPin = 10;

int arrayValues[] = {1168,1428,1706,1428,1650,1288,1490,1863,1221,1811,1486,1827,1986,1524,
  1187,1517,1540,1241,1807,1003}; //total time aprox 30 seconds

int pos = 0;


void setup() {
  //Serial.begin(9600);
  pinMode(emuPin,OUTPUT);

}

int getDelay(){

  if(pos <= (sizeof(arrayValues)/sizeof(int))-1){
    
    int getValue =arrayValues[pos];
  
    //netx position
    pos+=1;

    return getValue;
  }
  
  return 0;
}

void loop() {
  while (pos <= (sizeof(arrayValues)/sizeof(int))-1){


    // In this part I'm trying to activated and deactivated the interruption
    delay(getDelay());
    digitalWrite(emuPin, HIGH);
    valuee = getDelay();
    delay(getDelay()); //Can be a value between 1000 and 2000 mils
    digitalWrite(emuPin, LOW);

  }

the idea is that device 2 start the interruptions for and specific and accurate time slot, but I don't know how do that or it is possible...

Wow.

RayLivingston:
That makes no sense. The BigNumber functions should have nothing to do with delay() and millis(). You really need to explain better exactly what it is you're really trying to do. It sounds like your code is likely not well structured...

Regards,
Ray L.

maybe my code can be confusing or my explanation :slight_smile: sorry for that, I said that delay() and millis() are not accurate becouse the time to process the number afect the time to stay on the function. For sample the next code using the millis() to stay in the function.

/*
 * Device A with the bigNumber function
 * Arduino Mega
 */

#include <BigNumber.h> 

const int intPin = 2;
unsigned long in =0;
unsigned long out = 0;
unsigned long total = 0;

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

  attachInterrupt(digitalPinToInterrupt(intPin), fooInte, CHANGE);

}
void BibNumberTest(){
  
  BigNumber a;
  
  BigNumber::setScale (100);

   a = 2;
   int i =1800; // with 2940 value the Arduino Mega Stop!!
   unsigned long timeProcess = 1000;
   unsigned long pivotTime = millis();

  //while(i < 2800){ //set 2800 to dont stop Arduino execution
  while(millis() < pivotTime + timeProcess){
    BigNumber p = a.pow (i);
    //Serial.println(p);
    i+=1;  
  }
}
void loop() {
  Serial.println( ".........Start execution.............");
  in = millis();
  BibNumberTest();
  out = millis();
  total = out -in;
  Serial.print("in= "); Serial.println(in);
  Serial.print("out= "); Serial.println(out);
  Serial.print("Total ="); Serial.println(total);
  

}

void fooInte(){
  //Do something NOPs, it just waiting for a signal or pulse to stop this interruption and back to the normal program execution
}

I want to be the most accurate possible for an specific time slot, for example 30 seconds, where the bigNumber function will start and stop for specific time slot. If I have delays, my measurements using from oscilloscope can be affect. I'm using the oscilloscope to see the Atmega Arduino behavior when it operates with large numbers.

I believe you are running into memory issues and the program is crashing.

Nick Gammon, the library author, addresses the issue at Gammon Forum : Electronics : Microprocessors : Arbitrary precision (big number) library port for Arduino

Some caveats
Working with large numbers is necessarily slow - the larger the number, or the more decimal places, the slower.

Each digit requires a byte of memory, plus some overhead (eg. where the decimal point is) - large numbers will soon gobble up the available memory.

Doing a toString also requires memory - a byte per digit, plus the sign, decimal point, and trailing 0x00 byte.

An "error" condition inside the library (eg. running out of memory) calls exit(), effectively sending the library into a tight loop.

You may need to cast some numbers to avoid "ambiguous" warnings from the compiler.

If you only have 2048 bytes of RAM, you clearly need to use a library like this with caution. Running out of memory will be quite likely unless you closely manage the size of your numbers, and how many you have.

Memory fragmentation will quite possibly be a problem, particularly if you calculate numbers of different sizes (eg. factorials).

I believe that you need to add this to setup

BigNumber::begin ();

I think its an indication of memory issues is that the code you posted in reply #12 runs successfully on an ESP8266 and goes from 1800 to 1825 in the 1000ms.

cattledog:
I believe you are running into memory issues and the program is crashing.

Nick Gammon, the library author, addresses the issue at Gammon Forum : Electronics : Microprocessors : Arbitrary precision (big number) library port for Arduino

I believe that you need to add this to setup

BigNumber::begin ();

I think its an indication of memory issues is that the code you posted in reply #12 runs successfully on an ESP8266 and goes from 1800 to 1825 in the 1000ms.

Yes, the Arduino works slowly, but I want that, so I want to use Another Arduino to start an interruption that pause the binNumber function, and the same Arduino that start the interruption stop it, it is possible? :smiley:

I believe that the processor speed is not the reason for the different behaviour I saw on a UNO and and ESP8266.

If memory does not crash, the standard millis() timer can be used start and stop the bigNumber function.

I said that delay() and millis() are not accurate becouse the time to process the number affect the time to stay on the function. For sample the next code using the millis() to stay in the function.

Specifically, what accuracy issues? Have you tried micros() instead of millis()?

int arrayValues[] = {1168,1428,1706,1428,1650,1288,1490,1863,1221,1811,1486,1827,1986,1524,
  1187,1517,1540,1241,1807,1003}; //total time aprox 30 seconds

If you need to run the function in these unequal periods you need to pass these values to the interval.

I am still uncertain that you need an external interrupt to gate the function as opposed to a software timer.