// code for temperature and humidity monitoring using nodered dashboard
#include <WiFi.h>
#include <PubSubClient.h>
#include <DHT.h>
#include <ArduinoJson.h>
#include <HTTPClient.h>
const int buzzerPin = 27;
const float tempThreshold = 35.0;
const char* ssid = "Wokwi-GUEST";
const char* password = "";
const char* mqtt_server = "mqtt.eclipseprojects.io";// MQTT broker
char* my_topic2 = "/IoT1/temp";// topic2: sensor-temerature
char* my_topic3 = "/IoT1/hum";// topic3: sensor-humidity
const char* my_topic4 = "/buzzer/tone"; // MQTT publish
const char* mqttTopic = "esp32/pwm";
const char* fan_status_topic = "status/fan/current_speed";
const char* mqtt_topic = "esp32/sensors/data"; // single topic
const char* mqtt_topic1 = "weather/current";
const char* api_key = "53045586437ffd0209d81404b0ee2daf";
// Cities to monitor
const char* cities[] = {"Bellville", "Cape Town", "Durban"};
const int numCities = sizeof(cities) / sizeof(cities[0]);
const int ledPin = 13;
const int pwmFreq = 5000; // 5000 Hz frequency
const int pwmResolution = 8; // 8-bit resolution
const int pwmChannel = 0;
int pwmValue = 0; // Initial duty cycle
WiFiClient espClient;
PubSubClient client(espClient);
DHT dht(26, DHT22);
// ===== NTC Thermistor Setup =====
#define NTC_PIN 34 // ADC pin for thermistor
void setup() {
Serial.begin(115200); // Initialize serial communication for debugging
//my esp32.attach(5); // Attach the to GPIO pin 5
setup_wifi();
client.setServer(mqtt_server, 1883); // Set the MQTT broker server and port
client.setCallback(callback); // Set the callback function for incoming MQTT messages
dht.begin();
pinMode(buzzerPin, OUTPUT);
Serial.begin(115200);
Serial.println("PWM Configuration:");
Serial.printf("Frequency: %d Hz\n", pwmFreq);
Serial.printf("Resolution: %d-bit (Max Duty:255)\n", pwmResolution);
Serial.printf("Attached PWM to GPIO %d\n", ledPin);
Serial.printf("Initial Duty Cycle: %d\n", pwmValue);
// Configure PWM for fan control
pinMode(ledPin, OUTPUT);
analogWrite(ledPin, 0); // Start with fan off
setup_wifi();
client.setServer(mqtt_server, 1883);
client.setCallback(callback);
delay(2000);
}
// Connect to the Wi-Fi network using the provided credentials
void setup_wifi() {
delay(10);
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP()); // Print the local IP address of the ESP32 once connected
}
// Process incoming MQTT message and control the servo motor
//void callback(char* topic, byte* payload, unsigned int length) {
//if (topic = my_topic2){
//}
//}
// Attempt to reconnect to the MQTT broker if the connection is lost
void reconnect() {
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
if (client.connect("ESPClient")) {
Serial.println("connected");
client.subscribe(mqttTopic);
String clientId = "ESP32-FanController-";
clientId += String(random(0xffff), HEX);
client.subscribe(mqttTopic);
Serial.printf("Subscribed to topic: %s\n", mqttTopic);
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
delay(5000);
}
}
}
void callback(char* topic, byte* message, unsigned int length){
Serial.println("Message arrived ");
Serial.print(topic);
Serial.print(". Message: ");
String messageTemp;
for (int i = 0; i < length; i++) {
messageTemp += (char)message[i];
}
Serial.println(messageTemp);
// Check if message is for fan control
if (String(topic) == "esp32/pwm") {
int speed = messageTemp.toInt();
// Convert percentage to PWM value (0-255)
int pwm_value = map(speed, 0, 100, 0, 255);
analogWrite(ledPin, pwm_value);
Serial.print("Recieved Duty Cycle Value: ");
Serial.println(messageTemp);
Serial.print("Setting PWM Duty Cycle to: ");
Serial.println(speed);
// Publish current speed back to MQTT
client.publish(fan_status_topic, messageTemp.c_str());
}
}
void loop() {
// Check MQTT connection and process incoming messages
if (!client.connected()) {
reconnect();
}
client.loop();
delay(100); // Add a delay to avoid flooding the MQTT broker with messages
float temp = dht.readTemperature();
float humidity = dht.readHumidity();
Serial.print("Temp : ");
Serial.print(temp);
Serial.println(" C ");
Serial.print("Humidity : ");
Serial.print(humidity);
Serial.println(" % ");
String messaget = String(temp);
String messageh = String(humidity);
client.publish("/IoT1/temp", messaget.c_str());
client.publish("/buzzer/tone", messageh.c_str());
if (temp > tempThreshold) {
// Turn on the buzzer
digitalWrite(buzzerPin, HIGH);
Serial.println("Buzzer ON (Temperature above threshold)");
// Optionally, you can add a delay to keep the buzzer on for a certain time
delay(2000); // Buzzer on for 2 seconds
// Make the buzzer buzz for 1 second
tone(buzzerPin, 1000); // Frequency of 1000 Hz
delay(1000);
// Stop the buzzer
noTone(buzzerPin);
delay(1000);
// Turn off the buzzer
digitalWrite(buzzerPin, LOW);
Serial.println("Buzzer OFF");
} else {
// Turn off the buzzer
digitalWrite(buzzerPin, LOW);
Serial.println("Buzzer OFF (Temperature below threshold)");
}
delay(200);
// ===== NTC Calculation =====
int adcValue = analogRead(NTC_PIN);
float resistance = (10000.0 * adcValue) / (4095.0 - adcValue); // 10k pull-up, 12-bit ADC
// Steinhart-Hart equation constants (for typical 10k NTC thermistor)
const float A = 0.001129148;
const float B = 0.000234125;
const float C = 0.0000000876741;
float steinhart = log(resistance);
steinhart = 1.0 / (A + B * steinhart + C * steinhart * steinhart * steinhart);
float thermTemp = steinhart - 273.15; // Kelvin to Celsius
// ===== Validate readings =====
if (!isnan(temp) && !isnan(humidity) && !isnan(thermTemp)) {
char payload[256];
snprintf(payload, sizeof(payload),
"{\"dht22_sensor\":{\"temperature_celsius\":%.1f,\"humidity_percent\":%.1f},"
"\"thermistor_sensor\":{\"temperature_celsius\":%.1f}}",
temp, humidity, thermTemp
);
if (client.publish(mqtt_topic, payload)) {
Serial.print("Payload: ");
Serial.println(payload);
Serial.println("Published successfully");
} else {
Serial.println("Failed to publish combined data.");
}
} else {
Serial.println("Sensor read error.");
}
for (int i = 0; i < numCities; i++) {
fetchAndPublishWeather(cities[i]);
delay(2000); // slight delay between cities
}
}
void fetchAndPublishWeather(const char* cityName) {
HTTPClient http;
String url = "http://api.openweathermap.org/data/2.5/weather?q=" + String(cityName) + "&appid=" + api_key + "&units=metric";
http.begin(url);
int httpCode = http.GET();
if (httpCode > 0) {
String payload = http.getString();
StaticJsonDocument<1024> doc;
DeserializationError error = deserializeJson(doc, payload);
if (error) {
Serial.print("JSON parse failed: ");
Serial.println(error.c_str());
http.end();
return;
}
// Extract data
float temperature = doc["main"]["temp"];
String description = doc["weather"][0]["description"];
long timestamp = doc["dt"];
float latitude = doc["coord"]["lat"];
float longitude = doc["coord"]["lon"];
time_t raw = timestamp;
struct tm *dt = gmtime(&raw);
char buffer[30];
strftime(buffer, sizeof(buffer), "%Y-%m-%dT%H:%M:%SZ", dt);
// Build JSON string
String json = "{";
json += "\"location\":\"" + String(cityName) + "\",";
json += "\"temperature\":" + String(temperature, 1) + ",";
json += "\"description\":\"" + description + "\",";
json += "\"timestamp\":\"" + String(buffer) + "\",";
json += "\"lat\":" + String(latitude, 6) + ",";
json += "\"lon\":" + String(longitude, 6);
json += "}";
Serial.println("Publishing to MQTT:");
Serial.println(json);
client.publish(mqtt_topic, json.c_str());
client.loop();
} else {
Serial.print("HTTP request failed, code: ");
Serial.println(httpCode);
}
http.end();
}