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();
}
}