Температура, влажность и давление



Выбранные нами Arduino‑модули для измерения температуры, влажности и атмосферного давления также применяют связь по двухпроводному интерфейсу I2С. При этом библиотека для Barometer Sensor на основе чипа ВМР085[46] ориентирована на тот же самый аппаратный интерфейс I2С, реализованный через стандартную библиотеку Wire.h, что и часы DS‑13G7. Потому на схеме рис. 22.1 Barometer Sensor и подключен к тем же самым выводам А4 и А5. Микросхема ВМР085 производства Bosh устроена так, что перед чтением показаний давления следует обязательно прочесть температуру (см. пример по ссылке в сноске 3). Именно эту температуру мы в дальнейшем будем демонстрировать в качестве «внутренней» на дисплее главного модуля нашей станции – хотя нет никаких проблем в том, чтобы выводить и значение, получаемое из модуля SHT1.

Что же касается атмосферного давления, то модуль ВМР085 выдает его, как водится, в паскалях в виде действительного числа (т. е. типа float ). В программе придется ввести коэффициент пересчета для его представления в привычных миллиметрах ртутного столба, притом в виде целого числа (указывать десятичные доли атмосферного давления не имеет смысла). Вот тут и скажутся все преимущества высокоуровневого языка Arduino – этот коэффициент имеет величину 0,0075 (750 мм рт. ст. – это 1000 гПа с высокой точностью). Для умножения на такую величину в ассемблерной программе придется сначала преобразовывать ее в целое число, применять довольно громоздкие процедуры перемножения многобайтовых чисел, потом приводить результат к нужному виду (см. главу 20 ), а у нас это сведется к одной строке в программе:

mmHg = int(pressure*0.0075)+5;

Здесь мы применяем явное преобразование типов – результат умножения переменной pressure типа float на дробный коэффициент мы сразу приводим к целому виду типа int . За такую роскошь мы, конечно, расплачиваемся дополнительными килобайтами кода, но в данном случае оно того стоит.

* * *

 

Подробности

А зачем здесь к полученному значению добавляется еще и число 5? Это поправочный коэффициент, который вводится индивидуально из следующих соображений. В главе 20 мы упоминали, что для небольших высот над уровнем моря при изменении высоты на каждые 10–12 м давление меняется примерно на 1 мм рт. ст. В пределах такого города, как Москва, показания могут меняться в зависимости от местоположения примерно на 10 миллиметров. Мы же хотим, чтобы станция показывала величины, близкие к тем, что передаются Гидрометцентром, – иначе, проглядев прогноз погоды, ее показания придется все время пересчитывать в уме. Так что коэффициент 5 – это экспериментально вычисленная поправка в моем случае. Будьте готовы, что вам ее придется пересчитать, сравнивая показания с теми, что публикуются для вашего населенного пункта каждые три часа в интернет‑службах погоды. Если же вы хотите, чтобы станция показывала реальное давление без всяких поправок, то просто вычеркнуть этот коэффициент из программы будет недостаточно – придется датчик дополнительно калибровать. А это дело непростое – не каждый физический институт имеет средства для поверки датчиков атмосферного давления, потому и проще подогнать его показания под Гидрометцентр.

 

* * *

В библиотеке для барометра – файле Barometer.cpp (папка Barometer_sensor ) – необходимо закомментировать забытые разработчиками тестовые строки 28 и 40: Serial.print ("Teinperaturet: ") и Serial.print ("Temperaturet2: ") . В противном случае у вас собьется прием данных от Xbee‑модуля и все время на индикаторных панелях будет возникать лишний мусор.

В отличие от барометрического, библиотека для модуля измерения температуры и влажности SHT1x[47] применяет не аппаратный интерфейс 12С, а его программную реализацию (подробнее о том, как это делается, рассказано в моей книге [21]). Модуль подключается к любым цифровым выводам – на схеме рис. 22.1 в этом качестве выступают выводы А2 и A3 (что соответствует цифровым выводам 16 и 17 ). В программе в секции определений их надо указать:

 

#include <SHT1x.h>

#define dataPin 16

#define clockPin 17

SHT1x sht1x(dataPin, clockPin);

 

Особенность подключения SHT1x, как мы видим на схеме, – наличие двух разъемов, где выводы питания дублируются (рассмотрев плату, я не обнаружил между ними разницы), а сигнальные линии Data и SCK пространственно разделены. Это не доставляет никаких проблем при создании конструкции (все равно задействовано лишь два вывода Arduino), но если вы хотите уменьшить число проводов, то в «Амперке», кроме SHT1x, предлагается и другой подобный датчик – DHT11 (имеющий, впрочем, как утверждается, меньшую точность).

Тестовые программы для обоих модулей прилагаются к соответствующим библиотекам. В скетче для SHT1x следует только не забыть заменить номера выводов на указанные на схеме рис. 22.1.

 

 

Подключение радиомодулей ХЬее

Подключение Xbee‑модулей, возможно, самая сложная часть проекта. Трудность тут заключается в том, что для коммуникации с контроллером они используют тот же последовательный порт, что и USB‑соединение с компьютером (собственно, Xbee‑модуль представляет собой как бы продолжение UART в замену проводному кабелю). Поэтому Xbee‑модуль будет мешать не только коммуникации с компьютером, но и процессу программирования платы, отчего перед каждой модификацией программы его придется извлекать из схемы и вставлять заново. Опыт показал, что это делать необязательно, если ХЬее‑модуль не участвует в коммуникации (т. е. не осуществляет приема или передачи), но в общем случае на это полагаться не стоит – проще отключить его и подключить заново.

