MQTT trouble, fish dies

Hi

I have a pond that has an issue, sometimes the water runs out of pond uncontrollable and my fish may die...

Because this is a bit WERY IMPORTANT, I hope you can quick give me a hand

I use an ESP8266 board, compile as NODE MCU 1.0

I made a sensor that gives input if water is running, the status "water is running" I plan to send to Home Assistant as a string 1 (high)

nor: vann renner = en: water running

Under is my code that compiles with error:

D:\Arduino2024\FilterFultv3\FilterFultv3.ino: In function 'void loop()':
FilterFultv3:95:21: error: 'vannRennerTopic' was not declared in this scope; did you mean 'vannRenner'?
   95 |      client.publish(vannRennerTopic.c_str()       , vannRennerMsg);
      |                     ^~~~~~~~~~~~~~~
      |                     vannRenner
exit status 1
'vannRennerTopic' was not declared in this scope; did you mean 'vannRenner'?


Code:

   #include <ESP8266WiFi.h>
  #include <PubSubClient.h>            // MQTT
  
  const char* ssid = "X";      // Your WiFi network SSID
  const char* password = "Y";  // Your WiFi network password
  
  const int buttonPin = D2; // D2 pin
  int buttonState = 0;      // variable for reading the button status
  int lastButtonState = 0;  // variable to store the previous button state
  
  // MQTT
 WiFiClient espClient;
 PubSubClient client(espClient);

  int    maxRetryMQTT         = 3;
  int    retryMQTT            = 0;
  String MQTTstatus           = "_";                  // For å skrive til serial at kobling til HA er OK

  const char* mqtt_username   = "x";           // MQTT username virker 2023.07.05
  const char* mqtt_password   = "y";   // MQTT password virker 2023.07.05
  const char* mqtt_clientID   = "dam";                // MQTT client ID, må være unikt pr IoT
  char vannRennerMsg[10];
  
  String vannRenner           = "0";
  //--------------------------
  
  IPAddress MQTTserver(192, 168, 0, 60);        //MQTT server IP
  
  void setup() {
    Serial.begin(115200);    // initialize serial communication
    delay(500);
    pinMode(buttonPin, INPUT);    // set the D2 pin as an input
    digitalWrite(buttonPin, LOW); // enable internal pull-down resistor
  
    // Connect to WiFi
    WiFi.begin(ssid, password);
    Serial.print("Connecting to ");
    Serial.println(ssid);
  
    while (WiFi.status() != WL_CONNECTED) {
      delay(500);
      Serial.print(".");
    }
  
    // Print connection established
    Serial.println("");
    Serial.println("WiFi connected");
    Serial.println("IP address: ");
    Serial.println(WiFi.localIP());
  }
  
  
  void loop() {
  // kobler til mqtt
    if (!client.connected()) {
      while (!client.connected() && retryMQTT < maxRetryMQTT) {
        Serial.println("Kobler til MQTT...");
        if (client.connect(mqtt_clientID, mqtt_username, mqtt_password)) {
          Serial.println("MQTT koblet til!  IP 192.168.0.60:1883, web :8123");
          delay(1000);
          retryMQTT = 0; // Reset the retry count if the connection is successful
          MQTTstatus = "Koblet til HA";
        } else {
          Serial.print("Feila å koble til MQTT, Return Code = ");
          Serial.println(client.state());
          delay(500);
          retryMQTT++;
          MQTTstatus = "Ikke koblet til HA, RC = " + client.state();;
        }
        //ESP.restart();                          // ###################### behold denne muligheten  se på versjon tidligere
  
      }
    }
  
    // read the state of the pushbutton value
    buttonState = digitalRead(buttonPin);
  
    // check if the button state has changed
    if (buttonState != lastButtonState) {
      // check if the pushbutton is NOT pressed
      if (buttonState == HIGH) {
        Serial.println("                Det renner ikke vann");
      } else {
        Serial.println("                Det renner vann");
        vannRenner = "1";                   // setter til 1,  high
  
        //tildeling av topic
        String vannRenner                            = "dam/vannRenner";
  
        // Convert payload into Msg strings. PASS PÅ INT VS FLOAT %d vs %f
        snprintf(vannRennerMsg                       , 10, "%d"  , vannRenner);
  
        // Publish message to Home Assistant
        client.publish(vannRennerTopic.c_str()       , vannRennerMsg);
      }
  
      // update lastButtonState to the current buttonState
      lastButtonState = buttonState;
    }
    delay(100); // small delay to debounce the button
  }

