Измеряем концентрацию углекислого газа (CO2) с MH-Z14

Вы когда-нибудь задавались вопросом, почему люди очень часто чувствуют себя сонными по утрам, вялыми в течении дня и такими уставшими и измотанными к вечеру? А ведь причина — вот она, под ногами! А точнее — в воздухе, которым мы дышим!

co2

Что такое углекислый газ (CO2) и каковы пределы его концентрации в помещении для хорошего самочувствия человека? CO2 — бесцветный газ, без запаха, содержится в воздухе и выдыхается животными. Это нетоксичный газ, но превышение его концентрации в воздухе оказывает негативное влияние на здоровье человека. Измеряется в ppm (parts per million).

Качество воздуха в помещении описывается следующими факторами:

  • температура
  • влажность
  • запах
  • уровни концентрации различных газов

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

Уровни концентрации CO2 и их влияние на человекаco2_2

 Симптомы у взрослых здоровых людей  Концентрация CO2
 Нормальный уровень на открытом воздухе  300 — 450 ppm
 Приемлемые уровни  < 600 ppm
 Жалобы на несвежий воздух  600 — 1000 ppm
 Макс. уровень по мировому стандарту  1000 ppm
 Общая вялость и слабость  1000 — 2500 ppm
Нежелательные эффекты на здоровье  > 2500
Легкое отравление, тошнота, рвота 30000 ppm
Добавляется головная боль и потеря сознания  50000 ppm
Потеря сознания, в дальнейшем — смерть 100000ppm

Один из способов измерить уровень углекислого газа в воздухе — использовать arduino uno с инфракрасным датчиком MH-Z14.

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

Данный экземпляр детектирует COв диапазоне от 0 до 5000 ppm и соединяется с arduino по serial-интерфейсу (Tx и Rx). Напряжение питания 4-6V, максимальный ток достигает 100mA, но обычно держится в пределах <50mA. Желательно питать датчик не от самой arduino, а от отдельного источника питания, но для сборки прототипа этим можно пренебречь. Хочу заметить одно очень важное отличие в уровнях сигнала датчика и платы arduino:

  • arduino TX, RX — 5V
  • MH-Z14 TX, RX — 3.3V

Чтобы согласовать их сигналы, нам придется использовать конвертер логических уровней (TTL logic level covnerter).

Красная плата -
Красная плата — конвертер логических уровней

Еще одно замечание: при некотором простое, датчику нужно время, чтобы «разогреться». И это время составляет примерно 1 минуту; до этих пор датчик выдает 0 или какие-то нереальные значения.

Подключение

Вид сверху (с птичьего полета)
Вид сверху (с птичьего полета)
Arduino UNO TTL logic level converter MH-Z14
 VCC 5V  HV  15 (V+)
 VCC 3.3V  LV
 GND  GND любой  2 (V-)
 Analog 0  TX0 (на HV)
 Analog 1  RXI (на HV)
 TXI (на LV)  13 (T)
 RX0 (на LV)  14 (R)

Примечание: HV — high voltage (5V), LV — low voltage (3.3V).

Level Converter

Общий вид устройства
Общий вид устройства

Код программы для arduino IDE: arduino_mh_z14.zip

В терминале каждые 10 секунд выходит значение CO2 в ppm
В терминале каждые 10 секунд выходит значение CO2 в ppm

Что интересно, один человек, сидящий в комнате 3 часа с закрытыми окнами и дверью — повышает уровень CO2 с 450 ppm до 1800-1900 ppm (плохо!). Но если откинуть верхнюю часть одного окна стеклопакета, то через час концентрация снижается до <500 ppm (это супер) и держится на этом уровне (что и видно на фото с терминалом). 2 человека, проводящие ночь в одной комнате с закрытой дверью и окном, под утро повышают значение CO2 в комнате до >5000 ppm!

Вот и видео того, что получилось.

Заключение

Безусловно, полезная вещь, правда? Единственное, что дорогая… Хочу еще измерить уровень CO2 в маршрутке по пути на работу: иногда она так забивается, что реально нечем дышать, лицо краснеет и хочется вдохнуть глубже, потому что по ощущениям — не хватает воздуха. Как думаете, какая там набирается концентрация этого газа? =)

