Датчик MQ-7 — это популярный полупроводниковый сенсор для обнаружения угарного газа (CO). В связке с микроконтроллером ESP32, обладающим встроенным Wi-Fi, он становится основой для систем мониторинга качества воздуха в рамках концепции Интернета Вещей (IoT). Передача данных через протокол MQTT позволяет легко интегрировать показания датчика в системы умного дома (Home Assistant, Node-RED) или облачные платформы.

⚠️ Важное предупреждение по безопасности: Датчики серии MQ являются полупроводниковыми и подвержены дрейфу показаний, влиянию температуры и влажности. Они не пригодны для систем жизнеобеспечения, где на кону стоит человеческая жизнь. Не полагайтесь на них как на единственный источник сигнализации об угарном газе. Используйте их для ознакомительных целей и общего мониторинга тенденций.
1. Необходимые компоненты
Для реализации проекта вам понадобятся:
- Плата ESP32 (DevKit V1, NodeMCU-32S или аналог).
- Модуль датчика газа MQ-7 (рекомендуется готовый модуль с компаратором LM393, а не голый сенсор).
- Резисторы (для делителя напряжения): 10 кОм и 20 кОм (или любые в пропорции 1:2).
- Макетная плата и провода.
- Внешний источник питания 5В (рекомендуется, так как нагревательный элемент MQ-7 потребляет до 150 мА, что может быть много для USB-порта компьютера).
- MQTT-брокер (например, Mosquitto локально или облачный сервис вроде HiveMQ, CloudMQTT).
2. Особенности датчика MQ-7
В отличие от многих других сенсоров, MQ-7 требует специфического цикла нагрева для корректного определения угарного газа:
- Нагрев до 5В (90 секунд): Очищает сенсор от поглощенных газов.
- Нагрев до 1.5В (60 секунд): Рабочий режим, в котором производится измерение концентрации CO.
В большинстве любительских проектов этот цикл игнорируется, и датчик питается постоянным напряжением 5В. В этом случае сенсор реагирует на газы, но калибровка в ppm (частей на миллион) будет неточной.

