Why does network signal strength go high erratically?

I’m trying to track down why my core freezes up frequently - slows up dramatically for a minute or so then continues as normal - and it seems to correlate with the wi-fi signal strength reported by Network.RSSI() jumping up to +2dB from the usual -50 to -70dB. It happens on 2 different wi-fi networks.

Any thoughts on what causes this?

I have seen the +2dB on mine too, it hasn’t caused me any problems though so haven’t looked much into it

Hmm, interesting @AndrewS. Not sure what the issue is, but happy to help debug. Do you see any patterns for when this happens? How frequently and how regularly do you see this behavior? Also, what code are you running in your own application?

Thanks @zach, it may now be fixed but I’m not sure why and I would really appreciate someone casting a programmers eye over it as I am a beginner at this.

It has been running for 16 hrs now without any apparent symptoms. The loop() code is below.

The ‘if’ test starting about 20 lines form the end, headed ‘// signal strength LED’, is used to drive an LED (blink ON time proportional to RSSI strength) and I also use it to detect freezes by testing to see whether the blink time is much longer than expected. For more than 9 out of 10 freezes the RSSI value has been recorded as 2dB and I always suspected that had something to do with the problem.

2 days ago I added the ability to disconnect from wi-fi for 59mins every hour, just listening for commands for 1min. The thought was that it was the cc3000 that was causing the freezes (I had patched the cc3000 a week before). The ‘conn’, ‘stayConnected’ and ‘starting’ booleans manage the connection and I use a spark.function to toggle full time connection. This seemed to reduce the fault rate significantly, but they were still occurring.

The changes I made 16 hrs ago that may have fixed it were:

  • corrected an error at the start of the signal strength LED loop: if (td >= 0) was previously if (td >= strTime).
  • I had previously used a class called elapsedMillis (from the Arduino website) to simplify the 12 or so timers in the app. These are now handled ‘locally’ with millis()-xxxx tests. This change was a wild stab to see whether this was the cause and I don’t know why or if this fixed it.
void loop() {

  cSecs = Time.now() - UNIXMONTH;
  cMins = cSecs / 60 - DAYSMONTH * 24 * 60 + 600;       // add 600 to get local time from UTC
 
  if(starting)
  {
    if(millis() > 10 * 60 * 1000) starting = LOW;       // stay connected for 10 mins after resetting
  } 
  else
  {
    if(!conn && stayConnected) {                        // activate the stayConnected flag
        Spark.connect();
          conn=HIGH;
    }
  
    if(!stayConnected){
        if (conn && (cMins % 60) <= 58){
            delay(100);
            sprintf(publishString,"close bugMins:%i  bugCount:%i  cMins:%i Strength:%idB",bugMins,EEPROM.read(98),cMins,Network.RSSI());
            Spark.publish("connection",publishString);
            Spark.disconnect();
            conn=LOW;
        }
    }
  
    if(!conn && (cMins % 60) > 58){
        Spark.connect();
        delay(1000);
        sprintf(publishString,"open bugMins:%i  bugCount:%i  cMins:%i Strength:%idB",bugMins,EEPROM.read(98),cMins,Network.RSSI());
        Spark.publish("connection",publishString);
        conn=HIGH;
    }
  }
 
 /* 
  if (publishTime-millis()>pubTime){
      sprintf(publishString,"%i - %i  %idB",bugMins,cMins,Network.RSSI());
       Spark.publish("connection",publishString);
       publishTime=millis();
  }
  */
  
  if(debug){
  delay(500);

  Serial.print("version: ");
  Serial.print(version);
      
  Serial.print("mins: ");
  Serial.print(cMins);
  Serial.print("-");
  Serial.println(oMins);

  Serial.print("masks: ");
  Serial.print(mask0);
  Serial.print("-");
  Serial.println(mask1);
  Serial.println(Network.RSSI());
  Serial.println(Network.SSID());
  
  }
  
  // check time for new patterns
  if(cMins >= pattern[pIndex][0] + oMins){
    mask0 = pattern[pIndex][1];
    mask1 = pattern[pIndex][2];
    pIndex++;
    if (pIndex >= pMax) {
      pIndex = 0;
      oMins = oMins + 1440; 
    }
    readMask();
    tMins = pattern[pIndex][0] + oMins;
  }

  // control fans

  
  for (int i = 0; i < 9; i++) {
    cMillis=millis();
    if (outState[i] && (cMillis-tmElStr[i]) > ontime[i])     // fan is on and timer exceeded
    {				
      outState[i] = LOW;         // toggle the state from HIGH to LOW 
      digitalWrite(out[i], LOW);
      tmElStr[i] = cMillis;              // reset the counter to 0 so the counting starts over...
    }
    if (!outState[i]  && (cMillis-tmElStr[i]) > offtime[i]) 
    {
      outState[i] = HIGH;         // toggle the state from LOW to HIGH
      if(m[i] == 1) digitalWrite(out[i], HIGH);
      else digitalWrite(out[i], LOW);
      tmElStr[i] = cMillis;              // reset the counter to 0 so the counting starts over...
    }
  }

  // random blinking LED
  cMillis=millis();
  if (!LEDState  && (cMillis-tmElStrLED) > LEDTime) 
  {
    LEDState = !LEDState;         // toggle the state 
    digitalWrite(LEDOut, LEDState);
    tmElStrLED = cMillis;
    LEDTime = 50 + rand() % 200;              // LED ON period
  }
  if (LEDState  && (cMillis-tmElStrLED) > LEDTime) 
  {
    LEDState = !LEDState;         // toggle the state 
    digitalWrite(LEDOut, LEDState);
    tmElStrLED = cMillis;
    LEDTime = 50 + rand() % 1000;              // LED OFF period
    if(LEDTime < 400) LEDTime = 100;
  }
  
  // signal strength LED

  cMillis=millis();
  td = cMillis - tmElStrstr - strTime;
  if (td >= 0) 
  {
    if(conn) {
        sigstr = (int)Network.RSSI();      // what's the signal strength
        strcpy(SSID,Network.SSID());       // wi-fi network name
    }
    else {
        sigstr = -80;
    }

    if(td > 20000)                     // 20 secs more than expected -> some sort of slow down bug??? record it.
      {
         delay(20);
         int bugCount = EEPROM.read(98);
         delay(20);
         if(bugCount >= 250) bugCount = 0;
         delay(20);
         EEPROM.write(98,bugCount + 1);
         bugMins = cMins;
         delay(20);
         bugsig = sigstr;
         bugtime = td;
      } 
      
    if(!strState) 
    {
        strTime = map(sigstr,-80,-50,150,4000);
        strTime = constrain(strTime,150,4000);
        strState = HIGH;
        digitalWrite(strOut, HIGH);
    }
    else
    {
        strTime = 300;
        strState = LOW;
        digitalWrite(strOut, LOW);
    }
    tmElStrstr = cMillis;
  }
}

