Авторизация
Регистрация

Напомнить пароль

Датчик углекислого газа в воздухе (CO2) "MH-Z19B" - головоломка

Чтобы окончательно решить исход вековечной вражды в офисе между «теми, кому дует» и «теми, кому душно» решил разориться на бюджетный датчик содержания CO2 в атмосферном воздухе и прикрутить к нему сирену. Поскольку цена на такие датчики — совсем негуманная, выбрал вариант «MH-Z19B», который оказался самым бюджетным.

К сожалению, датчик подарил головоломку. Подробности — под катом.

(Внимание — в обзоре много «программизма», ругани в адрес китайских даташитов, присутствует шестнадцатеричная математика — так что если тема DIY вам не близка, проходите мимо, иначе будете разочарованы).

Датчик «MH-Z19B» сделан китайской компанией «Winsen» (даташит, PDF) и неоднократно упоминался на Habrahabr и Geektimes. Это вторая ревизия, с буквой «b» в названии, по результатам китайской «работы над ошибками». Первую ревизию одним неверным движением можно было ввести в режим калибровки, для которой требовалась атмосфера с нулевым содержанием CO2. Бедолагам, которые в это влетали, приходилось искать баллон с чистым азотом или кислородом, чтобы её организовать. В ревизии «b» китайцы сделали так, что модуль «эталонной» считает смесь с 400ppm углекислоты — то есть его можно, теоретически, перекалибровать просто в лесу или в парке.

Модуль пришёл в паре с небольшим шлейфом, основная плата имеет надпил, позволяющий отломать кусок с разъёмом и вместо этого припаять гребёнки. Модуль работает в двух режимах — UART (передавая показания по последовательному порту на 9600 бод) и PWM, контакты слева и справа, соответственно:



Для удобства я обрезал шлейф и насадил на провода дюпоновские наконечники. Правда, выяснилось, что часть проводов вообще ни к чему не подключена. Напротив, PWM оказался не выведен на шлейф, к контакту пришлось дополнительно подпаиваться, завернув из предосторожности датчик в плёнку поплотнее:



Датчик работает по следующему принципу — он получает по UART девятибайтовые команды (последний байт — CRC) и отвечает также девятибайтовыми пакетами. Замер концентрации СО2 выполняется командой с байтом 0x86:



Также показания можно прочитать, померяв ширину PWM-сигнала:



Тут подстерегала первая проблема — как узнать текущую размерность измерений? Даташит упоминает, что датчик может мерять в диапазаонах от нуля как до 2000, так и от нуля до 5000ppm:



Запросить текущее значение у датчика нельзя, поэтому остаётся только явно задавать размерность при каждом старте. Даташит описывает формат команды, которая скажет модулю, в какой шкале работать:



Почему-то ни одна инструкция в интернете этого вопроса не касается — никто толком не интересовался настройками датчика и просто принимают их как данность. Кряхтим и пишем код для Ардуино, который пошлёт модулю нужную команду:

  • 2000 ppm: «2000» в десятичной системе это «0x07 d0» в шестнадцатеричной, получается — третий байт команды будет 0x07, четвёртый байт — 0xD0, CRC (девятый байт) 0x8F
  • 5000 ppm: третий байт 0x13, четвёртый байт 0x88, CRC (девятый байт) 0xCB
(CRC вычисляем по формуле из того же даташита, (NOT(Byte1 + Byte2 + Byte3 + Byte4 + Byte5 + Byte6 + Byte7)) +1)

Пробуем и так, и эдак, но в результате получаем на выходе дикие неправдоподобные значения концентрации СО2, вылетающие за паспортные диапазоны показаний датчика в разы. Уже испугавшись, что запороли дорогой прибор, через какое-то время нагугливаем ссылку revspace.nl/MHZ19 со словами
According to the MH-Z19B datasheet, you can configure the measurement range by putting the desired range in byte 3 and 4. However, unlike what the MH-Z19B datasheet says, you can set the range using the following command (in this case 0x07d0 = 2000 ppm in byte 6 and 7)

Замечательные китайцы ухитрились ошибиться в даташите! Материмся, и вместо третьего и четвёртого байта пишем в шестой и седьмой. Благодаря подсказке неизвестного голландца — модуль воскресает.

Поскольку теперь доверия модулю нет никакого, решил разобраться с его показаниями досконально и сравнить результаты по UART и PWM. Пишем код под Ардуино, который сначала, в блоке setup, даёт команду установки размерности, а потом в цикле loop делает замеры. Модуль располагаем на сквозняке у форточки.

