Code exit every time from loop after 2 loop cicle

Hi everyone

I’m developing a solution that self-declares its own configuration and sends the data of the connected sensors in json format, through MQTT

The problem I have is that every time the code starts, runs a loop and starts again from the Setup
in practice it comes out of the loop as if it went wrong.

Can anyone help me.

 #include <MQTT.h>
 #include <ArduinoJson.h>
 #include <Adafruit_Sensor.h>
 #include <Adafruit_BME280.h>
 #include <EmonLib.h>

 #define RELAY_PIN D7
 #define PIR_PIN D1

 #define BME_SCK D4
 #define BME_MISO D3
 #define BME_MOSI D2
 #define BME_CS D5
 #define SEALEVELPRESSURE_HPA (1013.25)
 #define SENSORNUMBER (7)
 #define SERSORNAME "Clientino"

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

typedef struct
{
 char* sensortype;
 char* sensorunit;
 char* sensorID;
} sensor_conf;

typedef struct
{
  char macStr[19];
  sensor_conf sens[SENSORNUMBER];
} tini_conf;

typedef struct
{
  String topic;
  String message;
} mqtt_message;

mqtt_message mmessage;
tini_conf tini;

byte mac[6];
char macStr[19];
bool pir_state = false;

uint32_t lastTime;

MQTT client("aisens.beiot.cloud", 1883, callback);
Adafruit_BME280 bme(BME_CS, BME_MOSI, BME_MISO,  BME_SCK);
EnergyMonitor emon1;

void Tini_Configuration(){

  tini.sens[1].sensortype = "Temperature";
  tini.sens[1].sensorunit = "Celsius";
  tini.sens[1].sensorID = "00";

  tini.sens[2].sensortype = "Pressure";
  tini.sens[2].sensorunit = "HPA";
  tini.sens[2].sensorID = "00";

  tini.sens[3].sensortype = "Altitude";
  tini.sens[3].sensorunit = "Meter";
  tini.sens[3].sensorID = "00";

  tini.sens[4].sensortype = "Humidity";
  tini.sens[4].sensorunit = "Rate";
  tini.sens[4].sensorID = "00";

  tini.sens[5].sensortype = "PIR";
  tini.sens[5].sensorunit = "Digital";
  tini.sens[5].sensorID = "00";

  tini.sens[6].sensortype = "Apparent Power";
  tini.sens[6].sensorunit = "Watt";
  tini.sens[6].sensorID = "00";

  tini.sens[7].sensortype = "Current";
  tini.sens[7].sensorunit = "Ampere";
  tini.sens[7].sensorID = "00";

  tini.sens[8].sensortype = "Relay";
  tini.sens[8].sensorunit = "Digital";
  tini.sens[8].sensorID = "00";

}

void callback(char* topic, byte* payload, unsigned int length) {
    /*char p[length + 1];
    memcpy(p, payload, length);
    p[length] = NULL;
    String message(p);
    String t(topic);
    mmessage.message = message;
    mmessage.topic = t;*/

    char p[length + 1];
    memcpy(p, payload, length);
    p[length] = NULL;
    String message(p);

    if (message.equals("RED"))
        RGB.color(255, 0, 0);
    else if (message.equals("GREEN"))
        RGB.color(0, 255, 0);
    else if (message.equals("BLUE"))
        RGB.color(0, 0, 255);
    else
        RGB.color(255, 255, 255);
    delay(1000);
}

void initcicle(const char* t, const char* u, const char* i) {

  StaticJsonBuffer<300> jsonBuffer;
  JsonObject& root = jsonBuffer.createObject();
  root["eventID"] = 1;
  root["eventsensorname"] = tini.macStr;
  root["eventsensortype"] = t;
  root["eventsensorunit"] = u;
  root["eventsensorID"] = i;
  char buffer[300];
  root.prettyPrintTo(buffer, sizeof(buffer));
  client.publish("init", buffer);
  delay(100);
}

void init (){
  int i;
  for (i=1; i<=SENSORNUMBER; i++){
    initcicle(tini.sens[i].sensortype, tini.sens[i].sensorunit, tini.sens[i].sensorID);
    delay(100);
  }
}

void publishjson(int id, float value) {
  String topic = String(tini.macStr) + "/" + tini.sens[id].sensortype + "/" + tini.sens[id].sensorID;
  StaticJsonBuffer<200> jsonBuffer;
  JsonObject& root = jsonBuffer.createObject();
  root["eventsensordatetime"] = millis();
  root["eventsensorvalue"] = value;
  /*JsonArray& data = root.createNestedArray("data");
  data.add(value, 2);  // 6 is the number of decimals to print*/
  char buffer[200];
  root.prettyPrintTo(buffer, sizeof(buffer));
  client.publish(topic, buffer);
}

