Yun Crashes when writing to Thingspeak

I have set up my Arduino Yun to monitor temperature and adjust a vent for my BBQ smoker. I am using cloudMQTT to send live data to a webpage and I write data every 20 seconds to Thingspeak for storing data. Since I started writing to Thingspeak my Yun stops working/crashes after anywhere between 30 min and 90 min at which point my website stops receiving data from my Yun. When I re-upload the sketch or unplug-and-plug the Yun it starts working again. I've checked the forums for possible problems but haven't been able to uncover a cause or solution. I upgraded OpenWrt when I purchased my Yun a couple months ago. I'm running IDE 1.6.4. I looked at the System Log of the webpanel and saw this message at the time I stopped receiving messages: authpriv.info dropbear[19771]: Exit (root): Error writing. But I don't know how to address the issue of 'error writing'. Any ideas on how to solve this?? I'm attaching my code. As an aside, I previously tried using HttpClient with a client.get command but ran into the same issue.

#include <math.h>
#include <PubSubClient.h>
#include <string.h>
#include <Bridge.h>
#include <YunClient.h>
#include <Console.h>
#include <Servo.h>
#include <ArduinoJson.h>
 
#define MQTT_SERVER  "xxx"
#define USER "xxx"               
#define PASSWORD "xxx"
#define TOPIC "xxx"
#define PAYLOAD "xxx"
#define NAME "xxx"

#define     A_COEFFICIENT          0.0010689658797
#define     B_COEFFICIENT          0.0002977342773
#define     C_COEFFICIENT          0.0000027993909

#define     THERMISTOR_PIN1        0       // Analog pin to read thermistor values.
#define     THERMISTOR_PIN2        2       // Analog pin to read thermistor values.
#define     SERIES_RESISTOR        100000   // Resistor value (in Ohms) in series with the thermistor.
#define     ADC_SAMPLES            30       // Number of ADC samples to average for a reading.
#define     TIME_CHECK             5000

Servo myservo;  // create servo object to control a servo
int servoDeg;    // variable to read the degree value from the analog pin
int servoVal;    // variable that converts degrees to a scale of 1-10

int temperature1;
int temperature2;
int tempLast;
int myTempHistory[10];
int myTempChange;
int myRule = 0;
int EGG_TARGET = 225;
int MEAT_TARGET = 185;

String thingspeak_write_API_key = "xxx";//Insert Your Write API key here 
char thingSpeakAddress[] = "api.thingspeak.com";

unsigned long time;
unsigned long timeLastMQTT;
unsigned long timeLastTS;

// Variable Setup
long lastConnectionTime = 0; 
boolean lastConnected = false;
int failedCounter = 0;

YunClient yunClient;
YunClient TS2client;
PubSubClient client(MQTT_SERVER, 11639, callback, yunClient);
char message_buff[200];

void setup()
{
  Bridge.begin();
  Console.begin();
  myservo.attach(9);  // attaches the servo on pin 9 to the servo object  
  servoDeg = 130;
  myservo.write(servoDeg);
  time = millis();
  timeLastMQTT = time;
  timeLastTS = time;  
  
}

void loop() {
  time = millis();
  
  if (!client.connected()) { 
      // clientID, username, MD5 encoded password
      client.connect(NAME, USER, PASSWORD);
      client.publish(TOPIC, PAYLOAD);
      client.subscribe(TOPIC);
} 
    // update sensor values
    temperature1 = int(readTemp(THERMISTOR_PIN1));
    temperature2 = int(readTemp(THERMISTOR_PIN2));
    
    // update Servo 
    if ((time-timeLastMQTT) > TIME_CHECK) {  
      servoVal = updateServo(temperature1, EGG_TARGET, servoVal, tempLast);
    }
    
    // update temp history
      tempLast = temperature1;
      myTempHistory[0] = tempLast;
      for (int n = 9; n > 0; --n) {
        myTempHistory[n] = myTempHistory[n-1] ;      
      }
      myTempChange = myTempHistory[0] - myTempHistory[5];  //difference in temperature from the past 5 readings
  
  
    //build and write JSON
    String json = buildJson(temperature1, temperature2, servoVal, EGG_TARGET, MEAT_TARGET);
    char jsonStr[200];
    json.toCharArray(jsonStr,200);    
    client.publish(TOPIC, jsonStr);
    timeLastMQTT = time;
    
    //write to Thingspeak
    if ((millis()-timeLastTS) > 20000) {
     String thing_jsonstring = "field1="+String(temperature1)+"&field2="+String(temperature2)+"&field3="+String(servoVal)+"&field4="+String(EGG_TARGET)+"&field5="+String(MEAT_TARGET); 
     postToThingspeak(thing_jsonstring);
     timeLastTS = millis();
    }
    
    delay(50);  
     
  // MQTT client loop processing
  client.loop();

}
  