Код (финальный, уже включающий все позднейшие *открытия*
#include <SoftwareSerial.h>
#define pwmPin 10
SoftwareSerial swSerial(A0, A1); // RX, TX

void setup() {
  Serial.begin(9600); 
  swSerial.begin(9600); 
  pinMode(pwmPin, INPUT);

  /*
  Источник - https://revspace.nl/MHZ19
   2000 ppm range: 0xFF, 0x01, 0x99, 0x00, 0x00, 0x00, 0x07, 0xD0, 0x8F
   5000 ppm range: 0xFF, 0x01, 0x99, 0x00, 0x00, 0x00, 0x13, 0x88, 0xCB
  */

  // Этот вариант ("A") с записью команды в 6й и 7й байт - работает
  //           bytes:                         3     4           6     7
  byte setrangeA_cmd[9] = {0xFF, 0x01, 0x99, 0x00, 0x00, 0x00, 0x13, 0x88, 0xCB}; // задаёт диапазон 0 - 5000ppm
  unsigned char setrangeA_response[9]; 
  swSerial.write(setrangeA_cmd,9);
  swSerial.readBytes(setrangeA_response, 9);
  int setrangeA_i;
  byte setrangeA_crc = 0;
  for (setrangeA_i = 1; setrangeA_i < 8; setrangeA_i++) setrangeA_crc+=setrangeA_response[setrangeA_i];
  setrangeA_crc = 255 - setrangeA_crc;
  setrangeA_crc += 1;
  if ( !(setrangeA_response[0] == 0xFF && setrangeA_response[1] == 0x99 && setrangeA_response[8] == setrangeA_crc) ) {
    Serial.println("Range CRC error: " + String(setrangeA_crc) + " / "+ String(setrangeA_response[8]) + " (bytes 6 and 7)");
  } else {
    Serial.println("Range was set! (bytes 6 and 7)");
  }
  delay(1000);

/*  
  // Этот вариант ("B") с записью команды в 3й и 4й байт, согласно даташиту - НЕ работает и поэтому закомментирован
  //           bytes:                         3     4           6     7
  byte setrangeB_cmd[9] = {0xFF, 0x01, 0x99, 0x00, 0x00, 0x00, 0x13, 0x88, 0xCB};
  unsigned char setrangeB_response[9]; 
  swSerial.write(setrangeB_cmd,9);
  swSerial.readBytes(setrangeB_response, 9);
  int setrangeB_i;
  byte setrangeB_crc = 0;
  for (setrangeB_i = 1; setrangeB_i < 8; setrangeB_i++) setrangeB_crc+=setrangeB_response[setrangeB_i];
  setrangeB_crc = 255 - setrangeB_crc;
  setrangeB_crc += 1;
  if ( !(setrangeB_response[0] == 0xFF && setrangeB_response[1] == 0x99 && setrangeB_response[8] == setrangeB_crc) ) {
    Serial.println("Range CRC error: " + String(setrangeB_crc) + " / "+ String(setrangeB_response[8]) + " (bytes 3 and 4)");
  } else {
    Serial.println("Range was set! (bytes 3 and 4)");
  }
  delay(1000);
*/ 

}

void loop() {

  byte measure_cmd[9] = {0xFF,0x01,0x86,0x00,0x00,0x00,0x00,0x00,0x79};
  unsigned char measure_response[9]; 
  unsigned long th, tl, ppm = 0, ppm2 = 0, ppm3 = 0;

  // ***** узнаём концентрацию CO2 через UART: ***** 
  swSerial.write(measure_cmd,9);
  swSerial.readBytes(measure_response, 9);
  int i;
  byte crc = 0;
  for (i = 1; i < 8; i++) crc+=measure_response[i];
  crc = 255 - crc;
  crc += 1;
  if ( !(measure_response[0] == 0xFF && measure_response[1] == 0x86 && measure_response[8] == crc) ) {
    Serial.println("CRC error: " + String(crc) + " / "+ String(measure_response[8]));
  } 
  unsigned int responseHigh = (unsigned int) measure_response[2];
  unsigned int responseLow = (unsigned int) measure_response[3];
  unsigned int ppm = (256*responseHigh) + responseLow;

  // *****  узнаём концентрацию CO2 через PWM: ***** 
  do {
    th = pulseIn(pwmPin, HIGH, 1004000) / 1000;
    tl = 1004 - th;
    ppm2 =  2000 * (th-2)/(th+tl-4); // расчёт для диапазона от 0 до 2000ppm 
    ppm3 =  5000 * (th-2)/(th+tl-4); // расчёт для диапазона от 0 до 5000ppm 
  } while (th == 0);

  Serial.print(ppm);
  Serial.print(" <- ppm (UART) ");
  Serial.print((ppm/5)*2);
  Serial.println(" <- two fifths of it"); // Потом пришло озарение
  Serial.print(th);
  Serial.println(" <- Milliseconds PWM is HIGH");
  Serial.print(ppm2);
  Serial.println(" <- ppm2 (PWM) with 2000ppm as limit");
  Serial.print(ppm3);
  Serial.println(" <- ppm3 (PWM) with 5000ppm as limit");

  Serial.println("-----------");
  delay(5000);
}

Все замеры проводим, подключив модуль к питанию от 5 вольт; при 3.3 вольтах он выдаёт очевидно некорректные значения по верху диапазона.

В режиме PWM при заданном диапазоне значений от 0 до 2000ppm получаем, в условиях центра города, заполночь у форточки во двор, 1208ppm, что, безусловно, завышено. UART выдаёт нам близкое значение 1227ppm — различия вполне объяснимы ошибками оцифровки PWM-показаний.

Для сравнения, вот примерные дапазоны концентраций СО2, найденные в интернете:

— 350 — 450 ppm: Нормальный уровень на открытом воздухе.
— < 600 ppm: Приемлемые уровни. Уровень. рекомендованный для спален, детских садов и школ.
— 600 — 1000 ppm: Жалобы на несвежий воздух, возможно снижение концентрации внимания.
— 1000 ppm: Максимальный уровень стандартов ASHRAE (American Society of Heating, Refrigerating and Air-Conditioning Engineers) и OSHA (Occupational Safety & Health Administration).
— 1000 — 2500 ppm: Общая вялость, снижение концентрации внимания, возможна головная боль.
— 2500 — 5000 ppm: Возможны нежелательные эффекты на здоровье.

Переключаем датчик в диапазон 0 — 5000ppm. В режиме PWM у той же форточки во двор получаем 478ppm, что гораздо больше похоже на правду. Но вот в режиме UART наш датчик снова выдаёт совершенно неправдоподобное значение 1213ppm.

Десять раз перепроверив формулы, по близости показаний начинаю догадываться, что датчик считает с ошибками в арифметике. Модифицирую код, чтобы формула расчёта концентрации CO2 по данным PWM рассчитывалась с подстановкой всех вариантов верхнего предела значений. В момент какого-то озарения также дополнительно модифицирую код, чтобы значение, полученное по UART, дополнительно выводилось домноженным на 2000/5000:

диапазон 0 — 2000ppm

Range was set! (bytes 6 and 7)
1227 <- ppm (UART) 490 <- two fifths of it
606 <- Milliseconds PWM is HIGH
1208 <- ppm2 (PWM) with 2000ppm as limit
3020 <- ppm3 (PWM) with 5000ppm as limit


диапазон 0 — 5000ppm

Range was set! (bytes 6 and 7)
1213 <- ppm (UART) 484 <- two fifths of it
241 <- Milliseconds PWM is HIGH
478 <- ppm2 (PWM) with 2000ppm as limit
1195 <- ppm3 (PWM) with 5000ppm as limit


Делаем выводы:
  • в качестве рабочего диапазона работы датчика надо задавать 0 — 5000ppm
  • несмотря на это, для расчёта значений, полученных через PWM, надо в формулу подставлять константу 2000, а не 5000
  • для получения правдивых показаний от UART надо полученное значение умножать на 2/5
  • китайским даташитам, даже на вид добротным, верить нельзя
  • готовые скетчи для Ардуино из интернета брать нельзя
  • показания всех китайских «показометров» надо проверять хотя бы на соответствие здравому смыслу и внутреннюю непротиворечивость

После этого расследования датчик поселится в приборе в офисе, в компании с барометром, датчиком влажности воздуха, содержания пыли и ESP8266 для управления всем этим добром. Хоть я и вдохновился изначально приборчиками в переговорках московского Google, мой вариант не будет иметь цифр и экрана, а вместо этого получит более простую цветовую индикацию, как светофор — а подробные логи будет выкладывать по WiFi на сервер. Впрочем, это уже отдельная история.



P.S. Товар куплен за свои кровные:
Планирую купить +83 Добавить в избранное
+81 +142
свернутьразвернуть
Комментарии (149)
RSS
+
avatar
+3
  • 2gusia
  • 09 января 2018, 13:11
датчик поселится в приборе в офисе
это уже отдельная история
которую историю с нетерпением ждём. Для датчика СО2 это дёшево и весьма.
ну и было бы полезно указать принцип действия датчика. IR в даташите внушает оптимизм. Но после сказанного про дата в том шите
+
avatar
+3
  • Sanja
  • 09 января 2018, 13:20
да, датчик работает по принципу non-dispersive infrared (NDIR), что выгодно отличает его от тех же MG811, которые ещё и прокаливать-греть надо. Внутри помаргивают едва красные светодиоды. Копрус неразборный, из хлипкого пластика «под металл», лезть боязно.



Картинка из www.co2meter.com/blogs/news/6010192-how-does-an-ndir-co2-sensor-work — тут объясняется принцип работы. Вкратце — датчик считает поглощение света определённой длины волны и так определяет концентрацию CO2
+
avatar
0
  • rx3apf
  • 09 января 2018, 13:30
Что-то картинка сомнительная. Помнится мне, что, поскольку поглощение в достаточно длинноволновой области (https://hsto.org/files/689/da7/13d/689da713dd6f43d590571a4f2361e187.png), светодиод как источник света малопригоден, нужна лампа накаливания в сильном недокале. Если, конечно, не путаю…
+
avatar
0
  • Sanja
  • 09 января 2018, 13:34
я не уверен, что там именно «светодиод», возможно — и лампа. В пользу этого говорит то, что мограния становятся длиннее при проседании напряжения — будто датчик пытается компенсировать.
+
avatar
0
Почему малопригоден, есть же длинноволновые лазерные диоды до 13900 нм sinteclaser.ru/laser_diodes/. Но тогда вопрос, как автор мог заметить красное помаргивание. До 1000 нм теоретически можно заметить, а 2500 нм очень маловероятно.
+
avatar
0
Если определённая длина волны, то это не светодиод а скорей всего ИК-лазерный излучатель.
+
avatar
0
нужна лампа накаливания
её непрерывный спектр может делать численные измерения бессмысленными… а может быть, достаточно избирательности сенсора)
+
avatar
0
  • rx3apf
  • 09 января 2018, 13:25
Производитель уверяет, что NDIR (внешний вид конструкции тоже на то намекает). А опечатки в китайских даташитах — в порядке вещей (и «бренды», бывает, допускают такое).
+
avatar
0
  • DDimann
  • 09 января 2018, 20:37
и «бренды», бывает, допускают такое
Абсолютно верно.
Я лет 20-30 назад долго ругался матом на апликейшн от интела.
Два дня потреял, когда попытался для экономии времени стянуть кусок кода из апликейгена.
+
avatar
0
Интересно.
А можете посоветовать датчик pm 2.5? А то у нас в городе не всегда хороший воздух (из-за того, что есть много частных домов с печками, где топят чем попало).
+
avatar
0
  • Sanja
  • 09 января 2018, 13:15
я купил и датчик пыли (виднеется на скриншоте покупки), но он только ждёт своего часа.
+
avatar
0
Напишете о нем, как будет возможность?
+
avatar
0
  • Z2K
  • 09 января 2018, 14:17
А пыль от шин (скатов) автомобилей какой размерности? Будет диагносцировать?
+
avatar
0
  • Sanja
  • 09 января 2018, 14:47
я предварительно нагуглил его сравнение с несколькими дорогими моделями — www.howmuchsnow.com/arduino/airquality/ — и сделал вывод, что прибор хороший.
+
avatar
0
  • Harwest
  • 09 января 2018, 15:24
Нет, это не совсем нехорошая модель :)
Купил такой для самодельной станции где-то год назад.
Пришлось повозиться с переделкой электроники с софтом и калибровкой ЦАПа на ESP.
+
avatar
0
  • Sanja
  • 09 января 2018, 16:36