Xbee‑модули не требуют для своей работы каких‑либо библиотек – serial‑коммуникация через них осуществляется совершенно прозрачно для программиста, с применением стандартных функций последовательного порта. Это, как мы говорили, позволит нам через один и тот же порт осуществлять и прием данных от внешнего датчика, и установку часов из компьютера. Правда, тогда при подключении к компьютеру ХЬее‑модуль придется извлекать из устройства точно так же, как это делается при программировании контроллера. Но делать это придется очень редко – только для подстройки времени, если часы DS‑1307 сильно убегут, т. е. не чаще, чем где‑то раз в полгода), ну и, разумеется, при смене батарейки, которой, как обещают производители, должно хватить на несколько лет.

* * *

 

Подробности

Если мы не хотим озадачивать пользователя извлечением Xbee‑модуля, то пришлось бы использовать как минимум Arduino Mega, где UART‑портов несколько. На мой взгляд, как и в случае применения GPS‑модуля для полностью автоматической установки часов, это слишком большая цена за функцию, которая будет применяться лишь изредка.

Кстати, подкину еще одну идею: если приобрести третий ХЬее‑модуль, настроить его на совместную работу с остальными и подключать его к компьютеру через специальный Xbee‑адаптер, то через него можно не только устанавливать часы, как через обычный UART, но даже и программировать контроллер. Программу станции при этом можно использовать ту же, что приведена далее, только тогда перед обращением к часам извлекать ХЬее‑модуль не придется. Предлагаю вам заняться на досуге такой доработкой – базовый материал для нее есть в статье о настройке ХЬее на сайте «Амперки», которая упомянута в разд. «Подключение и настройка ХЬее‑модулей» этой главы.

Из этой ситуации можно вывернуться и еще одним способом – попросту организовать программный UART на свободных выводах Arduino Uno (правда, в случае ЖК‑дисплея для этого может не хватить контактов платы). О том, как это делается, см. http://arduino.ua/ru/prog/SoftwareSerial. Вариант этого способа – применить для общения датчика со станцией не ХЬее, а, например, беспроводной модуль на основе nRF24L01+[48]. Он предназначен в принципе для тех же целей, но управляется не через UART, а через SPI, и его можно использовать параллельно с записью на SD‑карточку. Как видите, платформа Arduino дает большое разнообразие способов решения для любых пришедших в голову идей.

 

Подключение и настройка ХЬее ‑модулей

Здесь придется повозиться: настройка пары ХЬее‑модулей для совместной работы – не самое простое занятие. Мы применим для их прошивки не отдельную плату XBee‑USB адаптера (который один раз используется, а затем оказывается ненужным), а универсальную Wireless Shield, которую потом приспособим и в схеме станции, причем в варианте с разъемом для SD‑карты (Wireless Shield SD[49]). Ее подробное описание можно найти на украинском сайте Arduino[50]. Там же имеются рекомендации по подключению Xbee‑модулей фирмы Digi. Обычно контроллер из платы Arduino перед прошивкой Xbee‑модулей через Wireless Shield рекомендуют извлекать, но мы поступим иначе – в упомянутом разделе украинского сайта приведена программа‑заглушка, которую перед настройкой следует закачать в Arduino, чтобы контроллер не мешал прошивке модулей. Программа очень проста и состоит из двух строк:

 

void setup() { }

void loop () { }

 

Отметим, что в обратной ситуации (т. е. при прошивке Arduino в присутствии ХЬее‑модуля) столь простого решения не существует – при необходимости изменить программу Xbee‑модуль придется извлекать каждый раз.

Скомпилируйте эту программу в новом файле и загрузите в Arduino. Затем подсоедините Wireless Shield к плате Arduino Uno, установите в него Xbee‑модуль (не забудьте про соответствие номеров контактов на модуле и «шилде»!) и переключите на плате Wireless Shield микропереключатель в положение «USB». Не забывайте, что для нормальной работы Xbee‑модуля с контроллером переключатель надо возвращать в положение «Micro».

При подключении USB‑кабеля к Arduino Uno теперь должен загореться красный светодиод PWR в углу платы Wireless Shield. При работе с модулем следует обращать внимание на этот светодиод – его ровное и яркое свечение сигнализирует о том, что модуль вставлен правильно. В этом неудобство применения таких модулей – они‑то прошиваются один раз, а рабочую программу приходится долго отлаживать. Потому стоит постараться отладить все возможное до установки ХЬее‑модуля, и напоследок оставить только беспроводные функции.

Теперь отвлечемся от украинского сайта – на нем рекомендуют настраивать мо‑ дуль руками с помощью посылки команд. Мы пойдем более простым путем и обратимся к статье на сайте Amperka.ru «Настройка пары модулей ХВее Series 2 для коммуникации друг с другом»[51]. Учтите, что все сказанное далее относится к модулям Series 2 (на плате помечены буковками S2), а встречающиеся в некоторых магазинах более дешевые модули Series 1 (они не помечены никак) настраиваются несколько иначе и несовместимы с Series 2.

Пропускаем там все, касающееся подключения модуля к XBee‑USB адаптеру, и далее узнаем, что надо скачать специальную программу X–CTU с сайта производителя. Отправившись по ссылке, даже подготовленный человек растеряется, – только для Windows там представлены три варианта указанной программы. Скачиваем наугад самую верхнюю (на момент написания этих строк это XCTU ver. 5.2.8.6) и устанавливаем. Ура! Мы попали как раз на то, что надо.

