/***** ESP32-S3 + DHT22 (GPIO4) + MQ2 + POT + DS18B20 + MPU6050 + OLED + Firebase *****
*
* Notes:
* - DHT_PIN is set to 4 (GPIO4) — wire DHT pin1->3.3V, pin2->GPIO4, pin4->GND
* - Add 4.7k-10k pull-up resistor between DHT DATA (pin2) and 3.3V if module doesn't include it
* - FIREBASE_AUTH left empty for test mode (use secure auth/token in production)
* - Do not publish secrets
*/
#include <WiFi.h>
#include <WiFiClientSecure.h>
#include <HTTPClient.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include "DHTesp.h"
#include <OneWire.h>
#include <DallasTemperature.h>
#include <MPU6050.h>
// ---------------- WIFI DETAILS ----------------
const char* WIFI_SSID = "Wokwi-GUEST";
const char* WIFI_PASSWORD = "";
// ------------- FIREBASE REALTIME DB ------------
// NOTE: no trailing slash in host
const char* FIREBASE_HOST = "fir-aurasense-default-rtdb.firebaseio.com";
const char* FIREBASE_AUTH = ""; // empty for test mode
const char* FIREBASE_PATH = "/multiSensorHub.json";
// ----------------- PIN CONFIG ------------------
// Verify ADC-capable pins on your board
#define DHT_PIN 4 // DHT22 data on GPIO4 (changed from 15)
#define MQ2_PIN 2 // MQ2 analog out
#define POT_PIN 1 // potentiometer analog (verify ADC-capable)
#define DS18B20_PIN 14 // one-wire
#define I2C_SDA_PIN 11 // OLED + MPU6050
#define I2C_SCL_PIN 12
// ----------- OBJECTS ---------------------------
// DHT22
DHTesp dht;
// DS18B20
OneWire oneWire(DS18B20_PIN);
DallasTemperature ds18b20(&oneWire);
// MPU6050
MPU6050 mpu;
// OLED
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
// ----------------- HELPERS ---------------------
bool isValidFloat(float v) {
return (!isnan(v)) && isfinite(v);
}
String jsonNumberOrNull(float v, int digits = 2) {
if (!isValidFloat(v)) return "null";
return String(v, digits);
}
// Single reusable secure client for HTTPS
WiFiClientSecure secureClient;
void connectWiFi() {
Serial.print("Connecting to WiFi");
WiFi.mode(WIFI_STA);
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
unsigned long start = millis();
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
if (millis() - start > 60000) {
Serial.println("\nWiFi connect timeout, restarting...");
ESP.restart();
}
}
Serial.println("\nWiFi connected!");
Serial.print("IP: ");
Serial.println(WiFi.localIP());
}
// send to firebase and print server response on non-2xx
bool sendToFirebase(const String &json) {
HTTPClient https;
String url = "https://" + String(FIREBASE_HOST) + String(FIREBASE_PATH) +
"?auth=" + String(FIREBASE_AUTH);
Serial.println();
Serial.print("Firebase URL: ");
Serial.println(url);
Serial.print("Payload: ");
Serial.println(json);
if (!https.begin(secureClient, url)) {
Serial.println("HTTPS begin failed");
return false;
}
https.addHeader("Content-Type", "application/json");
int httpCode = https.PUT(json);
if (httpCode > 0) {
Serial.print("HTTP code: ");
Serial.println(httpCode);
String payload = https.getString();
if (httpCode >= 200 && httpCode < 300) {
https.end();
return true;
} else {
Serial.print("Server response: ");
Serial.println(payload);
}
} else {
Serial.print("Firebase HTTP error: ");
Serial.println(https.errorToString(httpCode));
}
https.end();
return false;
}
// OLED helper (uses snprintf)
void showOnOLED(float t_dht, float h_dht,
float mq2, float pot,
float t_ds,
float ax_g, float ay_g, float az_g,
float gx_dps, float gy_dps, float gz_dps) {
char buf[80];
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.println("Multi Sensor Hub");
display.setCursor(0, 12);
if (isValidFloat(t_dht) && isValidFloat(h_dht)) {
snprintf(buf, sizeof(buf), "DHT: %.1fC %.1f%%", t_dht, h_dht);
} else {
snprintf(buf, sizeof(buf), "DHT: ---");
}
display.println(buf);
display.setCursor(0, 24);
snprintf(buf, sizeof(buf), "MQ2:%4.0f POT:%4.0f", mq2, pot);
display.println(buf);
display.setCursor(0, 36);
if (isValidFloat(t_ds)) {
snprintf(buf, sizeof(buf), "DS18: %.1fC", t_ds);
} else {
snprintf(buf, sizeof(buf), "DS18: ---");
}
display.println(buf);
display.setCursor(0, 48);
snprintf(buf, sizeof(buf), "Ax:%.2fg Gx:%.1f", ax_g, gx_dps);
display.println(buf);
display.display();
}
// Try to read DHT with a few retries (returns TempAndHumidity)
TempAndHumidity readDHTWithRetries(int attempts = 3, unsigned long waitMs = 1000) {
TempAndHumidity th;
for (int i = 0; i < attempts; ++i) {
th = dht.getTempAndHumidity();
if (isValidFloat(th.temperature) && isValidFloat(th.humidity)) {
return th;
}
delay(waitMs);
}
return th; // probably invalid
}
void setup() {
Serial.begin(115200);
delay(100);
// I2C
Wire.begin(I2C_SDA_PIN, I2C_SCL_PIN);
// DHT
dht.setup(DHT_PIN, DHTesp::DHT22);
// DS18B20
ds18b20.begin();
// MPU6050
Serial.println("Init MPU6050...");
mpu.initialize();
if (mpu.testConnection()) {
Serial.println("MPU6050 OK");
} else {
Serial.println("MPU6050 FAIL");
}
// OLED
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println("SSD1306 allocation failed");
for (;;);
}
display.clearDisplay();
display.display();
// WiFi
connectWiFi();
// Use insecure client for development (bypass cert verification).
// For production use setCACert() with root CA instead.
secureClient.setInsecure();
Serial.println("Setup complete.");
uint8_t devcount = ds18b20.getDeviceCount();
Serial.printf("DS18 devices found: %d\n", devcount);
if (devcount == 0) {
Serial.println("Warning: No DS18 devices found on OneWire bus.");
}
}
void loop() {
// DHT read with retries
TempAndHumidity dhtData = readDHTWithRetries(3, 1000);
float t_dht = dhtData.temperature;
float h_dht = dhtData.humidity;
if (!isValidFloat(t_dht) || !isValidFloat(h_dht)) {
Serial.println("Warning: DHT read invalid (NaN) — will send null for those values");
}
// MQ2 & POT
float mq2Val = analogRead(MQ2_PIN);
float potVal = analogRead(POT_PIN);
// DS18B20
float t_ds = NAN;
if (ds18b20.getDeviceCount() > 0) {
ds18b20.requestTemperatures();
t_ds = ds18b20.getTempCByIndex(0);
if (t_ds == DEVICE_DISCONNECTED_C || !isValidFloat(t_ds)) {
Serial.println("DS18B20: read failed / disconnected (sending null)");
t_ds = NAN;
}
}
// MPU6050 raw
int16_t ax_raw, ay_raw, az_raw, gx_raw, gy_raw, gz_raw;
mpu.getMotion6(&ax_raw, &ay_raw, &az_raw, &gx_raw, &gy_raw, &gz_raw);
// scale to human units
float ax_g = ax_raw / 16384.0f;
float ay_g = ay_raw / 16384.0f;
float az_g = az_raw / 16384.0f;
float gx_dps = gx_raw / 131.0f;
float gy_dps = gy_raw / 131.0f;
float gz_dps = gz_raw / 131.0f;
// Serial debug
Serial.printf("DHT: %s %s | MQ2: %.0f | POT: %.0f | DS: %s\n",
isValidFloat(t_dht) ? String(t_dht,1).c_str() : "nan",
isValidFloat(h_dht) ? String(h_dht,1).c_str() : "nan",
mq2Val, potVal,
isValidFloat(t_ds) ? String(t_ds,1).c_str() : "nan");
Serial.printf("MPU6050 raw Acc: %d,%d,%d Gyro: %d,%d,%d\n",
ax_raw, ay_raw, az_raw, gx_raw, gy_raw, gz_raw);
Serial.printf("MPU6050 scaled Acc(g): %.3f,%.3f,%.3f Gyro(dps): %.2f,%.2f,%.2f\n",
ax_g, ay_g, az_g, gx_dps, gy_dps, gz_dps);
// Create JSON payload (send null for bad floats)
String json = "{";
json += "\"dht\":{";
json += "\"temperature\":" + jsonNumberOrNull(t_dht, 2) + ",";
json += "\"humidity\":" + jsonNumberOrNull(h_dht, 2) + "},";
json += "\"mq2\":" + jsonNumberOrNull(mq2Val, 0) + ",";
json += "\"pot\":" + jsonNumberOrNull(potVal, 0) + ",";
json += "\"ds18b20_temp\":" + jsonNumberOrNull(t_ds, 2) + ",";
json += "\"mpu6050\":{";
json += "\"ax_g\":" + jsonNumberOrNull(ax_g, 3) + ",";
json += "\"ay_g\":" + jsonNumberOrNull(ay_g, 3) + ",";
json += "\"az_g\":" + jsonNumberOrNull(az_g, 3) + ",";
json += "\"gx_dps\":" + jsonNumberOrNull(gx_dps, 2) + ",";
json += "\"gy_dps\":" + jsonNumberOrNull(gy_dps, 2) + ",";
json += "\"gz_dps\":" + jsonNumberOrNull(gz_dps, 2) + "}";
json += "}";
// send to Firebase
if (WiFi.status() != WL_CONNECTED) {
connectWiFi();
}
bool ok = sendToFirebase(json);
// show on OLED
showOnOLED(t_dht, h_dht, mq2Val, potVal, t_ds, ax_g, ay_g, az_g, gx_dps, gy_dps, gz_dps);
if (ok) Serial.println("Firebase update OK");
else Serial.println("Firebase update FAILED");
delay(5000);
}
Loading
ds18b20
ds18b20