Go Down

Topic: MKR100 stalls (Read 7617 times) previous topic - next topic

ballscrewbob

Pretty sure this will have been covered but searching the forum didn't bring anything relevant up for "mkr stall" or "mkr stops". Think there were issues with some MKRs doing similar to this during the beta testing competition but cant remember as I had a hell of a time getting it to play nice and work took over.

Finally got time to play with it and took an easy route.

I figured soak it on thingspeak as it would be easy to to log its behaviour.
Well its badly behaved.

Second time its stopped outputting to thingspeak unless I restart the MKR.

First time it ran for two hours before it dropped out and the second time it ran for 5 hours befotre it dropped the ball again.

You can see the dropouts here

I will be extending the delay on line 145 to cover thingspeaks suggested 15 second post limit.

Just wondering if its normal or there is something simple I missed.
My ESP's never miss a beat and neither do the ethernet Arduinos unless somebody unplugs em.



Below is the code I am currently using (borrowed from somewhere).

Code: [Select]
/*
This sketch is a combination of ADAFruits DHT sketch, WiFi101 Webclient
and The arduino example from ThingSpeak
Modified by Stephen Borsay for the MKR1000, feel free to use
 */

#include <SPI.h> //you don't need this as we arn't using the shiled just chip
#include <WiFi101.h>
#include "DHT.h"

#define DHTPIN 1    // what pin we're connected to, pin1 is 5th pin from end

// Uncomment whatever DHT sensor type you're using!
//#define DHTTYPE DHT11  // DHT 11
#define DHTTYPE DHT21  // DHT 21  (AM2301)
//#define DHTTYPE DHT22  // DHT 22

DHT dht(DHTPIN,DHTTYPE);

String apiKey ="xxxxxxxxxx"; // api from ThingSpeak

char ssid[] = "xxxxxxx"; //  your network SSID (name)
char pass[] = "xxxxxxx";    //your network password
int keyIndex = 0;     // your network key Index number (needed only for WEP)

//#define WEBSITE "api.thingspeak.com"

int status = WL_IDLE_STATUS;
// if you don't want to use DNS (and reduce your sketch size)
// use the numeric IP instead of the name for the server:
//IPAddress server(74,125,232,128);  // numeric IP for Google (no DNS)
char server[] = "api.thingspeak.com";    // name address for Google (using DNS)

// Initialize the Ethernet client library
// with the IP address and port of the server
// that you want to connect to (port 80 is default for HTTP):
WiFiClient client;

void setup() {
  //Initialize serial and wait for port to open:
  Serial.begin(9600);
  while (!Serial)
  {
    ; // wait for serial port to connect. Needed for native USB port only
  }

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

  // attempt to connect to Wifi network:
  while (status != WL_CONNECTED)
  {
    Serial.print("Attempting to connect to SSID: ");
    Serial.println(ssid);
    //Connect to WPA/WPA2 network.Change this line if using open/WEP network
    status = WiFi.begin(ssid, pass);

    // wait 10 seconds for connection:
    delay(10000);
  }
 
  Serial.println("Connected to wifi");
  printWifiStatus();
 
}

