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:
Serial.begin(9600);
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: ");
Serial.println(ssid);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, pass);
while (WiFi.status() != WL_CONNECTED) {
// failed, retry
Serial.print(".");
delay(500);
}
Serial.println("You're connected to the network");
Serial.println();
Serial.print("Attempting to connect to the MQTT broker: ");
Serial.println(broker);
Serial.println("...");
client.setServer(broker, port);
client.setCallback(callback);
client.connect(clientID);
client.subscribe(topic);
Serial.println("Connection Status: " + String(client.state()));
if (!client.connected()) {
reconnect();
}
Serial.println("You're connected to the MQTT broker!");
GrabAndSetData();
Serial.println();
}
void loop() {
if (!client.connected()) {
reconnect();
}
// 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: ");
Serial.println("test/two");
if(client.publish("test/two", ToJSON, true) == true) {
Serial.println("Message Succeeded!");
Serial.println(ToJSON);
GrabAndSetData();
}
else {
Serial.println("Message Failed to Send!");
}
Serial.println();
count++;
}
client.loop();
}
void reconnect() {
// Loop until we're reconnected
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
// Attempt to connect
if (client.connect(clientID)) {
Serial.println("connected");
client.subscribe(topic);
} else {
Serial.print("failed, state: ");
Serial.println(client.state());
Serial.println("attempting reconnection...");
// Wait 5 seconds before retrying
delay(5000);
}
}
}
void callback(char* topic, byte* payload, unsigned int length) {
Serial.print("Message arrived [");
Serial.print(topic);
Serial.print("] ");
for (int i = 0; i < length; i++) {
Serial.print((char)payload[i]);
}
Serial.println();
}
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!