How to reconnect the MKR to WIFi

Hello
I have made a project using MKR1000 which sense the environment readings from outside every 5 minutes and send their hourly average to the server database every hour. I have also attached a screen display locally at MKR1000 which displays the present readings and display changes every 5 minutes with new readings.
when I tested my system it worked fine for the 5-6 hours and sometimes upto 12 hours but after that it stops sending data to server however display at screen is changing every 5 minutes with latest values.
So it means problem is MKR is not able to send data to server may be its WiFi connectivity is interrupted.

So my question is how to check for status of WiFi connection in the loop programming of MKR and if connection is lost how to reconnect it to WiFi ?

Hi @aurora123,

Please take a look at the following: ArduinoCloud/ReadAndWrite.ino at master · arduino-libraries/ArduinoCloud · GitHub

  if ( WiFi.status() != WL_CONNECTED) {
    while (WiFi.begin(ssid, pass) != WL_CONNECTED) {
      // unsuccessful, retry in 4 seconds
      Serial.print("failed ... ");
      delay(4000);
      Serial.print("retrying ... ");
    }
  }

hi @sandeepmistry
I tried this code, but WiFi is not getting reconnecting once the connection is lost.

Is there any other way?

Hi @aurora123,

Could you please share your full sketch and the output of the Serial monitor? Also, what version of the WiFi101 library are you using?

Sandeep -

Overall, I have been successful in creating a functional system to monitor various sensors, and transmit the data to an IOT server (Carriots) ... however I have had similar issues with "reconnecting to wifi" ... using the MRK1000

The bit of code you posted seems similar to the code below that I have been using ... except for the "delays" you have indicated ...

// attempt to connect to Wifi network:
// It appears that it will stay in this loop until connected
while (status != WL_CONNECTED)
{
Serial.print("Attempting to connect to SSID: ");
Serial.println(ssid);
// Connect to WPA/WPA2 network.
status = WiFi.begin(ssid, pass);
}

My code then goes on to send a "Connected to " message via Serial.print ... just for verification ...
Issues a "Client.connect(server,80) command ... and posts data to an IOT server ... then
Issues a "Client.stop() command to drop the server connection ... and loops back to repeat the process which of course includes all of the initial code to identify the ssid and password and reestablish the network connection.

My understanding of this code, and the code bit that you posted, would make me think that if "status" does not equal "WL_CONNECTED", then it would stay in this "while" loop indefinitely ... and not exit until the "status" EQUALS "WL_CONNECTED"

My experience has been that if the signal strength is weak and no connection is made ... at some point the "if" or "while" statement is ignored, and the code continues past that point to continue with the LCD display of data ... but does NOT reconnect to the defined wifi network. My solution has been to simply unplug the power supply to the MRK1000, and it resets ... and when the code calls for a "new" connection to the "WiFi" it does so properly.

I am using the SAMD Board driver version 1.6.6 running on Arduino IDE 1.6.11.

It appears that the SAMD driver has many updates ... up to version 1.6.11 ... and I have not checked the Arduino IDE in a while.

Any comments or thoughts?

hi @sandeepmistry,

This is the code I am using in my loop function to reconnect to wifi

status = WiFi.status();
    delay(1000);
    if(status == WL_CONNECTED)  
    {
       datatransfer();
    }
    else 
    {
    int retries=0;
    Serial.println("Connection to Network Interruptted");
    if(WiFi.status() != WL_CONNECTED)
    WiFi.begin(ssid, pass);      // wait 10 seconds for connection:
    delay(6000);
    status = WiFi.status();
    Serial.println(status);
    while((status != WL_CONNECTED) && (retries<2))
    {
      WiFi.begin(ssid, pass); 
      retries++;
      Serial.println("\n Trying to Reconnect to WiFi Network ");
      delay(5000);
      status = WiFi.status();
      Serial.println(status);
    }
    printWifiStatus();
    }