void loop() {

   // Wait a few seconds between measurements.
  delay(2000);

  //prefer to use float, but package size or float conversion isnt working
  //will revise in future with a string fuction or float conversion function

  int h = dht.readHumidity();
  // Read temperature as Celsius (the default)
  int t = dht.readTemperature();
  // Read temperature as Fahrenheit (isFahrenheit = true)
  int f = dht.readTemperature(true);

  // Check if any reads failed and exit early (to try again).
  if (isnan(h) || isnan(t) || isnan(f))
  {
    Serial.println("Failed to read from DHT sensor!");
    return;
  }

  // Compute heat index in Fahrenheit (the default)
  int hif = dht.computeHeatIndex(f, h);
  // Compute heat index in Celsius (isFahreheit = false)
  int hic = dht.computeHeatIndex(t, h, false);

  Serial.print("Humidity: ");
  Serial.print(h);
  Serial.print(" %\t");
  Serial.print("Temperature: ");
  Serial.print(t);
  Serial.print(" *C ");
  Serial.print(f);
  Serial.print(" *F\t");
  Serial.print("Heat index: ");
  Serial.print(hic);
  Serial.print(" *C ");
  Serial.print(hif);
  Serial.println(" *F\n");

    Serial.println("\nStarting connection to server...");
  // if you get a connection, report back via serial:
  if (client.connect(server, 80)) {
    Serial.println("connected to server");


          client.print(F("POST "));
          client.print("/update?key=apiKey&field1="
          +               (String) h
          +  "&field2=" +(String) t
          +  "&field3=" +(String) f
          +  "&field4=" +(String) hic
          +  "&field5=" +(String) hif
                                   );
                                     
          String tsData = "field1="   //need the length to give to ThingSpeak
          +             (String)  h
          +  "&field2=" +(String) t
          +  "&field3=" +(String) f
          +  "&field4=" +(String) hic
          +  "&field5=" +(String) hif
        ;


          client.print("POST /update HTTP/1.1\n"); 
          client.print("Host: api.thingspeak.com\n");
          client.print("Connection: close\n");
          client.print("X-THINGSPEAKAPIKEY: " + apiKey + "\n");
          client.print("Content-Type: application/x-www-form-urlencoded\n");
          client.print("Content-Length: ");
          client.print(tsData.length());  //send out data string legth to ts
          client.print("\n\n");
          client.print(tsData);
          client.stop();
          delay(10000); // 10 seconds + program cycle time (15 secs max post to TS)
    }

}


void printWifiStatus() {
  // print the SSID of the network you're attached to:
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());

  // print your WiFi shield's IP address:
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(ip);

  // print the received signal strength:
  long rssi = WiFi.RSSI();
  Serial.print("signal strength (RSSI):");
  Serial.print(rssi);
  Serial.println(" dBm");
}




It may not be the answer you were looking for but its the one I am giving based on either experience, educated guess, google or the fact that you gave nothing to go with in the first place so I used my wonky crystal ball.

sterretje

Maybe printing some info when a connection attempt fails will help to narrow it down

Code: [Select]

  if (client.connect(server, 80)) {
    Serial.print("connected to server: ");
    Serial.println (millis());
    ...
    ...
  }
  else
  {
    Serial.print("failed to connect to server: ");
    Serial.println (millis());
  }

I've modified your original println slightly to add a 'time' and added the else block. Maybe you can correlate your dropouts.

Looking at your code, the dropout might also be caused by a failure to read the sensor. But that should show on the serial monitor (or whatever you use).

Note that you need to keep your computer running with the serial monitor (or similar) application so you can view the results.

If you can't monitor the screen the whole time, you will need to find an alternative to serial monitor that can log to file. I think e.g. putty and realterm (and there will be others) can do so.

Note:
no experience with MKR1000 nor with WiFi nor with DHT
If you understand an example, use it.
If you don't understand an example, don't use it.

Electronics engineer by trade, software engineer by profession. Trying to get back into electronics after 15 years absence.

ballscrewbob

Thanks for getting back so quickly.

I found an updated version of the code to allow floats but that suffers from the same issue so I am back to v1

I can log via teraterm.

I tried to add your suggestion but it wont compile.
Only the first line "Serial.println (millis());" will compile. I get an error on line 67 "

"exit status 1
'printWifiStatus' was not declared in this scope" if I add the rest (not inc periods)


I can see the drop out in thingspeak and get a very close time that it happened.
That's why I posted the link. I set field 1 and 2 to show up the times.


Just noticed it dropped out again BUT as soon as I started the serial terminal it started to respond again as the serial terminal connected and I think there is a clue here but not sure why.

Did a bit more checking and there are still some issues with serial and the MKR so maybe that's what I am up against.
I may do a version without any serial prints and see how that goes.

It may not be the answer you were looking for but its the one I am giving based on either experience, educated guess, google or the fact that you gave nothing to go with in the first place so I used my wonky crystal ball.

sterretje

When you 'connect' a terminal program, the MKR might reset; this is the case for the SparkFun Redboard (Uno 'clone') that I use.

I assume that you replaced the "..." in my code by your original 'part'; else I can't explain the compile error.

You can post the new code and the full error (the output window contains more information than you gave ;)
If you understand an example, use it.
If you don't understand an example, don't use it.

Electronics engineer by trade, software engineer by profession. Trying to get back into electronics after 15 years absence.

ballscrewbob

At some point teraterm quit logging but despite that it ran the rest of the night without incident.