// handles message arrived on subscribed topic(s)
void callback(char* topic, byte* payload, unsigned int length) {
  int i = 0;
  for(i=0; i<length; i++) {
    message_buff[i] = payload[i];
  }
  message_buff[i] = '\0';
  //String msgString = String(message_buff);
  StaticJsonBuffer<200> jsonBuffer;
  JsonObject& root = jsonBuffer.parseObject(message_buff);
  int aMeatTarget = root["MeatTarget"];
  int aEggTarget = root["EggTarget"];
  if (aMeatTarget != MEAT_TARGET && !root.containsKey("EggTarget")) {
    MEAT_TARGET = aMeatTarget;
  } else if (aEggTarget != EGG_TARGET && !root.containsKey("MeatTarget")) {
     EGG_TARGET = aEggTarget;
  }
 
}

String buildJson(int j1, int j2, int j3, int j4, int j5) {
  String data = "{";
  data+="\"Probe1\": ";
  data+= j1;
  data+= ", ";
  data+="\"Probe2\": ";
  data+= j2;
  data+= ", ";
  data+="\"Servo\": ";
  data+= j3;
  data+=", ";
  data+="\"EggTarget\": ";
  data+= j4;
  data+=", ";
  data+="\"MeatTarget\": ";
  data+= j5;
  data+="}";
  return data;
}

float readTemp(int PIN) {
  float R = 0;
  for (int i = 0; i < ADC_SAMPLES; ++i) {
  R += analogRead(PIN);
   delay(50);
  }
  R /= (float)ADC_SAMPLES;
  R = SERIES_RESISTOR/((1023 / R) - 1);
  R = log10(R);
 return (1/(A_COEFFICIENT + B_COEFFICIENT*R + C_COEFFICIENT*pow(R, 3)))*9/5-459.67;
}

int updateServo(int temperature1, int eggTarget, int servoVal, int tempLast) {
   
  if (temperature1 > (eggTarget + 10) && temperature1 > tempLast) {
    servoVal = max(servoVal - 2, 1);
    myRule = 1;
  } else if (temperature1 > (eggTarget + 10) && temperature1 <= tempLast) {
    servoVal = max(servoVal - 1, 1);
    myRule = 2;
  } else if (temperature1 > (eggTarget + 5) && temperature1 > tempLast) {
    servoVal = max(servoVal - 1, 1);
    myRule = 3;
  } else if (temperature1 < (eggTarget - 10) && temperature1 < tempLast) {
    servoVal = min(servoVal + 2, 10);  
    myRule = 4;
  } else if (temperature1 < (eggTarget - 10) && temperature1 >= tempLast) {
    servoVal = min(servoVal + 1, 10);
    myRule = 5;
  } else if (temperature1 < (eggTarget - 5) && temperature1 < tempLast) {
    servoVal = min(servoVal + 1, 10);
    myRule = 6;
  } else if (myTempChange > 4) {
    servoVal = max(servoVal - 2, 1);
    myRule = 7;
  } else if (myTempChange < -4) {
    servoVal = min(servoVal + 2, 10);
    myRule = 8;
  }

  int newServoDeg;
  newServoDeg = 155-(4*(servoVal-1));
  myservo.write(newServoDeg);
  return servoVal;
 }

 void postToThingspeak(String tsData) {

 
  if (TS2client.connect(thingSpeakAddress, 80))
 
  {         
    TS2client.print("POST /update HTTP/1.1\n");
    TS2client.print("Host: api.thingspeak.com\n");
    TS2client.print("Connection: close\n");
    TS2client.print("X-THINGSPEAKAPIKEY: "+thingspeak_write_API_key+"\n");
    TS2client.print("Content-Type: application/x-www-form-urlencoded\n");
    TS2client.print("Content-Length: ");
    TS2client.print(tsData.length());
    TS2client.print("\n\n");
    TS2client.print(tsData);
    lastConnectionTime = millis();
            
    if (TS2client.connected())
    {
     failedCounter = 0;
    }
    else
    {
      failedCounter++;
  
      Console.println("Connection to Thingspeak failed ("+String(failedCounter, DEC)+")");   
    }
    
  }
  else
  {
    failedCounter++;
    
    Console.println("Connection to Thingspeak Failed ("+String(failedCounter, DEC)+")");   
    
    lastConnectionTime = millis(); 
  }
}

Are you using the ThingSpeak Communication Library for Arduino? It should help with this.

https://forum.arduino.cc/index.php?topic=343365.0

All the best,
-Rob

Id talk to ThingsSpeak from the linux side, using python its easy.
Your atmega may be running out of sram because of the many libraries you have in the sketch. Id move most of the code to python and leave only the sensor reading on the atmega.

Thank you Rob and mart256. I have a stable version up and running using the Thingspeak library but as mart256 observed I am running low on sram (99%). I will work on moving the Thingspeak function to the linux side so I can open space to do other things.

Rob - the only issue I have is that when I use the setField then writeFields functions I'm only able to get it to work with four fields. When I try and set five fields then write it returns null for all values. Any idea why this might be happening?

I'll take a look -- would you be able to share a snippet of your code so I can try to reproduce it? I can't imagine why it would stop after 4 fields, but I'll look into it and fix it if I can repro.

-Rob

#include <math.h>
#include <PubSubClient.h>
#include <string.h>
#include <Bridge.h>
#include <YunClient.h>
#include <Console.h>
#include <Servo.h>
#include <ArduinoJson.h>

a way over too much load at ATmega32u4, move most of them into AR9331 please.

http://forum.arduino.cc/index.php?topic=349996.msg2418791#msg2418791