Запускаем X–CTU, первым делом выбираем СОМ‑порт, соответствующий Arduino, и для проверки жмем кнопку Test/Query (напоминаю, что в Arduino перед этим уже должна быть загружена программа‑заглушка или контроллер извлечен из платы). Далее переходим на вкладку Modem Configuration и скачиваем свежие версии прошивок через кнопку Download new versions (что будет выполняться довольно долго – программа скачивает обновления для всех устройств, которые в ней предусмотрены).

И, наконец, выполняем собственно прошивку, как описывается в статье, для двух Xbee‑модулей: одного в режиме «координатора», другого – «роутера». Сначала выбираем тип модема, определенный программой через Test/Query (в нашем случае ХВ24‑В), затем в поле Function Set находим пункт ZNET 2.5 COORDINATOR AT (не ошибитесь! Там много пунктов с похожими названиями). Кроме этого, устанавливаем идентификатор сети в графе PAN ID (рис. 22.2).

 

 

Рис. 22.2. Установка параметров Xbee‑модуля в программе X–CTU  

 

Он должен быть одинаковый для обоих модулей, пусть у нас он будет равен 0FFF. Можно установить скорость обмена в пункте Serial interfacing/BD‑BaudRate , однако по умолчанию там и без того установлено значение 3 (9600). Потом на всякий случай поставьте отметку в пункте Always update firmware (при повторной прошивке этого можно не делать) и, наконец, нажмите кнопку Write .

Для второго модуля в поле Function Set находим ZNET 2.5 ROUTER/END DEVICE AT и делаем все то же самое, только еще в пункте Sleep Modes/SM‑Sleep Mode выбираем значение 1 – PIN HIBERNATE (это нам понадобится для установки режима энергосбережения в выносном датчике). Кроме этого, советуют в пункте Serial Interfacing/D7‑DIO7 Configuration установить значение 0 (CTS flow control disabled) . После этого устройство конфигурируется именно как END DEVICE , и нам станет доступен Sleep‑режим, который активируется установкой логической 1 на выводе 9 модуля.

Обязательно сохраните обе конфигурации (Profile | Save ). При повторном подключении модулей можно прочесть зашитую в них конфигурацию, нажав кнопку Read , и в случае необходимости что‑то подправить.

* * *

 

Подробности

Xbee‑модули фирмы Digi имеют весьма капризный характер. Если у вас в процессе настройки модуль перестал откликаться на запросы программы X–CTU, то не кидайтесь сразу выбрасывать довольно дорогой девайс, полагая его испорченным. Помогает следующая последовательность действий, проверенная мной на практике:

1. Извлеките из платы Wireless Shield (или из XBee‑USB адаптера, если вы используете его) «неисправный» Xbee‑модуль и подключите ее к компьютеру.

2. Запустите X–CTU, сразу перейдите на вкладку Modem Configuration , загрузите любую из сохраненных конфигураций (Profile | Load ) и попробуйте загрузить ее в устройство через кнопку Write . Естественно, вы получите сообщение о том, что никакого модема не обнаружено.

3. Закройте это окошко и вставьте Xbee‑модуль в плату. Затем снова нажмите кнопку Write . Скорее всего, модем «пропишется» как надо. После этого его можно будет прочесть кнопкой Read , как обычно, и внести необходимые исправления. Если с первого раза не получится, повторите эти операции.

 

* * *

После прошивки пометим модули на всякий случай, наклеив на них «лейблы» с буквами С (для «координатора») и R (для «роутера») и значением ID – вдруг мы захотим подключить еще один модуль? «Координатор» мы присоединим к основному модулю станции, а «роутер» – к выносному датчику (только END DEVICE можно вводить в режим энергосбережения).

Теперь мы отложим настроенные Xbee‑модули и займемся настройкой Arduino Mini, который у нас ляжет в основу выносного датчика станции.

 

 

Выносной датчик на основе Arduino Mini

Кстати, у Arduino Mini, несмотря на его миниатюрные размеры, портов даже больше, чем у Arduino Uno, – обратите на его схеме внимание на выводы AD6 и AD7 (см. http://arduino.ru/Hardware/ArduinoBoardMini). Правда, они могут использоваться только по прямому назначению – как аналоговые входы. По аналогии с выводами AD0‑AD5 (цифровые порты 14–19) может показаться, что им должны соответствовать цифровые порты с номерами 20 и 21, но это не так: AD6 и AD7 представляют собой отдельные входы АЦП контроллера ATmega328 (ADC6 и ADC7), которые, в отличие от остальных, никак не связаны с цифровыми выводами портов.

Отсутствие входов AD6 и AD7 в большинстве остальных модификаций Arduino объясняется просто: выводы ADC6 и ADC7 имеются лишь у ATmega328 в плоских корпусах TQFP и MLF, где число выводов увеличено до 32, а в PDIP‑корпусе с 28 выводами, на которых построено большинство обычных модификаций Arduino, они отсутствуют.

Для программирования Arduino Mini нам придется создать отдельную конструкцию, включающую внешний USB‑Serial адаптер, который придется приобрести отдельно. В датчике такой адаптер нам не нужен, и он все равно будет конфликтовать с Xbee‑модулем. Потому мы создадим отдельную схему для программирования платы, а отладку функций энергосбережения, чтения показаний датчика SHT1x и работы с Xbee‑модулем вынесем на отдельный макет.

Схема для программирования Arduino Mini показана на рис. 22.3.

 

 

Рис. 22.3. Схема для программирования Arduino Mini  

 

Обратите внимание, что линии RxD и TxD платы и адаптера соединены перекрестно. Конденсатор между выводами Reset адаптера и платы выбирается в пределах 0,1–0,5 мкФ – он служит для сброса контроллера перед программированием. Его можно не подключать, но тогда перед программированием на всякий случай нужно сбрасывать контроллер вручную, кнопкой на плате (нажимать не сразу, а когда появляется надпись Uploading , или, в русском варианте Загружаем ).

При подключении этой схемы через кабель mini‑USB к компьютеру, USB‑Serial адаптер должен самостоятельно прописаться в системе – в разделе Порты (СОМ и LPT) Диспетчера задач возникнет еще одно устройство под названием Arduino USB Serial Light Adapter (СОМxx). Запустите Arduino IDE, укажите ей через меню Сервис | Плата тип платы Arduino Mini w/ATmega328 ), а затем через меню Сервис | Порт – номер порта, который показывает Диспетчер задач для USB‑Serial адаптера. При подключении должны гореть два светодиода: на адаптере и на плате контроллера.

