ESP not publishing to MQTT

I have set up a d1 mini with a BME280 sensor. I have it all working, it reads the values, prints everything to serial, connects to the wifi and goes to sleep.

The only thing I cant seem to get working, is publishing a message to the MQTT broker.

I have mosquitto running on a pi, and other things are currently using MQTT so I know the server is up and running.

I replaced the message with a simple test string and got no compile errors. I also dont get any errors on the serial monitor trying to publish that message. I did attempt to change to other messages and when it doesn’t like it there is a ‘stack’ error so Im a bit stuck as to why I cant see these messages when everything appears to be ok.

Im subscribing to everything and subscribing to the exact topic and neither show any messages coming in.

Im not sure how to delve into mosquitto to see if it is getting the message and not handling it. So I cant say whats happening there for the time being. But if this code is deemed to work then thats my next option.

Thanks

//BME280 sensor libraries
//#include <BME280.h>
#include <BME280I2C.h>
//#include <BME280I2C_BRZO.h>
//#include <BME280Spi.h>
//#include <BME280SpiSw.h>
//#include <EnvironmentCalculations.h>

#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <Wire.h>
//#include <ArduinoJson.h>

const char* wifi_ssid     = "";
const char* wifi_password = "";
const char* mqtt_server   = "192.168.0.100";
const char* mqtt_user     = "";
const char* mqtt_password = "";
const char* topic         = "";
const char* clientName    = "";

WiFiClient espClient;
PubSubClient client(espClient);

BME280I2C bme;    // Default : forced mode, standby time = 1000 ms
// Oversampling = pressure ×1, temperature ×1, humidity ×1, filter off,

void setup() {
  Serial.begin(9600);
  Serial.println("");
  Serial.println("Serial port opened @ 9600");
  //SDA = D2 GPIO4, SCL = D1 GPIO5
  Wire.begin(); //check address 0x76 of BME280 sensor if not working
  Serial.println("i2c started");
  bool state = bme.begin();
  while (!state) {
    Serial.println("unable to connect to BME sensor");
    delay(5000);
  }
  if (WiFi.status() != WL_CONNECTED) {
    setup_wifi();
  }
  Serial.println("connect to mqtt server");
  client.setServer(mqtt_server, 1883);
  //wait until connection to MQTT broker is established
  while (!client.connected()) {
    if (client.connect(clientName, mqtt_user, mqtt_password)) {
      Serial.print("connected to mqtt server - ");
      Serial.print(mqtt_server);
      Serial.print(" - as client ID - ");
      Serial.println(clientName);
      sendValues();
    } else {
      delay(5000);
    }
  }

  //deep sleep on ESP, link RST to D0!
  //180,000,000 = 180 seconds (3mins)
  Serial.println("going to sleep!");
  //    ESP.deepSleep(180000000);
  ESP.deepSleep(30 * 1000000);
}

void setup_wifi() {
  Serial.println("setup wifi");
  delay(10);
  // We start by connecting to a WiFi network
  WiFi.begin(wifi_ssid, wifi_password);

  while (WiFi.status() != WL_CONNECTED) {
    Serial.print(".");
    delay(500);
  }
  Serial.println("wifi setup complete");
  Serial.print("connected to SSID ");
  Serial.print(WiFi.SSID());
  Serial.print(" at IP address ");
  Serial.println(WiFi.localIP());
}

void reconnect() {
  Serial.println("attempting to reconnect to MQTT server");
  // Loop until we're reconnected
  while (!client.connected()) {
    // Attempt to connect
    if (client.connect(clientName)) {
      return;
    } else {
      Serial.print(".");
      delay(5000);
    }
  }
}

void sendValues() {
  Serial.println("get sensor values");
  //get values from sensor
  float temp(NAN), hum(NAN), pres(NAN);
  BME280::TempUnit tempUnit(BME280::TempUnit_Celsius);
  BME280::PresUnit presUnit(BME280::PresUnit_Pa);

  bme.read(pres, temp, hum, tempUnit, presUnit);

  char buf[10];
  sprintf(buf, "%f", temp);

  Serial.print("temp - ");
  Serial.print(temp);
  Serial.print(" - hum  - ");
  Serial.print(hum);
  Serial.print(" - pres - ");
  Serial.println(pres);

  //    StaticJsonBuffer<200> doc;
  //    doc["temp"] = temp;
  //    doc["hum"]  = hum;
  //    doc["pres"] = pres;
  //    serializeJson(doc, buff);

  // send value to mqtt
  //client.publish(topic, buf);
  if (!client.connected()) {
    reconnect();
  } else {
    Serial.print("publish message - ");
    Serial.print(topic);
    Serial.println("test");
    client.publish("test", "test");
  }
}

void loop() {
  //no loop
}

worked it out, dont enable deepsleep instantly after asking it to do something else, like publish a message.

I added a 1s delay and it fixed it, what would be better however would be to wait for a confirmation of the publish then go to deepsleep, so Ill have to check the pubsubclient library to see if such a thing exists. I think there is a callback for this.

I had a look into the header file of the PubSubClient library.

// Finish off this publish message (started with beginPublish)
// Returns 1 if the packet was sent successfully, 0 if there was an error
int endPublish();

But looking into the cpp file the function just returns 1. Looks like this funcionality is not implemented yet.

int PubSubClient::endPublish() {
return 1;
}

I have been using the ArduinoMqttClient library and that seems to be checking and returning different values in the endMessage function.