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

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

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



    • 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, TX/RX в A0/A1, питание в 5В, землю — в Gnd:



    Позаимствованный скетч, в который добавлена проверка контрольной суммы
    #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 секунд. Значения перестали прыгать когда я отошел от сенсора.


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


    Убедившись, что все работает, уберем Arduino, заменив его на FTDI FT232RL.


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


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

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

    У меня всего один датчик и я очень не люблю разбирать то, что однажды сделал, поэтому предлагаю выбрать вам.
    Что сделать с датчиком?
    • 11%Подключить к компьютеру и написать десктопное приложение для мониторинга32
    • 16%Добавить его в погодную станцию42
    • 7%Сделать гаджет для мобильного устройства18
    • 63%Добавить к нему ESP8266, превратив в минималистичный компонент для «умного дома»166
    • 3%Свой вариант в комментарии7

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

    Метки:
    Поделиться публикацией
    Похожие публикации
    Реклама помогает поддерживать и развивать наши сервисы

    Подробнее
    Реклама
    Комментарии 69
    • +2
      Как раз получил такой же и планирую подключить с ESP8266.
      Насколько этот датчик врёт? Есть какой-то другой прибор для измерения что бы сравнить?
      • +1
        У меня не с чем сравнивать.
        В комментариях на Али пишут: I compared the results with EXTECH-CO250 and MH-Z19 seems to be very accurate.
        Статья, где его сравнивают с другим похожим датчиком: http://foogadgets.blogspot.com/2016/02/new-co2-sensor-support-for-wms-mk3.html
        • +1
          Спасибо за линк. Предполагаю, что точность ещё может от экземпляра зависеть.
          Я заказал более "взрослое" устройство для измерения CO2, но пока не получил. Попробую с ним сравнить тогда.
          • 0
            О, будет замечательно, если вы выложите результаты сравнения.
            • 0
              а можно модель более "взрослого" устройства узнать?
              • 0
                Обычно оно идёт как модель HT2000.

                Заголовок спойлера
                image
                • 0
                  Благодарю, я почему-то подумал о другом, принципиальном решении.
                  Предполагал голую железку с датчиком и контроллером.
                  Для иных целей требуется
              • 0
                Скажите, пожалуйста, удалось сравнить? Присматриваюсь сейчас тоже к этому датчику.
                • 0
                  К сожалению, руки не доходят. Могу только сказать, что слышал с других источников много позитивных отзывов про MH-Z19.
                  • +1
                    Если поможет — мой датчик MH-Z19.
                    Ночью в комнате спит 1 человек, закрыта дверь, окно на микропроветривании. Днем соответственно окно открыто, комната открыта.
                    В принципе, показания похожи на правду. Сравнить с чем-либо еще нет возможности.
                    Датчик подключен к ESP8266 по serial интерфейсу, прошивка написана в Arduino IDE. Работает больше 2-х месяцев непрерывно.
                    На влажность и температуру не обращайте внимания, стоит дешевый DHT11, температура еще на что-то похожа, а по влажности скорее всего врёт.
                    https://thingspeak.com/channels/98389
                    • 0
                      Отдельное спасибо за ссылку на thingspeak.com — как раз подумывал о том, как бы все это дело удобно визуализировать без лишних телодвижений.
              • 0
                У нас в офисе уже почти год висит девайс на MH-Z14 (предыдущая версия датчика от того же производителя, протокол такой же) и ESP8266.

                Как выглядит

                Благодаря ему нашли проблемы с вентиляцией.
                Сейчас уже используем MH-Z19, датчик работает стабильно, но на мой взгляд слегка занижает показания CO2 (при открытом окне через полчаса после завершения рабочего дня выдаёт 400 ppm, при том что уровень CO2 в атмосфере уже слегка превышает эту отметку), либо у нас в городе (Ярославская область) очень чистый воздух.
                • 0
                  Жду MH-Z14. Решил заказать его. Если это младшая модель, почему она немного дороже? У нее есть преимущества?
                  • +1
                    Кажется, мне нельзя вставлять картинки (read&comment аккаунт), поэтому вот ссылка, как выглядит девайс:
                    https://habrastorage.org/files/dd6/f94/c3d/dd6f94c3d4ca44888d2d287074a660b7.jpg
                    Вроде как из видимых отличий — только наличие DAC-выхода у MH-Z14 и более высокая скорость реакции (не очень актуально для измерения CO2, его концентрация нарастает очень плавно).
                    Скорее всего оптимизировали производство, сократили себестоимость и таким образом продвигают новый продукт.
                    Для нас MH-Z19 оказался наилучшим вариантом, т.к. имеет гораздо меньшие габариты, два окна воздухозабора и потребляет почти в 3 раза меньше энергии.
                    • 0
                      Все ясно. Значит зря переплачивал, если он хуже или такой-же за большие деньги.
                      • 0
                        Напишите публикацию про это. Какой средний потребляемый ток? Как часто просыпается для измерений и передачи данных?
                        • 0
                          А брали на али или ебее? Дорогой модуль?
                          Сейчас по 7 тысяч они.
                          • 0
                            все нашел.Вопрос исчерпан
                        • 0
                          Чтобы датчик показывал истинные значения его требуется периодически калибровать на специальных смесях газов, в противном случае неизбежен дрейф показаний. Не знаю как в этом датчике, но K-22, K-30 (или во всяком случае приборы на их основе) имеют, так называемую ABC калибровку, они принимают за 400 ppm самый свежий воздух которые видели, кажется, за неделю, при этом сдвиг не может превышать 50 ppm. Соответственно такой прибор показыват не концентрацию CO2, а «отношения» к концентрации за окном. Ну а если хочется именно настоящие показания, то без калибровки по смесям не обойтись, причем делать это придется раз полгода-год.
                      • 0
                        Если к PWM подключить интегрирующую цепочку, получится замечательный аналоговый выход.
                        • +1
                          Суровая получится rc-цепочка. Частота ШИМа-то 1гц.
                          • 0
                            Электролит на 5000 мкФ ничуть не суров.
                            • +2
                              Электролит в измерительной цепи? Хорошая шутка.
                              • 0
                                Это смотря какая точность нужна.
                        • 0
                          Спасибо за обзор. Как раз собираю домашнюю метеостанцию на esp — пригодится.
                          • 0
                            Предложу два варианта, второй предпочтительнее IMHO:
                            1) подключить к GPIO малины и написать bash/perl/… скрипт
                            2) подключить к PL2303 и написать bash/perl/… скрипт для того чтобы можно было подключать к роутерам (MR3020, etc), компьютерам и прочему без привязки к платформе

                            • 0
                              А чем плох вариант с FT232RL?
                              • –1
                                Ну или FT232RL, речь о реализации готового скрипте, который будет выводить в ответ человекочитаемые значения (как в примере через ардуину), проверяя CRC-суммы и проч (скажем, предусмотреть возможность указания номера датчика, если есть модели с несколькими датчиками и т.д.).
                                Т.е. чтобы было что-то типа
                                ```~# ./getco2.sh
                                785
                                Возможно, сразу предусмотреть обнаруженные вами проблемы, скажем с ключом --check выводить предупреждения, если значение является заведомо ошибочным (скажем ниже 300) или скачет (например, запрашивая дважды с интервалом в 10-15 сек, если значения разнятся (учитывая ваши примеры ошибок)).
                                • +1
                                  Не думаю, что стоит оформлять это отдельной статьей, хотя если кому-то нужно, то могу раскрыть тему подробнее.

                                  В конфиге ядра должен быть ключ: CONFIG_USB_SERIAL_FTDI_SIO=m
                                  При подключении девайса в dmesg появится что-то типа:
                                  ftdi_sio 2-1.7:1.0: FTDI USB Serial Device converter detected
                                  usb 2-1.7: FTDI USB Serial Device converter now attached to ttyUSB0
                                  Получить название порта можно командой: ls /dev/ttyUSB*
                                  Чтобы номер не скакал, его можно намертво прибить с помощью udev.
                                  Для работы perl-скрипту нужна библиотека Device::SerialPort, легко ставится через cpan или вручную.

                                  Скрипт будет выглядеть так
                                  #!/usr/bin/perl
                                  
                                  use strict;
                                  use Device::SerialPort qw( :PARAM :STAT 0.07 );
                                  
                                  # ls -al /dev/ttyUSB* or set manualy
                                  my $port_id = `ls /dev/ttyUSB*`;
                                  chomp $port_id;
                                  $port_id =~s/\s+.+//;
                                  print "Using port: $port_id\n";
                                  
                                  my $ob = new Device::SerialPort($port_id, 1) || die "Can't open $port_id: $!\n";
                                  
                                  $ob->baudrate(9600);
                                  $ob->parity('none');
                                  $ob->databits(8);
                                  $ob->stopbits(1);
                                  $ob->handshake('none');
                                  $ob->write_settings();
                                  
                                  $ob->write("\xFF\x01\x86\x00\x00\x00\x00\x00\x79");
                                  sleep 1;
                                  
                                  my $c = $ob->input || die "Read fail";
                                  my @data = map {ord($_)} split('', $c);
                                  
                                  my $crc = 0;
                                  $crc+=$data[$_] for (1..7);
                                  $crc = (($crc & 255) ^ 255) + 1;
                                  die "CRC error: $crc / $data[8]" if ($crc ne $data[8]);
                                  
                                  my $co2 = $data[2] * 256 + $data[3];
                                  print "OK: $co2\n";
                                  
                                  $ob->close();


                                  Это черновик, хотя и рабочий. Вместо ожидания девяти байт ответа, я поставил просто sleep 1 — датчик за такое время гарантированно успеет ответить (или с ним что-то не в порядке). Ждать три минуты не имеет смысла — датчик готов к работе через три минуты после физического подключения, а не через три минуты после установления связи, так что если он постоянно воткнут в USB, то всегда готов к работе. Но вы, конечно же, можете смотреть время подключения по dmesg.
                            • +1
                              Раз уж проголосовал за свой вариант — закажу и сделаю пока что простейший показометр с маленьким дисплеем (четыре семисегментника) на AVR. А потом уже подумаю, куда его внедрить.
                              • 0
                                Четвёртый вариант из голосования (погодная станция с ESP8266) я как раз делал. По SoftwareSerial тоже. Можете в ссылки добавить — по комментариям видно, что много кого интересует, а время на повторное написание имеющегося кода тратить не очень осмысленно. Кстати, опрашиваю раз в 5 секунд — проблем не замечено. У меня, кстати, инициализируется и выдаёт корректные данные после второго обращения, ждать 3 минуты не нужно — а как у вас? И реагирует на изменение обстановки мгновенно. Да, вы проверяли контрольную сумму? И у меня и у другого программиста из моего топика она упорно не сходилась, так что в результате остановились на проверке первых трёх байт.

                                • 0
                                  Конечно добавлю, хотя результатов голосования это не отменит.

                                  Опрашивать датчик можно хоть сразу, но с холодного старта он будет выдавать ошибочные значения. Однако есть тонкость — если вы датчик просто перезапустили, то ждать не надо.

                                  Насчет контрольной суммы — она у меня сходится, даже в статье пример взят с реальных данных. Если у вас не сошлась, то предположу, что проблема или в unsigned, или в том, что вы не ограничили ее одним байтом. Попробуйте вручную посчитать — там всего-то 8 операций.
                                • 0
                                  Что сделать с датчиком?
                                  Добавить индикатор, таким образом получить полнофункциональное устройство аналогичное:

                                  image
                                  но ВДВОЕ дешевле. Датчики температуры и влажности по вкусу.
                                  • 0
                                    Справедливости ради скажу, то не вдвое. MH-Z19 стоит уже сам по себе заметных денег, а ещё нужен корпус, дисплей, ардуина и желательно датчик температуры и влажности. У меня вот получилось за 44$, что на данный момент равно 3224р. Даджетовский сейчас, судя по сайту, стоит 4950 — дороже в полтора раза. "Всего" или "в целых" полтора раза — это уже от ваших потребностей, способностей и достатка зависит.

                                    • +2
                                      Даджетовский сейчас, судя по сайту, стоит 4950 — дороже в полтора раза.
                                      Вполне адекватная цена, у меня как раз такой — отличная вещь.
                                      Но далеко не все считают эту цену приемлемой.
                                      В 2500 вписаться легко можно: датчик, attiny2313 (удобный UART, ножек в достатке, кварц не нужен на таких скоростях), индикатор на выбор ЖК или цифровой-LED и по-мелочи — пара конденсаторов.
                                      Пожалуй и на температурный датчик останется )

                                      Если уж считаем копейки, то ардуино здесь лишнее.
                                      • 0
                                        Ардуино нынче меньше 2$ стоит — не дороже датчика температуры, это уже совсем копейки.
                                        Сэкономить значимо можно разве что на корпусе — если руки не кривые, можно из чего угодно собрать.

                                      • +1
                                        Да, как-то так.

                                        MH-Z19 — 26$
                                        Arduini Mini Pro — $1
                                        ESP8266 — 1.5$
                                        LCD 16x2 — 1.5$
                                        DHT22 — 2.5$
                                        BMP180 — 1.5$
                                        Итог: 34$

                                        Плюс расходы на изготовление платы, корпуса и разная мелочь.
                                        • 0
                                          А зачем здесь Arduino?
                                          • 0
                                            У ESP выводов маловато. Мне удобнее повесить все датчики, экран, кнопки и индикаторы на Arduino, оставив за ESP лишь коммуникацию и управление. На общем потреблении энергии это почти не скажется, место тоже экономить смысла нет.
                                            • 0
                                              Берите arduino compatible плату на ESP — будет одна плата с кучей выходов и интернетом. У меня вот используется wemos d1.
                                    • +2
                                      Я свою метеостанцию как раз на этом датчике собрал, только с ШИМ. По своим впечатлениям скажу что датчику действительно нужно 3 минуты разогрева чтобы начать работать более менее адекватно, и около 1-3 дня работы для повышения чувствительности. Когда его включил в систему первый раз, то был немного разочарован так как в большой комнате по началу он не замечал присутствия 1 человека, но поработав пару дней научился этому. Сейчас даже чувствует присутствие человека находящегося в другой комнате в квартире размером в 100м2. «Чистое» значение воздуха находится в пределах 420 ppm.
                                      • +2
                                        Тоже экспериментировал с этим датчиком. Повторюсь здесь, а то в обзоре нет информации по потреблению питания.

                                        Напряжение питания должно быть больше 3.6В, если оно будет ниже, то датчик начинает сильно завышать показания.
                                        Потребление тока у датчика импульсное, при напряжении 5В большую часть времени ток 4 мА, но каждые 6 сек потребление возрастает до 100 мА, длительность импульса меньше секунды.
                                        То есть датчик производит измерения раз в 6 секунд, и нет смысла опрашивать его чаще.
                                        Ранее написал маленькую программу — построитель графика CO2 для этого датчика, может, кому нибудь пригодится.
                                        Сложилось ощущение, что датчик начинает работать точней, проработав хотя бы полдня.
                                        Сейчас делаю автономный прибор для измерения CO2, с возможностью строить графики и передавать данные на компьютер при помощи NRF24L01:

                                        • +2
                                          В темноте, кстати, через фильтры видно пульсацию диода во время замеров.
                                          • 0
                                            Все рекомендуют не давать на этот датчик больше 3.3v, а вы говорите что напряжение должно быть больше чем 3.6v, кому верить или я что-то не правильно понял?
                                            • 0
                                              В даташите четко сказано: Working voltage 3.6 ~ 5.5 V DC, Interface level 3.3 V.
                                              Можете дать примеры ссылок, где не рекомендуют подавать больше 3.3V?
                                              • 0
                                                На самом деле вы правы, это я ошибся. Меня смутило написанное здесь https://geektimes.ru/post/278178/
                                                — Т.к. датчик имеет 3-вольтовую логику, обычные Arduino лучше не использовать.
                                                я не сразу разобрался что значит «3-х вольтовая» логика + на фотографии видно что автор подключил датчик к VCC выходу 3-х вольтовой ардуино, а судя по datasheet с нее выходит 3.3 вольта: https://learn.sparkfun.com/tutorials/pro-micro--fio-v3-hookup-guide
                                                — it’ll be either 3.3V or 5V respectively. This voltage is regulated by the voltage applied to the RAW pin. If the board is powered through the ‘RAW’ pin (or USB), this pin can be used as an output to supply other devices.
                                          • 0
                                            Отвлеченный вопрос — А как ESP8266 подключить что угодно с PWM? По-видимому, нужны какие-то дополнительные внешние компоненты, но какие?
                                            • 0
                                              В случае "что угодно" может быть понадобится согласовать уровни 3.3/5.
                                              • 0
                                                Не, это я понимаю. У ESP есть только GPIO ноги, видимо нужен внешний АЦП, вот я и хочу узнать какой можно использовать.
                                                • 0
                                                  PWM — это не аналоговый сигнал.

                                                  image
                                                  К слову АЦП там есть http://esp8266.ru/forum/threads/tochnost-adc.598/
                                                  • 0
                                                    Спасибо. У меня в голове каша :) Это чтобы выдавать на GPIO ноге определенное напряжение используют PWM, а не наоборот
                                                    • 0
                                                      PWM — ШИМ. Широтно Импульсная Модуляция — Импульсы разной длительности, что отображает картинка выше.
                                                      А "определенное напряжение" — этим занимаются ЦАП(DAC) — Цифро-аналоговые преобразователи.
                                              • 0
                                                А, я все понял. Это у меня неудачная плата esp8266 на которой не распаян ADC. Вопрос снимается.
                                                • 0
                                                  Ничего не нужно. Ловите переходы GPIO HIGH/LOW и засекаете время каждого состояния. Время, пока GPIO был HIGH — это и есть Thigh в формуле, Tlow — соответственно.

                                                  Для Arduino код выглядит так
                                                  void loop() {
                                                    long tt = millis();
                                                    int myVal = digitalRead(pwmPin);
                                                  
                                                    //Если обнаружили изменение
                                                    if (myVal == HIGH) {
                                                      digitalWrite(LedPin, HIGH);
                                                      if (myVal != prevVal) {
                                                        h = tt;
                                                        tl = h - l;
                                                        prevVal = myVal;
                                                      }
                                                    }  else {
                                                      digitalWrite(LedPin, LOW);
                                                      if (myVal != prevVal) {
                                                        l = tt;
                                                        th = l - h;
                                                        prevVal = myVal;
                                                        ppm = 5000 * (th - 2) / (th + tl - 4);
                                                        if (ppm < 5000 && (!last_ppm || ppm > last_ppm + 10 || ppm < last_ppm - 10)) {
                                                          last_ppm = ppm;
                                                          Serial.println("PPM = " + String(ppm));
                                                        }
                                                      }
                                                    }
                                                  }

                                                  Это не лучший вариант, правильно было бы отслеживать изменения через прерывание, но вполне рабочий.

                                                • 0
                                                  Объясните, пожалуйста, как работает этот датчик. Если это он инфракрасный, то, чтобы получить точные значения содержания углекислого газа в воздухе, надо знать еще и влажность, либо как-то осушать воздух, поскольку у водяного пара и углекислого газа спектры поглощения в ИК-диапазоне частично совпадают. В одном из проектов по изучению фотосинтеза, в котором я принимал участие, воздух сперва проходил через холодильник, где конденсировалась лишняя влага, а затем через химический осушитель, и только после этого подавался на инфракрасный газоанализатор для определения содержания углекислого газа.
                                                  • +1
                                                    Судя по обрывочным сведениям о его младшем брате MH-Z14 и других NDIR-датчиках, он умеет измерять температуру и влажность, корректируя свои показания. MH-Z14 даже возвращал температуру пользователю.

                                                    Ваши приготовления, вероятно, были связаны с высокой точностью измерений, тогда как у Z19 точность ± (50ppm + 5% reading value).
                                                  • 0
                                                    Все-таки непонятно, по документации вход RX 5v tolerant или нет? В статье написано, «5В не рекомендуется», но модуль при этом воткнут в ардуину без каких-либо логических трансляторов.
                                                    • 0
                                                      Это разница между макетом для проверки и готовой схемой. На макете кратковременное подключение к 5В проблем не выявило, но я не знаю, что будет если подавать пять вольт в течение полугода. Поэтому в конечной схеме я бы использовал резисторный делитель.

                                                      Аналогично и с напряжением питания. Сенсор работает даже на 3.3В. Но производитель указывает в качестве напряжения питания 3.6 — 5.5В, причем отдельной строкой подчеркивает важность соблюдения этих рамок.
                                                    • 0
                                                      Хочу поделиться своим положительным опытом
                                                      Приобрёл MH-Z19 и FTDI FT232RL, подключил к TP-Link TL-WR2543ND
                                                      Установил прошивку OpenWRT 15.05
                                                      https://downloads.openwrt.org/chaos_calmer/15.05/ar71xx/generic/openwrt-15.05-ar71xx-generic-tl-wr2543-v1-squashfs-factory.bin
                                                      Активировал SSH-сервер, подключился, установил пакеты:
                                                      wget http://downloads.openwrt.org/chaos_calmer/15.05/ar71xx/generic/packages/packages/coreutils-stty_8.23-1_ar71xx.ipk
                                                      wget http://downloads.openwrt.org/chaos_calmer/15.05/ar71xx/generic/packages/packages/coreutils_8.23-1_ar71xx.ipk
                                                      opkg install kmod-usb-serial-ftdi
                                                      opkg install coreutils_8.23-1_ar71xx.ipk
                                                      opkg install coreutils-stty_8.23-1_ar71xx.ipk
                                                      Далее установил правильную скорость порта
                                                      stty -F /dev/ttyUSB0 raw ispeed 9600 ospeed 9600 cs8 -ignpar -cstopb eol 255 eof 255
                                                      В одном сеансе SSH выполнил
                                                      head -c 9 /dev/ttyUSB0 | hexdump -d | cut -c 19-23
                                                      В другом
                                                      echo -en '\xff\x01\x86\x00\x00\x00\x00\x00\x79' > /dev/ttyUSB0
                                                      Получил значение CO2 (ppm) в десятичном виде, например, 00787
                                                      • 0
                                                        Мм… все же стоит проверять контрольную сумму.
                                                        Я не силен в bash-программировании, но полагаю, что скрипт будет выглядеть как-то так:
                                                        #!/bin/bash
                                                        
                                                        RESP=`head -c 9 /dev/ttyUSB0 | hexdump -v -e '1/1 "%d" " "'`
                                                        RA=(${RESP// / })
                                                        
                                                        if [ "${#RA[@]}" -lt "9" ]
                                                        then
                                                            echo "Read error"
                                                            exit 1
                                                        fi
                                                        
                                                        CRC=0
                                                        for i in {1..7}
                                                        do
                                                            let CRC+=RA[$i]
                                                        done
                                                        CRC=$((256-$((CRC%256))))
                                                        CRC=$((CRC%256))
                                                        
                                                        if [ "$CRC" == "${RA[8]}" ]
                                                        then
                                                            let CO2=RA[2]*256+RA[3];
                                                            echo "CO2: $CO2"
                                                        else
                                                            echo "CRC error"
                                                        fi
                                                        
                                                        exit 0
                                                        • 0
                                                          Датчик проработал нормально с неделю и случилась беда: стал показывать всегда 5000 ppm; перезагрузил его, теперь постоянно показывает ровно 900 ppm
                                                      • 0
                                                        Еще раз спасибо за статью.

                                                        Получил датчик почтой. Ваш код заработал без проблем на Arduino Micro, добавил поддержку OLED, получился такой мелкий показометр:
                                                        Картинка

                                                        (с корпусом и дизайном пока не придумал)

                                                        Думаю какой-нибудь светодиодный столбик найти, чтобы показывать не в цифрах а в виде бара.
                                                        • 0
                                                          А почему использован software serial, а не hardware?
                                                          • 0
                                                            Удобнее отлаживать и заливать новую прошивку.
                                                            • 0
                                                              Спасибо большое! А может вы можете разъяснить вопрос с питанием? Вот здесь https://geektimes.ru/post/278178/ автор подключает датчик к VCC выходу этой платы Arduino Micro ATmega32U4 3.3V и судя по описанию здесь https://learn.sparkfun.com/tutorials/pro-micro--fio-v3-hookup-guide на 3.3 вольтовой версии платы с этой ноги снимается 3.3в соответственно. То есть он питает датчик 3.3в хотя нужно 5в? Я правильно понял, что автор этой статьи ошибся?
                                                              • 0
                                                                Напряжение питания (Vin) 3.6 — 5.5В. Сенсор работает и выдает у меня те же значения при питании 3.3В, но производитель настоятельно рекомендует придерживаться рамок. Кто-то выше прокомментировал, что у него при 3.3В сенсор завышает показания. Поэтому мой выбор — 5В на питание, плюс резисторный делитель для логики.
                                                          • 0
                                                            Спасибо за статью. Единственный коментарий по поводу:
                                                            но не стоит запрашивать данные по UART чаще раза в 10 секунд, иначе сенсор начинает выдавать что-то странное.

                                                            В моем случае странных результатов не возникало даже при запросе раз в секунду. Возможно в последних версиях сенсора научились правильно обрабатывать такие запросы.
                                                            • 0

                                                              Купил себе недавно MH-Z19, ≈1300р.
                                                              Буду собирать с двумя АКБ по 3,7в,
                                                              Низкошумящем линейным стабилизатором от телефона на 3.3В, дисплеем лёд(микро от электронной сигареты) данные сдать по блютуз.
                                                              Кто знает что там сзади за разъём шлейфа, его распиновка и тип(как найти ответную часть) за ранее благодарен если кто откликается и от пишется на root@roon-art.ru.
                                                              С уважением.
                                                              Кордубин С.С.

                                                              • +1

                                                                Забавно получилось. Довольно давно использую датчик с NodeMCU (Lua) и MH-Z19 через uart. И вот недавно (в железе и софте ничего не менялось) после перезагрузки данные «пропали». Дебаг показал, что вместо последовательности FF 86 cc cc xx xx xx xx ss как в этой статье и как общепринято, где где cccc = концентрация и ss = контрольная сумма, стала приходить последовательность 86 cc cc xx xx xx xx ss FF. То есть первый байт 0xFF стал приходить последним o_O В остальном параметры корректные. Результат 100% воспроизводится после reset'ов и выключения питания. Теперь только так.


                                                                Пришлось добавить в код учёт обоих случаев.


                                                                Так что имейте в виду, если кто-то на те же грабли наступит :)

                                                                Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.