I have a project I am working on, based on an ESP32 from NodeMCU. I have a bunch of sensors connected to said ESP32 - they all work and the code itself "works" with a minor quirk.
The issue in question starts with a DHT11 sensor. I started from the basic "hello world" DHT11 code (you can find it easily with a DHT11 search in google). That sensor works in my code that you can see below - I copied and pasted the sample code, and except for changing variables, did not alter the sample code really at all.
The issue I have is that while the sample code will read accurately on every loop, in my code, it reads from the sensor exactly once the first time the loop runs, and then never again.
I believe I have isolated the issue to this bit of code and the corresponding function it calls (it didn't used to be a function - that was a troubleshooting step):
if (!client.connected()) {
reconnectMQ();
} etc...
By moving this statement and grouping the MQTT messaging to the end, the system runs a full loop with correct readings, exactly once, but after that function is called the DHT11 begins failing to read.
Things I have tried:
- different variable names for temp and humidity (in case "t" and "h" are in use in the MQ library)
- order of operations (made the loop work once)
- changing the reconnectMQ() to a full function and not just a loop in the main loop
- changing the logic of the DHT11 sensor to at least not hang forever trying to read - this meant it got through this part, but with 0 values
- "turning off" MQ - this means that everything works, but obviously is a bit like cutting off your arm for a sprained wrist.
- ENDLESS Google and Stack searches before resorting to this post.
I hate to do this as my project is 200 lines long, but I suspect the full code is needed to see what's possibly happening.
#include <time.h>
#include <DHT.h>
#include <WiFi.h>
#include <PubSubClient.h>
//use pin 23 to read temp and humidity
//our sensor is DHT11 type
//creates an instance of DHT sensor
#define DHTPIN 23
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);
//Define the analog pins inbound for the Soil Moisture sensors
const int sm1Pin = 33;
const int sm2Pin = 34;
const int sm3Pin = 35;
const int sm4Pin = 32;
const int power = 22;
const int exec = 21;
const int net = 19;
//define the pin for the light level reading
const int light = 36;
//Init MQTT payload arrays
char data0[50];
char data1[50];
char data2[50];
// declare our Wifi and MQTT connections and other constant settings for the network
const char* ssid = "*******"; // The SSID (name) of the Wi-Fi network you want to connect to
const char* password = "*******"; // The password of the Wi-Fi network
const char* mqtt_server = "192.168.1.195"; // The target mqtt server
const char* input_string = "{\"Reporting\":\"GardenUnit1\", "; // The name of this garden monitor unit
String clientId = "GP1";
int lcount = 0;
// declare our Wifi and MQTT connections
WiFiClient espClient;
PubSubClient client(espClient);
//
// Reconnects to the MQTT message-bus if the connection died, or we're
// not otherwise connected.
//
void reconnectMQ() {
digitalWrite(net, LOW); // turn the Blue NET LED Off
if (WiFi.status() != WL_CONNECTED) {
Serial.println("Wifi not connected - configuring");
setup_wifi();
} else {
Serial.println("Wifi Connected - connecting MQTT");
}
// Attempt to connect
Serial.println("Attempting to connect to MQTT Server...");
while (!client.connected()) {
if (client.connect(clientId.c_str())) {
Serial.println("connected to MQTT server");
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
// Wait 5 seconds before retrying
delay(5000);
}
}
// Once connected, publish an announcement...
String payload = String(input_string) + "\"MQTT\":\"Reconnected\"}";
payload.toCharArray(data1, (payload.length() + 1));
client.publish("control", data1); //the "control" topic is just for notifications - change to fit your needs
digitalWrite(net, HIGH); // turn the Blue NET LED on
delay(5000);
}
void setup_wifi() {
delay(10);
Serial.print("Connecting to ");
Serial.print(ssid); Serial.println(" ...");
WiFi.begin(ssid, password); // Connect to the wifi network
while (WiFi.status() != WL_CONNECTED) // Wait for the Wi-Fi to connect
delay(1000);
Serial.print('.');
Serial.println('\n');
Serial.println("Connected!");
Serial.print("IP address:\t");
Serial.println(WiFi.localIP()); // Send the IP address of the ESP32 to the serial port
}
void setup() {
Serial.begin(9600); // open serial port, set the baud rate as 9600 bps
// These Options control the precision of the reading, and the voltage reduction capability of the ESP32
// Attenuation number 3 is 11DB
analogSetWidth(10);
analogSetAttenuation((adc_attenuation_t)3);
// Define the MQTT Server connection settings and then launch the MQTT Connection
client.setServer(mqtt_server, 1883);
// Set output and input pins to correct modes
pinMode (power, OUTPUT);
pinMode (exec, OUTPUT);
pinMode (net, OUTPUT);
//Turn on Green Power light
digitalWrite (power, HIGH);
//Connect to the wireless network
setup_wifi();
//This call starts the dht11 sensor instance
dht.begin();
}
void loop() {
//Turn on RED EXEC light - this means a sample is being taken
digitalWrite (exec, HIGH);
//Read DHT11 Temp and Humidity - Humidity is a % and temp is in Celcius
float hum = dht.readHumidity();
float temp = dht.readTemperature();
// Check if any reads failed but insert bogus data so system continues
if (isnan(hum) || isnan(temp)) {
Serial.println("Failed to read from DHT sensor!");
client.publish("garden1", "{\"Error\":\"Humidty/Temp Sensor Offline!\"}");
hum = 0;
temp = 0;
} else {
// print the result to Terminal
Serial.print("Humidity: ");
Serial.print(hum);
Serial.print(" %\t");
Serial.print("Temperature: ");
Serial.print(temp);
Serial.println(" *C ");
}
//Read value and print to serial for S1
float s1 = analogRead(sm1Pin);
Serial.print("Sensor 1: ");
Serial.print(s1);
Serial.println();
//Read value and print to serial for S2
float s2 = analogRead(sm2Pin);
Serial.print("Sensor 2: ");
Serial.print(s2);
Serial.println();
//Read value and print to serial for S3
float s3 = analogRead(sm3Pin);
Serial.print("Sensor 3: ");
Serial.print(s3);
Serial.println();
//Read value and print to serial for S4
float s4 = analogRead(sm4Pin);
Serial.print("Sensor 4: ");
Serial.print(s4);
Serial.println();
float L1 = analogRead(light);
Serial.print("Light level: ");
Serial.print(L1);
Serial.println();
if (!client.connected()) {
reconnectMQ();
}
String payload = String(input_string) + "\"S1\":\"" + s1 + "\", \"S2\":\"" + s2 + "\", \"S3\":\"" + s3 + "\", \"S4\":\"" + s4 + "\"}";
payload.toCharArray(data0, (payload.length() + 1));
Serial.println("Publishing message 1:");
while (!client.publish("garden1", data0)) {
Serial.print(".");
}
String payload2 = String(input_string) + "\"Humidity\":\"" + hum + "\", \"Temperature\":\"" + temp + "\", \"Light\":\"" + L1 + "\"}";
payload2.toCharArray(data2, (payload2.length() + 1));
Serial.println("Publishing message 2:");
while (!client.publish("garden1", data2)){
Serial.print(".");
}
//Turn off RED EXEC light - this means a sample is done
digitalWrite (exec, LOW);
lcount = lcount + 1;
delay(10000);
}
What happens when the code I have here runs is that I see all the messages at the Mosquito server and in serial monitor, and the loop runs as expected. Due to the logic I had to put in to keep the program running, after the first reading from the DHT11, temp and hum come back as 0 forever. This is obviously not what I want.
What is obvious: Something happens between the first reading of the DHT11 and the next that makes it unhappy.
What is not: What that something is. That something occurs in the MQTT connection, but for the life of me I cannot figure out what it is or isolate it.
So now I leave it to the community. What the heck is happening here?!