MQTT Message lost/not found from ESP8266 to Embedded MQTT Broker [RESOLVED]

Ah, thank you SO much! It finally works as intended, and is publishing every second!!
You were right; I had a hunch that something was going on that was too much for the Arduino to handle at the same time. I cleaned up the code as per your suggestions and it now functions perfectly.
I’m so used to powerful engines, I think the issue -may- have even been something as simple as declaring the variables in the wrong scope. If this didn’t work I was going to ask about garbage collection, but I think what was happening was the I was making too manyy new vairables each instance clogging -something-. I can’t directly verify, but I can at least determine that the decreased workload on the chip allowed it to actually do its job! That was a great suggestion.
For anyone at any point in the future curious to see what the working code looks like, here’s what I made:

#include <SPI.h>
#include <Wire.h>
#include <WiFiClient.h>
#include <ESP8266WiFi.h>
#include <PubSubClient.h>

//WiFi Credentials (probably should include these in a secret .h file later)
char ssid[] = "XXXXX"; // IoT devices can only connect to 2.4 GHz wifi, DO NOT connect to 5GHz it will fail
char pass[] = "XXXXX";

int SensorPin = A0;
int SoilValue = 0;
int SoilPercent = 0; //this takes SoilValue, and converts it to a 0-100% based on AirValue & WaterValue
int AirValue = 866; //These two values are HAND MEASURED to determine air (no water) vs. full count of water.
int WaterValue = 540;
String Data;

WiFiClient wifiClient;
PubSubClient client(wifiClient);
const char broker[] = "XXXXX";
int port = 1883;
const char* topic = "tele/SoilSensor01";
const char* clientID = "SoilSensor01";
const char* buffer;
const char* ToJSON;
String JSONconverter;

const long interval = 1000;
unsigned long previousMillis = 0;

int count = 0;

void setup() {
  //Initialize serial and wait for port to open:
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  // attempt to connect to Wifi network:
  Serial.print("Attempting to connect to WPA SSID: ");
  WiFi.begin(ssid, pass);
  while (WiFi.status() != WL_CONNECTED) {
    // failed, retry

  Serial.println("You're connected to the network");

  Serial.print("Attempting to connect to the MQTT broker: ");

  client.setServer(broker, port);
  Serial.println("Connection Status: " + String(client.state()));
  if (!client.connected()) {
  Serial.println("You're connected to the MQTT broker!");



void loop() {
  if (!client.connected()) {
  // avoid having delays in loop, we'll use the strategy from BlinkWithoutDelay
  // see: File -> Examples -> 02.Digital -> BlinkWithoutDelay for more info
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= interval) {
    // save the last time a message was sent
    previousMillis = currentMillis;
    Serial.print("Sending message to topic: ");
    if(client.publish("test/two", ToJSON, true) == true) {
        Serial.println("Message Succeeded!");
    else {
        Serial.println("Message Failed to Send!");

void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Attempt to connect
    if (client.connect(clientID)) {
    } else {
      Serial.print("failed, state: ");
      Serial.println("attempting reconnection...");
      // Wait 5 seconds before retrying

void callback(char* topic, byte* payload, unsigned int length) {
  Serial.print("Message arrived [");
  Serial.print("] ");
  for (int i = 0; i < length; i++) {

void GrabAndSetData() {
    SoilValue = analogRead(SensorPin);
    SoilPercent = map(SoilValue, AirValue, WaterValue, 0, 100);
    Data = String(SoilPercent);
    //This allows the OpenHAB broker to read the message
    buffer = Data.c_str();
    JSONconverter = String("{\"moisture\": ") + String(buffer) + String("}");
    ToJSON = JSONconverter.c_str();

-I put the client.loop() at the end
-Ensured no variables were declared or initialized inside the loop
-wrapped the message and value into a function that would be called on setup() to initialize the values, and is then recalled after a message is sent in the loop so that the message parameter is never Null
…and Voila! A homemade soil sensor that connects to the MQTT broker!
This is huge for me! Now I can finally get to working on the other parts of my self automated watering system!

FYI it also no longer intermittently disconnects, which is also hugely helpful.

Maybe you intend to reinvent the wheel just for the heck of it. If not, or if you have had enough punishment, you could just flash tasmota-sensors onto that NodeMCU. Then you would have a door open to a world full of many things in line with your goals.

Well thankfully as mentioned above I got it all up and running okay. While Tasmota makes this specific scenario easy to handle, this was meant to be a learning experience so I can develop firmware that something like Tasmota can’t do. The big thing was figuring out how to properly communicate with the broker; that’s really what this was all about. I wouldn’t have gone through the effort if I didn’t want to know how to use code to communicate to my broker directly.
Now, for example, I can use my knowledge of this to program logic for an 8-channel motor driver circuit I’m working on that will take the messages that these sensors are sending and perform xyz. Something like that cannot be done through Tasmota, and requires me to build my own firmware on the 8266 so it does what I want.
I’m a firm believer that the only way to truly have all the doors open means understanding how something works, build something someone’s done before, and take that knowledge and understanding to build something new. Creativity becomes truly limitless once you can directly program to do what you want it to do. Plus, just as a personal opinion, that’s what makes projects like this fun for me. Programming’s what I enjoy doing the most, and I’ve done it since I was 8.
On the flip side I do understand that people need different levels of understanding to accomplish their goals, and sometimes reinventing the wheel is far more of a hassle than its worth.
I will never forget how annoyed I was when I was forced to take these intro computer science courses at Uni, and all they cared about was teaching people how to build things that are already found in the C++ standard library. I knew I was this weird exception that forced me to get stuck in intro level classes, but trying to build different kinds of lists, and literally making our own “string” or array of chars drove me absolutely -insane-. I was like “no wonder people don’t find programming fun when they take these classes”.