Plantower PMS-A003 и все-все-все

sadman41
Онлайн
Зарегистрирован: 19.10.2016
Ниже будет размещен небольшой рассказ о том, как дать езды датчику качества воздуха (Air Quality Seensor) Plantower PMS-A003. 
 
sadman41
Онлайн
Зарегистрирован: 19.10.2016
Большая просьба не комментировать этот пост, так как возможны дополнение и актуализация сведений, приведенных в нем.
 
Размерности и нормативы 
 
Забегая вперед, приведу некоторые сведения из общедоступных научно-популярных источников.
 
Размерности частиц, которые могут быть измерены датчиком:
- в среднем линейные размеры бактерий лежат в пределах 0,5–3 мкм; [http://evolution.powernet.ru/library/micro/03.html]
- мелкие грибные споры (1,5—5,0 мкм) способны достигать лёгочных альвеол и вызывать грибные (плесневые) заболевания человека ["Наука и жизнь"]; 
- крупные грибные (плесневые) споры (более 5,0 мкм) при вдыхании проникают в носоглотку неглубоко и чаще способствуют развитию аллергий ["Наука и жизнь"];
 
Англоязычная википедия наглядно рассказывает про разные взвешенные частицы.
 
Предельными допустимыми концентрациями частиц, установленными гигиеническими нормативами ГН 2.1.6.3492-17 "Предельно допустимые концентрации (ПДК) загрязняющих веществ в атмосферном воздухе городских и сельских поселений", являются:
a) Для взвешенных частиц PM 2.5 (2,5 мкм)
   - максимальная разовая 160 μg/m³ (0.16 мг/м³);
   - среднесуточная 35 μg/m³ (0.035 мг/м³), значение 99 перцентиля (отбрасывается 1% самых высоких значений из взятых проб);
   - среднегодовая 25 μg/m³ (0.025 мг/м³);
b) Для взвешенных частиц PM 10 (10 мкм)
   - максимальная разовая 300 μg/m³ (0.16 мг/м³) concentration units;
   - среднесуточная 60 μg/m³ (0.06 мг/м³), значение 99 перцентиля;
   - среднегодовая 40 μg/m³ (0.05 мг/м³);
 
Для оценки качества воздуха так же используется Air Quality Index, вычисляемый по простой формуле кусочно-линейной функции (piecewise linear function), который отображается на многих картах мониторинга выбросов, например такой: http://aqicn.org/city/beijing/
 
Свои соображения по поводу измерений PM2.5/CO2 и жизни с ними в доме с печным отоплением высказывает Виктор Борисов.
 
Рекомендуется к прочтению тема на IXBT, где обсуждаются фабрично изготовленные измерители загрязнения воздуха, однако встречаются и отзывы на отдельные датчики.
 
Общее описание
 
Сенсор Plantower PMS-A003 представляет собой хитроумное устройство, посредством встроенных лазерной неонки и думателя измеряющее и пересчитывающее микроскопические частицы, летающие по округе. Интернеты утверждают, что он измеряет фракции размером от 0.3мкм до 10мкм, что может помочь измерить количество бактерий, выдыхаемых здоровым ардуинщиком, или плесеневых грибков, если здоровье уже не то, что ране.  Так же, думаю, он справится с подсчетом объема копоти при излишне усердной пайке с канифолью.
 
В справочном листе датчика 1 μg/m³ рассматривается как единица измерения концентрации (concentration units)
 
Основная область применения сенсора китайскими пользователями - измерение концентрации "ультрадисперсных частиц" с целью определения необходимости надевания фильтрующего намордника и его типа.
 
Plantower PMS-A003 представляет собой миниатюрное корпусированное изделие с установленным внутри вентилятором, который через отверстие на торце затягивает воздух для анализа в камеру с установленными там лазерным излучателем и фотодатчиком. Голубой цвет - защитная пленка. A003 означает десятое поколение (PMS-5003 - пятое, PMS-7003 - седьмое). Изменения, как я понимаю, в конструктиве камеры и электронике, нацеленные на более стабильную работу и воспроизводимость результата измерений между разными экземплярами. 
 
