Community project

Generate A Clean High-resolution Technical Engin

Yashas, G

Published August 23, 2026

ESP32
Photo of Generate A Clean High-resolution Technical EnginGenerated with AI

This project builds a wearable gas detection and environmental monitoring system using an ESP32 microcontroller. It combines temperature and humidity sensing with gas detection to create a personal safety device that alerts the wearer to hazardous conditions through both visual and audio feedback.

The guide provides a complete wiring diagram, parts list, and step-by-step assembly instructions for integrating the 16x2 LCD display, DHT11 climate sensor, MQ-2 gas sensor, piezo buzzer alarm, push button, and HC-05 Bluetooth module. The included firmware handles sensor reading, alarm triggering, display management, and wireless communication, allowing real-time monitoring and remote data access from a paired mobile device.

Wiring diagram

Interactive · read-only
Wiring diagram for Generate A Clean High-resolution Technical Engin

Pan and zoom to explore the wiring. Remix the project to edit it in your own workspace.

Parts list

Bill of materials
ComponentQtyNotes
16x2 I2C LCD, 3.3 V compatible16x2 I2C, 3.3 V1A two-line, sixteen-character display module that shows the vest sensor readings.
DHT11DHT111Digital temperature and humidity sensor (lower accuracy than DHT22)
Piezo Buzzer3.3 V piezo1Passive piezo buzzer element driven by a 3–30 V peak-to-peak square wave; loudest around 4 kHz, usable from 2–10 kHz. Differential drive (swapping which pin is high/low each half-cycle) doubles the volume.
Hc 05 Bluetooth ModuleHC-051Serial Bluetooth module for wireless communication using UART interface. Operates at 9600 baud (Data Mode) or 38400 baud (AT Command Mode). Supports two-way full-duplex wireless functionality with range up to 100m.
MQ-2 Gas SensorMQ-2 module1Analog combustible-gas and smoke sensor module. Detects LPG, propane, methane, hydrogen, alcohol, and smoke using a heated tin-dioxide (SnO2) sensing element whose resistance falls as gas concentration rises. The breakout board provides an analog output (AO) proportional to concentration plus a digital output (DO) that trips when concentration crosses an onboard potentiometer threshold. Requires a 5 V supply for the internal heater and a 20-30 s warm-up before readings stabilise; the AO voltage is relative, so the sensor needs a clean-air baseline calibration rather than reporting an absolute ppm value.
Push ButtonMomentary1Momentary push button switch
10 kΩ Resistor10 kΩ1The upper resistor in the MQ-2 output divider that lowers the sensor voltage before it reaches A0.
10 kΩ Resistor10 kΩ1The lower resistor in the MQ-2 output divider that keeps the ESP8266 analog input safely below its limit.

Assembly