В данной статье мы рассмотрим подключение модуля с постоянным питанием для простоты, но с обязательным усреднением показаний.
3. Схема подключения
3.1. Питание
- VCC MQ-7 → 5V ESP32 (или внешний 5В с общей землей).
- GND MQ-7 → GND ESP32.
3.2. Аналоговый сигнал (AO)
Выход AO на модуле MQ-7 обычно выдает напряжение от 0 до 5В. Внимание: Аналоговые входы (ADC) ESP32 работают с напряжением 0–3.3В. Подача 5В может повредить микроконтроллер. Необходимо использовать делитель напряжения.
Схема делителя:
- Выход AO датчика → Резистор 20 кОм → Вход GPIO34 (ESP32).
- Точка соединения (между резистором и GPIO) → Резистор 10 кОм → GND.
Такая схема снизит 5В до примерно 3.3В.
| Пин MQ-7 | Подключение | Примечание |
|---|---|---|
| VCC | 5V | Питание нагревателя |
| GND | GND | Общая земля |
| AO | GPIO 34 (через делитель) | Аналоговый сигнал |
| DO | Не подключается | Цифровой выход (пороговый) |
Примечание: GPIO 34 выбран потому, что он поддерживает только вход (Input) и не имеет внутренних подтяжек, что идеально для аналоговых измерений.
4. Программная часть
4.1. Необходимые библиотеки
В Arduino IDE установите следующие библиотеки через Менеджер Библиотек:
- WiFi (встроена в пакет ESP32).
- PubSubClient (автор: Nick O’Leary) — клиент MQTT.
4.2. Код прошивки
#include <WiFi.h>
#include <PubSubClient.h>
// --- Настройки WiFi ---
const char* ssid = "YOUR_WIFI_SSID";
const char* password = "YOUR_WIFI_PASSWORD";
// --- Настройки MQTT ---
const char* mqtt_server = "broker.hivemq.com"; // Публичный брокер для теста
const int mqtt_port = 1883;
const char* mqtt_user = ""; // Оставьте пустым для публичных брокеров
const char* mqtt_pass = "";
const char* client_id = "esp32_mq7_sensor";
const char* topic_publish = "home/sensor/co_level";
// --- Настройки оборудования ---
const int MQ7_PIN = 34; // Аналоговый пин
const int READ_INTERVAL = 5000; // Интервал отправки данных (мс)
WiFiClient espClient;
PubSubClient client(espClient);
unsigned long lastMsg = 0;
char msg[50];
// --- Функция подключения к WiFi ---
void setup_wifi() {
delay(10);
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
// --- Переподключение MQTT ---
void reconnect() {
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
if (client.connect(client_id, mqtt_user, mqtt_pass)) {
Serial.println("connected");
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
delay(5000);
}
}
}
// --- Функция чтения и усреднения ADC ---
int readMQ7() {
int sum = 0;
int samples = 10;
for (int i = 0; i < samples; i++) {
sum += analogRead(MQ7_PIN);
delay(10);
}
return sum / samples;
}
void setup() {
Serial.begin(115200);
setup_wifi();
// Настройка ADC (ширина 12 бит, аттенюация для расширения диапазона)
analogReadResolution(12);
analogSetAttenuation(ADC_11db); // Позволяет читать до ~3.3В безопасно
client.setServer(mqtt_server, mqtt_port);
}
void loop() {
if (!client.connected()) {
reconnect();
}
client.loop();
unsigned long now = millis();
if (now - lastMsg > READ_INTERVAL) {
lastMsg = now;
// Чтение данных
int sensorValue = readMQ7();
// Конвертация в напряжение (опционально)
// ESP32 ADC: 0-4095 соответствует 0-3.3В (с учетом аттенюации)
float voltage = sensorValue * (3.3 / 4095.0);
// Формирование сообщения
// Отправляем сырое значение и напряжение
snprintf(msg, 50, "{\"raw\": %d, \"voltage\": %.2f}", sensorValue, voltage);
Serial.print("Publish message: ");
Serial.println(msg);
// Публикация в топик
client.publish(topic_publish, msg);
}
}
5. Калибровка и интерпретация данных
5.1. Прогрев
При первом включении датчику требуется 24–48 часов непрерывной работы для стабилизации химических процессов внутри сенсора. Первые показания будут нестабильными.
5.2. Преобразование в ppm
Получение точных значений в ppm (частей на миллион) требует построения калибровочного графика на основе логарифмической зависимости сопротивления сенсора от концентрации газа. Упрощенная формула (требует индивидуальной калибровки на чистом воздухе):
- Измерьте значение
R0(сопротивление сенсора в чистом воздухе). - Вычислите отношение
Rs/R0, гдеRs— текущее сопротивление. - Используйте кривую чувствительности из даташита MQ-7.
Для большинства задач умного дома достаточно отслеживать относительное изменение значения ADC. Резкий рост показаний указывает на наличие газа.
5.3. Настройка MQTT
В примере используется публичный брокер broker.hivemq.com. Для реальной системы рекомендуется поднять локальный брокер (например, Mosquitto на Raspberry Pi или ПК) и настроить аутентификацию.

Пример подписки в терминале (для проверки):
bashmosquitto_sub -h broker.hivemq.com -t "home/sensor/co_level" -v

