Обзор
MH-Z19 — это высокоточный датчик концентрации углекислого газа (CO₂), использующий технологию недисперсионного инфракрасного излучения (NDIR). Он идеально подходит для мониторинга качества воздуха в помещениях, системах вентиляции (HVAC) и теплицах. Датчик отличается высокой избирательностью, стабильностью и длительным сроком службы.
MH-Z19 — это инфракрасный датчик для измерения уровня CO₂. Он поддерживает интерфейсы UART и PWM, имеет встроенную температурную компенсацию и позволяет обнаруживать концентрацию газа до 2000 ppm (опционально до 5000 ppm).
О датчике CO₂ MH-Z19 (NDIR)
MH-Z19 — это инфракрасный (NDIR) датчик, разработанный для точного измерения концентрации углекислого газа. Благодаря технологии NDIR датчик обладает высокой чувствительностью, длительным сроком службы и устойчивостью к влиянию других газов.
⚡ Ключевые особенности
- Технология NDIR – Обеспечивает точное обнаружение CO₂ с минимальными помехами.
- Гибкие интерфейсы – Поддержка UART и PWM для связи с микроконтроллерами.
- Стабильность и долговечность – Надежное решение для систем непрерывного мониторинга.
- Идеально для умных систем – Широко применяется в HVAC, теплицах и бытовых мониторах воздуха.
Для обнаружения летучих органических соединений (VOC) рассмотрите также датчик CCS811, который измеряет TVOC и eCO₂. 🚀
Приобретите MH-Z19
Характеристики MH-Z19
Основные технические параметры датчика MH-Z19 для мониторинга CO₂.
Распиновка MH-Z19
Интерфейс MH-Z19 обычно состоит из 9 выводов, поддерживающих связь по UART и опциональный выход PWM.
- Технология NDIR — Высокая точность для CO₂.
- Компенсация — Встроенная температурная компенсация.
- Калибровка — Пин HD предназначен для установки «нуля» (400ppm).
| № | Название | Тип | Описание | Примечания |
|---|---|---|---|---|
| 1 | Vout | Питание | Выход 3.3В (макс 10мА) | Не для питания ESP32! |
| 2 | RXD | UART | Вход приема UART (3.3В) | К пину TX микроконтроллера |
| 3 | TXD | UART | Выход передачи UART (3.3В) | К пину RX микроконтроллера |
| 4 | SR | Зарезервировано | Заводской пин | Не подключать |
| 5 | HD | Калибровка | Калибровка нуля | Заземлить на >7с в свежем воздухе |
| 6 | Vin | Питание | Вход питания (3.6В–5.5В) | Рекомендуется 5В |
| 7 | GND | Земля | Подключение земли | Общая земля |
| 8 | AOT | Зарезервировано | Заводской пин | Не подключать |
| 9 | PWM | PWM | Выход ШИМ сигнала | Альтернатива UART |
Подключение MH-Z19 к ESP32
Для обмена данными через UART подключите Vin к 5V, GND к земле, TXD датчика к RX2 ESP32 (GPIO16), а RXD датчика к TX2 ESP32 (GPIO17).
| Вывод MH-Z19 | Связь | Вывод ESP32 | Описание |
|---|---|---|---|
| Pin 6 (Vin) ОБЯЗАТЕЛЬНО | → | 5V | Питание 5В для лучшей стабильности |
| Pin 7 (GND) ОБЯЗАТЕЛЬНО | → | GND | Общая земля |
| Pin 3 (TXD) ОБЯЗАТЕЛЬНО | → | GPIO 16 (RX2) | Датчик передает данные CO₂ |
| Pin 2 (RXD) ОБЯЗАТЕЛЬНО | → | GPIO 17 (TX2) | Датчик получает команды |
| Pin 5 (HD) ОПЦИОНАЛЬНО | → | Любой GPIO | Только для ручной калибровки нуля |
Устранение неполадок MH-Z19
Распространенные проблемы при работе с датчиком и способы их решения.
Ошибка инициализации датчика
Invalid preamble from MHZ19
Invalid preamble from MHZ19Проблема: Микроконтроллер не получает корректных данных от датчика.
Решение: Проверьте правильность подключения пинов TX и RX (они должны быть перекрещены: TX датчика к RX контроллера). Убедитесь, что датчик получает стабильное питание 5В (не 3.3В). Проверьте скорость UART (обычно 9600).
Постоянные высокие показания (5000 ppm)
Датчик застыл на максимуме
Проблема: Сенсор выдает 5000 ppm даже при проветривании.
Решение: Проведите «нулевую» калибровку. Оставьте датчик включенным на чистом воздухе не менее чем на 20 минут, затем кратковременно (на 7+ секунд) замкните пин HD на землю. Либо отправьте команду калибровки через UART.
Медленное обновление данных
Показания меняются неохотно
Замечание: Датчик имеет физическую инерцию, так как газ должен диффундировать в камеру.
Совет: Не опрашивайте датчик чаще чем раз в 2–5 секунд. Время отклика T90 составляет менее 120 секунд.
Примеры кода для MH-Z19
Готовые примеры реализации для различных платформ.
Arduino IDE
Базовый пример UART (SoftwareSerial)
C++
// Создаем объект для работы с UART на пинах 10 (RX) и 11 (TX) SoftwareSerial mySerial(10, 11);
void setup() { Serial.begin(9600); mySerial.begin(9600); }
void loop() { // Команда для чтения данных: заголовок, номер команды (0x86), пустые байты и чексумма byte cmd[9] = {0xFF, 0x01, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79}; mySerial.write(cmd, 9); delay(500);
if (mySerial.available()) {
byte response[9];
mySerial.readBytes(response, 9);
// Проверяем преамбулу и команду
if (response[0] == 0xFF && response[1] == 0x86) {
// Расчет концентрации: (High_Byte * 256) + Low_Byte
int CO2 = (response[2] << 8) + response[3];
Serial.print("Концентрация CO2: ");
Serial.print(CO2);
Serial.println(" ppm");
}
}
delay(2000);
}
<p class="mt-4 text-sm text-slate-600 dark:text-slate-400 leading-relaxed !mb-0">
Этот скетч отправляет команду запроса данных через SoftwareSerial. Концентрация CO₂ рассчитывается на основе байтов ответа и выводится в монитор порта каждые 2.5 секунды.
</p>
</div>
</details>
<div id="esp-idf"></div>
<details class="group border border-slate-200 dark:border-slate-800 rounded-2xl bg-white dark:bg-slate-900 overflow-hidden [&_summary::-webkit-details-marker]:hidden">
<summary class="flex items-center gap-4 p-4 cursor-pointer hover:bg-slate-50 dark:hover:bg-slate-800/50 transition-colors w-full outline-none">
<img src="/img/32WN7tz--V-40.png" alt="ESP-IDF" class="w-10 h-10 object-contain shrink-0" loading="lazy" />
<div class="flex-1 text-left min-w-0">
<div class="font-bold text-slate-900 dark:text-slate-100 text-base leading-tight">ESP-IDF</div>
<div class="text-xs text-slate-500 dark:text-slate-400 leading-tight">Нативный фреймворк Espressif</div>
</div>
<div class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-bold bg-indigo-100 text-indigo-700 dark:bg-indigo-900/40 dark:text-indigo-300">C</div>
<div class="ml-2 p-1 rounded-xl bg-slate-100 dark:bg-slate-800">
<svg class="w-5 h-5 text-slate-400 transition transform group-open:rotate-180" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7" /></svg>
</div>
</summary>
<div class="p-4 border-t border-slate-200 dark:border-slate-800 bg-slate-50 dark:bg-slate-900/50">
```c
#include <stdio.h>
#include "driver/uart.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#define UART_NUM UART_NUM_1
#define TXD_PIN (GPIO_NUM_17)
#define RXD_PIN (GPIO_NUM_16)
void app_main(void) {
const uart_config_t uart_config = {
.baud_rate = 9600,
.data_bits = UART_DATA_8_BITS,
.parity = UART_PARITY_DISABLE,
.stop_bits = UART_STOP_BITS_1,
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE
};
uart_param_config(UART_NUM, &uart_config);
uart_set_pin(UART_NUM, TXD_PIN, RXD_PIN, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
uart_driver_install(UART_NUM, 256, 0, 0, NULL, 0);
uint8_t cmd[9] = {0xFF, 0x01, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79};
uint8_t response[9];
while (1) {
uart_write_bytes(UART_NUM, (const char *)cmd, 9);
vTaskDelay(pdMS_TO_TICKS(500));
int len = uart_read_bytes(UART_NUM, response, 9, pdMS_TO_TICKS(1000));
if (len == 9 && response[0] == 0xFF && response[1] == 0x86) {
int CO2 = (response[2] << 8) | response[3];
printf("CO2: %d ppm\n", CO2);
}
vTaskDelay(pdMS_TO_TICKS(2000));
}
}
<p class="mt-4 text-sm text-slate-600 dark:text-slate-400 leading-relaxed !mb-0">
Пример конфигурации UART для ESP-IDF. Код опрашивает MH-Z19 и выводит результат в консоль каждую итерацию цикла.
</p>
</div>
ESPHome
Конфигурация для Home Assistant
YAML
sensor:
- platform: mhz19 co2: name: “MH-Z19 CO2” temperature: name: “MH-Z19 Температура” update_interval: 60s
<p class="mt-4 text-sm text-slate-600 dark:text-slate-400 leading-relaxed !mb-0">
Простая интеграция MH-Z19 в ESPHome. Поддерживает чтение уровня CO₂ и приблизительной температуры сенсора.
</p>
</div>
</details>
<div id="micropython"></div>
<details class="group border border-slate-200 dark:border-slate-800 rounded-2xl bg-white dark:bg-slate-900 overflow-hidden [&_summary::-webkit-details-marker]:hidden">
<summary class="flex items-center gap-4 p-4 cursor-pointer hover:bg-slate-50 dark:hover:bg-slate-800/50 transition-colors w-full outline-none">
<img src="/img/U_FT8ja_jJ-40.png" alt="MicroPython" class="w-10 h-10 object-contain shrink-0" loading="lazy" />
<div class="flex-1 text-left min-w-0">
<div class="font-bold text-slate-900 dark:text-slate-100 text-base leading-tight">MicroPython</div>
<div class="text-xs text-slate-500 dark:text-slate-400 leading-tight">Удобство Python на микроконтроллерах</div>
</div>
<div class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-bold bg-indigo-100 text-indigo-700 dark:bg-indigo-900/40 dark:text-indigo-300">Python</div>
<div class="ml-2 p-1 rounded-xl bg-slate-100 dark:bg-slate-800">
<svg class="w-5 h-5 text-slate-400 transition transform group-open:rotate-180" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7" /></svg>
</div>
</summary>
<div class="p-4 border-t border-slate-200 dark:border-slate-800 bg-slate-50 dark:bg-slate-900/50">
```python
from machine import UART, Pin
import time
# Настройка UART порта
uart = UART(2, baudrate=9600, tx=Pin(17), rx=Pin(16))
# Байты команды запроса данных
cmd = bytearray([0xFF, 0x01, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79])
def read_co2():
uart.write(cmd)
time.sleep(0.1)
if uart.any():
response = uart.read(9)
if len(response) == 9 and response[0] == 0xFF and response[1] == 0x86:
# Превращаем два байта в число ppm
co2 = (response[2] << 8) | response[3]
return co2
return None
while True:
val = read_co2()
if val is not None:
print(f"CO2 Concentration: {val} ppm")
else:
print("Ошибка чтения")
time.sleep(2)
<p class="mt-4 text-sm text-slate-600 dark:text-slate-400 leading-relaxed !mb-0">
Python скрипт для циклического опроса MH-Z19 через аппаратный UART ESP32.
</p>
</div>
Итоги
MH-Z19 — это отличный выбор для тех, кому нужны надежные и точные показания уровня СО₂ без ложных срабатываний на другие газы. Использование технологии NDIR делает его заметно надежнее дешевых полупроводниковых аналогов.
- Используйте 5В для стабильной работы инфракрасной лампы.
- Не забывайте о времени прогрева (мин. 3 минуты).
- Проводите калибровку раз в несколько месяцев для высокой точности.
- Не допускайте попадания влаги и конденсата.
- Избегайте сильных механических вибраций.
- Не подключайте пины калибровки к питанию.
Готовы собрать свой монитор воздуха?
Интегрируйте MH-Z19 в свой проект на ESP32 и узнайте точно, когда пора проветрить комнату!
Похожие варианты датчиков
Просмотрите другие популярные датчики качества воздуха и газа для ваших проектов.
Оптический датчик пыли для обнаружения частиц табачного дыма и пыли.
Компактный датчик для обнаружения широкого спектра горючих газов и летучих веществ.
Цифровой датчик для мониторинга TVOC и эквивалентного уровня CO₂.