А с этого места поподробнее, пожалуйста.

Я немного копнул этот вопрос и сделал вывод, что проще всё делать в мелкой ардуинке, а на ESP транслировать показания, мороки меньше.
+
avatar
0
  • batal
  • 09 января 2018, 16:48
Попробуйте посмотреть тут, поддержка этого датчика есть (у меня его нет, по-этому ничего не могу сказать про работоспособность)
www.letscontrolit.com/wiki/index.php/Official_plugin_list

(я для MH-Z19 и Sensair S8 использую именно эту прошивку для ESP, в случае необходимости и самому чего подправить можно)
+
avatar
0
  • batal
  • 09 января 2018, 16:49
Если чуть точнее, то лучше сразу сюда
www.letscontrolit.com/wiki/index.php/GP2Y10
+
avatar
+1
  • Harwest
  • 09 января 2018, 17:35
Я переделал схему 'поджига' ИК диода: заменил pnp транзистор на n-mosfet в корпусе SOT23. Это дало возможность управлять подсветкой 'положительной' логикой с ESP. Естественно поменял резисторы в обвязке, включая и токоограничиваюший самого диода.
На выходе датчика поставил резисторный делитель чтобы уложить вольтаж в границы АЦП ESP 1.024 вольт. Схема есть, если надо.
Для ESP я использую прошивку WiFi IoT и там уже задействую АЦП и один GPIO (15), скрипт написан на С подобном языке, необходимые тайминги выдерживаются.
Поправочные коэффициенты подобрал укутывая датчик в кучу слоев спец фильтровальной ткани и прокачивая воздух насосом. Верхний предел — перекрывая окно карандашом.
Но все равно показания плавают, надо добавить фильтр скользящего окна.

Код выполняется каждые 20 секунд в общем цикле, в конструкторе выглядит так:


digitalWrite(15,1); // dust LED on
delayMicroseconds(280); // wait 0.28 ms for measurement
adcin=system_adc_read();
delayMicroseconds(40); // wait 0.04 ms before LED off
digitalWrite(15,0); // dust LED off
valdes[0]=(adcin-30)*0.76; // calculate dust volume mg/m3
os_sprintf(data2, "%05s %d %06s", "Dust:", valdes[0], "mkg/m3");
+
avatar
0
  • SolarW
  • 10 января 2018, 09:49
А не затруднит сей экспириенс со схемкой (для совсем начинающих джедаев паяльника) переделки на форуме wifi-iot выложить?
Ну или ткнуть пальцем в ссылочку где это лежит?
+
avatar
+2
  • Harwest
  • 10 января 2018, 12:22
Я в общем чате на slak выкладывал схему, повторю тут.


Схема переделки самого датчика


Полный листинг кода (см по схеме — у меня дисплей 4х20)

void ICACHE_FLASH_ATTR
startfunc(){
digitalWrite(15,0); // dust LED off
char data0[20];
char data2[20];
os_sprintf(data0, "%02d:%02d %d%02s %d%02s %d%01s", time_loc.hour, time_loc.min, temp_DS3231/10, "'C", dht_t1/10, "'C", dht_h1/10, "%");
LCD_print(0,data0);
os_sprintf(data2, "%05s %d %06s", "Dust:", valdes[0], "mkg/m3");
LCD_print(2,data2);
}

void ICACHE_FLASH_ATTR
 timerfunc(uint32_t  timersrc) {
// выполнение кода каждые 20 секунд
if(timersrc%20==0){
char data0[20];
char data2[20];
int32_t adcin;
os_sprintf(data0, "%02d:%02d %d%02s %d%02s %d%01s", time_loc.hour, time_loc.min, temp_DS3231/10, "'C", dht_t1/10, "'C", dht_h1/10, "%");
LCD_print(0,data0);
digitalWrite(15,1); // dust LED on
delayMicroseconds(280); // wait 0.28 ms for measurement
adcin=system_adc_read();
delayMicroseconds(40); // wait 0.04 ms before LED off
digitalWrite(15,0); // dust LED off
valdes[0]=(adcin-30)*0.76; // calculate dust volume mg/m3
os_sprintf(data2, "%05s %d %06s", "Dust:", valdes[0], "mkg/m3");
LCD_print(2,data2);
}
}

void webfunc(char *pbuf) {
os_sprintf(HTTPBUFF, "%19s %d %06s", "Концентрация пыли: ", valdes[0], "mkg/m3");
}
+
avatar
0
А у меня он фигню какую-то показывал, SDS намного удобнее в использовании и чувствительность очень высокая.
+
avatar
0
  • Tolan
  • 10 января 2018, 18:36
Если топят чем попало — там уже надо другие газы определять — окислы азота, соединения серы…
+
avatar
+5
Использую в умном доме похожую модель MH-Z19, подключённую к роутеру с LEDE (OpenWRT). Если вдруг кому-то пригодится, процедура настройки:

opkg install coreutils-stty kmod-usb-serial-ftdi nano
nano /root/mh_z19.sh

while :
do
  data=$(hexdump -n 4 /dev/ttyUSB0)
  check=$(echo "$data" | cut -c9-12)
  hex1=$(echo "$data" | cut -c14-15)
  hex256=$(echo "$data" | cut -c16-17)
  dec1=$((0x${hex1}))
  dec256=$((0x${hex256}))
  val=$(($dec1+$dec256*256))
  if [ $check = "86ff" ]
  then
    echo "CO2 value: $val"
    wget -O /dev/null -o /dev/null "http://smarthome/api.php?sensor=1&value=$val"
  else
    echo "Incorrect answer"
  fi
done

chmod +x /root/mh_z19.sh
nano /etc/rc.local

echo "1" > /sys/bus/usb/devices/usb1/bConfigurationValue
echo "1" > /sys/bus/usb/devices/usb2/bConfigurationValue
ping 1.1.1.1 -w 10
stty -F /dev/ttyUSB0 9600 raw -echo
/root/mh_z19.sh &
exit 0

/etc/init.d/cron start
/etc/init.d/cron enable

export EDITOR=nano
crontab -e

* * * * * echo -e "\xff\x01\x86\x00\x00\x00\x00\x00\x79" > /dev/ttyUSB0
+
avatar
+1
окончательно решить исход вековечной вражды в офисе между «теми, кому дует» и «теми, кому душно»
помогло? )
+
avatar
+1
  • Z2K
  • 09 января 2018, 14:19
Те «теми, кому дует» и «теми, кому душно» — на фриланс. Работать должны те. кто молчит. Они таких мелочей не замечают. :)
+
avatar
0
  • tykhon
  • 09 января 2018, 13:38
О, я сам долго экспериментировал с этим датчиком и в итоге забросил до окончания ремонта дома. Спасибо!
+
avatar
+4

Вот так выглядит, когда ты ушёл из дома, и чистота воздуха плавно стремится к отметке 400ppm :-) Когда дома подышишь, и график пересечёт 700ppm, включается вытяжка, и значение примерно так же падает к 500ppm, вытяжка выключается
+
avatar
0
  • Ev3658
  • 01 декабря 2019, 16:48