I am able to reconnect to WIFI with the help of this code when I test it on my desktop..but when I put my MKR1000 board outside in a box where WIFI signal strength is good then it runs good for many hours but if once it loses its connection to WIFI then it doesn't connect to WIFI easily.
I have placed my board for test on 16th jan, it transferred the readings uninterrupted til 17th jan 3 p.m but after that it send next value after 4 hours (i.e average value of 4 hours), that was okay as I didn't placed the re-connect part in infinite while loop. After that it continued to send the readings till 12:00 p.m 18th jan, and until now it has not reconnected to WIFI while it is displaying the present readings on screen correctly.
The part where it didn't send for 4 hours was okay but it is still not able to connect from the past 24 hours is a problem, as if I restart/reset the MKR then my past data will be lost.

What changes do you recommend.
Does material of the box affect signal strength ??
I am confused as in that box only it was able to reconnect earlier.

Thanks

Aurora and Sandeepmistry -

I have been following this topic as well and have a very similar problem.
In my recent post I indicated that I am using version 1.6.11 of the Arduino IDE and version 1.6.6 of the SAMD board driver. My connection strength as indicated by the WifiStatus() function varies from -70 to -64 or so. I feel this is acceptable for my distance and tree cover. Line of sight is a little tough, and I have not seen an option for an antenna with the MRK1000 board. My assembled unit is in a RED box from SparkFun. I would NOT consider a metal box as that could degrade the signal of the onboard antenna.

Several questions come to mind -

Aurora - could you share what versions of the Arduino software are you using?
Does anyone think that the WiFi101 library has changed significantly? My download shows a 2014 date.

Lastly, when I issue a "Serial.print(status) command ... it returns the number 3 ... how does that relate to the WL_CONNECTED status in the WiFi101.h library? I am not clear on the way various status codes are "enumerated", but it appears that WL_CONNECTED would return "3" perhaps, and "WL_DISCONNECT" may return a different integer???

Best regards -

Jim

I am using Arduino IDE Version 1.6.12 and WiFi 101 library version is 0.11.2.
and yes Serial.print(status) returns 3 when connected to wifi and 6 when not connected.
According to me 3 represents connected status but I don't know what does 6 indicate.

WiFi.status()

Description

Return the connection status.

Syntax

WiFi.status();

Parameters

none

Returns

WL_CONNECTED: assigned when connected to a WiFi network;
WL_NO_SHIELD: assigned when no WiFi shield is present;
WL_IDLE_STATUS: it is a temporary status assigned when WiFi.begin() is called and remains active until the number of attempts expires (resulting in WL_CONNECT_FAILED) or a connection is established (resulting in WL_CONNECTED);
WL_NO_SSID_AVAIL: assigned when no SSID are available;
WL_SCAN_COMPLETED: assigned when the scan networks is completed;
WL_CONNECT_FAILED: assigned when the connection fails for all the attempts;
WL_CONNECTION_LOST: assigned when the connection is lost;
WL_DISCONNECTED: assigned when disconnected from a network;

WiFi library shown above has different return conditions but which number represents which condition I have no idea.
Thanks

Aurora and Sandeepmistry -

It seems we are running the same versions. I am hesitant to upgrade to Arduino ver. 1.8 unless the WiFi101 library requires it. Open source software is new to me as well.

As I interpret the WiFi101 code block, the "typedef enum" function actually assigns a number value in numeric order to a list of variables ... so CONNECTION_LOST would return a 5 if you count down from the assigned values starting with WL_IDLE_STATUS as 0.

typedef enum {
WL_NO_SHIELD = 255,
WL_IDLE_STATUS = 0,
WL_NO_SSID_AVAIL,
WL_SCAN_COMPLETED,
WL_CONNECTED,
WL_CONNECT_FAILED,
WL_CONNECTION_LOST,
WL_DISCONNECTED
}

Still our problem is that we are loosing a connection, and the "WiFi.begin(ssid,pass)" does not seem to reconnect properly. What I was thinking was to try to send a hard reset to the MRK1000 by setting the reset pin to high after a certain number of retries. Not sure exactly what the code would be for that, but something like your retries counter and identifying the proper pin number to connect to ground. That simulates my physically disconnecting the board from power, which is my present solution.

Hopefully Sandeepmistry or others will have some comments.

Jim

Hard Reset will not be the solution to my problem as after reset board will loose the readings to be transferred and will start again..My previous data will be lost which doesn't make my system reliable.