Принцип работы схожего датчика (от Honeywell) и его отличия от "светодиодных" моделей доходчиво описано в в журнале «Вестник Электроники» №1 2018, стр. 56-58
 
Найдена переводная англоязычная документация, или же можно ознакомиться с ней в первоисточнике, на китайском языке.
 
Судя по форумам, такой сенсор стоит в этом анализаторе, а исходя из фото, на котором видно, что он расположен посредине материнской платы и высовывание его воздухозаборником наружу не требуется, достаточно в корпусе щелей наделать:
 
 
Внутренний мир датчика примерно таков (подробней):
 
Оценить размер в масштабе:
 
 
Метрики устройство выдает в готовом виде через интерфейс UART. Производитель заявляет, что есть варианты с I2C, но на Алиэкспрессе я их не встречал.
 
Датчик не без проблем.
 
Первая: питание датчика +5V (для работы вентилятора), а TTL-уровень UART - 3.3V. Эта неприятная особенность частично нивелируется тем, что для получения данных достаточно только одного выхода TX, который, полагаю, может быть подключен напрямую к микроконтроллеру с 5V TTL при условии, что соответствующий вывод МК будет всегда находится в состоянии INPUT.  Однако, я не рискнул и применил преобразователь логических уровней такого типа (на борту стоит стабилизатор 3.3V, что избавляет от необходимости искать это напряжение на стороне) https://ru.aliexpress.com/item/5pcs-free-shipping-IIC-I2C-5-3v-level-shifter-module-Conversion-sensor-system-compatible-for-Arduino/32624528143.html
 
Вторая: интерфейсный разъём специфический и имеет шаг (pitch) 1.27мм.
Расследование показало, что внутри установлен разъем Harwin M50-4910545R , ответной частью к нему служит Harwin M50-4300545. Продавец положил в комплект отдельное гнездо типа Minitek 1.27 / PBD1.27-10 (2x5, DIP) и готовый переходник с такого гнезда на не менее дурацкий однорядный разъем с тем же шагом - 1.27мм.
Анализ сложившейся ситуации показал, что выходом из нее могут быть:
1) Комплект из дешевого переходника SOP-14 и PBD1.27-10S (SMT модификация);
2) Сверление переходника SOP-14 -> DIP под PBD1.27-10 из комплекта;
3) Отрезание одного из разъемов на шлейфе из комплекта;
4) Использование кабеля/переходника для SWD-программатора;
5) Изготовление переходника методом ЛУТ;
 
После замеров и чтения справочных листов я понял, что IDC1.27 (на SWD-кабеле) не влезет в разъем без подпиливания, а подпиливание его разрушит. Оптимальным вариантом посчитал 5-й (ЛУТ), так как он позволяет решить дополнительные задачи, такие как: крепление датчика к корпусу, установка схемы конвертора уровней прямо около выхода сенсора (о чем я слишком поздно сообразил).
 
При грандиозной помощи bwn был создан такой переходник, который при помощи подручных инструментов и... матери всех драконов был интегрирован в уже давно работающую конструкцию (запаяно моими корявыми руками):
 
 
 
 
Первичное тестирование 
 
За время нахождения на столе в помещении сенсор показал при следующих событиях: 8:30 я пришел в помещение, открыл окно; ~8:40 дыхнул в оба датчика; ~9:15 закрыл окно.
 
Интервал 14 часов: CO2; количество частиц, посчитанных по фракциям, концентрация частиц.
 
 
 
Интервал 2 часа: CO2; количество частиц, посчитанных по фракциям, концентрация частиц.
 
 
 
 
На ранее заданный вопрос о заменимости сенсора PM2.5 на простой Co2 можно ответить, что явной корелляции на коротком интервале не наблюдается.
 
Время жизни датчика
 
К великому сожалению - сенсор не вечен. Установленный внутри лазерный светодиод деградирует и, через некоторое время, показания датчика становятся недостоверными. Теоретически это можно исправить заменой светодиода и/или повторной калибровкой прибора, однако способ проведения таковой операции в бытовых условиях мне неизвестен.
 
