Цель: сверхраннее обнаружение признаков возгорания внутри закрытого электротехнического изделия.
Устройство на базе MQ-2 решает задачу комплексного контроля состава газовой среды внутри шкафа автоматики, что критически важно на ранних стадиях аварии, до появления открытого пламени.

Mодуль MQ-2 потребляет значительный ток на разогрев чувствительного элемента (SnO2).
Важное замечание: Регулятор Arduino Nano (обычно AMS1117-5.0) физически не способен долговременно отдавать ток 170 мА при входном напряжении 12 В, так как его максимальный ток обычно 800 мА, но критичным становится перегрев.
Решение: Необходимо питать нагреватель MQ-2 напрямую от 12 В через внешний линейный стабилизатор на 5 В (например, 7805 на радиаторе) или использовать внешний DC-DC преобразователь. В рамках задачи, мы уточняем, что стабилизатор Arduino питает только логику, а на MQ-2 подается питание с внешнего стабилизатора. В расчетах учитываем, что Arduino отдает ток только 20 мА. Внешний стабилизатор рассчитывается отдельно.
MQ-2 представляет собой делитель напряжения .
Типовые значения (при на плате модуля = 1 кОм):
Защита реализуется так же, как для герметичного датчика, но с учетом длинных проводов до датчика, расположенного в верхней точке шкафа.
| Обозначение | Компонент | Модель / Номинал | Примечание |
|---|---|---|---|
| A1 | Микроконтроллер | Arduino Nano (ATmega328P) | Клон |
| U1 | Датчик газа | MQ-2 (модуль) | Чувствителен к дыму, LPG, метану |
| U2 | Внешний стабилизатор | L7805CV (TO-220) | Для нагревателя MQ-2, на радиаторе |
| D1 | Стабилитрон | BZX55C5V1 | 5.1 В, 0.5 Вт |
| R1 | Резистор | 1 кОм, 0.25 Вт | Защитный |
| C1, C2 | Конденсатор | 100 нФ, керамика | Фильтрующий |
| C3, C4 | Конденсатор | 10 мкФ, электролит | По входу и выходу 7805 |
{"raw": 350, "status": "normal"}
{"raw": 512, "status": "warning", "msg": "Low smoke"}
{"raw": 850, "status": "alarm", "msg": "Fire detected!"}
В программе учитывается время прогрева датчика MQ-2 (около 60 секунд), в течение которого показания игнорируются.
#include <ArduinoJson.h>
// ==================== КОНФИГУРАЦИЯ ====================
#define SMOKE_SENSOR_PIN A0 // Аналоговый вход датчика
#define BUILTIN_LED 13 // Встроенный светодиод (L)
// Пороги срабатывания (подбираются экспериментально при настройке)
// Значения приведены для примера и зависят от конкретного модуля MQ-2
#define THRESHOLD_WARN 400 // Предупреждение (слабое задымление)
#define THRESHOLD_ALARM 700 // Тревога (сильное задымление)
// Время прогрева датчика MQ-2 (секунды)
#define WARMUP_TIME 60
// Период отправки данных
#define SEND_INTERVAL 1000
// ==================== ГЛОБАЛЬНЫЕ ПЕРЕМЕННЫЕ ====================
unsigned long lastSendTime = 0;
unsigned long startTime = 0;
int rawValue = 0;
void setup() {
Serial.begin(9600);
delay(100);
pinMode(BUILTIN_LED, OUTPUT);
digitalWrite(BUILTIN_LED, LOW);
startTime = millis();
// Отправка статуса старта
StaticJsonDocument<128> doc;
doc["status"] = "startup";
doc["msg"] = "MQ-2 warming up";
doc["warmup_sec"] = WARMUP_TIME;
serializeJson(doc, Serial);
Serial.println();
}
void loop() {
// 1. Чтение значения с MQ-2 (усреднение 10 замеров)
long sum = 0;
for (int i = 0; i < 10; i++) {
sum += analogRead(SMOKE_SENSOR_PIN);
delay(1);
}
rawValue = sum / 10;
// 2. Логика обнаружения (только после завершения прогрева)
String state = "warmup";
bool ledState = false;
if ((millis() - startTime) > (WARMUP_TIME * 1000)) {
if (rawValue >= THRESHOLD_ALARM) {
state = "alarm";
ledState = true; // Постоянно горит при пожаре
} else if (rawValue >= THRESHOLD_WARN) {
state = "warning";
ledState = (millis() / 200) % 2; // Мигает при предупреждении
} else {
state = "normal";
ledState = false;
}
} else {
// В режиме прогрева светодиод горит вполнакала (ШИМ можно, но мигнем просто)
ledState = (millis() / 500) % 2;
}
digitalWrite(BUILTIN_LED, ledState ? HIGH : LOW);
// 3. Отправка данных по расписанию
unsigned long now = millis();
if (now - lastSendTime >= SEND_INTERVAL) {
lastSendTime = now;
StaticJsonDocument<128> doc;
doc["raw"] = rawValue;
doc["status"] = state;
if (state == "warning") {
doc["msg"] = "Low smoke level detected";
} else if (state == "alarm") {
doc["msg"] = "FIRE ALARM! Heavy smoke!";
}
serializeJson(doc, Serial);
Serial.println();
}
// 4. Обработка команд с неттопа
if (Serial.available()) {
String cmd = Serial.readStringUntil('\n');
cmd.trim();
if (cmd == "STATUS") {
lastSendTime = 0; // Принудительная отправка в следующем цикле
} else if (cmd == "CALIBRATE") {
// Команда калибровки (сброс времени прогрева для имитации)
startTime = millis();
Serial.println(F("{\"status\":\"info\", \"msg\":\"Recalibration started\"}"));
}
}
}