Photon 2 goes offline - how do I figure out why this is happening?

Hello, I wrote a script to listen to MQTT for up and down signals for my projector screen. The script works for an hour or so and then the photon goes offline. What can I do to troubleshoot this?

// STATE MACHINE:
// A State Machine will be implemented to control the operation of the screen.
// This will eliminate the need for 'delay' statements and will allow the project screen to
// reverse part way through its opening or closing operations
//
// The states of the state machine are as follows (the number is the identifier of the state)
// 0 - SCREEN UP
// 1 - SCREEN LOWERING
// 2 - SCREEN DOWN
// 3 - SCREEN RAISING

// STATE DETAILS:
// 0 - SCREEN UP: This will be the initial state of the screen when the system starts.
// 1 - SCREEN LOWERING: When in this state, the screen will be lowering.
// 2 - SCREEN DOWN: This state is when the screen is down.
// 3 - SCREEN RAISING: When in this state, the screen will be raising.

#include <MQTT.h>
#include <Particle.h>

#define MQTT_MAX_PACKET_SIZE 512

// MQTT Configuration for Home Assistant
const char* mqtt_server = "192.168.x.x";
const int mqtt_port = 1883;
const char* mqtt_username = "user"; // Replace with your Home Assistant MQTT username
const char* mqtt_password = "pass!"; // Replace with your Home Assistant MQTT password
const String baseTopic = "homeassistant/cover/screen"; // Base topic for Home Assistant

MQTT client(mqtt_server, 1883, callback);

int relayScreenDown = D1;
int relayScreenUp = D2;
String screenState = "";
int stateReportTime = 1000;
int screenMovementDelay = 36000;
bool ignoreFirstMessage = true;

// State Machine Variables
int stateTime = 20;             // Time between successive calls to a state function (10 milliseconds)
int elapsedStateTime = 0;       // Number of milliseconds spent in the current state
int stateReportTimer = 0;       // Number of milliseconds spent in the current state

// NOTE: We will start in the Screen Up state.
int currentState = 0; // This is the current state of the state machine

// Setup MQTT callback function
void callback(char* topic, byte* payload, unsigned int length) {
    if (ignoreFirstMessage) {
        ignoreFirstMessage = false;  // Skip only the first message
        Particle.publish("debug", "Ignoring first MQTT message after boot");
        return;
    }

    String message = "";
    for (unsigned int i = 0; i < length; i++) {
        message += (char)payload[i];
    }

    if (String(topic) == baseTopic + "/set") {
        if (message == "DOWN" && screenState != "DOWN") { 
            functionScreenDown(relayScreenDown, true, "");
        } else if (message == "UP" && screenState != "UP") {
            functionScreenUp(relayScreenUp, true, "");
        }
    }
}

int functionOnOff(int device, bool onOff, String rawParameters) {
    digitalWrite(D7, (onOff) ? HIGH : LOW);
    return 1;
}

int functionScreenDown(int device, bool onOff, String rawParameters) {
    Particle.publish("screenState", "Screen Down Button was requested");
    digitalWrite(relayScreenDown, HIGH);
    delay(1000);
    digitalWrite(relayScreenDown, LOW);
    delay(1000);
    digitalWrite(relayScreenDown, HIGH);
    Particle.publish("screenState", "Screen is lowering");
    publishToMQTT(baseTopic + "/state", "LOWERING"); // Publish to MQTT topic
    delay(2000);
    digitalWrite(relayScreenDown, LOW);
    Particle.publish("screenState", "Screen is down");
    publishToMQTT(baseTopic + "/state", "DOWN"); // Publish to MQTT topic
    return 1;
}

int functionScreenUp(int device, bool onOff, String rawParameters) {
    Particle.publish("screenState", "Screen Up Button was requested");
    digitalWrite(relayScreenUp, HIGH);
    delay(1000);
    digitalWrite(relayScreenUp, LOW);
    delay(1000);
    digitalWrite(relayScreenUp, HIGH);
    Particle.publish("screenState", "Screen is raising");
    publishToMQTT(baseTopic + "/state", "RAISING"); // Publish to MQTT topic
    delay(2000);
    digitalWrite(relayScreenUp, LOW);
    Particle.publish("screenState", "Screen is up");
    publishToMQTT(baseTopic + "/state", "UP"); // Publish to MQTT topic
    return 1;
}

// MQTT Connection Setup (Directly in setup)
void setup() {
    pinMode(relayScreenDown, OUTPUT);
    pinMode(relayScreenUp, OUTPUT);
    // pinMode(D7, OUTPUT);

    Particle.variable("screenState", screenState); 
    Particle.function("downBtnPress", fxDownBtnPress);  
    Particle.function("upBtnPress", fxUpBtnPress);  

    client.connect("photonDev");

    // Connect to MQTT
    while (!client.isConnected()) {
        if (client.connect("ParticleDevice", mqtt_username, mqtt_password)) {
            Particle.publish("mqttStatus", "Connected to MQTT", PRIVATE);
        } else {
            Particle.publish("mqttStatus", "Failed to connect to MQTT", PRIVATE);
            delay(3000);
        }
    }
    
    // Subscribe to MQTT topics to receive commands from Home Assistant
    client.subscribe(baseTopic + "/set");
    
    Particle.publish("status", "Setup complete 0.8");
}

// Main loop
void loop() {
    client.loop();                      // Keep MQTT connection alive
    delay(3000);
    if (!client.isConnected()) {
        Particle.publish("mqttStatus", "MQTT connection lost, reconnecting...", PRIVATE);
        while (!client.connect("ParticleDevice", mqtt_username, mqtt_password)) {
            Particle.publish("mqttStatus", "Failed to reconnect to MQTT", PRIVATE);
            delay(1000);
        }
        Particle.publish("mqttStatus", "Reconnected to MQTT", PRIVATE);
        publishToMQTT(baseTopic + "/availability", "online"); // Publish to MQTT topic
        client.subscribe(baseTopic + "/set");
    } else {
        publishToMQTT(baseTopic + "/availability", "online"); // Publish to MQTT topic
    }

}

// Publish MQTT messages with status reporting
void publishToMQTT(String topic, String payload) {
    if (client.publish(topic.c_str(), payload.c_str())) {
        Particle.publish("status", "MQTT successful: " + topic);
    } else {
        Particle.publish("status", "MQTT failed: " + topic);
    }
}

////////////////////// PARTICLE FUNCTIONS ///////////////////

int fxDownBtnPress(String command) {
    if (command.equalsIgnoreCase("press")) {
        functionScreenDown(relayScreenDown, true, "");
        return 1;
    }
    return -1;
}

int fxUpBtnPress(String command) {
    if (command.equalsIgnoreCase("press")) {
        functionScreenUp(relayScreenUp, true, "");
        return 1;
    }
    return -1;
}

@clubanderson Which Device OS are you using? Before 6.3.0 there have been issues with losing connection.

it shows 5.9.0 - how do I upgrade?

I only see 6.2.1 as the highest for the device

Follow the instructions to enable pre-release versions.

Got to 6.2.1 and I already have more uptime today than I have had in a month. Thank you. I will look into getting to 6.3.0 next.

It was too good to be true. Offline again this morning. I guess the situation improved but I am back to search for an answer. I am going to try to get to 6.3.0 to see of this makes a difference. Could there be something in my code that causes this issue?

The problem definitely still exists in 6.2.1 and should be fixed in 6.3.0. See this thread for more information.

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.