Andrey Ovcharov

маленькое невинное хобби

Датчик углекислого газа MH-Z19b

Разбирая свои закрома радиодеталей наткнулся на любопытный модуль - MH-Z19b. Это простенький датчик уровня углекислого газа. С таким я ещё ни разу не игрался, попробую подключить. Немножко поковырявшись в интернете, выяснил его возможности.

  • Питание +5в, можно кормить любой зарядкой для мобильного
  • Данные можно снимать через последовательный порт
  • Диапазон измерения - до 5000ppm

В общем, то что надо для не критичного поделия на коленке.

Сборка

В качестве “мозга” устройства будет полюбившийся мне в последнее время ESP8266. Для подключения достаточно всего четырёх проводов, значит можно использовать самую простую версию - ESP-01. В качестве основы всей конструкции - макетная плата, несколько разъёмов и немного провода.

исходные модули

Разъёма питания на макетке не предусмотрено, но в закромах нашлась старая плата с припаянными Micro USB разъемом и регулятором напряжения на 3.3в. То, что надо. Отпилил всё лишнее и прикрутил к макетке двумя винтами М2.

Схема подключения тривиальная. Если нигде не напутать, то заработает сразу.

схема устройства

Резисторы по 10К, конденсаторы на питание я проигнорировал.

Программа

Программировалось всё на обычной Ардуине, благо там гора библиотек уже есть. Первым делом в скетч был добавлена возможность загрузки микропрограммы через WiFi - чтобы не переключать постоянно модуль между программатором и датчиком, называется Arduino OTA. Кстати, обновляется так гораздо быстрее чем через UART.

Для получения данных с датчика библиотека тоже есть, но её я не использовал - там и так всего несколько строк:

SoftwareSerial co2(0, 2);

void setup() {
  // ...
  co2.begin(9600);
}

int co2ppm() {
  static byte cmd[9] = {0xFF, 0x01, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79};
  static byte response[9] = {0};

  co2.write(cmd, 9);
  co2.readBytes(response, 9);

  unsigned int responseHigh = (unsigned int) response[2];
  unsigned int responseLow = (unsigned int) response[3];

  return (256 * responseHigh) + responseLow;
}

Измерение уровня углекислого газа это полдела. Оставшиеся полдела - отображение этого уровня и анализ.

Сбор данных

Для сбора данных у меня сейчас используется валявшийся ранее без дела микрокомпьютер Raspberry PI. На него был установлен брокер протокола MQTT mosquitto с конфигурацией по умолчанию. Внутри локальной домашней сети это достаточно безопасно, да и ничего приватного там все равно нет.

Установка простая:

sudo apt-get update
sudo apt-get install mosquitto

После этого малинка готова к приему циферок от датчика. Надо только установить библиотеку PubSubClient.

В программу добавилось следующее:

#include <PubSubClient.h>

const char* mqtt_server = "192.168.178.29";

WiFiClient espClient;
PubSubClient client(espClient);

void setup() {
  // ...
  client.setServer(mqtt_server, 1883);
}

void loop() {
  // ...
  static char msg[250];
  snprintf (msg, 250, "co2 ppm=%d", co2ppm());
  client.publish("sensor/co2", msg);
}

Данные отправляются в формате InfluxDB - это пригодится на следующем шаге.

Хранение истории для анализа

Хранятся данные в InfluxDB. Это специальная база данных для записей, упорядоченных по времени. Самое то для истории показаний.

Установка немножко более замороченная, потому что хочется последнюю версию от разработчиков:

curl -sL https://repos.influxdata.com/influxdb.key | sudo apt-key add -
echo "deb https://repos.influxdata.com/debian stretch stable" | sudo tee /etc/apt/sources.list.d/influxdb.list
sudo apt install influxdb telegraf

Все настройки по умолчанию, только нужно добавить конфигурацию для импорта данных из mosquitto в InfluxDB:

Файл /etc/telegraf/telegraf.d/sensors.conf

[[outputs.influxdb]]
urls = ["http://127.0.0.1:8086"]
database = "sensors"

[[inputs.mqtt_consumer]]
  servers = ["tcp://localhost:1883"]
  topics = [
    "sensor/co2"
  ]

Таким образом в базе данных sensors появятся показания нашего датчика.

Красивые графики

Красивые динамичные графики рисует пакет Grafana.

Установка, тоже последняя версия:

curl https://bintray.com/user/downloadSubjectPublicKey?username=bintray | sudo apt-key add -
echo "deb https://dl.bintray.com/fg2it/deb jessie main" | sudo tee -a /etc/apt/sources.list.d/grafana.list
sudo apt install grafana

После этого можно окрыть в браузере страницу http://<адрес малинки>:3000/ и настроить источник данных (InfluxDB) и панель с графиками. В результате можно сделать вот такую красоту:

график уровня углекислого газа

Результаты

Сначала датчик показывал какие-то дикие значения, но потом самостоятельно откалибровался и цифры стали более-менее вменяемыми. Самостоятельная калибровка заключается в том, что минимальное значение за прошедшие сутки принимается за 400ppm. Понятно, что это весьма смелое предположение и наверняка сильно отличается от реальных значений, но точно прибора для ручной калибровки у меня, увы, нет.

собранный прототип

В целом прибор оказался интересный. Показания, может и не точные, но представление о свежести воздуха дают. При закрытых окнах концентрация медленно растет и за несколько часов добирается до 1000ppm, что субъективно ощущается как чувство усталости и потери внимания. Если проветрить - опять опускается до 400-500ppm. Если же подышать прямо на датчик, то можно легко нагнать и 2000-3000ppm.

Резюме. Подключается и управляется очень просто. Данные, может быть, и не совсем точные, но для домашнего использования вполне достаточно. Можно очень легко сделать несколько таких датчиков, например, для каждой комнаты, и централизованно собирать с них показания и, например, посылать сообщение в мессенджер - все программы для этого уже есть, надо только собрать их вместе.