Заметил что у него вообще 400ppm нижний предел.
+
avatar
0
  • L-e-V
  • 09 января 2018, 13:48
Подскажите готовый девайс с минимальной ценой и относительно верными показаниями, плз ))
+
avatar
0
Статью читали? Так вот, это он и есть :-)
+
avatar
+2
  • IEI
  • 09 января 2018, 14:13
Предположу что нужен девайс «под ключ».
+
avatar
+1
Такие стоят дороже, а тут у нас махровый DIY
+
avatar
0
Готовые девайсы продаются довольно дорого, вот относительно недорогой dadget.ru/detektor-co2
+
avatar
0
  • L-e-V
  • 09 января 2018, 15:33
Хотелось бы не от перепродавцов, а из Китая :)
+
avatar
0
  • hugin
  • 09 января 2018, 20:26
www.co2meter.com/collections/desktop/products/co2mini-co2-indoor-air-quality-monitor
Не совсем из китая. И после того, как $ скаканул в 2 раза — разумнее стало отнести денег даджету.

А на али ищите по CO2 logger, но дешево всё-равно не будет.
+
avatar
0
В Китае в данном случае получается почему-то не дешевле. Может эта штуковина еще не стала массовым товаром
+
avatar
0
  • Andreyy
  • 15 января 2018, 02:33
Я в своё время купил Ht-2000. Проверял на работе в современном офисе — держал строго 998 весь день. Сейчас постоянно включен дома. Удается держать около 700-800 с бризером на минимальной скорости. После хорошего проветривания 500.
+
avatar
0
Спасибо за обзор, уберегли от сомнительной покупки. Раз не работает по datasheet, а показания приходится «на глаз» корректировать, так как сравнить не с чем — брать точно не стоит.
+
avatar
+2
  • Sanja
  • 09 января 2018, 14:03
ну я свой в следующий раз в Googlе в кармане отнесу и сверю с показаниями того, что на стене висит))
+
avatar
+4
  • Z2K
  • 09 января 2018, 14:45
Нашли с чем сравнивать. Они эти данные берут со своих карт. :)
+
avatar
0
  • Andreyy
  • 15 января 2018, 02:35
А с Ht-2000 сравнить можете?
+
avatar
+1
  • E_g_o_r
  • 09 января 2018, 14:31
Я брал 2 датчика предыдущей ревизии. Заработали с 0 без всяких танцев. Так что выводы поспешные.
+
avatar
+1
Предыдущая версия самостоятельно рекалибруется и от этого, похоже, не уйти. Видно по скачкам показаний раз в сутки. Но если особая точность не нужна — их отлично можно использовать
+
avatar
0
Пользуясь случаем спрошу, может кто уже юзал BME680? Стоит дорого, покупать жаба душит, даже описания нормального на русском нет. Датчик качества воздуха в помещении (как пишет Bosch)- это и есть датчик СО2?
+
avatar
0
  • Sanja
  • 09 января 2018, 14:09
нет, он проприетарный «индекс качества воздуха» считает по шкале от 0 до 500:

cdn-shop.adafruit.com/product-files/3660/BME680.pdf — см. стр. 8 и цветную табличку на стр. 10

Based on an intelligent algorithm, the BSEC provides an indoor air quality (IAQ) output. In principle, this output is in an index that can have values between 0 and 500 with a resolution of 1 to indicate or quantify the quality of the air available in the surrounding. Table 4 lists the IAQ system specification.
зато в нём барометр и датчик влажности встроен
+
avatar
0
  • chaloc
  • 09 января 2018, 14:15
но BME280 отдельно стоит 1,5$.
+
avatar
0
  • Sanja
  • 09 января 2018, 14:28
полтора доллара стоит BMP, BME — подороже.
+
avatar
+1
  • chaloc
  • 09 января 2018, 14:41
+
avatar
0
  • Sanja
  • 09 января 2018, 14:42
всё время забываю про eBay, спасибо!
+
avatar
+1
  • rx3apf
  • 09 января 2018, 14:51
Не забывайте, но тоже читайте описание внимательно. Любят китайцы такие приколы…
+
avatar
+2
  • Sanja
  • 09 января 2018, 14:56
ах ты ж засранцы:

BME280 5V Atmospheric Pressure Sensor Module for Arduino High Precision New

+
avatar
0
  • chaloc
  • 09 января 2018, 15:27
А слона я и не заметил. Придется ругаться с хитрым продавцом.
+
avatar
0
  • rx3apf
  • 09 января 2018, 16:00
Да за полтора бакса можно и без влажности обойтись, в конце концов. Потом другой купите.
+
avatar
0
  • rx3apf
  • 09 января 2018, 14:50
А Вы внимательно прочитайте описание лота? Чтобы потом возмущений не было «не то прислали»…
+
avatar
0
Это BMP280, я тоже попался год назад. Потом китаец исправил заголовок
+
avatar
0
Это BMP280
тем не менее, на скриншоте выше им «прекрасно» измеряют влажность:|
придётся подождать, что фактически получит chaloc (и, разумеется, это не даст следующему покупателю никаких гарантий)
+
avatar
0
То есть это не датчик СО2, а какой-то собственный показометр основанный непонятно на каких измерениях? А чё стоит тогда как самолёт…
+
avatar
0
  • rx3apf
  • 09 января 2018, 15:12
А про CO2 в даташите ничего и нет. Только горючие газы, там можно применять иной принцип.
+
avatar
+1
Чтоб поверили что настоящий
+
avatar
+1
Скорей всего один из тех что используют в кондиционерах. Если заглянуть в даташит на такой, так он на все газы реагирует в разных пропорциях. Ну и соответственно селективности никакой, поэтому и назвали никак не иначе как «датчик качества воздуха». На что-то реагирует, но сказать точно на что он среагировал невозможно — или СО, или метан или окись азота, ещё что-то…
+
avatar
+2
  • Z2K
  • 09 января 2018, 14:11
присутствует шестнадцатеричная математика
— это опасно? :))
+
avatar
+2
  • Sanja
  • 09 января 2018, 14:14
практика показывает, что некоторые жалуются на посты про diy и ардуинство
+
avatar
0
  • Z2K
  • 09 января 2018, 14:23
Криворукость не запрещена. :) У нас много таких фамилий и их носителей — Криворучко например. Очень распространенная фамилия.
+
avatar
0
  • DDimann
  • 09 января 2018, 20:45
Нет. Вот восьмеричная — точно опасно.
Это в шестнадцатиричном виде если 16-битное слово — FFFF, то байты у него — FF и FF.
А в восьмеричном если слово 177777, то байты — 377 и 377.
Хде логика, блин?
Практически приходилось в уме частично переводить в двоичный вид…
+
avatar
0
спасибо, что от троичной бог уберёг (хотя, может быть, и зря — чем ближе основание к e, тем эффективнее система счисления… помните три копейки?:)

Хде логика,
sqrt(017)=03.., всё честно
и так же красиво с эквивалентным 12-битным словом 07777 :)
+
avatar
0
  • DDimann
  • 16 января 2018, 21:54
спасибо, что от троичной бог уберёг
Вопрос спорный.
Именно потому, что основание натурального логарифмы выгодно в качестве основания системы счисления для ЭВМ, но затруднительно как то сделать цифровую машину с дробным основанием системы счисления (блин, сам уже запутался), была таки машинка с троичным основанием.
Сетунь называлась, на год младше меня… :)
+
avatar
+3
Есть предположение что вы его запороли разными недокументированными командами устанавливая диапазон. Как я понял диапазон вещь захардкоженая, в том числе может и конструктивно, недаром же при покупке предлагают в коментах написать какой нужен.

Вот мой, без b, график за полсуток.
+
avatar
+1
  • Sanja
  • 09 января 2018, 14:30
нет, я ему давал только документированные команды, старательно избегая команд на калибровку.

Разные показания по UART и PWM у датчика были «из коробки», что и сподвигло на расследование, собственно.