Достоверных данных о времени жизни на текущий момент не получено, однако многие источники в сети Internet приводят цифру в 8000 часов непрерывной работы. Небольшой поиск приводит к одной точке распространения этих сведений: https://www.letscontrolit.com/wiki/index.php/PMSx003 , где утвержадется, что "The laser diode inside the PMSx003 has a lifetime of about 8000h, nearly one year", однако официальной доступной документацией этот срок не подтверждается. Таковая цифра упоминается в документации на датчик частиц другого производителя - Inovafitness SDS011. В ней написано: "Service life is the key parameter of laser dust sensor. The laser diode in this sensor has high quality and its service life is up to 8000 hours."
 
В описаниии более дорогого устройства, такого как Telaire SM-UART-04L, содержится следующая строка: "Laser Life (Average Time Before Re-Calibration) - 40,000 hour". Таким образом, можно, тыкнув пальцем в небо, полагать, что в обозреваемом сенсоре стоит менее качественный светодиод и, вероятно, 8000 часов наработки - сопоставимая с его ценой цифра. 

Предполагаю, что продление времени жизни лазерного светодиода может быть осуществлено путём эксплуатации в режиме "сон/активность" (манипуляция входом #10). В официальных источниках этот момент так же обойдён вниманием, поэтому только остаётся довольствоваться гипотезами или производить реверс-инжиниринг датчика. 

Обратите внимание на то, что сенсор выходит на режим "достоверные данные" через 30 секунд после возврата из режима сна или после включения. Это связано с тем, что вентилятор, прогоняющий воздух через камеру замера, останавливается на время сна. Дословно в документации написано: "Stable data should be got at least 30 seconds after the sensor wakeup from the sleep mode because of the fan’s performance."
 
...пришёл ответ из службы поддержки Plantower, в которую я обратился, окончательно погрязнув в предположениях из интернетов:
 
------------------------------
Our sensor lifetime in our datasheet is 3years, but actually it can use more than 4.5year with works continuously.
 

Best regards,
Holly Gao(Ms.)

Sales Executive-Marketing Dept.
Beijing Plantower Technology Co., Ltd.
#613,Building 9,Yuxi Road No.9,Houshayu,Shunyi District,Beijing, P.R.China.

------------------------------

Получение показаний
 
В соответствии с англоязычной документации (или оригинальной китайской), датчик после включения переходит в так называемый "активный" режим и не требует подачи дополнительных команд для начала передачи метрик. Интервал передачи (не обновления!) значений метрик происходит каждые 800...200мс. При незначительном изменении концентрации регистрируемых частиц, актуализация данных происходит в "стабильном" подрежиме - каждые ~2.3 сек. Таким образом - в течении ~2.3 секунд трижды передаётся одно и то же значение. Резкое изменение концентрации (уровень не выяснен) приводит к переключению датчика в "быстрый" подрежим - время актуализации и передачи данных начинает снижаться до 200мс, таким образом каждый раз происходит передача обновлённых значений метрик.   
 
Собственную программную реализацию работы с сенсором приведу чуть ниже. Так же можно посмотреть на скетч от Adafruit. Те модели, по которым я нашел описания, имеют одинаковый протокол обмена (PMS-5003PMS-7003), так что можно брать любой доступный скетч для PMS-x003.
 
Моя версия кода. Вырезана из более объемного прожекта, поэтому некоторые приемы экономии на спичках могут показаться странными.
#include <SoftwareSerial.h>

#define PLANTOWER_UART_TX_PIN                                   (3)
#define PLANTOWER_UART_SPEED                                    (9600)
#define PLANTOWER_DEFAULT_READ_TIMEOUT                          (2500UL)

// Store all metric's value in the pretty struct
typedef struct {
  uint16_t frameLength;
  uint16_t standartPM10, standartPM25, standartPM100;
  uint16_t environmentPM10, environmentPM25, environmentPM100;
  uint16_t particles03um, particles05um, particles10um, particles25um, particles50um, particles100um;
  uint16_t unused;
  uint16_t checkCode;
} plantowerData_t;

// Get all metrics at once
uint8_t getPlantowerPMSMetrics(const uint8_t _rxPin, const uint8_t _txPin, plantowerData_t* _ptrPlantowerData) {
  uint8_t rc = false, headerDetected = false,
          writePos = 0x00;
  uint16_t checkCode;
  uint32_t readStartTime;

  // Reuse struct cells as work array
  uint8_t* ptrRawBuffer = (uint8_t*) _ptrPlantowerData;
  uint16_t* ptrConvertedBuffer = (uint16_t*) _ptrPlantowerData;

  SoftwareSerial swSerial(_rxPin, _txPin);
  swSerial.begin(PLANTOWER_UART_SPEED);

  readStartTime = millis();
  // Wait for all bytes for structure readed until time is not out
  while ((sizeof(plantowerData_t) > writePos) && (PLANTOWER_DEFAULT_READ_TIMEOUT > millis() - readStartTime)) {
    if (!swSerial.available()) {
      continue;
    }

    ptrRawBuffer[writePos] = swSerial.read();
    //Serial.print("currentChar (# "); Serial.print(writePos);  Serial.print(") => 0x"); Serial.println((byte) ptrRawBuffer[writePos], HEX);

    // Header of packet: 0x42 0x4D
    // On header waiting test first two byte every time when its in buffer (writePos == 0x01)
    // if signature is detected - write real data from the start of buffer
    // if not - just move second byte to first position and continue writing to the next cell of buffer
    if (!headerDetected) {
      if (0x01 == writePos) {
        headerDetected = (0x4D == ptrRawBuffer[0x01] && 0x42 == ptrRawBuffer[0x00]);
        if (headerDetected) {
          continue;
        } else {
          ptrRawBuffer[0x00] = ptrRawBuffer[0x01];
        }
      }
    }
    writePos++;
  }
  // Reading is not finished sucessfully
  if (writePos < sizeof(plantowerData_t)) {
    goto finish;
  }

  // Checkcode is sum of all bytes except packet's "check code" value (2 bytes). Two first byte always is 0x42 & 0x4D and can be precalculated
  checkCode = 0x42 + 0x4D;
  for (uint8_t i = 0; i < (sizeof(plantowerData_t) - 2); i++) {
    checkCode += ptrRawBuffer[i];
  }

  // Convert bytes to uint16_t
  for (uint8_t i = 0; i < (sizeof(plantowerData_t) / 2); i++) {
    //    uint16_t tmpValue = (ptrRawBuffer[0x00] << 8) | ptrRawBuffer[0x01];
    //    *ptrConvertedBuffer = tmpValue;
    // It's safe ?
    *ptrConvertedBuffer = (ptrRawBuffer[0x00] << 8) | ptrRawBuffer[0x01];
    ptrRawBuffer += 2;
    ptrConvertedBuffer += 1;
  }

  //Serial.print("checkCode (calc): "); Serial.println(checkCode, HEX); Serial.print("checkCode (read): "); Serial.println(_ptrPlantowerData->checkCode, HEX);

  rc = (checkCode == _ptrPlantowerData->checkCode);

finish:
  swSerial.~SoftwareSerial();
  return rc;
}

/***********************************************************************************************/
void setup() {
  Serial.begin(115200);
  Serial.println("Let's read!");

}

void loop() {
  uint8_t rc;
  plantowerData_t plantowerData;

  while (true) {
    Serial.print("\n\nTimestamp: "); Serial.print(millis());

    // RX pin does not used anyway
    rc = getPlantowerPMSMetrics(PLANTOWER_UART_TX_PIN, PLANTOWER_UART_TX_PIN, &plantowerData);
    if (rc) {
      Serial.println("\n---------------------------------------");
      Serial.println("Concentration Units (standard)");
      Serial.print("PM 1.0: "); Serial.print(plantowerData.standartPM10);
      Serial.print("\t\tPM 2.5: "); Serial.print(plantowerData.standartPM25);
      Serial.print("\t\tPM 10: "); Serial.println(plantowerData.standartPM100);
      Serial.println("---------------------------------------");
      Serial.println("Concentration Units (environmental)");
      Serial.print("PM 1.0: "); Serial.print(plantowerData.environmentPM10);
      Serial.print("\t\tPM 2.5: "); Serial.print(plantowerData.environmentPM25);
      Serial.print("\t\tPM 10: "); Serial.println(plantowerData.environmentPM100);
      Serial.println("---------------------------------------");
      Serial.print("Particles > 0.3um / 0.1L air:"); Serial.println(plantowerData.particles03um);
      Serial.print("Particles > 0.5um / 0.1L air:"); Serial.println(plantowerData.particles05um);
      Serial.print("Particles > 1.0um / 0.1L air:"); Serial.println(plantowerData.particles10um);
      Serial.print("Particles > 2.5um / 0.1L air:"); Serial.println(plantowerData.particles25um);
      Serial.print("Particles > 5.0um / 0.1L air:"); Serial.println(plantowerData.particles50um);
      Serial.print("Particles > 10.0 um / 0.1L air:"); Serial.println(plantowerData.particles100um);
      Serial.println("---------------------------------------");
    }
    delay(1000);
  }
}

Интерпретация значений

Сразу интересный факт: заголовок пакета схож с заголовком BMP-файла.

В пакете, получаемом от сенсора, можно увидеть следующие подвиды метрик: "Concentration unit (CF=1, standard particle)" , "Concentration unit (under atmospheric environment)", "The number of particles with diameter". 

На данный момент однозначно понятна только последняя, представляющая собой RAW-данные - количество частиц разных диаметров (в штуках), пролетевших мимо фотоэлемента за известный только одному производителю период. 

По поводу первых двух, полагаю, стоит опираться на "Note: CF=1 should be used in the factory environment". Т.е. в производственных условиях учитывать значения "CF=1" метрик, а в домашних - "under atmospheric environment". Хотя, на мой субъективных взгляд, большого разброса в них нет.

Я нашёл небольшую дискуссию по этому поводу: https://publiclab.org/questions/samr/04-07-2019/how-to-interpret-pms5003-sensor-values#c23772 , но вынужден констатировать, что приведённый ответ носит лишь предположительный характер.

Ben Kinh Tan в своей работе "Laboratory Evaluation of Low to Medium Cost Particle Sensors" пишет следующее: "Number concentrations are divided into six size channels. For mass concentration, the sensor reports readings for a ”standard” and ”atmospheric” type particle. The “standard” reading refers to industrial metal particle densities used for mass calculations and is suitable for environments such as an industrial production workshop. The “atmospheric” reading refers to pollutants commonly found in the atmosphere, and suitable for use in an indoor environment."

Служба поддержки Plantower сообщает:
---------------------------------------------
CF=1 means the metal particle in the certain environment such as the Industrial metal plant. 
Atmospheric environment is the particels in the normal air environment.

---------------------------------------------

sadman41
Онлайн
Зарегистрирован: 19.10.2016

Эксперимент №1. Канифолька.

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

Датчики находится на обычном расстоянии  - от паяльника до носа. События: 14:06 - окурил датчики дымком. Далее периодически тыкал горячим жалом в банку. В ~14:16 открыл окно в трех метрах от точки испытания и продолжил имитацию процесса паяния. В ~14:19 паяльник выключил и через пару минут убрал от сенсоров. Затем ушел, оставив окно в режиме среднего проветривания. И только в ~14:32 концентрации пришли в норму.

Из графиков видно, что величина CO2 остается терпимой (https://tion.ru/blog/normy-co2/) - до 800 PPM , а вот всякие взвеси в воздухе возрастают до адских значений (см. пост #1, раздел "Размерности и нормативы").

Примечание: concentration unit - 1 μg/m³ 

Вопросы / замечания ?

sadman41
Онлайн
Зарегистрирован: 19.10.2016

Эсперимент №2. Жилая комната.

Датчик два дня провел в жилой комнате обычного панельного дома в двух метрах от балконной двери, через которую осуществлялось периодическое проветривание и запуск взвешенных частиц снаружи. Графики за полтора дня, так как именно в этот интервал накапливались метрики "дневная доза по PM" (фиолетовая, коричневая и розовая горизонтальные линии на графике концентрации. Розовая в крапинку - триггерная).

Доза вычислялась по перцентилю 99, граничные значения в соответсвии с ГН 2.1.6.3492-17  (см. пост #1). 

Выяснилось следующее: робот-пылесос пыли не поднимает, сжигаемый материал в виде подогревающей свечи на расстоянии метра-полутора дает резкий скачок концентрации частиц (до 50 units по PM2.5) и постепенный спад (быстро до ~10 units по PM2.5 и медленно до ~5). Принюхивается что ли... Далее показания держатся вплоть до тушения источника огня. Причем, как будет видно на графиках интервалом в 5 часов - датчик нервничает каждый раз после проветривания. С чем связанно данное поведение я пока не понял, но учитывать такую особенность стоит - отбрасывать пики тем же перцентилем, например. Zabbix это умеет из коробки, в самопальных системах придется постараться. В целом за дневную норму выйти не получилось, стандартная бытовая активность роста концентрации частиц не вызывает (чего не скажешь о CO2 - на последнем графике) - держится на уровне 1-4 units (микрограмм/кубический метр).

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

sadman41
Онлайн
Зарегистрирован: 19.10.2016

Схожее, но более системное исследование "Monitoring Indoor Air Quality Using Low Cost Sensors at a Community Scale", проведёноое Yifang Zhu, Fanyu Zhang, Emily Marino Department of Environmental Health Sciences University of California, Los Angeles (UCLA) Vasileios Papapostolou, Brandon Feenstra, Berj Der Boghossian, Hang Zhang South Coast Air Quality Management District (AQMD): https://asic.aqrc.ucdavis.edu/sites/g/files/dgvnsk3466/files/inline-files/Yifang%20Zhu%20Air%20sensor_UCLA%20Village_Final.pdf

Приведены примеры измения PM в различных бытовых сценариях: кухонные дела - готовка, проветривание, а так же влияние внешних источников загрязнения, помощь очистителей воздуха и пр. Использовалось 12 Outdoor Sensors и 18 Indoor Sensors.

И ещё несколько долгих тестов датчиков...

Laboratory Evaluation of Low to Medium Cost Particle Sensors by Ben Kinh Tan.  A thesis presented to the University of Waterloo in fulfillment of the thesis requirement for the degree of Master of Applied Science in Mechanical and Mechatronics Engineering Waterloo, Ontario, Canada, 2017 © Ben Kinh Tan 2017

https://uwspace.uwaterloo.ca/bitstream/handle/10012/12776/Tan_Ben.pdf?sequence=5&isAllowed=y

Field evaluation of low-cost particulate matter sensors in high- and low-concentration environments

Tongshu Zheng, Michael H. Bergin, Karoline K. Johnson, Sachchida N. Tripathi, Shilpa Shirodkar, Matthew S. Landis, Ronak Sutaria, and David E. Carlson
Department of Civil and Environmental Engineering, Duke University, Durham, NC 27708, USA
Department of Civil Engineering, Indian Institute of Technology Kanpur, Kanpur, Uttar Pradesh 208016, India
US Environmental Protection Agency, Office of Research and Development, Research Triangle Park, NC 27711, USA
Center for Urban Science and Engineering, Indian Institute of Technology Bombay, Mumbai, Maharashtra 400076, India
Department of Biostatistics and Bioinformatics, Duke University, Durham, NC 27708, USA
Published: 22 August 2018

https://www.atmos-meas-tech.net/11/4823/2018/amt-11-4823-2018.pdf

b707
Offline
Зарегистрирован: 26.05.2017

очень занимательно. А на работу не носил? Мне вот особенно интересно, что оно показало бы у меня - в условиях химбиолабораторий на территории большой промзоны :)

Не увидел в теме ссылки на продавца, у которого ты брал датчик. Может просмотрел

sadman41
Онлайн
Зарегистрирован: 19.10.2016

Брал тут: Double lung electronic

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

https://ru.aliexpress.com/item/PLANTOWER-Laser-PM2-5-DUST-SENSOR-A003-High-precision-laser-dust-concentration-sensor-digital-dust-particles/32755423100.html

На работе мерял канифоль. Но я не в промзоне работаю, так что одинаково по фону - что дом, что контора.

UPD: в первопост добавлен раздел "Время жизни датчика"
UPD2: так же осуществлена попытка собрать в кучу найденную информацию в разделе"
Интерпретация значений"

UPD3: служба поддержки Plantower озвучила срок эксплуатации датчика. См. в разделе "Время жизни датчика" первопоста.
UPD4: появилась информация о трактовке метрик, отмеченных как (CF=1, standart particle).