Вы находитесь на странице: 1из 319

УДК 004.

4
ББК 32.973.26-018.2
П29

ПетинВ.А.
П29 Arduino и Raspberry Pi в проектах Intemet ofТhings. - СПб.:
БХВ-Петербург, 2016. - 320 с.: ил. -(Электроника)
ISBN 978-5-9775-3646-2
Рассмотрено создание простых устройств в рамках концепции Интернета ве­
щей (IoT, Intemet of Things) на базе популярной платформы Arduino и микроком­
пьютера Raspberry Pi. Показана установка и настройка среды разработки приложе­
ний Arduino IDE, а также среда макетирования Frizing. Описаны технические воз­
можности, особенности подключения и взаимодействия различных датчиков и
исполнительных устройств. Показана организация доступа разрабатываемых про­
ектов к сети Интернет, отправка и получение ими данных с использованием попу­
лярных облачных IoT сервисов: Narodmon, ThingSpeak, Xively, Weaved, Blynk,
Wyliodrin и др. Уделено внимание обмену данными с помощью платы GPRS/GSM
Shield. Рассмотрен проект создания собственного сервера для сбора по сети дан­
ных с различных устройств на платформе Arduino. Показано как использовать
фреймворк WeЫOPi для работы с Raspberry Pi. Приведены примеры использова­
ния Wi-Fi-модуля ESP8266 в проектах «Умный дом». На сайте издательства раз­
мещен архив с исходными кодами программ и библиотек.

Для интересующихся современной электроникой

УДКОО 4.4
ББК 32.973.26-018.2

Группа подготовки издания:


Главный редактор Екатерина Кондукова
Зам. главного редактора Игорь Шишигин
Зав. редакцией Екатерина Капалыгина
Редактор Григорий Добин
Компьютерная верстка Ольги Сергиенко
Корректор Зинаида Дмитриева
Дизайн обложки Марины Дамбиевой

По�писано в печать 12.01.16.


Формат 70х100 !,в. Печать офсетная. Усл. печ. л. 25,8.
Тираж 1200 экз. Заказ № 1237.
"БХВ-Петербурr'', 191036, Санкт-Петербург, Гончарная ул., 20.
Первая Академическая типография "Наука"
199034, Санкт-Петербург, 9 линия, 12/28

ISBN 978-5-9775-3646-2 © Петин В А, 2016


© Оформление, издательство "БХВ-Петербурr", 2016
Оглавление

Глава 1. Интернет вещей (вместо введения) ............................................................. 7


Глава 2. Среда программирования Arduino ШЕ .....................•.•..•.•..•.••.•.•..•.•.••.••.••. 9
2.1. Установка Arduino ШЕ ..........................................................................................................1О
2.1.1. В ОС Windows ..............................................................................................................10
2.1.2. В ОС Linux ....................................................................................................................12
2.1.3. В Мае OS Х ...................................................................................................................13
2.2. Настройка Arduino IDE ..........................................................................................................13

Глава 3. Среда разработки Fritzing ............................................................................ 17


3.1. Загрузка и установка среды Fritzing ......................................................................................17
3.2. Главное окно среды Fritzing...................................................................................................17
3.3. Создание схемы соединений..................................................................................................20
3.4. Создание принципиальной схемы .........................................................................................21
3.5. Добавление компонентов в среду Fritzing ............................................................................22

Глава 4. Arduino и аналоговые датчики................................................................... 25


4.1. Аналоговые датчики (сенсоры) .............................................................................................25
4.2. Arduino и датчик температуры LM335 .................................................................................27
4.3. Arduino, Ethemet Shield/W5100 и облачные сервисы ..........................................................29
4.3.1. От;�равка данных на сайт «Народный мониторинг»..................................................33
4.3.2. Чтение данных с фоторезистора .................................................................................39
4.3.3. Отправка данных в сервис ThingSpeak .......................................................................41
4.4. Arduino и инфракрасные датчики расстояния SНARP ........................................................49
4.4.1. Подключение датчиков Sharp к Arduino.....................................................................51
4.4.2. Подсчет количества посетителей магазина................................................................53
4.4.3. Приложение ThingTweet сервиса ThingSpeak ............................................................55
4.4.4. Отправка данных о количестве посетителей в Twitter из Arduino ........................... 57

Глава 5. Использование Arduino в качестве контроллера


исполнительны;х. устройств ......................................................................................... 63
5.1. Arduino и электромагнитное реле .........................................................................................63
5.1.1. Электромагнитное реле................................................................................................63
5.1.2. Устройство и принцип работы электромагнитного реле .......................................... 64
5.1.3. Подключение реле к Arduino .......................................................................................65
4 Оглавление

5.2. Arduino и твердотельное реле................................................................................................67


5.3. Arduino и диммер .................................................................................................................... 68
5.3.1. Диммер .......................................................................................................................... 68
5.3.2. Подключение диммера к Arduino................................................................................ 69
5.3.3. Скетч управления диммером ....................................................................................... 70
5.4. Arduino и сервоприводы......................................................................................................... 72
5.4.1. Принципы управления сервоприводами.....................................................................73
5.4.2. Управление сервоприводом с помощью Arduino ...................................................... 75
5.5. Arduino и библиотека TinyWebServer ...................................................................................77
5.5.1. Использование файлов с SD-карты для формирования веб-страниц....................... 78
5.5.2. Включение/выключение реле с веб-страницы ........................................................... 79
5.5.3. Веб-страница для управления реле ............................................................................. 80
5.5.4. Веб-страница для управления сервоприводом...........................................................85

Глава 6. Arduino и устройства 12 С ............................................................................. 89


6.1. Обзор протокола 12С ............................................................................................................... 89
6.2. Arduino и библиотека Wire .................................................................................................... 93
6.3. Arduino и датчик освещенности BHl750 на шине 12С ......................................................... 96
6.4. Arduino и сервис Xively .......................................................................................................... 99
6.4.1. Отправка данных в сервис Xively ............................................................................. 102
6.4.2. Получение данных из сервиса Xively .......................................................................105
6.5. Arduino и датчик влажности и температуры SHTZl на шине 12С ..................................... 107
6.6. Arduino и сервис Xively (продолжение) .............................................................................. 110
6.6.1. Отправка мультиданных в сервис Xively ................................................................. 11О
6.6.2. Получение мультиданных из сервиса Xively ........................................................... 113
6.7. Arduino и часы реального времени на шине 12 С ................................................................ 116
6.8. Arduino и SD-карта: чтение и запись данных ..................................................................... 121

Глава 7. Arduino и 1-Wire ································································-···•···················· 125


7.1. Технология l-Wire ................................................................................................................ 125
7.2. Применение l-Wire ............................................................................................................... 128
7.3. Интерфейс l-Wire ................................................................................................................. 129
7.3.1. Обмен информацией по шине 1-Wire ....................................................................... 130
7.3.2. Протокол обмена информацией l-Wire .................................................................... 133
7.4. Arduino и цифровой датчик температуры DS18B20 .......................................................... 135
7.4.1. Цифровой датчик температуры DS18В20 ................................................................ 135
7.4.2. Использование библиотеки OneWire для получения данных температуры
с датчика DS18В20 ............................................................................................................... 138

Глава 8. Сервер для сбора данных с ЕtЬеrnеt-модулей датчиков,


установленных на Arduino ........................................................................................ 141
8.1. Датчики влажности DHTl1 и DHT22 ................................................................................. 141
8.1.1. Подключение датчиков DHT к Arduino .................................................................... 143
8.1.2. Библиотека DHT ......................................................................................................... 143
8.2. Модуль датчика движения HC-SR501 ................................................................................ 145
8.3. Модуль датчика звука FC-04 ............................................................................................... 148
8.4. Еthеmеt-модуль датчиков на Arduino ....................................................: ............................. 149
8.5. Сервер сбора данных ............................................................................................................ 153
Оглввлвнив 5

Глава 9. Обмен данными с помощью платы GPRS/GSM Shield........................ 157


9.1. Отправка и получение SМS-сообщений .............................................................................159
9.2. Отправка данных на сайт «Народный мониторинг» ..........................................................162

Глава 10. Проект Blynk: управление Arduino с планшета.................................. 169


10.1. Начало работы: тестовый пример .....................................................................................170
10.2. Управление с планшета исполнительными устройствами,
подключенными к Arduino ................................................................................................. 178
10.3. Отправка данных из Arduino на экран планшета .............................................................181

Глава 11. Микрокомпьютер Raspberry Pi .............................................................. 187


11.1. Технические характеристики и возможности Raspberry Pi .............................................188
11.2. Установка операционной системы ....................................................................................191
11.3. Первоначальная настройка ОС RaspЬian ..........................................................................194
11.3.1. Меню конфигурации ..............................................................................................194
11.3.2. Настройка сетевых параметров .............................................................................196
11.3.3. Настройка доступа по Wi-Fi ..................................................................................196
11.3.4. Подключение 3G-модема ......................................................................................199
11.4. Интерфейс GPIO .................................................................................................................203
11.4.1. Управление GPIO из оболочки bash .....................................................................206
11.4.2. Управление GPIO командами языка Python ........................................................ 206
11.5. Raspberry Pi и датчик температуры DS18B20 на шине 1-Wire .......................................209
11.5.1. Подключение датчика DS18В20 к kaspberry Pi ...................................................209
11.5.2. Отправка данных с датчика DA18B20 в сервис «Народный мониторинг» .......212
11.6. Raspberry Pi и датчик освещенности BHl 750 на шине 12С .............................................215
11.6.1. Подключение датчика ВН1750 к Raspberry Pi .....................................................215
11.6.2. Получение на Raspberry Pi да1mых с датчика BHl 750........................................217

Глава 12. WeЫOPi- веб-интерфейс и облако для Raspberry Pi ...................... 219


12.1. Установка WeЫOPi на ОС RaspЬian .................................................................................219
12.2. Задание пользовательского пароля WeЫOPi ...................................................................221
12.3. Настройка сервера WeЫOPi ..............................................................................................222
12.4. Jаvаsсriрt-библиотека weЬiopi.js ........................................................................................223
12.4.1. Функции библиотеки weЬiopi.js ............................................................................224
12.5. Проект уnравления веб-камерой на сервоприводах ........................................................230
12.6. WeЬIOPi- подключение устройств ................................................................................236
12.7. Доступ к устройству из сервиса Weaved ..........................................................................238
12.7.1. Установка сервиса Weaved .................................................................................... 238
12.7.2. Подключение к Raspberry Pi в сервисе Weaved ...................................................242

Глава 13. Проект Wyliodrin: управление удаленными устройствами


из браузера ....................................................................................................................245
13.1. Добавление устройства в профиль ....................................................................................246
13.2. Запись образа Wyliodrin на SD-карту ................................................................................247
13.2.1. ...в ОС Windows ......................................................................................................248
13.2.2. ...в ОС Linux ............................................................................................................249
13.2.3. ...в Мае OS...............................................................................................................250
13.2.4. ...в ОС RaspЬian ......................................................................................................250
13.3. Запись на SD-карту настроек Wyliodrin ............................................................................250
б Оглавление
13.4. Подюпочение Raspberry Pi к Wyliodrin ............................................................................. 251
13.5. Создание приложения в графической среде программирования .........., ........................ 253
13.6. Вкmочение/выкmочение светодиода с веб-страницы ...................................................... 257
13.7. Подюпочение платы Arduino к сервису Wyliodrin... ........................................................ 259
13.7.1. ...с помощью библиотеки Finnata ......................................................................... 259
13.7.2. ...без использования библиотеки Finnata ............................................................. 266
13.8. Совместная работа Raspberry Pi и платы GrovePi............................................................270
13.9. Обмен сообщениями между платами Raspberry Pi через сервис Wyliodrin................... 274
13.10. Отправка данных в сервис Wyliodrin с мобильного устройства ................................... 277

Глава 14. Wi-Fi модуль ESP8266 .............................................................................. 283


14.1. Режим АТ-команд ............................................................................................................... 284
14.2. Прошивка NodeMCU ............................................... : .......................................................... 289
14.2.1. Запуск веб-сервера ··························································································:········291
14.2.2. Подкmочение к ESP8266 модулей датчиков средствами языка Lua .................... 292
14.3. Проект Home's Smart .......................................................................................................... 294
14.3.1. Прошивка и первоначальная настройка модуля ESP8266 .................................. 296
14.3.2. Обновление прошивки через Интернет ................................................................ 300
14.3.3. Подюпочение датчиков к модулю ESP8266 ......................................................... 300
Подкmочение датчика температуры DS18B20 .................................................... 300
Подюпочение датчика влажности DHTl 1 (DНТ22)............................................ 302
Подюпочение 12С-датчика освещенности BHl 750.............................................. 302
14.4. Отправка данных с модуля ESP8266 на сайт «Народный мониторинr» ........................ 306
14.5. Отправка данных с модуля ESP8266 в сервис ThingSpeak .......................................... : .. 307
14.6. Подюпочение дисплея WН1602 к плате модуля ESP8266 ..............................................310
14.7. Управление выводами GPIO модуля ESP8266.................................................................311
14.8. Работа с прерываниями модуля ESP8266 ......................................................................... 312
14.9. Управление каналами ШИМ модуля ESP8266 ................................................................ 313
14.10. Планировщик задач модуля ESP8266 ............................................................................. 314

Заключение ................................................................................................................... 315


Приложение. Описание электронного архива ....................................................... 316
Предметный указатель .............................................................................................. 317
ГЛАВА 1

Интернет вещей
(вместо введения)
Intemet of Things (IoT, Интернет вещей) - это концепция �<умного дома», где все
(или многие) бытовые приборы и системы управляются через Интернет.
Идея Интернета вещей впервые возникла еще в 1999 году у Кевина Эштона - ис­
следователя из Массачусетского технологического институга (МIТ), предложивше­
го тогда концепцию системы управления через Интернет промышленными объек­
тами. Интернет вещей предполагает оснащение каждого устройства, будь то пыле­
сос, холодильник или стиральная машина, модулем подключения к Интернету
с возможностью взаимодействия его с домашним компьютером или смартфоном
домовладельца.
С появлением Интернета вещей автоматически решится множество самых разных
проблем: от индивидуального комфорта и безопасности, когда «умный» дом будет
оценивать и контролировать собственное состояние, до ликвидации пробок на до­
рогах, когда машины сами станут договариваться со светофорами об оптимальном
трафике. Холодильники смогут следить за просроченными продуктами, лекарства
подскажут время приема, портфель в дождливую погоду напомнит хозяину, что тот
забьm зонтик, а автомобиль сам выдержит безопасную дистанцию в потоке машин
и покажет, где и как лучше припарковаться.
Интернет вещей - это не только множество различных приборов и датчиков, объ­
единенных между собой проводными и беспроводными каналами связи и подклю­
ченных к сети Интернет, а более тесная интеграция реального и виртуального
миров, в котором общение осуществляется между людьми и устройствами.
В этой книге мы познакомимся с практическими примерами создания простейших
устройств для Интернета вещей на базе популярного контроллера Arduino и микро­
компьютера Raspberry Pi. Чтобы Arduino и Raspberry Pi стали полноценными уст­
ройствами для Интернета вещей, их необходимо оснастить датчиками и исполни­
тельными устройствами и предоставить им доступ к сети Интернет. Соответствен­
но, мы рассмотрим работу Arduino и Raspberry Pi с различными датчиками и
устройствами, а также организацию доступа их к сети с дальнейшей отправкой
данных в известные облачные сервисы и получением их оттуда.
А последняя, 14-я, глава книги посвящена использованию в качестве устройства
для Интернета вещей нового, но быстро набирающего популярность Wi-Fi-модуля
ESP8266.
ГЛАВА 2

Среда программирования
Arduino IDE
Разработка собственных приложений на базе плат, совместимых с архитектурой
Arduino, осуществляется в официально бесплатной среде программирования
Arduino IDE. Среда предназначена для написания, компиляции и загрузки собст­
венных программ в память микроконтроллера, установленного на плате Аrduinо­
совместимого устройства. Основой среды разработки является язык Pro­
cessing/Wiring - это фактически обычный С++, дополненный простыми и понят­
ными функциями для управления вводом/выводом на контактах устройства. Для
и
операционных систем Windows, Мае OS Linux существуют свои версии среды.
Скачать среду Arduino IDE можно с ее официального �айта: www.arduino.cc.
Последняя версия Arduino IDE - 1.6.5 - имеет множество улучшений по сравне­
нию с предыдущими. Вот далеко неполный их список:
(j включена поддержка значительного количества платформ;
(:J организовано определение и отображение плат в меню списка портов вместе
с последовательным портом;
(:J увеличена скорость компиляции;
(:J добавлено автосохранение при компиляции/загрузке скетча;
(:J в основу монитора последовательного порта положена современная библиотека
JSSC (вместо старой RXTX), что дало возможность повысить его быстродейст­
вие;
(:J для опций Найти/Заменить организовано несколько вкладок;
(:J улучшено множество библиотек Arduino IDE (String, Serial, Printи пр.);
(:J обновлены инструменты и компиляторьЦаvr-gss, arm-gss, avrdude, bo,ssac);
(:J переработан интерфейс командной строки;
(:J добавлен вывод информации о размере скетча и использовании памяти;
(:J в редакторе теперь отображаются номера строк;
(:J меню с большим количеством строк имеют полосы прокрутки;
(:J организована загрузка устройства Arduino Yun через сеть;
10 Глава 2

(] улучшен класс HardwareSerial;


(] увеличены стабильность и производительность USB;
(] библиотека SPI теперь поддерживает транзакции для улучшения совместимости
при использовании одновременно нескольких SРl-устройств;
(] появилась возможность настроить подмешо с конфигурациями;
(] устранены проблемы загрузки на Leonardo, Micro и Yun;
(] усовершенствованы библиотеки для Arduino- в частности: Bridge, TFT,
Ethernet, Robot_Control, SoftwareSerial, GSM - и устранены проблемы в их ра­
боте;
(] устранено множество незначительных ошибок пользовательского интерфейса.

2.1. Установка Arduino IDE


2.1.1. В ОС Windows
Оrправляемся на страницу http://arduino.cc/en/Мain/Software (рис. 2.1 ), выбираем
версию для операционной системы Windows и скачиваем соответствующий архив­
ный файл. Его объем составляет чуть более 80 Мбайт и содержит все необходимое,
в том числе и драйверы. По окончании загрузки распаковываем скачанный файл
в удобное для себя место.

Download the Aiduino Softwaie

Рис. 2.1. Страница загрузки официального сайта Arduino


Среда программирования Arduino IDE 11

Для установки драйверов подключаем устройство (пусть это будет Arduino Uno)
к компьютеру- на контроллере должен загореться индикатор питания (зеленый
fВетодиод). Начавшаяся тут же попьпка Wind_ows автоматически установить драй­
веры заканчивается сообщением: Программное обеспечение драйвера не было
установлено.
Не беда: открываем Диспетчер устройств и в составе устройств находим значок
Arduino Uno- он там помечен восклицательным знаком. Щелкаем правой кнопкой
мыши на этом значке и в открывшемся окне выбираем опцию Обновить драйверы
и далее- Выполнить поиск драйверов на этом компьютере. Указываем путь
к драйверам- ту папку на компьютере, куда распаковывали скачанный архив, -
пусть это будет папка drivers каталога установки Arduino (например, C:\arduino-
1.6.5\drivers). Игнорируем все предупреждения Windows и получаем в результате
сообщение: Обновление программного обеспечения для данного устройства
завершено успешно. В заголовке окна будет указан и СОМ-порт, на который уста­
новлено устройство.
Осталось запустить среду разработки Arduino ЮЕ (рис. 2.2). Как уже отмечалось
' ранее, в новой версии Arduino ЮЕ в списке доступных портов отображается и на­
звание подключенной платы Arduino.

i void loop () {
'
11 put. your "а

Рис. 2.2. Среда разработки Arduino IDE: выбор порта


12 Глава 2

2.1.2. В ОС Linux
В Linux UЬuntu среда Arduino IDE устанавлива�ся еще проще, поскольку она на­
ходится в репозитории стандартных приложений Linux.
Итак, в меню Ubuntu Приложения I Центр приложений Ubuntu I Загрузить при­
ложение выбираем из списка доступных программ Arduino IDE, затем в списке
разделов выбираем Инструменты разработчика, в списке следующего уровня-
Все приложения и в следующем открывшемся списке- Arduino ЮЕ. В открыв­
шемся окне (рис. 2.3) щелкаем левой кнопкой мыши на значке этой программы-
справа от нее появляется кнопка Установить, нажимаем на эту кнопку, и среда
устанавливается автоматически. Для запуска Arduino IDE выбираем опцию меню
Приложения I Программирование I Arduino ЮЕ.

Рис. 2.3. Установка Arduino IDE из центра приложений Uoontu

Надо заметить, что при таком способе устанавливается не последняя версия про­
граммы Arduino IDE. И чтобы работать именно с ее последней версией, нужно
скачать со страницы загрузки официального сайта проекта Arduino (https://
www.arduino.cc/en/Мain/Software) архив с версией программы для Linux
(см. рис. 2.1) и распаковать его в желаемое место- например, в /home/
<user>/Arduino. Осталось для запуска программы вьmолнить из терминала команды:

cd -/Arduino
./arduino
Среда программирования Arduiпo IDE 13

2.1.3. В Мае OS Х
Для установки Arduino ЮЕ в операционной системе Мае OS Х, как и в предыду­
щих случцях, скачиваем со страницы загрузки официального сайта проекта Arduino
(https://www.arduino.cc/en/Мain/Software) архив с версией программы для OS Х
(см. рис. 2.1), распаковываем его· и копируем содержимое архива в папку Про­
граммь1 - после чего значок Arduino появляется в списке программ Launchpad
(рис. 2.4).

Рис. 2.4. Установка Arduino IDE в OS Х

2.2. Настройка Arduino IDE


. Среда разработки Arduino состоит из:
LI редактора программного кода;
LI области сообщений;
LI окна вывода текста;
LI панели инструментов с кнопками часто используемых команд;
LI нескольких меню.
Программа, написанная в среде Arduino, носит название скетч. Скетч пишется
в текстовом редакторе, который имеет цветовую подсветку создаваемого про-
14 Глава 2

граммного кода. Во время сохранения и экспорта проекта в области сообщений по­


являются пояснения и информация об ошибках. Окно вывода текста показывает
сообщения Arduino, включающие полные отчеты об ошибках и другую информа­
цию. Кнопки панели инструментов позволяют проверить и записать программу,
создать, открыть и сохранить скетч, открыть мониторинг последовательной шины.
Дополнительная функциональность может быть добавлена разрабатываемым скет­
чам с помощью библиотек, представляющих собой специальным образом оформ­
ленный программный код, реализующий некоторый функционал, который можно
подключить к создаваемому проекту. Специализированных библиотек существущ
множество. Обычно библиотеки пишутся так, чтобы упростить решение той или
иной задачи и скрыть от разработчика детали программно-аппаратной реализации.
Среда Arduino ШЕ поставляется с набором стандартных библиотек: Serial,
EEPROM, SPI, Wire и др. Они находятся в подкаталоге libraries каталога установки
Arduino. Внутри каталога с именем библиотеки находятся файлы *.срр и *.h.
Необходимые библиотеки могут_ быть также загружены с различных ресурсов -
папка загруженной библиотеки просто копируется в каталог стандартных библио­
тек (тот же самый подкаталог libraries каталога установки Arduino). Многие библио­
теки снабжаются примерами, расположенными в папке examples. Если библиотека
установлена правильно, то она появляется в меню Эсuз I Импорт .библиотек. Вы­
бор библиотеки: в меню приведет к добавлению в исходный код строчки:
#include <имя библиотеки.h>
Эта директива подключает заголовочный файл библиотеки с описанием ее объек­
тов, функций и констант, которые теперь могут быть использованы в проекте, по­
скольку среда Arduino станет компилировать создаваемый проект уже вместе с ука­
занной библиотекой.
При загрузке скетча используется загрузчик (bootloader) Arduino - небольшая про­
грамма, загружаемая в микроконтроллер на плате. Она позволяет загружать про­
граммный код без использования дополнительных аппаратных средств. fабота
загрузчика распознается по миганию светодиода на цифровом выводе D 13.
Перед загрузкой скетча требуется задать необходимые параметры в меню Инстру­
менты I Плата (рис. 2.5) и Инструменты I Порт (см. рис: 2.2).
Современные платформы Arduino перед загрузкой перезагружаются автоматиче­
ски. На старых же платформах для этого необходимо нажать кнопку перезагрузки.
На большинстве плат во время процесса загрузки мигают све1:одиодь1 RX и ТХ.
Монитор последовательного порта (Serial Monitor) отображает данные, посылаемые
в платформу Arduino (плату USB или плату последовательной шины). Для отправки
данных необходимо ввести в соответствующее поле текст и нажать кнопку Отпра­
вить (Send) или клавишу <Enter> (рис. 2.6), после чего из выпадающего списка
в правом нижнем углу окна монитора выбрать скорость передачи, соответствую­
щую значению serial.begin в скетче.
На Мае ОС или в Linux при подключении мониторинга последовательной шины
платформа Arduino будет перезагружена (скетч начнется сначала).
Среда программирования Arduino IDE 15

Рис. 2.5. Arduino IDE: выбор платы

ок
+cIO': "+79034461752", •• , "15/02/20, 14:58:10+12"
lll<IНµI' КВJ •ьАI +01Gr-1

+ CНGS •
+c!IGS: 22

1(

Рис. 2.6. Ar�uino IDE: монитор nоследовательt1ого порта


ГЛАВА 3

Среда разработки Fritzing

Среда разработки Fritzing предст.авляет собой инструмент разработчика с открытым


исходным кодом, предназначенный для прототипирования и создания прsграммно­
го кода на базе Arduino, а также и для обучения пользователей этим процедурам.
Среда работает как на Windows, так и на Мае OS и на Linux.
С помощью Fritzing можно создать принципиальную схему устройства и оформить
ее представление в виде соединения макетов элементов, разработать печатную пла­
ту, написать код программы и загрузить его в плату Arduino. В отличие от других
систем проектирования, у Fritzing простой интерфейс, который делает разработку
электронных схем интуитивно понятной.

3.1. Загрузка и установка среды Fritzing


Для установки среды разработки Fritzing перейдите на страницу ее загрузки
(http://fritzing.org/download/?donation=0) и выберите свою операционную систему
(рис. 3.1). На момент подготовки этой книги актуальна версия среды 0.9.2Ь. Для
установки программы на компьютер следуйте инструкциям, приведенным на стра¬
нице загрузки.

3.2. Главное окно среды Fritzing


В первый раз открыв среду разработки Fritzing, вы увидите окно, изображенное на
рис. 3.2.
Для разработки схемы соединения элементов разрабатываемого нами проекта пере¬
ключимся на вкладку Макетная плата (рис. 3.3).
В правой части окна находятся панели инструментов со всеми элементами и оп¬
циями. Они содержат как основные компоненты: провода, кнопки, резисторы и пр.,
так и различные специализированные компоненты — например, платы Arduino и
датчики.
Если компонент настраивается, то в панели инструментов Инспектор отображают¬
ся настраиваемые параметры для этого компонента (рис. 3.4).
18 Глава 3

Рис. 3.1. Страница загрузки Fritzing

Рис. 3.2. Окно программы Fritzing


Среда разработки Fritzing 19

Рис. 3.3. Вкладка Макетная плата

Рис. 3.4. Панель Инспектор для настройки параметров компонента


20 Глава З

3.3. Создание схемы соединений


В качестве примера соберем небольшую схему, в которой к выводу 13 платы
Arduino Uno будет подкточен светодиод. Для этого добавим на вкладку Макетная
плата следующие элементы: Arduino Uno, светодиод и резистор.
Резистор перетащим на макетную плату так, чтобы каждый его вывод попал на от­
дельный столбец на плате. При этом, когда компонент подключается к тому или
иному отверстию макетной платы, весь столбец отверстий становится светл6-
зеленым, а зеленая линия указывает на электрическое соединение между отвер­
стиями. В свойствах компонента f{a панели Инспектор выберем номинал резисто­
ра: 2200м.
Затем поместим на плату светодиод. Здесь так же, как и на реальной макетной пла­
те, мы можем добавлять провода, чтобы подключать необходимые нам элементы:
для добавления провода наведите курсор мыши на отверстие на макетной плате
(оно подсвечивается синим- это означает, что можно начинать вести провод),
щелкните на нем левой кнопкой мыши и, не отпуская кнопки, перетащите второй
конец провода в требуемую точку. Добавив таким образом необходимые провода,
мы получим схему, представленную на рис. 3.5. Чтобы использовать ее в дальней­
шем, необходимо сохранить ее в нужном формате (командой меню Файл I Экс­
порт).

Рис. 3.5. Схема подключения светодиода к выводу 1 З Arduino Uno


Среда разработки Fritzing 21

3.4. Создание принципиальной схемы


В предьщущем разделе мы рассмотрели создание схемы соединений. Теперь созда­
дим на основе этой схемы (см. рис. 3.5) принципиальную схему устройства, для чего
переключимся на вкладку Принципиальная схема (рис. 3.6).

Рис. 3.6. Вкладка Принципиальная схема для нашей схемы соединений:


исходное состояние

Как можно видеть, среда Fritzing создала все необходимые соединения, надо только
привести их к более опрятному виду. Для этого в меню Fritzing выбираем команду
Вид I Подогнать окно - чтобы автоматически сцентрировать и отмасштабировать
схему на рабочем поле. Затем, перетащrnвая и поворачивая компоненты, постара­
емся добиться того, чтобы проводники не пересекались, или же количество таких
пересечений стало минимальным (рис. 3.7).
После этого в левом нижнем углу окна среды Fritzing нажимаем кнопку Автотрас­
сировка, и схема приводится в порядок. Теперь ее можно сохранить для публика­
ции в удобном формате (командой меню Файл I Экспорт).
22 Глава 3

Рис. 3.7. Вкладка Принципиальная схема для нашей схемы соединений:


состояние после необходимой корректировки

3.5. Добавление компонентов


в среду Fritzing
Панели инструментов в правой части окна Fritzing содержат библиотеки уже
имеющихся распространенных элементов, а также некоторые"модули ряда произ­
водителей. Все это мы можем использовать сразу после устано�ки Fritzing. Но рано
или поздно возникает необходимость добавить какой-либо компонеш или шилд,
с которым мы планируем работать далее. Как же добавить новый компонеш в биб­
лиотеку Fritzing?
Вы можете создать собственный компонент с нуля или найти готовые комnоненты
на просторах Интернета. Большое количество таких компонентов собрано на рус­
скоязычном ресурсе «Роботоша» по адресу: http://robotosha.ru/arduino/fritzing­
library.html (рис. 3.8). Скачаем оттуда какой-нибудь компонеш- например,
16-кнопочную клавиатуру (файл KEYPAD 4x4.fzpz) и добавим ее в библиотеку
Fritzing.
Итак, выбираем раздел, в который мы собираемся добавить новый компонент, -
пусть это будет, например: М1NЕ I Му Parts (Мои компоненть1). Щелкаем правой
кнопкой мыши, выбираем пункт Import и в открывшемся окне выбираем скачан-
Среда разработки Fritzing 23

Рис. 3.8. Компоненты для Fritzing на сайте «Роботоша»

Рис. 3.9. Компонент добавлен в раздел MINE


24 Глава З

ный на свой компьютер файл компонента с расширением fzpz, fЬz или fzbz - ком­
понент появится в нашей библиотеке (рис. 3.9).
Теперь щелкнем правой кнопкой мыши на разделе М1NЕ и выберем команду
SaveBin - чтобы иметь возможность задействовать новый компонент и в после­
дующих сессиях работы с Fritzing. Если этого не сделать сразу, то при выходе из
Fritzing программа еще раз предложит вам сохранить изменения.
Вот, пожалуй, и все - мы рассмотрели основные возможности программы Fritzing,
которые пригодятся нам при дальнейшей работе с этой книгой.
ГЛАВА 4

Arduino и аналоговые датчики

4.1. Аналоговые датчики (сенсоры)


Датчик (сенсор) - это устройство, с помощью которого мы измеряем значение
какого-либо технологического параметра. Датчики позволяют определять, что про­
исходит во внешней среде, и действовать на основе этой информации, - их, на­
верное, можно назвать органами чувств системы. Любой датчик состоит из чувст­
вительного элемента и преобразовательного устройства, выполняющего преобра­
зование входного воздействия на датчик любой физической · величины в сигнал,
удобный для дальнейшего использования.
Самый простой тип датчиков - аналоговые датчики (первичные преобразователи),
применяемые в системах непрерывного измерения и регулирования. Принцип дей­
ствия аналоговых датчиков состоит в том, что в зависимости от изменения изме­
ряемого параметра происходит соответствующее изменение их выходного сигнала.
При этом выходное напряжение датчика может принимать значение от О В до на­
пряжения его питания. Впрочем, обычно рабочий диапазон напряжений аналого­
вых датчиков более узкий.
Примерами таких датчиков могут служить:
l::J акселерометры - для обнаружения наклона (используются в смартфонах и
планшетах);
l::J магнитометры - для обнаружения магнитных полей (используются при созда-
нии цифровых компасов);
l::J инфракрасные датчики - для определения расстояния до объекта;
l::J датчики температуры - для определения температуры;
l::J фоторезисторы - для измерения освещенности.
Между измеряемой величиной датчиков и возвращаемым напряжением установле­
на определенная зависимость. Например, чем больше величина, тем больше напря­
жение. Или, наоборот, - чем больше величина, тем напряжение меньше. Так, ин­
фракрасный датчик расстояния Sharp GР2УОАО2УК измеряет расстояние от него до
объекта - и чем меньше расстояние, тем больше напряжение. Если объект нахо-
26 Глава 4

дится на расстоянии 20 см, сенсор выдает на сигнальном проводе примерно 2,5 В.


На расстоянии 60 см - примерно 1 В, а на расстоянии 150 см - примерно 0,4 В
(рис. 4.1). Иногда зависимость более сложная: напряжение расtет до определенного
значения, затем падает пропорционально ему. Здесь все зависит от конкретного
датчика.

з
- White Reflectivity:90%

,
• • • • Gray Reflectivity: 18%


2.5

t 2
\
18
\
1\
1.5


"",'.....-...
0.5
"- -
--
О О 1О 20 30 40 50 60 70 80 90 1001IO1'20130 140 JSO

Distance to reflective °'j)ject L (cm)

Рис. 4.1. Диаграмма зависимости выходного напряжения от расстояния


для даn�ика Sharp GP2YOA02YK

Диаграммы для других аналоговых датчиков можно найти в документации на них


или получить экспериментально.
Преимуществом сенсоров с аналоговым сигналом является крайняя простота их
использования с Arduino. А главный недостаток аналогового сигнала - неустойчи­
вость к внешним шумам: если провод _от сенсора до микроконтроллера будет дос­
таточно длинным, он начнет работать как антенна й: улавливать внешние электро­
магнитные поля, - т. е. провод сам станет влиять на выходное напряжение и тем
самым искажать показания датчика. Поэтому разумный предел длины провода для
аналогового сенсора - не более 50 см.
АНАЛОrО-ЦИФРОВЫЕ ПРЕОБРАЗОВАТЕЛИ (АЦП)
Датчики, выдающие аналоговый сигнал (напряжение), .оцифровываются в управляю­
щей программе с помощью аналого-цифровых преобразователей (АЦП). Микрокон­
троллеры Atmega, используемые в Arduino, содержат шестиканальный АЦП. Разре­
шение такого преобразователя составляет 10 битов, что позволяет на выходе полу­
чать значения от О до 1023.
Различные платы Arduino имеют разные количества аналоговых входов. Например,
платы UNO и Duemilanovo имеют 6 аналоговых входов, Nano- 8, Yin- 12, Mega-
16. Основным применением аналоговых входов большинства платформ Arduino явля-
Arduino и аналоговые датчики 27

ется чтение показаний аналоговых датчиков, для чего в Arduino существует стандарт­
ная функция analogRead() . Вот пример чтения данных с аналогового входа АО:
int valuel=analogRead(AO);
Диапазон входного напряжения от О до 5 В в программе проецируется на диапазон
целочисленных значений от О до 1023. Для масштабирования значения к другим зна­
чениям можно использовать функц+1ю map() :
int value2=map(valuel,0,1024,min,max);

4.2. Arduino и датчик температуры LM335


Познакомимся с работой аналоговых датчиков температуры на примере датчика
LM335 (рис. 4.2)- недорогого температурного чувствительного элемента с диапа­
зоном ОТ -40 ДО+100 °С И С ТОЧНОСТЬЮ В 1 °С.

R1
(GND) LM135 Output
LM235 1omv1·к
LM335
ADJ
Рис. 4.2. Датчик температуры LМЗ�5 Рис. 4.3. Типовая схема включения датчика LМЗЗ5
\

По принципу действия датчик LM335 представляет собой; стабилитрон, у которого


напряжение стабилизации зависит от температуры, - при повышении температу­
ры на один градус Кельвина напряжение стабилизации увеличивается на 1О милли­
вольт. Типовая схема включения датчика (соответствует типовой схеме включения
стабилитрона) показана на рис. 4.3 (номинал резистора Rl равен 2,2 кОм).
При взгляде на' эту :rиповую схему сразу возникает вопрос о напряжении питания
(V+), подаваемом на датчик с учетом указанного номинала резистора Rl. Ответ со­
держится в технической документации на датчик (Datasheet), где сказано, что нор­
мальная работа изделия гарантируется в диапазоне токов 0,45-5,00 миллиампер.
Следует заметить, что предел в 5 мА превышать не следует, поскольку датчик ста­
нет перегреваться и измерять собственную температуру.
Согласно Datasheet датчик проградуирован в абсолютной шкале Ющьвина. При
температуре -273,15 °С (это абсолютный ноль по Кельвину) рассматриваемый дат­
чик должен показать и нулевое напряжение. А при увеличении температуры на
каждый градус выходное напряжение стабилитрона станет возрастать на целых
10 мВ, или на 0,010 В.
28 Глава 4
Температура 25 °С - единственная точка калибровки датчика. При этой темпера­
туре на выходе датчика должно присутствовать напряжение 298,15 х 0,010 =
= 2,9815 В. Для калибровки датчика используется схема, представленная на
рис. 4.4.
V+

А1
_____ Выход0
10 мВ/ К
LM135
LМ235 10 кОм*
LМЗ35

*Калиброван для 2,982 В при 2s•c


Рис. 4.4. Схема калибровки датчика LМЗЗ5

Итак, подключаем датчик температуры LM335 по схеме, представленной на


рис. 4.5, и пишем скетч считывания данных с датчика и вывода показаний в после­
довательный порт (листинг 4.1). Вывод результатов измерения данных датчиком
LM335 в последовательный порт показан на рис. 4.6.

fr1tzing
Рис. 4.5. Схема подключения датчика LМЗЗ5 к Arduino

int lm335=0; // подключение датчика к аналоговому входу АО


void setup()
{
Serial.begin(9600);
}
Arduino и аналоговые датчики 29
void loop()
{
douЫe val = analogRead(lrn335); // чтение
douЫe voltage = val*S.0/1024; // перевод в значение в вольтах
douЬle temp = voltage*lOO - 273.15; // перевод в градусы Цельсия
Serial.print(" temp = ");
Serial.println(temp);
delay(lOOO);
}

Рис. 4.6. Вывод результатов измерения данных датчиком LМЗЗ5 в последовательный порт

4.3. Arduino, Ethernet Shield/W5100


и облачные сервисы
Реализуя концепцию Intemet of Things (Инrернет вещей), согласно которой доступ
к данным датчиков должен быть обеспечен из любой точки мира, давайте сейчас
организуем отправку данных из Arduino в облачные сервисы, для чего необходимо
предоставить плате Arduino доступ к с�ти Интернет.
Самый распространенный способ предоставления такого доступа- использование
платы Ethemet Shield (рис. 4.7)- платы расширения, которая состыковывается
с платой Arduino посредством сопряженных разъемов и дает ей возможность., вы-
30 Глава 4

ступая в роли сетевого устройства, общаться по проводной сети с аналогичными


устройствами, с обычными компьютерами, принтерами, сервисами в Интернете и
прочими сетевыми ресурсами.

Рис. 4. 7. Плата Ethernet Shield RevЗ

ПЛАТА ETHERNET SHIELD


Плата Ethernet Shield основана на чипе Wiznet W5100, который подцерживает как
ТСР-, так и UDР-протоколы. Одновременно открытыми могут быть до четырех под­
ключений.
Плата обладает стандартным Ethemet-nopтoм для подключения к сети с помощью
патч-корда «витая пара» и набором контактов для сопряжения с Arduino. Для общения
между собой Ethemet Shield и Arduino задействуют контакты 4-й и с 10-го по 13-й, по­
этому их использование в других целях в присутствии платы расширения невозможно.
Для программирования сетевого взаимодействия служит библиотека Ethernet из стан­
дартного дистрибутива. При использовании этой библиотеки необходимо указывать
МАС-адрес платы (уникальный идентификатор любого сетевого устройства). В более
новых версиях платы Ethernet Shield ее МАС-адрес можно найти на наклейке на плате.
Если такой наклейки нет, то просто введите любую подходящую цифробуквенную
комбинацию, - главное, чтобы в вашей сети не было устройств с совпадающими
МАС-адресами.
Плата Ethemet Shield также оборудована слотом для карты памяти формата MicroSD,
на' которой можно хранить ресурсы, раздаваемые по сети. Для взаимодействия с SD-кар­
той может быть использована библиотека sdfatlib.
Последняя версия платы Ethemet Shield RevЗ полностью совместима с Arduino Mega2560.
Arduino и аналоговые датчики 31

Итак, с учетом сказанного, для отправки данных в облачные сервисы мы задейст­


вуем плату Arduino с подключенной к ней платой Ethernet Shield, выступающей
в качестве веб-клиента, и создадим на этой основе простой пример получения на­
шим устройством IР-адреса по DHCP. Подключается Ethernet Shield к плате Arduino
так же просто, как и любой другой шилд, - просто состыкуйте их вместе.
Соединив Ethernet Shield с платой Arduino, подключим плату Arduino к USВ-порту
компьютера, а к Ethernet Shield подсоединим сетевой кабель (рис. 4.8).

СОВЕТ
Следует учесть, что установка других шилдов поверх Ethernet Shield весьма затрудни­
тельна. Это связано с большими размерами разъема RJ-45, служащего для подклю­
чения сетевого кабеля, поэтому, ,если вы хотите использовать другие шилды, лучше
их размещать между Arduino и Ethernet Shield.

Рис. 4.8. Подключение плат Ethernet Shield RevЗ и Arduino

Пример получения IР-адреса по DHCP представлен в листинге 4.2.

// Получение IР-адреса ПО DHCP


// МАС-адрес Ethernet Shield (можно увидеть на наклейке на плате) или
// произвольный, но уникальный в сети
#include <Ethernet.h>
#include <SPI.h>

byte rnac[J = {ОхОО, ОхАА, ОхВВ, ОхСС, OxDE, Ох02);

void setup()
// Open serial coппnunications and wait for port to open:
Serial.begin(9600);
)
// запуск Еthеrnеt-соединения
if (Ethernet.begin(rnac) == О)
32 Глава 4

Serial.println("Failed to configure Ethernet using DHCP");


for (;;)

}
// печать в последовательный порт полученного по DHCP адреса
Serial.print("My IP address: ");
for (byte thisByte = О; thisByte < 4; thisByte++) {
Serial.print(Ethernet.localIP()[thisByte], DEC);
Serial.print(".");

Serial.println();

void loop() {;}

Пример назначения статического IР-адреса представлен в листинге 4.3.

// Получение статического IР-адреса


// МАС-адрес Ethernet Shield (можно увидеть на наклейке на плате) или
// произвольный, но уникальный в сети
#include <Ethernet.h>
#include <SPI.h>

byte rnac[J = {ОхОО, ОхАА, ОХВВ, ОхСС, OxDE, Ох02};


// IР-адрес, назначаемый Ethernet Shield:
byte ip[] = { 192, 168, О, 111 };
// IР-адрес, dns сервера:
byte sdns[] = { 192, 168, 1, 1 };
// адрес шлюза:
byte gateway[] = { 192, 168, О, 1 };
// маска:
byte suЬnet[J = { 255, 255, 255, О };

void setup() {
Serial.begin(9600);
// запуск Еthеrnеt-соединения
Ethernet.begin(rnac, ip, sdns, gateway, suЬnet);
delay(lOOO);
Serial.println(Ethernet.localIP());

void loop() { ;}

Получив дос'I)'П в Интернет, можно отправлят� данные с платы Arduino в облачные


сервисы. В следующем разделе мы рассмотрим пример такой отправки данных -
на сайг «Народный мониторинг».
Arduino и аналоговые датчики 33

4.3.1. Отправка данных


на сайт «Народный мониторинг»
Сайт «Народный мониторинг» (http://www.narodmon.ru)- проект по сбору и
отображению на карте мира показаний температуры, давления, влажности и т. п.
практически в реальном времени по фактическому их состоянию (а не на основе
прогнозов) от различных датчиков среды, установленных как на улице для публич­
ного доступа, так и в помещении для приватного, а также с веб-камер для частного
или публичного доступа. Передавать показания датчиков на narodmon.ru можно
посредством протоколов TCP/UDP или НТТР GET/POST. Минимальный интервал
передачи показаний датчика - 5 минут (если передавать чаще, то возможна блоки­
ровка).
Чтобы стать участником проекта, необходимо зарегистрироваться: заходим на сайт
http://www.narodmon.ru, выбираем команду меню Вход I Стать участником про­
екта и в открывшуюся форму (рис. 4.9) вводим адрес электронной почты, {()'да
будут нам отправлены логин и пароль для входа в профиль.

Рис. 4.9. Регистрация на сайте «Народный мониторинг»

Теперь настроим передачу и отображение показаний нашего, подключенного


к Arduino, датчика температуры LM335 из разд. 4.I. Для добавления датчика на
карту необходимо выполнить следующие действия:
1. Подключить устройство мониторинга (в нашем случае Arduino) к источнику
питания и к сет:н Интернет (с помощью платы Ethemet Shield).
2. Настроить передачу показаний на сайт narodmon.ru с интервалом 5-15 минут
(напомню, если чаще, то возможна блокировка).
34 Глава 4

3. Авторизоваться на сайте narodmon.ru, используя свой логин (e-mail или номер


мобильного телефона) и пароль, полученные при регистрации.
4. В разделе Мои Датчики добавить устройство, введя его уникальный алфавитно­
цифровой код (МАС-адрес). Добавление возможно только после успешной
передачи показаний на сервер и верно указанного МАС-адреса.
5. Выбрать тип данных нашего датчика: температура. Если у нас подключены
к Arduino еще несколько датчиков: влажности, давления и др., то выбираем все
актуальные.
6. Установить доступ к показаниям для каждого датчика: публичный (виден всем)
или приватный (только вам).
7. Указать названия для устройства и подключенных к нему датчиков.
8. Выполнить привязку к карте устройства мониторинга, указав полный адрес его
размещения или геокоординаты, щелкнув для этого по строке с адресом 13 поле
Устройство раздела Мои Датчики.
9. Уточнить свое местоположение, переместив маркер своего устройства на карте,
щелкнув на опции Переместить в его всплывающем окне.
Что ж, приступим к реализации перечисленных действий. И прежде всего подклю­
чим датчик температуры LM335 к плате Arduino с Ethemet Shield (рис. 4.10).

Рис. 4.10. Схема подключения датчика температуры LМЗЗ5 к плате Arduino,


состыкованной с Ethernet Shield/W5100

Далее загрузим на плату Arduino рекомендованный пример подключения к сервису


narodmon.ru от student-proger.ru, изменив его под свои требования (сетевые
параметры и датчики). Содержимое скетча представлено в листинге 4.4.

#include <SPI.h>
#include <Ethernet.h>
Arduino и аналоговые датчики 35

byte mac[J = { Ох94, OxDE, Ох80, ОхЗА, Ох90, ОхС9}; // МАС-адрес Arduino
const unsigned long postipginterval,= 600000; // интервал между отправками
// Д�ННЫХ - 10 МИНУТ
// IР-адрес, назначаемый Ethernet Shield:
byte ip[J = { 192, 168, О, 119};
// IР-адрес, dns сервера:
byte sdns[J = { 192, 168, 1, 1};
// адрес шruоза:
byte gateway[J, = { 192, 168, О, 28};
// маска:
byte suЬnet[J = { 255, 255, 255, О};

IPAddress server(94,19,113,221); // IР-адрес сервера


//IPAddress server(91,l-22,49,168); // IР-адрес сервера
EthernetClient client;
unsigned long lastConnectionTime О; // время последней передачи данных
boolean lastConnected = false; !/ состояние подключения
char replyBuffer[l60];

void setup()

Serial.begin(9600);
// Ethernet connection:
Ethernet.begin(mac,ip,sdns,gateway,suЬnet);
// секунда для инициализации Ethernet
delay(lOOO);
// первое соединение через 15 секунд после запуска
lastConnectionTime = millis()-postinginterval+l5000;

void loop()
{
// если не подключены, и прошпо определенное время, то делаем замер,
// переподключаемся и отправляем данные
if (!client.connected() && (millis() - lastConnectionTime > postinginterval))
{
// формирование НТТР-запроса
memset(replyBuffer, О, sizeof(replyBuffer));
strcpy(replyBuffer,"ID=");
// конвертируем МАС-адрес
for (int k=O; k<6; k++)
{
int Ы=mac[k]/16;
int b2=mac[k]%16;
char с1[2],с2[2];

if (Ь1>9) cl[OJ=(char)(Ы-10) +'А';


else cl[О·] = (char)(Ы) + 'О';
36 Глава 4

if (Ь2>9) c2[0]=(char)(Ь2-10)+'А';
else с2[0] = (char)(Ь2) + 'О';

cl[l]='\0';
с2[1]='\0';

strcat(replyBuffer,cl);
strcat(replyBuffer,c2);
}
strcat(replyBuffer,"&");
strcat(replyBuffer,"3351C4BA0200003B");
strcat(replyBuffer,"=");
char ternp[3];
douЫe tmpd=(analogRead(AO)*S.0/1024)*100-273.15;
int tmpi=int(tmpd);
itos(tmpi,temp);
strcat(replyBuffer,ternp);
strcat(replyBuffer,'\О');
// отправляем запрос
httpRequest();
}
// храним последнее состояние подключения
lastConnected = client.connected();

// функция отправки запроса


void httpRequest() {
if (client.connect(server, 80))

// send the НТТР POST request:


client.println("POST http://narodmon.ru/post.php НТТР/1.0");
client.println("Host: narodmon.ru");
client.println("Content-Type: application/x-www-form-urlencoded");
client.print("Content-Length: ");
client.println(len(replyBuffer));
client.println();
client.println(replyBuffer);
client.println();
lastConnectionTim� = millis();
}
else

client.stop();
}

// размер данных
int len(char *buf)
Arduino и аналоговые датчики 37

int i=O;
do

i++;
} while (buf[i] ! ='\0');
retum i;

// функция int to string


void itos(int n, char bufp[З]) //
{
cha,r buf[ЗJ = { '0', '0', '\0' };
int i = 1;
while (n > О)
{
buf[i] = (n % 10)+48;
i--;
n /= 10;

for (i=O; i<З; i++)


bufp[i]=buf[i];

Для передачи данных на сайт «Народный мониторинг» мы используем резервный


протокол передачи НТТР POST/GET на URL: http://narodmon.ru/post.php.
При этом НТТР-заголовки для POST будут следующими:
POST http://narodmon.ru/post.php HTTP/1.0\r\n
Host: narodmon.ru\r\n
Content-Type: application/x-www-form-urlencoded\r\n
Content-Length: NN(кол-во байт в строке данных ниже)\r\n
\r\n
ID=МAC&rnacl=valuel&... &rnacN=valueN[&tirne=UnixTirne][&narne=NAМEJ [&lat=LAT][&lng=L
NG]

Скетч запускает Еthеmеt-соединение, плата получает IР-адрес в Сети, один раз


в 5 минут считываются данные с датчика температуры, формируется строка с дан­
ными для отправки на сервер «Народный мониторинг», и данные отправляются
с использованием протокола НТТР POST.
ЭЛЕКТРОННЫЙ АРХИВ
СкеТ'-1, соответствующий листингу 4.4, можно найти в файле arduino:_scetches\_04\
_04_04.ino соnровождающеrо книгу электронного архива.

Теперь авторизуемся на сайте, используя логин и пароль, пришедшие на нашу


электронную почту, выбираем команду меню Датчики I Мои Датчики I Добавить
устройство и вводим МАС-адрес нашего устройства. Если данные уже были от­
правлены на сайт, устройство будет добавлено (рис. 4.11).
38 Глава 4

Рис. 4.11. Добавление усrройсrва на сайте «Народный мониторинг»

Затем выбираем тип данных для нашего датчика (темпераrура), устанавливаем дос­
rуп к показаниям (приватный), указываем название устройства и выполняем при­
вязку к карте устройства мониторинга, указав полный адрес щелчком по строке
с адресом. После чего выбираем опцию показать на карте (см. рис. 4.11) и в слу­
чае необходимости корректируем положение на карте с помощью плавающего
меню (рис. 4.12).

Рис. 4.12. Добавление усrройсrва на карту сайта «Народный мониторинг»


Arduino и аналоговые датчики 39

Через некоторое время мы можем посмотреть временной график изменения данных


датчика на нашем устройстве. Для этого выбираем команду меню Профиль I Мои
Датчики и значок графика для выбранного датчика. На графике (рис. 4.13) пред­
ставлено изменение переданных данных датчика во времени.

Рис. 4.13. Временной график переданных показаний на сайте «Народный мониторинг»

4.3.2. Чтение данных с фоторезистора


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

Рис. 4.14. Фоторезистор


40 Глава 4

Рис. 4.15. Графическая схема подключения фоторезистора к Arduino

нее - обычным резистором достаточно большого номинала (мы примецим здесь


резистор 10 кОм). Среднее же плечо делителя подкточается к аналоговому входу
АО Arduino.
Скетч, который измеряет напряжение на аналоговом входе и отправляет его в по­
следовательный порт, представлен в листинге 4.5.

// Получение данных с фоторезистора и отправка в последовательный порт


int light;
void setup()
{
Serial.begin(9600);
}

void loop()

light = analogRead(O);
Serial.println(light);
delay(lOO);
}
Arduino и аналоговые датчики 41

При уменьшении освещенности фоторезистора (можно просто затенить его рукой)


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

4.3.3. Отправка данных в сервис ThingSpeak


Сервис ThingSpeak (https://thingspeak.com)- открытая платформа данных для
проектов Intemet of Things, включающая в себя сбор данных с датчиков в реальном
времени, обработку этих данных, их визуализацию и использование в приложениях
иплагинах.
Чтобы начать работу с сервисом ThingSpea�, необходимо зарегистрироваться,
1
нажав на кнопку GetStarted Now в стартовом окне сервиса. В открывшемся окне
регистрации заполняем .требуемые поля формы (рис. 4.16), нажимаем на кнопку
Create Account и сразу 'попадаем в свой аккаунт (рис. 4.17).

Рис. 4.16. Форма регистрации ThingSpeak

Рис. 4.17. Успешная регистрация в сервисе ThingSpeak


42 Глава 4

Здесь нам надо создать·канал (Channel), в котором будут храниться наши данные.
Каждый канал включает в себя восемь полей ДJIЯ любого типа данных, три поля
местоположения и одно поле состояния. Таким образом, один канал мы можем
использовать для отправки и хранения данных с одного устройства, имеющего не
более восьми датчиков.
Для создання: канала нажимаем на кнопку New Channel, заполняем поля, как пока­
зано на рис. 4.18, и сохраняем канал, нажав на кнопку Save Channel. Все - канал
Склад создан (рис. 4.19). Как можно видеть на рис. 4.18, мы в качестве датчика за­
действовали в создаваемом канале фоторезистор, прописав его в поле Field 1.

Рис. 4.18. Заполнение полей канала ThingSpeak

Отправка данных в канал осуществляется с использованием протокола НТТР


POST:
URL: http://api.thingspeak.com/update
Content Туре: application/x-www-form-urlencoded
Content: key=<Your АР! Key>&fieldl=<data fieldl>

Для проверки возможности отправки данных в канал ТhingSpeak мы воспользуемся


дополнением Poster браузера Mozilla Firefox - удобным инструментом разработ­
чика, позволяющим отправлять НТТР-запросы.
На рис. 4.20 показано, как мы эмулируем отправку нескольких значений с датчика,
прописанного в поле Field 1 (т. е. с фоторезистора), а рис. 4.21 демонстрирует гра­
фик канала, отображающий поступившие данные.
Arduino и аналоговые датчики 43

Рис. 4.19. Канал ThingSpeak создан

Рис. 4.20. Отправка данных в ThingSpeak через НТТР POST с помощью дополнения Poster
браузера Mozilla Firefox
44 Глава 4

Рис. 4.21. Отображение поступивших данных на графике в канале

А сейчас мы осуществим отправку в ThingSpeak данных с реальных датчиков, под­


ключенных к плате Arduino, состыкованной с Ethemet Shield. Для этого подключим
к ней датчик температуры LM335 и фоторезистор по схеме, приведенной на
рис. 4.22, и отредактируем наш канал Склад, добавив поле Field 2 для датчика
температуры LM335 (рис. 4.23).
Скетч для отправки данных двух этих аналоговых датчиков в канал ThingSpeak
представлен в листинге 4.6.

Рис. 4.22. Схема подключения датчиков температуры и освещенности (фоторезистора)


кArduino
Arduino и аналоговые датчики 45

Рис. 4.23. Добавление нового поля (Field 2) в канал Скпад сервиса ThingSpeak

#include <SPI.h>
#include <Ethernet.h>

// уникальный МАС-адрес платы Arduino


byte rnac[] = { OxD4, Ох28, ОхВ2, OxFF, ОхАО, OxAl };

// IР-адрес, назначаемый Ethernet Shield:


byte ip[] = { 192, 168, О, 119};
// IР-адрес, dns сервера:
byte sdns[] = { 192, 168, 1, 1};
// адрес шлюза:
byte gateway[] = { 192, 168, О, 2'8 };
// маска:
byte SuЬnet[] = { 255, 255, 255, О};

// ThingSpeak Settings
char thingSpeakAddress[] = "api.thingspeak.com";
String writeAPIKey = "P8VDU06MDIMCЗМAМ";
// Интервал отправки данных на сервер - 16 сек
const int updateThingSpeakinterval = 16 * 1000;

// служебные переменные
long lastConnectionTime = О;
boolean lastConnected = false;
int failedCounter = О;
46 Глава 4

// Инициализация Arduino Ethernet client


EthernetClient client;

void setup()
{
// Запуск последовательного порта
Serial.begin(9600);
// Запуск Ethernet на Arduino ,
startEthernet();

void loop()

// Чтение данных из АО и Al
String analogValueO = String(analogRead(AO), DEC);
douЬle tempЗЗS=analogRead(Al)*S.0/1024*100-273.15;
String analogValuel = String(temp335);
// печать запроса в последовательный порт
if (client.availaЬle())
{
char с = client.read();
Serial.print(c);

// Разъединение с ThingSpeak
if (!client.connected() && lastConnected)

Serial.println("...disconnected");
Serial.println();
client.stop();

// отправка данных в канал ThingSpeak


if(!client.connected() && (millis() - lastConnectionTime >
updateThingSpeakinterval))
{
updateThingSpeak("fieldl="+analogValueO+"&field2="+analogValuel);
Serial.println(analogValueO);
Serial.println(analogValuel);

// При кол-ве неуспешных попыток >10 - перезапуск интернет-соединения


if (failedCounter > 10 ) {startEthernet();}
lastConnected = client.connected();

// отправка данных в канал ThingSpeak


void updateThingSpeak(String tsData)
Arduino и аналоговые датчики 47

if (client.connect(thingSpeakAddress, 80))
{
client.print("POST /update HTTP/1.1\n");
client.print("Host: api.thingspeak.com\n");
client.print("Connection: close\n");
client.print("X-THINGSPEAКAPIКEY: "+writeAPIKey+"\n");
client.print("Content-Type: application/x-www-form-urlencoded\n");
client.print("Content-Length: ");
client.print(tsData.length());
client.print("\n\n");

client.print(tsData);
lastConnectionTime = millis();
if (client.connected())
{
Serial.println("Connecting to ThingSpeak...");
Serial.println();

failedCounter = О;

else

failedCounter++;
Serial.println("Connection to ThingSpeak failed ("+String(failedCounter,
DEC)+")");
Serial.println();
}

else
{
// увеличение счетчика неуспешных попыток отправки данных
failedCounter++;
Serial.println("Connection to ThingSpeak Failed ("+String(failedCounter,
DEC)+")");
Serial.println();
lastConnectionTime millis();

// Перезапуск интернет-соединения
void startEthernet()

client.stop(); /

Serial.println("Connecting Arduino to network...");


Serial.println();
delay(lOOO);
Ethernet.begin(mac,ip,sdns,gateway,suЬnet);
48 Глава 4

delay(lOOO);
Serial.print("My IP address: ");
for (byte thisByte = О; thisByte < 4; thisByte++)
{
// печать IР-адреса
Serial.print(Ethernet.localIP() [thisByte], DEC);
Serial.print(".");

Serial.println();
delay(lOOO);

ЭЛЕКТРОННЫЙ АРХИВ
Скетч, соответствующий листингу 4.6, можно найти в файле arduino_scetches\_04\
_04_06.ino сопровождающего книгу электронного архива.

Загружаем этот скетч в плату Arduino и через некоторое время наблюдаем в окне
сервиса ThingSpeak графики, построенные на основе отправленных в наш канал
значений температуры и освещенности (рис. fl-.24).

Рис. 4.24. Отображение поступивших из плать1 Arduino данных


на графиках в канале сервиса ThingSpeak
Arduino и аналоговые датчики 49

4.4. Arduino
и инфракрасные датчики расстояния SHARP
Для измерения расстояния до объекта используются аналоговые оrпические датчи­
ки, основанные на методе триангуляции. Самые распространенные из них - это
инфракрасные (Infra-Red, IR) датчики расстояния с выходным аналоговым напря­
жением, производимые фирмой Sharp (рис. 4.25).
В датчиках Sharp установлен инфракрасный (IR) светодиод (LED), излучающий
через фокусирующую линзу узкий световой луч в инфракрасном диапазоне. Оrра­
женный от объекта луч направляется через другую линзу · на позиционно­
чувствительный фотоэлемент (Position-Sensitive Detector, PSD). Угол отражения
луча от объекта, а соот�етственно, и место на элементе PSD, куда попадает отра­
женный луч, зависят от расстояния до объекта (рис. 4.26). А проводимость элемен­
та PSD зависит от того, в какое место на нем попадает отраженный луч. Проводи­
мость эта преобразуется в напряжение, оцифровывая которое аналого-цифровым
преобразователем микро�онтроллера, можно вычислить расстояние до объекта.

U1

LED. PSD

Рис. 4.25. Инфракрасный датчик Рис. 4.26. Путь светового луча инфракрасного измерителя
расстояния Sharp расстояния при различных расстояниях
до объекта

Выход датчика расстояния Sharp 'Обратно пропорциональный - с увеличением


расстояния его значение медленно уменьшается (рис. 4.27). Датчики, в зависимости
от их типа, имеют границьJ измерения, в пределах которых их выход может быть
признан надежным. Измерение максимального реального расстояния ограничивают
два фактора: уменьшение интенсивности отраженного света и невозможность PSD
регистрировать незначительные изменения местоположения отраженного луча.
Так, при измерении расстояния до сильно удаленных объектов выход датчика оста-
50 Глава 4

ется приблизительно таким же, как и при измерении минимальных расстояний.


Дело в том, что минимально измеряемое датчиками Sharp расстояние ограничено
их особенностью, проявляющейся в резком падении выходного напряжения при
малых расстояних до объекта (в зависимости от типа датчика: от 4-х до 20 см). По
существу, это означает, что одному значению выходного напряжения соответству­
ют два расстояния: очень близкое и очень далекое. Для предотвращения возникно­
вения такой проблемы следует избегать слишком близкого приближения датчиков
к объекту.
В целом график зависимости напряжения от расстояния хоть и не является линей­
ным, однако в пределах допустимых расстояний график обратной величины вы-

Рис. 4.27. График зависимости напряжения U от расстояния d для датчиков Sharp

0.090

0,080

0.070

0,060

0,050


� 0,040

0,030

0,020

0,010

0,000
50 100 150 200 250 300 350 400 450 500
ADC
Рис. 4.28. График зависимости выходного напряжения датчика GP2YOA21YK от расстояния до объекта
Arduino и аналоговые датчики 51

ходного напряжения и расстояния к линейности приближается достаточно близко,


и с его помощью довольно просто получить формулу преобразования напряжения
в расстояние. Для нахождения такой формулы необходимо точки этого графика
ввести в какую-либо программу обработки табличных данных и из них создать но­
вый график, а на основе точек этого графика автоматически вычислить линию
тренда. На рис. 4.28 приведен график связи исправленной обратной величины вы­
ходного напряжения инфракрасного датчика GP2YOA21УК с расстоянием вместе
с линейной линией тренда. Выходное напряжение для упрощения формулы уже
переведено в 10-битное значение аналого-цифрового преобразователя с опорным
напряжение� +5 В.

4.4.1. Подключение датчиков Sharp к Arduino


Работать с сенсором Sharp очень просто - достаточно подключить к нему питание
и завести его вывод Vo на аналоговый вход Arduino (рис. 4.29). Значение получае­
мой функции analogRead представляет собой целое число в диапазоне от О до 1023.
Таким образом, чтобы узнать напряжение на выходе сенсора, необходимо значение
на аналоговом входе Arduino умножить на 0;0048828125 (5 В/ 1024). А расстояние
мы вычисляем по формуле:
distance = volts х 0,0001831 - 0,003097
Содержимое скетча, выдающего расстояние, измеряемое датчиком Sharp, в после­
довательный порт, представлено в листинге 4.7.

Рис. 4.29. Подключение к Arduino


инфракрасного датчика расстояния Sharp GP2YOA21YK
52 Глава 4

int IRpin = О; //аналоговый пин для подкпючения выхода Voсенсора

void setup() (
Serial.begin(9600); //старт последовательного порта
}

void loop() (
// SV/1024 = 0.0048828125
//считываем значение сенсора и переводим в напряжение
float volts = analogRead(IRpin)*0.0048828125;
//и в расстояние в см
float distance= 32*pow(volts,-1.10);
Serial.print(distance); // выдаем в порт значение

delay(lOO);
}

При чтении данных на каждой итерации цикла иногда для одного и того же рас­
стояния приходят разные значения сигнала. Дело в том, что датчик передает сигнал
на аналоговый порт с некоторой амплитудой, и когда итерация в момент считыва­
ния данных приходится на провал, измеренное значение оказывается отличным от
реального. В листинге 4.8 представлен код скетча, осуществляющего сглаживание
значений, получаемых с датчика расстояния.

const int IRpin = АО; //аналоговый пин для подюuочения выхода Vo


сенсора
int valuel; //для хранения аналогового значения

void setup()
Serial.begin(9600); // Запуск последовательного порта
}

void loop() (
Serial.println(irRead (), DEC);
//получаем сглаженное значение и переводим в напряжение
float volts = analogRead(IRpin)*0.0048828125;
//и в расстояние в см
float distance= 32*pow(volts,-1.10);
Serial.print(distance); // выдаем в порт значение
delay(200);
}
Arduino и аналоговые датчики 53

// Усреднение нескольких значений для сглаживания


int irRead() {
int averaging = О; // переменная для суммирования данных

// Получение 5 значений
for (int i= O; i<5; i++)
valuel = analogRead(IRpin);
averaging = averaging + valuel;
delay(55); // Ожидание 55 ms перед каждым чтением
}
valuel = averaging / 5; !/ усреднить значения
return(valuel);

ЭЛЕКТРОННЫЙ АРХИВ
Скетч, соответствующий листингу 4.8, можно найти в файле arduino_scetches\_04\
_04_08.ino соnровожд�ющеrо книгу электронного архива.

Точность измерений показаний датчика впрямую зависит от напряжения питания


АЦП - естественно, для лучшего результата необходимо питать АЦП от отдель­
ного источника калиброванного стабилизированного напряжения.

4.4.2. Подсчет количества посетителей магазина


Создадим пример отправки в сервис Twitter данных о количестве посетителей мага­
зина за определенный промежуток времени. Упростим задачу, предполагая, что
вход осуществляется через неширокую дверь, а для входа и выхода посетителей
служат разные двери.
На входе поставим инфракрасный датчик Sharp GP2YOA21YKOF с диапазоном из­
мерений 20-150 см таким образом, чтобы при проходе человека показания имели
значения от 1 О до 50 см, а при отсутствии людей в просвете двери - 80 см. Каждые
10 минут данные о посещаемости будут отправляться в Twitter.
Сначала напишем код обнаружения прохода человека через дверной проем (лис­
тинг 4.9).

const int IRpin = АО; // аналоговый пин для подключения выхода Vo сенсора
int valuel; // для хранения аналогового значения
unsigned long timevisitors; // время прохода
int count_visitors= O; // переменная подсчета посетителей

void setup() {
Serial.begin(9600); // Запуск последовательного порта
}
54 Глава 4

void loop() {
//получаем сглаженное значение и переводим в напряжение
valuel=irRead();
//Serial.println(valuel, DEC);
if(valuel>50) //фиксация прохода
{
tirnevisitors=millis();
while(irRead()>50) ;
if(rnillis()-tirnevisitors>ЗOO) //>.минимального времени прохода

e
S rial.println("passage ! ! ! ");
count_visitors=count_visitors+l; //увеличение счетчика
Serial.print("count_visitors=");
Serial.println(count_visitors);

delay(200);
}
//Усреднение нескольких значений для сглаживания
int irRead() {
int averaging = О; //переменная для суммирования данных

//Получение 5 значений
for (int i=O; i<5; i++)
valuel = analogRead(IRpin);
averaging = averaging + valuel;
delay(55)'; //Ожидание 55 rns перед каждым чтением
}
valuel = averaging /5; //усреднить значения
return(valuel);

ЭЛЕКТРОННЫЙ АРХИВ
Скетч, соответствующий листингу 4.9, можно найти в файле arduino_scetches\
_04\_04_09.ino сопровождающего книгу электронного архива.

Итак, датчик обнаруживает попадание человека в дверной проем. Теперь мы ожи­


даем завершения его прохода через проем, и если это время больше минимального
времени прохода (взмах руки, пролет постороннего предмета и пр. мы отсекаем), то
инкрементируем счетчик посетителей и выводим данные в последовательный порт
(рис. 4.30).
Нам осталось добавить отправку в Twitter полученных данных с периодичностью
в 1 О минут - этим мы в следующих разделах и займемся.
Arduino и аналоговые датчики 55

passage ! ! !
count_v1s1tors-2
passage ! ! !
coш1t_111s1 to rs=З
passage ! ! !
tount_v1s1tors-4
passage ! ! !
count_v1sitors=5

Рис. 4.30. Вывод в последовательный порт данных о проходе посетителей

4.4.3. Приложение ThingTweet сервиса ThingSpeak


Приложение ThingTweet сервиса ThingSpeak позволяет вашим устройствам послап,
сообщение в ваш профиль в Twitter, используя API ThingSpeak. При этом сервис
ThingSpeak действует для Twitter в качестве прокси-сервера - чтобы ваши устрой­
ства отправляли сообщения в Twitter без необходимости реализовывать открытую
аутентификацию (OAuth).
Что ж, авторизуемся в сервисе ThingSpeak и выберем пункт меню Apps - откроет­
ся окно выбора приложений (рис. 4.31 ).

Рис. 4.31. Окно выбора приложения в сервисе ThingSpeak


56 Глава 4

Рис. 4.32. Окно перехода в аккаунт Twitter

Выбираем здесь приложение ThingTweet и попадаем на страницу со ссылкой пере­


хода в ваш аккаунт Twitter (рис. 4.32).
В следующем окне (уже на странице Twitter) необходимо разрешить приложенmо
ThingTweet ДОС'I)'П к данным вашего аккаунта Twitter, нажав на кнопку Авт.оризо­
вать (рис. 4.33).

Рис. 4.33. Предоставление приложению ThingTweet доступа к вашему аккаунту Twitter

После того, как вы предоставите приложению ThingTweet дос'I)'П к данным вашего


аккаунта в Twitter (рис. 4.34), Twitter перенаправит вас обратно в ThingSpeak, где
приложение ThingTweet сгенерирует кточ API (рис. 4.35). Теперь, когда вы станете
посылать НТТР POST с ключом ThingTweet API (API Кеу), ваше сообщение будет
передано в Twitter.
Arduino и аналоговые датчики 57

Рис. 4.34. Доступ приложению к вашему аккаунту T�itter предоставлен

Рис. 4.35. Генерация АРl-ключей для перенаправления данных в Twitter

4.4.4. Отправка данных


о количестве посетителей в Twitter из Arduino
Продолжим создание примера из разд. 4.3.2. Нам сейчас необходимо добавить
в него оmравку с периодичностью в 1 О минут данных приложению ThingSpeak,
которое перенапр1;1вит их в Twitter. Для этого один раз в 10 минут мы станем от-,
правлять с нашей платы Arduino, состыкованной с Ethemet Shield, в сервис
ThingSpeak запрос НТТР POST следующего содержания:
POST /apps/thingtweet/1/statuses/update НТТР/1.1
Host: api.thingspeak.com
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: <length>api_key=<thingtweet_api_key>&status= <message>
58 Глава 4

где:
1:1 <length> - количество символов в сообщении;
1:1 '<thingtweet_:_api_key> - полученный АРI-ключ ЛJPPOTQ752M2AOEP (см.
рис. 4.35);
1:1 <message> - сообщение.
Итак, загружаем в нашу плату Arduino скетч, представленный в листинге 4.10.

#include <SPI.h>
#include <Ethernet.h>

byte mac[] = {ОхОО, ОхАА, ОхВВ, ОхСС, ОхОЕ, Ох02};


byte ip[J = { 192, 168, О, 97 };
byte sdns[J = { 192, 168, 1, 1 };
byte gateway[] = { 192, 168, О, 28 };
byte suЬnet[] = { 255, 255, 255, О };

const int IRpin = АО; // аналоговый пин для подключения выхода Vo сенсора
int valuel; // для хранения аналогового значения
unsigned long timevisitors;
int count_visitors=O;
unsigned long time10minute=500000;
-// ThingSpeak Settings
char thingSpeakAddress[] = "api.thingspeak.com";
String thingtweetAPIKey = "JUPPOTQ752M2AOEP";
// служебные переменные
long lastConnectionTime = О;
boolean lastConnected = false;
int failedCounter = О;
// инициализация Arduino Ethernet Client
EthernetClient client;

void setup()
{
Serial.begin(9600); // Запуск последовательного порта
startEthernet();
delay(lOOO);
}

void loop()
{
valuel=irRead();
if(value1>50)
{
timevisitors=millis();
Arduino и аналоговые датчики 59

while(irRead()>50) ;
if(millis()-tirnevisitors>ЗOO)

Serial.println("passage!!!");
count_visitors=count_visitors+l;
Serial.print("count_visitors=");
Serial.println(count_visitors);

delay(200);
if(millis()-timelQminute>бOOOOO)
{
String message="last 10.minute "+String(count_visitors)+" visitors";
updateTwitterStatus(message);
tirnelOminute=millis();

// печать ответа от сервера в монитор


while (client.availaЫe())
{
char с = client.read();
Serial.print(c);
}
// отключение от ThingSpeak
if (!client.connected() && lastConnected)

Serial.println("...disconnected");
Serial.println();
client.stop();
}
/! рестарт сетевого соединения
if (failedCounter > 3) {startEthernet();}
lastConnected = client.connected();

// Усреднение нескольких значений для сглаживания


int irRead()
{
int averaging = О; // переменная для суммирования данных

// Получение 5 значений
for (int i=O; i<5; i++)

valuel = analogRead(IRpin);
averaging = averaging + valuel;
delay(55); // Ожидание 55 ms перед каждым чтением
}
60 Глава 4

valuel averaging / 5; // усреднить значения


return(valuel);

void startEthernet()

client.stop();

Serial.println("Connecting Ardui�o to network...");


Serial.println();

delay(lOOO);
Ethernet.begin(mac, ip, sdns, gateway, suЬnet);
Serial.println(Ethernet.localIP());

// Connect to network amd obtain an IP address using DHCP


Ethernet.begin(mac, ip, sdns, gateway, suЬnet);
Serial.println(Ethernet.localIP());

delay(lOOO);

void updateTwitterStatus(String tsData)

if (client.connect(thingSpeakAddress, 80))

// данные НТТР POST D


tsData = "api_key="+thingtweetAPIKey+"&statµs="+tsData;

client.print("POST /apps/thingtweet/1/statuses/update HTTP/1.1\n");


client.print("Host: api.thingspeak.com\n");
client.print("Connection: close\n");
client.print("Content-Type: application/x-www-form-urlencoded\n");
client.print("Content-Length: ");
client.print(tsData.length());
client.print("\n\n");

client.print(tsData);
lastConnectionTime = millis();
if (client.connected())

Serial.println("Connecting to ThingSpeak ...");


Serial.println();
count_visitors= O;
failedCounter = О;
Arduino и аналоговые датчики 61

else

failedCounter++;
Serial.println("Connection to ThingSpeak failed ("+String(failedCounter,
DEC)+") ");
Serial.println();

else

failedCounter++;
Serial.println("Connection to ThingSpeak Failed ("+String(failedCounter,
DEC)+") ");
Serial.println();·
lastConnectionTime millis();

ЭЛЕКТРОННЫЙ АРХИВ
Скетч, соответствующий листинrу 4.10, можно найти в файле arduino_scetches\_04\
_04_10.ino сопровождающего книrу электронного архива.

iТfP1l 1 200 0К
s�rver· n9111x/l 7. 5
Date Wfd оа i\pr 201':, 05· -З9 10 00'
(ontent-Typ@, te'(t/htflll, char·эet:.иtf-8
Tran.:; f e- r-Encod1nq (hur1ked
rinrнч:t1or· ttoc;I'!
'1111} Accept-E'1(od1щJ
"1atus 200 ОК
l ·Fra!l\e-Opt1a11s. ALL<WALL
Ac:cf-:.�<l:!r1tro1 A1low-C'г1911,: -'
д,ce<;,;;-\щ1trol·.Allow-�!11tl1ods· CiET POST, РIЛ, ОРП\'1N$, DELE.TE, Р.АТСН
A-:r11st.-C1:.intr·ol �llaw-H,н1dtнs· ,.,r1gJ11, content typP /-Requested-Wit/1
дrc.es-:s-c.o,1trol-Ma1-Ь.qeo. lЭС.О \
ffaq. • с4са42 '8aOi>9,.J82\JdccS09oбf 7"949!> •
a..:.he Loлtrnl 81i1l з9е•О, pr);;ate. 11ust-гeYi1l1dd'te
t (Qok1P r eque'St_ 1ethod...f'OSТ; path .... /
X-Requ•st-Jd flafб3'12-7cl9·44b3 9'J07-a976444d2ЬOc

a�"ca9t.a1, 1
COU'1t 1/Иl tors-1
d�sэ°qe111
ount 'f'iHtor,n2
азsа9е; 1 •
ount 'f'l<;Jtors--з
Ql,<;jl\gfll!
cou11t нзitors.-.4
Pt1S'3d9e! i 1
(IJUГ!1_'H!iiton:;w5

Рис. 4.36. Отображение процесса подсчета посетителей


и отпр�вки данных в мониторе последовательного порта
62 Глава 4

Здесь при загрузке программы мы прежде всего устанавливаем настройки сети для
платы Ethernet Shield, после чего в основном цикле программы ведем по срабаты­
ванию инфракрасного датчика подсчет посетителей в переменной count_visitors и
по прошествии 10 минут (millis () -timelOminute>lO*бO*lOOO) отправляем серверу
api.thingspeak.com НТТР POST с сообщением "last 10 minute хх visitors". Затем
обнуляем счетчик посетителей count_visit?rs и опять ждем 10 минут для отправки
следующих данных. После трех неудачных попыток соединения с сервером пере­
подключаем Ethernet Shield к Сети.
На рис. 4.36 показано отображение в мониторе последовательного порта Arduino
IDE процесса подсчета посетителей и отправки данных в ThingSpeak, а на
рис. 4.37 -публикация этих сообщений в Twitter.

Рис. 4.37. Публикация отправляемых из Arduino данных в Twitter


ГЛАВА 5

Использование Arduino
в качестве контроллера
исполнительных устроиств
Концепция Internet of Things {Интернет вещей) предполагает не только удаленное
получение данных о состоянии объектов, но и удаленное управление исполнитель­
ными устройствами.

ИсnоЛНИТЕЛЬНЫЕ УСТРОЙСТВА
Исполнительные устройства - это элементы автоматики, создающие управляющее
воздействие на об1:�ект управления. Они изменяют положение или состояние регули­
рующего органа объекта управления таким образом, чтобы управляемый параметр
соответствовал заданному значению. Исполнительное устройство, или механизм
(actuator), преобразует электрическую энергию в механическую для воздействия на
управляемый процесс.
В качестве исполнительных механизмов могут быть задействованы световые и звуко­
вые устройства, электромагнитные клапаны, электродвигатели постоянного (DC) и пе­
ременного (АС) тока, сервоприводы, релейные системы и многое другое.

Плата Arduino, имеющая доступ к сети с помощью, например, платы Ethernet


Shield, вполне способна выступать в роли контроллера удаленных исполнительных
устройств. В этой главе мы рассмотрим использование платы Arduino для органи­
зации веб-сервера, получающего команды управления по НТТР и преобразующего
их в команды управления исполнительными устройствами, подключенными к циф­
ровым выводам Arduino.

5.1. Arduino и электромагнитное реле


5.1.1. Электромагнитное реле
Реле (от фр. relais)- электрическое или электронное устройство (ключ), предна­
значенное для замыкания и размыкания различных участков электрических цепей.
Изобретение реле стало великим открытием, перевернувшим мир. Произошло это
в далеком 1831 году. Позже, в 1937 году, Сэмюэл Морзе изобрел коммуникационное
реле и применил его в телеграфном аппарате. Сегодня электрические, пневматиче-
64 Глава 5

ские и механические реле используются весьма широкQ и выпускаются в огромном


количестве самых разнообразных их видов.
Наиболее распространенными являются электромагнитные реле - электромехани­
ческие устройства, замыкающие и/или размыкающие контакты внешней электриче­
ской цепи при подаче в обмотку реле управляющего электрического тока. Этот ток
порождает магнитное поле, вызывающее перемещение ферромагнитного якоря ре­
ле, механически связанного с электрическими контактами внешней электрической
цепи. Последующе� перемещение контактов коммутирует эту цепь.
К реле можно подключить лампочку, вентилятор, электромагнитный клапан для
управления поливом и программно управлять этими устройствами изменением
состояния на цифровых выводах Arduino.

5.1.2. Устройство и принцип работы


электромагнитного реле
Рассмотрим устройство электромагнитного реле на примере широко используемого
в связке с Arduino реле SRD-05VDC фирмы SONGLE (рис. 5.1). Это реле управля­
ется напряжением 5 вольт и способно коммутировать до 1О ампер постоянного тока
напряжением 30 В и переменного тока напряжением 250 В.

Рис. 5.1. Реле SRD-05VDC Рис. 5.2. Схема электромагнитного реле

Реле имеет две раздельных цепи, никак не связанные между собой: цепь управле­
ния, представленную контактами Al и А2, и управляемую цепь с контактами 1, 2
и 3 (рис. 5.2). Между контактами Al и А2 расположен металлический сердечник,
при протекании тока по обмотке которого к нему притягивается подвижный
якорь 2. Контакты 1 и 3 закреплены неподвижно. Стоит отметить, что якорь под­
пружинен, и пока мы не пропустим ток через обмотку сердечника, якорь будет
удерживаться прижатым к контакту 3. При подаче в обмотку сердечника управ­
ляющего тока, сердечник, как уже говорилось, превращается в электромагнит, и
якорь прижимается к контакту 1. При обесточивании обмотки сердечника пружина
снова возвращает якорь к контакту 3.
Использование Arduino в качестве контроллера исполнительных устройств 65

5.1.3. Подключение реле к Arduino


При подключении реле к Arduino возникает одна немаловажная проблема- кон­
такт микроконтроллера не может обеспечить мощность, необходимую для нор­
мальной работы катушки реле. Поэтому нам необходимо усилить управляющий
ток- что решается включением транзистора в схему управления реле. Удобнее
всего для усиления применять n-р-n-транзистор, включенный по схеме с общим
эмиттером (ОЭ), - как показано на рис. 5.3. При таком способе можно подключать
нагрузку с напряжением питания большим, чем питание микроконтроллера. Рези­
стор на базе транзистора- ограничительный. Его номинал может варьироваться
в широких пределах (1-10 кОм)- в любом случае транзистор будет работать
в режиме насыщения.
В этой схеме может быть применен любой n-р-n-транзистор, поскольку коэффици­
ент его усиления практически не имеет значения- достаточно подобрать транзи­
стор таким образом, чтобы он соответствоJlал нужному нам току коллектора и
напряженmо коллектор-эмРТГер (напряжение, которым запитывается нагрузка). На
основании личного опыта могу порекомендовать для этой схемы транзистор С945.

+12 V

1.5 kOm
Реле

кArduino
1 kOm NPN. (С945, С458
мnм аналогичные)

Рис. 5.3. Схема nодключения реле к Arduino (р--канальное управление)

Для включения реле, цодключенного по схеме с ОЭ, на вывод Arduino необходимо


подать 1, для выключения - О. Скетч, обеспечивающий работу схемы с реле, при­
веден в листинге 5.1.

int relayPin = 10; // подключение Arduino к выводу D10


void setup ( )
бб Глава 5

{
//
pinМode(relayPin, OUTPUT); // настроить вывод как выход (OUTPUT)
}

// the loop function runs over and over again forever


void loop()
{
digitalWrite(relayPin, НIGH); // включить реле
delay(5000);
digitalWrite(relayPin, LOW); // выключить реле
delay(5000);
}

Существуют и готовые модули для Arduino, со­


держащие сразу несколько реле с необходимой
обвязкой (рис. 5.4). Однако в таких модулях
обычно используется о-канальное управление
(рис. 5 .5), при котором реле включается пода­
чей на вывод Arduino низкого уровня.

Рис. 5.4. Модуль из 4 реле

sv

VТ1
signal --.-----1
LED2

sv
Рис. 5.5. Схема подключения реле к Arduino (n-канальное управление)
Использование Arduino в качестве контроллера исполнительных устройств 67

5.2. Arduino и твердотельное реле


Твердотельные реле (Solid State Relay, SSR) применяют в промышленном оборудо­
вании - там, где нужны большая надежность и малые габариты (рис. 5.6). Во всех
твердотельных оптоэлектронных реле коммутация цепей нагрузки осуществляется
бесконтактно - за счет управления встроенными полупроводниковыми элемента­
ми. Как правило, это тиристоры или симисторы (для коммутации переменного то­
ка) и транзисторы (для постоянного тока).
Такая конструкция дает твердотельным реле ряд преимуществ перед обычными
электромагнитными - ведь как и в обычных реле, в твердотельных существует
гальваническая развязка между напряжением катушки и напряжением на силовых
контактах. Только в эл�ктромеханических реле это достигается за счет разнесения
в пространстве, а в твердотельных - за счет оптической развязки, поскольку на
входе реле установлен оптрон.

Рис. 5.6. Твердотельное реле

Твердотельные реле потребляют и теряют гораздо меньше энергии при работе,


имеют меньшие габариты, высокое быстродействие, гораздо более длительный
срок службы и все это - абсолютно бесшумно! Но есть у них и серьезный недоста­
ток - высокая цена.
Для подключения твердотельного реле к Arduino минусовой контакт управляющей
сети подсоединяется к «земле», а плюсовой контакт - к цифровому выводу
Arduino. Выходного тока контакта Arduino для срабатывания твердотельного реле
вполне достаточно.
68 Глава 5

5.3. Arduino и диммер


5.3.1. Диммер
Перекточение нагрузки переменного тока с помощью Arduino довольно просто:
используется либо мехаJIИческое реле, либо твердотельное реле с оптически изоли­
рованным симистором. Становится сложнее, если необходимо, используя Arduino,
плавно уменьшать (диммировать) яркость лампы переменного тока: просто ограни­
чивать ток симистором не представляется возможным из-за необходимости в мощ­
ном симисторе и, как следствие, необходимости рассеивания большого количества
тепла. Неэффективно э'Го также и с точки зрения использования энергии. Правиль­
ный способ реализации этой задачи - применение регулирования фазы: симистор
полностью открыт, но только в одной части синусоидальной волны переменного
тока.
ПОЯСНЕНИЕ
Диммером называется устройство, обычно используемое для регулировки яркости
свечения ламп накаливания или светодиодов.

Можно, конечно, и просто открывать симистор с помощью Arduino на некоторое


количество микросекунд, но проблема здесь в том, что невозможно заранее пред­
сказать, в какой части синусоидальной волны симистор откроется и, следовательно,
какой уровень затемнения обеспечит. То есть, в синусоидальной волне нам необхо­
димо иметь точку отсчета. Найти ее способен детектор пересечения нуля - схема,
которая сообщает Arduino (или другому микроконтроллеру), когда синусоидальная
волна проходит через нуль и, следовательно, фиксирует на этой синусоидальной
волне определенную точку. Открытие симистора на некоторое количество микро­
секунд, начиная от пересечения нуля, как раз и даст нам предсказуемый уровень
затемнения.
Сделать такую схему несложно: пересечение нуля берется непосредственно из вы­
прямленного сетевого переменного тока, что и дает сигнал кащдый раз, когда волна
проходит через нуль. Поскольку синусоида сначала проходит двухфазное выпрям­
ление, сигнал пересечения нуля подается независимо от того, вверх или вниз идет
синусоидальная волна. Этот сигнал и может быть использован для вызова преры­
вания Arduino.
Схема диммера изображена на рис. 5. 7. Сетевое напряжение 220 В через два рези­
стора по 30 кОм идет к мостовому выпрямителю, :который вьщает двухфазный вы­
прямленный сигнал на оптрон 4N25. Светодиод в этом оптроне при низком уровне
работает на частоте 100 Гц, а на коллектор выходит сигнал высокого уровня с час­
тотой 100 Гц в соответствии с синусоидальной волной. Сигнал с 4N25 подается на
прерывающий вывод Arduino (или другого микропроцессора). Программа прерыва­
ний дает сигнал определенной длины на один из портов ввода/вывода. Сигнал
с порта ввода/вывода уходит в нашу схему и открывает светодиод в симисторном
оптроне МОС3021, который запускает оптотиристор.
Использование Arduino в качестве контроллера исполнительных устройств 69

Для затемнения реально пригодны только обычные лампы накаливания. Впрочем,


наша схема также будет работать и с галогенными лампами, но это сократит срок
их службы. А вот с компактными томинесцентными лампами (КЛЛ) схема рабо­
тать не будет - если только они не выполнены специально с возможностью дим­
мирования.

+Voc

В..IПIД дКl!ктора иум�


-2208

Наrруэка

диммировамия от МК
т,
МОС3(121

Рис. 5.7. Схема реализации диммера

5.3.2. Подключение дим�ера к Arduino


Подключим к плате Arduino диммер (рис. 5.8), приобретенный мной на сайте
http://carduino.ru. Схема соединений показана на рис. 5.9: выход детектора нуля
подсоединен к цифровому входу D2 платы Arduino - им мы воспользуемся для
вызова прерывания, а цифровой вход D4 служит в качестве входа диммирования
сигнала микроконтроллером.

Рис. 5.8. Диммер


70 Глава 5

Рис. 5.9. Подключение диммера к Arduino

5.3.3. Скетч управления диммером


Напишем теперь скетч управления яркостью подключенной к диммеру лампьr по­
средством отправки команд в последовательный порт Arduino. В листинге 5.2 при­
веден пример такого скетча, взятый у разработчика диммера, примененного
в разд. 5.3.2.
В скетче используется библиотека Cyberlib.h, которую можно найти на сайте
http://cyber-place.ru. Библиотека представляет набор макросов для низкоуровневой
работы с портами Arduino, что дает существенный прирост скорости записи/чтения
цифровых портов по сравнению со встроенными функциями Arduino, а также
уменьшает размер используемой памяти.

#include <CyberLib.h> // Библиотека от Cyber-Place.ru


volatile uint8 t tic, Dimmerl=255;
uint8_t data;

void setup()
(
D4_0ut; // настраиваем порт на выход
D4_Low; // установить на выходе низкий уровень сигнала
// настраиваем порт на вход для отслеживания прохождения сигнала
// через ноль
D2 In;
// настроить срабатывание прерывания interruptO на pin 2 на
// низкий уровень
attach!nterrupt(O, detect_up, LOW);
StartTirnerl(halfcycle, 40); // время для одного разряда ШИМ
StopTirnerl(); // остановить таймер
UART_Init(57600); // инициализация порта
)
Использование Arduino в качестве контроллера исполнительных устройств 71

// обработчики прерываний
void halfcycle() // прерывания таймера
{
tic++; // счетчик
if(Dimmerl < tic ) D4_High; // управляем выходом

void detect_up() // обработка внешнего прерывания: сработает по переднему


// фронту

tic= O; // обнулить счетчик


ResumeTimerl(); // запустить таймер
// перепрограммировать прерывание на другой обработчик
attachinterrupt(O, detect_down, HIGH);

void detect_down() // обработка внешнего прерывания: сработает по заднему


// фронту

StopTimerl(); // остановить таймер


D4_Low; // логический ноль на выходы
tic= O; // обнулить счетчик
// перепрограммировать прерывание на другой обработчик
attachinterrupt(O, detect_up, LOW);
}

void loop()

Start
if (UART_Read.Вyte(data))
{
if(data>47 && data<59)
{
data=225-(data-48)*25;
Dimmerl=data;

End

ЭЛЕКТРОННЫЙ АРХИВ
Скетч, соответствующий листинrу 5.2, можно найти в файле arduino_scetches\_05\
_05_02.ino, а библиотеку Cyberlib.h - в папке arduino_libraries\CyberLib сопровождаю­
щего книrу электронного архива.
72 Глава 5

5.4. Arduino и сервоприводы


Сервопривод (он же «серва», servo, рулевая машинка)- устройство, обеспечи­
вающее преобразование сигнала в строго соответствующее этому сигналу переме­
щение (как правило- поворот) исполнительного устройства. Представляет собой
прямоугольную коробку с мотором, схемой, редуктором и выходным валом, кото­
рый может поворачиваться на строго фиксированный угол, определяемый входным
сигналом. Как правило, этот угол имеет предел в 60 градусов, а иногда и в 180. Бы­
вают сервоприводы и постоянного вращения.
На вал сервопривода надевается рычаг в форме круга, крестовины или перекладин­
ки для передачи вращающего движения на рабочий орган. Выполнив поворот, вал
. остается в том же положении, пока не придет иной управляющий сигнал. Смысл
сервопривода заключен в гарантированном выполнении заданной команды- если
внешняя сила не позволит выполнить поворот на нужный угол, сервопривод все
равно закончит движение по окончании действия мешающего внешнего воздейст­
вия. Воспрепятствовать этому может лишь разрушение сервопривода, снятие
внешнего управляющего сигнала или пропадание напряжения питания.
Большинство сервоприводов внешне похожи друг на друга (рис. 5.10)- как пра­
вило, это прямоугольный корпус (внутри которого прячутся мотор, шестерни и
управляющая схема) с крепежными ушками по бокам и выходным валом, располо­
женным на верхней крышке. К валу, как уже отмечалось, крепится сменный (иду­
щий в комплекте) передаточный элемент в виде :диска с отверстиями по кругу, кре­
стовины с отверстиями на концах всех его перекладин или рычага, насаженного на
выходной вал либо своим центром, либо одним из концов. Чаще всего этот смен­
ный элемент белого цвета.
Иногда сервопривод имеет форму цилиндра- тогда его верхняя часть при работе
поворачивается вокруг своей оси. Некоторые сервоприводы вместо выходного вала
оснащаются шкивом (катушкой). На такой шкив наматывается (или с него сматы­
вается) тросик, с помощью которого управляют каким-то внешним приспособлени­
ем- например, парусом в моделях судов или яхт.

Рис. 5.1 О. Сервопривод


Использование Arduino в качестве контроллера исполнительных устройств 73

5.4.1. Принципы управления сервоприводами


Сервопривод - электрическое исполнительное устройство, подключаемое с по­
мощью трех проводов к устройству управляющему (контроллеру) и источнику пи­
тания.
По способу управления сервоприводы подразделяются на аналоговые и цифровые.
Аншюговые управляются аналоговым сигналом - буквально частотой, ,параметры
которой задаются с помощью широтно-импульсной модуляции (ШИМ). Цифровые
сервоприводы управляются цифровым сигналом, представляющим собой кодовые
команды, передаваемые по последовательному интерфейсу. Аналоговые сер13опри­
воды намного дешевле цифровых.
Управление сервоприводом осуществляется с помощью импульсов переменной
длительности, посьmаемых по сигнальному проводу, Параметрами этих импульсов
явля_,ются минимальная длительность, максимальная длительность и частота повто­
рения. Угол поворота сервопривода определяется длительностью посылаемого на
него импульса (это и называется широтно-импульсной модуляцией). Так, импульс
в 1,5 миллисекунды ( 1,5 мс) диктует мотору поворот на 90 градусов, что и соответ­
ствует его нейтральному положению. ОЖИдает сервопривод импульса каждые 20 мс.
Нейтральное положение сервопривода определяется как положение, в котором сер­
вопривод обладает одинаковым потенциалом вращения в обоих направлениях.
Важно отметить, что различные сервоприводы обладают разными ограничениями
в своем вращении, но они все имеют нейтральное положение, и это положение все­
гда находится в районе длительности импульса в 1',5 мс.
Когда сервопривод получает команду на перемещение, его управляющий орган пе­
ремещается в это положение и удерживает его. Если внешняя сила действует на
сервопривод, когда он удерживает заданное положение, сервопривод будет сопро­
тивляться перемещению из этого положения. Максимальная величина силы, кото­
рую может выдерживать сервопривод, характеризует вращающий момент серво­
привода. Однако сервопривод не навсегда сохраняет свое положение - импульсы
позиционирования должны повторяться, информируя сервопривод о необходимо­
сти сохранения положения.
Когда импульс, посьmаемый на сервопривод; оказывается короче 1,5 мс, сервопри­
вод поворачивает выходной вал на несколько градусов против часовой стрелки и
удерживает это положение. Если же приходит импульс шире, чем 1,5 мс, выходной
вал поворачивается на несколько градусов в противоположном направлении. Ми­
нимальная и максимальная ширина импульса, который управляет сервоприводом,
является свойством конкретного сервопривода. Различные марки, и даже различ­
ные сервоприводы одной марки, обладают различным минимумом и максимумом.
Как правило, ширина минимального импульса составляет примерно 1 мс, а ширина
максимального - 2 мс.
Различаются сервоприводы и габаритами. Существуют так называемые стандарт­
ные сервоприводы. Их габариты и вес в общем модельном ряду соответствуют не­
которым средним значениям. Они самые дешевые - в пределах 10-20 долларов.
74 Глава 5

При уменьшении или увеличении размеров сервопривода в сторону от стандартных


значений цена сервопривода возрастает пропорционально величине этих отклоне­
ний. Как и самые маленькие (микросервы), так и самые большие супермощные сер­
воприводы, - это самые дорогие устройства, цена их может доходить до сотен
долларов.
Сервоприводы различаются также материалом шестеренок. Самые дешевые серво­
приводы оснащены шестернями из пластмассы. Более дорогие - с одной выходной
шестерней из металла. Самые дорогие - с металлическими шестернями. Соответ­
ственно виду материала изменяется нагрузочная способность сервопривода. Самый
слабый сервопривод - с пластиковыми шестернями, самый мощный - с металли­
ческими.
Различия сервоприводов определяются и типом подшипников. Наиболее дешевые
не имеют подшипников вовсе: пластмассовые шестерни на пластмассовых валах
крутятся в отверстиях пластмассовых пластин, соединяющих шестерни в единый
редуктор, - это самые недолговечные сервоприводы. Более дорогие и, соответст­
венно, более долговечные сервоприводы имеют металлическую - обычно, латун­
ную - вrулку на выходном валу. Сервы подороже имеют на выходном валу, на
который приходится самая большая нагрузка, настоящий подшипник: шариковый
или роликовый. Шариковый - дешевле, роликовый - компактнее и легче. В еще
более дорогих сервоприводах на всех (металлических!) шестернях стоят подшип­
ники. Эго - самые долговечные и надежные устройства.
Сервоприводы различаются и по толщине. Она может сильно варьироваться при
одинаковых размерах по высоте и длине. Чем меньше толщина, тем выше цена, по­
скольку в узком корпусе труднее разместить шестерни.
Наконец, сервоприводы различаются по фирме-производителю. Наиболее раскру­
ченные бренды продают самые дорогие сервоприводы. При этом в их ассортименте
будут как дорогие, так и дешевые сервоприводы, но даже самый простенький и де­
шевый стандартный сервопривод крупного бренда стоит дороже, а иногда и суще­
ственно дороже, чем аналогичный сервопривод с наклейкой менее раскрученного
имени и, тем более, с именем никому не известной фирмы.
Очень мощные и очень дорогие сервоприводы могут иметь любую внешнюю фор­
му, определяемую назначением сервопривода. Так, сервоприводы для андроидов
(человекоподобных роботов) могут быть шаровидными или дисковидными. Но
обычно сервопривод - это все-таки черный параллелепипед с белой фитюлькой на
верхней крышке.
Сервоприводы применяются в основном в промышленности (стаJJки с числовым
программным управлением и т. п.). В них установлены, как правило, мощные дви­
гатели, в том числе и шаговые, что позволяет использовать их в автоматических
манипуляторах (в промышленных роботах).
Сервоприводы для моделирования имеют гораздо более худшие характеристики,
чем промышленные. Основным их параметром является момент сил, приложенных
· к «качалке» на заданном расстоянии от оси. Обычно такой момент измеряется
в кг/см. Самые слабые сервоприводы тянут 1-2 кг/см. Самые мощные непромыш-
Использование Arduino в качестве контроллера исполнительных устройств 75

лен;ные сервоприводы - более 100 кг/см. Момент этот также зависит от питающе­
го напряжения.
Немаловажным параметром является и скорость вращения вала сервопривода, как
правило, измеряемая в сек/60 °. Скорость сервопривода обычно важна, если он при­
меняется совместно с гироскопом или акселерометром (например, в моделях верто­
летов).

5.4.2. Управление сервоприводом


с помощью Arduino
Для управления сервоприводом в Arduino имеется .стан;дартная библиотека Servo.
Однако на платах, отличных от Mega, задействование этой библиотеки отключает
возможность использования функции analogWri te (} (ШИМ) на контактах 9 и 1О
(вне зависимости, подключены к этим контактам сервы или нет). В то же время на
платах Mega без влияния на функциональность ШИМ могут использоваться до
12 сервоприводов, но дальнейшее увеличение количества сервомашинок до 23-х
отключит ШИМ на контактах 11 и 12.

Рис. 5.11. Подключение сервопривода

Подключается сервопривод к плате Arduino тремя проводами (рис. 5.11): Vcc (пи­
тание), Gnd («земля») и S (сигнальный). Красный провод (питание) может быть
подключен на плате Arduino к выводу +5 В. Черный или коричневый про­
вод («земля») подключается к выводу Arduino GND, оранжевый, желтый или бещ,1й
сигнальный провод подключается к цифровому выводу контроллера Arduino. Сле­
дует отметить, что мощные сервоприводы могут создавать большую нагрузку -
в этом случае их следует запитывать отдельно (не через выход +5 В Arduino). То же
самое верно и для случая подключения сразу нескольких сервоприводов.
Итак, подключаем сервопривод к Arduino по схеме, показанной на рис. 5.12, и за­
гружаем скетч, представленный в листинге 5 .3.
76 Глава 5

#include <Servo.h> // подключение библиотеки Servo


Servo myservo; // создание экземпляра объекта Servo
int pos = О; // переменная для хранения текущей позиции сервопривода

void setup()
{
myservo.attach(9); // подключает переменную servo к выходу 9

void loop()

for(pos = О; pos <= 180; pos += 1) // вращение в одну сторону с шагом 1


{
myservo.write(pos); // переместить в новую позицию
delay(l5); // �ауза 15 ms для перемещения сервы
}
for(pos = 180; pos>=O; pos-=l) // вращение в одну сторону с шагом 1
{
myservo.write(pos
delay(l5);

Рис. 5.12. Схема подключения сервопривода


Использование Arduino в качестве контроллера исполнительных устройств 77

5.5. Arduino и библиотека TinyWebServer


Библиотека ТinyWebServer является небольшой и расширяемой реализацией НТТР­
сервера, предназначенного для работы в ограниченном количестве пространства
памяти плат Arduino. Дriя подключения к сети он использует плату Ethernet
Shield/W5100, состыкованную с платой Arduino в обычном порядке.
С помощью бйблиотеки ТinyWebServer логика работы контроллера теперь может
быть полностью отделена от отображения страниц. При этом Ardu'ino не обязатель­
но форм1:1ровать страницы полностью - веб-страницы, изображения и другой кон­
тент может быть скопирован пользователем вручную на SD-карту или загружен
через сервер НТТР.
Файлы библиотеки TinyWebServer можно скачать со страницы: https://github.com/
ovidiucpffinyWebServer. Работа библиотеки ТinyWebServer зависит от внешней
библиотеки Flash версии 5.0, файлы которой можно скачать со страницы:
http://arduiniana.org/libraries/flash/. При использовании новых версий Arduino
IDE (новее, чем 1.5) необходимо изменить файл Flash.h, включив в него сразу после ·
#include <AVR / pgmspace.h> следующие строки:
#if ARDUINO >= 150
typedef char prog_cliar _attribute_((_progmem_));
#endif
Для использования библиотеки TinyWebServer необходимо в скетч включить сле­
дующие строки:
#include <Ethernet.h>
#include <Flash.h>
#include <SD.h>
#include <TinyWebServer.h>
Функционал библиотеки TinyWebServer осуществляет класс TinyWebServer. Метод
конструктора принимает два аргумента: первый - список обработчиков, когда
клиентом НТТР запрашиnаются определенные адреса, второй - список имен заго­
ловков НТТР, для которых необходима реализация обработчиков. В листинге 5.4
представлен пример реализации библиотеки ТinyWebServer с одним обработчиком.

// МАС-адрес сетевой платы


static uint8_t mac[] = { OxDE, OxAD, ОхВЕ, OxEF, OxFE, OxED };
// обработчик для страницы "/" (вывод на страницу "Hello World!")
boolean index_handler(TinyWebServer& web_server)

web_server.send_error_code(200);
web server << F("<html><body><hl>Hello World!</hl></body></html>\n");
return true;
78 Глава 5
// список заголовков и привязанных к ним обработчиков
TinyWebServer::PathHandler handlers[] = (
// Register the index_handler for GET requests on /
("/", TinyWebServer::GET, &index_handler },
(NULL}, // The array has to Ье NULL terminated this way
};
// создать веб-сервер
TinyWebServer web = TinyWebServer(handlers, NULL);

void setup()
{
Serial.begin(115200);
EthernetDHCP.Ьegin(mac);
web.begin();
}
void loop()
(
web.process();

Здесь в цикле loop()для отслеживания НТТР-запросов мы должны вызвать метод


веб-сервера process(). При отсутствии запросов этот метод осуществляет возврат, а
при поступлении запроса он блокирует выполнение цикла, пока запрос не будет
обработан.

5.5.1. Использование файлов с SD-карты


для формирования веб-страниц
На плате Ethernet Shield/W5100 размещен слот для флеш-карты формата MicroSD,
на которую пользователем могут быть записаны те или иные файлы. TinyWebServer
позволяет задействовать эти файлы для формирования веб-страниц, что избавляет
нас от необходимости использовать для этого память Arduino.
В листинге 5.5 представлен код обработчика для вьщачи -веб-сервером страницы,
содержимое которой находится в файле на SD-карте.

boolean file_handler(TinyWebServer& web_server) (


ctlar* filename = TinyWebServer::get_file_from_path(web_serv�r.get_path());
if ( ! filename) (
web_server.send_error_code(404);
web_server << "Could not parse URL";
else (
TinyWebServer::MimeType mime_type
= TinyWebServer::get_mime_type_from_filename(filename);
Использование Arduino в качестве контроллера исполнительных устройств 79

web_server.send_error_code(mime_type, 200);
if (file.open(filename, O_READ))
web_server.send_file(file);
file.close();
else {
web server << "Could not find file: " << filename'<< "\n";

free(filename);

return true;

Список имен заголовков для этого обработчика следующий:


TinyWebServer::PathHandler handlers [] = {
{"/" "*", TinyWebServer::GET� &file handler },
{NULL},

Запись "/" "*" указывает, что обработчик вызывается для любого адреса (URL),
следующего после "/". При запросе /contentl на веб-страницу будет выводиться
содержимое файла content1 либо сообщение Could воt find file:contentl при его от­
сутствии на SD-карте.

5.5.2. Включение/выключение реле с веб-страницы


Напишем скетч для удаленного включения/выключения нескольких реле, подсо­
единенных к плате Arduino, состыкованной с Ethernet Shield. Для этого создадим на
Arduino веб-сервер-, используя библиотеку TinyWebServer.
Прежде всего подключим к цифровым выводам Arduino три реле. Контакты микро­
контроллера не могут обеспечить мощность, необходимую для нормальной работы
катушек реле. Поэтому нужно усилить ток - добавить n-р-n-транзистор, включен­
ный по схеме с ОЭ, согласно схеме, приведенной на рис. 5.3. В этом случае вьщача
высокого уровня на контакт Arduino приведет к включению реле, подача низкого
уровня - к его выключению.
Для того чтобы наш проект выглядел современно, мы воспользуемся технологией
AJAX, которая позволяет отправлять данные на сервер и получать данные с сервера
без перезагрузки страницы.

ТЕХНОЛОГИЯ AJAX
В нормальных веб-приложениях пользователи заполняют поля форм и нажимают
кнопку Submit (Подтвердить). Поспе этого форма передается на сервер полностью,
сервер обрабатывает сценарий (обычно РНР или Java, возможно, CGl-npoцecc или
что-то в этом роде), а r,отом передает назад всю новую страницу. Эта страница может
быть НТМL-страницей с новой формой с некоторыми заполненными данными, либо
страницей подтверждения, либо страницей с какими-то выбранными вариантами, за­
висящими от введенных в оригинальную форму данных. Естественно, пока сценарий
или программа на сервере не обработается и не возвратится новая форма, пользова-
80 Глава 5

тели должны ждать. Их экраны очистятся и будут перерисовываться по мере поступ­


ления новых данных от сервера. Вот где проявляется низкая интерактивность - поль­
зователи не получают немедленной обратной реакции и определенно чувствуют себя
не так, как при работе с настольными приложениям�.
Технология AJAX по существу помещает технологию JavaScript и объект
XMLHttpRequest между вашей веб-формой и сервером. Когда пользователи заполня­
ют формы, данные передаются в некий JavaScript-кoд, а не прямо на сервер. Вместо
этого JavaScript-кoд собирает данные формы и сам передает запрос на сервер. Пока
зто происходит, форма на экране пользователя не мелькает, не мигает, не исчезает и
не блокируется. Другими словами, код JavaScript передает запрос в фоновом режи­
ме - пользователь даже не замечает, что происходит запрос на сервер. Более того,
запрос передается асинхронно, а зто означает, что ваш JavaScript-кoд (и пользова­
тель) не ожидает ответа сервера. То есть, пользователи могут продолжать вводить
данные, прокручивать страницу и работать с приложением.
Когда же сервер передает данные обратно в ваш JavaScript-кoд (все еще находящий­
ся в вашей веб-форме), тот решает, что делать с данными. Он может обновить поля
формы «на лету», придавая свойство немедленности вашему приложению, - пользо­
ватели получают новые данные без подтверждения или обновления их форм.
JavaScript-кoд может даже получить данные, выполнить какие-либо вычисления и пе­
редать еще один запрос, и все зто без вмешательства пользователя! В этом заключа­
ется мощь XMLHttpRequest - он может общаться с сервером по своему желанию, а
пользователь даже не догадывается о том, что происходит на самом деле. В резуль­
тате мы получаем в веб-форме динамичность, чувствительность и высокую интерак­
тивность настольного приложения вместе со всеми возможностями Интернета.

5.5.3. Веб-страница для управления реле


Создадим НТМL-страницу для удаленного изменения стаrуса трех реле с исполь­
зованием технологии AJAX. Веб-страница представляет собой форму, на которой
расположены три элемента radio, - каждый такой элемент показывает стаrус од­
ного из реле: ON - включено, OFF - выключено (рис. 5.13).
Добавим в форму еще один элемент input, в который станем передавать ответ сер­
вера на аjах-запрос веб-страницы на изменения стаrуса реле. НТМL-код формы
представлен в листинге 5.6.

Set Arduino Relay Status


RELAY1
OFF<'if'i i#f;;•ON
RELAY2
OFF,'iif #;,ON
RELAYЗ
OFF(� 1�0N

Рис. 5.13. Веб-страница для удаленного включения/выключения реле, подключенных к Arduino


Использование Arduino в качестве контроллера исполнительных устройств 81

<form name=fonnl action='return false;'>


RELAYl<br>
OFF<input type=radio name=relayl value=O checked
onclick="SetArduinoOutput(l,O);">
<input type=radio name=relayl value=l onclick="SetArduinoOutput(l,l);">ON
<br>RELAY2<br>
OFF<input type=radio name=relay2 value=O checked
onclick="SetArduinoOutput(2,0);">
<input type=radio name=relay2 value=l onclick="SetArduinoOutput(2,l);">ON
<br>RELAYЗ<br>
OFF<input type=radio name�relayЗ value=O checked
onclick="SetArduinoOutp1;1t(З,O);">
<input type=radio name=relayЗ value=l onclick="SetArduinoOutput(З,l);">ON
<br><br><br><br>
<input type=text name="resl" id="resl" value="result"/>
</fonn>

При изменении значение элемента radio (с on на off или наоборот) вызывается


js-функция setArduinooutput(), которая создает объект XМLHttpRequest для от­
правки данных на сервер и получения ответа с сервера с использованием AJAX.
В листинге 5.7 представлен кодjs-функции SetArduinooutput().

<script>
function SetArduinoOutput(pin,valu�)

nocache = "&nocache=" + Math.random() * 1000000;


var request = new XМLHttpRequest();
request.onreadystatechange = function()
{
if (this.readyState == 4)
{
if (this.status == 200)
{
if (this.responseXМL ! = null)
{
// разбор ХМL ответа сервера
document.getElementByid("res 1").value
this.responseXМL.getElementsByТagName('message') [О].
childNodes(O].nodeValue;
}
82 Глава 5
request.open("GET", "setrelay"+"&pin="+pin.toString()+"&value="
+value.toString()+nocache, true);
request.send(null);

</script>

Код запр ашиваемой страницы должен находиться в файле RELAYS, расположенном


на SD-карте. Эта страница подгружается при URL-зaпpoce /relays к TinyWebServer
на Arduino. Вот список имен заголовков НТТР:
TinyWebServer::PathНandler handlers[] = (
("/", TinyWebServer::GET, &index_handler },
("/setrelay" "*", TinyWebServer::GET, &set_relays },
("/" "*", TinyWebServer::GET, &file handler },
(NULL},
};

При обр ащении по URL http: //<ipArduino>/relays вызывается обработчик file_


handler(), котор ый выведет на страницу содер жимое файла RELAYS с SD-карты.
Код обр аботчика представлен в листинге 5.8.

boolean file_handler(TinyWebServer& web_server)


(
if( ! has_filesystem)
(
web server.send error_code(500);
web server << F("Internal Server Error");
return true;

char* filename TinyWebServer::get_file_from_path(web_server.get_path());


if( ! filename)

web server.send_error_code(400);
web server << F("Bad Requestl");
return true;

send file_name(web_server, filename);


free(filename);
return true;

void send_file_name(TinyWebServer& web_server, const char* filename)

TinyWebServer::MimeType mime_type
TinyWebServer::get_mime_type_from_filename(filename);
Использование Arduino в качестве контроллера исполнительных устройств 83

if (file.open(&root, filename, O_READ))


{
web_server.send_error_code(200);
web_server.send_content_type(mime_type);
web_server.end_headers();

Serial << F("Read file "); Serial.println(filename);


web_server.send_file(file);
file.close();

else

web_server.send_error_code(404);
web_server.send_cont.ent_type("text/plain");
web_server.end_headers();

Serial << F("Could not find file: "); Serial.println(filename);


web server << F("404 - ERROR ") << filenarite << "\n";

Данные на сервер страница отправляет методом GET по URL http://<ipArduino>/


setrelay. При посrуплении на TinyWebServer этого запроса вызывается обработчик
set_relays(), который должен обработать полученные методом GET данные, выде­
лить номер реле и значение для него, включить (или выключить) реле и оmравить
серверу в формате ХМL ответ следующего содержания:
<xrnl version = "1.0" ?>"
<inputs>
<message>relay Х on(off)
</message>
</inputs>
Содержимое обработчика set_relays() представлено в листинге 5.9.

// включение/вЫЮIЮчение реле по запросу


boolean set_relays(TinyWebServer& web_server)

char* filename = TinyWebServer::get_file_from_path(web_server.get_path());


String strl(filename);
Serial.println(strl);
// установка реле
digitalWrite(pinцelays[convertl(strl,13,14)-1],convertl(strl,21,22));

if( ! filename)
{
web server.send_error_code(400);
84 Глава 5

web server << F("Bad Requestl");


return true;

web server.send_error_code(200);
web_server.send_content_type("text/xml");
web_server.end_headers();
web_server << F(·"<?xml version = \"1.0\" ?>");
web_server << F("<inputs>");
web_server << F("<rnessage>relay ")<<strl.suЬstring(lЗ,H);
if(convertl(strl,21,22)>0)
web server << F(" on");
else
web server << F(" off");
web server << F("</mess�ge>");
web server << F("</inputs>");
return true;

// выделение нужных значений из GЕТ-данных


int convertl(String strstr,int startl,int endl)

char *strint=new char[2];


String strЗ;
strЗ=strstr.suЬstring(startl,endl);strЗ.toCharArray(strint,2);
return atoi(strint);

При этом индексная страница на сервере (рис. 5.14) представляет собой меню для
выбора страницы включения/выключения реле Set relays (/relays) или управления
сервоприводами Set servos (/servos)- эту опцию мы рассмотрим в следующем
разделе. При поступлении запроса индексной страницы вызывается обработчик
index_handler() (листинг 5.10).

// главная страница
boolean index_handler(TinyWebServer& web_server)

web_server.send_error_code(200);
web_server.send_content_type("text/html");
web_server.end_headers();
web server << F("<html><body><hl>Menu</hl>");
web server << F("<a href='/relays'>Set relays</a><br>");
web server << F("<Ьr>");
web server << F("<a href='/servos'>Set servos</a><br>");
web server << F("<br>");
return true;
Использование Arduino в качестве контроллера исполнительных устройств 85

Menu

Set servos

Рис. 5.14. Индексная страница нашего TinyWebServer

ЭЛЕКТРОННЫЙ АРХИВ
Скетч, соответствующий 11истингам, описывающим управление реле из веб-страницы,
созданной с использованием технологии AJAX, можно найти в файле arduino_
scetches\_05\_05_1214.ino сопровождающего книгу электронного архива.

5.5.4. Веб-страница для управления сервоприводом


Добавим на наш TinyWebServer страницу управления сервоприводом (рис. 5.15).
С помощью НТМL-элемента range (ползунок) мы станем задавать угол поворота
сервопривода, а в элем:ент input - передавать ответ сервера на аjах-запрос веб­
страницы по изменению угла поворота сервопривода. НТМL-код такой формы
представлен в листинге 5.11.

Set Arduino Relay Status


RELAVl

Рис. 5.15. Веб-страница для удаленного управления сервоприводами, подключенными к Arduino

<fonn narne=fonnl action='return false;'>


Servol<input type=range narne=servol min= O max=l80 step=l value= 90
onchange="SetArduinoOutput(l,this.value);">
<br>
86 Глава 5

Servo2<input type= range name=servo2 min=O max= 180 step=l value= 90


onchange="SetArduinoOutput(2,this.value);">
<br><br><br><br>
<input type=text name=resl id=resl value="result">
</fo:r:m>

При щелчке мышью по линии движения ползунка (элемент range) или по его от­
пусканию по завершении передвижения вызывается js-функция setArduinoOUtput(),
которая создает объект XМLHttpRequest для отправки данных на сервер и получе­
ния ответа с сервера с использованием AJAX. В листинге 5.12 представлен код
js-функции SetArduinoOutput ().

<script>
function SetArduinoOutput(pin,value)

var valuel="";
if(value<lO)
valuel=valuel+"OO"+value;
else if(value<lOO)
valuel=valuel+"O"+value;
else
valuel=valuel+value;
nocache = "&nocache=" + Math.random () * lОООООСТ;
var request = new XМLНttpRequest();
request.onreadystatechange = function()
{
if (this.readyState 4)
{
if (this.status 200)
{
if (this.responseXМL ! = null)
{
// разбор ХМL ответа Gервера
document.getElementByid("resl").value
this.responseXМL.getElementsByТagName('message')
[OJ.childNodes[OJ .nodeValue;
}

request.open( "GET",
"setservo"+"&pin="+pin+"&value="+valuel+nocache, tru�);
request.send(null);

</script>

Код запрашиваемой страницы находится в файле SERVOS, расположенном на


SD-карте. Эта страница подгружается при URL запросе /servos к TinyWebServer на
Использование Arduino в качестве контроллера исполнительных устройств 87

Arduino. Добавляем этот запрос и обработчик запроса к списку имен заголовков


НТТР:
TinyWebServer::PathHandler handlers[] = {
{"/", TinyWebServer::GET, &index_handler },
{"/setservo" "*", TinyWebServer::GET, &set_servos },
{"/setrelay" "*", TinyWebServer::GET, &set_relays },
{"/" "*", TinyWebServer::GET, &file handler },
{NULL},
};
При обращении по URL http:/ /<ipArduino>/servos вызывается обработчик
file_handler( J, который выведет на страницу содержимое файла SERVOS с SD­
карты. С кодом этого обработчика мы уже знакомы (см. листинг 5.8).
Данные на сервер страница отправляет методом GET по URL http://<ipArduino>/
setservo. При поступлении на TiayWebServer этого запроса вызывается обработчик
set_servos(), который должен обработать полученные методом GET данные, вьще­
лить номер сервопривода и угол поворота, вьщать команду поворота для сервопри­
вода и отправить серверу в формате ХМL ответ следующего содержания:
<xml version = "1.0" ?>"
<inputs>
<rnessage>servo Х set ХХХ
</message>
</inputs>
Далее для управления сервоприводом используем библиотеку Arduino Servo:
1. Подкточаем библиотеку Servo:
#include <Servo.h>
2. Создаем экземпляры объектов:
Servo myservol;
Servo myservo2;
3. Подкточаем переменные myservol и myservo2 к выводам Arduino:
myservol.attach(2);
myservo2.attach(3);
4. Поворачиваем сервоприводы на угол, равный значению ползунка на веб-стра­
нице:
myservol.write(convertl(strl,21,24,4));
myservo2.write(convertl(strl,21,24,4));
Содержимое обработчика set_servos() представлено в листинге 5.13.

// управление поворотом сервопривода по запросу


boolean set_servos(TinyWebServer& web_server)
88 Глава 5

char* filename = TinyWebServer::get_file_from_path(web_server.get_path());


String strl(filename);
Serial.println(strl);
if( ! filename)

web server.send_error_code(400);
web server << F("Bad Requestl");
return true;

if(convertl(strl,13,14,2)==1)
myservol.write(convertl(strl,21,24,4)); // поворот серво 1
else if(convertl(strl,13,14,2)==2)
myservo2.write(convertl(strl,21,24,4)); // поворот серво 2
else

// ответ серверу
web server.send error_code(200);
web_server.send_content_type("text/xml");
web_server.end_headers();
web server << F("<?xml version = \"1.0\" ?>");
web server << F("<inputs>");
web server << F("<message>servo ")<<strl.suЬstring(lЗ,14);
web server << F(" set ")<<convertl(strl,21,24,4);
web server << F("</message>");
web server << F("</inputs>");
return true;

// выделение нужных значений из GЕТ-данных


int convertl(String strstr,int startl,int endl, int kol)

char *strint=new char[kol];


String strЗ;
strЗ=strstr.suЬstring(startl,endl);strЗ.toCharArray(strint,kol);
return atoi(strint);

ЭЛЕКТРОННЫЙ АРХИВ
Скетч, соответствующий листингам, описывающим управление сервоприводами из
веб-страницы, созданной с использованием технологии AJAX, можно найти в файле
arduino_scetches\_05\_05_1517.ino сопровождающего книгу электронного архива.

В следующих главах мы еще вернемся к использованию библиотеки TinyWebServer


для удаленного доступа к показаниям датчиков Arduino. Вернемся и к удаленному
управлению исполнительными устройствами, подключенными к Arduino, но уже
с использованием платы GPS/GPRS Shield.
ГЛАВА 6

Arduino и устройства 1 2 С

В главе 4 мы рассмотрели р�боту плат Arduino с аналоговыми датчиками, но может


ли Arduino общаться с более сложными устройствами? Разумеется! -Arduino спо­
собен реализовать имеющиеся возможности, взаимодействуя через различные ин-'
терфейсы со множеством внешних компонентов. Чтобы упростить обмен данными
между микроконтроллером и огромным количеством всевозможных модулей, соз­
дан ряд интегральных схем (ИС), реализующих стандартизированные цифровые
протоколы связи. В этой главе мы рассмотрим работу Arduino с устройствами I2C.

6.1. Обзор протокола 1 2 С


Разработанная фирмой Philips шина I2C (Inter-Integrated Circuit)- это двунаправ­
ленная асинхронная шина с последовательной передачей данных и возможностью
адресации до 128 устройств. Физически шина 12С содержит две сигнальные линии,
одна из которых (SCL) предназначена для передачи тактового сигнала, а вторая
(SDA)- для обмена данными. Для управления линиями применяются выходные
каскады с открытым коллектором, поэтому линии шины должны быть подтянуты
к источнику питания +5 В через резисторы сопротивлением 1-10 кОм (в зависимо­
сти от физической длины линий и скорости передачи данных). Длина соединитель­
ных линий в стандартном режиме мьжет достигать двух метров, скорость переда"'
чи- до 100 Кбит/с. Суммарная емкость линий не должна превышать 400 пФ,
входная .емкость на каждую И� должна находиться в пределах 5-1 О пФ.
Отличительные особенности протокола:
1:1 двунаправленный обмен по обеим линиям;
1:1 высокая скорость обмена-до 100 Кбит/с и выше;
1:1 возможность адресации до 128 устройств;
1:1 простота программной реализации Маstеr-абонента;
1:1 временная независимость процесса передачи.
Все абоненты шины делятся на два класса: Master и Slave. Устройство Master гене­
рирует тактовый сигнал (SCL) и, как следствие, является ведущим. Оно может
90 Глава б

самостоятельно выходить на шину и адресовать любое Slаvе-устройство с целью


передачи или приема информации. Все Slаvе-устройства «слушают» шину на пред­
мет обнаружения собственного адреса и, распознав его, выполняют предписывае­
мую операцию. Кроме того, возможен так называемый Multi Master - режим,
когда на шине установлено несколько Маstеr-абонентов, которые либо совместно
разделяют общие Slаvе-устройства, либо попеременно являются то Маstеr-уст­
ройствами - когда сами инициируют обмен информацией, то Slаvе-устрой­
ствами - когда находятся в режиме ожидания обращения от другого Маstеr­
устройства. Режим Multi Master требует арбитража и распознавания конфликтов.
Естественно, он сложнее в реализации (имеется в виду программная реализация)
и, как следствие, реже используется в реальных изделиях.
В начальный момент времени - в режиме ожидания - обе линии, SCL и SDA, на­
ходятся в состоянии логической единицы (транзистор выходного каскада с ОК за­
крыт). В режиме передачи (рис. 6.1) бит данных SDA стробируется положительным
импульсом SCL. Смена информации на линии SDA производится при нулевом
состоянии линии SCL. Slаvе-устройство может «придерживать» линию SCL в нуле­
вом состоянии - например, на время обработки очередного принятого байта, при
этом Маstеr-устройство обязано дождаться освобождения линии SCL, прежде чем
продолжить передачу информации.
2
Д11Я синхронизации пакетов шины I C различают два условия: Start и Stop, ограни­
чивающих начало и конец информационного пакета (рис. 6.2). Д11Я кодирования

SCL
______,
- -LГv-- v- - ,_i ____
х_ _ _ _ _ л _____
' ' '

SDA --·--------_______ """(t


,г--(�:: �
1
iXL_______j:_x___________________
; ;
1

Данные фиксированы: : Данные фиксированы


Смена
данных

Рис. 6.1. Диаграмма процесса передачи данных по ши�е 1 2С

---------------------j---1\ г-��, [' г--\ 1--1··------------


1 1
1 1 1 1

SCL

! 1-----t�----\ r--------\ ! !
1 1 ,,_ __...,_/ \._,__, _
J
\... ...... ____} : 1
1 1 1 1 '

----------------------t-\
SDA
Ч----
1
1 1
----- _j ___j}
1
1
1
1 1 1 1
1 1 1 1

Старт -условие Стоп-условие

Рис. 6.2. Диаграмма START/STOP усnовия шины 1 2С


Arduino и устройства /2 С 91

этих условий используется изменение состояния линии SCL, что недопустимо при
передаче данных. Start-ycлoвиe образуется при отрицательном перепаде линии
SDA, когда линия SCL находится в единичном состоянии, и, наоборот, Stор­
условие образуется при положительном перепаде линии SDA при единичном со­
стоянии линии SCL.
Передача данных начинаеп;я по первому положительному импульсу на линии SCL
(рис. 6.3), которым стробируется старший бит первого информационного байта.
Каждый информационный байт (8 битов) содержит 9 тактовых периодов линии
SCL. В девятом такте устройство-получатель выдает подтверждение (АСК) - от­
рицательный импульс, свидетельствующий о «взаимопонимании» передатчика и
получателя. Сразу отметим, что любой абонент шины - как Master, так и Slave -
может в разные моменты времени быть как передатчиком, так и получателем,
и в соответствии с режимом обязан либо принимать, либо выдавать сигнал АСК,
отсутствие которого интерпретируется как ошибка.

Старт-условие АСК
Подтверждение

Рис. 6.3. Диаграмма подтверждения приема байта на шине 1 2С

Временная диаграмма сигналов SCL и SDA шины 12 С показана на рис. 6.4 (здесь S
обозначает Start-ycлoвиe, а Р - Stор-условие). Значения временньrх характеристик
шины приведены в табл. 6.1.

{-- Ji--
fнDc&TA t,

SCL -- -- --

ш: · t ! /_-·----·- . к------ --
1

::: , tuж
1 1 1 1

ti
1
SDA
.. 1 ,,........._,,. _.........,,...................... ..... ...,..,,........,,.._,............,_,......
1 1� ......,__

: : : : tвur fно:о,,т tsu:o,,т


,р, ,51
,__ .J ·---·

Рис. 6.4. Временная диаграмма работы шины �С


92 Глава б

2
Таблица 6.1. Значения временных характеристик шины / С

Параметр Обозначение min max Единица


Частота сигнала SCL fSCL о 100 кГц
Свободная шина teuF 4.7 - мкс
Фиксация SТАRТ-условия tнD,ST 4.0 - мкс
Длительность LOW полупериода SCL tLow 4.7 - мкс
Длительность HIGH полупериода SCL tн1Gн 4.0 - мкс
Готовность повторного SТАRТ-условия tsu.sтд 4.7 - мкс
Удержание данных tнD,DAT о - мкс
Готовность данных tsu.DAT 250 - нс
Фронт сигналов SCL и SDA t, - 1000
Спад сигналов SCL и SDA t1 - 300
Готовность SТОР-условия tsu;STO 4.0 - мкс

о
От «Master» к «Slave»

О От «Slave» к «Master»

а) Передача от «Мaste,·,. к «Slave» «Start»-ycлoвиe

«Stор,,-условие

Бит подтверждения (АСК)


Отсутствие подтверждения

б) Чтение из «Slave»

Передача или чтение Повторный «Starto Передача или чтение

в) Комбинированный формат - передача/чтение

Рис. 6.5. Формат операций чтения/записи

Чтобы начать операцию обмена, устройство Master выдает на шину Start-ycлoвиe,


за которым следует байт с адресом Slаvе-устройства (рис. 6.5), состоящий из семи­
битового адреса устройства (занимает биты 1-7) и однобитового флага операции
R./W (бит О), определяющего направление обмена, причем О означает передачу от
Master к Slave (рис. 6.5, а), а 1 -:-- чтение из Slave (рис. 6.5, б). Все биы передаются
т

2
по шине I C в порядке старший-младший, т. е. первым передается 7-й бит, послед­
ним 0-й. За адресом могут следовать 9дин или более информационных байтов
Arduino и устройства / С
2
93

(в направлении, определенном флагом R/W), биты которых стробируются сигналом


SCL из Маstеr-устройства.
При совершении операции чтения Маstеr-абонент должен сопровождать прочитан­
ный байт сигналом лек, если необходимо прочитать следующий байт, и не выда­
вать сигнала лек, если собирается закончить чтение пакета.
Допускается и многократное возобновление Slave-aдpeca в одном цикле передачи,
т. е. передача повторного Stаrt-условия без предварительного Stор-условия. Такой
принцип широко применяется в управлении 12 е абонентами, когда выдача нового
Stаrt-условия служит для синхронизации начала нового пакета данных, сопровож­
даемого, например, новым управляющим словом, уточняющим адресацию пакета.
Логическая реализация протоколов на шине 12е не нормируется документами фир­
мы Philips, содержащими формальные описания шины, и может быть произвольной
для каждой конкретной ие.
Преимущества интерфейса 12 е:
D необходим всего один микроконтроллер для управления набором устройств;
D используется всего два проводника дщ1 подключения многих устройств;
D возможна одновременная �абота нескольких ведущих (master) устройств, под­
ключенных к одной шине I е;
D стандарт предусматривает «горячее» подключение и отключение устройств
в процессе работы системы;
D фильтр, встроенный в микросхемы, реализующие интерфейс, подавляет вспле-
ски, обеспечивая целостность данных.
Недостатки интерфейса I2e:
D . ограничение на емкость линии - 400 пФ;
О несмотря на' простоту протокола, программирование контроллера 12е затруднено
из-за обилия на шине возможных нештатных ситуаций. По этой причине боль­
шинство систем используют Ре с единственным ведущим (master) устройством
и распространенные драйверы поддерживают только монопольный режим об­
мена по I2e;
О трудность локализации неисправности, если одно из подключенных устройств
ошибочно устанавливает на шине состояние низкого уровня.

6.2. Arduino и библиотека ·Wire


Библиотека Wire позволяет Arduino взаимодействовать с различными устройствами
по интерфейсу I2e/ТWI. На платах Arduino версии R3 (с «распиновкой» 1.0) линии
SDЛ (данные) и SeL (тактовые импульсы), связанные с этим интерфейсом, распо­
ложены на разъеме возле контакта AREF. В Arduino Due реализовано два интер­
фейса I2e/TWI: линии одного из них (SDЛl и SeLl) расположены возле вывода
AREF, линии второго - на выводах 20 и 21. Расположение выводов I2e/ТWI для
различных плат Arduino показано в табл. 6.2.
94 Глава б

2
Таблица б.2. Расположение выводов / С!ТW/ для различньiх плат Arduino

Плата Arduino Выводы 1 2СГТWI


Uno, Ethernet А4 (SDA), А5 (SCL)
Mega2560 20 (SDA), 21 (SCL)
Leonardo 2 (SDA), З (SCL)
Due 20 (SDA), 21 (SCL), SDA1, SCL1

Начиная с версии языка Arduino 1.0, библиотека Wire наследует функции класса
strearn, что позволяет ей быть совместимой с другими библиотеками, осуществ­
ляющими запись и чтение данных. Поэтому методы send() и receive() были в ней
заменены методами read() и write().
Библиотека Wire использует следующие методы:
1::] void begin();void begin(uint8_t address);void begin(int address);
Описание: инициализация библиотеки Wire и подключение к шине 12 С в каче­
стве Master или Slave. Вызывается только один раз.
Параметр: address-7-битный адрес устройства (если оно работает в режиме
Slave). Если параметр не указан, то контроллер подключается к шине в роли
Master.
Возвращаемое значение: нет.
1::] uint8_t requestFrom(uint8_t address, uint8_t quantity);
Описание: используется мастером для запроса байта от ведомого устройства
(Slave). Байты могут быть получены с помощью методов availaЫe() и read().
Параметры:
• аddrеss-7-битный адрес устройсtва для запроса байтов данных;
• quantity-количество запрошенных байтов.
Возвращаемое значение: число считанных байтов.
1::] void beginTransmission(uint8_t address);
Описание: начало передачи 12 С для ведомого устройства (Slave) с заданным
адресом, с последующими вызовом метода write() для добавления последова­
тельности байтов в очередь предн�наченных для передачи и выполнением
самой передачи данных методом endTransmission().
Параметр: address-7-битный адрес устройства для передачи.
Возвращаемое значение: нет.
1::] uint8_t endTransmission(void);
Описание: завершает передачу данных для ведомого устройства (Slave), кото­
рое бьmо начато методом beginTransmission (), и фактически осуществляет пе­
редачу байтов, которь1е бьmи поставлены В очередь методом write().
Arduino и устройства /2 С 95

Параметры: нет.
Возвращаемое значение: байт, который указывает статус передачи:
• О-успех;
• 1 -данных слишком много, и они не помещаются в буфер передачи (размер
буфера задается определением #define BUFFER_LENGTH 32 );
• 2 -получили NACK на передачу адреса;
• 3 -получили NAC� на передачу данных;
• 4 -другая ошибка.
[:J size t write(uintB t data);size_t write(const uintB t *data, size t quantity);
Вызов:
• Wire.write(value);
• Wire.write(string);
• Wire.write(data, length);
Описание: записывает данные от ведомого устройства (Slave) в ответ на запрос
мастера (Master), или записывает, очередь байтов для передачи от мастера
к ведомому устройству (в промежутках между вызовами методов
beginTransmission() И endTransmission() ).
Параметры:
• value-значение для отправки как единичный байт;
• string-строка для отправки как последовательность байтов;
• data-массив байтов для отправки;
• length-число байтов для передачи.
Возвращаемое значение: число записанных байтов.
С] int availaЫe(void);
Описание: возвращает количество байтов, доступных для получения. Этот
метод должно быть вызван на мастере (Master) после вызова requestFrom () или
ведомым устройством (Slave) внутри обработчика onRecei ve () .
Параметры: нет.
Возвращаемое значение: число байтов, доступных для чтения.
С] int read(void);
Описание: считывает байт, который бьm передан от ведомого устройства (Slave)
к мастеру (Master) после вызова requestFrom () или бьm передан от Master
к Slave.
Параметры: нет.
Возвращаемое значение: следующий полученный байт.
Пример использования;этого метода приведен в листинге 6.1.
96 Глава б

#include <Wire.h>
void setup()
{
Wire.begin(); // подключение к шине I2C
Serial.begin(9600); // запуск последовательного порта
}
void loop()
{
Wire.requestFrom(2, 6); // запрос 6-го байта от
// устройства с адресом 2
while(Wire.availaЬle()) // пока есть, что читать

char с = Wire.read(); // получаем байт (как символ)


Serial.print(c); // печатает в порт

delay(500);
}

c::J void onReceive ( void (*function)(int) );


Описание: регистрирует функцию, которая вызывается, когда ведомое устрой­
ство (Slave) получает данные от мастера (Master).
Параметр: function - функция, которая вь1зывается, когда Slave получает дан­
ные. Обработчик должен принимать один параметр int (число байтов, считан­
ных от мастера) и ничего не возвращать.
Возвращаемое значение: нет.
c::J void onRequest( void (*function)(void) );
Описание: регистрирует функцию, которая вызывается, когда мастер запраши­
вает данные из этого ведомого устройства.
Параметр: function - функция, которая будет вызываться.
Возвращаемое значение: нет.

6.3. Arduino и датчик освещенности ВН1750


на шине 1 2 С
В главе 4 для измерения уровня осв.ещенности мы использовали фоторезистор. Но
если необходимо знать величину освещенности в физических единицах (люксах),
он не удобен, поскольку тогда нам пришлось бы делать для такого датчика измери­
тельную схему и калибровать полученные с него данные. Для получения точных
величин освещенности в люксах удобнее использовать датчик BHl 750, который
посредством цифрового интерфейса сможет выдавать нам готовые значения.
2
Arduino и устройства / С 97

Датчик BHl 750 обладает следующими характеристиками:


L1 цифровой интерфейс: I2 C;
(:] высокое разрешение: до 0,5 Лк;
(:] м�щый потребляемый ток и наличие функции «спящего» режима;
(:] фильтрация световых шумов: 50/60 Гц;
(:] малая зависимость от источника света (лампа накаливания, светодиод и т. д.);
(:] малое влияние инфракрасного излучения;
(:] возможность выбрать два адреса микросхемы для I2C интерфейса (можно под­
ключить одновременно два таких датчика к одной шине);
(:] не требует калибро);'ки, что максимально удобно для применения в любых про-
ектах;
(:] малые габариты;
(:] напряжение питания: 2,4-3,6 В;
(:] ток потребления: 120 мкА;
(:] ток потребления в спящем режиме: 0,01 мкА;
(:] измеряемая длина волны: 560 нм;
(:] точность в режиме высокого разрешения: 1 Лк;
(:] точность в режиме низкого разрешения: 4 Лк;
(:] период измерения в режиме высокого разрешения: 120 мс;
(:] период измерения в режиме низкого разрешения: 16 мс;
(:] 16-биrный АЦП.
Для использования с платой Arduino датчик выпускается в виде модуля (рис. 6.6).

Рис. 6.6. Модуль датчика ВН1750


98 Глава б

Итак, подключим модуль датчика ВН1750 к плате Arduino (рис. 6.7) и напишем
скетч получения значений освещенности в люксах. Для работы с модулем мы вос­
пользуемся библиотекой BHl 750, которая является «оберткой» для библиотеки
Wire. Содержимое скетча представлено в листинге 6.2.

Рис. 6.7. Схема соединения модуля ВН1750 с платой Arduino UNO

// подключение библиотек
#include <Wire.h>
#include <BH1750.h>
ВН1750 lightMeter;
void setup()
{
Serial.begin(9600); // запуск последовательного порта
lightМeter.begin(); // подключение к I2C
Serial.println("Running...");
}
void loop()
{
uintlб t lux = lightMeter.readLightLevel(); // получение значения
Serial.print("Light: ");
Seriai.print(lux);
Serial.println(" lx");
delay(lOOO);
}
Arduino и устройства /2 С 99

19ht: 302 lx
19ht: 303 lx
nn1n9 ...
1ght: 305 lx
19ht: 313 lx
19ht: 303 l�
19ht: 47 1.х
1qht: 43 lx
1ql1t: 317 lx
1ght: 311 lx
1ght: 310 1х
1ght: 311 li
1ght: 310 lx
1ght: 310 lx
19ht: 312 lx
1ght: 309 lx
1ght: 308 lx
1qht: :308 lx
1ght: 307 lx
1ght: 309 lx
1ght: 295 lx
19ht: 33 lx
1ght: 25 lx
1ght: 320 lx
1ght: 316 lx

Рис. 6.8. Вывод показаний модуля ВН1750 в монитор последовательного порта Arduino IDE

На рис. 6.8 показан вывод показаний модуля BHI 750 в монитор последовательного
порта Arduino IDE.

6.4·. Arduino и сервис Xively


Дпя отображения информации с датчиков Arduino служит и облачный сервис
Xively (https://xively.com), также реализующий возможности концепции Intemet of
Things.
Чтобы пользоваться этим сервисом, сначала необходимо в нем зарегистрировать­
ся, - на главной странице сервиса (рис. 6.9) нажимаем кнопку GET STARTED
и в открывшейся форме регистрации (рис. 6.1О) заполняем все необходимые поля.
Зарегистрировавшись, мы можем войти в свой профиль и в разделе DEVELOP
(рис. 6.11) добавить новое устройство, нажав на кнопку + Add Device. Откроется
форма (рис. 6.12), в поля которой мы вводим название (здесь: Zheleznovodsk), опи­
сание нового устройства (здесь: Zheleznovodsk sanatoriy), выбираем вид доступа
к нему (приватный или публичный) и нажимаем кнопку Add Device, в результате
чего попадаем в Xively Workbench - центр, объединяющий все датчики добавлен­
ного нами устройства. Здесь отображается информация об устройстве, последние
запросы, текущие значения каналов, ключей API, триггеров и многое другое.
100 Глава б

Рис. 6.9. Главная страница сервиса Xively

Рис. 6.10. Форма регистрации сервиса Xively


Arduino и устройства /2 С 101

Рис. 6.11. Добавление нового устройства в Xively

Рис. 6.12. Форма для вв9да данных нового устройства в Xively


102 Глава 6

6.4.1. Отправка данных в сервис Xively


Чтобы начать отправку данных из Arduino в Xively, необходимо добавить канал для
каждого потока данных - например, для значений каждого подключенного
к Arduino датчика. Д11я добавления канала в окне Xively Workbench (рис. 6.13)
нажимаем кнопку Add Channel и в поля открывшейся формы вводим данные для
нового канала, завершив ввод нажатием кнопки Save Channel. Как можно видеть,
мы создали канал для отображения данных с нашего датчика BHl 750.

Рис. 6.13. Добавление нового канала для устройства в Xively

Теперь приступим к написанию скетча на Arduino. Но .прежде всего нам необходи­


мо скачать и установить предназначенные для работы с Arduino библиотеки Xively
(https://github.com/xively/xively_arduino/archive/master.zip) и НТTPClient (https://
github.com/amcewen/llttpCiient/archive/master.zip).
Д11я отправки данных в канал нам также понадобятся значения API key
(x82lxX5skPez3TJEVAFcBxX1GzSkOPd3Cu7jEvsTveuZNC8t), feed (991165348) и
sensorIO (BHl 750), найти которые можно на странице устройства Zheleznovodsk
в окне Xively Workbench (см. рис. 6.13). Отправку данных мы станем делать раз
в минуту. Содержимое скетча представлено в листинге 6.3.

// Подключение библиотек
#include <SPI.h>
#include <Ethernet.h>
Arduino и устройства /2 С 103

#include <HttpClient.h>
#include <Xively.h>

// Мае address нашей платы Ethernet Shield


byte arduino_mac[J = OxDE, OxED, ОХВА, OxFE, OxFE, OxED };
// Настройки сети
IPAddress arduino_ip 192, 168, О, 120);
IPAddress dns_ip ( 192, 168, 1, 1);
IPAddress gateway_ip ( 192, 168, О, 28);
IPAddress suЬnet_mask(255, 255, 255, О);
// Your Xively key to let you upload data
char xivelyKey[] = "x82lxX5skPez3TJEVAFcBxX1GzSk0Pd3Cu7jEvsTveuZNC8t";
// Подключение библиотек для датчика ВН1750
#include <Wire.h>
#include <BH1750.h>
ВН1750 lightMeter;

// Данные для канала


char sensorid[] = "ВН1750";
XivelyDatastream datastreams[] = {
XivelyDatastream(sensorid, strlen(sensorid), DATASTREAМ_FLOAT),
};
// Направить поток данных в канал feed
XivelyFeed feed(991165348, datastreams, 1 /* количество каналов */);

EthernetClient client;
XivelyClient xivelyclient(client);

void setup()
{
// подключение последовательного порта
Serial.begin(9600);
// запуск датчика ВН1750
lightMeter.begin();

Serial.println("Starting single datastream upload to Xively...");


Serial.println();
// Подключение к сети
Ethernet.begin(arduino_mac,arduino_ip,dns_ip,gateway_ip,suЬnet_mask);
Serial.println(Ethernet.localIP());
}

void loop()
{
// получение данных с ВН1750
uint16 t lux = lightMeter.readLightLevel();
datastreams[OJ .setFloat(lux);
104 Глава б

Ser�al.print("BH1750 sensor value ");


Serial.println(datastreams[O] .getFloat());

Serial.println("Uploading it to Xively");
// Получение ответа от Xively
int ret = xivelyclient.put(feed, xivelyKey);
Serial.print("xivelyclient.put returned ");
Serial.println(ret);
// задержка 60 сек
delay(бOOOO);
}

Итак, устанавливаем в разъемы платы Arduino Uno плату Ethemet Shield, подклю­
чаем Ethemet Shield к сети, подключаем датчик BHl 750 и загружаем на плату
Arduino скетч из листинга 6.3. Затем открываем монитор последовательного порта
Arduino IDE и наблюдаем процесс отправки данных датчика BHl 750 в сервис
Xively (рис. 6.14).

Startн19 s1ng1e datastream upload to X111ely.,


J 92,168, О, 120
BHJ 750 se11".o r va 1 ue 342, 00
Uplo�rl1пg 1 t to X1vely
,пv;, lyctнпt, µtJt returned 200
BHl 750 s�n;o г v� l.ue ВО, 00
Upload1ng 1 t to Хне ly
н,elycl1ent. put r�tш··11ed ;юс,
ВН1750 s�пsor value 343.00
1.1rl.oad111r1 1 t t,, X1v�ly
xн�lyclient p<Jt rett1rned 2М
BHl 750 seпso г va l,1e 179, 00
Uploading 1 t to X111ely
.нvel.ycl1ent put ,·eturпed 200

Рис. 6.14. Контроль из монитора последовательного порта процесса отправки данных


в сервис Xively

Через некоторое время мы можем зайти в свой профиль в Xively, выбрать устрой­
ство и канал BHl 750 и увидеть графическое отображение отправленных из Arduino
данных (рис. 6.15).
2
Arduino и устройства / С 105

Рис. 6.15. Графическое отображение поступающих в канал данных

ЭЛЕКТРОННЫЙ АРХИВ
СкеТ'-1, соответствующий листингу 6.3, можно найти в файле arduino_scetches\_06\
_06_03.ino сопровождающего книгу электронного архива.

6.4.2. Получение данных из сервиса Xively


Мы можем не только отправлять данные в сервис Xively, но и получать из него
данные того или иного канала.
Для этого подключим другую плату Arduino с Ethemet Shield на борту к сети и
настроим для нее получение данных из канала BHI 750. Содержимое скетча пред­
ставлено в листинге 6.4.

// Подключение библиотек
#include <SPI.h>
#include <Ethernet.h>
#include <HttpClient.h>
#include <Xively.h>

// Мае address нашей платы Ethernet Shield


byte arduino_mac[] = OxDE, OxED, ОхВА, OxFE, OxFE, OxED };
// Настройки сети
IPAddress arduino_ip 192, 168, О, 120);
106 Глава б

IPAddress dns_ip ( 192, 168, 1, 1);


IPAddress gateway_ip ( 192, 168, О, 28);
IPAddress suЬnet_rnask(255, 255, 255, О);
// Your Xively key to let you upload data
char xivelyKey[J = "x82lxX5skPez3TJEVAFcBxX1GzSk0Pd3Cu7jEvsTveuZNC8t";

// Данные для канала


char sensorid[] = "ВН1750";
XivelyDatastream datastreams[] = {
XivelyDatastream(sensorid, strlen(sensorid), DATASTREAМ_FLOAT),
};
// Направить поток данных в канал feed
XivelyFeed feed(991165348, datastreams, 1 /* количество каналов */);

EthernetClient client;
XivelyClient xivelyclient(client);

void setup()
{
// подключение последовательного порта
Serial.begin(9600);
Serial.println("Starting single datastream upload to Xively...");
Serial.println();
// Подключение к сети
Ethernet.begin(arduino rnac,arduino_ip,dns_ip,gateway_ip,suЬnet_rnask);
Serial.println(Ethernet.localIP());
}

void loop()

// Получение ответа от Xively


int ret = xivelyclient.get(feed, xivelyKey);
Serial.print("xivelyclient.get returned ");
Serial.println(ret);
// если есть данные - обработать и вывести
if (ret > О)
{
Serial.println("Datastream is...");
Serial.println(feed[O]);
Sf3rial.print("Light is: ");
Serial.println(feed[O].getFloat());
}
// задержка 60 сек
delay(60000UL);
}
Arduino и устройства /2 С 107

Загрузим в плату Arduino, предназначенную для получения данных, скетч из лис­


тинга 6.4, откроем монитор последовательного порта Arduino ШЕ и увидим про­
цесс получения данных из канала BHl750 сервиса Xively (рис. 6.16).

192. 160. о. 1Z2


xive1ycl1ent.get returr1ed ,200
Datastream 1s ...
{ "1d" : "ВН1750', "current- va1ue" "279. С:ЭО" }
L1ght 1s: 279.00

x1ve1ycl1ent.9et returned 400


Datastream 1s .. ,
{ "1d" : "ВН1750", "current-valu::i" "45.00" }
L19ht lЭ: 45.00
x1velycl1ent.9et returned 20G
Datastream 1s ...
{ "1d" : "ВН1750", "current-va1ue" "294. 00" }
L1ght lS: 294.00
x1velyc11ent.9et returned 200
Datastream 1э .. ,
{ "1d" : "ВН1750", "current_va1ue" "293. 00" }
L1ght lS: 293.00

Рис. 6.16. Вывод в последовательный порт данных, полученных из сервиса Xively

ЭЛЕКТРОННЫЙ АРХИВ
Ске'Т'-1, соответствующий листингу 6.4, можно найти в файле arduino_scetches\_06\
_06_04.ino сопровождающего книгу электронного архива.

В следующем разделе мы рассмотрим отправку и получение данных для несколь­


ких каналов сервиса Xively.

6.5. Arduino и датчик влажности


и т�мпературь1 SHT21 на шине 1 2 С
Познакомимся с еще одним полезным датчиком, работающим по протоколу 12С, -
датчиком SНТ21 (рис. 6.17). По заявлению производителя (фирма Sensirion), это
самый маленький в мире датчик влажности и температуры. Датчик обладает сле­
дующими отличительными особенностями:
l:J миниатюрный размер: ЗхЗхl,1 мм- это, как уже отмечено, самый маленький
датчик влажности в мире;
108 Глава б

l::J напряжение питания: 2,1-3,6 В;


l::J всего 6 ножек по бокам корпуса (несмотря на миниатюрный размер, микросхему
вполне можно запаять обычным паяльником);
l::J диапазон измерения температуры: от -40 до +125 °С с разрешением 14 бит
(LSB = 0,01 °С);
l::J диапазон измерения влажности: от 0%RН до 100%RН с разрешением 12 бит
(LSB = О,04%RН);
l::J потребление в- режиме измерения-300 µА, в спящем режиме-О,15 µА;
l::J встроенный детектор разряда батареи выставляет флаг, если напряжение пита­
ния опускается ниже 2,25 В;
l::J встроенный нагреватель для самодиагностики датчиков.

Рис. 6.17. Датчик влажности и температуры SHT21

Если требуется получить высокую точность и стабильность показаний (в особенно­


сти температуры), то при разводке платы и работе с датчиком следует придержи­
ваться ряда правил. Это касается не только SHT2 l, но и любых датчиков темпера­
туры/влажности, от которых требуется высокая точность. Дело в том, что показа­
ния датчика могут оказаться ложными, если сам датчик и/или воздух вокруг него
нагреваются в процессе работы. Причин для этого может быть несколько:
l::J саморазогрев датчика из-за непрерывной работы. Действительно, если мы по­
стоянно заставляем датчик измерять температуру или влажность, пересчитывать
их и выдавать данные в линию, то он будет вьщелять тепло. А из-за маленького
размера корпуса (напомmо, SНТ21-самый маленький датчик влажности в ми­
ре) он скоро начнет нагреваться.
Решение этой проблемы напрашивается само собой-опрашивайте датчик как
можно реже. Хорошо, если отношение времени работы ко времени простоя
будет около 10%. Так, SHT21 требуется 70 мс для измерения температуры и
25 мс для измерения влажности. В сумме: 95 мс. Получается, что для того чтобы
датчик не разогревался, нам надо проводить замеры не чаще чем раз в 1 секунду.
Учитывая, что температура и влажность обычно изменяются медленно, увели­
чив задержку между опросами, мы ничего не потеряем;
l::J влияние источников тепла, расположенных в непосредственной близости от
датчика. Передавать датчику свое тепло могут как различные силовые элемен-
2
Arduino и устройства 1 С 109

ты, особенно если они работают в линейном режиме и сильно нагреваются, так и
мощные контроллеры, работающие на высокой частоте. Большая часть такого
тепла передается через медную фольгу на текстолите (печатный монтаж), по­
этому рекомендуется размещать датчик как можно дальше от источников тепла
и делать информационные дорожки к нему потоньше. При промышленном
производстве в плате вокруг датчика делают прорези, отделяя его от остальной
платы;
1:1 передача тепла посредством конвекции. Проще говоря, горячий воздух от тех
же силовых элементов может попасть в область действия датчика и привести
к изменению его показаний. Способ борьбы один - отгородить датчик от разо­
гретого воздуха перегородками. Впрочем, если наше устройство не замуровано
в корпус, то этой напасти можно не бояться;
1:1 солнечный свет тоже очень сильно влияет на показания термометра. Кстати, де­
лать «крышу» над датчиком, если он стоит на открытом воздухе, нужно не толь­
ко для защиты от солнца, но и от дождя.
Если устройство находится в корпусе, то датчик надо располагать так, чтобы кон­
такт с воздухом из окружающей среды был наибольшим. Самый хороший вари­
ант - когда внешний воздух свободно проходит около датчика, а от нагретого воз­
духа из корпуса датчик защищен перегородкой.
Для работы с Arduino датчик выпускается в виде модуля (рис. 6.18) с преобразова­
телем питания от 5 В.

Рис. 6.18. Модуль датчика SHT21

Схема подключения модуля датчика SHT21 к плате Arduino показана на рис. 6.19.
Для работы с модулем можно исполь.зовать библиотеку SHT2x. В листинге 6.5
представлен пример считывания с датчика SHT21 данных влажности и температу­
ры и вывод их в монитор последовательного порта.

#include <Wire.h>
#includ� <SHT2x.h>
void setup ()
110 Глава,б

Wire.begin();
Serial.begin(9600);
}
void loop()
{
Serial.print("Hщnidity(%RН): ");
Serial.print(SHT2x.GetHumidity());
Serial..print(" Temperature(С): ");
Serial.println(SHT2x.GetTemperature());
delay(lOOO);
}

Рис. 6.19. Схема подключения модуля датчика SHT21 к плате Arduino

6.6. Arduino и сервис Xively (продолжение)


6.6.1. Отправка мультиданных в cepвиcXively
Добавим в схему, приведенную на рис. 6.7, датчик SНТ21 и настроим дополни­
тельно к отправке в сервис Xively данных освещенности (от датчика BHI 750) также
и отправку данных влажности и температуры. Для этого в сервисе Xively для наше­
го устройства Zheleznovodsk добавим еще два канала: SHT-H- для отправки зна­
чений влажности и SHT-T- для отправки значений температуры (рис. 6.20).
Arduino и устройства 12 С 111

Рис. 6.20. Соэдание дополнительных каналов для отправки в сервис Xively данных от датчика SHT21

Изменим соответственно и скетч из листинга 6.3, добавив в него отправку данных


в несколько каналов устройства Xively. Измененный скетч представлен в листин­
ге 6.6. Загрузим его в плату Arduino 'и увидим в сервисе Xively графическое ото­
бражение поступающих с датчиков ВН 17 50 и SН21 данных (рис. 6.21 ).

// Подключение библиотек
Hnclude <SPI.h>
#include <Ethernet.h>
#include <HttpClient.h>
#include <Xively.h>

// Мае address нашей платы Ethernet Shield


byte arduino_mac[] = OxDE, OxED, ОхВА, OxFE, OxFE, OxED }';
// Настройки сети
IPAddress arduino_ip 192, 168, О, 120);
IPAddress dns_ip ( 192, 168, 1, 1);
112 Главаб

IPAddress gateway_ip ( 192, 168, О, 28);


IPAddress suЬnet_rnask(255, 255, 255, О);
// Your Xive1y key to let you upload data
char xivelyKey[] = "x82lxX5skPez3TJEVAFcBxX1GzSk0Pd3Cu7jEvsTveuZNC8t";
// Подключение библиотек для датчика ВН1750
#include <Wire.h>
#include <BH1750.h>
ВН1750 lightMeter;
// Подключение библиотеки для датчика SHT21
#include <SHT2x.h>

// Данные для каналов


char sensorid[] = "ВН17'50";
char sensoridl[] = "SHT21-H";
char sensorid2] = " SHT21-T";
XivelyDatastream datastreams[J = {
XivelyDatastream(sensorid, strlen(sensorid), DATASTREAМ_FLOAT),
XivelyDatastream(sensoridl, strlen(sensoridl), DATASTREAМ_FLOAT),
XivelyDatastream(sensorid2, strlen(sensorid2), DATASTREAМ_FLOAT),
};
// Направить поток данных в канал feed
XivelyFeed feed(991165348, datastreams, 3 /* количество каналов */);

EthernetClient client;
XivelyClient xivelyclient(client);

void setup()
{
// подключение последовательного порта
Serial.begin(9600);
!/ запуск датчика ВН1750
lightMeter.begin();

Serial.println("Starting single datastream upload to Xively... ");


Serial.println();
// Подключение к сети
Ethernet.begin(arduino_rnac,arduino_ip,dns ip,gatew�y ip,suЬnet rnask);
Serial.println(Ethernet.localIP());
)

void loop{)
{
// получение данных с ВН1750
uintlб t lux = lightMeter.readLightLevel();
datastreams[OJ .setFloat(lux);
datastreams[l] .setFloat(SHT2x.GetHшnidity());
datastreams[2] .setFloat(SHT2x.GetTemperature());
Arduino и устройства /2 С 113

Serial.println("Uploading it to Xively");
// Получение отв�та от Xively
int ret = xivelyclient.put(feed, xivelyKey);
Serial.print("xivelyclient.put returned ");
Serial.println(ret);
// задержка 60 сек
delay(бOOOO);
}

Рис. 6.21. Графическое отображение поступающих в канал данных

ЭЛЕКТРОННЫЙ АРХИВ
Скетч, соответствующий листинrу 6.6, можно найти в файле arduino_scetches\_06\
_06_06.ino сопровождающего книrу электронного архива.

6.6.2. Получение мульtиданных из сервиса Xively


Изменим скетч из листинга 6.4 для получения данных из нескольких созданных
нами каналов: ВН1750, SHT21-H и SHT21-T. Содержимое скетча представлено
в листинге 6.7.
114 Глава б

// Подключение библиотек
#include <SPI.h>
#include <Ethernet.h>
#include <HttpClient.h>
#include <Xively.h>

// Мае address нашей платы Ethernet Shield


byte arduino_rnac[] = OxDE, OxED, ОхВА, OxFE, OxFE, OxED };
// Настройки сети
IPAddress arduino_ip 192, 168, О, 120);
IPAdqress dns_ip ( 192, 168, 1, 1);
IPAddress gateway_ip ( 192, 168, О, 28);
IPAddress suЬnet_rnask(255, 255, 255, О);
// Your Xively key to let you upload data
char xivelyKey[] = "x82lxX5skPez3TJEVAFcBxX1GzSk0Pd3Cu7jEvsTveuZNC8t";

// Данные для каналов


char sensorid[] = "ВН1750";
char sensoridl[] = "SHT21-H";
char sensorid2] = " SHT21-T";
XivelyDatastream datastreams[] = {
XivetyDatastream(sensorid, strlen(sensorid), DATASTREAМ_FLOAT),
XivelyDatastream(sensoridl, strlen(sensoridl), DATASTREAМ_FLOAT),
XivelyDatastream(sensorid2, strlen(sensorid2), DATASTREAМ_FLOAT),
};
// Направить поток данных в канал feed
XivelyFeed feed(991165348, datastreams, 3 /* количество каналов */);

EthernetClient client;
XivelyClient xivelyclient(client);

void setup()
{
// подключение последовательного порта
Serial.begin(9600);
Serial.println("Starting single datastream upload to Xively...");
Serial.println();
// Подключение к сети
Ethernet.begin(arduino rnac,arduino_ip,dns_ip,gateway_ip,suЬnet_rnask);
Serial.println(Ethernet.localIP());
}

void loop()

// Получение ответа от Xively


int ret = xivelyclient.get(feed, xivelyKey);
2
Arduino и устройства / С 115

Serial.print("xivelyclient.get returned ");


Serial.println(ret);
// если есть данные - обработать и вывести
if (ret > О)
{
Serial.println("Datastream is...");
Serial.println(feed[O]);
Serial.print("Light is: ");
Serial.println(feed[O].getFloat());
Serial.print("Hшnidity is: ");
Serial.println(feed[l].getFloat());
Serial.print("Temp is: ");
Serial.println(feed[?J,getFloat());
}
// задержка 60 сек
delay(бOOOOUL);
}

Загружаем в плату Arduino скетч из листинга 6.7, открываем монитор последова­


тельного порта Arduino IDE и наблюдаем процесс получения данных из трех кана­
лов сервиса Xively (рис. 6.22).

1velycl1ent.get returned 200


atastream 1s .. ,
1ght lS: 153.00
IIПlldl ty lS: 43, 48
en1p 1s: 21. 99
1velyc11ent.get returned 200
atast ream 1s ...
)}1ght 15: 152, 00
�um1d1ty 1s: 43.22
i;remp 1s: 22.01
�;
\tavelyc11ent. get returned 200
,!Patast ream 1 s, ..
i1}1ght lS: 150.00
�um1d1ty 1s: 43.34
lfemp 1s: 22. 13
:�'
1�1ve1.yc11eпt.9et returned 200
�atastr·eam 1s,,.
[Щ.1qht 15: 142.00
um1d1ty 1s: 42.52
emp 1s: 22.04

Рис. 6.22. Вывод в последовательный порт данных, полученных из сервиса Xively


116 Глава б

ЭЛЕКТРОННЫЙ АРХИВ
Ске"N, соответствующий листингу 6.7, можно найти в файле arduino_scetches\_06\
_06_07.ino сопровождающего книгу электронного архива.

6. 7. Arduino и часы реального времени


на шине 1 2 С
Познакомимся с еще одним I2 С-устройством, весьма часто необходимым при соз­
дании систем на Arduino, -микросхемой часов реального времени ( RTC). Допус­
тим, ваша плата Arduino собирает данные с подсоединенных к ней датчиков и ведет
запись данных на внешний накопитель - например, на SD-карту. Чтобы анализи­
ровать находящиеся на карте данные, необходимо записывать их вместе с времен­
ной меткой, - тут и пригодится микросхема часов реального времени.

Рис. 6.23. Модуль RTC на микросхеме DS1307

Подключаемая к микроконтроллеру при помощи шины I2 C, микросхема Dallas


DS1307 (рис. 6.23) представляет собой часы реального времени с календарем и до­
полнительной памятью nvSRAM ( 56 байтов). Количество дней в месяце OHf.l спо­
собна с учетом високосных лет рассчитать до 2100 года. В микросхеме DS 1307
имеется встроенная схема, определяющая аварийное отключение питания и авто­
матически подключающая резервную батарейку. При этом отсчет времени продол­
жается, и после восстановления питания часы показывают правильное время. Име­
ется в этой микросхеме и программируемый генератор прямоугольных импульсов,
позволяющий вырабатывать одну из четырех частот ( 1Гц, 4096 Гц, 8192Гц или
32 768Гц). Часы подключаются по протоколу I2 C всего двумя проводами -через
выводы SCL и SDA интерфейса I2 C. Выводы, через которые подключаются часы
к шине питания, необходимо дополнительно подтянуть с помощью резисторов
2к0м.
Контакты SCL и SDA на разных платах Arduino расположены на различных вы­
водах:
r:J Uno, Nano -на выводах А4(SDA) и А5 (SCL);
r:J Меgа 256 0-на выводах 20(SDA) и 21(SCL);
r:J Leonardo -на выводах 2(SDA) и 3(SCL).
Arduino и устройства /2 С 117

Вывод SDA часов подкточается к выводу SDA контроллера, а вывод SDL часов -
соответственно, к выводу SDL контроллера.
Схема подключения микросхемы часов реального времени DS1307 и жидкокри­
сталлического (LCD) индикатора WH1602 к плате Arduino показана на рис. 6.24.

Рис. 6.24. Схема подключения кArduino модуля часов реальноrо времени DS1307
и жидкокристаллическоrо (LCD) индикатора WH1602

Напишем скетч для вывода даты и времени, получаемых с микросхемы часов ре­
ального времени DS1307, на экран LСD-индикатора WН1602 (листинг 6.8). При
написании скетча мы воспользуемся библиотекой Time, которая является «оберт­
кой» для библиотеки DS1307, и библиотекой Wire, предназначенной для работы
2
с 1 С-устройствами. Для работы с LС:D-индикатора нам пригодится также библио-
тека LiquidCrystal.

// подключение библиотек для RTC


#include <Wire.h>
#include <Time.h>
#include <DS1307RTC.h>
// подключение библиотеки для lcd
#include <LiquidCrystal.h>
// инициализация с указанием контактов подключения
LiquidCrystal lcd(9, 8, 7, 6, 5, 4);
118 Глава б

void setup()

lcd.begin(lб, 2); // установить размерность дисплея


}
void loop()
{
tmElements_t trn;
if (RTC.read(trn)) // получение времени
{
print2digits(trn.Hour,0,0);
lcd.print(':');
print2digits(trn.Minute,3,0);
lcd.print(':');
print2digits(trn.Second,6,0);
print2digits(trn.Day,0,1);
lcd.print('/');
print2digits(trn.Month,3,1);
lcd.print('/');
lcd.print(trnYearToCalendar(trn.Year));
}
else

if (RTC.chipPresent())
{
lcd.clear();
lcd.setCursor(O, О);
lcd.print("DS1307 is stopped");
}
else

lcd.clear();
lcd.setCursor(O, О);
lcd.print("DS1307 read error");
}
delay(9000);
}
delay(lOOO);
}
// процедура вывода на дисплей с добавлением до двух цифр
void print2digits(int nurnЬer,int col, int str)
{
lcd.setCursor(col, str);
if (nurnЬer >= О && nurnЬer < 10)
{lcd.print("O");}
lcd.print(nurnЬer);
Arduino и устройства /2 С 119

При запуске скетча на экране дисплея мы увидим неверное время и неверную дату.
Дело в том, что при отсутствии питания значение времени в микросхеме DS1307
сбрасывается на 00:00:00 01/01/2000. Чтобы при откточении питания время не
сбрасывалось, предусмотрено аварийное питание модуля от батарейки 3 В.
Для установки времени в библиотеке имеется функция RTC.write(tmElements_t tm).
Добавим в наш скетч возможность установки данных RTC по последовательному
порту отправкой в модуль строки вида: dd/пm/YYYY hh:пm:ss. Содержимое скетча
показано в листинге 6.9.

!/ подключение библиотек для RTC


#include <Wire.h>
#include <Time.h>
#include <DS1307RTC.h>
// подключение библиотеки для lcd
#include <LiquidCrystal.h>
// инициализация с указанием контактов по�ключения
LiquidCrystal lcd(9, 8, 7, 6, 5, 4);
// строка, собираемая из данных, приходящих в последовательный порт
String inputString = "";
boolean stringComplete false; // флаг комплектнос�и строки

void setup()
{
Serial.begin(9600); // запустить последовательный порт
lcd.begin(lб, 2); // установить размерность дисплея
}

void loop()

tmElements t tm;

// ожидание конца строки для анализа поступившего запроса:


if (stringComplete)
{
tm.Day=(int(inputString[0])-48)*10+(int(inputString[l])-48);
tm.Month=(int(inputString[3])-48)*10+(int(inputString[4])-48);
tm.Year= CalendarYrToТm((int(inputString[6])-
48)*1000+(int(inputString[7])-48)*100+
(int(inputString[8])-48)*1Q+(int(inputString[9])-48) );

tm.Hour=(int(inputString[ll])-48)*10+(int(inputString[l2])-48);
tm.Minute= (int(inputString[l4])-48)*10+(int(inputString[l5])-48);
tm.Second= (int(inputString[l7])-48)*10+(int(inputString[l8])-48);
RTC.write(tm); // записать время в RTC
120 Глава б

// ОЧИСТИТЬ строку
inputString = "";
stringComplete = false;
}
if (RTC.read(tm))
{
print2digits(tm'.Hour, О, О);
lcd.print(':');
print2digits(tm.Minute,3,0);
lcd.print(':');
print2digits(tm.Second,6,0);
print2digits(tm.Day,O,l);
lcd.print('/');
print2digits(tm.Month,3,l);
lcd.print('/');
lcd.print(tmYearToCalendar(tm.Year));
}
el$e

if (RTC.chipPresent())
{
lcd.clear();
lcd.setCursor(O, О);
lcd.print("DS1307 is stopped");
}
else

lcd.clear();
lcd.setCursor(O, О);
lcd.print("DS1307 read error");
}
delay(9000);
}
delay(lOOO);
}
// процедура вывода на дисплей с добавлением до двух цифр
void print2digits(int numЬer,int col, int str)
{
lcd.setCursor(col, str);
if (numЬer >= О && numЬer < 10)
{lcd.print("0");}
lcd.print(numЬer);
}
// получение данных по последовательноь,rу порту
void serialEvent()

while (Serial.availaЬle())
Arduino и устройства /2 С 121

{ // получить очередной байт:


char inChar (char)Serial.read();
// добавить в с�року
inputString += inChar;
// /n - конец передачи
if (inChar == '\n')
{stringComplete = tru�;}

Теперь установим время из монитора последовательного порта отправкой в модуль


строки dd/пun/YYYY hh:пun:ss и увидим на экране дисплея отображение верных даты
и времени.
ЭЛЕКТРОННЫЙ АРХИВ
Ске,чи, соответствующие листингам 6.8 и 6.9, можно найти в файлах arduino_
scetches\_06\_06_08.ino и _06_09.ino сопровождающего книгу электронного архива.

6.8. Arduino и SD-карта:


чтение и запись данных
Если вашим Arduino-npoeктaм не хватает памяти (а объем энергонезависимой па­
мяти EEPROM в платах Arduino совсем небольшой), можно использовать внешние
носители. И одним из самых простых по подключению к платам Arduino является
накопитель на SD-карте: мы можем подсоединиться к SD-карте напрямую, а можем
и использовать соответствующие модули. 1

Итак, подсоединим модуль SD Card к плате Arduino и напишем пример сохранения


на SD-карте данных от датчика BHl 750. Для анализа данных освещенности потре­
буется знать и время производства замеров, поэтому мы задействуем и модуль
часов реального времени (RTC). Схема, соответствующая нашим пожеланиям,
показана на рис. 6.25.

Рис. 6.25. Схема подключения к Arduino модулей SD Card и DS1307


122 Глава б

При написании скетча мы воспользуемся библиотекой SD для работы с SD-картой,


а также библиотеками Тime и DS1307 для работы с модулем RTC. Содержимое
скетча nоказано в листинге 6.1 О: каждые 5 минут мы считываем данные с датчика
BHl 750 и заносим время измерения и данные в файл вида d-m-Y. В начале суток
создаем новый файл на новый день.

// подключение библиотек для RTC


#include <Wire.h>
#include <Time.h>
#include <DS1307RTC.h>
// подключение б.иблиотеки для SD
#include <SD.h>

File myFile;
String sfilename;
char filename[20];
const int LМ335=АО; // для подключения LМ335
trnElements
' -t tm;
unsigned long millisl=O;
// Подключение библиотек для датчика ВН1750
#include <Wire.h>
#include <BH1750.h>
ВН1750 lightMeter;

void setup()

// запуск датчика ВН1750


lightMeter.begin();
}

void loop()

// проверка, прошло 5 минут?


if(millis()-millisl>5*60*000)
{
millisl=millis();
// получить имя файла для текущего дня
sfilename=get_file_name();
sfilename.toCharArray(filename,20);
// открыть файл или создать
myFile = SD.open(filename, FILE_WRITE);
// получить данные ВН1750
uintlб t lux = lightMeter.readLightLevel();
2
Arduino и устройства / С 123

// получить время H:m


// создать запись дпя файла
record=get_time();
record+=" ";
record+=String(lux);
myFile.println(record);
myFile.close();
}
/ / получение времени дня
String get_time()
{
String timel;
RTC.read(tm);
if(tm.Hour()<10)
timel="O"+String(tm.Hour(),DEC);
else
timel=String(tm.Hour(),DEC);
if(tm.Minute()<lO)
timel+=":O"+String(tm.Minute(),DEC);
else
timel+='':
, "+String(tm,Minute (),DEC);
return timel;

ЭЛЕКТРОННЫЙ АРХИВ
Скетч, соответствующий листингу 6.10, можно найти в файле arduino_scetches\_06\
_06_10.ino сопровождающего книгу электронного архива.
ГЛАВА 7

Arduino и 1-Wire

В этой главе мы рассмотрим примеры использования Arduino в связке с устройст­


вами, основанными на протоколе 1-Wire.

7.1. Технология 1-Wire


1-Wire (от англ. - единственный провод)- зарегистрированная торговая марка
корпорации Dallas Semiconductor для системотехники шины устройств связи Dallas
Semiconductor. Протокол обеспечивает низкоскоростной интерфейс для данных-
обычно 16,4 Кбит/с (J!,lаксимум 125 Кбит/с в режиме overdrive). Для связи с устрой­
ством необходимо лишь два провода: на данные и заземление. Дело в том, что ин­
тегральная схема включает конденсатор емкостью 800 пФ для питания от линии
данных (так называемое питание от паразитного источника). При этом электро­
питание схемы осуществляется за счет конденсатора, который заряжается в период
наличия высокого уровня напряжения на линии данных. Здесь следует учитывать,
что связь с устройствами, использующими паразитное питание, возможна только
на коротких линиях, на длинных же линиях приходится задействовать дополни­
тельный провод питания.
Протокол регламентирован разработчиками для применения в четырех основных­
сферах-приложениях:
[:] приборы в специаль:иых корпусах MicroCAN для решения проблем идентифика­
ции, переноса или преобразования информации (технология iButton);
[:] программирование встроенной памяти интегральных компонентов;
[:] идентификация элементов оборудования и защита доступа к ресурсам электрон-
ной аппаратуры;
[:] системы автоматизации (технология сетей 1-Wire).
Первое из этих направлений широко известно на мировом рынке и уже давно поль­
зуется заслуженной популярностью. Второе- с успехом обеспечивает возмож­
ность легкой перестройки функций полупроводниковых компонентов, производи­
мых фирмой Dallas Semiconductor и имеющих малое количество внешних выводов.
126 Глава 7

Третье - позволяет обеспечить недорогую, но достаточно эффективную иденти­


фикацию и надежную защиту самого разнообразного оборудования. Что касается
четвертого применения, то реализация локальных распределенных систем на базе
шины 1-Wire является на сегодня де-факто наиболее оптимальным решением для
большинства практических задач автоматизации. В настоящее время Dallas
Semiconductor поставляет широкую номенклатуру однопроводных компонентов
различных функционал�ных назначений для реализации самых разнообразных
сетевых приложений. Поэтому имеется огромное число конкретных примеров
использования интерфейса 1-Wire для целей автоматизации в самых различных
областях, и все больше разработчиков проявляют интерес к этой технологии.
Так в чем же особенность этого сетевого стандарта? Ведь в качестве среды для п�­
редачи инфор1"4ации по однопроводной линии чаще всего возможно использование
обычного телефонноrQ кабеля и, следовательно, скорость обмена в этом случае не
велика. Однако если внимательно проанализировать большинство объектов, тре­
бующих автоматизации, то больше чем для 60% из них предельная скорость об­
служивания в 16,3 Кбит/с будет более чем удовлетворительной. А вот и другие
преимущества технологии 1-Wire:
[:] простое и оригинальное решение адресуемости абонентов;
[:] несложный протокол;
[:] простая структура линии связи;
[:] малое потребление компонентов;
[:] легкое изменение конфигурации сети;
[:] значительная протяженность линий связи;
[:] исключительная дешевизна всей технологии в целом.
Все эти преимущества отражают очевидную рациональность и высокую эффектив­
ность технологии 1-Wire при решении задач комплексной автоматизации в самых
раз:личных областях деятельности.
Сеть 1-Wire представляет собой информационную сеть, использующую для осуще­
ствления цифровой связи одну линию данных (DATA) и один ·возвратный (или зем­
ляной) провод (RЕт). Таким образом, для реализации среды обмена этой сети могут
быть применены досrупные кабели, содержащие неэкранированную витую пару
той или иной категории и даже обычный телефонный провод. Такие кабели при их
прокладке не требуют наличия какого-либо специального оборудования, а ограни­
чение максимальной длины однопроводной линии регламентировано разработчи­
ками на уровне 300 м.
Основой архитектуры сетей 1-Wire является rопология общей шины, когда каждое
из устройств подключено непосредственно к единой магистрали, без каких-либо
каскадных соединений или ветвлений. При этом в качестве базовой используется
структура сети с одним ведущим (или мастером) и многочисленными ведомыми.
Впрочем., существует и ряд специфических приемов организации работы однопро­
водных систем в режиме мультимастера.
Arduino и 1-Wire 127

Конфигурация любой сети 1-Wire может произвольно меняться в процессе ее рабо­


ты, не создавая помех дальнейшей эксплуатации и работоспособности всей систе­
мы в целом, если при этих изменениях соблюдаются основные принципы организа­
ции однопроводной шины. Эrа возможность достигается благодаря присутствию
в протоколе интерфейса 1-Wire специальной команды поиска ведомых устройств
(поиск ПЗУ), которая позволяет быстро определить новых участников информаци­
онного обмена. Благодаря наличию в составе любого устройства, снабженного ин­
терфейсом 1-Wire, индивидуального уникального адреса (отсутствие совпадения
адресов для компонентов, когда-либо выпускаемых Dallas Semiconductor, гаранти­
руется самой фирмой-производителем), такая сеть имеет практически неограни­
ченное адресное пространство. При этом каждый из однопроводных компонентов
сразу готов к использованию в составе сети 1-Wire без каких-либо дополнительных
аппаратно-программных модификаций.
Однопроводные компонентьi представляют собой самотактируемые полупроводни­
ковые устройства, в основе обмена информацией между которыми лежит управле­
ние длительностью импульсных сигналов в однопроводной среде и их измерение.
Передача сигналов для интерфейса 1-Wire - асинхронная и полудуплексная, а вся
информация, циркулирующая в сети, воспринимается абонентами либо как коман­
ды, либо как данные. Команды сети генерируются мастером и обеспечивают раз­
личные варианты поиска и адресации в�домых устройств, определяют активность
на линии даже без непосредственноиV адресации
}
отдельных компонентов, управля-
ют обменом данными в сети.
Стандартная скорость работы сети 1-Wire, изначально нормированная на уровне
16,3 Кбит/с, бьmа выбрана, во-первых, исходя из обеспечения максимальной на­
дежности передачи данных на большие расстояния, и, во-вторых, с учетом быстро­
действия наиболее широко распространенных типов универсальных микрокон­
троллеров, которые в основном должны использоваться при реализации ведущих
устройств шины 1-Wire. Эrа скорость обмена может быть снижена до любой воз­
можной благодаря введению принудительной задержки между передачей в линию
отдельных битов данных (растягиванию временных слотов протокола). Увеличение
скорости обмена в сети 1-Wire выше значения 16,3 Кбит/с приводит к сбоям и
ошибкам при работе на магистрали 1-Wire длиной более 1 м. Однако если длина
линии 1-Wire не превышает 0,5 м, то скорость обмена может быть значительно уве­
личена за счет перехода на специальный режим ускоренной передачи - overdrive
(до 125 Кбит/с), который допускается для отдельных типов однопроводных компо­
нентов. Как пр_авило, такой режим обмена аппаратно реализован для однопровод­
ных компонентов, имеющих большой объем встроенной памяти и предназначен­
ных для эксплуатации на небольшой, но качественной и не перегруженной другими
устройствами линии 1-Wire. Типичным примером таких компонентов являются
микросхемы семейства iButton.
При реализации интерфейса 1-Wire используются стандартные КМОП/ТТЛ логиче­
ские уровни сигналов, а питание большинства однопроводных компонентов может
осуществляться от внешнего источника с рабочим напряжением в диапазоне от 2,8
до 6,0 В. Причем, такой источник может быть располож�н либо непосредственно
128 Глава 7

возле компонента (например, батарея в составе микросхем iButton), либо энергия от


него может посrупать по отдельной линии магистрали 1-Wire. Альтернативой при­
менению внешнего питания служит так называемый механизм паразитного пита­
ния, действие которого заключается в использовании каждым из ведомых компо­
нентов линии 1-Wire электрической энергии импульсов, передаваемых по шине
данных, аккумулируемой затем специальной, встроенной в микросхему, емкостью.
Кроме того, отдельные однопроводные компоненты сетей 1-Wire могут использо­
вать особый режим питания по шине данных, когда энергия к приемнику поступает
непосредственно от мастера по шине DATA магистрали, при этом обмен информаци­
�й в сети принудительно прекращается.

7 .2. Применение 1-Wire


О признании шины 1-Wire в качестве международного стандарта и серьезности от­
ношения к этому интерфейсу со стороны маститых разработчиков и производите­
лей электроники говорят многочисленные факты. Например, нет практически ни
одного универсального м»кроконтроллера, в литературе по применению которого
не обсуждались бы способы организации на его базе мастера линии 1-Wire.
Рационально использование технологии 1-Wire при построении систем автоматиза­
ции контроля и управления для разнообразного рассредоточенного оборудования,
когда не требуется высокая скорость при обслуживании, но необходима сущест­
венная гибкость и наращиваемость при невысоких затратах на реализацию. Приве­
дем некоторые примеры активного применения устройств 1-Wire:
[] автоматизация;
[] метеостанции;
[] многоточечные системы контроля температуры - применяются при монито­
ринге микроклимата самых различных объектов, при ревизии любых операций
по переработке и хранению пищи и медикаментов, для контроля температуры во
многих областях промышленного производства, в холодильной технике и т. п.;
[] технология «Умный дом» (Home Automation)- комплекс автоматики, который
управляет инженерными системами жилища (освещением, отоплением, венти­
ляцией, кондиционированием, энергоснабжением, водоснабжением, электро­
приводами, оборудованием пожарных и охранных систем и прочим);
[] идентификация и защита электронных изделий - например, маркирование и
защита картриджей для принтеров и копировальных аппаратов, а также любых
требующих этого электронных издепий;
[] менеджмент автономных источников энергии - строгая и полная идентифика­
ция источниJ(ов энергии, сохранение в памяти встроенного в батарею электрон­
ного устройства особенностей ее изготовления и индивидуальных технических
характеристик, наиболее полный мониторинг их основных эксплуатационных
параметров на протяжении всего срока службы, а также формирование коррект-
Arduino и 1-Wire 129

ного управляющего воздействия, связанного с восстановлением заряда обслу­


живаемого аккумулятора;
Q ограничения и сопряжение с промышленными и глобальными сетями.
Русскоязычную информацию об однопроводных компонентах, наиболее подходя­
щих для организации сетей 1-Wire, можно посмотреть в сети Интернет по адресу
http://www.elin.ru/l-Wire/?topic=component. Полные списки всех однопроводных
устройств и приспособлений для их поддержки можно получить на интернет-сайте
компании-производителя Dallas Semiconductor: http://www.maxim-ic.com.
Устройства 1-Wire . достаточно шщ,око представлены в российских интернет­
магазинах по приемлемым, достаточно низким, ценам.

7 .3. Интерфейс-1-Wirе
Интерфейс 1-Wire, как уже отмечалось ранее, разработан фирмой Dallas Semi­
conductor (ныне МАХIМ) в конце 1990-х годов. Этот интерфейс интересен тем, что
ДJIЯ двустороннего обмена по нему требуется всего одна линия, причем на эту
линию можно повесить сразу несколько устройств. Правда, потребуются также
общий провод («земля))) и - но не всегда - провод питания. Протокол очень
прост и легко реализуется на микроконтроллере программно. На рис. 7.1 представ­
лена блок-схема аппаратной реализации 1-Wire.

Микроконтроллер

4,7К УСТРОЙСТВО 1-Wire


DQ
Шина 1-Wire
5µА

J Г-тх
1000
Rx= ПРИЕМ MOSFET
Тх= ПЕРЕДАЧА

Рис. 7.1. Блок-схема аппаратной реализации 1-Wire

Вывод DQ устройства представляет собой вход КМОП-логического элемента, ко­


торый может быть зашунтирован (замкнут на общий провод) полевым транзисто­
ром. Сопротивление канала этого транзистора в открытом состоянии - oкo,JJo
100 Ом. Когда транзистор заперт, имеется небольшой ток утечки (примерно 5 мкА)
на общий провод.
Шина 1-Wire должна быть «подтянута)) отдельным резистором к напряжению пи­
тания (может быть от 3 до 5 В - нужно уточнять по характеристикам подключае-
130 Глава 7

мого устройства). Сопротивление этого резистора 4,7 К, однако это значение под­
ходит лишь для весьма коротких линий. Если шина используется для подключения
устройств на большее расстояние, то сопротивление подтягивающего резистора
необходимо уменьшить (это сопротивление зависит от величины максимального
втекающего тока линии DQ конкретного устройства 1-Wire).
Примечательный момент - как уже отмечалось, некоторые устройства 1-Wire
могут использовать так называемое паразитное/фантомное питание (Parasite
I

power) - при котором питание устройства осуществляется от линии данных за


счет встроенного конденсатора, который заряжается в период наличия высокого
уровня напряжения на линии данных. Здесь следует учитывать, что связь с устрой­
ствами, использующими паразитное питание, допусmма только на коротких лини­
ях. На ДJIИННЪIХ линиях могут присутствовать непонятные побочные эффектъ1. По­
этому, если возможно, такого типа питания устройств следует избегать.

7.3.1. Обмен информацией по шине 1-Wire


Рассмотрим, как происходит обмен информацией по шине 1-Wire.
1:] Передача информации возможна только выдачей низкого уровня в линию, т. е.
замыканием 'ее на общий провод. В высокий логический уровень линия вернется
сама из-за наличия подтягивающего резистора (теперь становится понятно, что
наличие внешнего подтягивающего резистора - обязательное условие работы
1-Wire).
1:] Обмен происходит по инициативе ведущего устройства (обычно - микрокон­
троллера).
1:] Обмен информацией начинается с подачи импульса сброса (RESET pulse) на ли­
нию.
1:] Устройства 1-Wire предусматривают «горячее» подключение.

1:] При подключении устройство 1-Wire выдает в линию DQ импульс присутствия


(PRESENCE pulse). Эrот же импульс выдается при обнаружении сигнала RESET.
1:] Обмен информацией ведется так называемыми тайм-слотами - один слот со­
держит один бит информации.
1:] Данные передаются побайтно - бит за битом, начиная с младшего байта. Дос­
товерность даннъIХ (проверка отсутствия искажений) гаранmруется путем под­
счета циклической контрольной суммы (CRC).
Микроконтроллер (МК) формирует импульс RESET, переводя в низкий логический
уровень шину 1-Wire и удерживая ее не менее 480 микросекунд. Затем МК «отпус­
кает» шину, и напряжение возвращается к высокому логическому уровню - время
«отпускания» зависит от емкости линии и сопротивления подтягивающего резисто­
ра. Протокол 1-Wire ограничивает это время диапазоном от 15 до 60 микросекунд,
что и влияет на выбор подтягивающего резистора (на время возврата линии к высо­
кому уровню большее влияние оказывает емкость линии, но, чаще всего, мы изме­
нить ее не можем). Обнар� импульс RESET, ведомое устройство формирует от-
Arduino и 1-Wire. 131

ветный импульс PRESENCE. Для этого устройство «прижимает» линию DQ к «земле>>


и удерживает ее в таком состоянии от 60 до 240 микросекунд. Затем устройство так
же «отпускает» шину. После этого устройству еще дается время для завершения
внутренних процедур инициализации. Таким образом, МК должен приступить
к любому обмену с устройством не ранее, чем через 480 микросекунд после завер­
шения импульса RESET. Соответственно, процедура инициализации, с которой на­
чинается обмен данными между устройствами, длится минимум 960 микросекунд
(рис. 7.2).

МК передает импульс RESET МК находится в состоянии приема


480 µs минимум 480 µs минимум

Устройство передает
импульс PRESENCE
Время реакции 15-60 µs 60-240 µs
1
(
Шина
1-Wire
GND

- МК удерживает низкий

-
уровень
Устройство удерживает
низкий уровень
, Уровень в линии обеспечивает
резистор "подтяжки"

Рис. 7.2. Процедура инициализации

Теперь рассмотрим процедуры обмена битами информации, которые осуществ­


ляются определенными тайм-слотами - жестко лимитированныl\-fи по времени
последовательностями смены уровней сигнала в линии 1-Wire (рис. 7.3).
Различают 4 типа тайм-слотов:
L1 передача « 1 » от МК;
L1 передача «О» от МК;
L1 прием « 1» от устройст�а;
L1 прием «О» от устройства.
Тайм-слот всегда начинает микроконтроллер, «прижимая» шину к «земле». Дли­
тельность тайм-слота находится в пределах от 60 до 120 микросс:жунд.
Между тайм-слотами всегда должен быть интервал не менее 1 микросекунды (оп­
ределяется параметрами ведомого устройства). Тайм-слоты передачи отличаются
от тайм-слотов приема поведением микроконтроллера:
L1 при передаче МК только формирует сигналы;
L1 при приеме МК еще и опрашивает уровень сигнала в линии 1-Wire.
132 Глава 7

Начало Начало
тайм-слота тайм-слота
Тайм-слот передачи "О" Тайм-слот передачи "1"
1 µs < TREc < 00
60 µs < Тх "О"< 120 > 1 µs

Шина
1-Wire
GNo��.J---------------------..i.---J,-....._.._��������-

15 µs 30 µs

Тайм-слот приема
Устройство передает "О" Устройство передает "1"
1 µs < TREc < оо

+
Шина
1-Wire
GNo��.J-__,...._.,;;.�,;;,,.';ы,;,;.,,;.,,���,i__�---J,-.+-,ii.._��������-
_>_1-'-µs
--f3-
I . Зо на ввода
з ач я в МК
:. 1 µs
Зона ввода
_ ___ н е ни · з"Начения в. МК

15 µs 45 µs 15 µs

Рис. 7.З. Процедура обмена битами информации

Тайм-слот передачи «О» заключается просто в «прижимании» шины 1-Wire к «зем­


ле» в течение всей длительности тайм-слота. Передача «1» осуществляется путем
«отпускания>> шины 1-Wire со стороны МК не ранее чем через 1 микросекунду по­
сле начала тайм-слота, но не позже чем через 15 микросекунд. Ведомое устройство
опрашивает уровень в шине 1-Wire в течение временного интервала (показанного
на рис. 7.3 в виде серого прямоугольника), т. е. начиная с 15-й микросекунды от
начала тайм-слота и заканчивая 60-й микросекундой его от начала (для большинст­
ва устройств - около 30-й микросекунды от начала тайм-слота).
Заштрихованная на рис. 7.3 область - это область «нарастания» уровня в шине
1-Wire, которая зависит от емкости линии и сопротивления подтягивающего рези­
стора. Тайм-слоты приема информации отличаются тем, что МК формирует только
начало тайм-слота (так же, как при передаче «1»), а затем управление уровнем ши­
ны 1-Wire берет на себя устройство, а МК осуществляет ввод этого уровня так же
в определенной зоне временных интервалов. Зона эта, как видно из рис. 7.3, довольно
мала. Поскольку заштрихованная область - область неопределенности, то для
ввода микроконтроллеру остается даже не промежуток, а скорее конкретный мо-
Arduino и 1-Wire 133

мент, когда он должен ввести уровень сигнала из линии. Эrот момент времени -
14-я или 15-я микросекунда от начала тайм-слота.
Резюмируем:
(] микроконтроллер начинает тайм-слот, «прижимая)) шину 1-Wire к логическому
«О)) в течение 1 микросекунды;
(] последующий уровень зависит от типа тайм-слота: для приема и передачи «1>>
уровень должен стать высоким, а для передачи «О)) - оставаться низким вплоть
до конца тайм-слота, т. е. от 60 до 120 микросекунд;
(] принимая даннъ1е, МК должен считывать уровень в шине 1-Wire в промежуrке
от 13-й до 15-й микросекунды тайм-слота;
(] микроконтроллер должен обеспечить интервал между тайм-слотами не менее
1 микросекунды (лучше_- больше, максимал�ное значение не ограничено).
Для достижения требуемых временных интервалов надо следовать простым пра­
вилам:
(] все сигналы, которые должен формировать МК, следует формировать по прин­
ципу необходимого минимума длительности (т. е. немного больше, чем указан­
ная минимальная длительность);
(] от устройства следует ожидать сигналов по принципу наихудшего (т. е. ориен­
тироваться на самые худшие варианть1 временных параметров сигнала).

7.3.2. Протокол обмена информацией 1-Wire


Каждое устройство 1-Wire обладает уникальным идентификационным 64-битным
номером, программируемым на этапе производства микросхемы:
С] первые 8 битов - номер серии устройства (список некоторых кодов семейств
1-Wirе-устройств приведен в табл. 7.1);
С] следующие 48 битов - уникальный серийный номер;
С] последние 8 битов - СRС-код предыдущих 56 битов информации.
Фирма-производитель гарантирует, что не найдется двух микросхем с одинаковым
идентификационным номером. Нетрудно посчитать, ·что устройств одного типа
может быть выпущено 281 474 976 710 655 (десятичное представление
OxFFFFFFFFFFFF - 48 битов, или 6 байтов идентификационного номера).
Предположим, что на шине 1-Wire имеется более одного устройства. В этом случае
перед микроконтроллером встают две проблемы: определение количества имею­
щихся устройств и выбор (адресация) одного конкретного из них для обмена дан­
ными., Номера некоторых устройств наносятся прямо на корпус микросхем (напри­
мер, для ключей-таблеток - iButton), а номера других можно определить при по­
моIЦИ специальных программ или устройств. Итак, пусть мы знаем номера всех
устройств 1-Wire на шине. Алгоритм работы с ними следующий:
1. Микроконтроллер посьmает импульс RESET, и все имеющиеся устройства выда­
ют PRESENCE.
134 Глава 7

2. Микроконтроллер посьшает в шину команду, rсоторую принимают все устройст­


ва. Определено несколько общих команд дЛЯ всех типов устройств 1-Wire, есть
так же и команды, уникальные дЛЯ отдельных типов устройств.
3. После того, как микроконтроллер вьщаст команду READ RОМ, от устройства по­
ступит 8 байтов его собственного уникального адреса - микроконтроллер дол­
жен их принять. Любая процедура обмена данными с устройством должна бьпъ
завершена полностью либо прервана посьшкой сигнала RESET.
4. Если отправлена команда МАтсн RОМ, то после нее микроконтроллер должен пе­
редать 8 байтов адреса конкреrного устройства, с которым будет осуществлять­
ся последующий обмен данными.
5. Приняв эту команду, каждое устройство сравнивает передаваемый адрес со сво­

и
им собственным. Все устройства, адрес которых не совпал, прекращают ,анализ
вьщачу сигналов й линии 1-Wire, а опознавшее адрес устройство продолжает
работу. Теперь все данные, передаваемые МК, будут попадать только к этому
«адресованному» устройству.
6. ,Если устройство на шине единственное - можно ускорить процесс взаимодей­
, ствия с ним при помощи команды SKIP RОМ. Получив эту команду, устройство
сразу считает адрес совпавшим, хотя никакого адреса за этой командой не сле­
дует. Некоторые процедуры не требуют приема от устройства никаких данных,
в этом случае команду sкrP RОМ можно использовать дЛЯ передачи какой-то ин­
формации сразу всем устройствам - например, дЛЯ одновременного запуска
цикла измерения температуры несколькими датчиками-термостатами типа
DS18S20.
Общие команды дЛЯ всех типов устройств 1-Wire представлены в табл. 7.1.

Таблица 7.1. Общие командь, для всех типов устройств 1-Wi,e

Команда Значение Описание


байта
SEARCH ROM OxFO Поиск адресов - используется при универсальном алгоритме
определения количества и адресов подкл�ченных устройств
READ RОМ ОхЗЗ Чтение адреса устройства - используется для определения
адреса единственного устройства на шине
МАТСН RОМ Ох55 Выбор адреса - используется для обращения к конкретному
адресу устройства из многих подключенных
SKIP RОМ ОхСС Игнорировать адрес - используется для обращения к единст-
венному устройству на шине, при этом адрес устройства игно-
рируется (можно обращаться к неизвестному устройству)

Прием и передача байтов всегда начинается с младшего бита. Порядок следования


байтов при передаче и приеме адреса устройства так же ведется от младшего
к старшему. Порядок передачи другой информации зависит от конкретного уст­
ройства.
Arduino и 1-Wire 135

Алгоритм поиска устройств 1-Wire следующий:


1. Поиск начинается с импульса RESET от ведущего устройства и принятия
PRESENCE от ведомых.
2. Затем посьmается 1 байт команды:
• OxFO- осуществляется поиск всех устройств на линии;
• ОхЕС- поиск среди устройств, находящихся в состоянии тревоги (alar.m
state).
3. Устройства отправляют первый бит своего уникального номера. Если несколько
устройств передают свой бит одновременно, результирующий бит на линии по­
лучится как результат операции логического И (AND).
4. Следующий бит, который отправляют устройства,- это дополнение первого
бита (если первый бит бьm 1, то будет О и наоборот: если бьm О- теперь бу­
дет 1). На основании этих двух битов ведущее устройство может сделать вывод
о первом бите устройств на линии.
5. Далее микроконтроллер отправляет принятый бит назад. И теперь продолжат
работу только те ведомые устройства, у которых этот бит установлен. Если же
устройство такого бита не имеет, оно должно перейти в режим ожидания до сле­
дующего сигнала RESET.
6. Такая «двубитная передача» пов1'оряется для всех следующих 63 битов ROM.
7. Все устройства на линии, кроме одного, перейдут в состояние ожидания, а код
ROM этого единственного устройства будет известен.

7 .4. Arduino
и цифровой датчик температуры DS18B20
7.4.1. Цифровой датчик температуры DS18B20
DS18В20 (рис. 7.4)- цифровой термометр с программируемым разрешением от 9
до 12 битов, способный сохранять данные замеров в памяти EEPROM прибора.
DS18В20 обменивается данными по шине 1-Wire и при этом может быть как един­
ственным устройством на линии, так и работать в группе. Все процессы на шине
управляются центральным микропроцессором.
Диапазон измерений датчика: от -55 до,+125 ° С с точностью О,5° С в диапазоне
от-10 до +85 °С. В дополнение DS18B20 может питаться напряжением линии дан­
ных (так называемое питание от паразитного источника) при отсутствии внешне­
го источника напряжения.
Каждый датчик типа DS 18В20 имеет уникальный 64-битный последовательный
код, который позволяет общаться с множеством датчиков DS18В20, установленных
на одной шине. Первые 8 битов- код серии (для DS18B20- 28h), затем 48 битов
уникального номера и в конце 8 битов СRС-кода. Такой принци;п позволяет ис-
136 Глава 7

QЮТТОМ Vll!W)
ТО-92
(DS18В20)
Рис. 7.4. Цифровой да"Nик температуры DS18B20

пользовать один микропроцессор, чтобы контролировать множество датчиков


DS18B20, распределенных по большому участку.
Характеристики датчика DS18S20:
C:J интерфейс 1-Wire;
C:J измеряемая температура: от-55 до+125 °С;
C:J точность 0,5 °С в диапазоне от-1О до+85 °С;
C:J температура считывается 9-ю битами данных;
C:J время на конвертацию температуры-750 мс (максимальное).
Данные о температуре хранятся в оперативной памяти датчика (рис. 7.5). Память
состоит из оперативной ROM и энергонезависимой EEPROM:
C:J первые два байта-содержат данные об измеренной. темп�ратуре;
C:J третий и четвертый байтъ1 хранят верхний (тн) и нижний (тL) пределы темпера­
туры;
C:J пятый и шестой-не задействованы;
C:J седьмой и восьмой- байты-счетчики. Они могут использоваться для более
точного измерения температуры;
C:J девятый байт хранит СRС-код предыдущих восьми.
Кроме общих для всех типов 1-Wirе-устройств команд, пред�тавленных в табл. 7.1,
датчик может выполнять следующие команды:
C:J Ala:пn search [EChJ-операция этой команды идентична операции поиска адре­
сов [ FOhJ, за исключением того, что в данном случае ответят только те датчики,
Arduino и 1-Wirв 137

.}-��:;;j
j
SCRATCНPAD (Power-up State)
Ь:,,1е О T�pcra�; LSB (50h)__
byte I Temperartt.re MSB (OSb)
----------------------- EEPROM
f ----------------------
byte 2 Тн Rcgister or tJser BJ!�----� <114t-----1.,.. l Тн Register or tJ�er Byte i
byte 3 ТL Register or User Byt:_3�----� 4 • [i�-�-�!-�=te=r _or_�--:!"=B_yt!}....
byte 4 Contigiiration Register* 14 " L C'onfiguration Register

:�:: ::::: �=:- ---- --� ----- -- -- -- --


--=��- -��:
)

:: ; ��:�� (}=� �- J
•Сосю,�нме� вкnюченмн пит- эввж:ит от 3Н8'18Нмй, сохраненноrо в EEPROM

Рис. 7.5. Карта памяти DS18B20

у которых при последнем измерении температура вышла за установленные пре­


делы (выше тн или ниже тL);
(] Convert т [44hJ - конвертировать температуру. Датчик произведет измерение
и запись данных о текущей температуре. Если ведущее устройство будет за этой
командой слать тайм-слоты чтения, то пока конвертация не закончена, DS 18S20
будет выдавать в линmо «О», а после завершения конвертации «1»;
(] Write scratchpad [4EhJ - запись в память. Эта команда позволяет записать
3 байта в память датчика. Первый байт запишется в тн, второй - в TL, а третий
байт запишется в пятый байт памяти - это байт конфигурации;
(] Read Scratchpad [BEhJ - чтение памяти. Команда позволяет нам считать память
датчика. В ответ на эrу команду датчик вернет 9 байтов своей памяти, начиная
с О-го байта TEМPERATURE LSB и заканчивая восьмым - CRC;
(] сору scratchpad [48hJ - копировать память. Датчик скопирует содержимое
ОЗУ - тн и TL в EEPROM.
Для ПО,!JУЧеНИЯ от датчика данных о температуре необходимо вьщать следующую
последовательность команд:
1. Произвести RESET и поиск устройств на линии 1-Wire.
2. Выдать команду Ох44, чтобы запустить конвертацmо температуры датчиком.
3. Подождать не менее 750 мс.
4. Вьщать команду охвЕ, чтобы считать ОЗУ датчика (данные о температуре будут
в первых двух байтах).
Датчик может запитываться двумя способами: внешним питанием (три провода)
или паразитным (питание от шины, два провода). Схема подключения к Arduino
датчика, запитанного от внешнего источника, представлена на рис. 7.6.
138 Глава 7

DS18820 Arduino
Rx
GND DQ VDD Тх АО
D2 А1
2 з 03 А2
АЗ
05 А4
R1 06 А5
4,11<
07 А6
DS А7
D9
D10 +З.ЗV
011
D12 +5V
D13
GND

Рис. 7.6. Подключение кArduino датчика DS18B20

7 .4.2. Использование библиотеки OneWire


для получения данных температуры с"датчика DS18B20
Дпя работы с датчиками по интерфейсу 1-Wire можно использовать библиотеку
OneWire.
ЭЛЕКТРОННЫЙ АРХИВ
Библиотеку OneWire вы найдете в папке arduino_libraries\OneWire соnровождающеrо
книrу электронноrо архива.
Скетч получения данных с датчика температуры DS 18В20 и вывода данных в по­
следовательный порт с помощью библиотеки OneWire представлен в листинге 7.1.

Jinclude <OneWire.h>
OneWire ds(lO); // линия 1-Wire будет на pin 10

void setup(void)
{
. Serial. begin( 9600);
}

void loop(void)
{
byte i;
Arduino и 1-Wire 139

byte present = О;
byte data[l2];
byte addr[8];

if ( !ds.search(addr))
//Serial.print("No more addresses.\n ,.');
ds.reset_search();
return;

if ( OneWire::crc8( addr, 7) != addr[7])


Serial.print("CRC is not valid!\n");
rettirn;

if ( addr[O] != Ох28) {
Serial.print("Device is not а DS18B20 family device.\n");
return;

ds.reset();
ds.select(addr);
ds.write(Ox44,l); // запускаем конвертацию

delay(750); // ждем 750 мс

present = ds.reset();
ds.select(addr);
ds.write(OxBE); // считываем ОЗУ датчика

for ( i = О; i < 9; i++) // обрабатываем 9 байтов


data[i] = ds.read();

// высчитщэаем температуру :)
int HighВyte, LowByte, TReading, Tc_lOO;
LowByte = data(OJ;
HighВyte = data[l];
TReading = (HighВyte << 8) + LowByte;
Serial.print(Teпp/16);
Serial.print(".");
Serial.print(((Тепр%16) *100)/16);
Serial.println();
}

Вывод показаний датчика температуры DS 18В20 в последовательный порт показан


на рис. 7.7.
140 Глава 7

Т • 19 41

Т • 19.43

1 • 19 43

Т • 1� 43

Т • 19.43

Т • 1g 50

Т • 19 43

1 • 19.5()

Т • L9 50

Т "19 50

Т • 19 50

Т • 19.�

Т • 19 50

Рис. 7.7. Вывод показаний датчика DS18820 в посnедовательный порт

В главе 8 мы рассмотрим использование датчика DS 18В20 в проекте сервера


Internet of Thing, собирающего данные с Еthеmеt-модулей различных датчиков,
подкmоченных к плате Arduino.
ГЛАВА 8

Сервер для сбора данных


с Ethernet-мoдyлeй датчиков,
установленных на Arduino
В этой главе мы создадим веб-сервер для сбора и отображения данных с Еthеmеt­
модулей датчиков, сопряженных с платами Arduino. Каждый модуль представляет
собой плату Arduino, состыкованную с платой Ethemet Shield, к которой подключе­
ны несколько датчиков. Будут использованы следующие датчики:
1:1 температуры DS18В20;
1:1 влажности DНТI 1 (или DHT22);
1:1 освещенности BHI 750;
1:1 движения HC-SR501;
1:1 звука FC-04.
На каждом модуле установлен веб-сервер, отдающий показания в формате JSON
при обращении к нему с центрального сервера (может быть использован любой
компьютер). На центральном сервере можно посмотреть отображение собираемых
с нескольких модулей данных в графическом и табличном виде.
Датчик измерения освещенности BHI 750 мы рассмотрели в главе 6, датчик темпе­
ратуры DS18В20 - в главе 7. Далее мы кратко познакомимся с другими датчиками,
задействованными в этом проекте.

8.1. Датчики влажности DHT11 и DHT22


Датчики DНТI 1 (рис. 8.1) и DHT22 (рис. 8.2) не отличаются высоким быстродейст­
вием и точностью, однако могут найти свое применение в радиолюбигельских про­
ектах из-за своей невысокой стоимости. Конструкция этих датчиков основана на
емкостном датчике влажности и термисторе. Кроме того, они содержат в себе про­
стенький АЦП для преобразования аналоговых значений влажности и температуры
в их цифровое представление.
142 Глава В

Датчики DНТ имеют по 4 вывода стандарта 2,54 мм:


Q 1-VCC (питание 3-5 В);
Q 2-DАТА(вывод данных);
Q 3-не используется;
Q 4-GND («земля»).

Рис. 8.1. Датчик влажносrи DHT11 Рис. 8.2. Датчик влажносrи DHT22

Протокол обмена - однопроводный, по структуре он весьма схож с протоколом


датчика температуры DS18В20, но с важными оговорками:
Q датчики DНТ не умеют работать в «паразитном» режиме (питание по линии
данных);
Q каждый датчик температуры DS18В20 имеет персональный идентификатор, что
дает возможност� подключения нескольких таких датчиков к одному выводу
Arduino. Однако у датчщов DHT такой возможности нет- один датчик ис­
пользует строго один цифровой вывод.
Общие характеристики датчиков:
Q DHТll:
, • , весьма низкая стоимость;
• питание и 1/0: 3-5 В;
• определение влажности: 20-80% с точностью 5%;
• определение температуры 0-50 °С с точностью 2%;
• частота опроса не более 1 Гц{не более одного раза в 1 сек.);
• размеры 15,5х12х5,5 мм;
Q DHT22:
• низкая стоимость;
• питание и 1/0: 3-5 В;
Сервер для сбора данных с Еthетеt-модулей датчиков, установленных на Arduino 143

• определение влажности: 0-100% с точностью 2-5 %;


• определение температуры: от -40 до+125 °С с точностью ±0,5 °С;
• частота опроса не более 0,5 Гц (не более одного раза в 2 сек.);
• размеры 15,lx25x7,7 мм.
Сенсор DHT22 имеет JIY'ПIIИe, чем DНТl1 характеристики, но более высокую стои­
мость.

8.1.1. Подключение датчиков DHT к Arduino


Рекомендуемая схема подключения датчиков DHT к Arduino (рис. 8.3) содержит
обязательный для однопроводных линий резистор-подтяжку к VCC и, в качестве
опции, рекомендуется конденеатор (фильтр по питанию между VCC и GND).

VJ "о V,J р

5К1 1Pln

MCU DATA 2Pln DHT


.4Pin

...
GND

Рис. 8.3. Схема подключения к Arduino

Если к вам в руки попали DHTl1 или DНТ22 на небольшой плате, можно подклю­
чать их к Arduino напрямую - резистор и конденсатор там уже и так есть.

8.1.2. Библиотека DHT


Для работы Arduino с датчиками DHl1 и DН22 существует готовая библиотека
(DHT), скачать которую можно со страницы: https://github.com/adafruit/DHT­
sensor-library.
ЭЛЕКТРОННЫЙ АРХИВ
Библиотеку DHT вы найдете в папке arduino_libraries\DHT сопровождающеrо книrу
электронноrо архива.
Скетч получения данных с датчика температуры и влажности DНТ22 и вывода по­
лученных данных в последовательный порт представлен в листинге 8.1.
Для использования в этом скетче датчика DНТl1 необходимо закомментировать
строку:
//#define DHTTYPE DHT22 // DHT 22 (АМ2302)
144 Глава 8

и раскоммеIПИровать:
#define DHTTYPE DHTll // DHT 1�
Вывод показаний датчика темпера'I)'J)Ы и влажности DHT22 в последовательный
порт показан на рис. 8.4.

зt.70 • Tap•ra1:цre: tS.70 •С


Эt.'10 t ,....... r:-.ц-r•: ZS.'10 •С
ЭZ.70 t T-,.•r�цr•: 2S.70 •с
ЗZ.70 \ •Te.per11t;uжe:
ZS.70 "С
З!.60 t т-...rкure: tS.70 •с
эz.,о. T41111:'era1:цr•:
:Z5.70 '"С
ЗZ,60 t т-,..rм,цrе; :Z5.70 --с
эz.,о. С
Т8111181<8Ш8: 2:S.'10 .-с
32:.10, Tw,per-.we•� 2:s.•o •с
ЭZ.60 t T-.p•rм:.ur•: 2:S.40 •с
�.,о• т-.,еrкuж•: Z.S.40 •с
:.IZ,60 t тa»p'erour•.:! ZS.40 •с
ЭZ.60 t т...,....,v.r•; zs.эo •с
и:.,о-, T-ai•r•w.•o Z.S.!10 •с
ЭZ.60 t т-,еrкцr•: ts.,o •с

Рис. 8.4. Вывод данных с датчика в монитор посnедQВательного порта

#include "DHT.h"
#define DHTPIN 2 // пин подключения
//#define DHTTYPE DHTll // DHT 11
#define DНТТУРЕ DHT22 // DHT 22 (АМ2302)
//#define DHTTYPE DHT21 // DHT 21 (АМ2301)

DHT dht(DHTPIN, DHTTYPE);

void setup() {
Serial.begin(9600);
Serial.println("DHTxx test!");
dht.begin();
}

void 1,оор() {
// Reading ternperature or humidity t�kes about-250 milliseconds!
// Sensor readings may also Ье up to 2 seconds 'old'
// (its а very slow sensor)
Сервер для сбора данных с Еthетеt-модулей датчиков, установленных на Arduino 145

float h = dht.readНшnidity();
float t = dht.readTemperature();

// check if returns are valid, if they are NaN (not а numЬer)


// then something went wrong!
if (isnan(t) 11 isnan(h)) {
Serial.println("Failed to read from DHT");
} else {
Serial.print("Humidity: ");
Serial.print(h);
Serial.print(" %\t");
Serial.print("Temperature: ");
Serial.print(t);
Serial.println(" *С"·);

8.2. Модуль датчика движения HC-SR501


HC-SR501 (рис. 8.5)- мqдуль, состоящий из PIR-ceнcopa и схемы управления.

ПОЯСНЕНИЕ: PIR-SENSOR
PIR-sensor переводится с английского как Pyroelectric (Passive) lnfraRed sensor -
пироэлектрический (пассивный) инфракрасный сенсор. Пироэлектричество - это
свойство генерировать оnределенное электрическое поле при облучении материала
инфракрасными (тепловыми) лучами. И поскольку тело человека излучает тепло, РIR­
датчики позволяют обнаруживать движение людей в контролируемой зоне. Такие дат­
чики маnы по размеру, недороги, имеют низкое энергопотребление, просты в исполь­
зовании и не изнашиваются.

Рис. 8.5. Модуль датчика движения (PIR Motion sensor) HC-SR501

В модуле датчика движения HC-SRSO 1 в качестве органов настройки используются


два потенциометра и перемычка (рис. 8.6):
n параметр Delay Time Adjust, регулируемый одним из потенциометров, опреде­
ляет время, в течение которого при обнаружении движения на контакте ОUТ
будет удерживаться высокий уровень (5-300 сек.);
146 Глава 8

С] параметр Distance Adjust определяет чувствительность датчика - центр кон­


тролируемой зоны: от 3 до 7 м;
СОВЕТ
Не стоит располагать РIR-датчики в местах, где температура меняется быстро. Это
приведет к тому, что датчик не сможет обнаруживать появление человека в контроли­
руемой зоне, а станет выдавать множество ложных срабатываний.

С] режим работы модуля задается перемычкой, обеспечивающей установку одного


из двух режимов: режима Н или режима L. На рис. 8.6 в модуле установлен ре­
жим Н. В этом режиме при срабатывании датчика несколько раз подряд на его
выходе (на OUT) остается высокий логический уровень. В режиме L при каж­
дом срабатывании датчика на выходе модуля появляется отдельный импульс.

-111.
VCC !И2VDC ::::::;-,
OUТ(>
>V�

Рис. 8.6. Элементы настройки модуля датчика движения HC-SR501

Основные параметры модуля датчика движения HC-SR501 приведены в табл. 8.1.

Таблица 8.1. Основные параметры модуля HC-SR501

Параметр Значение
Размеры.см примерно 3,2х2,4х 1,8
Напряжение питания, В постоянное 4,5-20
Ток на выводе OUT, мА < 60
Напряжение на выходе Высокие и низкие уровни 3,3 В в ТТL-логике
Дистанция обнаружения, м З-7(настраивается)
Угол обнаружения до 120-140 °(в зависимости от конкретного датчика и линзы)
Длительность импульса 5-200(настраивается)
при обнаружении, сек.
Сервер для сбо ра данных с Еthетеt-модулей датчиков, установленных на Arduino 147

Таблица 8.1 (окончание)

Параметр Значение
Время блокировки до следую- 2,5 (но можно изменить заменой SМD-резисторов)
щего замера, сек.
Рабочая температура, •с от-20до +80
Режим работы L - одиночный захват, Н - повторяемые измерения

Схема подключения модуля датчика движения HC-SR501 к плате Arduino показана


на рис. 8.7.

Рис. 8.7. Схема подключения модуля HC-SR501 к плате Arduino

Итак, устанавливаем перемычку в режим работы L и подаем питание. Необходимо


подождать примерно 20-40 сек. (для некоторых модулей и до 60 сек.) - в это вре­
мя датчик калибруется. Теперь, как только датчик зафиксирует движение, на вход
Arduino поступит высокий уровень, который будет держаться время, установленное
потенциометром Delay Time Adjust. В листинге 8.2 'приведен скетч для подсчета
срабатываний РIR-датчика.

int count_motion=O; // счетчик срабатываний

void setup()
{
attachinterrupt(O,motion,RISING); // запустить прерывания (pin D2)
}
148 Глава В

void loop {)
{; }

// обработка прерывания ИК датчика движения


void motion {)
{
detachinterrupt{O);
count_motion++;
attachinterrupt(O,motion,RISING);
}

8.3. Модуль датчика звука FC-04


Датчик звука FC-04 (рис. 8.8) построен на основе микрофона и имеет регулировку
чувствительности. Выход датчика цифровой - при -превышении установленного
звукового порога на выходе датчика устанавливается логическая, единица.

Рис. 8.8. Датчик звука FC-04

Датчик звука FC-04 измеряет интенсивность звука и предназначен для определения


факта наличия звука, но он не может определить его уровень и звуковые частоты.
Датчик МОЖНО Применить, например, ДЛЯ ГОЛОСОВЫХ JJЫКJПОЧателеЙ, В ТОМ ЧИСЛе
с расшифровкой кодовой последовательности звуков (например, три хлопка в ла­
доши) определителя лая собаки, если она остается одна в квартире в течение рабо­
чего дня, сигнализации о других посторонних звуках в квартире.
Датчик звука FC-04 представляет собой печатную плату с установленными на ней
микрофоном, микросхемой LM393, а также несколькими другими электронными
комnонентами. Основные характеристики датчика:
С] напряжение питания звукового датчика: от +2,7 до +5,5 В;

C:J ток потребленuя сенсора звука: 1,4 мА;


С] интерфейс или. тип выходного сигнала датчика звука: цифровой TTL;

С] цифровой выход сигнала: рабочее напряжение на выходе 5 В;

С] подкmочается н�посредственно к микроконтроллеру;


Сервер для сбора данных с Еthетеt-модулей датчиков, установленных на Arduino 149

l:J рабочая темпераrура: от -30 до +85 °С;


l:J размеры модуля звука (длина х ширина х высота): 47х18,4х10 мм;
l:J вес модуля: 3 грамма;
l:J диаметр отверстия для монтажа датчика: 3 мм.
Звуковой сенсор снабжен специальным штырьковым разъемом (mпа «папа») для
подключения к плате микроконтроллера Arduino. Для регулировки чувствитель­
ности на плате имеется потенциометр.
В лисmнге 8.3 представлен скетч для определения срабатьmания датчика зву�tа.
При срабатывании зажигается светодиод, подкточенный к выводу 13 Arduino.

const int SensorPin = 9; // номер pin для датчика


const int ledPin = 13; // номер led pin
// переменные, изменяемые в процессе работы:
int SensorState = О; // переменная для чтения
// состояния датчика

void setup()
{
pinМode(ledPin, OUТPUT); // начальная установка led pin
;;·как выхода (output)
pinМode(SensorPin, INPUT); // установка pin датчика как входа (input)
)
void loop()
{
SensorState = digitalRead(SensorPin); // Чтение состояния датчика:

if (SensorState == HIGH) // если на выходе 1


{
digitalWrite(ledPin, HIGH); // включить светодиод
delay(200); // Задержка 0.2 сек
)
else // иначе - выключить светодиод

digitalWrite(ledPin, LOW);
delay(200);
)

8.4. Ethernet-мoдyль датчиков на Arduino


Еthеmеt-модуль датчиков (рис. 8.9) состоиr из платы Arduino, платы Ethernet Shield
и пяти подключенных к ним датчиков: движения HC-SR501, темпера'I)'ры
DS18В20, звука FC-04, освещенности BHl 750 и влажности DНТl 1.
150 Глава В

НC·SR501 DS18820

An:luino
Rt
т�
r.-...---tD2
03
04

..----------tD8
05
1:)$
�----------------01

D10
DH
012
D1З

Рис. 8.9. Электрическая схема Ethernet-мoдyля даТ"lиков

На каждом модуле установлен простейший веб-сервер. Каждый модуль имеет уни­


кальный IР-адрес й свой уникальный порт обращения. При обращении по НТТР
к модулю он отдает в формате JSON следующие данные датчиков температуры,
влажности, освещенности, количества срабатываний датчика движения и датчика
звука после последнего обращения:
{«rneteo»: {«ternpl»:«25.31»,«hurnidityl»:«35.00»,«luxl»:«10»,«soundl»:«O»,
«rnotionl»:«О»} }
Содержимое скетча для Еthеmеt-модуля датчиков представлено в листинге 8.4.

// подключение библиотек
#include <SPI.h>
·#include <Ethernet.h>
#include <OneWire.h>
#include <Wire.h>
#include <BH1750.h>
// объекты для датчиков ВН1750, DHTll, DS18B20
ВНl750 lightl;
#include "DHT.h"
DHT dht(8, DHTTYPE);
OneWire ds(7); // on pin 7
Сервер для сбора данных с Еthетеt-модулей датчиков, установленных на Arduino 151

!/ датчик (для каждого датчика назначить уникальный iр-адрес и порт)


byte mac[] = { ОхАА, ОХВВ, ОхСС, OxDD, ОхЕЕ, OxFl };
byte ip[] == { 192, 168, 1, 121 };
EthernetServer server(lOOOl);
byte my_addr[8] = {0x28,0x2A,Ox78,0x65,5,0,0,0xl0};
// переменные для подсчета срабатываний датчика движения и датчика звука
int count_motion=O;
uintlб_t count_sound=O;

void setup() {
Serial.begin(9600);
Serial.println("start");
Ethernet.begin(mac, ip);
// запуск сервера
server.begin();
Serial.print("server is at ");
Serial.println(Ethernet.localIP());

Wire.begin();
lightl.begin();
// прерывание для РIR-датчика
attachinterrupt(O,motion,RISING);

void loop ()

EthernetClient client = server.availaЬle();


if (client) {
boolean currentLineisBlank = true;
while (client.connected()) {
if (client.availaЬle()) {
char с = client.read();
// ожидание конца запроса
if (с == '\n' && currentLineisBlank)
{
// отправить стандартные header
client.println("HTTP/1.1 200 ОК");
client.println("Content-Type: text/html");
client.println();
// отправка JSОN-данных
client.print('{');
// данные температуры
client.print('"');client.print("meteo");client.print('"');
client.println(":");
client.print('{');
int Temp=get_temp();
client.print('"');client.print("templ");client.print(.'"');
client.print(":");
152 Глава 8

client.print( "");client.print(Temp/16);
client.print(".");
client.print(((Ternp%16) *100)/16);client.print('"');client.print(',');
// данные влажности
float h = dht.readНumidity();
client.print('"');client.print("humidityl");client.print('"');
client.print(":");
client.print('"');client. print(h); client. print('"');
client.print(',');
// данные bhl750
uintlб_t lux = lightl.readLightLevel();
client.print( "'');client.print("luxl");client.print('"');
client.print(":");
client.print('"');client.print(lux);client.print('"');
client.print(',');
// sound
client.print( "'');client.print ("soundl") ;client.print ('"');
client.print(":");
client.print('"');client.print(count_sound);client.print('"');
client.print(',');
count_sound=O;
// датчик движения
client.print('"');client.print("motionl");client.print('"');
client.print(":");
client.print('"');client.print(count_motion);client.print('"');
client.println("}");
client.print("}");
count_motion=O;
break;

if (с =>= '\n')
'(currentLineisBlank true;}
else if (с != '\r')
{currentLineisBlank false;}

// пауза, чтобы данные ушли


delay(l);
// закрыть Еthеrnеt-соединение
client.stop();
}
// sound
if(analogRead(AO)<SOO)
'{count_sound++;delay(lOOO);}

// получение температуры датчика


int get_temp()
Сервер для сбора данных с Еthетеt-модулей датчиков, установленных на Arduino 153

byte i;
byte present = О;
byte data[12];
byte addr[ 8 ];
int Ternp;

ds.reset();
ds.select(my_addr);
ds.write(Ox44,l);
delay(lOOO); // пауза 750 цс
present = ds.reset();
ds.select(my_addr);
ds.write(OxВE); 71 команда чтения
for ( i = О; i < 9; i++)
data[i] = ds.read();

Temp=(data[l]<<B)+data[O];
Temp=Temp;
return Temp;

// обработка прерывания ИК датчика движения


void motion()

detachinterrupt(O);
count_motion++;
attachinterrupt(O,motion,RISING);
}

Все Еthеmеt-модули датчиков квартиры/дома соединены в единую локальную сеть.


В этой же сети настроен описанный в следующем разделе сервер для сбора данных
с устройств и представления данных в виде графиков и таблиц, а также для ото­
бражения данных в виде виджетов на плане дома или квартиры.

8.5. Сервер сбора данных


На сервере (Apache, mySQL, php) локальной сети для сбора данных установлен
сайт, осуществляющий опрос Еthеmеt-модулей датчиков по cron каждые 5 минут.
Данные собираются в базу данных mySQL, где также хранятся настройки всех
модулей, задействованных в системе (рис. 8.1О).
Сайт написан на НТМL5 с элементами canvas, что обеспечивает вывод виджетов на
плане объекта. Отправка информации на сервер осуществляется без перезагрузки
страницы (использована технология AJAX и библиотека xajax). Вид объектов
с виджетами (средние значения температуры, влажности, освещенности) показан на
рис. 8.11.
154 Глава В

Рис. 8.1 О. Данные модулей в базе mySQL

Рис. 8.11. Вид объектов с виджетами на плане дома


Сервер для сбора данных с Еthетеt-модулей датчиков, установленных на Arduino 155

После авторизации (рис. 8.12) ссылки с виджетов становятся доступны в режиме


администратора, позволяющем осуществлять просмотр данных с возможностью
выбора объекта (квартира, дача, гараж), подобъекта (1 этаж ...), комнаты и даты
считанных данных (рис. 8.13 ).

Рис. 8.12. Активация ссылок с виджетов в режиме администратора

Рис. 8.13. Выбор настроек для просмотра данных, считанных с модулей

Для температуры, влажности, освещенности строятся соответствующие графики


(рис. 8.14). Для датчиков звука и датчиков движения- таблицы с количеством
срабатываний между запросами (рис. 8.15). При построении графиков и таблиц ис­
пользуется API Google Chart.
156 Глава 8

Рис. 8.14. Данные в виде графиков (представлены данные замеров температуры с да�ика DS18820)

Рис. 8.15. Данные в виде таблиц (представлены данные срабатывания да�ика движения HC-SR501)

ЭЛЕКТРОННЫЙ АРХИВ
Скетч, соответствующий листинrу 8.4, можно найти в файле arduino_scetches\_081
_08_04.ino, а файлы сайта и дамп базы данных сервера - в папке arduino_scetchesl
_08\web сопровождающего книrу электронного архива.
ГЛАВА 9

Обмен данными
с помощью платы GPRS/GSM Shield
Плата Arduino GPRS/GSM Shield предоставляет нам возможность использовать для
удаленного приема и передачи данных в проектах Arduino сеть мобильной GSМ­
связи. Осуществить это можно тремя способами:
О используя отправку/прием коротких текстовых сообщений (SMS);
О отправкой голосовых (аудио) команд на основе технологий CSD (стандартная
технология передачи данных в сети GSM) и/или DTМF (двухтональный много­
частотный аналоговый сигнал, используемый для набора телефонного номера);
О используя пакетную передачу данных на основе технологии GPRS.
Рассмотрим один из вариантов платы GPRS/GSM Shield - Quad-Band GPRS Shield
на основе чипа SIМ900 (рис. 9.1).
Основные характеристики GSМ-модуля SIM900 платы Quad-Band GPRS Shield:
О четыре диапазона GSM: 850/900/1800/1900 МГц;
О класс передачи данных: GPRS multi-slot class 10/8;

Рис. 9.1. Плата S1M900 Quad-Band GPRS Shield


158 Глава 9

LJ соответствие стандарту GSM фазы 2/2+;


LJ класс мощности 4 (2 Вт в диапазонах 850/900 МГц);
l:J класс мощности 1 (1 Вт в диапазонах 1800/1900 МГц);
l:J управление АТ-командами (GSM 07.07, 07.05 и фирменные АТ-команды
SIМCom);
l:J аудиокодеки НR, FR, EFR, АМR, подавление эха;
l:J скорость передачи данных по технологии CSD: до 14,4 Кбит/с;
l:J РРР-стек;
l:J встроенный стек TCP/IP, UDP/IP;
l:J протоколы НТТР и FTP;
l:J протокол защищенных сокетов SSL;
l:J декодирова�е DТМF-тонов;
l:J eMail - формирование и отправка электронных писем посредством АТ-команд;
l:J SMS Autorun - исполнение АТ-команд, полученных по SMS от определенного
абонента;
l:J встроенная память для пользовательских данных: 2,5 Мбайт;
l:J ММS - формирование, дополнение пользовательскими файлами и отправка
с помощью АТ-команд;
l:J АМR play - воспроизведение аудиофайлов в динамик или в сторону удаленно-
го абонента;
,l:J функция обнаружения глушения сигнала (Jamming Detection);
l:J РОТА - обновление прошивки модуля по беспроводному каналу;
l:J Easy Scan - получение информации об окружающих базовых станциях без под­
ключения SIМ-карты;
l:J PING - проверка доступности адреса в Интернете посредством обмена IСМР­
пакетами.
Особенности платы S1М9ОО Quad-Band GPRS Shield:
l:J ·совместимость с Arduino Mega;
l:J наличие слота для карт SD ( включение/отключение с помощью перемычки);
l:J гнездо наушников «два в одном»;
l:J программное и аппаратное обеспечение последовательного порта - может об­
щаться с Arduino через последовательный щ>рт программного обеспечения
(D2/D3) или последовательный порт (DO/Dl);
l:J интерфейс FTDI;
l:J наличие слота батарейки для часов реального времени (RTC);
l:J 1О цифровых входов/выходов GPIO;
Обмен данными с помощью платы GPRSIGSM Shield 159

t:J 2 выхода ШИМ;


2
t:J интерфейс I C.
Плату SIМ900 Quad-Band GPRS Shield можно включить двумя способами: аппарат­
ным (кратковременное нажатие кнопки PWRКEY) и программным (используется
выход D7 Arduino).

9.1. Отправка и получение SМS-сообщений


В этом примере мы каждые 30 минут будем с помощью платы GSM/GPRS Shield
отправлять на определенный телефонный номер показания аналогового датчика
температуры LM335, подсое.т.�;иненного к выводу АО платы Arduino.
Установим SIМ-карту в соответствующий слот платы GSМ/GPRS Shield, а саму
плату GSМ/GPRS Shield состыкуем с Arduino. С помощью джамперов соединим
контакты для работы через SoftwareSerial-эмyляцию. Схема соединений представ­
лена на рис. 9.2. Содержимое скетча для отправки SMS приведено в листинге 9 .1.

Рис. 9.2. Схема подключения модуля GSM/GPRS Shield и датчика LM335


160 Глава 9

// подключение библиотеки SoftwareSerial


iinclude �SoftwareSerial.h>
// номер телефона для отправки sms (поменяйте на свой),
idefine PHONE "+79034461752"
// Быводы для SoftwareSerial (у вас могут быть 7,8)
SoftwareSerial Sim900Serial(2, 3);
const int lm335=AO; // для подключения LМ335
unsigned long rnillisl;

void setup()
{
Sim900Serial(19200); // активация последовательного соединения
}
void loop()

if (millis()-rnillis1>30*60*1000) // прошло 30 минут?


{
Sen?TextMessage(); // отправить sms
rnillisl=millis();
}

// подпрограмма отправки sms


void SendTextмessage()
{
// АТ-команда установки text rnode
Sim900Serial.print("AT+CМGF=l\r");
delay(lOO);
// номер телефона получателя
Sim900Serial.println("AT + CМGS \"");
Sim900Serial.println(PHONE);
Sim900Serial.println("\"");
delay(lOO);
// сообщение - данные температуры
douЬle val = analogRead(lrn335); // чтение
douЬle voltage = val*S.0/1024; // перевод в вольты
douЫe temp = voltage*lOO - 273.15; // в градусы Цельсия

Sim900Serial.println(ternp);
delay(lOO);
// ASCII к9д ctrl+z - окончание передачи
Sim900Serial.println((char)26);
delay(lOO);
Sim900Serial.println();
}
Обмен данными с помощью платы GPRSIGSM Shie/d 161

ЭЛЕКТРОННЫЙ АРХИВ
Скетч, соответствующий листинrу 9.1, можно найти в файле arduino_scetches\_09\
_09_01.ino сопровождающего книrу электронного архива.

Проверим работу скетча и, если все в порядке, изменим скетч таким образом, что­
бы плата Arduino оmравляла SМS-сообщение с данными температуры только при
получении приходящего сообщения с текстом ternp. Содержимое измененного скет­
ча показано в листинге 9.2.

#include <SoftwareSerial.h>
SoftwareSerial Sim900Serial(2, 3);
String currStr = ""; . //
String phone = ""; //
// True, если текущая строка является sms-сообщением
boolean isStringMessage = false;

void setup()
{
Serial.Ьegin(19200);
Sim900Serial.begin(19200);
// Настраиваем прием сообщений с других устройств
Sim900Serial.print("AT+CМGF=l\r");
delay(ЗOO);
Sim900Serial.print("AT+IFC=l, 1\r");
delay(ЗOO);
Sim900Serial.print("AT+CPBS=\"SM\"\r");
delay(ЗOO);
Sim900Serial.print("AT+CNМI=l,2,2,1,0\r");
delay(500);
}

void loop()

if (!Sim900Serial.availaЫe())
return;
char currSymЬ = Sim900Serial.read();
if ('\r' == currSymЬ)
{
if (isStringMessage) // текущая строка - sms-сообщение,
{
if (! currStr. compareTo("ternp")) // текст sms - temp
{
// отправить sms на приходящий �омер
Sim900Serial.print("AT+CМGF=l\r");
delay(lOO);
Sim900Serial.print("АТ'+ CМGS = \"");
162 Глава 9
Sim900Serial.print(phone);
Sim900Serial.println("\"");
delay(lOO);
douЫe val = analogRead(AO); // чтение
douЬle voltage = val*S.0/1024; // перевод в вольты
douЬle temp = voltage*lOO - 273.15; // в градусы Цельсия
Serial.println(temp);
Sif1900Serial.println(temp);
delay(lOO);
Sim900Serial.println((char)26);
delay(lOO);
Sim900Serial.println();
}
Serial.println(currStr);
isStringMessage = false;
}
else

if (currStr.startsWith("+CМТ")) {
Serial.println(currStr);
// выделить из сообщения номер телефона
phone=currStr.suЬstring(7,19);
Serial.println(phone);
// если текущая строка начинается с "+СМТ",
// то следующая строка является сообщением
isStringMessage = true;
}

currStr = ""·',

else if (' \n' ! = currSymЬ)

currStr += String(currSymЬ);

ЭЛЕКТРОННЫЙ АРХИВ
Скетч, соответствующий листингу 9.2, можно найти в файле arduino_scetches\_09\
_09_02.ino сопровождающего книгу электронного архива.

9.2. Отправка данных


на сайт «Народный мониторинг»
_ С сервисом «Народный мониторинг» мы уже познакомились в главе 4, где отправ­
ляли ему данные с помощью IШаты Ethemet Shield. А сейчас мы рассмотрим при­
мер отправки данных на сайт «Народный мониторинг» с использованием IШаты
GPRS/GSM Shield.
Обмен данными с помощью платы GPRSIGSM Shield 163

Итак, подключаем к Arduino плаrу GPRS/GSM Shield и датчик температуры


LМЗЗS. В режиме отправки/получения данных GPRS чип S1М9ОО потребляет ток
до 2 А, поэтому ему необходимо внешнее питание.
Для отправки НТТР-данных по GPRS соединению необходимо выполнить отправку
АТ-команд в следующей последовательности:
l. Первой отправляется команда АТ-ответ должен быть ок.
2. AT+SAPBR= l, 1-установка GРRS-связи.
3. AT+SAPBR= З, 1, "СОNТУРЕ", "GPRS"- настройка типа подключения (в данном cлy­
чae-GPRS).
4. AT+SAPBR= З, 1, "APN", "internet.beeline.ru"- настройка APN (в данном слу-
чае -для «Билайц»).
5. AТ+HTTPINIT-инициализировать НТТР.
6. AТ+HTTPPARA= "CID", 1-идентификатор Carrier 1D (CID).
7. AT+HTTPPARA="URL", "http: //narodrnon.ru/post.p!1.p" -собственно URL.
8. Строка данных GET.
9. AТ+HTTPACTION= O-отправка данных методом GET.
10. Дождаться ответа.
11. AT+HTTPREAD-получить ответ.
12. АТ+НТТРТЕRМ -остановить НТТР.
Теперь пишем скетч отправки данных (листинг 9.3).

Jdefine INТERVALSEND 60000


Jdefine LМ335 АО

Jinclude <SoftwareSerial.h>
SoftwareSerial GPRS(7, 8);
int onМodulePin= 9;
char aux_str[150];
char aux;
char data[512J;
int data_size;
uint8_t answer= O;

unsigned long rnillissend= O;

char apn[]="internet.beeline.ru";
char ur], (150];
String surl= "http://narodrnon.ru/post.php/?";
164 Глава 9

void setup()

GPRS.begin(l9200); !z скорость для GPRS


Serial.begin(9600);
Serial.println("Starting...");
pinМode(onМodulePin,OUTPUT);
power_on();
delay(ЗOOO);
// точка доступа APN
sendATcommand("AT+SAPBR=З,l,\"CONTYPE\",\"GPRS\"", "ОК", 2000);
snprintf(aux_str, sizeof(aux_str), "AT+SAPBR=3,l,\"APN\",\"%s\"", apn);
sendATcommand(aux_str, "ОК", 2000);
while (sendATcommand("AT+SAPBR=l,l", "ОК", 2000) == О)

delay(2000);
}
delay(lOOO);
}

void loop()

// 'отправка,раз в 10 минут
if(millis()-millissend>INTERVALSEND

// Initializes НТТР service


answer = sendATcommand("AT+HTTPINIT", "ОК", 10000);
if (answer == 1)

// Sets CID parameter


answer = sendATcommand("AT+HTTPPARA=\"CID\",l", "ОК", 5000);
if (answer == 1)
{// Sets ·url
douЫe val = analogRead(LМ335); // чтение показаний LМ335
douЬle voltage = val*5.0/1024; // переЕод в вольты
douЬle temp = voltage*lOO - 273.15; // в градусы Цельсия
String
surll=surl+"#AO:F3:Cl:70:AA:94\n#01395000524329l#"+String(temp)+"\n##";

surll.toCharArray(url,surll.length()tl);
snprintf(aux_str, sizeof(aux_str), "AT+НТTPPARA=\"URL\",\"%s\"", url);
answer = sendATcommand(aux_str, "ОК", 5000);
if (answer == 1)
{// Starts GET action
answer = sendATcommand("AT+HTTPACTION=O", "+HTTPACТION:0,200", 10000);
if (answer == 1)

sprintf(aux_str, "AT+HTTfREAD");
Обмен данными с помощью платы GPRSIGSM Shield 165

sendATcommand(aux_str, "ОК", 5000);

else

Serial.println("Error getting the url");

else

Serial.println("Error setting the url");

else

Serial.println("Error setting the CID");

else
1
Serial.println("Error initializating");

sendATcommand("AT+HTTPTERМ", "ОК", 5000);


millissend=millis();

// отправка АТ-команд
int8_t sendATcommand(char* ATcommand, char* expected_answer, unsigned int timeout)

uint8_t х=О, answer=O;


char response[150];
unsigned long previous;

memset(response, '\О', 150); // Initialize the string


delay(lOO);
while( GPRS.availaЬle() > О) GPRS.read(); // Clean the input buffer
GPRS.println(ATcommand); // Отправка АТ-команды
х = О;
previous = millis();
// this loop waits for the answer
do{
if(GPRS.availaЬle() ! = О)
{
// if there are data in the UART input buffer, reads it and checks for
the asnwer
response[x] = GPRS.read();
х++;
166 Глава 9

// check if the desired answer is in the response of the module


if (strstr(response, expected_answer) != NULL)
{
answer = 1;

}
// время ожидания ответа
while((answer == О) & & ( (millis() - previous) < timeout));
Serial.println(response);
return answer;

// программное вюnочение питания


void power_on()
{
uintB_t answer=O;
pinМode(onМodulePin,OUТPUT);
// checks if the module is started
digitalWrite(onМodulePin,LOW);
delay(lOOO);
digitalWrite(onМodulePin,HIGH);
delay(2000);
digitalWrite(onМodulePin,LOW);
delay(ЗOOO);
answer = sendATconuм.nd("AT", "ОК", 2000);
if (answer == О)
{
digitalWrite(onМodulePin,LOW);
delay(lOOO);
digitalWrite(onМodulePin,HIGH);
delay(2000);
digitalWrite(onМodulePin,LOW);
delay(ЗOOO);
digitalWrite(onМodulePin,HIGH);
delay(ЗOOO);
digitalWrite(onМodulePin,LOW);*/
// время ожидания ответа
while(answer == 0)

// Send АТ every two seconds and wait for the answer


answer = sendATconuм.nd("АТ", "ОК", 2000);

ЭЛЕКТРОННЫЙ АРХИВ
Скетч, соответствующий листингу 9.3, можно найти в файле arduino_scetches\_09\
_09_03.ino сопровождающего книгу электронного архива.
Обмен данными с помощью платы GPRSIGSM Shield 167

Загружаем скетч в плату Arduino и проверяем отправку данных на сайт. После


отправки данных можно добавить новое устройство в список устройств своего
профиля (рис. 9.3).

Рис. 9.3. Подключение устройства на сайте «Народный мониторинг»


ГЛАВА 10

Проект Blynk: управление Arduino


с планшета
Здесь мы рассмотрим, как управлять Arduino с Imаншета или смартфона, используя
возможности проекта Blynk (http://www.Ыynk.cc), который в начале 2015 года
успешно профинансировался на сайте Kickstarter почти на 500%.
Проект Blynk позволяет установить в приложении на Imаншете/смартфоне различ­
ные виджеты (кнопки, слайдеры, дисШiеи, графики и пр.) и с их помощью управ­
лять Imатой Arduino или получать с нее данные. Как можно видеть, проект Blynk
работает через Интернет (рис. 10.1).

Рис. 10.1. Архитектура проекта Blynk


170 Глава 10

10.1. Начало работы: тестовый пример


Программное обеспечение Blynk Cloud, написанное на Java, использует простые
IР-сокеты ТСР и работает на сервере icloud.blink.cc. Приложения Blynk для IOS и
Android подключаются к Blynk Cloud по умолчанию - каждому пользователю
Blynk обеспечивается к нему свободный доступ.
Для начала работы с проектом Blynk необходимо выполнить следующие шаги:
1. Скачать и установить бесплатное приложение Blynk: для Android - из Play
Маркет, для IOS - из Арр Store.
2. Запустить скачанное приложение Blynk и зарегистрироват!>ся в сервисе Blynk.
3. Настроить приложение для своего устройства, добавив на экран необходимые
виджеты.
4. Скачать и установить Аrduinо-библиотеку, загрузить скетч примера на плату
Arduino.
5. Запустить приложение на планшете, после чего можно будет управлять вывода-
ми Arduino и отображать полученные данные.
Итак, для скачивания приложения для Android заходим в Play Маркет и находим по
поиску приложение Blynk (рис. 10.2). Скачиваем его, устанавливаем И: создаем себе
на сервисе учетную запись (аккаунт), указав адрес своей электронной почты и
пароль.
Войдя в аккаунт, для создания нового проекта нажимаем кнопку+, вводим имя
проекта и выбираем тип устройства (рис. 10.3). Сервис поддерживает множество

Blynk for Arduino,RPi and


more
Blynk.cc

Оптимизировано дпя ·телефонов

КОдИЧIЮТIIО 68.:.
скачиаа1н;ii

Управление Arduino, Малина Pi, SparkCore и другие с смартфона


в минуту!
Рис. 10.2. Приложение Blynk в Play Маркет
Проект Blynk: управление Arduino с планшета 171

устройств, включая несколько плат Arduino, Raspberry Pi, ESP8266 и ряд других
(список устройств создатели сервиса обещают пополнять). При выборе устройства
автоматически генерируется уникальный ключ авторизации (АUТН ТОКЕN), ко­
торый нам понадобится при написании скетча. В завершение нажимаем на кнопку
Create - и проект создан.

Рис. 10.3. Соэдание нового проекта в Blynk

Теперь в проект можно добавлять виджеты для управления платой Arduino и полу­
чения с нее данных. Для добавления виджетов нажимаем в окне проекта кнопку+.
На момент подготовки книги выбор виджетов небольшой - явно меньше заявлен­
ного на Kickstarter: камера, джойстики, графики для отображения данньIХ там пока
не присутствуют, но что выбрать, все же, есть (рис. 10.4).
Чтобы воспользоваться виджетами, подготовим сначала схему: к плате Arduino
с установленной на ней платой Ethemet Shield подключим RGВ-светодиод, два
обычньIХ светодиода и фоторезистор (рис. 10.5).
После чего согласно этой схеме в проект Blynk на экране планшета мы добавляем
виджетъ1 Button (рис. 10.6) - задаем переключатель switchl состояния вывода DS
Arduino, три слайдера для управления выводами R, G и В RGВ-светодиода
(рис. 10.7), таймер для включения вывода D12 (рис. 10.8) и виджет Value Display
для отображения показаний фоторезистора, подключенного к выводу Al Arduino
(рис. 10.9). Общий вид проекта представлен на рис. 10.10.
172 Глава 10

Рис. 10.4. Виджеты для проекта в Blynk

Рис. 10.5. Схема подключения для примера Blynk


Проект Blynk: управление Arduino с планшета 173

, Рис. 10.6. Подключение виджета Button

Рис. 10.7. Подключение виджета Slider


174 Глава 10

Рис: 10.8. Подключение виджета Timer

Рис. 10.9. Подключение виджета Value Display


Проект B/ynk: управление Arduino с планшета 175

Рис. 10.10. Общий вид нашего проекта Blynk

Вернемся к нашей плате Arduino:


1. Скачиваем библиотеку Blynk по ссылке https://github.com/Ыynkkk/Ыynk­
library/archive/v0.2.1.zip.
2. Распаковываем библиотеку и копируем ее в папку libraries Arduino ЮЕ.
3. Создаем скетч (листинг 10.1) на основе примера Arduino_Ethemet_Manual.ino из
библиотеки Blynk:
• прописываем в нем настройки для нашей платы Arduino (IP, DNS, gateway,
subnet, МАС-адрес платы);
• прописываем ключ авторизации нашего проекта (АUТН ТОКЕN);
• сервер: "cloud.Ыynk. се";
• порт 8442 (облако cloud.Ыynk.cc использует два порта для обмена данными:
8443 - для мобильных устройств, 8442 - для контроллеров).
4. Загружаем скетч в нашу плату Arduino и открываем монитор последовательного
порта.
На рис. 10.11 показан процесс соединения Arduino с сервером cloud.Ыynk.cc.
176 Глава 10

// подключение библиотек
#define BLYNK PRINT Seria'l.
#include <SPI.h>
#include <Ethernet.h>
#include <BlynkSimpleEthernet.h>

// токен автор�зации для проекта на планшете


char auth [] = "16bcc28b557d4c45b3fd380f5cf8da6б";
// МАС-адрес и настройки сети для Etbernet shield
byte arduino_mac [] = { 0-xDE, OxED, ОхВА, OxFE, Ox-FE, · OxED } ;
IPAddress arduino_ip ( 192, 168, О, 120);
IPAddress dns_ip ( 192, 168, 1, 1);
IPAddress gatew,ay_ip ( 192, 168, О, 28);
IPAddress suЬnet_mask(255, 255, 255, О);
void setup()
{
Serial.begin(9600);
Blynk.begin(auth, "cloud.Ьlynk.cc", 8442, arduino_ip, dns_ip, gateway_ip,
suЬnet_mask,
arduino_mac);

void loop()

Blynk.run();
}

ЭЛЕКТРОННЫЙ АРХИВ
Ске"Т'-1, соответствующий листингу 10.1, можно найти в файле arduino_scetches\_10\
_10_01.ino сопровождающего книгу электронного архива.

, . 4774) Ready !
, ·10) Slynk v0.2.1
J О] Us1ng stat1c IP
АlЗОО] Му IP: 192.168.0.120
Н301] Connect1119 to cloud. Ыynk. се: 8442
(117313) Timeout
· .:123313) Connect1ng to с loud, Ь lynk, се: 8442
j 237551 Ready !

Рис. 10.11. Процесс соединения с сервером cloud.Ыynk.cc


Проект 8/ynk: управление Arduino с планшета 177

Рис. 10.12. Управление выводами Arduino с экрана планшета

Рис. 10.13. Монтажная плата соединения элементов для платы Arduino


178 Глава 10

Теперь запускаем на планшете наш проект на выполнение и с помощью слайдеров


устанавливаем цвет свечения RGВ-светодиода. Данные фоторезистора (вывод Al,
виджет Value Display) обновляются раз в 10 секунд, виджет Button (switchl) рабо­
тает как переключатель состояния светодиода, подключенного к выводу D8. Timer
подает 1 на вывод D12 в 15.00 и О- в 15.30 (рис. 10.12).
При этом на плате Arduino наблюдаем изменение состояния светодиодов
(рис. 10.13).

10.2. Управление с планшета


исполнительными устройствами,
подключенными к Arduino
С тестовым примером мы разобрались, надо двигаться дальше. Добавим к нашему
проекту возможность управления со смартфона исполнИJ:ельными устройствами,
подключенными к Arduino. Если для управления реле достаточно использования
. виджета Button с опцией switch, то управлять сервоприводом подобным образом
не получится. Рассмотрим, как это можно сделать.
Чтобы .обеспечить угол поворота сервопривода от О до 180 градусов, в наш проект
на планшете добавляем виджет Slider, в качестве виртуального порта (PIN) для
него выбираем Virtual VO и задаем область значений в промежутке О до 180
(рис. 10.14).

Рис. 10.14. Создание виджета Slider для виртуального порта VO


Проект Blynk: управление Arduino с планшета 179

Для получения данных из облака с виртуального порта VO (при изменении значе­


ния на выводе VO) необходимо добавить функцию BLYNI<_WRITE ( о J • В качестве
параметра в эту функцию как раз и приходит значение виртуального порта VO. Вы­
ведем его в последовательный порт:
BLYNK_WRITE (О)
{
int valVO=param.asint();
Serial.print("virtual pinO=");Serial.println(valVO);

Добавим этот фрагмент в скетч из листинга 10.1 и загрузим в плату Arduino. Те­
перь, меняя значение на слайд�ре в проекте на планшете, мы видим вывод этого
значения в монитор последовательного порта (рис. 10.15).

[О Му IP: 192.168.0.120
[1301] Connect1n9 to c1oud.Ыynk.cc:8442
[О] B1ynk v0.2.1
[0] Us1n9 stat1c IP
[1300] Му IP: 192.168.0.120
[1301] Connett1ng to cloud.Ыynk.cc:8442
[2393] Ready!
v1rtual p1nO=O
v1rtual p1n0=15
v1rtual pin0=66
virtual pin0=75
v1rtual pin0=75
v1rtual pin0-75
virtual pin0-76
irtual pin0=97
v1rtual p1n0=128
1rtua l pin0"132
virtual p1n0=132
v1rtual p1n0=132
v1rtual p1n0=130
Рис. 10.15. Получение значений виртуального порта VO на Arduino

Соответственно, получаемое Arduino значение положения слайдера мы можем ис­


пользовать для задания угла поворота сервопривода - подсоединяем сервопривод
в выводу D9 платы Arduino (рис. 10.16) и загружаем в плату скетч из листинга 10.2.
Теперь с помощью слайдера на планшете мы можем управлять поворотом подклю­
ченного к плате Arduino сервопривода (см. рис. 10.16).
180 Глава 10

Рис. 10.16. Управляемый слайдером сервопривод добавлен к монтажной плате

// подключение библиотек
#define BLYNK PRINT Serial
#include <SPI.h>
#include <Ethernet.h>
#include <BlynkSimpleEthernet.h>
#include <Servo.h>
// создание экземпляра объекта Servo
Servo servol;
// токен авторизации для проекта на смартфоне
char auth[J = "16bcc28b557d4c45b3fd380f5cf8da66";
// МАС-адрес и настройки сети для Ethernet shield
byte arduino_mac[J = { OxDE, OxED, ОхВА, OxFE, OxFE, OxED };
IPAddress arduino_ip ( 192, 168, О, 120);
IPAddress dns_ip ( 192, 168, 1, 1);
IPAddress gateway_ip ( 192, 168, О, 28);
IPAddress suЬnet_mask(255, 255, 255, О);
Проект Blynk: управление Arduino с планшета 181

BLYNK_WRITE (О)

int valVO=param.asint();
Serial.print("virtual pinO=");Serial.println(valVO);
servol.write(valVO); // поворот сервопривода

void setup()
{
Serial.begin(9600);
Blynk.begin(auth, "cloud.Ьlynk.cc", 8442, arduino_ip, dпs_ip, gateway_ip,
suЬnet_mask,
arduino_mac);
servol.attach(9); // П:одКЛIQЧает переменную servo к выходу 9
}
void loop()
{
Blynk.run();
}

ЭЛЕКТРОННЫЙ АРХИВ
Скетч, соответствующий листингу 10.2, можно найти в файле arduino_scetches\_10\
_ 10_02.ino сопровождающего книгу электронного архива.

10.3. Отправка данных из Arduino


на экран планшета
Дополним наш проект возможностью отображения на экране планшета данных
с любых датчиков, подключенных к плате Arduino. Воспользуемся для этого датчи­
ком освещенности BHl 750, и станем отправлять с него данные в облако каждые
1 О секунд. Чтобы организовать этот процесс, добавим .в наш проект на планшете
виджет Value Display. В качестве виртуального порта (PIN) выберем Virtual Vl
(рис. 10.17).
Создадим новый скетч (листинг 10.3) на основе скетча из листинга 10.1, добавив
в него процедуру получения Arduino данных с датчика BHl 750 и отправку этих
данных в проект на планшете через облако cloud.Ьlynk.cc. Для задания периодич­
ности опроса датчика и отправки данных в облако мы воспользуемся библиотекой
SimpleТimer. Отправку данных в виртуальный порт обеспечивает функция:
Blynk.virtualWrite(pin, value);
182 Глава 10

Рис. 10.17. Создание виджета Value Display для виртуального порта V1

// подключение библиотек
#define BLYNK PRINT Serial

#include <SPI.h>
#include <Ethernet.h>
#include <BlynkSimpleEthernet.h>
#include <Servo.h>
#include <SirnpleTimer.h>
#include <BH1750.h>
#include <Wire.h>

// создание экземпляра объекта ВН1750


ВН1750 lightl;
// создание экземпляра объекта Servo
Servo servol;
// создание экземпляра объекта SirnpleTirner
SirnpleTirner tirner;

// токен авторизации для проекта на смартфоне


char auth[] = "16bcc28b557d4c45b3fd380f5cf8da66";

// МАС-адрес и настройки сети для Ethernet shield


byte arduino_rnac [] = { OxDE, OxED, 'ОхБА, OxFE, OxFE, OxED ) ;
Проект Blynk: управление Arduino с планшета 183

IPAddress arduino_ip ( 192, 168, О, 120);


IPAddress dns_ip ( 192, 168, 1, 1);
IPAddress gateway_ip ( 192, 168, О, 28);IPAddress suЬnet_mask(255, 255, 255,
О);
!! получение значения с виртуального порта VO
BLYNK_WRITE (0)
{
int valVO=param.asint();
Serial.print("virtual pinO=");Serial.println(valVO);
servol.write(valVO); // поворот сервопривода

void setup()
{
Serial.begin(9600);
Blynk.begin(auth, "cloud.Ыynk.cc", 8442, arduino_ip, dns_ip, gateway_ip,
suЬnet_mask,arduino_mac);
servol.attach(9); // подключает переменную servo к выходу 9
lightl.begin(); // запуск датчика ВН1750
timer.setinterval(lOOOO, sendВH1750);
}

void loop()

Blynk.run();
timer.run();

void sendВH1750()
{
// получить значение освещенности в lx
uint16_t lux = lightl.readLightLevel();
Serial.println(lux);
// отправка значения освещенности
Blynk.virtualWrite(l, lux);
}

ЭЛЕКТРОННЫЙ АРХИВ
Скетч, соответствующий листингу 10.3, можно найти в файле arduino_scetches\_10\
_10_03.ino, а библиотеку SimpleTimer- в папке arduino_libraries\SimpleTimer сопрово­
ждающего книгу электронного архива.

Теперь на планшете в виджете Value Display каждые 10 секунд мы видим измене­


ние данных с датчика ВН1750 (рис. 1�.18).
Для отображения данных с датчика, подключенного к плате Arduino, необязательно
писать код отправки данных по таймеру - можно воспользоваться возможностями
библиотеки Blynk (листинr-10.4).
184 Глава 10

Рис. 10.18. Получение на планшете данных сдатчика ВН1750,


подключенного к Arduino

При создании виджета Value Display (ВН1750) мы указывали время опроса


1О секунд (см. рис. 10.17). С помощью библиот�ки Blynk мы также каждые
1О секунд отправляем данные в виртуальный порт Vl при получении запроса из
виджета:
BLYNK_READ(l)
{
// получить значение освещенности в lx
uintlб_t lux = lightl.readLightLevel();
Serial.println(lux);
// отправка значения освещенности
Blynk.virtualWrite(l, lux);
}
Проект Blynk: управление Arduino с планшета 185

!/ подключение библиотек
#define BLYNK PRINT Serial

#include <SPI.h>
#include <Ethernet.h>
#include <BlynkSimpleEthernet.h>
#include <Servo.h>
#include <BH1750.h>
+++++-#include <Wire.h>

// создание экземпляра объекта ВН1750


ВНl750 lightl;
// создание экземпляра объекта Servo
Servo servol;

// токен авторизации для проекта на планшете


char auth[J = "16bcc28b557d4c45b3fd380f5cf8da66";

// МАС-адрес и настройки сети для Ethernet shield


byte arduino_mac[ ] = { OxDE, OxED, ОхВА, OxFE, OxFE, OxED } ;
IPAddress arduino_ip ( 192, 168, О, 120);
IPAddress dns_ip ( 192, 168, 1, 1);
IPAddress gateway_ip ( 192, 168, О, 28);
IPAddress suЬnet_mask(255, 255, 255, О);

BLYNK_WRITE(O)
{
int valVO=param.asint();
Serial.print("virtual pinO=");Serial.println(valVO);
servol.write(valVO); // поворот сервопривода

// функция обработки запроса с выхода Vl


BLYNK_READ(l)
{
// получить значение освещенности в lx
uint16_t lux = lightl.readLightLevel();
Serial.println(lux);
// отправка значения освещенности
Blynk.virtualWrite(l, lux);
}

void setup()

Serial.begin(9600);
186 Глава 10

Blynk.begin(auth, "cloud.Ьlynk.cc", 8442, arduino_ip, dns_ip, gatew�y_ip,


suЬnet_mask,arduino_mac);
servol.attach(9); // подключает переменную servo к выходу 9
lightl.begin();
}

void loop()

Blynk.run();
}

ЭЛЕКТРОННЬIЙ АРХИВ
Скетч, соответствующий листингу 10.4, можно найти в файле arduino_scetches\_101
_ 10_04.ino сопровождающего книгу электронного архива.

Мы рассмотрели здесь базовые возможности сервиса Blynk. Разработчики сервиса


обещают добавлять в него новые возможности, поэтому периодически заходим на
сайт http://Ьlynk.cc и следим за новостями.
ГЛАВА 11

Микрокомпьютер Raspberry Pi

Raspberry Pi - это миниатюрный, размером с кредитную карту, компьютер стои­


мостью порядка 25 дшmаров за базовую модель и 35 - за более продвинутую, сни­
скавший огромную популярность и разошедшийся по миру в количестве более
4,5 миллионов штук (на начало 2015 года).
Одним из основных преимуществ Raspberry Pi является соотношение качества про­
дукта и его стоимости. Конечно, этот мини-ПК не столь мощный, как современные
компьютеры, но он прекрасно подходит для изучения компьютера и основ работы
с ним, для решения многих практических задач, для интернет-серфинга, а также
для проигрывания видео- и прослушивания аудиqфайлов.
В первую очередь, Raspberry Pi отводится роль компьютера, предназначенного для
изучения с его помощью базовых информационных технологий в школе. Позицио­
нируется Raspberry Pi и как дешевое решение для начинающих разработчttков.
С учетом удовлетворительной мощности этого устройства, низкого энергопотреб­
ления и малой себестоимости его можно использовать для создания личного мини­
сервера.
Raspberry Pi - идеальный компьютер для постановки различных экспериментов.
А применительно к статистическому управлению процессами (от англ. Statistical
Process Control, SPC) - методу мониторинга производственных процессов с целью
управления качеством продукции непосредственно в процессе производства,
Raspberry Pi является первым доступным техническим решением такого размера,
которое можно использовать повсеместно для программирования на многих языках
и в качестве микроконтроллеров для управления роботизированными устройст­
вами.
Одна из главных и привлекательных особенностей Raspberry Pi - наличие на плате
аппаратных портов ввода/вывода GPIO (General Purpose lnput/Output, интерфейс
ввода/вывода Qбщего назначения), что открывает перспективы использования его
в робототехнических проектах и устройствах «умного дома».
188 Глава 11

11.1. Технические характеристики


и возможности Raspberry Pi
Первые версии Raspberry Pi: модели «А», «В» (рис. 11.1), «А+» и «В+»- оснаще­
ны процессором Broadcom ВСМ2835 архитектуры ARМl 1 с тактовой частотой
700 МГц и модулем оперативной памяти на 256 (или 512) Мбайт, размещенным по
технологии package-on-package непосредственно на процессоре. Модель «А» осна­
щается одним портом USB 2.0, модель «В»- двумя такими портами, модель
«В+»- четырьмя. У моделей «В» и «В+» также наличествует порт Ethernet. По­
мимо основного ядра, процессор ВСМ2835 включает графическое ядро с поддерж­
кой OpenGL ES 2.0, аппаратного ускорения и видео Full НD, а также ядро DSP
(Digital Signal Processor, цифровой сигнальный процессор).

RCA VШЕО AUDIO

POWER
.....
__....
�-
Рис. 11.1. Схема Raspberry Pi, модель «В»

Питание компьютера осуществляется через разъем MicroUSB, при этом сила тока
должна составлять минимум 0,5-0,7 А. При меньших значениях компьютер все еще
может включиться, но будет уходить в перезагрузку при �апуске ресур�оемких за­
дач. Следовательно, подключать плату лучше не через хаб, а напрямую к USВ­
порту компьютера или в розетку через специальный переходник.
Никаких кнопок включения/выключения на плате Raspberry Pi нет. Если необходи·
мо устройство запустить- подключаете USВ-питание, для выключения- выдер­
гиваете шнур. Остается надеяться, что в будущих ревизиях Raspberry Pi, возможно,
добавят питание по Ethernet, поскольку это один из самых частых запросов от поль­
зователей.
Микрокомпьютер Raspberry Pi 189

Версии «А» и «В» устройства оснащены слотом для карт памяти формата SD, вер­
сии «А+» и «В+» - слотом для карт формата MicroSD. Без карты памяти Raspberry
Pi не включается, поскольку именно на ней должна быть записана операционная
система, - это все равно что пробовать запустить компьютер без жесткого диска.
Поскольку собственной ОС во внутренней памяти (как, например, в теле}}}онах)
у Raspberry Pi не имеется, то из этого слрдует один положительный момент -
устройство практически невозможно превратить в «кирпич»: после любого неудач­
ного эксперимента достаточно перезаписать дистрибутив на карте памяти, и
Raspberry Pi снова заработает как новенький.
Для подключения дисплея на плате Raspberry Pi имеются сразу два интерфейса:
RCA Video (композитный) и НDМI. Применяя соответствующие переходники,
можно выйти и на более традиционные: VGA и DVI. НDMI поддерживает передачу
как видео, так ц звука, но если потребуется отдельный аудиоканал, то и он присут­
ствует на плате в виде стандартного мини-джека 3,5 мм. Подключение микрофона
также возможно, но для этого liIОнадобится найти USВ-устройство, совместимое
с Raspberry Pi.
Существующие сейчас модели Raspberry Pi не имеют модуля Wi-Fi, и для работы
с ними в Интернете понадобится задействовать порт Ethemet. Поскольку физически
на плате он скоммутирован через USB 2.0, то обеспечивает не гигабитную, а всего
лишь 100-мегабитную скорость.
Чипы процессора и графического ускорителя не оснащены даже простейшими ра­
диаторами, и после нескольких часов работы компьютера становится очевидным,
почему его разработчики остановились именно на этом решении: плата нагревается
при работе совсем незначительно - она скорее теплая, чем горячая.
Частота процессора, как уже упоминалось, составляет 700 МГц, и, в зависимости от
дистрибьютора, его можно разогнать до 1ООО МГц без потери гарантии (tюзможен
выбор и более щадящих режимов). Чип памяти производства Samsung или Hynix
напаян прямо поверх основного чипсета, так что увеличить RАМ самостоятельно
не получится. При покупке стоит обратить внимание на маркировку этой SoC (от
англ. System-on-a-Chip, системы на кристалле): номер партии для «старых» версий
модели «В» с 256 Мбайт RАМ начинается с K4P2G, а у выпуска с 512 Мбайт памя­
ти - с К4Р4G.
Видеоускоритель Broadcom VideoCore IV позволяет даже при таком слабом про­
цессоре декодировать видео 1080р h.264 с битрейтом вплоть до 40 Мбит/с. Для ап­
паратного ускорения МРЕG-2 и VC-1 лицензии придется докупать отдельно.
Плата оснащена индикаторами - пятью светодиодами: три из них демонстрируют
активность и режим работы Ethemet, а еще два сигнализируют о наличии питания и
работе с SD-картой.
На рынке можно найти несколько корпусов как официальных производителей уст­
ройства, так и сторонних, которые применяются для повышения защищенности
компьютера и более удобной его транспортировки.
А теперь - самое интересное: уточним набор низкоуровневых интерфейсов, кото­
рые позволяют подключать к Raspberry Pi платы расширения, внешние контролле-
190 Глава 11

ры, датчики и прочие аксессуары. Во-первых, на Шiате имеются 15-штырьковые


слоты CSI-2- для подключения камеры и DSI- для подключения дисплея.
Во-вторых, присутствует колодка на 26 (40- для версии «В+») линий вво­
да/вывода общего назначения GPIO. На них же реализованы интерфейсы UART,
консо6�ьный порт, шина SPI (Serial Peripheral Interface, последовательный перифе­
рийный интерфейс), РС (lnter-Integrated Circuit, последовательная шина данных для
связи интегральных схем) и PS (lntegrated Inter-chip Sound, последовательная шина
данных, служащая для соединения цифровых аудиоустройств). Использование
GPIO- это как раз самое интересное и творческое применение Raspberry Pi.
Впрочем, недостатков у Raspberry Pi тоже хватает. В нем, к примеру, нет собствен­
ных часов реального времени (Real Time Clock, RTC), поэтому единственный спо­
соб получения времени- это синхронизация с NТР-серверами. SoC, как уже упо­
миналось, содержит в себе цифровой сигнальный процессор (DSP), но полного дос­
тупа к его API до сих пор нет. Выводы GPIO никак не защищены от короткого
замыкания, поэтому ошибка в монтаже может сгубить весь мини-ПК. Кроме того,
Raspberry Pi способен обрабатывать только цифровые сигналы. Видеовыходы не
могут одновременно выводить картинку. Аудиовхода вообще нет...
В 2015 году выпущена новая версия- Raspberry Pi 2 Model В (рис. 11.2). Вместо
процессора ВСМ2835 в ней установлен чип ВСМ2836. Отличается он от предшест­
венника наличием четырех ядер АRМ Cortex-A7 с набором инструкций ARМv7 -
против ARМvбk у ВСМ2835. Тактовая частота этого процессора составляет
900 МГц- не слишком много по меркам современных решений Qualcomm и даже
MediaTek, но для подавляющего большинства DIУ-проектов (от англ. Do lt Your­
self, «Сделай сам») ее хватит с лихвой, тем более что, напомним, ядер на этот раз
целых четыре. Объем оперативной памяти нового устройства увеличен с 512 Мбайт
до 1 Гбайт. Видеоядро изменений не претерпело, и это по-прежнему Broadcom

Рис. 11.2. Микрокомпьютер Raspberry Pi 2


Микрокомпьютер Raspberry Pi 191
'
VideoCore IV. Разработчики говорят о шестикратном приросте производительности
в многопоточных тестах и о трехкратном - в однопоточных. Новая мощь может
пригодиться во встроенных системах при обработке изображений - есть много
энтузиастов, которым хочется создать компьютерное зрение на основе
OpenCV. Примечательно, что на новую модель сохранилась демократичная цена
в 35 долларов США.
Raspberry Pi может стать в ваших руках и медиацентром, и управляющим центром
«умного дома», и мозгом робота - тут уж все зависит от вашей фантазии и жела­
ния. В Сети есть немало примеров, готовых проектов, сообществ пользователей и
целых магазинов, посвященных Raspberry Pi. Есть даже официальный очень-очень
скромный интернет-магазин The Pi Store (http://store.raspberrypi.com/projects)
с небольшим количеством ПО, игр, руководств и собственным журналом.
В этой книге мы рассмотрим использование микрокомпьютеров Raspberry Pi в про­
ектах IoT (Интернет вещей).

11.2. Установка операционной системы


Для того чтобы запустить Raspberry Pi, необходимо установить на него операцион­
ную систему. В качестве таковой нам доступны три официальных дистрибутива
Linux:
1:1 Pidora- основанныii на Fedora;
1:1 Archlinux - установка этого дистрибутива происходит практически вручную;
1:1 RaspЬian - основанный на DeЬian.
Кроме этих трех операциощ1ых систем, на Raspberry Pi портировано очень много
других. Поскольку операционная система устанавливается на SD-карту, чтобы за­
пустить другую систему, достаточно вставить в устройство карту с этой системой.
Мы в наших проектах будем ориентироваться на операционную систему RaspЬian.
Самый простой способ установить дистрибутив на Raspberry Pi - инструмент
NOOBS от создателей Raspberry Pi, который позволяет при первой загрузке вы­
брать для установки одну операционную систему из следующих:
1:1 ArchLinux;
1:1 OpenElec;
1:1 Pidora;
1:1 RaspBMC;
1:1 RaspЬian;
1:1 Risc Os.
Для установки дистрибутива на Raspberry Pi с помощью NOOBS потребуется карта
формата SD (для моделей «А» и «В») или MicroSD емкостью 4 Гбайт или более.
SD-карту необходимо отформатировать, в чем нам поможет программа SD
Formatter 4.0, архив которой доступен для закачки по ссылке https://
www.sdcard.org/downloads/formatter_4/eula_windows/ (рис. 11.3 ).
192 Глава 11

Рис. 11.3. Страница загрузки программы SD Forrnatter 4.0

Итак, помещаем нашу карrу в картридер компьютера, скачиваем программу, уста­


навливаем ее на компьютер и запускаем. Выбираем нашу SD-кapry, нажав кнопку
Options, задаем параметр FORМAT SIZE ADJUSTMENT равным ON и формати­
руем (рис. 11.4).

Рис. 11.4. Окно программы SD Formi:.tter 4.0

Далее скачиваем программное обеспечение NOOBS (http://downloads.raspberrypi.org/


noobs) и распаковываем ZIР-файл на нашу SD-кapry.
По завершении записи вынимаем SD-кapry из картридера компьютера и вставляем
ее в Raspberry Pi. Подключаем монитор (по НDМI или VGA), клавиатуру, а так­
же - опционально - мыщь и кабель Ethemet. Затем подаем питание через порт
MicroUSB. При первой загрузке устройства нам будет продемонстрировано меmо,
предлагающее установить одну из нескольких операционных систем в свободное
пространство на карте памяти (рис. 11.5).
После установки операционной системы Raspberry Pi станет загружаться в обыч­
ном режиме. Тем не менее, NOOBS остается на карте, поэтому, удерживая клавишу
Микрокомпьютер Raspberry Pi 193

Рис. 11.5. Меню NOOBS при первой загрузке

Рис. 11.6. Редактирование файла config.txt


194 Глава 11

<Shift> во время загрузки, можно вернуться к меню выбора. Это позволяет пере­
ключиться на другую операционную систему или заново переписать установку
текущей, а также предоставляет удобный инструмент для редактирования установ­
ленной операционной системы - файл конфигурации config.txt (рис. 11.6) и даже
веб-брау�ер, так что в случае проблем с установкой можно будет найти информа­
цию в Сети на тематических форумах.

11.3. Первоначальная настройка ОС Raspblan


11.3.1. Меню конфигурации
При первом запуске ОС RaspЬian мы увидим на экране монитора, подключенного
к Raspberry Pi, меню конфигурации (рис. 11. 7). Рассмотрим некоторые пункты
этого меню:
а Expand Filesystem - расширение раздела на все пространство флеш-нако­
пителя (операция будет выполнена после перезагрузки);
а Change User Password - изменение пароля пользователя Pi;
а ЕпаЫе Boot to Desktop- запуск графического режима при загрузке;

Рис. 11.7. Меню конфиrурации Raspblan

О Internationalisation Options- выбор языка и региональных настроек:


• Change locale- изменение языка: устанавливаем два значения: en_GB.UТF-8
и ru_RU.UTF-8;
• Change Timezone- настройка часового пояса;
• Change Keyboard Layout- изменение раскладки клавиатуры;
а ЕпаЫе Camera- поддержка модуля камеры;
а Overclock- увеличение частоты процессора (разгон), можно разогнать до
1 ГГц;
Микрокомпьютер Raspberry Pi 195

i:J Advanced Options-дополнительные параметры:


• Overscan- настройка режима overscan (вылета развертки): если у вас по
краю изображения имеется широкая черная полоса, то необходимо выклю­
чить этот режим (опция DisaЫe);
• Hostname-имя компьютера в сети (по умолчанию raspberrypi);
• Memory split-количество памяти, выделяемое под видео (по умолчанию-
64 Мбайт);
• SSH � включение ssh-cepвepa;
• Uрdаtе-обновленя_е программы raspi-config;
1:] About raspi-config-о программе.
Настроив все необходимые параметры, выбираем Finish- система запросит раз­
решение на перезагрузку. Соглашаемся. Если вы позже захотите поменять какие­
либо настройки, необходимо в консоли набрать команду:
sudo raspi-config
После продолжительной перезагрузки, система выйдет на запрос логина и пароля:
вводим логин пользователя Pi и пароль, который бьm введен при настройке. Для
запуска графического режима набираем в коцсоли команду:
startx
и попадаем на рабочий стол RaspЬian (рис. 11.8).

Рис. 11,8. Рабочий стол Raspblan


196 Глава 11

11.3.2. Настройка сетевых параметров


Скорее всего, вы не будете использовать Raspberry Pi для вывода информации на
монитор -вам наверняка понадобится удаленный доступ к нему по ssh, поэтому
сейчас следует настроить его сетевые параметры.
Установку сетевого соединения для Raspberry Pi обеспечивает файл конфигурации
/etc/network/interfaces, и если IР-адрес Raspberry Pi получает по DHCP, то ничего пра­
вить в этом файле вам не придется. В случае же назначения Raspberry Pi статиче­
ского IР-адреса, выполняем команду:
sudo nano /etc/network/interfaces
и дописываем в файл конфигурации /etc/network/interfaces следующие строки:
iface ethO inet static
address 192.168.0.117
netmask 255.255.255.0
gateway 192.168.0.28
auto ethO
где:
1:1 iface ethO inet static-указывает системе, что интерфейс (iface ethO) нахо­
дится в диапазоне адресов 1Pv4 (inet) со статическим IР-адресом (static);
1:1 address 192.168.о.117-указывает, что IР-адрес (address) нашей сетевой карты
192.168.0.117;
1:1 netmask 255.255.255.о- указывает, что наша маска подсети (netmask) имеет
значение 255.255.255.о;
1:1 gateway 192.168.о.28- указывает, что адрес шлюза (gateway) по умолчанию
192.168.О.1;
1:1 auto ethO-указывает, что интерфейс ethO необходимо включать автоматиче­
ски при загрузке системы с указанными здесь параметрами.
. Если требуется изменить адреса серверов DNS, выполняем команду:
sudo gedit /etc/resolv.conf
и вписываем в открывшийся файл конфигурации resolv.conf следующие строки:
nameserver 192.168.1.1
nameserver 8.8.8.8
где: 192.168.1.1 и 8.8.8.8- адреса серверов DNS. Если нужно добавить бош,ше
адресов -каждый адрес следует начинать с новой строки и со слова nameserver,

11.3.3. Настройка доступа по Wi-Fi


Далеко не всегда удобно вести к Raspberry Pi сетевой провод. Решить эту nроблему
можно с помощью адаптера Wi-Fi,' подключаемого через USB. У меня в наличии
имеется соответствующий адаптер (рис. 11.9), купленный в Китае за 7 долларов.
Микрокомпьютер Raspberry Pi 197

Позиционируется он в интернет-магазине как устройство, специально предназна­


ченное для Raspberry Pi.
Еще раз напомню, что при подключении адаптера Wi-Fi, как и любого другого
внешнего устрОЙ(?ТВа, запитывать Raspberry Pi следует от достаточно мощного бло­
ка питания.

Рис. 11.9. USВ-адаптер Wi-Fi

Итак, подключаем адаптер в USВ-порт и проверяем, определит ли его система. Ре­


зультат выполнения команды iwconfig (рис. 11.1О) показывает, что наше устройст­
во (wlanO) найдено.

Рис. 11.10. Результат выполнения команды iwconfig


198 Глава 11

Теперь сканируем пространство на поиск доступных беспроводных сетей коман­


дой:
sudo iwlist wlanO scan

и видим (рис. 11.11), что найдена точка доступа AndroidAP- в нашем случае это
планшет Samsung GalaxyTab 2, настроенный как точка доступа Wi-Fi.

Рис. 11.11. Поиск доступных беспроводных сетей

Теперь соединимся с точкой доступа по WPА-шифрованию. Соединение с таким


шифрованием поддерживает утилита wpa_passphrase. С помощью этой утилиты,
которая входит в состав пакета wpa_supplicant, генерируем пароль на основе ключа
доступа (для моей точки доступа AndroidAP- lcwt9634):
wpa_passphrase AndroidAP lcwt9634

Утилита выдает сгенерированную строку psk (рис. 11.12).


Далее блок, содержащий ssid сети (AndroidAP) и строку psk, вставляем в конец
конфигурационного файла /etdwpa_supplicant/wpa.:._supplicant.conf ( рис. 11.13).

Рис. 11.12. Генерирование строки psk


Микрокомпьютер Raspberry Pi 199

В завершение перезагружаем наш Raspberry Pi и наблюдаем на планшете Samsung


подключение Raspberry Pi (устройство raspЬerrypi2) к нашей точке доступа
(рис. 11.14).

Рис. 11.13. Добавление данных в конфигурационный файл wpa_supplicant conf

Рис. 11.14. Подключение к точке доступа Wi-Fi

11.3.4. Подключение ЗG-модема


Поскольку сотовая связь доступна практически на всей населенной территории РФ,
бесспорное достоинство ЗG-модема сост�ит в том, что в любой точке зоны охвата
можно соединиться с Интернетом, пусть и на относительно малых скоростях.
У меня как раз оказался в наличии ЗG-модем ZTE MF 180 от «Билайн» (рис. 11.15),
и хотя я и не . нашел его в списке совместимого с Raspberry Pi оборудования
200 Глава 11

Рис. 11.15. ЗG-модем ZТЕ MF180 от «Билайн»

(http://elinux.org/RPi_VerifiedPeripherals), однако подключить его и получить Ин­


тернет на скорости ЗG у меня получилось. Рассмотрим, как это удалось сделать.
Итак, ДJIЯ подключения к Raspberry Pi по USB ЗG-модема прежде всего необходимо
установить пакеты ррр и sakisЗg. Для установки пакета ррр выполним команду:
sudo apt-get install ррр

Затем скачиваем пакет sakisЗg:


sudo wget "http://www.sakis3g.org/versions/latest/aпnv4t/sakis3g.gz"
Этот источник очень часто бывает недоступен, и, попав в такую ситуацию, можно
обратиться к альтернативному:
sudo wget "http://raspberry-at-home.com/files/sakis3g.tar.gz"
Получив пакет, распаковываем его в предварительно созданную папку
/usr/Ьin/modemЗg:
sudo mkdir /usr/bin/modemЗg
sudo chmod 777 /usr/bin/modemЗg
sudo ер sakisЗg.tar.gz /usr/bin/modemЗg
cd /usr/bin/modemЗg
sudo tar -zxvf sakisЗg.tar.gz
sudo chmod +х sakisЗg

Теперь можно запустить скрипт sakisЗg, работающий в терминале:


sudo ./sakisЗg -interactive
В открывшемся главном меню программы (рис. 11.16) выбираем подключение
к сети ЗG. Скрипт sakisЗg считывает с модема настройки и предлагает выбор точ­
ки доступа для подключения (рис. 11.17).
Для моего тарифа приходится вводить свои параметры точки доступа:
home.beeline.ru (рис. 11.18).
Микрокомпьютер Raspberry Pi 201

Рис. 11.16. Главное меню программы SakisЗG

Рис. 11.17. Выбор точки доступа

Рис. 11.18. Ввод параметров точки доступа


202 Глава 11

Затем вводим логин (рис. 11.19) и пароль - скрипт пытается подключиться к сети
и выдает нам об э:гом соответствующее сообщение. Как можно видеть, подклю­
читься к сети у нас получилось (рис. 11.20).

Рис. 11.19. Ввод логин.а/пароля для точки доступа

Рис. 11.20. Сообщение о подключении к точке доступа

Рис. 11.21. Меню программы SaklzЗG


Микрокомпьютер Raspberry Pi 203

Рис. 11.22. Просмотр данных соединения

Далее мы попадаем в меню скрипта (рис. 11.21), где можно посмотреть настройки
соединения (рис. 11.22) или разорвать его.

11.4. Интерфейс GPIO


Как уже отмечалось ранее, Raspberry Pi несет на борrу интерфейс, называемый
GPIO (рис. 11.23), - набор портов ввода/вывода общего назначения (General
Purpose Input/Output). В моделях «А» и «В»- это 26 линий, из которых для управ­
ления доступны 17, в моделях «В+»- 40 линий, из которых доступны 26.

Рис. 11.23. Порты GPIO на плате Raspberry Pi


204 Глава 11

На этих линиях реализованы интерфейсы UART, консольный порт, SPI (Serial


Peripheral Interface,, последовательный периферийный интерфейс) и РС (Inter­
Integrated Circuit, последовательная шина данных для связи интегралью.ц( схем).
2
Расстояние между выводами - 2,54 мм. Выводы UART, SPI и I C в случае необхо­
димости могут быть настроены как обычные порты ввода/вывода.
' '

Назначение выводов GPIO (так называемая распиновка) представлено на


рис. 11.24-11.26. Для плат «А» и «В» первой ревизии выводы 4, 9, 14, 17, 20,
25 обозначены как DNC (Do Not Connect), и подсоединять к ним что-либо не следу­
ет - плата может сгореть. На новых ревизиях платы разведены, но не распаяны, еще
четыре GPIO, дополнительно дающие интерфейсы РС и PS (Inter-Integrated Circuit,
последовательная шина данных для связи интегральных схем). Первые 26 выводов
GPIO платы «В+» полностью идентичны разъемам GPIO плат «А» и «В», осталь­
ные 14 содержат 9 выводов GPIO общего назначения, которые могут быть сконфи­
гурированы как вход или выход, 3 вывода GND и 2 вывода не задействованы.
С помощью выводов GPIO к Raspbeпy Pi можно подключать датчики и внешние
исполнительные устройства, что открывает интересные возможности творческого
использования Raspbeпy Pi.

Рис. 11.24. «Распиновка» портов GPIO Рис. 11.25. «Распиновка» портов GPIO
плат «А» и «В» Revision 1 плат «А» и «В» Revision 2

При работе с портами GPIO следует помнить о некоторых их особенностях и со­


блюдать определенные меры предосторожности, чтобы не повредить ,RаsрЬепу Pi.
Вот основные из них:
t:J максимальный суммарный ток обоих выводов 3,3 В равен 50 мА,
и эти выводы
могут использоваться для питания внешних устройств только в том случае, если
их потребляемый ток меньше 5{) мА;
Микрокомпьютер Raspberry Pi 205

Рис. 11.26. «Распиновка»


портов GPIO
плат «В+» и «В 2»

1:1 максимальный суммарный ток обоих выводов 5 В равен 300 мА, и эти выводы
также могут использоваться для питания внешних устройств только в том слу­
чае, если их лотребляемый ток меньше 300 мА;
1:1 на GPIO нельзя подавать напряжение больше 3,3 В! Цифровые выводы GPIO
имеют уровни напряжения 0-3,3 В и не совместимы с традиционными уровнями
напряжения 0-5 В. Если подать на вывод GPIO логическую единицу, представ­
ляющую собой 5 В (а не·3,3 В), -этот вывод может выйти из строя;
1:1 выводы GPIO 14 и GPIO 15 по умолчанию выполняют альтернативную функцию
и являютс� выводами UART (RXD и TXD), поэтому после включения на них
присутствует высокий уровень 3,3 В, однако программно их можно переконфи­
гурировать в обычные выводы. Все остальные выводы GPIO после включения
Raspbeпy Pi выполняют основную функцию и работают как обычные цифровые;
1:1 все' настраиваемые выводы GPIO - кроме GPIO О (SDA) и GPIO 1 (SCL) -по
умолчанию являются входами и поэтому имеют высокое входное сопротивле­
ние, при этом подтяжка логического уровня у них не включена, так что после
включения Raspbeny Pi напряжение на них может «плавать»;
к
1:1 выводы GPIO О (SDA) и GPIO 1 (SCL) по умолчанию «подтянуты» питанию,
поэтому после включения Raspbeпy Pi на них присутствует напряжение логиче­
ской единицы (3,3 В);
1:1 сигнал на любом из цифровьrх выводов может служить источником внешнего
прерывания.
Нужно помнить, что GPIO - это выводы, непосредственно подключенные к про­
цессору Raspberry Pi, они являются инструментом для взаимодействия с ним.
Поэтому неосторожное обращение с GPIO может привести к необратимым послед­
ствиям для процессора.
206 Глава 11

Работать с GPIO можно двумя способами:


r::J используя оболочку bash и файловую систему RaspЬian;
r::J используя языки программирования.

11.4.1. Управление GPIO из оболочки bash


ОС RaspЬian представляет собой один из дистрибутивов Linux, а концепция Linux
предполагает, что любой объект является файлом. Именно это позволяет выводить
и считывать сигналы с GPIO обычными командами оболочки bash прямо в терми­
нале. Вывод логической единицы при этом выглядит как команда записи "1"
в файл, соответствующий нужному выводу:
sudo su -
echo "25" > /sys/class/gpio/export
echo "25" > /sys/class/gpio/export
echo "out" > /sys/class/gpio/gpio25/direction
echo "1" > /sys/class/gpio/gpio25/value
echo "0" > /sys/class/gpio/gpio25/value
ДтIЯ чтения входов надо использовать команду cat и путь к файлу:
echo "24" > /sys/class/gpio/export
echo "in" > /sys/class/gpio/gpioO/direction
cat /sys/class/gpio/gpio24/value
Все операции должны выполняться от имени пользователя root.

11.4.2. Управление GPIO командами языка Python


Для работы с GPIO на языке Python требуется специальная библиотека RPi.GPIO.
В новом дистрибутиве RaspЬian она уже установлена, а если у вас дистрибутив ста­
рый, то для установки библиотеки RPi.GPIO выполните команду:
sudo apt-get install python-rpi.gpio
Чтобы использовать эту библиотеку, необходимо в програм.му на Python добавить
строку импорта библиотеки RPi.GPIO:
Import RPi.GPIO as GPIO
При написании программы можно выбрать один из двух способов нумерации пор­
тов GPIO: первый - GPIO.BOARD - использует систему нумерации портов на
плате Raspbeпy Pi. Преимущество этой системы нумерации в том, что ваше обору­
дование будет работать всегда, независимо от номера ревизии - вам не придется
· перемонтировать свой разъем или изменить имеющийся код. Вторая система нуме­
рации - GPIO.BCM (номера ВСМ). Это более низкий уровень работы - с прямым
обращением к номерам каналов на процессоре Broadcom. Выбор способа нумера­
ции определяется соответствующими командами:
GPIO.setmode(GPIO.BOARD)
GPIO.setmode(GPIO.BCМ)
Микрокомпьютер Raspberry Pi 207

Следующие команды устанавливают режим работы контакта на вход или выход:


GPIO.setup(channel, GPIO.IN)
GPIO.setup(channel, GPIO.OUT)
Если входной канал ни к чему не подключен, его значение может «плыть». Сле­
дующие команды устанавливают начальную «подтяжку» вывода к питанию или
к «земле»:
GPIO.setup(channel, GPIO.IN, GPIO.PUD_UP)
GPIO.setup(channel, GPIO.IN, GPIO.PUD_DOWN)

Для выходов оuт можно установить начальное значение О или 1:


GPIO.setup(channel, GPIO.OUT, GPIO.LOW)
GPIO.setup(channel,. GPIO.OUT, GPIO.HIGH)

Для чтения значения контакта GPIO, настроенного как вход IN, служит следующая
команда:
GPIO.input(channel)

Значение контакта, настроенного как выход оuт, устанавливается следующей


командой:
GPIO.output(channel, state)
В листинге 1 1.1 приведен пример использования команд работы с GPIO.

irnport RPi.GPIO as GPIO #подключаем библиотеку


GPIO.setmode(GPIO.BCМ) #устанавливаем режим нумерации
GPIO.setup(7, GPIO.OUT) #конфигурируем GPIO 7 как выход
GPIO.setup(8, GPIO.IN) #конфигурируем GPIO 8 как вход
GPIO.output(7, True) #выводим на GPIO 7 логическую "1" (3.3 V)
GPIO.output(7, False) #выводим 'на GPIO 7 логический "0"
signal = GPIO.input(8) #считываем с GPIO 8 в переменную signal
GPIO.cleanup() #завершаем работу с GPIO

Библиотека RPi.GPIO позволяет использовать контакты GPIO в качестве выходов


ШИМ (сигналов широтно-импульсной модуляции).
Для создания экземпляра ШИМ служит команда:
р = GPIO.PWМ(channel, frequency)

где frequency - частота, Гц.


Для старта ШИМ на контакте:
р.start(dc)

где dc - рабочий цикл ШИМ (0,0-100,0).


208 Глава 11

Для изменения частоты сигнала:


p.ChangeFrequency(freq)

где freq - частота сигнала, Гц.


Для изменения рабочего цикла ШИМ:
p.ChangeDutyCycle(dc) # where О.О<= dc<= 100.0
Останов выдачи сигнала ШИМ на контакте:
р.stop()
В листинге 11.2 представлен пример плавного включения/выключения светодиода,
подключенного к контакту.

import time
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BOARD)
GPIO.setup(l2, GPIO.OUT)

р = GPIO.PWМ(l2, 50) # контакт 12 частота 50 Гц


p.start(O)
try:
while 1:
for dc in range(O, 101, 5):
p.ChangeDutyCycle(dc)
time.sleep(O.l)
for dc in range(lOO, -1, -5):
p.ChangeDutyCycle(dc)
time.sleep(O.l)
except Keyboardinterrupt:
pass
p.stop()
GPIO.cleanup()

Функция ожидания события - изменения состояния на входе IN - выглядит сле­


дующим образом:
GPIO. wait_for_ edge (channel, GPIO.RISING,)
GPIO.wait_for_edge(channel, GPIO.FALLING)
GPIO.wait_for_edge(channel, GPIO.BOTH)

Эта функция прерывает выполнение программы до изменения состояния на входе


GPIO. В отличие от нее функция add_event_detected() выполняется в цикле про­
граммы, и для того, чтобы узнать об изменении состояния на контакте GPIO, необ­
ходимо в цикле проверять наступление события event_detected() :
Микрокомпьютер Raspberтy Pi 209

GPIO.add_event_detect(channel, GPIO.RISING

if GPIO.event_detected(channel):
print('Button pressed')
Каждый контакт GPIO может быть настроен на работу в режиме прерывания -
в этом случае при наступлении события на контакте, управление передается функ­
ции обработки прерывания. Функция обработки прерывания работает в отдельном
потоtсе, не прерьmая выполнения основной программы:
def my_callback(channel):
рrint('обработк� прерывания!')
GPIO.add_event_detect(channel, GPIO.RISING, callback=my_callback)
В конце любой проr:раммы рекомендуется очистить все ресурсы, которые могли
использоваться. Для такой очистки в конце скрипта надо предусмотреть команду:
GPIO.cleanup()
Для сброса одного контакта служит команда:
GPIO.cleanup(channel)

11.5. Raspberry Pi
и датчик температурь� DS18B20 на wине 1-Wire
11.5.1. Подключение датчика DS18820 к Raspberry Pi
В главе 7 мы уже рассматривали датчик температуры DS 18В20, работающий по
однопроводному интерфейсу 1-Wire.
Схема подключения датчика DS 18В20 к контактам GPIO Raspberry Pi по протоколу
1-Wire приведена на рис. 11.27. Протокол 1-Wire позволяет подключить к одной
шине и несколько датчиков DS 18В20 (рис. 11.28).

Рис. 11.27. Схема подключения датчика DS18B20 к RaspЬerry Pi по wине 1-Wlre


210 Глава 11

Рис. 11.28. Схема подключения к Raspberry Pi нескольких датчиков DS18820

Для использования с Raspberry Pi датчиков DS 18В20 на шине 1-Wire необходимо


загрузить два специальных модуля: wl-gpio и wl-term. Для этого набираем в тер­
минале:
sudo modprobe wl-gpio
sudo modprobe wl-therm
Первая строка здесь активирует протокол модуля 1-Wire на GPI04,. а вторая - за­
гружает модуль, который, собственно, и читает темпераrуру с шины 1-Wire. Чтобы
модули автоматически загружались после перезагрузки или выключения Raspberry
Pi, две эти строки нужно добавить в файл /etc/modules, отвечающий за автозагрузку
модулей, для чего набираем в терминале:
sudo nano /etc/modules
и добавляем в конец открывшегося для редактирования файла две следующие
строчки:
wl-gpio
wl-therm
Через несколько секунд после подключения датчика в каталоге /sys/Ьus/w1/devices
появится вложенный каталог вида 28-хххххххххххх (рис. 11.29). Если этого не про­
изошло, значит у вас установлена новая версия RaspЬian, в которой по умолчанию
отключена поддержка дерева устройств. Чтобы исправить ситуацию, открываем
файл /Ьoot/config.txt:
sudo nano /boot/config.txt
вписываем в конец файла следующую строку:
dtoverlay=wl-gpio
и перезагружаемся.
Для каждого подключенного по шине 1-Wire датчика темпераrуры создается свой
такой каталог. Название каждого каталога - это уникальный серийный номер дат­
чика DS 18В20.
Микрокомпьютер Raspberry Pi 211

Рис. 11.29. Каталог для датчика DS18820 в папке /sys/bus/w1/devices

Данные температурьi хранятся в файле 28-000003b816b0/w1-slave, содержимое кото­


рого можно считать по команде:
cat /sys/bus/wl/devices/28-000003b816b0/wl_slave
Результат считывания показаний датчика DS18B20 приведен на рис. 11.30.

Рис. 11.30. Содержимое файла с показаниями датчика DS18820

Обратите внимание на присутствующий в считанной информации фрагмент:


t = 16687. Эrо температура по шкале Цельсия, умноженная на 1000. То есть, реаль­
но замеренная температура составляет 16687/1ООО = 16,687 °С. Не надо обманы­
ваться относительно трех знаков после запятой - абсолютная точность датчика
всего 0,5 °С.
Напишем на языке Python скрипт, считывающий и выводящий каждые три секунды
данные температуры с датчика DS18B20 (листинг 11.3).

#-*-coding:utf-8 -*-
from time import sleep

while 1:
tfile=open("/sys/bus/wl/devices/28-000003b816b0/wl_slave")
212 Глава 11

ttext=tfile.reaq()
tfile. close ()
temp=ttext.split("\n") [1] .split(" ") [9]
temperature=float(temp[2:J)/1000
print "temperature= "+str(temperature)
sleep(З)

Запустим этот скрипт на выполнение:


python listing_ll_OЗ.py
и наблюдаем вывод показаний (рис. 11.31).

Рис. 11.31. Работа скрипта, читающего показания датчика DS18820

11.5.2. Отправка данных с датчика DA18820


в сервис «Народный мониторинг»
Как известно, для регистрации какого-либо датчика в сервисе «Народный монито­
ринг» сначала необходимо отправить туда данные его замеров. Так что, прежде
всего напишем скрипт, отправляющий данные с датчика в этот сервис. Для этого
создаем файл listing_11_04.py, заносим в него код из листинга 11.4, запускаем наш
скрипт на выполнение:
python listing_11_04.py
и наблюдаем отправку данных (рис. 11.32).
Микрокомпьютер Rвspberтy Pi 213

Рис. 11.32. Отправка данных в сервис «Народный мониторинг» из руthоп-скрипта listing_11_04.ру

#-*-coding:utf-8 -*-

import socket
from time import sleep

# МАС-адрес устройства. Заменить на свой!


DEVICE МАС = 'Ь827еЬ8За32с'
# идентификатор устройства
SENSOR ID 1 = '2800000ЗЬ816Ь0'
# значения датчика, тип float/integer
sensor value 1 = О

while 1:
tfile=open("/sys/bus/wl/devices/28-000003b816b0/wl_slave")
ttext=tfile.read()
tfile.close()
temp=ttext.split("\n")[1].split(" ") [9]
temperature=float(temp[2:J)/1000
print "temperature="+str(temperature)
sensor_value_l=temperature

# создание сокета
sock = socket.socket()
# обработчик исЮIЮчений
try:
# подЮIЮЧаемся к сокету
sock.connect(('narodmon.ru', 8283))
# пишем в cokeT единичное значение датчика
sock.send("# {)\n#{)#{) \n##".format(DEVICE-МАС, SENSOR_ID_l,
sens�r_value_l))
# пишем в сокет множественные значения датчиков
# sock.send("#{)\n#{)#{}\n#{}#{}\n##",format(DEVICE МАС, SENSOR ID 1,
sensor_value_l, SENS0R_ID_2, sensor value_2))
# читаем ответ
data = sock.recv(1024)
sock.close()
print data
214 Глава 11

except socket.error, е:
print( 'ERROR! Exception {} '. fonnat ('е))
sleep(600)

Отправив данные, заходим в свой профиль на сайте http://www.narodmon.ru,


выбираем пункт меню Датчики, нажимаем на кнопку Добавить датчик к в соот­
ветствующее поле открывшегося окна вносим МАС-адрес нашего устройства (ис­
пользуем МАС-адрес сетевой платы Raspberry Pi). Если данные бьши переданы
успешно, наша плата появится в списке устройств (рис. 11.33).

Рис. 11.33. Добавление датчика на сайт сервиса «Народный мониторинг»

Рис. 11.34. График передачи показаний датчика температуры


Микрокомпьютер Raspberтy Pi 215

Осталось настроить параметры датчика ншчего устройства, и через некоторое вре­


мя можно будет увидеть график его показаний (рис. 11.34).
ЭЛЕКТРОННЫЙ АРХИВ
Скрипт, соответствующий листингу 11.4, можно найти в файле python\Jisting_11_04.py
сопровождающего книгу эл�ктронного архива.

11.6. Raspberry Pi
и датчик освещенности ВН1750 на шине 1 2 С
11.6.1. Подключение датчика ВН1750 к Raspberry Pi
В главе 6 мы уже рассматривали датчик освещенности BHl 750 на шине 12 С - под­
ключим его теперь к Raspberry Pi.
Для работы с датчиками 12 С на Raspberry Pi необходимо сначала настроить под­
держку интерфейса 12 С, который в нем отключен по умолчанию. Поэтому запуска­
ем утилwгу конфигурации raspi-config:
sudo raspi-config
и выбираем в главном меню пункт Advanced options, а в открывшемся окне
(рис. 11.35)-вариант А7 I2C, чем и включаем поддержку интерфейса 12 С.
Затем добавляем в файл /etc/modules, отвечающий за автозагрузку модулей, сле­
дующие строки:
i2c-bcrn2708
i2c-dev

Рис. 11.35. Настройка поддержки протокола 1 2С в меню конфиrурации raspi-config


216 Глава 11

и устанавливаем утилиты python-smbus и i2c-tools:


sudo apt-get install python-srnЬus
sudo apt-get install i2c-tools
Теперь подключаем к Raspberry Pi датчик освещенности BHl 750 (рис. 11.36) и про­
веряем, видит ли Raspberry Pi наш датчик, - отдаем в терминале команду
i2cdetect, которая содержится в утилите i2c-tools:
i2cdetect -у 1

и видим «решетку адресов» (рис. 11.37)-адрес нашего датчика здесь: Ох23.

Рис. 11.36. Схема подключения датчика ВН1750 к Raspberry Pi

Рис. 11.37. «Решетка адресов» 1 2 С-датчиков, подключенных к Raspberry Pi


Микрокомпьютер Raspberry Pi 217

11.6.2. Получение на Raspberry Pi


данных с датчика ВН1750
Напишем на языке Python скрипт получения Raspberry Pi данных с датчика BHl 750
(листинг 11.5).

#!/usr/bin/python
import srnЬus
import time

# Установка констант по технической документации


DEVICE Ох23 # I2C адрес датчика

POWER DOWN ОхО О # Неактивное состояние


POWER ON OxOl # Включение
RESET Ох07 # Сбросить значение регистра Не POWER DOWN = ОхОО #

# Запуск измерения с разрешением 4 lx. Время, как правило, 16 мс.


CONTINUOUS LOW RES MODE = ОхlЗ
# Запуск измерения с разрешением· 1 lx. Время, как правило, 120 мс
CONTINUOUS HIGH RES MODE 1 = OxlO
# Запуск измерения с разрешением 0.5 lx. Время, как правило, 120 мс
CONTINUOUS HIGH RES MODE 2 = Oxll
# Запуск измерения с разрешением 1 lx. Время, как правило, 120 мс
# Устройство автоматически устанавливается на Power Down после измерения.
ONE ТIМЕ HIGH RES MODE 1 = Ох20
# Запуск измерения с разрешением 0.5 lx. Время, как правило, 120 мс
# Устройство автоматически устанавливается на Power Down после измерения.
ONE_TIМE_HIGH_RES_MODE_2 = Ох21
# Запуск измерения.с разрешением 1 lx. Время, как правило, 120 мс
# Устройство автоматически устанавливается на Power Down после измерения.
ONE ТIМЕ LOW RES MODE Ох23

#bus = srnЬus.SМВus(O) # Rev 1 Pi uses О


bus = srnЬus.SМВus(l) # Rev 2 Pi uses 1

def convertToNurnЬer(data):
# перевод данных датчика в числовое значение
return ((data[l] + (256 * data[O])) / 1.2)

def readLight(addr=DEVICE):
data = bus.read i2c Ыock_data(addr,ONE_TIМE_HIGH_RES MODE 1)
return convertToNurnЬer(data)
218 Глава 11

def rnain() :

while True:
print 11 Light Level 11
+ str(readLight()) + 11 lx 11
tirne.sleep(О.5)

if name == 11 rnain 11 •

rnain()

Запустим этот скрипт в терминале:


python listing_ll_05.py
и увидим там вывод показаний датчика BHl 750 (рис. 11.38).

Рис. 11.38. Вывод показаний датчика ВН1750

ЭЛЕКТРОННЫЙ АРХИВ
Скрипт, соответствующий листинrу 11.5, можно найти в файле python\listing_11_05.py
сопровождающего книгу электронного архива.

Теперь данные освещенности с датчика BHl 750 можно отправлять в облачный сер­
вис - например, в тот же «Народный мониторинг», добавив в этот скрипт код
отправки данных из листинга 11.4.
ГЛАВА 12

WeЫOPi - веб-интерфейс
и облако для Raspberry Pi
Воспользуемся для доступа к портам GPIO фреймворком WeЫOPi- сервисом
Internet of Things, позволяющим контролировать состояние и управлять всеми пор­
тами GPIO локально или удаленно, из браузера или любого приложения.
Возможнос'Ги WeЫOPi:
С] доступ к функционалу сервиса через основанный на НТТР интерфейс REST API
(Representational State Transfer, передача состояния представления) и протокол
ограниченного применения СоАР (Constrained Application Protocol) с поддерж­
кой мультикаста (многоадресного вещания);
С] работа с портами GPIO, Serial, 12С, SPI, 1-Wire;
С] встроенная поддержка более чем 30 устройств, включая ЦАП, АЦП, датчики;
С] возможность работь1 с облачным сервисом Weaved;
С] совместимость с Python 2 и 3;
С] защита логином/паролем;
С] множество примеров.

12.1. Установка WeЫOPi на ОС Raspblan


Для установки фреймворка WeЫOPi на ОС RaspЬian необходимо скачать соот­
ветствующий архцв, извлечь содержащиеся в нем файлы и запустить сценарий
установки, который автоматически загрузит и инсталлирует необходимые зависи­
мости:
wget http://webiopi.googlecode.com/files/WeЫOPi-0.7.1.tar.gz
tar xvzf WeЫOPi-0.7.1.tar.gz
cd WeЫOPi-0.7.1
sudo ./setup.sh
В процессе достаточно продолжительной установки вам будет предложено создать
профиль в облачном сервисе Weaved (https://www.weaved.com) для доступа
220 Глава 12

WeЫOPi Main Menu


GPIOHeader
CODlrol lllld DeЬug the RaspЬeny Pi GPIO wilh а dispв}- wblch looks like lhe physical head«.

GPIO List
Coatrol lllld DeЬug the RaspЬeny Pi GPIO cж&red in а siogle colomn.

Serial Monitor
UR tЬе Ьro\'\'Ser to pla.y wiCЬ Saiir1 iated'aces cooigured in WeЬIOPi

Devices Moвitor
Coatrol and DeЬdg devices and circuil:s wired to УО\К" Pi aad ccatigured in WeЬIOPi

Рис. 12.1. Стартовая страница WeЫOPi

-
, Рис. 12.2. Страница управления выводами GPIO
WeЫOPi - веб-интерфейс и облако для Raspberry Pi ,22'1

к WeЫOPi из сети Интернет (установка сервиса Weaved рассмотрена в разд. 12. 7).
Установленный WeЫOPi лучше запускать как сервис:
sudo /etc/init.d/webiopi start
Если нужно, что бы WeЫOPi стартовал автоматически при загрузке системь�,
выполните следующую команду:
sudo update-rc.d webiopi defaults
Теперь можно открыть веб-браузер на любом компьютере домашней сети, набрать
адрес: http: //iprasp: вооо (где iprasp- IР-адрес Raspberry Pi) и авторизовать,;.я­
имя пользователя (логин): weЬiopi, пароль: raspberry. В результате в браузере от­
кроется стартовая страница WeЫOPi (рис. 12.1).
На странице управления выводами GPIO (рис. 12.2), открывающейся по ссылке
GPIO Header, можно задать режим работы любой ножки и устан:овить значение на
выходе.

12.2. Задание
пользовательского пароля WeЫOPi
Сервер WeЫOPi использует зашифрованный файл etc/weblopi/passwd, содержащий
логин и пароль (по умолчанию логин: weЬiopi, пароль: raspberry). Чтобы измен:ить
пароль, необходимо выполн1;1ть f\ОМЩJДу:
weЬiopi-passwd
и далее следовать инструкциям (рис. 12.3).

Рис. 12.3. Изменение пароля WeЫOPi

После изменения пароля сервер необходимо перезагрузить:


sudo /etc/init.d/weЬiopi restart
Для снятия защиты при входе в WeЫOPi необходимо либо ввести пустой пароль,
либо удалить файл /etc/weblopi/passwd.
222 Глава 12

12.3. Настройка сервера WeЫOPi


Настраивается сервер WeЫOPi внесением изменений в файл его конфигурации:
Синтаксис этого файла такой же, как и у прочих INI-файлов, - он
/etc/weblopi/config.
содержит несколько разделов, содержащих пары <(ключ = значение».
!:J Блок [HTTPJ позволяет включить или отключить НТТР, а также изменить значе­
ние порта. В этом блоке можно изменить местоположение файла passwd, домаш­
ней папки и название индексного файла НТМL:
[НТТР]
enaЫed = true
port = 8000
passwd-file = /etc/webiopi/passwd
doc-root = /home/pi/webiopi/exarnples/scripts/rnacros
welcome-file = i'ndex.html
!:J Блок [COAPJ позволяет включить или отключить сервер СоАР, а также изменить
значение порта:
[СОАР]
enaЬled = true
port = 5683
multicast = true
!:J Блок [GPIOJ позволяет установить пользовательские настройки и значения для
портов GPIO при запуске WeЫOPi. Например:
[GPIO]
21 = IN
23 = OUT О
24 = OUT О
25 = OUT 1

!:J Блок [-GPIOJ позволяет установить пользовательские настройки и значения для


портов GPIO при перезагрузке WeЫOPi. Например:
[-GPIO]
21 IN
23 = IN
24 = IN
25 = оuт О

!:J Блок [SCRIPTSJ определяет список скриптов, выполняемых при запуске WeЫOPi.
Например:
[SCRIPTS]
myscript = /home/pi/webiopi/exarnples/scripts/macros/script.py
!:J Блок позволяет с помощью REST API (см. разд. 6.2.3) ограничить доступ
[RESTJ
GETIPosт к некоторым портам:

[REST]
gpio-export = 21, 23, 24, 25
WeЫOPi - веб-интерфейс и облако для Raspberry Pi 223

gpio-post-value = false
gpio-post-function = false
device-mapping = false
Q Блок [DEVICESJ позволяет подключить устройства, поддерживаемые WeЫOPi,
к конкретным портам GPIO (список поддерживаемых WeЫOPi устройств см. на
странице: https://code.google.com/p/weblopi/wiki/DEVICES):
usbO = Serial device:ttyUSBO baudrate:9600
adc = МСР3008
dac = МСР4922 chip:1
gpioO = МСР23017
gpiol = МСР2З017 slave:Ox21
gpio2 = МСР23017 slave:Ox22
pwmO = РСА9685
pwml = РСА9685 slave:Ox41
Q Блок [ROUTES J определяет список маршрутов переадресации. Это позволяет при
использовании REST API скрыть в адресной строке значение порта доступа или
другое назначение, т. е. придать адресам удобный вид:
/bedroom/light = /GPI0/25/value
/bedroom/temperature = /devices/temp2/sensor/temperature/c

12.4. Jаvаsсriрt-библиотека weblopi.js


WeЫOPi включает в себя НТТР-сервер, обеспечивающий как НТМL-ресурсы, так и
интерфейс REST API для управления выводами GPIO. При запуске сервера браузер
сначала загружает НТМL-файл с включенной Jаvаsсriрt-библиотекой weblopi.js,
содержащей библиотеку jQuery для асинхронных вызовов к REST API. Этот метод
очень эффективен, потому что не требует для обновления данных обновления стра­
ницы. Расширить возможности WeЫOPi можно путем загрузки пользовательского
сценария Python, содержащего функции настройки выводов GPIO и созданноrо
с использованием Arduino-пoдoбнoro синтаксиса (рис. 12.4).

НПР
REST
API
ПPRESTAP

Рис. 12.4. Схема WeЫOPi


224 Глава 12

Для подключеНИJI библиотеки weЬiopi.js на странице НТМL в блок [НEADERJ поме­


щаем следующий код:
<script type="text/javascript" src="/weЬiopi.js"></script>

12,4.1. Функции библиотеки weblopi.js


noRCHEHHE
Здесь и далее weЬiopi ()-возвращаемый объект WeЫOPi.

Функция WeЫOPl.ready
Функция weЫOPi.ready() регистрирует функцию обратного вызова при загрузке
библиотеки weЬiopiJs.
Синтаксис: WeЫOPi. ready(callback)
Параметр: callback - функция обраmого вызова.
Функция WeЫOPl.setFunctlon
Функция weЫOPi.setFunction() устанавливает назначение вывода GPIO.
Синтаксис:
(] WeЫOPi.setFunction(gpio, func)
(] WeЫOPi.setFunction(gpio, func, callback)
Параметры:
С] gpia � .номер аы:еода GPIO;
а func :-- назначение вывода:
• m - вывод конфиrурирован как вход;
• оuт - вывод конфиrурирозан как выход;
• Р\Щ----.- вывод
конфигурирован как IIIИМ-выход.
(] callback - функция обратного вызова.

Функцtut WeЬIOPi.dlgltalWrlte
Функция WeЫOPi.digitalWrite(} устанавливает цифровое значение вывода GPIO,
сконфиrурированного как выход (оuт).
Синтаксис:
(] WeЫOPi.digitalWrite(gpio, value)
(] WeЫOPi.digitalWrite(gpio, value, callback)
Параметры:
(] gpio - номер вывода GPIO;
(] value - значение для вывода (О или 1);
C:J callback - функция обраmого вызова.
WeЫOPi - веб-интерфейс и облако для Raspbeny Pi 225

Функция WeЫOPi.digita/Read
Функция weЫOPi.digitalRead() получает значение с вывода GPIO, сконфигуриро­
ванного как вход (IN).
Синтаксис:
r:] WeЫOPi.digitalRead(gpio)
r:] WeЫOPi.digitalRead(gpio, callback)
Параметры:
r:] gpio - номер вывода GPIO;
r:] callback - функция обратного вызова.
Возвращаемое значение: value (О или 1 ).

Функция WeЫOPi.toggleValue
Функция weЫOPi.toggleValue() переключает значение на выводе GPIO на проти­
воположное.
Синтаксис:wеЫОРi. toggleValue(gpio)
Параметр: gpio - номер вывода GPIO.

Функция WeЫOPi.cal/Macro
Функция WeЫOPi.callMacro() выполняет макрофункцию на сервере WeЫOPi. Мак­
рос может объявляться в скрипте Python, запускаемом при старте WeЫOPi.
Сингаксис:
r:] WeЫOPi.callMacro(macro)
r:] WeЫOPi.callMacro(macro, args)
r:] WeЫOPi.callMacro(macro, args, callback)
Параметры:
r:] macro - наименование макрофункции;
С] args - массив передаваемых аргументов для макрофункции;
С] callback - функция обратного вызова.

Функция WeЫOPi.outputSequence
Функция WeЫOPi.outputSequence() отправляет последовательность битов на выход
GPIO.
Синтаксис:
С] WeЫOPi.outputSequence(gpio, period, sequence)
С] WeЫOPi.outputSequence(gpio, period, sequence, callback)
Параметры:
r:J gpio - вывод GPIO;
С] period - время отправки (миллисекунд) одного бита;
226 Глава 12

(] sequence-последовательность битов;

(] callback-функция обратного вызова.


Пример:
var sequence = "01010100110011001100101010";
// отправка последовательности на gpio 7 с периодом 100 мсек
webiopi().outputSequence(7, 100, sequence, sequenceCallback);

Функция WeЫOPi.pulse
Функция WeЫOPi.pulse () отправляет импульс на выход GPIO.
Синтаксис:
1:1 WeЫOPi.pulse(gpio)
(] WeЫOPi.pulse(gpio, callback)
Параметры:'

C:J gpio-вывод GPIO;

(] callback-функция обратного вызова.

Функция WeЫOPi.pulseRatio
Функция WeЫOPi.pulseRatio() отправляет ШИМ-сигналы на выход GPIO.
Синтаксис:
(] WeЫOPi.pulseRatio (gpio, ratio)
(] WeЫOPi.pulseRatio (gpio, ratio, callback)
Параметры:

C:J gpio -вывод GPIO;

(] rаtiо-значение для сигнала ШИМ (0,0-1,0);

(] callback-функция обратного вызова.

Функция WeЫOPi.pu/seAngle
Функция WeЫOPi.pulseAngle() отправляет ШИМ-сигналы на выход GPIO. Эга
функция удобна при управлении сервоприводами для установки угла поворота
рабочего органа от -45 до +45 градусов.

Синтаксис:
(] WeЫOPi.pulseAngle (gpio, angle)
(] WeЫOPi.pulseAngle(gpio, angle, callback)
Параметры:

C:J gpio-вывод GPIO;

(] angle-значение сигнала ШИМ (от -45 до +45);

(] callback - функция обратного вызова.


WeЫOPi - ввб-интерфейс и облако для Raspberry Pi 227

Функция WeЫOPi.createButton
Функция WeЫOPi.createButton() возвращает объект - просrую кнопку.
Синтаксис:
LI WeЫOPi.createButton(id, label)
LI WeЫOPi.createButton(id, label, mousedown)
LI WeЫOPi.createButton(id, label, mousedown, mouseup)
Параметры:
LI id- идентификатор кнопки;
LI label- надпись на кнопке;
LI mousedown- функция, вызываемая при событии mousedown (нажатие по кнопке);
LI mouseup- функция, вызываемая при событии mouseup (отпускание кнопки).
nРИМЕЧАНИЕ
События mousedown и mouseup в основном используются, когда идет нажатие на кнопку,
перемещение ее, а потом мышь отпускается.

Чтобы кнопка появилась на странице, ее необходимо добавить - например, так:


button = weЬiopi() .createButton("btl", "buttonl", fun_down, fun_up);
$,("#divl") .append(button);

Функция WeЫOPi.createFunctionButton
Функция WeЫOPi.createFunctionВutton() создает объект - кнопку, при нажатии
на которую изменяется назначение вывода GPIO.
Cинтaкcиc:weЫOPi.createFunctionButton(gpio)
Параметр: gpio- вывод, назначение которого изменяется (IN, оuт), при этом на
кнопке выводится соответствующая надпись (IN, ОUТ).
Функция WeЫOPi.createGPIOButton
Функция WeЫOPi.createGPIOButton() создает объект - кнопку, при нажатии на
которую изменяется значение (О или 1) вывода GPIO.
Cинтaкcиc:weЫOPi.createGPIOButton(label, gpio)
Параметры:
LI label- надпись на кнопке;
LI gpio- вывод, назначение которого изменяется (о, 1), при этом на кнопке выво­
дится соответствующая надпись (О, 1).
Функция WeЫOPi.createMacroButton
Функция WeЫOPi.createMacroButton () создает объект - кнопку, при нажатии на
которую выполняется макрофункция на сервере (макрофункции прописываются
в Руthоn-скрипте, запускаемом при старте weЬiopi).
228 Глввв 12

Cинтaкcиc:weЫOPi.createMacroButton(id, label, macro, args)


Параметры:
!:1 id - идентификатор кнопки;
!:1 label - надпись на кнопке;
!:1 macro - название макрофункции на сервере;
!:1 args - список параметров, передаваемых макрофункции.

Функция WeЫOPi.createSequenceButton
Функция WeЫOPi.createSequenceButton() создает объекr - кнопку, при нажатии на
которую на вывод GPIO отправляется последовательность битов.
Cинтaкcиc:weЫOPi�createSequenceButton(id, label, gpio, period, sequence)
Параметры:
!:1 id - идентификатор кнопки;
!:1 label - надпись на кнопке;
!:1 gpio - вывод для отправки последовательности битов;
!:1 pe-riod - время отправки одного бита (мсек);
!:1 sequence- последовательность битов в виде строки.
Пример:
button = weЬiopi() .createSequenceButton("butl", "labell", 25, 100,
"01010100110011001100101010");
$("#divl").append(button);

Функция WeЫOPi.createRatioS/ider
Функция WeЫOPi.createRatioSlider() создает объекr- шкалу (см. рис.6.15), поло­
же�ем указателя на которой регулируется значение IIШМ-сигнала на выводе GPIO.
Cинтaкcиc:weЫOPi.createRatioSlider(gpio, ratio)
Параметры:
!:1 gpio - вывод для отправки последовательности битов;
!:1 ratio - начальное значение для llШМ (0,0-1,0).
Пример:
button = weЬiopi().createRatioS1ider(24, 1.0);
$("#divl") .append(button);

Функция WeЫOPi.createAngleS/ider
Функция weЫOPi.createAngleSlider() СОЗДljiет объект - шкалу, положением указа­
теля которой регулируется значение ШИМ-сигнала, подаваемого на вывод GPIO
при управлении сервоприводом для значений поворота угла рабочего органа от -45
до +45 градусов.
WeЫOPi - ввб-интврфейс и облако для Raspberry Pi 229

Cинтaкcиc:weЫOPi.createAngleSlider(gpio, angle)
Параметры:
lj gpio - вывод для отправки последовательности битов;
lj angle - начальное значение угла для сигнала ШИМ (от-45 до +45).

Функция WeЫOPi.setLabel
Функция WeЫOPi.setLabel () изменяет надпись на кнопке.
Синтаксис: WeЫOPi.setLaЬel(id, laЬel)
Параметры:
lj id - идентификатор кнопки;
lj lаЫе - новая надпись для кнопки.
В листинге 12.1 представлен пример кода страницы для формирования элементов
управления weЬiopi, а на рис. 12.5 - вид этой НТМL-страницы.

<htrnl>
<head>
<rneta http-equiv="Content-Type" content= "text/html; charset=UTF-8">
<rneta name="viewport" content "height = device-height, width = 420,
user-scalaЫe = no" />
<title>WeЫOPi I Demo</title>
<script type="text/javascript" src="/weЬiopi.js"></script>
<script type="text/javascript">
weЬiopi().ready( function()
var content, button;
content = $("#content");

button = weЬiopi().createFunctionButton(25);
content.append(button);

button = weЬiopi().createGPIOButton(7, "SWITCH");


content.append(button);

button weЬiopi() .createSequenceBiitton("sos", "S.O.S 1", 25, 100,


=
"01010100110011001100101010");
content.append(button);

button = weЬiopi().createМacrol3utton("macro",,, "Print


, Time", "PrintTime" )J
content.append(button);

bUtton = webiopi().createAngleS1ider(23, 30);


content.append(button);
230 Глава 12
button = webiopi() .createRatioS1ider(24, 0.5);
content.append(button);

webiopi() .refreshGPIO(true);
) );

</head>
<body>
<div id="content" align="center"></div>
</body>
</html>

Рис. 12.5. Вид НТМL-страницы с элементами управления- weЬiopi

12.5. Проект управления веб-камерой


на сервоприводах
Для создания своего проекта с использованием фреймворка WeЫOPi необходимо
реализовать следующие его компоненты:
i:J веб-интерфейс-НТМL-страницу с использованием библиотеки webiopi.js;_
i:J серверный скрипт на языке Python, запускаемый при старте weЬiopi для реализа­
ции функционала веб-интерфейса;
i:J файл конфигурации с установкой начальных значений портов.
WeЫOPi - ввб-интврфвйс и облако для Raspberтy Pi 231

Подготовим проект управления из веб-интерфейса камерой, укрепленной на подве­


се, снабженном сервоприводами, Из веб-интерфейса можно будет поворачивать
камеру, а также делать снимки и оmравлять их на электронную почту.
Для проекта понадобятся следующие детали:
LI подвес для камеры (рис. 12.6);
LI сервоприводы TG9 (рис. 12.7)- 2 шт.;
LI дополнительный блок питания 5 В;
LI камера Raspberry Pi Camera Board (рис. 12.8).

Рис. 12.6. Подвес для камеры с сервоприводами Рис. 12.7. Сервопривод TG9

Рис. 12.8. Камера Raspberry Pi Camera Board


232 Глава 12

L7805,
'+ " 1 IN OUT з RaspЬerry Pi GP\O

Lipo J1 GND' J1
-г,;
+SV
2 1 +З.ЗВ +5В 2
з GPIOO +5В 4
-
--=- 5 GPI01 GND в
7 GPI04 GPI014 8
9 GND GPI015 10 1 ]2
11 GPI017 GPI018 12
Servo
L�
GN: .....
13 GPI021 GND 14

Vcc
s
.,
... �. 15

17
GPI022

+З.ЗВ
GPI023 16
GPI024 18 .,.._
19 GPI010 GND
Servo 20

GND ""'� .. 21

23
GPI09

GPI011
GPI025 22

GPIOB
Vcc 24
s t"!<'lol,I
25 GND GPI07 26

Рис. 12.9. Электрическая схема проекта

Для управления сервоприводами задействуем два вывода GPIO: GPI023 и GPI024.


Электрическая схема проекта представлена на рис. 12.9.
Сначала настроим в файле конфигурации config, который находится в папке
/etc/weblopi/, необходимые параметры: путь к домашней папке и путь к скриmу,
выполняемому при запуске weЬiopi:
doc-root = /horne/pi/weЬiopi/exarnples/servo-carnera
script = /horne/pi/weЬiopi/exarnples/servo-carnera/carnera.py
Поскольку камера Raspberry Pi Camera Board подключена напрямую к графическо­
му процессору через СSI-разъем, СSl-разъем на плате, защ1сь и кодирование видео
происходят без использования процессорного времени. Установим для передачи
потокового видео с этой камеры пакет MJPG-streamer:
su pi
https://svn.code.sf.net/p/rnjpg-strearner/code/rnjpg-strearner/ rnjpg-strearner
cd rnjpg-strearner/rnjpg-strearner
rnake USE LIBV4L2=true clean all
sudo su
rnake DESTDIR=/usr install
ер -R www /var/
Напишем запускающий камеру sh-скрипт stream_start.sh (листинг 12.2), создав для
него предварительно файл:
sudo nano /usr/local/Ьin/strearn_start.sh
sudo chrnod +х /usr/local/Ьin/strearn_start.sh
WeЫOPi - веб-интерфейс и облако для Raspberтy Pi 233

# ! /Ьin/bash
if [ -d /tmp/stream ];then
echo:"/trnp/stream already c;__reated"
else
mkdir /trnp/stream
fi

if -f /tmp/stream/pic.jpg ];then
echo "raspistill already running"
else
raspistill -w 320 -h 240 -q 5 -о. /home/pi/webiopi/examples/
servo-camera/pic.jpg -tl 100 -t 9999999&
fi
mjpg streamer -i "input file.so -f /home/pi/weЬiopi/examples/servo-camera"
-о "output_http.so -w /home/pi/weЬiopi/examples/servo-camera"

Запуск скрипта осуществляе�я командой:


/usr/local/Ьin/stream_start.sh
Напишем на языке Python серверный скрипт camera.py (листинг 12.3), который бу­
дет запускаться при запуске weЬiopi. В скрипте пропишем назначение контактов,
макросы и выполним начальный запуск камеры потокового видео. Учтем при этом,
что управляющие контаkТы сервоприводов подключены к выводам 16 (GPI023)
и 18 (GPI024) GPIO. Плюс еще одна дополнительная опция_:... мигание светодиода,
подключенного к выводу-22 (GPI025).

import weЬiopi
import sys
import time
from suЬprocess import call

GPIO = weЬiopi.GPIO

SERVOl = 23
SERV02 = 24
LED1 = 25

def camera_start():
return code = call("/usr/share/weЬiopi/examples/servo-camera/
str.eam_start.sh", shell='J'rue)

def setup():
weЬiopi.debug("Blink script - Setup")
234 Глава 12
# Установка выводов GPIO
GPIO.setFunction(SERVOl, GPIO.PWМ}
GPIO.setFunction(SERVOl, GPIO.PWМ}
GPIO.setFunction(LEDl, GPIO.OUT}
GPIO.pwmWriteAngle(SERVOl, О} # set to О (neutral}
GPIO.pwmWriteAngle(SERV02, О} # set to О (neutral}
GPIO.digita1Write(LED1, GPIO.HIGH)
camera_start(}
# Цикл loop(}
def loop(} :
# Toggle LED each 5 seconds
value = not GPIO.digita1Read(LED1}
GPIO.digita1Write(LED1, value}
webiopi.sleep{5}
# Возврат выводов в начальное состояние
def destroy(} :
weЬiopi'.debug( "Blink script - Destroy"}
# Reset GPIO functions
GPIO.setFunction(SWITCH, GPIO.IN}
GPIO.setFunction(SERVO, GPIO.IN}
GPIO.setFunction(LEDO, GPIO.IN}
GPIO.setFunction(LEDl, GPIO.IN}

Веб-интерфейс у нас будет достаточно простой: два слайдера управления подвесом


камеры, кнопка для оmравки фото на e-mail и картинка изображения с камерьJ
(рис. 12.10). При изменении позиции слайдера подвес поворачивается в направле-

down р
1en-+--nght
Рис. 12.10. НТМL-страница проекта управления подвесом для камеры
WeЫOPi - веб-интерфейс и облако для Raspberry Pi 235

нии вверх-вниз и влево-вправо. Изображение с камеры . постоянно обновляется


запуском функции set_т irneout(). Необходимо также запретить кэширование стра­
ницы. Код НТМL-страницы camera.html представлен в листинге 12.4.

<!DOCTYPE html PUBLIC "-//WЗC//DTD НТМL 4.01 Transitional//EN"


"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta http-equiv "cache-control" content = "max-age= O">
<meta http-equiv "cache-control" content = "no-cache">
<meta http-equiv "expires" content = "0">
<meta http-equiv "expires" content = "Tue, 01 Jan 1970 1:00:00 GMT">
<meta http-equiv "pragma" content = "no-cache">
<meta name "viewport" content = "height = device-height, width = 420,
=
user-scalaЫe = no" />
<title>WeЫOPi camera</title>
<script type="text/javascript" src="/weЬiopi.js"></script>
<script type="text/javascript">
function init() {
var button;

button = weЬiopi().createButton("photo", "Ьig photo", photo);


$i"#cam").append(button);

button = weЬiopi().createAngleS1ider(23, 30);


$("#updown").append(button);

button = 'weЬiopi().createAngleS1ider(24, О);


$("#leftright").append(button);
}

function photo()
$("#ph").html('');
$("#ph").html('<img src="pic.jpg">');
}
function get_img()
{
docшnent.getElementByid("irngl").src="http://192.168.0.101:8080/pic.jpg";
}
weЬiopi().ready(init);

</script>
<style type="text/css">
236 Глава 12

button {
margin: 5рх 5рх 5рх 5рх;
width: 150рх;
height: 50рх;
font-size: 12pt;
font-weight: bold;
color: Ыасk;

</style>
</head>
<body onload='setinterval("get_img();",1000);'>
<div style= "float:left">
<div id= "content" align="center">
<div id="cam"></div>
<div id="vid"><img id= "imgl" width= "320" height="240"
src="http://192.168.0.101:8080/pic.jpg"></div>
<div>down<span id="updown"></span>up</div>

<div>left<span id= "leftright"></span>right</div>


</div>
</div>
<div style="float:right" id="ph"></div>
</body>
</html>

ЭЛЕКТРОННЫЙ АРХИВ
Коды листингов этого проекта вы найдете в папке python\servo-camera сопровождающе­
го книгу электронного архива.

12.6. WeЫOPi - подключение устройств


Фреймворк WeЫOPi позволяет использовать устройства. типов Serial, 12 С, SPI и
1-Wire прямо из интерфейса REST API, без написания макросов (список поддержи­
ваемых датчиков имеется на странице: https://code.google.com/p/weblopi/wiki/
DEVICES).
Включить поддержку устройства можно в блоке [DEVICEJ файла конфигурации
раскомментировав строку с выбранным датчиком, который сле­
/etc/weblopi/config,
дует подключить к выходам GPIO:
[DEVICES]

#tempO = ТМР102
#templ = ТМР102 slave:Ox49
temp2 = DS18B20
#tempЗ = DS18B20 slave:28-0000049bc218
WeЫOPi - веб-интерфейс и облако для Raspberтy Pi 237

Пример схемы подключения датчика температуры DS 18В20 представлен на


рис. 12.11.
Выполнив необходимые монтажные манипуляции, открываем стартовую страницу
WeЫOPi (см. рис. 12.1), выбираем пункт Device Monitor и попадаем на страницу
подключенных устройств (рис. 12.12). В нашем случае здесь отображен только дат­
чик температуры DS 18В20. Страница демонстрирует данные, получаемые с датчи­
ка, с обновлением их каждые 5 секунд.

RaspЬerry Pi GPIO
DS18B20
1 +З.ЗВ +58 2 ,.--
1 GND DQ VDD 1 з GPIOO +58 4
1 2 з 5 GPI01 GND 6
7 GPI04 GPI014 8

9 GND GPI015 10

11 GPI017 GPI018 12

13 GPI021 GND 14

15 GPI022 GPI023 16
4,�t: 17 +З.ЗВ GPI024 18

19 GPI010 GND 20
21 GPI09 GPI025 22

23 GPI011 GPI08 24

25 GND GPI07 26

Рис. 12.11. Схема подключения к GPIO ,11аNика DS18820

Devices Monitor
temp2: Temperature: 19.5б0С

Рис. 12.12. Монитор подключенных устройств


238 Глава 12

12. 7. Доступ к устройству из сервиса Weaved


Сервис Weaved (https://www.weaved.com) позволяет подключиться к Raspberry Pi
(и не только) из браузера, находясь в любой точке мира. Если вы не установили
программное обеспечение для сервиса Weaved при установке WeЫOPi, сейчас для
этого самое время.

12. 7.1. Установка сервиса Weaved


Для установки сервиса сначала необходимо в нем зарегистрироваться. Сделать это
можно на странице https://developer.weaved.com/portal/ (рис. 12.13), открываемой
по нажатmо кнопки Sign Up на главной странице сервиса.

+weaved.

lnternet of Things for Everyone


Пщrе i,; вt1co:)t ro trvuut (щrprodш:.ts.шd ��1,,1/(f'l-s, \•;rejusr н�еd to kn{)\Vytvu 1 и' J .rcal pec:"1-otk

:,. . . -- -- . . . . .. . � . -- . . . .. - ·'
'

liiffii
Рис. 12.13. Регистрация в сервисе Weaved

Зарегистрировавшись в сервисе, запускаем терминал нашего Raspberry Pi и скачи­


ваем установщик программного обеспечения для сер�щса Weaved:
wget https://githuЬ.com/weaved/installer/raw/rnaster/binaries/
weaved-nixinstaller 1.2.13.bin
Делаем файл установщика исполняемым:
chmod +х. weaved-nixinstaller 1.2.13.bin
Запускаем установку:
./weaved-nixinstaller_l.2.13.bin
WeЫOPi - веб-интерфейс и облако для Raspberry Pi 239

Во время установки вам будет предложено выбрать вид доступа для связи с Rasp­
berry Pi (рис. 12.14):
tJ SSH на порту 22;
tJ Web (НТТР) на порту 80;
tJ WeЫOPi на порту 8000;
tJ VNC на порту 5901 (tested with tightvncserver);
tJ пользовательский сервис ТСР.
Выбрать можно только один из предложенных. Если вы хотите использовать не­
сколько видов доступа, необходимо запускать установку несколько раз, выбирая
каждый раз новый вид доступа.

Рис. 12.14. Выбор вида доступа к плате из сервиса Weaved:


здесь выбрано подключение по Web (НПР)

Далее необходимо ввести данные для авторизации в сервисе Weaved: логин (адрес
электронной почты) и пароль (рис. 12.15).
После чего создать имя для устройства в сервисе Weaved (рис. 12.16).
В завершение установки выдается информация по командам для запуска/остановки
сервиса (рис. 12.17).
Завершив установку, мы можем зайти в свой профиль в сервисе Weaved и увидеть
список наших устройств (рис. 12.18).
240 Глава 12

Рис. 12.15. Ввод данных для авторизации в сервисе Weaved

Рис. 12.16. Создание имени для устройства в сервисе Weaved


WeЫOPi - веб-интерфейс и облако для Raspberry Pi 241

Рис. 12.17. Информация по командам запуска сервисов для доступа из Weaved

Рис. 12.18. Список устройств в сервисе Weaved


242 Глава 12

12.7.2. Подключение к Raspberry Pi в сервисе Weaved


Подключимся для начала к Raspberry Pi по WeЫOPi. Этому подключению соответ­
ствует устройство raspberry_pi_02 (см. рис. 12.18)- выбираем его и попадаем на
страницу авторизации сервиса WeЫOPi нашего Raspberry Pi (рис. 12.19).

::, https·//akfzcgdi.pб.weaved.com
---- - -- - -·- .. - -- - ---- ------- --- -- -·-- ---- - --- --- --- - - - --- ----
Х ,
Необкодима авторизация

Дм� достуn� н,а cepl!i,.i!p https·l.'М:.fucgdt,pб.weaVIO.com·


443 1'р�уется. у-,.аяrъ lr'.Y\:I nQJE.i=,108aт�nя i11 nApo.l'!b
(ообшен;,:е сереера.; w�ЫOPi.

Рис. 12.19. Страница доступа к WeЫOPi из Weaved

После авторизации- мы на главной странице WeЪIOPi нашего Raspberry Pi


(рис. 12.20).

+- с ' е https:i'/rngtdphf.pб.weaved.com
WeЫOPi Main �·lenu
GPIOHeader
Control 1111d Debug the RаsрЬепу Pi GPIO 1'irh а display \\iuch looks like the phys1cal l1eader.

GPIO List
Co11trol aud Debug tЬ,е Rа�рЬепу Pi GPIO ordered ша sшgle column.

Seria) Monitor
Use the bro\\·ser to play \\-itl1 Ser1al щterfaces coufigured it1 WeЫOPi.

Devices :мonitor
Control and Deb11g deпces and circuit\ ,пred to your Pi and c011f1gured ш \VeЫOPi.

Рис. 12.20. Страница доступа к WeЫOPi из Weaved

Подключимся теперь к Raspberry Pi по Web. Этому подключению соответствует


устройство raspberry_pi_02_http (см. рис. 12.18). Для такого подключения на
Raspberry Pi необходимо установить веб-сервер:
WeЫOPi - веб-интерфейс и облако для Raspberтy Pi 243

sudo apt-get update


sudo apt-get install apache2

Страница доступа из Weaved к веб-серверу на Raspberry Pi показана на рис. 12..21.

Itworks!
ТJ:us is the demult ,veb page forthis serv«.

Tl1e ,veb sбVer


1
software is running Ьut no contem has Ьееn added, vet.

Рис. 12.21. Страница доступа к веб-серверу на Raspberry Pi из Weaved


ГЛАВА 13

Проект Wyliodrin: управление


удаленными устройствами
из браузер·а
Румынский онлайн-сервис Wyliodrin (https://www.wyliodrin.com/), основанный на
графической среде программирования Blockly, предоставляет возможность графи­
ческого программирования сенсоров/актуаторов на Intel Galileo, Intel Edison, Beagle
Bone Black, Raspberry Pi, Arduino и еще целом ряде устройств (рис. 13.1). С по­
мощью Wyliodrin можно программировать устройства, загружать в них программы
и управлять этими устройствами прямо из браузера.
Дn:я программированиия встраиваемых устройств необходимо, как правило, чтобы
они были подключены к компьютеру. Однако при работе через Wyliodrin устройст­
во должно быть подключено только к Интернету. А раз так, то и находиться оно
может в любом месте, - вы можете запрограммировать его, просто войдя в свою
учетную запись (аккаунт) �yliodrin. Таким образом, если у вас есть, например,
метеостанция или удаленные устройства автоматизации, вы можете программиро­
вать их и управлять ими непосредственно из своего дома или офиса. Сервис позво­
ляет также строить графики для отображения данных, получаемых с устройств.
Программирование встраиваемьtх. устройств обычно требует знания языков С или
С++. Работая же через Wyliodrin, вы можете выбрать язык, который хорошо знаете
и любите: от тех же С/С++ до Java, Pascal, Shell Script, Perl, РНР, Objective-C, С#,
Python или JavaScript. И даже если вы не знаете никакого языка программирования,
то сможете воспользоваться визуальной средой программирования, где построение
программы осуществляется простым перетаскиванием блоков.
Чтобы начать пользоваться сервисом, необходимо зарегистрироваться, после чего
вы сможете выбрать тип учетной записи: бесплатный (использовать одно устройст­
во и создать три приложения) или платный (от 3,9 до 50 долларов в месяц). Для
владельцев плат Intel Galileo действует специальное предложение - годовая под­
писка, позволяющая бесплатно использовать :ГРИ платы и создать 1 S приложений.
Итак, регистрируемся в сервисе и попадаем в свой профиль. Сейчас наш профиль
пуст - какая-либо информация о подключенных устройствах и созданных прило-
246 Глава 13

Рис. 13.1. Главная страница проекта Wyliodrin

жениях в нем отсутствует. Так что, прежде всего нам надо fобавить в него уст­
ройство.

13.1. Добавление устройства в профиль


Для добавления устройства нажимаем в окне профиля кнопку Add New Board
и в открывшемся окне New Board (рис. 13.2) �водим название устройства (в поле

Рис. 13.2. Добавление устройства


Проект Wy/iodrin: управление удаленными устройствами из браузера 247

Name), выбираем IUiaтy, с которой собираемся работать (сейчас это Raspberry Pi),
и нажимаем КНОП!(У Next. В следующем окне (рис. 13.3) выбираем тип подклю­
чения устройства к сети Интернет и нажимаем кнопку' Submit - все, устройство
·
добавлено в профиль (рис. 13.4).

Рис. 13.3. Выбор настроек подключения устройства к Интернету

Рис.13.4. Профиль пользователя с добавленными устройствами

13.2. Запись образа Wyliodrin на SD-карту...


Теперь необходимо настроить наше устройство, для чего следует прежде всего ска­
чать и загрузить на карту памяти образ Wyliodrin для Raspberry Pi, выбрав из выпа­
дающего меню опцию Download SD Card (рис. 13.5).
ПРИМЕЧАНИЕ
Нам понадобится карта MicroSD емкостью минимум 4 Гбайт (рекомендуемый класс -
не ниже 10).
248 Глава 13

Рис. 13.5. Закачка образа Wyliodrin для Raspberry Pi

13.2.1 . ... в ОС Windows


Дпя записи образа Wyliodrin на SD-карту в операционной системе Windows скачай­
те и установите на компьютер программу Win32 Disk Imager (инсталлятор про­
граммы находится в свободном доступе по ссьmке http://win32-disk-imager.ru.
uptodown.com/).
Запустив установленную программу, выберите устройство (картридер), где нахо­
дится ваша SD-карта (рис. 13.6), и, нажав на значок папки у поля Image File, ука­
жите путь к файлу со скачанным и распакованным образом Wyliodrin (рис. 13.7).

Рис. 13.6. Выбор местонахождения SD-карты

Вернувшись после этого в окно программы Win32 Disk Imager, нажмите кнопку
Write- начнется процесс записи образа Wyliodrin на карту (рис. 13.k), по завер­
шении которого нажмите кнопку Exit и закройте приложение. Теперь ваша карта
MicroSD готова для использования на Raspberry Pi.
Проект Wy/iodrin: управление удаленными устройствами из браузера 249

Рис. 13.7. Указание пути к файлу образа

Рис. 13.8. Запись образа на SD-карту

13.2.2. ... в ОС Linux


Для записи образа Wyliodrin на SD-карту в операционной системе Linux вставьте
SD-карту в картридер- карта должна определиться в системе (в данном случае­
под именем mmcЫkO) (рис. 13.9).

Рис. 13.9. Определение SD-карты в списке устройств /dev


250 Глава 13

Выполните в терминале команду:


dd if=wyliodrin_raspberrypi_image_file of=/dev/device_name
где wyliodrin_raspberrypi_image_file- пуrь к скачанному и распакованному об­
разу Wyliodrin, а /dev/device_name - пуrь к подключенному картридеру с SD­
картой (например: /dev/mmcЫkO). Осталось только дождаться завершения процесса
записи.

13.2.3 .... в Мае OS


Для записи образа на SD-карту в операционной системе Мае OS Х скачайте утили­
ту PiWriter (http://sourceforge.net/projects/piwriter/), вставьте SD-карту в картри­
дер, запустите утилиту и следуйте инструкциям на экране.

13.2.4. ... в ОС Raspblan


Если вы опытный пользователь, то можете установить образ Wyliodrin сразу на
SD-карту с операционной системой RaspЬian. Для этого скачайте из репозитория
архив https://github.com/Wyliodrin/wyliodrin-server-nodejs/tree/development, рас­
пакуйте его на эту карту и запустите скрипт инсталляции:
./wyliodrin-server-raspberry-pi.sh
Если используется беспроводное соединение, необходим6 изменить файл /etc/
network/interfaces, записав в него код из листинга 13.1.

auto lo
iface lo inet loopback
iface ethO inet dhcp
allow-hotplug wlanO
iface wlanO inet rnanual
#wpa-roam /etc/wpa_supplicant/wpa_supplicant.conf
wpa-roam /home/pi/wyliodrin-server-nodejs/conf/wireless/wireless.conf
iface default inet dhcp

13.3. Запись на SD-карту


настроек Wyliodrin
Для каждой новой платы система генерирует уникальный файл настроек
скачайте из своего профиля этот файл, выбрав из выпадающего ме·
wyliodrin.json -
ню опцию Download wyliodrin.json (рис. 13.10), и запишите его на ту же карту
MicroSD, куда уже бьm записан образ Wyliodrin (рис. 13.11).
Проект Wyliodrin: управление удаленными устройствами из браузера · 251

Рис. 13.1О. Закачка файла настроек wyliodrin json

Рис. 13.11. Запись файла настроек на карту MicroSD

13.4. Подключение Raspberry Pi к Wyliodrin


Вставьте подготовленную SD-карту в Raspberry Pi и загрузитесь с нее. Если плата
получила доступ в Интернет, то после загрузки системы в профиле Wyliodrin ее
статус изменится на Online (рис. 13.12).
Из веб-интерфейса Wyliodrin можно произвести удаленную загрузку библиотек
(опция Extra Libraries) и обновление (опция Update lmage) системы (рис. 13.13),
причем протекание этих процессов вам будет наглядно показано (рис. 13.14).
252 Глава 13

Рис 13.12. Подключение Raspberry Pi к Wyliodrin

Рис. 13.13. Возможность удаленной загрузки библиотек и обновления системы

Рис. 13.14. Процесс удаленной загрузки библиотек на плату Raspberry Pi


Проект Wyliodrin: управление удаленными устройствами из браузера 253

Так же удаленно (из браузера) вы можете запустить оболочку shell (рис. 13.15)
и диспетчер задач (рис. 13.16), а также просто выключить Raspberry Pi.
Ну вот, наша плата готова к программированmо, и мы можем приступить к 'tозда­
нию приложений.

Рис. 13.15. Удаленный запуск оболочки shell

Рис. 13.16. Удаленный запуск диспетчера задач

13.5. Создание приложения


в графической среде программирования
Для создания нового приложения в окне профиля (см. рис. 13.13) нажмите кнопку
Create new application, после чего в открывшемся окне New Project введите назва­
ние нового приложения, его описание и выберите язык программирования.
254 Глава 13

В списке языков программирования Programming Language уже имеется несколь­


ко готовых шаблонов приложений от Wyliodrin - выберите в качестве первого
приложения: Led Blink- Visual Programming (рис. 13.17). Подтвердите свой
выбор, и наше новое приложение создано (рис. 13.18).

Рис. 13.17. Соэдание нового приложения

Рис. 13.18. Список приложений профиля


Проект Wy/iodrin: управление удаленными устройствами из браузера 255

Выбрав приложение в списке приложений (см. рис. 13.18), мы попадем в окно его
редактирования (рис. 13.19)- здесь можно посмотреть, как выглядит код прило­
жения на языках Python и JavaScript, внести в этот код какие-либо изменения, а
также загрузить приложение на плату и запустить на выполнение.

Рис. 13.19. Окно редактирования приложения

Немного подредактируем наше приложение: изменим в визуальных блоках значе­


ния pin на в:ь1вод 7 и увеличим задержки delay до 2000 мс (рис. 13.20).

Рис. 13.20. Редактирование приложения


256 Глава 13

Теперь подключим к Raspberrry Pi светодиод согласно схеме, приведенной на


рис. 13.21, и нажмем в окне приложения на надпись Stopped (выделена кружком
на рис. 13.20). Система проверит код и, если все в порядке, осуществит загрузку
приложения на плату и запуск его на выполнение (рис. 13.22).

Рис. 13.21. Схема подключения светодиода к плате Raspberry Pi

Рис. 13.22. Запуск приложения


Проект Wy/iodnn: управление удаленными устройствами из браузера 257

В это время на Шiате Raspbeпy Pi мы можем наблюдать мигание светодиода, под­


ключенного к выводу 7. Нажатие кнопки Stop в правом верхнем углу окна прило­
жения (рис. 13.22) приведет к остановке приложения на Шiате.

13.6. Включение/выключение светодиода


с веб-страницы
Для управления светодиодом с веб-страницы создадим новый проект web_raspi и
в визуальном редакторе впишем код, представленный на рис. 13.23. Запустим на
Raspbeпy Pi веб-сервер (порт 5000). При попадании на главную страницу браузер
выдает код:
<br><a href='/on'>On</a>
<br><a href='/off'>Off</a>

По нажатию на ссьmку Оп светодиод, подключенный к выводу 7, зажигается, по


нажатию на ссылку Off - гаснет.

Рис. 13.23. Код приложения web_raspi в визуальном редакторе

Теперь надо узнать адрес нашего веб-сервера, т. е. IР-адрес Raspbeпy Pi, - запус­
тим для этого из браузера оболочку shell и выполним в ней команду ip addr show
(рис. 13.24).
Далее запускаем в Wyliodrin наше приложение web_raspi (рис. 13.25), набираем
в браузере адрес bttp://ip_raspberry:5000 и управляем включением/выключением
светодиода переходом по ссылкам (рис. 13.26).
258 Глава 13

Рис. 13.24. Получение IР-адреса Raspberry Pi из командной оболочки shell

Рис. 13.25. Запуск приложения web_raspi

Qn
Off

Рис. 13.26. Веб-страница управления включением/выключением светодиода


Проект Wy/iodtin: управление удаленными устройствами из браузера 259

13.7. Подключение платы Arduino


к сервису Wyliodrin...
Плату Arduino невозможно нацрямую использовать для подключения к сервису
Wyliodrin. Но программное обеспечение Wyliodrin позволяет использовать возмож­
ности платы Arduino, подключенной к микрокомпьютеру Raspberry Pi. Рассмотрим
здесь соответствующие примеры.

13.7.1 . ...с помощью библиотеки Firmata


Сначала загрузим на плату Arduino скетч StandartFirmata из Аrduinо-библиотеки
Firmata (рис. 13.27), входящей в состав Arduino IDE. Библиотека Firmata реализует
протокол Firmata, упрощающий общение с программами на компьютере.

Рис. 13.27. Загрузка на плату Arduino скетча StandartFirmata из библиотеки Firmata

Подсоединим теперь плату Arduino к нашему Raspberry Pi, создадим в своем про­
филе Wyliodrin новый проект arduinol и выберем в качестве; языка программиро­
вания VisualProgramming. На следующем шаге выберем подключение платы
Arduino: Connect an Arduino to the board (Raspberry Pi only)- как показано на
рис. 1З.2�,
260 Глава 13

Рис. 13.28. Выбираем при создании проекта подключение платы Arduino

Создав проект� зайдем в окно редактирования проекта и в визуальном редакторе


впишем код мигания светодиодом на 13-м выводе Arduino с периодичностью 2 сек.
(рис. 13.29). Узнать порт подюпочения платы Arduino к Raspberry Pi можно прямо из
сервиса Wyliodtin, запустив оболочку shell и выполнив команду drnesg (рис. 13.30).

Рис. 13.29. Программа в VisualProgramming


Проект Wy/iodrin: управление удаленными устройствами из браузера 261

Рис. 13.30. Определение порта подключения Arduino с помощью оболочки shell

Осталось запустить проект и наблюдать мигание светодиода на выводе 13 платы


Arduino.
Создадим новый проект (arduino2), для которого подкточим к аналоговым входам
Аrduinо-аналоговый датчик температуры LM35 и фоторезистор (рис. 13.31), и рас­
смотрим отображение получаемых данных в виде виджетов и графиков.
Выберем для этого проекта тот же язык программирования - VisualProgramming
и подкточение платы Arduino: Connect an Arduino to the board (Raspberry Pi
only)- как показано на рис. 13.28. Создав проект, заходим в режим редактирова­
ния и создаем в визуальном редакторе код, приведенный на рис. 13.32.
Запускаем проект на выполнение и наблюдаем вывод в монитор программы на сай­
те Wyliodrin показаний датчика температуры LM35 и фоторезистора (рис. 13,33).
Теперь добавим в браузере отображение температуры на виджете и показаний фо­
торезистора щ� графике. Для этого в окне редактирования приложения arduino2
открываем вкладку Signals (рис. 13.34), выбираем элемент Send signal " ... " with
value О и добавляем его в цикл опроса данных аналоговых входов. Добавить следует
262 Глава 13

Рис. 13.31. Схема подключения к плате Arduino


аналогового датчика температуры и фоторезистора

Рис. 13.32. Программа в VisualProgramming для получения показаний с датчиков


Проект Wy/iodrin: управление удаленными устройствами из браузера 263

Рис. 13.33. Получение показаний с датчиков температуры и освещенности

Рис. 13.34. Вкладка Signal

два таких элемента: один - для фоторезистора, второй - для датчика темпераrу­
ры (рис. 13.35). При этом присваиваем каждому сигналу соответствующее имя:
GraphPhoto - для отправляемых значений фоторезистора, VidgetTemp - для от­
правляемых значений датчикр темпераrуры.
264 Глава 13

Рис. 13.35. Элементы вкладки Signal (Send signal ...) добавлены в программу

Далее нажимаем в окне программы (см. рис. 13.34) на ссьmку Dashboard и добав­
ляем в окно из правого списка два элемента: виджет температуры Thermometer и
график Spline Line (рис. 13.36). Добавленные элементы необходимо отредактиро­
вать так, чтобы они отображали данные отгq,авляемых нашей программой сигна­
лов, -редактируем элементы (рис. 13.37 и 13.38) и запускаем программу.

Рис. 13.36. Добавление элементов в окне Dashboard


Проект Wyliodnn: управление удаленными устройствами из браузера 265

Рис. 13.37. Изменение параметров элемента Thermometer

Рис. 13.38. Изменение параметров элемента Spline Line


266 Глава 13

Рис. 13.39. Графическое отображение в брауэере данных фоторезистора


и датчика температуры

Теперь в браузере мы можем увидеть графическое отображение температуры и


график изменения во времени ПО!(азаний фоторезистора (рис. 13.39).

13.7.2. ...без использования библиотеки Firmata


Чтобы отправить в сервис Wyliodrin результат mобого скетча, выполняемого на
Arduino, надо чтобы плата Arduino по последовательному порту отправляла данные
в Raspberry Pi, а скриm, запущенный на Raspberry Pi, отправлял бы эти данные
в сервис Wyliodrin.
Допустим, мы собираемся отправлять в сервис Wyliodrin данные с датчиков, рабо­
тающих по протоколу I2 C, - воспользуемся для этого датчиком освещенности
ВН1750 и датчиком влажности и температуры SHT2l, рассмотренными нами в гла­
ве 6. Данные с этих датчиков будут отправляться из Arduino в Raspberry Pi по по­
следовательному порту, а скриm на языке Python, запущенный на Raspberry Pi,
станет принимать эти данные и отправлять в сервис Wyliodrin. Схема подкточения
датчиков BHl750 и SHT21 к плате Arduino представлена на рис. 13.40.
Загрузим на плату Arduino скетч из листинга 13.2. Arduino здесь получает данные
с датчиков и отправляет эти данные в формате JSON по последовательному порту
в Raspberry Pi.
Проект Wyliodtin: управление удаленными устройствами из браузера 267

Рис. 13.40. Схема подключения датчиков ВН1750 и SHT21 к плате Arduino

// Подключение библиотек для датчика ВН1750


#include <Wire.h>
#include <BH1750.h>
ВН1750 lightMeter;
// Подключение библиотеки для датчика SHT21
#include <SHT2x.h>

uintlб t lux;
float temp;
float humidity;

void setup()
{
// подключение последовательного порта
Serial.begin(9600);
// запуск датчика ВН1750
lightMeter.begin();
}
268 Глава 13
void loop()

// получение данных с ВН1750


lux = lightMeter.readLightLevel();
humidity=SHT2x.GetHumidity();
temp=SHT2x.GetTemperature();
Serial.print("{lux:");Serial.print(lux);
Serial.print(",temp:");Serial.print(temp);
Serial.print(",humidity:");Serial.print(humidity);
Serial.println("}");
// задержка 10 сек
delay(lOOOO);
}

Зайдем теперь в сервис Wyliodrin и создадим новое приложение: arduino3. Выбе­


рем для него язык программирования Python и впишем в окне редактирования про­
граммы (рис. 13.41) код, приведенный в листинге 13.3. Здесь мы считываем по по­
следовательному порту из Arduino данные с датчиков BHl 750 и SHT21 в формате
JSON и отправляем эти значения в виджеты Lux (Освещенность), Temp (Темпера­
тура) и Humidity (Влажность).

Рис. 13.41. Код приложения arduinoЗ


Проект Wy/iodrin: управление удаленными устройствами из браузера 269

frorn wyliodrin import


irnport json
import serial

def rnain() :
initCoппnunication()
print 'Hello from Wyliodrin\n'
ser = serial.Serial('/dev/ttyACМO', 9600, tirneout=l)
ser.open()
try:
while 1:
responsel ser.readline()
if len(responsel)>O:
print responsel
rnll responsel.find('lux') + 1 + 4
rn12 responsel.find(', t') + 1 - 1
mЗl responsel.find('humidity') + 1 + 9
rn21 responsel.find('temp') + 1 + 5
rn22 responsel. find(', h') + 1 - 1
rn31 responsel. find('humidity') + 1 + 9
m32 responsel.find('}') + 1 - 1
print(responsel[int(rn21 - 1) : int(rn22)])
try:
lux=float (responsel[int(rnll - 1) : int(rn12)])
hurnidity=float (responsel[int(rn31 - 1) : int(rn32)])
ternp=float (responsel[int(rn21 - 1) : int(rn22)])
humidity=float (responsel[int(rn31 - 1) : int(m32)])
sendSignal('Lux', lux)
sendSignal('Temp', temp)
sendSignal('Humidity', humidity)
except ValueError:
print("ERROR")
except Keyboardinterrupt:
ser.close()

if narne " main "·


rnain()

Теперь мы можем запустить приложение arduino3 в браузере в Wyliodrin и наблю­


дать вывод данных с датчиков на виджеты и в монитор (рис. 13.42).
270 Глава 13

Рис. 13,42. Запуск приложения arduinoЗ

13.8. Совместная работа Raspberry Pi


и платы GrovePi
Система Grove представляет- собой набор готовых к использованию электронных
устройств в виде модулей. Она включает базовую плату и различные модули со
стандартными разъемами для подключения к ней. Базовая плата позволяет легко
связать выводы популярных микроконтроллеров с контактами модулей Grove. Су­
ществуют бюовые платы для Arduino, Raspberry fit, Intel GаШео, Intel Edison, mbed,
LaunchPad и других микроК:Энтроллеров и мик�э�к:эмпьюте�э�в. Большой выбор
базовых плат и модулей Grove представлен в интернет-магазине Seeedstudio:
https://www.seeedstudio.com/depot/s/grove.html?search_in_description=O.
Для подключения к Raspberry Pi (рис. 13.43) используются платы расширения
GrovePi и GrovePi+ (плата для подключения плат Raspberry Pi версий «А+»
и «В+»).
Плата GrovePi+ поддерживает подключение семи цифровых и трех аналоговых вы­
водов, трех портов I2 c, одного последовательного порта подключения к GrovePi
и последовательного порта подключения к Raspberry Pi.
Для работы Raspberry Pi с платой GrovePi необходимо установить соответствующее
программное обеспечение. Для этого подключаемся по ssh к нашему �aspberry Pi
и клонируем репозиторий GrovePi:
git clone https://githuЬ.com/Deкterind/GrovePi
Проект Wyliodrin: управление удаленными устройствами из браузер а 271

Рис. 13.43. Подключение платы GrovePi+ к RaspWerry Pi

Переходим в цапку GrovePi/Script:


cd GrovePi/Script
Предоставлям файлу install.sh права н� выполнение:
sudo chmod +х install.sh
И запускаем его:
sudo ./insta�l.sh
Скрипт будет работать достаточно продолжительное время, связанное с зttкачкой
из Интернета и установкой дополнительных пакетов (рис. 13.44). По завершении
работы скрипта Rasp�rry Pi необходимо перезагрузить:
sudo reboot
После перезагрузки можно подключить GrovePi к Raspberry и использовать с ним
устройства Grove. На странице http://www.seeedstudio.com/wiki/GrovePi+ можно
найти ссьmки на проекты с кодом по подключению некоторых датчиков системы
Grove (рис. 13.45).
Работать с устройствами Grove через плату GrovePi в Wyliodr-in весьма просто: под­
соединим к контактам АО платы GrovePi датчик света Grove light (рис. 13.46), соз­
дадим в Wyliodrin новое приложение arduino4 и выберем для него язык
VisualProgramming, напишем программу вывода получаемых значений на график
(рис. 13.47), запустим программу и увидим график получаемых с датчика Grove
light значений (рис. 13.48).
272 Глава 13

Рис. 13.44. Установка программного обеспечения

Рис. 13.45. Ссылки на проекты с подключением да"Nиков Grove к плате GrovePi


Проект Wy/iodrin: управление удаленными устройствами из браузера 273

Рис. 13.46. Датчик Grove light

Рис. 13.47. Программа для вывода данных датчика Grove light на график

Рис. 13.48. График получаемых с датчика Grove light значений


274 Глава 13

13.9. Обмен сообщениями


между платами Raspberry Pi
через сервис Wyliodrin
В сервисе Wyliodrin существует возможность обмена сообщениями между платами.
Чтобы исследовать эту возможность, добавим к нашему профилю еще одну плату
Raspberry Pi (см. разд. 13.1)- и назовем ее Raspberry_pi_02. Запишем на нее об­
раз, файл настроек wyliodrin.json и подключим плату к сети Интернет. Откроем свой
профиль Wyliodrin и увидим, что она находится в статусе Online (рис. 13.49).

Рис. 13.49. Добавление в профиль еще одной платы Raspberry Pi: RaspЬerry_pi_02

Наша новая плата будет принимать JSОN-сообщения, отправляемые платой


Raspberry_pi_Ol, к которой подключена плата Arduino UNO с датчиками освещен­
ности BHl 750 и влажносm и температуры SHT21 (см. рис. 13.40).
В плату , Arduino загружен скетч из лисmнга 13.2, который каждые 1О секунд
отправляет данные датчиков в формате JSON по последовательному порту в
Raspberry_ pi_Ol. Эги данные плата Raspberry_pi_Ol станет оmравлять в плаrу
Raspberry_pi_ 02 через Wyliodrin.
Создадим ,io�9e ,прцложение: arduin'o5_send_data, выберем для него язык про­
граммирования Python и запишем в него код из листинга 13.4.

frorn wyliodrin import *


irnport json
irnport serial

def rnain() :
initCornrnunication()
print 'Hello frorn Wyliodrin\n'
ser = serial.Serial('/dev/ttyACМO', 9600, tirneout=l)
ser.open()
try:
while 1:
responsel = ser.readline()
Проект Wy/iodrin: управление удаленными устройствами из браузера 275

if len(responsel)>O:
print responsel
sendМessage('victoruni_raspberry_pi_02@wyliodrin.com', 'labell',
json.dumps(responsel))
except Keyboardinterrupt:
ser.close()

if name " main "·


main()

Функция sendМessage('boardid', 'laЬel', json.dumps(message)) отправляет сооб­


щение message с меткой label в плату boardid. Параметр boardid можно посмотреть,
выбрав в настройках платы пункт BoardШ (рис. 13.50).

Рис. 13.50. Значение параметра boardid

Теперь напишем приложение для платы Raspberry_pi_02, обеспечивающее получе­


ние сообщений от платы Raspberry_pi_Ol: создаем новое приложение arduino6_
get_message, выбираем для него язык программирования Python и заносим в при­
ложение код из листинга 13.5.

from wyliodrin irnport *


import json

def messagesReceiver(sender, laЬel, error,· message):


print(message)

def main():
openConnection( '1abell', messagesReceiver)

if name " rnain "·


main()
276 Глава 13

Теперь при запуске на плате Raspbeпy_pi_02 этого приложения мы увидим по­


лучение сообщений, отправленных приложением из платы Raspbeпy_pi_Ol
(рис. 13.51).

Рис. 13.51. Получение платой Raspberry_pi_02 сообщений из платы Raspberry_pi_01

Использовать получаемые в сообщениях данные можно по своему усмотрению. Мы


же просто выделим из них нужные значения и выведем их на виджеты (для темпе­
раТ)<рЫ и влажности) и график (освещенность) - как мы делали в разд. 13. 7.
Изменим для этого приложение arduino6_get_message, добавив в него парсинг
значений из получаемого сообщения и вывод их на виджеты и график (рис. 13.52).
Код приложения приведен в листинге 13.6.

from wyliodrin import *


import json

def messagesReceiver(sender, label, error, me�sage):


print(message)
mll = message.find('lux') + 1 + 4
ml2 = message.find(', t') + 1 - 1
mЗl = message.find('humidity') + 1 + 9
m21 = message.find('temp') + 1 + 5
m22 = message.find(', h') + 1 - 1
, m31 = message.find('humidity') + 1 + 9
m32 = message.find('}') + 1 - 1
try:
lux= float (message[int(mll - 1) int(ml2)])
humidity=float (message[int(m31 - 1) : int(m32)])
Проект Wyliodrin: управление удаленными устройствами из браузера 277

temp=float (message[int(m21 - 1) : int(m22)])


hщnidity=float (message[int(m31 - 1) : int(m32)])
print(lux)
print(temp)
print(hщnidity)
sendSignal('Lu:t:', lux)
sendSignal('Тетр', temp)
sendSignal( 'Humidity', hщnidity)
except ValueError:
print("ERROR")

def main():
openConnection('labell', messagesReceiver)

if name " main н:


main()

Рис. 13.52. Вывод значений, получаемы,� платой Raspberry_pi_02


из платы Raspberry_pi_01, на виджеты и график

13.1 О. Отправка данных в сервис Wyliodrin


с мобильного устройства
Сервис Wyliodrin позволяет плате Raspberry Pi получать данные с датчиков мо­
бильного устройства (планшета или смартфона). Для этого необходимо скачать
и установить на него из Play Маркет приложение Wyliodrin Sensors (рис. 13.53).
278 Глава 13

В приложении следует задать настройки: Ю устройства и интервал передачи дан­


ных (рис. 13.54) и выбрать список датчиков устройства для передачи данных
(рис. 13.55).

Рис. 13.53. Приложение Wyliodrin Sensors в Play Маркет

Рис. 13.54. Задание 1D устройства и интервала передачи данных

В окне профиля платы Raspberry Pi из соответствующего выпадающего меню надо


выбрать возможность получения мобильных сообщений: ЕnаЫе Moblle Messages
(рис. 13.56). Сделав это, создайте соединение между платой и мобильным прило­
жением - просто нажмите кнопку Board m
в выпадающем меню, и QR-код со­
единения отобразится на экране. Чтобы сканировать этот код, нажмите на большую
красную кнопку Scan Token в мобильном приложении. Завершив сканирование
QR-кода (рис. 13.57), мобильное устройство начнет посылать в сервис Wyliodrin
данные, поступающие из выбранных датчиков.
Проект Wy/iodrin: управление удаленными устройствами из браузера 279

Рис.13.55. Выбор датчиков для передачи данных

Рис.13.58. Включение мобильных сообщений для платы RaspЬerгy Pi


280 Глава 13

Рис. 13.57. Сканирование QR-кода в мобильном приложении

Теперь создадим в Wyliodrin приложение arduino8 для платы Raspberry_pi_02 и


выберем для него язык программирования VisualProgramming. Код для этого при­
ложения представлен на рис. 13.58. Здесь мы получаем показания сенсора light
с мобильного устройства и выводим данные на экран и в график.
с

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


устройства, передаваемые нашему приложению.

Рис. 13.58. Код приложения arduino8


Рис. 13.59. График и показания датчика light мобильного устройства,
передаваемые нашему приложению
ГЛАВА 14

Wi-Fi модуль ESP8266

С конца 2014 года на китайских торговых площадках появились Wi-Fi модули


ESP8266. Причем, как выяснилось,
1
это не просто модули Wi-Fi, а полноценные
32-битные микроконтроллеры со своими наборами GPIO, в том числе поддержи-
вающими шины SPI, UART и 12С. При этом сами модули состоят из минимального
количества деталей: собственно чипа ESP8266, Flаsh-памяти и кварцевого генера­
тора. Характеристики модулей представлены в табл. 14.1.

Таблица 14.1. Характеристики модулей ЕSР82бб

Частота Wi-Fi 2412-2484 МГц


Стандарт 802.11 Ыg/n
Мощность +20дБ
Поддерживаемые типы wифрования WEP, WPA, WPA2
ПоАдерживаемые режимы работы Клиент (STA), точкадоступа (АР),
клиент+точкадоступа (STA+AP)
Напряжение питания 1,7-3,6 В
Потребление тока 70 мА (пиковое значение 240 мА)
Количество доступных выводов GPIO 4-10
Внеwняя Flаsh-память 512 Кбайт
RАМданных 80 Кбайт
RAM инструкций 32 Кбайт
Температурный режим От-40 ДО +70 °С

В настоящее время выпускается 12 модификаций плат модулей ESP8266, разли­


чающихся количеством выводов и вариантами исполнения (рис. 14.1). Модули
продаются с загруженной прошивкой, которая образует мост Wi-Fi ---+ UART для
подключения к другому микроконтроллеру, в том числе и к Arduino. Настройка со­
единения и обмен данными осуществляются с помощью АТ-команд.
284 Глава 14

ESP-01 ESP-02 ESP-03 ESP-04 ESP-05 ESP-06

ESP-07 ESP-08 ESP-09 ESP-1 О ESP-11


Рис. 14.1. Модули ESP8266

Возможно два варианта работы с модулем:


[::J использование его совместно с микроконтроллером, который будет управлять
модулем по UART;
[::J создание собственной прошивки для чипа ESP8266 и его применение как само­
достаточного устройства.

14.1. Режим АТ-команд


Рассмотрим работы с модулем ESP8266 в режиме АТ-команд, для чего подключим
его к компьютеру через переходник USB-to-RS232. Назначение выводов модуля
представлено на рис. 14.2. Для работы модуля требуется внешнее питание 3,1 В.
Схема подключения весьма простая:
[::J вывод VCC-питание платы (+3,3 В);
[::J вывод GND-общий;
·r:J выводы RX и ТХ-подключаем к конвертеру USB-to-RS232 (в режиме 3,3 В);
r:J вывод CB_PD (Chip еnаЫе)-подключаем к питанию платы (+3,3 В).
Для отправки в модуль АТ-команд я использовал в Мае OS Х программу CoolТerm,
а в ОС Windows- программу Termite. Узнать скорость СОМ-порта для соедине-
--- RХ
---vcc
---GPIOO
---RESEТ
...---CH_PD
---GPI02
---тх
---GND
Рис. 14.2. Назначение выводов модуля ESP8266 исполнения ESP-01
Wi-Fi модуль ЕSР82бб 285

ния с модулем можно только экспериментально, поскольку для различных проши­


вок она может быть разной. Так, для моего модуля эта скорость оказалась равной
9600 бод. Кроме того, установить обмен удалось только после отключения и по­
вторного подключения к питанию вывода CH_PD.
После удачного подключения модуля к 'компьютеру набираем в терминале АТ и
должны получить в ответ от модуля ок. Команда AT+GМR выдает номер версии про­
шивки модуля, команда AT+RST - перезагружает модуль (рис. 14.3).

Рис. 14.3. Отправка АТ-команд в модуль из программь1 Termite

Набор доступных АТ-команд в новых версиях прошивки модулей ESP8266 посто­


янно пополняется. В табл. 14.2 приведен полный список АТ-команд для комплекта
средств разработки (SDK) 0.9.5 версии 021.
Таблица 14.2. Полный список АТ-команд для SDK 0.9.5 версии 021

Команда Описание Выполнение


АТ Проверка модуля, Если модуль АТ
успешно стартовал, то он отвечает
ок
AT+RST Перезапуск модуля AT+RST
AT+GМR Отобразить версию прошивки AT+GMR
AT+GSLP Переход в режим пониженного АТ+GSLР=<время мс>
энергопотребления
АТЕ Включить/выключить эхо АТО
ATl
AT+RESTORE Сбросить на заводские настройки AT+RESTORE
Aт+UART Настройка последовательного AT+UART= baudrate, databits,
интерфейса stopbits, parity, flow control
286 Глава 14

Таблица 14.2 (продолжение)


Команда Описание Вь1полнение
Ат+СWМОDЕ Переключение режима Wi-Fi. Ат+СWМОDЕ?
Для вступления в силу требуется AT+CWМODE=). (station)
перезапуск модуля командJй
AT+RST AT+CWМODE=2 (АР)
АТ+СWМОDЕ=З (station+AP)
AT+CWJAP Подключение к АР(точке доступа) AT+CWJAP =<идентификатор
сети>,<пароль>
AT+CWJAP?
AT+CWIAP Отобразить список доступных АР AT+CWIAP
AТ+CWQAP Отключение от АР AT+CWQAP
Aт+CWSAP Установить параметры AT+CWSAP= <идентификатор сети>,
для режима АР <пароль>, <канал>,
�тип шифрования>
AT+CWLIF Отобразить IР-адреса подключен- AT+CWLIF
ных клиентов
AT+CWDHCP Установить режим DHCP АТ+СWDНСР=<режим>, <вкл>
АТ+СIРSТАМАС 1 Посмотреть/установить МАС-адрес AT+CIPSTAМAC=<mac>
в режиме station AT+CIPSTAМAC?
АТ+СIРАРМАС Посмотреть/установить МАС-адрес AT+CIPAPМAC=<mac>
в режиме softAP АТ+СIРАРМАС?
АТ+ CIPSTA Посмотреть/установить IР-адрес АТ+ CIPSTA=<ip>
в режиме station АТ+ CIPSTA?
-
АТ+ CIPAP Посмотреть/установить IР-адрес АТ+ CIPAP=<ip>
в режиме softAP
, АТ+ CIPAP?
AT+CIPSTATUS Отобразить статус подключения. AT+CIPSTAТUS
Возвращает 1D соединения,
тип соединения(ТСР или UDP),
IР-адрес, порт, тип связи(клиент,
сервер)
AТ+CIPSTART Установить подключение ТСР
или UDP
AT+CIPSEND Отправить данные AТ+CIPSEND=?
АТ+СIРSЕNО=<длина>
АТ+СIРSЕND=<идентификатор><длина>
AT+CIPCLOSE Закрыть подключение ТСР '

или UDP
AT+CIFSR Отобразить IР-адрес, который
получили от АР, и адрес softAP
AT+CIPМUX Выбрать режим ОДИНОЧНЫХ или
множественных подключений '

AТ+CIPSERVER Запустить(перезапустить)сервер
Wi-Fi модуль ЕSР82бб 287

Таблица 14.2 (окончание)

Команда Описание Выполнение


AT+CIPSTO Установить тайм-аут сервера
AT+CIPMODE Установить сквозной режим
AT+CIUPDATE Обновление прошивки через
облако. Модуль должен находиться
в режиме 1 или З и быть подклю-
ченным к АР с доступом к Интернету
AT+PING Пинг по имени хоста или IР-адресу
+IPD Получить данные из сети

Рис. 14.4. Программа AppStack ESP8266 Config


288 Глава 14

Легко настроить модуль ESP8266, не заморачиваясь с АТ-командами, можно с по­


мощью программы AppStack ESP8266 Config, свободно доступной для закачки,
например, с российского сайта поддержки платы по ссылке: http://esp8266.ru/
download/esp8266-utils/ESP8266_Config.zip.
Внешний вид программы AppStack ESP8266 Config представлен на рис. 14.4. На­
стройка модуля осуществляется с помощью графического интерфейса, при этом
выполнение команд можно видеть в мониторе программы (рис. 14.5). Из командной
строки монитора также можно посылать в модуль и АТ-команды.
Обновление прошивок модуля ESP8266 возможно осуществлять через облако.
Модуль при этом должен находиться в режиме 1 или 3 и быть подключен к точке
доступа с выходом в Интернет. Для обновления прошивки надо переключить мо­
дуль в режим прошивки, «подтянув» GPIOO на «минус» и выполнить команду:
AT+CIUPDATE
После прошивки эту «подтяжку» следует отключить.

Рис. 14.5. Serial Monitor программы AppStack ESP8266 Config


Wi-Fi модуль ESP8266 289

Следуя этой инструкции, можно обновиться только до официальных версий. Есть и


другой вариант обновления прошивки - вручную. Для этого можно воспользо­
ваться программами ХТСОМ UТIL, ESP8266 Flasher, NodeMCU Flasher и рядом
других, доступных для свободной закачки с российского сайта поддержки платы
ESP8266 (http://esp8266.ru ).

14.2. Прошивка NodeMCU


Прошивка NodeMCU способна интерпретировать команды языка Lua - скрипто­
вого языка программирования, разработанного подразделением Tecgraf Католиче­
ского университета Рио-де-Жанейро. Интерпретатор этого языка распространяется
свободно, с открытым1:1 исходными текстами на языке Си.
Прошивка NodeMCU, кроме интерпретирования команд языка Lua, может также
создавать файлы во Flаsh-памяти модуля ESP8266 и выполнять их. Роль запускаю­
щего файла прошивки (autorun) исполняет при этом файл init.lua. С помощью luа­
команд можно:
(J подключаться к точке доступа Wi-Fi;
r:J выступать в роли точки доступа Wi-Fi;
r:J уходить в глубокий сон для снижения энергопотребления (недоступно для
АТ-команд);
(J привязать luа-функцию к кнопке на GPI016 (недоступно для АТ-команд в стан­
дартной прошивке, частично доступно в некоторых кастомнь�х);
(J включать/выключать светодиод на GPI016 (недоступно для АТ-команд в стан­
дартной прошивке, доступно в некоторь�х кастомнь�х);
(J перенаправлять вывод - в примерах использования прошивки есть Telnet­
cepвep (недоступно для АТ-команд);
(J создавать, записывать, читать, выполнять, искать, удалять, выводить списком
файлы Flаsh-памяти (недоступно для АТ-команд);
(J в режиме startsmart автоматически находить открьrrую сеть Wi-Fi и подключать­
ся к ней (недоступно для АТ-команд);
(J выводить свой МАС-адрес (недоступно для АТ-команд в стандартной прошивке,
доступно в некоторь�х кастомных);
(J управлять пользовательским таймером (недоступно для АТ-команд);
(J управлять таймером WatchDog (недоступно для АТ-команд в стандартной про­
шивке, частично доступно в некоторь�х кастомнь�х);
(J управлять (запись, чтение, триггер) выводами GPI01-GPI05, GPIOlO, GPI012-
GPI015 (недоступно для АТ-команд);
(J обеспечивать РWМ (IIШМ) на выводах GPI01-GPI05, GPIOlO, GPI012-
GPI015 (недоступно для АТ-команд);
r::J использовать ТСР/IР-сокеты;
290 Глава 14

(] обеспечивать режим веб-сервера;


(] осуществлять адресацию, запись, чтение по шине 12С - (недоступно для
АТ-команд);
(] выполнять 10-битное преобразование АЦП на выводе TOUT (недоступно для
АТ-команд).
Чтобы воспользоваться прошивкой NodeMCU, надо скачать ее последнюю версию
с сайта https://github.com/nodemcu/nodemcu-firmware/tree/master/pre_build и
прошить ее на пла1}', например, с помощью утилиты ESP8266 Flasher (рис. 14.6),
которую можно скачать со страницы http://esp8266.ru/down1oads/esp8266-
utils/#wpfЬ-cat-3.

Рис. 14.6. Прошивка модуля программой esp8266_flasher_win

Затем со страницы http://esp8266.ru/esp1orer-ide-esp8266 скачиваем комплект


средств разработки (SDK) и запускаем ESPlorer (рис. 14.7). Средство ESPlorer от­
личается от других программ для ESP8266 тем, что:
(] работает на множестве платформ;
LI поддерживает несколько открытых файлов;
(] обеспечивает подсветку кода языков Lua и Python;
LI имеет режимы Undo/Redo;
LI поддерживает цветовые темы редакторов: dark, Eclipse, IDEA, Visual Studio;
LI осуществляет автозавершение кода по нажатию комбинации клавиш
<Ctrl>+<Space>;
(] обеспечивает «умную» отправку файлов с ожиданием ответа;
LI поддерживает несколько прошивок одновременно.
Wi-Fi модуль ЕSР82бб 291

Рис. 14.7. Окно программы ESPlorer

Как уже было отмечено, обеспечивающий autorun скрипт init.lua автоматически


стартует при перезагрузке. Создадим этот скрипт и внесем в него код для автома­
тического подключения модуля в качестве клиента к беспроводной сети (лис­
тинг 14.1), а для модуля установим режим client+AP.

wifi.setmode(З)
print('set mode= STATION (mode= ',wifi.getmode(),') '}
print('МАС= ',wifi.sta.getmac())
print('set wifi'}
wifi config start
wifi.sta.config("dlinkdap",""}
wifi config end

Загрузим скрипт в модуль, нажав на кнопку Save to ESP (см. рис. 14. 7), перезагру­
зим модуль и убедимся, что он подключен в качестве клиента к беспроводной сети.

14.2.1. Запуск веб-сервера


Теперь напишем скрипт создания прос.тейшего веб-сервера, чтобы при обращении
к модулю по НТТР с него выдавалась информация. Создадим для этого файл
server1 .lua и запишем в него код, дредставленный в листинге 14.2.
292 Глава 14

port = 80
srv=net.createServer(net.TCP)
srv:listen(port,
function(conn)
conn:send("HTTP/1.1 200 OK\nContent-Type: text/html\nRefresh: 5\n\n"

"<!DOCTYPE HTML>" ..
"<html><body>" ..
"<b>ESP8266</b></br>"
"Node ChipID : " .. node. chipid () .. 11 <br>" ..
1
1 Node МАС :
11
• • wifi.sta.getmac() .. "<br> 11
11
Node Неар : 11 • •
node.heap() 11
<br> 11
11
Timer Ticks : 11 • • tmr.now() .. 11 <br>11 • •
11
</html></body>")
conn:on( 11 sent 11 ,function(conn) conn:close() end)
end

Сохраним файл server1.lua в модуле и запустим.


ВНИМАНИЕ/
Для запуска сервера при загрузке модуля необходимо в конце нашего autorun-фaйлa
init.lua добавить строку:
dofile(serverl.lua)

А для проверки работы сервера подключимся к точке доступа модуля и наберем


в браузере ее адрес: Ьttp://192.168.4.1 (рис. 14.8).

ESP8266··· ·
Node ChiplD · 10269131
Node МАС 18-FE-34-9C-FF-EB
Node Неар · 17600
Timer Ticks : 461355948

Рис. 14.8. Обращение к серверу на ESP8266

14.2.2. Подключение к ESP8266 модулей датчиков


средствами языка Lua
Важный момент - в прошивке NodeMCU присутствуют модули датчиков, которые
можно подключать к скриптам командой require() . Количество таких модулей по-
Wi-Fi модуль ЕSР82бб 293

стоянно увеличивается, и они доступны для просмотра и закачки на странице


https://github.com/nodemcu/nodemcu-tirmware/tree/master/lua_modules.
В листинге 14.3 приведен пример скрипта для подключения модуля датчика темпе­
ра1УJ>Ы DS 18В20, получения и вывода его значений.

-- подключение модуля
t = require("dsl8b20")
-- GPIO карта модуля ESP-01
gpioO = 3
gpio2 = 4
t.setup(gpioO)
addrs = t.addrs()
if (addrs -= nil) then
print("Total DS18B20 sensors: " ..taЬle.getn(addrs))
enci
-- чтение температуры
print("Temperature: "..t.read() .."'С")
-- освободить память после использования
t = nil
dsl8b20 = nil
package.loaded [ "dsl8b20"] =nil

Результат выполнения этого скрипта при подключении датчика температуры к вы­


воду GPIOO приведен на рис. 14.9.

Рис. 14.9. Получение и вывод значений да;чика температуры DS18B20 с помощью модуля ESP8266
294 Глава 14

14.3. Проект Home's Smart


Мы рассмотрим здесь один из проектов, в котором наиболее полно реализованы
функции Интернета вещей, - российский проект Home's Smart («Умный дом»)
(http://homes-smart.ru), обеспечивающий, в том числе, сопряжение различных
датчиков с беспроводным Wi-Fi модулем ESP8266 для отправки данных на удален­
ные серверы.
Последняя на момент написания книги прошивка модуля ESP8266 (0.1.1 Конструк­
тор) поддерживает чтение датчиков DHТl 1/22, BМPOSS/180, BHl 750, DS18В20,
АМ2321 и др. и умеет передавать их показания на сайт «Народный мониторинг», на
сервис учета метрик ThingSpeak.com, на МQТТ-сервер, в систе� «умного дома»
MajorDoMo, в систему компьютерного контроля «Бенукс». Имеется в этой прошив­
ке и возможность управлять состоянием свободных GPIO для передачи команд на­
грузкам (реле), читать состояние входов GPIO, выводить данные на LCD- или
ОLЕD-экран, поддерживается также множество и других функций.

Рис. 14.10. Региqтрация в личном кабинете проекта Home's Smart

Чтобы собрать прошивку модуля ESP8266 под свои требования в личном каби­
нете проекта Ноте' s Smart, необходимо там зарегистрироваться, - переходим
по адресу http://esp8266.homes-smart.ru/registeruser.php, вводим необходимые
регистрационные данные (рис. 14.10) и после регистрации попадаем в личный ка­
бинет.
Для генерации своей конфигурации прошивки необходимо приобрести ключи -
нажимаем кнопку Купить ключи и указываем количество ключей, равное коли­
честву устройств, которое должна будет поддерживать прошивка. Оплачиваем
необходимое количество ключей из расчета 100 рублей за ключ (рис-14.11), вы­
бираем позиции, необходимые для учета в прошивке (рис. 14.12), и создаем про­
шивку.
Wi-Fi модуль ESP8266

Рис. 14.11 .. Приобретение ключа для генерации собственной прошивки

Рис. 14.12. Выбор опций для генерации и генерация прошивки


296 Глввв 14

14.3.1. Прошивка
и первоначальная настройка модуля ESP8266
Как можно бьmо видеть на рис. 14.12, мы скачиваем с сайта проекта Home's Smart
три файла собранной нами прошивки.
Схема соединений для прошивки платы ESP8266 представлена на рис. 14.13. Для
заливки прошивки на плату ESP8266 мы воспользуемся утилитой NodeMCU Flasher
(рис. 14:14), скачать которую можно со страницы https://github.com/nodemcu/
nodemcu-flasher.

Рис. 14.13. Схема соединений для прошивки моду11я ESP8266

Рис. 14.14. Утилита NodeMCU Flasher


Wi-Fi модуль ЕSР82бб 297

Рис. 14.15. Настройки вкладки Config утилиты NodeMCU Flasher

,На вкладке Config утилиты NodeMCU Flasher указываем файлы прошивки и адреса
смещения (рис. 14.15).
На вкладке Advanced утилиты NodeMCU Flasher необходимо всегда устанавливать
размер: Flash size 512 kВyte (рис. i4.16).

Рис. 14.16. Настройки вкладки Advanced утилиты No\JeMCU Flasher

На вкладке Operation выбираем порт подключения платы и нажимаем на кнопку


Flash(IO- процесс загрузки прошивки на плату ESP8266 начнется (рис. 14.17),
а надпись Flash(IO на кнопке сменится на Stop@.
Первоначальную настройку модуля ESP8266 лучше всего производить в так назы­
ваемом безопасном режиме (Safe mode). Необходим такой режим и если по каким-'
либо причинам бьm потерян пароль к настройкам. Для активации безопасного ре­
жима следует перед включением модуля соединить вместе выводы � и ТХ, при
этом к ним не должно бьпь ничего подключено.
Итак, переводим модуль ESP8266 в безопасный режим, подключаемся к точке дос­
тупа проекта Home's Smart и набираем в браузере: http: //192 .168. 4 .1. На странице
настроек выбираем пункт Main и вводим данные для подключения модуля к сети
298 Глава'14

Wi-Fi (рис. 14.18). Далее обновляем страницу и видим внизу IР-адрес, на который
уже можно будет заходить внутри вашей локальной сети. Там же вы можете
установить свои логин и пароль на страницу настроек веб-интерфейса - длина ло­
гина и пароля не должна превышать 8 символов {по умолчанию логин: esp8266,

Рис. 14.17. Загрузка прошивки на плату ESP8266

Рис. 14.18. Первоначальная настройка модуля в безопасном режиме (Safe mode)


Wi-Fi модуль ЕSР82бб 299

пароль: 0000). Здесь же можно задать имя модуля, которое будет отображаться на
главной странице и в системе flymon, а так же в пути на сервере MQTT.
Теперь активируем версию прошивки Pro (она позволяет подкточить к модулю
ESP8266 до 1О датчиков DS18В20, работающих по протоколу 1-Wire, два датчика
DHТl 1 (DHT22) и т. п.)- для этого необходимо приобрести специальный ключ:
заходим в личный кабинет на сайте http://esp8266.bomes-smart.ru/, выбираем раз­
дел Активация ключей и нажимаем в нем кнопку Добавить ключ. В соответст­
вующее поле открывшейся формы вводим Ю нашего модуля и нажимаем кнопку
ОК (рис. 14.19)- будет сформирован ключ для выбранного м<;>дуля (рис. 14.20),
который необходимо ввести в веб-интерфейсе модуля (рис. 14.21), чего достаточно
для активации версии Pro.

Рис. 14.19. Добавление ключа: ввод 1D модуля

Рис. 14.20. Генерация ключа для модуля ESP8266


300 Глава 14

Рис. 14.21. Активация версии Pro: ввод полученного ключа

14.3.2. Обновление прошивки через Интернет


Модуль ESP8266 может получать обновления прошивки через Интернет - так на­
зываемое обновление ОТА (от англ. Over The Air, «по воздуху»), например, для из­
менения состава модулей прошивки и исправления ошибок. Для такого обновления
в конструкторе прошивки необходимо включить соответствующую опцию. Про­
шивка через программатор необходима только в первый раз, далее обновления уже
можно получать, заходя в соответствующий раздел веб-интерфейса ESP8266. Перед
запуском обновления необходимо заранее в конструкторе прошивки выставить не­
обходимые опции и собрать прошивку.
Обновление через Интернет имеет недостаток - ограничение размера прошивки
в 236 Кбайт+ 4 Кбайт для загрузчика при Flаsh-памяти в 512 Кбайт. При выборе
опции Flash size 1 mByte (в окне, показанном на рис. 14.16) и модуле с одним и
более мегабайтом памяти, этого ограничения нет. Так, модули ESP-12 всех моди­
фикаций имеют на борту 4 мегабайта.
На модуль должен быть обязательно получен ключ для режима Pro - по его коду
идет привязка прошивки к вашей учетной записи в личном кабинете конструктора
(без ключа будет загружена облегченная версия прошивки:). Однако после получе­
ния ключа из облегченной версии можно обновиться до полной версии, созданной
в конструкторе.

14.3.3. Подключение датчиков к модулю .ESP8266


К модулю ESP8266 мы можем подключить датчики, которые выбрали при генера­
ции прошивки в личном кабинете проекта Ноте' s Smart.

Подключение датчика температуры DS18B20


Как уже отмечалось ранее, версия Pro позволяет подключить к модулю ESP8266 до
1О датчиков температуры DS18В20, работающих по протоколу 1-Wire. Подключим
сейчас датчик DS18B20 к модулю ESP8266/ согласно схеме, приведенной на
рис. 14.22.
Чтобы датчик DS18В20 начал работу, необходимо в веб-интерфейсе модуля зайти
на вкладку Hardware и активировать подключение датчика к выбранному выводу
GPIO (рис. 14.23), а затем зайти на вкладку 1-Wire и просканировать адреса
(рис. 14.24).
Wi-Fi модуль ЕSР82бб 301

Рис. 14.22. С!!ема подключения датчика температуры DS18820 к модулю ESP8266

Рис. 14.23. Активация датчика DS18820 на вкладке Hardware веб-интерфейса модуля ESP8266

Рис. 14.24. Сканирование адресов 1-Wire


302 Глава 14

Рис. 14.25. Пока�ания да"Nика DS18B20 на главной странице веб-интерфейса модуля ESP8266

Через некоторое время на главной странице веб-интерфейса модуля ESP:t266 мы


можем увидеть вывод показаний датчика DS18B20 (рис. 14.25).

Подключение датчика влажности РНТ11 (DHT22)


�ак уже отмечалось ранее, версия Pro позволяет подключить к модулю ESP8266 до
ж
двух датчиков температуры и вланости DHTl 1 (DHT22). Подключим сейчас дат­
чик DHТl 1 (DHT22) к модулю ESP8266 согласно схеме, приведенной на рис. 14.26.
Выводы модуля для подключения датчика указываются· на вкладке Hardware его
веб-интерфейса (рис. 14.27).
Через некоторое время на главной странице веб-интерфейса модуля ESP8266
(рис. 14.28) мы можем увидеть вывод показаний датчика DHTl 1 (DHT22).

Подключение 1 2 С-датчика освещенности ВН1750


В глав� 6 мы уже знакомились с 12 С-датчиками. Подключим сейчас один из них -
датчик освещенности BHl 750 - к модулю E.gP8266.
Чтобы датчик BHl 750 начал работу, необходимо в веб-интерфейсе модуля зайти на
вкладку Hardware и активировать подключение датчика к выбранным выводам
GPIO модуля ESP8266 (рис. 14.29). Для I2 С-интерфейса мы задействуем здесь
выводы GPIOO (SCL) и GPI02 (SDA).
Wi-Fi модуль ЕSР82бб 303

Рис. 14.26. Схема подключения датчика температуры и влажности DНТ11 (DHT22)


к модулю ESPS266

Рис. 14.27. Активация датчика DHT11 (DHT22) на вкладке Hardware


304 Глава 14

Рис. 14.28. Показания да"Nика DHT11 (DHT22)


на главной странице веб-интерфейса модуля

Схема подключения 12С-датчика BHl 750 к модулю ESP8266 показана на рис. 14.30.
Подключив датчик, просканируем подключенные к модулю ESP8266 12С-уст­
ройства с помощью опции 12С-сканирования (рис. 14.31 ).
Через некоторое время показания датчика освещенности BHl 750 появятся на глав­
ной странице веб-интерфейса нашего модуля (рис. 14.32).
Wi-Fi модуль ESP8266 305

2
Рис. 14.30. Схема подключения 1 С-датчика ВН1750 к модулю ESP8266

Рис. 14.31. Вывод списка адресов подключенных к модулю ESP8266 1 2С-устройств


опцией 1 2С-сканирования

Рис. 14.32. Показания датчика ВН1750 на главной странице вЕ\б-интерфейса


модуля ESP8266
306 Глава 14

14.4. Отправка данных с модуля ESP8266


на сайт «Народный мониторинг»
В предыдущих главах книги мы уже рассматривали отправку различных данных на
сайт «Народный мониторинr>) (http:www.narodmon.ru). Для отправки туда данных
с модуля ESP8266 следует открыть вкладку Servers веб-интерфейса модуля и акти­
вировать там соответствующую позицию (рис. 14.33).

Рис. 14.33. Активация отправки данных на сайт Narodmon.ru

Через некоторое время после активации надо зайти в свой профиль на сайте «На­
родный мониторинг)) и добавить наше устройство (модуль ESP8266): вводим 1D
устройства (рис. 14.34) и попадаем в список его датчиков, где можно при необхо­
димости подредактировать имеющиеся там данные (рис. 14.35).
Wi-Fi модуль ЕSР82бб 307

Рис. 14.35. Список датчиков модуля ESP8266, передающих показания на сайт narodmon.ru

14.5. Отправка данных с модуля ESP8266


в сервис ThingSpeak
В главе 4 мы уже рассматривали отправку данных в сервис ThingSpeak (https://
thingspeak.com)- открытую rmатформу данных для проектов Intemet of Things,
включающую в себя сбор данных с датчиков в реальном времени, обработку этих
данных, их визуализацию и использование в приложениях и rmагинах.
Напомню, что при создании прошивки ESP8266 мы предусмотрели отправку дан­
ных в сервис ThingSpeak (см. рис. 14.12), и чтобы это стало возможным, необходи­
мо создать в сервисе новый канал для хранения данных: на вкладке Му Channels
нажимаем на кнопку New Channel (рис. 14.36) и вводим данные для канала
(рис. 14.37) в соответствии с табл. 14.3.

Таблица 14.3. Данные, отправляемые в канал ThingSpeak

Поле Field в ThingSpeak Датчик Данные


field1 DHT11/AM2321 температура
field2 DHT11/AM2321 влажность
fieldЗ ВМР температура
field4 ВМР давление
308 Глава 14

Таблица 14.3 (окончание)

Поле Field в ThingSpeak Датчик Данные


field5 DHT22/INA219 температура/напряжение
field6 DHT22/INA219 влажность/ток
field7 DS18B20/LM75 те�пература
field8 ВН1750 освещенность

Рис. 14.36. Создание нового канала в сервисе ThingSpeak

Рис. 14.37. Ввод данных для нового канала в сервисе ThingSpeak


Wi-Fi модуль ЕSР82бб 309

Затем по ссьmке API Keys сервиса ThingSpeak (см. рис. 14.36) находим кточ Write
API Кеу (рис. 14.38) и заносим его в соответствующее поле модуля ESP8266 на
вкладке Servers его веб-интерфейса (рис. 14.39).

Рис. 14.38. Значени,э Write API Кеу для канала

Рис. 14.39. Ввод ключа для сервиса ThingSpeak

Осталось некоторое время подождать, и мы увидим на графиках сервиса


ThingSpeak отображение поступающих с датчиков данных в канале ESP8266 1
(рис. 14.40).
310 Глава 14

Рис. 14.40. Графическое отображение данных с датчиков модуля ESP8266 в сервисе ThingSpeak

14.6. Подключение дисплея WH1602


к плате модуля ESP8266
К плате модуля ESP8266 можно подсоединить и LСD-дисплей. Созданная нами
прошивка (см. рис. 14.12) поддерживает подключение LСD-дисплеев WН1602,
1604, 2004 и OLED по интерфейсу 12С. Если ваш LСD-дисплей не поддерживает
12С-интерфейс, вы можете воспользоваться соответствующим переходником
(рис. 14.41).

Рис. 14.41. Переходник для 1 2С-интерфейса для LCD 1602, 1604, 2004
Wi-Fi модуль ЕSР82бб 311

Адрес у LСD-переходника I2 C по умолчанию Ох27, но его можно поменять в на­


стройках дисплея. У ОLЕD-дисплеев адрес фиксирован: ОхЗС. Активация поддерж­
ки дисплея осуществляется на вкладке Display веб-интерфейса модуля ESP8266,
здесь же можно настроить и вывод на дисплей показаний подключенных датчиков
(рис. 14.42). При этом, выбрав опцию Out msg, мы получим возможность отправ­
лять сообщения на экран дисплея через веб-интерфейс:
http://IP_ADRESS/lcdrnsg?st=X&txt=text&font=N
где:
l:J х - номер строки;
l:J text - сообщение (пробелы заменяем на нижнее подчеркивание);
l:J N - шрифт (для OLED).

Рис. 14.42. Настройка поддержки дисплея в веб-интерфейсе модуля ESP8266

14.7. Управление выводами GPIO


модуля ESP8266
Модуль ESP8266 имеет 16 выводов GPIO, причем на различных версиях плат мо­
дуля количество доступных для управления выводов GPIO колеблется от 4 до 10.
К выводу GPIO можно подсоединить, например, реле и удаленно управлять его со­
стоянием, или датчик открытия двери или окна (геркон) и наблюдать его состояние
через веб-интерфейс.
Чтобы получить доступ к управлению выводами GPIO, необходимо прежде всего
в веб-интерфейсе ESP8266 зайти в настройки GPIO и указать, какие выводы вы хо­
тите задействовать, для чего ввести номер GPIO в соответствующее поле ввода,
выбрать нужн_ый режим и нажать кнопку Set (рис. 14.43).
312 Глава 14

Рис. 14.43. Настройка выводов GPIO

Управлять состоянием GPIO можно отправкой GЕТ-запроса:


http://IP_ADRES/gpio?st=DATA&pin=N
где:
1:1 N - номер вывода GPIO;
1:1 DАТА-данныедля установки: О или 1.
Если дописать к команде фрагмент &flash= l, то настройка запишется в энергонеза­
висимую память модуля.
Просмотреть состояние выводов GPIO можно по адресу: http://IP_AD�SS/
gpioprint (рис. 14.44).

4:1;5:1;

Рис. 14.44. Просмотр состояния выводов GPIO через GЕТ-эапрос

Выбрав для вывода GPIO режим INPUT (см. рис. 14.43), состояние вывода можно
получить GЕТ-запросом: http://IP_ADRESS/gpioprintinp�t.

14.8. Работа с прерываниями модуля ESP8266


При создании прошивки модуля ESP8266 можно выбрать и работу с прерываниями.
Модуль умеет считать импульсы (например, для водо- и электросчетчиков) и от­
правлять показания на удаленные серверы -для этого надо активировать соответ­
ствующий пункт в меню его веб-интерфейса (рис. 14.45). Так, при включении
режима Active send модуль будет немедленно отсьmать событие на сервер при
изменении состояния на входе прерывания на выбранном GPIO ( функция эта акту­
альна идля датчиков движения и датчиков открытия двери). При ,включении режи­
ма Кеу модуль может управлять другим GPIO- (выключение/включение), указан­
ным в поле GPIO For Кеу.
Wi-Fi модуль ЕSР82бб 313

Рис. 14.45. Установка настроек прерываний в веб-интерфейсе модуля ESP8266

14.9. Управление каналами ШИМ


модуля ESP8266
Модуль ESP8266 имеет три канала ШИМ (РWМ). Для работы с ШИМ необходимо
указать количество каналов и задать выводы GPIO, на которых необходимо запус­
тить ШИМ (рис. 14.46). Управление ШИМ осуществляется GЕТ-запросом:
bttp://IP_ADRESS/pwm?ch=Y&set=XXX
где:
[] У -номер канала (О, 1, 2);
[] ХХХ-уровень ШИМ 0-255.

Рис. 14.46. Установка настроек ШИМ (PWM) в веб-интерфейсе модуля ESP8266

Посмотреть установленные уровни ШИМ можно по GЕТ-запросу http://


IP_ADRESS/pwmprint (рис. 14.47). Для сохранения состояния ШИМ в энергонеза­
висимую память необходимо дописать к этому запросу фрагмент &flasb=l.
314 Глава 14

РWМО: l46;PWМ1:55;

Рис. 14.47. Просмотр значений ШИМ (PWM) на выводах GPIO через GЕТ-запрос

14.10. Планировщик задач модуля ESP8266


Планировщик Sheduler веб-интерфейса модуля ESP8266 позволяет управлять
состоянием выводов GPIO, а также и уровнем ШИМ (РWМ) по определенному
времени. Прошивка модуля позволяет установить до 8 задач планировщика
(рис. 14.48).

,Рис. 14.48. Настройка задач планировщика Sheduler


Заключение

Интернет вещей (Intemet of Things, IoT)- это новое направление, которое сейчас
стремительно развивается. Связанные с Интернетом вещи призваны сделать нашу
жизнь еще более функциональной и удобной. Интернет вещей трансформирует
привычные для нас объекты в совершенно новые инструменты, позволяющие со­
бирать, агрегировать и анализировать значительные объемы информации об окру­
жающей нас действительности. Устройства с постоянным подключением к Интер­
нету могут следить практически за всеми измеримыми параметрами. Таким обра­
зом, Интернет вещей предоставляет нам возможности наблюдения за любыми
показателями окружающей среды в реальном времени. И, что самое важное, -
возможность реализации функций анализа получаемых показателей и управления
устройствами, их изменяющими.
По оценкам аналитиков Интернет вещей в ближайшем будущем охватит огромное
число подключений: 1,9 миллиардов устройств к концу этого года и 9 миллиар­
дов - к 2018-му. Ценность' Интернета вещей будет расти в геометрической про­
грессии.
В этой книге мы рассмотрели вопросы реализации идей Интернета вещей на самых
известных и популярных платформах - Arduino, Raspberry Pi, а также на ставшем
весьма популярным в последнее время Wi-Fi модуле ESP8266.
А практическое воплощение полученных при прочтении книги знаний поможет вам
поучаствовать в построении мира Интернета вещей не только в качестве потреби­
теля, но и разработчика.
Желаю вам творческих успехов!
ПРИЛОЖЕНИЕ

Описание электронного архива

Электронный архив с материалами, сопровождающими книгу, можно скачать


с FТР-сервера издательства по ссьmке ftp:/lftp.bhv.ru/9785977536462.zip, а также
со страницы книги на сайте www.bhv.ru.
В архиве находятся следующие папки:
l::J \arduino_scetches-иcxoдники примеров и проектов глав 4-10 для Arduino IDE;
l::J \python-исходники примеров для глав 11 и 12;
l::J \arduino_libraries - библиотеки Arduino, используемые в примерах и проектах
книги и не включенные в среду разработки Arduino IDE.
Предметный указатель

м s
МАС-адрес 30,34,35,37,45 Slаvе-устройство 90
Маstеr-устройство 90 Start-ycлoвиe 91
Stор-условие 91
р
PIR-sensor 145
w
Wi-Fi модуль ESP8266 283
R
Raspberry Pi 187

А г
Автоматическая центровка и масштабирование График показаний фоторезистора в сервисе
схемы 21 Wyliodrin 261
Активация версии прошивки Pro модуля
ESP8266 299
Аналоговые датчики 25 д
О оптические 49 Датчик 25
Аналоговый датчик О влажности DHТl 1 141
О освещенности (фоторезистор) 39 О влажности DHT22 141
О температуры LM335 27 О влажности и температуры SHT21 в сервисе
О температуры LM35 261 Wyliodrin 266
Аналого-цифровые преобразователи (АЦП) 26 О влажности и температуры SHT21 на шине I2c
Аппаратные порты ввода/вывода GPIO 187 107
О движения HC-SR501 145
Б О звука FC-04 148
О освещенности ВН1750 181,215,302
Библиотека
0 в сервисе Wyliodrin 266
О TinyWebServer 77
0 на шине 12С 96
О света Grove light 271
О Wire 93
О температуры DS18B20 209,237,300

в О температуры LM335 163


О температуры LM35 в сервисе Wiliodrin 261
О температуры и влажности DHТl 1 (DHT22)
Видеоускорителъ Broadcom VideoCore IV 189 302
Виджет температуры в сервисе Wyliodrin 261 Диммер 68
Виджеты для проекта в Blynk 171 Дисплей WН1602 310
Включение транзистора в схему управления Добавление
реле 65 О в библиотеку Fritzing новых компонентов 22
Вращающий момент сервопривода 73 О устройства в сервис Wyliodrin 246
318 Предметный указатель

3 О сообщениями между платамиRaspberry Pi


через сервис Wyliodrin 274
Загрузка скетча14 Обновление прошивок модуля ESP8266 288
Загрузчик (bootloader) Arduino 14 Онлайн-сервис Wyliodrin 245
Запись образа Wyliodrin наSD-карту247 Оптрон67
Отправка данных
и О в несколько каналов111
О в сервисThingSpeak 42
Изменение пароля WeЫOPi 221 О в сервис Wyliodrin с мобильного устройства277
Интернет вещей29 О из Arduino в Xively 102
ИнтерфейсGPIO (General Purpose Input/Output) О на сайт «Народный мониторинг»
200 r с использованием платыGPRS/GS Shield 162
Инфракрасные датчики расстоянияSharp 49 О сRaspberry Pi в сервис «Народный
О GP2YOA02YK 25 мониторинг» 212
Исполнительные устройства 63 О с модуля ESP8266 на сайт «Народный
Использование мониторинг» 306
О в сервисе Wyliodrin платы Arduino, О с модуля ESP8266 в сервис ThingSpeak 307
подключенной кRaspberry Pi 259 О с платы Arduino в облачные сервисы33
Отправка и получениеSМS-сообщений
О внешних носителей121 с помощью платыGSМ/GPRS Shield 159
О технологии 1-Wire 128

к п
Первоначальная настройка модуля ESP8266 297
КамераRaspberry Pi Camera Board 231 Пироэлектрический инфракрасный сенсор 145
Карта памяти Питание от паразитного источника 125
О форматаMicroSD 189 Планировщик задач модуля ESP8266 314
О форматаSD 189 Плата
КонцепцияIntemet ofThings 29 О Arduino GPRS/GSM Shield 157
О Ethemet Shield 29,63
м О SIM900 Quad-Band GPRS Shield 157
Платы расширенияGrovePi иGrovePi+'270
Меню конфигурацииRaspberry Pi 194 Подключение
Методы библиотеки Wire 94 О 3G-модема кRaspberry Pi 199,200
Микросхема часов реального времениDallas О Raspberry Pi к Wyliodrin 251
DS1307 116 О датчика BHl750 к плате Arduino 98
Монитор последовательного порта14 О датчика DS18В20
0
к контактам GPIO Raspberry Pi 209
н 0 к модулю ESP8266 300
О датчика освещенности BHl750 к модулю
ESP8266 302
Набор стандартных библиотек14
О датчика температуры и влажности DH ТI1
Назначение выводовGPIO 204 (DHT22) к модулю ESP8266 302
Накопитель наSD-карте121 О датчиков DНТ к Arduino 143
Настройка
О датчиков расстояния Sharp к Arduino 51
О доступа кRaspberry Pi по Wi-Fi 196 О диммера к Arduino 69
О сервера WeЫOPi 222 О кRaspberry Pi датчикаВН1750 215
О сетевых параметровRaspberry Pi 196 О модуляSD Card 121
НейтраJ_Iьное положение сервопривода73 О твердотельного реле к Arduino 67 •
'

о
О электромагнитного реле к Arduino 65
Получение данных
О из сервиса Xively 105
Облачный сервис Xively 99 О из нескольких каналов113
Обмен ПриложениеThingTweet сервисаThingSpeak 55
О информацией по шине1-Wire 130 Пример отправки данных вTwitter 53
Предметный указатель 319

Принцип действия датчиков расстояния Sharp 49


Проект
т
О Blynk 169 Твердотельное реле 67
О Home's Smart («Умный дом») 294 Техническая документация (Datasheet) 27
Протокол 1-Wire 125 Технология
Процессор О «Умный дом» 128
О ВСМ2836 190 О AJAX 80
О Broadcom ВСМ2835 188 Тиристоры 67
Прошивка NodeMCU модуля ESP8266 289 Топология общей шины 126
Точка калибровки датчика 28

Работа у
О с GPIO на языке Python 206 Угол поворота сервопривода 73
О с прерываниями модуля ESP8266 312 Управление
О с ШИМ модуля ESP8266 313 О выводами GPIO модуля ESP8266 311
Регистрация в сервисе Wyliodrin 245 О светодиодом с веб-страницы Wyliodrin 257
Режим АТ-команд модуля ESP8266 284
О сервоприводом 73

с О сервоприводом из проекта Blynk 178


Установка
О Arduino IDE 10
Сайт «Народный мониторинг» 37
О WeЫOPi нa OC RaspЬian219
Сборка прошивки модуля ESP8266 294
Сглаживание значений, получаемых с датчика О дистрибутива ОС на Raspberry Pi 191
расстояния 52 О драйверов Arduino IDE 11
Сенсор 25 О среды разработки Fritzing 17
Сервис Устройство электромагнитного реле 64
О ThingSpeak 41 Учетная запись Wyliodrin 245
О Twitter 53
О Weaved 238 ф
Сервопривод 72
Симистор 67, 68 Файл настроек Wyliodrin 250
Система Grove 270 Фоторезистор 39, 96
Скетч 13 Фреймворк WeЫOPi 219
Скорость врашения вала сервопривода 75
Слот для флеш-карты MicroSD 78
Создание ч
О �овоrо проекта в Blynk 170 Часы реального времени (RTC) 190
О приложения в среде программирования
Wyliodrin 253
О принципиальной схемы 21
Среда программирования
ш
О Arduino IDE 9 Шина12С 89
О Blockly 245 Широтно-импульсная модуляция (ШИМ) 73
Среда разработки Fritzing 17
Стабилитрон 27
Стандартные сервоприводы 73
э
Стартовая страница WeЫOPi 221 Электромагнитное реле 64
Статистическое управление процессами 187 О SRD-05VDC фирмы SONGLE 64
Страница управления выводами GPIO
на WeЫOPi 221
Схема я
О подключения к GPIO датчика температуры
Язык программирования Lua 289
DS18B20 237
О соединения элементов 17

Вам также может понравиться