Smoke and Gas Alarm
Intermediate35 minAn alarm that goes off when smoke or a flammable gas (LPG, natural gas, methane) shows up in the kitchen or a room: the MQ-2 sensor's analog output is read, the clean air value is measured at start-up, and once the reading rises well above it the buzzer plays the three-beep pattern (T3) that real smoke alarms use while the red LED flashes with the beeps. The green LED blinks while warming up and stays on once the alarm is armed. It teaches reading an analog sensor against its own clean air value, using two separate thresholds so the alarm does not flicker at the edge, and playing a sound pattern with millis() while still taking readings. No extra library needed. This is a learning project; it does not replace a certified smoke and gas alarm at home.
Build it step by step in the appWhat you need
1 × Arduino Uno R3
1 × Breadboard 830 Points (MB-102)
1 × MQ-2 Flammable Gas and Smoke Sensor
1 × Passive Buzzer (Piezo)
1 × LED - Green (5mm)
1 × LED - Red (5mm)
2 × Resistor 220 Ω (1/4W)
6 × Jumper Wire - Male/Male
3 × Jumper Wire - Male/Female
Wiring steps
- 1
Connect the power rails (5V and GND)

In this project every part sits in the bottom half of the breadboard (rows A–E) and on the bottom power rails. Plug a black male-male jumper wire into one of the GND pins on the Arduino's power header and connect its other end to the breadboard's bottom blue (−) rail. Plug a red wire into the 5V pin on the same header and connect its other end to the bottom red (+) rail. The MQ-2 sensor is powered from these two rails, and the buzzer and the LED resistors take their ground from the (−) rail. The top rails are not connected to the bottom ones, so leave them unused.
- Arduino 5V → the bottom red (+) rail (red wire)
- Arduino GND → the bottom blue (−) rail (black wire)
- 2
Add and wire the buzzer

Plug the passive buzzer's + leg into column 11 in the bottom half of the breadboard and its other leg into column 10; the + leg is usually the longer one and the body has a + mark. Connect the Arduino's pin 8 to column 11 with an orange jumper wire (BUZZER_PIN 8). Connect column 10 to the bottom (−) rail with a short black wire.
- buzzer − leg → column 10, bottom half
- buzzer + leg → column 11, bottom half
- Arduino pin 8 → column 11, bottom half (orange wire)
- column 10, bottom half → the bottom blue (−) rail (black wire)
- 3
Add the green and red LEDs with their resistors

Plug the green LED's long leg (+) into column 19 in the bottom half and its short leg (−) into column 18. Put one end of a 220 Ω resistor in column 18 and the other end in the bottom (−) rail. Connect the Arduino's pin 11 to column 19 with a green jumper wire (GREEN_LED 11). Plug in the red LED the same way: long leg in column 23, short leg in column 22, and the second 220 Ω resistor from column 22 to the (−) rail. Connect the Arduino's pin 12 to column 23 with a blue wire (RED_LED 12). The resistors limit the current through the LEDs.
- green LED long leg (+) → column 19, bottom half
- green LED short leg (−) → column 18, bottom half
- red LED long leg (+) → column 23, bottom half
- red LED short leg (−) → column 22, bottom half
- green LED's resistor (leg 1) → column 18, bottom half
- green LED's resistor (leg 2) → the bottom blue (−) rail
- red LED's resistor (leg 1) → column 22, bottom half
- red LED's resistor (leg 2) → the bottom blue (−) rail
- Arduino pin 11 → column 19, bottom half (green wire)
- Arduino pin 12 → column 23, bottom half (blue wire)
- 4
Connect the MQ-2 sensor

