Arduino Nano Gas Sensor: Industrial Air Quality System
Perfect gas sensor wiring confirmed! **A0=Analog Out, 5V VCC, GND**. Professional MQ-2/MQ-5/MQ-135 detection (LPG, Smoke, CO, H2, Alcohol, Propane, Methane) with PPM calculation, 3-stage alarms (Warning→Danger→CRITICAL), buzzer D8, status LED D13, auto-calibration.
**Breathe/expose to alcohol → Serial shows PPM rising + escalating alarms**! 30s baseline calibration.
Production Gas Detection Components
- Arduino Nano
- Gas Sensor Module (MQ-2/MQ-5/MQ-135)
- Active Buzzer (D8)
- Status LED + 220Ω (D13)
- 10kΩ load resistor (optional)
- Jumper wires
Standard Gas Sensor Wiring
VCC → 5V (heater power)
GND → GND
A0 → A0 (analog concentration)
// Arduino Nano GAS SENSOR - INDUSTRIAL AIR QUALITY MONITOR
// A0=Analog | PPM calc + 3-stage alarms + buzzer + LED
const int gasPin = A0;
const int buzzerPin = 8;
const int ledPin = 13;
float baseline = 0;
float cleanAir = 0;
void setup() {
Serial.begin(9600);
pinMode(buzzerPin, OUTPUT);
pinMode(ledPin, OUTPUT);
Serial.println("=== GAS SENSOR PROFESSIONAL MONITOR ===");
Serial.println("Raw PPM | Status | Alarm");
// 30s baseline calibration (clean air)
calibrateBaseline();
}
void loop() {
int raw = analogRead(gasPin);
float ppm = calculatePPM(raw);
String status = getGasStatus(ppm);
triggerAlarm(ppm);
// Live monitoring
Serial.printf("%4d %6.1f | %-8s | %s\n", raw, ppm, status.c_str(), getAlarmLevel(ppm));
delay(500);
}
void calibrateBaseline() {
Serial.println("CALIBRATING BASELINE (30s clean air)...");
long sum = 0;
for(int i=0; i<60; i++) {
sum += analogRead(gasPin);
delay(500);
}
cleanAir = sum / 60.0;
Serial.printf("Clean air baseline: %.1f\n", cleanAir);
}
float calculatePPM(int raw) {
// Non-linear MQ curve approximation
float ratio = (float)raw / cleanAir;
if(ratio < 1.0) return 0;
// Rs/R0 vs PPM logarithmic curve
float ppm = pow(10, (log10(ratio) - 0.3) / -0.85) * 10;
return constrain(ppm, 0, 10000);
}
String getGasStatus(float ppm) {
if(ppm < 100) return "CLEAN";
if(ppm < 500) return "NORMAL";
if(ppm < 2000) return "WARNING";
if(ppm < 5000) return "DANGER";
return "CRITICAL";
}
String getAlarmLevel(float ppm) {
if(ppm < 1000) return "OFF";
if(ppm < 3000) return "LOW";
if(ppm < 7000) return "MEDIUM";
return "HIGH";
}
void triggerAlarm(float ppm) {
if(ppm > 1000) {
digitalWrite(ledPin, HIGH);
if(ppm > 3000) {
warningAlarm();
if(ppm > 7000) criticalAlarm();
}
} else {
digitalWrite(ledPin, LOW);
noTone(buzzerPin);
}
}
void warningAlarm() {
tone(buzzerPin, 1000, 300);
Serial.println("*** WARNING: Elevated gas levels ***");
}
void criticalAlarm() {
for(int i=0; i<3; i++) {
tone(buzzerPin, 2000, 500);
delay(600);
}
Serial.println("*** CRITICAL: GAS LEAK! EVACUATE! ***");
}
UPLOAD → 30s CALIBRATION + LIVE PPM
**Breathe on sensor → PPM rises + Warning → Danger → Critical alarms**!
MQ-2/MQ-5/MQ-135 Gas Detection
- MQ-2: Smoke, LPG, Propane, H2, Methane, Alcohol
- MQ-5: LPG, Natural Gas (Methane), Town Gas
- MQ-135: CO2, Ammonia, Benzene, Alcohol, Smoke
- **A0 0-1023:** Clean air → Dangerous levels
- **Preheat 48hrs:** First use burn-in required
PPM Calculation
\[ \text{PPM} = 10^{(log_{10}(R_s/R_0) - b)/m} \]
Multi-Gas Array
// Monitor <b>MQ-2</b>, <b>MQ-5</b>, <b>MQ-135</b>, <b>MQ-7</b>
const int gasPins[] = {A0,A1,A2,A3};
for(int i=0; i<4; i++) {
float ppm = calculatePPM(analogRead(gasPins[i]));
Serial.printf("Gas%d: %.0f PPM\n", i, ppm);
}
Auto-Valve Control
// Add to criticalAlarm()
digitalWrite(7, LOW); // Close gas valve
Serial.println("*** GAS SUPPLY CUT ***");
Calibration & Burn-In
- **48hr preheat** → First use required
- **Clean air 30s** → Auto-baseline on startup
- **Recalibrate weekly** → Sensor drift compensation
- **Avoid silicone/solvents** → Poison sensor
Troubleshooting
- Always 0 PPM: A0 wiring + 48hr burn-in
- Always HIGH: Sensor poisoned
- False alarms: Ventilation + recalibrate
- Erratic: 10µF cap VCC-GND