Dashboard Widgets Stop Updating After Two Days

I am using an Arduino Mega feeding sensor data to a Raspberry Pi 3B+ via Serial. I am using a DHT22, a ds18b20, an analog pH sensor, and a DF Robot Soil Moisture sensor. My sensors update great for about a day, and then they they cease to update. My devices are still listed as online. The RPi system data updates without a problem, but the data coming in from the Arduino stops updating after about 24 hrs. I have five channels of data coming in. The dashboard indicates that data packets are still being sent and are time stamped with the current time I am viewing them, but the data does not change. Here is a screen shot of my dashboard.

Here is the code running on the arduino mega

//Include DHT Library and declare DHT Type as DHT22 and Pin as 4
#include "DHT.h"
#define DHTTYPE DHT22
#define DHTPIN 4

//Include libraries for ds18b20 and declare pin as 2
#include <OneWire.h>
#include <DallasTemperature.h>
#define tempPin 2

//Create ds18b20 object
OneWire oneWire(tempPin);
DallasTemperature tempSensor(&oneWire);

//Create DHT Object
DHT dht(DHTPIN, DHTTYPE);

//Declare Channel Numbers for MQTT
const int airTempPin = 0;
const int humPin = 1;
const int waterTempPin = 2;
const int moisturePin = 3;
const int pHPin = 4;

//Create variables to hold sensor values
float hum, airTemp, waterTemp, moisturePercent, pHValue, voltage;

//unsigned long previousTime = 0;
//const int waitTime = 10000;

//Include library to communicate with Cayenne
#include <CayenneMQTTSerial.h>

// Cayenne authentication info. This should be obtained from the Cayenne Dashboard.
char username[] = "#####################";
char password[] = "#######################";
char clientID[] = "#########################";

//Import RCSwitch Library
#include <RCSwitch.h>

//Instantiate a mySwitch object from the RCSwitch library
RCSwitch mySwitch = RCSwitch();

//pH Reading values
#define SensorPin A2            //pH meter Analog output to Arduino Analog Input 1
#define Offset 0.12           //deviation compensate
#define LED 13
#define samplingInterval 20
#define printInterval 800
#define ArrayLength  40    //times of collection
int pHArray[ArrayLength];   //Store the average value of the sensor feedback
int pHArrayIndex=0;

void setup()
{
  //Baud rate can be specified by calling Cayenne.begin(username, password, clientID, 9600);
  Cayenne.begin(username, password, clientID);
  //Initialize DHT Object
  dht.begin();
  //Initialize ds18b20 Object
  tempSensor.begin();
  //Initialize the mySwitch object to transmit its signal through pin 10
  mySwitch.enableTransmit(10);
}

void loop() {
  Cayenne.loop();
  reportAirTemp(airTempPin);
  reportHumidity(humPin);
  reportWaterTemp(waterTempPin);
  reportMoisture(moisturePin);
  reportpH(pHPin);
}

void reportAirTemp(int airTempPin)
{
  float airTemp = dht.readTemperature(true);
  if (airTemp >= 78.00) {
  mySwitch.setPulseLength(178); 
 mySwitch.send("000100010101010100110011");//ON
}
  else {
    mySwitch.setPulseLength(178);
    mySwitch.send("000100010101010100111100");//OFF
    }

  Cayenne.virtualWrite(airTempPin, airTemp);
}

void reportHumidity(int humPin)
{
  float hum = dht.readHumidity();

  Cayenne.virtualWrite(humPin, hum);
}

void reportWaterTemp(int waterTempPin)
{
  tempSensor.requestTemperatures();
  waterTemp = tempSensor.getTempFByIndex(0);
  Cayenne.virtualWrite(waterTempPin, waterTemp);
}

void reportMoisture(int moisturePin)
{
 //Take raw data from Moisture Sensor 1  
float moisture = analogRead(A1);
//Print data to Serial for calibration and debugging
//Serial.println(moisture);
//Map raw Analog data to a percentage
moisturePercent = map(moisture, 294, 531, 100, 0);
moisturePercent = constrain(moisturePercent, 0, 100);
Cayenne.virtualWrite(moisturePin, moisturePercent);
}

void reportpH(int pHPin)
{
  static unsigned long samplingTime = millis();
  if(millis()-samplingTime > samplingInterval)
  {
      pHArray[pHArrayIndex++]=analogRead(SensorPin);
      if(pHArrayIndex==ArrayLength)pHArrayIndex=0;
      voltage = avergearray(pHArray, ArrayLength)*5.0/1024;
      pHValue = 3.5*voltage+Offset;

      samplingTime=millis();
  }
  Cayenne.virtualWrite(pHPin, pHValue);
}

double avergearray(int* arr, int number){
  int i;
  int max,min;
  double avg;
  long amount=0;
  if(number<=0){
    Serial.println("Error number for the array to avraging!/n");
    return 0;
  }
  if(number<5){   //less than 5, calculated directly statistics
    for(i=0;i<number;i++){
      amount+=arr[i];
    }
    avg = amount/number;
    return avg;
  }else{
    if(arr[0]<arr[1]){
      min = arr[0];max=arr[1];
    }
    else{
      min=arr[1];max=arr[0];
    }
    for(i=2;i<number;i++){
      if(arr[i]<min){
        amount+=min;        //arr<min
        min=arr[i];
      }else {
        if(arr[i]>max){
          amount+=max;    //arr>max
          max=arr[i];
        }else{
          amount+=arr[i]; //min<=arr<=max
        }
      }//if
    }//for
    avg = (double)amount/(number-2);
  }//if
  return avg;
}

Welcome to the community!

Looks like you are getting rate limited, please read this post Sending MQTT messages within rate limits

2 Likes

As @adam said you are hitting rate limit, just send data at time interval rather than sending continuously in loop.

1 Like

Thanks for the quick response. Makes perfect sense. I will try adding the delay with millis() as a solution.

1 Like