Problem connecting arduino to mqtt broker

Hi,
Been trying for days to get a mqtt connection with an arduino MKR Wifi 1010 with a MKR ETH shield.
I have HA running on a Linux virtual machine.
I use the mosquitto mqtt broker. The diagnostics show:

"integration_manifest": {
    "domain": "mqtt",
    "name": "MQTT",
    "codeowners": [
      "@emontnemery",
      "@jbouwh"
    ],
    "config_flow": true,
    "dependencies": [
      "file_upload",
      "http"
    ],
    "documentation": "https://www.home-assistant.io/integrations/mqtt",
    "iot_class": "local_push",
    "quality_scale": "gold",
    "requirements": [
      "paho-mqtt==1.6.1"
    ],
    "is_built_in": true
  },
  "data": {
    "connected": true,
    "mqtt_config": {
      "broker": "core-mosquitto",
      "port": 1883,
      "username": "**REDACTED**",
      "password": "**REDACTED**",
      "keepalive": 60,
      "tls_insecure": false,
      "protocol": "3.1.1",
      "transport": "tcp",
      "discovery": true,
      "discovery_prefix": "homeassistant",
      "birth_message": {
        "topic": "homeassistant/status",
        "payload": "online",
        "qos": 0,
        "retain": false
      },
      "will_message": {
        "topic": "homeassistant/status",
        "payload": "offline",
        "qos": 0,
        "retain": false
      }
    },
    "devices": [],
    "mqtt_debug_info": {
      "entities": [
        {
          "entity_id": "sensor.mkr_humidity",
          "subscriptions": [
            {
              "topic": "MKR1010_1/humidity",
              "messages": []
            }
          ],
          "discovery_data": {
            "topic": "",
            "payload": ""
          },
          "transmitted": []
        },
        {
          "entity_id": "sensor.mkr_temperature",
          "subscriptions": [
            {
              "topic": "MKR1010_1/temperature",
              "messages": []
            }
          ],
          "discovery_data": {
            "topic": "",
            "payload": ""
          },
          "transmitted": []
        }
      ],
      "triggers": []
    }

My arduino code:

#include <SPI.h>
#include <Ethernet.h>
#include <DHT.h>
#include <PubSubClient.h>

// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = {
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
};
IPAddress ip(192, 168, 69, 10);
IPAddress gateway(192, 168, 69, 1);
IPAddress subnet(225, 225, 225, 0);

// Initialize the Ethernet server library
// with the IP address and port you want to use
// (port 80 is default for HTTP):
EthernetServer server(80);


#define mqtt_server "196.168.69.203"  // Home Assistant IP address
#define mqtt_user "HAmqtt"   // Home assistant user name
#define mqtt_password "saxopraan2.0"  // Home Assistant password
#define DEVICE_ID "MKR1010_1"    // give a unique name to your device

//MQTT topics: humidity and temperature
String humidity_topic;
String temperature_topic;

#define LED 2                 // Send data led pin
#define READ_DELAY_MS 60000   // 1 mn between reads (in milliseconds)

#define DHTPIN 6             //Pin of your DHT sensor
#define DHTTYPE DHT11
DHT dht(DHTPIN,DHTTYPE,30);

int ledState = 0;

EthernetClient ethClient;

PubSubClient client(ethClient);

void setup() {
  pinMode(LED,OUTPUT);
  
  Serial.begin(19200);

  delay(5000);

  Serial.println("debug 1");

  humidity_topic = String(DEVICE_ID) + "/humidity";
  temperature_topic = String(DEVICE_ID) + "/temperature";
  
  setup_eth();
  client.setClient(ethClient);
  client.setServer(mqtt_server, 1883);
  
  delay(200);
}

void setup_eth() { 
  delay(10);
  Serial.println("debug 2");
  ledToggle();
  Serial.println("debug 3");

  // start the Ethernet connection and the server:
  Ethernet.begin(mac, ip, gateway, subnet);

  // Check for Ethernet hardware present
  if (Ethernet.hardwareStatus() == EthernetNoHardware) {
    Serial.println("Ethernet shield was not found.  Sorry, can't run without hardware. :(");
    while (true) {
      delay(1); // do nothing, no point running without Ethernet hardware
    }
  }
  if (Ethernet.linkStatus() == LinkOFF) {
    Serial.println("Ethernet cable is not connected.");
  }

  // start the server
  server.begin();
  Serial.print("server is at ");
  Serial.println(Ethernet.localIP());
  ledToggle();

}