Убедимся, что все работает, загрузив в контроллер какую‑нибудь простенькую программку, вроде стандартного мигания светодиода на выводе 13 . В Arduino Mini такого светодиода нет, но на этом выводе имеется балластный резистор 1 кОм, потому светодиод к нему можно подключать непосредственно (отрицательным выводом к «земле»). Текст всемирно известной тестовой программы на всякий случай привожу:

 

Void setup()

{

pinMode(13, OUTPUT); // настраиваем 13 вывод на выход

}

Void loop()

{

digitalWrite(13, HIGH); // включаем светодиод

delay(1000); // ждем 1000 миллисекунд

digitalWrite(13, LOW); // выключаем светодиод

delay(1000); // ждем 1000 миллисекунд

}

 

Если с первого раза получаете «отлуп» (в виде того самого красного сообщения avrdude: stk500_getsync(): not in sync: resp =0x1c ), то проделайте следующее: запустите Диспетчер задач и найдите там устройство Arduino USB Serial Light Adapter . Затем выдерните USB‑кабель из адаптера и сразу включите вновь (в Диспетчере задач устройство исчезнет и опять появится). Теперь ему следует сделать дополнительный программный сброс – в контекстном меню Arduino USB Serial Light Adapter разыщите пункт Отключить . Отключите устройство и сразу же включите опять (напомню, что в Windows 7 и 8 пункт меню будет называться Задействовать ). Если после этих манипуляций связь с платой все равно не заработает, как надо, то перезагрузите компьютер – должно помочь.

 

 

Схема выносного датчика

Схема выносного датчика показана на рис. 22.4. Его мы будем вводить в режим энергосбережения, потому придется принять ряд схемотехнических мер.

 

 

Рис. 22.4. Схема выносного датчика метеостанции

 

Подключение Xbee‑модуля к Arduino Mini отличается от стандартного наличием линии Sleep (контакт 9 платы Xbee‑модуля). По этой линии мы будем загонять модуль в режим низкого потребления в паузах между измерениями. Обратите внимание, что выходы Arduino подключены к модулю через согласующие делители R1/R2 и R3/R4 с довольно большим сопротивлением, – без согласования, как мы говорили, ток через эти выводы резко возрастет. В этих же целях придется выпаять из платы Arduino Mini желтый неуправляемый светодиод, который сигнализирует о подаче питания (его не было в ранних релизах Arduino Mini). Этот светодиод мы заменим на красный, подключенный к стандартному 13‑му выводу платы и заставим его кратковременно включаться в момент считывания показаний и передачи их в станцию (напомним, что к 13‑му выводу на плате уже подключен балластный резистор 1 кОм).

Хитрое включение батарейного питания ориентировано на достижение энергосбережения в максимальной степени. От трех элементов АА (реальное напряжение около 4,5–4,8 В) питается плата Arduino, а от отвода между вторым и третьим – модуль ХЬее (напряжение 3,0–3,2 В). Диод D1 типа КД922 (с переходом Шоттки, т. е. с малым падением напряжения) развязывает источники питания 5 и 3,3 В, чтобы они по каким‑то причинам не начали работать друг на друга. Если бы мы подключили обычное питание 7–9 В к стабилизатору платы, а модуль ХЬее через какой‑нибудь из стандартных «шилдов» со встроенным стабилизатором 3,3 В, то теряли бы питание не только на самих стабилизаторах, но и за счет их собственного потребления.

* * *

 

Подробности

Правда, в Arduino Mini установлен малопотребляющий стабилизатор LP2985AIM5‑5.0 (в этом отличие Mini от Uno, где стоит стабилизатор NCP1117ST50T3G – более мощный, но совсем не экономичный). Однако его, во‑первых, может не хватить для питания Xbee‑модуля в случае, если мы выберем Pro‑версию (согласно документации фирмы Digi, модуль ХЬее Pro может потреблять в момент передачи почти 300 мА, а LP2985 допускает только 150). Во‑вторых, для получения 3,3 В все равно нужен дополнительный стабилизатор, а в нашем Wireless Shield установлен СХ1117‑3.3 – тоже не самый экономичный.

 

* * *