I believe you are correct in that an external event on the serial monitor acts like a soft reset of some sort.

There were no full resets caused by the monitor as nothing shows in the logs I have and nothing shows on the thingspeak channel.

Whatever the serial bug is makes the MKR unsuitable for long term monitor projects.

Not sure I am capable of writing some form of autoreset code into the program as thats the only method I can see to aid relibility.

Going to look again at adding your code as it is probably an error on my part.

Thinking aloud in that if I can get your code in it may be possible to use it as a trigger for an external hardware type reset.



It may not be the answer you were looking for but its the one I am giving based on either experience, educated guess, google or the fact that you gave nothing to go with in the first place so I used my wonky crystal ball.

sterretje

Note that auto-reset when connecting a terminal program is intended behaviour (for the Uno type boards). There are ways to work around it (like cutting a track).

You can consider the use of a watchdog timer (not sure if the MKR1000 has one in the micro). It's a piece of hardware (often embedded in the micro) that you have to kick once in a while. If you don't kick it, it will eventually cause a reset. It's usually used to force the system to get out of an endless loop.

As said, no experience with the MKR1000; there is a dedicated MKR1000 section; you might get better help there.
If you understand an example, use it.
If you don't understand an example, don't use it.

Electronics engineer by trade, software engineer by profession. Trying to get back into electronics after 15 years absence.

ballscrewbob

Yup found it thanks.

Can I get a mod to move this over there please ?
It may not be the answer you were looking for but its the one I am giving based on either experience, educated guess, google or the fact that you gave nothing to go with in the first place so I used my wonky crystal ball.

sterretje

Just click the report button under your first post in the thread and ask it to be moved ;)
If you understand an example, use it.
If you don't understand an example, don't use it.

Electronics engineer by trade, software engineer by profession. Trying to get back into electronics after 15 years absence.

ballscrewbob

#8
May 18, 2016, 06:56 pm Last Edit: May 19, 2016, 04:48 pm by Ballscrewbob
UPDATE

I had 5 connection errors to TS logged by monitoring the traffic from the MKR's IP but the board carried on regardless and worked as it should.
This I think confirms a serial error within the MKR itself.

Those connection errors did not follow any specific time pattern so could have been for any reason
The previous "stalls" when serial was enabled are also not within any sort of pattern either if I look at them on TS

------------------------------------------


I think I have isolated the problem with the MKR stalling out sending data to thingspeak.

Below is the code I swapped into the MKR and so far it has run  consistently without error.
If it continues then there would appear to be quite an issue with the serial section of the MKR.

Yes all I did was comment out anything serial but it seems to work.
It would also explain why I could not get reliable debug data for the MKR for my contest project. (small part of the reason I did not complete)

