Winsen ZPHS01B

negavoid2
negavoid2 аватар
Offline
Зарегистрирован: 06.05.2020

Приехал ко мне Winsen ZPHS01B - многофункциональный модуль для контроля качества воздуха.



В состав устройства входят следующие датчики:

• Лазерный датчик пыли;

• Датчик углекислого газа (CO2);

• Электрохимический датчик формальдегида (CH2O);

• Электрохимический датчик озона (O3);

• Датчик угарного газа (CO);

• Датчик летучих органических веществ;

• Датчик диоксида азота;

• Датчик температуры;

• Датчик влажности.



Основные особенности и технические характеристики:

• Определяемые вещества: CO, CO2, CH2O, O3, NO2, летучие органические вещества, мелкодисперсные частицы;

• Измерение температуры и влажности;

• Напряжение питания: 5В;

• Средний потребляемый ток: <300мА;

• Выходной интерфейс: UART;

• Диапазон рабочих температур: от -10°C до +50°C;

• Габаритные размеры: 135x50x26,2мм.

negavoid2
negavoid2 аватар
Offline
Зарегистрирован: 06.05.2020

Сперва - ссылки на превосходные обзоры от коллеги по форуму на датчики Winsen по отдельности:

https://arduino.ru/forum/obshchii/winsen-ze15-co

https://arduino.ru/forum/obshchii/winsen-zs05

https://arduino.ru/forum/obshchii/winsen-ze08-ch2o

Сайт производителя сенсора https://www.winsen-sensors.com, сенсор продаётся на али продавцом по имени Winsen (удивительно), стоит $90, ехал ~2.5 недели (на 20-сентября-2022). Содержит пачку распаянных датчиков из тех, что указаны выше по ссылкам.

Коробочка была довольно помятая, но содержимое оказалось в целости и сохранности. Немножко прифигел, когда достал из коробочки ещё и два листа сертификатов "поверок", аж с подписью!

Стоит сделать отступление: ВАЖНО! Получившееся устройство не является поверенным/сертифицированным измерителем, не стоит использовать и полагаться на него в критических для жизни и здоровья ситуациях - можно больно и мучительно умереть.

Устройство собирал на клоне Lolin Wemos D1 R1 mini, хотел передавать данные по вайфаю, на самом-то деле, убил вчера почти целый день, прежде чем осознал, что SoftwareSerial у esp8266 конфликтует с вайфаем, и ведь помнил же, но естественно, забыл )) Как только отказался от вайфая - всё сразу заработало.

Схема очень простая, если берём 3.3V плату:

Winsen G --> Wemos GND

Winsen V --> Wemos +5V !!!

Winsen R(rx) --> Wemos D3 (3.3V !!!)

Winsen T(tx) --> Wemos D4 (3.3V !!!)

Разъём на сенсоре - XH2.54-4P. Поскольку у меня дома (разумеется) такого нет, воспользовался обычными ардуиновскими дюпонами папа-мама, папами в ардуину, мамы отлично налезли на штырьки xh2.54 (ещё бы не налезли).

Измучившись с вимосом, решил хотя бы проверить, а живой ли вообще сенсор. В usb-uart с али на ch340g впихивать побоялся, поскольку там на уарте вроде бы 5V на выходе, поэтому залил в тот же вимос serial-мост, пусть работает переходником.

#include <SoftwareSerial.h>

SoftwareSerial WinsenSerial(D4, D3);

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

void loop() {
  String str = "";

  if (Serial.available()) {
    while (Serial.available() > 0) {
      char c = Serial.read();
      str += c;
    }
    
    WinsenSerial.print(str);
  }

  str = "";

  if (WinsenSerial.available() > 0) {
    while (WinsenSerial.available() > 0) {
      char c = WinsenSerial.read();
      str += c;
    }
    
    Serial.print(str);
  }
}

Заливаем, запускаем, и обращаемся к нему из любой софтины, работающей с ком-портом.

import serial
import time

serialPort = serial.Serial(port="COM3", baudrate=9600, bytesize=serial.EIGHTBITS, timeout=1, parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE)
if serialPort.isOpen():
    print("Opened " + serialPort.portstr)