Push the female ends of male-female jumper wires onto the MQ-2 board's pins; the pin names are printed on the board. Connect VCC to the bottom (+) rail with a red wire, GND to the bottom (−) rail with a black wire, and AO (analog output) straight to the Arduino's A0 pin with a yellow wire (GAS_PIN A0). The DO pin stays empty: it only gives on/off against the threshold set by the small screw on the board, and here the code sets the threshold. The sensor has a heater inside that draws about 150 mA and gets warm while it runs: that is normal, do not touch the metal mesh. A new sensor may smell slightly burnt for its first few runs.
- MQ-2 VCC → the bottom red (+) rail (red wire)
- MQ-2 GND → the bottom blue (−) rail (black wire)
- Arduino A0 → MQ-2 AO (yellow wire)
Arduino sketch
// The MQ-2's analog output (AO)
const int GAS_PIN = A0;
// Buzzer and the two LEDs' pins
const int BUZZER_PIN = 8;
const int GREEN_LED = 11;
const int RED_LED = 12;
// Heater warm-up time (ms)
const unsigned long WARM_UP = 30000;
// The alarm sounds once the reading rises
// this far over clean air (0-1023)
const int ALARM_RISE = 150;
// It stops once back down to this
const int CLEAR_RISE = 100;
// Time between readings (ms)
const unsigned long MEASURE_EVERY = 1000;
// Siren pitch (Hz)
const int ALARM_HZ = 3000;
int baseline = 0;
bool alarmOn = false;
bool beeping = false;
unsigned long alarmStart = 0;
unsigned long lastMeasure = 0;
void setup() {
pinMode(BUZZER_PIN, OUTPUT);
pinMode(GREEN_LED, OUTPUT);
pinMode(RED_LED, OUTPUT);
Serial.begin(9600);
// Green LED blinks while warming up
Serial.println("Sensor warming up, wait 30 s...");
unsigned long start = millis();
while (millis() - start < WARM_UP) {
digitalWrite(GREEN_LED, (millis() / 500) % 2 ? HIGH : LOW);
}
// Clean air value: mean of 10 readings
long total = 0;
for (int i = 0; i < 10; i++) {
total += analogRead(GAS_PIN);
delay(200);
}
baseline = total / 10;
Serial.print("Clean air value: ");
Serial.println(baseline);
// Close to 0: the sensor has no power
if (baseline < 10) {
Serial.println("Cannot read the sensor, check the wires.");
digitalWrite(GREEN_LED, LOW);
while (true) {}
}
digitalWrite(GREEN_LED, HIGH);
Serial.println("Alarm armed.");
}
// Smoke alarm pattern (T3): three half-
// second beeps, then 1.5 s of quiet
void updateAlarm() {
bool beep = false;
if (alarmOn) {
// Where we are in the 4 s cycle
unsigned long t = (millis() - alarmStart) % 4000;
beep = t < 2500 && (t / 500) % 2 == 0;
}
// tone() only when the sound changes
if (beep != beeping) {
beeping = beep;
if (beep) {
tone(BUZZER_PIN, ALARM_HZ);
} else {
noTone(BUZZER_PIN);
}
}
digitalWrite(RED_LED, beep ? HIGH : LOW);
digitalWrite(GREEN_LED, alarmOn ? LOW : HIGH);
}
void loop() {
if (millis() - lastMeasure >= MEASURE_EVERY) {
lastMeasure = millis();
int gas = analogRead(GAS_PIN);
int rise = gas - baseline;
Serial.print("Gas: ");
Serial.print(gas);
Serial.print(" | Rise: ");
Serial.println(rise);
// Two thresholds: no flicker at edge
if (!alarmOn && rise >= ALARM_RISE) {
alarmOn = true;
alarmStart = millis();
Serial.println("ALARM! Smoke or gas detected.");
} else if (alarmOn && rise <= CLEAR_RISE) {
alarmOn = false;
Serial.println("Air is clear, alarm stopped.");
}
}
updateAlarm();
}
What the Serial Monitor shows
Sensor warming up, wait 30 s... Clean air value: 181 Alarm armed. Gas: 183 | Rise: 2 Gas: 180 | Rise: -1 Gas: 251 | Rise: 70 Gas: 393 | Rise: 212 ALARM! Smoke or gas detected. Gas: 534 | Rise: 353 Gas: 355 | Rise: 174 Gas: 269 | Rise: 88 Air is clear, alarm stopped. Gas: 223 | Rise: 42
If a wire is loose
Clean air value: 0 Cannot read the sensor, check the wires.
What you will see
At start-up the green LED blinks for 30 seconds: the sensor's heater warms up meanwhile, and the sensor should be in clean air. Then the Serial Monitor prints the clean air value, the green LED stays on, and every second the reading and its rise over clean air are printed. To try it, blow out a match or an incense stick and bring the smoke close to the sensor; or hold a lighter near the sensor without lighting it, just pressing the gas button for 1-2 seconds. Once the rise passes 150, the buzzer sounds three short beeps and then a short pause, the red LED flashes with the beeps and the green LED goes off. Air out the area around the sensor and the rise drops under 100 and the alarm stops. If it says "Cannot read the sensor", check the MQ-2's VCC and GND wires. If the alarm never sounds, check that the yellow wire is on A0, or lower ALARM_RISE in the code. If the alarm sounds by itself, the sensor was not in clean air at start-up or has not warmed up enough yet: leave a new sensor on for a few minutes the first time, then press the Arduino's reset button. Safety: never bring an open flame near the gas while testing; this project does not replace a certified smoke and gas alarm at home.
In the app, tick off every wire, match the parts to your inventory and pick up where you left off.
Build it step by step in the app