[solved] ISR

Hello,
In almost all sources about timer interupts and ISR, I find a “must” : ISR must be very small, if possible one statement only.

But I havent find the “why”.
Ok, I can think of 2 reasons :
a. If time needed to execute the ISR is very long, there may be some interrupts missed.
b. Clock “is not ticking” for interrupt counters-timers while in the ISR, so time from one interrupt to the next (for the same reason (for example OVF)), is ISR dependent and not time dependent (a good reason for using an interrupt).

Is any of these correct, or what else can be the “must”?

thank you

demkat1:
Hello,
In almost all sources about timer interupts and ISR, I find a "must" : ISR must be very small, if possible one statement only.

But I havent find the "why".
Ok, I can think of 2 reasons :
a. If time needed to execute the ISR is very long, there may be some interrupts missed.
b. Clock "is not ticking" for interrupt counters-timers while in the ISR, so time from one interrupt to the next (for the same reason (for example OVF)), is ISR dependent and not time dependent (a good reason for using an interrupt).

Is any of these correct, or what else can be the "must"?

thank you

Both are correct. Interrupts also delay the main code.

There are no good reasons for having a long ISR, and several problems arise when you try, for example, you can't do anything else that requires interrupts, while executing interrupt code.

ok, let me explain the "project".
at spesific timing I want to "output" a 8bit and exactly after this to set a pin high and back low.
The output must be calculated in each time "period".
there must be a serial input, so to change (if needed) the calculation.

I see the following code (ok, dont look for syntax, just the idea)

byte NumArray[]={1, 3, 8, 2, 250, 147}
int i=0;
char inchar=' ';
String txtmsg="";

setup {
Serial.begin(115200);
// arrange OVF interrupt every 100ms
// enable interrupts
}

loop{
ReadSerial()
}