There are various other support functions that are not called frequently, eg UNIXMONTH, DAYSMONTH, pattern[][], etc. are stored in EEPROM and received OTA using a spark.function and read from memory upon reset or on command. The spark.publish component is in development and only works when connected.

Debugging capability is limited and is normally via queries to various variables using a spark.function as it is not easy to wire up via USB when in-situ.

The core is being used in a kinetic artwork driven by data scraped from a public website. The example here is running with a UNO which requires me to reprogram it daily by USB. The goal is to program it from home OTA with the core. Data scraping and communication uses Processing, but I just saw this post which gives me hope the whole thing can be done real-time on the core - subject to my programming skills :sweat_smile:

Thanks for your help,
Andrew

Bugger. Just ran my hourly check and there has been a freeze in the last hour. bugCount tracks that via an EEPROM stored counter and it increased by 3, suggesting either 3 freezes or the test passed 3 times in succession.

The number of resets also incremented by 1 so the core reset itself as well that time and that hasn’t happened in days. This variable is also stored in EEPROM and updated at reset.

I’m perplexed.

Actually witnessed a freeze/reset this time.

The core had been in breathing green mode (disconnected) and it was 10 minutes after the scheduled 1 minute of connect time (I did not see this). When I noticed it the core was blinking cyan and it did this for 30 secs, it then appeared to blink red (maybe this was an SOS pattern) and then flashed red once. It then blinked green for 5 secs or so, blinked cyan for a few secs and then started breathing cyan and continued as if it was a normal reset. During the first blinking cyan the other outputs of the core were frozen.

I invariably get reports of RSSI 2db after exactly 12 loops of the following code, seemingly regardless of whether compiled on the cloud or locally. Any ideas why?

unsigned long loopNum = 0;
void setup() {
    Serial.begin(115200);
}

void loop() {
    Serial.print("Loop: "); Serial.println(loopNum++);
    Serial.print("SSID: "); Serial.println(WiFi.SSID());
    Serial.print("RSSI: "); Serial.print(WiFi.RSSI()); Serial.println("dB");
    Serial.println();
    delay(5000);
}