В результате при батарейном питании проще вообще обойтись без нагромождения стабилизаторов – до напряжения 1,1 В на каждый элемент схема должна работать надежно, а это практически 80 % емкости щелочных батарей (см. рис. 9.2). И раз уж мы применяем Arduino, который позволяет многое без особого напряжения сил, то для удобства станем измерять напряжение батареи датчика, передавать его в главный модуль вместе с данными и заставлять станцию сигнализировать, если элементы питания на исходе. В главном модуле для индикации того, что батарейки садятся, заставим строку с внешними данными мигать, если напряжение ниже установленного порога (пусть это будет 3,3 В – по 1,1 В на каждый элемент, возможно, по результатам эксплуатации эту величину придется подкорректировать). Мне неизвестны какие‑либо бытовые приборы, имеющие подобную функцию контроля за напряжением источников питания (кроме, разумеется, мобильников или фотокамер), – пусть это будет наше ноу‑хау.

Программу для выносного датчика можно скачать с сайта автора по ссылке http://revich.lib.ru/AVR/Extsens.zip. В программе используются встроенные возможности Arduino IDE для ввода контроллера в режим энергосбережения и пробуждения по встроенному таймеру WDT. О применении этих режимов можно прочесть на официальном сайте Arduino по ссылке http://playground.arduino.cc/Learning/ArduinoSleepCode (к сожалению, на английском языке). Поиском в Сети можно найти и русскоязычные примеры их использования.

* * *

 

Подробности

Заметим, что в этой конструкции применяется довольно несовершенный метод измерения аналоговой величины напряжения батарейки, когда в качестве опорного напряжения АЦП использован внутренний источник (см. строку analogReference (INTERNAL ), подробности о работе АЦП в МК AVR см. главу 20 и книгу [21]). Потому коэффициент пересчета не вычисляется теоретически, а должен устанавливаться именно путем калибровки, причем с реальным источником питания (набором батареек), а не при подключении к USB или внешнему адаптеру.

Делитель напряжения R5/R6 (он добавляет к общему потреблению менее микроампера) нужен для «подгонки» измеряемого значения под опорное. Не стоит бояться, что входное сопротивление АЦП внесет погрешность при установке столь высокоомного делителя – в МК AVR оно измеряется десятками гигаом. В данном случае выходной код АЦП определяется формулой ADC = 1024Vin /Vref (подробности см. в главах 17 и 20 ). При превышении входным напряжением опорного этот код «застынет» на максимальном значении 1023, так что нам необходимо иметь на входе АЦП напряжение, заведомо меньшее опорного. А опорное напряжение определяется в нашем случае внутренним источником и имеет величину примерно 1,2 В с довольно большим разбросом. Отсюда соотношение сопротивлений резисторов этого делителя должно быть около 5, а точное значение величины коэффициента в программе, с помощью которого вычисляется реальная величина напряжения (переменная voltage, см. строку 105 исходного текста скетча) и должно быть определено с помощью калибровки. Коэффициент будет равен частному от деления реального напряжения батареи в вольтах на величину кода АЦП (переменная val ) – у меня он получился равным 0,0059. Если задаться величиной опорного напряжения, равной 1,1 В, то теоретический расчет даст близкое значение.

Чтобы проверить и при надобности уточнить значение коэффициента, измерьте напряжение батарейки мультиметром во время работы датчика, затем сравните с тем, что запишется в файл на карте (см. далее). Поделив записанное значение на измеренное, вы получите поправку, на которую необходимо умножить значение коэффициента из программы. В случае ЖК‑индикатора без записи на карту, операция калибровки будет сложнее – вам придется временно подправить программу так, чтобы вывести на дисплей значение напряжения, получаемое с датчика.

 

* * *

Во время работы в соответствии с программой датчик основное время потребляет примерно 500 мкА, и каждые 8 секунд по WD‑таймеру включается примерно на 0,8 с – снимает показания с SHT‑модуля, измеряет напряжение батарейки и передает данные через Xbee‑модуль. Напряжение батарейки во избежание случайных выбросов усредняется за каждые 16 показаний. Измерения показали, что во включенном состоянии потребление всего выносного датчика в среднем составляет около 15 мА. Пиковое потребление обычного Xbee‑модуля в момент передачи может превышать 40 мА, но это происходит лишь в течение нескольких миллисекунд, и мы этими выбросами можем пренебречь в своих расчетах. Итого среднее потребление датчика составит приблизительно 2 мА – в соответствии с данными приложения 2 АА‑батареек должно хватить примерно на два месяца непрерывной работы.

Заметим, что если бы мы писали программу на ассемблере, то могли бы уменьшить время активного состояния в несколько десятков раз, и батарейки работали бы гораздо дольше.

Ресурс батареек можно увеличить, если задать снятие показаний и их передачу не каждое пробуждение по WD‑таймеру, а, например, каждое седьмое (т. е. примерно раз в минуту), но отладка такой медленной программы резко усложнится.

 

 

Версия станции с ЖК‑дисплеем

У нас уже все готово для того, чтобы представить версию метеостанции без записи на SD‑карту. Реализацию этой версии мы оформим в виде варианта с ЖК‑дисплеем MT‑12864J, рассмотренным в главе 21 . Для подключения SPI‑интерфейса карты вместе с дисплеем у нас все равно не хватит выводов, так что запись на карту мы реализуем отдельно.

Схема метеостанции в таком варианте представлена на рис. 22.5.

 

 

Рис. 22.5. Схема метеостанции с ЖК‑дисплеем MT‑12864J  

 

Подключение датчиков и часов ничем не отличается от рассмотренного ранее, а подключение ЖК‑дисплея и обращение с ним описано в главе 21 . Полную программу для этого случая можно скачать с сайта автора по ссылке http://revich.lib.ru/AVR/Meteo_LCD.zip. Внешний вид дисплея при работе этой программы показан на рис. 22.6.

 

 

