Interrupts dont re-enable after failed WiFi.on()

I think there is a little bug with WiFi.on() i think it sets interrupts off at some point, if it connects to a network they get set back on and you don’t even know the difference! but if there is no WiFi to connect to and a timeout routine sets WiFi.off() then they don’t get re-enabled.

void checkWifi() {
  last_wifi_status = WiFi.status();
  if (millis() - lastWifi > FIVE_MINUTES && !Spark.connected()) {

    if (ProgMode) Serial.print("Attempting to connect...");
    
    timer = millis();
    WiFi.on();
    
    while (WiFi.status() != WIFI_ON && millis() <= timer + TIMEOUT) SPARK_WLAN_Loop();
    
    if (millis() >= timer + TIMEOUT) {
      WiFi.off();
      if (ProgMode) Serial.println("Unable to Connect WiFi");
      lastWifi = millis();
      return;
    }
    Spark.connect();
    timer = millis();
    
    while (!Spark.connected() && millis() <= timer + TIMEOUT) SPARK_WLAN_Loop();
    
    if (millis() >= timer + TIMEOUT) {
      WiFi.off();
      if (ProgMode) Serial.println("Unable to connect to the Spark Cloud");
      lastWifi = millis();
      return;
    }
    
    if (ProgMode) Serial.println("Connected to the Cloud");
    
    Log((char*) "Connected to the Spark Cloud");  
  }
} 

@Hootie81, in your code, what do you see happening that makes you think that interrupts are disabled?

the button that triggers the interrupt function appears to do nothing after it tries to connect, if i add interrupts() after the wifi.off() it works without issue.

i havent tested it extensively but adding the interrupts() made the button work again. Ive been trying to get TCPclient working again :frowning: it never connects

@Hootie81, since I don’t have your whole code I assume you have a button that you attach an interrupt to. So you say if WiFi.on() is called, fails and you set WiFi.off() then (user) interrupts are disabled, correct? I’ll have to look at the core firmware to see what it does.

@zachary, any thoughts on this?

I would post my whole code but it relies on many many libraries now… and there is something like 1800 lines of code now… so the troubleshooting is getting hard!

Ill try and thst that part some more now and see whats happening

Edit: Ill try again when i go to my big tin box with no wifi at all… i cant make it happen right now, but i cant turn off the router to test it without making dozens of people mad

I’ve given it some thought and dug around the code a bit. I can’t think of any reason WiFi.on() or WiFi.off() would affect interrupts.

Take a look for yourself here:
https://github.com/spark/core-firmware/blob/master/src/spark_wiring_wifi.cpp#L35

@zachary, I dug deeper and could not find anything either.

it must be something blocking in my code after checking wifi, not allowing the main loop to run… which will stop the call to the function. is this the correct way to use an interrupt? (in a very trimmed down version)

before setup

int doorbellPin = D0;
volatile boolean doorbellPressed = false;

in setup()

pinMode(doorbellPin, INPUT_PULLUP); 
attachInterrupt(doorbellPin, doorbellPush, FALLING);

in loop()

if (doorbellPressed) playDoorbell();
//the rest of my code... check fingerprint reader
//check RFID etc. etc.

interrupt function

void doorbellPush() {
    doorbellPressed = true;
}

play doorbell function

void playDoorbell() {
playRTTTL();
doorbellPressed = false;
}

@Hootie81, the code looks fine but could playRTTTL() be causing problems? Can you explain what that function does?

I think playRTTL() is @BDub ring-tone text transfer language player.

It must use a timer on the output pins to get the PWM signal for the audio tones, so it could be timer interrupts, not user interrupts are affected.

The very first (and only) version of my RTTTL library does not use interrupts and just tries to play one note at a time, each time through the user loop(). While it’s doing this it’s also blocking all other user code because it was manually bit banging the outputs. It would be better now that we have a tone() and noTone() function in the Spark Core that uses PWM outputs to convert that library to use those to make it non-blocking. However, you still have to manage the duration of notes then with a background timer (millis() would work).

This could all be done with interrupts, but probably not worth the headache to make it that much of a background task.

@Hootie81 did you modify my RTTTL library at all? Perhaps if you did there could be some issue with interrupts() / noInterrupts(). which will affect the user attachInterrupts() functions.

1 Like

I did try changing to the tone library but got errors… something to do with SPI i think… cant remember. and i gave up on that pretty quickly and went back to your original one. i did simplify the call to play with this in a function… i couldn’t make it work the way it was in your example… because i didn’t trigger from the web, i just used a button on D0

begin_rtttl(song);
while (next_rtttl()) next_rtttl();

Its very very blocking i know, but the doorbell is only a few seconds long. I also use it to make ‘bum-bow’ and ‘cha-ching’ noises :blush:

I’m trying to put the whole code on Git now… but the internet here is very very slow so its taking ages.

I was sure the main loop was running too… because it kept trying to connect wifi every minute (the FIVE_MINUTES in the first post i changed to 60seconds at the define for testing) and the fingerprint reader was working and i got in and out of ‘program mode’ which opens the serial port. so it must have been going past the function… anyway my code is up now… be warned its long and a bit (a lot) of a hack job!

@Hootie81, doing a quick look at your code under CheckWiFi, you have:

last_wifi_status = WiFi.status();
    if (millis() - lastWifi > FIVE_MINUTES && !Spark.connected()) {

However, it is possible to have wifi on and not have a cloud connection. So should the statement not be as follows?

last_wifi_status = WiFi.status();
    if (millis() - lastWifi > FIVE_MINUTES && wifi_status == OFF {

yep true, now I’m wondering if i need the code at all? what happens if we do a wifi.on… will it block until it connects? ill try it tonight when i try and get the interrupts to stop again… when there is no wifi around

OK so i tested some more last night, and couldn’t get the interrupts to stop, or turn off.

I also tried just turning on the wifi and not testing if its connected, that works well and doesn’t block my code… the flash got a bit annoying after a while as i was in my little bunk testing, but taking control of the LED worked to fix that :smile:

i did however have an issue with the fingerprint reader not reading prints at one point, but a reset fixed that… ill have to dig a bit deeper into that now as i don’t want it to happen once i put it to use