while True:
    serialPort.flush()
    serialPort.flushInput()
    serialPort.flushOutput()

    serialPort.write(b'\xff\x01\x86\x00\x00\x00\x00\x00\x79')
    s = serialPort.read(26)

    if len(s) == 26 and s[0] == 0xff and s[1] == 0x86:
        result = {
            'pm1.0': s[2] * 256 + s[3],
            'pm2.5': s[4] * 256 + s[5],
            'pm10': s[6] * 256 + s[7],
            'co2': s[8] * 256 + s[9],
            'voc': s[10],
            'temperature': ((s[11] * 256 + s[12]) - 435) * 0.1,
            'rh': s[13] * 256 + s[14],
            'ch2o': (s[15] * 256 + s[16]) * 0.001,
            'co': (s[17] * 256 + s[18]) * 0.1,
            'o3': (s[19] * 256 + s[20]) * 0.01,
            'no2': (s[21] * 256 + s[22]) * 0.01
        }
        print(time.ctime())
        print(*result.items(), sep='\r\n')
        print("")
    else:
        print(time.ctime() + " no data")
        print("")

    time.sleep(10)

Работает, показания выдаёт ))

Маленький нюанс - видите, при подсчёте температуры нужно вычитать коэффицент. Правильный коэффицент -435, а в даташите ( https://www.winsen-sensor.com/d/files/zphs01b-english-version1_1-20200713.pdf ) написано вычитать -500!!! Поубивал бы ногами за такое.

При питании по проводу от USB 2.0 сенсор углекислого газа выдаёт всегда 5000ppm, максимальную границу. При питании от павербанка всё в порядке; видимо не хватает, хотя судя по показаниям, трескало максимально 5V 0.41А - на сенсор+вимос+ssd1306.

Ну, а удостоверившись в работоспособности сенсора, и решив отказаться от вайфая, уже вполне можно дотюнить работу с SoftwareSerial, и добавить дисплей для автономности.

SSD1306 SCK --> Wemos D2

SSD1306 SDA --> Wemos D1

SSD1306 VDD --> Wemos +5V !!!

Куда подключать SSD1306 GND, предлагаю догадаться самостоятельно (гусары, молчать!). :) 

Работающую для esp8266 библиотеку SoftwareSerial взял вот тут, просто положил два файла в папку и сделал инклюд через кавычки, как и написано на странице библиотеки: https://github.com/CrazyRobMiles/Esp8266EdgeSoftwareSerial

Библиотека для OLED SSD1306 для ESP8266 у меня тоже сторонняя: https://github.com/ThingPulse/esp8266-oled-ssd1306

#include <Adafruit_GFX.h>
#include "SoftwareSerial.h"
#include <Wire.h>

#include <SSD1306Wire.h>
SSD1306Wire display(0x3C, D1, D2);

#define TX D3
#define RX D4

SoftwareSerial WinsenSerial(RX, TX);

int pm1;
int pm25;
int pm10;
int co2;
int voc;
float temp;
float rh;
float ch2o;
float co;
float o3;
float no2;
int chk;

void read_winsen() {
  const uint8_t cmd[9] = {0xFF, 0x01, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79};
  for (int i = 0; i < 9; i++) {
    WinsenSerial.write(cmd[i]);
  }

  byte s[26];
  if (WinsenSerial.available()) {
    for (int i = 0; i < 26; i++) {
      s[i] = WinsenSerial.read();
    }

    pm1 = s[2] * 256 + s[3];
    pm25 = s[4] * 256 + s[5];
    pm10 = s[6] * 256 + s[7];
    co2 = s[8] * 256 + s[9];
    voc = s[10];

    temp = ((s[11] * 256 + s[12]) - 435) * 0.1;
    rh = s[13] * 256 + s[14];
    ch2o = (s[15] * 256 + s[16]) * 0.001;
    co = (s[17] * 256 + s[18]) * 0.1;
    o3 = (s[19] * 256 + s[20]) * 0.01;
    no2 = (s[21] * 256 + s[22]) * 0.01;

    chk = s[25];
  }
}

void draw_1306()
{
  display.clear();

  display.drawString(1, 1, "CO2: " + String(co2));
  display.drawString(80, 1, "VOC: " + String(voc));

  display.drawString(1, 14, "Temp: " + String(temp));
  display.drawString(1, 22, "RH: " + String(rh));
  display.drawString(1, 30, "CH2O: " + String(ch2o));
  display.drawString(1, 38, "CO: " + String(co));
  display.drawString(1, 46, "O3: " + String(o3));
  display.drawString(1, 54, "NO2: " + String(no2));

  display.drawString(90, 22, String(pm1));
  display.drawString(90, 30, String(pm25));
  display.drawString(90, 38, String(pm10));

  display.display();
}