5 steps
  1. Place the controller and make power rails

    Place the NodeMCU ESP8266 in the middle of the breadboard. Run one red wire from its 3V3 pin to a positive rail and one black wire from GND to a ground rail. Run a second red wire from VIN (5 V while USB powered) to a separate 5 V rail; do not join the 5 V and 3.3 V rails.

    • Tip: Keeping 3.3 V and 5 V on different breadboard rails prevents accidental damage to the ESP8266 inputs.
    • Do not connect the 5 V rail to any NodeMCU signal pin — ESP8266 pins can be damaged by 5 V.
  2. Wire the LCD and climate sensor

    Connect lcd_16x2 VCC to 3V3 (power), lcd_16x2 GND to GND (ground), lcd_16x2 SDA to NodeMCU D2 / GPIO4 (data), and lcd_16x2 SCL to NodeMCU D1 / GPIO5 (clock). Connect dht11_1 VCC to 3V3 (power), dht11_1 GND to GND (ground), and dht11_1 DATA to D3 / GPIO0 (signal).

    • Tip: If the DHT11 is a bare four-pin sensor rather than a small three-pin module, add a 10 kΩ pull-up resistor from DATA to 3V3.
    • Tip: The display may use address 0x27; if it stays blank after deployment, its board may instead use 0x3F.
    • Make sure VCC and GND are not swapped on either module — swapped power can damage the parts.
  3. Wire the alarm, button, and Bluetooth module

    Connect piezo_1 Lead 1 to D5 / GPIO14 (alarm signal) and Lead 2 to GND (ground). Connect button_1 SIGNAL to D0 / GPIO16 (signal) and button_1 GND to GND (ground). Connect hc05_1 Vcc to VIN / 5 V (power), hc05_1 GND to GND (ground), hc05_1 TX to D6 / GPIO12 (Bluetooth data into the board), and hc05_1 RX to D7 / GPIO13 (Bluetooth data out of the board).

    • Tip: The button uses the board's built-in pull-up, so it should read as a press only when it connects D0 to ground.
    • Tip: Follow the labels printed on the HC-05 breakout board; TX and RX cross between the module and controller.
    • Do not use an unregulated battery or supply on the HC-05 Vcc pin; use the board's USB-powered 5 V rail for this version.
  4. Add the protected gas-sensor connection

    Connect mq2_1 VCC to VIN / 5 V (heater power) and mq2_1 GND to GND (ground). Connect mq2_1 AO to one end of r_mq2_top. Join the other end of r_mq2_top to one end of r_mq2_bottom and to NodeMCU A0 (gas-level signal). Connect the remaining end of r_mq2_bottom to GND (ground). Use the two 10 kΩ resistors exactly as this divider.

    • Tip: The joined resistor ends and A0 are one shared row on a breadboard.
    • Tip: Let the MQ-2 warm up for several minutes before treating its reading as meaningful.
    • Never connect MQ-2 AO straight to A0 — its 5 V output can damage the ESP8266 analog input.
  5. Fit the electronics into the vest

    After checking every wire, mount the board and modules inside a non-conductive pouch on the vest. Keep the MQ-2 sensor exposed to air and away from fabric, and route wires so they cannot pull loose when the wearer moves. Power the NodeMCU from USB for this design.

    • Tip: Use strain relief such as tape or small cable ties near each module so a tug does not bend its pins.
    • Tip: Place the buzzer opening and LCD where they can be heard and read.
    • The MQ-2 heater gets warm during use; keep it away from skin, loose fabric, and anything flammable.

Pin assignments

Board wiring reference
PinConnectionType
3V3lcd_16x2 VCCpower
GNDlcd_16x2 GNDground
GPIO 4lcd_16x2 SDAi2c
GPIO 5lcd_16x2 SCLi2c
3V3dht11_1 VCCpower
GNDdht11_1 GNDground
GPIO 0dht11_1 DATAdata
GPIO 14piezo_1 Lead 1digital
GNDpiezo_1 Lead 2ground
VINhc05_1 Vccpower
GNDhc05_1 GNDground
GPIO 12hc05_1 TXdata
GPIO 13hc05_1 RXdata
VINmq2_1 VCCpower
GNDmq2_1 GNDground
EXTmq2_1 AO10 kΩ Resistor End 1analog
GPIO 17r_mq2_top End 2analog
GNDr_mq2_bottom End 2ground
GNDbutton_1 GNDground
GPIO 16button_1 SIGNALdigital
EXTr_mq2_bottom End 110 kΩ Resistor End 2analog

Firmware

ESP32
main.cppDeploy to device
#include <HardwareSerial.h>
#include <Arduino.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <DHT.h>

// Forward declarations
String fit16(String text);
void showStatus(const String &line1, const String &line2);
bool readAcknowledgePress();

constexpr uint8_t LCD_SDA_PIN = 4;   // NodeMCU D2
constexpr uint8_t LCD_SCL_PIN = 5;   // NodeMCU D1
constexpr uint8_t DHT_PIN = 0;       // NodeMCU D3
constexpr uint8_t BUZZER_PIN = 14;   // NodeMCU D5
constexpr uint8_t BT_RX_PIN = 12;    // NodeMCU D6, receives HC-05 TX
constexpr uint8_t BT_TX_PIN = 13;    // NodeMCU D7, sends HC-05 RX
constexpr uint8_t MQ2_PIN = A0;
constexpr uint8_t BUTTON_PIN = 16;   // NodeMCU D0

