Publish at random intervals after a few hours

Hi,

I publish a variable to the cloud and to an mqtt broker every 3 seconds.

After a few hours the 3 second interval is random. It will go from as low as 3 seconds to as high ad 15 seconds.

After I reset the board it works fine for some hours again and then the intervals are random again.

Any clue on what this may be?

Thanks.

hmmmm… can you post your code?

Well, it is 364 lines and it is working with threads. I think everyone will be bored, but here goes:

SYSTEM_THREAD(ENABLED);
SYSTEM_MODE(AUTOMATIC);

#include "nokia-5110-lcd.h"
#include "MQTT.h"

#define mqtt_client_id    "01"
#define mqtt_user         "user"
#define mqtt_pass         "pass"
#define MQTT_PAYLOAD_SIZE 100

#define DIFF_PIN              A0
#define LCD_RS                D5
#define LCD_EN                D4

//#define SERIAL_DEBUG
#ifdef SERIAL_DEBUG
#define debug_print   Serial.printf
#else
#define debug_print   //
#endif

int LED = D7;
int blPin = D5;
Nokia5110LCD::Display nokiaLCD(D3, D1, D6, blPin);

void callback(char* topic, byte* payload, unsigned int length);

// struct for the distance ultrasonice sensor.
typedef struct {
    char vec[50];
    int index;
    int distance;
} dist_par;

dist_par d_pars;

uint32_t diff;
double fdiff;

bool automatic_operation = 0;
double water_level_low;
double water_level_high;

#define SERVER_IP "xx.xx.xx.xx"
MQTT mqtt_client(SERVER_IP, 1883, callback);

// Application Threads.
//Thread *read_diff_press_thread;
Thread *expose_diff_sensor_threads;
Thread *start_distance_measurement_thread;
Thread *time_thread;
Thread *serial1_thread;

os_thread_return_t serial1_task(void *param)
{
    while (1) {
        while (Serial1.available()) {
        //if (Serial1.available()) {
            d_pars.vec[d_pars.index] = Serial1.read();
            d_pars.index++;

            if (d_pars.index == 4) {
                if (d_pars.vec[0] == 0xFF) {
                    if (d_pars.vec[3] = ((d_pars.vec[0] + d_pars.vec[1] + d_pars.vec[2]) & 0x00FF)) {
                        d_pars.distance = (d_pars.vec[1] << 8) + d_pars.vec[2];
                    }
                    else {
                        debug_print("crc wrong\n");
                    }
                }
                else {
                    debug_print("first char wrong\n");
                }
            }
        }
        //delay(20);
        delay(100);
    }
}

os_thread_return_t time_task(void *param)
{
    char msg[20];
    int current_seconds, previous_seconds;
    int previous_day, current_day;

    previous_day = current_day = 0;
    previous_seconds = current_seconds = 0;
    uint32_t no_wifi_counter = 0;
    uint32_t no_particle_cloud_counter = 0;

    while (1) {
        no_wifi_counter = 0;
        current_seconds = Time.second();
        if (previous_seconds != current_seconds) {
            sprintf(msg, "%02d:%02d:%02d      ", Time.hour(), Time.minute(), Time.second());
            current_day = Time.day();
            nokiaLCD.setStr(msg, 0, 32, BLACK);
            ATOMIC_BLOCK() {
                nokiaLCD.updateDisplay();
            }
            previous_seconds = current_seconds;

            if (Time.month() == 10) {
                if (Time.weekday() == 1) {
                    if ((Time.day() <= 31) && (Time.day() >= 25)) {
                        Time.endDST();
                    }
                }
            }
            else if (Time.month() == 3) {
                if (Time.weekday() == 1) {
                    if ((Time.day() <= 30) && (Time.day() >= 24)) {
                        Time.setDSTOffset(1);
                        Time.beginDST();
                    }
                }
            }
        }
        // Watchdog!!
        else if (WiFi.ready() != true) {
            no_wifi_counter++;
            if (no_wifi_counter == 400) {
                System.reset();
            }//if 20 seconds without connection
        }

        if (Particle.connected() == false) {
            no_particle_cloud_counter++;
            if (no_particle_cloud_counter == 200) {
                System.reset();
            }
        }
        else {
            no_particle_cloud_counter = 0;
        }

        if (current_day != previous_day) {
            previous_day = current_day;
            if (Particle.connected()) {
                Particle.syncTime();
            }
        }
        delay(50);
    }
}

void callback(char* topic, byte* payload, unsigned int length) {
    char msg[MQTT_PAYLOAD_SIZE];
    uint8_t i;

    debug_print("MQTT message=  %s, length = %d\n", topic, length);

    if (length > MQTT_PAYLOAD_SIZE) {
        return;
    }

    if (strcmp(topic, "6e06744c735ee16bb87078c6/dl/LED") == 0) {
        if ((char)payload[0] == '0') {
            digitalWrite(LED, LOW);
        }
        else if ((char)payload[0] == '1') {
            digitalWrite(LED, HIGH);
        }
    }
    else if (strcmp(topic, "6e06744c735ee16bb87078c6/dl/auto") == 0) {
        if ((char)payload[0] == '1') {
            automatic_operation = 1;
            debug_print("automatic operation\n");
        }
        else if ((char)payload[0] == '0') {
            automatic_operation = 0;
            debug_print("manual operation\n");
        }
    }
    else if (strcmp(topic, "6e06744c735ee16bb87078c6/dl/water_low") == 0) {
        for (i = 0; i < length; i++) {
            msg[i] = payload[i];
        }
        msg[i] = 0;
        water_level_low = atof(msg);
        debug_print("%f\n", water_level_low);
    }
    else if (strcmp(topic, "6e06744c735ee16bb87078c6/dl/water_high") == 0) {
        for (i = 0; i < length; i++) {
            msg[i] = payload[i];
        }
        msg[i] = 0;
        water_level_high = atof(msg);
        debug_print("%f\n", water_level_high);
    }
    else if (strcmp(topic, "6e06744c735ee16bb87078c6/dl/reset") == 0) {
        System.reset();
    }
}