void setup()
{
  display.init();
  display.flipScreenVertically();
  display.setContrast(7);
  display.display();

  WinsenSerial.begin(9600);
  while (!WinsenSerial) {
    delay(100);
  }
}

void loop()
{
  read_winsen();
  draw_1306();
  delay(5000);
}

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

Единственное, что мне не очень нравится - показания влажности 65%. Рядом стоит несколько других датчиков, все показывают ~35-40%, между собой они согласны, датчики разные, а этот вот 65-67 и всё. Ну да ладно, мне от этого сенсора гигрометр особо-то и не нужен, а может просто надо ещё какой коэффицент из лживого датащита поправить.

Хлопнул пива, подышал на датчик - формальдегид сантиметров с 30 чувствует. Лазеру очень не нравятся сигареты - моментально добавляется загрязнение х3-x4, из-за тяжёлых частиц дыма, наверное. Причём я не дышу на прямо сам датчик, от него до меня сантиметров 50-60, и дым я выдуваю в другую сторону, а всё равно всё ему видно.

PS Не имею отношения к китайцам и компании винсен, но точно так же, как и коллега, вынужден постоянно повторять именно их название - ибо это весьма доступные датчики по относительно доступной цене, лучше хлама, хуже профессиональных. Остальные, более профессиональные, весьма дороже; да и эти-то уже не каждый подряд DIYщик будет покупать.

PPS За почти неделю так и не удалось особо поиграться с датчиком, другие дела, но датчик не выключал, поглядывал днём, показания показывает стабильные, ПДК вроде в норме, ничего не сломалось, всё работает.

negavoid2
negavoid2 аватар
Offline
Зарегистрирован: 06.05.2020

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

 

sadman41
Offline
Зарегистрирован: 19.10.2016

Китайцы в своём репертуаре...

Вижу распаянный ZP07-MP503 Air-Quality Detection Module (с маленьким бочонком на борту и контактами A-B). В даташите на него указано: "Output Data 0-10 grade pollution signal". Но сама общая плата возвращает только TVOC Range 0~3 grades. Какие там три из десяти взяты - ни слова. Да и что за эти "0-10 grade", какие у них размерности - тайна, покрытая мраком. Написано, конечно, что это Pollution Class, но, что-то, интернеты про такие классы безмолвствуют. Т.е. смысла в этой цифире на данный момент никакого. Разве что значение 0 будет успокаивать.

Посмотрел на картинки Winsen Dust sensor (видимо ZH06-II) и понял, что контактная группа и корпус имеют знакомый вид. Похоже, что это брат-близнец датчика PMS7003 от Plantower https://www.plantower.com/en/products_33/76.html . Протокольная часть, наверное, прояснила бы ситуацию, но винсен не хочет её публиковать.  По первому "релизу" протокол описан и  https://www.winsen-sensor.com/d/files/ZH06.pdf и он заголовком 0x42 0x4D выдает родство с Plantower (https://download.kamami.pl/p564008-PMS7003%20series%20data%20manua_Engli...). По метрикам же Winsen == усеченный Plantower.