constexpr int GAS_ALARM_LEVEL = 650;
constexpr unsigned long SAMPLE_INTERVAL_MS = 2000;
constexpr unsigned long DEBOUNCE_MS = 40;

LiquidCrystal_I2C lcd(0x27, 16, 2);
DHT dht(DHT_PIN, DHT11);
HardwareSerial bluetooth(2);

bool alarmAcknowledged = false;
bool previousButtonReading = HIGH;
bool stableButtonState = HIGH;
unsigned long lastButtonChangeMs = 0;
unsigned long lastSampleMs = 0;
String lastLine1;
String lastLine2;

String fit16(String text) {
  if (text.length() > 16) return text.substring(0, 16);
  while (text.length() < 16) text += ' ';
  return text;
}

void showStatus(const String &line1, const String &line2) {
  if (line1 != lastLine1) {
    lcd.setCursor(0, 0);
    lcd.print(fit16(line1));
    lastLine1 = line1;
  }
  if (line2 != lastLine2) {
    lcd.setCursor(0, 1);
    lcd.print(fit16(line2));
    lastLine2 = line2;
  }
}

bool readAcknowledgePress() {
  bool reading = digitalRead(BUTTON_PIN);
  if (reading != previousButtonReading) lastButtonChangeMs = millis();

  if ((millis() - lastButtonChangeMs) > DEBOUNCE_MS && reading != stableButtonState) {
    stableButtonState = reading;
    if (stableButtonState == LOW) {
      previousButtonReading = reading;
      return true;
    }
  }
  previousButtonReading = reading;
  return false;
}

void setup() {
  pinMode(BUZZER_PIN, OUTPUT);
  pinMode(BUTTON_PIN, INPUT_PULLUP);
  digitalWrite(BUZZER_PIN, LOW);

  Wire.begin(LCD_SDA_PIN, LCD_SCL_PIN);
  lcd.init();
  lcd.backlight();
  dht.begin();
  bluetooth.begin(9600, SERIAL_8N1, BT_RX_PIN, BT_TX_PIN);

  showStatus("Safety Vest", "Starting sensor");
  delay(1200);
}

void loop() {
  if (readAcknowledgePress()) {
    alarmAcknowledged = true;
  }

  if (millis() - lastSampleMs < SAMPLE_INTERVAL_MS) return;
  lastSampleMs = millis();

  float humidity = dht.readHumidity();
  float temperatureC = dht.readTemperature();
  int gasRaw = analogRead(MQ2_PIN);
  bool gasAlarm = gasRaw >= GAS_ALARM_LEVEL;
  bool dhtValid = !isnan(humidity) && !isnan(temperatureC);

  if (!gasAlarm) alarmAcknowledged = false;
  bool soundAlarm = gasAlarm && !alarmAcknowledged;
  digitalWrite(BUZZER_PIN, soundAlarm ? HIGH : LOW);

  String line1;
  if (dhtValid) {
    line1 = "T:" + String(temperatureC, 1) + "C H:" + String((int)humidity) + "%";
  } else {
    line1 = "DHT11 check";
  }

  String line2 = "Gas:" + String(gasRaw);
  if (gasAlarm) line2 += alarmAcknowledged ? " ACK" : " ALERT";
  showStatus(line1, line2);

  bluetooth.print("TEMP=");
  if (dhtValid) bluetooth.print(temperatureC, 1); else bluetooth.print("NA");
  bluetooth.print(",HUM=");
  if (dhtValid) bluetooth.print(humidity, 0); else bluetooth.print("NA");
  bluetooth.print(",MQ2=");
  bluetooth.print(gasRaw);
  bluetooth.print(",ALARM=");
  bluetooth.println(gasAlarm ? "1" : "0");
}

“Deploy to device” opens this project in Schematik, where you can flash it to your board over USB.

Remix this project

Make it yours in one click

Open a full copy of this project in your own Schematik workspace — diagram, code, parts, and assembly steps included. Swap the sensor, add features, or redesign the whole thing with AI. The author's original stays untouched.

Open in Schematik