Code: [Select]
 /*
  This sketch is a combination of ADAFruits DHT sketch, WiFi101 Webclient
  and The arduino example from ThingSpeak
  Modified by Stephen Borsay for the MKR1000, feel free to use
   */
  
  #include <SPI.h> //you don't need this as we arn't using the shiled just chip
  #include <WiFi101.h>
  #include "DHT.h"
  
  #define DHTPIN 1    // what pin we're connected to, pin1 is 5th pin from end
  
  // Uncomment whatever DHT sensor type you're using!
  //#define DHTTYPE DHT11  // DHT 11
  #define DHTTYPE DHT21  // DHT 21
  //#define DHTTYPE DHT22  // DHT 22
  
  DHT dht(DHTPIN,DHTTYPE);
  
  String apiKey ="EDITED"; // api from ThingSpeak
  
  char ssid[] = "EDITED"; //  your network SSID (name)
  char pass[] = "EDITED";    //your network password
  int keyIndex = 0;     // your network key Index number (needed only for WEP)
  
  //#define WEBSITE "api.thingspeak.com"
  
  int status = WL_IDLE_STATUS;
  // if you don't want to use DNS (and reduce your sketch size)
  // use the numeric IP instead of the name for the server:
  //IPAddress server(74,125,232,128);  // numeric IP for Google (no DNS)
  char server[] = "api.thingspeak.com";    // name address for Google (using DNS)
  
  // Initialize the Ethernet client library
  // with the IP address and port of the server
  // that you want to connect to (port 80 is default for HTTP):
  WiFiClient client;
  
  void setup() {
    //Initialize serial and wait for port to open:
   // Serial.begin(9600);
   // while (!Serial)
    {
      ; // wait for serial port to connect. Needed for native USB port only
    }
  
    // check for the presence of the shield:
    if (WiFi.status() == WL_NO_SHIELD) {
    //  Serial.println("WiFi shield not present");
      // don't continue:
      while (true);
    }
  
    // attempt to connect to Wifi network:
    while (status != WL_CONNECTED)
    {
     // Serial.print("Attempting to connect to SSID: ");
     // Serial.println(ssid);
      //Connect to WPA/WPA2 network.Change this line if using open/WEP network
      status = WiFi.begin(ssid, pass);
  
      // wait 10 seconds for connection:
      delay(10000);
    }
    
   // Serial.println("Connected to wifi");
    printWifiStatus();
    
  }
  
  void loop() {
  
     // Wait a few seconds between measurements.
    delay(12000);
  
    //prefer to use float, but package size or float conversion isnt working
    //will revise in future with a string fuction or float conversion function
  
    int h = dht.readHumidity();
    // Read temperature as Celsius (the default)
    int t = dht.readTemperature();
    // Read temperature as Fahrenheit (isFahrenheit = true)
    int f = dht.readTemperature(true);
  
    // Check if any reads failed and exit early (to try again).
    if (isnan(h) || isnan(t) || isnan(f))
    {
    //  Serial.println("Failed to read from DHT sensor!");
      return;
    }
  
    // Compute heat index in Fahrenheit (the default)
    int hif = dht.computeHeatIndex(f, h);
    // Compute heat index in Celsius (isFahreheit = false)
    int hic = dht.computeHeatIndex(t, h, false);
  
  //  Serial.print("Humidity: ");
  //  Serial.print(h);
  //  Serial.print(" %\t");
  //  Serial.print("Temperature: ");
  //  Serial.print(t);
  //  Serial.print(" *C ");
  //  Serial.print(f);
  //  Serial.print(" *F\t");
  //  Serial.print("Heat index: ");
  //  Serial.print(hic);
  //  Serial.print(" *C ");
  //  Serial.print(hif);
  //  Serial.println(" *F\n");
  
    //  Serial.println("\nStarting connection to server...");
    // if you get a connection, report back via serial:
    if (client.connect(server, 80)) {
     // Serial.println("connected to server"); // original code

            client.print(F("POST "));
            client.print("/update?key=apiKey&field1="
            +               (String) h
            +  "&field2=" +(String) t
            +  "&field3=" +(String) f
            +  "&field4=" +(String) hic
            +  "&field5=" +(String) hif
                                     );
                                        
            String tsData = "field1="   //need the length to give to ThingSpeak
            +             (String)  h
            +  "&field2=" +(String) t
            +  "&field3=" +(String) f
            +  "&field4=" +(String) hic
            +  "&field5=" +(String) hif
          ;
  
  
            client.print("POST /update HTTP/1.1\n");  
            client.print("Host: api.thingspeak.com\n");
            client.print("Connection: close\n");
            client.print("X-THINGSPEAKAPIKEY: " + apiKey + "\n");
            client.print("Content-Type: application/x-www-form-urlencoded\n");
            client.print("Content-Length: ");
            client.print(tsData.length());  //send out data string legth to ts
            client.print("\n\n");
            client.print(tsData);
            client.stop();
            delay(1000); // 1 seconds + program cycle time
      }
  
  }
  
  void printWifiStatus() {
    // print the SSID of the network you're attached to:
    //   Serial.print("SSID: ");
    //  Serial.println(WiFi.SSID());
  
    // print your WiFi shield's IP address:
    IPAddress ip = WiFi.localIP();
    //  Serial.print("IP Address: ");
    //  Serial.println(ip);
  
    // print the received signal strength:
    long rssi = WiFi.RSSI();
    //  Serial.print("signal strength (RSSI):");
    //  Serial.print(rssi);
    // Serial.println(" dBm");
  }
It may not be the answer you were looking for but its the one I am giving based on either experience, educated guess, google or the fact that you gave nothing to go with in the first place so I used my wonky crystal ball.

ballscrewbob

So still not resolved. It just happened to run for quite a while with no issue but its back up to its old tricks.

Any help at all in sorting out why this thing that is supposedly meant for IOT will not behave itself in an IOT was eg. reliably.