Never trust a computer with a life or death situation.

Install a very simple float switch to turn off valves, pumps or close gates if the water is too low.

1 Like

As someone who has spent a lot of time developing medical devices, I'm of two minds about this statement :slight_smile:

2 Likes

It is probably not wise to assume that people posting on this forum have expertise in "fail-safe" Arduino applications :wink:

1 Like

For what reason does this happen, exactly?

1 Like

I do not know anything about MQTT.

So where did you declare vannRennerTopic? It's nowhere to be found.

You might very well have a problem there as well.

  1. Two variables called vanRenner, one global and one local. Which one will be used in the snprintf()?
  2. snprintf() can not handle Strings. And %d would be the wrong format specifier to convert a text. If your vanRenner variable is supposed to only hold the values "0" and "1", use an int instead of a String; the %d will work for that.

I suspect that String vannRenner = "dam/vannRenner"; should be String vannRennerTopc = "dam/vannRenner";

1 Like

That's really true. Once a broken sensor said the water level in the river was low, really low. The draining of the river closed up. One fire station was flooded as well as a nearby amusement park. The flood spread into yard for rain deer that drank the dirty water, and died....

1 Like

Hi

lots of interesting answers/questions.

To start, I dont use automation as life and death, but while I try to figure out what's happening I use some surveillance to help find the main reason. Actually I hate using automation for this kind of systems, so this is a temporarilly installation.

But I dont manage to find fault in my code, so now I was hoping to get some code help.

Some of my kois

See post #6 for some of the problems, fix those, and post again if you encounter others.

I suggest to avoid MQTT and monitor the status directly, using very simple code.

1 Like

Below a code that compiles; if it works as you expect is another question. Please compare it with your original; changes are marked with sterretje.

#include <ESP8266WiFi.h>
#include <PubSubClient.h>            // MQTT

const char* ssid = "X";      // Your WiFi network SSID
const char* password = "Y";  // Your WiFi network password

const int buttonPin = D2; // D2 pin
int buttonState = 0;      // variable for reading the button status
int lastButtonState = 0;  // variable to store the previous button state

// MQTT
WiFiClient espClient;
PubSubClient client(espClient);

int    maxRetryMQTT         = 3;
int    retryMQTT            = 0;
String MQTTstatus           = "_";          // For å skrive til serial at kobling til HA er OK

const char* mqtt_username   = "x";          // MQTT username virker 2023.07.05
const char* mqtt_password   = "y";          // MQTT password virker 2023.07.05
const char* mqtt_clientID   = "dam";        // MQTT client ID, må være unikt pr IoT
char vannRennerMsg[10];

// sterretje
//String vannRenner           = "0";
uint8_t vannRennerFlagg       = 0;
//--------------------------

IPAddress MQTTserver(192, 168, 0, 60);      //MQTT server IP

void setup() {
  Serial.begin(115200);    // initialize serial communication
  delay(500);
  pinMode(buttonPin, INPUT);    // set the D2 pin as an input
  digitalWrite(buttonPin, LOW); // enable internal pull-down resistor

  // Connect to WiFi
  WiFi.begin(ssid, password);
  Serial.print("Connecting to ");
  Serial.println(ssid);

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

  // Print connection established
  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}