Рис. 22.6. Отображение результатов работы метеостанции на ЖК‑дисплее

 

Если внешний датчик будет недоступен (отключен, пропадет связь, закончатся батарейки), то в верхней строке после слов «На улице» будут отображаться прочерки. Если передаваемая устройством величина напряжения батарейки станет меньше порога (установленного нами в 3,3 В), то строка с данными начнет мигать. После включения питания внешнего датчика в течение первых 16 переданных показаний вместо значения напряжения батарейки станут передаваться одни нули, соответственно, дисплей главного модуля также будет миганием напоминать, что батареи в датчике якобы разряжены. Однако примерно через 2 минуты начнет передаваться измеренное среднее значение, и все должно встать на свои места.

* * *

 

Подробности

Величину порога, возможно, придется подкорректировать по результатам испытаний. Arduino Mini фактически ничего, кроме контроллера, не содержит, и она должна вообще «тянуть» вплоть до полного истощения батареек (согласно документации, у ATmega328 нижний предел питания 1,8 В[52]). У сенсора SHT1x нижний порог повыше (2,4 В), но это тоже далеко за пределами того, что дадут три даже истощенных элемента. То есть, нас будет лимитировать Xbee‑модуль, который, согласно документации фирмы Digi, функционирует до 2,1 В. Из этих соображений и выбран порог в 1,1 В на элемент: 2,2 В на модуль или 3,3 В на все питание. В реальности это требует тщательной проверки, причем с реальными батарейками, а не в искусственно созданных условиях. Что же касается дальности работы выносного датчика, то Xbee‑модули проявили себя наилучшим образом – в процессе испытаний данные уверенно принимались через три гипсолитовых межкомнатных перегородки толщиной 20 см каждая (уровень сигнала Wi‑Fi в тех же условиях падает примерно на 70–80 дБ, что снижает скорость передачи до почти полной неработоспособности канала). Впрочем, если вас дальность работы не удовлетворит, то та же фирма Digi выпускает намного более мощный Xbee Pro.

 

Запись на SD‑карту и программа станции с OLED‑дисплеем

Наличие библиотеки для работы с SD‑картой– один из самых ярких примеров преимуществ Arduino. Можно только представить себе, сколько трудов стоило бы написание на ассемблере кода доступа к флэш‑карте, отформатированной в системе FAT32. Не невозможная задача, конечно, но весьма трудновыполнимая, особенно для любителя, да и вряд ли кто‑нибудь когда‑нибудь пытался выполнить ее на ассемблере. В моей книжке [21] есть пример кода записи/чтения применительно к картам типа ММС – «младшему брату» карт Secure Digital. Ни о каких именах файлов, разумеется, там и речи не идет – данные пишутся просто в ячейки памяти карты, и считаны могут быть только таким же способом, через контроллер. А здесь такие операции, как создание, удаление файла или проверка его существования, стандартные для «больших» компьютеров, выполняются не сложнее, чем в Windows. С единственным ограничением – собственно форматирование карты должно быть выполнено заранее.

Обычно карты продаются уже отформатированными в нужной нам системе FAT 16 или FAT32. Однако оно может «слететь» в процессе эксплуатации или наших с вами издевательств над картой, кроме того, изредка встречаются карты, отформатированные в системе, отличной от FAT. Для того, чтобы проверить систему и при необходимости заново отформатировать карту, ее надо вставить в кардридер компьютера, подождать, пока она появится в Проводнике и через контекстное меню выбрать пункт Свойства . Там на самой первой вкладке Общие будет показана Система , в которой отформатирована эта карта. Если она отличается от FAT 16 (просто FAT) или FAT32, то закройте окно свойств, заново вызовите контекстное меню и выберите пункт Форматировать .

Мы воспользуемся уже упоминавшимся модулем Wireless Shield SD, кроме разъема для Xbee‑модуля, имеющим также слот для миниатюрной карты MicroSD. Более универсальным будет отдельный SD Card shield V4.0,4 куда можно вставлять SD‑карты обычного типоразмера (карты MicroSD вставляются в него через адаптер). Обращение с этими модулями совершенно одинаково, и заняты у них одни и те же контакты, ориентированные на применение библиотеки SD, входящей в комплект Arduino IDE.

Недостаток большинства подобных стандартных Arduino‑модулей с разъемом для SD‑карты состоит в том, что они в качестве вывода «выбор кристалла» задействуют вывод номер 4 . Это сделано по понятным причинам – чтобы освободить стандартный вывод SS порта SPI (вывод 10 ) для использования этого интерфейса в каких‑то иных целях. Однако такой прием приводит к ограничениям на применение вывода 10 – он должен быть установлен только «на выход», иначе стандартные функции SPI контроллера работать не будут. Потому вместо одного дополнительного вывода карта фактически занимает два. К счастью, в качестве выходного мы можем применять порт 10 по своему усмотрению – в нашей схеме он служит одной из линий данных.

 

 

Работа метеостанции с функциями записи на SD‑карту

Полную программу метеостанции с OLED‑индикаторами, построенной согласно схеме на рис. 22.1 с добавленными функциями записи на SD‑карту, можно скачать с сайта автора по ссылке http://revichJib.ru/AVR/Meteo_OLED.zip. Внешний вид индикационной панели с отображением данных показан на рис. 22.7 далее, в разд. «Конструкция». Согласно этой программе, при каждом включении питания в файл data.txt будет записываться строка Arduino meteostation data . А в установленные моменты времени в него записываются данные в виде строки:

06:00 06.04.14 +21.2 26 750 +20.7 27 4.4

