В предыдущей части я писал про попытку создания счетчика импульсов газового счетчика с измерением температуры и влажности двумя отдельными датчиками. И там же я отметил что, даже несмотря на то, что созданное устройство работает, мне захотелось реализовать нечто большее. Мне, необъяснимым образом, потребовалось подключить устройство к сети интернет не посредством витой пары, а беспроводным способом, а заодно измерять атмосферное давление. Впрочем, захотелось вполне объяснимым образом — кончились свободные порты на установленном коммутаторе локальной сети в месте установки устройства, а свободные слоты для подключения Wi-Fi устройств еще остались на двух роутерах. Кроме того, датчик атмосферного давления выгодно дополнил бы погодный функционал.
Собственно, для опытов и для создания конечного устройства из закромов было изъято две платы WeMos D1 R2 на чипе от Espressif, два датчика DHT22 от RobotDyn, плата GY-68 с датчиком BMP180.
Проблемы
При сборке любого устройства своими силами неминуемо возникают проблемы различного характера. Не обошлось без удивительных непонятностей и в этом проекте. О них подробно ниже.
Чип ESP8266
Я уже пел дифирамбы чипу ESP8266 и платам на его основе. Мол, дескать, чип очень шустрый, да и неимоверно мощный. А он действительно очень шустрый. Без какой-либо оптимизации, мой код работает раза в три быстрее, чем на референсной Arduino Uno R3. Мол ESP8266 и платы на его основе очень дешевые. И против этого не поспоришь, дешевле плат с аналогичными характеристиками просто нет. Дескать ESP8266 вообще классный и нужно работать только на нем. Все это, разумеется, правда, но в каждой бочке меда, есть и свой половник протухшего кода. Начнем понемногу разбираться с чипом ESP8266.
Самая неприятная проблема, которая может возникнуть при работе с ESP8266 — возникновение нештатных ситуаций и срабатывание сторожевых псов (WatchDog). В ESP8266 их два. Один программный, настроенный по умолчанию на срабатывание по порогу 3.2 секунды, второй аппаратный и срабатывает уже за 6.5 секунд. Срабатывают оба пса если какая-то процедура или функция слишком надолго и плотно заняла процессор чипа. Хочу сразу же заметить, что при настройках по умолчанию, программный сторожевой пес может сработать при 1.6 секундах и должен сработать при 3.2 секундах.
Программный сторожевой пес срабатывает в том числе и на исключения. При его срабатывании происходит перезагрузка устройства. Обычно, в этом случае на последовательный порт выдается еще и некая отладочная информация, позволяющая понять, где и в каком месте кода произошла ошибка. Разобраться в коде обычными средствами очень непросто, ведь отладочная информация представляется в виде некой последовательности цифр. Поскольку с такими ошибками во время отладки программ среднестатистический программист встречается чуть ли не на каждом сотом шаге, то сообществом разработчиков была разработана утилита для декодировки сообщений при использовании Arduino IDE. При возникновении исключения или другой причины срабатывания программного пса в верхнее окно копируется Stack trace. Соответственно утилита декодировки пробует привязать точки прохождения кода и вывести разработчика на проблемный участок в исходном коде. А дальше уже чистая эвристика по выяснению причин неполадки.
Программным сторожевым псом можно управлять. Можно задавать длительность его реагирования (ESP.wdtEnable(time), где time порог в миллисекундах), но не стоит делать ее выше порога у аппаратного пса. Кроме того, программного сторожевого пса можно подкармливать (ESP.wdtFeed()), если вы уж умудрились написать код, который молотит, не переставая сразу с десяток секунд. Ну и для самых запущенных случаев программного сторожевого пса можно вообще отключить, навсегда или временно (ESP.wdtDisable()). Обратное включение осуществляется через вызов метода длительности реагирования.
А вот с аппаратным сторожевым псом не все так просто. Его не отключить. И срабатывает он жестко. В большинстве случаев срабатывание аппаратного сторожевого пса приводит к перезагрузке платы, если она не подключена к последовательному порту, но могут случаться ситуации, когда, выплюнув короткое сообщение о срабатывании аппаратного сторожевого пса, плата остается в зависшем состоянии. Не очень приятно, но лечится кнопкой резет или передергиванием питания.
Но даже будучи экипированным таким мощным арсеналом из внимательных псинок разработчик не застрахован от возникновения других, не менее неприятных ситуаций, связанных с высокоскоростным чипом. Помимо обычных ошибок в коде, могут возникать ошибки на всех уровнях между кодом разрабатываемом программистом и непосредственно аппаратным обеспечением. И тут тоже не все так просто, как могло бы показаться.
Если изобразить очень упрощенно, то для того чтобы написать свою программу под ESP8266, можно воспользоваться несколькими способами. Если вы действительно чувствуете в себе силы, то запрограммировать процессор и контроллеры можно используя язык Assembler и скомпилировать прямой код для целевого процессора. Аналогичным функционалом можно воспользоваться и в некоторых компиляторах C/C++.
Если же сил немного меньше, то можно воспользоваться SDK (Software Development Kit) распространяемого официально Espressif. Разрабатывать, вестимо, тут тоже придется на С/С++, но трудозатрат будет куда меньше. Тем более что SDK периодически обновляется, добавляются новые функции, устраняются ошибки.
Но разработка с использованием только официального, низкоуровневого, SDK требует существенных ресурсов. Меньше чем при написании на ассемблере, но все же еще много. И вот тут были созданы SDK высокого уровня, позволяющие существенно сократить время написания программного кода. Для ESP8266 их уже разработано чуть ли не десяток. Приведу лишь самые популярные:
Arduino ESP8266 SDK — разрабатывается сообществом энтузиастов и позволяет использовать язык Wiring (язык С/С++ и платформа для экосистемы Arduino), Arduino IDE и множество библиотек, разработанных для Arduino. Пожалуй, именно эта SDK является основой повышенной популярности ESP8266. Ведь благодаря Arduino SDK, появилась возможность воспользоваться всей мощью ESP8266 не прикладывая особо много усилий по написанию программного кода.
Чуть меньшей популярностью пользуется NodeMCU, являющейся, по сути, очередным высокоуровневым SDK, но уже для языка Lua. Еще меньшей популярностью пользуется UDK (Unofficial Development Kit). UDK, в отличие, например, от Arduino ESP8266 SDK разрабатывается вообще одним человеком и позволяет использовать обычные C или C++ среды для разработки прошивок под ESP8266.
Но проблема в каждом из приведенных вариантах в том, что в программном коде и аппаратной реализации могут быть ошибки (и в действительности, они там есть). А чем больше слоев между вашей программой и непосредственно железом, тем больше ошибок будет содержаться в конечной прошивке. И дело тут далеко не в ошибках в вашем коде.
Разрабатывая прошивку для своего устройства, я столкнулся с труднообъяснимыми зависаниями и перезагрузкой по аппаратному таймеру. Я по очереди грешил на все подключенные библиотеки и отключал отдельные участки кода, дабы попытаться разобраться что же все же происходит. Но все было тщетно. Устройство глючило с периодичностью от 10 минут и до часа с лишним. И единственный результат, который я получал — было краткое сообщение о срабатывании аппаратного сторожевого пса и код 4, означающий что проблема кроется где-то в районе прерываний. Мне потребовалось несколько недель и полный рефакторинг моего кода, дабы найти причину возникновения столь не комплиментарного поведения.
А все дело оказалось в банальной ошибке где-то в официальном SDK или в Arduino SDK для ESP8266 связанной с PWM (ШИМ). Многие пользователи уже столкнулись с тем, что попытки использовать ШИМ-модуляцию для управления внешними устройствами при включенной коммуникацией Wi-Fi приводит к зависанию чипа или же срабатыванию сторожевого пса. Данную проблему признали и даже запланировали ее решить в одном из следующих релизов. Но, постойте. Ведь у меня нет никакого управления ШИМ никаких внешних устройств. Или же есть? Как оказалось, решив добавить небольшого количества красивостей, я управлял встроенным светодиодом при помощи ШИМ-модуляции, плавно зажигая его и снижая яркость с частотой, зависящей от уровня сигнала Wi-Fi. Оказалось, что описанная ошибка имеет куда больший эффект, нежели разработчики SDK полагали ранее.
ThingSpeak
Но рефакторинг не прошел даром. Пытаясь найти проблему, я изменял и переписывал множество участков кода. Особые подозрения у меня вызывала библиотека для коммуникации с ThingSpeak. Слишком уж долго проходила коммуникация с сервером при отправке показаний. В конце концов, я написал свой код, выполняющий ту же функцию. Если отправка сведений у оригинальной библиотеки занимает в среднем 1.5 секунды, то мой код справляется за 0.3 секунды. К тому же он проще и понятнее.
Единственное сомнение с моей стороны было в том, что на сайте ThingSpeak в примерах используется отправка показаний по HTTPS, а работа с HTTPS с такими мелкими устройствами, как Arduino, несколько затруднена. Да, есть библиотеки, позволяющие установить надежное защищенное соединение с сервером в интернет, даже поддержка TLS присутствует, но тут есть один подводный камень. Все они работают с прямым указанием fingerprint сертификата сервера. Способа получить оные fingerprints в автоматическом режиме я не нашел. А прописывать «отпечатки» в коде — прямой путь получить устройство неспособное отправить сведения той стороне из-за сменившегося сертификата через пару лет.
Хорошо, что ThingSpeak спокойно принимает показания и по обычному HTTP, а о безопасности передаваемых на сервер показаниях я решил не особо беспокоиться. В конце концов, утянуть их можно только взломав мой собственный Wi-Fi, а такая задача далеко не тривиальная. Но каково было мое удивление, когда я обнаружил, что передача сведений на сервер в официальной библиотеке сделана точно так же, без какого-либо применения HTTPS.
Умирание чипа
Но даже кривости в SDK не так страшны и опасны, как банальное умирание железа. Если углубиться в дебри интернет, то можно найти блоги, где авторы даже разрабатывают целые инструкции, что делать с EPS8266, если вдруг вы ловите нежданные перезагрузки. И ведь ловим. Даже после рефакторинга и устранения проблемы с PWM, одно из моих устройств перезагружается с возникновением исключения. Сначала его обрабатывает программный сторожевой пес, а затем аппаратный перезагружает все устройство.
0x401077ac: interrupt_handler at C:\Program Files (x86)\Arduino\hardware\esp8266com\esp8266\cores\esp8266/core_esp8266_wiring_digital.c line 124 0x40100a62: ppEnqueueRxq at ?? line ? 0x40100ece: pp_post at ?? line ? 0x40107774: interrupt_handler at C:\Program Files (x86)\Arduino\hardware\esp8266com\esp8266\cores\esp8266/core_esp8266_wiring_digital.c line 118 0x402028c6: dht_wrapperA() at C:\Users\vkrav\Documents\OneDrive\Documents\Arduino\Garage_WeMos-v12/Garage_WeMos-v12.ino line 97 0x40107810: interrupt_handler at C:\Program Files (x86)\Arduino\hardware\esp8266com\esp8266\cores\esp8266/core_esp8266_wiring_digital.c line 140 0x401077fa: interrupt_handler at C:\Program Files (x86)\Arduino\hardware\esp8266com\esp8266\cores\esp8266/core_esp8266_wiring_digital.c line 136 0x40104cad: ets_timer_disarm at ?? line ? 0x40104cad: ets_timer_disarm at ?? line ? 0x40107774: interrupt_handler at C:\Program Files (x86)\Arduino\hardware\esp8266com\esp8266\cores\esp8266/core_esp8266_wiring_digital.c line 118 0x40201a20: delay_end at C:\Program Files (x86)\Arduino\hardware\esp8266com\esp8266\cores\esp8266/core_esp8266_wiring.c line 38 0x40105212: spi_flash_read at ?? line ? 0x40107b08: pvPortZalloc at C:\Program Files (x86)\Arduino\hardware\esp8266com\esp8266\cores\esp8266/heap.c line 54 0x4021a745: pm_set_sleep_time at ?? line ? 0x4021ac1e: pm_get_sleep_type at ?? line ? 0x4021ace3: pm_get_sleep_type at ?? line ? 0x40201a28: delay_end at C:\Program Files (x86)\Arduino\hardware\esp8266com\esp8266\cores\esp8266/core_esp8266_wiring.c line 40 0x40234a5d: ets_timer_handler_isr at ?? line ? 0x40234aa2: ets_timer_handler_isr at ?? line ? 0x4020e19f: loop_task at C:\Program Files (x86)\Arduino\hardware\esp8266com\esp8266\cores\esp8266/core_esp8266_main.cpp line 56
Несмотря на всю «красоту» ESP8266, все портит качество комплектующих. Многие авторы жалуются на флеш-микросхемы низкого качества. Дескать они очень быстро выходят из строя. Я не скажу конкретно за микросхемы флеш-памяти, но что-то явно выходит из строя, поскольку одна из моих плат подвергается именно таким спонтанным перезагрузкам с очень интересным результатом в виде «spi_flash_read at ?? line ?». Особо смышленые авторы перепаивают микросхемы флеш-памяти, но мы такой ерундой заниматься не будем. Во-первых, микросхемы на чипах WeMos закрыты металлическими кожухами, а во-вторых, флеш-микросхемы еще тоже откуда-то нужно взять и не повредив припаять. А припайка микроскопической деталюшки с множеством тончайших ножек — занятие не для слабонервных новичков.
Ничего с ним не поделаешь, только менять микросхему или всю плату, благо стоят они неастрономические суммы и доступны к приобретению пачками. Исходя из описанного выше, имеет смысл проводить разработку на одной плате, а длительные тестирования уже на другой. Ну а в работу пускать вообще на третьей.
Датчики
Если с датчиком BMP180, производства Bosh, никаких проблем не возникло, то с DHT серией пришлось повозиться. Но уделю все же пару абзацев и датчику давления.
BMP180 не просто цифровой, полностью откалиброванный на заводе, датчик давления, использующий для передачи сведений протокол I2C, но и встроенный высокоточный термометр. Для подключения к плате я использовал, да ничего не использовал. Просто соединил соответствующие контакты на плате и на плате датчика. Благо и там, и там 3.3 вольта и никакого согласования производить не требовалось. Организовать снятие результатов с датчика при помощи стандартной библиотеки для сенсоров BMP180/085 от AdaFruit не составило никакого труда. В работе, впрочем, датчик абсолютно ненавязчив, значения считываются моментально, никаких ошибок и вопросов не возникает. Сплошное удовольствие.
Сенсор способен измерять атмосферное давление в пределах от -500 метров и до +9000 метров под и над уровнем моря. По заявлению производителя, точность датчика составляет всего 25 см. Соответственно им можно измерять высоту с весьма достойной точностью. Помимо непосредственного измерения давления, прибор может измерять еще и температуру, ведь измерение давления зависит в том числе и от температуры. Поэтому в устройство встроен весьма точный термометр, на показания которого корректируются измерения давления. Да, температуру при помощи BMP180 также можно получать. И знаете что? Она точнее даже чем у датчиков DHT22! Проверил лично при помощи откалиброванного пирометра.
В целом я в восторге от BMP180, да и по цене сенсор вполне доступен. Если же у вас есть желание ознакомиться с подробными техническими характеристиками, то рекомендую сделать это самостоятельно, посмотрев официальный даташит от производителя, например, тут. От себя замечу, что приводить показание давления к давлению на уровне моря я не стал, поскольку показания наших метеостанций, по всей видимости, так же к нему не приводятся. А вот при установке датчика на каком-то этаже выше первого потребует вносить корректировку в получаемые показания.
Но вернемся к нашим многострадальным DHT. Как мне удалось выяснить в предыдущей части, датчики серии DHT11 никуда не годны, кроме как для обучения детишек сборке схем. Температурные показания могут существенно отличаться даже у двух рядом лежащих датчиков. А про измерение влажности и говорить нечего. DHT11 упорно занижают влажность, процентов так на 30.
Но, как мне удалось выяснить экспериментальным путем, DHT22 не сильно лучше своих предшественников. Во-первых, температура хоть и меняется синхронно на двух рядом лежащих датчиках, она все же менее точна даже по сравнению с температурой, подаваемой датчиком давления. А во-вторых… Во-вторых, способ получения показаний с сенсоров, мягко говоря, подходит далеко не для всех реализаций.
В реализации устройства на плате Arduino Uno R3 стандартная библиотека DHT от AdaFruit выдавала вполне стабильные результаты, да и вообще работала и не вызывала никаких проблем. Вообще, реализация на Uno оказалась практически лишенной серьезных заморочек ввиду своей простоты. А вот на куда более производительном чипе ESP8266 несовершенство DHT вообще и DHT22 в частности вылезло в полной мере.
Первое, с чем я столкнулся — невозможность нормального использования библиотеки от AdaFruit, даже несмотря на то, что она рекомендована и протестирована сообществом, развивающим SDK ESP8266 для Arduino. Проблема заключается в том, что информацию о температуре и влажности сенсор передает импульсами. Для чтения импульсов в стандартной библиотеке запрещаются все прерывания. Время опроса одного сенсора, по моим измерениям, на чипе ESP8266 занимает от 230 и до 270 миллисекунд. Это если не было никаких ошибок. А ошибки возникают постоянно, поскольку ESP8266 чип с встроенным контроллером Wi-Fi. И в нем невозможно запретить все прерывания иначе работа Wi-Fi будет нарушена. И именно тут возникает конфликт. Либо нижележащие слои программного кода мешают получению данных с DHT, либо библиотека от AdaFruit входит в ступор. На прикладном уровне мы получаем сразу три эффекта:
А. Ошибки в чтении данных с датчика.
Б. Увеличенное время опроса датчика, в некоторых случаях до секунд. Сразу же возникает риск пропуска импульсов счетчика.
В. Срабатывание WatchDog чипа с приостановкой работы или перезагрузкой.
Самым лучшим способом был бы переход с датчиков DHT на что-то аналоговое, где требуется лишь считать сопротивление. Либо на что-то продвинутое, оповещающее о статусе через I2C или аналогичный интерфейс. Но, что делать, если датчиков других нет, а проект очень хочется завершить?
В таком случае я рекомендую воспользоваться другой библиотекой для сенсоров DHT. На выручку мне пришла библиотека от PietteTech. Видимо, столкнувшись с аналогичной проблемой что и я, автор решил создать свою библиотеку, построенную на немного другом принципе. В ней нет никаких блокировок прерываний, более того, сам опрос датчиков построен на прерываниях. В конечном итоге проблемы, описанные выше, ушли полностью. Более того, время опроса датчика суммарно занимает от 3 и до 4 миллисекунд. Разница почти в два порядка, что достойно уважения. Но, справедливости ради, отмечу, что иногда все же возникают ошибки чтения датчика, но они не приводят к зависанию всего и срабатыванию сторожевых псов, да и возникают они с частотой раз в день при опросе датчиков раз в 3 минуты. На мой взгляд, работа альтернативной библиотеки — превосходная.
Впрочем, DHT22 далеко не панацея в проекте. Несмотря на большую точность с датчиками то и дело возникают проблемы. Вспылили проблемы во время натурного тестирования, где плата гоняется в непрерывном режиме в «боевых» условиях. Ни с того, ни с сего, показания температуры и влажности с одного из DHT22 становятся равными -5. Соответственно -5 градусов Цельсия и процентов относительной влажности. То ли это влияние макетной платы, мол там скапливается влажность или окисляются контакты, то ли сами датчики начинают подглючивать. А может быть и порт на ESP8266 «подвисает» и начинает выдавать странные результаты. При этом цифровой датчик BMP180 работает вполне адекватно. Лечится проблема перезагрузкой контроллера. Либо заменой DHT на что-то типа SHT с полностью цифровым интерфейсом. Исходя из того, что так начинает глючить сначала один датчик, а затем другой, я прихожу к выводу, что это какая-то системная проблема и скорее всего мне придется мигрировать именно на датчики SHT.
Дребезг контактов
Проблема появилась оттуда, откуда ее и не ждали. Если в лабораторных условиях все работало идеально, импульсы от нажатия на кнопку вылавливались надежно, то в реальности, при подключении к IN-Z61 импульсов стало ловиться заметно больше, чем их было на самом деле.
Реализованная схема с применением магнитного или иного другого переключателя внутри счетчика импульсов оказалась на редкость шумящей контактами. Реализовывать аппаратную схему подавления дребезга контактов я не желал, поэтому пришлось опытным путем подкручивать параметры для программного DeBauncer-а. Похоже, что подбирать параметры придется для каждого датчика импульсов сугубо индивидуально, эмпирическим путем.
Работающая реализация, функции
В результате всех длительных упражнений рабочая версия счетчика импульсов скрещенного с измерительной станцией внешних условий под WeMos D1 R2 была реализована. Перечислю функции, которые она исполняет:
- Регистрация импульсов, получаемых со счетчика импульсов газового счетчика.
- Регистрация температуры и относительной влажности с двух цифровых сенсоров.
- Регистрация атмосферного давления и температуры с одного цифрового сенсора.
- Передача накапливаемых сведений, как со счетчика импульсов, так и с сенсоров на сервера ThingSpeak в сети Интернет. Во время передачи сведений возможна регистрация одного импульса со счетчика импульсов.
- Вывод отладочной информации в последовательный порт.
- Определение текущего времени при помощи NTP.
- Вывод текущей информации о количестве импульсов, показаниях сенсоров, количестве отправок на сервера ThingSpeak, количестве ошибок об отправках, последних десяти ошибках, возникших при работе устройства, причинах последней перезагрузки устройства.
- Обновление прошивки устройства «по воздуху».
В целом все функции, так или иначе, повторяют функции устройства, построенного на Arduino Uno, хотя и были улучшены. Так стал куда более информативным веб-сайт устройства, теперь отображается куда больше полезной информации. Появилась возможность понимать, чем занимается устройство и хоть как-то проверить результаты его работы. Ведь несмотря на то что каждый раз, когда устройство стартует оно увеличивает количество запусков в поле на ThingSpeak, но понять причину, хотя бы удаленно, можно только через веб-интерфейс.
Хорошим подспорьем по контролю устройства, стало получение реального времени с сервера NTP. Теперь, после многодневного, самостоятельного полета устройства, я знаю, что две недели тому назад, была ошибка с одним из сенсоров, а потом все нормализовалось. Не менее интересной и удобной я считаю функцию обновления устройства по воздуху. Если оно установлено где-то в подсобном помещении, да еще и внутри кожуха, прикрученного к стене, то удобнее всего его обновить будет именно без подключения кабелем, а по сети Wi-Fi сидя в удобном кресле в рабочем кабинете.
Некоторые глазастые читатели заметят, что мол, зачем тебе, дорогой писатель, аж три датчика температуры и два влажности. А я, предвосхищая такой вопрос, уже запасся ответом. Один DHT22 пойдет на улицу и будет измерять там температуру забортного воздуха вкупе с влажностью. Второй DHT22 разместится внутри помещения и будет измерять температуру воздуха уже в нем, плюс займется мониторингом влажности. Датчик с давлением и встроенным высокоточным термометром уютно разместится внутри корпуса устройства и будет измерять температуру в этой частично изолированной среде. Вот такой мониторинг.
Поскольку чип ESP8266 обладает внушительным объемом памяти, то я себя не ограничивал в написании кода и постепенно он разросся до внушительного размера. За время работы над проектом, я успел попробовать сразу несколько IDE: Platformio IDE для Atom, Visual Studio с плагином для Arduino и Eclipse с плагином для Arduino. Но, в конце концов, остался на Arduino IDE, правда, настроил черную схему через настройку файлов конфигурации, да разбил основной файл на несколько. Так жить стало намного проще. А для сложных случаев, когда требуется провести большую переработку или же требуется одновременная работа с несколькими окнами, то я просто использую Atom.
Вообще, применение сторонних IDE себя не оправдала. Никакого значительного преимущества перед Arduino IDE они не дают. Исключением я могу назвать только Visual Studio где присутствует возможность отладки. А так, только лишний мусор на жестком диске. Все что требуется есть и в Arduino IDE. Автодополнения, конечно, ускоряют работу разработчика, но далеко не в такого размера проектах. После разбивки единого файла скетча на несколько стало наконец-то заметно легче искать отдельные функции в программном коде. В идеале, по крайней мере, для меня, хотелось бы получить среду наподобие Visual Age for Java от IBM, где есть не только древо классов с методами, но и возможность изоляции при изменениях вплоть до отдельного метода, но, похоже, что это скорее из области фантастики, нежели реальности.
Потребление энергии
И как всегда, меня заботит, в том числе, и потребление энергии вновь созданным устройством. Ведь оно будет работать долгие годы, вести мониторинг потребления газа, да измерять микро и макроклимат.
Espressif заявляет категорически низкое электропотребление для своего чипа, не во всех, но в некоторых режимах. Датчики DHT и BMP потребляют мизер. Да, еще адаптер питания на 5V, обычный USB блок от какого-то давно почившего телефона. Вообще, запитывать мелкие платки от USB — идея здравая. Пятивольтовых USB зарядок у народа просто немеряно. Использовать их некуда, а выкинуть жалко. В подобных проектах они и пригождаются.
Начну с того, что измерил потребление платы WeMos со всей установленной начинкой и зарядкой. В рабочем, естественно, состоянии. Прибор показал потребление 0 Вт. Конечно, показание потребления в 0 Вт вовсе не означает, что само устройство питается исключительно Манной небесной. Нет, это означает, что потребление настолько незначительное, что оно меньше нижней границы шкалы измерений. В таком случае на выручку пришел измерить потребления непосредственно для порта USB. Который и показал, что в пике, WeMos потребляется чуть меньше половины ватта. С максимумом потребления в момент включения всех четырех светодиодов. Что и не мудрено, ведь каждый из них нагружен еще и сопротивлением. Кстати о сопротивлениях. Я намеренно использую 220 омные резисторы даже на 3 мм светодиодах и на всех цветах. Слишком уж ярко они светят, в темное время в помещении царит натуральная светомузыка из перемигивающихся цветных огоньков.
Потребление устройства получилось воистину скромное и в качестве питающего блока можно использовать даже самые маломощные версии на 500 мА. Их хватит с запасом. Кстати, наверняка электропроводка всего моего загородного строения, тратит больше на т.н. потери, чем потребляет созданный датчик с передачей сведений по Wi-Fi. Впрочем, хочу тут заметить, что точка доступа, к которой подключается WeMos располагается в пределах прямой видимости, на расстоянии вытянутой руки. Что существенно сокращает расход энергии на устройстве и поднимает его в целом во всей системе из-за необходимости питания самой точки доступа.
Программный код
Ну и предвещая третью часть повествования, спешу разместить тот программный код, который используется в устройстве на момент написания статьи. Не исключено, что с течением времени он будет обновляться и улучшаться. Прошу обратить внимание на то, что сам код разбит на отдельные части и они все должны компилироваться скопом, иначе компилятор будет выдавать ошибку. Исходный код в архиве.
Update1: Как подбирать значение отсечки для устранения дребезга контактов? Процедура весьма проста, но требует времени. Я подбирал его статистическим способом. Брал некое значение, например 50 мс, проводил замеры на протяжении недели, сколько посчитается импульсов устройством и сколько по счетчику. Если импульсов поймано больше или меньше, то рассчитывал разницу в процентах и проводил корректировку отсечки на соответствующий процент. А затем новое испытание. Проще было бы посмотреть сам импульс при помощи хорошего осциллографа, но в отсутствие такового пришлось действовать статистическим методом подбора.
Напомню, что в этой версии импульсы ловятся в двух местах. Первый: при помощи библиотеку Bounce2, ее обработчик вызывается при каждом удобном случае. Второй: при помощи прерывания в тот момент, когда происходит отправка значений на сервер ThingSpeak. Поскольку отправка, в случае неудачи, может занимать длительное время, за которое может проскочить импульс, то в случае возникновения импульса во время отправки, он посчитается без привлечения методов подавления дребезга контактов. Тут возникает потенциальная возможность по накрутке дополнительного импульса, но ей можно пренебречь из-за слишком малой окончательной погрешности. В любом случае, данную возможность можно отключить.
Update2: На ровном месте возникла проблема с неверным подсчетом импульсов. И дело тут даже не в пресловутом дребезге контактов. В отличие от версии для Arduino, в версии для ESP8266 я реализовал подсчет импульсов в полном соответствии с показаниями счетчика, т.е. с дробной частью. Счетчик подсчитывает потребление газа с точностью до 1 тысячной кубометра, а вот генератор импульсов реагирует только на каждую сотую потребленного газа. Соответственно каждый импульс у меня выглядит как 0.01. А переменная с показанием счетчика напоминает что-то подобное 34560.98. Обе переменные типа float. И вот тут я столкнулся с очень интересным эффектом.
По непонятной мен причине в фреймворке Arduino и на ESP8266 простая арифметика с переменными типа float работает не так, как ожидает от нее пользователь, привыкший к обычным дробным числам. Так 34560.98 + 0.01 может быть вовсе не 34560.99, а 34561.00. Понятно, что дело тут в том, в каком виде float числа хранятся в памяти и почему возникает подобная ерунда. Дело в том, что 0.01 на самом деле может быть чем-то в виде 0.0143894791203 или в любом другом дробном виде, да и математические (не только они) операции со значениями типа float весьма не однозначны. Неплохое объяснение эффекта можно найти в статье на Хабре. А способом лечения возникшей проблемы я выбрал использование значений типа unsigned long, хотя и просто long хватит, для хранения и манипуляций со значением счетчика.
Данные изменения не отражены в коде, поэтому с ними придется поработать самостоятельно. При получении значения показания счетчика с сервера ThingSpeak стоит привести его из дробного в целочисленное. Производится сия операция посредством умножения значения на требуемую разрядность, в моем случае на 100. Либо, тот же самый результат можно получить, разделив значение на значение прироста импульса, в моем случае на 0.01. Не забываем привести результат к типу long. Каждый пойманный импульс увеличивает переменную для хранения данных о счетчике на единицу. При отправке сведений на сервер ThingSpeak или при выводе на экран делим значение переменной на ту же сотню или же умножаем на 0.01. Не забываем результат поместить в переменную с типом float.
Ознакомиться со всем циклом статей можно по следующим ссылкам:
Измеряем температуру, влажность и отслеживаем показания газового счетчика с использованием ThingSpeak. Часть 1. Используем Arduino Uno R3.
Измеряем температуру, влажность и отслеживаем показания газового счетчика с использованием ThingSpeak. Часть 2. Используем ESP8266.
Измеряем температуру, влажность и отслеживаем показания газового счетчика с использованием ThingSpeak. Часть 3. Собираем все вместе.
Измеряем температуру, влажность и отслеживаем показания газового счетчика с использованием ThingSpeak. Часть 4. Обрабатываем значения.
Измеряем температуру, влажность и отслеживаем показания газового счетчика с использованием ThingSpeak. Часть 5. Избавляемся от сенсоров DHT.