void loop() {
  // kobler til mqtt
  if (!client.connected()) {
    while (!client.connected() && retryMQTT < maxRetryMQTT) {
      Serial.println("Kobler til MQTT...");
      if (client.connect(mqtt_clientID, mqtt_username, mqtt_password)) {
        Serial.println("MQTT koblet til!  IP 192.168.0.60:1883, web :8123");
        delay(1000);
        retryMQTT = 0; // Reset the retry count if the connection is successful
        MQTTstatus = "Koblet til HA";
      } else {
        Serial.print("Feila å koble til MQTT, Return Code = ");
        Serial.println(client.state());
        delay(500);
        retryMQTT++;
        MQTTstatus = "Ikke koblet til HA, RC = " + client.state();;
      }
      //ESP.restart();                          // ###################### behold denne muligheten  se på versjon tidligere

    }
  }

  // read the state of the pushbutton value
  buttonState = digitalRead(buttonPin);

  // check if the button state has changed
  if (buttonState != lastButtonState) {
    // check if the pushbutton is NOT pressed
    if (buttonState == HIGH) {
      Serial.println("                Det renner ikke vann");
    } else {
      Serial.println("                Det renner vann");
      // sterretje
      //vannRenner = "1";                   // setter til 1,  high
      vannRennerFlagg = 1;

      // sterretje
      //tildeling av topic
      //String vannRennerTopic                            = "dam/vannRenner";
      char topic[] = "dam/vannRenner";

      // sterretje
      // Convert payload into Msg strings. PASS PÅ INT VS FLOAT %d vs %f
      //snprintf(vannRennerMsg                       , 10, "%d"  , vannRenner);
      snprintf(vannRennerMsg                       , 10, "%d"  , vannRennerFlagg);


      // Publish message to Home Assistant
      client.publish(topic, vannRennerMsg);
    }

    // update lastButtonState to the current buttonState
    lastButtonState = buttonState;
  }
  delay(100); // small delay to debounce the button
}

Notes:

  1. You do set the flag vanRenner but you never clear it. This might be intentional or not.
  2. There is a minor issue in the PubSubClient library (I used GitHub - knolleary/pubsubclient: A client library for the Arduino Ethernet Shield that provides support for MQTT.); I have not checked if it will cause disaster
/home/wim/Downloads/arduino-1.8.19-esp8266/portable/sketchbook/libraries/pubsubclient-master/src/PubSubClient.cpp: In member function 'boolean PubSubClient::publish_P(const char*, const uint8_t*, unsigned int, boolean)':
/home/wim/Downloads/arduino-1.8.19-esp8266/portable/sketchbook/libraries/pubsubclient-master/src/PubSubClient.cpp:523:16: warning: comparison of integer expressions of different signedness: 'unsigned int' and 'int' [-Wsign-compare]
  523 |     return (rc == expectedLength);
1 Like

Many good tips from you all, thanks!

I got help, I got code, I have now a system running, to alarm me if water is flooding.

M

Do you mind sharing your final solution so others that encounter similar issues can compare.

1 Like

Hi

I use, no compilation errors:

name=PubSubClient
version=2.8
author=Nick O'Leary nick.oleary@gmail.com
maintainer=Nick O'Leary nick.oleary@gmail.com
sentence=A client library for MQTT messaging.
paragraph=MQTT is a lightweight messaging protocol ideal for small devices. This library allows you to send and receive MQTT messages. It supports the latest MQTT 3.1.1 protocol and can be configured to use the older MQTT 3.1 if needed. It supports all Arduino Ethernet Client compatible hardware, including the Intel Galileo/Edison, ESP8266 and TI CC3000.
category=Communication
url=http://pubsubclient.knolleary.net
architectures=*

That sounds like life support to me. I know of no Arduino approved for life support. That is hard to get from the processor manufacture also.

Final code:

#include <ESP8266WiFi.h>
#include <PubSubClient.h>            // MQTT

const char* ssid = "";      // Your WiFi network SSID
const char* password = "";  // Your WiFi network password

const int buttonPin = D2; // D2 pin
int buttonState     = 0;      // variable for reading the button status
int lastButtonState = 0;  // variable to store the previous button state
int vannRennerFlagg = 0;
int previousState   = 0;