И до готового устройства ко всему выше неплохо было бы добавить:

  • DHT-11 (DHT-22) — датчик температуры и влажности, тоже показатель качества воздуха
  • MQ-2 — датчик взрывоопасных газов бутана и метана, а также дыма, вместе с какой-то пищалкой, чтобы не пропустить момент утечки газа или возгорание
  • дисплей LCD1602 или 2.4″ TFT экран, чтобы видеть результаты на экране, без подключения к компьютеру
  • блок питания, чтобы не зависеть от USB порта компьютера
  • корпус, что само собой красота и юзабилити
  • можно добавить модуль для работы с SD-карточками и часы реального времени и писать туда статистику, а потом перенести на компьютер и в excel построить графики; а можно приделать wifi / ethernet модуль и настроить на компьютере какой-нибудь веб сервер xampp, и записывать статистику туда
  • и, повторюсь, сделать питание датчика напрямую от блока питания (мимо платы arduino) — надежнее так…

Еще можно много чего прикрутить: реле, которое включит камин, если в комнате холодно; вытяжку/приток воздуха, когда в комнате становится душно; и так далее… но это уже тянет в области умных домов и выходит за рамки статьи! А мне остается пожелать…

Удачных вам экспериментов!

57 thoughts on “Измеряем концентрацию углекислого газа (CO2) с MH-Z14

  1. Сергей says:

    Почему используются аналоговые входы для эмуляции serial, а не цифровые?

  2. André says:

    АЛЕКС Привет я делаю исследования на моем колледже для определения уровня CO2 в классных комнатах. Я использовал датчик MQ135, но не может использовать, так что я видел ваше видео на YouTube, и я решил купить датчик MH-Z14. У вас есть пример: «http://2.bp.blogspot.com/-t1uvjNZl66g/UtQ2fH5MRXI/AAAAAAAAByM/0idIB5adptY/s1600/Arduino+Protoboard+-+Sequencial.png»
    чтобы показать, как сделать связи между датчиком, Arduino и преобразователь логического уровня

    Я использую Google переводчик извините ничего!

    Спасибо!
    ________________________________________
    Hello Alex Santehnik I’m doing a college research to read the CO2 level on class rooms. I was using the MQ135 sensor but no sucess, then I saw your video on youtube and I decided to buy a MH-z14 sensor. Do you have a example like this: «http://2.bp.blogspot.com/-t1uvjNZl66g/UtQ2fH5MRXI/AAAAAAAAByM/0idIB5adptY/s1600/Arduino+Protoboard+-+Sequencial.png» To show me how I do the conections between the sensor, the arduino and the «Logic level converter»

    Thanks!!

      • Luiz says:

        How did you calibrate? or it came already calibrated when you bought?

        Как калибровать? или он пришел уже откалиброван, когда вы купили?

        • Alex Santehnik says:

          Если датчик постоит некоторое время без питания (не засекал точно сколько времени), нужно дать ему пол минуты — минуту на разогрев, пока он выводит случайные значения (как правило — большие). Можно выставить таймер какой-то в ардуине, чтобы перезагрузить ее через минуту. После перезагрузки идут корректные значения.

  3. Luiz says:

    Do you have some assurance of the correct value?

    Есть ли у вас какие-то гарантии правильного значения?

  4. Alexsey Djatlov says:

    в районе 760 ррм — 950ррм происходит резкий скачек (больше 1000ррм) цифровых значений, хотя на аналоговом выходе все нормально. В чем может быть дело?

    • Alex Santehnik says:

      Да, бывают скачки… я их сглаживаю, беря среднее последних трех значений. Почему прыгает? У меня прыгал при разных значениях; возможно из-за неравномерного движения воздуха. Цифровой, по идее, точнее.

      • Alexsey Djatlov says:

        Спасибо за ответ? Alex! Но тут происходит явный ЦИФРОВОЙ сбой, что то с разрядами происходит или внутри контроллера датчика или при передаче. Потому, что никаких скачков на аналогом выходе не случается. Хорошо видно, что по аналогу концентрация плавно спадает, в то время как цифра прыгает вверх, причем сильно(с 764 сразу 1025 например), и именно на этих пределах!… Может это брак контроллера датчика?
        Я подключал его и к нано и к уно эффект тотже. Для согласования уровней RX, TX использую микруху TXS0108e.

    • Alex Santehnik says:

      Глубже этот вопрос не изучал. В интернете крайне мало информации по этому датчику, так что все методом тыка. Как обойти (усреднением значений) я написал, а в чем именно причина точно… мне неизвестно! Одни предположения )

    • Alex Santehnik says:

      В коде есть комментарии… что делает код? Периодически опрашивает датчик по serial интерфейсу и выводит значения на экран компьютера (тоже через serial)

  5. Serg Kitain says:

    Вы сравнивали значения на разных выходах датчика? UART, PWM, 2 аналоговых? У меня PWM показывает стабильно в 2.5 раза меньше значение чем аналоговые( возможно, это ошибка в документации в формуле расчета. Она приведена для датчика с диапазоном 0-2000, а у меня датчик 0-5000. Как раз получается 2.5). Два аналоговых выхода показывают примерно идентичные значения. UART до 1000 значения сильно занижает по сравнению с аналоговыми выходами (400-500 на uart и 700-900 на аналоговых). После 1000 значения выравниваются. Какому выходу стоит верить?

    • Alex Santehnik says:

      Нет, не сравнивал. Подключал только по цифровому каналу. Адекватность значений проверил эмпирически: нашел таблицу, что на улице значения в диапазоне 300 — 450 ppm. В закрытом помещении выше 2000 ppm реально становится душно.

    • Dima Darin says:

      PWM output
      CO2 output range: 0ppm-2000ppm
      Allowed max. current for OC: 5mA maximum
      Cycle: 1004ms±5%
      High level output for beginning: 2ms (in name)
      Middle of cycle: 1000ms±5%
      Low level output for ending: 2ms(in name)
      Account formula for CO2 concentration which get through PWM:
      Cppm=2000*(Th-2ms)/(Th+Tl-4ms)
      Among: Cppm is calculated CO2 concentration, unit is ppm;
      Th is time for high level during an output cycle;
      Tl is time for low level during an output cycle.

    • Egor says:

      Совершенно верно, формула должна содержать максимальное значение конечно же, то есть 5000, а не 2000

  6. Alex G says:

    А у меня этот датчик, проработав непрерывно 2.5 недели, стал показывать значение 400ppm (проверял через PWM и UART). Хотя, при повышении концентрации СО2, показания тоже увеличиваются, но при снижении концентрации — снова возвращаются на 400. На улице показывает тоже 400 и ниже этого значения не падает.
    Причем, он начинает выдавать эти 400ppm сразу после включения, т.е. без прогрева.
    До этого, 2.5 недели датчик работал как надо, но, как отмечали выше, показания иногда тоже «прыгали».
    Что теперь с ним делать — непонятно.

    • Alex Santehnik says:

      В темноте он моргает красным светом, если присмотреться? Как вариант, испортился ИК-светодиод или ИК-приемник…

      • Alex G says:

        Дык в том-то и дело, что и моргает и показания выдает, только неправильные.
        Причем, по-моему, самое странное, что сразу 400 выдает после включения, а раньше показания несколько минут были нереальные.
        Пробовал отсылать команды на калибровку, но, в результате, ничего не меняется.
        При считывании температуры выдает значение 63 (хотя, так было и тогда, когда правильно работал). Для градусов — многовато, для фаренгейтов — маловато.
        Думаю, что еще с ним можно сотворить..
        Заказал для экспериментов MH-Z19. Посмотрим, как он себя через 2 недели работы поведет)))

    • Egor says:

      Я с этим столкнулся когда подключил его к другому источнику питания — оказалось питания датчику не хватало для правильной работы. Кстати, в комплекте с ним у меня и DHT11 работает — он от плохого питания начал просто занижать температуру и влажность процентов на 30. Вернул обратно хороший БП — все заработало.

  7. Тима says:

    У меня обратная задача: необходимо поддерживать концентрацию углекислого газа до 10% об (до 100000 ррм). Есть газовый баллон, магнитный клапан, могу ли я с помощью этого устройства запрограммировать, чтоб он автоматически поддерживал необходимую концентрацию (разную по времени)? и могу ли я к этому же устройству подключить датчик температуры, влажности, увлажнитель и нагреватель?

    • Alex Santehnik says:

      Этот датчик CO2 работает в диапазоне 0-5000ppm, поэтому в вашем случае необходим какой-то промышленный датчик с подходящим диапазоном.

  8. Egor says:

    Сегодня тестировал MH-Z14, по PWM действительно выдаёт в 2.5 раза меньше реального значения, по UART показывает правильно. Для сравнения сравнивал с проверенным дорогим датчиком K-30.
    По поводу «всегда показывает 400, если подышать — покажет выше» — у этого датчика нижний порог 400, он просто не покажет ниже цифру, так что тут лито у вас действительно хороший воздух, либо он правда глючит.

    • Egor says:

      На самом деле по PWM тоже все правильно, только формула должна быть не 2*(Th — 2), а 5*(Th — 2), датчик ведь от 0 до 5000, а не до 2000, просто инструкция видимо была сделана для модели до 2000, вот и забыли исправить.

  9. Dzmitry says:

    Уважаемый Alex Santehnik, спасибо за интересную статью. Собрал схему как у Вас, но почему-то не работает. Показывает какие-то большие значения (даже на улице >700, а в доме >1600). Если подышать на датчик то доходит до 4790. Поясните, пожалуйста, соединения по схеме: A0 и A1 подключать к TX0 и RXI конвертера? Какие светодиоды на Arduino моргают во время работы (у меня вспыхивает TX, а RX — нет). Не могу понять в чём дело. Как можно подключить датчик к Arduino по другому? Можно ли использовать контакты Tx, Rx вместо A0, A1?

    • Alex Santehnik says:

      Используйте любые, кроме цифровых tx и rx, потому что их занимает arduino при подключении к компьютеру.

  10. Julie says:

    Привет, Алекс,
    Я пытаюсь использовать датчик MH-Z14 (0-5000ppm) с моей плате Arduino Uno. У вас есть схема, как вы подключили датчик к преобразователю питания к плате? Или вы могли бы сказать мне, какие контакты соединяются друг с другом на каждом устройстве? Я очень новичок в Arduino и электроники в целом. Я также хотел бы знать, что источник питания, к которому подключен датчик? Моя Arduino плата питается от моего ноутбука с помощью кабеля USB. Спасибо! (И я прошу прощения, это было написано с помощью Google Translate)

    • Alex Santehnik says:

      Если на arduino uno больше ничего не висит, кроме MH-Z14 — можно питать от самой платы UNO. До 200mA плата спокойно отдает от 5V.

  11. Сергей says:

    «Если датчик постоит некоторое время без питания (не засекал точно сколько времени), нужно дать ему пол минуты — минуту на разогрев»

    А сколько потребляет датчик во время «разогрева»?

  12. Владимир says:

    Я поставил MQ135. Цена на порядок ниже, а для дома высокой точности не нужно. Бонусом- реагирует на кучу других вредных газов.

    • Alex Santehnik says:

      Есть определенные минусы у датчика MQ135: 24 часа первоначальной калибровки. 10 минут для прогрева выхода на нормальные значения при следующих запусках. Необходима подстройка каждого конкретного датчика (изменение множителя в коде), а для этого нужно иметь эталонные значения. Диапазон измерения CO2 от 300 до 2000ppm — это маловато для измерения в комнате, где значение CO2 колеблется от 400ppm (свежо) до 6000 (крайне душно, как правило в комнате с закрытой дверью и окном после ночи сна вдвоем). Однако, другие газы хорошо определяет.

      • Владимир says:

        24 часа первоначального прогрева, для меня не проблема. Процедура делается только один раз за всё время использования датчика. Высокая точность, лично мне не нужна, да и доводить до 6000, тоже не нужно. Вентиляция включается гораздо раньше. Не считаю нужным переплачивать в 30 раз за точность.

        • Alex Santehnik says:

          Для вашей задачи MQ135, конечно, подходит. Я лишь перечислил минусы MQ135 для детектирования CO2. Безусловным плюсом MQ135 является очень низкая цена.

  13. Максим says:

    Подскажите, выходы DAC1 и DAC2 которые выдают 0-2в — там какой диапазон выдаётся, до 2000 ppm или 5000? Может кто нибудь сравнить вывод ppm uart и напряжения этих выходов?

    • Илья says:

      А зачем вам DAC? Если у вас нет TTL-преобразователя, то используйте PWM выход. Да, возможно вы читали даташит и увидели там пример, в котором сказано, что при чтении сигнала с PWM диапазон измерения ограничен 2000ppm, но в действительности это не так. PWM выдает значения в диапазоне до 5000ppm, это показал сравнительный анализ с результатами, получаемыми через UART. Тут выше писали, что UART дает меньшую точность чем PWM в диапазоне ниже 1000ppm, но вот у меня выдаваемые данные полностью идентичны.
      Вы наверное видели вот эту формулу:
      Cpp=2000*(Th-2)/(Th+Tl-4)
      Так вот, она неправильная. Для нашего датчика формула должна быть вот такой:
      Cpp=5000*(Th-2)/(Th+Tl-4)
      И кстати скетч, который умеет читать данные с PWM вы найдете вот здесь: http://www.2150692.ru/faq/87-co2-mhz19-arduino
      Он для другой версии датчика, но и для z14 работает.

      Использовать PWM для данного датчика вообще гораздо удобнее, ну если речь идет о подключении к ардуино. Хотя UART конечно дает больше уверенности в правильности считанных значений.

    • Илья says:

      Привет еще раз.
      Что касается выходов Vout1 и Vout2 (DAC1 и DAC2), то с ними все сложнее, чем можно было бы ожидать.
      Оказалось, что на них с периодичностью в 270 секунд происходят скачки напряжения (длительность скачка напряжения — 135 секунд). С чем это связано я точно не знаю, но на выходе PWM никаких скачков не наблюдается:
      https://dl.dropboxusercontent.com/u/585158/sensors.jpg
      Так то можно было бы подобрать коэффициенты и использовать Vout1 и Vout2, хотя бы потому, что на первый взгляд это проще, чем PWM и здесь не нужно считать длительность импульса. Но в свете полученных данных о скачках напряжения использование Vout1 и Vout2 все же кажется не таким простым как могло бы быть.

  14. Илья says:

    Привет. Подключил как показано, 5 вольт с отдельного источника питания. Датчик выдает всегда 0 ppm, при этом на датчике мигают маленькие квадраты по краям. Что я делаю не так? Вот как подключено:

    https://www.dropbox.com/s/86f57tam5q7tuga/2016-04-02%2022.54.34.jpg?dl=0

    Кстати говоря, крупные прямоугольники как на картинке сквозь белую наклейку не просматриваются. Не нужно ли там ее случаем отклеивать?

    • Alex Santehnik says:

      Отклеивать не нужно. Это сетка из какого-то синтетического материала. CO2 через нее хорошо проходит.
      На сколько я вижу по фоткам — у вас нет общей земли. При питании от разных источников — нужно чтобы земля (минус) от одного источника была соединена с минусом другого. Попробуйте, отпишитесь. Для проверки самого датчика, запитайте его прямо от дуины.

      • Илья says:

        Спасибо, я разобрался. У меня было целых две ошибки — леонардо похоже не может работать в режиме SoftwareSerial на А0 и А1 (ну по крайней мере в инструкции о них ничего не сказано и поэтому я перекинул SoftwareSerial на 10 и 11 цифровые пины), а во-вторых я не менял местами выходы с преобразователя логических уровней.

  15. Влад says:

    Подскажите, какую температуру показывает датчик?
    у меня 4 битом приходит 62 или 63, что это за градусы непонятно.
    Значения CO ниже 600 на улице не падают( живу за городом.

    • Илья says:

      В комментах выше пишут, что минимальный диапазон 400ppm и показания ниже он просто не отображает. У меня такое было как началось лето и мы открыли окна. Я какое то время думал, что датчик сломан, но оказалось, что он просто лежал на сквозняке. Я живу на границе города.
      Если окна закрыты, то поднимается до 1600 и выше.
      Температура тоже отображается в районе 63

      • Влад says:

        Не очень понятно, что это за температура…
        А с показаниями разобрался. Он вылежался фактически на улице и показания стали адекватными 435 на улице. У него самокалибровка же. Жаль в мануале не написано более подробно как и когда она действует.

  16. Andrey says:

    Просто скопировав код для теста был рад что датчик отвечает. Но радость была не долгой, так как показания датчика иногда МЕНЯЛИСЬ СКАЧКАМИ в 255 ppm. Что навело меня на мысль о косячности датчика или кода. И косяк был найден в КОДЕ!!! Почитав отзывы вижу что многие это заметили. Так вот МЕНЯЙТЕ ТИП char response[9]; на byte response[9]; И ВСЕ ЗАРАБОТАЕТ КАК НАДО!!!

  17. Param says:

    Подключил напрямую к ардуине без конвертера, так как в даташите сказано «Interface level 3.3 V (5V compatible)» и всё работает.

Добавить комментарий