Еще заметил на плате MH-Z19 новой модификации. Полез на сайт перепроверить и да, действительно, Winsen наклепал новых CO2 NDIR сенсоров. В частности - MH-Z19C / MH-Z19E (https://www.winsen-sensor.com/sensors/co2-sensor/mh-z19e.html) с увеличенным вдвое сроком службы (>10 лет против >5 лет у классической MH-Z19B). 

Так же, как оказалось, выпущен CO2 NDIR MH-Z1311A c быстрым разогревом и пониженным потреблением. Его средний ток "< 800uA " против "< 60mA" у MH-Z19B. У нового сенсора, правда, с точностью измерения есть нюансы, но для "батареечных" девайсов, похоже, он получше.

 

negavoid2
negavoid2 аватар
Offline
Зарегистрирован: 06.05.2020

sadman41

С питанием, вроде, разобрался, питания хватает (сенсор+esp8266+ssd1306) и напрямую от usb, и от павербанка.

Из того, что я успел заметить, VOC он считает, скорее всего, по частицам 1, 2.5, 10, после сигареты за столом частицы (дым) увеличиваются раз в 10, быстро нарушая все пдк, VOC становится 3, потом в течение получаса падает на место. Но - не всегда ведёт себя так. Возможно, учитывает ещё CO2 и формальдегид, иногда бывает и без курения, после закрытия окна становится 1-2.

Датчик PM1/2.5/10 - очень чувствительный, показывает сигареты большими пиками на графике, когда курю на кухне - метров 10 до неё по коридорам - ан нет, всё видит, дым разъезжается по всей квартире мгновенно.

CO всегда стоит на 0.5, что бы я ни делал, хоть обдышаться прямо на него. В банку со свечкой не запихивал пока, нет свечки. Двуокись азота тоже всегда на месте, ну, как бы я азотную кислоту дома и не синтезирую; пытались, скорее всего, всё же для производства датчик сделать (странно, тогда и серу было бы логично добавить), а не для дома. Озон - почти всегда 0.02, очень редкие замеры раз в несколько часов скачут до 0.04-0.05, закономерности особо не заметил, может что натираю где. Искусственно вызвать озон тоже не получилось, озонатора нет, грозы ещё не скоро, на пьезо ему пофиг, а чем-то более мощным пробивать воздух искрами на рабочем столе я постеснялся.

Показания этого датчика CO2, кстати, надо фильтровать, выбросы с интервалом 3-4 минуты, только непонятно как - по среднему, по выбросам, или по медиане. Этот датчик на дыхание реагирует, быстро растёт и так же быстро падает (при этом выбросы остаются на месте).

sadman41
Offline
Зарегистрирован: 19.10.2016

Наврядли он в интегральную оценку по VOC включает частицы. VOC - это больше химия, а Particles - физика. Просто по VOC он ловит крайне широкий спектр химозы и сигарета легко организует его выброс. То, что 3 - максимальное, 0 - минимальное, а 2 - посередине - логично. Вопрос только в том, для какого существа эта середина и сколько ею можно наслаждаться. Этого без абсолютных показателей не понять.

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

CO2 действительно странный. Если все это не в барокамере происходит, то так скакать не должно. Процесс инерционный и выравнивание в сторону нормализации за секунды не происходит. Тем более пила в одних и тех же границах... Непонятное явление. Может они читают датчик по PWM и есть проблема с таймингами.... Надо по схеме смотреть. Там же какой-то общий МК стоит?

negavoid2
negavoid2 аватар
Offline
Зарегистрирован: 06.05.2020

Да, там стоит stm32f051k86, с обратной стороны платы. Почему-то думал, что VOC просто будет оценка качества по существующим датчикам, из-за цейтнота получается только урывками поиграться. CO2 очень инерционный, и пила долгая - 2-3 минуты растёт, пиковое значение, 2-3 минуты падает, потом 2-3 минуты покоя, потом всё повторяется.

sadman41
Offline
Зарегистрирован: 19.10.2016

Такой явной пилы я никогда не видел. На моих вот так: https://arduino.ru/forum/obshchii/telaire-t6703#comment-480605

Для VOC отдельный электрохимический датчик, смысла что-то вычислять, исходя из показаний других, как-то не наблюдается.

negavoid2
negavoid2 аватар
Offline
Зарегистрирован: 06.05.2020

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

PS Да, подтверждаю, PM очень мелкие показания, а VOC показывает 2-3.

sadman41
Offline
Зарегистрирован: 19.10.2016

Специально поставил период опроса 15sec,  на графике диапазон в пять минут. Пилы нет. На диапазоне в 15 мин и выше - тоже.  Датчик смонтирован в пластиковом корпусе электрического 6-постового бокса, стоит на шкафу в комнате. Никто на него специально не дышит.

Нескладуха на этой плате какая-то. Может осциллограффом подсесть на PWM NDIR-у и посмотреть, что он там выдает... ABС не должен повлиять на пилу, так как он вычисляет только смещение по оси Y в зависимости от намерянного за сутки/неделю (в зависимости от датчика). Т.е. с ABC пила будет или выше или ниже, но останется пилой.

По VOC у меня было наблюдение: рядом со свежим пластиком сенсор фонил, как безумный.

negavoid2
negavoid2 аватар
Offline
Зарегистрирован: 06.05.2020

Всё-таки дело было в питании, от повербанка пила совсем малюсенькая.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

а вот кстати, компактный сигнализатор СО2 и метана весьма актуален, кто исследует пещеры