void bme_controller(){
  publishjson(1, bme.readTemperature());
  delay(100);
  publishjson(2, bme.readPressure() / 100.00F);
  delay(100);
  publishjson(3, bme.readAltitude(SEALEVELPRESSURE_HPA));
  delay(100);
  publishjson(4, bme.readHumidity());
}

void pir_controller(){

  if (digitalRead(PIR_PIN) == HIGH && !pir_state){
    publishjson(5, 1);
    pir_state = true;
  }
  else if (digitalRead(PIR_PIN) == LOW && pir_state){
    publishjson(5, 0);
    pir_state = false;
  }
}

void ct_controller(){
  double Irms = emon1.calcIrms(1480);  // Calculate Irms only
  publishjson(6, Irms*230.0);	       // Apparent power
  publishjson(7, Irms);		       // Irms
  delay(100);
}

// setup() runs once, when the device is first turned on.
void setup() {

  Particle.syncTime();
  Time.zone(1);

  //while(!bme.begin());

  emon1.current(1, 26.6);

  WiFi.macAddress(mac);
  snprintf(macStr, sizeof(macStr), "T%02x%02x%02x%02x%02x%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
  strcpy (tini.macStr, macStr);
  client.connect(SERSORNAME);
  Tini_Configuration();
  if (client.isConnected()) {

      String message6 = Time.timeStr();
      char  cstr[24];
      strcpy(cstr, message6.c_str());
      client.publish(String("lasttime/")+tini.macStr, "pluto"); //publish time starts up
      client.subscribe(String(tini.macStr) + "/" + tini.sens[8].sensortype + "/" + tini.sens[8].sensorID);
      delay(100);
  }

  init();
  pinMode(RELAY_PIN, OUTPUT);
  pinMode(PIR_PIN, INPUT);
  pinMode(D7, OUTPUT);
  lastTime = millis();
  if (client.isConnected()) {
      client.publish(String("lasttime/")+tini.macStr, "paperina");

  }// Put initialization like pinMode and begin functions here.

}



// loop() runs over and over again, as quickly as it can execute.
void loop() {


  if (client.isConnected()) {
      client.loop();
      delay(100);
      pir_controller();

      if(millis() - lastTime > 15000){
        //init();
        bme_controller();
        delay(100);
        ct_controller();
        lastTime = millis();
      }
      delay(100);

  }
  else
      {

        if(!client.isConnected()){

        client.connect(SERSORNAME);

        String message7 = Time.timeStr();
        char  cstr[24];
        strcpy(cstr, message7.c_str());
        client.publish(String("lasttime/")+tini.macStr, "pippo"); //publish time starts up
        delay(100);
        }
      }


  // The core of your code will likely live here.

}

Do you see any red flashes or other interesting RGB codes before that happens?

BTW, max publish payload can be a char[256] (or a string of 255 length).

Your best chance to locate the cause is with adding some debug log lines and see how far your code gets before that happens. Following your code through and guessing the data flow isn’t what I like the most :wink:
BTW, you do intend to only move around the string pointers and not want to copy the strings, right?
e.g. in your Tini_Configuration() the actual string literals will live in flash and your tini pointers will point there, so no way to alter the contents.

Hi, no, I dont see any led flashing, i've adding some checkpoint to debug the code but in the loop with debug:

void loop() {
    Serial.println("Photon loop start!");

  if (client.isConnected()) {
      Serial.println("Photon loop if start!");
      client.loop();
      delay(100);
      pir_controller();

      if(millis() - lastTime > 1500){
        //init();
        //bme_controller();
        delay(100);
        ct_controller();
        lastTime = millis();
      }
      delay(100);
      Serial.println("Photon loop if end!");

  }
  else
      {
        Serial.println("Photon else start!");
        reconnect();
        if(!client.isConnected()){

        client.connect(SERSORNAME);

        String message7 = Time.timeStr();
        char  cstr[24];
        strcpy(cstr, message7.c_str());
        client.publish(String("lasttime/")+tini.macStr, "pippo"); //publish time starts up
        delay(100);
        }
        Serial.println("Photon else end!");
      }
      Serial.println("Photon loop end!");

  // The core of your code will likely live here.

}

the serial result is :

Photon loop start!
Photon loop if start!
Photon loop if end!
Photon loop end!
Photon setup starts!
Photon setup end!
Photon loop start!
Photon loop if start!
Photon loop if end!
Photon loop end!
Photon setup starts!
Photon setup end!
etc...
1 Like

I’ve notice that some times it start blink fast blue 2 blink yellow 1 blink green e after it return to blink slow blue

This seems as if there is some deleyed issue that causes your device to regularly reset.
It might be an electrical issue like a too low supply current or something pulling the RESET pin low, or a software thing in connection with the TCP client losing connection which causes a reset.

You may need to add some more test prints in the other functions too and also print out the millis() counter.

A nice way to add logging is the Log feature present since 0.6.0 which also provides some insight into the system (including the timestamps)
https://docs.particle.io/reference/firmware/photon/#logging

Just add

SerialLogHandler logHandler;

to the top of your project and call something like this

  Log.info("whatever you want to log %d", someIntToCheck);

Thanks for your reply

i’ve make some mod ed now it seems to work
i’ve mod the payload lenght to max 240 and mod the reconnect function and pir controller function like as you had already suggested me in the post: Mqtt library and pinmode error

In addition I have also modified the provision of the Code:

/*
 * Project TIni2
 * Description:
 * Author:
 * Date:
 */

 #include <MQTT.h>
 #include <ArduinoJson.h>
 #include <Adafruit_Sensor.h>
 #include <Adafruit_BME280.h>
 #include <EmonLib.h>

 #define RELAY_PIN D7
 #define PIR_PIN D1

 #define BME_SCK D4
 #define BME_MISO D3
 #define BME_MOSI D2
 #define BME_CS D5
 #define SEALEVELPRESSURE_HPA (1013.25)
 #define SENSORNUMBER (7)
 #define SERSORNAME "Clientino"



typedef struct
{
 char* sensortype;
 char* sensorunit;
 char* sensorID;
} sensor_conf;

typedef struct
{
  char macStr[19];
  sensor_conf sens[SENSORNUMBER];
} tini_conf;

typedef struct
{
  String topic;
  String message;
} mqtt_message;

mqtt_message mmessage;
tini_conf tini;

byte mac[6];
char macStr[19];
int prevState = 0;

uint32_t lastTime;



void callback(char* topic, byte* payload, unsigned int length);
void initcicle(const char* t, const char* u, const char* i);
void init ();
void publishjson(int id, float value);
void bme_controller();
void pir_controller();
void ct_controller();
void reconnect();


MQTT client("aisens.beiot.cloud", 1883, callback);
Adafruit_BME280 bme(BME_CS, BME_MOSI, BME_MISO,  BME_SCK);
EnergyMonitor emon1;

// setup() runs once, when the device is first turned on.
void setup() {

  Serial.begin(9600);

  Serial.println("Photon setup starts!");

  Particle.syncTime();
  Time.zone(1);

  while(!bme.begin());

  emon1.current(1, 26.6);

  WiFi.macAddress(mac);
  snprintf(macStr, sizeof(macStr), "T%02x%02x%02x%02x%02x%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
  strcpy (tini.macStr, macStr);
  client.connect(SERSORNAME);

  tini.sens[1].sensortype = "Temperature";
  tini.sens[1].sensorunit = "Celsius";
  tini.sens[1].sensorID = "00";

  tini.sens[2].sensortype = "Pressure";
  tini.sens[2].sensorunit = "HPA";
  tini.sens[2].sensorID = "00";

  tini.sens[3].sensortype = "Altitude";
  tini.sens[3].sensorunit = "Meter";
  tini.sens[3].sensorID = "00";

  tini.sens[4].sensortype = "Humidity";
  tini.sens[4].sensorunit = "Rate";
  tini.sens[4].sensorID = "00";

  tini.sens[5].sensortype = "PIR";
  tini.sens[5].sensorunit = "Digital";
  tini.sens[5].sensorID = "00";

  tini.sens[6].sensortype = "Apparent Power";
  tini.sens[6].sensorunit = "Watt";
  tini.sens[6].sensorID = "00";

  tini.sens[7].sensortype = "Current";
  tini.sens[7].sensorunit = "Ampere";
  tini.sens[7].sensorID = "00";

  tini.sens[8].sensortype = "Relay";
  tini.sens[8].sensorunit = "Digital";
  tini.sens[8].sensorID = "00";


  if (client.isConnected()) {
      client.publish(String("lasttime/")+tini.macStr, "pluto"); //publish time starts up
      client.subscribe(String(tini.macStr) + "/" + tini.sens[8].sensortype + "/" + tini.sens[8].sensorID);
      delay(100);
  }

  init();
  pinMode(RELAY_PIN, OUTPUT);
  pinMode(PIR_PIN, INPUT);
  pinMode(D7, OUTPUT);
  lastTime = millis();
  if (client.isConnected()) {
      client.publish(String("lasttime/")+tini.macStr, "paperina");

      Serial.println("Photon setup end!");
  }

}




void loop() {
    Serial.println("Photon loop start!");

  if (client.isConnected()) {
      Serial.println("Photon loop if start!");
      client.loop();
      pir_controller();
      if(millis() - lastTime > 15000){
        //init();
        bme_controller();
        delay(100);
        ct_controller();
        lastTime = millis();
      }
      delay(100);
      Serial.println("Photon loop if end!");

  }
  else
      {
        Serial.println("Photon else start!");
        reconnect();
        if(!client.isConnected()){

        client.connect(SERSORNAME);

        String message7 = Time.timeStr();
        char  cstr[24];
        strcpy(cstr, message7.c_str());
        client.publish(String("lasttime/")+tini.macStr, "pippo"); //publish time starts up
        delay(100);
        }
        Serial.println("Photon else end!");
      }
      Serial.println("Photon loop end!");



}



void reconnect() {
  if(!Particle.connected()) {
    Particle.connect();
    waitUntil(Particle.connected);
  }
}

void ct_controller(){
  double Irms = emon1.calcIrms(1480);  // Calculate Irms only
  publishjson(6, Irms*230.0);	       // Apparent power
  publishjson(7, Irms);		       // Irms
  delay(100);
}

void pir_controller(){

  /*if (digitalRead(PIR_PIN) == HIGH && !pir_state){
    publishjson(5, 1);
    pir_state = true;
  }
  else if (digitalRead(PIR_PIN) == LOW && pir_state){
    publishjson(5, 0);
    pir_state = false;
  }*/

  int currState = digitalRead(PIR_PIN);
  Serial.printlnf("%d (%8u)", currState, millis());
  if (currState != prevState) {
    prevState = currState;
    publishjson(5, currState);
  }
}

void bme_controller(){
  publishjson(1, bme.readTemperature());
  delay(100);
  publishjson(2, bme.readPressure() / 100.00F);
  delay(100);
  publishjson(3, bme.readAltitude(SEALEVELPRESSURE_HPA));
  delay(100);
  publishjson(4, bme.readHumidity());
}

void publishjson(int id, float value) {
  String topic = String(tini.macStr) + "/" + tini.sens[id].sensortype + "/" + tini.sens[id].sensorID;
  StaticJsonBuffer<200> jsonBuffer;
  JsonObject& root = jsonBuffer.createObject();
  root["eventsensordatetime"] = millis();
  root["eventsensorvalue"] = value;
  char buffer[200];
  root.prettyPrintTo(buffer, sizeof(buffer));
  client.publish(topic, buffer);
}

void init (){
  int i;
  for (i=1; i<=SENSORNUMBER; i++){
    initcicle(tini.sens[i].sensortype, tini.sens[i].sensorunit, tini.sens[i].sensorID);
    delay(100);
  }
}

void initcicle(const char* t, const char* u, const char* i) {

  StaticJsonBuffer<240> jsonBuffer;
  JsonObject& root = jsonBuffer.createObject();
  root["eventID"] = 1;
  root["eventsensorname"] = tini.macStr;
  root["eventsensortype"] = t;
  root["eventsensorunit"] = u;
  root["eventsensorID"] = i;
  char buffer[300];
  root.prettyPrintTo(buffer, sizeof(buffer));
  client.publish("init", buffer);
  delay(100);
}

void callback(char* topic, byte* payload, unsigned int length) {
    char p[length + 1];
    memcpy(p, payload, length);
    p[length] = NULL;
    String message(p);
    String t(topic);
    mmessage.message = message;
    mmessage.topic = t;

    /*char p[length + 1];
    memcpy(p, payload, length);
    p[length] = NULL;
    String message(p);

    if (message.equals("RED"))
        RGB.color(255, 0, 0);
    else if (message.equals("GREEN"))
        RGB.color(0, 255, 0);
    else if (message.equals("BLUE"))
        RGB.color(0, 0, 255);
    else
        RGB.color(255, 255, 255);
    delay(1000);*/
}
2 Likes