Hi all!
First of all, excuse my english, but I hope you understand me.
I opened an issue to the Wifi101 GitHub site, on past June:

The problem described there is basically same as yours: lost of wifi connection after a time.
Through different tests and improvements, the library becomed more stable but, still today it keeps the same problem (at least to me...).
In that case, not many users were founding this behaviour, nor was easily reproductable.
In the first versions, the test sketch hanged after a few hours or days of serving a webpage (throug the sketch example 'SimpleWebServerWifi.ino'), althroug it had a re-connection routine.
Nowdays, i've found the webserver keeps alive after many days BUT...if i disconnect manually the home router, and then reconnect it, the board isn't able to attach again.
This means the system is not reliable enough to keep serving a webpage on a remote location, because it is sensible to any wify disconnection.
So, sandeepmistry, could you study this case a little bit deeply, please?
Thank you very much!

Hi, me too am having the wifi connection issue. I've been searching the internet for days now without success.

Configuration:
Firmware version: 19.4.4
Arduino IDE:1.8.0
WiFi101: 0.13.0
Mac OS 10.12.3

MKR1000 connects to a server (Raspberry PI) with Node-Red.

This is my source code:

#define DEBUG
 
#define ONE_WIRE_BUS 7

#include <RTCZero.h>
#include <SPI.h>
#include <WiFi101.h>
#include <OneWire.h>
#include <DallasTemperature.h>

RTCZero rtc;
IPAddress server(192,168,1,33);
WiFiClient client;

// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);

// Pass our oneWire reference to Dallas Temperature. 
DallasTemperature sensors(&oneWire);

char ssid[] = "mySSID";     //  your network SSID (name)
char pass[] = "MyPassword";  // your network password
int status = WL_IDLE_STATUS;     // the WiFi radio's status
bool flag = false;
const byte seconds=0;
byte minutes;
byte hours;
const byte sleepMinutes = 1;
const byte sleepSeconds = 30;
const byte maxReadings = 14;
float vorigeTemp = 0.0;
float tempSensorA;
float tempSensorB;
float temperatuur;
byte teller;
bool verbonden;

void setup() {
  // wacht om door te gaan om sleep mode te kunnen omzeilen
  delay(10000);

  //Initialize serial and wait for port to open:
  Serial.begin(9600);

  sensors.begin();

  rtc.begin();
  rtc.setTime(0, 0, 0);
  rtc.setDate(1, 1, 2000);
  
  // check for the presence of the shield:
  if (WiFi.status() == WL_NO_SHIELD) {
    while(true);
  } 

  /*Serial.print("Firmware version: ");
  Serial.println(WiFi.firmwareVersion());*/
}

void loop() {
    //makeWifiConnection();
    getTemperatuur();
    delay(15000);
    //goDeepSleep();
}

void getTemperatuur() {
  // if you get a connection, report back via serial:
  sensors.requestTemperatures();
  delay(200);
  tempSensorA = sensors.getTempCByIndex(0);
  tempSensorB = sensors.getTempCByIndex(1);
  temperatuur = (tempSensorA + tempSensorB) / 2;
  
  // Temperatuur verzenden
  Serial.println("make connection");

  // Maak WiFi Connection
  // check for the presence of the shield:
  if (WiFi.status() == WL_NO_SHIELD) {
    //Serial.println("WL_NO_SHIELD");
    // don't continue:
    while (true);
  }

  //status = WiFi.begin(ssid, pass);
  // attempt to connect to WiFi network:
  teller = 0;
  while (teller++ < 5) {
    Serial.println("wait for connection...");
    Serial.println(teller);
    while ( status != WL_CONNECTED) {
      // Connect to WPA/WPA2 network:
      status = WiFi.begin(ssid, pass);
      // wait 10 seconds for connection:
      //delay(4000);
    }
    delay(4000);
    if ( status = WL_CONNECTED ) {
      teller = 6;
    }
  }
  Serial.println("Sending temp");
  verbonden = false;
  teller = 0;
  while (teller++ < 5  ) {
    Serial.println("wait for client connection...");
    Serial.println(teller);  
    verbonden = client.connect(server, 2000);
    if (verbonden) {
      teller = 6;
    }
    delay(2000);
    }
    if (!verbonden) {
      Serial.println("Client connect failed");
    }
    
    String cmd = "{\"kamer\":\"K00\", \"temperatuur\":";
    String temp = cmd + temperatuur + "}";
    Serial.println(temp);
    client.print(temp);
    //delay(200);
    
    client.stop();    

  WiFi.end();
  Serial.println("Wifi closed");
}

