When using platformio, add this in lib_deps: 256dpi/MQTT @ ^2.5.2 Create 256mqtt.h and include it in the main source code, define the MQTT_HOST, MQTT_PORT and MQTT_TOPIC as well: const char *mqtt_broker = "broker.emqx.io"; // EMQX broker endpoint const char *mqtt_topic = "emqx/esp8266"; // MQTT topic const char *mqtt_username = "emqx"; // MQTT username for authentication const char *mqtt_password = "public"; // MQTT password for authentication const int mqtt_port = 1883; // MQTT port (TCP) const char *lwt_topic = "esp8266/status"; const char *lwt_message = "device is offline now"; const int lwt_qos = 1; const bool lwt_retain = true; Code for mqtt.h (including Last Will and Testament (LWT): #include // this is for ESP8266, change for ESP32 #include WiFiClient espClient; MQTTClient mqtt_client; bool mqttconnected = false; void messageReceived(String &topic, String &payload) { Serial.println("incoming: " + topic + " - " + payload); // Note: Do not use the client in the callback to publish, subscribe or // unsubscribe as it may cause deadlocks when other things arrive while // sending and receiving acknowledgments. Instead, change a global variable, // or push to a queue and handle it in the loop after calling `client.loop()`. } void connectmqtt() { Serial.print("\nconnecting..."); while (!mqtt_client.connect(mqtt_clientid, mqtt_username, mqtt_password)) { Serial.print("."); delay(1000); } mqtt_client.subscribe(mqtt_topic); mqtt_client.setWill(lwt_topic,lwt_message,lwt_retain,lwt_qos); } void initializemqtt() { mqtt_client.begin(mqtt_broker, espClient); mqtt_client.onMessage(messageReceived); connectmqtt(); } In the loop: mqtt_client.loop(); if (!mqtt_client.connected()) { connectmqtt(); } To set will; Set a will message (last testament) that gets registered on the broker after connecting. setWill() has to be called **//before//** calling connect(): void setWill(const char topic[]); void setWill(const char topic[], const char payload[]); void setWill(const char topic[], const char payload[], bool retained, int qos); void clearWill(); To Subscribe or Publish: bool subscribe(const String &topic); bool subscribe(const String &topic, int qos); bool subscribe(const char topic[]); bool subscribe(const char topic[], int qos); To Publish: bool publish(const String &topic); bool publish(const char topic[]); bool publish(const String &topic, const String &payload); bool publish(const String &topic, const String &payload, bool retained, int qos); bool publish(const char topic[], const String &payload); bool publish(const char topic[], const String &payload, bool retained, int qos); bool publish(const char topic[], const char payload[]); bool publish(const char topic[], const char payload[], bool retained, int qos); bool publish(const char topic[], const char payload[], int length); bool publish(const char topic[], const char payload[], int length, bool retained, int qos); Advance options: void setKeepAlive(int keepAlive); void setCleanSession(bool cleanSession); void setTimeout(int timeout); void setOptions(int keepAlive, bool cleanSession, int timeout); * The keepAlive option controls the keep alive interval in seconds (default: 10). * The cleanSession option controls the session retention on the broker side (default: true). * The timeout option controls the default timeout for all commands in milliseconds (default: 1000). Below link: https://registry.platformio.org/libraries/256dpi/MQTT https://github.com/256dpi/arduino-mqtt