Внутри MQ-2 нагреваемый слой оксида металла: газ меняет его сопротивление, плата превращает это в напряжение на AO. Чувствителен он сразу ко многим веществам — сжиженный газ, метан, водород, дым, спирты, — и отличить их друг от друга не может.
Датчику нужен прогрев, а для перевода в ppm — калибровка по кривым из даташита. Для сигнализации достаточно порога: включить при высоком уровне, выключить при заметно более низком. Цифровой выход DO на модуле с компаратором низкий, когда газа больше порога.
Выводы
Вывод
Назначение
AO
аналоговый выход: выше напряжение — больше газа
DO
цифровой выход компаратора, низкий при превышении порога
// Сигнализация утечки газа на MQ-2.
//
// Датчик греет внутренний нагреватель, и первые минуты его показания
// плавают. Здесь прогрев сокращён до пяти секунд, чтобы было видно
// работу; на настоящем датчике ждут минимум пару минут.
//
// Порогов два: включаем при высоком, выключаем только при заметно более
// низком. Иначе у границы сигнал будет дребезжать от шума АЦП.
//
// Внимание: у модуля на 5 В выход AO доходит до 5 В, а вход ESP32
// терпит 3,3 В. На настоящей плате AO ставят через делитель (например,
// 10 кОм и 20 кОм).
const int GAS = 34;
const int LED = 2;
const int ALARM_ON = 2400;
const int ALARM_OFF = 1800;
const unsigned long WARMUP_MS = 5000;
bool gasAlarm = false;
void setup() {
Serial.begin(115200);
pinMode(LED, OUTPUT);
Serial.println("прогрев датчика...");
}
void loop() {
if (millis() < WARMUP_MS) {
delay(200);
return;
}
int level = analogRead(GAS);
if (!gasAlarm && level > ALARM_ON) {
gasAlarm = true;
Serial.println("ГАЗ! превышен порог");
} else if (gasAlarm && level < ALARM_OFF) {
gasAlarm = false;
Serial.println("воздух чистый");
}
digitalWrite(LED, gasAlarm);
Serial.printf("уровень: %d\n", level);
delay(300);
}
// Сигнализация утечки газа на MQ-2.
//
// Нагреватель датчика греется минуты, и всё это время показания
// плавают. Здесь прогрев сокращён до пяти секунд ради демонстрации; на
// настоящем датчике ждут минимум пару минут.
//
// Порогов два: включаем при высоком, выключаем при заметно более
// низком, чтобы сигнал не дребезжал у границы.
const int GAS = A0;
const int LED = 8;
const int ALARM_ON = 600;
const int ALARM_OFF = 450;
const unsigned long WARMUP_MS = 5000;
bool gasAlarm = false;
void setup() {
Serial.begin(9600);
pinMode(LED, OUTPUT);
Serial.println("прогрев датчика...");
}
void loop() {
if (millis() < WARMUP_MS) {
delay(200);
return;
}
int level = analogRead(GAS);
if (!gasAlarm && level > ALARM_ON) {
gasAlarm = true;
Serial.println("ГАЗ! превышен порог");
} else if (gasAlarm && level < ALARM_OFF) {
gasAlarm = false;
Serial.println("воздух чистый");
}
digitalWrite(LED, gasAlarm);
Serial.print("level=");
Serial.println(level);
delay(300);
}
В железе
Нагреватель потребляет заметный ток и рассчитан на 5 В: питайте модуль от USB-5 В платы, а не от вывода 3,3 В. Выход AO у такого модуля доходит до 5 В, поэтому для входа ESP32 его нужно пропустить через делитель. Датчик нельзя считать защитным устройством: для настоящей сигнализации утечки газа нужен сертифицированный прибор.
Частые ошибки
Читать значения сразу после включения: нагреватель ещё холодный, и показания плывут. Подождите прогрева.
AO напрямую на вход ESP32 при питании 5 В: на выходе может быть больше 3,3 В. Нужен делитель.
Перевод в ppm по формулам из интернета без калибровки в чистом воздухе: числа получаются красивые, но неверные.
Порог без гистерезиса: на границе сигнал включается и выключается от шума АЦП.