Качественное «запарывание» описано тут — geektimes.ru/post/285572/ — товарищ аж в недокументированный режим MODBUS прибор загнал и снёс калибровку, но для этого он просто грубой силой перебирал коды.
+
avatar
0
PWM я понял лучше не использовать, все таки цифра с контрольной суммой надежнее.
Еще нюансы: датчик выходит на режим через 3 минуты после включения, по UART часто нельзя запрашивать данные (не чаще раза в 10 секунд), UART и PWM могут иметь разные диапазоны, встречал что UART 5000ppm, а PWM 2000ppm, работа сенсора заявлена от 3.6V, 3.3V не подойдут.
+
avatar
0
  • E_g_o_r
  • 09 января 2018, 14:43
Согласно даташиту: Working voltage 4.5 ~ 5.5 V DC
+
avatar
0
Да, верно в новом, в старом было 3.6 ~ 5.5 V DC
+
avatar
0
  • E_g_o_r
  • 09 января 2018, 15:05
Согласен даташит на MH-Z19
+
avatar
0
  • Sanja
  • 09 января 2018, 14:44
вот и я «встретил».

Да, 3.3 вольта не подходит — сенсор начинает дико «тупить» и выдаёт значения по верху диапазона.
+
avatar
0
  • Z2K
  • 09 января 2018, 14:48
А что, сброса в заводской дефол нету?
+
avatar
0
  • Sanja
  • 09 января 2018, 14:54
так весь цимес в том, что узнать снаружи, каков «дефолт» — невозможно :)

Оттого веселят другие обзоры на этот модуль, где авторы просто втыкают его и верят показаниям.
+
avatar
0
Их несложно проверить, на улице должно быть около 400ppm
+
avatar
0
  • Z2K
  • 09 января 2018, 15:22
400ppm
— показывает исправно, а дальше как повезет
+
avatar
0
Плюсую, интересное и бюджетное решение, спасибо за настойчивость и изобретательность!
+
avatar
+2
  • E_g_o_r
  • 09 января 2018, 14:30
Что касается измерений по выходу PWM. Надо мерять и длину 1, и длину 0, а не полагаться на то, что цикл будет ровно 1004мс! Из-за ошибок как задающего генератора в датчике, так и в Ардуине(есп8266) тут может накопиться ошибка. Больше скажу, по моим наблюдениям касательно предыдущей ревизии суммарная длина пачки немного, но плавает от пачки к пачке. Потому в исходном коде как раз и присутствует th и tl — и рассчитывается итоговое значение на основе длины и того, и другого. Подставив 1004, обрекаем себя на ошибки.
+
avatar
0
  • Sanja
  • 09 января 2018, 14:32
я буду пользоваться показаниями с UART, но для начала хотелось избавиться от «шизофрении» у датчика :) А так PWM мне особо и не сдался, мороки с ним больше.
+
avatar
+15
  • batal
  • 09 января 2018, 14:34
Хех)

Играюсь как раз с этим датчиком достаточно давно (около года). Но недавно решил сравнить MH-Z19, MH-Z19B и Sensair S8 (0053)

1) Этап 1:
В конце прошлого года тестировал одновременно (стояли на расстоянии 2см друг от друга):
2 штуки MH-Z19
2 штуки MH-Z19B (один с отключенной ABC, второй с включенной)

Вывод: MH-Z19B «из коробки» работет вполне нормально (если помещение нормально проветривается). Если помещение проветривается плохо (к примеру раз в неделю) — то обязательно нужно отключать ABC (у MH-Z19B она реализована очень странно, период калибровки всего 1 день).

MH-Z19 можно выкинуть (свои убрал куда подальше). 400 показывает нормально, а вот все что выше — может врать на 200-400ppm легко.

2) Этап 2 (в процессе):
Все теже 2 штуки MH-Z19B (c включенной ABC калибровкой и с отключенной)
1 штука Sensair S8 (купленный за адекватные 36$ на тао (вместе с доставкой!))

Вывод (основанный пока только на 3 днях тестов, что само собой мало):
Нормально откалиброванный MH-Z19B (с отключенной ABC) практически полностью совпадает с S8.

В моем случае все 3 датчика стоят в хорошо прповетриваемой комнате (как минимум раз в сутки открываем окно) — в итоге все показания всех 3 датчиков совпадают (разброс максимум 100ppm, что укладывается в погрешность).

Для себя сделал вывод что вместо MH-Z19B все таки лучше предпочесть S8. Его 8 дней на калибровку выглядят куда адекватнее 1 дня у MH-Z19B.

Итого, за 40$ можно собрать миниатюрный анализатор CO2. Очень компактный, достаточно точный и дешевый.
Все что нужно — платка Wemos, 4 проводка и сам сенсор (картинка не моя) + готовая прошивка (EspEasy):
+
avatar
+2
  • Sanja
  • 09 января 2018, 14:52
про отключение a.b.c. — спасибо за напоминание. Надо себе узелок на память оставить:

+
avatar
0
Сенсор интересный, надо будет купить попробовать, а вот картинка странная, не знаю где у него точно вход и выход воздуха, но похоже он этими местами прижат к ESP-хе, и кстати она достаточно греется, так что термостабилизация сенсора будет давать сбой.
+
avatar
+1
  • Sanja
  • 09 января 2018, 14:59
я к своему прикрутил через транзистор компьютерный кулер. Перед измерением прибор 5 сек. принудительно обдувается.

С термостабилизацией у него, кажется, всё грамотно — на сквозняке от форточки при минус пяти и дома при плюс 25 показания не разбегаются.
+
avatar
+1
  • batal
  • 09 января 2018, 15:00
Неа) у Sensair S8 «вход» ка краз таки как на картинке сверху, черная «тряпочка» справа наверху) А вот MH-Z19 «перевернутый» (выход снизу и сбоку). Распиновка и размеры у них совпадают.

Про нагрев — да, есть такой момент. По этому себе буду собирать с ESPхой вниз (у Wemos Mini Pro одна стороная «голая», к ней и будет прижат датчик.

К слову о нагреве — MH-Z19B анализирует раза в 2 чаще (сужу визуально по морганию лампы) чем MH-Z19. И за счет этого греет существенно больше. При комнатной температуре 25, MH-Z19 нагревается до 30, а MH-Z19B аж до 36 (данные по их же внутренним датчикам температуры).
+
avatar
+1
Понятно спасибо, вот интересно китайский MH-Z19 это реплика S8?
У меня еще есть mh-z14, правда его показания я ни с чем не сравнивал.
Накопал еще статейку geektimes.ru/post/285572/
+
avatar
+1
  • batal
  • 09 января 2018, 15:16
Дада, статья отличная, читал :)

Про реплику — нет, врядли. Общие у них только распиновка, внешние размеры и принцип действия.

MH-Z14 у меня нет. слишком громоздкий. Он кстати тоже бывает в версии B (думаю что изменения аналогичны MH-Z19 -> MH-Z19B)

На сколько я читал, S8 вполне себе промышленный датчик и используется более менее серьезных устройствах (тот же тионовский MagicAir)
+
avatar
0
  • FAlVik
  • 09 января 2018, 20:26
Те без «B» в мусорку?
У меня два «безб» лежат дома рядышком и показания совпадают в нижнем диапазоне до 50 единиц, а в верхнем до 200.
Днём при проветривании 'через щелочку' показания становятся 400, ночью поднимаются до 1500..2500. Без проветривания через неделю показывают какой-то бред.
+
avatar
+2
  • batal
  • 10 января 2018, 10:45
Ну вот у меня тоже год трудился один без B — я был им доволен :) Потом как-то решил заказать еще датчиков. Пришел еще один без B и два B.

Как итог — оба с B совпадают между собой, плюс совпадают с SenseAir S8.
А вот оба без B — могут показать 400 тогда, когда S8 и B показывают 600-700.

Для себя решил что без B однозначно в мусорку. Но это про мои датчики. Я не берусь утверждать что они все такие.
+
avatar
+1
  • bombus
  • 13 января 2018, 18:50
