Disabling Interrupts Period

Hello,

We're having a great time with the arduino leonardo, and for deterministic principles, we'd like to try disabling interrupts. Right now, we have the following which works very well within the code, but overall there is still some nondeterminism in the execution from loop iteration to loop iteration:

void loop{
cli();

...code...

sei();

Can we disable interrupts in setup{} and never reenable them? Is this dangerous in anyway to the function or future functions of the arduino?

Thanks,

Zach

There are a lot of things that rely on interrupts - millis(), servos, PWM, some ways of reading the analog to digital converter, serial data, etc. Disabling all interrupts, permanently, is really not a good idea.

You can if you wish but why doit?

What do you mean by "deterministic principles"?

What are you really trying to do, remember you will lose the timers (millis), pwm and Serial.

Mark

We're logging data from an encoder along with the time each data point is recorded. When processing for V = d/dt and then A = dv/dt, the dt array values should be constant if we are truly taking data at constant intervals. Sometimes the spacing is 1 ms, sometimes 2 ms. Double the dt means half the velocity, and we get outliers in the data set. We'd like to avoid the outliers since they are manifested by timing issues of the arduino, and I thought a good way would be to try disabling interrupts so that a predictable and constant amount of time passes between each recorded data. Thoughts of other work arounds?

One thing you might consider is using micros instead of millis for your timing; since you're apparently in the 1 to 2 ms range, your velocity calcs aren't going to be very accurate otherwise.

Thoughts of other work arounds?

Posting your code, perhaps.

We're logging data

Where? Is the "timing" issue related to the fact that some SD card writes take longer than others?

I believe this would ensure that only your code runs.

void setup(void)
{
    cli();
    for (;;) {
        //your code here
    }
}

void loop(void)
{
}

Can you go into a little more detail as to what happens where? Are you saying that you are experiencing as much as 1mS jitter in the operation of things? That would be extreme in my opinion. Do you poll the device, or does it send you data asynchronously? How are you establishing the time that data arrives? Are you using millis() to determine how long anything takes? How precisely do you need to know the "time"?

NASAZach:
We're logging data from an encoder along with the time each data point is recorded. When processing for V = d/dt and then A = dv/dt, the dt array values should be constant if we are truly taking data at constant intervals. Sometimes the spacing is 1 ms, sometimes 2 ms. Double the dt means half the velocity, and we get outliers in the data set.

You might want to look at this:

I was timing intervals fairly precisely in the sketch there.

We'd like to avoid the outliers since they are manifested by timing issues of the arduino, and I thought a good way would be to try disabling interrupts so that a predictable and constant amount of time passes between each recorded data. Thoughts of other work arounds?

You can disable interrupts, but there has to be a certain amount of jitter, unless perhaps you put the processor to sleep.

The thing is, if you have a loop, and you are checking for "the event" to be up, the event might be up at some point in the loop, which you won't know.

I had this issue when trying to do VGA graphics, which is highly timing dependent.

In that sketch, I put the processor to sleep, and waited for an interrupt to wake it. Once it is asleep, the time taken to wake it is fixed, and you aren't halfway through some sort of checking loop.

So my suggestion is, use an interrupt to detect the event itself, use micros() as suggested above, and put the processor to sleep to eliminate jitter.

For more help, I suggest you post your code. Virtually every time someone wants to disable interrupts, or enable them inside an ISR, or "jump out" of an interrupt they are describing their low-level solution to a problem, but without stating the problem itself.

What's the resolution of mills() does any one know?

The reference for micros() gives the following

Returns the number of microseconds since the Arduino board began running the current program. This number will overflow (go back to zero), after approximately 70 minutes. On 16 MHz Arduino boards (e.g. Duemilanove and Nano), this function has a resolution of four microseconds (i.e. the value returned is always a multiple of four). On 8 MHz Arduino boards (e.g. the LilyPad), this function has a resolution of eight microseconds.

But what about mills?

Mark

What's the resolution of mills() does any one know?

One microsecond, with the occasional jump by two microseconds, since 1000 and 1024 are not exactly equal.

PaulS:

What's the resolution of mills() does any one know?

One microsecond, with the occasional jump by two microseconds, since 1000 and 1024 are not exactly equal.

millisecond

millis() will almost always be out by a bit because the timer interval is 1.024 mS thus it will have an error of 24 uS, cumulatively, per tick. It adjusts around every 42 counts so the effect isn't cumulative over the long term, however micros() will be much more accurate.

(edit) Having said that, you won't really notice millis() being out, because the resolution is 1 mS, however it does mean that the "tick" will not occur at exactly the right moment.

From post #3

When processing for V = d/dt and then A = dv/dt, the dt array values should be constant if we are truly taking data at constant intervals. Sometimes the spacing is 1 ms, sometimes 2 ms. Double the dt means half the velocity, and we get outliers in the data set.

The odd jump on mills may well explain the above from the OP.

Mark

True, and using micros() should totally fix that.

For timing incoming pulses, the Timer1 capture facility is the best way I know to get jitter free results. Messes up the PWM on 9 and 10 though on my Uno. Since I had to change the mode anyway, I changed the prescaler to give me .5uS resolution. Works great.