// put arduino in deep sleep mode
void goDeepSleep() {
   
  //Serial.println("goDeepSleep - start");
  //hours = rtc.getHours();
  //minutes = rtc.getMinutes();
  rtc.setTime(0, 0, 0);
  
  rtc.setAlarmTime(00, 0, sleepSeconds); //set alarm time to go off in 10 seconds
  
  //following two lines enable alarm, comment both out if you want to do external interrupt
  rtc.enableAlarm(rtc.MATCH_HHMMSS); //set alarm
  rtc.attachInterrupt(wakeUp); //creates an interrupt that wakes the SAMD21 which is triggered by a FTC alarm
  //comment out the below line if you are using RTC alarm for interrupt
 // extInterrupt(A1); //creates an interrupt source on external pin
  
  //puts SAMD21 to sleep
  rtc.standbyMode(); //library call
  //samSleep(); //function to show how call works
}


void wakeUp() {   
  // wakker geworden
  //Serial.println("wakeUp - Start");
  //WiFiClient client;
}

Running this script gives the following output on the serial monitor

make connection
wait for connection...
1
Sending temp
wait for client connection...
1
{"kamer":"K00", "temperatuur":22.53}
Wifi closed
make connection
wait for connection...
1
Sending temp
wait for client connection...
1
wait for client connection...
2
wait for client connection...
3
wait for client connection...
4
wait for client connection...
5
Client connect failed
{"kamer":"K00", "temperatuur":22.56}
Wifi closed

The temperature never arrives at the server, and the connection to the server seems to fail.

What I also notice on de Node-Red side is that the connections don't seem to close (see image in attach)

When I comment out the Wifi.end() all works well.
Than the connections at Node-Red side open and close properly.

What I find strange is that it worked for about a week with the doDeepSleep active. Any suggestion are more than welcome. I'm a bit desperate on this one.

NodeRedTCP.jpg

After commenting out Wifi.end() , do you receive data on the server ??

Also my WiFi re-connectivity problem solved when I placed my device nearer to the wifi Router.
Guess the problem was with the strength of the signal...

Hi,
I have looked through this topic and it is relevant to the problem I am having with all of my MKR1000's - they will connect to a network using connect code above, however after a while they drop the connection and will not reconnect without a hard reboot - no a viable solution.

Has there been any working solution to this yet?

@ D6equj5

Did you do the firmware update ?

That fixes almost all the connection issues.Even my BETA version MKR is exceptionally stable since the upgrade.

ballscrewbob:
@ D6equj5

Did you do the firmware update ?

That fixes almost all the connection issues.Even my BETA version MKR is exceptionally stable since the upgrade.

Excellent, thank you. No I did not "do the firmware upgrade" (presumably not a dance).
I gave as much info, to go on, as was necessary. Usually I found giving lots of unnecessary code, distracts the helper into critisising the coding style and belittling the requester so I tend not to give code where not necessary.
Thanks again.

A short video here of the process MKR1000 Firmware update 2017 04 13 at 13 53 33 - YouTube

I don't understand how you solve the problem.

I'm using:

    • MKR1000 - ATMEL 2015 AMW25-MR510PB Rev.R3
    • IDE 1.8.10.0
    • WiFi101 Firemware WINC 1501 Model B (19.5.2) - current available firmware