Решил последовать вашему совету — заказал на таобао SenseAir S8.
Когда выбирал, самый дешевый вариант был за 28$, приятно удивился. Но в описании увидел, что точность указана — 70ppm, хотя на официальном сайте указана точность — 40ppm. Похоже дело в версии платы — такая точность (70ppm) указана для версии Senseair S8 Article No. 004-0-0013, хотя продавец на тао указал что версия 053, что очевидно не так (там и фото говорит, что не 053). В итоге нашел современную версию платы (053), но самый дешевый вариант нашел за 44$, что тоже дешевле ebay/aliexpress, но дороже чем у вас.
Вы когда покупали, учитывали версию платы? Интерес вызван большим разбросом цен (28$, 36$, 44$) и честностью продавцов, может чего не учел.
+
avatar
0
  • batal
  • 15 января 2018, 16:15
У меня именно 0053
Брал тут https://item.taobao.com/item.htm?id=536930055559
Но по-моему за 170-180 там все именно 0053
0013 дороже — около 210

Ищу всегда по «Senseair»
+
avatar
0
  • bombus
  • 15 января 2018, 21:46
Странно, вроде как у старой ревизии 013 точность измерений ниже — 70 ppm против 40 ppm у версии 053, и соответственно должна стоить дешевле.
А как можно убедиться, что версия платы такая-то, когда прибор будет в наличии?
+
avatar
0
  • batal
  • 16 января 2018, 09:55
Не знаю :)

Мой выглядит в точности вот так
ae01.alicdn.com/kf/HTB10JgyPVXXXXc4XFXXq6xXFXXXv/SenseAir-Infrared-CO2-Carbon-Dioxide-Sensor-S8-0053.jpg

В том числе есть слегка смущающие меня 01.14. Надеюсь это не дата производства :)
+
avatar
0
  • bombus
  • 20 января 2018, 17:12
Прошу подсказать. Сделал заказ и оплатил неделю назад (в прошлую субботу).
Смотрю на статус покупки:


и не могу понять уже пора беспокоиться или все в порядке?
С одной стороны в таблице — статус «оплачено» (я рассчитывал на — «отправлено»). С другой стороны этот заказ находится в статусе «To be shipped». Как правильно это перевести? Будет оправленно? Уже отправлено?
+
avatar
0
  • batal
  • 20 января 2018, 19:41
Не знаю. Я через посредника заказываю. Напрямую так и не разобрался как это сделать…
+
avatar
0
  • bombus
  • 20 января 2018, 20:33
Полелитесь ссылкой на посредника? Хотелось бы посмотреть.
Заранее спасибо!
+
avatar
0
«To be shipped»
«ожидает отправки»…
(«to be continue» — «продолжение следует», но когда?)
(я рассчитывал на — «отправлено»)
«to be received» — «ожидает получения»
+
avatar
0
Что то не смог выставить MH-Z19B ноль через UART. Пришлось через замыкание HD на землю — так выставилось. Вы не пробовали?
+
avatar
0
  • zhevak
  • 09 января 2018, 15:51
А кому-нибудь доводилось пощупать датчик MSH-P/CO2/5/V/P?

Внешний вид такой:
+
avatar
+2
  • MadOrc
  • 09 января 2018, 21:37
Я делал так, в статье есть исходники, в китай-ДШ не лез, просто посмотрел как с ним другие товарищи общаются в своих проектах.
Никаких проблем с датчиком, пока питаешь его не менее 4в, как положено.
Прибор работает уже больше года, круглосуточно, всё штатно.
+
avatar
0
А из более дорогих, кто-то щупал CozIR LP, K30, S8?
+
avatar
0
  • Q2W
  • 09 января 2018, 22:22
У меня K30. Всё ок, только питать надо минимум 7В (установлено опытным путём) и без провалов, а то начинает врать, либо отдавать ошибку.
+
avatar
0
Спасибо, а какой интерфейс используете для забора данных?
А то думаю K30 или CozIR LP взять, на taobao они примерно одинаково в районе 70 баксов стоят.
CozIR LP конечно нравится размерами и питанием от 3,3 В, как раз stm32 тоже от 3.3 работает. K30 насколько понимаю от 12 вольт можно запитать.
+
avatar
0
  • Q2W
  • 10 января 2018, 00:31
По UART с помощью официальной библиотеки.
+
avatar
0
  • SotM
  • 09 января 2018, 22:46
Я так понимаю, что это самый дешевый и более-менее адекватный датчик, который можно использовать с Ардуино?
+
avatar
+1
  • Sanja
  • 09 января 2018, 23:10
да
+
avatar
0
  • SolarW
  • 10 января 2018, 09:42
А такое бюджетное решение кто-то сравнивал с рассматриваемым вариантом?
Датчик CO2 CCS811 ( CJMCU-811 )
homes-smart.ru/index.php/component/kunena/4-zhelezo/1333-datchik-co2-ccs811-cjmcu-811
+
avatar
0
  • batal
  • 10 января 2018, 10:46
У меня лежат два. Но пока звести нормально не удалось (я по ссылке тоже отписывался).
+
avatar
0
Купил побаловаться, вместе с MH-Z19 и DSM501A, но пока что ничего полезного с датчика не получил, выдаёт какой то бред, слабо связанный с CO2, причём через раз вообще выдаёт что-то в районе 300-400, а в следующее чтение снова 6к-8к, иногда упирается в потолок 8к. Пока времени нет разбираться чего он так делает, поэтому просто пишу эти данные.
Дополнительная информация


+
avatar
0
если игнорировать прыжки и переполнение, нижний график вполне себе плавный…
он по форме не напоминает ход какого-нибудь реального показателя в/вблизи вашей локации?
+
avatar
0
Переполнение ладно, это понятно, не понятно что за прыжки. При этом датчик находятся практически на улице, и там вроде как показания должны быть в районе как раз тех самых прыжков, а не 4-8к, даже не смотря на то, что я живу в Челябинске.
+
avatar
+2
  • Mach
  • 10 января 2018, 11:11
Использую такой датчик в домашней метеостанции. Пока его не было, даже не задумывался о том, как быстро растет содержание СО2 в квартире. Теперь думаю об автоматизации приточно-вытяжной вентиляции. Как более дешевый вариант, можно взять датчик качества вздуха MQ-135. Точные значения СО2 с него считать не получится, но судить об общем состоянии воздуха — вполне. Кстати, заводил оба этих датчика в одной комнате, наложил графики изменения показаний — с определенной долей точности они повторяют друг друга (каждый в своей размеренности, конечно).
+
avatar
0
по идее, датчики MQ-## CO² вообще не чувствуют, в нём дальше окисляться нечему
+
avatar
+1
Настали времена, когда надо начинать изучать китайский. На китайском есть свежий даташит с правильной командой. Может у вас последняя прошивка датчика к которой нужен последний даташит?

版本号:1.3
实施日期:2017-12-08
例,2000ppm 量程命令:0xFF 0x01 0x99 0x00 0x00 0x00 0x07 0xD0 0x8F
+
avatar
0
  • FAlVik
  • 13 января 2018, 21:18
Ссылку или выложите, пожалуйста
+
avatar
+3
style.winsensor.com/pro_pdf/MH-Z19B.pdf
Кстати, заметьте что в этом даташите нарисован датчик как у автора этого обзора — с разъемом под шлейф. А в даташите по ссылке данной автором обзора плата датчика без разъема. Вероятно версии (прошивки) датчиков изменяют со временем, а продавцы не указывают ее.
+
avatar
0
  • Sanja
  • 14 января 2018, 02:52
спасибо, очень полезная ссылка
+
avatar
0
  • FAlVik
  • 14 января 2018, 10:09
Да. Это новый даташит, на английском этой версии ещё нигде нет
+
avatar
0
  • batal
  • 15 января 2018, 16:19
Один из моих MH-Z19B явно был когда-то с таким разьемом, который был отломан — остались следы)

За ссылку большое спасибо!
+
avatar
0
Настали времена
вы же не про эти?:|
«Третий Ангел вострубил, и упала с неба большая звезда, горящая подобно светильнику, и пала на третью часть рек и на источники вод»

