Community project
Generate A Clean High-resolution Technical Engin
Generated with AIThis 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
Pan and zoom to explore the wiring. Remix the project to edit it in your own workspace.
Parts list
Bill of materials| Component | Qty | Notes |
|---|---|---|
| 16x2 I2C LCD, 3.3 V compatible16x2 I2C, 3.3 V | 1 | A two-line, sixteen-character display module that shows the vest sensor readings. |
| DHT11DHT11 | 1 | Digital temperature and humidity sensor (lower accuracy than DHT22) |
| Piezo Buzzer3.3 V piezo | 1 | Passive 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-05 | 1 | Serial 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 module | 1 | Analog 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 ButtonMomentary | 1 | Momentary push button switch |
| 10 kΩ Resistor10 kΩ | 1 | The upper resistor in the MQ-2 output divider that lowers the sensor voltage before it reaches A0. |
| 10 kΩ Resistor10 kΩ | 1 | The lower resistor in the MQ-2 output divider that keeps the ESP8266 analog input safely below its limit. |
Assembly
5 stepsPlace 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.
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.
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.
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.
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| Pin | Connection | Type |
|---|---|---|
| 3V3 | lcd_16x2 VCC | power |
| GND | lcd_16x2 GND | ground |
| GPIO 4 | lcd_16x2 SDA | i2c |
| GPIO 5 | lcd_16x2 SCL | i2c |
| 3V3 | dht11_1 VCC | power |
| GND | dht11_1 GND | ground |
| GPIO 0 | dht11_1 DATA | data |
| GPIO 14 | piezo_1 Lead 1 | digital |
| GND | piezo_1 Lead 2 | ground |
| VIN | hc05_1 Vcc | power |
| GND | hc05_1 GND | ground |
| GPIO 12 | hc05_1 TX | data |
| GPIO 13 | hc05_1 RX | data |
| VIN | mq2_1 VCC | power |
| GND | mq2_1 GND | ground |
| EXT | mq2_1 AO → 10 kΩ Resistor End 1 | analog |
| GPIO 17 | r_mq2_top End 2 | analog |
| GND | r_mq2_bottom End 2 | ground |
| GND | button_1 GND | ground |
| GPIO 16 | button_1 SIGNAL | digital |
| EXT | r_mq2_bottom End 1 → 10 kΩ Resistor End 2 | analog |
Firmware
ESP32#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.