Получение показаний датчиков метеостанции DYKIE
Очередная рассылка от 8devices о том, что появилось в продаже новое устройство WeIO очень меня заинтересовала. Сделана она на базе Carambola2, но дополнительно появились интерфейсы UART, SPI, I2C и поддержка MicroSD. Кроме того, заявлено, что это так же сделано на базе OpenWrt, что означает, что можно добавить очень много других дополнительных пакетов. Сразу было заказано два таких устройства. Выглядит это устройство так:
Питание можно подать как через отдельный разъем, так и через разъем MiniUSB. Интересный способ подготовки устройства сначала мне показался необычным. Устройство сразу включалось в режиме точки доступа WiFi. К этой сети нужно было подключиться, зайти без пароля и сконфигурировать подключение к нужной сети.
Для проверки работоспособности интерфейса I2C был подключен датчик давления и температуры LPS331AP. Проблем с подключением не возникло, на основе примера работы с интерфейсом I2C был написан несложный код на Python и устройство без проблем начало снимать показания. Этого показалось мало….
Так как у меня есть небольшая метеостанция DYKIE с беспроводными датчиками возникла идея получать показания с этих датчиков. Вот как выглядит сама метеостанция с датчиком:
Вдохновленный примерами снятия показаний с метеостанции Vitek VT-6404 взялся за дело. Прежде всего удалось выяснить, что датчики передают показания на частоте 433 Мгц (написано на самом датчике). Разбор датчика результатов не дал. Китайские платы не всегда можно идентифицировать, просто кусок платы с бескорпусной микросхемой без маркировки. Разборка самой метеостанции оказалась более результативной. На приемнике видно, что он основан на микросхеме PT4303-S. Тут же был заказан приёмник (и передатчик в комплекте) на основе этой микросхемы. Выглядят они так:
Приемник передает данные через один контакт. Этот контакт был подключен к WeIO и началась эпопея снятия показаний с беспроводного датчика. Нужно ли говорить, что простое снятие сигнала с беспроводного приемника ничего, кроме хаоса каких то странных сигналов не давало. Дальнейшее исследование показало, что код на Python-е не может снимать показания даже с одного цифрового GPIO с частотой более 500Гц. Что, конечно, оказалось неожиданным, но вот эта статья объяснила, что на питоне максимальная частота опроса даже цифрового порта GPIO не превышает 500 Гц. Попытки выполнить рекомендации статьи по увеличению быстродействия у меня не привели к существенному росту производительности. Стало понятно, что такой производительности для снятия показаний с беспроводного датчика недостаточно. Изучение документации как собрать собственную прошивку и написать модуль на с привело к грустному выводу — можно, но достаточно сложно. Поэтому было принято решение попробовать для этих целей другой модуль от Arduino. Выбор пал на на Arduino Nano.
Давно слышал про Arduiono и вот теперь предоставилась возможность попробовать. Первые впечатления оказались очень положительными (особенно когда нашел, что для загрузки скетча следует использовать OldBootloader). Скорость опроса цифрового GPIO оказалась в пределах 4 микросекунд (10-6 секунды), что превышало мои самые смелые ожидания. Однако, опрос даже с такой частотой не принес понимания, что же творится в хаосе эфира на частоте 433 МГц. Поэтому пришлось просто разобрать датчик метеостанции и подключиться к разъему Data передатчика. После оцифровки и анализа стало понятно, что с интервалом примерно в одну минуту датчик делает посылку, в которой передает от 4 до 6 одинаковых пакетов. Отдельный пакет выглядит так:
Анализ показал, что посылка состоит из серии сигналов начинающихся с сигнала высокого уровня ~ 500 мс, за которым следует пауза. Паузы бывают трех видов:
- 2000 мс — логический ноль,
- 4000 мс — логическая единица,
- 8000 мс — признак начала посылки.
Вот пример посылки, указана длительность сигналов и пауз (нечетное значение сигнал, четное — пауза):
504,8144,508,8144,508,2044,496,2040,504,2052,508,2048,504,4108,508,4144,504,4120,500,2052,504,2048,508,4156,496,2064,496,4116,496,2060,496,4156,504,4108,508,2048,504,2052,496,4156,504,2052,508,4108,504,4116,496,4164,500,2052,512,4108,496,4116,504,2092,504,4108,504,2060,500,4116,504,2088,508,2052,504,2048,500,2060,504,4156,500,2052,504,2060,496,2052,504,2096,500,4116,504,2052,504,2052,504,4176,
508,8152,504,8152,496,2040,504,2052,496,2052,504,2060,496,4116,504,4156,500,4116,504,2060,496,2060,496,4164,500,2048,504,4244,504,2060,500,4156,504,4120,504,2052,504,2052,504,4156,504,2052,508,4116,504,4116,500,4164,492,2060,500,4116,504,4116,508,2100,492,4120,504,2052,504,4116,508,2088,496,2060,504,2052,508,2048,504,4168,496,2060,496,2060,496,2060,504,2100,496,4120,504,2064,500,2060,504,4184,
500,8160,504,8160,500,2052,496,2052,496,2060,504,2060,500,4116,504,4164,496,4120,504,2060,496,2060,504,4156,508,2048,504,4128,500,2060,504,4152,504,4120,508,2060,492,2060,508,4156,504,2060,496,4128,496,4124,500,4164,504,2052,508,4120,504,4124,500,2096,504,4120,508,2060,496,4128,500,2100,504,2060,496,2060,504,2060,500,4160,508,2060,496,2060,508,2052,504,2100,508,4116,504,2060,496,2060,504,4196,
496,8172,504,8164,504,2044,504,2048,500,2060,504,2060,496,4128,504,4156,508,4128,496,2060,504,2064,496,4164,508,2060,504,4116,508,2060,504,4156,508,4124,508,2048,504,2060,508,4164,496,2060,508,4128,496,4128,508,4168,504,2048,508,4128,504,4124,500,2100,504,4124,500,2060,504,4124,500,2096,504,2060,508,2060,504,2052,508,4160,508,2060,504,2060,500,2060,504,2096,508,4128,504,2048,508,2060,504,4196,
496,8180,496,8180,500,2048,504,2052,496,2060,504,2064,496,4128,504,4172,500,4124,504,2060,500,2060,504,4176,496,2060,504,4128,504,2060,496,4176,504,4252,496,2060,504,2060,508,4168,504,2064,504,4128,504,4128,496,4176,504,2060,496,4132,500,4124,504,2108,500,4124,504,2060,508,4128,504,2100,504,2064,508,2064,496,2060,504,4176,496,2060,504,2060,508,2060,504,2100,508,4124,504,2060,508,2060,504,4184,
504,8172
Если принять начало посылки за X то посылка выглядит так (не та что в примере выше):
XX00 10100111 0100 0101 1110 0011 0011 0101 01000001
XX00 10100111 0100 0101 1110 0011 0011 0101 01000001
XX00 10100111 0100 0101 1110 0011 0011 0101 01000001
XX00 10100111 0100 0101 1110 0011 0011 0101 01000001
XX00 10100111 0100 0101 1110 0011 0011 0101 01000001
X
Части посылки одинаковы, видимо для контроля. Разбираем отдельную часть:
Значение полей:
- FB — первый байт, суть не ясна, предположительно случайное число которое генерируется при включении датчика.
- CH — канал датчика. По умолчанию к метеостанции может быть подключено 3 датчика. Это значение определяет номер датчика — 1.
- T — температура. Значение пришлось вычислять сравнивая с показаниями метеостанции (порядок полубайт байт обратный T = (T2 << 8) | (T1 << 4) | T0). Формула получилась такого вида:
Температура в цельсиях = T/18.0 — 67.775; - H — влажность. Порядок полубайт обратный H = (B1 << 4) | B0
- CRC — предположительно контрольная сумма. Алгоритм вычисления определить пока не удалось, что создает сложности с определением достоверности полученных данных. Пока считаю показания достоверными, если в одном пакете есть две одинаковых посылки. Одинаковые искажения обоих посылок маловероятны.
Для примера описание байт совсем другого датчика можно посмотреть здесь. Есть некоторая аналогия.
Полученные таким образом посылки Arduino Nano передает через UART в новое устройство WeIO. Получился хороший вариант, быстродействующая Arduino следит за эфиром, ловит посылки, расшифровывает их и передает на обработку в WeIO кардинальным образом снижая нагрузку на последнего.
Если научиться вычислять контрольную сумму, можно без проблем пересылать на метеостанцию свои данные. Кроме того, это несколько повысит достоверность получаемых данных.
Результат исследований можно посмотреть здесь.
Первый опыт использования 3D принтера Дальнейшее исследование формата передачи показаний датчиков метеостанции DYKIE