Go Down

Topic: Keep an attachInterrupt for determinate time (Read 400 times) previous topic - next topic

robaer

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?

gfvalvo

#1
Apr 16, 2019, 06:20 pm Last Edit: Apr 16, 2019, 06:21 pm by gfvalvo
attachInterrupt()
detachInterrupt()

Google knows about these functions.
No technical questions via PM. They will be ignored. Post your questions in the forum so that all may learn.

RayLivingston

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.

cattledog

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.


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

cattledog

Quote
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 https://gammon.com.au/interrupts

Quote
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

RayLivingston

#6
Apr 16, 2019, 06:51 pm Last Edit: Apr 16, 2019, 06:52 pm by RayLivingston
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.

robaer

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.

cattledog

Quote
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  :)

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.

RayLivingston

#9
Apr 16, 2019, 09:03 pm Last Edit: Apr 16, 2019, 09:04 pm by RayLivingston
Quote
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.

robaer

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
Code: [Select]

/*
 * 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

Code: [Select]

/*
 * 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...

lastchancename

Experienced responders have a nose for laziness, (they were beginners once)... Sure, there are trolls, chest-beaters, and pretenders - but the help you'll get here is about as good as it gets - if you try to help youself!.

robaer

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 :) 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.

Code: [Select]

/*
 * 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.

cattledog

#13
Apr 17, 2019, 07:59 am Last Edit: Apr 17, 2019, 08:07 am by cattledog
I believe you are running into memory issues and the program is crashing.

 Nick Gammon, the library author, addresses the issue at http://www.gammon.com.au/forum/?id=11519

Quote
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
Code: [Select]
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.

robaer

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

 Nick Gammon, the library author, addresses the issue at http://www.gammon.com.au/forum/?id=11519


I believe that you need to add this to setup
Code: [Select]
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? :D

Go Up