Tried it on its own dedicated mini USB psu.
A powered hub that is also known for its reliability.
Checked my router logs and nothing amiss there.
Its not time specific in regards to the current time.
Not interval specific eg every 2 hours.

Disabling the serial seemed to help but now it seems to takes more than a simple reset to make it behave.
I have to do a regular reset and then try the serial monitor even though I know I am not going to get anything on the display.
It may not be the answer you were looking for but its the one I am giving based on either experience, educated guess, google or the fact that you gave nothing to go with in the first place so I used my wonky crystal ball.

sterretje

If your router logs show that the MKR1000 is sending data when you expect it, there are two options in my opinion.

MKR sends incorrect data
Other side isn't able to process it.

I would put some debug back in. You want to be able to see on the serial port that you can connect or not (both cases). You also want to be able to see which data is sent; this can indicate if the MKR1000 is at fault or something else.
If you understand an example, use it.
If you don't understand an example, don't use it.

Electronics engineer by trade, software engineer by profession. Trying to get back into electronics after 15 years absence.

ballscrewbob

Thanks sterretje.

The router logs show no outages and two other arduinos send consistently and have been doing for months via ethernet.

I managed to get your suggestion working and it was my fault.

Now I have very basic serial output with a single message for wifi connect, the millis counts for a good connect and a bad connect working with millis.

Seen a couple of missed connects but then it pushes data as normal until it just quits doing anything at all.

Now 100% sure its the MKR which is getting a pretty stable 4.97V 1A supply so I am also sure its not dropouts in power.

I love my ardies but this ones gonna get a slap round the cpu with a hammer if it dont behave  :)

It may not be the answer you were looking for but its the one I am giving based on either experience, educated guess, google or the fact that you gave nothing to go with in the first place so I used my wonky crystal ball.

sterretje

I don't understand how it can push out data if it can't connect. As far as I understand your code, after a failed connect it should only try to connect again after 12 seconds.

Not familiar with the networking side of things on the arduino. Does 'client.Stop' close the connection? If not, it's possible that you run out of connections. Is there a 'client.Close'?
If you understand an example, use it.
If you don't understand an example, don't use it.

Electronics engineer by trade, software engineer by profession. Trying to get back into electronics after 15 years absence.

ballscrewbob

If it achieves a connection it pushes the data.
If it doesn't achieve a connection it loops around and tries again
It doesn't stop trying at the first failure.

The output from your suggestion showed that but it was in the IDE comm windows and there is no CP from that to post here (wish they would ad CP to the serial windows)

Hopefully it fails again while I have tera term watching it as I can pull that and log it properly.
As I said I ruled out many of the easier things and am left with the MKR just giving up at some point all on its own.

Now if it gives up just after a failed connection that would be great as it may rule out the MKR but if it gives up after a good connection then that isolates completely down to the MKR.

This is a battle between me and it and one way or another I am going to win. I just have to be patient.
I swear it only drops out when I am not looking LOL

It may not be the answer you were looking for but its the one I am giving based on either experience, educated guess, google or the fact that you gave nothing to go with in the first place so I used my wonky crystal ball.

sterretje

It does not try again as far as I can see; there is a 12 second delay in the beginning of your loop. What am I missing?


You might want to add something in the line of

Code: [Select]

void loop()
{
  // variable to remember if data was send
  static bool fSend = false;

  // variables to remember when connect fails
  static int t = 0;
  static int h = 0;
  static int f = 0;

  // do a measurement if previous send was successful
  if(fSend == true)
  {
    // indicate that we have to send again
    fSend = false;
    delay(12000)

    // measure
    h = dht.readHumidity();
    t = dht.readTemperature();
    f = dht.readTemperature(true);
  }
  else
  {
    // nothing to do here
    // keep old readings for retry
  }

 
  if(fSend == false)
  {
    // if you get a connection, report back via serial:
    if (client.connect(server, 80))
    {
      // indicate success;
      fSend = true;

      // your send code here
      ...
      ...
    }
    else
    {
      // retry; nothing to do
    }

  }

 

}


You can copy from serial monitor; you just have to use the mouse and use <ctrl>C.
If you understand an example, use it.
If you don't understand an example, don't use it.

Electronics engineer by trade, software engineer by profession. Trying to get back into electronics after 15 years absence.

Go Up