MKR 1000 and noInterrupts() function.

So I'm not sure if I'm posting in the right place but I just wanted to pass on an experience I've just gone thru in case anyone else makes the same mistake. Here's where the mistake in my code was: (it's the noInterrupts() call which I've since commented out)

void setup() 
{
  //
  pinMode(interruptPin, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(interruptPin), ISR_smoke, CHANGE);
  noInterrupts();
  // Open serial communications and wait for port to open:
  Serial.begin(57600);
  //
  while (!Serial);

and then later on in the code: (the interrupts() call which I've since commented out)

      if(strcmp(inString, "ack\r\n") == 0)
      {
        // save this IP address
        Sentinel = lanIPx;
        // set flag true
        sentinelFound = true;
        Serial.print(F("Got it!\nSentinel's IP address is: "));
        Serial.println(Sentinel);
        // clear inString
        memset(inString, 0, sizeof(inString));
        inIdx = 0;
        // allow interrupts now that we know where data is to be sent
        interrupts();
        break;  // from for() loop
      }
      else Serial.println(F("Invalid response."));
    }
    else Serial.println(F("failed."));
  } // end for() loop
  //
  return sentinelFound;
}

the issue I experienced was that the first noInterrupts() statement in the setup() function totally bunged up my MKR 1000. Windows no longer recognized it and said it was malfunctioning. I was distraught. I thought I'd done something to smoke my unit.
Turns out it seems like a really bad idea to disable interrupts in the setup() function of a sketch. There was a reason why I wanted to this, but it is moot since it completely messed up the MKR 1000. I suspect that a noInterrupts() call in the setup() function would most likely mess up any board its loaded onto.

Any way, I got rid of both the noInterrupts() call and the interrupts() call and my MKR 1000 now works just fine and it gets along with Windows and I can happily continue with my project. But for a while I was freaked and pissed off. Turns out I'm just a fool. But hopefully this will help anyone else out there who may have done what I did.

I read through the Reference page regarding noInterrupts() and while it does make vague reference that
"Some functions will not work while interrupts are disabled, and incoming communication may be ignored."
I put it out there for consideration that it be amended to include:

"Don't put a noInterrupt() call in the setup() function of your sketch!"

Happy coding!
Stephen

I’m unsure about this -I’ve had “no interrupts” in setup without an issue ( UNO) , wondered if this is a specific issue with the Mkr1000 board due to way the USB and reset works ?

Any expert willing to comment ?

That's right. This is not MKR1000-specific. You will get the same result even with an ATmega32U4-based board. Here's a minimal sketch:

void setup() {
  noInterrupts();
}
void loop() {}

This is just the nature of the native USB boards. You have to make sure not to interfere with that background USB code if you want the CDC serial port to continue working. You'll get similar results with sleep code.

That's a nice thing about the Uno, Nano, Mega, Nano Every, etc. boards that have a dedicated USB chip. You can do whatever you like in your sketch on the primary microcontroller and you'll never lose that port. But of course there are significant benefits to having native USB as well.

Very important to mention is that even if you completely break USB in your sketch, that doesn't have any effect on the bootloader. So you can always recover your native USB boards from this situation by resetting them manually to activate the bootloader. The modern native USB boards have a nice feature where you can press the reset button twice quickly to put them constantly (until another reset or power cycle) in bootloader mode. Then the port comes back and you can upload to that port as usual. The Leonardo and Micro use an older bootloader that doesn't have the double reset capability, so on these boards you have to do the reset right when the upload starts (after the sketch compilation finishes).

So it's really not something to be scared of. Feel free to experiment in the Arduino spirit!

Yes it was by double tapping the reset button that I realized the my PC didn’t freak out with the malfunction message. I discovered I could still upload the Blink program and it worked! So clearly all was not lost. But that was what led me to question my code. The problem began the instant I tried to upload/run my sketch with the noInterrupts() in it.

Still, lesson learned!

I wonder though if the problem was putting the noInterrupts() call before Serial.begin()? or is my first thought that a noInterrupts() statement anywhere in the setup() function will muck up the board? Any thoughts? maybe I’ll try it, but not til I’m done my project!

Just re-read pert’s post. Looks like a noInterrupts() call anywhere in setup() will muck things up…

It's not about it being in setup(), it's just about interrupts being disabled. For example, this use of noInterrupts() in setup() will do no harm:

void setup() {
  noInterrupts();
  interrupts();
}
void loop() {}

But this use of it in loop() will break USB just as badly as it would in setup():

void setup() {}
void loop() {
  noInterrupts();
}

The correct way to use noInterrupts() is to call it immediately before running some timing/atomicity-sensitive code, then immediately call interrupts() after that to enable them again.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.