Nachrichten via MQTT

Moin,
ich habe ein kleines Problem mit einem Code, die beiden Topics "digitalTopic" und "analogTopic" werden im Seriellen Monitor (ja nicht das Topic wird angezeit sonder der Wert der versendet wird) angezeit und via MQTT versendet. Bei "home/strom/aktuell" passiert nichts, weder im Seriellen Monitor noch bei MQTT. Kann mir bitte jemand helfen.

Danke und Gruss
Olaf

#include <Arduino.h>
#include <PubSubClient.h>
#include <ESP8266WiFi.h>

const char *ssid = "SSID";
const char *password = "PASSWORD";

const char *mqtt_server = "192.168.68.101"; 
const int mqtt_port = 1883;
const char *mqtt_user = "MQTT_USER";
const char *mqtt_password = "MQTT_PASSWORD";
const char *clientID = "Zaehler";
const char *mqtt_topic = "home/strom/aktuell";
const char *analogTopic = "sensor/analog";
const char *digitalTopic = "sensor/digital";

const unsigned int rpm_per_kWh = 75;
#define IRPIN D2
#define RED LOW
#define SILVER HIGH
#define MINTIME 20

WiFiClient espClient;
PubSubClient client(espClient);

unsigned long lastmillis = 0;
unsigned long pendingmillis = 0;
bool inbuf[MINTIME];
bool startup = true;
uint8_t lastState = 0;

const byte NUM_READINGS = 5;
const float MILLIS_PER_HOUR = 3600000.00;

int analogPin = A0;
int digitalPin = D7;

void setup_wifi() {
  Serial.println(F("Connecting to WiFi..."));
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.print(".");
  }
  Serial.println(F("\nWiFi connected"));
  Serial.println(F("IP Address: "));
  Serial.println(WiFi.localIP());
}

// Overloaded function for publishing integer values
void publishSensorValue(const char *topic, int value) {
  client.publish(topic, String(value).c_str());
}

// Overloaded function for publishing float values
void publishSensorValue(const char *topic, float value) {
  client.publish(topic, String(value).c_str());
}

bool getInput(uint8_t pin) {
  byte inchk = 0;
  for (byte i = 0; i < NUM_READINGS; i++) {
    inchk += digitalRead(pin);
    delay(2);
  }
  return (inchk >= 3);
}

bool procInput(bool state) {
  byte inchk = 0;
  for (byte k = MINTIME - 2; (k >= 0 && k < MINTIME); k--) {
    inbuf[k + 1] = inbuf[k];
    inchk += inbuf[k];
  }
  inbuf[0] = state;
  inchk += state;
  return (inchk > MINTIME / 2);
}

void calcPower(void) {
  unsigned long took = pendingmillis - lastmillis;
  lastmillis = pendingmillis;

  if (took == 0) {
    Serial.println(F("Error: 'took' is zero. Skipping calculation."));
    return;
  }

  float kWh = (MILLIS_PER_HOUR / took) / rpm_per_kWh;

  if (!startup) {
    Serial.print(kWh);
    Serial.print(F(" kW @ "));
    Serial.print(took);
    Serial.println(F("ms"));

    // MQTT
    if (client.connected()) {
      publishSensorValue(mqtt_topic, kWh);
    }

    digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
  } else {
    startup = false;
  }
}

void readAndPublishSensorValues() {
  int analogVal = analogRead(analogPin);
  int digitalVal = digitalRead(digitalPin);

  publishSensorValue(analogTopic, analogVal);
  Serial.print(analogVal);
  Serial.print(F("\t"));
  Serial.println(digitalVal);

  delay(500);

  publishSensorValue(digitalTopic, digitalVal);
  delay(500);
}

void setup() {
  Serial.begin(115200);
  delay(1000);
  Serial.println(F("\nPower Monitor - Initializing\n"));

  pinMode(IRPIN, INPUT_PULLUP);
  pinMode(LED_BUILTIN, OUTPUT);
  pinMode(digitalPin, INPUT);
  lastmillis = millis();

  setup_wifi();
  client.setServer(mqtt_server, mqtt_port);
}

void loop() {
  if (!client.connected()) {
    reconnect();
  }
  client.loop();

  bool cur = getInput(IRPIN);
  cur = procInput(cur);

  switch (lastState) {
    case 0:  // Silver; Waiting for transition to red
      if (cur != SILVER) {
        lastState++;
        pendingmillis = millis();
        Serial.println(F("Silver detected; waiting for red"));
        calcPower();
      }
      break;
    case 1:  // Red; Waiting for transition to silver
      if (cur != RED) {
        lastState = 0;
        Serial.println(F("Red detected; Waiting for silver"));
      }
      break;
  }

  readAndPublishSensorValues();
}

void reconnect() {
  while (!client.connected()) {
    Serial.print(F("Connecting to MQTT broker..."));
    if (client.connect(clientID, mqtt_user, mqtt_password)) {
      Serial.println(F("connected"));
    } else {
      Serial.print(F("Failed, rc="));
      Serial.print(client.state());
      Serial.println(F(" Retrying in 10 seconds"));
      delay(10000);
    }
  }
}

An welcher Stelle soll denn dahin was gesendet werden? Ich finde es nicht im Code.

Prüfe mit Serialen Ausgaben, an verschiedenen Stellen im Code, ob die gewünschten Stellen erreicht werden. Oft findet man so den Denkfehler.

Funktioniert denn ein einfaches publish im Setup an das Topic?

Dein Code gibt ja einige Meldungen auf die Serielle Schnittstelle. Ein Log davon könnte etwas Licht ins dunkle bringen.

Wenn du schon dabei bist kannst du noch ein paar Statusmeldungen dazuschreiben:

void calcPower(void) {
  unsigned long took = pendingmillis - lastmillis;
  lastmillis = pendingmillis;

  Serial.println("took:"+String(took))
  if (took == 0) {
    Serial.println(F("Error: 'took' is zero. Skipping calculation."));
    return;
  }

  float kWh = (MILLIS_PER_HOUR / took) / rpm_per_kWh;
  Serial.println("kWh:"+String(kWh))

  Serial.println("startup:"+String(startup))
  if (!startup) {
    Serial.print(kWh);
    Serial.print(F(" kW @ "));
    Serial.print(took);
    Serial.println(F("ms"));

    // MQTT
    if (client.connected()) {
      publishSensorValue(mqtt_topic, kWh);
    } else {
		Serial.println("MQTT ist nicht verbunden")
	}
	
    digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
  } else {
    startup = false;
  }
}

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