I have found that the status (status = WiFi.begin(ssid, pass):wink: always remains in the staus == WL_CONNECTED.
(as described by Aquaponics2016)

When I reboot my Router (WiFi - Access Point for the MKR1000) - the status is "WL_CONNECTED" and will not changed to WL_CONNECT_FAILED, or WL_CONNECTION_LOST or WL_DISCONNECTED.

After the reboot of the router the WiFi connection will not be re-established.
Is that works as designed?

Hi,
I'm having a very similar problem. I have 2 MKR Wifi 1010 and 2 ESP8266 communicating through my WiFi.
I have a Mosquitto MQTT broker in my Raspberry Pi to exchange messages between the MKRs and ESPs.
The 2 ESP8266 work without any problems, but the 2 MKRs get blocked after a few hours.
The MKRs are sometimes able to reconnect, but after some hours in the end they fail and get blocked. It's not anly that they don't reconnect, but the also stop working with the rest of the code.
I've updated the firmware in both MKRs, but no improvements.

Has anybody found a way to reconnect always?

#include <WiFiNINA.h>                          // For the ESP8266 I've used ESP8266WiFi.h
#include <PubSubClient.h>


const char* ssid = "CASA4";
const char* password = "mypassword";
const char* mqtt_server = "192.168.0.192";
const int LED_VERDE = 7;                          // Pin for LED green.
const int LED_ROJO = 8;                           // Pin for LED Red.
const int PULSADOR = 9;                          // Pin for the pushbutton.
unsigned long instante = 0;                       // For the debounce.
boolean gatillo = LOW;
int veces = 0;                                    // To count the times I connect to the WiFi.
long lastReconnectAttempt = 0;

WiFiClient espClient;
PubSubClient client(espClient);                

char msg[50];                                     //************--------------do I need this? ***
String clientId = "mkr01";           

void basculo() {
  digitalWrite(LED_ROJO, gatillo);
  if (gatillo == HIGH) {
    client.publish("mkr01/pulsador", "1");       // Publish "1" in "mkr01/pulsador" topic
  }
  else {
    client.publish("mkr01/pulsador", "0");       // Publish "0" in "mkr01/pulsador" topic
  }
  Serial.println(gatillo);
  gatillo = !gatillo;
}

void setup_wifi() {                      // Connect to WiFi.
  delay(10);

  Serial.println();
  Serial.print("Conectando a ");
  Serial.println(ssid);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  randomSeed(micros());

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}

void callback(char* topic, byte* payload, unsigned int length) {    
  Serial.print("Incoming message: [");
  Serial.print(topic);
  Serial.print("] ");
  for (int i = 0; i < length; i++) {
    Serial.print((char)payload[i]);
  }
  Serial.println();

  // Switch on the green LED if a 1 was received as first character
  if ((char)payload[0] == '1') {
    digitalWrite(LED_VERDE, HIGH);
  }
  else {
    digitalWrite(LED_VERDE, LOW);
  }
}

boolean reconnect() {
  if (client.connect("mkr01")) {     
    // To see how many times do I re-connect:
    veces++; 
    Serial.print("Veces re-conectado: ");             
    Serial.println(veces);                           

  // Once connected, publish an announcement...
    client.publish("mkr01/pulsador", "MKR01 connected ");
    // ... and resubscribe
    client.subscribe("+/pulsador");          // Subscribe to all topics that contain "pulsador".
  }
  return client.connected();
}


void setup() {

  pinMode(LED_VERDE, OUTPUT);
  pinMode(LED_ROJO, OUTPUT);
  pinMode(PULSADOR, INPUT_PULLUP);
  Serial.begin(115200);
  setup_wifi();
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);
  client.subscribe("+/pulsador");
}

void loop() {
    //  ***********This comes from the example 'mqtt_reconnect_nonblocking'
    if (!client.connected()) {
      long now = millis();
      if (now - lastReconnectAttempt > 5000) {
        lastReconnectAttempt = now;
        // Attempt to reconnect
    reconnect();
    if (reconnect()) {
          lastReconnectAttempt = 0;
        }
      }
    }


 client.loop();                                                    

  if (millis() > instante + 250) {                      // wait 250 ms for debounce.
    if (!digitalRead(PULSADOR)) {
      basculo();
    }
    instante = millis();
  }
}
if (client.connect("mkr01")) {

Every mqtt client must use a different/unique client name. mosquitto blocks clients with duplicate names. This is true for ESP and MKR.