Winsen ZE08-CH2O
- Войдите на сайт для отправки комментариев
Втр, 23/04/2019 - 15:10
Что делать, если в воздухе появился неприятный запах, а под рукой есть Ардуина? Попробуем разобраться...
Что делать, если в воздухе появился неприятный запах, а под рукой есть Ардуина? Попробуем разобраться...
2) химические фокусы с электролитом выведут датчик из строя через некоторое время (working life).
#include <SoftwareSerial.h> // Activate debug messages output #define DEBUG_ON #define WINSEN_ZE08_CH2O_UART_TX_PIN (2) #define WINSEN_ZE08_CH2O_UART_SPEED (9600) #define WINSEN_ZE08_CH2O_UART_DEFAULT_READ_TIMEOUT (2500UL) #define WINSEN_ZE08_CH2O_UART_START_BYTE (0xFF) #define WINSEN_ZE08_CH2O_UART_GAS_NAME (0x17) #define WINSEN_ZE08_CH2O_UART_GAS_UNIT (0x04) // We can use 0xFFFF as error code because sensor's ppb range is 0x00...0x1388 (0...5000) #define WINSEN_ZE08_CH2O_READ_ERROR_CODE (0xFFFF) // Store all metric's value in the pretty struct typedef struct { uint8_t gasName; uint8_t gasUnit; uint8_t noDecimalByte; uint8_t concentrationHighByte, concentrationLowByte; uint8_t fullRangeHighByte, fullRangeLowByte; uint8_t checkSum; } Ze08Ch2OData_t; uint16_t getZe08Ch2OMetric(const uint8_t _rxPin, const uint8_t _txPin) { uint8_t headerDetected = false, writePos = 0x00, checkSum = 0x00; uint16_t rc = WINSEN_ZE08_CH2O_READ_ERROR_CODE; uint32_t readStartTime;; Ze08Ch2OData_t Ze08Ch2OData; uint8_t* ptrRawBuffer = (uint8_t*) &Ze08Ch2OData; SoftwareSerial swSerial(_rxPin, _txPin); swSerial.begin(WINSEN_ZE08_CH2O_UART_SPEED); readStartTime = millis(); while ((sizeof(Ze08Ch2OData) > writePos) && (WINSEN_ZE08_CH2O_UART_DEFAULT_READ_TIMEOUT > millis() - readStartTime)) { if (!swSerial.available()) { continue; } ptrRawBuffer[writePos] = swSerial.read(); #if defined(DEBUG_ON) //Serial.print("currentChar (# "); Serial.print(writePos); Serial.print(") => 0x"); Serial.println((byte) ptrRawBuffer[writePos], HEX); #endif if (!headerDetected) { headerDetected = (WINSEN_ZE08_CH2O_UART_START_BYTE == ptrRawBuffer[0x00]); } else { writePos++; } } // Reading is not finished sucessfully: not all bytes recieved or wrong Gas ID / Unit ID contained in the packet if (writePos < sizeof(Ze08Ch2OData) || WINSEN_ZE08_CH2O_UART_GAS_NAME != Ze08Ch2OData.gasName || WINSEN_ZE08_CH2O_UART_GAS_UNIT != Ze08Ch2OData.gasUnit) { goto finish; } // Calculate checksum. //Start byte & recieved checksum is not taken in account. The first one is dropped in the read procedure and the second one just will skipped in calculation for (uint8_t i = 0x00; i < sizeof(Ze08Ch2OData) - 1; i++) { checkSum += ptrRawBuffer[i]; #if defined(DEBUG_ON) Serial.print(" 0x"); Serial.print(ptrRawBuffer[i], HEX); #endif } checkSum = (~checkSum) + 1; #if defined(DEBUG_ON) Serial.print("\nRecieved / calculated checksum: 0x"); Serial.print(Ze08Ch2OData.checkSum, HEX); Serial.print(" / 0x"); Serial.println(checkSum, HEX); #endif if (checkSum == Ze08Ch2OData.checkSum) { #if defined(DEBUG_ON) // rc = (Ze08Ch2OData.fullRangeHighByte << 0x08) + Ze08Ch2OData.fullRangeLowByte; Serial.print("Full range (ppb): "); Serial.println(rc); #endif rc = (Ze08Ch2OData.concentrationHighByte << 0x08) + Ze08Ch2OData.concentrationLowByte; } finish: swSerial.~SoftwareSerial(); return rc; } void setup() { Serial.begin(115200); Serial.println("Winsen ZE08-CH2O sensor reading demo (UART, active mode)"); ; } void loop() { delay(2000); uint16_t ch2O = getZe08Ch2OMetric(WINSEN_ZE08_CH2O_UART_TX_PIN, WINSEN_ZE08_CH2O_UART_TX_PIN); Serial.print("["); Serial.print(millis()); Serial.print("] CH2O: "); if (WINSEN_ZE08_CH2O_READ_ERROR_CODE != ch2O) { Serial.print(ch2O); Serial.print(" ppb, \t"); Serial.print(ch2O / 1000.0, 3); Serial.println(" ppm"); } else { Serial.println("read error"); } }Отчёт с испытаний - несколько секунд подержал над чужой бутылкой с чем-то "протирающим" (на этикетке написано "Раствор антисептический, медицинский. Этанол 95%", хозяин утверждает, что содержимое соответствует):
В процессе изучения справочных материалов выяснилось, что датчики MH-Z14A, MH-Z19B v2.0 (опознаётся по наличию доп.разъема на отламываемой площадке текстолита) и ZE08-CH2O имеют практически одинаковую распиновку одного из выходных разъёмов (в MH-Z19B, например, не выведен PWM, но UART/питание совпадают у всех трёх), формат пакетов обмена по UART в пассивном режиме работы (запрос-ответ), алгоритм расчёта контрольной суммы (несмотря на то, что приведённые в datasheet примеры выглядят по-разному). Это факт можно учитывать при сборке измерителя уровня CO2+формальдегид.
Comment #1 reserved for future use.
Comment #2 reserved for future use.
Вот интересно, как авторы тем представляют себе эту "просьбу не комментировать".
Вот, скажем, прочитал я основной пост темы.
Все 3-4 экрана.
Потом автору захотелось добавить на 2-м и 4-м экранах по одному предложению.
Т.е. по мнению автора я буду перечитывать эти 4 экрана, чтобы найти изменения?
Мне кажется, сама эта идея - дополнять первый пост - порочная. Все дополнения следует делать отдельными постами. А если тема вдруг, наконец, обретет свой окончательный вид, то перевыложить все в последнем посте, либо создать новую - в окончательном варианте.
А у меня другое соображение: пришёл читатель в тему, ознакомился с первопостом, а потом ещё нужно все 100500 страниц изучить, чтобы узнать, где была допущена опечатка, например?
Не, ну как вариант:
1. Исправления в основном тексте выделяются цветом. Через пару дней цвет меняется, а через неделю - становится обычным.
2. Исправления дублируются новым постом.
И, кстати, как я могу узнать:
- что в текст пробралась опечатка?
- что она была исправлена?
- в каком месте основного поста ее следует искать?
При всём уважении, andriano, мне бы не хотелось переводить общение по теме в спор о том, какой способ нарезания подаваемого за стол хлеба более правильный: вдоль, поперёк или по диагонали. Вашу позицию я понял (хотя и не во всём согласен), свою объяснил.
Это все понятно.
Прошу прощения, что отписался именно в твоей теме, но кому-то ведь должно было не повезти, т.к. подход достаточно частый и, на мой взгляд не удоный.
Ты - услышал. Те, кто будет создавать подобные темы (а в том, что они нужны и очень полезны, ни у кого сомнения нет) - тоже, надеюсь, услышали. Так что теперь, по-хорошему, надо бы посты с №4 по №8 удалить. Ну или постепенно перевести их в резерв аналогично №2-3.
Еще раз прошу прощения.
В отвлечённых было что-то по оформлению постов - можно туда переместиться.
Спасибо, заработало сразу как надо, вот только иногда проскаивает:
Да, вижу ошибку. До компьютера доберусь - исправлю.
...ошибка, похоже, по стечению обстоятельств, не влияла на корректность результата. Тем не менее - код в посте немного изменил, добавил отладочного вывода. Нужно проверить, что из датчика прилетает (строки #70 и #71).
Впрочем, я вижу, что вывод отличается от моего - может Вы неправильно рассматриваете return code функции? 0xFFFF, он же 65535 - код ошибки, который говорит о том, что сенсор не ответил или ответил некорректным пакетом.
Прошу прощение за поднятие некропоста, но сам ковыряю сабж и тоже имею в минимуме 47 ppb
По нормативам это дофига, не думаю, что действительно у меня в проветренной комнате такой уровень. Может быть, датчик не откалиброван? Вроде как в даташите есть калибровка нуля, но с припиской only for factory use. Вот думаю, попробовать откалибровать или просто вычитать 47 из показаний, учитывая, что график зависимости напряжения от концентрации формальдегида линейный?
Калибруют со специальными поверочными смесями. В быту нет смысла, думаю, браться.
Мой 47ppb не выдавал. Может отнести его в другое место?
47 - это я про логи Coldman. Мой, помнится, за окном 20 ppb показывал. Попробую еще погулять с ним.