Здесь после значения времени идут сведения о внутренней температуре и влажности, затем давление, потом температура и влажность с выносного датчика. В конце выводится информация о напряжении батареи датчика, которая позволит осуществлять контроль за работой узла определения разрядки батареи (в случае необходимости подкорректировать порог надо знать, при каком напряжении датчик прекратил работу). Строка содержит 40 символов, так что об исчерпании пространства на карте можно не беспокоиться – самой маленькой карты объемом в гигабайт хватит примерно на 8 тысяч лет непрерывной записи. Учитывая такой объем свободного пространства, на карте удобно заодно хранить все сопутствующие программы: Arduino IDE вместе с прошивкой станции и утилиту для установки часов. В соответствии с программой, запись данных на карту будет происходить в часы, кратные трем: в 0, 3, 6, 9, 12, 15, 18 и 21 час. Согласно международным правилам, три часа составляют так называемый синоптический интервал, а моменты записи должны отсчитываться по всемирному времени UTC. В настоящее время московский регион отличается от UTC на четыре часа (т. е. всемирному времени 00:00 соответствует московское 04:00), потому для укладки в стандартный ряд синоптических наблюдений необходимо учитывать эту поправку[53]. Закомментированная строка в начале процедуры записи на карту if (clock.second = 0) служит для отладки программы – если ее восстановить (а вышележащую, наоборот, спрятать за комментарием), то запись на карту будет происходить каждую минуту.

После вставки карты следует обязательно перезагрузить станцию и проследить, чтобы после загрузки в первую очередь появилась надпись SD card Ok. Если вместо этого появляется сообщение об ошибке инициализации SD card failed , то выключить и включить питание станции необходимо еще раз. Если карта инициализировалась верно, то в файл data.txt на ней запишется строка Arduino meteostation data . Если этот файл на карте не существовал, то он будет создан заново, иначе указанная строка просто запишется в него еще раз, сигнализируя о том, что станция включалась.

Подтверждение тому, что запись действительно идет успешно, можно получить, если проследить за поведением станции в момент, соответствующий очередному сеансу записи, – не должно появиться сообщение File open failed! , которое возникает, если карта просто отсутствует в слоте. Если же карта вставлена, но инициализация прошла неудачно, то в момент записи станция «повиснет» примерно на 12 секунд – таковы особенности работы библиотеки SD.

Повторю – для успешной записи на карту карта должна быть вставлена в слот до включения питания станции. Следует взять за правило перезапускать станцию после каждого извлечения/вставки карты. Предоставляю читателю самому поэкспериментировать с модификацией программы, которая позволила бы избежать таких ограничений. Вероятно, для этого придется привлечь какую‑нибудь другую библиотеку по работе с SD‑картами в Arduino – особенность прилагаемой библиотеки SD в том, что если карта однажды была инициализирована, то после извлечения и последующей ее вставки при работающем контроллере от программы невозможно добиться не только сообщений об ошибках, но не получается даже принудительно инициализировать карту заново.

 

 

Конструкция

Все элементы разработанных нами схем по рис. 22.1 и 22.5 продаются в комплекте с соединительными кабелями, исключение составляют только дисплеи. В «Амперке» имеется в продаже специальная расширительная плата Troyka Shield, позволяющая подключать подобную периферию. Таким образом, самый простой вариант создания законченной конструкции главного модуля станции заключается в приобретении этой платы и установке друг на друга последовательно трех плат (Arduino Uno, Troyka Shield и Wireless Shield). Ha Wireless Shield, которая должна быть сверху этого «бутерброда» (для лучшей работы модуля ХЬее), имеется поле пустых контактов достаточного размера, чтобы на нем можно было установить контактную колодку для подключения ЖК‑дисплея.

Все это монтируется в пластиковый (обязательно!) корпус, передняя стенка которого вырезана под дисплей. Работе ХЬее пластиковый корпус не помешает, а вот датчики лучше вынести наружу – даже то небольшое количество тепла, которое выделяют компоненты схемы при работе, исказит значения температуры, а влажность в герметичном корпусе может отличаться от реальной на десятки процентов (не в этом ли причина столь плохой работы серийных изделий?).

Сложнее окажется конструкция варианта с двумя OLED‑дисплеями – на стандартных Arduino‑платах для них просто не хватит места. Возможный вариант – изготовление кросс‑платы, на которую устанавливаются все модули, соединенные дорожками с контактами платы Arduino. Отверстия на кросс‑плате делаются так, чтобы штыри Wireless Shield можно было протащить насквозь, пропаять, а затем надеть на них плату Arduino Uno с другой стороны. На рис. 22.7 показано, как выглядит вариант конструктивного исполнения станции с отображением информации на дисплеях.

 

 

Рис. 22.7. Готовая метеостанция на стене загородного дома

 

В выносном датчике устанавливать какие‑либо платы расширения не имеет особого смысла. Все компоненты схемы по рис. 22.4 можно установить на печатной макетной плате (подобной показанной на рис. 3.2 слева ), и соединить их монтажными проводами. Конечно, не стоит паять непосредственно выводы платы Arduino Mini – придется приобрести переходные колодки типа PBS.