void reconnect() {
  int mqttFailuresNumber = 0;
  ledToggle();
  
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Attempt to connect
    if (client.connect(DEVICE_ID, mqtt_user, mqtt_password)) {
      Serial.println("connected");
    } else {
      if (mqttFailuresNumber==3) {
        //reset wifi if too many mqtt failures
        mqttFailuresNumber = 0;

        //re-initialize the Wifi connection, whatever happened
        //client.stop();//WiFi.end();
        Ethernet.begin(mac, ip);//status = WiFi.begin(ssid,pass);
      } else {
        mqttFailuresNumber++;
        Serial.println(mqttFailuresNumber);
      }
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
  ledToggle();
}

long lastMsg = 0;
float temp = 0.0;
float hum = 0.0;
float diff = 1.0;

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

  long now = millis();
  if (now - lastMsg > READ_DELAY_MS) {
    ledToggle();
    lastMsg = now;

    float newTemp = dht.readTemperature();
    float newHum = dht.readHumidity();

    if(!isnan(newTemp)) {
      temp = newTemp;
      Serial.print("Temperature:");
      Serial.println(String(temp).c_str());
      client.publish(temperature_topic.c_str(), String(temp).c_str(), true);
    }

    if(!isnan(newHum)) {
      hum = newHum;
      Serial.print("Humidity:");
      Serial.println(String(hum).c_str());
      client.publish(humidity_topic.c_str(), String(hum).c_str(), true);
    }
    
    ledToggle();
  }
}

// change the wifi connetcion led status 
void ledToggle(){
  if (ledState == 0){
    digitalWrite(LED,HIGH);
    delay(10);
    ledState = 1;
  } else {
    digitalWrite(LED,LOW);
    delay(10);
    ledState = 0;
  }
 }

The ethernet connection is OK. I can ping it.
The serial moniotor shows:

debug 1
debug 2
debug 3
server is at 192.168.69.10
Attempting MQTT connection...1
failed, rc=-2 try again in 5 seconds
Attempting MQTT connection...2
failed, rc=-2 try again in 5 seconds
Attempting MQTT connection...3
failed, rc=-2 try again in 5 seconds
Attempting MQTT connection...failed, rc=-2 try again in 5 seconds

The Mosquitto broker log returns:
2023-05-07 21:50:07: New connection from 172.30.32.2:38188 on port 1883.
2023-05-07 21:50:07: Client closed its connection.

I have no idee where this IP commes from as I defined my arduino as 192.168.69.10. I can ping both.

Thanks in advance for any help debugging this.

P.S. I know a MKR Wifi 1010 is overkill for the application, but it’s a test setup for a bigger project to read data from a Finder energy meter that currently publishes to Arduino iot Cloud.

Hi,
I’d suggest a few troubleshooting steps to look at first:

  • Cross-check what the broker is seeing using https://mqtt-explorer.com/ and the logs - any connection attempts?
  • Run wireshark and trace the connection attempts - any traffic from the Arduino?

The 172.30.32/24 is a HASS docker internal IP address within HASSOS - has the MQTT add-on connected to the broker successfully?

I see similar all the time:

2023-05-07 20:15:06: New connection from 172.30.32.2:46680 on port 1883.
2023-05-07 20:15:06: Client <unknown> closed its connection.

Do you have other MQTT devices working (e.g. a Sonoff running Tasmota)?

If not, a basic guide might help:

My suggestion is to get other MQTT devices working (e.g. Tasmota) first, as this gives a better idea of the HASS Discovery and Tasmota Discovery standards that run on top of MQTT and can be very useful (there are a few posts on here about writing your own code for this).

If this helps, :heart: this post!

mqtt-explorer connects to the broker.

The arduino responds to the ping. Alas I’m not familiar with prtg to get more out of it.

I was able to succesfully connect a ESP8266 with a DHT11 temperature sensor. Readings are comming in every minute for the last 2 days. I bought a Tasmota power soccet, but still waiting for it to arrive.

The error messages for the Arduino changed to:

023-05-11 21:30:30: New connection from 172.30.32.1:49084 on port 1883.
error: received null username or password for unpwd check

Nothing has changed to neighter user nor pswrd. I haven’t touched the Arduino compilation.

I was wondering:
In the arduino code I define de Device_ID as MKR1010_1. The only lines I added to configuration.yaml is:

#MQTT sensors
mqtt:
  sensor:
    - name: "MKR humidity"
      state_topic: "MKR1010_1/humidity"
      unit_of_measurement: "%"
    - name: "MKR Temperature"
      state_topic: "MKR1010_1/temperature"
      unit_of_measurement: "°C"

I assumed that the connection with the device was defined by the MKR1010_1 in state_topic. I’m beginning to wonder if this is correct. How does the broker know the device_id? I suppose it has to be defined somewhere?