Зарегистрироваться

Датчик углекислого газа в воздухе (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. Товар куплен за свои кровные:
Планирую купить +54 Добавить в избранное +70 +112
+
avatar
  • 2gusia
  • 09 января 2018, 13:11
+1
датчик поселится в приборе в офисе
это уже отдельная история
которую историю с нетерпением ждём. Для датчика СО2 это дёшево и весьма.
ну и было бы полезно указать принцип действия датчика. IR в даташите внушает оптимизм. Но после сказанного про дата в том шите
+
avatar
  • Sanja
  • 09 января 2018, 13:20
+2
да, датчик работает по принципу non-dispersive infrared (NDIR), что выгодно отличает его от тех же MG811, которые ещё и прокаливать-греть надо. Внутри помаргивают едва красные светодиоды. Копрус неразборный, из хлипкого пластика «под металл», лезть боязно.



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

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

(я для MH-Z19 и Sensair S8 использую именно эту прошивку для ESP, в случае необходимости и самому чего подправить можно)
+
avatar
  • batal
  • 09 января 2018, 16:49
0
Если чуть точнее, то лучше сразу сюда
www.letscontrolit.com/wiki/index.php/GP2Y10
+
avatar
  • Harwest
  • 09 января 2018, 17:35
0
Я переделал схему 'поджига' ИК диода: заменил 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
  • SolarW
  • 10 января 2018, 09:49
0
А не затруднит сей экспириенс со схемкой (для совсем начинающих джедаев паяльника) переделки на форуме wifi-iot выложить?
Ну или ткнуть пальцем в ссылочку где это лежит?
+
avatar
  • Harwest
  • 10 января 2018, 12:22
+1
Я в общем чате на 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
  • Tolan
  • 10 января 2018, 18:36
0
Если топят чем попало — там уже надо другие газы определять — окислы азота, соединения серы…
+
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
  • Z2K
  • 09 января 2018, 14:19
0
Те «теми, кому дует» и «теми, кому душно» — на фриланс. Работать должны те. кто молчит. Они таких мелочей не замечают. :)
+
avatar
  • tykhon
  • 09 января 2018, 13:38
0
О, я сам долго экспериментировал с этим датчиком и в итоге забросил до окончания ремонта дома. Спасибо!
+
avatar
+4

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

А на али ищите по CO2 logger, но дешево всё-равно не будет.
+
avatar
0
В Китае в данном случае получается почему-то не дешевле. Может эта штуковина еще не стала массовым товаром
+
avatar
0
Спасибо за обзор, уберегли от сомнительной покупки. Раз не работает по datasheet, а показания приходится «на глаз» корректировать, так как сравнить не с чем — брать точно не стоит.
+
avatar
  • Sanja
  • 09 января 2018, 14:03
+2
ну я свой в следующий раз в Googlе в кармане отнесу и сверю с показаниями того, что на стене висит))
+
avatar
  • Z2K
  • 09 января 2018, 14:45
+4
Нашли с чем сравнивать. Они эти данные берут со своих карт. :)
+
avatar
  • E_g_o_r
  • 09 января 2018, 14:31
+1
Я брал 2 датчика предыдущей ревизии. Заработали с 0 без всяких танцев. Так что выводы поспешные.
+
avatar
+1
Предыдущая версия самостоятельно рекалибруется и от этого, похоже, не уйти. Видно по скачкам показаний раз в сутки. Но если особая точность не нужна — их отлично можно использовать
+
avatar
0
Пользуясь случаем спрошу, может кто уже юзал BME680? Стоит дорого, покупать жаба душит, даже описания нормального на русском нет. Датчик качества воздуха в помещении (как пишет Bosch)- это и есть датчик СО2?
+
avatar
  • Sanja
  • 09 января 2018, 14:09
0
нет, он проприетарный «индекс качества воздуха» считает по шкале от 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
  • chaloc
  • 09 января 2018, 14:15
0
но BME280 отдельно стоит 1,5$.
+
avatar
  • Sanja
  • 09 января 2018, 14:28
0
полтора доллара стоит BMP, BME — подороже.
+
avatar
  • chaloc
  • 09 января 2018, 14:41
+1
+
avatar
  • Sanja
  • 09 января 2018, 14:42
0
всё время забываю про eBay, спасибо!
+
avatar
  • rx3apf
  • 09 января 2018, 14:51
+1
Не забывайте, но тоже читайте описание внимательно. Любят китайцы такие приколы…
+
avatar
  • Sanja
  • 09 января 2018, 14:56
+2
ах ты ж засранцы:

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

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

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

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

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

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

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

Играюсь как раз с этим датчиком достаточно давно (около года). Но недавно решил сравнить 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
  • Sanja
  • 09 января 2018, 14:52
+1
про отключение a.b.c. — спасибо за напоминание. Надо себе узелок на память оставить:

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

С термостабилизацией у него, кажется, всё грамотно — на сквозняке от форточки при минус пяти и дома при плюс 25 показания не разбегаются.
+
avatar
  • batal
  • 09 января 2018, 15:00
+1
Неа) у 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
  • batal
  • 09 января 2018, 15:16
+1
Дада, статья отличная, читал :)

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

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

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

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

Для себя решил что без B однозначно в мусорку. Но это про мои датчики. Я не берусь утверждать что они все такие.
+
avatar
  • zhevak
  • 09 января 2018, 15:51
0
А кому-нибудь доводилось пощупать датчик MSH-P/CO2/5/V/P?

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


+
avatar
  • Mach
  • 10 января 2018, 11:11
+2
Использую такой датчик в домашней метеостанции. Пока его не было, даже не задумывался о том, как быстро растет содержание СО2 в квартире. Теперь думаю об автоматизации приточно-вытяжной вентиляции. Как более дешевый вариант, можно взять датчик качества вздуха MQ-135. Точные значения СО2 с него считать не получится, но судить об общем состоянии воздуха — вполне. Кстати, заводил оба этих датчика в одной комнате, наложил графики изменения показаний — с определенной долей точности они повторяют друг друга (каждый в своей размеренности, конечно).