гугл пока справляется:^
«Номер версии: 1.3
Дата реализации: 2017-12-08
Пример: команда диапазона 2000ppm: ...»
____
^ (с технической фигнёй:)
+
avatar
0
  • Andreyy
  • 15 января 2018, 02:44
А что насчет датчика кислорода? На Али видел автомобильные. Их можно приспособить под себя?
+
avatar
0
  • Fakel63
  • 24 января 2018, 00:23
Народ, как отличить mh-z19b от mh-z19 без «b»? на картинках у всех продавцов никакой маркировки нет (с них же станется прислать один под видом другого)
+
avatar
0
  • batal
  • 24 января 2018, 10:06
Но вообще, я бы лично рекомендовал SenseAir S8. На али есть за 36$
+
avatar
0
  • Fakel63
  • 24 января 2018, 14:18
да, часто высказывается мнение, что s8 точнее, но в построении своей домашней метеостанции ориентировался на прошивку wifi-iot, но она поддерживает только серию MH-Z1x. Можно, конечно сделать костыль в виде отдельной пары esp+s8, а потом данные с нее «закидывать» на wifi-iot, но я в этом не силен. Вообще, многие нахваливают SenseAir S8, но внятных гайдов его подключения для домохозяек) я не нашел.
+
avatar
+2
  • batal
  • 24 января 2018, 15:05
Хех. Очень знакомо про wifi-iot :) Я тоже не решался связаться с S8 из-за того что он не поддерживался этой прошивкой.

Но случайно наткнулся на espeasy — тоже готовая прошивка для ESP8266, но с поддержкой S8.

В итоге бОльшая часть девайсов у меня на wifi-iot, а там где используются CO2 датчики, там espeasy.

EspEasy кстати имеет более широкую поддержку в том числе и MH-Z19B — имеется возможность «читать» символ «U» по которому можно судить о том когда девайс самокалбируется, а так же есть возмоность эту самую автокалибровку отключить.

Кстати, имейте ввиду что MH-Z19B хорошо работет в помещениях которые хотя бы раз в сутки проветриваются до 400ppm. Если нет — автокалибровку обязательно нужно отключать.
+
avatar
0
  • Fodin
  • 05 февраля 2018, 12:33
Чудит датчик у меня сильно. Мало того, что с UART не захотел работать вообще (не откликается на команды), так еще и вот такой график выдает.Т.е., долго старательно падает вниз аж ниже 400, а потом резко взлетает до большого значения и медленно спускается до приемлемых чисел.
+
avatar
0
  • Fodin
  • 05 февраля 2018, 12:39
Кстати, в китайском даташите уже пишут, что датчик не до 5000ppm работает, а аж до 10000.
На PWM, судя по всему, диапазон измерения фиксированный — до 2000.
И нигде в статьях не встречал упоминания, что можно снимать показания с V0 — аналогового выхода, где уровнь CO2 показывается напряжением на выходе.
+
avatar
0
  • Werdan
  • 11 февраля 2018, 10:18
Пришла и моя очередь экспериментов с этим датчиком. У меня версия B, пока писал прошивку, ориентировался на эту статью, коэффициент 2/5 использовал и вроде бы все было хорошо. За исключением, разве что, значения 340 ppm в комнате после длительного проветривания. Ну, думаю, откалибруется через сутки, будет показывать немного больше. Не тут-то было. Через сутки на графике образовался скачок 410ppm -> 250ppm. Подключил к банке, вынес на улицу, оставил там на пол часа — 140ppm. И тут я понял, что коэффициент надо выкидывать, а состояние воздуха в квартире и офисе из вполне адекватного сразу превратилось в хреновое.
+
avatar
0
  • greensky
  • 18 февраля 2018, 23:12
Точно, у меня та же история. Как только концентрация после проветривания «снизилась» до 280 ppm, понял что коэффициент 2/5 не нужен. А воздух в квартире гораздо хуже, чем я изначально думал.
Датчик MH-Z19B, использую UART. По итогу испытаний: датчик работает достоверно в обоих диапазонах (2000 и 5000) без каких-то корректирующих коэффициентов. Конечно, неплохо бы сверить с заведомо точным датчиком, но пока такой возможности нет.
Кое-кто пишет, что по UART нельзя часто опрашивать данные. А в чем проблема? Специально сравнивал графики с интервалом 5с и 60с — показания в целом совпадают (на 5c, конечно, заметнее выбросы типа «случайно выдохнул в сторону датчика»).
Автокалибровку отключил, при этом показания изменились не более 5 ppe (очевидно, датчик еще не успел перекалиброваться).
В целом датчик очень чувствительный и малоинерционный. Думаю, в готовом устройстве вентилятор для принудительного обдува не понадобится.
+
avatar
0
  • tapir
  • 19 февраля 2018, 03:37
На работе у сотрудника MH-Z19A. Вот если его опрашивать часто, то он начинает выдавать ерунду.
Свой MH-Z19B я в целях эксперимента опрашивал 10 раз в секунду, всё ок.
По результатам эксперимента сделал вывод что чаще чем 3 секунды нету смысла, ибо датчик меряет CO2 раз в 3 секунды, и до следующего измерения каждый раз выдаёт предыдущий результат измерений.
+
avatar
0
  • greensky
  • 18 февраля 2018, 23:43
Кстати, кто-нибудь нашел в даташите распиновку разъема, с которым поставляется MH-Z19B (ну, про который автор статьи упоминает, что его можно при ненадобности отломать)?
Посмотрев дорожки на просвет, разводка по цветам проводов:
Желтый — не распаян
Зеленый — RX (уровень сигнала 3.3В)
Синий — TX (уровень сигнала 3.3В)
Красный — Ground
Черный — V0 (выходное напряжение 3.3В, не более 10мА)
Белый — не распаян
Коричневый — ?
Последний распаян, но назначение непонятно. По логике это должен быть HD, но дорожка ведет не к нему, а куда-то внутрь.
+
avatar
0
  • tapir
  • 19 февраля 2018, 03:36
В даташите который на китайском есть распиновка
http://style.winsensor.com/pro_pdf/MH-Z19B.pdf
Вооружившись переводчиком имеем:
//                   //                   pin 1 (brown)  // CO2 Vo
//                   //                   pin 2 (white)  // CO2 Nothings
#define pinCo2Vin    // GND <-----------> pin 3 (black)  // CO2 GND
#define pinCo2Gnd    // 5V <------------> pin 4 (red)    // CO2 Vin
#define pinCo2Rx  14 // A0 Arduino Tx <-> pin 5 (blue)   // CO2 Rx (UART)
#define pinCo2Tx  15 // A1 Arduino Rx <-> pin 6 (green)  // CO2 Tx (UART)
//                   //                   pin 7 (yellow) // CO2 Nothings
+
avatar
0
  • greensky
  • 20 февраля 2018, 02:17
Спасибо!
Выходит, его и запитывать можно с этого разъема, а к контактам с другой стороны есть смысл лезть только если хочешь снимать результаты в ШИМ.
+
avatar
0
  • tapir
  • 19 февраля 2018, 03:29
Отпишусь и я про свой опыт.
С датчиком играюсь уже около двух месяцев.
Автор всё супер написал, спасибо. Можно всё делать как он, и не париться, если бы не упоминание про мифический коэффициент.
Я в итоге показания своего датчика сравнивал с другими приборами. Совпадают 1 в 1.
+
avatar
0
Не совсем понял, Вы используете коэффициент пересчёта 2/5 (как автор). Или у Вас и без этого коэффициента всё правильно показывается?
+
avatar
0
Добрый день!
Подскажите пожалуйста как решить проблему?
Использую датчик MH-Z19, данные собираю через PWM. На макетной плате все отлично работало.
Спаял проводами с ардуино, собрал во временный корпус, через час показания свалились к 400ppm.
Показывает только 395-404 ppm. После перезагрузки немного работал в нормальном режиме. Показывал похожие на правду значения, но снова стал показывать около 400.
Уже перепаивал все, возвращал на макетную плату, ничего не помогает.
Вот мой скетч, если интересно.

