Best Practice noInterrupts() and AdaFruit Sensor Libraries (DHT11)

I was playing with a DHT11 Sensor using AdaFruits Libraries off GitHub .

It has a cute object encapsulating noInterrupts()/Interrupts(). At least I thought it was cute:

class InterruptLock {
  public:
   InterruptLock() {
    noInterrupts();
   }
   ~InterruptLock() {
    interrupts();
   }

};

They uses it to disable interrupts while polling the sensor. By just creating the object and allowing the compiler to clean it up when it goes out of scope.

InterruptLock lock;

All this seem great, but, mixed through out the code are conditional compile Serial.print()'s. If these conditionals are ever engaged (#define DHT_DEBUG), I think bad things would occur?

It would seem to me that sending a lot of Debug Text to the Serial port with Interrupts disabled is a BAD choice?

Would it have been a better coding style to create a dynamic object and immediately delete it at the conclusion of the time critical section? Instead of waiting for the Object (lock) to go out of scope?

InterruptLock *lock=new InterruptLock;

// time critical section

delete lock;

// the rest of the calculation/conversion code

What is wrong with my Idea? Am I missing Something?

Chuck.

Serial.print with interrupts disabled can be a really bad thing, especially if the built-in buffer is exceeded.

vaj4088:
Serial.print with interrupts disabled can be a really bad thing, especially if the built-in buffer is exceeded.

That's my feeling.

What is wrong with just using noInterrupts() and interrupts() directly?

Just because you can do something doesn't mean you should do it.

Chuck.

chucktodd:
What is wrong with just using noInterrupts() and interrupts() directly?

Also my thought. The code in your Original Post seems to use 9 lines of code where 2 would be sufficient.

FWIW I always use them directly.

...R

What is wrong with just using noInterrupts() and interrupts() directly?

Agreed!

Serial was fixed a while back to allow it to work with interrupts disabled. If the buffer is full and interrupts are disabled it polls the serial output hardware and sends from the buffer when the hardware says that the output register is available.

You could limit the scope of the lock object by adding brackets around the critical section.

I prefer explicit use of noInterrupts() and interrupts() for Arduino sketches.

When doing this in a library function you should store SREG (Status REGister, contains the global interrupt enable flag) and restore it. That way if you get called with interrupts disabled they will still be disabled when you return.

johnwasser wrote (in part):

Serial was fixed a while back to allow it to work with interrupts disabled.

Thank you for the information, I stand corrected. Do you know at what version of the IDE the change to Serial became available?

Does the OP know what version of the IDE was in use?

I agree with the entirety of your post #5. Thanks!

vaj4088:
Thank you for the information, I stand corrected. Do you know at what version of the IDE the change to Serial became available?

The change was added April 18, 2013 (over four years ago).

The versions after that are:

ARDUINO 1.0.5 - 2013.05.15
and
ARDUINO 1.5.3 BETA - 2013.08.30

Thanks!

johnwasser:
Serial was fixed a while back to allow it to work with interrupts disabled. If the buffer is full and interrupts are disabled it polls the serial output hardware and sends from the buffer when the hardware says that the output register is available.

You could limit the scope of the lock object by adding brackets around the critical section.

I prefer explicit use of noInterrupts() and interrupts() for Arduino sketches.

When doing this in a library function you should store SREG (Status REGister, contains the global interrupt enable flag) and restore it. That way if you get called with interrupts disabled they will still be disabled when you return.

It is good to know that a Serial.write() operation fails back into a polling method if interrupts are disabled. As you can see, I assumed it would hang.

Does anyone think that InterruptLock is a best practice?

Chuck.

chucktodd:
Does anyone think that InterruptLock is a best practice?

The main advantage is that you can't forget to turn interrupts back on. The disadvantages are: It's easy to put too much code inside the critical section, and it always enables interrupts on exit, even if they were not enabled on entry. The later disadvantage can be fixed by saving SREG in the constructor and restore it in the destructor.