Обзор инфракрасного датчика CO2 MH-Z19

в 1:46, , рубрики: co2, diy или сделай сам, MH-Z19, метки:

В последнее время популярны гаджеты, показывающие уровень CO2, равно как и статьи, рассказывающие как монитор CO2 можно превратить в подключенный к компьютеру датчик. Я хочу показать решение задачи с другой стороны.

В отличие от старых датчиков CO2, MH-Z19 не требует специфического напряжения или высокой мощности и умеет передавать данные через UART и PWM.

Обзор инфракрасного датчика CO2 MH-Z19 - 1

  • Hd — калибровка нуля начнется, если на Hd более 7 секунд подается LOW. Калибровку проводить не нужно.
  • SR — не используется
  • Tx — уровень сигнала — 3.3В
  • Rx — тоже 3.3В (работает и с 5В, но я бы не рекомендовал)
  • Vo — выходное напряжение 3.3В, не более 10мА

  • PWM, данные снимаются так: длина цикла 1004мс, первые 2мс всегда HIGH, последние — всегда LOW, а «середина» пропорциональна концентрации CO2 в пределах 0 — 5000ppm (а не 2000ppm как в документации).
    Cppm = 5000 * (Thigh — 2ms)/(Thigh + Tlow — 4ms)
    Отмечу, что PWM — штука очень капризная, требующая аккуратной пайки и 3.3В.
  • AOT — не используется
  • Gnd — земля
  • Vin — напряжение питания 3.6 — 5.5В (сенсор работает и выдает те же значения при питании 3.3В, но производитель настоятельно рекомендует придерживаться рамок)

Не то, чтобы я не доверял PWM, но лучше получать данные в цифре и с контрольной суммой. UART позволяет запрашивать уровень концентрации CO2 и заниматься двумя видами калибровки. Оставим калибровку Гаррусу и рассмотрим запрос данных. Для этого на скорости 9600 (8 bit, stop — 1, parity — none) нужно отправить следующие девять байт:
• 0xFF — начало любой команды
• 0x01 — первый сенсор (он всего один)
• 0x86 — команда
• 0x00, 0x00, 0x00, 0x00, 0x00 — данные
• 0x79 — контрольная сумма.

В ответ придет что-то такое:
• 0xFF — начало любого ответа
• 0x86 — команда
• 0x01, 0xC1 — старшее и младшее значение (256 * 0x01 + 0xC1 = 449)
• 0x3C, 0x04, 0x3C, 0xC1 — в документации сказано, что должно приходить что-то типа 0x47, 0x00, 0x00, 0x00, но на деле приходит непонятно что.
• 0x7B — контрольная сумма.

Контрольная сумма считается следующим образом: берутся 7 байт ответа (все кроме первого и последнего), складываются, инвертируются, увеличиваются на 1: 0x86 + 0x01… + 0xC1 = 0x85, 0x85 xor 0xFF = 0x7A, 0x7A + 1 = 0x7B.

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

Сенсор реагирует на изменение концентрации CO2 с задержкой около минуты. При превышении концентрации в 5000ppm (например, вы минуту интенсивно на него дышали), он некоторое время будет выдавать ложные данные, занижая уровень CO2 — я так получал даже 80ppm.

В документации это не отражено, но не стоит запрашивать данные по UART чаще раза в 10 секунд, иначе сенсор начинает выдавать что-то странное.

Пришло время картинок. Подключим сенсор к Arduino Uno через Software Serial, RX/TX в A0/A1, питание в 5В, землю — в Gnd:

Обзор инфракрасного датчика CO2 MH-Z19 - 2

Позаимствованный скетч, в который добавлена проверка контрольной суммы

#include <SoftwareSerial.h>;

SoftwareSerial mySerial(A0, A1); // A0 - к TX сенсора, A1 - к RX

byte cmd[9] = {0xFF,0x01,0x86,0x00,0x00,0x00,0x00,0x00,0x79}; 
unsigned char response[9];

void setup() {
  Serial.begin(9600);
  mySerial.begin(9600);
}

void loop() 
{
  mySerial.write(cmd, 9);
  memset(response, 0, 9);
  mySerial.readBytes(response, 9);
  int i;
  byte crc = 0;
  for (i = 1; i < 8; i++) crc+=response[i];
  crc = 255 - crc;
  crc++;

  if ( !(response[0] == 0xFF && response[1] == 0x86 && response[8] == crc) ) {
    Serial.println("CRC error: " + String(crc) + " / "+ String(response[8]));
  } else {
    unsigned int responseHigh = (unsigned int) response[2];
    unsigned int responseLow = (unsigned int) response[3];
    unsigned int ppm = (256*responseHigh) + responseLow;
    Serial.println(ppm);
  }
  delay(10000);
}

Каждое измерение идет с интервалом 10 секунд. Значения перестали прыгать когда я отошел от сенсора.
Обзор инфракрасного датчика CO2 MH-Z19 - 3

Теперь сделаем датчик мобильным. Для этого потребуется устройство с OTG и приложение типа DroidTerm.
Тут есть тонкость: чтобы связь установилась — нужно перезагрузить Arduino.
Обзор инфракрасного датчика CO2 MH-Z19 - 4

Убедившись, что все работает, уберем Arduino, заменив его на FTDI FT232RL.
Обзор инфракрасного датчика CO2 MH-Z19 - 5

Питание на датчик стоит подавать уже после подключения чтобы не было проблем с соединением.
Для отправки бинарных данных через COM-порт я использую RealTerm:
Обзор инфракрасного датчика CO2 MH-Z19 - 6

Возможно, стоит добавить управление питанием через DTR, чтобы можно было перезапускать датчик.

Полезные ссылки:
Мануал по датчику MH-Z19
Схема подключения и код для PWM
Сравнение с другим датчиком

У меня всего один датчик и я очень не люблю разбирать то, что однажды сделал, поэтому предлагаю выбрать вам.

Автор: Hellsy22

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js