#include <Wire.h> 
#include <LiquidCrystal_I2C.h>
#include <Adafruit_GFX.h>
#include <dht11.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);
dht11 DHT;
#define DHT11_PIN 7
#define pwmPin 2
#define LedPin 13

int prevVal = LOW, times = 0;
long th, tl, h, l, ppm;

void setup() {
  Serial.begin(9600);
  pinMode(pwmPin, INPUT);
  pinMode(LedPin, OUTPUT);
// инициализация LCD
  lcd.begin();

  // темный фон, светлые буквы
  lcd.backlight();
}

void loop() {
  long tt = millis();

  //чтение PWM от CO2
  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);
      Serial.println("PPM = " + String(ppm));
      lcd.setCursor(0, 0);
      lcd.print("                ");
      lcd.setCursor(0, 0);
      if (ppm < 1000)
        lcd.print("CO2 " + String(ppm));
      else
        lcd.print("CO2 " + String(ppm));
      times++;

      if (times >= 3) {
        times = 0;
        int chk = DHT.read(DHT11_PIN);    // Чтение данных
        switch (chk) {
          case DHTLIB_OK:
            break;
          case DHTLIB_ERROR_CHECKSUM:
            lcd.print(" ce");
            break;
          case DHTLIB_ERROR_TIMEOUT:
            lcd.print(" te");
            break;
          default:
            lcd.print(" ue");
            break;
        }
        // Выводим показания влажности и температуры
        lcd.setCursor(0, 1);
        lcd.print("Hum:");
        lcd.setCursor(5, 1);
        lcd.print(DHT.humidity, 1);
        lcd.setCursor(10, 1);
        lcd.print("C:");
        lcd.setCursor(13, 1);
        lcd.print(DHT.temperature, 1);
      }

      lcd.display();
    }
  }
}
+
avatar
0
Вот и я играюсь с этим датчиком (по UART). Датчик настраиваю на диапазон 5000ppm. Пришёл к выводу, что в моём случае корректирующий коэффициент 2/5 не нужен. После проветривания квартиры в течение получаса показания PPM снизились с 840 до 540 (живу в большом городе, не знаю насколько это влияет), через час — 470ppm. Если бы использовался коэффициент 2/5, то были бы показания 336 — 216 — 188, что совершенно неправдоподобно.
+
avatar
0
Привет.Может кто подскажет как его вообще проверить?
Я кучу скетчей перепробовал, и PWM и UART, ничего не показывает.
И наразных arduino и даже esp8266 на lua скрипт пробовал.
Вообще ничего не показывает.
Может мне китаец херню прислал?
+
avatar
0
  • ac1d
  • 12 января 2019, 12:32
Большое спасибо за статью и особенно за найденный баг в даташите.
Подключаю mh-z19b к arduino uno используя ваш скетч и столкнулся с двумя проблемами:
1) При попытке компиляции вашего кода возникает конфликт переменных:
MH-Z19B:75:16: error: conflicting declaration 'unsigned int ppm'

   unsigned int ppm = (256*responseHigh) + responseLow;

****

unsigned long th, tl, ppm = 0, ppm2 = 0, ppm3 = 0;

Заменил переменную PPM на PPM1, однако не уверен, что это правильный путь.

2) Похоже, что отображаемые данные не вполне соответствуют действительности. Ниже показания датчика, находящегося у открытого окна:

-----------
1922 <- ppm (UART) 768 <- two fifths of it
376 <- Milliseconds PWM is HIGH
27 <- ppm2 (PWM) with 2000ppm as limit
34 <- ppm3 (PWM) with 5000ppm as limit
-----------
1938 <- ppm (UART) 774 <- two fifths of it
380 <- Milliseconds PWM is HIGH
35 <- ppm2 (PWM) with 2000ppm as limit
54 <- ppm3 (PWM) with 5000ppm as limit
-----------
1962 <- ppm (UART) 784 <- two fifths of it
384 <- Milliseconds PWM is HIGH
43 <- ppm2 (PWM) with 2000ppm as limit
9 <- ppm3 (PWM) with 5000ppm as limit
-----------



Если я правильно расшифровываю данные, ppm = 784, что довольно много при открытом окне (датчик по сути на улице)
значение PWM выглядит гораздо убедительнее, хотя тоже есть сомнения, в сторону занижения значений.
Как думаете, почему может быть некорректная выдача? И как было бы правильно решить проблему с конфликтом переменных?
+
avatar
0
  • 4ebura
  • 15 января 2019, 20:41
Тут подстерегала первая проблема — как узнать текущую размерность измерений?
Sanja, а вы не обратили внимания на ТТХ датчика при покупке или на информацию на наклейке на корпусе?

при покупке на Али я видел 2 релиза данного датчика на 2000 и на 5000, и заказал на 5000.

Не совсем понял, с какой целью реализовано подключение одновременно по UART и по PWM?
расшифруйте, пожалуйста.
+
avatar
0
  • Dogger3
  • 27 февраля 2019, 14:47
Тут спрашивали про коричневый провод на шлейфе MH-Z19B. Это аналоговый выход, 1mV=1ppm, очень удобно для проверки датчика.
Сабж может выдавать концентрацию одновременно по трём каналам. Непоняток по этому сильно интеллектуальному датчику хватает, и кто умеет все каналы свести к одинаковым показаниям — тот красавчик.
Мне не повезло, по UART полный молчок «CCR Error 0/0», если кто может подсказать — буду признателен.
+
avatar
0
  • sg12
  • 11 марта 2019, 12:31
Вообще не понятно от куда взялся этот коэффициент 2/5, с ним за ночь в комнате 20м2 двое взрослых и ребенок без проветривания, максимальные показания 680ppm, а если проветрить то опускается меньше 200ppm, и это в городе весной. Этот коэффициент мапит значение с 5000 к 2000, т.е. больше чем 2000 ни как на получить.
+
avatar
0
  • Alex183
  • 16 марта 2019, 22:32
Попробуй вот этот скетч:

#include <SoftwareSerial.h>;
//////////////////////////////////////////////////////////////////////////////////////////////
SoftwareSerial co2Serial(D1, D2); // RX- D2, TX — D1; //Wemos D1 mini

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

void loop() {

readCo2Sensor();
}

//////////////////////////////////////////////////////////////////////////////////
void readCo2Sensor() // Initialisiere CO2 Sensor MH-Z19
{
byte cmd[9] = {0xFF,0x01,0x86,0x00,0x00,0x00,0x00,0x00,0x79};
unsigned char response[9];

co2Serial.write(cmd, 9);
memset(response, 0, 9);
co2Serial.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]));
}
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);
}
/////////////////////////////////////////////////////////////////////////////////////////////
+
avatar
0
  • Lucky13
  • 22 апреля 2019, 21:03
Здравствуйте! Столкнулся с проблемой с датчиком MH-Z19. Датчик долгое время нормально работал в домашней метеостанции, при этом не был запаян а просто воткнут в отверстия на плате. При последней модификации метеостанции, не касающейся самого датчика, решил его запаять. Теперь после подачи питания он некоторое время работает, но при этом довольно часто ответ от датчика не приходит и показания его на графике выглядят более изрезанными чем раньше, а через непродолжительное время работы ответы вообще перестают приходить. При этом ШИМ выход работает. Кто-нибудь сталкивался с подобной проблемой?
+
avatar
0
  • Ev3658
  • 30 ноября 2019, 13:19
Я написал программу для калибровки и проверки этого датчика, к сожалению проверить полностью не могу, но думаю многим поможет: yadi.sk/d/Ih0MGx6P7D5rRQ
Добавил не задокументируемые функции, такие как сброс. Если чего, пишите на e-mail, в программе всё есть.
+
avatar
0
  • mr_Rulez
  • 28 сентября 2020, 19:41
Проверьте код — одна переменная (ppm) в двух типах?
"…
unsigned long th, tl, ppm = 0, ppm2 = 0, ppm3 = 0;
unsigned int ppm = (256*responseHigh) + responseLow;
..."
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.