Your new topic does not fit any of the above??? Check first. Then post here. Thanks.

Moderator: igrr

User avatar
By ElCaron
#47830 I was a little unclear before, because I confused another error that led to an actual crash with the yield one. The ESP does NOT crash, but only looses the wifi connection. The other code keeps running. The MQTT client seems to be able to reconnect, but then it almost immediately crashes again.
So for me, this is clearly n issue with the internal functions.

Here is my code. It has been working stable for a week. If I replace the delay with yield, it fails after seconds:
Code: Select all#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266mDNS.h>
#include <PubSubClient.h>

#define min(a,b) ((a)<(b)?(a):(b))

const char *ssid = "myssid";
const char *password = "mywifipw";

const char *mqtt_server = "192.168.2.6";
const char *mqtt_user = "powermeter";
const char *mqtt_pw = "mymosquittow";
const char *mqtt_state_topic = "home-le/consumption/power";
unsigned long mqttReconnectTime = millis();
unsigned long mqttReconnectInterval = 5000;

const int analogInPin = A0;
const int ledPin = BUILTIN_LED;

unsigned int threshold = 208;
int thresholdbins[30];
unsigned int thresholdcount = 0;
boolean calibrated = false;

unsigned int sensorValue = 0;
unsigned int valueCount = 0;

float meanSensorValue = 0.;
float lastValue = 0.;
float beforeLastValue = 0.;

unsigned long dispTime = millis();
unsigned int dispInterval = 100;

unsigned long ledTime = millis();
unsigned int ledInterval = 500;

unsigned long lastCountTime = millis();
unsigned int lastCountInterval = 3000;

float powerCons = 0;

WiFiClient espClient;
PubSubClient mqttclient(espClient);

void setup() {
  pinMode(ledPin, OUTPUT);
  digitalWrite ( ledPin, LOW );
  Serial.begin ( 115200 );
  WiFi.begin ( ssid, password );
  Serial.println ( "" );

  // Wait for connection
  while ( WiFi.status() != WL_CONNECTED ) {
    delay ( 500 );
    Serial.print ( "." );
  }

  Serial.println ( "" );
  Serial.print ( "Connected to " );
  Serial.println ( ssid );
  Serial.print ( "IP address: " );
  Serial.println ( WiFi.localIP() );

  if ( MDNS.begin ( "powermeter" ) ) {
    Serial.println ( "MDNS responder started" );
  }

  mqttclient.setServer(mqtt_server, 1883);
  mqttclient.setCallback(mqtt_callback);
  digitalWrite ( ledPin, HIGH );
}

void mqtt_callback(char* topic, byte* payload, unsigned int length) {
}

void loop() {
  delay(2);
  sensorValue += analogRead(analogInPin);
  valueCount++;

  if (!mqttclient.connected()) {
    if (millis() - mqttReconnectTime > mqttReconnectInterval) {
      mqtt_reconnect();
      mqttReconnectTime = millis();
    }
  }
  else {
    mqttclient.loop();
  }

  if (millis() - ledTime > ledInterval)
  {
    digitalWrite ( ledPin, HIGH );
  }

  if (millis() - dispTime > dispInterval)
  {
    meanSensorValue = (float)sensorValue / valueCount;

    int readval = 190;
    if ( meanSensorValue > threshold && lastValue > threshold && beforeLastValue < threshold && (millis() - lastCountTime) > lastCountInterval )
    {
      powerCons = 48000. / (millis() - lastCountTime);
      lastCountTime = millis();

      if (mqttclient.connected()) {
        char outputStr[5];
        sprintf(outputStr, "%d", (int)(powerCons * 1000));
        if (calibrated)
          mqttclient.publish(mqtt_state_topic, outputStr, true);
        Serial.print("Published ");
        Serial.println(outputStr);
      }
      readval = 210;

      digitalWrite ( ledPin, LOW );
      ledTime = millis();
    }

    //    Serial.print(min(220,meanSensorValue));
    //    Serial.print("  ");
    //    Serial.print(210);
    //    Serial.print("  ");
    //    Serial.print(readval);
    //    Serial.print("  ");
    //    Serial.println(190);
    binning_compute(meanSensorValue);

    beforeLastValue = lastValue;
    lastValue = meanSensorValue;
    valueCount = 0;
    sensorValue = 0;

    dispTime = millis();
  }
}

void mqtt_reconnect() {
  // Loop until we're reconnected
  if (!mqttclient.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Attempt to connect
    if (mqttclient.connect("powermeter", mqtt_user, mqtt_pw)) {
      Serial.println("connected");
    } else {
      Serial.print("failed, rc=");
      Serial.print(mqttclient.state());
      Serial.println(" try again in 5 seconds");
    }
  }
}

void binning_compute(float sensorval) {
  thresholdcount++;

  unsigned int bin = (int)sensorval - threshold + 15;
  if (bin >= 0 && bin < 30) {
    thresholdbins[bin] = thresholdbins[bin] + 1;
  }

  if (thresholdcount == 9000) {
    print_thresholdbins();
    threshold = threshold - 15 + binning_findmin();
    calibrated = true;
    Serial.print("New threshold: ");
    Serial.println(threshold);
    thresholdcount = 0;
    binning_start();
  }
}

void binning_start() {
  memset(thresholdbins, 0, 30 * sizeof(thresholdbins[0]));
}

int binning_findmin() {
  unsigned int maxpos_s = 0;
  unsigned int maxpos_e = 29;

  while (maxpos_s < 29 && thresholdbins[maxpos_s] <= thresholdbins[maxpos_s + 1]) {
    maxpos_s++;
  }
  Serial.print("Max_s: ");
  Serial.println(maxpos_s);

  while (maxpos_e > 0 && thresholdbins[maxpos_e] <= thresholdbins[maxpos_e - 1]) {
    maxpos_e--;
  }

  Serial.print("Max_e: ");
  Serial.println(maxpos_e);

  if (maxpos_e == maxpos_s) {
    return 15;
  }

  unsigned int minpos = (maxpos_s + maxpos_e) / 2;
  if (minpos < 1 || minpos > 28) {
    return 15;
  }

  int direct = ((thresholdbins[minpos] - thresholdbins[minpos + 1]) >= 0) ? 1 : -1;
  while ((thresholdbins[minpos] - thresholdbins[minpos + direct]) > 0) {
    minpos = minpos + direct;
    Serial.print(direct);
    Serial.print(" ");
    Serial.print(thresholdbins[minpos]);
    Serial.print(" ");
    Serial.print(thresholdbins[minpos + direct]);
    Serial.print(" ");
    Serial.print(thresholdbins[minpos] - thresholdbins[minpos + direct]);
    Serial.print(" minpos: ");
    Serial.println(minpos);
  }



  if (thresholdbins[minpos] == 0) {
    int zerocount = 1;
    while (thresholdbins[minpos + direct * zerocount] == 0) {
      zerocount++;
    }

    minpos = minpos + direct * (zerocount / 2);
  }

  Serial.print("minpos_z: ");
  Serial.println(minpos);

  return minpos;
}

void print_thresholdbins() {
  for (int i = 0; i < 29; i++) {
    Serial.print(thresholdbins[i]);
    Serial.print(" ");
  }
  Serial.println(thresholdbins[29]);
}