6. Типичные ошибки и решение
| Проблема | Причина | Решение |
|---|---|---|
| Показания «скачут» | Шум питания или ADC | Используйте усреднение в коде (как в примере) и добавьте конденсатор 100мкФ на питание датчика. |
| ESP32 перезагружается | Просадка напряжения | Нагреватель MQ-7 потребляет много тока. Используйте отдельный блок питания 5В для датчика, объединив только земли (GND). |
| Нет данных в MQTT | Ошибка подключения | Проверьте лог в Serial Monitor. Убедитесь, что брокер доступен и порт 1883 не заблокирован фаерволом. |
| Повреждение ESP32 | Подача 5В на GPIO | Всегда используйте делитель напряжения на аналоговом входе. |
7. Подробнее про технологию MQTT и ее особенности по сравнению с обычным HTTPS
MQTT-брокер — это центральный компонент архитектуры обмена сообщениями по протоколу MQTT (Message Queuing Telemetry Transport). Он выступает в роли «почтового узла», который принимает сообщения от издателей (publishers) и доставляет их подписчикам (subscribers).
Если проводить аналогию:
| Компонент | Аналогия | Роль в системе |
|---|---|---|
| Издатель (Publisher) | Отправитель письма | Устройство, которое публикует данные (например, датчик температуры) |
| Подписчик (Subscriber) | Получатель письма | Устройство или сервис, который получает данные (например, смартфон или база данных) |
| Брокер (Broker) | Почтовое отделение | Принимает, фильтрует и рассылает сообщения по нужным адресам |
| Топик (Topic) | Адрес доставки | Иерархическая строка, определяющая категорию сообщения (например, home/kitchen/temp) |
7.1. Почему нельзя общаться напрямую?
Теоретически, устройства могут обмениваться данными напрямую (Point-to-Point), но такой подход имеет серьезные ограничения:
Проблемы прямого соединения:
[Датчик] ──→ [Сервер]
[Датчик] ──→ [Приложение]
[Датчик] ──→ [База данных]
- Жесткая связность: Датчик должен «знать» IP-адреса всех получателей.
- Масштабируемость: При добавлении нового получателя нужно перепрошивать все датчики.
- Надежность: Если получатель временно недоступен, данные теряются.
- Безопасность: Каждое устройство должно управлять множеством соединений.
Решение через брокер:
[MQTT Брокер]
│
┌──────────────┼──────────────┐
│ │ │
[Датчик] [Сервер] [Приложение]
[Публикует] [Подписан] [Подписан]
на topic на topic
- Слабая связность: Издатель не знает, кто получает его данные.
- Гибкость: Новые подписчики подключаются без изменения кода датчиков.
- Централизованное управление: Аутентификация, логирование, контроль доступа в одном месте.
7.2. Ключевые функции брокера
7.2.1. Маршрутизация по топикам
Брокер фильтрует сообщения на основе подписок:
// Датчик публикует в топик
client.publish("home/room1/temperature", "23.5");
// Подписчики получают только нужные данные:
// Подписка "home/room1/temperature" → получит сообщение
// Подписка "home/room2/temperature" → не получит
// Подписка "home/+/temperature" → получит (wildcard +)
// Подписка "home/#" → получит всё из home/ (wildcard #)
7.2.2. Качество обслуживания (QoS)
Брокер поддерживает три уровня надежности доставки:
| QoS | Название | Гарантия | Трафик | Когда использовать |
|---|---|---|---|---|
| 0 | At most once | «Отправил и забыл» | Минимальный | Телеметрия, где допустимы потери |
| 1 | At least once | Минимум один раз, возможны дубли | Средний | Команды управления, где важно исполнение |
| 2 | Exactly once | Ровно один раз, без дублей | Максимальный | Критичные транзакции, финансовые данные |
7.2.3. Сохраненные сообщения (Retained Messages)
Брокер может хранить последнее сообщение в топике и автоматически отправлять его новым подписчикам:
// Публикация с флагом retained
client.publish("home/status/online", "true", true); // true = retained
// Новый подписчик сразу получит "true", даже если сообщение было отправлено час назад
Применение: Статусы устройств, последняя известная температура, конфигурация.
7.2.4. «Последняя воля» (Last Will and Testament)
Устройство может заранее указать сообщение, которое брокер опубликует, если клиент неожиданно отключится:
// При подключении устройство задает Last Will
MQTT_CLIENT_SET_LAST_WILL(client, "home/device/status", "offline", true);
// Если устройство обрывает соединение без корректного DISCONNECT,
// брокер автоматически опубликует "offline" в указанный топик
Применение: Мониторинг доступности устройств, автоматическое оповещение о сбоях.
7.2.5. Сессии и очередь сообщений
При использовании «чистой сессии» (clean_session = false) брокер хранит подписки и накапливает сообщения для офлайн-клиентов:
[Датчик] публикует → [Брокер] сохраняет → [Приложение] подключается → получает накопленные данные
7.3. Практические сценарии использования
Сценарий 1: Умный дом
Топики:
home/kitchen/temp → датчик температуры
home/kitchen/light/cmd → команда на включение света
home/kitchen/light/sts → статус лампы
Поток данных:
1. Датчик → publish("home/kitchen/temp", "22.1")
2. Брокер → рассылает всем подписчикам этого топика
3. Подписчики:
- Веб-интерфейс → обновляет график
- Система логики → решает, включить ли обогрев
- Мобильное приложение → показывает пользователю
Сценарий 2: Промышленный мониторинг
Топики:
factory/line1/motor1/vibration
factory/line1/motor1/temp
factory/alerts
Преимущества:
- Десятки датчиков публикуют данные независимо
- Разные системы (аналитика, аварийное оповещение, архив) подписываются на нужные топики
- При добавлении новой системы аналитики не нужно трогать датчики
Сценарий 3: Логистика и трекинг
Топики:
fleet/truck_123/location
fleet/truck_123/fuel
fleet/truck_123/commands
Особенности:
- Грузовики (издатели) работают в условиях нестабильной связи
- Брокер с QoS=1 гарантирует доставку критичных команд
- Диспетчерская (подписчик) видит актуальное состояние всего парка
7.4. Популярные MQTT-брокеры
| Брокер | Лицензия | Особенности | Для чего подходит |
|---|---|---|---|
| Mosquitto | EPL/EDL | Легковесный, надежный, поддержка MQTT 5.0 | Домашние проекты, Raspberry Pi, обучение |
| EMQX | Apache 2.0 / Коммерческая | Высокая производительность, кластеризация, веб-интерфейс | Промышленные решения, масштабируемые системы |
| HiveMQ | Коммерческая / Бесплатный план | Облачная нативность, интеграции, мониторинг | Корпоративные облачные решения |
| VerneMQ | Apache 2.0 | Распределенная архитектура, отказоустойчивость | Высоконагруженные распределенные системы |
| AWS IoT Core | Платный сервис | Полная интеграция с экосистемой AWS | Проекты на облачной инфраструктуре Amazon |
Быстрый старт с Mosquitto (Docker)
# Запуск брокера локально
docker run -d -p 1883:1883 -p 9001:9001 eclipse-mosquitto
# Тест публикации
mosquitto_pub -h localhost -t "test/topic" -m "Hello MQTT"
# Тест подписки (в другом терминале)
mosquitto_sub -h localhost -t "test/topic"
7.5. Когда брокер НЕ нужен?
Несмотря на преимущества, MQTT с брокером — не универсальное решение:
| Ситуация | Альтернатива | Почему |
|---|---|---|
| Прямое управление одним устройством | HTTP, WebSocket | Проще реализовать, меньше накладных расходов |
| Высокочастотные данные с жесткими требованиями к задержкам | UDP, специализированные протоколы | Брокер добавляет небольшую задержку на маршрутизацию |
| Полностью офлайн-система | Локальная шина (I2C, SPI, CAN) | Нет сети — нет смысла в сетевом протоколе |
| Очень ограниченные устройства (< 10 КБ RAM) | CoAP, упрощенные протоколы | Даже легковесный MQTT-клиент может не поместиться |
7.6. Безопасность и лучшие практики
Обязательные меры:
- Аутентификация: Используйте логин/пароль или клиентские сертификаты.
- Шифрование: Подключайтесь по TLS (
mqtts://, порт 8883). - Контроль доступа (ACL): Ограничьте права публикации/подписки для каждого клиента.
- Изоляция топиков: Разделяйте критичные и публичные данные.

Заключение
Подключение датчика MQ-7 к ESP32 с передачей данных по MQTT — это классическая задача для начала работы с IoT. Она объединяет работу с аналоговыми сигналами, управление питанием мощной нагрузки (нагревателя) и сетевое взаимодействие.
Ключевые моменты для успешного проекта:
- Безопасность напряжения: Защищайте входы ESP32 делителем.
- Стабильность питания: Обеспечьте достаточный ток для нагревателя сенсора.
- Фильтрация данных: Используйте усреднение показаний для снижения шума.
- Осторожность: Помните об ограничениях точности полупроводниковых сенсоров.
Развивая этот проект, можно добавить веб-интерфейс на самом ESP32 для отображения графиков или настроить автоматические уведомления в Telegram при превышении пороговых значений.