// MQTT
WiFiClient espClient;
PubSubClient client(espClient);

int    maxRetryMQTT         = 3;
int    retryMQTT            = 0;
String MQTTstatus           = "_";          // For å skrive til serial at kobling til HA er OK

const char* mqtt_username   = "";           // MQTT username virker 2023.07.05
const char* mqtt_password   = "";   // MQTT password virker 2023.07.05
const char* mqtt_clientID   = "dam";                // MQTT client ID, må være unikt pr IoT
char vannRennerMsg[10];


IPAddress MQTTserver(192, 168, 0, 60);      //MQTT server IP

void setup() {
  Serial.begin(115200);    // initialize serial communication
  delay(500);
  PrintFileNameDateTime();
  client.setServer(MQTTserver , 1883);         // MQTTk

  pinMode(buttonPin, INPUT);    // set the D2 pin as an input
  digitalWrite(buttonPin, LOW); // enable internal pull-down resistor

  // Connect to WiFi
  WiFi.begin(ssid, password);
  Serial.print("Connecting to ");
  Serial.println(ssid);

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

  // Print connection established
  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}


void loop() {
  // kobler til mqtt
  if (!client.connected()) {
    while (!client.connected() && retryMQTT < maxRetryMQTT) {
      Serial.println("Connect to MQTT...");
      if (client.connect(mqtt_clientID, mqtt_username, mqtt_password)) {
        Serial.println("MQTT   IP 192.168.0.60:1883, web :8123");
        delay(1000);
        retryMQTT = 0; // Reset the retry count if the connection is successful
        MQTTstatus = "Connect to til HA";
      } else {
        Serial.print("Error MQTT connection, Return Code = ");
        Serial.println(client.state());
        delay(500);
        retryMQTT++;
        MQTTstatus = "Not connected to HA, RC = " + client.state();;
      }
      //ESP.restart();                          // ###################### behold denne muligheten  se på versjon tidligere

    }
  }

  // read the state of the pushbutton value
  buttonState = digitalRead(buttonPin);

  // check if the button state has changed
  if (buttonState != lastButtonState) {
    // check if the pushbutton is NOT pressed
    if (buttonState == HIGH) {
      vannRennerFlagg = 0;                // nullstiller etter en lekkasje
      Serial.print("                Det renner ikke vann, sender verdi: ");

      Serial.println(vannRennerFlagg);
      client.loop();                                                   // MQTT loop


      // 1 lager topic
      String vannRennerTopic = "dam/vannRenner";
      // 2 konverterer variable til string
      snprintf(vannRennerMsg, 10, "%d"  , vannRennerFlagg);
      // 3  Publish message to Home Assistant
      client.publish(vannRennerTopic.c_str(), vannRennerMsg);

    } else {
      vannRennerFlagg = previousState;     // 1 betyr at det renner vann
      vannRennerFlagg++;
      previousState = vannRennerFlagg;   // holder styr på antall ganger det har runnet vann
      Serial.print("                Det renner vann, sender verdi:      ");
      Serial.println(vannRennerFlagg);
      client.loop();                                                   // MQTT loop

      // 1 lager topic
      String vannRennerTopic = "dam/vannRenner";

      // 2 konverterer variable til string
      snprintf(vannRennerMsg, 10, "%d"  , vannRennerFlagg);

      // 3  Publish message to Home Assistant
      client.publish(vannRennerTopic.c_str(), vannRennerMsg);

    }

    // update lastButtonState to the current buttonState
    lastButtonState = buttonState;
  }
  delay(100); // small delay to debounce the button
}
// helper-functions
void PrintFileNameDateTime() {
  Serial.println( F("Code running comes from file: ") );
  Serial.println( F(__FILE__) );
  Serial.print( F("Compilert") );
  Serial.print( F(__DATE__) );
  Serial.print( F(" ") );
  Serial.println( F(__TIME__) );
}

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