void ReadSerial(void) {

  if (Serial.available() > 0) {
    
    inchar = Serial.read();
    txtmsg += inchar;
    if (inchar == 10) {//line feed?
      if (txtmsg.substring(0, 1) == "i")      {
        i=(txtmsg.substring(1).toInt();
        if (i>5) i=0;
      }
      txtmsg = "";
    }
  }
}

ISR{
 //portb=NumArray[i]; //portb is an example
 i++;
 if (i>5) i=0;
 digitalWrite(A0, HIGH);
 digitalWrite(A0, HIGH);//give a delay , dont use delay()
 digitalWrite(A0, LOW);

}

So, 100ms is MORE than enough to execute the ISR. The rest will be consumed to run ReadSerial() for any change. Change is not critical to happen exactly on next interrupt
If a change appears, it is read in 2-3-5... loops.

So, in this example, does anybody sees any reason for NOT having many statements in ISR?

Long ISR's also delay other ISR's. That's why Servo gets the jitters when you use SoftwareSerial at low baud rates. Servo uses a timer interrupt for pulse timing and SoftwareSerial turns off interrupts for the duration of each character sent.

johnwasser:
Long ISR's also delay other ISR's. That's why Servo gets the jitters when you use SoftwareSerial at low baud rates. Servo uses a timer interrupt for pulse timing and SoftwareSerial turns off interrupts for the duration of each character sent.

I dont see a "servo" here nor a SoftSerial.
I willnot use delay, a/d, pwm....other interrrupts.....I will only use "math" to calc the NumArray numbers

If time needed to execute the ISR is very long, there may be some interrupts missed.

"very long" is relative term.

The purpose of interrupts is to monitor events ( time , external I/O, etc.) for the main process to do its functions.

This is foreign to Arduino concept of continuous loop() which apparently needs to
run no matter if it does anything useful.

Using this loop() concept leads to much convoluted code even when such simple act as "push the button" to turn LED ON/OFF is attempted.

On the other hand learning to dodge the loop() with usage of millis() could be useful to some.

Cheers

The code you posted in reply 3 doesn't even compile, so why are you wasting our time?

does anybody sees any reason for NOT having many statements in ISR?

Yes. There is no good reason to put them in the ISR.

String txtmsg="";

There is no good reason to use Strings on Arduino, either. If you do, be prepared for program crashes and misbehavior.

TolpuddleSartre:
The code you posted in reply 3 doesn't even compile, so why are you wasting our time?

TolpuddleSartre:
The code you posted in reply 3 doesn't even compile, so why are you wasting our time?

I dont believe you , read again last line before code it says:

I see the following code (ok, dont look for syntax, just the idea)

doesnt it?

There is no good reason to use Strings on Arduino, either. If you do, be prepared for program crashes and misbehavior.

thank you

demkat1:
at spesific timing ...

How specific is your timing? At best, the ATmega328P has a resolution of 62.5 nanoseconds at 16 MHz. I have found that when working with timing, which I do a lot of, it is hard to fathom the difference between nanoseconds, microseconds and milliseconds. In 1 millisecond, which is often precise enough timing, an AVR can perform 16000 instructions at 16 MHz. This may be your entire program several times over. In 1 microsecond, an AVR can perform 16 instructions at 16 MHz. At max bit rate to send 1 byte via the serial UART, it will take 139 clock cycles at 16 MHz.
If you start with what you are trying to do you might get more appropriate help. For example, "I want to drive a CD4094 shift register with the UART."
If you do need very precise timing, a microcontroller may not be the right solution. You may want to consider an FPGA.
An ISR is short because the common use of ISR is to set a flag or increment a global variable etc. This flag or variable get's further processed procedurally with all other code. This is so that if you are doing many things at the same time, you don't miss doing something else.
If you are only doing one thing in your sketch, the use of an ISR is no more precise than the sketch itself.

demkat1:
I dont believe you , read again last line before code it says:

I see the following code (ok, dont look for syntax, just the idea)

doesnt it?

You don't believe it doesn't compile? :o

So if I'm not supposed to look for the syntax, what am I supposed to look for?

If that's not a reasonable definition of a waste of time, I'm not sure what is.

232:
Using this loop() concept leads to much convoluted code even when such simple act as "push the button" to turn LED ON/OFF is attempted.

Try writing code that blocks in ‘loop()’ on an ESP8266 and see how far you get. You’ll be treated to a never-ending series of Watchdog Timer resets. Reason being is that your application code is not the only thing that needs to run on the processor. It also needs to service its IP Stack among other things.

demkat1:
ok, let me explain the "project".
at spesific timing I want to "output" a 8bit and exactly after this to set a pin high and back low.
The output must be calculated in each time "period".
there must be a serial input, so to change (if needed) the calculation.

So, 100ms is MORE than enough to execute the ISR. The rest will be consumed to run ReadSerial() for any change. Change is not critical to happen exactly on next interrupt
If a change appears, it is read in 2-3-5... loops.

So, in this example, does anybody sees any reason for NOT having many statements in ISR?

Hi,

Your pseudocode looks OK. I think once refined it will work. Yes, I think you can put your digitalWrite instructions inside the ISR.

On the other hand, your mood is far from polite (I dont think I should develop the idea).

Regards

vffgaston:
Hi,

Your pseudocode looks OK. I think once refined it will work. Yes, I think you can put your digitalWrite instructions inside the ISR.

It is very nice to "hear" someone talking on the real issue. Thank you.

vffgaston:
Hi,
...
On the other hand, your mood is far from polite (I dont think I should develop the idea).

Critisism is also welcome, sinse it also helps in adjusting communication rules.
But, my friend, if someone asks for help on a "why", and at least 6 "forumers", even experienced ones, keep looking and talking about things that have nothing to do with the problem...let me remind some ,

you can't do anything else that requires interrupts, while executing interrupt code.
That's why Servo gets the jitters when you use SoftwareSerial...
On the other hand learning to dodge the loop() with usage of millis() could be useful to some....
Yes. There is no good reason to put them in the ISR...
How specific is your timing?
So if I'm not supposed to look for the syntax, what am I supposed to look for?
There is no good reason to use Strings on Arduino, either. If you do, be prepared for program crashes and misbehavior.
At max bit rate to send 1 byte via the serial UART, it will take 139 clock cycles at 16 MHz.

then my mood may be it became abrupt, but I dont aggree it is not polite.
kind regards

This topic is [solved].

demkat1:
It is very nice to "hear" someone talking on the real issue. Thank you.

Thanks. You are welcome.
Regards.

demkat1:
So, 100ms is MORE than enough to execute the ISR.

I hope you meant “100 microseconds” (‘ms’ is the abbreviation for milliseconds. Use ‘us’ or spell out microseconds). If you leave interrupts off for even as much as 2 milliseconds a timer interrupt will be lost and any timing operations will run long.
Not to mention that 100 microseconds is long enough to cause 10% (18°) jitter on Servo outputs.
You should aim for your ISR to complete in AT MOST a few tens of microseconds, say 20 or 30. Shorter is better! In some cases, more than a microsecond might be too long.