os_thread_return_t start_distance_measurement_task(void *param)
{
    Serial1.begin(9600, SERIAL_8N1);
    serial1_thread = new Thread("serial1", serial1_task, 0);

    delay(100);

    while (1) {
        Serial1.write(0x55);
        d_pars.index = 0;
        delay(500);
    }
}

os_thread_return_t expose_diff_tasks(void *param)
{
    char diffValStr[40];
    char distanceStr[40];
    char msg[20];
    unsigned long s_time, e_time;

    while (1) {
        ATOMIC_BLOCK() {
            fdiff = (((double)diff * 3.3) / 4095);
        }
        fdiff = ((fdiff/5) - 0.04) / 0.018;
        fdiff /= 0.0980665;

        sprintf(diffValStr, "P1: %.2f cm", fdiff);
        sprintf(distanceStr, "d: %d cm", d_pars.distance / 10);

        if (WiFi.ready()) {
            /*s_time = micros();
            Particle.publish("diff_distance", diffValStr, PRIVATE);
            e_time = micros();
            debug_print("cloud: %s, time = %d\n", distanceStr, e_time - s_time);*/
            s_time = micros();
            Particle.publish("ultra_distance", distanceStr, PRIVATE);
            e_time = micros();
            debug_print("cloud: %s, time = %d\n", diffValStr, e_time - s_time);
            sprintf(msg, "%s", WiFi.SSID());
            msg[14] = 0;
            nokiaLCD.setStr(msg, 0, 40, BLACK);
        }

        nokiaLCD.setStr("              ", 0, 8, BLACK);
        nokiaLCD.setStr(diffValStr      , 0, 8, BLACK);
        nokiaLCD.setStr("              ", 0, 0, BLACK);
        nokiaLCD.setStr(distanceStr     , 0, 0, BLACK);

        ATOMIC_BLOCK() {
            nokiaLCD.updateDisplay();
        }

        if (mqtt_client.isConnected()) {
            /*sprintf (msg, "%.2f", fdiff);
            s_time = micros();
            mqtt_client.publish("6e06744c735ee16bb87078c6/ul/1", msg);
            e_time = micros();
            debug_print("mqtt d2:%s, time= %d us\n", msg, e_time - s_time);*/
            sprintf (msg, "%.2f", (double)d_pars.distance / 10);
            s_time = micros();
            mqtt_client.publish("6e06744c735ee16bb87078c6/ul/0", msg);
            e_time = micros();
            debug_print("mqtt d1: %s, time= %d us\n", msg, e_time - s_time);
        }

        delay(3000);
    }
}

os_thread_return_t read_diff_press_task(void *param)
{
      setADCSampleTime(ADC_SampleTime_480Cycles);

      while (1) {
          diff = analogRead(DIFF_PIN);

          delay(300);
      }
}

void mqtt_reconnect(void)
{
    // Loop until we're reconnected
    while (!mqtt_client.isConnected()) {
        debug_print("Attempting MQTT connection...\n");
        // Attempt to connect
        if (mqtt_client.connect(mqtt_client_id, mqtt_user, mqtt_pass)) {
            debug_print("connected\n");
            mqtt_client.subscribe("asdf/dl/+");
        }
        else {
            debug_print("failed, try again in 5 seconds\n");
            // Wait 5 seconds before retrying
            delay(5000);
        }
    }
}

void setup() {
    pinMode(LED, OUTPUT);
    digitalWrite(LED, LOW);

    nokiaLCD.begin(); // This will setup our pins, and initialize the LCD
  	nokiaLCD.setContrast(55); // Pretty good value, play around with it

  	nokiaLCD.clearDisplay(WHITE);

    nokiaLCD.updateDisplay();

    //read_diff_press_thread = new Thread("read_diff_press", read_diff_press_task, 0);
    expose_diff_sensor_threads = new Thread("expose_diff", expose_diff_tasks, 0);
    start_distance_measurement_thread = new Thread("start_distance measurement", start_distance_measurement_task, 0);

    WiFi.useDynamicIP();
    while (WiFi.ready() != true)
    {
        delay(10);
    }

#ifdef SERIAL_DEBUG
    Serial.begin(115200);
    while(!Serial.isConnected());
#endif
    debug_print("Photon is connected\n");

    // mqtt
    debug_print("trying to connect to ");

    mqtt_client.connect(mqtt_client_id, mqtt_user, mqtt_pass);
    if (mqtt_client.isConnected()) {
        debug_print("connected!\n");
        mqtt_client.subscribe("asdf/dl/+");
    }

    Time.zone(2);
    Time.setDSTOffset(1);
    //Check for DST.
    if ((Time.month() > 3) && (Time.month() < 10)) {
        Time.beginDST();
    }
    else if (Time.month() == 3) {
        if ((Time.weekday() >= 25) && ((31 - Time.day() + 1) <= Time.weekday())) {
            Time.beginDST();
        }
    }
    else if (Time.month() == 10) {
        if ((Time.weekday() <= 24) && ((30 - Time.day() + 1) >= Time.weekday())) {
            Time.beginDST();
        }
    }

    time_thread = new Thread("time_update", time_task, 0);
}

void loop() {
    if (mqtt_client.isConnected()) {
        mqtt_client.loop();
    }
    else if (WiFi.ready() == true) {
        mqtt_reconnect();
    }
}