Трудность состоит в том, что шаг выводов Xbee‑модуля – 2 мм, и под него довольно сложно найти готовую плату. Так что придется либо раскладывать и изготавливать ее самостоятельно, либо пожертвовать экземпляром Wireless Shield, вырезав из нее кусок с колодками для подключения Xbee‑модуля. На этой плате рядом с колодками имеются соединенные с ними контактные площадки, расположенные с обычным шагом 2,5 мм, куда можно поместить вилку штыревого PLS‑разъема, получив таким образом переходную панельку для установки в обычную плату. Все это монтируется в корпус вместе с батарейным отсеком на три элемента типоразмера АА или С. Как и в случае главного модуля станции, плату SHT1x с датчиками лучше вынести за пределы корпуса, защитив ее от внешних воздействий ограждением или кожухом из пластиковой сетки.

 

 

О недостатках Arduino

Как мы видим, проектировать и изготавливать конструкции с помощью Arduino гораздо проще, чем обычным дедовским способом, из отдельных компонентов. Но за эту простоту приходится платить. В некотором смысле ситуация с Arduino напоминает историю персональных компьютеров – как известно, самым первым продуктом компании Microsoft, созданной в 1976 году, была реализация языка Бейсик под компьютер Altair, для которой требовалось аж целых 4 килобайта памяти. Андрее Хейлсберг тоже создавал свою первую версию Pascal на чистом ассемблере, получив файл объемом 31 Кбайт. Современные среды программирования (в том числе и для тех же самых языков) занимают гигабайты, но при этом работают на гигагерцовых компьютерах медленнее, чем первые продукты Гейтса и Хейлсберга на машинах того времени с тактовой частотой и объемом памяти в тысячи раз меньшими. Подобно им и AVR‑контроллеры, запрограммированные в среде Arduino, оказываются далеки от своих потенциальных возможностей.

Я не ставлю перед собой задачу как‑то принизить значение Arduino и отговорить читателей от работы с этой платформой. Наоборот, я всячески приветствую ее энтузиастов и распространителей. Хочется только, чтобы натолкнувшись в Сети на ее критику, неискушенный читатель не впадал в уныние, а хорошо представлял себе, как говорится, «на каком свете он находится».

Простота Arduino во многом обусловлена тем, что практически все действия в программе осуществляются в ее главном цикле. Но такая простота оборачивается недостаточной надежностью работы – «правильно» запрограммированный контроллер работает почти исключительно через прерывания. Например, неверно заставлять программу отслеживать нажатие кнопки в главном цикле и убирать дребезг путем простых временных задержек, как это делается в распространенном примере для начинающих[54]. Когда контроллер основное время занят последовательным отслеживанием происходящих событий, он запросто может потерять какое‑то из них. Так поступали в семидесятые годы, когда контроллеры были намного примитивнее сегодняшних. В «правильной» программе состояние кнопки отслеживается по внешнему прерыванию, а дребезг убирается его запретом и последующим разрешением по прерыванию таймера. Только так эти действия не могут помешать никаким другим процедурам в программе.

В Arduino просто эксплуатируется факт, что современные микроконтроллеры работают очень быстро, но, по мере усложнения программы, вы довольно скоро упретесь в порог этого быстродействия и не будете понимать, как из этой ситуации вывернуться. На Habrahabr.ru один критик платформы писал, что «вы можете всю жизнь формировать задержки с помощью delay‑функций и не иметь простейшего представления, как работает таймер на микроконтроллере».

Впечатляют и размеры программ, получающихся после компилирования скетчей в среде Arduino IDE. Программа метеостанции с ЖК‑дисплеем займет почти 20 килобайт – около 10 тыс. AVR‑команд. Это непредставимо большая величина для таких устройств, и неудивительно, что при выполнении времязависимых операций они будут тормозить, – именно по этой причине при сборе данных, поступающих из последовательного порта, нам приходится с помощью задержек ожидать, пока они не соберутся в буфере. А если нам понадобится принять или передать пару десятков килобайт или мегабайт данных, что много больше объема буфера? Как угадать задержки так, чтобы гарантированно ничего не потерять?

Программа, состоящая из всего двух функций: digitalWrite (HIGH) и digitalWrite (LOW) , переменно переключающих внешний вывод без искусственных задержек, при проверке на осциллографе покажет меандр с частотой 50Гц – это в контроллере, работающем на частоте 16 МГц! Простая замена этих функций на непосредственное управление портом, даже без выхода за пределы среды Arduino, ускоряет выполнение операций переключения порта примерно в 10 тыс. раз – с почти 2 миллисекунд до долей микросекунды.

Хорошей иллюстрацией к расточительности языка служит также пример пустой программы из двух строк, которую мы употребляли в качестве заглушки при программировании Xbee‑модуля. Ее размер после компиляции составит целых 466 байтов – с помощью ассемблера в такой объем можно запросто втиснуть небольшую программку ориентирования по звездам для орбитального аппарата (реальный случай с одним программистом 60‑х годов прошлого века из НАСА, который упаковал такую программу в остававшиеся свободными 256 байт памяти бортовой ЭВМ спутника).

Нет особых проблем применять к разработке программ для Arduino все возможности МК AVR, включая и прерывания, но при этом среда Arduino потеряет свою простоту и идеальную приспособленность к нуждам любителей. Придется ковыряться в англоязычных «даташитах», изучать регистры, прерывания и таймеры, вникать в тонкости программирования той или иной процедуры, и тогда вы быстро придете к выводу, что Arduino IDE вместе с языком Proccesing только мешают – придется переходить на обычный С или на ассемблер. К этому выводу в конце концов приходят все, кто старается двигаться дальше. Но не унывайте: Arduino дает отличный старт!

 

 

Приложения

 

Резисторы

 


Дата добавления: 2019-02-12; просмотров: 239; Мы поможем в написании вашей работы!

Поделиться с друзьями:






Мы поможем в написании ваших работ!