Автор: Иго Т.
Теги: программные средства компьютерные технологии электроника автоматизация микроконтроллеры arduino интернет компьютерная техника
ISBN: 978-5-9775-3970-8
Год: 2019
Том Иго
УМНЫЕ ВЕЩИ
Arduino, датчики и сети
для связи устройств
3-е издание
Санкт-Петербург
«БХВ-Петербург»
2019
УДК 004.4
ББК 32.973.26
И26
И26
Иго Т.
Умные вещи: Arduino, датчики и сети для связи устройств: Пер. с англ. — 3-е изд. — СПб.:
БХВ-Петербург, 2019. — 608 с.: ил. — (Электроника)
ISBN 978-5-9775-3970-8
Рассмотрен 31 проект на основе микроконтроллерной платы Arduino, в которых показано, как
сделать, чтобы электронные устройства могли обмениваться между собой данными и реагировать на
команды. Показано, как изменить настройки домашнего кондиционера, «позвонив ему» со своего
смартфона; как создавать собственные игровые и видеоконтроллеры, взаимодействующие по сети; как
использовать устройства Wi-Fi, Bluetooth, LoRa и инфракрасное излучение для получения информации
от датчиков и организации взаимодействия объектов. Рассмотрена работа с четырьмя программными
платформами и библиотеками с открытым исходным кодом: Arduino IDE 1.8, Processing, node.js и p5.js.
В третьем издании добавлены новые проекты, описано использование в проектах не только Arduino Uno,
но и Arduino 101, Arduino MKR1000, ESP32, ESP8266 и Raspberry Pi, а также уделено внимание вопросам
безопасности.
Для интересующихся современной электроникой
УДК 004.4
ББК 32.973.26
Группа подготовки издания:
Руководитель проекта
Зав. редакцией
Компьютерная верстка
Оформление обложки
Игорь Шишигин
Екатерина Сависте
Людмилы Гауль
Карины Соловьевой
© 2019 BHV
Authorized russian translation of the English edition of Making Things Talk, 3rd Edition, ISBN 978-1-68045-215-0 © 2017 Maker Media, Inc.
This translation is published and sold by permission of O'Reilly Media, Inc., which owns or controls all rights to publish and sell the same.
Авторизованный русский перевод английской редакции книги Making Things Talk, 3rd Edition, ISBN 978-1-68045-215-0 © 2017 Maker
Media, Inc.
Перевод опубликован и продается с разрешения O'Reilly Media, Inc., собственника всех прав на публикацию и продажу издания.
«БХВ-Петербург», 191036, Санкт-Петербург, Гончарная ул., 20.
ISBN 978-1-68045-215-0 (англ.)
ISBN 978-5-9775-3970-8 (рус.)
© 2017 Maker Media, Inc.
© Перевод на русский язык, оформление, ООО «БХВ-Петербург», ООО «БХВ», 2019
Посвящается Френку Иго,
который раскрыл для меня потенциал компьютеров,
и Реду Бернсу (Red Burns), который показал мне,
как заставить этот потенциал приносить пользу людям
ОГЛАВЛЕНИЕ
Предисловие ............................................................................................................. 11
Для кого предназначена эта книга? ..................................................................................................................................12
Что вам нужно знать? ...............................................................................................................................................................13
Содержание книги ....................................................................................................................................................................14
Приобретение деталей и компонентов...........................................................................................................................15
Использование примеров кода ..........................................................................................................................................16
Использование примеров схем ..........................................................................................................................................16
Примечания ко второму изданию .....................................................................................................................................17
Примечания к третьему изданию ......................................................................................................................................18
Благодарности ............................................................................................................................................................................20
Глава 1. Средства ......................................................................................................27
Все начинается с прикосновения.......................................................................................................................................28
Несколько слов об импульсах .............................................................................................................................................29
Компьютеры всех видов и размеров ................................................................................................................................30
Обзаведитесь хорошими привычками ............................................................................................................................31
Инструментарий.........................................................................................................................................................................33
Создаем первые программы для микроконтроллера..............................................................................................67
Одноплатные компьютеры ..........................................................................................................................................75
Как выбрать правильную плату? ........................................................................................................................................81
Работа с осциллографом ........................................................................................................................................................84
Прикосновением все и завершается ................................................................................................................................86
Глава 2. Простейшая сеть .......................................................................................89
Компоненты для проектов этой главы.............................................................................................................................90
Уровни согласования ...............................................................................................................................................................93
Устанавливаем соединение: нижние уровни ...............................................................................................................95
Отправка сообщений: уровень приложений ........................................................................................................... 101
Проект 1. Управление яркостью трехцветного светодиода с клавиатуры ........................................ 101
Усложняем задачу................................................................................................................................................................... 105
Проект 2. Мартышкин пинг-понг (Monski Pong) ............................................................................................. 105
Управление потоком данных ............................................................................................................................................ 120
Проект 3. Беспроводной мартышкин пинг-понг ............................................................................................ 121
Проект 4. Arduino-совместимая плата своими руками ............................................................................... 127
Заключение ............................................................................................................................................................................... 136
Глава 3. Более сложная сеть ................................................................................139
Компоненты для проекта этой главы ............................................................................................................................ 140
Сетевые топологии и сетевые адреса ........................................................................................................................... 141
Клиенты, серверы и протоколы управления связью ............................................................................................. 151
Проект 5. Сетевой кот ................................................................................................................................................. 167
Заключение ............................................................................................................................................................................... 198
8
Оглавление
Глава 4. «Глянь, мама, здесь нет компьютера!»
Микроконтроллеры в Интернете.........................................................201
Компоненты для проектов этой главы.......................................................................................................................... 202
Введение в сетевые модули ............................................................................................................................................... 203
Проект 6. Привет, Интернет!..................................................................................................................................... 206
Приложение встроенного сетевого клиента ............................................................................................................. 216
Проект 7. Сетевой измеритель качества воздуха .......................................................................................... 216
Форматы данных ..................................................................................................................................................................... 229
Принцип REST и интерфейсы API для Сети ................................................................................................................. 233
Инструменты для программирования и диагностирования встроенных модулей ................................ 239
Заключение ............................................................................................................................................................................... 247
Глава 5. Связь в режиме реального (почти) времени.....................................249
Компоненты для проектов этой главы.......................................................................................................................... 250
Интерактивные системы и цепи обратной связи .................................................................................................... 251
Протокол TCP: сокеты и сеансы ........................................................................................................................................ 252
Проект 8. Управление воспроизведением видео на основе сокетов TCP .......................................... 254
Клиент пульта управления ................................................................................................................................................. 257
Проект 9. Управление воспроизведением видео на основе протокола WebSocket ..................... 272
Сервер и клиент браузера.................................................................................................................................................. 274
Клиент пульта управления WebSocket .......................................................................................................................... 281
Заключение ............................................................................................................................................................................... 284
Глава 6. Беспроводная связь ...............................................................................287
Компоненты для проектов этой главы.......................................................................................................................... 288
Почему не вся связь беспроводная? ............................................................................................................................. 290
Два типа беспроводной связи: инфракрасная и радио ...............................................................................................292
Проект 10. Инфракрасное управление цифровой фотокамерой........................................................... 295
Принцип работы радио ....................................................................................................................................................... 300
Радиосети ................................................................................................................................................................................... 304
Выбор и приобретение радиоустройств ..................................................................................................................... 306
Проект 11. Дуплексная радиосвязь ...................................................................................................................... 310
Проект 12. Управление фотокамерой с помощью Bluetooth LE .............................................................. 319
Заключение ............................................................................................................................................................................... 334
Глава 7. Бессеансовые сети и двоичные протоколы .......................................337
Компоненты для проектов этой главы.......................................................................................................................... 338
Сеансы или сообщения? ...................................................................................................................................................... 341
Широковещательные сообщения или направленные? ........................................................................................ 342
Проект 13. Сетевые светильники ........................................................................................................................... 347
XBee: еще один протокол на основе сообщений ..................................................................................................... 362
Проект 14. Предупреждение о наличии в мастерской токсичных испарений ................................ 367
Заключение ............................................................................................................................................................................... 384
Оглавление
Глава 8. Как узнать местонахождение (почти) чего угодно?.........................387
Компоненты для проектов этой главы.......................................................................................................................... 388
Сетевое местонахождение и физическое .................................................................................................................. 391
Определение расстояния ................................................................................................................................................... 396
Проект 15. Инфракрасный дальномер................................................................................................................ 397
Проект 16. Ультразвуковой дальномер .............................................................................................................. 400
Проект 17. Определение уровня принимаемого сигнала ......................................................................... 404
Определение местонахождения методом трилатерации ....................................................................................................409
Проект 18. Геолокационные службы и протокол NMEA.............................................................................. 410
Определение направления и положения в пространстве .....................................................................................................420
Проект 19. Определение направления с помощью цифрового компаса ........................................... 423
Проект 20. Определение положения в пространстве ................................................................................. 426
Заключение ............................................................................................................................................................................... 435
Глава 9. Идентификация .......................................................................................437
Компоненты для проектов этой главы.......................................................................................................................... 438
Физическая идентификация .............................................................................................................................................. 441
Проект 21. Распознавание цветов с помощью веб-камеры ...................................................................... 444
Проект 22. Обнаружение лиц с помощью веб-камеры ............................................................................... 449
Проект 23. Распознавание двумерных штрихкодов с помощью веб-камеры .................................. 453
Радиочастотная идентификация (RFID) и ближняя бесконтактная связь (NFC) ......................................... 456
Проект 24. Чтение меток RFID ................................................................................................................................. 460
Проект 25. Чтение и запись сообщений NDEF ................................................................................................. 464
Проект 26. NFC и бытовая автоматизация ......................................................................................................... 467
Безопасность устройств сетевой связи........................................................................................................................ 477
Проект 27. Двухфакторная идентификация с использованием NFC ..................................................... 478
Сетевая идентификация ...................................................................................................................................................... 497
Проект 28. Геолокация по IP-адресу ..................................................................................................................... 499
Заключение ............................................................................................................................................................................... 504
Глава 10. Сети мобильной телефонной связи и физический мир................507
Компоненты для проектов этой главы.......................................................................................................................... 508
Одна большая сеть ................................................................................................................................................................. 510
Проект 29. Возвращение сетевого кота .............................................................................................................. 514
Проект 30. Звоним термостату................................................................................................................................ 537
Интерфейсы на основе текстовых сообщений ......................................................................................................... 544
Микроконтроллеры в мобильных телефонных сетях ........................................................................................... 548
Приложения для операционных систем мобильных телефонов ..................................................................... 558
Проект 31. Мобильный регистратор личных биометрических данных .............................................. 566
Заключение ............................................................................................................................................................................... 584
Приложение. Где брать компоненты и прочее? ..............................................587
Компоненты............................................................................................................................................................................... 588
Поставщики аппаратных компонентов ........................................................................................................................ 592
Программное обеспечение ............................................................................................................................................... 597
Предметный указатель .........................................................................................601
9
ПРЕДИСЛОВИЕ
Несколько лет тому назад Нил Гершенфельд (Neil Gershenfeld)
написал толковую книгу, названную им «Когда вещи начинают
думать». В ней он рассматривает мир, в котором обыденные
вещи и устройства наделены вычислительными способностями,
то есть мир сегодняшний. В частности, там обсуждаются
последствия обмена между такими устройствами информацией
о наших с вами личностях, возможностях и действиях.
Книга хорошая, но ее название, на мой взгляд, — неудачное.
Я бы назвал ту книгу «Когда вещи начинают общаться»,
поскольку — давайте признаем это — даже самые
захватывающие идеи чего-либо стоят лишь тогда,
когда их обсуждаешь с кем-то другим.
И моя книга, подзаголовком которой мог бы стать девиз
«Пусть вещи общаются!», — рассказывает, как создавать вещи,
способные общаться друг с другом, и как предоставить людям
возможность использовать эти вещи для общения между собой.
Предисловие
12
,
.
, ,
— ,
. — , "
.
.
,
— ,
" ( , " ). # , ,
,
, — ,
.
$ , "
% .
&
$
: , , , , (
) % . . '
$ ,
,
" , " % . *
. +
$
. ,
,
. /
-
1. 0 ,
, — , , $ %
.
& ,
, " . / , ,
" " .
1
& : «object-oriented hardware».
Для кого предназначена эта книга?
Эта книга писалась для тех, кто хочет наделить вещи способностью взаимодействовать друг с другом. Например, для преподавателя естественных наук, который намерен показать своим ученикам,
как отслеживать погодные условия одновременно в нескольких местах школьного округа. Или для
скульптора, желающего заполнить помещение скоординированно движущимися механическими
скульптурами. Или для дизайнера, которому необходимо быстро создавать макеты новых продуктов, моделируя как их форму, так и функции. Или же для хозяина кота, который любит наблюдать за
своим питомцем, даже когда находится вне дома. В общем, книга предназначена стать начальным
пособием для людей, обладающих ограниченным техническим опытом, но имеющих большой заряд энтузиазма и желающих успешно воплощать в жизнь интересующие их проекты.
0 ,
" ,
,
, -
—
%
,
" .
2
%
"
, . # ,
,
Предисловие
" " %. +
$
(
)
% ,
.
3
, "
, % $
"
, "
, . 4 -, , BASIC Stamp2
LEGO Mindstorms3, , %
2
7
%
BASIC (PBASIC),
ROM.
3
( $ )
( . http://ru.wikipedia.org/wili/LEGO_Mindstorm).
13
,
$ , $ . 0
- ,
"
.
& , , , $
, ,
, " . &
Bluetooth TCP/IP,
Ethernet.
9
, . 0 "
-
, %
. ;
,
— " " —
.
Что вам нужно знать?
Чтобы извлечь для себя как можно больше пользы из этой книги, вам необходимы базовые знания аппаратной и программной части микроконтроллеров, определенное представление об
Интернете и доступ к тому и другому.
7 ,
,
,
$
. ;
$
,
. 4 -
— $ .
,
, %
,
. & , ,
.
4
, ,
,
$
. + " «Physical Computing: Sensing
Предисловие
14
and Controlling the Physical World»4 ( Thomson), =
0’# (Dan O’Sullivan). &
$ , . + - $
" , "
- .
&
7 > (Massimo Banzi)
«Getting Started With Arduino»
Make.
$,
. 4
4
$, ,
,
- , .
$ ,
Processing,
: www.processing.org. ;
"
. # Processing ,
,
% $
,
" ,
"
.
. /
, , ,
, " , .
Содержание книги
В книге представлены основные принципы создания объектов сетевой структуры, а также приводятся примеры, их иллюстрирующие. Каждая глава содержит инструкции по созданию работающих проектов, основанных на изложенных в ней концепциях.
?
1. 2
,
,
«Hello World!» («2 , !»)
.
?
2.
,
" . 2
,
, ,
$ . &
,
,
Bluetooth.
#
,
.
•
3.
— +
. 2 ,
,
$ . 9 " , "
,
+
,
" . 0 +
.
?
4. 2
,
# .
# "
,
.
,
-
Предисловие
?
?
?
15
5. # " % # — ,
. 2
%
,
,
" # .
$ "
, , —
,
.
?
8. 2
( ),
.
?
6.
. 0
,
. 2
% , " $ «Hello World!»
(«2 , !»)
.
9. 2
. +
. *
.
?
7. 2 , "
" , 5. /
" —
UDP ( +
)
802.15.4 (
).
& - , "
" , -
10. 2
,
"
( )
.
& , ,
+
.
$
— " .
Приобретение деталей и компонентов
Для реализации проектов, описанных в книге, потребуется много деталей и компонентов,
вследствие чего вам придется познакомиться с их поставщиками. Поскольку в моем городе нет
больших розничных центров продажи деталей электроники, я покупаю все мне нужное через
Интернет. Если вам повезло, и у вас есть возможность покупать необходимые детали в обычном магазине, тем лучше для вас. В противном случае познакомьтесь со следующими интернетпоставщиками:
Jameco (http://jameco.com), Digi-Key (www.
digikey.com) Farnell (www.farnell.com) —
$
"
$ , "
. 3 ",
SparkFun (www.sparkfun.com), Adafruit (www.
adafruit.com) Seeed Studio (www.seeedstudio.
com),
,
.
"
.
4 - ,
% , $
.
Предисловие
16
X , +
, "
- . ;
$ . 0
, -
, -
% . #
,
% "
,
.
Использование примеров кода
Эта книга предназначена для того, чтобы помочь вам реализовать свои проекты. Соответственно,
код из нее можно использовать в своих программах и документации без необходимости запрашивать какое-либо разрешение, если только речь не идет о коммерческом воспроизведении
значительного объема кода.
* ,
$ %
,
CD-ROM
OYReilly % .
Z $ , ,
%
,
% .
7
$ . [
-
, , ISBN . * : «Making Things Talk: Practical
Methods for Connecting Physical Objects, by Tom
Igoe. Copyright 2011 Maker Media, 978-144939243-7»5. 4 ,
% ,
$ $
permissions@oreilly.com.
5
&
" $
.
Использование примеров схем
Для сборки проектов из этой книги вам придется разбирать или даже ломать те или иные устройства и нарушать условия их гарантии. Если вам это не по душе, закройте книгу и займитесь чемлибо другим. Эта книга не для тех, кто дрожит от мысли, что если они разберут вещь, то не смогут
собрать ее обратно.
& ,
,
.
—
.
0 ,
.
* ,
$
. ; , " , ,
$
,
,
Предисловие
$
, $
. 4
17
- " , ,
$ .
Примечания ко второму изданию
Две новые тенденции побудили меня переписать эту книгу: развитие движения за открытое (open
source) оборудование и рост культуры прямого участия, в том числе и в деле создания интерактивных устройств. Это хорошо видно на примере быстрого увеличения круга пользователей Arduino
в частности и числа участников движения за открытое оборудование в целом. Последствия этих
тенденций все еще в процессе оценки, но одно ясно — объектно-ориентированное оборудование и использование компьютерной техники для взаимодействия с реальной физической средой становятся повседневной реальностью. В настоящее время электроникой занимается намного больше людей, чем я мог бы вообразить в 2005 году.
" ,
" . _
- ,
$
. = 2005 , ,
,
« ».
& " , ,
Wii Kinect — $ ,
% ,
. #
$ , %
# .
% $
% , "
" , $ %
. _ Kinect ,
, "
. 0
Wii, . _ ,
$ , $.
Arduino, , Arduino - ,
$
,
,
. ` , %
$
, Arduino
. /
" , %, ,
. ' ,
$
,
,
$ , $
.
%
Arduino
,
, — " % . 0
, $
Предисловие
18
, "
$
. & , "
% , ,
" . # %
%
,
« "». ; ,
-
, $ , ,
, . >
, $ % , % . ` ,
$
.
Примечания к третьему изданию
Переписать эту книгу в предыдущий раз меня побудили две обнадеживающие тогда тенденции:
развитие движения за открытое (open source) оборудование и рост культуры прямого участия,
в том числе и в деле создания интерактивных устройств. Тенденции, которые толкнули меня
переписать книгу в третий раз, не столь оптимистичные: распространение бытовых устройств,
которые собирают данные обо всех физических аспектах нашей жизни, а также постепенное сокрытие информации о том, куда в конечном итоге эти данные попадают и для чего используются.
Такие устройства предлагаются на рынке под ширмой продуктов и услуг, обеспечивающих нам
простоту и удобство их использования. Указанные тенденции и их последствия требуют внимательного рассмотрения. Понимание технологий, лежащих в основе этих тенденций, поможет нам
принимать обоснованные решения о том, какую роль им следует играть в нашей жизни.
& ,
$ ,
(
% ), +
" . + , " $ ,
,
$ . q , «+
" »
1999 3%
(Kevin Ashton), Auto-ID
7 .
& «That “Internet of Thins” Thing»6
(www.rfidjournal.com/articles/view?4986) " , % +
. = ,
"
, $
. 0 ,
$ «
,
,
! .
6
'
“+
" ”».
: «' % $
" ! RFID ! ##
, ! #
! ,
#
, ».
0
, ,
% ,
% % ,
,
,
, .
+
, 3%
% ,
,
, $ .
+
% , , % — " , ,
% , —
% %
.
Предисловие
19
/ , ,
,
,
, %
%
$
.
, "
,
$ % % .
7 Nest ,
,
, " Hue
" , " ,
" Alexa
, %.
7 ,
$
,
« ».
* «» — $ ,
. ' , $ %
, " ,
% . ` ,
$ % ,
% , $
, .
` , , $
%
, $
, $
.
$ %
« »
. +
(& , # )
,
IP7 HTTP8. & $ ,
«
» , " .
2 , % %
$ , +
,
7
Internet Protocol — +
.
Hypertext Transfer [Transport] Protocol —
.
8
-
. # 2016 —
Mirai
—
, +
%
,
. * ,
% ,
. & "
, +
,
, "
. ~
#
$ ,
" .
' +
", $
,
,
, .
= %
% ,
%
. ~ , ,
$ ,
"
.
3% : «$ #
! , ». / %
, %
% , # .
О программном обеспечении
#
"
.
*
,
,
. = — Arduino
Processing — ,
"
". &
,
Предисловие
20
-
,
-
/ %
.
+
" gitHub https://github.com/
tigoe/MakingThingsTalk2
. + "
www.makingthingstalk.com.
Об используемом оборудовании
'
,
-
$ Arduino 101
MKR1000. >%
Arduino
Uno,
. = % ,
Arduino,
ARM
Cortex-M0 ESP8266.
Linux. = $
Raspberry Pi,
%
BeagleBone.
Благодарности
Эта книга является продуктом обсуждения и сотрудничества со многими людьми. Ее создание
было бы невозможным без поддержки и ободрения со стороны круга моих соратников, который
продолжает увеличиваться.
` %
9
Tisch10 *-
— ,
%
" .
+
«# »,
. ` ,
$
.
0 9 > (Red Burns)
$ . 0
, ,
% "
. 0
,
,
,
9
10
& : «Interactive Telecommunications Program».
& : «Tisch School of the Arts».
,
"
.
7 = 0Y# ,
,
, % %
$
. 0
,
. >% $
= . +
,
% .
* $
% " -
,
.
& , 7 (Marianne Petit),
$ (Clay Shirky), =$ $ 9
Предисловие
(Daniel Rozin), = (Dan Shiffman),
&$ / (Shawn Van Every), >
(Benedetta Piantella), 7 (Mimi
Yin), / $ % (Allison Parrish), q
> - (Gabriel Barcia-Colombo), _
= (Luke Dubois), = (Katherine
Dillon), *$ ~$ (Nancy Hechinger),
7 2 (Marina Zurkow), -7
q (Jean-Marc Gauthier), = 3
(George Agudow), / q (Edward
Gordon), 7 ` (Midori Yasuda), /
9 (Eric Rosenthal), 7 =
(Megan Demarest), *$ _ (Nancy Lewis),
9 9 (Robert Ryan), = =$ (John
Duane), > _ (Ben Light), 7 /
(Marlon Evans), ; Z (Tony Tseng), >
(Brian Kim), q # (Gloria Sed),
7$ > (Matthew Berger), -3 '
(Yen-An Chen), 3 3 % (Ahmad Arshad),
= = = (Dante DelGiacco) 3
q (Anna Gallagher)
,
, .
7
- ,
$ .
# % : = 3 (Jamie Allen), 7
> (Mustafa Bagdatli), 7$ >
(Matthew Belanger), + > (Ithai
Benjamin), =$ > (David Boyhan),
$
> (Caroline Brown),
# (Christian Cerrito), =
(Dennis Crowley), = (Jody Culkin),
= = (John Dimatos), =
(Patrick Dwyer), 2 + (Zach Eveland),
9 [ (Robert Faludi), = [ (Doria
Fan), = [ (John Farrell),
[ (Xiaoyang Feng), = [
(Jeff
Feddersen),#[ (Scott Fitzgerald),
; q (Thomas Gerhardt), q
q
(Gabriela Gutierrez), 7 ~$
(Meredith Hasson), ~ (Patrick
21
Hebron), _ % ~ (Liesje Hodgson), ;
q (Todd Holoubek), = =
(Jeremiah Johnson), (Craig Kapp),
(Peter Kerlin), $
(Kacie Kinzer), 9 (Raffi Krikorian),
= _ (Jihyun Lee), 9 7
(Rune
Madsen), 3 7 (Adi Marom), 2 7 %
(Zannah Marsh), # 7 (Surya Mattu),
7 (Carlyn Maw), 7 % (Corey
Menscher), 3 $ * (Ariel Nevarez),
=$ * (David Nolen), 9 * (Rory
Nugent), 7 0 (Michael Olson), 7$
(Matt Parker), = 9 (Dustyn
Roberts), 7$ 9 (Matt Richardson),
9 (Paul Rothman), 7
# (Maria Paula Saba), = (John
Schimmel), 7 (Michael Schneider),
q $ (Greg Shakar), (Yining
Shi), / 2 (Andy Sigler), $ # (Peiqi
Su), = # (Deqing Sun), = ; (James
Tu), ; ; (Tymm Twillman), &
(Karl Ward), 3 & (Antonius
Wiriadjaja), 9 (Rosalie Yu) Z
' (Jingwen Zhu).
= $ ,
. $ 9 (Casey Reas) > [ (Ben
Fry)
, Processing
" Processing (processingfoundation.
org). p5.js, _
7 (Lauren McCarthy),
$ ,
"
. *
Arduino 7 > (Massimo
Banzi), = 7 (Gianluca Martino),
= (David Cuartielles) =
7 (David Mellis), / > (Hernando Barragan) — Wiring
* 2 (Nicholas Zambetti), % $ . 7
$ ,
Предисловие
22
, %
Arduino
.
` ",
.
*
, ,
, — $ * 2
(Nathan Seidle) Spark Fun, _ [ (Limor
Fried) [ ; (Philip Torrone)
Adafruit, X 0 $ (Windell Oskay) _
/ (Lenore Edman) Evil Mad Science Labs
/ (Eric Pan) Seeeed Studio.
>%
: = (Don Coleman),
# 7 (Sandeep Mistry) 3
3 (Alasdair Allan).
$ "
,
% .
; %
Fritzing. /
$
- www.fritzing.org — 9 & (Reto Wettach), 3
(Andre Knorig) = $
(Jonathan Cohen)
. #
= 0 (Giorgio Olivero) =
(Jody Culkin) ,
$ .
7 , «+
»
11,
«Z
#7+ »
_ -3 12, «+
»
0 , +
+ 13 +
14. # 7 ~
(Mark
Hansen) 7 % (Michael Krisch)
Z > #7+
15
$ .
+ $
.
` $
, : ; 3 ;. * (Tuan Anh
T. Nguyen), = (Joo Youn Paek),
= [$ (Doria Fan), 7 7
(Mauricio Melo) = (Jason
Kaufman). ; (Tarikh Korula)
=% 9-_ (Josh Rooke-Ley) — «*
». = - 7
(Jin-Yo Mok), 3 > (Alex Beim), /
(Andrew Schneider), q _
(Gilad Lotan), 3 (Angela Pablo),
7 3 (Mouna Andraos), #
# (Sonali Sridhar). ; = (Tim Dye)
Sonoma Technologies. q > -
(Gabriel Barcia-Colombo), $ ~ (Kate
Hartman), _ (Kati London) #
# (Sai Sriskandarajah). [
_ (Frank Lantz) # (Kevin
Slavin) —
«; /».
# (Sarah Johansson), >
(Benedetta Piantella) = =
(Justin Downs) Groundlab; 7 ~$
(Meredith Hasson), 3 $ *
(Ariel
Nevarez) * (Nahana Schelling),
; 3 (Timo Arnall), / #
7
(Elnar Sneve Martinussen), =
(Jrn Knutsen), 7 >
(Mustafa Bagdatli), [
q (Frances
Gilbert) and = (Jake), 0
(Pedro Oliveira) # ' (Xuedi Chen). 3
' ,
,
; (Tali Padan) .
13
& : «Interaction Design Institute Ivrea».
& : «Copenhagen Institute of Interaction Design».
15
& : «Brown Center for Media Innovation at Columbia University».
14
11
12
& : «Royal College of Arts».
& : «University of California in Los Angeles».
Предисловие
# =
q (Giana Gonzalez),
(Younghui Kim), =
7 (Jennifer Magnolfi), = - 7
(Jin-Yo Mok), 7$ (Matt Parker),
/ (Andrew Schneider), q
_ (Gilad Lotan), 3 (Angela
Pablo), = >
(James Barnett),
7 *$ (Morgan Noel), _% 16
7 % .
#
, %
: 7 (Michael Shiloh), 7
~ (Mikal Hart), 7 7 (Michael
Margolis), # (Paul Stoffregen),
3 7 (Adrian McEwen), 3 > (Alexander Brevig), 9 7 (Ryan Mulligan), (Keith
Casey), > (Bonifaz Kaufmann),
3 q (Andreas Goransson), ~
> (Helena Bisby), 7 3
(Michael Adams), =$ q (Joel
Gahwiler). 9 [ (Robert Faludi) ,
«Digi International» XBee and Digi. `
Lantronix:
q 7 (Garry Morris), q$ 7
(Gary Marrs) =
/ $ (Jenny
Eisenhauer).
= # (Geoff Smith), ~
(Chris Heathcote), = >% (Durrell
Bishop), 7 (Mike Kuniavsky),
; (Tod Kurt), >
~ (Bjoern
Hartmann), / (Eric Paulos), &
(Wendy Ju), _ / ~ (Lars Erik
Holmquist) «Sketching
in Hardware» ,
, % " ,
.
16
& : «Noodles».
,
%
«0 3 », 9 *
$ .
23
0 MAKE, =$ =
(Dale Dougherty), ,
% ,
- . 9 > = (Brian Jepson) = ~ (Patrick Di Justo) $
. # [ (Scott Fitzgerald)
,
" "
. 3 *$
(Nancy Kotary), X (Katie Wilson)
; _ (Lillis)
. > ~
(Sherry Huss) Maker Faire $
% . & " ,
MAKE. ;
«# >».
# ,
, , ,
$ , ". =
~$ (Denise Hand), >
_ (Ben Light),
; (Clive Thompson), = ~
(Joe Hobaica), 7 X (Max Whitney)
= 7 (Jennifer Magnolfi) $ .
#
, %
. ` .
* , , = , $
. ` ,
" .
Предисловие
24
Мы хотим знать ваше мнение
4
-
$ ,
" :
Maker Media, Inc.
1700 Montgomery Street, Suite 240
San Francisco, CA 94111
# ,
- : http://shop.oreilly.com/
product/0636920031369.do.
0
$
: bookquestions@oreilly.
com.
«Maker Media» — «OYReilly Media», "
% " " ,
,
- , $ . 0 " «
» .
= «Maker Media» : http://makermedia.com.
Глава 1
СРЕДСТВА
Эта книга представляет собой что-то вроде сборника кулинарных
рецептов, и в ее первой главе я познакомлю вас с основными
используемыми при готовке ингредиентами. Описанные здесь
понятия и инструменты найдут применение во всех остальных главах книги. Для каждого инструмента дается достаточно
информации, чтобы вы могли сказать «Здравствуй, мир!» с его
помощью. Скорее всего, некоторые из рассматриваемых в этой
главе инструментов или подобные им вам уже приходилось держать
в руках. В таком случае вы можете спокойно пропускать знакомый
вам материал и переходить к инструментам, с которыми вам еще
не приходилось сталкиваться. Использование этих инструментов
в проектах, представленных в следующих главах, демонстрирует
для большинства из них лишь малую толику того, на что они
способны, поэтому рекомендуется самостоятельно разобраться
с менее знакомыми вам инструментами, чтобы получить более
полное представление о том, что с их помощью можно сделать.
Для этого в книге приводятся ссылки на материалы для дальнейшего самостоятельного изучения инструментов, которые вам не столь
хорошо знакомы.
Happy Feedback Machine1, созданная Туаном Анхом Т. Нгуеном (Tuan Anh T. Nguyen)
0 , $ ,
" " . 0 ,
$ , — , % , ",
"" ,
.
1
/
».
: «7%
Глава 1
28
Все начинается с прикосновения
Все рассматриваемые в этой книге объекты — как осязаемые, так и неосязаемые — демонстрируют определенное поведение. Программные объекты отправляют и получают сообщения, хранят данные или делают и то, и другое. Физические объекты двигаются, светятся или издают звуки.
Первый вопрос, который нужно задать об объекте, — что он делает? А следующий вопрос — как
принудить объект делать то, что он должен делать? Или, иными словами, какой у этого объекта
интерфейс?
+
.
— ! . / , : ,
, , % .
,
,
. [
. +
.
% , , % $ , ,
,
. & , $
,
,
% ,
" . # , -
.
# "
—
: ,
, . &
, — " " . *%
,
,
.
,
, , $
$ ,
, %
.
-
, . *
" ,
. 7
>... ; —
,
,
. /
% . + -
,
% $ ,
, "
.
* ,
— %
, "
$ $ ,
" . 4
,
$ . *
" , ,
% $ ,
.
Средства
29
Несколько слов об импульсах
Для взаимодействия друг с другом объекты используют протоколы связи. Протокол — это
набор взаимно согласованных правил для взаимодействия между двумя или несколькими
объектами.
—
USB, MIDI
HID (Human Interface Device,
) —
,
, , %
. #
— Ethernet TCP/IP —
( ), ( % ) .
" ,
"
.
$
.
-
,
—
. *
,
, — $
,
.
;
, % , "
,
,
, " —
$ :
, $
( )
"
. ;, " $ " -
" % %
USB-
. =
$ . =
,
. 3
, " "
.
$
, " $ ,
, , —
- ,
. X ,
" ( - ,
"
$ ), % % .
Глава 1
30
Компьютеры всех видов и размеров
В этой книге мы встретимся с несколькими разными типами компьютеров, сгруппированными
по их физическим интерфейсам. Самый знакомый из них — это персональный компьютер. Будь
это настольный компьютер или ноутбук, персональный компьютер имеет клавиатуру, экран и
мышь, и вы, скорее всего, пользуетесь им каждый божий день. Эти три элемента — клавиатура,
экран и мышь — составляют физический интерфейс персонального компьютера.
, , — %
. ~ , " %
%
, , " %
: "
% ,
. + $
" , "
,
% , " %
.
; ,
$ , — ,
" ,
. / % $
,
$ . &
" "
% :
1. , "
:
,
$
— $ $ .
2. , , " $ $ .
3. # , ",
.
7
, . + ,
.
& ,
Arduino Uno,
Arduino
, $ .
2
,
, — , Raspberry Pi.
~ %
$
, ,
"
,
.
, ,
$ , — . /,
,
, ,
%. 9 ,
,
, "
. _
. = $ %
.
Средства
31
>%
,
,
. $
,
%
.
# "
*
— $
:
, ,
. .
, "
,
, %
.
~
,
. ; , $
,
, , —
— .
Обзаведитесь хорошими привычками
Взаимодействие сетевых объектов в чем-то схоже с личными отношениями: вы не знаете, о чем
думает ваш партнер, — вы только слышите, что он говорит. Основная проблема и тех, и других
заключается в том, что, посылая сигнал, мы никогда полностью не можем быть уверены, понимает ли получатель, что мы хотим этим сигналом сказать. Поскольку нам неизвестен внутренний
процесс мышления получателей сигнала, мы никогда точно не знаем, как они истолковывают
наше сообщение. Все что мы знаем — это как они реагируют на него. Кроме того, существует бесчисленное множество вариантов потери сигнала или искажения его значения при передаче.
; , , " % , ,
, " $ "
% , .
$,
(
% ), "
:
?
% % , ;
?
,
%
, ;
?
;
?
" .
Слушайте больше, чем говорите
#
%
% — $ % % .
#% — , .
q , ,
, % % - ,
%.
% $ ,
,
% " ,
" % ,
$ . 0 " , ,
, $
. 0
"
,
.
Никогда не предполагайте
#% % , , , . + $
% ,
$
Глава 1
32
. 4 , %
"
,
$ , . * %,
" , .
#
,
$ % .
,
,
% %. >% %
. &
, " «2 ,
!»,
. = $ " — , .
*
" — % , %. = % $
,
$
. +
%, % , ,
. ` ,
%
" , , "
" .
* ,
$ ,
% . ,
$ ,
, ,
. & " ,
. 3 ,
.
Установите правила обмена
информацией
& % % " ,
"
. 7
,
%
, " ,
,
.
" ,
. +
, " " . " " ,
,
" . 4
,
,
. * ,
% ,
- ,
. * ,
,
,
.
Попросите разъяснений
" .
* ,
% -
, ,
, % , $ ,
, %
. $,
Средства
%, %
. ;
,
" , %
. 0 " , , ,
% ,
$ %. = ,
,
- . 7 %
,
, ,
33
. ;
. * ,
" ,
, , ,
. $,
" , " . *
$ % , " .
"
%
, $
.
Инструментарий
Учитывая, что в дальнейшем вы будете иметь дело с физическими, программными и электрическими интерфейсами объектов, вам потребуются «физические» инструменты, программное обеспечение и компьютерное оборудование.
«Физические» инструменты
О поставщиках деталей
4
$ , ,
,
. *
. 1.1 , $ . ; —
—
" ( - . 1.1).
& $
" . ` " — ,
. X
. 1.1 "
, ". *
$
.
0 " — . 4
,
$ .
,
$
. 0 . 1.1
" ".
7 ,
"
,
$
".
&
, $ .
;,
,
".
" $
.
Глава 1
34
8
10
7
9
6
18
11
16
1
34
3
15
5
4
13
19
33
31
25
32
2
27
29
30
12
24
28
14
17
20
26
21
22
23
Рис. 1.1. Инструменты и детали, используемые в проектах этой книги. Их краткое описание дается далее (обратите внимание:
после указания поставщика приводится номер детали по его каталогу)
1.
2.
2
. = %
,
Hakko FX-888D,
Weller WLC-100
SP
$
% . * .
,
$ .
": Digi-key (www.digikey.com): 16911083-ND; Adafruit (www.adafruit.com): 1204;
Farnell (www.farnell.com): 2320747.
3.
. + ,
. Jameco: 2214889;
Adafruit: 148; Farnell: 1792724.
4.
, ,
. *
« »,
. /
, % $
,
$ .
? : Jameco:
159291; Farnell: 609195; SparkFun (www.
sparkfun.com): TOL-12630;
. _%
21.23 AWG2. 4 , ,
. Jameco (www.jameco.com):
2210116; Farnell: 419266.
AWG, American Wire Gauge System — (
). . : http://ru.wikipedia.org/wiki/ _ _ .
? : Jameco: 161411; Farnell: 3125397;
SparkFun: TOL-10447;
? !
: Jameco: 217891;
3127199; SparkFun: TOL-08793.
5.
Farnell:
"
- . —
. 0 .
Jameco: 127271; Farnell: 4431212.
Средства
6. #$ . 9
,
. SparkFun: SWG-11046;
Farnell: 1696193.
7. «% ». /
. Jameco: 681002; Farnell: 1367049;
SparkFun TOL-11784.
8. " . *
. ~ ,
, ,
$ . Jameco: 220759; Farnell:
7430566; SparkFun: TOL-12966.
9. &.
, DSO Nano
% $100 — . SparkFun: TOL-11702 (v2); Seeed
Studio (www.seeedstudio.com): 109990013;
Adafruit: 468.
10.
9–12 '. 0
. *
— - $ .
& ,
-
. >%
,
%
2,1 % — 5,5 ( . 11), $ % "
.
Jameco: 170245 (12 V, 1000 mA); Farnell: 1176248
(12 V, 1000 mA); SparkFun: TOL-00298.
35
Adafruit: 80; Digi-Key: 1568-1237-ND; Jameco:
2207056; Farnell: 1650675 1737256.
13. < - (LiPo) . =
$
( ) LiPo —
. 0 %
, , 3,7 & 800–2000 3.
SparkFun: PRT-13813 PRT-08483; Adafruit: 258
2011.
14. USB- . = $ USB- 3- -B (
USB- ), A- - -B
(USB- ,
). SparkFun: CAB-00512, CAB-13244; Farnell:
1838798, 2444222.
15. %
)
« ». X
— $ . Jameco: 10444; RS (www.rs-online.com):
161.6511; SparkFun: PRT-12978.
16.
,
" « ». Jameco: 135299; SparkFun: CAB-00501.
17. =
USB/TTL-Serial.
USB- TTL. / . SparkFun: DEV-14050 DEV-12935; Adafruit:
3309 284; SeeedStudio: 317990026.
18. "
. * . 1.1
Arduino Uno,
Arduino 101 Arduino MKR100. SparkFun: DEV13787; Digi-Key 1660-1003-ND 1659-1005-ND;
RS: 913-9999 124-0657. ; . https://store.
arduino.cc.
11. () (+ )
2,1 % — 5,5 .
/
. 9
,
,
$ . %
" . SparkFun PRT-10288;
Jameco: 159611; Digi-Key: CP-024A-ND; Farnell:
3648102.
19. > . * . 1.1
Raspberry Pi Zero W,
Pi 3 BeagleBone Green. SparkFun DEV-13825;
Adafruit: 3055 3400; Seeed Studio: 102010048
114990584 RS: 896-8660; Farnell: 2525225.
; . www.raspberrypi.org.
12. ()
« ». /
,
. SparkFun: PRT-09518;
20. (
A . 9
,
Глава 1
36
, "
. *
$ :
5 & 3,3 &. >
. 0
,
.
? 3,3 &. Digi-Key: 497-1491.5-ND; Jameco:
242115; Farnell: 1703357; RS: 438-4885
? 5 &. Digi-Key: LM7805CT-ND; Jameco: 51262;
Farnell: 9756078; RS: 918-1971.
21. % TIP120. ;
,
" % . #" , $
TIP120. 0 ,
%
$
,
( . . 20). + $
, $,
, . Digi-Key: TIP120-ND;
Jameco: 32993; Farnell: 9804005.
22. "- IRF520. /
, TIP120
, $
. Jameco: 209226 Digi-Key: IRF520IRND; Farnell: 9103031.
23. C . +
% . _
% ,
« » . Jameco: 20723
(2 %
); Farnell: 4692810;
Digi-Key: 438-1045-ND; SparkFun: PRT-12615
PRT-12002.
24. D
. =
, . 0
.
$
. Jameco: 333973;
Farnell: 1208851; Digi-Key: 160-1144-ND.
25. ( . = $
. *
. 1.1.
26. H ). /
, $
, " .
* %
% . Jameco: 103377; DigiKey: A26509-20-ND; Farnell: 1593411.
27.
(
).
#"
.
X
,
. = / .
? !
. Jameco: 150551; Adafruit:
182 SparkFun: SEN-08606;
? !
. SparkFun: SEN09375; Adafruit: 166; Digi-Key: 1027-1001-ND.
28.
. = $ % :
—
(
Arduino
% Wiring),
, —
,
$ . *, ,
.
? !
Digi-Key: SW400-ND;
SparkFun: COM-00097;
= =.
Jameco: 119011;
? ! =. Digi-Key:
GH1344-ND; SparkFun COM-09181.
29. . (
) . Jameco: 29082; SparkFun: COM09939; RS: 91A1A-B28-B15L; Farnell: 350072,
RS 249-9294.
30. Ethernet. ~ " %
Wi-Fi,
. DigiKey: N002-004-BK-ND; Farnell: 1526202.
Средства
37
31. ,
, A . =
%
22 AWG. 2 ,
,
,
— " . *
.
? J
— Jameco: 36792.
? D
— Jameco: 36768.
? # — Jameco: 36822.
? — Jameco: 36856.
? K — Jameco: 36920.
? ( — Jameco: 2153705, SparkFun
PRT-11375.
32. " A A
. 3 ,
. + , $
. Jameco:
20723, SparkFun: PRT-12796; RS: 791.6463;
Adafruit: 759.
33. . = $
. *
. 1.1.
34. N . &
%
$
, $
. SparkFun: TOL-09316.
Таблица 1.1. Перечень наиболее часто используемых в проектах книги
электронных деталей и компонентов
Код, полное имя и веб-сайт поставщика:
D — Digi-Key, http://digikey.com
F — Farnell, www.farnell.com
J — Jameco, http://jameco.com
SF — SparkFun, www.sparkfun.com
RS — RS, www.rs-online.com
Деталь (компонент), номинал Код поставщика и номер детали по его каталогу
Резисторы
100
220
470
1K
10 K
22 K
100 K
1M
D — 100QBK-ND, J — 690620, F — 9337660, RS — 755-0707
D — 220QBK-ND, J — 690700, F — 9339299, RS — 707-7612
D — 470QBK-ND, J — 690785, F — 9339531, RS — 707-8659
D — 1.0KQBK-ND, J — 690865, F — 9339051, RS — 707-8669
D — 10KQBK-ND, J — 691104, F — 9339060, RS — 707-7745
D — 22KQBK-ND, J — 691180, F — 9337814, RS — 739-7140
D — 100KQBK-ND, J — 691340, F — 9337695, RS — 707-8940
D — 1.0MQBK-ND, J — 691585, F — 9337709, RS — 131-700
Конденсаторы
0,1F
1 F $
10 F $
100 F $
D — 399-4151.ND, J — 15270, F — 3322166, RS — 716-7135
D — P10312-ND, J — 94161, F — 8126933, RS — 475-9009
D — P11212-ND, J — 29891, F — 1144605, RS — 762-1736
D — P10269-ND, J — 158394, F — 1144642, RS — 762-1746
Регуляторы напряжения
3,3 &
5&
D — 497-1491-5-ND, J — 242115, F — 1703357, RS — 438-4885
D — LM7805CT-ND, J — 51262, F — 9756078, RS — 918-1971
Глава 1
38
Таблица 1.1 (окончание)
Деталь (компонент), номинал Код поставщика и номер детали по его каталогу
Аналоговые датчики
+
=
D — 905-1000-ND, J — 150551, RS — 708-1277
D — 1027-1000-ND, J — 2128260
Светодиоды
5 ,
5 ,
,
,
D — 160-1144-ND, J — 34761, F — 1855510, RS — 228-5944
D — 160-1665-ND, J — 94511, F — 1855570, RS — 848-6480
Транзисторы
2N2222A
TIP120
IRF520
D — P2N2222AGOS-ND, J — 38236, F — 1611371, RS — 295-028
D — TIP120-ND, J — 32993, F — 9804005, RS — 774-3653
D — IRF520IR-ND, J — 209226, F — 9103031, RS — 541.1180
Диоды
1N4004-R
3,3 & (1N5226)
D — 1N4004-E3/54GICT-ND, J — 35991, F — 9556109,
RS — 628-9029
D — 1N5226B-TPCT-ND, J — 743488, F — 1700785,
RS — 805-0110
Кнопки
=
=
D — SW400-ND, J — 119011, F — 1555981
D — GH1344-ND, J — 2231822, F — 1634684, RS — 718-2213
Беспаечные макетные платы
9
D — 438-1045-ND, J — 20723, 20601, F — 4692810
Монтажный провод
D — C2117R-100-ND, J — 36856, F — 1662031
D — C2117B-100-ND, J — 36792, F — 1662027
J — 36768, F — 1662034
J — 36920, F — 1662032
Набор монтажных перемычек
9
J — 20723, SF — PRT-12796, F — 2396146, RS — 791-6463,
AF — 759
Потенциометр
10 K
D — 987-1649-ND, J — 29081, F — 1760793
Разъемы
%
D — A26509-20-ND, J — 103377, F — 1056427, SF — PRT-00116
D — S1121E-36-ND, F — 1056429, SF — PRT-00553
q
D — ED7102-ND, F — 1122344, SF — PRT-00115
Разъем для батареи «Крона»
9&
D — 1568-1237-ND, J — 2207056, F — 1650675, SF — PRT-09518
Средства
39
Программные средства
=
, $
,
.
Среда Processing
0
,
$ ,
,
Processing. /
,
- www.processing.org. #
Processing Java ,
.
;
, Processing —
-
, "
: , %
, — %
Processing. , ,
Processing Java,
Processing
Java. # macOS, Windows Linux. #"
Processing Android. 4
-
Processing,
$
,
.
2
Processing
,
. 0 , . 1.2.
``Панель инструментов.
Содержит элементы управления
для запуска и остановки скетчей
``Окно редактирования.
Сюда вводится код скетчей
``Панель консоли.
Здесь выводятся предупреждения
и сообщения об ошибках
Пишем код
; % Processing. & "
, Run
(+ ) —
Processing.
println("
,
!");
Рис. 1.2. Окно редактора кода
среды Processing
Глава 1
40
* , $ . +
$ : # , !
.
, .
Processing
(sketch),
Processing
. & ,
. 9
Processing
« », " .
, " " ,
$
Java. , $ .
Пишем код
9
,
Processing.
Контекст использования
кода
&
$
, " ,
: Processing, Arduino,
node.js . .
/*
: Processing
*/
.
.
// " :
float redValue = 0;
// #
float greenValue = 0; // $ #
float blueValue = 0; // #
//
setup()
$
:
void setup() {
size(320, 240); // $
background(0); // %
fill(0);
// $ # $ % (0 = )
smooth();
// %
}
// & draw() ,
// . , '
// $
:
void draw() {
// + $ $ , $
// ' - #:
redValue = random(255);
greenValue = random(255);
blueValue = random(255);
// $ # :
stroke(redValue, greenValue, blueValue);
//
// ( ):
if (mousePressed == false) {
//
triangle(mouseX, mouseY, width/2, height/2, pmouseX, pmouseY);
}
Средства
41
//
else {
background(0);
fill(0);
}
}
_ Processing
( ): setup()
draw(). 7 setup()
,
, — ,
. .
3 draw() — ,
"
, .
=
Processing
. &
redValue, greenValue
blueValue — " (float), . .
" . =
, , $:
?
int —
?
char —
;
ASCII;
?
boolean —
false ();
?
string — ;
?
byte — .
true ( )
` Java, ,
Processing 3
for-next
"
:
$ .
= New
File
Processing.
:
. + , $
,
,
. $
. * ,
byte , int —
. . ,
$ ,
,
, $
.
Java JavaScript,
Processing
#.
,
(
void — . .
"
). &
,
. X
(if-then),
(for-next), #.
2 for-next, $
.
for (int myCounter = 0; myCounter <=10; myCounter++) {
println(myCounter);
Глава 1
42
Пользователям BASIC и Python
4
for-next #, $ - % . & , . & ,
, $
myCounter,
, $ % 10. + myCounter++
myCounter . /
BASIC " :
for myCounter = 0 to 10
Print myCounter
next
3 Python $ :
for myCounter in range (0, 10):
print myCounter
Processing —
$ ,
. 0
Java ". 4
Java,
Java
Processing. & Processing
%
" ,
+
.
$ $ 9
> [ , «Getting Started with Processing» ( O’Reilly). ;
" «Learning
Processing» ( Morgan Kaufmann),
= $ (Daniel
Shiffman).
Processing
,
$ —
. /
, $
,
$ .
0 $ ,
$ ,
, "
. 4
%
, $
,
. 7
, -
.
=
Processing ,
- www.processing.org. X %
Processing «Processing:
A Programming Handbook for Visual Designers
and Artists» ( MIT Press), -
Интерфейсы командной строки
и удаленные серверы
* $
" " ,
"
Средства
. 7
, $
$
,
$ , %
. +
%
,
, $
"
.
*
UNIX,
, BSD, Linux, macOS
. 0
,
,
POSIX3. & " $
$ .
Доступ к интерфейсу командной
строки
=
$ .
В macOS и Linux
& macOS $ Terminal
Utilities
Applications. & Linux $ xterm, rxvt, Terminal
Konsole.
В Windows
+
Windows
DOS
,
POSIX. * Windows , cmd
3
POSIX, Portable Operating System Interface —
.
43
Виртуальные
частные серверы
7
$ -
,
- . #
-
. +
- ,
" - ,
"
(&'#). X
- ,
. &
- - , -
- ,
-
-
. #"
" - , "
" — - %
.
* , " - ,
Digital Ocean (www.digitalocean.com), Amazon
Web Services (aws.amazon.com), BlueHost (www.
bluehost.com) DreamHost (www.dreamhost.com),
&'#
. *
" / ,
$ .
4
% " -
- ,
. / , " -
- " .
* -
,
, ,
- ,
% . $
,
" - —
,
. ;
, $ , ".
Глава 1
44
.
$ , Microsoft
POSIX
Windows 10 ( : bash
Windows 10) — " ,
"" .
(
"
)
POSIX Windows , Cygwin (www.cygwin.com).
,
$ Windows
Cygwin
. &
Cygwin
Net (
$ Packages "),
, " POSIX.
Подключение к удаленному
веб-хосту
~
, $
:
Рис. 1.3. Главное окно программы PuTTY
- ,
. >% " -
Linux, BSD, Solaris
UNIX- .
= Windows "
,
PuTTY, www.puttyssh.org.
—
- "
Windows
. * macOS Linux
OpenSSH, $
. 2
Terminal " ssh.
В macOS и Linux
0 . 0
" :
Last login: Wed Feb 22 07:20:34 on ttyp1
ComputerName:~ username$
& POSIX $
. $ " , $ ,
. &
,
$ , ,
$ .
' :
ssh
_$@
,
_-.com
9 ,
_$
_-.com
( _$)
- ( _-.com)
.
& ,
- ,
.
Средства
45
В Windows
2 PuTTY ( . 1.3). &
- ( _-.com)
Host Name, Connection
type SSH
Open. 2
,
" %
.
ssh. /
,
% % " . $
$ .
Работа с командной строкой
–l ls list
—
. &
$ :
X
,
- " :
Last login: Wed Feb 22 08:50:04 2016
from 216.157.45.215
[userid@myhost ~]$
/ , ,
$
.
= , . = $ " :
long
total 44
drwxr-xr-x 13 igoe users 4096 Apr 14
11:42 public_html
drwxr-xr-x 3 igoe users 4096 Nov 25
2005 share
/
,
" " ,
:
?
$ pwd
print working directory,
« ». 0
"
. (7 POSIX — . #
,
.) &
" — :
/
/home/igoe
/ ( )
. = ls (list):
$ ls -l.
Точки в конце команды
; « " », — « " ».
$
( :
%
$ : ,
;
$ (13)
$
;
$ (igoe)
, (users) —
;
$ (4096)
, % (Apr 14 11:42) —
;
, $ (public_
html) .
drwxr-xr-x)
?
?
?
?
&
POSIX , , "
. /
— , ,
. ' , , ls
: -la:
$ ls -la
Глава 1
46
= :
mkdir (make directory):
$ mkdir directoryname
/
"
. ls –l,
, $ "
.
(
)
" ls -la
:
drwxr-xr-x 2 tqi6023 users 4096 Feb
17 10:19 .
drwxr-xr-x 4 tqi6023 users 4096 Feb
17 10:19 ..
— — $
, —
—
. ;
, .
' , rm (remove directory) , " :
$ rmdir directoryname
X , $
— ,
. rmdir
, ,
$
. *
,
.
& % - -
% ,
html pub HTML
lic_html, — "
" . 4 % -
, "
mkdir:
$ mkdir html
= "
cd (change directory) — . * ,
html ,
" :
$ cd html
' %
, :
$ cd ..
= % ( )
cd ~ ():
$ cd ~
& % , cd .
=
$
/ ( $%). * ,
html % ,
cd~/html. '
(
root — ),
— /.
.
Управление доступом к файлам
& ls –l, " ,
! .
* , :
drwx
------
, (d —
directory), % ( ) (r — read), (w — write),
(x — execute). 9
% :
-rw-rw-rw
Средства
47
= ,
(
), ,
(
$ ), ,
,
. $ rw- % ,
— , — .
& % " chmod:
$ chmod go-w
_%
$ , ,
% . &
% (-w) (g —
group) (o —
others), . 3 "
:
$ chmod go+wx
_%
,
chmod u (user), g —
(group), o — (others). 7
, r %
(read), w — (write), x —
(execute). 2 + ( )
% , – ( ) — % .
> ,
%
% ( ).
,
,
$ , — " -
— .
Создание, просмотр и удаление файлов
=
"
: nano less.
nano — $
,
, $
%
" - ,
, ,
. * %
nano .
'
" nano
,
" :
$ nano
_% .txt
0
( . 1.4).
Рис. 1.4. Окно текстового редактора
nano. В нижней части окна имеется
список доступных команд, которые исполняются по нажатию клавиши <Ctrl>
совместно с клавишей буквы английского алфавита, указанной слева от соответствующей команды. Например, нажатие комбинации клавиш <Ctrl>+<K>
выполняет операцию вырезания (kut)
выделенного фрагмента текста
Глава 1
48
& nano
% <Ctrl>. * ,
% <Ctrl>+<X>. *
.
X
rm (remove):
" -
$ rm filename
rmdir, rm
,
$
.
* nano
% , % less. /
$ . =
less $ ,
:
$ less
_% .txt
& $ , % (:)
$ . * % " $ . ' % , % <q>.
0
,
less ,
—
—
« ».
= cat, head tail.
cat $
:
$ cat
_% .txt
3 head tail
, -
. , "
:
$ head -5
_% .txt
& $
_% .txt. :
$ tail -10 filename.txt
$
_% .txt.
cat, head tail ,
.
/
"
.
Объединение нескольких программ
в одну
0 UNIX
«
». + , ( ,
)
,
%.
,
.
,
. * ,
ls
% ,
$
" . * ls less,
, "" $ . = $ "
:
$ ls -la . | less
Средства
& (|) ,
% .
& $
— , . ;,
, " :
49
-
. 7
$ .
, " 5. # ,
help,
— :
man
_
$ ls -la . > _% .txt
/ _% .
txt ls. 4
" , ls.
&
" "
,
:
$ ls -la . >> _% .txt
0 ,
, ,
POSIX-
,
. * ,
$
— standard out,
stdout. 3
— standard in, stdin. [
,
"
"
(stdin) (stdout).
'
%
,
logout. & Linux $ loguot exit.
* %
POSIX — % macOS, Linux
—
%
,
ssh. >% $
Cygwin %
Windows. +
, $ .
=
UNIX Linux
, , 3 * (Aaron
Newcomb) «Linux for Makers» (
Maker Media).
,
, . ; , "
. ; / FIFO4:
—
.
/
4
FIFO, First In, First Out — % ,
% .
5
0 . command shell — , .
Глава 1
50
Платформа node.js
>% - $
( ) node.js, "
JavaScript.
JavaScript - ,
- ,
HTML6. &
- . & 2009
9 = (Ryan Dahl) Joyent %
JavaScript
,
node.js. & $
%
, %
.
& ,
node.js
,
$ 7. /
, . node.js -
%
+
. '
$ , %
.
&
node.js
"
Processing,
. 9
"
.
6
HTML, HyperText Markup Language — .
7
2 $
,
,
— PHP, - — , Apache.
2 " node.js
https://nodejs.org/en/
. 2 , "
, :
$ node –v
& $ " " :
v6.9.5
/ " node.js,
.
$
node.js 6.9.5, $
%
$
node.js.
Установка набора
средств разработки
= node.js
,
" . ; ,
8 ( ). = Windows % $
Microsoft Visual Studio, macOS —
XCode.
Visual Studio
, " Community Edition.
2 , , : www.visualstudio.com/
downloads/.
XCode Mac App Store. $
XCode . / , " :
$ xcode-select --install
node.js.
8
0 . toolchain.
Средства
51
Пишем код
+, node.js
. 2
,
" :
hello.js
.
console.log("Hello world!");
2
,
. 2
, :
$ node hello.js
&
$
$
" :
Hello world!
" , %
Processing9, ?
Веб-сервер на node.js
node.js - ,
" %
.
& — $ ,
, . -
-
HTTP10.
& $
HTML, , $ - . * , % , " ,
%
- . #
(. . ) , " $
- .
HTTP,
3,
node.js.
9
,
node.js
, $
«2 , !»
.
Пишем код
# %
simpleServer. 2
,
server.
js simpleServer.
9
,
, " node.js:
10
HTTP, Hypertext Transfer [Transport] Protocol —
.
Глава 1
52
1. :
// '
"
:
var express = require('express'); // '
// express
2. 0
:
var server = express(); // $ " server,
// $ express
3. 0
:
// % # ', $
//
$ :
function respondToClient(request, response) {
console.log("got a request"); //
//
// :
response.writeHead(200, {"Content-Type": "text/html"});
response.write("Hello, client!");
response.end();
}
4. +
// :
server.listen (8080);
// ,
$ :
server.get('/*', respondToClient);
console.log("Server is listening on port 8080");
:
X +
,
simpleServer :
$ npm install express
/ npm —
node (node package manager) express.js,
. &
,
, %
" . ; "
:
%
, $ .
0 - :
http://localhost:8080
& , . 1.5.
$
" " :
Got a request! (
!)
% 8080)
+
-
.
+
-
, favicon — %
- .
$
, ,
hello.js,
-
'
%
,
% <Ctrl>+<C>.
$ node server.js
&
$
" :
$
Server is listening on port 8080 (#
Средства
53
Рис. 1.5. Результат исполнения программы
сервера node.js в браузере
Структура программ node.js
# node.js (
) ,
Processing. 9 $ .
, JavaScript (,
,
node.js)
. / ,
— "
var. 3 JavaScript
.
& , JavaScript
. ;
,
. &
,
$ . -
" . & ( %! ) node.js express,
express. [
$
http. &
express() $
express,
server. = , , -
listen() server,
% 8080 .
; ,
JavaScript
. / ,
" ,
%
.
! , , -
.
server.js — server.
get()
respondToClient(),
. > JavaScript,
, % ,
.
& JavaScript
# Java. & ,
( )
,
.
# #
if-then
for.
Глава 1
54
#
:
node.js
1. # " require()
.
2. 0
,
( ).
3. 0 ,
.
4. +
.
HTML5 и веб-приложения
# — HTML5 —
. 0 %
, " $ . * , HTML5
,
,
JavaScript
CSS3.
HTML5, JavaScript CSS3
"? X ", ,
HTML "
,
CSS —
, JavaScript —
,
. ` HTML
$
: ,
$ , . 0 " ,
- : , ,
. ., — HTML
" DOM11.
CSS $ : , % ,
$ . . 3
11
DOM, Document Object Model — .
& $
server.js.
=
node.js , - www.nodejs.org. >
node.js $ (Shelley
Powers) «Learning Node: Moving to the ServerSide» ( O’Reilly). 3 /
> (Ethan Brown) «Learning JavaScript» ( O’Reilly)
JavaScript.
JavaScript
$
,
. 7
, , $ %
,
,
, ,
—
.
, " ,
,
. 9
% +
, ,
.
&
- ! , ,
+
, $ % %. ~
, "
.
& , % "
+
—
-
"
Google Docs
Средства
Dropbox. >
" ,
% # .
9 " —
% ,
. #
HTML5 JavaScript, "
, $ .
& "
, GPS12,
.
* $ —
" . $
, ,
,
. & " ,
,
%
,
.
Библиотека p5.js
-
" node.js, - ,
" . =
$
-
HTML
" JavaScript. #" JavaScript
. ,
. ; ,
Processing,
p5.js,
"
Processing. #
,
$
.
12
Global Positioning System — ( )
.
55
> p5.js . $
,
https://p5js.org.
=
_
7 (Lauren
McCarthy) «Getting Started with p5.js» ( Maker Media).
= p5.js
,
$ . '
, (
Complete Library)
https://p5js.org/download.
&
empty-example,
p5.js . # $
, ,
,
, " : HTML index.html
% ,
libraries p5.js
%
(addons): p5.dom.js ( DOM HTML- )
p5.sound.js ( ). &
sketch.js — ,
.
' p5.js
( JavaScript) HTML- , <script>,
. /
URL-
% , , "
. =
<script>. 0 index.html
example-project, ,
p5.js,
sketch.js:
Глава 1
56
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" width=devicewidth, initial-scale=1.0, maximumscale=1.0, user-scalable=0>
<style> body {padding: 0; margin: 0;}
</style>
<script src="../p5.min.js"></script>
<script src="../addons/p5.dom.min.js">
</script>
<script src="../addons/p5.sound.min.js">
</script>
<script src="sketch.js"></script>
</head>
<body>
</body>
</html>
/ %
. = ,
,
, — $
" .
p5.js
. = $ " node
p5manager:
$ sudo npm install -g p5-manager
$
p5.js,
:
$ p5 generate --bundle myProject
:
$ p5 g -b myProject
~ p5.js Processing
,
. Processing, p5.js setup() draw(),
Processing,
p5.js JavaScript. & ,
p5.js
JavaScript,
Java,
" var,
— " myFunction() . .
7
p5.js Processing:
function setup() {
// $ $ #
}
function draw() {
// ,
// #
}
% - ,
draw() , - , .
$ p5.js
draw().
Пишем код
#
p5.js, sketch.js
" :
/*
M'
context: p5.js
,
'
*/
var myButton, responseDiv; // R DOM
function setup() {
createCanvas(windowWidth, windowHeight); // Z$ -
myButton = createButton('click me'); // Z$ :
Средства
# , index.html
.
57
myButton.touchEnded(changeButton); // % # '
//
myButton.position(10, 10); //
responseDiv = createDiv('catch me'); // C$
// $ div
responseDiv.position(10, 40); //
}
// \ ' :
function changeButton() {
var x = random(windowWidth) - myButton.width; // ^
// var y = random(windowHeight) - myButton.height; // ^
// y
myButton.position(x, y);
//
responseDiv.html(x + ',' + y); // $
// responseDiv
}
> p5.js %
- ,
$. " %
( , ) " $ ,
. & , ,
, $ draw(),
% (
$ ).
Инструменты для работы
через последовательный порт
$
" ,
" $
. & "
% $
USB
. '
" ,
.
9
( . !. «'
»)
%
+
,
$
.
. # % +
"
- %
,
"
,
. 3
(bulletin boards, BBS) "
p5.js
: https://p5js.org/reference.
7
" p5.js " .
& $ . #" %
— , .
0 CoolTerm,
Глава 1
58
9 7 (Roger Meier),
- http://freeware.
the-meiers.org. macOS, Windows, —
$
.
4
% ,
,
.
= Windows %
-
PuTTY ( . 1.6), , ssh,
. &
— Screen (
GNU), " . /
OS, %
, CoolTerm.
Рис. 1.6. Установка типа подключения и последовательного порта в PuTTY
Рис. 1.7. Окно программы терминала CoolTerm
Средства
59
Кто получит порт?
;
. + ,
,
,
% $ .
,
%
. $
, " ,
$
. 2 % , .
+ , "
, . &
,
. & , ,
, , $
. & $
, " , . 4 ,
.
Программа CoolTerm
2 CoolTerm ( . 1.7)
" % Options. & %
Connection Options
" Port
,
Arduino. +
macOS
:
/dev/ tty.usbmodem1441
& Windows COM1, COM2,
COM3 . . ' ,
%
Arduino, , — . , % -
, . '
, Connect
. ' , Disconnect.
Программа GNU Screen
Linux macOS
CoolTerm ( . . 1.7)
GNU Screen.
* Ubuntu 15 GNU Screen
, :
$ sudo apt-get install screen
' GNU Screen macOS
Linux,
" :
$ ls /dev/tty —* # macOS
$ ls /dev/tty* # Linux
&
$
, . [ macOS Linux
, COM1, COM2 . .,
Windows,
$ 0# . &
:
$ screen _ _
* ,
macOS Arduino 9600 , :
screen /dev/tty.usbmodem1441 9600
# "
:
Linux
screen /dev/ttyUSB0 9600
Глава 1
60
&
" , , ,
. $
$
, ,
,
$ ASCII.
'
, % <Ctrl>+<A>, —
<Ctrl>+<\>.
& " ,
" " .
Оборудование
& , " ,
" :
?
—
. 1.1;
?
$
,
,
"
;
?
—
,
;
?
.
Микроконтроллеры
" .
4 - $
, ,
, " . &% $
" , , ,
—
%
. 7
,
"
, $ , ,
$ ,
.
&
"
. 0 % ,
. / ( 13)
/ #
! . &
GPIO (
. General-Purpose Input and Output)
I/O. 7
( )
GPIO, , $
" , "
- . &
"
. 7
,
: ,
(RAM14 ROM15),
—
,
.
=
8-
,
,
8 ( ). 0
,
%
" , — ,
$ .
13
0 . pin — .
Random Access Memory — , 02X.
15
Read-Only Memory — , 2X.
14
Средства
*
32-
(
32 ) , 8-
. & % ,
,
64-
, — 32-
.
*
. &
PIC Microchip
(www.microchip.com), AVR Atmel
(www.atmel.com) MSP430 Texas
Instruments (www.ti.com),
%
%
. #
32- "
%
ARM (www.arm.com).
/
,
. ,
, Intel (www.intel.
com),
,
$
,
ARM, Atmel AVR .
~
( $1 $10 %),
,
, ,
,
% , , $ . / %
%
, $ . Basic Stamp 2
(BS-2) Parallax, PICAXE, Wiring,
Arduino ,
$ , "
,
.
61
Arduino, Wiring и подобные
микроконтроллерные модули
= $
Arduino.
7 Arduino (www.arduino.cc),
— Wiring
(www.wiring.com), +
+ (Ivrea) 2005 . 0
ATmega Atmel (www.atmel.com),
« » C/C++. / « »
Processing, ,
IDE ( .
Integrated Development Environments),
" $ " " . & ,
IDE
Arduino Wiring
$ Processing —
setup() loop()16, map() .
$ ,
" Wiring, Arduino . & " "
Arduino, "
. ;
"
Wiring,
Wiring S. ,
Arduino. * . 1.8
%,
$ . ~ "
Arduino , %
Arduino
% . &
, $ . =
API17, "
Arduino Wiring, $ "
, Arduino Wiring,
16
7 draw() Processing
loop().
17
API, Application Programming Interface —
.
Глава 1
62
2
3
1
4
15
16
14
11
12
13
10
5
9
8
7
6
Рис. 1.8. Несколько как уже устаревших, так и актуальных сейчас моделей плат Arduino и ее клонов, Wiring и прочих:
1. Arduino Uno. 2. ATtiny85. 3. LilyPad Arduino. 4. Wiring. 5. Arduino Due. 6. Arduino Pro. 7. Arduino c.2005. 8. Arduino c.2006.
9. Arduino Fio. 10. Arduino Micro. 11. Arduino MKR1000. 12. Adafruit Feather Huzzah! 8266. 13. SparkFun 8266 Thing. 14. Arduino
Leonardo. 15. Red Bear BLE Nano. 16. Arduino 101
,
$ . ;
,
Arduino, - , , %
.
& $ % , " 32-
.
Arduino Uno, " , Wiring S "
8-
,
$
. *,
" ,
$
. =
$
,
.
Arduino IDE 1.8.2
,
www.arduino.cc.
3
Arduino, Wiring
, -
Средства
" . #
",
,
. 3 ,
,
. 0 " -
%
,
%
,
. '
$ , 2
Arduino-
.
0 % Arduino
Wiring — $ , Windows, macOS
Linux, —
. =
$ %
. ; ,
Processing
Java, ,
IDE Wiring Arduino, C/C++,
C — AVR-C. = $
$ .
3 Arduino
«Getting Started with Arduino»
( O’Reilly), 7
> (Massimo Banzi).
Другие микроконтроллеры
&
$
. $
" $
: %
,
.
63
; ,
, , % $ ,
"
( #) " . *
%
— Python JavaScript,
" . 32- ( ARM) , % $ . 7
ARM , MicroPython, BBC Micro Bit,
Espruino NodeMCU. + Python
JavaScript,
$ .
0
" . ;
,
% "
. MKR1000,
Arduino 101 "
— Ethernet (Wi-Fi)
. #
Bluetooth LE18
"
— ,
ESP8266 Espressif
Wi-Fi, BLE Micro BLE Nano
RedBear Labs — Bluetooth LE. 4 ,
.
Функциональные возможности
микроконтроллеров
7
— $ % %
. + , "
,
18
LE, Low Energy —
$
.
Глава 1
64
а
б
Arduino 101
MKR1000
Кнопка Разъем
Разъем питания полного USB
(пост. тока) сброса
Разъем
USB
Кнопка
сброса
I
~Выводы ШИМ
(3, 5, 6, 9)
Выводы
питания
Аналоговые
вводы
Цифровой
ввод/вывод
(0 – 13)
Аналоговые
вводы
(A0 – A5)
Bluetooth LE
Радио, акселерометр
(на микросхеме
процессора)
Разъем
для подключения
LiPo-батареи
2C
Разъем SPI
Выводы ШИМ
Цифровой
ввод/вывод
(0 – 14)
УАПП
Aref
A0
A1
A2
A3
A4
A5
A6
0
1
~2
~3
~4
~5
Кнопка
сброса
WiFi
Radio
(in processor)
5В
(ввод питания)
+5 В (вывод)
+3,7 В (вывод)
Общий («земля»)
Сброс
14 –> TX
13 <–RX
12 SCL
11 SDA
10 MISO
9 SCK
8 MOSI
7
6
Выводы
питания
УАПП
I2C
SPI
Рис. 1.9. Функциональные части плат Arduino 101 (а) и MKR1000 (б). Обратите внимание, что номера функциональных
выводов — т. е. аналоговый А1, цифровой 2 и т. п. — не соответствуют номерам физических выводов платы. В технической
документации обычно имеются в виду номера функциональных выводов, а не физических
. *
. 1.9
"
Arduino 101
MKR1000. 0 $
,
/ " (GPIO),
. =
: (
) —
(X3)19 :
SPI20
I2C21. 0 $
2. *
% USB. = — , Arduino Uno,
19
0 . UART, Universal Asynchronous Receiver-Transmitter.
20
SPI, Serial-Peripheral Interface —
.
21 2
I C, Inter-Integrated Circuit communications — .
% USB USB/
TTL-Serial.
>% , . .
. * ,
,
(~),
, ,
. /
- (+7)22 , ,
" $ .
* ,
-
"
:
22
0 . PWM, Pulse Width Modulation.
Средства
?
?
?
?
65
/ " ;
;
+7 (PWM);
:
• X3 (UART) —
• SPI — ;
• I2C — .
;
&
,
% , —
.&
,
,
.
Какую микроконтроллерную плату
выбрать?
= $ % %
Arduino
. * $ , $ ,
. * $ , — — %
,
.
О напряжении питания плат
= "
Arduino
5 &,
%
5 &. * , $ ,
3,3 &. *
, Arduino 101,
5 &,
$ %
3,3 &.
$ — Arduino 101 —
Intel Curie. /
32-
: 86 ARC23,
" . 9 24 $ , Arduino Uno.
,
, ,
Bluetooth LE.
& — MKR1000 —
SAMD21 Cortex-M0+ Atmel.
/ % "
LiPo-
, %
.
Wi-Fi.
; ESP8266
Espressif. *
, 32-
" Wi-Fi.
/ $
% , " .
* $ % ,
/
, Wi-Fi .
$ , , ,
. * $
" ESP8266
Arduino,
$
. + ESP8266,
,
Huzzah! ESP8266
Adafruit ESP8266 SparkFun. , "
$ .
23
ARC, advanced RISC Computing —
%
RISC- .
24
=
,
« » ,
« /
». 7 , , - « », %
% $ $
% .
Глава 1
66
* , Adafruit
Feather Huzzah! ESP8266 %
Huzzah! ESP8266 breakout
board. 3 SparkFun
ESP8266 Thing ESP8266 Thing Dev Board
. # Feather Huzzah!
ESP8266 ESP8266 Thing Dev Board
" ,
USB. 3 -
Huzzah! ESP8266 breakout
board ESP8266 Thing
USB/TTL-Serial. 4
, , Feather
Huzzah! 8266 8266 Thing Dev Board.
&
, $ .
Шилды Arduino
0
Arduino,
, % ,
(shield),
Arduino
. &
Arduino %
, %.
* $ ,
Arduino Uno rev3
. = %
, % Arduino
, " % ,
. + " %
Arduino.
,
" "
$ . +
%
- www.arduino.cc.
# $
- . &
$ %,
. * . 1.10
% . & % $ % ,
, $ — Arduino 101,
MKR1000.
0 ! * % . 0
,
5 & 3,3 &. $,
% , %
, , .
Рис. 1.10. Шилды и внешние модули для широкого диапазона приложений
Средства
67
Создаем первые программы для микроконтроллера
Загрузите последнюю версию программного обеспечения для Arduino с сайта www.arduino.cc
и установите его на свой компьютер, следуя приведенным далее инструкциям.
Установка на macOS
Начало работы
9
,
" %.
Arduino.
;
Arduino. USB
" Arduino IDE
" , . 0
( . 1.11).
" Arduino.
X
Arduino,
.
Установка на Windows 10
2 " Windows,
. &
%
USB.
9 % $
.
%
Arduino IDE .
Установка на Linux
&
Arduino Linux
Linux.
= Ubuntu 14
www.arduino.cc,
, " :
$
$
$
$
sudo mv arduino-1.8.2 /opt
cd /opt/arduino-1.8.2/
chmod +x install.sh
./install.sh
%
"
Arduino
. $,
dialout,
:
$ sudo usermod -a -G dialout $USER
# Arduino
Processing:
D (New), (Open) D=
(Save). ; — (Verify)
# (Upload). *
,
% ,
# — .
,
"
(Serial
Monitor),
.
Внимание!
Arduino
. & $
Arduino IDE 1.8.2. * , , 0 , $
Arduino
(www.arduino.cc) .
Глава 1
68
``Панель инструментов.
Самая правая дальняя кнопка —
Монитор порта (Serial Monitor)
``Окно редактирования.
Рекомендуется установить
флажок Показать номера
строк (Numbering) в меню
Настройки (Preferences)
``Панель консоли.
Здесь выводятся предупреждения
и сообщения об ошибках
``Индикатор версии платы и номера порта
Рис. 1.11. Среда разработки Arduino
Пишем код
Processing,
Arduino
. =
%
:
/* &
: Arduino
'
*/
.
void setup() {
pinMode(LED_BUILTIN, OUTPUT); // %
// }
void loop() {
digitalWrite(LED_BUILTIN, HIGH); // '
//
delay(500); //
digitalWrite(LED_BUILTIN, LOW); // '
//
delay(500); //
—
}
& $ . 2
(Tools)
(Board) . 4
%
,
" " A ( $ ,
! «*
» ).
2
(Serial Port) -
. * macOS Linux :
/dev/tty.usbmodem1421 (Arduino 101)
* Windows COMx,
x — - . * , COM5.
Средства
69
Порты Windows
* Windows
COM1 COM4
—
,
.
Менеджер плат
7 ,
$ % Arduino IDE.
' ,
. = $ "
" A Arduino IDE, ( Arduino 1.6.6
)
| | " A .
"
# , " "
"
:
Z $ 928 (2%)
. + 32256 .
2
.
% ,
(
25
L )
. & $ «2 , !».
Программа не работает
& %
. 4 , : N . & "
N .
=
%, —
(URL) " Arduino IDE. * ,
ESP8266,
\ | ]
!
" A .
= ESP8266 : http://
arduino.esp8266.com/stable/package_esp8266com_
index.json. 2 OK
. $
. ; .
&
, , . %
% "
" + . ;
# ,
.
2
. % "
4 -
,
". 7
Learning -
Arduino (www.arduino.cc/en/Tutorial).
, Arduino (www.arduino.cc/forum)
,
".
~
/ , $ ,
, LED_BUILTIN,
,
. * , Arduino 101
Uno
13,
MKR1000 6. 0
LED_BUILTIN
,
"
. &
— , , $ ,
"
.
25
0 . L, LED — .
Глава 1
70
Связь по последовательному
порту
0
,
$ ,
, , ,
-
,
.
Пишем код
& " :
, , "
,
$
—
.
/*
: Arduino
& ;
#
. '
.
*/
/ Arduino
. 0
,
(
,
" ),
.
void setup() {
pinMode(LED_BUILTIN, OUTPUT); // 13,
//
Serial.begin(9600);
// $
//
// 9600 /
}
int inByte = 0;
// - // long blinkTimer = 0; // ,
// '
int blinkInterval = 1000; // ' /' —
//
void loop() {
// - :
if (Serial.available() > 0) {
inByte = Serial.read(); //
Serial.write(inByte+1); //
//
//
}
Z :
M $
#
:
//
.
// +'
:
if (millis() - blinkTimer >= blinkInterval / 2) {
digitalWrite(LED_BUILTIN, HIGH); // '
}
// Z '
// :
if (millis() - blinkTimer >= blinkInterval) {
digitalWrite(LED_BUILTIN, LOW); // '
blinkTimer = millis();
//
}
}
Средства
71
Инструмент Монитор порта
+ "
Arduino IDE
" Arduino. =
. 2
" (
) — ( . 1.12).
9600 .
& ( % <Enter>
). 7 " . & —
,
ASCII26
.
26
ASCII, American Standard Code for Information Interchange — ( , ),
.
Куда делся мой последовательный порт?
,
Arduino,
,
Arduino USB.
. ,
. * Windows $
COM- , macOS
- .
. /
,
, , , — ,
% , .
*
! — , " $
( % —
). +
.
Рис. 1.12. Окно монитора порта среды
Arduino при исполнении предшествующего
скетча: пользователь ввел буквы ABCDEF
Глава 1
72
Подсоединение компонентов
к плате
/ , Arduino
Wiring
"
, $ , "
"
(
), . * . 1.13
Arduino
$ .
Базовые схемы ввода/вывода
& $
. 4
,
$ . 7 $ , ,
. =
, $
— ,
, " .
Цифровой ввод
Z — $ % ( , ),
,
" (« »)
(10 0 ).
/ # ! . 7 « »
, ,
, —
.
& $
# . %" "
.
,
. 1.14, ( ) . 3
: " ,
—
.
Рис. 1.13. Подключение электронных компонентов к плате
Arduino с помощью беспаечной макетной платы. Питание
(+5 В и общий) подаются от
модуля на крайние ряды гнезд
макетной платы, называемые
шинами питания. В результате
все датчики и приводы имеют общее питание с модулем.
Сигнальные и управляющие
контакты каждого датчика и
привода подключаются к соответствующим контактам ввода/вывода платы. В этом примере две кнопки подключены
к контактам 2 и 3 цифрового
ввода физических
Средства
73
A B
К плюсу
К общему
C D E
F
G H
J
I
1
1
5
5
Входное напряжение
К цифровому вводу
микроконтроллера
10
10
Кнопка
К цифровому вводу
микроконтроллера
15
15
Понижающий
резистор
20
20
25
25
30
30
A B
A B
К плюсу
К общему
К аналоговому вводу
микроконтроллера
К аналоговому вводу
микроконтроллера
C D E
C D E
F
G H
F
J
I
G H
I
J
1
1
5
5
10
10
15
15
20
20
Рис. 1.14. Цифровой ввод на микроконтроллер:
общий вид макетной платы (слева); принципиальная схема соединений (справа)
Входное напряжение
Переменное
сопротивление
(светочувствительный
резистор)
Постоянное
сопротивление
К аналоговому
вводу
микроконтроллера
Входное напряжение
Потенциометр
25
25
30
К аналоговому
вводу
микроконтроллера
30
A B
C D E
F
G H
I
J
Рис. 1.15. Ввод в микроконтроллер аналогового сигнала: общий вид макетной платы (слева); справа показаны принципиальные схемы двух способов получения входного аналогового сигнала: с использованием в делителе напряжения светочувствительного резистора (вверху) и с использованием потенциометра (внизу). Эти сигналы можно подавать на два разных контакта
аналоговых вводов микроконтроллера
Аналоговый ввод
# ,
. 1.15, . & $ ,
, — -
. * % $ . * ,
Глава 1
74
.
3
, , 1 2 0 (
), $ 2/3 .
4
- , "
"
,
. +
: , , , . .
& . 1.15 (
!) ,
.
, "
.
"
. & , — $
. 4
, — " , " .
& " , $ ,
.
Документируйте свою работу
/ ,
- , . . $
, $ , , , , $. $
,
:
• Adobe Illustrator (www.adobe.com/products/illustrator.html). /
,
,
% . = $
" $
,
# .
• Affinity Designer (https://affinity.serif.com/en-us/
designer/) — , $ Windows " - .
/
% ,
SVG27 % , Adobe Illustrator. ; .
. / %
, ,
, . =
%
$
,
, "
$
.
/ 28
" $
, "
, = (Jody Culkin)
= 0 (Giorgio Olivero),
3 (Andre
Knorig) = $ (Jonathan Cohen),
Fritzing.
• Fritzing (www.fritzing.org) — Fritzing
, $ -
* , , ,
% . _
:
Wordpress (www.wordpress.org) "
- www.makingthingstalk.com,
http://tigoe.net/blog http://tigoe.net/pcomp/code,
" github (https://github.com/tigoe) Maker’s Notebooks (www.makershed.
com, 9781449358976).
27
28
SVG, Scalable Vector Graphics — % .
+
.
Средства
Специальные схемы и модули
&
. 7
. & $
,
. 1.13–1.15,
,
. * ,
,
, .
& $
"
,
$
.
,
$
.
Arduino ,
,
.
Рис. 1.16. Одноплатные компьютеры (слева направо):
Raspberry Pi 3; Raspberry Pi Zero W; BeagleBone Green;
Arduino Yuún
75
Ознакомьтесь с техническими характеристиками компонентов
& $
. $
, %
, .
Одноплатные компьютеры
& ,
—
, / — $
% . *
, , "
,
. & ,
$
, " "
,
Глава 1
76
% $ , $ . 0
,
. 0 ,
,
,
. & %
- Linux, Windows 10,
. >% $ "
/
" , %
/ . , /
3,3 & , $,
,
.
& $
Raspberri Pi,
"
. *
, BeagleBone Texas
Instruments , Raspberry
Pi. #
%
$
BeagleBone.
Raspberry Pi 3 & " ARM Cortex A7 Broadcom
1,2 qq,
1 q RAM. ,
, Wi-Fi Bluetooth.
HDMI,
&
Linux, " Raspbian, "
"
" .
,
,
/ ,
— Wi-Fi, ,
. . +
$
,
. & $ Raspberry Pi % .
Плата Raspberry Pi
0
Raspberry Pi %
2012 .
35 ,
" $ , $
. # %
%
,
Raspberry Pi 3
, " , % .
$ Pi Zero W
10 . $
"
Wi-Fi.
& , Raspberry
Pi 35
. '
,
: ,
,
"
. * Raspberry Pi . & ,
.
/ , ,
- .
$ -
Средства
Raspberry Pi %
. #
,
, " $ .
,
.
77
Raspberry Pi, ,
,
% .
Основы работы с Raspberry Pi
?
A 5 '
)
-USB. # , $ , 2 . = $
" USB;
?
MicroSD
8 q , " % — 16 q . + ,
;
, ,
Raspberry Pi, — $ Linux
Raspberry Pi ( Raspbian)
www.raspberrypi.org/downloads/raspbian/.
2 Raspbian Jessie 4.4
. = $
Lite, , ,
. 9
, "
$ , MicroSD,
, USB/
TTL-Serial ( . 1.17), USB .
?
- =
USB/TTL-Serial. /
, "
. *
"
, - USB/
TTL-Serial Raspberry Pi (ID: 954) FTDI Friend (ID: 284) Adafruit;
Внимание!
'
% , Raspbian, " , 1 2017 ,
. =
$ ,
MicroSD ,
"
config.txt " :
?
Wi-Fi,
USB- ( Raspberry Pi 3 Zero W). & ,
%
,
" ,
Wi-Fi
. = Raspberry Pi
Wi-Fi (AF: 2638),
,
,
Miniature WiFi (802.11b/g/n) Adafruit (AF:
814), Wi-Fi
Realtek.
,
' Raspberry Pi $ , "
:
[code style]
enable uart=1
X USB/TTL-Serial
,
CoolTerm
. X
115 200
% . * $ % :
Raspbian GNU/Linux 8 raspberrypi ttyAMA0
raspberrypi login:
Глава 1
78
TX
, Ethernet "
.
,
Wi-Fi.
RX
USB 2x
BLACK
GND
CTS
VCC
TX
RX
RTS
GREEN
Power
CSI (CAMERA)
HDMI
Audio
ETHERNET
USB 2x
DSI (DISPLAY)
GPIO
Подключение через сетевой кабель
, — % . 4 % %
DHCP ( %
% $
),
Raspberry Pi . $ , :
$ ifconfig eth0
Рис. 1.17. Плата Raspberry Pi 2/3 B с подсоединенным переходником USB/TTL-Serial. Контакты последовательного ввода/вывода одинаковы на всех моделях плат Raspberry Pi
= Raspbian (login) pi, —
raspberry. & $
.
&
, , Linux,
Linux,
!. «+
» .
0 " raspi
.
= $ :
" :
eth0 Link encap:Ethernet HWaddr b8:27:eb:63:37:4a
inet addr:192.168.0.17 Bcast:192.168.0.255
Mask:255.255.255.0
inet6 addr: fe80::ffc5:e696:3b93:5b47/64
Scope :Link
UP BROADCAST RUNNING MULTICAST MTU:1500
Metric:1
RX packets:110 errors:0 dropped:0 overruns:0
frame:0
TX packets:103 errors:0 dropped:0 overruns:0
carrier:0 collisions:0 txqueuelen:1000
RX bytes:38147 (37.2 KiB)
TX bytes:12819 (12.5 KiB)
config
$ sudo raspi-config
0 , "
" %- , , % <Enter>. # 1.
Expand Filesystem, % — 2. Change Password
.
* $ $ %
/ ,
Ethernet Ethernet (
" eth0)
192.168.0.17. 4
,
. >
3.
Подключение через адаптер Wi-Fi
4
Wi-Fi,
Raspbian
. '
Jessie
$,
Средства
79
USB-
" :
$ iwconfig wlan0
4
" :
-
wlan0 IEEE 802.11bgn Nickname:"<WIFI@REALTEK>"
$ ,
Wi-Fi . '
Wi-Fi,
"
:
Настройка Wi-Fi с помощью wpa_cli
wpa_cli ,
. #
, , ,
, .
,
, %
. ' ,
:
$ sudo wpa_cli
$ sudo iwlist wlan0 scan
* $ "
Wi-Fi " .
&
"
$ , "
scan less, :
$ sudo iwlist wlan0 scan | less
= "
% , % — % <q>.
О команде sudo
& POSIX sudo %
,
(
! ). * ,
sudo,
. & % , wpa_cli ,
% . *
Raspberry Pi %
sudo.
X
— ifconfig iwconfig —
. * ,
ifconfig (
: InterFace CONFIGuration). 3
$ : eth0 wlan0 —
:
Ethernet
29. /
,
, Wi-Fi. = $ %
" Raspbian
, "
wpa_cli.
29
WLAN — Wireless Local Area Network.
* $
wpa_cli, " :
Selected interface 'wlan0' //
// % 'wlan0'
Interactive mode // \
//
>
# > % . & " :
add_network
&
:
0 >
, -
Глава 1
80
/
, . = :
> set_network 0 ssid "_SSID"
> set_network 0 psk " "
& _SSID
Wi-Fi
. 4
, " :
> set_network 0 key_mgmt NONE
2 :
> enable_network 0
//
//
> save_config
// Z-
// % #
; , % Raspberry
Pi
$
. ' %
wpa_cli, quit.
,
, "
ifconfig wlan0 iwconfig wlan0, . * $ ifconfig
Pi,
iwconfig — .
Подключение к одноплатному компьютеру по ssh
, ssh. = $ ,
" ifconfig. 0
_
ssh
$@xx.xx.xx.xx. 2
_$
. = Raspberry Pi $ pi,
— root. 3 xx.xx.
xx.xx
. * , Pi
192.168.0.23 $
: ssh pi@192.168.0.23. % ,
,
.
Проверка сетевого подключения
с помощью curl
_
— Wi-Fi —
.
- , %
curl. / -
-
. 2 , " :
$ curl http://www.example.com
& $
HTML, " :
<body>
<div>
<h1>Example Domain</h1> ( )
nts. You may use this domain in
examples without prior
coordination or asking for
permission.</p>
( $
- $
$ .)
<p><a href="http://www.iana.org/
domains/example">More
information...</a></p>
(( % # ...)
</div>
</body>
</html>
;
, , , % Raspberry Pi
+
. curl "
- ,
, - , — . .
HTML-. ' ,
URL-
.
Средства
81
X
Упорядочивание системы
Raspberry Pi
+
" node.js. = ,
Raspberry Pi.
# " apt ( Raspbian)
:
node.js:
$ sudo apt-get remove --purge node* npm*
# " curl
node (nvm):
$ sudo curl -o- https://raw.githubusercontent.
com/creationix/nvm/v0.33.1/install.sh | bash
& ,
:
$ nvm install v6.9.5
#
node
node (npm)
:
$ sudo ln -s /home/pi/.nvm/versions/
node/v6.9.5/bin/node/usr/bin/node
$ sudo ln -s /home/pi/.nvm/versions/
node/v6.9.5/bin/npm/usr/bin/npm
* , Processing:
$ curl https://processing.org/download/
install-arm.sh | sudo sh
$ sudo apt-get update
X
node.js 6.9.5:
$ sudo logout raspberrypi login: pi
. ; , Pi,
,
.
* $ $
:
$ sudo poweroff
" , ,
.
Как выбрать правильную плату?
Выбирая микроконтроллер или одноплатный компьютер для какого-либо проекта, нужно принять во внимание несколько факторов.
, — ,
, ?
, , . 3 $
.
#
10 30 ,
. &
,
. 7
,
, . & ,
.
Глава 1
82
Операционные системы
и «реальное время»
&
,
. / , 100%
$ . /, , , $
:
—
% $ .
% "
,
. 0 — $ , . ; # ! ,
,
% —
SD- , ! /
(>#&&)30,
, $ .
2 ! ! ,
%
, "
"
.
, %
/ . ;
« ».
,
. & , $ , ,
-
, , $
. '
,
,
, ,
,
(0#9&)31.
;
/ ,
%
. 0 , ,
/ ,
% . &
0#9& . : Arduino 101
. 0#9& ,
, ,
.
>% 0#9&
%
" . 0#9&
Arduino 101 % , , Bluetooth
, .
$
,
/ .
Сетевое время
4
, $
, , -
7
0#9& %
,
, -
30
31
0 . BIOS, Basic Input-Output System.
0 . RTOS, Real-Time Operating System.
Средства
, "
. *
, "
:
,
,
,
%
. =
% ,
, 0#9&. = %
. 2
,
" "
?
&
, -
- ,
,
. = %
. / . &% %,
, , " "
USB-
,
. / —
— "
$ .
Безопасность
2 , " % ?
, "
, -
83
. .? >%
%
,
% .
" ,
+
, % . & " .
2 %
,
%
, % , ,
,
.
& +
"
, ,
"
. X .
0 "
%
, %
. * %
, $
"
. 0
" %
.
, "
- ,
, "
. * , $
Wi-Fi, . 3
,
.
2 $
%
. *
Глава 1
84
Wi-Fi, " ,
, . /
,
,
0#9&,
. 4 ,
%
.
Работа с осциллографом
Большинство проектов этой книги содержат схемы, которые отслеживают меняющееся во времени напряжение. Независимо от выполняемой микроконтроллером операции: будь то отслеживание состояния цифрового или аналогового входа, управление скоростью электродвигателя
или отправление данных на персональный компьютер — он или считывает или генерирует изменяющееся во времени напряжение. Частота событий, с которыми работает микроконтроллер,
настолько высокая, что она находится вне диапазона человеческого восприятия. Например, при
последовательном обмене, который мы недавно рассматривали, импульсы электрического тока
подаются со скоростью 10 тыс. раз в секунду. Эти колебания тока невозможно определить с помощью мультиметра. Для этого требуется осциллограф.
0 — $
$
. =
,
(
% ) ( , % ). ;
—
, ,
,
( ).
4"
% , "
. +
DSO Nano,
Seed Studio ( . 1.18).
$100 $
% $ $ . ~
,
,
$ . 0 1 7q,
% . * . 1.18
Nano «2 , »
Arduino.
. , — . &
%
% 200
% , — 1
% . 0 "
" (« »)
Arduino, — 1,
"
.
,
Logic Saleae (www.saleae.com)
. * ,
" " -
Средства
85
Рис. 1.18. Отслеживание последовательного потока данных на осциллографе DSO Nano
. *, ,
. #
Logic —
Logic 4 — ,
DSO Nano, % .
,
" — -
, .
, , . *
$ " %
, .
$
. *
, # % .
Глава 1
86
Прикосновением все и завершается
Хотя большая часть материала этой книги посвящена решению задач общения устройств друг
с другом, важно помнить, что наши проекты создаются, скорее всего, для того, чтобы они могли
доставлять удовольствие людям, которым не интересны внутренние технические детали.
*
,
- . * , , " % , ,
, ,
,
% . &
,
. $
,
"
. +
, , % ,
.
*
,
, . * ,
. =, ,
"
$ ,
"
. +
, % ,
"
,
-
,
. / ",
,
.
— $ %
% ,
-
.
* " —
/
.
,
,
, . # , $
.
,
, $ . &
, %
,
, $
. + ,
, % "
$ ,
,
«% ». * %
. & ,
% .
X ,
%
,
%
%
, . &
, ,
" " "
, — $ % " .
Глава 2
ПРОСТЕЙШАЯ СЕТЬ
Самая простая сеть — это соединение двух объектов один
к одному. В этой главе подробно рассматривается двусторонняя
связь, и начнем мы с характеристик, которые нужно оговорить
прежде всего. Мы познакомимся с некоторыми логистическими
элементами сетевой связи: протоколами данных, управлением
потоками и адресацией. Эти теоретические понятия мы применим
на практике, создав два устройства, реализующих примеры
использования последовательной связи между микроконтроллером
и персональным компьютером. Мы также рассмотрим
модемную связь и узнаем, как заменить кабель, соединяющий
микроконтроллер и компьютер, на приемопередатчики
беспроводной связи Bluetooth. Наконец, мы научимся
программировать микроконтроллеры низкого уровня с тем,
чтобы распределять вычислительные потребности наших проектов
между разными процессорами.
«Молниеносный» оркестр Джу Йон Паэка (2006)
/
" - . 2
" ,
, " . 0 ' 1 4 % (Joo Youn Paek).
Глава 2
90
Компоненты для проектов этой главы
Коды поставщиков
?
A — Arduino Store, http://store.arduino.cc
?
AF — Adafruit, http://adafruit.com
?
D — Digi-Key, www.digikey.com
?
F — Farnell, www.farnell.com
?
J — Jameco, http://jameco.com
?
RS — RS, www.rs-online.com
?
SF — SparkFun, www.sparkfun.com
?
SS — Seeed Studio, www.seeedstudio.com
Рис. 2.1. Новые компоненты для проектов этой главы: 1. Компоновочный корпус. 2. Литиево-полимерная батарейка.
3. Батарейка типа «Крона», 9 В. 4. Контактный разъем для батарейки «Крона» 9 В с разъемом питания. 5. Небольшая мягкая
игрушка по имени Мартышкин. 6. Мячик для настольного тенниса. 7. Трехцветный светодиод. 8. Датчики изгиба. 9. Шилды
для прототипов. 10. Кнопки. 11. Микроконтроллер ATtiny85. 12. Адаптерная плата микросхемы CH340G. 13. Адаптерная
плата FTDI Friend. 14. Адаптерная плата микросхемы CP2104 Friend. 15. Штыревые разъемы. 16. Модуль Bluetooth Mate.
17. Модуль Bluefruit EZ-Link
1
3
4
2
5
17
9
14
8
16
7
13
10
11
12
15
6
Простейшая сеть
ПРОЕКТ 1. Управление яркостью
трехцветного светодиода
с клавиатуры
"
, 1 +. = $
Arduino . &
MKR1000 Arduino 101,
Arduino Uno .
MKR1000 — AF: 3156, RS: 124-0657, A: ABX00004,
GBX00011 (3 4#), D: 1659-1005-ND
Arduino 101 — D: 1660-1003-ND, J: 2239331,
SF: DEV-13787, AF: 3033, F: 2520713, RS: 9139999, SS: 114990575, A: ABX00005, GBX00005
(3 4#)
Arduino Uno — D: 1050-1024-ND, J: 2151486,
SF: DEV-11021, A: A000099, AF: 50, F 1848687,
RS: 715-4081, SS: ARD132D2P
% = $ ,
1 +. /, , ! 0
, .
D: 754-1492.ND, J: 2125181, SF: COM-00105,
F: 2290374, RS: 861-4290
( 220 , 1 +.
D: 220QBK-ND, J: 690700, F: 9339299, R: 7077612
C , 1 +.
D: 438-1045-ND, J: 20723 20601, SF: PRT12615 PRT-12002, F: 4692810, AF: 64,
SS: 319030002 319030001
> .
]= =
. & $ Arduino — $ %
USB.
* ,
% .
"
, 1 +. 7
.
ПРОЕКТ 2. Мартышкин пинг-понг
(Monski Pong)
"
, 1 +. = $
-
91
Arduino . &
MKR1000 Arduino 101,
Arduino Uno .
MKR1000 — AF: 3156, RS: 124-0657, A: ABX00004,
GBX00011 (3 4#), D: 1659-1005-ND
Arduino 101 — D: 1660-1003-ND, J: 2239331,
SF: DEV-13787, AF: 3033, F: 2520713, RS: 9139999, SS: 114990575, A: ABX00005, GBX00005
(3 4#)
Arduino Uno — D: 1050-1024-ND, J: 2151486,
SF: DEV-11021, A: A000099, AF: 50, F 1848687,
RS: 715-4081, SS: ARD132D2P
(
, 2 +.
D: 905-1000-ND, J: 150551, SF: SEN-10264,
AF: 182, RS: 708-1277
& , 2 +. +
. &
,
% .
D: GH1344-ND SW400-ND, J: 2231822
119011, SF: COM-09337, F: 1634684, RS: 718-2213
( 10 , 4 +.
J: 29082, SF: COM-09939, F: 350072, RS: 2499294
C , 1 +.
D: 438-1045-ND, J: 20723 20601, SF: PRT12615 PRT-12002, F: 4692810, AF: 64,
SS: 319030002 319030001
> .
]= =
. ; , " .
]+ +
" +
, 1 +. ( —
).
ПРОЕКТ 3. Беспроводной
мартышкин пинг-понг
# +
»
«" +
2.
C 9 '
)
-
)
, 1 +.
D: 1568-1237-ND, J: 2207056, SF: PRT-09518,
A: 80, F: 1650675
Глава 2
92
= MKR1000 9 &
- , 1 +.
SF: PRT-13813 PRT-08483; A: 258 2011
) 2,1
, 5,5 + . 4
Farnell, $
.
D: CP3-1000-ND, J: 28760, SF: PRT-10287, A: 369,
F: 1737256
Bluetooth, 1 +.
AF: 1588, SF: WRL-12580 WRL-12576
,
Bluetooth, 1 +.
ПРОЕКТ 4. Arduino-совместимая
плата своими руками
" Arduino, 1 +. _% Arduino Uno, MKR1000 Arduino
101.
MKR1000 — AF: 3156, RS: 124-0657, A: ABX00004,
GBX00011 (3 4#), D: 1659-1005-ND
Arduino 101 — D: 1660-1003-ND, J: 2239331,
SF: DEV-13787, AF: 3033, F: 2520713, RS: 9139999, SS: 114990575, A: ABX00005, GBX00005
(3 4#)
Arduino Uno — D: 1050-1024-ND, J: 2151486,
SF: DEV-11021, A: A000099, AF: 50, F 1848687,
RS: 715-4081, SS: ARD132D2P
"
ATtiny84, 1 +. 4 $ ,
.
D: ATtiny84A-PU-ND, SF: COM-11232, F: 1455160,
RS: 7380684
% = $ , 1 +.
; , 1.
D: 754-1492.ND, J: 2125181, SF: COM-00105,
F: 2290374, RS: 861-4290
( 220 , 1 +.
D: 220QBK-ND, J: 690700, F: 9339299, R: 7077612
C , 1 +.
D: 438-1045-ND, J: 20723 20601, SF: PRT12615 PRT-12002, F: 4692810, AF: 64,
SS: 319030002 319030001
.
J: 20723, SF: PRT-12796, F: 2396146, RS: 7916463, AF: 759
Для всех проектов
USB/TTL-Serial. /
. * - USB-A
USB-Mini-B USB-Micro-B. 0
, ,
USB/TTL-Serial,
.
D: 36-84-4-ND, J: 216452, SF: DEV-09716
DEV-14050, A: 3309 284, SS: 317990026.
Рис. 2.2. Адаптеры USB/TTL-Serial
(слева направо): Adafruit FTDI Friend;
Adafruit CP2104 Friend; SparkFun Serial
Basic Breakout CH340G
Простейшая сеть
93
Уровни согласования
Прежде чем мы предоставим устройствам возможность общаться друг с другом, нам нужно
определиться с основными вопросами такого общения. Эти вопросы можно разбить на пять
уровней, каждый из которых основывается на предыдущем.
?
\ .
? # " ?
?
{ .
? 5 &? 3,3 &? - ?
?
< . — ? # ,
1, — 0,
,
: 0, —
1, — .
?
N =. "
? #
: 8, 9, 10 % ?
0
?
?
N
A . " ? "
, - ?
/ "
, " OSI1.
&
,
. %
1
OSI, Open System Interconnect, (&0#). #
,
ISO ( ISO-7498)
1984 .
.
,
$ .
,
, $
— $ % $ . X , " "
,
$ .
" "
,
.
' 0 1
, ,
: .
0 ( . 2.3). #
( : ) .
3
,
( ) ( . 2.3
:
SPI
I2C). #
( ,
). & $
,
$
, "
$ : Ethernet-
.
Глава 2
94
Асинхронный обмен данными
Передатчик
Приемник
Направление данных
RX (Прием)
TX (Передача)
Направление данных
TX (Передача)
RX (Прием)
Общий
(«земля»)
Общий
(«земля»)
Асинхронный обмен данными: каждое устройство использует свой собственный генератор тактовых (синхронизирующих) сигналов, обмен данными осуществляется с заранее согласованной скоростью.
Синхронный обмен данными (интерфейс SPI)
Master (ведущее устройство)
Slave (ведомое устройство)
Chip Select (CS)
Выбор схемы
Chip Select (CS)
Выбор схемы
Выход ведущего,
вход ведомого
Направление данных
MOSI (выход ведущего,
вход ведомого)
Направление данных
Вход ведущего,
выход ведомого
Направление сигнала
тактирования
Clock (CLC)
Сигнал тактирования
MISO (вход ведущего,
выход ведомого)
Clock (CLK)
Сигнал тактирования
3,3 В
Тактовые импульсы
0В
Синхронный обмен данными (интерфейс SPI, Serial Peripheral Interface): ведущее устройство подает сигнал тактирования на ведомое устройство и инициирует обмен, подавая сигнал выбора схемы. Обмен данными происходит по смене
уровня напряжения сигнала тактирования на обратное.
Синхронный обмен данными (интерфейс I2C)
Master (ведущее устройство)
Slave (ведомое устройство)
Обмен данными осуществляется
в обоих направлениях
Serial Data (SDA)
Последовательные
данные
Serial Clock (SCL)
Сигнал последовательного
тактирования
Направление сигнала тактирования
SDA (последовательные
данные)
SCL (cигнал последовательного тактирования)
3,3 В
Тактовые импульсы
0В
Синхронный обмен данными (интерфейс I2C): ведущее устройство подает сигнал тактирования на ведомое устройство, выбирая ведомое по его адресу. Обмен данными происходит по смене уровня напряжения сигнала тактирования на обратное.
Рис. 2.3. Типы последовательной связи
Простейшая сеть
95
Устанавливаем соединение: нижние уровни
Мы уже знакомы с одним примером последовательного обмена данными — между микроконтроллером и персональным компьютером. В частности, в главе 1 мы подключили микроконтроллерный модуль к персональному компьютеру через порт USB. Это подключение является примером асинхронного последовательного обмена данными с использованием двух протоколов
последовательной связи: TTL Serial и USB.
— $ ,
, 778 (TTL2 Serial). /
" :
Arduino Uno, USB
;;_
. * — ,
MKR1000 Arduino 101, $
.
?
\ . 0 , . & Arduino
,
RX (
Receive, ), ,
TX ( Transmit, ).
0
USB " " USB3,
TTL. 0 "
:
?
{ . 0
. & 3,3 &, — 5 &.
?
< . &
(3,3 5 &) 1, (0 &) — 0.
\ . USB
: Data+
Data– (+5 &
" ).
?
{ . # Data–
Data+,
$ . /
%
$ — $
$ .
4
,
.
?
?
N =. 0
" 9600
. =
,
8
,
(
).
?
N
A . * $
,
" .
?
< . _ 1 +5 & (
Data+) –5 & ( Data–),
0 — 0 &.
* $ "
. +
. #
TTL/USB- ,
TTL-
USB- . *
— ,
?
N =. X
USB
,
"
;;_. & USB
480
. 0
2
TTL, Transistor-Transistor Logic —
(;;_).
3
-
USB, Universal Serial Bus (protocol) — % .
Глава 2
96
,
8
,
. * USB
(
).
%
,
$
% "
.
?
N
A . * USB/TTL-Serial
Arduino
,
. 0 $
,
,
$ .
& $ , USB ,
USB — неисчерпаемый источник последовательных портов
0 — ,
. * ,
%
,
,
. 3 $
,
, $ —
. 0 % USB
. 4 "
USB,
USB , "
. 3 USB
,
USB- ().
* , Arduino USB-, . *
% Mac OS :
/dev/cu.usbmodem1441
/dev/cu.usbmodem1461
/dev/cu.usbmodem1471
& POSIX, macOS,
: /dev/tty.usb-
modemXX " /dev/cu.usbmodemXX. /
$ : TTY4
" , CU5 — ". =
USB/TTL-Serial,
$ ,
" .
* % Windows $ , , : COM8, COM9, COM10.
>%
"
USB/TTL-Serial. = ,
,
$15–20. 0
,
, "
TTL, FTDI (Future Technology
Devices International),
www.ftdichip.com. /
Maker SHED, SparkFun, Adafruit
. = : 5 &
3,3 & —
$ . - USB/
TTL-Serial FTDI . 2.4, TTL — . 2.5.
4
5
TTY, Teletype Unit — .
CU, #alling Unit — " .
Простейшая сеть
97
. 7 USB/
TTL-Serial Arduino
USB
(9600 —
1).
Рис. 2.4. Кабель-переходник USB/TTL-Serial компании FTDI
Рис. 2.5. Распиновка разъема TTL кабеля USB/TTL-Serial компании FTDI. Кроме линий передачи, приема и питания он также
имеет линии для аппаратного управления обменом данных: RTS (Request-to-send, запрос на передачу) и CTS (Clear-to-send,
готовность к передаче). Некоторые устройства используют эти линии для управления потоком последовательных данных
Распиновка разъема TTL
кабеля USB/TTL-Serial компании FTDI
Общий («земля»)
GND
Черный
Готовность к передаче
CTS
Коричневый
Используется для подачи питания
на устройство от USB-порта компьютера
Vcc
Красный
К контакту RX (Прием) микроконтроллера
TX
Оранжевый
К контакту TX (Передача) микроконтроллера
RX
Желтый
RTS
Зеленый
Запрос на передачу
4 " —
BASIC Stamp
, USB, ,
,
" 9- USB/RS-232
( USB RS-232
. 2.6). / DB-9
D-sub-9
: RS-232.
RS-232 USB
"
. / "
:
?
\ . =
RS-232
2,
3. 5 —
« ».
?
{ . =
RS232 : +3 & +25 & –3 & –25 &.
?
< . & ( +3 & +25 &) 0, ( –3 &
–25 &) — 1.
, $ ( ) .
?
N =. ; , TTL, — 8-
.
Глава 2
98
1
2
3
4
2
3
1
4
USB тип A
USB тип B
1 2 3 4 5
5 4 3 2 1
USB тип Mini-B
USB тип Micro-B
1 — +5 В
2 — Данные –
3 — Данные +
4 — «Земля»
2
3
4
5
2 — Прием на ПК
3 — Передача с ПК
5 — «Земля» ПК
7
8
9
6
RS-232 (штекерный разъем)
1 — +5 В
2 — Данные –
3 — Данные +
4 — ID
5 — «Земля»
# % ,
— , BASIC Stamp,
RS-232?
,
;;_
RS-232 .
RS-232 " ,
USB, , , , % ,
. >%
"
USB/TTL-Serial.
& %
% ,
$ " .
;
,
$ , -
.
Преобразователи USB/Serial
>%
$
, ,
,
, "
- . #
TTL-
— TTL-Serial.
* , %
GPS6
6
1
GPS, Global Positioning System —
.
Рис. 2.6. Распиновка разъемов USB и RS-232
( 8)
"
TTL-Serial. = ,
$
, USB/
TTL-Serial
.
*
USB/Serial. 0
FT232RL,
FTDI. * $ - , $
- . FTDI ( . . 2.4) ,
( . . 2.5) -
$ .
- FTDI,
, Adafruit, SparkFun, Parallax
. 7 FT232RL " ,
XBee Digi -
Arduino
RedBoard SparkFun.
/ ,
TTL-
: 5 3,3 &.
SparkFun
, FTDI
Friend Adafruit
,
Простейшая сеть
99
. , $
RS-232. =
RS-232 Parallax,
"
DB-9.
— , Prolific (
PL2303), Silicon Labs ( CP2102), Jiangsu
Heng Qin ( CP340) . =
$
" :
?
www.ftdichip.com/FTDrivers.htm (FTDI);
+ USB/TTL-Serial
.
(TX) $
(RX) .
0" (« ») " ,
VCC
. ,
,
, .
* %
USB/TTL-Serial 5 &, 3,3 &. & 1
, " USB/TTLSerial FTDI Raspberry Pi ( . . 1.17).
*
.
?
www.silabs.com/products/mcu/Pages/
USBtoUARTBridgeVCPDrivers.aspx
(Silicon Labs);
?
www.prolific.com.tw/US/Show-Product.
aspx?pcid=41 (Prolific);
?
www.wch.cn/download/CH341SER_ZIP.
html (Jiangsu Heng Qin).
'
USB/Serial,
$ . USB/TTL-Serial
.
=
%
.
$ ,
,
. & $ %
FTDI —
$
" Windows, macOS
Linux.
* FTDI,
USB/TTLSerial -
& Arduino Uno USB/
TTL-Serial " Atmel 16U2,
$ . = $
macOS Linux,
USB Windows " Windows. +
USB/TTL-Serial Arduino Uno
hardware/arduino/avr/firmwares/ATmegaxxu2
https://github.com/arduino,
USB
- www.usb.org/developers/usbfaq.
USB/TTL-Serial
,
, CTS (clear-to-send, ) RTS (request-to-send, ).
>% , "
USB/TTL-Serial, — ,
Huzzah!
ESP8266 Adafruit ESP8266
Thing SparkFun, "
$ ,
$. = USB/TTLSerial "
% .
Глава 2
100
Использование платы Arduino в качестве адаптера
USB/TTL-Serial
4
USB/
TTL-Serial,
Arduino ,
.
& , $
MKR1000 Arduino 101. 0
, "
USB,
$ , ,
. =
" TX ( ) RX ( ) Serial1.
= $ . & USB
(RX) ,
USB — (TX) . ; ,
USB " USB/TTL-Serial.
void setup() {
// # $
// ' :
Serial.begin(9600); // USB
Serial1.begin(9600); // TTL
}
void loop() {
// RX TTL, USB:
if (Serial1.available()) {
char c = Serial1.read();
Serial.write(c);
}
// USB,
if (Serial.available()) {
char c = Serial.read();
Serial1.write(c);
}
}
TX TTL:
7
— ,
Arduino Uno,
USB. $,
USB,
"
USB/TTL-Serial. & (TX)
(RX) . / ,
Arduino USB/TTL-Serial.
= $
,
:
void setup() {}
void loop() {}
2
" ( : , ):
• % — RX (0) Arduino;
• % — TX (1) Arduino.
; % USB/TTL-Serial
Arduino, .
,
.
Простейшая сеть
101
Отправка сообщений: уровень приложений
Теперь, когда у нас появилось представление о том, как устанавливать соединение между устройствами, настало время создать пару проектов, чтобы научиться организовывать отправляемые
данные.
Проект 1
Управление яркостью трехцветного светодиода с клавиатуры
В этом примере мы будем управлять микроконтроллером нажатием клавиш клавиатуры компьютера. Это очень простой проект — в нем используется минимальное количество деталей, что
даст нам возможность сосредоточиться непосредственно на обмене данными.
= ,
,
. =
,
, , ,
,
« ».
/
Arduino — ,
" ,
analogWrite(). ;
7
:"* ,
( ), , ,
" .
= $
, . ` $
.
;
,
:
, ,
" .
$
( ), (
)
" . ($
" )
7
+7, % - .
Требуемые компоненты
;
, 1 %.
9
(RGB)
" -
220 0, 1 %.
# Arduino ( . 2.8, , MKR1000, ! —
Arduino 101), 1 %.
+
: X3
(UART), +7 (PWM).
> , 1 %.
.
7
, 1 %.
220 0 « »
,
— +7,
. 2.7 ( MKR1000 — $ 3,
5 4, Arduino 101 — 3, 5 6).
,
%
—
% , , ,
. 2.8. 7
" . 4 % , ,
.
Глава 2
102
Макетная плата с модулем MKR1000
A B
C D E
F
G H
I
J
1
1
5
5
10
10
15
15
Рис. 2.8. Светодиод с надетым на него теннисным мячиком,
играющим роль светорассеивающего абажура
+3,3 В
20
20
25
25
30
Модуль
микроконтроллера
ШИМ
ШИМ
ШИМ
30
A B
C D E
F
G H
I
Принципиальная схема
Показаны только
задействованные выводы
J
Общий («земля»)
Макетная плата
Arduino
101/Uno
Макетная
платассмодулем
модулем
Arduino
101/Uno
A B
C D E
F
G H
I
J
1
1
5
5
10
10
15
15
20
20
25
25
30
30
A B
C D E
F
G H
I
J
Рис. 2.7. Подключение анодов трехцветного светодиода к выводам ШИМ микроконтроллерной платы:
для платы MKR1000 (вверху) — это контакты 3, 5 и 4, а для платы Arduino 101 (внизу) — 3, 5 и 6.
Общий катод светодиода подключается через последовательный резистор номиналом 220 Ом к контакту «земля» платы
220½ Ом
Простейшая сеть
103
Создаем коммуникационный
протокол
+, , %,
, . = $
,
%
:
?
,
: r, g b;
?
, : 0 9.
* , ( % 0 9)
— 5,
— 3 — 7, " :
r5g3b7
& — . *
" ,
, % , —
.
Пишем код
, , ,
($ ).
; :
" :
/*
M -#
: Arduino
-# , r
( ), g ($ )
b ( )
3, 5
4 .
/*
// - :
//
' $ MKR1000.
// ^ Arduino 101 $
// -.
const int redPin = 3; // Arduino 101 $ 3
const int greenPin = 5; // Arduino 101 $ 6
const int bluePin = 4; // Arduino 101 $ 5
int currentPin = 0; //
int brightness = 0; //
= setup()
:
$
void setup() {
// # ' :
Serial.begin(9600);
// $ :
pinMode(redPin, OUTPUT);
pinMode(greenPin, OUTPUT);
pinMode(bluePin, OUTPUT);
}
&
:
void loop() {
// % ,
// :
if (Serial.available() > 0) {
int inByte = Serial.read();
Глава 2
104
4 - "
,
.;,
, if, :
// $ 'r', 'g', 'b'
// '0' '9'.
// ' $ :
if (inByte == 'r') {
currentPin = redPin;
}
if (inByte == 'g') {
currentPin = greenPin;
}
if (inByte == 'b') {
currentPin = bluePin;
}
+, , "
( )
" analogWrite():
if (inByte >= '0' && inByte <= '9') {
// $ -
// $ analogRead():
brightness = map(inByte, '0', '9', 0, 255);
// $ '
// :
analogWrite (currentPin, brihtness);
}
}
}
2 $ , , " "
( . 2.9).
&
"
:
r9
;
. ; :
r2g7
Рис. 2.9. Значок монитора порта в панели инструментов
среды разработки Arduino
,
. = :
g0r0b8
7 . &! 7
.
4
, , , ,
, ,
. / %
,
.
=
Arduino
IDE. _ ,
,
Arduino . ;
, " ,
Processing.
Простейшая сеть
105
Несколько слов об ASCII
,
,
? / ,
$
ASCII.
ASCII
. * ,
ASCII 'r' — 114, '0' — 48. 2
,
, ASCII.
* , $ :
brightness = map(inByte, '0', '9', 0, 255);
$ :
ASCII ‘0’ 48, ‘9’ — 57.
ASCII , . &
ASCII
, —
ASCII $ . &
,
. >
ASCII
!
«; ASCII?» $ .
brightness = map(inByte, 48, 57, 0, 255);
Усложняем задачу
В предыдущем проекте мы управляли микроконтроллером с компьютера, используя для этого
очень простой протокол. На этот раз уже микроконтроллер будет управлять анимацией на компьютере. Коммуникационный протокол для этого проекта будет более сложным.
Проект 2
Мартышкин пинг-понг (Monski Pong)
В этом проекте мы, по сути, создадим аналог компьютерной мыши. Ведь если рассматривать
мышь в качестве объекта данных, она будет выглядеть, как показано на рис. 2.10: есть сигналы
на входе, есть реакция на выходе.
Требуемые компоненты
9
, 2 %.
, 2 %.
9
4 0, 4 %.
> , 1 %.
# Arduino ( . 2.11
MKR1000, ! —
Arduino 101), 1 %.
+ :
, , X3 (UART).
Рис. 2.10. Представление мыши в виде объекта данных
Вывод: 4 значения:
Ввод:
движение
по оси X
1
2
— координата Х, 10 битов
— координата Y, 10 битов
— кнопка 1, 1 бит
— кнопка 2, 1 бит
Кнопки ввода
.
* % % %, 1 %.
Ввод:
движение по оси Y
Глава 2
106
1
5
10
15
20
25
30
5
10
15
20
25
30
25
30
Принципиальная схема
Показаны только задействованные выводы
+3,3 В
I
G H
F
C D E
A B
A B
C D E
F
G H
I
J
J
1
Макетная плата с модулем Arduino 101/Uno
+3,3 В
+3,3 В
Резистивный датчик изгиба
сопротивлением 15 кОм
10 кОм
Резистивный датчик изгиба
сопротивлением 15 кОм
10 кОм
сброс
Модуль
микроконтроллера
4
Analog0
5
подача
10 кОм
10 кОм
A1
Общий («земля»)
5
10
15
20
5
10
15
20
25
30
A B
C D E
F
G H
I
J
1
A B
C D E
F
G H
I
J
1
Макетная плата с модулем MKR1000
Рис. 2.11. Монтажные (вверху и внизу) и принципиальная (в центре) схемы проекта «Мартышкин пинг-понг». Датчики здесь —
для удобства вычерчивания — показаны с короткими проводами, но для реального проекта датчики нужно подсоединять
проводами значительно большей длины
Простейшая сеть
'
%
, . & % % ,
. 0
.
,
% % "
.
+
.
—
,
.
2
—
. : «# » «».
,
. 2.11.
% %
%,
. & , %,
107
" ( . 2.12). 9 "
%
,
. + -
, , —
% . X ,
,
. ~ %
— %
$ ,
. = $ .
& " ,
, $
. 9 $
.
Рис. 2.12. Закрепите датчики
изгиба на какой-либо плотной
основе и прикрепите их к рукам
мартышки
Глава 2
108
Пишем код
;
Arduino " ,
.
&
Arduino —
9600 ,
1 —
" :
284,284,1,1
285,283,1,1
286,284,1,1
289,283,1,1
,
,
.
/*
Z $
: Arduino
Z $ - - -
# %- -
- $ .
-
' :
— A0
— # % 4
5
*/
const
const
const
const
int
int
int
int
int
int
int
int
leftSensor = A0;
rightSensor = A1;
resetButton = 4;
serveButton = 5;
leftReading = 0;
rightReading = 0;
resetReading = 0;
serveReading = 0;
A1
//
//
//
//
# %
# %
//
//
//
//
$
$
void setup() {
// :
Serial.begin(9600);
// configure the digital inputs:
pinMode(resetButton, INPUT);
pinMode(serveButton, INPUT);
}
void loop() {
// $ - :
leftReading = analogRead(leftSensor);
rightReading = analogRead(rightSensor);
// $ # %- :
resetReading = digitalRead(resetButton);
serveReading = digitalRead(serveButton);
// +
$ R:
Serial.print(leftReading);
Serial.print(',');
Serial.print(rightReading);
Serial.print(',');
Serial.print(resetReading);
Serial.print(',');
/*
R $
' % #
printlin(), $ $
:
/*
Serial.println(serveReading);
}
Простейшая сеть
;
,
$
, "
:
9
$
:
.,P,,
(,F,,
(,A,,
),I,,
109
Serial.write(leftReading);
Serial.write(44);
Serial.write(rightReading);
Serial.write(44);
Serial.write(resetReading);
Serial.write(44);
/*
R $ '
% #
printlin(), $ - $
:
/*
Serial.write(serveReading);
Serial.write(10);
Serial.write(13);
Возвратите прежний код
" ,
$
Processing,
.
' ? &
Serial.print(),
$
ASCII,
" Serial.write()
$ «
»
.
7 ( ) ,
ASCII, $
ASCII
«
» . * ,
13 10
ASCII « » « »,
44 — . /
. +
(leftValue, rightValue,
reset serve). &
,
, , 65, «A»,
$ ASCII -
65.
ASCII
www.
asciitable.com.
,
—
(«
»)
ASCII? /
, "
,
, .
. *
,
$ ,
ASCII.
, ASCII
,
" $ .
= «7 % - » ASCII ( ) , , , $
.
Глава 2
110
Что такое ASCII?
ASCII (American Symbolic Code for Information
Interchange,
) 1967 . American Standards Association8 (
ANSI9)
, "
, . /
, . &
, , $
.
, , ASCII
, " —
( ), 8
3 .
ANSI, American National Standards Institute — 3
.
9
4
" $
,
«# » ,
. =%
,
ASCII 10 13 .
; ,
"
. /
32
ASCII (ASCII 0–32).
=
128 ASCII , , " . *
$
, "
. $ "
ASCII
"
,
Unicode
ASCII. Unicode
, " .
$
, - . /
,
Arduino. = %
Processing.
Пишем код
# Processing
" :
/*
: Processing
*/
import processing.serial.*; //
// Processing
Serial myPort;
//
String resultString; // Z $
void setup() {
size(480, 130); // $
printArray(Serial.list()); // +
R
//
//
$ .
Простейшая сеть
111
// ^ '
// ,
// R
' Serial.list()[0].
// \$ 0 ,
//
'
:
String portName = Serial.list()[0];
// :
myPort = new Serial(this, portName, 9600);
// %,
// (ASCII 10):
myPort.bufferUntil('\n');
}
void draw() {
// $ # %
$ :
background(#044f6f);
fill(#ffffff);
//
:
if (resultString != null) {
text(resultString, 10, height/2);
}
}
/* & serialEvent()
$, % $
$ , bufferUntil()
# setup():
/*
void serialEvent(Serial myPort) {
// Z $ %:
String inputString = myPort.readStringUntil('\n');
// $
//
$ :
inputString = trim(inputString);
// ' resultString:
resultString = "";
// $ - ' $
$
// % # :
int sensors[] = int(split(inputString, ','));
// $ $ :
for (int sensorNum = 0; sensorNum < sensors.length;
sensorNum++) {
resultString += "Sensor " + sensorNum + ": ";
resultString += sensors[sensorNum] + '\t';
}
// +
$ R:
println(resultString);
}
Глава 2
112
Текст или двоичный код?
0 "
. ASCII
Unicode
, , -
. , ,
$
.
Разве не все данные двоичные?
*, , . & ,
. $
. * " ,
. * ,
«1-2-3, go». & " $ "
" ASCII .
Символ
1
-
2
-
3
,
g
o
!
Код ASCII
49
45
50
45
51
44
32
103
111
33
Двоичный
00110001 00101101 00110010 00101101 00110011 00101100 01000000 01100111 01101111 01000001
код
*, , " ?
RGB,
0 255:
% " . & ,
36 , 9 . *
, %
. ; , , ".
& ,
,
. _%
( , $ ),
ASCII Unicode. & ,
%
, $
ASCCI Unicode
, %
,
. #
:
102,198,255,127,127,212,255,155,127,
•
7 , %
, $ ,
, . 3 ? = . & $
80 . = ,
TTL-
9600 . 4 ( $ TTL RS-232),
96 , ,
$ " 1/100 . & " -,
.
7 , " ( 0 255
256 , 28, 8 ), $ %
. * ,
, -
%
,
( ) ;
•
ASCII Unicode;
•
%
,
.
Простейшая сеть
113
Интерпретация двоичного протокола
$ , " , " . * ,
" , $
, . $
.
=
. + $
. >% SPI I2C % . +
. $
%
, . 7 $ % ( 16)
. , %
0x,
Arduino, C, 0b, : 0b10101010.
; , " % ?
$2,508
0 — 2,
% — ,
103. ; 2 % . ' $
,
.
% "
?
0b10010110
# %
, 128, 27.
0 , ,
,
. * , 7 API XBee
2- , "
Channel Indicator,
. & $ 16- 9 % , " 6 — 4 ,
%
. +
$
" . 4
,
Channel Indicator "
:
0111111000000000
, 9- % ,
" ,
" 6- , 0,
" , 1, " , $ . &
$
2- — ,
$ ,
, .
+
16- ,
—
64- . / -
XBee. 9 % 3Z 10 , $
. ; ,
1023. 4 ,
3, — 255. & %
$ 0x3FF. ' ,
256 (3 × 256 = 768) (FF = 255),
1023 (768 +255 = 1023).
+ ,
256.
Глава 2
114
Польза шестнадцатеричного представления
, , ,
, %
? / , ,
16. * , MIDI ,
128 ,
,
, 16. & " . 0x9n (Note On), n
0 A % . ;, 0x9A
3 ( 10 ).
3 0x8A (note off)
3. ; , , MIDI 16,
%
.
" : (r — red),
(g — green) (b — blue). * :
= 0xFF0000
$
= 0x00FF00
= 0x0000FF
2 $, "
% . * ,
0x26B0E7
" (0x26, 38 255),
(0xB0, 176)
(0xE7, 231). /
.
Пакеты данных, заголовки, полезные нагрузки и «хвосты»
; ,
( % ) ( , " Processing), , . 0 , $ " :
Датчик левой руки Датчик правой руки Кнопка сброса
(0-1023)
(0-1023)
(0 или 1)
1–4
1–4
1
' $
ASCII 44, . 7
"
. >
"
—
$ ! ! ,
— « ». 2
! . /
,
— .
2 — $ ,
"
,
$
. &
, "
,
, ,
, . ; ,
,
,
" .
*
— , " " . & % ,
Кнопка подачи
(0 или 1)
Символ возврата каретки,
символ перевода строки
1
2
" , $
" , "
" .
& " , $. "
, , , « ». =
" !
. & %
. # Processing
, % 16-
. #" % %
,
"
. &
,
,
" .
Простейшая сеть
115
0 " . 0
(
,
),
. ; % Processing. 4
%,
, . 2.13.
; $
,
- . ,
Processing —
setup() — $
(
% ):
Числа
с плавающей запятой
&
$
"
(floats),
. * ,
: 480 400 — 1,
1,2. ;
:
400 480 — 0,
0,833.
#
,
. + $
% map().
Рис. 2.13. Вывод списка значений датчиков в окне апплета
float leftPaddle, rightPaddle;
//
//
int resetButton, serveButton; //
int leftPaddleX, rightPaddleX; //
//
int paddleHeight = 50;
//
int paddleWidth = 10;
//
float leftMinimum = 120; //
//
float rightMinimum = 100; //
//
float leftMaximum = 530; //
//
float rightMaximum = 500; //
//
void setup() {
size(640, 480); //
String portName = Serial.list()[0];
// :
myPort = new Serial(this, portName, 9600);
// %,
// (ASCII 10):
myPort.bufferUntil('\n');
//
:
leftPaddle = height/2;
rightPaddle = height/2;
resetButton = 0;
serveButton = 0;
//
leftPaddleX = 50;
rightPaddleX = width - 50;
//
noStroke();
}
:
:
Глава 2
116
;
serialEvent() "
, "
:
void serialEvent(Serial myPort) {
//
:
String inputString = myPort.readStringUntil('\n');
//
// :
inputString = trim(inputString);
//
resultString:
resultString = "";
//
//
:
int sensors[] = int(split(inputString, ','));
//
,
:
if (sensors.length == 4) {
//
// :
leftPaddle = map(sensors[0], leftMinimum,
leftMaximum, 0, height);
rightPaddle = map(sensors[1], rightMinimum,
rightMaximum, 0, height);
//
//
:
resetButton = sensors[2];
serveButton = sensors[3];
//
:
resultString += "left: "+ leftPaddle + "\tright: " +
rightPaddle;
resultString += "\treset: "+ resetButton + "\tserve: "
+ serveButton;
}
}
* ,
draw(),
(
% ).
void draw() {
// $ # %
background(#044f6f);
fill(#ffffff);
$
:
//
:
rect(leftPaddleX, leftPaddle, paddleWidth, paddleHeight);
//
:
rect(rightPaddleX, rightPaddle, paddleWidth, paddleHeight);
}
Простейшая сеть
117
9 ,
,
. . ,
. & ,
%,
,
. [ map()
, " .
= $ ,
%,
, . 2
%, ,
. 2% . 2 $
leftMinimum,
leftMaximum, rightMinimum leftMaximum setup(). $
, %
$ .
* ,
. 0 "
.
$
.
$
" .
.
= $
,
setup():
int ballSize = 10; //
int xDirection = 1; //
!
//
// : –1, : 1
int yDirection = 1; //
!
//
// : –1, : 1
int xPos, yPos;
//
// !
3 setup() :
//
xPos = width/2;
yPos = height/2;
; : animateBall()
resetBall(). / draw():
void animateBall() {
// ! :
if (xDirection < 0) {
//
if ((xPos <= leftPaddleX)) {
//
!
:
if((leftPaddle - (paddleHeight/2) <= yPos) &&
(yPos <= leftPaddle + (paddleHeight /2))) {
//
! :
xDirection =-xDirection;
}
}
}
:
Глава 2
118
// ! :
else {
//
if ((xPos >= ( rightPaddleX + ballSize/2))) {
//
!
// :
if((rightPaddle - (paddleHeight/2) <=yPos) &&
(yPos <= rightPaddle + (paddleHeight /2))) {
//
// ! :
xDirection =-xDirection;
}
}
}
//
if (xPos < 0) {
resetBaVL();
}
//
if (xPos > width) {
resetBall();
}
:
:
//
!
if ((yPos - ballSize/2 <= 0) || (yPos +ballSize/2 >=height)) {
//
!
// :
yDirection = -yDirection;
}
//
!
:
xPos = xPos + xDirection;
yPos = yPos + yDirection;
//
:
rect(xPos, yPos, ballSize, ballSize);
}
void resetBall() {
//
xPos = width/2;
yPos = height/2;
}
7 . *
. =
(
setup()
) " , ,
. = "
.
boolean ballInMotion = false; //
int leftScore = 0;
int rightScore = 0;
:
! ?
Простейшая сеть
119
7
.
0 " $
draw():
if()
, if() "
"
, ,
if() "
:
//
!
if (ballInMotion == true) {
animateBaH();
}
7 animateBall(),
,
(
% ):
//
- $ :
if (xPos < 0) {
rightScore++;
resetBall();
}
//
- $ :
if (xPos > width) {
leftScore++;
resetBall();
}
=
setup()
:
int fontSize = 36; //
=
:
// ! ,
if (serveButton == 1) {
ballInMotion = true;
}
!
// ! ,
// ! :
if (resetButton == 1) {
leftScore = 0;
rightScore = 0;
ballInMotion = true;
}
!
setup()
, " % :
//
,
PFont myFont = createFont(PFont.list()[2], fontSize);
textFont(myFont);
* , draw()
:
// # :
text(leftScore, fontSize, fontSize);
text(rightScore, width-fontSize, fontSize);
& ! ; «7 %
- » ( . 2.14). ' , %
,
- .
Рис. 2.14. Игра «Мартышкин пинг-понг» на экране компьютера
:
:
Глава 2
120
Управление потоком данных
Возможно, вы заметили, что ракетки на экране не всегда плавно повторяют движения мартышкиных рук. Иногда ракетки движутся с отставанием от них, а могут на долю секунды и застывать.
Причина этому — асинхронная связь между компьютером и микроконтроллером.
~ $
, $
, "
.
&"
,
" ,
.
& %
,
.
, $
(Processing % ),
, —
= $
"
startup() Arduino
( . «& ! »
!. «4 2. *
- »). + $ ,
Arduino "
,
Processing:
2
loop() Arduino if(),
(
% ):
$ ,
" , ,
.
# ,
, ,
.
#" ,
% % $ .
& ,
Processing %
,
,
,
.
while (Serial.available() <= 0) {
Serial.println("hello"); //
}
void loop() {
// ,
// :
if (Serial.available() > 0) {
//
:
//
—
// :
int inByte = Serial.read();
// # '
// ...
}
}
Простейшая сеть
* " %
serialEvent()
Processing, "
«7 % - »:
121
void serialEvent(Serial myPort) {
// '
myPort.write('\r'); //
}
; $
. *%
% " : "hello" ,
-
,
. /
,
,
,
. 4
, .
;
Processing
, "
.
, " ,
serialEvent(), $ .
, , ,
, —
$ . 4
( , $ "hello"), Processing
.
+
Processing
serialEvent(). *%
,
,
,
,
. ; ,
Processing
.
2
"
. / %
Processing, ""
,
. * "
"
"hello", , % Processing , " , $ Processing
. ;
!
. /
.
Проект 3
Беспроводной мартышкин пинг-понг
Игра «Мартышкин пинг-понг» могла бы быть еще более занимательной, если бы сам Мартышкин
не был привязан к компьютеру кабелем USB. Этот проект ликвидирует проводное соединение
между микроконтроллером и персональным компьютером и вводит новые сетевые понятия:
«модем» и «адрес».
Приобретите адаптер Bluetooth
4 %
"
Bluetooth, "
% . 4 %
.
Глава 2
122
Bluetooth: многоуровневый сетевой
протокол
& $ — Bluetooth, "
:
,
RX ( ) TX ( ), ,
"
Bluetooth. ; ,
Bluetooth
.
,
.
, — . ; ,
:
,
" +
, , "
.
7
Bluetooth
. $
—
— "
. #
Bluetooth — $
,
$ , " Bluetooth Serial Port Profile, SPP10. =
Bluetooth
: — HSP11,
% — HID12.
Bluetooth
$ , " 13, " 10
SPP, Serial Port Profile —
.
11
HSP, Headset Profile — % .
12
HID, Human Interface Device —
« % ».
13
Service Discovery Protocol.
Требуемые компоненты
2 %
.
2. " +
-
# Arduino ( . 2.15
Arduino 101/Uno, ! — MKR1000), 1 %.
+ :
, , X3 (UART).
> 9 &
, "
% , 1 %.
q 2,1
, 5,5 % , 1 %.
7 Bluetooth Serial, 1 %.
, 1 %.
Bluetooth.
# , Bluetooth ,
,
. & $
Bluetooth RS-232
USB,
%
$
.
+, Bluetooth
«7 % - », . 2.15 ( ! —
, — ). &
Bluefruit EZ-Link Adafruit,
Bluetooth Mate SparkFun.
"
: VCC
— +5 & , " (GND) — " (–). #
TX RX Arduino RX TX Bluetooth . ,
.
Простейшая сеть
Стойте, разве плата Arduino 101
не имеет встроенного адаптера
Bluetooth?
0
. * $ Bluetooth 4.0,
Bluetooth LE Bluetooth
Smart. /
$ . ,
Bluetooth 4.0 Serial Port,
. +
Bluetooth 4.0
" .
3 Serial Port
Bluetooth 2.2,
Bluefruit EZ-Link
Bluetooth Mate, , "
TTL-Serial,
. & $
. + Bluetooth
Bluetooth
,
%
Bluetooth, " .
, $ Arduino , "
(X3).
Сопряжение компьютера с модулем
Bluetooth
'
Bluetooth, $ . =
$
Bluetooth, "
Bluetooth.
* %
macOS
System Preferences,
Bluetooth. X , Bluetooth
123
, Show
Bluetooth status in the menu bar (0
Bluetooth ).
,
Bluetooth.
3 % Windows 10
Bluetooth Settings
(
Bluetooth) —
,
.
& Bluetooth Ubuntu
Linux
, $ %
BlueMan
(Bluetooth Manager). = $ Z
Ubuntu,
BlueMan $ . X
BlueMan, D .
&
, Bluetooth,
Bluetooth Manager. 0 — Bluetooth, %
.
# $
00:3A:45:6C:9A:
06 — $ MAC-
14
. &
. 2 . & ,
Adafruit-EZ-Link-XXXX, XXXX —
. 4
Bluetooth, $
Bluetooth — . 4 , 1234, ! —
.
*
macOS
Adafruit-EZ-Link-XXXXSPP, Windows — COMX
( $ COM14).
14
MAC, Media Access Control —
.
Глава 2
124
Ubuntu " ] — , . *
' ,
% Bluetooth: /dev/rfcomm0.
Модификация программы
микроконтроллера
' %
«7 % » Bluetooth, .
Arduino.
Arduino — Arduino Uno Mega,
RedBoard SparkFun,
"
USB, $
USB/
TTL-Serial. * X3
USB/TTL-Serial, TX ( )
RX ( ) . $ $ . * Bluetooth
TX RX ,
% .
3
USB — Arduino 101
MKR1000, USB
X3,
Serial. &
TX RX
X3,
,
" Serial
Serial1. ; , "
, " RX ,
"
Serial1.read(),
TX
"
Serial1.write(), Serial1.print()
Serial1.println(). $,
%
Bluetooth,
TX RX ,
Serial Serial1. * $
.
Bluetooth,
. 3
.
Модификация программы
«Мартышкин пинг-понг»
Bluetooth
,
. 2
«7 % - »
.
/
%
Bluetooth. $
portName setup():
String portName = Serial.list()[0];
* ,
Bluetooth ,
:
portName = Serial.list()[8]
& ,
USB-
.
Завершающие штрихи:
упорядочиваем и закрываем
& «> % - » . = $
% , . 2.16 (
, . 2.15).
&
%
" .
Простейшая сеть
125
30
20
20
A B
C D E
F
G H
I
J
15
15
30
10
10
25
5
5
25
1
A B
C D E
F
G H
I
J
1
GND
DSR
Vin
<TX
X
>RX
X
DTR
STS
3Vout
3Vo
V
Макетная плата
с модулем MKR1000
Принципиальная схема
Показаны только задействованные выводы
+3,3 В
+3,3 В
+3,3 В
Резистивный датчик изгиба
сопротивлением 15 кОм
сброс
Модуль
микроконтроллера
подача
10 кОм
10 кОм
Analog0
4
5
Резистивный датчик изгиба
сопротивлением 15 кОм
10 кОм
TX
A1
RX
Общий («земля»)
10 кОм
Модуль
Bluetooth Bluefruit
RTS
RX
TX
Vin
+3,3 В
CTS
Общий («земля»)
20
25
30
20
25
30
10
A B
C D E
F
G H
I
J
15
15
5
5
GND
DSR
Vin
X
<TX
10 X
>RX
DTR
1
A B
C D E
F
G H
I
J
1
STS
3Vo
V
3Vout
Макетная плата
с модулем Arduino 101/Uno
Рис. 2.15. Монтажные (вверху и внизу) и принципиальная (в центре) схемы проекта «Беспроводной мартышкин пинг-понг»
с подсоединенным модулем Bluetooth
Глава 2
126
# ,
, " ,
$
( . 2.17).
-
Рис. 2.16. Сборка проекта
«Беспроводной
мартышкин пинг-понг» на макетном
шилде
Рис. 2.17. Проект «Беспроводной мартышкин пинг-понг» в завершенном виде
Простейшая сеть
127
Проект 4
Arduino-совместимая плата своими руками
Иногда в проекте требуется задействовать больше одного микроконтроллера, или — наоборот — для работы проекта достаточно только одного или двух выводов общего назначения
микроконтроллера, что делает излишним включение в такой проект микроконтроллера с широкими возможностями. Бывают также ситуации, когда вместо использования одного микроконтроллера для выполнения ряда задач проще задействовать несколько микроконтроллеров,
возложив на каждый из них ответственность только за одну задачу. Для таких случаев прекрасно
подойдут микроконтроллеры Atmel семейства ATtiny. Эти небольшие микроконтроллеры ценой
всего лишь несколько долларов можно программировать с помощью платы Arduino или ее клона по синхронному последовательному протоколу SPI.
,
, MKR1000,
Arduino 101 Arduino Uno,
%
. >% $
!
. 7 "
,
,
, "
. *
USB/TTL-Serial, — MKR1000 Arduino 101 —
.
' % , ,
% — % . ,
%
%
. ;
,
"
8-
AVR-
Atmel DIP15, " . 0
ATmega328T,
Arduino Uno. *
15
DIP, Dual-in-Line Package —
( ) ( ).
Требуемые компоненты
# Arduino (Arduino 101/
Uno MKR1000), 1 %.
+
: X3
(UART), SPI.
7 ATtiny84, 1 %.
> , 1 %.
;
, 1 %.
(RGB)
9
.
" -
220 0, 1 %.
,
,
ATtiny84
ATtiny85. 0 $
/ " (GPIO),
,
+7 ( . 2.18). +
,
, +7. ~
X3,
SoftwareSerial.
,
" "
.
Глава 2
128
& $ , "
"
Точка обозначает вывод 1
, — ,
$ 1.
Выемка обозначает верхнюю часть корпуса
Сброс
Вход напряжения питания
3 (аналоговый ввод 3)
2 (аналоговый ввод 1, SCK)*
ATtiny85
4 (аналоговый ввод 2)
1 (PWM, MISO)
Общий («земля»)
0 (PWM, ARef, MOSI)
Точка обозначает вывод 1
Выемка обозначает верхнюю часть корпуса
Вход напряжения питания
Общий («земля»)
10
0 (аналоговый ввод 0, ARef)*
9
Сброс
1 (аналоговый ввод 1)
ATtiny84
8 (PWM)
2 (аналоговый ввод 2)
3 (аналоговый ввод 3)
7 (аналоговый ввод 7, PWM)*
4 (аналоговый ввод 4, SCK)*
6 (аналоговый ввод 6, PWM, MOSI)*
5 (аналоговый ввод 5, PWM, MISO)*
*Здесь:
•
•
•
•
•
SCK — тактирование;
PWM — ШИМ;
MISO — вход ведомого, выход ведущего;
ARef — опорное напряжение;
MOSI — выход ведомого, вход ведущего.
Рис. 2.18. Распиновка микроконтроллеров ATtiny84
(вверху) и ATtiny85 (внизу)
Использование Arduino в качестве устройства ISP
Arduino Un
% , ! ! (bootloader)
,
,
.
4
$
X3 (UART). 4 $
, -
. > $
Arduino USB.
*
. &
ICSP16
16
$
ICSP ISP, In-Circuit Serial Programmer —
.
Простейшая сеть
129
Введение в интерфейс SPI
= $ , "
SPI17. +
SPI
I2C18 (
TWI19)
,
- . /
— , Wi-Fi MKR1000 SD-
,
.
" ,
( ) "
.
" ,
%
.
+
SPI " ( "
, )
( ) :
• (SCK) — , "
( );
• = $, = (MOSI, Master
Out, Slave In): $ "
;
• = $, = (MISO, Master In,
Slave Out): $
" . 4
" , MISO ;
• (SS, Slave Select) = (CS, Chip Select) — %
,
17
SPI, Serial Peripheral Interface —
.
18 2
I C, Inter-Integrated Circuit — %
.
19
TWI, Two-Wire Interface — .
CS
" . ' , "
$ .
4 $ , % .
Master
Slave 1
Chip Select 1
CS
MOSI
MOSI
MI SO
MI SO
Clock
CLK
Chip Select 2
Slave 2
CS
MOSI
MI SO
CLK
SPI
AVR,
% $ ,
Arduino Uno
, "
ICSP,
SPI. /
" :
Белая точка обозначает вывод 1
1: MISO
2: Вход напряжения питания
3: SCK
4: MOSI
5: Сброс
6: Общий («земля»)
4 % ICSP,
, , . * SPI
.
& "
SPI Arduino Uno, 101
MKR1000:
Функция
MOSI
MISO
CLK
Uno
101
MKR1000
11 ICSP4
12 ICSP1
13 ICSP3
ICSP4
ICSP1
ICSP3
CS
10
10
8
10
9
Глава 2
130
SPI.
,
"
. , ,
. " -
" — ,
AVR AVRISP mkII Atmel USBTinyISP
Adafruit.
# Arduino
, — ArduinoISP — "
Рис. 2.19. Монтажные (вверху) и принципиальная (внизу) схемы программирования микроконтроллера ATtiny84 с помощью
платы Arduino (вверху слева) и MKR1000 (вверху справа). Полукруглый неглубокий вырез на одном конце микросхемы ATtiny
обозначает ее верх, а круглое очень мелкое углубление с одной стороны этого выреза — физический вывод 1 микросхемы (это
стандартная маркировка микросхем в корпусе DIP)
Макетная плата с модулем Arduino 101/Uno
Макетная плата с модулем MKR1000
A B
C D E
F
G H
I
J
1
1
5
5
10
10
15
15
20
20
25
25
30
30
A B
A B
Принципиальная схема
Показаны только задействованные выводы
C D E
F
G H
+3,3 В
К выводу MOSI программатора
Сброс
F
G H
I
J
1
5
5
10
10
15
15
20
20
25
25
J
30
Vin
К выводу CS программатора
I
C D E
1
30
A B
C D E
F
G H
I
J
ATtiny84
6
Общий («земля»)
4
К выводу SCK программатора
5
К выводу MISO программатора
Простейшая сеть
131
Arduino ICSP- . 0
$
, \ | |
ArduinoISP, , . 2 ATtiny84 Arduino,
. 2.19.
*
ATtiny84
,
Arduino.
; , $ 1 ( . !
«* »),
\ | ]
!
" A
" : http://www.leonardomiliani.com/repository/package_leonardomiliani.com_index.json.
2 OK
. &
| ATtiny. =
AVR
. * ,
ATmega328P
Arduino Uno, ATmega2560 — Arduino Mega.
=
ATtiny
.
/
20. $
, , . .
& ATtiny84
:
?
: ATtiny;
?
Processor: ATtiny84;
?
: 8 7q (
?
: ,
, .
20
).
0 . fuse — .
= $
ATtiny24/44/84,
Micro. & $ $
ATtiny84@8 MHz (internal oscillator; BOD
disabled), ,
.
Arduino as ISP —
%
Arduino ATtiny.
2 #
(Burn Bootloader), . % " # +
(Done Burning Bootloader). ;
ATtiny84.
4 , ATtiny84 ATtiny84@8
MHz (internal oscillator; BOD disabled). /
, %
,
. ATtiny ,
, — $
( +3 & +5 &),
%"
. & $ ,
Blink («7»). *
13- 6
D | #
. &
Arduino % Arduino ATtiny. 4
6 ATtiny
, ,
.
Глава 2
132
Библиотека SoftwareSerial
и управление яркостью
светодиода с помощью ATtiny
7 ATtiny
$ —
: .
= $ / 6, 7 8
ATtiny84. /
+7 —
+7 Arduino 101 MKR1000, $ . 2
Arduino «X » ,
$ .
Пишем код
= —
SoftwareSerial
$ $
"
/ (GPIO). 7 0 1:
#include <SoftwareSerial.h> //
SoftwareSerail:
;
:
// -
:
const int redPin = 8;
const int greenPin = 7;
const int bluePin = 6;
=
'
SoftwareSerial swSerial(0, 1); // RX, TX
Serial swSerial. > SoftwareSerial
print(), println(),
read(), write() available(),
Serial.
2
ATtiny84, Arduino
, ,
«7». 2
USB/TTL-Serial ( . 2.20). & TX
0 ( ,
) , RX — 1.
-
, « » «" » "
.
2 CoolTerm , , $
. * :
r5g3b7
`
, . 0
, $
,
% .
Простейшая сеть
133
Макетная плата с установленным на ней микроконтроллером
ATtiny84 и подключенным адаптером USB/TTL-Serial
A B
C D E
F
G H
I
1
J
BLACK 1
GND
CTS
VCC
TX
5
5
RX
RTS
GREEN
TX
10
10
15
15
20
20
25
25
30
RX
30
A B
C D E
F
G H
I
J
Принципиальная схема
Показаны только задействованные выводы
Общий («земля»)
CTS
Vcc*
TX
10 кОм
Адаптер USB/TTL-Serial
RX
RTS
Напряжение
питания
микроконтроллера
ATtiny84
Сброс
0
1
ATtiny84
8
7
220 Ом
6
Общий («земля»)
*Напряжение питания с адаптера USB/TTL-Serial
Рис. 2.20. Монтажная (вверху) и принципиальная (внизу) схемы реализации проекта управления яркостью светодиода с клавиатуры на микроконтроллере ATtiny84. Питание на микроконтроллер и сопутствующую схему подается через адаптер USB/
TTL-Serial из порта USB компьютера. Поскольку микроконтроллер ATtiny84 и светодиоды могут работать на напряжении величиной как 3,3 В, так и 5 В, величина подаваемого адаптером напряжения не имеет значения. Подключенный к выводу
сброса микроконтроллера повышающий резистор номиналом 10 кОм не допускает произвольного сброса микроконтроллера, удерживая на этом выводе высокий уровень напряжения. Сброс микроконтроллера осуществляется кратковременным
замыканием вывода сброса на землю
Глава 2
134
Эмуляция последовательных портов:
библиотека SoftwareSerial
X
(X3) (
0 1,
RX TX) "
, , $ " . / ,
X3
. * ,
Arduino %
?
/ % "
X3. * , Arduino Mega2560
X3. *
$ X3 , %
. &
" SoftwareSerial.
0 $
$
X3. > " $ ,
" .
SoftwareSerial X3 ,
,
X3,
%
4800 / 57,6 / . /
— , ATtiny.
& , $
X3 — , Arduino Uno, ,
$ X3 .
~
,
.
* , ESP8266, $ ,
Wi-Fi, %
,
1 . $ ,
— , «7 % », $
. *
ATtiny84 ATtiny85.
. & $
, ,
.
& , ,
,
. * ,
# "
Arduino
AVR,
. +
,
Arduino
"
:
?
ATmega328P — " Arduino Uno;
?
ATmega168 — " Arduino
Diecimila Duemilnove;
?
ATmega8 — " Arduino NG
;
?
ATmega2560 — " Arduino
Mega2560;
?
ATmega32U4 — " Arduino
Micro.
Простейшая сеть
135
,
Arduino Uno,
Arduino- ,
+
.
3 $ , "
:
?
?
?
?
ATtiny84;
ATtiny44;
ATtiny 85;
ATtiny45.
* . 2.21
Arduino Uno . 2
,
ATtiny:
SPI ,
Arduino Uno, .
+
,
,
ATtiny ATmega328P. %
% , "
30
25
20
10
J
Принципиальная схема
Показаны только задействованные выводы
F
G H
I
RX
TX
RTS
GREEN
VCC
CTS
BLACK 5
GND
F
G H
I
J
1
78xxl
15
TX
RX
Макетная плата с установленным на ней микроконтроллером
ATmega328P и подключенным адаптером USB/TTL-Serial
Общий («земля»)
C D E
A B
30
25
20
15
10
5
C D E
Vcc
1
CTS
A B
ATMEGA328
TX
Адаптер USB/TTL-Serial
RX
RTS
Стабилизатор
напряжения
7805
+9-12V
In*
+5 В
Out**
10 кОм
Сброс
*Входное напряжение
**Выходное напряжение
Напряжение
питания
0 (RX)
22 пФ
1 (TX)
ATmega328P
Кварц
Кварц
22 пФ
Общий («земля»)
Рис. 2.21. Монтажная (вверху) и принципиальная (внизу) схемы для сборки на макетной плате совместимого с Arduino Uno
микроконтроллерного устройства на основе микроконтроллера ATmega328P и адаптера USB/TTL-Serial
Глава 2
136
2 , ,
USB/TTL-Serial, —
$ .
. 2.21
-
5 & , % 9–12 &. 9 ATmega328P : www.
arduino.cc/en/Hacking/PinMapping168.
Заключение
Проекты, рассмотренные в этой главе, поясняют несколько понятий, являющихся базовыми для
всех типов сетевого обмена данными. Прежде всего запомните, что обмен данными основан на последовательности уровней соглашений: первым идет физический уровень, затем электрический,
логический, уровень данных и, наконец, уровень приложений. Имейте эти уровни в виду при разработке и диагностировании своих проектов, так как это облегчит вам задачу локализации проблем.
?
' : ,
ASCII,
(«
»)
.
$ ,
, . * ,
, , ,
%
ASCII.
?
% :
" ,
,
,
% . / %
.
: , « »,
.
?
J :
"
%
.
« - »
.
?
: , "
% ,
USB/TTL-Serial Bluefruit. &
,
",
% .
?
] ,
,
. # ,
, ATtiny,
. /
"
.
* ,
. & $ " "
.
JitterBox. Автор Габриель Барсия-Коломбо (Gabriel Barcia-Colombo)
JitterBox21 — $
,
40- % ,
. 4
— , . ; " , , " ,
,
Arduino,
40- % . /
,
" . & JitterBox " 9 7
(Ryan Myers).
21
JitterBox — jitterbug ( ) jukebox (
).
Простейшая сеть
137
Глава 3
БОЛЕЕ СЛОЖНАЯ СЕТЬ
Теперь, когда мы обладаем основными знаниями о сетевом обмене
данными, можно перейти к более сложным вопросам. И лучше всего
начать с самой знакомой нам сети передачи данных — Интернета.
По сути, это не одна сеть, а система сетей разных поставщиков
сетевых услуг, которые связаны между собой с помощью
определенных общих протоколов. В этой главе мы рассмотрим
структуру Интернета, а также устройства и протоколы, которые
соединяют эту сеть в единое целое. Вы на практике познакомитесь
с закулисными сторонами работы веб-браузера и клиента
электронной почты и научитесь использовать сообщения
этих сетевых средств для подключения своих объектов к Сети.
Сетевые цветы Дории Фэн (Doria Fan), Маурисио Мело (Mauricio Melo) и Джейсона
Кауфмана (Jason Kaufman)
# " «# »
" . X
- ,
" .
Глава 3
140
Компоненты для проекта этой главы
Коды поставщиков
?
A — Arduino Store, http://store.arduino.cc
?
J — Jameco, http://jameco.com
?
AF — Adafruit, http://adafruit.com
?
RS — RS, www.rs-online.com
?
D — Digi-Key, www.digikey.com
?
SF — SparkFun, www.sparkfun.com
?
F — Farnell, www.farnell.com
?
SS — Seeed Studio, www.seeedstudio.com
Рис. 3.1. Новые компоненты для проекта этой главы: 1. Резистивные датчики давления серии 402 компании Interlink. 2. Провод
для монтажа накруткой диаметром 30 AWG. 3. Инструмент для монтажа накруткой (в ручку инструмента вставлено приспособление для снятия изоляции с провода). 4. Веб-камера. 5. Резиновые подкладки. 6. Листы толстого картона или фанеры для
основания под датчики давления
3
5
6
4
1
2
ПРОЕКТ 5. Сетевой кот
"
, 1 +. = $
Arduino . &
Arduino 101, Arduino
Uno, MKR1000 .
Arduino Uno — D: 1050-1024-ND, J: 2151486,
SF: DEV-11021, A: A000099, AF: 50, F 1848687,
RS: 715-4081, SS: ARD132D2P
"
ATtiny84. '
,
$ .
MKR1000 — AF: 3156, RS: 124-0657, A: ABX00004,
GBX00011 (3 4#), D: 1659-1005-ND
D: ATTINY84A-PU-ND, SF: COM-11232, F:
1455160, RS: 738-0684
(
400
Interlink, 2 4 +. & 402,
400 .
Arduino 101 — D: 1660-1003-ND, J: 2239331,
SF: DEV-13787, AF: 3033, F: 2520713, RS: 9139999, SS: 114990575, A: ABX00005, GBX00005
(3 4#)
Более сложная сеть
141
D: 1027-1001-ND, J: 2128260, SF: SEN-09375,
A: 166
( 1 , 1 +. _ .
D: 1.0KQBK-ND, J: 690865, F: 9339051, R: 7077666
C , 1 +.
D: 438-1045-ND, J: 20723 20601, SF: PRT12615 PRT-12002, F: 4692810, AF: 64, SS:
319030002 319030001
> .
]= =
. " .
'- , 1 +.
. 4
& , 2 +. .
A
.
D: K386-ND, J: 22577, F: 09WX4670
( .
D: 3M156065-ND, RS: 120-6041, J: 2119718, A:
550, SF: C0M-10594, F: 1165068
A .
D: K445-ND WSU-30M, J: 2150361, F: 441089
H ).
D: A26509-20-ND, J: 103377, SF: PRT- 00116, F:
1593411
USB/TTL-Serial. ,
ATtiny.
, .
SF: DEV-09716 DEV-14050, A: 3309 284,
SS: 317990026
, 1 +.
Сетевые топологии и сетевые адреса
Задача отслеживания маршрутов сообщений из предыдущей главы была простой, так как созданная нами сеть состояла только из двух узлов: отправителя и получателя. Но в любой сети,
состоящей из более чем двух узлов: от трех до трех миллиардов — нужна карта сети для отслеживания объектов, с которыми установлено соединение. А чтобы сообщения доставлялись
по месту назначения, требуется схема адресации.
Сетевые топологии:
как соединяются объекты?
0
% "
. " —
. ; -
"
.
,
( . 3.2, ).
#"
—
( )
Рис. 3.2. Три типа сетевой топологии: полносвязная (слева), звездообразная (в центре) и кольцевая (справа)
Прямое соединение узлов сети
Топология «Звезда»
Топология «Кольцо»
142
"
"
. ;
! ! ! ( . 3.2, )
, ,
. ,
%
, % ,
" .
; —
( . 3.2,
).
, "
,
" % ,
.
) %
* ( +
( . 3.3). &
(
)
(
%
). 3
%
Рис. 3.3. Сложная многоуровневая звездообразная сеть
Глава 3
(
).
$
%
$ , "
.
; ,
, "
"
,
- " .
#
. 4 , "
.
* % ,
,
. ,
, % , $
,
,
, %
.
; , +
,
$ . *
,
,
, % % . =
,
. 3.2, $ . *
, , $
, " +
.
Более сложная сеть
143
Модемы, хабы, коммутаторы и маршрутизаторы
=
( . . 3.3), +
,
.
*
,
( ), %
(
). & %
,
$ . 9
,
.
* — ,
. &
DSL- , " +
% . /
% %
, ,
,
, % " +
. $
Bluetooth, 2,
$ .
= ( ) ,
( )
"
. = ,
" , — . &
Адреса аппаратные и сетевые
* : , —
-
.
.
* $ " "
$ . ;, Bluetooth 2
" " ,
$ " " ,
. ~
,
.
> , % "
. & , " , "
, , .
0
, , ,
(
%
DSL- ,
), !
.
0
. 7 %
, "
,
, $
% . 7 %
IP- ,
" , % . *
% +
—
, DSL-
, — % $ % .
Bluetooth. 3
+
1
IEEE , , , IEEE 802.x. * , % %
,
,
Ethernet,
IEEE 802.3. 3
Ethernet — Wi-Fi —
1
IEEE, Institute of Electrical and Electronics Engineers —
+
$ $ (#3).
Глава 3
144
IEEE 802.11: 802.11a, b, g n. #
%
$ . ;
Bluetooth IEEE
802.15.1. & 802.
MAC- 2. MAC- ,
,
6-
,
$
Ethernet . =
MAC-
IEEE
MAC- . MAC-
.
= Ethernet Wi-Fi
+
IP3. IP-
# ! ,
, . . MAC- ,
, !
. 4
, !#
IP- , # !
% *G&- , !
IP- .
' !
IP- MAC- .
4
"
, IP-
MAC-
, $
" :
?
2
%
macOS
, System Preferences | Network. /
, +
. #
, % "
MAC-
( . Media Access Control) —
.
3
IP, Internet Protocol —
- .
Ethernet- Wi-Fi. 0
$
IP- ,
,
. *
Advanced , Hardware,
MAC-
,
TCP/IP,
IP-
, ;
?
% Window 10
( , | ),
"
D . 0 Wi-Fi, , % . "
! . 0
—
D, "
IP-
;
?
% Ubuntu Linux
D ,
]
| D
> . 0 , "
. & ,
, .
* . 3.4
% macOS ( )
Windows (). *
, MAC-
IP-
" :
?
%
% — :
00:11:24:9b:f3:70;
?
IP-
,
, — : 192.168.1.20.
IP-
, " , % ,
, MAC- ,
IP- . $,
Более сложная сеть
а
145
б
Рис. 3.4. Диалоговые окна параметров сетевого подключения для машин под macOS (а) и Windows (б)
,
,
.
Улица, город, область, страна:
структура IP-адресов
% ,
" ( ) ( ).
, IP-
. * IP — ,
. % "
IP- ,
. 7 %
,
, IP-
,
.
q IP- ,
. & , ,
IP-
217.123.152.20. 7 % ,
$ , ,
,
217.123.152.1.
2
0–255,
% .
* , %
XXX.XXX.XXX.1. $ % -
%
217.123.152.XXX. + % %
,
% . ;
217.123.1.1.
%
.
, % , . ; :
255.255.255.0.
. 9
$ ,
. '
( ) 32 .
,
, $ . ,
,
255.255.255.255. * ,
255.255.255.255
— % . 4
0 ( . . 3.1),
$ —
Глава 3
146
% — 255 (
.255 % "
" ). 255.255.255.192
62 % (255 – 192 – 1 = 62) . *
-
,
%. & . 3.1 "
" .
Таблица 3.1. Соотношение между значением маски подсети и максимальным количеством
поддерживаемых узлов этой подсети
Маска подсети
Максимальное количество машин в подсети, включая маршрутизатор
(учитываются зарезервированные адреса)
255.255.255.255
1 ( % )
255.255.255.192
62
255.255.255.0
254
255.255.252.0
1022
255.255.0.0
65,534
IP- " . 0
$ : -
, $
*
IP-
,
%
. .
.
Частные и общедоступные IP-адреса
* +
. + % , %
, " "
, $ "
% . & IP-
. /, ,
192.168.XXX.XXX, 10.XXX.XXX.XXX
172.16.XXX.XXX 172.31.XXX.XXX. ;
% % . & %
%
,
,
$ . * " , % % ,
,
" IP- % . ;
NAT- ! 4. + , % ,
.
4
NAT, Network Address Translation —
.
* ,
192.168.1.45, % - - . /
% %
. =
%
% 192.168.1.1,
+
" 66.187.145.75. 7 %
" , ,
$ "
. - , %
( ) 192.168.1.45. ; ,
, " " IP- , " ,
+
.
Более сложная сеть
147
Протокол ARP
ARP, "
73#-
" IP- . ; , "
arp IP-
% %
,
.
3
" ARP5. & , POSIX arp
5
ARP, Address Resolution Protocol — %
.
Просматриваем таблицу ARP
0 ( macOS
Linux, bash % Windows)
" ( , $
% ,
):
0 " :
$ arp -a
?
?
?
?
?
?
?
(192.168.0.1) at ac:b3:13:a1:d7:77 on en0 ifscope [ethernet]
(192.168.0.2) at 0:17:88:a:17:45 on en0 ifscope [ethernet]
(192.168.0.15) at 0:e0:4c:9:3b:3f on en0 ifscope [ethernet]
(192.168.0.176) at (incomplete) on en0 ifscope [ethernet]
(192.168.0.255) at (incomplete) on en0 ifscope [ethernet]
(224.0.0.251) at 1:0:5e:0:0:fb on en0 ifscope permanent [ethernet]
(255.255.255.255) at (incomplete) on en0 ifscope [ethernet]
ARP % —
%
. &
IP-
,
( at) — MAC- . &
arp -a, $
IP-
. , 73#
% IP- .
# (incomplete) ,
— ,
$ , -
, $
,
.
Команда ping: вы там?
arp , ,
,
$
. # " — ping —
IP- .
/
" «& ?», .
Ограничения p i n g и a r p
0
— , % , ,
ping. * , $ ,
— arp —
. 4
, $
, %
. & — $ % .
Глава 3
148
0
" (
% Windows
- –n. +, ,
$
—
$ %
):
/
127.0.0.1 "
.
,
, " ,
.
0
" :
-
$ ping -c 3 127.0.0.1
PING 127.0.0.1 (127.0.0.1): 56 data
64 bytes from 127.0.0.1: icmp_seq=0
64 bytes from 127.0.0.1: icmp_seq=1
64 bytes from 127.0.0.1: icmp_seq=2
& ping
—
-c ( macOS/Linux) -n ( Windows).
% ,
" .
" :
--- 127.0.0.1 ping statistics
--3 packets transmitted, 3 packets
received, 0.0% packet loss
round-trip min/avg/max/stddev =
0.056/0.061/0.072/0.008 ms
& %
% ,
$. & ,
,
— ,
,
$ . &
ping ,
%
.
bytes
ttl=64 time=0.056 ms
ttl=64 time=0.056 ms
ttl=64 time=0.072 ms
0
.
Специальные адреса локальной
сети
3
127.0.0.1 — $
, " (loopback address) ! (localhost
address). #" ,
$
,
. & localhost. # "
localhost
. =
$ $
,
, —
.
& arp "
: X.X.X.255 ( X.X.X.
). /
# . #"
Более сложная сеть
149
. "
,
, , ,
%
.
+ % "
ping,
, " .
Пробуем ping с широковещательным адресом
0
" ( —
Windows — - -n):
0 " :
$ ping -c 3 192.168.0.255
64 bytes from 192.168.0.12: icmp_seq=0 ttl=64 time=0.102 ms
64 bytes from 192.168.0.4: icmp_seq=0 ttl=64 time=1.457 ms
64 bytes from 192.168.0.1: icmp_seq=0 ttl=64 time=12.232 ms
64 bytes from 192.168.0.12: icmp_seq=1 ttl=64 time=0.061 ms
64 bytes from 192.168.0.4: icmp_seq=1 ttl=64 time=1.672 ms
64 bytes from 192.168.0.1: icmp_seq=1 ttl=64 time=10.419 ms
64 bytes from 192.168.0.12: icmp_seq=2 ttl=64 time=0.062 ms
--- 192.168.0.255 ping statistics -3 packets transmitted, 3 packets received, +4 duplicates,
0.0% packet loss
round-trip min/avg/max/stddev = 0.061/3.715/12.232/4.877 ms
Еще об ограничениях p i n g
+ ping
% " "
. &
Request timed out ( %
). >
$
% .
0 , $ 192.168.0.255,
73#- .
7 % "
192.168.0.255
6. $ %
$ — ,
, ping. ; ,
% " ping, $
, IP-
6
3
$ . =
.
. %
, $
% , , , " ,
,
%
Ethernet Wi-Fi.
*
$ % "
. / ping, % . 4 % "
ping
,
,
,
%
, 5-
7- , .
Примечание
* "
% " ,
$ % % .
Глава 3
150
, IP-
, ping $ . /, , % -
, %
.
Преобразование числовых адресов в имена
& , , , $
, +
- www.makezine.
com www.archive.net. / ,
IP- ,
,
, . 2 $
DNS 7,
-
IP- . / — DNS 8,
,
. 0
,
,
DNS. *
$ %
"
DHCP 9,
IP- , $
.
Коммутация пакетов:
как сообщения путешествуют
по Интернету?
; "
? /
, , . = % % ",
" % . '-
" , Ethernet (
) " -
,
, ! , "
.
" ". ;
, IP
" ,
" " " . 0 " ,
, .
" . / .
= +
: TCP10
UDP11. 7
$
$ . 0
, TCP
, " , , $,
, UDP,
, .
% "
% . 4 %
" % 12,
,
. ; ,
"
" % ,
10
7
DNS, Domain Name System —
.
8
DNS, Domain Name Server —
.
9
DHCP, Dynamic Host Control Protocol — .
TCP, Transmission Control Protocol — .
11
UDP, User Datagram Protocol — .
12
& " % — % ,
% % " " .
Более сложная сеть
151
$ " % . &
% , "
( % ) .
" % " .
0
" ( )
% .
$ $ .
=
—
. #
$ , ,
. + %
%
.
Клиенты, серверы и протоколы управления связью
Теперь, когда у нас появилось представление об организации Интернета, давайте разберемся,
как все это там делается. Например, каким образом сообщение электронной почты доставляется своему адресату? Или как ввод адреса в адресную строку браузера или щелчок на ссылке
доставляет соответствующую веб-страницу на компьютер? В основе всего этого лежит обмен
сообщениями между сетевыми объектами, использующими только что описанную систему их
транспортировки. Рассмотрим это более подробно, используя в качестве примера просмотр
веб-страницы.
Как веб-страница попадает
на компьютер?
* . 3.5 - :
-
, - %
. %
"
,
,
, % " .
Рис. 3.5. Путь веб-страницы от веб-сервера к браузеру пользователя. Географическое расположение физических компьютеров не имеет значения, если известны адреса веб-сайтов
Сервер
веб-сайта
Поставщик сетевых
услуг веб-сайта
Интернет
Поставщик сетевых
услуг веб-сайта
Сервер
веб-сайта
-
Ваш поставщик
сетевых услуг
Ваш кабельный
или DSL-модем
Ваш
маршрутизатор
Ваш компьютер
Глава 3
152
# - — $ , " ,
-
+
, "
# . ,
,
, ,
# ,
.
& -
HTML, ,
$ " -
+
.
> — $ ,
,
. * , % ,
,
, - . #
( )
, " - , % .
#
IP-
"
,
. * , - 80,
$
$ - . 3
25,
$ .
_ ,
. & $
%
. 7 %
— , $ ,
(FTP), telnet
- . # %
,
(
). > - " :
1. &
(URL) - : http://www.
example.com/index.html.
2.
www.example.com 80.
3. # .
4. %
- : index.html.
-
5. #
%
,
$
.
6. >
,
- ( ,
- , . .)
$ , .
, .
&
,
( ), . X $
,
. 0 ,
$ ,
ping. * % Windows PuTTY.
Версия telnet для Windows
& telnet, " Windows,
. * , localecho,
$ ,
"
Trying... Connected. $
PuTTY.
Более сложная сеть
153
Обращаемся к серверу
& " %
<Enter>.
$ telnet www.example.com 80
# " :
Trying 64.233.161.147...
Connected to www.example.com.
Escape character is '^]'.
= "
( ,
,
.
% <Enter>
):
* $
:
GET /index.html HTTP/1.1
Host: www.example.com
Connection: Close
-
HTTP/1.1 200 OK
Cache-Control: max-age=604800
Content-Type: text/html
Date: Hon, 11 Apr 2016 15:51:58 GMT
Etag: "359670651+gzip+ident"
Expires: Hon, 18 Apr 2016 15:51:58 GMT
Last-Modified: Fri, 09 Aug 2013 23:54:35 GMT
Server: ECS (lga/1384)
Vary: Accept-Encoding
X-Cache: HIT
x-ec-custom-error: 1
Content-Length: 1270
Connection: close
$
HTML — $ HTML-
- www.example.com.
+
-
— " HTTP13. http://
- $
. # , % 13
HTTP, HyperText Transfer Protocol —
.
Выход из telnet
4 telnet
, % <Ctrl>+<]>,
% telnet
quit.
" HTML, !
HTTP. 2 HTTP ,
"" , , $
. $
,
.
Глава 3
154
Создаем веб-сервер
- ,
" node.js 1? ~
,
, $
" - , " HTTP. $
,
- .
#
" %
—
"
. & $ ,
, .
Пишем код
&
"
server.js
dateServer.js.
2 ,
1,
$
:
-
$ node dateServer.js
; "
, telnet localhost ( 127.0.0.1)
8080 $
. &
$
" , " HTTP "
:
/*
Z
: node.js
*/
var express = require('express'); // '
// express:
var server = express(); // $ " server,
// $ express
// % # ', $
//
$ :
function respondToClient(request, response) {
// :
response.writeHead(200, {"Content-Type": "text/html"});
response.write("< " + new Date() + ">"); response.end();
}
// :
server.listen (8080);
//
server.get('/*', respondToClient);
$ :
Примечание
HTTP/1.1 200 OK
&
dateServer.js
X-Powered-By: Express
, server.js, ,
Content-Type: text/html
express.js :
Date: Tue, 11 Apr 2017 16:43:39 GMT
Connection: keep-alive
npm install express
Transfer-Encoding: chunked
< Tue Apr 11 2017 12:43:39 GMT-0400 (EDT)>
~ - ,
,
, "
,
,
% Processing
. =
$
< >.
,
HTTP
—
,
. =
%
.
Более сложная сеть
155
HTTP
"
:
2
: name age, tom
14
.
, " (&).
HTTP
«-! ».
. &
request, req,
" :
%" , , %"
, ,
,
. 7
"
$
,
response ( res), "
"
.
> HTTP node.js
, "
$
= HTTP GET,
"" , .
http://localhost:8080/?name=tom&age=14
Пишем код
# "
node.js
$ :
/*
Z
: node.js
*/
var express = require('express'); // '
// express:
var server = express(); // $ " server,
// $ express
// % # ', $
//
$ :
function respondToClient(request, response) {
// Z ' JSON.stringify $
// :
var request = "request: " + JSON.stringify(request.query);
// :
response.writeHead(200, {"Content-Type": "text/html"});
response.write(request);
response.end();
}
// :
server.listen(8080);
//
server.get('/', respondToClient);
$ :
# $
getParameters.js,
,
:
http://localhost:8080/?name=tom&age=14
& " :
request: {"name":"tom","age":"14"}
Глава 3
156
HTTP/1.1 200 OK
X-Powered-By: Express
Content-Type: text/html
Date: Mon, 11 Apr 2016 17:16:48 GMT
Connection: keep-alive
Transfer-Encoding: chunked
/ -
"
telnet
PutTTY, $ ,—
GET
:
request: {"name":"tom","age":"14"}
?name=tom&age=14
;
.:
GET /get-parameters.php?name=tom&age=14
& $ -
( HTTP), " :
Методы HTTP GET и POST
#
,
HTTP,
. * ,
,
,
, ,
" $
, " .
= $
(URL) , " node.js,
$ "
"
$ .
HTTP
: GET, POST, PUT DELETE.
*
PUT DELETE,
GET POST.
& node.js
GET $ "
request.query. " JSON, "
,
.
Пишем код
%
,
, $ . & "
-
ageCheck.js.
/*
$
: node.js
Z#
$ HTTP :
name ( )
age (# )
+$ $ ,
$ $ ($ age).
*/
var express = require('express'); // '
// express:
var server = express(); // $ " server,
// $ express
Более сложная сеть
157
2 $
:
node ageCheck.js
,
" ,
:
// % #
$ $:
function respondToClient(request, response) {
// Z ' JSON.stringify $
// :
var request = "request: " + JSON.stringify(request.query);
// :
response.writeHead(200, {"Content-Type": "text/html"});
response.write(request);
response.end();
}
?name=tom&age=14
;
" :
-
/check/?name=tom&age=14
* , age % ,
21.
/
. # ,
, . .:
http://localhost:8080/,
,
. .: http://localhost:8080/check.
&
$
! . ,
(/),
.
function checkAge(request, response) {
var name = request.query.name;
var age = request.query.age;
var responseString = "";
if (age < 21) {
responseString = "<p>" + name
+ ", +
,
.</p>\n";
} else {
responseString = "<p> , " + name
+ ". + $ ,
' , ";
responseString += " R
$
.</p>\n";
}
// :
response.writeHead(200, {"Content-Type": "text/html"});
response.write(responseString);
response.end();
}
// :
server.listen (8080);
//
server.get('/', respondToClient); //
//
server.get('/'check', checkAge); //
//
> express.js "
,
GET POST . $
GET "
server.get(), POST — c "
server.post(). > $
4, "
(REST)14.
14
REST, REpresentational State Transfer ( : ) —
.
$ :
/?
/check/?
+
: http://localhost:8080/
http://localhost:8080/check —
. / ,
.
9
,
.
#
. *
,
$
Глава 3
158
. =
POST. &
(URL),
$ GET, POST HTTP.
, POST
—
.
, POST
% ,
$ -
— URL,
URL
. & GET
,
POST
" :
http://www.example.com/check
3
, POST. =
" ,
: GET POST.
Пишем код
'
POST,
(
% ). #
:
var express = require('express');// '
// express:
var server = express(); // $ " server,
// $ express
var bodyParser = require('body-parser'); //
//
//
URL:
server.use(bodyParser.urlencoded({ extended: true }));
// ... -
=
checkAge —
,
% :
% #
checkAge
function checkAge(request, response) {
var name, age;
if (request.method === "GET") {
name = request.query.name;
age = request.query.age;
} else if (request.method === "POST") {
name = request.body.name;
age = request.body.age;
}
var responseString = "";
//
* , , " POST
/check. /
,
GET. [ .get()
.post() " ,
GET
"
POST.
$
# # .
server.get('/check', checkAge); //
// /check/?
server.post('/check', checkAge); // !
// POST
Более сложная сеть
159
* $ , " npm body-parser. = $
,
,
" :
$ npm install body-parser
; , express,
,
" " ,
% . ;
body-parser node_modules,
.
Тестируем код
- " telnet
127.0.0.1 8080
" . * $ $
" POST:
POST /check HTTP/1.0
Host: example.com
Connection: Close
Content-Type: application/x-www-form-urlencoded
Content-length: 16
name=tom&age=14
Примечание
& ,
GET,
—
.
9
(
$ Content
. $,
, , % % ,
,
" .
length:)
Доставка файлов
& , - ,
,
HTML,
- ,
.
9
$
"
,
. $
,
node.js,
(
), .
,
. * "
$
, %
-
. = $
HTML , ,
$ /check
" POST. *
checkAge, , "
$ HTML- .
& " body-parser % POST. & $
" " server.use(). /
(middleware),
.
& % " " — express.static,
,
%
node.js
Глава 3
160
. / , "
,
. =
. * "
,
: http://localhost:8080/ _&.html.
Пишем код
# ,
,
public. #
,
$ index.html.
+,
<html>
<body>
<form action="/check" method="post"
enctype="application/x-www-form-urlencoded">
Name: <input type="text" name="name" /><br>
Age: <input type="text" name="age" />
<input type="submit" value="Submit" />
</form>
</body>
</html>
index.
html public. :
form action="/check" method="post"
,
ageCheck,
POST. ; ,
Submit % POST
/check,
%
.
= checkAge.js
" ,
% :
Рис. 3.6. Форма для проверки возраста
// use the parser for data that's URL-encoded:
server.use(bodyParser.urlencoded({ extended: true }));
// serve static pages from public/ directory:
server.use('/',express.static('public'));
; respondToClient() "
server.get(). / %
,
.
#
. &
: http://localhost:8080/index.html —
, . 3.6. #
GET, POST.
Более сложная сеть
& %
$ . 7
-
,
- ,
, " public.
161
4
,
, — , /
$ , check,
, ,
" .
Отправка запросов с помощью curl
+
$
HTTP,
" telnet. & ,
. *
. ,
$ %,
POSIX- curl,
Linux macOS
(
Raspberry Pi 1). +
Windows 10
curl,
Cygwin
( , $
,
1,
Net). 2 POST %
" curl "
:
< X-Powered-By: Express
< Content-Type: text/html
< Date: Tue, 12 Apr 2016 17:58:46 GMT
< Connection: keep-alive
< Transfer-Encoding: chunked
<
* Connection #0 to host localhost left intact
<p>tom, + ,
.</p><a href="/index.html">
'. </a>
curl %
,
$ , : man curl. =
. + $
.
?
$ curl -v -d "name=tom&age=14"
localhost:8080/check
):
(
-
curl -v http://www.example.com
3
:
* Trying ::1...
* Connected to localhost (::1) port 8080 (#0)
> POST /check HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.46.0
?
2 POST
:
curl -d "key=value&key2=value2"
http://www.example.com
?
2 GET :
curl -G -d "key=value&key2=value2"
http://www.example.com
> Accept: */*
> Content-Length: 15
> Content-Type: application/x-www-form-urlencoded
>
* upload completely sent off: 15 out of 15 bytes
< HTTP/1.1 200 OK
?
0
curl -L http://www.example.com
:
Глава 3
162
Принцип работы электронной почты
0
" $ " " . & $
: $
,
$ . " ,
" , ",
$ " $ , " " . 2
$ ,
"
$ .
,
$
" . 0
$ , "
.
= " $
SMTP 15. Q
# : POP 16
IMAP 17. 4 HTTP, % .
15
SMTP, Simple Mail Transfer Protocol —
($ ) .
16
POP, Post Office Protocol — .
17
IMAP, Internet Message Access Protocol — ($ ) +
.
Пишем код отправителя почты
=
node.js " $ . # $
mailer.js. X
nodemailer:
npm install nodemailer
& "
%
%
. 465
SSL- 18.
/ % " ,
.
18
SSL, Secure Socket Layer — (
)
.
*
, $ .
, $ ,
" .
/*
: node.js
*/
// ' nodemailer:
var nodemailer = require('nodemailer');
//
' $ :
var account = {
host: 'smtp.gmail.com',
Измените на действительный SMTP-сервер, если вы
port: 465,
не используете Gmail
secure: true,
auth: {
user: '_ _@gmail.com'
pass: '_ '
}
};
Измените на свой
действительный адрес
электронной почты
Более сложная сеть
163
& "
" .
= $ . 0
: to
(), from (), subject ( )
text ( ). &
" :
// :
var message = {
from: account.auth.user,
to: ' @gmail.com',
subject: ' ',
text: ' ,
',
};
*
" , "
% . $
$ :
// $ % # ' $
// $ ' :
function confirm(error, info){
if(error){
console.log(error);
} else {
console.log('Message sent: ' + info.response);
}
}
0 % "
$ , "
createTransport , " . [ sendMail
" %
" :
// $
$
// :
var client = nodemailer.createTransport(account); client.
sendMail(message, confirm);
~ $ $ nodemailer, " %
node.js "
$ .
node.js —
,
$ Processing,
,
.
Измените на действительный
адрес электронной почты адресата
Авторизация в Gmail
Gmail
% . =
OAuth2. '
%
% , % Gmail, My Account (3 Google), " Sign-in and Security (> )
Apps with account access ( , ) $
Allow less secure apps (9 %
)
ON (& ). %
$
OFF. > , %
Gmail
. = ""
$
OAuth2 http://nodemailer.com/
smtp/oauth2/ ( $ ).
Глава 3
164
Шифрование паролей
& "
,
". =
, %
,
$ . = , ,
% "
- .
#" ,
,
.
node.js crypt, "
%
.
% -
' % ,
% , % % , % . & "
" % "
% ,
, % "
. /
" — , .
Пишем код шифрования
# $
encrypt.js. &
node.js, $
.
/*
# " process.
argv[]
(
) node.
js . & %
" % ,
.
// $ :
var key = process.argv[3];
// R
//
var message = process.argv[2]; //
R
//
2
, % " . & % ,
% :
// % - $ %
:
var fileName = 'info.txt';
Z#
%
: node.js
*/
// ' crypto
var crypto = require('crypto');
var fs = require('fs');
fs:
Более сложная сеть
=
"
% ,
,
$ %
% :
165
" .
// Z$ %:
var cipher = crypto.createCipher('aes-256-cbc', key);
// %
$ #:
var encryptedMsg = cipher.update(message, 'utf8', 'hex');
writeFile() , $
19:
// # $ % #
writeFile():
function success(data) {
console.log('I wrote to the file: ' + fileName);
}
* ,
// $ % % :
fs.writeFile(fileName, encryptedMsg, success);
writeFile(), % :
19
, node.js
. 4 "
,
, "
. $
% " .
9 % " .
#
" :
-
$ node encrypt.js '
# ' ,
, " %
% . #"
.
" info.txt,
%
. # $
( ). % " " " .
Пишем код расшифровки
# $
decrypt.js. #
% , % :
/*
Z#
%
: node.js
*/
,
% :
var crypto = require('crypto'); // ' crypto
var fs = require('fs'); // ' %
// fs
& process.argv[]
% ,
:
// $ :
var key = process.argv[3]; // R
// :
var fileName = process.argv[2]; // $ %
// $ %
Глава 3
166
# "
% :
// Z$ %:
var decipher = crypto.createDecipher('aes-256-cbc', key);
readFile()
, $
. & $
%
" % :
// # $ % #
readFile():
function success(error, data) {
if (data){
data = data.toString();
var decryptedMsg = decipher.update(data, 'hex', 'utf8');
decryptedMsg += decipher.final('utf8');
console.log('I read this from the file: ' + decryptedMsg);
} else if (error) {
console.log(error);
}
}
* ,
fs.readFile(fileName, success);
readFile(),
% :
X , info.txt,
% , ,
% ,
" :
$ node decrypt.js
_% '
* $ : _% ,
% , %
.
' —
9
":
I read this from the file:
( $ % :)
,
% "
. 2% $ ,
% " $ , % . /
, " %
.
; ,
HTTP $ " , % , " .
Более сложная сеть
167
Проект 5
Сетевой кот
Людям очень просто выполнять такие задачи, как просмотр веб-страниц или работа с электронной почтой, потому что для нас созданы компьютерные интерфейсы, очень хорошо взаимодействующие с нашими руками: клавиатура отлично подходит для работы с ней пальцами, а мышь
удобно помещается в ладонь. Но, например, для кота отправить сообщение электронной почты — задача не из легких. В этом проекте мы попытаемся исправить такую дискриминацию
котов, одновременно демонстрируя создание нашего первого физического интерфейса для
Интернета.
4
, , , , %
, .
,
"
,
,
. 3
,
$
( $ ), — $ " % . + , %
" $ ,
! *% $ .
# " :
"
— % , " $
. 7
,
- .
, .
/ ,
Processing ,
, , HTTP GET - .
$ , - " $ , ,
%
"
. , Processing
-
-
" HTTP
POST.
Требуемые компоненты
9
Interlink, 2–4 %.
9
400 -
1 0, 1 %.
> , 1 %.
7 Arduino, 1 %.
+
: , X3 (UART).
.
& - , 1 %.
, 1 %.
0 .
, 2 %.
.
.
.
9
.
/
:
?
Arduino
"
Processing;
?
Processing
HTTP GET;
?
node.js HTML-
$
HTTP GET;
Глава 3
168
?
-
-
;
"
?
%
;
?
% Processing
-
,
$ HTTP POST.
$
,
" , - ,
, , "
. + . 3.7
#
.
Рис. 3.7. Наглядная схема подключения кота к Сети
Клиент получает сообщение электронной почты
и открывает веб-страницу, чтобы увидеть снимок кота.
Вау! Симпатяга!!
Почтовый сервер получает сообщение
электронной почты и сохраняет его
для последующей отправки клиенту
> SMTP
> 250 OK
> HTTP/1.1
> 200 OK
Сервер отправляет сообщение
электронной почты
и доставляет веб-страницу
со снимком кота
Пока кот остается на подстилке,
программа Processing каждые две минуты
отправляет запросы на загрузку снимка
Микроконтроллер отправляет
показания датчиков
программе Processing
по последовательному каналу
Когда кот ложится на подстилку,
программа Processing посылает запрос HTTP GET
на отправку сообщения электронной почты
Более сложная сеть
169
* . 3.8 - #
( ), " ( )
" ( ). ;
— " ,
, —
.
Установка датчиков в подстилку
для кота
,
, . = $ "
, "
. &
(9==)
400 Interlink ( . 3.9).
; ,
, .
Рис. 3.8. Блок-схема подключения кота к Сети
Почтовый сервер
Программа
почтового сервера
Персональный компьютер
Почтовый клиент
Протокол SMTP
Протокол SMTP
Веб-клиент
HTTP GET
/index.html
Веб-сервер
Серверная программа
на node.js
HTTP POST
/ загрузка снимков
HTTP GET
/ почта
Персональный компьютер
Sensor
Программа загрузчика
Входное аналоговое
напряжение
Камера
Программа
считывания
показаний датчиков
Микроконтроллер
Данные TTL-Serial по USB
Видео по USB
170
Глава 3
Рис. 3.9. Поскольку резистивные датчики при пайке легко пережечь, вместо пайки я применил монтаж накруткой
проводом диаметром 30 AWG. Инструменты для монтажа накруткой стоят недорого, не требуют особого умения
для пользования ими, но создают надежное соединение.
Подсоединив провода к датчикам давления, я изолировал
места соединений с помощью термоусадочного кембрика
(кембриковая изоляция на рисунках не показана)
=
Arduino . * %
, $ ATtiny ( . 2)
SoftwareSerial. * . 3.10
, MKR1110,
Arduino 101/Uno ATtiny84.
'
,
: ,
,
" ( . 3.11). *
$ — % , :
,
,
- . & $ "
,
.
% ,
.
, % ,
Номиналы резисторов
& %
. 3.10
(
1 0). 4 $
% ,
4,7 10 0.
. 2
( . . 3.11, !
). '
,
( . . 3.11, ! ), " (
). ;
, % .
2
" ,
,
,
"
.
4
% ,
Более сложная сеть
171
Принципиальная схема
Показаны только
задействованные выводы
3,3 В
Резистивные датчики
давления, 4 шт.
Модуль
микроконтроллера
Аналоговый ввод 0
1 кОм
Общий («земля»)
Макетная плата с микроконтроллером ATtiny84
Макетная плата с модулем MKR1000
A B
C D E
F
G H
I
Вывод сброса микроконтроллера нужно подключить
к плюсу питания через повышающий резистор номиналом
10 кОм. Для подключения к порту USB компьютера понадобится отдельный адаптер USB/TTL-Serial (слева вверху). Этот
адаптер здесь также используется для подачи питания на
микроконтроллер
J
1
5
5
10
10
15
15
20
20
25
25
30
30
TX
RX
1
A B
C D E
F
G H
I
RX
TX
VCC
C D E
F
G H
I
J
1
5
5
10
10
15
15
20
20
25
25
RTS
GREEN
CTS
BLACK
GND
A B
1
J
30
Макетная плата с модулем Arduino 101/Uno
A B
C D E
30
A B
F
G H
I
C D E
F
G H
I
J
J
1
1
5
5
10
10
15
15
20
20
25
25
30
30
A B
C D E
F
G H
I
J
Рис. 3.10. Принципиальная (вверху) и монтажные (внизу) схемы подключения датчиков давления к микроконтроллерам.
Поскольку все резистивные датчики давления соединены между собой параллельно, от них отходят всего два контакта
172
Глава 3
Рис. 3.11. Сборка панели датчиков: размещение датчиков по углам нижней пластины (вверху); резиновая накладка, передающая давление верхней пластины на датчик (внизу слева); датчик давления, смонтированный на нижней пластине (внизу справа). Все четыре датчика давления подключаются параллельно. Обратите внимание на резиновые накладки, которые
передают на датчики давление верхней пластины. Обязательно изолируйте все соединения перед тем, как скреплять панели.
Выводы датчиков соединяются с проводом, ведущим к микроконтроллеру, обычными разъемами типа «мама»
Более сложная сеть
173
, % ,
, .
7
,
% ", ,
,
$ — . = $
,
, ,
. 3.10, , — $
.
7
" . $, ATtiny84
USB/TTL-Serial, $
( . . 3.10, !). Arduino Uno/101
MKR1000
USB , $
.
#
,
Arduino " , .
Тестируем панель датчиков
4 ATtiny84
X3, SoftwareSerial,
$ 2.
' ,
9600 . 2
$
. X
,
.
- %
% ,
- . X % ,
,
,
,
"
$ .
/*
Z $
: Arduino
-
Z $ Analog 0
R $ $
% ASCII.
*/
void setup() {
//
// 9600 .
Serial.begin(9600);
}
void loop() {
// Z :
int sensorValue = analogRead(A0);
// +
$ R:
Serial.println(sensorValue);
}
Глава 3
174
Датчики и события
*%
"
$ , . = $
. ' $ ,
,
%
%. + . +
" , ,
,
, ,
, . . 3 "
, , ,
.
& "
>
Arduino IDE. 2 $
, "
, %
. ,
,
. 3.12.
+, ,
,
— " .
7 $
% ,
. ;
,
% ,
. ,
,
: ,
.
' $ ,
.
, % .
3
, $
, ,
% .
*
,
. 7 ,
, $
$ .
; , .
Рис. 3.12. Вывод программы графического отображения
значений датчиков давления
Более сложная сеть
175
Пишем псевдокод
*% Processing
" .
,
-
. ;
$
:
/*
7 ,
setup(),
. 3 draw()
$ .
void setup() {
// \ # $
// M
}
# "
, $
serialEvent(). 0
:
void serialEvent(Serial myPort) {
// - // - :
// - $
// - R.
}
= , ,
. =
,
,
,
:
void sendMail() {
//
// $ R. :
// - $ HTTP GET
// R.
// -
}
$
: Processing
*/
// \
' $
void draw() {
// +
$ R
// ,
R
// - ,
// $
}
void uploadPicture() {
//
// $ $ :
// -
// - $ HTTP POST $ $
// -
}
' ,
"
,
.
Глава 3
176
Пишем код
= % "
. /
,
«7 % - »
2:
&
$
—
,
«7 % ». *
, .
/*
$
: Processing
*/
// \
import processing.serial.*;
Serial myPort;
//
void setup() {
// \ # $ ' $
// \$ 0 ,
//
'
:
String portName = Serial. list()[0];
myPort = new Serial(this, portName, 9600);
// Z$ serialEvent()
// :
myPort.bufferUntil('\n');
}
void draw() {
}
void serialEvent(Serial myPort) {
// - String inString = myPort.readStringUntil('\n');
int sensorValue = 0;
if (inString != null) {
// M :
inString = trim(inString);
// $ $ int:
sensorValue = int(inString);
println(sensorValue);
}
}
X % , $ , %, «
». ,
,
, . * ,
" ,
. +
$ , %
. 3
, , .
$
,
,
, ,
. $, " ,
,
% %
. *
,
,
.
+
,
.
Более сложная сеть
177
' , ,
"
". = $
,
,
: lastSensorReading, threshold catOnMat (
% ):
Serial myPort;
//
int threshold = 400;
// $
int lastSensorValue = 0;
// $
//
boolean catOnMat - false;
// ?
2 SerialEvent "
. &
" "
"
"
lastSensorReading
"
. 0
println(sensorValue) %
, $ .
void serialEvent(Serial myPort) {
// - String inString = myPort.readStringUntil('\n');
int sensorValue = 0;
if (inString != null) {
// M :
inString = trim(inString);
// $ int
R:
sensorValue = int(inString);
// println(sensorValue); %
! .
}
// * " "
if (sensorValue > threshold ) {
//
>
if (lastSensorValue <= threshold) {
//
<
catOnMat - true; // # ,
//
println("7 ");
// %!
,
// #. :
uploadPicture();
sendMail();
}
} else {
// " "
if (lastSensorValue > threshold) {
catOnMat - false;
println("7 ");
}
}
// 9
:
lastSensorValue = sensorValue;
Избавляемся от проводов
с помощью Bluetooth
*
,
Bluetooth —
«7 % - »
2. 9
,
.
}
Глава 3
178
* , "
$
. *
" $
.
3 $
"
" $ .
; % " :
void sendMail() {
// % # $ $ HTTP GET
// R.
println(" R. ");
}
void uploadPicture() {
// % # $ $ HTTP POST
// $ $ :
println(" $ .");
}
" ,
% , ,
" $ .
4 % %
, %
. =
% , "
%" , ,
. * $
% ,
.
, %
,
, ,
, . /
% , , " $ .
' ,
,
" %
, . / , sendMail()
, ,
" . 2 uploadPicture().
= , $ .
Дорабатываем код
0 " $ , . =
$ , "
:
int
int
= draw()
currentTime (
% ):
void draw() {
// C
currentTime = hour() * 3600 + minute() * 60 + second();
}
int
int
int
currentTime = 0;
lastMailTime = 0;
//
//
//
mailInterval = 60;
//
//
lastUploadTime = 0; //
uploadInterval = 120; //
//
!
!
Более сложная сеть
179
;
uploadImage()
" (
% ):
sendMail()
, $
" " —
serialEvent().
mailInterval uploadInterval
" $
-
. 2
% : %
% , . & %
" ,
.
void sendMail() {
// ,
// #. :
int timeDifference = currentTime - lastMailTime;
if ( timeDifference > mailInterval) {
println(" R. ");
// 9
#.
// :
lastMailTime = currentTime;
}
}
void uploadPicture() {
// ,
//
int timeDifference = currentTime - lastUploadTime;
if (timeDifference > uploadInterval) {
println(" $ .");
// 9
lastUploadTime = currentTime;
}
}
:
2
,
. +
, " $ .
Отправка сообщений от кота
%
Processing, node.js, ,
$ ,
express.js 1. /
" $ GET.
?
crypto — % % $ ;
*%
?
filesystem —
;
?
nodemailer — " $ ;
?
express —
.
?
?
?
:
" $
HTTP GET;
,
Processing ( $
);
= , ,
$ . & ,
:
HTML
.
-
-
-
Глава 3
180
$,
— multer.
#
catServer,
catServer.js.
—
* $ $ ,
. = $ % "
% ,
%
info.txt
catServer.
Планируем сценарий сервера
* , $ ,
%
. ,
,
1. & :
cat server
: node.js
// ' :
// crypto, filesystem, express, multer, nodemailer
=
%,
:
//
//
//
//
//
//
//
//
//
//
2
" :
// % #
$
// - GET
// - POST $ $
* , ,
,
" :
// %
%
//
// - $
% :
- %
- $ % $ %
:
- $ - %
- -
- $ - %
- % , $- $ $
:
- $
-
Задаем конфигурационные параметры
#
node.js.
:
// ' :
var crypto = require('crypto');
// % / %
var fs = require('fs');
// %
var express = require('express');
// -
var nodemailer = require('nodemailer');
//
:
Более сложная сеть
181
2
% —
, $
encrypt.js decrypt.js:
//
$ ' % %
// :
var key = process.argv[3];
// Z % - # :
var fileName =__dirname + "/info.txt";
// Z$ %:
var decipher = crypto.createDecipher('aes-256-cbc', key);
= ,
express
, HTML, —
, $
checkAge.js:
// Z$ ' express
// - - % :
var server = express();
serve r.use('/',express.static( 'public'));
2 , ,
nodemailer. + — $
:
//
' $ R :
var account = {
Замените на адрес своего
host: 'smtp.gmail.com',
почтового сервера
port: 465,
secure: true,
$
// SSL
// $
// $ -
auth: {
user: process.argv[2], //
//
pass: '' // %
}
$
$
$
};
// R. :
var message = {
Замените на свой
from: account.auth.user,
адрес
эл. почты
to: 'cat.owner@example.com',
subject: ' ',
text: ' ! http://www.example.com/catcam.html'
};
0
, .
" GET /
mail, " $ .
#
%
node.js. #
,
// # $ $
//
R. :
function sendMail(request, response) {
// # $
//
% :
function confirmMail(error, info) {
if(error){ console.log(error);
response.end("- .
$
.");
} else {
response.send("Z : " + message.to);
}
}
Глава 3
182
" . [
confirmMail() sendMail().
& Processing
(
Java) Arduino (
#), JavaScript :
// Z$
:
var mailClient = nodemailer.createTransport(account);
var responseString = mailClient.sendMail(message,
confirmMail);
}
=
% . /,
, ,
decrypt.js. 9 % ,
account.auth.pass
nodemailer:
// # $ % $ % :
function decryptFile(error, data) {
//
$ % ,
// % :
if (data){
var content = data.toString();
var decryptedPassword = decipher.update(content,
'hex', 'utf8');
decryptedPassword += decipher.final('utf8');
account.auth.pass = decryptedPassword;
// $ , R :
} else if (error) {
console.log(error);
}
}
// Z $ % :
fs. readFile(fileName, decryptFile);
console.log("M " + account.auth.user + "
.");
* ,
, % ,
:
#
.
,
// :
server.listen(8080);
server.get('/mail', sendMail);
console.log(" ' - .");
, , 2
" :
X ,
:
-
$ node catServer.js __
@_ _.com
2
$ npm install crypto express nodemailer
_ _$@
_ _ .com '
= node ,
. +
, , $ npm.
$ ,
% .
"
" :
Более сложная сеть
183
M __
@_ _.com
.
' - .
;
:
.
&
" ,
" $ .
". &
"
" :
http://localhost:8080
From: _ _$@_
_ .com
To: _ _$@_
_ .com
Subject:
Date: Wed, 27 Apr 2016 23:30:42 +0000
! http://www.example.
com/catcam.html
X % ,
" $
%
, Processing,
POST.
& Processing
, loadStrings() HTTP GET.
/ Processing - .
+ POST
. 7
,
$ , . 3
"
sendMail()
Processing,
.
Модифицируем скетч
= "
Processing
"
(
% ).
/*
$
: Processing */
// ... ' ' ...
int uploadlnterval = 120; // & .
// $ $
String serverAddress = "localhost";
int port = 8080;
String mailRoute = "/mail";
// ... % #
setup(), draw()
serialEvent()', ...
2 println() void sendMail() {
sendMail() , // % # $ $ HTTP GET
// R.
" // + ,
% . /
// $ R. :
URL
int timeDifference = currentTime - lastMailTime;
serverAddress,
if ( timeDifference > maillnterval) {
port mailRoute, String mailUrl = "http://" + serverAddress + ":" +
" loadStrings() port + mailRoute;
String[] response = loadStrings(mailUrl);
HTTP GET
println("K :");
$ .
printArray(response);
$
// Z- R. '
. [ load// -:
Strings() "
lastMailTime = currentTime;
—
}
:
}
Глава 3
184
# - (
catServer.js), Processing
,
" ,
.
; Processing %
,
" Processing "
" :
* %
"
" . ! &
% ". %
. ;
-
-
.
$
$ :
Z : _ _
$@_ _ .com
Создание веб-страницы для размещения снимков с веб-камеры
* - "
,
. *%
, " public
.
_ HTML- , " $ ,
,
" :
http://localhost:8080/
Рис. 3.13. Страница сетевого кота в браузере
_%
# , " - catServer.js, public.
#
,
catcam.jpg $ public. 2
:
http://localhost:8080/catcam.jpg
#
( . 3.13). ; - , $ .
Более сложная сеть
185
Создаем веб-страницу
# index.html
public " :
JavaScript update(),
$ - : (img)
(div).
2
setInterval(), update()
.
; ,
. &
, $
JavaScript $ img div ,
.
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
// # $
//
#:
function update() {
// '
:
var now = new Date();
// R #: $
//
$:
var timeLabel = document.getElementById('timeLabel');
var catPic = document.getElementById('catPic');
// $ $ URL, $
// , $
// #:
catPic.src= "/catcam.jpg?" + now;
// $:
timeLabel.innerHTML = now;
}
// $
$ % #
// '
:
setInterval(update, 60000);
</script>
<title>CatCam!</title>
</head>
<body align=center> <h1>CatCam!</h1>
<img src="/catcam.jpg" id="catPic">
<div id="timeLabel"></div>
</body>
</html>
Загрузка файлов на веб-сервер с помощью node.js
* " %
. 2 "
HTML HTML POST.
% (middleware)
, "
( % : application/x-www-form-urlencoded)
" %
$
request.body. , 0, ,
, "
request.file.
% $ . >
,
,
multer. X $ "
:
$ npm install multer
;
.
Глава 3
186
Пишем код для загрузки снимков
= " " require catServer.js " (
% ):
/*
cat server
context: node.js
*/
// ...
' ' ...
var nodemailer = require('nodemailer'); //
var multer = require('multer'); // ! $N
//
2
"
0
multer.
imgStore
,
,
.
var server = express();
server.use('/' ,express.static('public'));
upload $ multer, , server
$
express.
.
, Processing:
:
// !
var imgStore = multer.diskStorage({
destination: dirname + '/public/', //
//
filename: saveUpload //
//
});
//
! multer,
//
:
var upload = multer({storage: imgStore});
//
: "image"
// ( !
! ! ):
var type = upload.single('image');
;
saveUpload(),
imgStore. 9
$
sendMail(). ; ,
, — destination —
imgStore,
,
.
// % # $ $ $ $ % :
function saveUpload(request, file, save) {
// $ % # multer, - % :
save(null, file.originalname);
}
4"
, . = $
server.
post()
server.get() :
server.get(7mail', sendMail); //
// R.
server.post('/upload', type, getUpload); // !
//
console.log(" ' $ - .");
Более сложная сеть
187
* ,
$ . 9 $ sendMail():
// Q
// :
function getUpload(request, response) {
//
# :
var fileInfo = JSON.stringify(request.file);
console.log(fileInfo);
response.end( fileInfo + '\n');
}
; %
. * "
. * , curl,
$ . 2
" curl " " :
$ curl -F image=@path/to/catcam.jpg 'http://localhost:8080/upload'
& $ path/to/catcam.jpg , URL-
. 2
JPEG-
,
index.html,
. *
.
Анатомия составного запроса POST
[ HTML,
POST
:
HTTP ,
: multipart/form-data,
, . & $ ,
- . 9 HTTP
, Здесь определяется boundary (разделитель). Им может быть любая строка,
лишь бы она была уникальной. Такой разделитель предшествует каждой части
POST /upload HTTP/1.1
Host: www.example.com:8080
Content-Type: multipart/form-data; boundary=----H4rkNrF
Content-Length: 40679
------H4rkNrF
Content-Disposition: form-data; name="submit"
Значение для этой части. При загрузке посредUpload
ством формы это будет вывод кнопки Submit формы
------H4rkNrF
Content-Disposition: form-data; name="image"; filename-"catcam.jpg"
Content-Type: image/jpeg
Content-Disposition — заголовок, определяющий эту
часть. Для файлов также содержит локальный путь к файлу
[$ ' $ % ]
Финальный разделитель с двумя дополнительными дефисами
------H4rkNrF--
Глава 3
188
Захват и загрузка изображений с помощью Processing
; ,
,
,
$
. 9
- " , — —
. + ,
$ "
Processing,
% : video ( ) net ( ). > ,
Processing 3.0,
$ .
Захват изображения
= .
4 %
"
, % - ,
USB. 0 ,
% -
. * % macOS
Photo
Booth, Windows 10 — Camera,
Ubuntu Linux % Cheese. 4 %
, ,
Processing .
' video Processing, Contribution Manager, $
Sketch | Import Library | Add Library.
& Filter video,
Video The Processing
Foundation ( : Author) Install. X
,
+
. % Contribution Manager,
— . ; %
-
.
Пишем код для проверки вывода видео с камеры
9 video
Serial. ; ,
Serial, video
$ :
#
" Capture.list().
=
$ Capture — , $ ,
Serial:
/*
-
: Processing */
import processing.video.*; // \
Capture myCam; //
void setup() {
size(400, 30020); // $
// '- '
String[] devices = Capture.list();
video
printArray(Capture.list());
// \$ '
myCam = new Capture(this, width, height, devices[0]);
myCam.start();
}
20
/ %
% , Processing
"
" % . & % 800×600 640×480.
Более сложная сеть
189
=
image().
— myCam —
.
3
"
:
void draw() {
// +
image(myCam, 0, 0);
}
,
$
captureEvent(). +
"
myCam.read():
// R - ,
// :
void captureEvent(Capture MyCam) {
myCam.read();
}
$-
R
# $
Camera . &
.
Пишем код захвата кадров
; , , video, % .
#
video
(
% ).
3 —
:
= setup() " 21:
21
X %
(400×300)
% , Processing "
"
% . & % 800×600 640×480.
/*
$
: Processing
*/
// \
import processing.serial.*;
import processing.video.*;
// ... ' $ $ .
Capture myCam;
// $
String fileName = "catcam.jpg"; //
//
void setup() {
size(400, 300); // %
// `
// Processing
// ,
String[] devices = Capture.list();
printArray(devices);
// %
0 devices[0] :
myCam = new Capture(this, width, height, devices[0]);
myCam.start();
setup()
...
// ... % #
}
Глава 3
190
& draw()
:
void draw() {
// :
currentTime = hour() * 3600 + minute() * 60 + second();
// !
image(myCam, 0, 0);
}
= captureEvent() :
// # ,
// :
void captureEvent(Capture MyCam) {
myCam.read();
}
& uploadPicture()
println("
void uploadPicture() {
// + ,
// $ $ $
int timeDifference = currentTime - lastUploadTime;
if (timeDifference > uploadInterval) {
PImage img = get();
img.save(fileName);
// Z- $ $ ' :
lastUploadTime = currentTime;
}
}
$
"
:
");
#
.
, " % %
, uploadPicture()
catCam.jpg
. 0 $ .
0 uploadPicture()
"
uploadInterval. & $
120 ( ). 4 ,
uploadInterval. *
% — .
Ставим метку времени на снимки
>
,
,
.
/ , " ( % )
draw()
image():
, . 3.14.
image(myCam, 0, 0);
// Q
: ~~::99 --:
String timeStamp = nf(hour(), 2) + ":" + nf(minute(), 2)
+ ":" + nf(second(), 2) + " " + nf(day(), 2) + "-"
+ nf(month(), 2) + "-" + nf(year(), 4);
//
,
//
1 :
fill(15);
text(timeStamp, 11, height - 19);
//
:
fill(255);
text(timeStamp, 10, height - 20);
}
Более сложная сеть
191
Рис. 3.14. Вывод изображения кота с меткой времени
* " %
,
HTTP
POST. + $ Processing —
,
$
loadStrings(). # net
, % ,
POST,
. #
$
,
! «G ! POST», —
,
- . * %
$ — ,
" :
POST /upload HTTP/1.1
Host: localhost:8080
Content-Length: 19006
Content-Type: multipart/form-data; boundary=H4rkNrF
--H4rkNrF
Content-Disposition: form-data; name="image";
filename-"catcam.jpg"
Content-Type: image/jpeg
['
----H4rkNrF--
% ]
Глава 3
192
Пишем запрос POST
=
, " . ,
, .
; ,
,
".
// \
import processing.serial.*;
import processing.video.*;
import processing.net.*;
// ...
Client
String
String
' $ $ ...
thisClient; //
uploadRoute = "/upload"; //
boundary = "H4rkNrF"; // 9
// POST
&
net
,
:
;
POST. = $
,
new Client
:
void postFile() {
// %!
! :
byte[] thisFile =loadBytes(fileName);
// N
:
thisClient = new Client(this, serverAddress, port);
3 . #
:
String request = "";
// N
POST HTTP:
request += "POST " + uploadRoute + " HTTP/1.1\r\n";
request += "Host: " + serverAddress + ":" + port + "\r\n";
2
. / ,
: ContentType:
// Q
:
String boundaryHeader = "--" + boundary + "\r\n";
boundaryHeader +="Content-Disposition: form-data;
name=\"image\"; ";
boundaryHeader += "filename=\"" + fileName + "\"\r\n";
boundaryHeader +="Content-Type: image/jpeg\r\n\r\n";
$
:
// Q
:
String boundaryTail ="\r\n--" + boundary + "--\r\n";
; $
,
. = $ ,
, % :
// $
,
// , boundaryTail:
int contentLength = boundaryHeader.length()
+ thisFile.length + boundaryTail.length();
request += "Content-Length: " + contentLength + "\r\n";
// 9
, POST
//
,
// - # :
request += "Content-Type: multipart/form-data; boundary=";
request += boundary + "\r\n\r\n";
Более сложная сеть
193
// N
, boundaryHeader,
// boundaryTail:
thisClient.write(request);
thisClient.write(boundaryHeader);
thisClient.write(thisFile);
thisClient.write(boundaryTail);
* , ,
,
" thisClient.write():
}
2 $
uploadPicture() (
% ):
void uploadPicture() {
// % # $ $ HTTP POST
// $ $ :
// + ,
// $ $ $
int timeDifference = currentTime - lastUploadTime;
if (timeDifference > uploadlnterval) {
PImage img = get();
img.save(fileName);
postFile();
// Z- $ $ ' :
lastUploadTime = currentTime;
}
}
'
, "
draw()
,
. 4 thisClient
- , $
$
:
text(timeStamp, 10, height - 20);
* ,
,
. * ,
,
uploadPicture(), " ,
. =
$
draw():
// * !
!
if (catOnMat == true) {
//
uploadPicture();
}
}
// POST,
// # :
if (thisClient != null) {
String result = "";
while (thisClient.available() > 0) {
result += char(thisClient.read());
}
if (result != "") println(result);
}
,
Глава 3
194
Тестируем всю систему
'
, - ,
.
-
,
" $ .
"
" .
-
.
(
)
,
- .
,
, -
"
. & Processing " , %
. ,
- ,
.
+
,
,
,
( ) . 7
,
. 0 , . 7
,
, —
"
.
* %"
%
IP- .
$
"
Размещаем сервер на ресурсе с общедоступным IP-адресом
*% Processing -
node.js "
, ,
localhost.
+
, ,
,
. . 3.7, -
+
. ;
"
IP- ,
" +
.
7 " - %
- ,
%
node.
js
.
1, %
% - — $
,
, . * , Amazon Web Services EC2
Elastic Beanstalk, node.js,
Python, Ruby on Rails . 3 Digital
Ocean
22
droplet
% ,
.
" ,
$ node.js.
Установка сценариев на сервер
node.js,
node.js
,
22
= — .
.
Более сложная сеть
* ,
catServer.js,
$ ,
$ . 2 ,
$ , :
$ npm install crypto express nodemailer
,
,
, .
195
Подключение к общедоступному
серверу
% "
, , ,
IP-
$
. *
— — serverAddress Processing
, % . ,
- ,
:
http://server.address:8080
server.address
- .
%
Управление библиотеками node.js
с помощью файла package.json
node.js
, ,
, "
. ;
. #
"
npm. , $ :
package.
(
) ,
:
json. 2
$ npm install
=
$
-
package.json
$ npm init
& ,
npm
package.json,
. [
, ,
(
node_modules). ; ,
,
.
=
$ ,
node.js,
" package.json, "
:
www.github.com/tigoe/MakingThingsTalk2/tree/
master/3rd_edition.
Использование программы forever
X - node.js, " forever, "
node.js. X npm , , —
" ( Windows sudo):
$ sudo npm install -g forever
Глава 3
196
# " forever
" :
$ forever start catServer.js
&
$
:
warn: --minUptime not set. Defaulting to: 1000ms
(+ minUptime $.
' 1000 )
warn: --spinSleepTime not set. Your script will exit if it does not stay up for at least 1000ms
(+ spinSleepTime the $. \ # ,
1000 )
info: Forever processing file: catServer.js
(Forever % : catServer.js)
%
, . ' forever
, :
$forever list
0 " :
info: Forever processes running
(\' # Forever)
data:
uid command
script forever pid id logfile
uptime
data: [0] kEH1 /usr/local/bin/node catServer.js 1803 1808 /home/username/.forever/kEH1.log 0:0:2:7.956
= "
, , :
. ' -
$ forever stop n
n
,
.
forever , $
. " " " :
-
$ forever logs
&
:
info: Logs for running Forever processes
data: script logfile
data: [0] catServer.js /home/username/.forever/9QCs.log
[ " less, tail, head
,
1. * , " :
$ tail -10 home/username/.forever/9QCs.log
" .
>
%
- %
, -
(
)
. / % —
" .
Более сложная сеть
197
Завершающие штрихи
> ,
-
%
node.
js, Processing
" -
. & % -
. & %
,
+
. ;
+
( . 3.15).
Рис. 3.15. Завершенный проект «ложа» для кота: кот на своей
подстилке (вверху слева); часть панели датчиков, которая находится под подстилкой, и бамбуковый ящичек для ювелирных украшений, оформленный под стиль остальной мебели,
с размещенными в нем электронными компонентами (справа внизу). Кабель USB подсоединен к компьютеру (компьютеры проекта здесь не показаны). В обязательном порядке
основательно обезопасьте все провода, чтобы кот, ласкаясь
об электронику, случайно их не погрыз (внизу слева)
Глава 3
198
4
% , " ,
node.js, " % - .
/
+
.
& , ,
% ($, , ), "
"
.& "
:
"
+
, ? & , +
" , , +
,
, $ .
Заключение
Полагаю, что прочитав эту главу, вы лучше поняли организационную структуру Интернета
и принципы работы сетевых приложений.
+
, , — $ , "
. =
" ,
,
% +
.
" , ,
$ "
. =
.
$ , "
telnet, -
" . 7
, " $ ,
«# ». ; , , " ,
, — " +
"
Ethernet .
Глава 4
«ГЛЯНЬ, МАМА,
ЗДЕСЬ НЕТ КОМПЬЮТЕРА!»
МИКРОКОНТРОЛЛЕРЫ
В ИНТЕРНЕТЕ
Первая мысль, которая приходит многим людям в голову после
создания проекта наподобие подключенного к Сети места отдыха
для кота из главы 3, — Замечательно! А как бы вообще обойтись
без компьютера? Подключать к настольному компьютеру или даже
к ноутбуку микроконтроллер лишь для того, чтобы он мог получить
доступ в Интернет… В конце концов, как мы видели в той же главе 3,
протоколы управления связью в Интернете — это всего лишь
текстовые строки, а микроконтроллеры могут обмениваться
короткими текстовыми сообщениями без каких бы то ни было
проблем. Использование микроконтроллеров совместно
с периферийными модулями, которые могут подключаться к Сети,
придаст и им эту полезную способность. В этой главе мы узнаем,
как подключить микроконтроллер к Интернету с помощью
периферийного устройства беспроводной связи Wi-Fi.
Необычные проекты
X YBox (http://uncommonprojects.com/site/play/ybox-2) RSS-
% , $ Ethernet-
XPort Propeller. 0 ! Uncommon Projects.
Глава 4
202
Компоненты для проектов этой главы
Коды поставщиков
?
A — Arduino Store, http://store.arduino.cc
?
J — Jameco, http://jameco.com
?
AF — Adafruit, http://adafruit.com
?
RS — RS, www.rs-online.com
?
D — Digi-Key, www.digikey.com
?
SF — SparkFun, www.sparkfun.com
?
F — Farnell, www.farnell.com
?
SS — Seeed Studio, www.seeedstudio.com
Рис. 4.1. Новые компоненты для проектов этой главы: 1. Микроконтроллер с возможностями Wi-Fi. Слева направо показаны
платы Arduino MKR1000, SparkFun ESP8266 Thing и Adafruit Feather Huzzah! ESP8266. 2. Фотодатчики. 3. Красный, зеленый и синий светофильтры. 4. Вольтметр. В принципе подойдет любой, но для лучшего эффекта желательно найти вольтметр как можно
более «антикварного» вида
2
1
3
4
ПРОЕКТ 6. Привет, Интернет! Веб-сервер цвета дня
Arduino- MKR1000, 1 +.
AF: 3156, RS: 124-0657, A: ABX00004, GBX00011
(3 4#), D: 1659-1005-ND
&
ESP8266.
SF: WRL-13231, AF: 2471
N >
Wi-Fi, 1 +. 4
+
Wi-Fi, $
. 0
.
Wi-Fi
(
10 , 3 +.
J: 29082, SF: C0M-09939, F: 350072, RS: 249-9294
«Глянь, мама, здесь нет компьютера!» Микроконтроллеры в Интернете
\
), 3 +.
(
-
D: PDV-P9200-ND, J: 202403, SF: SEN-09088, F:
7482280
C , 1 +.
D: 438-1045-ND, J: 20723 20601, SF: PRT12615 PRT-12002, F: 4692810, AF: 64, SS:
319030002 319030001
203
D& , 3 +.:
,
. + .
> .
]= =
. " .
ПРОЕКТ 7. Сетевой измеритель качества воздуха
Arduino- MKR1000, 1 +.
AF: 3156, RS: 124-0657, A: ABX00004, GBX00011
(3 4#), D: 1659-1005-ND
&
ESP8266.
SF: WRL-13231, AF: 2471
N >
Wi-Fi, 1 +. 4
+
Wi-Fi, $
. 0
Wi-Fi
.
C , 1 +.
D: 438-1045-ND, J: 20723 20601, SF: PRT12615 PRT-12002, F: 4692810, AF: 64, SS:
319030002 319030001
' , 1 +.
% %
. & ,
0–5 & $.
SF: TOL-10285, F: 1015878, RS: 244.890
D , 1 +.
D: 160-1144-ND 160-1665-ND, J: 34761
94511, F: 1855510, RS: 228-5972 826-830, SF:
COM- 09592 COM-09590
( 220 , 1 +.
D: 220QBK-ND, J: 690700, F: 9339299, R: 7077612
> .
]= =
. " .
Введение в сетевые модули
В течение последних нескольких лет на рынке появилась линейка коммерческих устройств,
способных выходить в Интернет без участия персонального компьютера. Такую способность им
придают встроенные микроконтроллеры — подобные рассмотренным в этой книге ранее — обладающие возможностью устанавливать связь по сети Ethernet или по беспроводному каналу
Wi-Fi. Простейшие из них могут обрабатывать одну транзакцию за раз, запрашивая информацию
у сервера, а затем ожидая ответа, или отправляя простое сообщение в ответ на какое-либо событие. Эти устройства обычно играют роль клиента удаленного сервера, но некоторые из них
также могут функционировать и в качестве сервера локальной сети.
D-Link, Sony, Axis
, "
, — Ethernet,
Wi-Fi. Nest
, "
+
. Philips ,
%
. 3 Belkin
,
,
+
. & $
,
$ .
Глава 4
204
= , $
:
,
SMTP HTTP. / ,
,
, .
0
. *
. % , $
, ,
—
— %
. [ , $
, "
Wi-Fi
Ethernet. ;
Bluetooth,
2,
. & "
$ %
Ethernet,
Ethernet — ,
Wi-Fi, — , Wi-Fi ,
Wi-Fi .
Сравниваем два модуля Wi-Fi
7 Wi-Fi
,
Arduino. & $ " : Wi-Fi
WINC1500 Atmel ESP8266
Espressif,
1. 7 WINC1500 MKR1000, % Arduino WiFi101
Feather M0 WiFi WIN1500
Adafruit. 3 ESP8266
Huzzah! ESP8266 Adafruit,
Thing SparkFun . Thing Dev SparkFun,
MKR1000 Feather Huzzah! ESP8266
Adafruit
. 4.2.
Рис. 4.2. Оснащенные модулями Wi-Fi микроконтроллерные платы: Thing Dev компании SparkFun (слева), MKR1000 (в центре)
и Feather Huzzah! ESP8266 компании Adafruit (справа). Для проектов этой книги, использующих беспроводной канал Wi-Fi,
можно взять любую из них, так же как и плату Feather Huzzah! WINC1500. Плата MKR1000 имеет большее количество контактов ввода/вывода общего назначения и аналогового ввода. Платы MKR1000 и Feather оснащены встроенными зарядными
устройствами
Off
D0
RESET
On
RX
TX
D5
Pwr
3.3V
NC
GND
GND
GND
3.3V
Vin
A0
D2
D5
D14
D0
RESET
D4
TX
D13
RX
D12
5V
D16
NC
A0
GND
D15
Antenna
VBat
NC
En
NC
VUSB
NC
D14
NC
D12
NC
D13
SCK
D15
MOSI
D0
MISO
D16
RX
D2
TX
SCL
CHPD
D2
SDA
«Глянь, мама, здесь нет компьютера!» Микроконтроллеры в Интернете
+ $ : ESP8266 WINC1500 —
WINC1500,
% ,
, "
.
WINC1500
TCP/IP,
. 0 :
MKR1000 Feather M0 c WINC1500 — "
Cortex M0 Atmel,
Wi-Fi SPI.
3 ESP8266
Wi-Fi « ». 0
(0#9&),
, ,
Arduino. * $ % /
" , MKR1000
Feather M0 c WINC1500.
7 ESP8266
USB-Serial,
TTL- . 0 ESP8266 Thing
Dev SparkFun " USB/Serial FTDI, Feather
ESP8266 Huzzah! Adafruit — USB/Serial Silicon Labs, $
$ "
,
$ !. «4 ! USB/
Serial» 2.
,
ESP8266 Thing ESP8266 Thing Dev
% ,
Feather ESP8266
Huzzah!, $ $ %
.
SparkFun %
ESP8266 —
: https://learn.sparkfun.com/tutorials/
esp8266-thing-hookup-guide/installing-theesp8266-arduino-addon.
205
$
MKR1000, "
WINC1500,
. = $
Arduino IDE , "
"
.
> WiFi101 WINC1500 ESP8266WiFi
Arduino %
. / ,
MKR100 ESP8266 . & ,
$
, — $ .
# ,
ESP8266
, . ;
, , ,
/ " ESP8266
MRK1000.
0 ,
802.11n ( 5 qq)
API-
.
Глава 4
206
Проект 6
Привет, Интернет!
Из предыдущей главы мы узнали, что сетевые устройства могут работать как клиент или как
сервер. В этом проекте мы на основе Arduino-совместимого микроконтроллера создадим очень
простой веб-сервер, предоставляющий веб-страницу, чей фон меняется в соответствии с цветом,
освещающим подключенные к микроконтроллеру датчики.
Требуемые компоненты
#
Arduino ,
"
Wi-Fi,
1 %., — MKR1000
ESP8266.
+
: Wi-Fi,
, X3 (UART).
X +
Wi-Fi, 1 %.
9
10 0, 3 %.
[ (
), 3 %.
-
> , 1 %.
#
.
, 3 %.:
,
Установка соединения
$ ,
,
Arduino IDE
.
, MKR1000
| , ,
" 1.
2 , D | > WiFi101. 4 ,
" 2
D | > | N
. =
ESP8266 \ | ]
]
1
MKR1000 Arduino SAMD Boards.
2
' $ , " % Arduino, % — Wi-Fi 101.
!
" A
$
http://arduino.esp8266.
com/stable/package_esp8266com_index.json.
2 " A esp8266 by ESP Community.
/ SparkFun, Adafruit.
= "
,
:
,
. /
. *
—
" . & $
.
MKR1000 . 4.3.
Как работает библиотека WiFi101?
,
WiFi101 Arduino
( $
ESP8266 WiFi). > WiFi101
WINC1500 , ,
. 7
$ : Server Client.
,
, " -
+
, Wi-Fi. 3
, -
«Глянь, мама, здесь нет компьютера!» Микроконтроллеры в Интернете
$ .
,
,
: read(), write(), print()
println() Stream,
Serial,
Client Server. Client, , connect()
, connected()
stop() . 7
$ —
. 0
% ,
. > ESP8266 WiFi, $ Stream, $
.
0
,
% Wi-Fi
+
. & ,
% Wi-Fi ( , % % ) —
(SSID)3, % . ,
MAC-
% Wi-Fi, $
% . 4 % %
MAC- ,
MAC-
%
%
MAC-
% . =
$
% ,
. X MAC-
" ,
, !. «& ».
4
Wi-Fi
/ MAC-
, " 3
SSID, Service Set Identifier —
[
] [ ] .
A B
C D E
207
F
G H
I
J
1
1
5
5
10
10
15
15
20
20
25
25
30
Красный
светофильтр
Зеленый
светофильтр
Синий
светофильтр
30
A B
C D E
F
G H
I
J
Фотосопротивление 200 кОм
10 кОм
Фотосопротивление
200 кОм
3,3 В
Модуль
микроконтроллера
Analog 0
Analog 1
Analog 2
10 кОм
Фотосопротивление
200 кОм
Общий
10 кОм
Рис. 4.3. Монтажная (вверху) и принципиальная (внизу) схемы
подключения RGB-сервера к модулю MKR1000. Обратите внимание на три цветных светофильтра, установленные на фотодатчиках
Глава 4
208
. = $
scanNetwork()
WiFi101. / %
, MAC !. «& » — $ MAC-
%
Wi-Fi, .
,
$. # ,
%
(SSID)
, .
% Wi-Fi
,
. & $ -
Библиотека Stream для Arduino
Arduino,
, Serial, SPI, I2C Wi-Fi Client Server, ,
. / Stream,
,
(stream)
.
& 1
, , % % ,
. 2
( , Serial.write())
,
( , Serial.read())
.
> Stream read(), write(),
available(), print() println(),
. &
, Stream.
> Stream TextFinder 7 7 (Michael
Margolis),
. & , readString()
string.
3 readBytesUntil()
,
, — : readByteUntil('\n’). [
readStringUntil() ,
" string. > Stream
.
[ find() findUntil()
,
parseInt() parseFloat()
" " . / , HTTP. [
Stream $ . = Stream
www.arduino.cc/en/Reference/
HomePage.
Сканируем адреса
= %
Wi-Fi SPI
WiFi101. 2 ,
$ .
= ESP8266
WiFi101.h
ESP8266WiFi.h:
/*
Z
: Arduino
WINC1500
*/
#include <SPI.h>
#include <WiFi101.h>
void setup() {
Serial.begin(9600); // \ # $ ' $
}
«Глянь, мама, здесь нет компьютера!» Микроконтроллеры в Интернете
209
& loop()
:
$ 73#- % , —
.
* % , $
$ :
void loop() {
printMacAddress(); // +
R &Z-
Wi-Fi
listNetworks(); // Z Wi-Fi
delay(10000); // '
$ 10
' MAC-
Wi-Fi,
WiFi.macAddress(),
"
6 .
MAC-
$
printMacAddress()
( ESP8266WiFi " MAC- , $
0 5
5 0):
void printMacAddress() {
Serial.print("MAC-: ");
byte mac[6]; // & - MAC-
WiFi.macAddress(mac); // MAC-
for (int i = 5; i > 0; i--) { // # 5 1
if (mac[i] < 0x10) { // ,
// 1 # # %,
Serial.print("0");
//
}
Serial.print(mac[i], HEX); // +
R
// '
MAC-
Serial.print(":"); // R $
}
Serial.println(mac[0], HEX); //
R
// MAC-
}
[ WiFi.scanNetworks()
"
,
,
% :
void listNetworks() {
Serial.print("+ - :");
int numSsid = WiFi.scanNetworks();
if (numSsid == -1) {
Serial.println("^ ' Wi-Fi");
return; // +$ #
}
[
WiFi.encryptionType() " , " % :
// +
- - :
Serial.println(numSsid);
// +
:
for (int thisNet = 0; thisNet < numSsid; thisNet++) {
String message = WiFi.SSID(thisNet);
message += "\tM : ";
message += WiFi.RSSI(thisNet);
message += " dBm \t % :";
message += WiFi.encryptionType(thisNet);
Serial.println(message);
}
Serial.println();
}
1.
2.
3.
4.
5.
WEP
WPA
WPA2
*
3
> ESP8266WiFi " : 1 — %
0 — %
:
Глава 4
210
Планируем сценарий веб-сервера
#
- , ,
" :
/*
+-
: Arduino
?
?
?
;
;
HTTP.
%
$ ,
. =
- :
"
, HTTP-
.
$
. 0
, , HTTP,
:
*/
//
'
WINC1500
" % #
void setup() {
// \ # $ ' $
// ' Wi-Fi,
// '
//
' , $
//
R
}
void loop() {
// '
// ',
//
- ,
//
- $ $
//
' R.
//
((\n \r\n)
//
HTTP
//
,
//
',
//
' .
}
HTTP/1.1 200 OK
*%
.
*, " ,
$
. #
%
% $ — $
,
#include. = $ "
,
( . 4.4, ), New Tab (* ). 2
( . 4.4, !) — , config.h. & $
$ . # " $
Рис. 4.4. Создание новой вкладки в среде разработки Arduino (вверху) и присвоение ей имени (внизу)
«Глянь, мама, здесь нет компьютера!» Микроконтроллеры в Интернете
,
#include "config.h" .
# ,
" ,
SSID %
:
ssid
char ssid[] = "ssid"; // \ (SSID)
// Wi-Fi
char password[] = " "; //
// -
211
; " ,
%
%
. *
$
config.h.
&
% " — config.h —
Arduino.
Пишем код веб-сервера
+,
%
- .
&
% config.h. ;
$
. # 80,
- :
& setup() Wi-Fi
,
,
,
. >
WiFi101
% : WEP4 WPA/WPA25,
. ; % WiFi.begin(). =
WPA WPA2 $ " : WiFi.
begin(ssid, ); ( ). 4 %
" ,
. ; %
WEP
:
4
WEP, Wired Equivalent Privacy — , " .
5
WPA, WiFi Protected Access — ""
Wi-Fi.
/*
+-
: Arduino
WINC1500
*/
#include <SPI.h>
#include <WiFi101.h>
#include "config.h" // ssid[]
WiFiServer server(80); // Z$
password[]
R$
void setup() {
Serial.begin(9600);// \ # $ ' $
// ' Wi-Fi,
while ( WiFi.status() != WL_CONNECTED) {
Serial.print(" ' : ");
Serial.println(ssid);
WiFi.begin(ssid, ); // '
delay(2000); // $ 2
// '
}
Глава 4
212
& ,
$ IP-
,
,
:
server.begin(); //
' , $
//
R IP-
Serial.print(" - - % R
: http://");
IPAddress ip = WiFi.localIP();
Serial.println(ip);
}
&
.
HTTP-
:
void loop() {
// '
WiFiClient client = server.available();
while (client.connected()) { // ',
if (client.available()) { // - ,
// - $ $
String request = client.readStringUntil('\n');
Serial.println(request); //
'
// R.
, :
// ((\n \r\n)
if (request.length() <= 2) {
client.println("HTTP 200 OK\n"); //
// HTTP
delay(10); // ,
//
if (client.connected()) { //
// ',
client.stop();
// ' .
}
}
}
}
}
0
. 2
IP-
,
.
&
$ HTTP,
, %
. /
,
,
HTTP 3. ;
($
" curl):
GET / HTTP/1.1
Host: 192.168.43.184
User-Agent: curl/7.46.0
Accept: */*
>% HTTP
,
:
, , %
, , , % .
2 , %
,
GET/. & % "
,
,
$ — —
.
'
- , ,
" - HTML.
= , $ .
«Глянь, мама, здесь нет компьютера!» Микроконтроллеры в Интернете
213
Недостаток аналоговых вводов в платах ESP8266
& $ ,
WSP8266 .
Дорабатываем скетч веб-сервера
&
makeResponse(),
"
.
& HTTP, —
( \n\n ).
2
HTML:
String makeResponse() {
String result = "HTTP/1.1 200 OK\n"; // HTTP
result += "Content-Type: text/html\n\n"; //
//
# $
result += "<!doctype html>\n";
// HTML
result += "<html><head><title>"; // HTML, head title
result += " Arduino</title></head>"; // #
// $ HTML
result += "\n<body>\n"; // ^ HTML
& HTML $
MKR1000. =
%
analogChannel:
// +
$ :
for (int analogChannel = 0; analogChannel < 6;
analogChannel++) {
result += " ";
result += analogChannel;
result += " ";
result += analogRead(analogChannel);
result += "<br />\n";
}
* ,
" </body>
,
HTML
:
result += "</body></html>\n\n"; // #
//
return result;
}
-
</html>
%
& loop()
client.
println("HTTP 200 OK\n")
" (
% ):
&
,
,
Wi-Fi
.
if (request.length() <= 2) {
//client.println("HTTP 200 OK\n"); // HTTP
String response = makeResponse();
client.println(response);
delay(10); // ,
Глава 4
214
;
.
$ ,
"
, -
Arduino « "» . & makeResponse() HTML —
,
"
,
,
.
,
. *
,
$ ? = $ makeResponse()
, " </head>,
" (
% ),
:
*%
Arduino
, —
+
. *
, %
, . *, %
makeResponse(), %
- Arduino Wi-Fi. = , ",
$ .
result += " Arduino</title></head>"; // #
// $ HTML
result += "<meta http-equiv=\"refresh\" content=\"3\">";
;
.
&
.
& $ , %
, . = $
makeResponse() for
$
" (
% ).
*
" ,
% :
2 % %
" , , " .
result += "\n<body>\n"; // ^
// %
:
result += "<body bgcolor=#";
// 9
:
int red = analogRead(A0) / 4;
int green = analogRead(A1) / 4;
int blue = analogRead(A2) / 4;
// N!
// :
result += String(red, HEX);
result += String(green, HEX);
result += String(blue, HEX);
// %
:
result += ">";
// %
HTML- :
result += " Arduino #";
result += String(red, HEX);
result += String(green, HEX);
result += String( blue, HEX);
result += "</body></html>\n\n"; // #
//
return result;
}
«Глянь, мама, здесь нет компьютера!» Микроконтроллеры в Интернете
215
Предоставление доступа из Интернета к устройству
с частным IP-адресом
=
%
-
%
. 3
, , %
+
.
" "
, % % %
IP- ,
%
%
. ' $ ,
, %
% " " .
= $
% % $ Port forwarding
(
) Port mapping (0 ). +
% ,
$ . = 80, $
% , 80 %
Wi-Fi 8080 % (
% % "
). $
"
IP- % 8080
IP- WiFi 80.
Рис. 4.5. Настройки перенаправления портов маршрутизатора Apple AirPort Express
0 , %
. * ,
80,
% $
. $
— , 8080. ;
$
%
node.js 8080.
-
80,
,
:
http://www.myserver.com:8080/
; "
% Wi-Fi %
. * ,
IP-
% % 203.48.192.56,
-
http://203.48.192.56:8080.
&
% Apple
AirPort Express . 4.5,
% Linksys — . 4.6.
Будьте осторожны!
& , %
%
!
/ %
+
. & , % (, " . .),
$ .
Рис. 4.6. Настройки перенаправления портов беспроводного маршрутизатора Linksys
Глава 4
216
Приложение встроенного сетевого клиента
Теперь, когда наш сервер готов, пора создавать клиента. Это будет встроенный веб-клиент, запрашивающий данные у веб-сайта, отслеживающего качество воздуха, и выводящий эти данные
на физическое устройство — стрелочный индикатор, в роли которого выступит аналоговый
вольтметр.
Проект 7
Сетевой измеритель качества воздуха
Кроме вывода на веб-страницы, всевозможные данные могут отображаться многими иными способами. В наших домах, например, имеются часы, барометры и термометры, служащие в качестве
как информационных, так и декоративных устройств. Но чтобы физическое устройство могло
показывать нам полученные из Интернета данные, оно должно уметь подключаться к серверу,
запрашивать эти данные и преобразовывать их в цифровой ряд, управляющий устройством их
отображения.
& $ .
= $
- %
: . ` ,
%
$
%
. 7 ,
,
, ,
,
, % .
7
- ,
# " Wi-Fi.
2
,
,
" analogWrite()
, % (+7) $
.
7
- ,
HTML
( - ! 6), , , " % "
- " ,
6
0 . web-scraping.
Требуемые компоненты
#
Arduino ,
"
Wi-Fi, 1 %.:
• MKR1000;
• Arduino Uno-
% WiFi101;
•
ESP8266.
+
: Wi-Fi,
+7 (PWM), X3 (UART), /
" (GPIO).
X +
Wi-Fi, 1 %.
> , 1 %.
& , 1 %.
# , 1 %.
9
220 0, 1 %.
" %
,
HTML CSS. ;
API7.
AirNow — 3
-
"
7
API, Application Programming Interface —
.
«Глянь, мама, здесь нет компьютера!» Микроконтроллеры в Интернете
#3 (www.airnow.gov). * $
#3. C "
%
( , #3) ,
$
- .
217
Для жителей других стран
= , #3, - AirNow — Sonoma Technologies — % . 4 AirNow-I
$ ,
; 7 . =
www.sonomatech.com/project.cfm?uprojectid=1102
.
Управление вольтметром с помощью микроконтроллера
,
"
" .
7
,
,
. ' % %
,
%
. / - (+7)8.
' +7
, , " ,
, . * , +7
, , ,
8
0 . Pulse-Width Modulation (PWM).
, " "
" , 30 . 3
"
, $ %
+7.
,
— " , ,
+7 % .
* . 4.7 $ . ,
: — MKR1000, — % ,
4. / .
Скетч для проверки работоспособности вольтметра
# " ,
:
/*
\$ analogWrite() .
: Arduino WINC1500
*/
const int meterPin = 5; //
-
// ESP8266 $ # %
void setup() {
Serial.begin(9600);
}
void loop() {
//
// - :
Глава 4
218
for (int pwmValue = 0; pwmValue < 255; pwmValue ++) {
analogWrite(meterPin, pwmValue);
Serial.println(pwmValue);
delay(10);
}
delay(1000);
// Z $ '
$ :
analogWrite(meterPin, 0);
delay(1000);
}
A B
C D E
F
G H
I
J
1
1
5
5
10
10
15
15
20
20
25
25
30
30
A B
3,3 В
D6
Встроенный
светодиод
Модуль
микроконтроллера
Цифровой вывод 4
Цифровой вывод 5 (ШИМ)
Общий
Светодиод
V
Вольтметр
C D E
F
G H
I
J
Рис. 4.7. Монтажная (вверху) и принципиальная (внизу) схемы подключения вольтметра к микроконтроллерной плате MKR1000.
Встроенный светодиод подключен к цифровому выводу платы 6 (D6)
«Глянь, мама, здесь нет компьютера!» Микроконтроллеры в Интернете
=
pwmValue % . & ,
$
,
.
=
,
, 0–5 &,
$ "
,
MKR1000 3,3 &. * «
»
219
0–3 &,
$
pwmValue 230,
3 &, . 0
pwmValue $ . / % % .
Запрос данных веб-страницы через ее API
* . 4.8 -
AirNow *- (www.airnow.
gov/?action=airnow.local_city&zipcode=10003
&submit=Go).
/
-
" (AQI9)
. * 9
AQI, Air Quality Index — (+&).
- AirNow
, . 7 ASCII
. 0 -
, $
. *,
, - AirNow
— " -
Рис. 4.8. Веб-страница AirNow отображает текущее качество воздуха для географического местоположения, определяемого почтовым индексом США.
Однако в интерфейсе API веб-страницы
географическое положение определяется широтой и долготой точки замера
Глава 4
220
API, docs.airnowapi.org.
= API-
, 500 API .
;
-
API (
API
- AirNow ) - , " , HTML. 2 API "
HTTP ,
, $ « " » 3. 4 , API-
, %
. 7 API-
API, "
% . API-
-
, % .
# API-
- AirNow, - AirNow
, Current Observations by Reporting Area By Lattitude/Longitude "
Query Tool (https://docs.airnowapi.org/Current
ObservationsByLatLon/query). 0 , "
API-
% .
#
, "
, % , ,
,
"
%
.
&
,
$ ( API,
):
http://www.airnowapi.org/aq/observation/latLong/historical/?format=application/
json&latitude=40.7496&longitude=-73.9836&date=2016-05-10T00-0000&distance=10&API_
KEY=0000AAAA-0A0A-1111-A123-11223344AA55
0
:
[{"DateObserved":"2016-05-10 ","HourObserved":0,"LocalTimeZone
":"EST","ReportingArea":"Newark","StateCode":"NJ","Latitude":40
.7496,"Longitude":-73.9836,"ParameterName":"OZONE","AQI":28,"Cat
egory":{"Number":1,"Name":"Good"}},{"DateObserved":"2016-05-10
","HourObserved":0,"LocalTimeZone":"EST","ReportingArea":
"Newark","StateCode":"NJ","Latitude":40.7496,"Longitude":73.9836,"ParameterName":"PM2.5","AQI":33,"Category":{"Number":1,"
Name":"Good"}}]
& $ , $ ,
HTML. &
PM2.5 —
. > , $ , ,
10 %
. = , -
" ,
$ .
& PM2.5 $ : , PM2.5,
" (AQI). / %
" Arduino.
«Глянь, мама, здесь нет компьютера!» Микроконтроллеры в Интернете
221
Планируем чтение параметра PM2.5
; ,
Wi-Fi # , AirNow
, "
:
1. 0
-
.
2. 0 HTTP GET.
3. .
4. 0 .
5. *
.
6. & "
.
HTTP. = $ 6 (
) 4 ( ).
& — ArduinoHttpClient. > $
3 7 (Adrian
McEwen), % # 7 (Sandeep Mistry)
HTTP GET, POST, PUT DELETE,
. # " $
HTTP,
HTTP, .
Версии библиотек HttpClient
%
" $ ,
,
#"
HttpClient.
* ,
ArduinoHttpClient.
>
" ,
Arduino. 0
D ,
>
|
N , % " A
(
%) ArduinoHttpClient,
N .
/*
:
void loop() {
// HTTP-$
// M HTTP-$
}
+- AirNow
: Arduino WINC1500
*/
// '
% # %
// /
"
//
void setup() {
// \ # $ ' $
// \ # $
// ' Wi-Fi,
// '
// &
#
'
// ' ,
R
//
}
void connectToServer() {
// $ HTTP,
// ,
//
$ $
//
'
"PM2.5",
PM2.5
Глава 4
222
>- $
. 4.9. 0
%
if ) (
, "
— .
9
-
, .
/ , ,
true ( ).
// $ $ - (\+),
//
$ , $ $,
// - R $ HTTP
}
void setMeter() {
// Z
$ PM2.5
$
// ,
$
}
void setLeds() {
// ' , ' #
// '
// ' TCP, '
// ' -
}
void blink() {
// &
}
API . 4
,
"
. &
, .
, ,
$ - ,
— .
Сочетание в строке данных разных типов
- . 7 $
% "
,
HTTP,
$ . &
$ , API, , % ,
. 9 $
Arduino
String. #
"
, . 3 " ,
String(),
. >
% ,
$ BIN HEX.
*
( char),
( string). & "
"
toCharArray(). =
:
String myString = "/some/server/route";
char stringArray[myString.length() + 1];
myString.toCharArray(stringArray, myString.
length() + 1);
$ ,
0, $ $
% , $
. #
" "
.c_str() String.
«Глянь, мама, здесь нет компьютера!» Микроконтроллеры в Интернете
223
Пытаемся подключиться
к серверу
Подключились
к серверу?
Да
Нет
Отправляем
запрос HTTP
Нет
Да
Ответ содержит ИКВ?
Прошло достаточное время
после последней попытки
подключения?
Да
Извлекаем значение ИКВ
из ответа
Сопоставляем результат
диапазону показаний
вольтметра
Выводим результат
на вольтметр
Рис. 4.9. Блок-схема программы Arduino для
отправки запроса HTTP GET и обработки полученного ответа
Пишем код веб-клиента AirNow
; ,
- (+&), .
+ , ,
.
/*
+- AirNow
: Arduino
WINC1500
*/
// '
#include <SPI.h>
#include <WiFi101.h>
#include <ArduinoHttpClient.h>
#include "config.h"
% # %
224
Глава 4
SPI, WiFi101
ArduinoHttpClient. ,
config.h
(SSID) — , $
.
APIKey
API:
2
(
ESP8266 ),
(
) :
// / "
// :
const int networkLED = LED_BUILTIN; //
// '
const int connectedLED = 4; // '
const int meterPin = 5;
//
const int meterMin = 0;
//
const int meterMax = 255; //
const int AQIMax = 200; //
// $ -
const long requestInterval = 120000; // $
//
*
: WiFiClient
,
,
API
:
WiFiClient netSocket;
//
const char serverAddress[] = "www.airnowapi.org"; //
//
String route = "/aq/observation/latLong/current/"; // API
long lastRequestTime = 0;
// $
& setup() ,
, , $
.
2 , , :
blink()
. 0 $
:
void setup() {
Serial.begin(9600); // # $ ' $
pinMode(networkLED, OUTPUT); // %
// ' #
//
pinMode(connectedLED, OUTPUT); // %
// ' # '
//
pinMode(meterPin, OUTPUT); // %
//
// ' Wi-Fi,
while ( WiFi.status() != WL_CONNECTED) {
Serial.print(" ' : ");
Serial.println(ssid); // R (SSID)
WiFi.begin(ssid, password); // '
blink(networkLED, 5); // #
// '
}
// ' , R
//
«Глянь, мама, здесь нет компьютера!» Микроконтроллеры в Интернете
225
IPAddress ip = WiFi.localIP();
Serial.print("IP Address: ");
Serial.println(ip);
& setup()
,
URL- ,
"
API- AirNow. #
,
$
,
.
* ,
% %
,
:
//
' API:
route += "?format=application/json&latitude=40.7296";
route += "&longitude=-73.9936&date=2016-05-10T000000&distance=10";
route += "&API_KEY=";
route += APIKey;
}
& loop() .
— $
(
lastRequestTime) "
( millis()),
, %
" . 4 ,
connectTo
Server(). 3 — $
setLeds()
. 4
:
void loop() {
// HTTP-$
:
if (millis() - lastRequestTime > requestInterval) {
connectToServer();
}
// M :
setLeds();
}
[ connectToServer()
. &
HTTP (
HttpClient),
HTTP GET,
:
void connectToServer() {
int AQI = -1; // $ \+
HttpClient http(netSocket, serverAddress); // $
// HTTP
http.get(route); // $ HTTP
http.skipResponseHeaders(); // $
// HTTP-
Глава 4
226
,
,
setLeds(), , .
findUntil() $ "PM2.5",
"
parseInt() "
.
+&
(AQI) setMeter() :
// ' :
while (http.connected()) {
setLeds();
// :
if (http.available()) {
http.findUntil("PM2.5", "\n"); //
// "PM2.5"
AQI = http.parseInt(); //
$
// $ PM2.5
http.flush(); //
}
}
if (AQI > -1) { // $
// $ - AQI (\+),
Serial.print("PM2.5: ");
Serial.println(AQI);
setMeter(AQI); //
$
}
2
, http.
stop(), "
lastRequestTime:
http.stop(); // $ $
lastRequestTime = millis(); // - R
// $ HTTP
}
& setMeter() map(),
+& "
.
2
"
analogWrite():
void setMeter(int level) {
// $ $ ' -
// $ :
int meterSetting = map(level, 0, AQIMax, meterMin, meterMax);
//
$ :
analogWrite(meterPin, meterSetting);
& setLeds() , % #
WiFi.status() ,
Wi-Fi
, . WiFiClient.
Connected()
" :
void setLeds() {
// ' , '
// #
' :
if (WiFi.status() == WL_CONNECTED) {
digitalWrite(networkLED, HIGH);
} else {
digitalWrite(networkLED, LOW);
}
// ' TCP, '
// ' - :
int connectedToServer = netSocket.connected();
digitalWrite(connectedLED, connectedToServer);
}
«Глянь, мама, здесь нет компьютера!» Микроконтроллеры в Интернете
* , blink()
" 200 . * ,
,
,
:
227
void blink(int thisPin, int howManyTimes) {
// & :
for (int blinks = 0; blinks < howManyTimes; blinks++) {
digitalWrite(thisPin, HIGH);
delay(200);
digitalWrite(thisPin, LOW);
delay(200);
}
}
& - . #
AQIWebClient
MKR1000.
" ,
( . 4.10).
Рис. 4.10. Завершенный проект сетевого измерителя качества воздуха
Глава 4
228
Определение IP-адреса сетевого узла
& $ , IP- . X IP-
" ping, 3. * , :
ping -c 1 www.makezine.com
( Windows -n -),
" IP- :
" ,
PING makezine.com (104.25.44.28): 56 data bytes
64 bytes from 104.25.44.28: icmp_seq=0 ttl=52 time=38.870 ms
4 ping (
" +
,
" ),
nslookup.
* , nslookup makezine.com " " :
Server: 8.8.8.8
Address: 8.8.8.8#53
Non-authoritative answer:
Name:
makezine.com
Address: 104.25.45.28
IP-
.
Команда nslookup также возвращает адрес сервера
DNS, который она использовала
, $
Послесловие к завершенному проекту
&
$ %
,
,
. &
$ " .
?
:
,
$ ,
. = ,
,
.
,
, —
"
. & $
%
,
, %
.
?
' : $ ,
% ,
, "
, -
,
. +
"
,
, $
. + "
, ,
,
,
- ,
.
?
% :
,
, $ %
. &
«Глянь, мама, здесь нет компьютера!» Микроконтроллеры в Интернете
,
,
,
API- ,
% ,
,
"
,
% .
& "
,
, ,
$
% ,
.
+
"
% "
. /
—
,
229
" Hue lighting hub
Philips. 0 Wi-Fi
WINC1500 ESP8266
. , ,
,
,
,
" % . &
$ ,
. $ %
% .
Форматы данных
Разбираясь с проектами этой книги, мы уже познакомились с рядом существующих протоколов,
основанных на передаче текстовых данных, и даже создали несколько своих. По сути, протокол — это средство для структурирования данных при организации связи. Некоторые протоколы просто передают информацию, а другие отдают команды — явно или неявно — посредством
запросов. Далее нам придется часто работать с разными протоколами, поэтому сейчас было бы
полезно подытожить наши знания о рассмотренных к этому моменту форматах данных.
Простые форматы данных
& «7 % - »
,
10
11
. [ CSV TSV
— CSV
, . ~ %
CSV
NMEA-0183,
GPS.
$ 10
CSV, Comma-separated values — ,
.
11
TSV, Tab-separated values — ,
.
-
. 7
«- ».
% , ,
(
), .
& , «- » HTTP, ,
HTTP. [
,
,
— . * , "
, — :
Глава 4
230
"DateObserved":"2016-05-10 ","HourObserved":0,"LocalTimeZone":"
EST","ReportingArea":"Newark","StateCode":"NJ","Latitude":40.7267
,"Longitude":-74.1442
3 "
(&).
(=),
— -
?name=tom&age=14
3
—
"
«»,
. 2
,
:
&
: ,
, ,
. 3 : .
'
$ $
,
$ .
Host: localhost
Content-Length: 19006
Content-Type: multipart/form-data
7
+
— HTTP12 SMTP13. 0 "
:
GET
POST,
, . 2
"
, "
. _ "
«- »,
, $
(&).
& , , " HTTP
POST 2:
POST /check HTTP/1.0
Host: example.com
Connection: Close
Content-Type: application/x-www-formurlencoded
Content-length: 16
name=tom&age=14
12
HTTP, HyperText Transfer Protocol —
.
13
SMTP, Simple Mail Transfer Protocol —
[$ ] .
Примечание
& Java, JavaScript C
, ,
,
# " :
•
•
•
— \n
— \r
— \t
*
,
" % "
.
$
. & "
«Глянь, мама, здесь нет компьютера!» Микроконтроллеры в Интернете
231
Форматы структурированных данных
=
,
«- »,
- . 9 , ,
,
% (. 4.1).
Таблица 4.1. Массив датчиков, расположенных
в разных местах дома
Адрес Размещение
1
2
3
4
5
q
&
#
Последнее
чтение
Значение
12:30:00
05:40:00
01:15:00
09:25:00
06:20:00
60
54
23
18
3
& $
$
« ». & ,
«- » ( , , :3, $ :23).
&
. =
$
JSON14.
14
JSON, JavaScript Object Notation —
JavaScript.
Формат JSON
[ JSON , «- ».
,
. =
,
. 4.1, " :
[{"":1,"$ ":" -"," ":"12:30:00"," ":60},
{"":2,"$ ":" "," ":"05:40:00"," ":54},
{"":3,"$ ":""," ":"01:15:00"," ":23},
{"":4,"$ ":""," ":"09:25:00"," ":18},
{"":5,"$ ":" "," ":"06:20:00"," ":3}]
/
. /
,
, $ " .
$ , , % . #
, JSON, $
" :
"$ ":" ",
" ":"05:40:00",
" ":54
},
{
"":3,
"$ ":"",
" ":"01:15:00",
" ":23
},
{
"":4,
"$ ":"",
" ":"09:25:00",
" ":18
[
},
{
{
"":1,
"$ ":" -",
" ":"12:30:00",
" ":60
"":5,
"$ ":" ",
" ":"06:20:00",
" ":3
},
{
}
"":2,
]
Глава 4
232
" , JSON, —
,
,
,
. ;
,
% ,
, $
$
. =
JSON HTTP,
( )
.
JSON и JavaScript
,
JSON JavaScript, $
JSON , " $ .
> ,
JavaScript " JSON. *
.
& ,
,
JSON.
7 -
JSON
API- ,
"
,
$ JavaScript. & -
AirNow, 7, " JSON. =
node.js
$ .
Парсинг ответа сервера с помощью сценария на node.js
# "
$ .
[
JSON
JSON.parse()
> http node.js, $
.
http,
. 0 ,
$ (
options)
JSON. & $
«- »,
. 2
API
(
% ) :
JSON,
.
— JSON.stringify() —
JSON .
/*
AQI client
: node.js
*/
var http = require('http'); // ' http:
// $ $ R " JSON:
var options = {
host: 'www.airnowapi.org',
port: 80,
path: '/aq/observation/latLong/current/?format=application/
json&latitude=40.7296&longitude=-73.9936&date=2016-05-10T000000&distance=10&API_KEY=0000AAAA-0A0A-1111-A123-11223344AA55'
};
«Глянь, мама, здесь нет компьютера!» Микроконтроллеры в Интернете
233
[
,
handleRespons(),
, .
"
result.
3 response.on('end')
JSON , , $ :
function handleResponse(response) {
var result = ''; // Z -
* ,
http.request() %
request.end():
var request = http.request(options, handleResponse); // ^
// $
request.end(); // $
response.on('data', function (data) { // ,
result += data;
// $
});
response.on('end', function () {
//
//
var response = JSON.parse(result); //
//
console.log(response);
//
});
$ '
,
$
R
}
# $
aqiClient.js
:
$ node aqiClient.js
,
JSON $ . 0 ,
$
$
$ response [0], — $
response[0].AQI response[0].Longitude.
&
, .
/
,
$
API- , "
JSON. # "
HTTPS,
require('https');
% 443.
Принцип REST и интерфейсы API для Сети
Протокол HTTP основан на принципе передачи состояния представления REST15. REST — это не
протокол, а, скорее, архитектурный стиль для обмена информацией. Он часто используется
в Сети в интерфейсах прикладного программирования (API). И хотя принцип REST берет свое
начало в веб-приложениях, он нашел применение и в иных областях. Некоторое представление о REST не только поможет вам понимать другие системы, но также и разрабатывать свои
собственные коммуникационные протоколы. Усвоив этот принцип, вы уже не сможете в своей
жизни без него обойтись.
15
0 . REpresentational State Transfer —
.
Глава 4
234
0 REST " :
- # - ( ). & , $
,
, , $ , " % . 7
"
, $ . REST
( ) $
# $
.
7 REST — $ , HTTP.
, GET,
POST .
X
%
( ,
HTML
. 4.8
- AirNow.gov, " ),
$ ( ,
" ).
REST URL — "
,
,
— ,
"
.
& URL-
$% ( ). * , REST ,
2. X
, , Arduino " :
GET /color/r/
# 0
255, " . 3
, , , "
:
& $
255. & %
Arduino
,
"
, .
0
:
1. (
)
$%.
2. 2 —
,
. 2 HTTP
: GET, POST, PUT DELETE. 2
GET , PUT — , POST —
" "
, DELETE — " "
. + $ , GET POST
.
3. /
. #
, - , " HTML XML,
node.js, "
$ ,
PHP Ruby, C/C++, " Arduino, . ;
:
, $
—
.
& , REST
. ;, REST
OSC16,
MIDI. REST
POST /color/g/255
16
OSC, Open Sound Control.
«Глянь, мама, здесь нет компьютера!» Микроконтроллеры в Интернете
Ethernet,
. ,
REST,
,
" ,
,
.
4" " REST ,
, "
, URL-
.
%
html, $
, , ,
, $ . ; ,
- ,
$ . #
.
'
-
REST,
( , -
) ,
$
. $ REST:
?
/"/ —
-
235
Традиционная веб-служба
= ,
"
, .
= $
: ( , ), . URL-
$ 31 2012 "
:
?
31 2012 :
PUT /myrun.example.com/runnerName/31/1/2012
?
:
GET /myrun.example.com/
runnerName/31/1/2012/distance/
?
12,56 :
POST /myrun.example.com/runnerName/31/1/2012/
distance/12.56
0 ,
, ,
, " ,
GET ( ) PUT POST
,
( ) .
;
?
/"/ / —
.
—
— PUT POST. >
HTTP.
= . 0 —
- , —
.
Физическое веб-устройство
= ,
% . &
12 , . &
1 10.
. URL-
" :
?
:
GET /mywindows.example.com/windows
Глава 4
236
?
( — 2):
GET /mywindows.example.com/window/2/
?
:
-
POST /mywindows.example.com/window/2/height/5
?
:
POST /mywindows.example.com/windows/height/S
# % . 7
,
,
$ .
3 REST , -,
.
3 REST
. & , , — $ "
"
$%, ,
, " "
.
/ .
URL- ,
, , :
http://myrun.example.com/?runnerName=George
&day=31&month=1&year=2012&distance=12.56
REST — $ ,
,
$ ,
, ,
. *
-
REST. * , - AirNow.gov,
" %
,
REST,
. 7
REST " $ .
& ,
HTTP REST, node.js
Arduino.
Работа по REST в node.js
node.js express.js REST, $
$
" ,
REST, . ;,
" express.js
, ,
. * :
server.post('/check/age/:age', checkAge);
= $ " POST:
http://www.example.com/check/age/21
"
request.params.
age, 21. _ , -
" /age/,
. 7 "
:
server.post('/check/name/:name/age/:age',
checkAge);
*
,
REST, $ % ,
. 4 ,
express.js .
«Глянь, мама, здесь нет компьютера!» Микроконтроллеры в Интернете
237
Модифицируем код сценария «Проверщик возраста» в стиле REST
=
« " »
( . ageCheck.js 3), REST. *
% .
# $
restAgeCheck.js, express.js:
$ npm install express
& $
: request.
params.name request.params.
age — . ;
— ,
$
:
2
,
$
:
/*
RESTful age checker
$ REST
: node.js
*/
var express = require('express'); // '
// express:
var server = express(); // C$ " server,
// $ express
function checkAge(request, response) {
var name = request.params.name;
var age = request.params.age;
var responseString = "";
if (typeof age === 'undefined') {
responseString = "<p>9! , ?.</p>\n"
} else {
if (age < 21) {
responseString = "<p>" + name
+ ", + , ..</p>\n";
} else {
responseString = "<p> Hi " + name
+ ". + $ , ' , , ";
responseString += " R $ ..</p>\n";
}
}
// :
response.writeHead(200, {"Content-Type": "text/html"});
response.write(responseString);
response.end();
}
// start the server:
server.listen(8080);
//
$ :
server.get('/check/name/:name', checkAge);
server.get('/check/age/:age', checkAge);
server.get('/check/name/:name/age/:age', checkAge);
& ,
, GET. 9
REST ,
POST PUT? # GET $ ,
,
. X % ,
,
server.get() server.post().
#
" :
$ node RestAgeCheck.js
-
2 , " :
http://www.myserver.com:8080/check/
name/tom/age/42
3 , " curl:
$ curl http://www.myserver.com:8080/
check/name/tom/age/42
& www.myserver.com
localhost,
"
.
Глава 4
238
Работа по REST в Arduino
' REST
Arduino
, node.js.
= $
,
6. #
,
,
. 2 Stream,
$
( -
, Serial,
Client
Server WiFi101 $ Stream).
[ setup()
REST
6
, loop() .
Пишем код Arduino в стиле REST
*
HTTP,
"
:
GET /check/age/21 HTTP/1.1
#
, : GET
POST:
=
,
$% (/). 4 "
,
"
:
while
& while
"
"
:
$
,
node.js.
.
void loop() {
// '
WiFiClient client = server.available();
while (client.connected()) { // ',
if (client.available()) { //
- ,
// ' - ,
// $:
String request = client.readStringUntil(' ');
// check if the request is GET or POST:
if (request == "GET" || request == "POST") {
// / :
String lastToken = ""; //
while (!lastToken.endsWith("HTTP")) {
String currentToken = client.readStringUntil('/');
if (lastToken == "age") {
int age = currentToken.toInt(); //
Serial.print("age: ");
Serial.println(age);
}
//
lastToken = currentToken;
}
, , :
client.println("HTTP 200 OK\n\n"); // HTTP
if (client.connected()) { // ',
client.stop(); // ' .
}
}
}
}
}
«Глянь, мама, здесь нет компьютера!» Микроконтроллеры в Интернете
239
Инструменты для программирования
и диагностирования встроенных модулей
При попытках подключиться к сети в проектах этой главы вам, возможно, пришлось столкнуться с некоторыми проблемами. Не исключено, что самым трудным моментом их диагностирования было то, что модуль Wi-Fi очень скудно информировал вас о проблеме, если предоставлял
какую-либо информацию вообще. Такая ситуация является нормой взаимоотношений со встроенными модулями в собственных разработках. Чтобы помочь вам в решении таких проблем, мы
рассмотрим несколько моментов, которые нужно учесть в подобных случаях, а также несколько
инструментов диагностирования. Эти методы применимы как при работе с модулями Wi-Fi, так
и с другими сетевыми или коммуникационными модулями. Мы будем постоянно использовать
эти методы в последующем материале книги. Они вам также пригодятся и в других ситуациях, не
связанных с нашими проектами.
Три самые распространенные ошибки
Проверьте линии питания
Проверьте соединения
& : (" ). /
%
MKR1000 ESP8266.
* % WiFi - ,
(
)
%
$. 4 ,
"
,
" .
* , ,
(") ,
.
. X ,
, , , " ,
,
,
. & ,
" ( " ) .
Проверьте конфигурацию
4
, ,
, .
& ,
IP- , (SSID),
. ;
Wi-Fi, .
Средства и методы диагностирования
X % , , " , % .
& , $
, $
,
,
.
& , . ,
Глава 4
240
/
, $ . ", . 4
- , " $
" .
,
Физические методы
диагностирования
#
. * $ , ,
. '
,
, " . ;
, %
. & $
,
, % , $
" . & — $
,
. / " , " . $ , ,
, %
. + .
Использование
для диагностирования
последовательного обмена
- ,
Wi-Fi,
$ , , "
. * ,
,
, ,
" , ,
"
$ " . =
$ " ,
.
$ ,
.
.
7
,
. ~ $
,
. $
, %
.
Используйте отладочные команды
0 —
, , "
. 4
%
if (DEBUG), ,
DEBUG false:
const boolean DEBUG = true;
void setup() {
Serial.begin(9600);
}
void loop() {
if (DEBUG) Serial.println(" ");
}
«Глянь, мама, здесь нет компьютера!» Микроконтроллеры в Интернете
241
Объявляйте вызовы функций
. 0 ,
$ , , $
"
. = $ Serial.print() " " ,
" :
void connectToServer() {
if (DEBUG) Serial.print("\ % #
connectToServer()...");
// Z' % #
}
void setMeter() {
if (DEBUG) Serial.print("\ % # setMeter()...");
// Z' % #
}
void setLeds(int thisLevel) {
if (DEBUG) Serial.print("\ % # setLeds()...");
// Z' % #
}
Проверьте условные операторы
&
,
% ,
,
. &
% %,
. $
, ,
" " , "
:
while (http.connected()) {
if (DEBUG) Serial.print("http.connected...");
setLeds();
// :
if (http.available()) {
if (DEBUG) Serial.print("http.available...");
http.findUntil("PM2.5", "\n"); //
// "PM2.5"
AQI = http.parseInt(); //
$ $
// PM2.5
http.flush(); //
}
}
Проверьте вложенные операторы
#
. X
%
. 4 , " . * ,
,
. $ $ ,
" :
int AQI = -1; // $ \+
HttpClient http(netSocket, serverAddress); // $
// HTTP
http.get(route); // $ HTTP
while (http.connected()) { // ' ,
if (http.available()) { //
//
$ $ \+
// ... $ $
...
}
}
if (AQI > -1) { // $ \+,
setMeter(AQI); //
$
}
Глава 4
242
Разделите код на части
$ , $ "
. *
. * , "
client.connect(), :
if (client.connect()) {
// ' ,
// $ :
Serial.println(" ' ");
}
else {
// ' :
Serial.println(" ' ");
}
X $ ,
%
$ . ,
% .
* % .
= $
$
, :
client.connect(); // connect
delay(1); // wait a millisecond
if (client.connected()) {
// ' ,
Serial.println(" ' ");
}
else {
// ' :
Serial.println(" ' ");
}
$ :
Просто наблюдайте
+ %
,
. 0 ,
, $ ,
. /
. 0"" ,
% ,
, . $
, , — , , .
// ', - - :
if (client.connected()) {
if (client.available()) {
char inChar = client.read();
Serial.write(inChar);
}
}
«Глянь, мама, здесь нет компьютера!» Микроконтроллеры в Интернете
243
Создайте программу проверки состояния сети Wi-Fi
,
. = $ MAC-
% Wi-Fi,
,
. # " $ -
Wi-Fi,
, % —
$ IP-
MAC-
Wi-Fi,
. /
,
.
Скетч для проверки параметров сети Wi-Fi
$ ,
$ config.h, " SSID
.
/*
WiFi Status check
Wi-Fi
Context: Arduino, with WINC1500 module
*/
#include <SPI.h>
#include <WiFi101.h>
#include "config.h"
void setup() {
Serial.begin(9600);
Serial.println("^ ");
// ' Wi-Fi,
while ( WiFi.status() != WL_CONNECTED) {
Serial.print(" ' : ");
Serial.println(ssid); // R (SSID)
WiFi.begin(ssid, password); // '
delay(2000); // $ 2
// '
}
}
void loop() {
printWiFiStatus();
delay(10000);
}
[ printWiFiStatus()
$
:
void printWiFiStatus() {
// + R SSID , ':
Serial.print("SSID: ");
Serial.println(WiFi.SSID());
// + R IP- '$ ,
// ':
IPAddress ip = WiFi.gatewayIP();
Serial.print("IP- '$: ");
Serial.println(ip);
// +
R
// ':
IPAddress subnet = WiFi.subnetMask();
Serial.print("& : ");
,
Глава 4
244
Serial.println(subnet);
// +
R MAC- ,
// ':
byte apMac[6];
WiFi.BSSID(apMac);
Serial.print("BSSID (MAC- ): ");
for (int i = 0; i < 5; i++) { // # 0 4
if (apMac[i] < 0x10) { // , 16
// (0-0 # % )
Serial.print("0"); // +
R 0:
}
Serial.print(apMac[i], HEX);// +
R
// MAC-
Serial.print(":"); //
}
Serial.println(apMac[5], HEX);
//
R
//
MAC-
$
Wi-Fi (
ESP8266WiFi "
MAC- , $
0 5
5 0):
Внимание!
Разные библиотеки
// +
R MAC- Wi-Fi:
byte mac[6];
WiFi.macAddress(mac);
Serial.print("MAC- : ");
for (int i = 5; i > 0; i--) { // # 5 1
if (mac[i] < 0x10) { // , 16
// (0-0 # % )
Serial.print("0"); // +
R 0:
}
Serial.print(mac[i], HEX); // +
R
// MAC-
Serial.print(":"); //
}
Serial.println(mac[0], HEX); //
R
// MAC-
# ESP8266WiFi
.
=
macAddress() BSSID() $
" ,
# .
// +
R IP- Wi-Fi:
IPAddress gateway = WiFi.localIP();
Serial.print("IP- ");
Serial.println(gateway);
Wi-Fi:
// +
long rssi = WiFi.RSSI();
Serial.print("M : (RSSI):");
Serial.print(rssi);
Serial.println(" ");
Serial.println();
}
Создайте тестовую программу клиента
_
, %
. 7
. # Arduino
,
. #
$ ,
: . / %
,
,
, .
"
HTTP
,
«Глянь, мама, здесь нет компьютера!» Микроконтроллеры в Интернете
245
Пишем код вывода ответа сервера
/ % ,
" ,
. 4
,
,
, ,
%
.
$ ,
$ config.h, " SSID
.
/*
Test HTTP Client
HTTP
: Arduino
WIN1500
*/
// '
% # %
#include <SPI.h>
#include <WiFi101.h>
#include <ArduinoHttpClient.h>
#include "config.h"
WiFiClient netSocket; //
const char server[] = "myserver.com"; //
String route = "/foo"; // API
void setup() {
Serial.begin(9600); // # $ '
$
while ( WiFi.status() != WL_CONNECTED) { //
',
Serial.print(" '
: ");
Serial.println(ssid); // R (SSID)
WiFi.begin(ssid, password); // '
delay(2000);
}
// ' ,
R
:
IPAddress ip = WiFi.localIP();
Serial.print("IP-: ");
Serial.println(ip);
}
void loop() {
HttpClient http(netSocket, server, 8080); // $
HTTP
http.get(route); // $ HTTP
while (http.connected()) { // ' ,
if (http.available()) { //
:
String result = http.readString(); //
Serial.print(result); //
R
}
}
// #
http.stop(); // $ $
delay(10000); // 10
}
Глава 4
246
Создайте тестовую программу сервера
"
" .
* $
,
$
,
% " . 4
=
node.js, .
"
$ " ,
. ; HTTP.
,
node.js,
$
. 9 % ,
, ,
. % $
,
:
,
,
"
. '
$ ,
,
.
/*
test web server
-
: node.js
*/
// '
"
var express = require('express'); //
//
var server = express();
//
//
//
:
'
express:
C$ " server,
$
express
// % # ' $, $
//
$ :
function respondToClient(request, response) {
console.log(request.connection.remoteAddress);
console.log(request.headers);
console.log(request.query);
// write back to the client:
response.write(" , !\n");
response.end();
}
// :
server.listen(8080);
//
server.get('/', respondToClient);
$ :
«Глянь, мама, здесь нет компьютера!» Микроконтроллеры в Интернете
247
Заключение
В этой главе вам был продемонстрирован подход, позволяющий создавать очень гибкие и полезные сетевые объекты. По сути, сетевой объект представляет собой браузер, запрашивающий
содержимое из Сети и извлекающий требуемую информацию, или сервер, который доставляет
информацию клиенту. Такой подход можно использовать во многих разных проектах.
" $ ,
,
" " -
. # % —
node.js, " "
" " - . ; ,
%
- , - ,
. /
,
,
.
0
$
, "
, " . *
,
,
$ . # % .
; , ,
" $ , ,
.
Глава 5
СВЯЗЬ В РЕЖИМЕ РЕАЛЬНОГО
(ПОЧТИ) ВРЕМЕНИ
До сих пор большинство рассмотренных нами коммуникационных
проектов использовали для работы веб-браузер. Наше устройство
посылало запрос удаленному серверу, сервер исполнял программу,
а затем отправлял устройству ответ на запрос. В процессе этой
транзакции клиент устанавливал подключение к веб-серверу,
происходил обмен информацией, а затем подключение разрывалось. В этой главе мы узнаем, как удерживать такое подключение
открытым. Для этого мы создадим две разные серверные
программы, которые позволят удерживать подключение открытым
с тем, чтобы обеспечить более быстрый и надежный обмен данными
между сервером и клиентом.
Музыкальный ящик Джин-Йо Мока (2004)
7
" - +
" TTL-Serial/Ethernet.
" ,
. #
- " %
. 0 ' -1 * (Jin-Yo Mok).
Глава 5
250
Компоненты для проектов этой главы
Коды поставщиков
?
A — Arduino Store, http://store.arduino.cc
?
J — Jameco, http://jameco.com
?
AF — Adafruit, http://adafruit.com
?
RS — RS, www.rs-online.com
?
D — Digi-Key, www.digikey.com
?
SF — SparkFun, www.sparkfun.com
?
F — Farnell, www.farnell.com
?
SS — Seeed Studio, www.seeedstudio.com
Рис. 5.1. Новые компоненты для проектов этой главы: 1. Матовый картон для корпуса. 2. Датчик угла поворота (энкодер).
3. Гнездовые разъемы. 4. Светодиоды. 5. Плата MKR1000. 6. Кнопка со встроенным светодиодом. 7. Перфорированная печатная
плата
3
4
1
2
5
7
6
ПРОЕКТЫ 8 и 9. Управление воспроизведением видео
Arduino- MKR1000, 1 +.
AF: 3156, RS: 124-0657, A: ABX00004, GBX00011
(3 4#), D: 1659-1005-ND
&
Arduino Uno % WiFi101
WINC1500.
AF: 3033 2891
N >
Wi-Fi, 1 +. 4
+
Wi-Fi, $
. 0
Wi-Fi
.
C , 1 +.
D: 438-1045-ND, J: 20723 20601, SF: PRT12615 PRT-12002, F: 4692810, AF: 64, SS:
319030002 319030001
Связь в режиме реального (почти) времени
( 220 , 5 +.
D: 220QBK-ND, J: 690700, F: 9339299, R: 707-7612
&
,
1 +.
AF: 1609, D: V2018-ND, J: 616673, F: 4903213,
RS: 159-5420
H 18 "3 =, 4 +. = %
,
.
D: 36-2204-ND, RS: 123-6835, F: 2301244
' "3
6 ,
8 +.
D: 36-9300-ND, RS: 274-5086, F: 2500400
D , 3–5 +.
D: 160-1144-ND 160-1665.ND, J: 34761
94511, F: 1855510, RS: 228-5972 826-830,
SF: COM-09592 COM-09590
251
!
(
1 +.
AF: 377, SF: COM-10982
311130001
)
,
BOB-11722, SS:
, 1 +.
D: GH1344-ND SW400-ND, J: 2231822
119011, SF: COM-09337, F: 1634684, RS: 7182213
H ).
D: A26509-20-ND, J: 103377, SF: PRT-00116,
F: 1593411
).
D: ED7102-ND, F: 1122344, SF: PRT- 00115
).
, 1 +. (
.
Интерактивные системы и цепи обратной связи
В любой интерактивной системе имеются цепи обратной связи: пользователь предпринимает
действие, система реагирует на это действие, пользователь видит результат реакции (или извещение о нем) и предпринимает другое действие, возможно, зависящее от результатов предыдущего. В некоторых системах реагирования цепь обратной связи может быть весьма «неповоротливой» — со значительными задержками между действием и реакцией на него, в то время как
для других приложений реагирование должно быть быстрым.
* , « »
3
" ,
,
. * , , , — $
,
. 3
% -
( . 2), , —
7 % , . ; , % , .
_ , "
,
. & , ,
.
,
.
& $
,
(
), — , "
.
&
$ .
=
. 4 %
,
Глава 5
252
" , . = ,
( , $ HTTP),
$ .
,
. *
, $ .
,
. 2 $
,
? +
$ ,
? 3, ,
« -- »,
? $ - . &
,
, " $ , . &
, "
. 3
,
%
.
& % ,
,
"
. #
"
Skype Google
Hangout. #
,
"
"
,
,
- ( . chat servers). & $
%
, " - . #
" " . " +
,
"
. *
,
, ,
.
Протокол TCP: сокеты и сеансы
Работа каждого открытого подключения клиента к веб-серверу обеспечивается протоколом
TCP1. Протокол TCP определяет, каким образом объекты в Интернете открывают, удерживают и закрывают подключение, связанное со множественными обменами сообщениями. Подключение,
установленное между двумя объектами с помощью протокола TCP, называется сокетом (socket).
Сокет можно представить как канал, соединяющий два объекта. Сокет позволяет передачу данных в обоих направлениях в течение всего времени удержания подключения. Для нормальной
работы подключения обе стороны должны поддерживать его открытым.
9 , ,
-
" . ,
, ,
1
%
. 4
—
,
.
TCP, Transmission Control Protocol —
.
Связь в режиме реального (почти) времени
2 . 0
, " TCP,
. & $
,
% %
.
О «наилучшем» маршруте
0 —
%
- , ,
,
% .
%
(session). &
, " ,
( ) ,
,
,
,
, % . & $
TCP/IP,
Net Processing
Wi-Fi,
4.
# TCP
. * , —
" $
$
. ,
" , . *
%
TCP
-
253
, , " , .
0 #
— $ UDP 2. &
TCP "
, UDP
% . >
UDP 7.
Сокеты TCP и веб-сокеты
3
" telnet - ,
TCP,
HTTP
. *
- , ,
, %
webSockets,
HTML5. webSockets ( - )
HTTP
— ,
,
.
&
, $ , - ,
— TCP.
.
2
UDP, User Datagram Protocol —
.
-
Глава 5
254
Проект 8
Управление воспроизведением видео на основе сокетов TCP
Разработка приложений для управления мультимедиа предоставляет хорошую возможность
изучить подключения, осуществляемые в режиме реального времени. Следующий проект представляет собой сетевое видеоприложение, которым можно управлять с помощью физического
устройства (пульта). Сервером будет программа Processing, а клиентом — пульт, оснащенный
микроконтроллером, подключенным к Сети по Wi-Fi. Экраны клиента и сервера должны быть
расположены вблизи друг от друга, чтобы пользователь мог их видеть. Здесь мы используем сетевую связь потому, что она предоставляет гибкость в работе с множественными подключениями, а не ради ее возможности подключаться к удаленным устройствам.
_
" $ :
/ , , , , . % " :
/ ,
,
.
3
1. &
" :
.
2.
TCP.
3.
.
4.
:
-
"
-
• ;
• N-
;
• .
5. 2 ,
" .
0 ,
.
,
TCP-
"
" ASCII.
, ,
"
% ( $ ). 4
,
" , % " .
*
$ " ,
.
«- »,
$ ,
. /
. #" " :
?
?
— connect: n
2 n
;
— playing: n
?
?
?
2 n 1, 0 ( );
— position: n
2 n
. ,
— ;
— exit: n
2 n=1
;
"
(\n).
Связь в режиме реального (почти) времени
255
Тестовый чат-сервер
,
. #
, % ,
" . =
Processing, "
$ .
0
, " ,
,
.
Пишем код чат-сервера
#
,
.
& , net,
. 0
: $ Server,
ArrayList
. *
$
Server ArrayList
,
,
setup():
/*
: Processing
Z$ , '
R - .
, .
*/
& setup() :
void setup() {
size(640, 360); //
}
7 draw()
" readMessage()
:
void draw() {
// $ :
Client currentClient = myServer.available();
// , :
if (currentClient != null ) {
readMessage(currentClient);
}
}
// ' Net:
import processing.net.*;
int port = 8080; // ,
// '
Server myServer = new Server(this, port); // "
ArrayList clients = new ArrayList(); // Z
$
Массивы типа ArrayList
& $
, , , "
:
ArrayList. / , . $
ArrayList
, $
. ; ,
$ , . & $
, , $
ArrayList, %
. ` Processing $
Java. ArrayList - Processing www.processing.org.
` JavaScript ArrayList, , , Arduino #.
Глава 5
256
[ readMessages() " " . 0
" ( , ,
" ) $
" ,
IP-
. 4
" ,
"
"exit",
:
void readMessage(Client thisClient) {
// Z ' '
//
R:
String message = thisClient.readStringUntil('\n');
// , % # :
if (message == null) return;
// +
R
IP- :
println(thisClient.ip() + ": " + message);
if (message.contains("exit")) {
//
// ' ,
myServer.disconnect(thisClient); // '
clients.remove(thisClient);
//
$
// .
}
}
[ serverEvent() " ,
.
[ "
. 0
" ,
ArrayList:
// ' ,
// - ServerEvent.
void serverEvent(Server myServer, Client thisClient) {
println("^ : " + thisClient.ip()); // +
// R IP-
clients.add(thisClient); //
//
thisClient.write(" :" + clients.size() + "\n");
//
}
* , keyRe
%
.
/
:
void keyReleased() {
myServer.write(key);
}
leased()
2
telnet ( % Windows 10 telnet $ ). 4 IP-
% ,
, 192.168.1.45, (
8080) :
telnet 192.168.1.45 8080
, , " :
telnet localhost 8080
telnet 127.0.0.1 8080.
, telnet,
, ,
,
.
" : playing, position
exit. exit:1
.
; ,
,
.
Связь в режиме реального (почти) времени
257
Клиент пульта управления
Клиент пульта управления видео отслеживает как локальный, так и удаленный ввод. Локальный
ввод поступает от пользователя, а удаленный — от сервера. Клиент постоянно ожидает ввод от
пользователя, а от сервера — только тогда, когда тот подключен к нему.
=
" :
?
. ; ,
;
?
?
.
;
=
" :
?
,
;
?
,
;
?
.
"
, "
. = $
. =
-
,
,
, , , / " . $
, "
, , "" %
. &
$ ,
. # $
,
, $ .
& , "
:
. 4
, %
.
Схема клиента пульта управления
Требуемые компоненты
Arduino-
, "
Wi-Fi, 1 %.:
• MKR1000;
• ,
Arduino Uno,
% WiFi101;
• WINC1500.
+ : Wi-Fi, / , X3 (UART).
X +
Wi-Fi, 1 %.
> , 1 %.
9
220 0, 5 %.
, 1 %.
# , 3–5 %. ( .
).
, 1 %.
= ($ ) , 1 %.
, 1 %. (
).
.
258
#
MKR1000. * /
"
,
.
ESP8266 $
/ ,
$,
,
,
. ;
/
.
&
,
%
% . =
"
, " 360°.
"
. /
, ,
, " . $
(gray code).
$
.
9
$
. ;, $ ,
$
, 24
. / ,
24
/ .
$
— $ , $ . ;
/
.
/
SparkFun, ,
"
"
,
-
Глава 5
. 0
$
Adafruit,
" .
=
. /
$
. & ,
% .
,
. ,
«" » , « ». &
(LOW) .
; (
) , ,
" . & ,
,
pinMode(pinNumber, INPUT_PULLUP).
>%
/ " (GPIO)
" (pullup)
, .
,
« » . ,
«" »
, .
= $
—
, , "" . # $
.
Связь в режиме реального (почти) времени
259
45
50
55
60
45
50
55
60
I
G H
F
C D E
35
10
A B
A B
C D E
F
G H
I
J
J
40
C30
30
% %
40
25
25
35
20
20
A
B1
B2
15
+
. 0
,
, $
15
5
5
10
1
1
* . 5.2
, . 5.3 — $
. 7 ,
,
. 5.4 ( ) . 5.5
( ).
Рис. 5.2. Монтаж компонентов пульта управления видео на беспаечной макетной плате. Хотя здесь использована полноразмерная макетная плата, схема поместится на макетную плату вдвое меньшего размера
Рис. 5.3. Принципиальная схема пульта управления видео
220 Ом
220 Ом
3,3 В
Энкодер
Digital 0
220 Ом
Digital 1
Digital 2
Модуль
микроконтроллера
Digital 3
Кнопка подключения
к серверу
Digital 4
Digital 5
220 Ом
Светодиод индикации
состояния воспроизведения
220 Ом
Светодиод индикации
подключения к серверу
Общий
Глава 5
260
. *
( . . 5.4 5.5),
( . . 5.3),
,
.
=
. 7
, . * ,
% ,
, % $ . % $ , , !
3 ,
-
C
A
B1
B2
Рис. 5.4. Монтаж схемы пульта управления видео на перфорированной печатной плате (вид сверху). За исключением
резисторов, все компоненты схемы подключены вставкой их
штыревых контактов в гнездовые разъемы платы, чтобы их
можно было легко извлечь
. * . 5.6 5.7 ,
, . 5.8 — % . 4
— , , ,
,
" . #
%
% ,
.
0 "
73,
%
.
%
, .
.
Рис. 5.5. Монтаж схемы пульта управления видео на перфорированной печатной плате (вид снизу). Здесь хорошо видны
соединения пайкой монтажных проводов, резисторов и гнездовых разъемов на обратной стороне плат
Связь в режиме реального (почти) времени
261
Рис. 5.6. Пульт управления видео, смонтированный в корпусе из твердого картона. Высота расположения деталей схемы
рассчитана таким образом, чтобы светодиоды и ручка энкодера слегка выступали над верхней панелью корпуса. Прежде
чем приступать к изготовлению корпуса для пульта, соберите и смонтируйте его схему, чтобы знать, какого размера корпус
делать
Рис. 5.7. Cхема пульта управления видео, собранная на перфорированной печатной плате и подготовленная для упаковки в корпус. Монтаж на эту плату светодиодов, энкодера и светодиодов осуществляется с помощью гнездовых разъемов.
Использование дополнительных удлиняющих разъемов намного облегчает задачу подгонки высоты компонентов под корпус. Откусывайте выводы светодиодов понемногу, пока не будет достигнута требуемая высота, а затем вставьте их в разъемы.
Шестигранные стойки позволяют приподнять плату над днищем корпуса, создавая пространство для LiPo-батареи, которая
удобно подключается к специальному разъему в плате MKR1000. Для проекта необходимо использовать батарею емкостью
минимум 1000 мА
Глава 5
262
83,8 мм
Ø 5,2 мм
34,9 мм
Ø 3,2 мм
73 мм
Ø 3 мм
24,3 мм
8,9 мм
101,6 мм
Ø 8,3 мм
Ø 5 мм
Ø 7 мм
33,5 мм
76,2 мм
5 мм
7,6 мм
Диаметр всех нижних
отверстий 3,2 мм
12,6 мм
5,8 мм
52 мм
8,9 мм
73 мм
8,9 мм
52 мм
55,6 мм
61,2 мм
68 мм
74,9 мм
5,2 мм
52 мм
34,2 мм
Ø 3,2 мм
Вырежьте по сплошным линиям
Сделайте насечки и согните по пунктирным линиям
Линии с засечками служат только для указания размеров
Рис. 5.8. Шаблон для выкройки корпуса пульта управления видео. Заготовку можно вырезать из плотного картона,
а затем согнуть по линиям разметки и склеить. Размеры шаблона будут зависеть от вашей сборки схемы пульта, поэтому подгоните их по месту, как потребуется. Несмотря на то, что на рисунке все размеры выглядят рассчитанными точно, в действительности они взяты с готового корпуса
Связь в режиме реального (почти) времени
263
Код клиента для управления воспроизведением видео
& , " , : Encoder, # (Paul Stoffregen) Button, 7 3 (Michael Adams). /
, $ %
. > Encoder $ . & ,
-
$ " / ,
, " % " .
3 Button
" /
. 0
"
: , "
.
Разрабатываем псевдокод сценария клиента
, " ,
( $ )
.
.
& "
:
/*
: Arduino
*/
// +' - :
// \ # $ :
void setup() {
// '
// \ # $ # %
:
// \ # $ ' $
}
void draw() {
// Z
// Z
// ' ,
// -
//
$ ,
$
//
//
$ ' ,
// ' '
//
$ $ ,
// ' $
//
}
Пишем код сценария клиента
config.h (SSID)
, , $
Arduino 4:
// config.h
char ssid[] = "ssid";
// \ (SSID) Wi-Fi
char password[] = "s3c3r3+!"; // -
Глава 5
264
&
:
// '
#include <SPI.h>
#include <WiFi101.h>
#include <Encoder.h>
#include <Button.h>
#include "config.h"
% # %
0
IP-
(IP-
,
)
,
$
WiFiClient. / $ TCP
:
const char serverAddress[] = "192.168.0.12"; // IP-
2 $
Encoder Button
$ . 0
,
,
. * ,
$ :
Encoder myEncoder(0, 1); // $ Encoder
Button playButton(2);
// $ Button
Button connectButton(3);
const int playLED = 4;
// ^ '
//
const int connectLED = 5;
boolean playing = false; //
// $
long lastPosition = 0;
// $ #
// R
& setup()
/ $
. 0 , ,
$ ,
INPUT_PULLUP. ;
$
"
.
void setup() {
Serial.begin(9600);
,
$ 4:
int port = 8080;
WiFiClient tcpSocket;
//
//
Замените указанное здесь значение
на IP-адрес своего сервера
// # $
// ' $
pinMode(0, INPUT_PULLUP); // \ # $
// ' R
pinMode(1, INPUT_PULLUP);
pinMode(connectLED, OUTPUT); // \ # $
// '
pinMode(playLED, OUTPUT);
connectButton.begin();
// \ # $
playButton.begin();
// ' Wi-Fi,
while ( WiFi.status() != WL_CONNECTED) {
Serial.print(" '
: ");
Serial.println(ssid); // R (SSID)
WiFi.begin(ssid, password); // '
delay(2000);
}
Связь в режиме реального (почти) времени
265
О прерываниях
= Encoder
. 3
" "
. 4
% MKR1000 Wi-Fi, , :
#define ENCODER_DO_NOT_USE_ INTERRUPTS
.
// ' ,
// :
IPAddress ip = WiFi.localIP();
Serial.print("IP-: ");
Serial.println(ip);
R
}
[ loop()
:
readEncoder() readButtons(),
.
$ , — . 2
,
,
.
.
* ,
. #
, $
, " tcpSocket.connected(), 1 ( )
0 (). 3
,
playing, 1
( ) 0 ():
void loop() {
// Z :
readEncoder();
readButtons();
// - - - :
if (tcpSocket.connected()) { // ' ,
if (tcpSocket.available()) { //
// ,
String result = tcpSocket.readString(); //
Serial.print(result); //
R
// ( #- )
}
}
// :
digitalWrite(connectLED, tcpSocket.connected());
digitalWrite(playLED, playing);
}
Глава 5
266
[ readEncoder() myEncoder.read(), "
$ .
" $ ,
— . # "
, ,
,
. 2 "
$ "
:
void readEncoder() {
long position = myEncoder.read(); // Z R
long difference = position - lastPosition; //
// $ #
if (difference != 0) {
// $ # $
if (tcpSocket.connected()) {
// ',
tcpSocket.print("position:"); // '
tcpSocket.println(difference); // $
}
lastPosition = position; // $
// $ #
}
}
& readBut
Connect , , ,
, . 4 ,
, . 4
,
exit:1,
.
void readButtons() {
if (connectButton.toggled()) { //
// ' $ ,
if (connectButton.read() == LOW) {
//
,
if (!tcpSocket.connected()) {
//
'
// ,
connectToServer();
// '
} else {
//
' ,
tcpSocket.println("exit:1"); // '
}
}
} // # % #
connectButton.toggled
tons()
& , ( connectButton.toggled() true),
" $
(connectButton.
read() == LOW), ,
. 4
,
, ,
:
&
readButtons() Play.
; , , $
,
. 4 ,
playing , ,
, " "
$
:
if (playButton.toggled()) {
//
// $ $ ,
if (playButton.read() == LOW) {
//
,
playing = !playing;
// $ $
// playing
if (tcpSocket.connected()) { // '
// ,
tcpSocket.print("playing:"); // '
tcpSocket.println(playing); // $
}
}
} // # % #
playButton.toggled
} // # % #
readButtons()
Связь в режиме реального (почти) времени
* , connectToServer(),
readButtons(). /
.connect()
WiFiClient,
. / " —
,
. #
,
:
267
void connectToServer() {
Serial.println(" ' ...");
// ' $
if (tcpSocket.connect(serverAddress, port)) {
Serial.println(" ' ");
} else {
Serial.println("^ ' ");
}
}
2 $ ,
Processing - ,
. 0 ,
" .
,
. *
$ , Processing
" . 4 Processing -
:
% <Enter>, $
Arduino.
4 , , .
0
" , $ ,
, .
X % , $
,
.
Аппаратные прерывания
G
" "
. & Encoder
$ . >
Arduino www.
arduino.cc/en/Reference/AttachInterrupt. &
. ;, ATmega328, Arduino
Uno,
(0 1),
2 3
. * Arduino 101
. 3 MKR1000
0, 1, 4, 5, 6, 7, 8, 9, A1 A2. [
digitalPinToInterrupt( )
. * , Arduino Uno
digitalPinToInterrupt(3) " 1. * $
Arduino
101, $ .
Глава 5
268
Доработка видеосервера
0
- ,
"
.
" , - ,
$,
,
" Processing
" .
$ " :
?
;
—
?
setup() —
;
?
draw() —
;
?
serverEvent() —
?
readMessage() — «- » "
"
.
+ "
:
?
movieEvent()— , ;
?
scrub() —
.
-
> video
, 3.
0 %
, Processing H.264.
9 % —
640×480 . 4
,
, . &
data.
;
Добавляем в скетч код для работы с видео
& video
" (
% ):
/*
+
: Processing
*/
// ' - :
import processing.net.*;
import processing.video.*;
// :
int port = 8080; // , '
Server myServer; // "
ArrayList clients = new ArrayList(); // Z
Movie myVideo; // $
boolean playing = false; // :
// /
String lastMessage = ""; //
Связь в режиме реального (почти) времени
269
& setup() size(),
.
&
size()
% ( ) , $ movie
.
0 scrub(),
"
,
:
void setup() {
size(640, 360);
myVideo = new Movie(this, "movie.mov"); //
// # Movie:
myServer = new Server(this, port); //
scrub(0.0); // $
}
& draw()
.
2 , $ « » 3,
, "
"
, $ :
void draw() {
// $ :
Client currentClient = myServer.available();
// , :
if (currentClient != null ) {
readMessage(currentClient);
}
// N!
:
image(myVideo, 0, 0, width, height);
// N!
,
:
fill(15); // C
-
text(lastMessage, 11, height-19); //
fill(255); //
text(lastMessage, 10, height-20); //
}
=
: movieEvent() scrub().
[ movieEvent()
. &
— $
.read() video .
void movieEvent(Movie myVideo) {
myVideo.read();
}
void scrub(float newPosition) {
myVideo.loop(); //
myVideo.jump(newPosition); // $
//
if (!playing) myVideo.pause(); // * !
// ,
}
[ scrub()
. *
.loop()
%
"
"
.jump(). 4
, .pause():
Глава 5
270
* ,
readMessage(),
" " ,
,
% . *
- ,
: if
(message.contains("exit")):
, " trim()
« »: %
, . /
. *
( ,
Arduino printlin() \r\n —
),
%
.
void readMessage(Client thisClient) {
// Z ' '
//
R:
String message = thisClient.readStringUntil('\n');
// , % # :
if (message == null) return;
// +
R
IP- :
println(thisClient.ip() + "\t" + message);
message = message.trim(); // `
String[] decodedMsg = split(message, ":"); // K
//
String property = decodedMsg[0]; // $ —
int value = int(decodedMsg[1]); // —
2
"
: — $
" , — :
split()
+
,
( if), " .
# playing ( ) :
#"
"
position
.
// * ! ,
//
if (property.equals("playing")) {
playing = boolean(value); // $
//
if (playing) { // * ,
myVideo.loop(); //
} else { //
myVideo.pause(); //
}
}
// * (position),
//
:
if (property.equals("position")) {
float frames = value * 0.033;
Связь в режиме реального (почти) времени
=
0,033 :
3 exit ( )
:
& "
, draw() $ :
271
float videoTime = myVideo.time() + frames;
scrub(videoTime); // $
// ()
}
// *
(exit),
//
:
if (property.equals("exit") && value == 1) {
myServer.disconnect(thisClient); // N
clients.remove(thisClient); //
// .
}
// 9
// # :
lastMessage = thisClient.ip() + ": " + message;
}
# $
, - .
2
,
" telnet, $. * "
. * . 5.9
— ,
" .
, " . *
$ , " %
. / %,
% " , .
$
" . ,
.
Использование Raspberry Pi для управления видео
& $
. = Raspberry
Pi
.
HDMI- Processing. &
Raspberry Pi 2 3 $ . HDMI
Raspberry Pi ,
USB — %. 2
.
'
Processing,
,
Processing -
1. #
Processing
Raspberry Pi , .
2
Raspberry Pi " Programming,
processing .
& Processing Raspberry Pi , ,
video,
$ . Processing Raspberry Pi
: https://github.com/processing/processing/wiki/Raspberry-Pi.
Глава 5
272
Рис. 5.9. Снимок экрана воспроизведения видео сервером Processing. В нижнем левом углу изображения можно видеть IP-адрес клиента и его последнее сообщение
Проект 9
Управление воспроизведением видео на основе протокола
WebSocket
При работе скетча видеосервера из предыдущего проекта вы, наверное, заметили некоторую
задержку между моментом воздействия на элементы управления пульта и моментом, когда в
Processing начиналось воспроизведение видео. Объясняется это тем, что для воспроизведения
видео требуются значительные вычислительные ресурсы. Так что было бы предпочтительней отделить серверную часть скетча, которая обрабатывает сетевые транзакции, от части, которая работает с видео, чтобы серверу не приходилось выполнять объемные вычисления. Здесь мы это
и сделаем, создав веб-сервер в node.js — вместо сервера Processing, и веб-страницу — вместо
клиента дисплея на Processing. Клиент пульта будет управлять видео на клиенте дисплея, а сервер станет управлять сетевым обменом. Постоянное подключение между клиентами и сервером
будет поддерживаться с помощью веб-сокетов (webSockets).
& :
HTTP- , $ 4? & ,
? & , , ,
"
HTTP
. * ,
HTTP
,
$
— %
,
.
HTTP
%
webSocket. / % -
HTTP % ,
,
"
. & TCP
. $ webSocket
, "
.
* . 5.10 -
. #
— ,
. 4
,
" .
Связь в режиме реального (почти) времени
273
0 -
,
TCP- . #
HTTP, " :
Upgrade: websocket
Connection: Upgrade\r\n
Sec-WebSocket-Key:
dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13
2 Upgrade Connection
, , Sec-WebSocket-Key
,
Sec-WebSocket-Version
webSocket,
. 0
" :
.
*
, % " , ,
webSocket. =
% " webSocket,
. & "
-
HTML5
JavaScript, HTML. ; "
webSocket
node.js. & , $ —
ws. > Arduino, , webSocket
ArduinoHttpClient, " .
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept:
s3pPLMBiTxaQ9kYGzzhZRbK+x0o=
О взаимодействии библиотек webSocket
Sec-WebSocket-Accept
, % webSocket,
.
Рис. 5.10. Блок-схема видеосервера на веб-сокетах. Сервер
предоставляет видеостраницу HTML и видеоресурс для браузера посредством HTTP, затем посредством заголовка HTTP
Upgrade подключает веб-сокеты клиентов пульта управления и дисплея. Этот сервер может одновременно поддерживать несколько клиентов обоих типов
7 webSocket
,
. * $ ws node.js %
Arduino HTML5. 4 % ,
,
.
Устройство
видеоклиента
Программа
клиента
webSocket
Веб-клиент
Устройство
видеоклиента
Веб-клиент
Микроконтроллер
Серверная программа
на node.js
Программа клиента
webSocket
1
Микроконтроллер
2
HTTP GET/
Upgrade: websocket
position: n
playing: n
exit: n
Веб-клиент
1
HTTP GET
index.html
2
HTTP GET
/movie.mov
3
HTTP GET/
Upgrade: websocket
Веб-сервер
Устройство
видеоклиента
Глава 5
274
Сервер и клиент браузера
Серверы webSocket создаются поверх серверов HTTP, поэтому нашим начальным сервером для
этого проекта станет HTTP-сервер на основе библиотеки express node.js (вспомните сервер, с которым мы работали в главе 4). А клиент браузера будет страницей HTML, отображающей и управляющей видео с помощью библиотеки p5.js языка JavaScript.
Пишем код сервера на node.js
*
, $ express.js. #
wsExpressServer.js,
a
express, $ :
$ npm install express
# ,
$
,
public
,
4,
$ .
/*
Z webSocket express
: node.js
*/
// ' :
var express = require('express'); //
var http = require("http");
//
express
http
var server = express(); // c express
var httpServer = http.createServer(server); // http
// % $ - /public:
server.use('/',express.static('public'));
// :
httpServer.listen(8080); //
' http
> webSocket $ http node.js, $
$ $
express,
:
~
,
,
,
.
* - ,
. ' $ - ,
p5.js.
Промежуточное программное обеспечение
[ express.static() , " . / HTTP,
— http.get() http.post(). & "
. [ .use()
,
, 0,
.
Связь в режиме реального (почти) времени
275
Добавление интерактивных элементов с помощью p5.js
& 1 JavaScript p5.js, " - , " Processing. ; % , $ . #
,
public
p5.js. = ,
:
public/
index.html
sketch.js
libraries/
p5js
p5.dom.js
p5.sound.js
4
p5.manager, p5.js
" :
$ p5 g -b public
2
public p5.js :
$ p5 update
& " : node.js, "
, public, " p5.js. #
node.js p5.js .
Пишем код
index.html % p5.js,
" :
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script type="text/javascript" src="p5.js"></script>
<script type="text/javascript" src="libraries/p5.dom.js">
<script type="text/javascript" src="sketch.js">
<title></title>
</head>
& JavaScript,
,
sketch.js. 0 $
" :
/*
: p5.js
*/
var myVideo; //
function setup() {
myVideo = createVideo("movie.mov"); // \ # $
// R$ " Movie.
R %
//
% ,
// $ , - ( '
// % )
myVideo.size(640, 360); // $
// $
myVideo.position(10, 30); //
myVideo.loop(); // + $
}
Глава 5
276
#
public,
.
;
%
. 2
:
2
" :
-
http://localhost:8080
& .
$ node wsExpressServer.js
Добавление функциональности webSocket
; ,
HTTP-
HTTP- ,
webSocket. = -
. 5.10 "
" ,
-
1 2, — %
index.html
. %
3. #
% % $ —
webSocket,
.
$
,
"
. + " " :
?
— connect: n
2 n
;
?
— playing: n
?
2 n 1, 0 ( );
— position: n
?
2 n
. ,
— ;
— exit: n
?
2 n=1
;
"
(\n).
* $ ,
,
JavaScript, " JSON,
JavaScript . / , " , — ,
«- » . 2
$
JSON.parse() JSON.stringify().
Пишем код для webSocket
&
ws
$ (
*
, $
.
,
server, $
% ). > ws :
$ npm install ws
/*
Z webSocket express
: node.js
*/
var express = require('express'); // '
// express
Связь в режиме реального (почти) времени
277
express.js,
. &
,
httpServer,
, HTTP. +
,
wss, , webSocket:
var http = require("http"); // ' http
var WebSocketServer = require('ws').Server; // Server
// ws
var server = express(); // express
var httpServer = http.createServer(server); // http
var wss = new WebSocketServer({ server: httpServer }); //
// websocket
&
HTTP. ;
webSocket % "
webSocket:
// :
httpServer.listen(8080); // ' http
wss.on('connection', connectClient); // N!
// webSocket:
=
express
public, newClient() "
webSocket. /
% ,
. %
$ .
&
connectClient()
:
"
.
+ .size,
.length ,
wss.clients
set. & JavaScript
$ set ,
$
. &
ws
$ set, " wss.
clients:
webSocket "
: " , %. $
, %
connectClient(). ;
: readMessage(), readError()
disconnect().
// serve static files from /public:
server.use('/',express.static('public'));
function connectClient(newClient) {
// 7 webSocket:
function readMessage(data) {
// #
}
// if there's a webSocket error:
function readError(error){
console.log(error);
}
// $ webSocket:
function disconnect() {
console.log('Client ' + newClient.clientName + ' ');
}
// 9
newClient.on('message', readMessage);
newClient.on('error', readError);
newClient.on('close', disconnect);
// 7 ,
//
:
var greeting = {" ": wss.clients.size};
newClient.send(JSON.stringify(greeting));
}
Глава 5
278
+
readMessage()
,
" " ,
%,
. 2 «%» $ ,
, $ .
"
" playing position,
,
. [ broadcast()
$ . 4 "
"
exit,
1,
webSocket $ :
[ broadcast() connectCli
ent(). 0
webSocket —
$ " . 4
,
% "
" . =
sendToAll() $
wss.clients .forEach():
// 7 webSocket:
function readMessage(data) {
var result = JSON.parse(data); //
// JSON
if (result.hasOwnProperty('clientName')) { //
// clientName,
newClient.clientName = result.clientName; //
//
}
if (result.hasOwnProperty('playing') || //
// playing,
result.hasOwnProperty('position')) { //
broadcast(newClient, result); //
//
}
if (result.exit === 1) { // exit,
console.log(" " + result.clientName + " ");
newClient.close(); //
webSocket
}
console.log(result); //
#
}
// $
// webSocket:
function broadcast(thisClient, data) {
function sendToAll(client) {
if (client !== thisClient) {
console.log(' :' +
client.clientName);
client.send(JSON.stringify(data));
}
}
//
sendToAll() ! #
// wss.clients:
wss.clients.forEach(sendToAll);
}
#
webSocket %
Processing
% . &- ,
webSocket
clients,
Processing,
, ,
ArrayList. &- , $
" "
—
. - -
" "
readMessage() Processing,
. * %
,
Processing ,
.
+, ,
webSockets.
, ws,
Связь в режиме реального (почти) времени
279
$
. *
- ,
sketch.js $
"
- . =
$
.
Модифицируем сценарий sketch.js
&
,
" , - " " . &
message client
browser,
,
. ~ $
, :
/*
& setup()
HTML
div,
$ createDiv().
& $ "
.
2 webSocket
.
;
%
:
— %
, —
" :
function setup() {
myVideo = createVideo("movie.mov"); // \ # $
// R$ " Movie:
myVideo.size(640, 360); // $
// $
myVideo.position(10, 30); //
myVideo.loop(); // + $
#
lastMessage = createDiv(''); // 9
div
//
lastMessage.position(10, 10); // %
!
socket = new WebSocket('ws://' + host); // $
//
socket.onopen = sendIntro; // $
//
socket.onmessage = readMessage; // $
//
}
,
draw(),
$
, webSocket. [ sendIntro()
"
:
function sendIntro() {
// $
//
:
socket.send(JSON.stringify(message));
}
Video client
context: p5.js
*/
var
var
var
var
var
myVideo; //
socket; // -
lastMessage; // $
host = document.location.host; //
message = {"client": "browser"}; // 9 ! ,
//
Глава 5
280
[ readMessage()
. 0 "
" ,
JSON, "
: playing position.
$
, , $
readMessage()
Processing. &
readMessage() " "
:
#
sketch.js,
,
"
, . &
"
( . 5.11).
3
"
{ client: 'browser' }. ;
.
function readMessage(event) {
// ~
:
var msg = event.data; // 9
// onmessage
var videoTime = myVideo.time(); // $
//
var message = JSON.parse(msg); // $
//
JSON
// * ! ,
//
if (message.playing) {
myVideo.loop();
} else {
myVideo.pause();
}
// * position,
//
:
var value = parseFloat(message.position);
if (!isNaN(value)) { // * # ,
var frames = value * 0.033; // 1 .
// 30
videoTime += frames; //
//
myVideo.time(videoTime); // `
}
// 9
// # :
lastMessage.html(JSON.stringify(message));
}
Рис. 5.11. Кадр видео в окне браузера
Связь в режиме реального (почти) времени
281
Клиент пульта управления WebSocket
Клиент пульта управления для этого проекта физически такой же, как и клиент пульта управления предыдущего проекта. Для него можно использовать ту же схему, изменив при этом только
программу микроконтроллера. Единственное различие между этим клиентом микроконтроллера и предыдущим состоит в том, что вместо подключений сокетов TCP этот клиент должен открывать подключения webSocket. Для этого мы воспользуемся библиотекой ArduinoHttpClient,
опыт работы с которой у нас уже имеется. Эта библиотека содержит класс webSocket, благодаря
которому задача открытия подключения не представляет никаких сложностей.
Пишем код клиента пульта управления
* Arduino " . & %
ArduinoHttpClient. ;
$ webSocket
(
% ).
>%
. [ setup()
"
:
[ loop() " .
7 TCP-
webSocket,
. [
parseMessage() webSocket "
" " . X %
, " "
Stream
read() readString().
;
connectLED,
webSocket, TCP- :
/*
webSocket
: Arduino WINC1500
*/
#include
#include
#include
#include
#include
#include
<SPI.h>
<WiFi101.h>
<ArduinoHttpClient.h>
<Encoder.h>
Замените указанное здесь значение
<Button.h>
на IP-адрес своего сервера
"config.h"
const char serverAddress[] = "192.168.0.12"; // IP-
//
int port = 8080; //
WiFiClient tcpSocket; //
//
# webSockt
WebSocketClient webSocket = WebSocketClient(tcpSocket,
serverAddress, port);
void loop() {
readEncoder();
readButtons();
// $
- , !
:
if (webSocket.connected()) {
int msgLength = webSocket.parseMessage(); // $
//
if (msgLength > 0) { // if it's > 0,
String message = webSocket.readString(); //
//
Serial.println(message); //
#
}
}
// :
digitalWrite(connectLED, webSocket.connected());
digitalWrite(playLED, playing);
}
282
Глава 5
& readEncoder()
: TCP, .
sendJsonMessage() " webSocket. #
sendJsonMessage() :
void readEncoder() {
long position = myEncoder.read(); // Z R
long difference = position - lastPosition; //
// $ #
if (difference != 0) { // $ # $ ,
if (webSocket.connected()) { //
-
sendJsonMessage("position", difference);
//
JSON
}
lastPosition = position; // $
// $ #
}
}
+
readButtons()
readEncoder().
void readButtons() {
if (connectButton.toggled()) { //
// ' $ ,
if (connectButton.read() == LOW) { //
,
if (!webSocket.connected()) {
//
//
connectToServer();
// '
} else { //
'
sendJsonMessage("exit", 1); //
}
}
} // # % #
connectButton.toggled
connectButton
TCP- - ,
connectToServer(). 3
" exit, .
- ,
"
:
[ connectToServer()
, "
. * webSocket.begin()
" 1, $
,
" . /
"
. =
$
sendJsonMessage(),
:
if (playButton.toggled()) { //
// $ $ ,
if (playButton.read() == LOW) { //
,
playing = !playing; // $ $
// playing
if (webSocket.connected()) { //
// ,
sendJsonMessage("playing", playing);
//
}
}
} // # % #
playButton.toggled()
} // # % #
readButtons()
void connectToServer() {
Serial.println(" ' ...");
boolean error = webSocket.begin(); // $
//
if (error) {
Serial.println(" ");
} else {
Serial.println("$ ");
sendJsonMessage("", 0); // N
//
}
}
Связь в режиме реального (почти) времени
4
$ —
sendJsonMessage(). 0 " JSON
.
" webSocket
" ,
$
webSocket.beginMessage() .
$ " —
webSocket ( : text, binary, ping
.). 2
"
print() println().
* , webSocket.
endMessage()
" :
// 9 "- " JSON
// :
void sendJsonMessage(String key, int val) {
webSocket.beginMessage(TYPE_TEXT); // : text
webSocket.print("{\"clientName\":\"MKR1000\"");
if (key != "") { //
,
webSocket.print(",\""); //
//
webSocket.print(key);
//
webSocket.print("\":"); //
//
webSocket.print(val);
//
}
webSocket.print("}");
webSocket.endMessage();
}
2
. 2
.
&
" :
{ clientName: 'MKR1000' }
# , " :
{"client":1}
4 ,
$
—
.
Рис. 5.12. Один клиент пульта управления может одновременно управлять
несколькими клиентами браузера
283
/
( . 5.12). 0
$
. * ,
"
,
$ .
Глава 5
284
Заключение
Базовую структуру клиентов и сервера из проектов этой главы можно использовать всегда, когда вы хотите создать систему, которая управляет одновременными подключениями нескольких
сетевых объектов. Основные задачи сервера состоят в ожидании подключения новых клиентов,
отслеживании уже подключенных клиентов, а также в обеспечении передачи сообщений без
ошибок соответствующим клиентам. Из них первостепенной задачей сервера должно быть ожидание попыток подключения клиентов.
"
,
"
.
.
,
% ,
,
,
" . 0 , $
, — , "
client exit, $ . #"
, ,
. 9 , " %
, , $ JSON.
2
-
.
&
"
TCP, $ - (webSockets).
,
— ,
—
TCP- . #
, -
%
" " HTTP, - .
$
( HTTP 4)
( $ ).
$ ,
. & "
+
.
Связь в режиме реального (почти) времени
Исходный эскиз музыкального ящика Джин-Йо
Мока
Композиторский интерфейс музыкального ящика
285
Глава 6
БЕСПРОВОДНАЯ СВЯЗЬ
Полагаю, что вас, как и многих людей, интересует эта область, и вы
приобрели мою книгу, потому что мечтаете создать устройства,
взаимодействующие друг с другом по беспроводной связи.
Возможно, вам так не терпелось разобраться с этим вопросом, что
вы «перепрыгнули» через весь предыдущий материал прямо сюда.
Если вы действительно это сделали, возвратитесь к началу
и прочитайте все, что пропустили! В предыдущих главах мы
познакомились с такими распространенными видами
беспроводной связи, как Wi-Fi и Bluetooth, но, что более важно,
в них мы также рассмотрели некоторые принципы цифрового
взаимодействия, на которых основана беспроводная связь.
В частности, если вы не знакомы с последовательным обменом
данными между компьютерами и микроконтроллерами, вам надо
обязательно изучить материал главы 2. А в этой главе беспроводная
связь рассматривается более подробно — в ней мы встретимся еще
с двумя типами беспроводной связи, а также создадим несколько
работающих проектов.
«Зиготы» Алекса Байма (www.tangibleinteraction.com)
«2 » — $ %
% ,
" ZigBee. , .
0
% , ,
, ,
% $ . 0 G
Z (Alex Beim).
Глава 6
288
Компоненты для проектов этой главы
Коды поставщиков
?
A — Arduino Store, http://store.arduino.cc
?
MS — Maker SHED, www.makershed.com
?
AF — Adafruit, http://adafruit.com
?
RS — RS, www.rs-online.com
?
D — Digi-Key, www.digikey.com
?
SF — SparkFun, www.sparkfun.com
?
F — Farnell, www.farnell.com
?
SS — Seeed Studio, www.seeedstudio.com
?
J — Jameco, http://jameco.com
Рис. 6.1. Новые компоненты для проектов этой главы: 1. Инфракрасный пульт дистанционного управления. 2. Логический
пробник компании Saleae (по желанию). 3. Плата Arduino 101. 4. Радиомодули RFM95W, поддерживающие технологию LoRa1.
5. Осциллограф DSO Nano. 6. Инфракрасный светодиод. 7. Инфракрасный фототранзистор
1
LoRa ( . Long Range) — , " % /
$ .
2
1
7
6
5
3
4
Беспроводная связь
289
ПРОЕКТ 10. Инфракрасное управление цифровой фотокамерой
"
, 1 +. = $
Arduino . &
MKR1000 Arduino 101,
Arduino Uno .
MKR1000 — AF: 3156, RS: 124-0657, A:
ABX00004, GBX00011 (3 4#), D:
1659-1005-ND
• Arduino 101 — D: 1660-1003-ND, J: 2239331,
SF: DEV-13787, AF: 3033, F: 2520713, RS:
913-9999, SS: 114990575, A: ABX00005,
GBX00005 (3 4#)
• Arduino Uno — D: 1050-1024-ND, J:
2151486, SF: DEV-11021, A: A000099, AF: 50,
F 1848687, RS: 715-4081, SS: ARD132D2P
& , 1 +.
•
(
220 , 1 +.
D: 220QBK-ND, J: 690700, F: 9339299, R: 7077612
( 10 , 1 +.
D: 10KQBK-ND, J: 691104, F: 9339060, R: 7077745
&.
SS: 109990013, SF: TOL-11702, AF: 468
-
( . ).
-
-& , 1 +.
D: 365-1068-ND, RS: 654-8542
C , 1 +.
J: 106526, A: 387, SF: COM-09469, F: 1716710,
RS: 577-538, SS: MTR102A2B
, 1 +.
D: 438-1045-ND, J: 20723 20601, SF: PRT12615 PRT-12002, F: 4692810, AF: 64, SS:
319030002 319030001
> .
D: GH1344-ND SW400-ND, J: 2231822
119011, SF: COM-09337, F: 1634684, RS: 7182213
]= =
. " .
ПРОЕКТ 11. Дуплексная радиосвязь
C , 2–3 +.
D: 438-1045-ND, J: 20723 20601, SF: PRT12615 PRT-12002, F: 4692810, AF: 64, SS:
319030002 319030001
"
, 1 +. = $
Arduino .
•
•
•
MKR1000 — AF: 3156, RS: 124-0657, A:
ABX00004, GBX00011 (3 4#), D:
1659-1005-ND
Arduino 101 — D: 1660-1003-ND, J: 2239331,
SF: DEV-13787, AF: 3033, F: 2520713, RS:
913-9999, SS: 114990575, A: ABX00005,
GBX00005 (3 4#)
Arduino Uno — D: 1050-1024-ND, J:
2151486, SF: DEV-11021, A: A000099, AF: 50,
F 1848687, RS: 715-4081, SS: ARD132D2P
( HopeRF RFM95W
SX1276, 2–3 +.
Semtech
AF: 3072, SS: 113060006
, 2–3 +.
D: GH1344-ND SW400-ND, J: 2231822
119011, SF: COM-09337, F: 1634684, RS: 7182213
( 220 , 2–3 +.
D: 220QBK-ND, J: 690700, F: 9337792, RS: 7077612
D , 2–3 +.
D: 160-1144-ND 160-1665-ND, J: 34761
94511, F: 1855510, RS: 228-5972 826-830, SF:
COM-09592 COM-09590
> .
]= =
. " .
Глава 6
290
ПРОЕКТ 12. Управление фотокамерой с помощью Bluetooth LE
Arduino 101 Arduino
Bluetooth LE nRF8001 nRF51822 Nordic Semiconductor, 1 %.
MKR1000 — AF: 3156, RS: 124-0657, A:
ABX00004, GBX00011 (3 4#), D:
1659-1005-ND
• Arduino 101 — D: 1660-1003-ND, J: 2239331,
SF: DEV-13787, AF: 3033, F: 2520713, RS:
913-9999, SS: 114990575, A: ABX00005,
GBX00005 (3 4#)
• Arduino Uno — D: 1050-1024-ND, J:
2151486, SF: DEV-11021, A: A000099, AF: 50,
F 1848687, RS: 715-4081, SS: ARD132D2P
N Bluetooth LE (Bluetooth 4.0), 1 +.
•
AF: 1697
&
RedBear BLE Nano "
USB- MK20.
MS: MKRBL5, SF: WRL-14071
C , 1 +.
D: 438-1045-ND, J: 20723 20601, SF: PRT12615 PRT-12002, F: 4692810, AF: 64, SS:
319030002 319030001
& , 1 +.
J: 106526, A: 387, SF: COM-09469, F: 1716710,
RS: 577-538, SS: MTR102A2B
( 220 , 1 +.
D: 220QBK-ND, J: 690700, F: 9337792, RS: 7077612
+ > , &
,
$ Bluetooth LE, 1 +.
7 ,
, "
Bluetooth LE.
4
, " %
, $ "
.
]= =
. " .
Почему не вся связь беспроводная?
Преимущество беспроводной связи кажется очевидным — нет проводов. Это значительно упрощает конструкцию любого проекта, в котором взаимодействующие устройства должны перемещаться. Носимые сенсорные системы, цифровые музыкальные инструменты, дистанционно
управляемые транспортные средства — вот всего лишь несколько примеров устройств, работу
с которыми можно упростить, используя беспроводную связь. Но этот тип связи имеет определенные ограничения, которые необходимо принять во внимание, прежде чем переводить на нее
все, что движется.
?
C
A ,
. +
,
. [ $ ,
, —
,
$ , %
,
(
" ) "
.
?
C ,
,
= = = . # ,
-
,
,
"
"
. + $ ,
"
. * ,
Bluetooth, % Wi-Fi
( 802.11b, g n) ZigBee ( 802.15.4) —
2,4 qq
Беспроводная связь
291
( 802.11n
5 qq). + ,
% , % ZigBee
, , , Wi-Fi, -
.
?
?
C >
$ $ . #
, .
" " ,
%
,
$
. #
$ , $
% , ,
,
,
% , .
C
. X $
,
. 3
« », . >
,
. 0
%,
% - .
$
% ». #
«
,
$ $
, $
%
. 4
$ , %,
. 0
, " ,
, ,
,
$ . $,
,
,
$ ,
.
?
N >
.
* ,
$ $ ,
. / $ ,
% "
% +
.
+
, $ $
,
% , $ ?
?
> >.
D
9
$
,
" ,
$
. $, "
,
.
Глава 6
292
Два типа беспроводной связи: инфракрасная и радио
Большинству людей в своей жизни и работе приходится сталкиваться с двумя видами беспроводной связи: посредством инфракрасного излучения и посредством радиоволн. С точки зрения
пользователя или разработчика, основная разница между ними состоит в их направленности и
радиусе действия.
.
& ,
,
$ . + , ,
Рис. 6.2. Сигнал от инфракрасного светодиода распространяется в виде направленного луча (слева), а сигнал радиоантенны — во всех направлениях (справа)
.
,
, $
« »
. X
,
. =
. & %
. + ,
.
$, "
, %
,
. #
,
%
, — .
9
. 6.2.
Передатчики, приемники и приемопередатчики
, " : ,
,
,
,
,
,
,
, .
7 ,
,
$ ?
,
. & , , ,
,
$
, . = % %, "
,
. ; , ,
. /
.
;
,
" ,
Беспроводная связь
. * ,
Bluetooth Wi-Fi
.
0
, ,
, -
% , " .
, $ -
293
. 2 —
% ,
? =
, . #
, " ? 7 % $ , " ,
?
$ , ,
-
$
.
Принцип работы инфракрасной связи
X
,
$ .
/ ,
" $ . "
( ,
,
. .),
. = $,
" ,
. #
$
, #
,
. , ,
"
. 2
" ,
. ;
% .
*
, % , -
, % $ . & ,
,
% , $ $
,
"
. ;
,
$
$ $
, "
.
% $
. '
%
,
" ,
" . >%
"
38
40 q. '
"
, $
— , 500
2000 . = %
$
,
. & ,
$ ,
8-
. & , , Control-S Sony
Глава 6
294
: 12-, 15- 20-
. 3 %
RC5
Philips 14-
.
. 3 EPanorama
orama.net/links/irremote.html)
4 , +
% , "
. +
-
$
, SparkFun, Adafruit,
Seeed Studio . SparkFun
Adafruit -
4 , ,
%
—
%
,
"
, ,
"
. *
"
.
(www.epan .
Как увидеть инфракрасный свет?
'
, $
. ' , % "
, — - . 4
, - $ . * . 6.3
,
- ,
: — ,
— . # "
, $
. *
"
, $,
- ,
-
, $
, — ,
.
Рис. 6.3. Вид инфракрасного светодиода через веб-камеру: слева — светодиод выключен, справа — включен
Беспроводная связь
295
Проект 10
Инфракрасное управление цифровой фотокамерой
В этом проекте мы будем управлять цифровой фотокамерой с помощью инфракрасного светодиода и микроконтроллера. Этот простой проект позволит вам получить общее представление
о работе инфракрасных устройств дистанционного управления.
>%
(SLR2)
" .
,
: . & +
% , "
. & $
, . = Adafruit
https://learn.adafruit.com/ir-sensor
MulitCameraIR,
# 2 (Sebastian Setz). ~ $
Arduino,
.
& %
Canon RC-3
Nikon ML-L3. ; ,
Nikon Canon,
%
, $
%
. * ,
" %
"
.
2
SLR, Single Lens Reflex —
.
Чтение ИК-сигнала
=
. +
$ % DSO Nano.
;
Logic 4 Saleae (www.saleae.com),
, Nano. 0
DSO Nano,
,
$ ( . 6.4). 3 Logic 4 ,
,
$ .
=
"
$ , « »
Рис. 6.4. Отображение начальной части ИК-сигнала пульта
дистанционного управления камеры Nikon на экране осциллографа DSO Nano
Глава 6
296
(" )
. , %
,
% ( $ ,
% %
). >%
,
. X
, ,
,
.
&
. ;
"
"
.
Canon 32,7 q,
Nikon — 38 q. '
.
& . 6.1
Canon Nikon. /
$
,
.
% ,
" . /
,
.
Таблица 6.1. Сигналы инфракрасных пультов управления для спуска затвора
двух разных цифровых камер
Nikon (38 кГц)
Canon (32,7 кГц)
2 —
16 —
27 —
7,33 —
0,4 —
16 —
1,5 —
100 —
0,5 —
3,44 —
0,5 —
65 —
Схема инфракрасного пульта управления
Требуемые компоненты
Arduino-
+
/ .
+
, 1 %.
:
, 1 %.
+
, 1 %.
0 , 1 %.
-
+
, 1 %.
, 1 %.
9
220 0, 1 %.
9
10 0, 1 %.
> % , 1 %.
Беспроводная связь
297
A B
C D E
F
G H
I
J
1
1
5
5
10
10
15
15
3,3 В
Модуль
микроконтроллера
Кнопка
Цифровой вывод 7
20
20
25
25
30
30
Цифровой вывод 4
220 Ом
Общий
A B
C D E
F
G H
I
10 кОм
J
Рис. 6.5. Монтажная (слева) и принципиальная (справа) схемы
простейшего инфракрасного пульта управления
0
$
.
/ % , $ .
# . 6.5. 2 Arduino 101,
%
MO, AVR
Curie.
, ,
- .
# ( $ ),
"
( . 6.6).
Пишем код для инфракрасного пульта управления
,
"
" :
/*
\
: Arduino
# %
' \-$ .
*/
const int pushButtonPin = 4; //
,
//
'
const int IRPin = 7; //
,
//
' \-
const int CAM_NIKON = 1; // # %-
const int CAM_CANON = 2;
int buttonState = 0;
//
int lastButtonState = 0; //
& setup() +-
:
void setup() {
pinMode(pushButtonPin, INPUT); //
//
pinMode(IRPin, OUTPUT);
// \-
//
}
Глава 6
298
& loop()
". 4 , ,
$ shutterClick(),
. =
Canon
$
CAM_CANON. 2 "
" :
void loop() {
// Z '
buttonState = digitalRead(pushButtonPin);
[ shutterClick()
. +-
, $
:
void shutterClick(int cameraType) {
if (cameraType == CAM_NIKON) { // Nikon
unsigned long irFrequency = 38000; //
// \- = 38 #
for (int i = 0; i < 2; i++) { //
//
IRPulse(2000, irFrequency); // '
// 2
delay(27); // '
27
IRPulse(400, irFrequency); // '
// 0,4
delayMicroseconds(1500);
// '
// 1,5
IRPulse(500, irFrequency); // '
// 0,5
delayMicroseconds(3500);
// '
// 3,44
IRPulse(500, irFrequency); // '
// 0,5
delay(65); // $ 65
}
}
:
if (buttonState != lastButtonState) { //
//
$ ,
if (buttonState == HIGH) { //
shutterClick(CAM_NIKON); // \-
// $
}
}
// Z- ' :
lastButtonState = buttonState;
}
if (cameraType == CAM_CANON) { // Canon
unsigned long irFrequency = 32700; //
// \- = 32,7 #
for (int i = 0; i < 2; i++) { //
//
IRPulse(489, irFrequency); // 16
//
delayMicroseconds(7330); // $ 7,33
IRPulse(489, irFrequency); // 16
//
delay(100); // $ 100
}
}
}
Беспроводная связь
'
, shutterClick()
IRPulse().
/ " Arduino tone()
+-
" ,
%
, .
tone()
delayMicroseconds(),
$ $
:
299
// \- $
:
void IRPulse(unsigned long interval, unsigned long
frequency) {
unsigned long now = micros(); //
//
tone(IRPin, frequency); // IRPin
// $
while (micros() - now < interval);//
// $
noTone(IRPin); // '
}
Рис. 6.6. Это устройство создано с использованием только что описанного подхода. Микроконтроллер Arduino в корпусе,
стоящем рядом с камерой, улавливает изменение показаний пассивного инфракрасного датчика А и посылает камере инфракрасный сигнал с командой сделать снимок
А
Глава 6
300
Принцип работы радио
Радио работает на основе электромагнитного эффекта, называемого индукцией. Суть его заключается в следующем. При изменении протекающего в проводнике электрического тока генерируется соответствующее магнитное поле, излучаемое проводником в окружающее пространство.
Если в это изменяющееся магнитное поле попадает другой проводник, оно индуцирует (наводит)
в нем соответствующий электрический ток. Частота изменения магнитного поля равна частоте
изменения электрического тока в первом проводнике. Таким образом, если мы хотим передать
электрический сигнал, не используя для этого проводов, мы можем генерировать переменный
электрический ток определенной частоты в одном проводнике, а к другому проводнику подсоединить схему для выявления изменений тока на этой частоте. Таков вкратце принцип работы
радиосвязи.
9 ,
, " ,
,
,
.
'
, % .
0
"
"
. 3
,
% , . *
,
.
, $ $
. *
:
= 5,616 ' /
&# = 14,26606 / &#
/ «American
Radio Relay League Handbook»3 1929 . & $
. / ,
5% , ,
. =
, ,
3,0×108 / .
; ,
, , 915 7q, :
1/915 × 106 × 3,0×108 × 0,95/2 = 0,1557382
+ 15,6 .
,
,
. > $
. =
%
.
Аналоговая и цифровая
радиопередача
,
. &
$ ( , )
" 4.
/
" ,
. &
"
, $
"
$ . + ,
4
3
#
.
*
.
" -
Беспроводная связь
301
, —
.
$ [ . 9 "
%
. /
, . &
.
~
,
$ ,
, , " ,
. ;, % , "
, "
. /
,
$ . 4
,
, . / $ . Z $
"
. /
%
. 7 ,
,
. > " $ $ " , . &
" , $ . ; $
" $
0 — 7
[ ,
.
& $ $ $
. _ "
,
$
,
" $
. & % ,
, —
,
.
, ,
, "
Радиопомехи
+
$ . 4
, ,
-
% "
.
*
,
9 Wi-Fi ,
!,
$
.
7
"
$
" ,
" , ,
,
.
0
, , $ ,
.
0
$
. $
. = $ ( ) " ,
—
%. $ %
,
, ,
, " . 3 , " -
302
$
% $ . ; , $
,
" . ; $
.
#" %
. $
. 2
"
.
Мультиплексирование
и протоколы
, "
. #
, $,
,
. & $
%
:
, ,
. & $,
,
$
. #
. /
, . 4
,
,
,
"
. + ,
.
Глава 6
+ ,
, $ ,
. ;
"
%
. + , . 9
—
(
). $
.
9 $ , , .
3
"
%,
% ,
(
1: % ,
% % , ). + ,
, ,
%
() "
.
/ " " (
) .
*
% . 4
"
,
" . & $
! (
). / ,
. + " , ,
$ .
&
Беспроводная связь
. * % $
,
% .
7 $ ,
,
.
/ .
; , ,
.
.
* , Bluetooth, ZigBee Wi-Fi — $
,
.
& $
( Wi-Fi —
$
Ethernet). 0
$
,
,
. 0
,
. 3
—
%
. 0 " .
Радио: передатчики, приемники
и приемопередатчики
, %, , -
? " , ,
, ,
. & % . > ,
, (,
, ) ,
.
303
*
. #
. &
,
, ,
,
,
. ; ,
. 4 ,
" . 3
" , " . ,
,
. *
.
& " %
,
.
* , Bluetooth 2
Bluetooth,
,
%. 9 ,
" ,
. =
% ,
% % .
# % ,
. /
, %, " -
, " .
Глава 6
304
Радиосети
Расстояние, на которое сообщение может передаваться по радио, в основном зависит от мощности передатчика и чувствительности приемника. Повышение мощности передатчика означает
повышение расхода электроэнергии. Но дальность передачи сообщения можно повысить, используя радиосеть. В таком случае сообщения можно передавать по цепочке от одного радиоустройства к другому или сохранять, пока требуемый приемник не окажется в радиусе действия
передатчика. Технические характеристики радиосети определяются методом ее управления балансировкой энергопотребления, радиуса действия и доставки сообщений.
Топологии радиосетей
9 3
. =
! ! !
. &
"
$
( . 6.7, ), —
% " ( . 6.7,
). & , , % "
( . 6.7,
).
# % " . X $
,
"
.
,
. ;
. &
,
" , % " .
X ( . . 6.7, )
" . 0
% "
, ,
% .
Bluetooth.
Рис. 6.7. Три типа топологии радиосетей: полносвязная (слева), звездообразная (в центре) и ячеистая (справа). В первом типе
все узлы соединены друг с другом напрямую, во втором — обмен между периферийными узлами реализуется через один центральный узел, а в третьем — сообщения могут передаваться от одного узла другому через цепочки промежуточных узлов
Прямое соединение узлов сети
Топология «Звезда»
Ячеистая топология
Беспроводная связь
305
& ( .
. 6.7, )
% "
,
. /
Wi-Fi,
% ( ).
& ( . . 6.7,
)
% " —
" ,
, % . *
" ,
, $ % "
, "
% . , "
$ . 7 % "
" ,
,
% - .
$ % $ " " ,
,
" .
`
,
.
4
, %
%
,
% .
Сеансы и сообщения
#
$
(
) — "
.
-
. $
,
" . 3 ,
(
" ), "
. $ "
.
3
, ,
% ,
. # Bluetooth, 2,
,
.
X
Wi-Fi ,
$ UDP,
, $ TCP.
=
.
9
( , TCP
,
UDP), $ . 3
( " )
$ $ , $
. *
" "
% . "
" ,
" ,
" , ,
"
" .
Глава 6
306
Стеки протоколов беспроводной связи
;
. /
( ,
4),
—
"
,
.
"
, $
,
" ,
. /
,
,
8.
# .* , "
, $ "
,
$ . # %
. * , : Wi-Fi, Bluetooth ZigBee —
. & $
IEEE 802,
Ethernet. # Ethernet 802.3, Wi-Fi —
802.15.1, ZigBee — 802.15.4. 0
"
. * Wi-Fi Bluetooth
,
$ " $ " .
Физические радиоинтерфейсы
Z
,
:
X3, SPI I2C
,
, USB -
,
.
9 , ,
,
,
" .
Выбор и приобретение радиоустройств
В настоящее время доступно много разнообразных протоколов цифровой радиосвязи для разных промышленных, бытовых и прочих приложений, и каждый год появляются все новые протоколы. Все эти протоколы предназначены для выполнения разных задач и имеют различные
ограничения. Поэтому, прежде чем приступать к работе над каким-либо проектом с использованием радиосвязи, следует внимательно рассмотреть доступные варианты. Далее отмечаются
несколько моментов, которые следует принять во внимание при выборе радиоустройства для
своих проектов.
Беспроводная связь
307
% . + $ ,
. *
Wi-Fi Bluetooth. /
% ( ,
% , ),
(
, %, , . .) +
. &
—
" — ZigBee.
3 ANT "
— ,
. =
% "
LoRa.
= $
. * ,
ZigBee
XBee 802.15.4 Digi
ZigBee
,
Digi . /
,
Digi. 0
, Wi-Fi
Bluetooth %
,
.
$ %
,
$ Bluetooth
Nordic Texas Instruments
Bluetooth
% % , . = " ,
,
, % .
~
% , , $
,
. 4 , %
. 3 %
" "
, %
.
0 %
%
— $
.
— % .
&
, , $
. ;
, ,
,
%
« », %
% ,
$
. 4
, ,
. 3
, , , %
.
?
\ &
.
" , % : , SPI I2C. ; ,
.
?
\ . >
?
Глава 6
308
?
?
(
.
*
" ? $ ,
? # %
$
? X ,
,
"
, , %
,
.
,
, ,
$
. * ,
%
,
Wi-Fi % . =
%
, ,
- ,
" % " .
3 %
% .
?
. =
"
( " ), ,
,
"
.
?
D , , , , ,
. & .
0
— $
-
,
. 7 ,
$
,
,
$ . =
,
.
?
, ,
,
%
% . +
, "
% ,
$
.
,
.
& . 6.2
, . &
$
. %
$ , XBee
Digi % ,
- . *
, +
,
Wi-Fi Bluetooth. 0
Bluetooth
, Wi-Fi, ,
Bluetooth SIG5
, Wi-Fi Alliance6
.
HopeRF ,
5
Bluetooth Special Interest Group — Bluetooth.
6
Wi-Fi Alliance —
, "
Wi-Fi- " Wi-Fi.
Беспроводная связь
309
Таблица 6.2. Технические характеристики нескольких наиболее популярных радиоустройств,
используемых в микроконтроллерных проектах. Из них мы уже знакомы с устройствами Wi-Fi
Радиоустройство
Протокол
Частота
Топология
ESP8266
Wi-Fi
2,4 qq
«2 »
_ (TCP UDP)
WINC1500
Wi-Fi
2,4 qq
«2 »
SPI
Digi Xbee
802.15.4
802.15.4,
[
2,4 qq
,
X3
* "
(
X3)
HopeRF
RFM69
[
433, 868,
915 7q
SPI
*
"
HopeRF
RFM95W
LoRa
433, 868,
915 7q
SPI
*
"
Nordic 51822 Bluetooth LE 2,4 qq
SPI
*
"
Cambridge
Silicon
CSR8510
Bluetooth LE 2,4 qq
USB
*
"
RF Link
TTL Serial
"X3
*
( X3)
434 7q
% , $ % . + ,
LoRa,
LoRa Alliance7, "
, $ ,
.
SparkFun Seeed Studio
-
X3. * $
,
,
. =
% " .
7
LoRa Alliance (3 LoRa) — , "
LoRa- .
Проводной
интерфейс
Протокол на основе сообщений (пакетов)/сеансов
_ (TCP UDP)
"
. Curie Intel
Bluetooth
Nordic Semiconductor, "
Arduino 101. 3 ESP8266, , Wi-Fi. X $,
, $
,
" % .
& " ,
LoRa,
, , Bluetooth LE.
Глава 6
310
Проект 11
Дуплексная радиосвязь
В этом проекте мы подключим радиоприемопередатчик и кнопку к микроконтроллеру. Для создания канала связи потребуются два таких устройства. Каждый микроконтроллер при нажатии
его кнопки будет посылать сигнал другому. Когда один из микроконтроллеров получает сообщение, он реагирует на это событие, зажигая светодиод, а также отправляет сообщение по каналу
последовательной связи.
Bluetooth Wi-Fi , " " , ,
- ,
" % . /
%
.
$ , HopeRF
Semtech. & $ " % .
9
RFM9x
HopeRF
SX127x Semtech LoRa. /
,
%
"
$ . 0 %
! ,
, $
.
( " ), $
,
.
LoRa
, .
/
. 0
LoRa LoRaWAN.
0 %
,
" # .
#" ,
% " , .
/
.
LoRa ,
LoRa !
(sync
word),
" ,
$ .
& ,
" ,
. [
,
" , % .
* ,
125 q,
— 915 7q. [
, % " 125 q
915 7q. [ $ 6 12, 7. >
, $
.
Беспроводная связь
311
Схема организации дуплексной радиосвязи
Требуемые компоненты
Arduino- , 2–3 %.
+ :
/ ,
SPI.
> , 2–3 %.
9 HopeRF RFM95W
Semtech SX1276, 2–3 %.
, 2–3 %.
# , 2–3 %.
9
220 0, 2–3 %.
* , , . 3 ,
, $
, " . & $
RFM95W LoRa Radio Transceiver
Breakout Adafruit. * $
% Dragino
LoRa Arduino, Wireless SX1276
Modtronix
Seeed Studio. / : 868–915 7q
433 7q.
915 7q, . X
SPI, $ " ( . 6.8–6.11).
MOSI, MISO,
(SCK) (CS),
(RST)
(IRQ G0),
. 0 ,
(G0)
D1 MKR1000 ( . . 6.10 6.11),
D2, Arduino Uno Arduino
101 ( . . 6.8 6.9), $
.
' % , . "
$ %,
(ANT). [
!. «4
» $ .
& , 915 7q
7,8 . / , $ (
,
—
). 7
$
. — — % $
. & $ " , ,
30–50
.
Полосы радиочастот ISM
& , , %
.
/ ISM, %
,
8. =
$
% . =
ISM
8
ISM — Industrial, Science, Medical.
7 $
. =
LoRa " :
4 : 863–870 7q 433 7q
#3: 902–928 7q
3 : 915–928 7q
: 779–787 7q 470–510 7q
Глава 6
312
A B
C D E
F
G H
I
J
1
1
5
5
10
10
Антенна
15
VIN
G1
GND
G2
EN
G3
G0
G4
SCK
G5
15
MISO
MOSI
CS
20
20
RST
RFM95 Radio
25
25
30
30
A B
C D E
F
G H
I
J
Рис. 6.8. Монтажная схема подключения адаптерной платы с радиомодулем RFM95W к плате Arduino 101 или Arduino Uno
(для обеих этих плат задействуются одни и те же выводы). Обратите внимание на подключение антенны, длина которой должна
быть около 7,8 см для частотного диапазона 915 МГц и 16,5 см для 433 МГц. Обе антенны четвертьволновые
Рис. 6.9. Принципиальная схема подключения адаптерной платы
с радиомодулем RFM95W к плате Arduino 101 или Arduino Uno
+3,3 В
+3,3 В
G0
Напряжение
питания
D13
SCK
D12
MISO
D11
MOSI
Модуль
RFM95W
7,8 см
CS
Микроконтроллерный модуль
Arduino 101 или Arduino Uno
RST
D7
ANT
Общий
D6
D5
D4
D3
D2
220 Ом
Общий
Напряжение
питания
Беспроводная связь
313
45
50
55
45
50
55
60
40
RFM95 Radio
40
J
60
35
A B
C D E
F
G H
I
CS
RST
G5
MOSI
G4
MISO
G3
SCK 35
30
30
G2
25
25
G0
20
20
EN
15
15
G1
10
10
GND
5
5
VIN
1
A B
C D E
F
G H
I
J
1
Антенна
Рис. 6.10. Монтажная схема подключения адаптерной платы c радиомодулем RFM95W к плате MKR1000. Обратите внимание
на подключение антенны, длина которой должна быть около 7,8 см для частотного диапазона 915 МГц и 16,5 см для 433 МГц. Обе
антенны четвертьволновые
Рис. 6.11. Принципиальная схема подключения адаптерной платы
c радиомодулем RFM95W к плате MKR1000
+3,3 В
+3,3 В
G0
Напряжение
питания
SCK
MISO
Микроконтроллерный
модуль
MKR1000
D10
MOSI
D9
CS
D8
RST
D7
Модуль
RFM95W
D4
D3
D2
D1
220 Ом
7,8 см
ANT
Общий
D6
D5
Общий
Напряжение
питания
Глава 6
314
Код для проекта дуплексной радиосвязи
=
%
Arduino. * Stream — , " ,
, — $
LoRa. = $ ,
LoRa, LoRa by Sandeep Mistry . = $
,
https://github.com/sandeepmistry/
arduino-LoRa.
Пишем код
,
.
2
( irqPin)
,
% . *
5
( .
! «G
»). & ,
Arduino Uno 101 $ 2,
Cortex-M0 ARM (
MKR1000) — 1.
=
. +
:
& setup() ,
915 7q. 0 91543
$
#. 2 $
915×103. 2
. * , ,
:
/*
$ LoRa
: Arduino
*/
#include <SPI.h> //
#include <LoRa.h>
const
const
const
const
const
int
int
int
int
int
'' :
buttonPin = 4;
receiveLED = 5;
csPin = 7; // +
- LoRa
resetPin = 6; // Z LoRa
irqPin = 1; //
int lastButtonState = HIGH; // \-
byte msgCount = 0; // - -
byte localAddress = 0xBB; //
byte destination = 0xFF; //
byte syncWord = 0xB4; // Z - $ ' ( )
byte spreadingFactor = 8; // % (6-12);
void setup() {
Serial.begin(9600); // \ # $ ' $
LoRa.setPins(csPin, resetPin, irqPin); // %
// CS,
IRQ
if (!LoRa.begin(915E6)) { // \ # $
// $ 915 &#
Serial.println("^ # $# '
LoRa. .");
while (true); //
# $#
}
LoRa.setSyncWord(syncWord);
LoRa.setSpreadingFactor(spreadingFactor);
LoRa.setTimeout(10); // $ 10
// - Stream
Serial.println("\ # $# LoRa .");
//
:
pinMode(buttonPin, INPUT_PULLUP);
pinMode(receiveLED, OUTPUT);
}
Беспроводная связь
[ loop()
. 4 " ,
, $ ,
. 0 , $
"
. 2
. 4
, " ,
$ sendMessage(),
. 2
lastButtonState
" .
& onReceive(),
. / " "
$ . *
"
LoRa.parsePacket(),
Stream,
4. /
" . 7
7 " UDP:
[ sendMessage() ,
" .
& , , " (destination — 1 ),
(localAddress — 1 ), " (msgCount —
1 ),
" (outgoing.length — 1 ),
315
void loop() {
int buttonState = digitalRead(buttonPin);// Z
//
if (buttonState != lastButtonState) { //
$ ,
delay(3); // , - $
if (buttonState == LOW) {
// $
// ,
String message = "HeLoRa!"; //
sendMessage(message);
Serial.println(message); // +
R
//
}
lastButtonState = buttonState; // Z-
//
}
// +
$
onReceive(LoRa.parsePacket());
}
% # ' onReceive:
Глава 6
316
" .
2
" . ~ $ «
» ,
$ ,
. & onReceive(),
, ,
" " :
void sendMessage(String outgoing) {
LoRa.beginPacket(); // ^
LoRa.write(destination); //
LoRa.write(localAddress); //
LoRa.write(msgCount); //
//
LoRa.write(outgoing.length()); // $
//
LoRa.print(outgoing); //
LoRa.endPacket(); // $
//
msgCount++; // M $
}
* , onReceive(). , "
"
" ,
. 4 $
%
0, "
" loop().
4 "
, $, .
2
: , , "
" (
" ), " ,
, " :
void onReceive(int packetSize) {
if (packetSize == 0) return; // ,
// $ #
2
"
.
4
, "
" % . ,
$
$ % "
. 4
, , "
:
"
if (msgLength != incoming.length()) { //
//
Serial.println(" : . ");
return; // % #
}
// R
,
if (recipient != localAddress && recipient != 0xFF) {
Serial.println(" .");
return; // % #
}
= $ $ " . $ ,
, LoRa
$ : %
/%.
// R
,
//
:
Serial.print(" : ");
Serial.println(sender, HEX);
Serial.print(" : ");
Serial.println(recipient, HEX);
Serial.print("ID : ");
digitalWrite(receiveLED, HIGH); // +'
//
// Z $ :
int recipient = LoRa.read(); //
byte sender = LoRa.read(); //
byte incomingMsgId = LoRa.read(); // %
// -
byte msgLength = LoRa.read(); // -
//
String incoming = LoRa.readString();//
Беспроводная связь
317
* , $ %
:
Serial.println(incomingMsgId);
Serial.print(" : ");
Serial.println(msgLength);
Serial.print("Z : ");
Serial.println(incoming);
Serial.print("RSSI: ");
Serial.println(LoRa.packetRssi());
Serial.print("Snr: ");
Serial.println(LoRa.packetSnr());
Serial.println();
digitalWrite(receiveLED, LOW); // +'
//
}
2 $
( "
)
. =
.
*
. 2 CoolTerm, ( CoolTerm
) -
- . &
.
Широковещательные сообщения
. / , onReceive(),
" . &
, %
" , ,
! 9. /
,
.
4
,
, $ $ -
(
localAddress),
0xFF.
onRecieve()
" " ,
$ .
*
, % " ,
, . 0
"
,
% " ,
" "
. &
$ " ,
+
$
, % , ,
, $
$ . 0 ,
$
.
Слова синхронизации
и фактор распределения
&
"
, " .
/ ,
9
0 . promiscuous mode.
Глава 6
318
LoRa . = ,
.
, $ $ .
&
"
. 9
"
.
, , —
% .
~ % $ ,
.
0
:
— . /
HopeRF Semtech,
PDF : www.hoperf.
com/upload/rf/RFM95_96_97_98W.pdf ( RFM95W HopeRF) www.
semtech.com/images/datasheet/sx1276.pdf ( SX1276 Semtech). 0 $
.
Уровень принимаемого сигнала
0 , ,
(+X#)10, "
. > $ 8. $ $ , "
% .
$ ,
$, "
.
Отношение сигнал/шум
= , ,
/11. /
,
, —
,
%. ' % $ % , . 0
% /%
, %
" " . * %
, .
Циклический контроль
избыточности
&
LoRa
! 12,
. 7 ! #
!# !
. 4 ! #
!
.
& # ! ! ,
,
. 4 # ,
, ! .
! !
% ,
! LoRa.crc(). / , .
* * *
9 LoRa
. + $
%
, % , " .
11
10
0 . RSSI, Received Signal Strength Indicator.
12
0 . SNR, Signal-to-Noise Ratio.
0 . CRC, Cyclic Redundancy Check.
Беспроводная связь
319
Проект 12
Управление фотокамерой с помощью Bluetooth LE
В главе 2 мы научились подключать микроконтроллер к персональному компьютеру с помощью
радиомодуля Bluetooth (см. проект 3). Там мы использовали профиль последовательного порта
(Serial Port Profile) Bluetooth из спецификации Bluetooth 2.0. Здесь же мы возьмем устройство
спецификации Bluetooth 4.0 (называемой также Bluetooth LE) и задействуем его для управления
инфракрасным пультом фотокамеры из проекта 10 этой главы.
/ % , % ,
. & , ,
, $
— , % . /
Bluetooth.
# Bluetooth 4.0 (Bluetooth LE)
.
Arduino 101 "
Bluetooth LE,
$ . *
. > Bluetooth,
,
Bluetooth nRF8001 nRF58122
Nordic Semiconductor. /
%
,
, — , ,
BLE Nano RedBear Lab. 4
, Bluetooth LE,
.
& 4.0 Bluetooth %
. Z $
— —
$ $ ,
Bluetooth. ; SPP (Serial Port Profile, )
Bluetooth GAP (General
Access Profile, " ),
GATT (Generic Attribute Profile, "
). & «Make: Bluetooth» ( «Maker Media»), 3
3 (Alasdair Allan), = (Don
Coleman) # 7 (Sandeep Mistry),
" Bluetooth LE.
Bluetooth LE: центральные
и периферийные устройства
X Bluetooth LE
" : .
,
GAP (General Access Profile, "
). Z
%
,
.
,
! . =
GATT (Generic Attribute Profile,
" ). ;, "
Bluetooth
LE
— , Z, " : . *
" ,
$
. 3
,
— , +.
$ \ ,
,
Глава 6
320
, ,
.
* GATT
SPP ?
SPP
Bluetooth ,
. 2
, -
. -
, $ , SPP
. &
«
% —
% »,
. & $, GATT
Рис. 6.12. Устройство Bluetooth 2.0 (схема вверху) — в нашем случае светильник — предоставляет профиль SPP. При подключении к устройству весь обмен данными происходит через поток данных последовательного порта. Центральное устройство
(планшет, смартфон, ноутбук) считывает все три элемента данных и выбирает требуемые.
Светильник на Bluetooth 4.0 (Bluetooth LE), показанный на схеме внизу, предоставляет сервис Z, имеющий три характеристики. В зависимости от свойств этих характеристик центральное устройство может выполнять операции чтения, записи или
подписки с любой из них
Bluetooth 2.0: профиль последовательного порта (SPP)
Сопряжение
Поток данных
Яркость, Оттенок, Вкл \n
Планшет, смартфон, ПК
Светильник
Bluetooth 4.0: профиль общих атрибутов (GAP)
Сопряжение
Свет
Вкл
Яркость
Оттенок
Планшет, смартфон, ПК
(центральное устройство)
Светильник
(периферийное устройство)
Беспроводная связь
.
(
),
,
. /
, .
,
. & ,
,
"
.
X Bluetooth 2.0
. * , Bluefruit,
2,
SPP, % Bluetooth — (Audio Profile),
%
— HID
(Human Interface Device,
--
321
% ). & $,
Bluetooth 4.0 (LE)
. , %
Bluetooth LE , ,
, ,
,
.
0
Bluetooth . 6.12.
~
, ,
" ,
, . 7 ,
" " $ .
Схема управления фотокамерой с помощью Bluetooth LE
= Arduino 101
, 10
( . . 6.5), $ "
Bluetooth LE.
3 Arduino Uno nRF8001 Nordic
Semiconductor
. 6.13 ( ) 6.14 ( ). 7
SPI, $
.
$
Arduino
ATmega328
Cortex-MO —
SPI , " .
~ $ Arduino Uno, Arduino 101
MKR1000, Arduino -
Требуемые компоненты
Arduino 101
Arduino
Bluetooth LE nRF8001 nRF51822 Nordic Semiconductor, 1 %.
+ :
/ , Bluetooth LE.
+
9
, 1 %.
220 0, 1 %.
> %
, 1 %.
%
"
, ,
Bluetooth LE, 1 %.
Bluetooth nRF8001 nRF51822 Nordic Semiconductor
, $ .
Глава 6
322
A B
C D E
F
G H
I
J
1
1
5
5
10
10
SCK
MISO
15
15
MOSI
nRF8001
Bluetooth LE
REQ
RDY
UNO
ACT
RST
20
3Vo
20
GND
VIN
25
25
ON
30
30
A B
C D E
F
G H
I
J
Рис. 6.13. Монтажная схема проекта управления фотокамерой посредством Bluetooth LE на основе платы Arduino Uno и радиомодуля nRF8001 компании Nordic Semiconductor. Для платы Arduino 101 можно использовать схему из проекта 10, поскольку эта
плата содержит встроенный радиомодуль Bluetooth
Рис. 6.14. Принципиальная схема проекта управления фотокамерой посредством Bluetooth LE на основе платы Arduino Uno
и радиомодуля nRF8001 компании Nordic Semiconductor
+3,3 В
Модуль
микроконтроллера
+3,3 В
D13
SCK
D12
MISO
D11
MOSI
D10
Req
D9
RDY
Напряжение
питания
Модуль nRF8001
Act
Reset
D7
Общий
D2
Общий
220 Ом
Инфракрасный светодиод
Беспроводная связь
323
+
, "
, — .
* $
cameraService. #
— , shutter
, "
.
$ 1,
. %
shutter 0.
X Bluetooth LE,
128-
UUID13 — : 2f45c1ee-5048-11e6-beb8-9e71128cae77
( % ). *
— ,
—
, 16-
UUID,
Bluetooth SIG (
UUID
: https://
www.bluetooth.com/specifications/gatt/services).
#
0-180F, ,
13
UUID, Universally Unique Identifiers —
.
,
UUID, , $
. =
128-
UUID,
" "
. 0
$ 16- .
Код для управления камерой
по Bluetooth LE
& $
BLEPeripheral, # 7
(Sandeep Mistry). = , Arduino 101,
" . &
Arduino 101 CurieBLE
. = CurieBLE : www.
arduino.cc/en/Reference/CurieBLE, BLEPeripheral — : https://
github.com/sandeepmistry/arduino-BLEPeripheral. 0
,
( ,
Arduino 101,
% ).
Пишем код
, - /*
M ' Bluetooth LE
: Arduino 101
. ! Arduino 101 /*
> CurieBLE:
#include <CurieBLE.h>
Внимание!
' $ Arduino 101, 2.0.1
( ) Arduino 101.
" .
Глава 6
324
! =
>
SPI
BLEPeripheral.
2
" Request (2 ), Ready
(q ) Reset (# ).
=
$ , $ :
/*
UUID
. 9
: BLEIntCharacteristic ( $
) —
, BLEFLoatCharacteristic — " ,
BLECharCharacteristic —
ASCII . .
$
.
//
% UUID :
BLEService cameraService("F01A");
//
% UUID - $
BLEIntCharacteristic shutter("F01B", BLERead | BLEWrite);
const int IRPin = 7; //
,
// ' \-
const int CAM_NIKON = 1;
// # %-
const int CAM_CANON = 2;
int buttonState = 0;
//
int lastButtonState = 0;
//
Bluetooth LE IR Camera Control
context: Arduino Other
/*
#include <SPI.h> //
// SPI BLEPeripheral
#include <BLEPeripheral.h>
// N
,
// Bluetooth Request, Ready Reset
// ( ,
Arduino 101)
const int BLE_REQ = 10;
const int BLE_RDY = 2;
const int BLE_RST = 9;
// 9
# :
BLEPeripheral blePeripheral = BLEPeripheral(BLE_REQ, BLE_
RDY, BLE_RST);
$
10:
! Arduino 101
setup()
,
, .
. 2 shutter,
$ .setValue(),
,
.begin():
void setup() {
Serial.begin(9600);
BLE.begin();
//
%
//
" :
BLE.setLocalName("irRemote");
BLE.setAdvertisedServiceUuid(cameraService.uuid());
//
-
// % :
BLE.addService(cameraService);
cameraService.addCharacteristic(shutter);
BLE.advertise(); // "
//
shutter.setValue(0); // $
// - $
Serial.println("^ ");
}
Беспроводная связь
325
! = , >$ = BLEPeripheral,
$ blePeripheral,
.addAttribute().
& $
blePeripheral.begin()
:
void setup() {
Serial.begin(9600);
//
%
//
" :
blePeripheral.setLocalName("irRemote");
blePeripheral.setAdvertisedServiceUuid(cameraService.uuid());
//
-
// % :
blePeripheral.addAttribute(cameraService);
blePeripheral.addAttribute(shutter);
blePeripheral.begin(); //
//
shutter.setValue(0); // $
// - $
Serial.println("^ ");
}
loop() % $ ,
$ .poll() (
, ).
/
.written()
,
,
%
shutter.
shutterClick(), " .
void loop() {
// %
// :
BLE.poll(); // Arduino 101 $ R
// blePeripheral.poll(); //
#
// BLEPeripheral
// # % #
// - $:
if (shutter.written()) {
//
$ - 1:
if (shutter.value() == 1) {
shutterClick(CAM_NIKON); // \-
// $
Serial.println("");
shutter.setValue(0); // Z $ 0
}
}
}
&
shutterClick() IRPulse()
:
Глава 6
326
Приложения диагностики для Bluetooth LE
;
—
%
Bluetooth
LE. $
,
, . #" , "
Bluetooth LE ,
. 7
"
$ : LightBlue
macOS LightBlue Explorer
iOs — Punch Through
Designs. 3 Android nRF Connect
Nordic Semiconductor. & $
macOS, iOS Android. X
, % .
& "
, $
% .
Приложение LightBlue для macOS
LightBlue
Bluetooth LE.
, "
( . 6.15) . 0
. " $
-
. ¥
, " .
*% $ irRemote,
. ; , Arduino 101-XXXX,
MAC Bluetooth. ; ,
,
.
¥
, ,
UUID,
cameraService. = " ( shutter). = $
UUID,
, Read , . 2
%
ASCII. &
0-01 % <Enter>. LightBlue
Рис. 6.15. Рабочее окно приложения
LightBlue для сканирования устройств
Bluetooth LE. В окне выводятся обнаруженные устройства Bluetooth LE,
и там же можно просматривать их параметры
Беспроводная связь
327
$ ,
%
. $
"
$
0,
$ .
Программа LightBlue Explorer
для iOS
~ $ , ,
:
$ , "
. 0
, "
( . 6.16).
; , , $
. *
%
0-. '
, Hex
$ ,
,
.
Рис. 6.16. Приложение LightBlue Explorer для iOS — здесь показан экран
просмотра характеристик
Приложение nRF Connect
для Android
nRF Connect Nordic
Semiconductor
" "
Android,
Bluetooth LE.
, " Bluetooth
LE. * $ ( . 6.17, )
,
( . 6.17, ) —
, ( . 6.17, ) — -
,
, $ % .
2
,
. =
UINT 8
( . . 6.17, ), 1
( . 6.17, ). * Send,
.
Глава 6
328
а
б
в
г
Рис. 6.17. Приложение nRF Connect для Android
*
*
*
* , Bluetooth
LE $
,
%
" . &
%
Bluetooth LE
.
Центральное приложение Bluetooth LE на node.js
= Bluetooth LE
,
.
~
Bluetooth
LE " , , Windows,
$ . #"
Bluetooth LE macOS, ,
, " . 0
node.js, macOS, Linux
Windows. > noble # 7 .
& %" $
node.js,
%
- . $
p5.js,
" .
Установка библиотек noble и express
> noble node.js.
, express,
.
# , , , NobleCameraControl,
, :
$ mkdir NobleCameraControl
$ cd NobleCameraControl
$ npm install noble express
Беспроводная связь
329
&
.
;, % macOS
, %
2012 , Bluetooth
Bluetooth LE. =
Windows Linux,
"
, Bluetooth LE,
CSR8510 Cambridge Silicon,
$ ( . . 6.2). =
$
Windows. =
Linux, Raspberry Pi, " :
$ sudo apt-get install bluetooth
bluez libbluetooth-dev libudev-dev
= Windows
USB
Bluetooth, noble ,
$
. # $
Zadig,
http://zadig.akeo.ie,
noble
" https://github.
com/noble/noble. ;
$
Linux. # noble, .
Код сервера node.js
/
HTTP,
" -
Bluetooth LE.
" : $
,
,
, , . /
node.js
, $
,
.
Создаем псевдокод
= ,
% node.js:
.
,
, :
//
//
'' :
'
//
//
//
//
//
//
',
%
% ,
,
'
-
//
//
//
//
//
//
'
-
% :
-
- - $ shutter
-
//
//
//
//
//
//
HTTP $ GET #
$:
- shutter:
$
HTTP $
Глава 6
330
Пишем код
&
express.
— noble
2 $ express:
/*
Z Bluetooth LE noble
: node.js
*/
var noble = require('noble');
var express = require('express');
var server = express();
// C$ " server,
// $ express
=
UUID
% ,
. 4"
.
2 public
,
" express.
use(). #
:
&
% .
noble,
(.on('stateChange')),
— (.on('discover')).
,
.
$
express %
GET /click:
,
stateChange.
,
Bluetooth stateChange.
var cameraUuid = 'f01a';
var
var
var
var
// \ % UUIS
//
shutterUuid = 'f01b'; // \ % UUID
// - $
shutter = null; // - $
clickCount = 0; // $
device; // %
// % $ - /public:
server.use('/',express.static('public'));
// Z % // % UUID
noble.on('stateChange', scanForPeripherals);
noble.on('discover', readPeripheral);
server.listen(8080); // express
server.get('/click', click); //
$ GET
Беспроводная связь
331
& ,
,
,
. ;
.startScanning(),
UUID
:
// # $ stateChange:
function scanForPeripherals(state){
if (state === 'poweredOn') { //
// Bluetooth ',
noble.startScanning([cameraUuid], false); //
// % // % UUID
console.log("+ ...");
} else { // Bluetooth ',
noble.stopScanning(); //
console.log("M Bluetooth .
.");
process.exit(0); //
.
}
}
,
,
readPeripheral(). / "
% readServices()
.
device, % :
// # $ discover:
function readPeripheral (peripheral) {
console.log(' ' + peripheral.advertisement.
localName);
console.log('M : ' + peripheral.rssi);
function readServices() {
device = peripheral; // Z- %
//
console.log(' : ' +
peripheral.advertisement.localName);
//
- - .
//
- $ % # ' explore:
peripheral.discoverAllServicesAndCharacteristics(explore);
}
noble.stopScanning(); //
peripheral.connect(); // '
// %
peripheral.on('connect', readServices); //
// '
}
#
,
, explore()
// # explore
- .
//
- , %.
// , R
,
// ' % #
readPeripheral().
function explore(error, services, characteristics) {
// Z -
-
console.log('Z : ' + services);
console.log(' : ' + characteristics);
//
% UUID -
// UUID - shutter
for (c in characteristics) {
if (characteristics[c].uuid === shutterUuid) {
// - ,
shutter = characteristics[c];
}
}
}
.discoverAllServicesAndCharacteristics(). / -
"
UUID shutter. *
,
$ ,
$
- . $
,
:
Глава 6
332
* , GET HTTP. & $
,
" ,
shutter, .
&
HTTP % % :
// # HTTP $ GET
// $:
function click(request, response) {
var result = "^ % "; // Z ,
//
// '
' - :
if (device.state === 'connected' && shutter != null ) {
// $ - :
var output = new Buffer([0x01]);
shutter.write(output, true);
clickCount++; // M $
// $
result = "Click count: " + clickCount; // \$
}
response.end(result); // HTTP
}
& . # server.js
NobleCameraControl
, :
node server.js
Bluetooth LE.
4 %
, $ " :
+ ...
irRemote
: irRemote
Z : {"uuid" :"f01a","name" :null,"type":null,"includedServic eUuids":null}
: {"uuid":"f01b","name":null,"type":null,"Z :":["read", "write"]}
,
,
. + ,
$ ,
. = ArduinoBLE
Arduino,
CurieBLE — ARDUINO 101XXX, XXX
%
MAC .
Веб-интерфейс
%
%
, "
" - . =
,
,
$
5. = $
NobleCameraControl public,
—
p5.js. #
p5.js
p5.js, $ 5. +
p5-manager, p5.js
" :
$ p5 generate --bundle public
2
public p5.js :
$ p5 update
*% HTML
$ : div
"
.
0 $ $ "
JavaScript,
% " p5.js.
GET,
. HTML %
index.html
p5.js .
7 $
% JavaScript,
sketch.js.
Беспроводная связь
333
Пишем код веб-страницы
& sketch.js
:
/*
Z # \-
: p5.js
*/
p5.js
var shutterButton; // $
var messageDiv; // $
//
& setup()
. /
$
. = touchEnded getShutter(). 7
$ :
function setup() {
// Z$ $, $ #
//
$ % # ' $ getShutter()
shutterButton = createButton('shutter');
shutterButton.position(windowWidth/2, 20);
shutterButton.touchEnded(getShutter);
// Z$ $
$ #:
messageDiv = createDiv(" ...");
messageDiv.position(20, 50);
}
[
// # $ % #
$
function getShutter() {
httpGet('/click', 'text', clickDone);
}
getShutter() GET HTTP,
$ p5.js httpGet().
&
,
.
= — clickDone() —
:
// # $ $ httpGet()
function clickDone(data) {
messageDiv.html(" : " + data);
}
& . # , ,
% ,
server.js,
: http://localhost:8080,
. &
"
,
,
. 6.18.
# "
..., — :
- $. -
Рис. 6.18. Страница веб-интерфейса для сервера центрального устройства Bluetooth
, - .
Глава 6
334
*% %
, $ : ,
- ,
" .
# Bluetooth LE
. *
node.js ,
% ,
,
IP-
% . /
" .
Заключение
Беспроводная связь в некотором роде значительно отличается от проводной. Вследствие осложнений, связанных с природой беспроводной связи, нельзя рассчитывать на бесспорное прохождение сообщений, как в случае с проводной связью, поэтому нужно определиться со способами
решения подобных проблем.
, 4 %
% ,
% - " " %, "
, Bluetooth
, -
" - , Wi-Fi,
"
, , $, ,
. $ , & % ,
- %.
,
%
; ,
,
. & - — — 2,
" - $
—
.
- %- 7 " $ . ,
* - % ,
, , " $
. &
, " ( ),
,
,
TCP $ :
. & "
$
" .
. = Городской сонар. Авторы Кэйт Хартман (Kate Hartman), Кэти Лондон (Kati London) и Саи Срискандараджа
(Sai Sriskandarajah)
& %
. 7
Bluetooth ( % ). &
, ,
,
" $ , "
, +
.
Беспроводная связь
335
Глава 7
БЕССЕАНСОВЫЕ СЕТИ
И ДВОИЧНЫЕ ПРОТОКОЛЫ
Сетевые подключения, с которыми мы до сих пор имели дело,
были в основном выделенными соединениями между двумя
объектами. Для последовательной связи требуется управление
последовательным портом, а для подключений почты, браузера
и telnet — сетевой порт. Во всех этих случаях присутствует
устройство, которое предоставляет порт (обычно это сервер),
и устройство, запрашивающее доступ к порту (так называемый
клиент). Классическими примерами этого подхода были проекты
главы 5. В этой главе мы рассмотрим, как организовать прямое
взаимодействие любого сетевого устройства с другим сетевым
устройством или одновременно с несколькими другими
сетевыми устройствами.
Все рассмотренные нами ранее протоколы были текстовыми.
Но некоторые протоколы требуют умения интерпретировать
цифровые данные в виде чисел или битов. Эти вопросы мы также
рассмотрим более подробно в этой главе.
Туфли-дирижеры Эндрю Шнайдера (Andrew Schneider)
;
Digi.
«» .
Глава 7
338
Компоненты для проектов этой главы
Коды поставщиков
?
A — Arduino Store, http://store.arduino.cc
?
P — Pololu, www.pololu.com
?
AF — Adafruit, http://adafruit.com
?
PX — Parallax, www.parallax.com
?
D — Digi-Key, www.digikey.com
?
RS — RS, www.rs-online.com
?
F — Farnell, www.farnell.com
?
SF — SparkFun, www.sparkfun.com
?
J — Jameco, http://jameco.com
?
SS — Seeed Studio, www.seeedstudio.com
Рис. 7.1. Новые компоненты для проектов этой главы: 1. Датчик газа Hanwei на адаптерной плате. 2. Держатель для трех батареек
типа ААА. 3. Подстроечные потенциометры номиналом 47 кОм. 4. Модуль XBee S2C компании Digi. 5. Адаптерная плата XBee-toSerial. 6. Одноплатный мини-компьютер Raspberry Pi. 7. Конденсаторы. 8. Стабилизаторы напряжения на 3,3 и 5 В. 9. Транзистор
TIP120. 10. Инфракрасный дальномер Sharp GP2Y0A21YK. 11. Гнездовые разъемы. 12. Программируемые светодиоды WS2812.
13. Матовая пластиковая трубка диаметром 10 см. 14. Жестянка из-под леденцов. 15. Игрушка шимпанзе Чарли
15
14
5
4
13
3
11
1
12
6
2
7
10
9
8
Бессеансовые сети и двоичные протоколы
339
ПРОЕКТ 13. Сетевые светильники
Набор компонентов приведен для каждого отдельного светильника. Проект выглядел бы более
эффектно с большим количеством светильников (от 6 до 30), но разобраться в его работе можно
и всего с двумя.
Arduino- MKR1000, 1 +.
AF: 3156, RS: 124-0657, A: ABX00004, GBX00011
(3 4#), D: 1659-1005-ND
&
ESP8266.
SF: WRL-13231, AF: 2471
& Sharp GP2Y0A21YK,
1 +.
C , 1 +.
JJ: 2150256, D: 425-2063-ND, AF: 164, F: 1243869,
RS: 666-6564
WS2812
(NeoPixel), 3–7 +.
K - &
10 - "
.
D: 438-1045-ND, J: 20723 20601, SF: PRT12615 PRT-12002, F: 4692810, AF: 64, SS:
319030002 319030001
C 3,3 ' 5 ', 1 +.
AF: 771, D: BC4AAW-ND, SS: 320180002
"
10 , 1 +.
AF: 2226, 2858 2859, D: 1528-1610-ND,
J: 2247947, SF: BOB-13282, SS: 104990139
ПРОЕКТ 14. Предупреждение о наличии в мастерской токсичных испарений
Для этого проекта нужно собрать три отдельные схемы. Наборы компонентов приведены для
каждой из них отдельно, хотя для программирования радиомодуля используется один адаптер.
XBee-to-USB , 1 +.
J: 32400, SF: WRL-11812, AF: 247, PX: 32400.
4 XBee,
XStick 802.15.4 Digi.
D: 602-1200-ND
Компоненты для схемы датчика
C , 1 +.
D: 438-1045-ND, J: 20723 20601, SF: PRT12615 PRT-12002, F: 4692810, AF: 64, SS:
319030002 319030001
( XBee XBee Pro S2C 802.15.4.
AF: 128, D: 602-1892-ND, SF: WRL-08665,
J: 2253722, PX: 32416
D A 5 ', 1 +.
J: 51262, D: LM7805CT-ND, F: 9756078, RS: 9181971
D A 3,3 ', 1 +.
D: 497.1491-5-ND, J: 242115, F 1:703357, RS:
438-4885
9–12 ',
1 +. , $ .
SF: TOL-00298, AF: 798, J: 170245, F: 1176248
XBee, 1 +.
SS: 113100001, SF: BOB- 08276
!= +
, 2 +.
D: A26509-20-ND, J: 103377, SF: PRT-00116,
F: 1593411
!= ), 2 +.
SF: PRT-08272, D: 3M9406-ND
1 \, 2 +.
D: 1189-1324-ND, J: 94161, F: 8126933, RS: 4759009
10 \, 2 +.
D: P11212-ND, J: 29891, F: 1144605, RS: 7621736
!
Hanwei, 1 +.
SF: SEN-09405, P: 1481, PX: 605-00009
Глава 7
340
, 1 +. 9 Hanwei « » , $ « ».
SF: BOB-08891, P: 1479 1639
D , 1 +.
Компоненты для схемы
исполнительного устройства
(шимпанзе Чарли с ударными
тарелками)
C , 1 +.
D: 160-1144-ND 160-1665-ND, J: 34761
94511, F: 1855510, RS: 228-5972 826-830, SF:
COM-09592 COM-09590
( 220 , 1 +.
D: 438-1045-ND, J: 20723 20601, SF: PRT12615 PRT-12002, F: 4692810, AF: 64, SS:
319030002 319030001
( XBee XBee Pro S2C 802.15.4.
D: 220QBK-ND, J: 690700, F: 9339299, R: 707-7612
47 ,
1 +.
AF: 128, D: 602-1892-ND, SF: WRL-08665, J:
2253722, PX: 32416
+ + J , 1 +.
D: A105657-ND, J: 254028, RS: 186-205
Компоненты для схемы сервера
D
> Raspberry Pi, 1 +.
BeagleBone Green
Linux.
D: 497.1491-5-ND, J: 242115, F: 1703357, RS: 4384885
XBee, 1 +.
SF: DEV-13825, AF: 3055 3400, SS: 102010048
114990584, RS: 896-8660, F: 2525225
( XBee XBee Pro S2C 802.15.4.
SS: 113100001, SF: BOB- 08276
!= +
AF: 128, D: 602-1892-ND, SF: WRL-08665, J:
2253722, PX: 32416
XBee-to-USB- , 1 +. 0
XBee.
J: 32400, SF: WRL-11812, AF: 247, PX: 32400.
Об источнике питания для игрушки
4 % %
3 & ( , D),
3,3 &
. * $
. 4
, «»
$ %. &
.
A
3,3 ', 1 +.
, 2 +.
D: A26509-20-ND, J: 103377, SF: PRT-00116, F:
1593411
!= ), 2 +.
SF: PRT-08272, D: 3M9406-ND
D , 1 +.
D: 160-1144-ND 160-1665-ND, J: 34761
94511, F: 1855510, RS: 228-5972 826-830, SF:
COM-09592 COM-09590
( 220 , 1 +.
D: 220QBK-ND, J: 690700, F: 9339299, R: 707-7612
! NPN- TIP120,
1 +.
D: TIP120-ND, J: 32993, F: 9804005, RS: 808-0502
(
1 , 1 +.
D: 1.0KQBK-ND, J: 690865, F: 9339051, R: 7077666
100 \, 1 +.
D: P10269-ND, J: 158394, F: 1144642, RS: 7621746
Бессеансовые сети и двоичные протоколы
341
Сеансы или сообщения?
До сих пор большинство проектов связи из этой книги работали, открывая выделенное соединение между двумя узлами на весь период обмена данными. Такой тип связи называется связью на
основе сеансов (session-based). Но иногда требуется организовать между объектами более свободный вариант обмена данными — когда они могут менять партнеров по общению «на лету»
или даже отправлять сообщения целой группе узлов, если ситуация того требует. Для этого нужен протокол, основанный на сообщениях (message-based).
, " .
Так сеансы или сообщения?
& 5
TCP,
%
+
. =
" TCP
. &
, . 2
, % . & $ « — — — » (
). 4
,
. #
TCP.
*
. & +
"
— UDP1. UDP,
" ,
, .
& TCP, UDP "
(message-based). #" UDP
. =
,
, . =
$
. 0
,
,
1
UDP, User Datagram Protocol —
.
-
; , UDP
« -- » , % "
" . ;,
192.168.1.45 " UDP 192.168.1.255,
$ "
$ . '
,
% "
:
=.=.=.255, =
. /
, "
, "
. ;
,
"
.
" UDP
" , . ,
. 3 ,
,
.
UDP
, " % " , —
. - %
,
"
" .
Глава 7
342
# TCP UDP
(SPP) Bluetooth,
2, LoRa,
6.
9 LoRa " ,
. TCP,
Bluetooth
, ,
,
,
, LoRa.
& $
" , " 802.15.4,
Digi.
Широковещательные UDP-сообщения
в офисных сетях
& " % " UDP- " . 4
% % ,
$
. *
% " UDP" . $,
,
$ % "
UDP- " ,
. & , UDP, %
+
, %
-
,
% " " .
Широковещательные сообщения или направленные?
Первое преимущество бессеансовых протоколов, таких как UDP, состоит в том, что они позволяют передавать сообщения одновременно всем узлам сети. Впрочем, все время делать это нежелательно, поскольку это наводнит сеть сообщениями, которые нужны далеко не каждому устройству, но такую возможность полезно иметь под рукой, когда надо узнать, какие еще устройства
имеются в сети. Для этого нужно просто отправить широковещательное сообщение с вопросом
«Кто там?» и ожидать ответов.
Кто здесь, кроме нас? — выявление других устройств с помощью UDP
node.js dgram
. =
UDP-
$ . #
"
, +
UDP- .
> WiFi101
Arduino
UDP. / ,
% "
"
. ; ,
% . 0
% "
" node.js.
MKR1000
ESP8266 . 0
% "
UDP- " ,
"
netcat POSIX,
$ .
netcat
Raspberry Pi
BeagleBone,
.
Бессеансовые сети и двоичные протоколы
343
Пишем код сервера UDP-сообщений
# " node.js % "
UDP" "
UDP 8888.
/
,
.
# % "
"
=.=.=.255,
" . ' % "
" % ,
$
"
. * ,
IP-
% %
192.168.0.1, % "
"
192.168.0.255.
& " ,
, $
,
, "
UDP " : udp.send(),
,
" ,
:
/*
Z UDP
: node.js
*/
var dgram = require('dgram'); // '
//
dgram:
var UDP_PORT = 8888; // ^ $
var udpServer = dgram.createSocket('udp4'); // Z$
// UDP-
var broadcastAddress = '192.168.0.255'; //
// .
//
//
function udpBegin() {
udpServer.setBroadcast(true);
console.log('Z UDP $ ');
}
function readMessage(message, sender) {
console.log(sender.address + ':' + sender.port +' sent:
' + message);
}
udpServer.bind(UDP_PORT); // UDP
udpServer.on('listening', udpBegin); // UDP
udpServer.on('message', readMessage); // \
// ' UDP
// :
var data = " ";
udpServer.send(data, 0, data.length, UDP_PORT,
broadcastAddress);
Пишем код скетча, ожидающего сообщения UDP и отвечающего на него
# " Arduino " UDP
8888 .
2 MKR1000
ESP8266 (
WiFi101
ESP8266). =
.
/*
$ UDP
: Arduino
*/
#include <SPI.h>
#include <WiFi101.h>
// #include <ESP8266WiFi.h> // - ESP8266
// $ R
#include <WiFiUdp.h>
#include "config.h"
Глава 7
344
9
,
setup(),
, —
Wi-Fi. *
Wi-Fi
, "
. 0
,
config.h ( $
- " ). 0 $
" , UDP, " " UDP,
WiFiUdp:
WiFiUDP Udp; // Z$ R$ WiFiUDP
const int port = 8888; // ,
//
Z loop() " UDP
,
node.js
% "
" .
void loop() {
// ,
if (Udp.parsePacket() > 0) { // +
// - :
String message = "";
Serial.print(": "); // +
R
//
Serial.print(Udp.remoteIP());
Serial.print(" : "); //
Serial.println(Udp.remotePort());
while (Udp.available() > 0) { // +
//
message = Udp.readString();
}
Serial.print("Z : " + message); // +
// R
sendPacket(message); //
}
}
UDP
TCP.
UDP
,
.
$ .
/
parsePacket()
WiFiUdp, . #
" $ $
" . 2
"
Stream ( $ readStream())
" ,
TCP :
void setup() {
Serial.begin(9600);
// ' Wi-Fi,
while ( WiFi.status() != WL_CONNECTED) {
Serial.print(" ' : ");
Serial.println(ssid); // R (SSID)
WiFi.begin(ssid, password); // '
delay(2000);
}
// ' ,
R
// :
IPAddress ip = WiFi.localIP();
Serial.print("IP-: ");
Serial.println(ip); Udp.begin(port);
}
Бессеансовые сети и двоичные протоколы
7 sendPacket() . & %
IP-
, " . 0
% " ,
" ,
" :
345
void sendPacket(String message) {
// ^ :
Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
Udp.print(" : " + message); //
-
Udp.endPacket(); //
}
,
"
UDP " TCP.
" %.
beginPacket()
Wi-Fi "
, endPacket()
% , $
. &
.
2 Arduino
"
. Arduino
IP- , "
" :
'
myNetwork
Connected to wifi
SSID: myNetwork
IP-: 192.168.0.3
signal strength (RSSI):-36 dBm
:
;
"
node.js. &
Arduino "
" :
: 192.168.0.8 : 8888
Z :
3
" IP- %
. 3
" .
& ,
"
,
" :
Z UDP $
192.168.0.4:8888 sent:
192.168.0.3:8888 sent: Received:
2 — ,
% "
" .
& — . 4
$ ,
. ; $ % ,
.
* "
% "
,
—
, " . / ,
" " ,
" node.js.
,
. &
$ UDP % , sendPacket ()
, % , % "
.
Глава 7
346
Программа netcat
= UDP- "
POSIX netcat. /
TCP-,
UDP- , , . /
.
' $
" , %
" node.js, " (
, ,
,
$
8888):
$ nc -u -l 8888
* Raspberry Pi $ ,
sudo:
, -
$ sudo nc -u -l 8888
, $ ,
, ,
% 8888
" " . 0 -u ,
UDP, -l — %
" " ,
" . & $
(Raspberry Pi, BeagleBone . .),
.
% " " " :
4 ,
,
. 9 " % <Ctrl>+<C>.
* netcat % ,
% " .
& ,
"
" , "
:
$ nc -u 192.168.0.4 8888
$
" % <Enter>.
,
" ,
.
0 , " Arduino " netcat,
"
, 8888. / ,
netcat " 8888
,
,
.
*
netcat
- . * ,
Linux % "
" -b, macOS
% " "
. $
, :
$ man nc
netcat Windows,
"
Windows,
, . Net
Cygwin bash Windows 10,
$ - ,
netcat.
Бессеансовые сети и двоичные протоколы
347
Перенаправление вывода в сообщении UDP
netcat, POSIX
"
UDP . $
" :
$ echo "& " > /dev/
udp/192.168.0.4/8888
& $ echo
$
/dev/
udp/<IP->/<>,
,
.
/
,
" UDP. * , date:
;
macOS
Linux, POSIX.
Net Cygwin -
bash Windows 10, , ,
Windows.
node.js
POSIX, , ,
UDP. *
UDP
, .
$ date > /dev/udp/192.168.0.4/8888
Проект 13
Сетевые светильники
Протокол UDP удобно использовать для реализации сетевых проектов, в которых большое количество устройств выполняют обмен данными между собой или с сервером, причем такой обмен
осуществляется нерегулярно и в течение короткого времени. В этом проекте мы создадим набор
мерцающих сетевых светильников, которые обмениваются сигналами друг с другом, когда над
каким-либо из них проводят рукой.
* Wi-Fi
— %
. &
$ , $
, . 2 $ .
# " ,
,
( . 7.2). 4 ,
,
. & , ,
. #
"
" UDP: % % "
" UDP,
. #"
. >
UDP,
,
".
+ UDP
$ :
% " " . & ,
UDP
.
/ ,
,
Глава 7
348
" .
&
% ,
+
. $
,
, , ,
$ ,
$. 3 " , %
TCP,
.
Требуемые компоненты
= ( 6, % — 30) :
Arduino MKR1000, WINC1500,
ESP8266.
+
: Wi-Fi,
/ ,
/
.
+
Sharp GP2Y0A21YK,
1 %.
(NeoPixels), 3–7 %.
Рис. 7.2. Сетевые светильники
WS2812
> % , 1 %.
>
3,3–5 &, 1 %.
7 10 ,
1 %.
-
10 , 1 %.
# ,
,
. ` .
% %
$ ...
Схема устройства светильника
" WiFi
WS2812 Worldsemi. Adafruit
NeoPixels. #
SparkFun Seeed Studio. =
(RGB)
(RGBW)
$ . = ,
" ,
%
(« »
Бессеансовые сети и двоичные протоколы
349
" ) .
> 2 $ : https://learn.
adafruit.com/adafruit-neopixel-uberguide.
% 1 &. / , ,
$ ,
% 1 &,
.
,
.
& MKR1000 ( . 7.3) "
, $
Wi-Fi
ESP8266 ( . 7.4 7.5).
&
. * $
.
ESP8266
(
ADC
SparkFun,
Adafruit),
-
+
,
. 7.3–7.5,
10 80 , "
$
"
0 5 &.
ESP8266
,
%" 1 &,
, % $
.
. 7.4,
, ,
%
2
, .
Рис. 7.3. Монтажная схема проекта сетевых светильников (версия для платы MKR1000). Слева здесь показана LiPo-батарея,
обеспечивающая электропитание всех устройств проекта. Емкость батареи должна быть не менее 800 мА, а еще лучше —
1200–2000 мА. Это необходимо для питания как электронной части проекта, так и самих светодиодов, потребляющих значительный ток
A B
C D E
F
G H
I
J
2000mAh
1
1
5
5
10
10
15
15
20
20
25
25
30
30
A B
C D E
F
G H
I
J
Глава 7
350
$ 1 &. * $
,
"
, , .
= , NeoPixels,
5 &, , %
4,5 &,
33, 3,7 &,
$ LiPo.
3,3 & , " , ,
.
5 & Adafruit
NeoPixels
470 0. 0
,
$ ,
,
, , ,
% .
=
,
. =
NeoPixel Jewel Adafruit, . &
,
, " "
. 0 ,
NeoPixel 60
, $ , %
,
.
Рис. 7.4. Принципиальная схема проекта сетевых светильников. Максимальное рабочее напряжение аналогового ввода плат
на микросхеме ESP8266 (обозначен ADC на платах компаний SparkFun и Adafruit) составляет 1 В, поэтому используйте делитель
напряжения (см. его схему справа), чтобы уменьшить напряжение, подаваемое на него с выхода инфракрасного датчика расстояния, до допустимого уровня
+3,3 В
Напряжение
питания (Vin)
Вывод
+3,3 В
Напряжение питания (Vin)
A0
Для плат на микросхеме ESP8266
используйте делитель напряжения,
чтобы уменьшить максимальное
выходное напряжение
инфракрасного дальномера
до величины, не превышающей 1 В
+3,3 В
Программируемые Напряжение
питания (Vin)
светодиоды
(NewPixels)
Входные
данные
Выходные
данные
Модуль
микроконтроллера
10 кОм
ADC
Вывод
220 Ом
Общий
D5
Общий
Общий
Напряжение
питания (Vin)
+3,3 В
Общий
Бессеансовые сети и двоичные протоколы
351
OFF
A B
1
C D E
+
F
GND
3V3
VIN
3 x AAA
J
1
0
5
4
DTR
10
I
5
SCL
OFF-ON
G H
GND
SDA
5
ON
-
TX
13
RX
12
5V
XPD
NC
ADC
GND
10
EN
15
15
20
20
25
25
30
30
A B
C D E
F
G H
I
J
Рис. 7.5. Монтажная схема проекта сетевых светильников (версия для платы ESP8266). В качестве источника питания для этого
проекта можно использовать три батарейки типа ААА. Но питание от батареек подключайте не через схему питания платы, а
непосредственно к выводу Vin. Плата Feather Huzzah! ESP8266 компании Adafruit имеет иную распиновку, но вывод от датчика
расстояния так же можно подавать на вывод ADC платы, а светодиоды подключать к ее выводу 5
Код для управления светодиодами
= NeoPixel Adafruit.
> — Arduino.
" , ,
.
Работа с библиотекой NeoPixel
,
NeoPixel, — $ % :
Adafruit_NeoPixel candle = Adafruit_
NeoPixel(
numPixels, neoPixelPin, NEO_
GRB + NEO_KHZ800);
numPixels neoPixelPin
( ,
") ,
.
. & (NEO_GRB)
, NeoPixel
. =
,
,
RGB (
, ), — GRB (
, ), ,
,
, , ),
RGBW (
, , . &
GRB GRBW. +
Глава 7
352
,
. & (NEO_KHZ800) ,
. & %
800 q.
?
candle.setPixelColor(( , #));
&
. * , 0xFFFF0000
. 4
", ,
.
X
:
?
, :
:
candle.setPixelColor( ,
, $ , );
=
:
$
% — , HTML:
& "
% .
candle.setPixelColor( ,
, $ , , );
Познакомимся с библиотекой NeoPixel поближе
= ,
NeoPixel —
.
X % , ,
,
, -
.
HTML,
" :
,
, . &
.show()
, $
. .clear()
0x000000
:
?
?
?
: 0xFF0000
: 0x00FF00
: 0x0000FF
2 "
( ) 0
255 (0x00–0xFF % ).
* , 0x2375FF
-
.
/*
-
: Arduino
*/
#include <Adafruit_NeoPixel.h>
const int neoPixelPin = 5; // +
const int numPixels = 7; // $ -
Adafruit_NeoPixel candle = Adafruit_NeoPixel(
numPixels, numPixels, NEO_GRB + NEO_KHZ800);
void setup() {
Serial.begin(9600); // \ # $
// $
'
Бессеансовые сети и двоичные протоколы
353
candle.begin(); // \ # $ '
candle.clear();
candle.show(); // ' -
// -
}
void loop() {
for (int pixel = 0; pixel < numPixels; pixel++) {
candle.setPixelColor(pixel, 0xFF0000);
}
candle.show(); // -
delay(1000);
candle.clear(); // +'
candle.show(); //
delay(1000);
}
Создание эффекта мерцания светильника
9 :
" ,
" UDP $ . #
. *
"
.
9 " " $ .
" , ,
% %
"
, $ . +
$ $ , (
) % $
. $
—
. 2
. " . 4
, % .
.
~ ( , , , ) 4-
$ , , .
, 0xCB500F,
, 0x853E0B,
, "
(. 7.1). + ,
"
, "
"
%
.
Таблица 7.1. Составляющие текущего
и целевого цветов
Красный
Зеленый
Синий
Текущий
0xCB
0x50
0x0F
Целевой
0x85
0x3E
0x0B
Глава 7
354
9 ,
" " " , .
/
,
, % . / " . '
4- .
;
byte
( ). 2
, "
% .
"
.
,
%
,
.
Пишем код для сравнения составляющих цветов
# "
"
"
,
"
%. /
$
. 7
$
:
unsigned long compare(unsigned long thisColor, unsigned
long thatColor) {
// + #:
byte r = thisColor >> 16; // Z
byte g = thisColor >> 8; // Z
byte b = thisColor; //
// + #:
byte targetR = thatColor >> 16; //
//
byte targetG = thatColor >> 8; //
//
byte targetB = thatColor; //
Z
Z
// + - # :
if (r > targetR) r--; // $ #
// ,
if (g > targetG) g--;
if (b > targetB) b--;
' %
NeoPixels, %
— , .
if (r < targetR) r++; // $ #
// ,
if (g < targetG) g++;
if (b < targetB) b++;
// Z $ , #:
unsigned long result = candle.Color(r, g, b);
return result;
}
Бессеансовые сети и двоичные протоколы
355
Битовый сдвиг и побитовое маскирование
'
. 7 Arduino
:
// $ :
myBit = bitRead(someByte, bitNumber);
// $ $ :
bitWrite(someByte, bitNumber, bitValue);
& 1
3, 0 —
4. $ "
:
// $ 1:
bitSet(someByte, bitNumber);
// $ 0:
bitClear(someByte, bitNumber);
• AND (&): 4 ,
1. & $ 0:
1
0
1
0
&
&
&
&
1
0
0
1
=
=
=
=
-
1
0
0
0
• OR (|): 4 1,
1. & $ 0:
1
0
1
0
|
|
|
|
1
0
0
1
=
=
=
=
1
0
1
1
• XOR (^): 4
,
1. & $ 0:
1
0
1
0
^
^
^
^
1
0
0
1
=
=
=
=
-
0
0
1
1
+
. ;
. / "
, C, Java JavaScript. 0 (<<)
,
(>>) — .
# " , ,
, " :
0b00001111 << 2; // $ 0b00111100
0b10000000 >> 7; // $ 0b0000001
* , ,
"
NeoPixels " :
/
:
0x00FF00 >> 8; // $ 0x0000FF
0x0000CD << 16; // $ 0xCD0000
0
,
, $ $ .
_ + (AND), +_+ (OR) " +_+ (XOR)
. ; :
3
4
0 . Setting the bit.
0 . Clearing the bit.
0b00001111 & 2;
// 0b00000010, 2
0b00001111 | 0b10000000;
// 0b10001111, 143
// $
// $
// $ $ #:
unsigned long myColor = 0x1A3CFF; //
// # -$
unsigned long green = 0;
// $ $ :
green = myColor & 0x00FF00; // $
// 0x003C00
& $
.
Глава 7
356
Активация вспышки светильника
&
$ —
—
:
, , %
,
$ % " UDP- " . $
triggered true ( ), ,
% .
+
! . & %
" triggered
" % "
" , %
. /
,
" . X
,
triggered false (). & "
$ ,
. # $ ,
, , $ %
.
Собираем все части скетча воедино
#
%
.
,
config.h, "
(SSID)
($
, "
):
/*
=
UDP, % "
" .
NeoPixels:
, $
candle NeoPixel:
WiFiUDP Udp; // Z$ R$ UDP
IPAddress destination(192,168,0,255); // IP- $
const int port = 8888; // UDP-
2 keyColors
,
.
// # RGB- :
unsigned long keyColors[] = {0xCB500F, 0xB4410C, 0x95230C,
0x853E0B};
unsigned long currentColor = keyColors[0]; //
#
//
Z
: Arduino
*/
#include <SPI.h>
#include <WiFi101.h>
// #include <ESP8266WiFi.h> //
-
ESP8266
// $ R
#include <WiFiUdp.h>
#include <Adafruit_NeoPixel.h>
#include "config.h"
const int neoPixelPin = 5; // +
//
const int numPixels = 7;
// $ //
// Z$ R$ NeoPixel:
Adafruit_NeoPixel candle = Adafruit_NeoPixel(
numPixels, neoPixelPin, NEO_GRB + NEO_KHZ800);
Бессеансовые сети и двоичные протоколы
357
target
, currentColor — " , lastFadeTime — .
, interval % (30 %
),
threshold — , triggered —
:
unsigned long target = keyColors[1]; // ,
// -
long lastFadeTime = millis(); // $
// #
long interval = 30; // - (30 )
int threshold = 500; // $
boolean triggered = false; // $ #
[ setup()
$ candle
NeoPixel. 2
" .clear()
,
"
.show() . [ .show() ,
.
void setup() {
Serial.begin(9600); // \ # $ '
// $
candle.begin(); // \ # $ R$ candle
// NeoPixel
candle.clear(); // +'
candle.show(); // -
// ' Wi-Fi,
while ( WiFi.status() != WL_CONNECTED) {
Serial.print(" ' : ");
Serial.println(ssid); // R (SSID)
WiFi.begin(ssid, password); // '
//
delay(2000);
}
0 setup()
:
,
$ IP-
UDP- :
// ' ,
R
// :
IPAddress ip = WiFi.localIP();
Serial.print("IP-: ");
Serial.println(ip);
Udp.begin(port); // \ # $ UDP-$:
}
[ loop()
, . 4 %
, triggered.
4 false (),
(0xFFFFFF)
void loop() {
int sensorReading = analogRead(A0); // Z $
// :
if (sensorReading > threshold) { //
// $ ,
Serial.print(sensorReading); //
R
if (!triggered) { //
//
currentColor = 0xFFFFFF; // #
Глава 7
358
" currentColor
UDP- ,
triggered true ( ).
,
, % "
$ :
// UDP- $ :
Udp.beginPacket(destination, port);
Udp.print("ping");
Udp.endPacket();
triggered = true; // ,
//
}
}
loop(),
% "
. =
"
millis() % 30 . 4 "
, compare(),
(
loop()). 4
" ,
keyColors:
// # 30
:
if (millis() - lastFadeTime >= interval) {
triggered = false; // M $ #
// false
loop(),
for
,
, .show(). $
lastFadeTime " , "
millis(),
" :
// M # - :
for (int pixel = 0; pixel < numPixels; pixel++) {
candle.setPixelColor(pixel, currentColor);
}
candle.show(); // //
lastFadeTime = millis(); // Z- -
//
}
2 % loop()
"
UDP- " .
.parsePacket(), "
, , "
.available(), " .
& ,
// ,
if (Udp.parsePacket() > 0) {
String line = "";
// UDP-, :
while (Udp.available()) {
line = Udp.readStringUntil('\n'); // Z
//
}
IPAddress sender = Udp.remoteIP(); //
// IP-
Serial.print(": "); // +
R IP-
//
if (currentColor != target) {
// + - # #
# :
currentColor = compare(currentColor, target);
} else {
// +
$ keyColors $
// #:
int next = random(4);
target = keyColors[next];
}
Бессеансовые сети и двоичные протоколы
.avail " ,
.parsePacket(),
IP-
.
4 "
ping,
.
able()
359
Serial.print(sender);
Serial.print(", Z : "); //
Serial.println(line);
if (line == "ping") { // "ping",
currentColor = 0xFFFFFF; //
// #
}
}
} // # % #
loop()
// % #
compare()
2 % compare(),
. #
loop()
:
2
,
, node.js, " % " " ,
$ . ' , " $
"ping". —
" ,
.
# node.js " .
&
, . &
- 10 , —
. = $ ,
, $,
$ ,
" $
. $ ,
%
,
. * . 7.6 " .
+ $ , . + —
, . & ,
33 333
. 3 %
,
— ,
. =
$ " candle.show() setup(), loop():
// +'
#
//
// ' :
if (WiFi.status() != WL_CONNECTED) {
candle.setPixelColor(0, 0x0000FF);
}
Глава 7
360
10 см
+ %
UDP" . + % " " " $ , ,
% " "
. >% % IP-
, $ 30 ,
,
192.168.0.2 192.168.0.31. " ,
"
Udp.beginPacket():
int addr = random(30) + 2; // $
// 2 31
10 см
destination = IPAddress(192, 168, 0, addr);
// IP-
3
" ,
$ $ .
* ,
" IP- ,
% %
.
Рис. 7.6. Версия схемы светильника для платы MKR1000, собранная на макетной плате уменьшенного размера. При такой компоновке вся схема помещается в жестяную коробку
из-под леденцов диаметром 10 см. Светодиодная сборка, изолированная от микроконтроллера резиновой прокладкой,
размещена достаточно близко к центру трубки для создания
хорошего светового эффекта, а датчик — достаточно близко
к ней, чтобы край трубки не вызывал ложных срабатываний.
Батарейка находится под платой. На нижнем рисунке показана только сама монтажная разводка без микроконтроллерной
платы и светодиодной сборки
"
"
,
,
"
. / ,
! #
(TTL5), % .
#
,
IP TTL, "
" % ,
% . $
% % TTL ,
% , 0
%
.
5
TTL — Time-To-Live.
Бессеансовые сети и двоичные протоколы
361
UDP в действии: traceroute
# ,
. = $
, " traceroute. traceroute
UDP
" ,
%
. &
-
$ IP- % ,
" . /
,
" , $
" . = traceroute:
$ traceroute -a makezine.com
traceroute: Warning: makezine.com has multiple addresses; using 104.25.44.28 traceroute to
makezine.com (104.25.44.28), 64 hops max, 52 byte packets
1 [AS0] 192.168.0.1 (192.168.0.1) 5.359 ms 7.537 ms 10.090 ms
2 * * *
3 [AS12271] tge-0-10-0-10.nymanyfo01h.nyc.rr.com (68.173.209.1) 30.503 ms 32.057 ms 34.002 ms
4 [AS12271] agg115.nyclnyrg01r.nyc.rr.com (68.173.198.64) 30.132 ms 38.111 ms 39.582 ms
5 [AS19548] bu-ether19.nwrknjmd67w-bcr00.tbone.rr.com (66.109.6.78) 41.176 ms 34.952 ms 24.525 ms
6 [AS19548] bu-ether12.nycmny837aw-bcr00.tbone.rr.com (66.109.6.27) 34.226 ms 40.067 ms 34.095 ms
7 [AS7843] 0.ae2.pr0.nyc20.tbone.rr.com (107.14.19.147) 35.052 ms [AS19548] 0.ae0.pr0.nyc20.
tbone.rr.com (66.109.6.157) 29.482 ms [AS19548] 0.ae1.pr0.nyc20.tbone.rr.com (66.109.6.163)
27.959 ms
8 [AS1299] nyk-b5-link.telia.net (62.115.34.145) 20.895 ms 43.579 ms 47.807 ms
9 [AS1299] nyk-bb2-link.telia.net (80.91.254.15) 40.781 ms 29.687 ms 29.712 ms
10 [AS1299] nyk-b2-link.telia.net (62.115.134.108) 31.577 ms 29.079 ms 30.539 ms
11 [AS1299] cloudflare-ic-301663-nyk-b2.c.telia.net (213.248.77.162) 30.656 ms 35.082 ms 25.414 ms
12 [AS13335] 104.25.44.28 (104.25.44.28) 29.912 ms 30.884 ms 27.869 ms
= , $ . traceroute ,
UDP- ( % $ makezine.com,
IP- 104.25.44.28). , IP UDP- TTL, 1. /
" % ,
,
,
,
% . 2 UDP- TTL, 2. / % " , $
% TTL,
" "
% ,
% . /
, traceroute
. ; ,
traceroute -
%
.
~ traceroute UDP,
TCP
+
. & ,
%
-
. 7 %
traceroute,
ICMP6,
ping.
traceroute
UDP- " ,
, —
"
" .
6
ICMP, Internet Control Messaging Protocol —
" " [ ] +
.
Глава 7
362
&
traceroute -a,
( AS7). X
, AS
https://apps.db.ripe.net/search.
* % %
( . 2 traceroute)?
7 % , % " ,
. X $ , $ traceroute : * * *.
7
* - www.yougetsignal.com/tools/visualtracert
traceroute, %
. ~ $ - ,
, , ,
"
+
.
> $ 9.
Traceroute для Windows
& Windows
tracert
-a.
traceroute —
AS, Autonomous Systems —
.
XBee: еще один протокол на основе сообщений
Линейка радиоустройств XBee компании Digi представляет собой еще один подход к организации связи по протоколу на основе сообщений. Эти радиоустройства могут работать в режиме
асинхронной радиосвязи для отдельного устройства или же выполнять независимые операции
чтения и записи на своих собственных контактах ввода/вывода. Они работают подобно модемам
в том смысле, что их настройка осуществляется по асинхронному последовательному подключению (то есть через УАПП). Радиоустройства XBee используют созданный компанией Digi двоичный протокол связи на основе сообщений, с помощью которого им можно посылать команды по
радио, или считывать их контакты ввода, или управлять их контактами вывода.
X
API- XBee, Digi " . $
: ZigBee, Wi-Fi . .
& " %
XBee —
XBee Pro S2C 802.15.4. +
Digi
$ ,
XBee.
ZigBee и XBee
; ZigBee
ZigBee, XBee — Digi,
Inc. / . =
XBee.
= XBee
—
, , .
XBee UDP
,
,
% "
" . 0 LoRa,
6, —
,
, "
8 ( ! ,
LoRa). # XBee
:
,
.
"
8
0 . Personal Area Network (PAN) ID.
Бессеансовые сети и двоичные протоколы
363
/ ,
/ .
/ ,
($
9), ( ),
" ,
. 3
XBee "
X3 (UART),
. =
Digi
XCNU, : www.digi.com/support/
product-support. & Select Your Product
for Support XCTU,
.
. & , $
" «» Bluetooth, . /
XCTN, " XBee " , "
. 9
Write ,
Hayes AT,
.
* Digi "
,
Hayes AT — ,
. &
Hayes (,
,
Digi)
ASCII. + " $ ,
.
" +++. &
" . ,
" ( ) ,
ASCII AT, ,
"
,
—
( ),
. %
ASCII . 7
" OK,
,
.
= XBee
XBee-to-Serial XBee.
Digi $
, " $
XBee-to-USB. /, ,
USB-to-Serial,
,
"
, XBee. * . 7.7,
: XBee-to-USB
Adafruit Parallax ( ) XBee Explorer SparkFun (
).
Hayes AT
,
9
0 . sampling.
Настройка радиомодулей XBee
XBee
" XCTU
Add a Radio (= ) —
, . , , ,
. 7.8. X
$
,
Write, . X
,
3;.
Глава 7
364
Выбор вспомогательного оборудования
для радиомодулей XBee
*
XBee,
"
:
• > XBee
> —
USB-to-XBee. *
. 7.7,
USB-to-XBee Adafruit Parallax ( )
SparkFun XBee Explorer (
). &
XBee. & ,
USB-toSerial, $ 3,3 &. & $
TX RX , . *
XBee, % XStick
802.15.4 Digi;
• > XBee
— $
Fio v3 SparkFun, "
Arduino
(ATmega32U4) XBee ( . 7.7, );
• > XBee = —
XBee
LilyPad ( . 7.7, )
XBee XBee Breakout ( . 7.7, ).
3
SparkFun XBee LilyPad XBee
Explorer Regulated ( SparkFun:
WRL-11373) "
,
XBee % .
9 XBee Digi
3,3 &, $, (
%
),
3,3 &.
Рис. 7.7. Вспомогательные платы XBee: а — адаптер XBee-to-USB производства компаний Adafruit и Parallax (слева) и плата
SparkFun XBee Explorer (справа); б — адаптерная плата SparkFun Fio; в — адаптерная плата SparkFun XBee LilyPad; г — адаптерная плата XBee Breakout
а
б
в
г
Бессеансовые сети и двоичные протоколы
0 XCTU 3;
,
"
( . 7.9).
Примечание
4 XCTU
,
. = $
( 5) " . *
, ,
5,
" .
Рис. 7.8. Конфигурационная панель приложения XCTU, с помощью которой можно
просматривать и устанавливать параметры радиоустройств. Измененные в этом
окне значения параметров отправляются
на радиоустройство по нажатию кнопки
Write, в результате чего программа XCTU
создает соответствующую команду АТ для
установки на радиоустройстве заданного
значения параметра
Рис. 7.9. Панель терминала последовательной связи программы XCTU. Чтобы
с помощью терминала подключиться к радиоустройству, нажмите кнопку Open/
Close (на рисунке кнопка имеет надпись
Close, поскольку последовательный порт
уже открыт). После этого из панели можно
обмениваться данными напрямую с последовательным портом радиоустройства
365
& ,
XCTU. = $
CoolTerm
.
> , 3; ,
,
.
Digi
, XCTU. &
.
Глава 7
366
&
XCTU
:
+++
+
% <Enter>
%
$ . 7 XBee
" :
OK
= , +++
, $
! # (guard time). 4
, 10
. $,
$
+++, 10 ,
, " %.
+, OK , . XBee
16-
64-
, $
: % % ( % , "
, ).
& % " 16-
.
+ "
,
:
ATMY\r
3 $
:
,
ATMY1\r
/
1. 0 : \r, %" % , ,
% <Enter>.
; ,
(
, %
" ),
(
+++), :
ATDL\r
#
,
0, $
. *
,
, % . 9
16-
. 3
% ,
0 FFFF.
+ PAN ID (
) ,
:
ATID\r
PAN
3332, , " :
ATID1111\r
7 XBee $ ,
:
OK
2
,
WR,
. ; , $
. * :
ATID1111,WR\r
0
XCTU: +++
,
,
WR % <Enter>. =
ATCN\r.
Бессеансовые сети и двоичные протоколы
367
Проект 14
Предупреждение о наличии в мастерской токсичных
испарений
Если у вас есть мастерская, вы оцените этот проект. Подключив датчик летучих испарений
к радиомодулю Digi 802.15.4, вы сможете обнаруживать повышенную концентрацию паров растворителей в атмосфере своей мастерской. При работе с химикатами легко привыкнуть к их
испарениям, что может повлечь нежелательные последствия, вплоть до летальных. Этот проект
демонстрирует, как предотвратить такое развитие событий.
2 . 0
Raspberry Pi, "
- . & % — % ' —
- ,
. / ,
%
, ,
. 4
, $
,
.
* . 7.10
$
. 3 7.11 .
Это демонстрационный проект!
*
, $
. # . 0
%
, %
" . * $ ,
.
# , ,
.
Рис. 7.10. Проект, выявляющий наличие токсичных газов,
в сборе: датчик газа, шимпанзе Чарли и сервер на одноплатном компьютере. В качестве альтернативы радиомодулю
на сервере можно использовать модуль Digi XStick (показан
справа)
Глава 7
368
Требуемые компоненты
= $ . *
,
:
3
XBee-to-USB, 1 %.
Компоненты для схемы датчика
> , 1 %.
9 XBee XBee Pro S2C
802.15.4, 1 %.
# 5 &, 1 %.
# 3,3 &, 1 %.
+ 9–12 &,
1 %. , $ .
3 XBee, 1 %.
=
%
, 2 %.
=
, 2 %.
1 [, 2 %.
10 [, 2 %.
= MQ-6
Hanwei, 1 %.
3 , 1 %.
# , 1 %.
Рис. 7.11. Блок-схема системы выявления токсических газов
Радиомодуль
XBee датчика
Радиомодуль
XBee сервера
Raspberry Pi
в качестве
веб-сервера
Локальная
сеть
Веб-браузер
Радиомодуль XBee
исполнительного
устройства
9 220 0, 1 %.
47 0, 1 %.
Компоненты для схемы
исполнительного устройства
> , 1 %.
9 XBee XBee Pro S2C
802.15.4, 1 %.
+ % % '
, 1 %.
Об источнике питания для игрушки
4 % % 3 & ( ,
D), 3,3 &
. * $ .
4
,
«» $ %. &
.
# 3,3 &, 1 %.
3 XBee, 1 %.
=
%
, 2 %.
=
, 2 %.
# , 1 %.
9 220 0, 1 %.
= NPN- TIP120,
1 %.
9 1 0, 1 %.
100 [, 1 %.
Компоненты для схемы сервера
0
Raspberry Pi, 1 %. BeagleBone Green
Linux.
9 XBee XBee Pro S2C
802.15.4, 1 %.
XBee-to-USB- , 1 %. 7 , ,
( 802.15.4) XStick Digi,
USB .
Бессеансовые сети и двоичные протоколы
369
Настройка радиомодулей
XBee-to-USB. / ,
Raspberry Pi . &
: ,
(
-
% )
. 9
,
, PAN ID (
). & $
/ . * ,
, . ,
+7- .
[
,
($ ). &
$
"
XCTU AT.
Z . 7
(D0,
20)
$ % "
( PAN). ~ %
,
, $
,
. *
" :
?
ATMY01
—
;
?
ATDLFFFF —
% "
;
?
ATID1111 — PAN ID;
?
ATD03 —
/ 0 (D0) ;
?
ATIR64 —
100 (0-64h). 4
,
% ;
?
ATIT1 — , . ; ,
"
100 : 1 × 100
= 100 ;
?
—
.
ATIAFFFF
9 "
, ,
- " , " D0,
D0
. + ,
. * " :
?
ATMY02
—
;
?
ATDL01 —
?
ATID1111 — PAN ID;
?
ATD04 —
D0
;
?
ATIU1 —
"
01). * $ ,
(
,
,
$
" ;
/
. / —
Глава 7
370
$
;
?
-
ATDL01 — "
01). * $, ,
(
, $
" ;
?
ATID1111 — PAN ID;
?
ATIU1 —
ATIA01 ATIAFFFF — -
,
01 (
). 4 $
FFFF,
, $
.
; ,
.
9
"
"
. * $ ,
% ,
" :
?
?
ATMY03 —
-
;
/
. /
.
Сброс настроек радиомодуля
'
XBee (
, ),
ATRE\r.
& . 7.2
.
Таблица 7.2. Сводная конфигурационная информация для всех радиомодулей проекта
Радиомодуль датчика
Радиомодуль исполнительного
устройства (шимпанзе Чарли)
Радиомодуль сервера
MY = 01
MY = 02
MY = 03
DL= FFFF
ID = 1111
D0 = 3
IR = 64
IT = 1
IA = FFFF
DL = 01
ID = 1111
D0 = 4
IU = 1
IA = 01 FFFF
DL = 01
ID = 1111
IU = 1
0
,
WR\r.
& XCTU $
Write.
3; ,
. * ,
, " :
1. & +++.
2. 0 ,
OK. 2
"
(0 D02 — $ ,
):
%
ATMY1, DLFFFF\r
ATID1111, D03, IR64\r
ATIT1, IAFFFF, WR\r
* " :
Бессеансовые сети и двоичные протоколы
371
ATMY2, DL1\r
ATID1111, D04\r
ATIU1, IAFFFF, WR\r
3 $
:
ATMY3, DL1\r
ATID1111, IU1, WR\r
Совет
>
XBee,
,
,
" . ~ ,
. 7.12.
Рис. 7.12. Рекомендуемая разметка радиомодулей, позволяющая их не перепутать
Монтаж рабочих схем проекта
& , ,
. & $ "
, Digi
. ; ,
, , "
.
Схема датчика газа
D0. 9 XBee
-
%
. /
9 & % ,
. *
( !
) " , .
Стабилизатор напряжения 3,3 В модели
LD1117-33V
= 5 &, $
5 & — , 3,3 & — , 9 & . = $ 9 &,
$ 9–12 &.
& $ 3,3 & LD1117-33V. 9
$
5 &. $
,
.
* . 7.13
( ) ( !) .
& MQ-6, $ Hanwei.
47 0
,
~
,
,
% , $ . #
,
—
. /
Глава 7
372
К «плюсу» источника питания
постоянного тока 9–12 В
Стабилизатор
напряжения
7805 на 5 В
Вход
Выход
10 мФ
1 мФ
A
H
B
Датчик газа MQ-6
компании Hanwei
Радиомодуль XBee
LD1117-33V
Voltage Reg
Вход
H
Выход
Vcc
AD0 / DIO0
TX
AD1 / DIO1
RX
AD2 / DIO2
DO8
AD3 / DIO3
47 кОм
10 мФ
1 мФ
RTS / AD6 / DIO6
RESET
PWM0 / RSSI
Ass't / AD5 / DIO5
PWM1
Vref
NC
SLP
+ 3,3 В
220 Ом
15
20
25
30
20
25
30
30
30
15
25
25
10
20
20
10
15
15
LD11
D 17
D1
7
VReg
g
5
10
10
7805
805
5
VReg
g
J
I
G H
A B
C D E
F
G H
C D E
A B
F
G H
F
C D E
A B
A B
C D E
F
G H
I
I
I
J
J
5
5
J
1
LD1117
VReg
5
AD4 / DIO4
1
GND
1
CTS / DIO7
1
7805
VReg
DTR/DI8
Рис. 7.13. Принципиальная (вверху) и монтажная (внизу) схемы подсоединения радиомодуля XBee к датчику газа
Бессеансовые сети и двоичные протоколы
$ . +
« ». #
(_0#). _0# ( .
MQ-6), $
47 0, "
.
_0#
1,4–1,7 &. /
% %
, (
). . 7.13
(
22 0),
"
, , (
,
).
$ 2,3 &. , ,
1,6 &.
&%
, $
,
.
&
, (D0). ;
XBee ( 14) 3,3 &.
Проветрите помещение
2 , " . &
" " .
373
Схема исполнительного
(сигнального) устройства
=
(%
% )
,
. 7.14. > 3 ,
XBee,
.
. & , %
, ,
3 &. * . 7.15
%. 3
% .
#
"
/ . & +7 XBee
TIP120, ,
,
: , — .
= $ ,
,
.
, _0#,
,
, . *
" . # ,
,
.
& $
, . ,
. 4
,
,
Глава 7
374
220 0
+3 & . / -
% 1,5 &
.
Рис. 7.14. Принципиальная (вверху) и монтажная (внизу) схемы подсоединения сигнального устройства (обезьянки с ударными
тарелками) к радиомодулю XBee
К «плюсу» источника питания 3 В
Электродвигатель
постоянного тока
Радиомодуль XBee
1 кОм
AD0 / DIO0
TX
AD1 / DIO1
RX
AD2 / DIO2
DO8
AD3 / DIO3
RESET
PWM0 / RSSI
Транзистор
TIP120
RTS / AD6 / DIO6
Ass't / AD5 / DIO5
PWM1
Vref
NC
SLP
+ 3,3 В
220 Ом
DTR/DI8
CTS / DIO7
GND
AD4 / DIO4
10
15
20
25
30
10
15
20
25
30
C D E
F
G H
I
J
5
5
A B
A B
C D E
F
G H
I
J
1
TIP120
Darlington
1
100 мФ
Vcc
M
Бессеансовые сети и двоичные протоколы
375
Рис. 7.15. Внутреннее устройство игрушки с изменениями подсоединения проводов двигателя. Припаяйте провода питания
для макетной платы к «плюсу» батареи, а общий провод — к ее «минусу» (поз. А). Обрежьте провода, шедшие на двигатель
(поз. Б — «плюс», поз. В — общий), и припаяйте взамен новые, подсоединенные к макетной плате
Схема сервера
Библиотека node-serialport
=
Raspberry Pi % "
XBee-to-USB.
Raspberry Pi
. 7
nose.js,
- .
= $
node-serialport.
= node.js
% ,
.
,
node.js — node-serialport, " npm,
:
" , , " . * $ " :
, " XBee
.
$ % % , $
" - .
$ npm
% . & - $ , -
https://github.com/node-serialport/node-serial
port#installation-instructions, "
.
$ npm install serialport
Глава 7
376
= macOS, Windows Linux
%
. * Raspberry Pi
. $
, "
! «$
Raspian».
> node-serialport
,
,
. & , " " :
/
: open ( ), close
( ), error (%) data (
).
2
. '
— data —
.
, $
—
.
# "
" :
var myPort = new SerialPort(portName);
// ' serialport:
var SerialPort = require('serialport');
var portName = '/dev/ttyUSB0' // \$
var myPort = new SerialPort(portName);
// # $ - - -:
function readData(data) {
// :
console.log(data);
}
// #
:
// +$
:
myPort.on('open', portOpen);
// +$
- - - -:
myPort.on('data', readData);
// +$
$ :
myPort.on('close', portClose);
// +$
myPort.on('error', portError);
:
= . #
,
.
&
"
. 2
express.js
HTTP, $
" .
readData()
Бессеансовые сети и двоичные протоколы
377
Вк лючение пос ледовательных портов в Raspian
0
,
Raspberry Pi,
"
,
,
. * $
.
"
USB/TTL-Serial — ,
% .
# , ,
Raspberry Pi "
USB/TTL-Serial, ,
"
.
>% $
Raspian. ' ,
Raspian % ,
USB
:
$ ls /dev/tty*
4
. & +
Raspian Debian % USB/TTL-Serial.
/dev/ttyUSB0,
4
(
)
( ,
TX RX /
), ( ) . 1,
Raspberry Pi. = ,
,
, —
,
% —
. *
,
" ssh. ;
.
' , ssh (
$ !)
raspi-config. 2 Advanced Options (=
), Serial. * Would
you like a login shell to be accessible over serial?
(
?)
No. 2 Finish
Raspberry Pi. $
. 4
: /dev/ttyAMA0.
Чтение протокола XBee
$ %
, "
,
"
.
&
,
,
XCTU . & " " :
7E 00 0A 83 00 01 1F 00 01 00 05 00 01 59
7E 00 0A 83 00 01 1F 00 01 00 05 00 01 59
7E 00 0A 83 00 01 1F 00 01 00 05 00 01 59
API XBee (
) , $ %
,
.
" . [ " XBee 802.15.4 Digi. =
$ . 4
,
$
:
Глава 7
378
?
1 (7E) —
(
). /
;
?
2–3 (00 0) — . ;
?
4 (83) — API
(, " );
?
5–6 (00 01) —
;
12–13 — , " (1) (0)
. $ . & %
00 01 ,
D0. 3 , ,
00 02 (0000 0010 )
D1.
"
?
7 (1F) —
(+X#, RSSI10);
?
8 (00) — % "
( % );
?
9 (05) — .
7 $
" IT ;
?
10–11 (00 01) — / ,
"
.
& %
— D0,
;
10
?
— 0x7E ( 126),
$ .
# $
node-serialport,
$ npm,
. 2 $
serialServer.js.
RSSI, Received Signal Strength Indicator.
Читаем пакет
/ " ,
0-7, "
" . ; ,
.
node-serialport.
2
USB/
TTL-Serial. + $ "
. 2
"
,
:
/*
serialServer.js
: node.js
*/
var SerialPort = require('serialport'); // '
// serialport
var portName = ' /dev/tty.usbserial-xxx'; //
//
var incoming = []; // & - - - // :
var myPort = new SerialPort(portName);
Бессеансовые сети и двоичные протоколы
379
=
% ,
% . & $
,
%
:
function portOpen(portName) {
console.log('port ' + myPort.path + ' open');
console.log('baud rate: ' + myPort.options.baudRate);
}
2
, "
. = $ for,
,
0-7, " " ,
"
$ :
function readData(data) {
for (c=0; c < data.length; c++) { // #
var value = Number(data[c]); // $
if (value === 0x7E) {
// $ 0x7E $
//
console.log(incoming); //
R
//
incoming = [];
//
-
// - } else { // $ 0x7E,
incoming.push(value); //
// - -
}
}
}
:
// +$
:
myPort.on('open', portOpen);
// +$
- - - -:
myPort.on('data', readData);
// +$
:
myPort.on('error', portError);
. #
:
function portError(error) {
console.log('
: ' + error);
myPort.close();
}
$ node serialServer.js
+
$
$ " " :
$ , 126
(0x7Eh % ),
"
XBee.
port /dev/tty.usbserial-00001414 open
baud rate: 9600
[]
[[ 0, 10, 131, 0, 1, 35, 0, 1, 0, 1, 0, 1, 85 ]
[ 0, 10, 131, 0, 1, 35, 0, 1, 0, 1, 0, 1, 85 ]
[ 0, 10, 131, 0, 1, 42, 0, 1, 0, 1, 0, 1, 78 ]
[ 0, 10, 131, 0, 1, 41, 0, 1, 0, 1, 0, 1, 79 ]
[ 0, 10, 131, 0, 1, 34, 0, 1, 0, 1, 0, 1, 86 ]
[ 0, 10, 131, 0, 1, 36, 0, 1, 0, 1, 0, 1, 84 ]
Глава 7
380
>%
13 ,
. &
,
.
$ — , XBee , node.
js
. & ,
,
"
.
var message = {
//
//
packetLength: -1, //
apiId: 0,
//
address: -1,
//
rssi: 0,
//
channels: 0,
//
//
sampleData: 0,
//
pinStates = []
//
//
XBee
" JSON:
$
\ % API
' XBee
M
/, $
-
& ,
# %-
};
0 , " ,
message. /
JSON
$
"
XBee:
Разбираем пакет
& readData() console.log() parseData().
2 $
readData(). / " ,
. 0
" :
if (value === 0x7E) { // $ 0x7E $
parseData(incoming); //
output = []; //
- - } else {
// $ 0x7E,
incoming.push(value); // - //
}
&
.
>
0-7
13 . 4 $ ,
" $
JSON. > $ "
" :
function parseData(thisPacket) {
if (thisPacket.length >= 13) { // 13
// Z . R - $ ,
// $ _ = _ * 256 + _ :
message.packetLength = (thisPacket[0] * 256) +
thisPacket[1];
// + #
$
// # % , R
$
// # - $ :
message.apiId = '0x' + (thisPacket[2]).toString(16);
// ' %
- :
message.address = (thisPacket[3] * 256) + thisPacket[4];
// Z
:
message.rssi = -thisPacket[5];
_$ = _
* 256 + _
Бессеансовые сети и двоичные протоколы
,
for,
.
( D0 D8), , ,
$ :
381
// - $ .
// % ,
// R
$ ' :
message.channels = ((thisPacket[8] * 256) +
thisPacket[9]).toString(2);
// Z # %- :
message.sampleData = (thisPacket[10] * 256) +
thisPacket[11];
// $
//
# %-
:
for (var pin = 0; pin < 9; pin++) {
// + - :
var thisPinState = message.sampleData & (1 << pin);
// Z- # %
:
message.pinStates.push(thisPinState);
}
console.log(message); // +
R R
}
}
Добавляем сервер
; , " XBee,
, "
- .
0 $
- node.js. 2
% .
0
express . &
express
$ ,
:
var express = require('express'); // $
// express:
var server = express(); // C
server,
// express
server.use('/',express.static('public')); //
// public
&
GET:
server.listen(8080); // %
server.get('/json', respondToClient); // N
// GET
parseData() GET,
% $ :
//
,
// :
function respondToClient(request, response) {
// N
:
response.end(JSON.stringify(message));
}
// \ # $
var SerialPort = require('serialport'); // '
// serialport
Глава 7
382
2
. * $
«
»
$ "
JSON:
{ packetLength: 10,
apiId: '0x83',
address: 1,
rssi: -33,
channels: ‘1’,
sampleData: 1,
pinStates: [ 1, 0, 0, 0, 0, 0, 0, 0, 0 ] }
4 , "
,
$ , . &
,
- , — $ % ,
%
. # "
:
?
-
" ? 4 ,
XBee ?
-
?
?
XBee-to-USB XCTU - ;
?
"
" ?
" 1 10.
X % ,
, -
: http://
localhost:8080/json. &
, " , " :
{"packetLength":10,"apiId":"0x83",
"address":l,"rssi":-37,"channels "
:"1", "sampleData" :1, "pinStates":
[1,0,0,0,0,0,0,0,0]}
= - .
Создаем веб-страницу
,
p5.js
public $ . = $
p5.js, :
/*
Z - # $
: P5.js
*/
var sensorState = 'UNKOWN'; //
var bgColor = 0; // # % #
$ p5 g -b public
2 sketch.js
setup()
:
[ setup()
,
% . 2
GET HTTP
:
function setup() {
createCanvas(windowWidth, windowHeight); //
//
textSize(24); // $ %
fill(255); // # %
httpGet('/json','json',getResponse); //
// $
}
$
Бессеансовые сети и двоичные протоколы
383
getResponse(),
,
GET HTTP. [
, :
// # $ % #
httpGet():
function getResponse(message) {
// $
0:
if (message.pinStates[0] === 1){ //
sensorState = 'HIGH'; //
bgColor = '#FF0000'; // # %
} else {
// $
sensorState = 'low'; //
bgColor = 0; // # %
}
httpGet('/json','json',getResponse); //
// ' $
}
[ draw() $ " :
function draw() {
// %
$ '
# :
background(bgColor);
// +
R
text(' $ : ' + sensorState, 30, 30);
}
& . * . 7.16
.
; ,
, %
%
, %
: %,
,
- .
9 Digi 802.15.4 API XBee
. ~ " ,
,
. & $
.
API
.
7
— . & $ $
% .
Рис. 7.16. Снимки с экрана веб-страницы радиомодуля сервера датчика газа. Как сам текст, так и цвет фона окна позволяют с первого взгляда понять текущее состояние качества
воздуха в мастерской: состояние атмосферы в мастерской
нормальное (вверху — фон окна черный) или опасное (внизу — фон окна красный)
Глава 7
384
API XBee
«XBee/
XBee-PRO S2C 802.15.4 RF Module User
Guide», :
http://cms.digi.com/resources/documentation/
Digidocs/90001500. 9
$
Digi — ,
Wi-Fi ,
10. /
.
Заключение
>
" ,
"
. = "
,
. 0
% ,
"
. +
" ,
, " .
# $ , ,
( 13 " -
, 14 — API XBee),
. & $
" % "
% — $
%
. ;
, %
" — $ %
,
" .
; ,
,
,
, "
: .
Свадебные свечи Тома Иго, Пейки Сю (Peiqi Su), Декинга Суна (Deqing Sun), Бена Лайта (Ben Light)
и Энди Зиглера (Andy Sigler)
/
" .
Wi-Fi, " UDP
Глава 8
КАК УЗНАТЬ МЕСТОНАХОЖДЕНИЕ
(ПОЧТИ) ЧЕГО УГОДНО?
К этому времени вы уже должны достаточно хорошо понимать,
как можно организовать сетевое общение объектов между
собой. Вы познакомились с пакетами, сокетами, дейтаграммами,
клиентами, серверами и различными протоколами связи. В этой
и следующей главах мы углубим наши знания, рассмотрев два часто
задаваемых вопроса: «Где я?» и «С кем я имею дело?» Технологии
определения местонахождения и идентификации имеют ряд общих
важных свойств. Вследствие этого их часто путают между собой,
полагая, что технологию определения местонахождения можно
использовать для идентификации лица или объекта и наоборот.
В физическом мире — это две разные задачи, и таковыми они также
часто являются и в сетевом окружении. Системы, определяющие
физическое местонахождение объектов, не всегда обладают
хорошими способностями для определения личности тех, кто там
находится, а системы идентификации не всегда хорошо определяют
точное местонахождение найденных объектов. Точно так же знание
того, кто находится на узле, обменивающемся с вами информацией,
не всегда может помочь узнать местонахождение этого узла.
В последующих примерах мы рассмотрим методы определения
местонахождения объектов и их идентификации как в физическом,
так и в сетевом окружении.
«Адрес 2007» от Моуны Андраос (Mouna Andraos) и Сонали Сридхар (Sonali Sridhar)
& $ GPS. , . 0
'. (J. Nordberg).
Глава 8
388
Компоненты для проектов этой главы
Поскольку предметом рассмотрения этой главы является определение местонахождения различных объектов, то большинство новых деталей в ней — это датчики.
Коды поставщиков
?
A — Arduino Store, http://store.arduino.cc
?
P — Pololu, www.pololu.com
?
AF — Adafruit, http://adafruit.com
?
PX — Parallax, www.parallax.com
?
D — Digi-Key, www.digikey.com
?
RS — RS, www.rs-online.com
?
F — Farnell, www.farnell.com
?
SF — SparkFun, www.sparkfun.com
?
J — Jameco, http://jameco.com
?
SS — Seeed Studio, www.seeedstudio.com
Рис. 8.1. Новые компоненты для проектов этой главы: 1. Приемник Bad Elf GPS Pro+. 2. Приемник GPS Garmin GLO. 3. Модуль
GPS на адаптерной плате компании Adafruit Ultimate GPS Breakout. 4. Ультразвуковой дальномер HC-SR04. 5. Адаптерная плата 9DOF IMU компании Adafruit. 6. Цифровой компас LMS303DLH. 7. Инфракрасный дальномер GP20Y0A21 компании Sharp.
8. Плата Arduino 101
2
1
3
4
7
8
5
6
Как узнать местонахождение (почти) чего угодно?
389
ПРОЕКТ 15. Инфракрасный дальномер
"
, 1 +. = $
Arduino .
MKR1000 — AF: 3156, RS: 124-0657, A: ABX00004,
GBX00011 (3 4#), D: 1659-1005-ND
Arduino 101 — D: 1660-1003-ND, J: 2239331,
SF: DEV-13787, AF: 3033, F: 2520713, RS: 9139999, SS: 114990575, A: ABX00005, GBX00005
(3 4#)
Arduino Uno — D: 1050-1024-ND, J: 2151486,
SF: DEV-11021, A: A000099, AF: 50, F: 1848687,
RS: 715-4081, SS: ARD132D2P
& GP2Y0A21YK, 1 +.
J: 2150256, D: 425-2063-ND, AF: 164, F: 1243869,
RS: 666-6564
10 \, 1 +.
D: P11212-ND, J: 29891, F: 1144605, RS: 762-1736
H
, 3 +.
D: A26509-20-ND, J: 103377, SF: PRT-00116, F:
1593411
> .
]= =
. " .
ПРОЕКТ 16. Ультразвуковой дальномер
"
, 1 +. = $
Arduino .
MKR1000 — AF: 3156, RS: 124-0657, A: ABX00004,
GBX00011 (3 4#), D: 1659-1005-ND
Arduino 101 — D: 1660-1003-ND, J: 2239331,
SF: DEV-13787, AF: 3033, F: 2520713, RS: 9139999, SS: 114990575, A: ABX00005, GBX00005
(3 4#)
Arduino Uno — D: 1050-1024-ND, J: 2151486,
SF: DEV-11021, A: A000099, AF: 50, F 1848687,
RS: 715-4081, SS: ARD132D2P
N HC-SR04, SRF04
. / " ,
.
SF: SEN-13959, D: 1568.1421-ND
H
, 4 +.
.
> .
]= =
. " .
ПРОЕКТ 17. Определение уровня принимаемого сигнала
Arduino- MKR1000, 1 +.
AF: 3156, RS: 124-0657, A: ABX00004, GBX00011
(3 4#), D: 1659-1005-ND
&
ESP8266.
SF: WRL-13231, AF: 2471
" + Wi-Fi, 1 +. +
.
> .
]= =
. " .
ПРОЕКТ 18. Геолокационные службы и протокол NMEA
1
GPS
, 1 +. = $
.
9
.
1
GPS, Global Positioning System —
.
AF: 746, SF: GPS-1275
GPS Bad Elf GPS Pro+
- https://bad-elf.com,
GPS Garmin GLO — -
https://www.garmin.com.
Глава 8
390
Bluetooth Serial, 1 +.
AF: 1588, SF: WRL-12580 WRL-12576
7
USB-to-Serial.
-
SF: DEV-09716 DEV-14050, AF: 3309
284, SS: 317990026
> Bluetooth, 1 +. 4
%
"
Bluetooth, % Bluetooth- .
AF: 1327, RS: 807-7742, SS: 113990026
C
, 1 +.
GPS.
ПРОЕКТ 19. Определение направления с помощью цифрового компаса
C , 1 +.
D: 438-1045-ND, J: 20723 20601, SF: PRT12615 PRT-12002, F: 4692810, AF: 64, SS:
319030002 319030001
"
, 1 +. = $
Arduino .
MKR1000 — AF: 3156, RS: 124-0657, A:
ABX00004, GBX00011 (3 4#), D: 16591005-ND
Arduino 101 — D: 1660-1003-ND, J: 2239331,
SF: DEV-13787, AF: 3033, F: 2520713, RS: 9139999, SS: 114990575, A: ABX00005, GBX00005
(3 4#)
Arduino Uno — D: 1050-1024-ND, J: 2151486,
SF: DEV-11021, A: A000099, AF: 50, F 1848687,
RS: 715-4081, SS: ARD132D2P
& LSM303DLH
ST Microelectronics, 1 +.
AF: 1120, SF: B0B-13303, P: 1250, SS: 101020081
H
, 4 +. # .
D: A26509-20-ND, J: 103377, SF: PRT-00116, F:
1593411
> .
]= =
. " .
ПРОЕКТ 20. Определение положения объекта в пространстве
C , 1 +.
D: 438-1045-ND, J: 20723 20601, SF: PRT12615 PRT-12002, F: 4692810, AF: 64, SS:
319030002 319030001
"
, 1 +. = $
Arduino .
MKR1000 — AF: 3156, RS: 124-0657, A:
ABX00004, GBX00011 (3 4#), D: 16591005-ND
Arduino 101 — D: 1660-1003-ND, J: 2239331,
SF: DEV-13787, AF: 3033, F: 2520713, RS: 9139999, SS: 114990575, A: ABX00005, GBX00005
(3 4#)
Arduino Uno — D: 1050-1024-ND, J: 2151486,
SF: DEV-11021, A: A000099, AF: 50, F 1848687,
RS: 715-4081, SS: ARD132D2P
/ , 1 +. & LSM303 L3Gxx ST Microelectronics. Arduino101
"
.
AF: 1120, SF: BOB-3303, P: 1250, SS: 101020081
H
, 6–8 +.
JD: A26509-20-ND, J: 103377, SF: PRT-00116, F:
1593411
> .
]= =
. " .
Как узнать местонахождение (почти) чего угодно?
391
Сетевое местонахождение и физическое
Одной из самых распространенных задач, решения которых люди хотят добиться с помощью
сенсорных систем, является определение местонахождения объектов. Естественная реакция на
осознание диапазона всего того, что могут выявлять датчики, — это восторг от предоставляемой ими свободы. Ведь теперь для взаимодействия с компьютерами больше не требуется быть
прикованным к креслу. Можно свободно танцевать, бегать, прыгать, — а компьютер все равно
сможет различить выполняемые вами действия и отреагировать на них каким-либо образом.
*
— $
, ,
. %
Wireless
E911 (
,
) ,
,
, $
. 0
-
% .
2
. 0"
,
, "
:
IP-
-
. * $ , , —
%
, . / , %
( ! ) ,
Wi-Fi. ;
,
" . 4
- $ ,
,
,
, ,
,
. ; ,
,
.
Шаг 1: спросите человека
_ .
* $ %
, "
% $ , , "
,
. 3
% ,
,
.
$ , $
% — ,
, —
, .
. 4
,
, — , " . & " % :
% % , , ,
392
Глава 8
, " , " , , —
-
. *
, ,
,
, ,
. & ,
% , ,
, — $
,
, "
"
.
, " ,
, " ,
, " .
% $
"
" ,
.
;, , , ,
,
.
/ % ,
. ;
"
%
$ . #
,
,
, , ,
$ , . & $
"
. 2 " % ,
, ,
. ;
,
.
* , ,
,
" . ;
,
« - »,
, "
. '
$
— , $
$ , —
"
.
9 . # ,
- ,
—
— "
. ' ,
? & , , ,
, " -
. ;
$
,
, % . & ,
,
, ,
", $ % .
* , "
" . $,
,
,
, ,
% ,
" .
Как узнать местонахождение (почти) чего угодно?
393
Шаг 2: определитесь на местности
, , % .
_
. * ,
, % ,
- . $
,
. 4
,
. ;, % , "
—
$ .
& $ , , % ,
,
, .
#
, %
.
;, %
% #3.
* $
-
#3, %
,
" .
,
. +
, $ .
0
" ,
%
.
* , - www.vterrain.org/Culture/
geocoding.html
#3
,
2
Virtual Terrain Project . , -
2
«&
%».
geocoder.opencagedata.com
,
"
OpenStreetmaps,
API Google’s maps -
developers.google.com/maps.
q (% )
, " ,
. * ,
,
. 0
, $
$
" . + %
% ,
OpenCellID (www.opencellid.org), " ,
GPS.
* IP-
,
. ;
, "
IP- .
, %
"
, $,
% , ,
+
$ % ,
% .
q
IP-
,
" ,
,
+
.
, IP-
394
IP- . & "
.
7 , ,
Глава 8
, ,
. * % , $
, " " ,
.
Шаг 3: уточните происходящее
, ,
: % $ .
,
% , " . &
,
- . X ,
,
, "
.
& ,
. +
% , ,
. + , - - ,
% ,
, . &
. , - , % , ,
$ . * ,
. & -
— %
,
, $
. &
, "
" " , - .
[
,
. X
. * ,
- ,
, $ .
0
, , —
,
…
Как узнать местонахождение (почти) чего угодно?
395
35 способов определить свое местонахождение
*
ETech3 2004, O’Reilly,
~ (Chris Heathcote)
% : «35
»4. 0
,
,
% . +, , , % - - %
. 4 —
, "
%
. =
$ .
• , 2 . +
, $ %
, .
•
•
• =
?
?
?
• *
•
" ?
.
• * .
• X /
.
• * .
• * .
• 7
.
-
• ; — ,
" Wi-Fi.
• GPS, A-GPS5, WAAS6 % GPS.
• >% %
.
/ -
• # 7.
• 0
.
• # -.
• + :
?
• + -, "
.
• .
• +
.
3
-
Emerging Technology Conference —
" .
4
& : «35 Ways to Find Your Location».
5
A-GPS ( . Assisted GPS) — , " «
» GPS- . X
.
6
WAAS (Wide Area Augmentation System) —
. 9 #3 %
GPS .
7
# ( ) —
( " ) ( ,
,
,
) .
Глава 8
396
Определение расстояния
Электронные системы определения местонахождения — такие как GPS, сонар или локация мобильных телефонов — сначала кажутся каким-то волшебством, поскольку нет никаких видимых
индикаторов принципа их действия. Но если разбить этот процесс на составляющие компоненты, то ничего волшебного в нем не останется, и все станет сравнительно просто для понимания.
Большинство систем определения физического местоположения объекта основаны на одном из
двух принципов: измерении времени, затрачиваемого сигналом для прохождения от известного места до этого объекта, или измерении уровня сигнала в точке приема. В обоих методах для
определения местоположения объекта в двух- или трехмерном пространстве с помощью трилатерации комбинируются измерения от нескольких источников.
7
,
.
,
$ . / , , % %
,
,
. ,
, $ ,
,
,
$ .
* , GPS
,
,
. #
,
, , " .
— Skyhook (www.
skyhookwireless.com) —
(Wi-Fi, GPS
)
.
7
. &
" ,
, ,
. 9
$
, . # . ;,
,
. ; GPS
.
&
"
"
. 2
, $
. 9
.
, $ .
,
«
» «
»
, . &
.
3 " %
, , . $
,
Как узнать местонахождение (почти) чего угодно?
. ;
" ,
.
397
&
, —
. & "
.
Пассивное определение расстояния
X SRF04
GP2Y0A21YK
. = SRF04 , GP2Y0A21YK —
. =
"
. 0
:
GP2Y0A21YK —
10 80 ,
SRF04 — 0 3–4 . ;
,
, $
%
. 0
"" ,
,
" ,
" .
Проект 15
Инфракрасный дальномер
Инфракрасные дальномеры серии GP2Yx компании Sharp достаточно точно определяют короткие расстояния, измеряя яркость отраженного от цели инфракрасного луча. На рис. 8.2 показаны
монтажная (вверху) и принципиальная (внизу) схемы подключения инфракрасного дальномера
GP2Y0A21YK к модулю Arduino. Эта связка может определять объекты, находящиеся от нее на
расстоянии от 10 до 80 см.
& Sharp —
,
,
,
. & GP2Y0A21YK,
: www.sharp-world.com/products/device/lineup/data/pdf/datasheet/gp2y0a21yk_e.
pdf, . *
10 80 . $ 21,7 &¨ . &
— 30 , $
.
Требуемые компоненты
7 Arduino, 1 %.
+
: +5 &.
+
Sharp GP2Y0A21YK,
1 %.
10 [, 1 %.
, 3 %.
+
"
,
. + "
Глава 8
398
Напряжение питания
Uno
=
, ,
, ,
5 &. *, 13 7, $
3,3 &.
ON
+5 В
Напряжение питания
+5 В
Напряжение
питания
10 мФ
Выход
Модуль
микроконтроллера
A0
Общий
Общий
Рис. 8.2. Монтажная (вверху) и принципиальная (внизу) схемы подключения инфракрасного дальномера GP2Y0A21YK компании
Sharp к модулю Arduino. Конденсатор, подсоединенный параллельно линиям питания дальномера, сглаживает колебания напряжения и тока, вызываемые его нагрузкой
Как узнать местонахождение (почти) чего угодно?
%
,
,
.
& , % " ,
.
~
GP2Y0A21YK 4,5–5,5 &,
. & , 3,3 & MKR1000 Arduino 101
. 0
$
,
, .
399
# "
. 2
.
$
+ $ , ,
, , —
%
, - . ,
— analogRead() $ .
Пишем код
/*
\-
: Arduino
Sharp GP2xx
*/
void setup() {
Serial.begin(9600); // \ # $
// ' $
}
void loop() {
int sensorValue = analogRead(A0);
// $
// $
float voltage = sensorValue * (5.0
// +
float distance = 21.7 / voltage;
Serial.print(voltage);
Serial.print(" V\t");
Serial.print(distance);
Serial.println(" ");
// 39
,
// $ .
delay(39);
}
// Z
/ 1024.0);
Глава 8
400
Проект 16
Ультразвуковой дальномер
Ультразвуковые дальномеры измеряют расстояние примерно так же, как это делают инфракрасные, но обладают большим радиусом действия. Разумеется, вместо инфракрасного света они
излучают ультразвуковой сигнал и принимают возвращенное эхо. Показания датчика отражают
время возвращения эха, которое соответствует расстоянию до отражателя. На рынке предлагается широкий диапазон модулей ультразвуковых дальномеров, большинство из которых основаны на керамических преобразователях компании ProWave (www.prowave.com.tw). Самые
первые модули для электронщиков-любителей выпускались компанией Devantech (www.robotelectronics.co.uk), но, благодаря открытой конструкции этих модулей, сейчас их предлагают
практически все розничные поставщики электронных компонентов.
Требуемые компоненты
7 Arduino, 1 %.
+ :
.
X HC-SR04, SRF04
, 1 %.
, 4 %.
#" ,
Devantech
SRF04,
(
$ HC-SR04). & ,
, ,
(trigger)
(echo).
10 , ,
.
. = $
.
* , $ 58, ,
148 — . * . 8.3
( ) (
)
HC-SR04 Arduino.
X
,
,
% . * ,
SRF04
70° ( " $ )
3–4 . #
, % ,
,
" % .
* . 8.4
" 4×4 ,
. $ ,
, % , — $
.
"
50 , 250 .
/
3,3 &,
/
Arduino 101 MKR1000, 5 &,
5 &, USB.
Как узнать местонахождение (почти) чего угодно?
5В
401
5В
Модуль
микроконтроллера
Цифровой вывод 4
Цифровой вывод 3
Напряжение
питания (Vcc)
Вывод активации подачи
выходного сигнала (Trigger)
Вывод приема отраженного
сигнала (Echo)
Uno
GND.
Echo
Vcc
Общий
Trig.
Общий
ON
Рис. 8.3. Принципиальная (слева) и монтажная (справа)
схемы подключения ультразвукового датчика HC-SR04
к модулю Arduino
Рис. 8.4. Измерение расстояния в двух координатах с использованием ультразвуковых дальномеров. Квадрат на каждой
схеме представляет комнату размером 4×4 метра. Для того чтобы обеспечить покрытие всего пространства комнаты, нужно
расположить несколько датчиков по ее сторонам
Измерение расстояния «спереди-сзади»
Измерение расстояния «слева-справа»
Датчик 1
Датчик 4
Датчик 3
Датчик 2
Датчик 5
Глава 8
402
Пишем код
# "
, ,
. ;
,
, .
/*
M$
: Arduino
*/
const int triggerPin = 4;
const int echoPin = 3;
void setup() {
//
// ' $
pinMode(triggerPin, OUTPUT);
pinMode(echoPin, INPUT);
Serial.begin(9600);
}
# $
void loop() {
digitalWrite(triggerPin, HIGH); //
//
#
(trigger)
delayMicroseconds(10);
// 10
,
digitalWrite(triggerPin, LOW); //
//
// $
// (echo):
long pulsewidth = pulseIn(echoPin, HIGH);
float distance = pulsewidth / 58.0; // cm = microseconds/58
Serial.println(distance);
}
Активное определение расстояния
X
,
" ,
. #
GPS
( . 8.5). / (
GPS) (
GPS).
. ; % %
. *
. =
-
" , $
.
*
, . =
$
, $ ,
. 0
GPS
GPS
,
"
.
Wi-Fi, Bluetooth, 802.15.4
Как узнать местонахождение (почти) чего угодно?
, $
.
0
, % , $
-
.
* , , , , , -
403
Bluetooth %
,
Bluetooth — . " , , . & $ , , ,
. *
, $ % , , , - ,
, MAC-
(
" ).
Рис. 8.5. Активное и пассивное определение расстояния
Ответный сигнал, излучаемый
Response signal generated by
мобильным устройством
mobile unit
(e.g., cell
phone).
(например,
сотовым
телефоном)
Основное
устройство
Base
unit (sensor)
sends out
(дальномер) излучает сигнал,
signal,
reads
reflection
затем принимает сигнал,from
отраженный
от объекта
mobile object
or person
Исходный
сигнал,
излучаемый
Initial signal
generated
by
основным устройством
base unit (e.g., cell tower)
(например, базовой станцией)
Пассивное определение
Активное определение
Active
distance ranging
расстояния
Passive
distance ranging
расстояния
Глава 8
404
Проект 17
Определение уровня принимаемого сигнала
В проектах с устройствами Wi-Fi главы 4, в проектах с устройствами LoRa и Bluetooth главы 6
и в проекте с использованием устройств Digi 802.15.4 главы 7 мы познакомились со свойством
этих радиоустройств, заключающемся в индикации уровня принимаемого сигнала8 (ИУПС). Эта
характеристика предоставляет нам информацию о том, какой силы был последний принятый
устройством сигнал. При отсутствии преград сила принятого сигнала обратно пропорциональна
квадрату расстояния от приемника до передатчика. Таким образом, если мы знаем силу принимаемого сигнала, то можем приблизительно установить расстояние до передатчика.
* « »,
" +X#
. &
,
.
3
%,
. ,
,
,
- " . ;
, +X#
,
"
—
% — .
#
(>). & ,
–65 >.
$ ? 0
% " >.
' >,
. * ,
1 " log 1 >. log 1 = 0, 1 & =
0 >. "
1 &, > 0. * , 0,5 & = (log 0,0005) > –3,01 >.
= : 0,25 & = (log 0,00025) >
–6,02 >.
8
0 . Received Signal Strength Indicator, RSSI.
4
, , 0 > — $ " , 0 > ,
%
3 > . '
,
,
%
. & ,
, %
.
&
,
, , "
. &
Wi-Fi 4
,
MKR1000 ESP8266,
" :
long rssi = WiFi.RSSI();
3 LoRa 6 $
:
int rssi = LoRa.packetRssi();
= ,
Bluetooth LE
" "
" " node.js:
console.log('signal strength: ' +
peripheral.rssi);
# Bluetooth
-
Как узнать местонахождение (почти) чего угодно?
,
$
.
* ,
Digi 802.15.4 7
" Digi
API " "
:
message.rssi = -thisPacket[5];
& $
.
405
+
node.js,
p5.js.
POST:
POST /rssi/value
value
.
#
,
" GET:
GET /rssi
Создаем сервер ИУПС
,
node.js
server.js. ; , ,
express:
$ npm install express
/*
Z \M Z
: node.js
*/
var express = require('express'); // '
express:
var server = express(); // C$ " server,
// $ express
var rssi = -100; //
//
2 rssi ,
:
2
:
getRssi() postRssi(). /
. —
postRssi() —
POST,
URL- .
3 — getRssi() —
:
function postRssi(request, response) {
rssi = request.params.rssi; //
$ $
// $
response.send(" $ \M Z: " + rssi); //
//
response.end(); // '
}
function getRssi(request, response) {
// Z$
// meta
var message = "<meta http-equiv=\"refresh\"
content=\"3\">\n";
var message = " $ \M Z: " +
rssi + " <br>";
message += " - ";
if (rssi <= -60 ) { // Z
message += " ";
}
Глава 8
406
if (rssi > -60 && rssi <=-40 ) {// ^
//
message += "
- ";
}
if (rssi > -40 && rssi <=-20 ) {
message += "
- ";
}
if (rssi > -20 ) { //
message += "
";
}
message += " " // #
response.send(message); //
response.end(); // '
}
*
GET POST. &
:
//
server.listen(8080);
//
$ :
server.get('/rssi', getRssi); // GET /rssi
server.post('/rssi/:rssi', postRssi); // POST /rssi/value
Рис. 8.6. Вывод в окне браузера результатов работы скетча, получающего сведения об уровне силы радиосигнала
от только что созданного нами сценария сервера ИУПС.
Сервер может выводить значения уровня принятого сигнала не только устройств Wi-Fi. С таким же успехом можно создать клиента, который будет получать от сервера значения
уровня принимаемого сигнала радиоустройств LoRa, или
Bluetooth, или любого другого радиоустройства, обладающего возможностью измерять величину уровня принимаемого им радиосигнала. Если такой клиент может осуществлять вызовы HTTP POST, он будет работать
= $
,
% " . ,
, " GET
" ,
,
$ . 7
.
# " HTTP POST
ESP8266 MRH1000,
"
,
Wi-Fi.
= $
.
$
. 8.6.
Как узнать местонахождение (почти) чего угодно?
407
Пишем код скетча для вывода сведений об уровне силы радиосигнала
; , " ,
config.h, "
. 3
(
% )
%
. [ setup() % WiFi :
/*
RSSI HTTP Client
Context: Arduino, with WINC1500 module
*/
// include required libraries and config files
#include <SPI.h>
#include <WiFi101.h>
//#include <ESP8266WiFi.h> //
- ESP8266
// $ R
#include <ArduinoHttpClient.h>
#include "config.h"
WiFiClient netSocket; //
const char server[] = "192.168.0.8"; // IP- .
// R $
String route = "/rssi/"; // API
void setup() {
Serial.begin(9600); // \ # $ ' $
// ' Wi-Fi,
while ( WiFi.status() != WL_CONNECTED) {
Serial.print(" ' : ");
Serial.println(ssid); // R (SSID)
WiFi.begin(ssid, password); // '
delay(2000);
}
Serial.print(" ' : "); // + ' ,
Serial.println(ssid); //
R
}
& loop()
HTTP
POST. & :
void loop() {
HttpClient http(netSocket, server, 8080); // Z$
// HTTP
int rssi = WiFi.RSSI(); // $ \M Z:
http.post(route + rssi); // $ POST:
while (http.connected()) { // ' ,
if (http.available()) { // ,
String result = http.readString(); //
Serial.println(result); //
R
}
}
// #
http.stop(); // $ $
delay(3000); // 3
}
2 $
. 2
: http://
localhost:8080/rssi, GET. = "
-
" ( % Wi-Fi),
$
. =
% Wi-Fi, .
Глава 8
408
Множественное отражение сигнала
#
, " % Wi-Fi
" ,
.
*
,
.
#
% $ -
, " $ " ( . 8.7).
* ,
%
,
,
,
% . / %
, "
.
Рис. 8.7. Эффект множественного отражения сигнала. Отраженные радиоволны создают эффект наличия фантомных радиомаяков, которые приемник не может отличить от настоящего радиомаяка. Это вызывает ошибки в вычислениях, основанных на
уровне мощности сигнала
Actual
Настоящий
Beacon
радиомаяк
Фантомный
Phantom
радиомаяк
Beacon
Фантомный
Phantom
радиомаяк
Beacon
Отраженный
Reflected
сигнал
Signal
Отраженный
Reflected
сигнал
Signal
Основной
Primary
сигнал
Signal
Здание
Здание
Building
Building
Приемник
Receiver
Как узнать местонахождение (почти) чего угодно?
; " , ,
%. $, ,
% , — , ,
% %
,
,
" . & $ $
409
,
% ,
% .
& GPS $
%
, %
$
. 0
,
" .
Определение местонахождения методом трилатерации
Определение расстояния предоставляет информацию о том, как далеко в каком-либо одном направлении находится объект от точки, из которой выполняется это определение, но не предоставляет полной информации о местоположении объекта. Расстояние между исходной точкой
и целевым объектом определяется кругом с центром в исходной точке (или сферой — в случае
трех измерений). Наш объект может находиться в любой точке этого круга.
$,
- ,
% , . '"
,
, . / -
. 4 ,
, ( . 8.8). =
,
$
Рис. 8.8. Трилатерация на плоскости: расстояние от точки до объекта определяет круг возможных местонахождений объекта
(слева), расстояние до объекта от двух точек сужает возможное местонахождение объекта до двух точек (в центре), а расстояние до объекта от трех точек определяет точное его местонахождение в одной точке плоскости (справа)
Глава 8
410
. &
, " , ,
. 7
, ,
$ , .
& (GPS)
2 . 7
" .
, -
GPS. ,
. >% GPS % ,
%
. # ,
Wireless E911, ,
$ .
Проект 18
Геолокационные службы и протокол NMEA
Хорошей новостью для пользователей системы GPS является то, что им не нужно самостоятельно выполнять вычисления трилатерации или триангуляции, поскольку это делает сам приемник
GPS, который выдает пользователю его местоположение в виде географических координат (широты и долготы). В системе GPS используется несколько протоколов для приемников, но самым
распространенным из них является протокол NMEA 0183, разработанный ассоциацией NMEA9
США. Практически все приемники GPS, имеющиеся на рынке, предоставляют данные по этому
протоколу, а также обычно еще по одному или двум другим протоколам.
>
Bluetooth
Bluefruit ( GPS),
1 %.
, GPS. * % , GPS.
* ,
, , -,
NMEA. $
$ , , GPS .
NMEA 0183 — $
. >%
,
RS-232 TTL. #
NMEA 0183 4800
,
.
NMEA 0183
& "
GPS- , %
%
"
GPS- . * GPS-
,
$
GPS
Требуемые компоненты
GPS- ( .
), 1 %.
-
Bluetooth- Bluefruit (
GPS), 1 %.
9
NMEA, National Marine Electronics Association — * $ .
Как узнать местонахождение (почти) чего угодно?
411
Рис. 8.9. Модуль Ultimate GPS Breakout компании Adafruit (справа), подключенный
к ее же Bluetooth-модулю Bluefruit (слева). Чтобы получить качественный сигнал GPS,
нужно находиться на открытой местности, для чего более чем удобно использовать
беспроводную передачу данных и батарейный источник питания. Комплект радиоустройств Bluefruit содержит разъем для подключения батареи, который можно припаять к радиоустройству, что позволит питать от аккумулятора LiPo как само радиоустройство, так и подключенный к нему приемник GPS
FIX
DTR
>RX
<TX
Vin
DSR
GND
STS
3Vout
3Vo
V
3.3V
EN
VBAT
FIX
TX
RX
GND
VIN
PPS
%
. ; Garmin, Trimble, Bad Elf
. 0
GLO Garmin
GPS Pro GPS Pro+ Bad Elf. ~
GPS
"
,
Bluetooth
,
.
*
GPS,
. * . 8.9 Ultimate
GPS Breakout Adafruit,
Bluetooth- Bluefruit, 2.
& $
,
GPS GLO Garmin GPS-
Bad Elf.
Разбор предложений NMEA
NMEA 0183 %
, GPS
. GPS Adafruit
SparkFun Bluetooth "
Bluefruit ( . 8.9) " USB/TTLSerial. 3
GPS Garmin Bad Elf
" Bluetooth.
. $ (
9600 ) ":
Глава 8
412
$GPGGA,180226.000,4040.6559,N,07358.1789,W,1,04,6.6,75.4,M,-34.3,M,,0000*5B
$GPGSA,A,3,12,25,09,18,,,,,,,,,6.7,6.6,1.0*36
$GPGSV,3,1,10,22,72,171,,14,67,338,,25,39,126,39,18,39,146,35*70
$GPGSV,3,2,10,31,35,228,20,12,35,073,37,09,15,047,29,11,09,302,20*7D
$GPGSV,3,3,10,32,04,314,17,27,02,049,15*73
$GPRMC,180226.000,A,4040.6559,N,07358.1789,W,0.29,290.90,220411,,*12
$GPGGA,180227.000,4040.6559,N,07358.1789,W,1,04,6.6,75.4,M,-34.3,M,,0000*5A
$GPGSA,A,3,12,25,09,18,,,,,,,,,6.7,6.6,1.0*36
$GPRMC,180227.000,A,4040.6559,N,07358.1789,W,0.30,289.06,220411,,*1C
& NMEA
, . *
, —
, — ,
. .
($),
. 2
,
. (*), , .
9 $GPRMC,
(
% ). # " RMC10
, $
. /
,
. + , " ,
. 8.1.
3 $GPGSV (GPS Satellites in View11)
. ; $
GPS . 4 % ,
, GPS
. *
" , $
10
11
RMC, Recommended Minimum specific —
.
# GPS .
« »
, 10–15
.
NMEA
"
$ " . / " ,
«7 % - » 2.
*
NMEA,
.
& % GPS ,
% , . &
HTML5
, :
GPS- , "
, Wi-Fi
-
$
. 4
GPS,
— , p5.js , NMEA
, $
API
HTML5.
/
Bluetooth
Как узнать местонахождение (почти) чего угодно?
413
Таблица 8.1. Информация, содержащаяся в предложении $GPRMC протокола NMEA
Идентификатор сообщения
Время
Состояние данных (действительные или нет)
Широта
Индикатор юга/севера
Долгота
Индикатор востока/запада
Скорость относительно поверхности (земли)
Направление движения относительно поверхности
Дата
Магнитное склонение
Режим
Контрольная сумма (Перед контрольной суммой нет запятой.
Последняя запятая в таком предложении ставится не перед контрольной суммой, а между магнитным склонением и режимом,
которые в этом предложении отсутствуют)
% GPS- " iOS Android.
GPS-
Garmin Bad Elf
iOS, $
,
$ % GPS,
GPS.
$GPRMC
180226,000 18:02:26 GMT12
A—
(V —
)
4040.6559 40°40.6559'
N — # (North), S — (South)
07358,1789 73°58,1789'
W — 2 (West), E — & (East)
0,29
290.90 290,90° #
220411 22 , 2011
*12
X Android
% GPS,
" "
Bluetooth GPS, https://play.google.com/
store/apps/details?id=googoo.android.btgps.
Выбор оборудования GPS
*
%
GPS ( . 8.10),
, "
. =
,
.
>%
GPS
TTL NMEA 0183. $
, % , . 9 $ ,
, , %
GPS,
( , % , % ),
( ,
% , % ) $ . SparkFun %
GPS,
12
GMT, Greenwich Mean Time —
q .
, : https://www.sparkfun.com/pages/
GPS_Guide. & ,
GPS , — $
: « » « » (« »). *
GPS " , .
&
GPS GPS GLO Garmin ( .
. 8.10, ) — % , ,
" Bluetooth. &
$
GPS,
% .
Глава 8
414
а
б
в
г
Рис. 8.10. Приемники GPS разных производителей: а — GPS-приемник EM-506 компании SparkFun. 48 каналов, хороший прием, и не такой дорогой, как другие варианты; б — модуль Ultimate GPS Breakout компании Adafruit. 22 канала (66 для поиска),
оснащен также памятью для хранения данных; в — приемник GPS GLO компании Garmin. Оснащен интерфейсом Bluetooth и
смонтирован в компактном корпусе; г — приемник GPS Pro+ компании Bad Elf. Компактный, имеет экран пользовательского
интерфейса, оснащен интерфейсом Bluetooth
Геолокация в браузере
& HTML5
API
navigator,
%
. = " $ getCurrentPosition(), —
watchPosition(). & $
success failure options
. + $
"
p5.js.
$ , .
& ,
API
,
HTML, " $ .
7
% ,
HTTP,
$
HTTPS,
%
.
# index.html — $ p5.js, $
,
% . , sketch.js,
" .
&
GeolocationServer, — public
p5.js: index.html, sketch.js,
p5.js. &
p5-manager $ " " :
$ p5 g -b public
$ cd public
$ p5 u
Как узнать местонахождение (почти) чего угодно?
415
Определяем местонахождение
* "
label,
JSON options
.
& setup() ,
%
.
>% % , % . * ,
watchPosition() .
&
: % ,
% ,
, ,
JSON :
/*
#
Context: p5.js
*/
var label = "
var options = {
enableHighAccuracy: true,
timeout: 10000,
maximumAge: 0
};
$
#
...";
function setup() {
//
- '
//
createCanvas(windowWidth, windowHeight);
fill('#A3B5CF');
// Z-
textSize(36);
// $ %
textAlign(CENTER); // + #
// #
navigator.geolocation.watchPosition(success, failure,
options);
}
[ draw() %
:
function draw () {
background('#0D1133');
text(label, width/2, 100);
}
[
,
"
label. & JSON options
(HighAccuracy) , $ %
.toFixed() "
.
% % " .
function success(position) {
var coordinates = position.coords;
var now = new Date(position.timestamp);
label = '+ :'
+ '\n : ' + coordinates.latitude.toFixed(5)
+ '\n: ' + coordinates.longitude.toFixed(5)
+ '\n+ - ' + coordinates.accuracy + ' .
: '
+ '\n' + new Date(position.timestamp);
}
success()
[ fail "
%
label:
ure()
& . #
.
function failure(error) {
label = ' ' + error.code + ': \n' + error.message;
}
Глава 8
416
Предоставление файлов по протоколу HTTPS
% ,
, "
API,
HTTPS, %
, "
$ .
2 %
.
0 HTTPS, ,
%
,
.
%
, HTTP,
, % . - ,
, . *,
- % ,
( $ — . ! «4
HTTPS »).
# "
GeolocationServer
node
https-server.js. #
. '
keys
,
" :
$ openssl req -newkey rsa:2048 -nodes
-keyout keys/domain.key -x509 -days 365
-out keys/domain.crt
&
%
.
% , $
. &
keys : domain.crt domain.key. — $
, —
%
, "
%
. 3 "
% .
Для систем под Windows
Cygwin bash Windows 10 openSSL. *
Linux
macOS, Windows. + $
OpenSSL macOS
% - , Linux.
7
Raspberry Pi.
# ,
. , , "
npm express.js:
$ npm install express
2 https-server.js
" .
Как узнать местонахождение (почти) чего угодно?
417
Создаем сервер HTTPS
*%
HTTP HTTPS.
express,
node.
js: http, https fs. — fs —
:
=
HTTPS
, " ,
,
"
fs.readFileSync().
=
express.static(),
$ HTTP
HTTPS,
/*
Z HTTP/HTTPS
: node.js
*/
// '
" :
var express = require('express'); // '
// express:
var https = require('https'); // HTTPS
var http = require('http');
// http
var fs = require('fs');
// filesystem
var server = express();
// Z$ " server,
// $ express
var options = { //
HTTPS
key: fs.readFileSync('./keys/domain.key'), // '
cert: fs.readFileSync('./keys/domain.crt') // %
};
server.use('/', httpRedirect); // % # '
// $ http
server.use('/',express.static('public')); // ,
// ' %
httpRedirect:
2
redirect. /
,
"
HTTPS, , HTTPS. 3 "
HTTPS
express.static():
* ,
$
HTTP,
HTTPS. # HTTPS
443:
.
function httpRedirect(request,response, next) {
if (!request.secure) {
console.log(" $ http $
$ https");
response.redirect('https://' + request.hostname + request.url);
} else {
next(); // $ % #
express.static()
}
}
// :
http.createServer(server).listen(8080); // $
// HTTP
https.createServer(options, server).listen(443); //
// $ HTTPS
418
= $
%
macOS Linux
sudo " :
$ sudo node https-server.js
2
, -
: http://
localhost:8080. #
$ HTTPS,
Рис. 8.11. Пример страницы геолокации в браузере на
устройстве под Android. Обратите внимание на перечеркнутый префикс https в адресной строке браузера — таким
образом браузер информирует вас о том, что сервер использует недостоверный сертификат (в данном случае — подписанный нами самими)
Глава 8
% ,
. X
, %
(
Chrome "
Advanced). & % index.html.
2 ,
,
% . = "
% ,
% . * . 8.11
.
% GPS
$
.
9 GPS
,
"
. $ ,
, .
7
"
GPS , , , : %
? #
,
GPS,
.
$,
, ,
, % $ ,
.
Как узнать местонахождение (почти) чего угодно?
419
Протокол HTTPS и сертификаты
,
HTTP TCP.
HTTP,
%
%
" % . _ ,
. /
. ;
,
,
, $
% HTTP, HTTPS.
> HTTPS
TLS13.
, , —
,
, , !
HTTPS.
> # , !#
HTTPS,
, # . >
. Z
,
. & , ,
IP- ,
. #
,
% " ,
.
,
% . #" , %
, %
"
,
.
13
TLS, Transport Layer Security — "
.
$ ,
,
,
$
.
, " "
" , %
$ . '
, $
. 4
,
,
" . &
"
" ,
%
( . . 8.11).
~ "
, %
% $ ,
, Symantec, Comodo,
GoDaddy GlobalSign. +
$ .
,
Internet Security Research
Group14
Let’s Encrypt,
. 0 Electronic Frontier
Foundation (certbot.eff.org)
Let’s Encrypt. 4
HTTPS, $
,
, .
14
q +
.
Глава 8
420
Определение направления и положения в пространстве
Определив свое местонахождение, интересно также определить свое положение относительно
окружающего мира. Люди обладают врожденной способностью ориентироваться в окружающем пространстве, но объекты такой способности лишены. Поэтому для уточнения ориентации
объектов обычно применяются соответствующие датчики: магнитометры, акселерометры и гироскопы. С их помощью можно определить, в какую сторону света вы смотрите, а также где верх
и где низ.
Q , , — $
, 2 . 4 -
,
, ,
. *
,
$
. &
— . 9 : (roll) —
, ,
(pitch) —
( ) .
(yaw). ,
"
X, Y Z
. / —
# . 3
$
# (surge), # (sway)
# (heave). & $
%
( . 8.12) % .
.
* ,
2 . G
$
— $ %
. ;,
Рис. 8.12. Вращения и смещения объекта в трех измерениях
Крен (roll)
Продольное
смещение
(surge)
Рыскание (yaw)
Вертикальное смещение
(heave)
Тангаж (pitch)
Боковое смещение
(sway)
Как узнать местонахождение (почти) чего угодно?
2 ,
,
, . \
"
"
. + ,
,
,
421
" ,
—
, . /
" . & ,
% " . 3
Arduino 101
.
Терминология датчиков ориентации
& ,
"
, $ . ! (IMU)15, Arduino
101, " $ , —
CurieIMU. &
. *%
,
,
Analog Devices, Freescale, ST Microelectronics
and Bosch. = IMU ,
(AHRS)16,
! ,
(MARG)17
6- (6-DOF)18.
#" 9-
, "
$ , "
. Adafruit
10-DOF, " .
= " . *
" ,
$
15
0 . Inertial Measurement Unit, IMU.
0 . Attitude and Heading Reference System, AHRS —
.
17
0 . Magnetism, Angular Rate and Gravity, MARG.
18
0 . 6-Degree Of Freedom sensor, 6-DOF.
16
SPI,
I2C. & $ , ,
: X, Y
Z. 0 Z , $
"
.
*
. _
! (/ 2) g (1 g =
9,8 / 2). X ( / ).
&
. * , LSM303
ST Microelectronics +/–2 g +/–16 g, — +/–1,8
+/–8,1 . 3 L3GD20
250
2000 . ; . =
2 g,
% . ,
" 250 ,
Глава 8
422
.
*
,
. "
$ % , — .
"
—
, $ , .
;,
, ,
, — $ . ;
%
( . 8.13).
( ), % Z,
X Y
. 4
,
Z ,
. " Y ( )
% X,
.
3 " X
(
) %
Y.
[
, " , . = $
%
. * ,
2 g % 16
216, –32 768 32 767. 2 ,
–2 g +2 g,
" :
$ _ /32,768 =
/2.0
:
= $ _ * 2.0 / 32,768
2 .
* $
, , — ,
:
.
Рис. 8.13. Оси трехмерного датчика. Показания его акселерометра будут такими, как здесь показано
Значение координаты Z наибольшее,
координаты X и Y — в состоянии
покоя
Значение координаты X наибольшее,
координаты Z и Y — в состоянии
покоя
Значение координаты Y наибольшее,
координаты Z и X — в состоянии
покоя
Как узнать местонахождение (почти) чего угодно?
423
Проект 19
Определение направления с помощью цифрового компаса
Магнитометры, которые также называются цифровыми компасами, измеряют изменения в магнитном поле Земли, точно так же, как это делают обычные компасы. При этом, как и обычные
компасы, цифровые компасы подвержены помехам от внешних магнитных полей, включая поля,
генерируемые мощной электрической индукцией. Поэтому направление с помощью цифрового
компаса можно определить, если вы находитесь в пространстве, в котором нет слишком сильных магнитных помех.
& $
ST Microelectronics LSM303.
7 Adafruit, SparkFun Polulu. * . 8.13
9-DOF Adafruit,
. 7
I2C. = LSM303 $
"
, " .
–32,768
32,767, +/– 1,3 .
= LSM303 16- %
-
* . 8.14
(
Требуемые компоненты
> , 1 %.
7 Arduino, 1 %.
+ : % I2C.
Z LSM303DLH ST Microelectronics, 1 %.
, 4 %.
( )
)
Рис. 8.14. Монтажная (слева) и принципиальная (справа) схемы подключения модуля
9-DOF компании Adafruit с компасом LSM303 к микроконтроллерной плате MKR1000
(здесь показаны только задействованные выводы). Такой вариант подключения можно
использовать с любой совместимой с Arduino микроконтроллерной платой, поддерживающей интерфейс I2C
A B
C D E
F
G H
I
J
1
1
5
5
10
10
15
15
20
X Y Z
20
9 DOF
25
30
A B
C D E
LRDY
LIN2
LIN1
GRDY
GINT
SDA
SCL
GND
3Vo
VIN
F
G H
Напряжение питания (Vcc)
SCL
SDA
SDA
SCL
Модуль
микроконтроллера
GND
3Vo
25
Общий
30
I
J
+Vcc
Vin
Модуль компаса
LSM303DLH
Глава 8
424
9-DOF Adafruit
LSM303
MKR1000. & , $
Arduino , "
I2C.
5 & . * " :
?
Vin — "
5 &. # $ 5 & ;
?
GND — " (« »). # $
GND ;
?
SCL — . # $
SCL ;
?
SDA —
. # $ SDA .
=
.
$
-
= LSM303
,
Polulu — .
=
I2C Wire. ' $ , D | >
| N , % " A
LSM303,
LSM303 by Polulu
N . X , .
Пишем код для цифрового компаса
$
LSM303 compass. & setup()
,
Wire I2C, % $ compass. * , enableDefault()
compass
.
+/–1,3 ,
2 :
/*
[ loop()
compass,
$ read(),
" heading()
:
void loop() {
compass.read(); // Z $
float myHeading = compass.heading(); // +
Serial.println(myHeading); // +
$ R
delay(100); // + $ 100
}
$ LSM303
: Arduino
*/
#include <Wire.h>
#include <LSM303.h>
LSM303 compass; // Z$
R$
void setup() {
Serial.begin(9600); // ' $
Wire.begin();
// $ % I2C
compass.init();
// \ # $
compass.enableDefault(); //
//
'
}
Как узнать местонахождение (почти) чего угодно?
425
Калибровка цифрового компаса
, ,
: $ , , $ , " , $ .
$
$ .
, $ , % .
= $
, % , .
Serial.print(compass.m.x);
Serial.print("\t");
Serial.print(compass.m.y);
Serial.print("\t");
Serial.println(compass.m.z);
% 16 ,
–32,768 ( ) 32,767 ( ).
2
,
setup() " :
compass.m_min.x
compass.m_min.y
compass.m_min.z
compass.m_max.x
compass.m_max.y
compass.m_max.z
LSM303 ,
, " , " . &
" ,
" github.
" . 7
"
,
. =
$ " loop():
=
=
=
=
=
=
-680;
-623;
-616;
422;
451;
424;
Локальные пределы
X
. #
, %
.
X $
% % .
=
API
LSM303 "
https://github.
com/pololu/lsm303-arduino.
Введение в интерфейс I2C
LSM303
I2C19. ]
! TWI20
SPI, ! 2.
19 2
I C, Inter-Integrated Circuit —
.
20
TWI, Two-Wire Interface — .
# I2C SPI ,
I2C " ( " )
"
. I2C
: # (SCL)21,
21
SCL, Serial Clock —
.
"
Глава 8
426
( ),
. *
(SDA)22,
.
(
, )
I2C. 3
(
! , )
I2C . & SPI, I2C
.
,
,
, .
; ,
I2C
% (% ) ( " )
( ) :
22
SDA, Serial Data —
• <
(SCL) — , "
;
• <
= (SDA) — ,
.
-
& , "
I2C, " % , "
$ .
> Wire
%
I2C Arduino
. >% ,
I2C,
Wire.
& I2C ,
Arduino % Arduino
SCL
SDA.
.
Проект 20
Определение положения в пространстве
Курс по компасу — это прекрасный способ определить направление, если вы находитесь на земной поверхности. Но направление представляет собой лишь одно из условий нахождения правильного положения объекта в пространстве. Кроме направления, надо также знать, где верх,
а где низ, — чтобы определить тангаж и крен. И здесь нам помогут акселерометры — устройства, измеряющие линейное ускорение, и гироскопы, измеряющие угловую скорость вращения.
Таким образом, в этом проекте мы научимся определять положение объекта в пространстве,
используя акселерометры и гироскопы.
Требуемые компоненты
> % , 1 %.
7 Arduino, 1 %.
/ , 1 %. .
& $
LSM303 L3Gxx ST Microelectronics
Arduino 101, "
.
, 6–8 %. ("
% ).
3
. & %
,
"
.
,
$
2 ,
. # , , ,
. +
$
, . 0 ,
Как узнать местонахождение (почти) чего угодно?
,
,
,
. 3
,
, . .
,
.
3
%
, $
. =
2 g —
$ . >%
, "
, —
,
3–6 g. *
% — , ( )
100 g!
427
& $
/ $
" . 7 ,
,
" # ,
7 (Sebastian Madgwick),
Processing $ .
& "
. & $
/ LSM303
(
" ) L3G ST
Microelectronics. 7 LSM303
$ Arduino, . 8.14. 3
Arduino 101
/ Bosch BM160 ( $
).
Снимаем показания (вариант с платой Arduino 101)
/*
Внимание!
/
/ ,
Arduino 101
#
,
Arduino 101.
> CurieIMU
, "
,
g, ,
(/ ). =
( |
Z - # - $
CurieIMU
: Arduino
Z $ # $
Arduino 101.
*/
#include "CurieIMU.h"
void setup() {
Serial.begin(9600); // ' $
CurieIMU.begin(); // \ # $ # // $
// $ $
+/-2 g
CurieIMU.setAccelerometerRange(2);
// $ $
+/- 250 /
CurieIMU.setGyroRange(250);
}
void loop() {
float x, y, z; // // $
$
Глава 8
428
float gx, gy, gz; // // $
$
// Z
$
CurieIMU.readAccelerometerScaled(x, y, z);
CurieIMU.readGyroScaled(gx, gy, gz);
Serial.print("x: "); // +
R $
// X
Serial.print(x);
Serial.print(",\ty: "); // +
R $ ',
// # '
$ Y
Serial.print(y);
Serial.print(",\tz: "); // +
R $ ',
// # '
$ Z
Serial.print(z);
Serial.print("\tgx: "); // +
R $ ',
// # '
$ X
Serial.print(gx);
Serial.print(",\tgy: "); // +
R $ ',
// # '
$ Y
Serial.print(gy);
Serial.print(",\tgz: "); // +
R $ ',
// # '
$ Z
Serial.println(gz);
| " A ) Intel Curie Boards by Intel,
(D | >
| N ) CurieIMU.
, ,
/
,
%
:
}
Снимаем показания (вариант с использованием интерфейса I2C)
/
LSM203 L3Gxx.
= $
, "
,
" L3G
Polulu.
# : LSM303 ST Microelectronics
(
" ) L3Gxx. /
9-DOF Adafruit,
Polulu. SparkFun :
L3G4200D LSM303.
= Adafruit , 19 —
I2C.
# "
SDA SDA , SCL — SCL ( % I2C
).
Внимание!
&
Wire
I2C
,
. 2
$
accelerometer gyro:
/*
Z $
LSM303
L3G
: Arduino
Z $ $
LSM303
L3G
*/
#include <Wire.h>
#include <LSM303.h>
#include <L3G.h>
LSM303 accelerometer;
L3G gyro;
Как узнать местонахождение (почти) чего угодно?
429
& setup()
I2C,
. X
:
void setup() {
Serial.begin(9600); // ' $
Wire.begin(); // \ # $
% I2C
accelerometer.init(); // \ # $
accelerometer.enableDefault(); //
// $ $
' (+/- 2g)
gyro.init(); // \ # $
gyro.enableDefault(); // $
// $
' (+/- 250 /)
}
& loop()
,
"
readAcceleration() readGyro() " . 0 $
:
void loop() {
accelerometer.read(); // Z $
gyro.read(); // Z $
// $ $ # g
float x = readAcceleration(accelerometer.a.x);
float y = readAcceleration(accelerometer.a.y);
float z = readAcceleration(accelerometer.a.z);
// $ $ # /
float gx = readGyro(gyro.g.x);
float gy = readGyro(gyro.g.y);
float gz = readGyro(gyro.g.z);
}
[ readAcceleration()
g, $
CurieIMU, readGyro() . 9 %
16 ( –32 768 +32 767)
LSM303 –2g +2g.
3 %
+/– 250 / :
float readAcceleration(int rawValue) {
// $ LSM303 16
//
$ +/- 2g
float result = (rawValue * 2.0) / 32768.0;
return result;
}
float readGyro(int rawValue) {
// $ L3G 16
//
$ +/- 250 /
float result = (rawValue * 250.0) / 32768.0;
return result;
}
Определение направления вверх с помощью акселерометра
# ,
,
.
, 9,8 / 2,
. 0 $ , ,
( . . 8.13) :
$ ,
x > 0
- 1
else
Y
y >
else
Z
z >
else
-
2
$ ,
0
3
4
$ ,
0
5
6
Глава 8
430
Ориентация объекта (базовый подход)
/
,
. = $
%
loop() "
:
/*
#
: Arduino
' , "
*/
// Z' ' $ -
// ' , " - //
% #
setup().
void loop() {
// Z' - % #
int orientation = readOrientation(x, y, z);
Serial.println(orientation);
}
;
. /
x, y z g,
"
,
. =
,
g.
2
" ,
: , , , ,
. & ,
.
int result = -1; // $
int absX = abs(x); //
int absY = abs(y);
int absZ = abs(z);
// N
int bigger = max(absX, absY);
int biggest = max(bigger, absZ);
if (biggest == absX) { // *
if (x > 0) { // !
result = 1;
} else { //
result = 2;
}
}
if (biggest == absY) { // * Y
if (y > 0) { // ! y
result = 3;
} else {
result = 4; //
// y
}
}
/ , %
. 0
"
:
int readOrientation(float x,
float y, float z) {
if (biggest == absZ) { // * Z
if (z > 0) {
result = 5; // ! z
} else {
result = 6; // z
}
}
return result;
}
Как узнать местонахождение (почти) чего угодно?
431
Определение рыскания, тангажа и крена
;
, — , ,
" . *
,
. ;
,
,
. 0
.
$
Freescale
Semiconductor, PDF : http://cache.freescale.com/
files/sensors/doc/app_note/AN3461.pdf. &
,
" .
# 2 . $,
©
( ), $ X
, — Y ( . 8.15).
X
X Y
" , " :
x 2 + y 2 = z 2.
2 $, "
"
. # "
X (Xaxis) ,
sin ©, Y (Yaxis) —
,
cos © ( ,
%
, — %
" ). 0 :
§
·
Xaxis
> arctg ¨
¸
2
2
© Yaxis Zaxis ¹
7
§
·
Yaxis
arctg ¨
¸
2
2
© Xaxis Zaxis ¹
Z
X
Y
Сила тяжести
Θ
Рис. 8.15. Вычисление составляющих силы тяжести на основе
угла
' ,
g, $ . 3 ,
, .
Метод Мадгвика
& 2010 # 7 (Sebastian
Madgwick)
, $
. 0 $
,
,
. / : http://x-io.
co.uk/open-source-imu-and-ahrs-algorithms/.
7
%
%
$ ,
PDF :
http://x-io.co.uk/res/doc/madgwick_internal_
report.pdf.
~ > (Helena Bisby)
7 Arduino, % -
Глава 8
432
# (Paul Stoffregen)
Arduino. &
.
=
Madgwick. = $ -
D | >
| N , % " A
Madgwick, Madgwick by Arduino N . X ,
"
"
.
Ориентация объекта (продвинутый подход)
'
Madgwick,
$
filter.
/ $
—
%
40 ,
25 q.
=
4. 2
% :
/*
& setup()
25 q:
void setup() {
// Z'
filter.begin(25); // N
}
[ loop()
, ,
% 40 . 4
%, .
void loop() {
// Z' - % #
loop()
if (millis() - lastReading >= readingInterval) {
// N
Madgwick
filter.updateIMU(gx, gy, gz, x, y, z);
// $
, !
// #
float roll = filter.getRoll();
float pitch = filter.getPitch();
float heading = filter.getYaw();
Serial.print(heading);
Serial.print(",");
Serial.print(pitch);
Serial.print(",");
Serial.println(roll);
lastReading = millis(); // N
//
}
}
[ readOrientation()
$ " .
,
getRoll(), getPitch()
getYaw(),
. & $
$ ,
. * , . &
:
#
&
: Arduino
Z $ '
/
*/
// Z' ' $ -
// '
" - #include <MadgwickAHRS.h>
long lastReading = 0; //
long readingInterval = 40; // 40 = 25
Madgwick filter; // Madgwick
- % #
25
Как узнать местонахождение (почти) чего угодно?
433
Соберем все вместе
/ Processing
. 0 "
,
. * , ,
,
.
/*
&
: Processing
$
$
- ,
.
*/
import processing.serial.*; // \ serial
float heading, pitch, roll; //
float position; // & ,
Serial myPort; //
7 setup()
, :
void setup() {
// draw the window:
size(400, 400, P3D);
// calculate translate position for disc:
position = width/2;
// +
R
printArray(Serial.list());
// , $
myPort = new Serial(this, Serial.list()[0], 9600); //
// - , $ R
// $ Serial.list(),
// '
// serial ,
// :
myPort.bufferUntil('\n');
// %
textSize(12);
textAlign(CENTER, CENTER);
}
7 draw(), ,
. 0 tilt(),
:
void draw () {
// #:
background(#20542E);
fill(#79BF3D);
// :
tilt();
}
# 3D Processing " 0 2ª
. 7 tilt() ( , ) $
void tilt() {
// Z #:
translate(position, position, position);
// X — $
rotateX(radians(roll+90));
// Y —
Глава 8
434
. 0
Processing translate()
rotate() " " :
rotateY(radians(pitch));
// Z -
rotateZ(radians(heading));
// # $ :
fill(#79BF3D);
// :
ellipse(0, 0, width/3, width/3);
// # :
fill(#20542E);
// +
, ''
//
' :
text(heading + "," + pitch + "," + roll, 0,0,1);
}
7 serialEvent() , "
,
ASCII, —
, $ «*
- »
2:
,
, , $
.
void serialEvent(Serial myPort) {
// Z $ %:
String myString = myPort.readStringUntil('\n');
// - , :
if (myString != null) {
myString = trim(myString);
// $ $ :
String items[] = split(myString, ',');
if (items.length > 2) {
heading = float(items[0]);
pitch = float(items[1]);
roll = float(items[2]);
println(heading, pitch, roll);
}
}
}
Рис. 8.16. Вывод скетча Processing для отображения положения акселерометра методом Мадгвика
" , $ "
$
"
( . 8.16).
~ " ,
. 8.16,
% ,
. +,
"
,
$
" . " Madgwick $
.
"
, $ %
,
%
Как узнать местонахождение (почти) чего угодно?
Processing. & $ Processing
, "
.
; " .
7 % ,
, —
, %
. *
435
$
2 ,
%
.
7 , 7 " Z.
& , LSM303, " ,
$ .
Заключение
Начиная разрабатывать проекты, которые используют системы определения местоположения,
мы обычно обнаруживаем, что меньше означает больше. Довольно часто бывает так, что мы начинаем разработку проекта, полагая, будто нам нужно знать местоположение, расстояние и направление, а потом — по мере углубления в проект — выясняется, что физические ограничения
создаваемых объектов и пространства, в которых они создаются, решают за нас многие проблемы и дают возможность проект упростить.
/ $
% .
% " $ ,
, , ,
$
. ; $
,
.
&
$
. *
,
«Адрес 2007» от Моуны Андраос (Mouna Andraos)
и Сонали Сридхар (Sonali Sridhar)
,
. 0 '. (J. Nordberg).
. $
,
,
. & " ,
" .
Глава 9
ИДЕНТИФИКАЦИЯ
В предыдущих главах мы предположили, что идентичность равнозначна адресу. Зная адрес устройства в сети, мы уже могли с ним взаимодействовать. Но представьте себе, какими непредсказуемыми были бы
последствия, если бы мы использовали этот подход в повседневной
жизни, — например, сняли трубку телефона, набрали номер и просто
начали говорить. А что, если мы набрали неправильный номер? А если
ответит кто-либо другой, а не тот, кого мы ожидаем услышать?
Адреса устройств в сети обозначают их сетевое расположение, но не
имеют никакого отношения к содержанию сообщений, которые между
ними пересылаются. Это мы сетевые устройства используем для передачи тех или иных сообщений другим людям. При этом сетевой идентификатор устройства и физическая идентичность лица — это две
абсолютно разные вещи. Физическая идентичность обычно оценивается присутствием (это возле меня?) или адресом (где это?), а сетевая
идентификация также принимает во внимание сетевые возможности
устройства и его состояние, когда с ним устанавливается контакт.
В этой главе мы рассмотрим некоторые методы наделения физических
объектов сетевыми идентификаторами, а также способы, посредством
которых устройства в сети могут определить возможности друг друга
с помощью пересылки сообщений и используемых протоколов.
Вы также узнаете, как устройства в сети могут определять возможности
друг друга через отправляемые ими сообщения и используемые
протоколы.
«Нюхач» — игрушка для детей с проблемами зрения от Сары Йогансон (Sara Johansson)
& RFID.
RFID,
,
.
9 # , «0" » 0 ,
; 3 (Timo Arnal)
7
# (Mosse Sjaastad). 0 & 1 .
Глава 9
438
Компоненты для проектов этой главы
Основные новые компоненты в проектах этой главы — веб-камеры и считыватели меток RFID,
которыми мы воспользуемся для идентификации цветов, лиц, меток RFID и прочих внешних признаков.
Коды поставщиков
?
A — Arduino Store, http://store.arduino.cc
?
J — Jameco, http://jameco.com
?
AF — Adafruit, http://adafruit.com
?
P — Pololu, www.pololu.com
?
AMZ — Amazon, www.amazon.com
?
PX — Parallax, www.parallax.com
?
B — Belkin, www.belkin.com
?
RS — RS, www.rs-online.com
?
D — Digi-Key, www.digikey.com
?
SF — SparkFun, www.sparkfun.com
?
F — Farnell, www.farnell.com
?
SS — Seeed Studio, www.seeedstudio.com
?
ID — Identiv, www.identiveusa.com
Рис. 9.1. Новые компоненты для проектов этой главы: 1. Шилд NFC PN532 компании Seeed Studio. 2. Адаптерная плата PN532
компании Adafruit. 3. Считыватель NFC-меток SCL3711 USB компании Identiv. 4. USB-камера (если ваш компьютер не оснащен встроенной веб-камерой). 5. Розетка WeMo компании Belkin. 6. Объекты разных цветов. 7. Соленоидный замок. 8. Набор
QR-кодов. 9. Метки RFID Classic компании Mifare
5
3
1
2
4
6
8
9
7
Идентификация
439
ПРОЕКТ 21. Распознавание цветов с помощью веб-камеры
- .
>
>
) = .
ПРОЕКТ 22. Распознавание лиц с помощью веб-камеры
- .
>
>
J- .
ПРОЕКТ 23. Распознавание двумерных штрихкодов с помощью веб-камеры
- .
>
>
.
ПРОЕКТ 24. Чтение меток RFID
D RFID, 1 +. 7 NFC- SCL3711 USB
Smart Card Reader Identiv.
AF: 359 360, SF: SEN-10128 SEN-11319,
SS: 113990013
> Raspberry Pi, 1 +.
ID: SCL3711
" RFID Classic
Mifare. &
"
, ,
% .
SF: DEV-13825, AF: 3055 3400, SS: 102010048
114990584, RS: 896-8660, F: 2525225
ПРОЕКТ 25. Чтение и запись сообщений NDEF
D RFID, 1 +. 7 NFC- SCL3711 USB
Smart Card Reader Identiv.
AF: 359 360, SF: SEN-10128 SEN- 11319,
SS: 113990013
> Raspberry Pi, 1 +.
ID: SCL3711
" RFID Classic
Mifare. &
"
, ,
% .
SF: DEV-13825, AF: 3055 3400, SS: 102010048
114990584, RS: 896-8660, F: 2525225
ПРОЕКТ 26. NFC и бытовая автоматизация
C , 1 +.
D: 438-1045-ND, J: 20723 20601, SF: PRT12615 PRT-12002, F: 4692810, AF: 64, SS:
319030002 319030001
, 1 +. , .
A: 1609
H 37 "3 =, 4 +. = .
D: 36-2206-ND
H 12 "3 =, 2 +. = .
D: 36-2203-ND
Глава 9
440
' "3
6 ,
12 +. = .
D: 36-9300-ND
, 1 +. 7
8 9 5.
Arduino MKR1000, 1 +.
AF: 3156, RS: 124-0657, A ABX00004, GBX00011
(3 4#), D: 1659-1005-ND.
&
ESP8266.
SF: WRL-13231, AF: 2471
" NFC- PN532, 1 +. X %
SPI, I2C UART (X3). * -
$
NFC- DFRobot,
" X3
% AVR.
AF: 364, D: 1528-1781-ND, SS: 113030001
" RFID Classic
Mifare, 2 +.
AF: 359 360, SF: SEN-10128 SEN-11319,
SS: 113990013
( WeMo
Belkin, 2 +.
B: P-F7C027
> .
]= =
. " .
ПРОЕКТ 27. Двухфакторная идентификация с использованием NFC
D RFID, 1 +. 7 NFC- SCL3711 USB
Smart Card Reader Identiv.
ID: SCL3711
" RFID Classic
Mifare. &
"
, ,
% .
AF: 359 360, SF: SEN-10128 SEN-11319,
SS: 113990013
> Raspberry Pi, 1 +.
SF: DEV-13825, AF: 3055 3400, SS: 102010048
114990584, RS: 896-8660, F: 2525225
% TIP120, 1 +.
D: TIP120-ND, J: 32993, F: 9804005 RS: 8080502
( 1 , 1 +.
D: 1.0KQBK-ND, J: 690865, F: 9339051, RS: 7077666
D , 1 +.
AF: 1512
ПРОЕКТ 28. Геолокация по IP-адресу
> >
.
12 ', 1 +.
A
J: 170245, F: 1176248
)
5,5 + — 2,1 , 1 +.
D: CP3-1000-ND , J: 28760, SF: PRT-10287, A:
369, F: 1737256
]+ , 1 +.
SF: PRT-12044, AF: 65, D: 923273-ND
, 1 +. , .A: 1609
H 14 "3 =, 4 +.
D: 36-2204-ND
' "3
6 ,
8 +. = .
D: 36-9300-ND
, 1 +. 7
8 9 5.
Идентификация
441
Физическая идентификация
Процесс идентификации физических объектов является столь существенной частью нашего жизненного опыта, что мы редко отдаем себе отчет в том, как мы это делаем. Конечно же, мы полагаемся в этом на наши органы чувств: смотрим на объекты, ощупываем, поднимаем и встряхиваем
их, прислушиваемся к ним, нюхаем и пробуем их на вкус и так до тех пор, пока мы не сориентируемся в том, что они собой представляют, после чего навешиваем на них соответствующие ярлыки. Весь этот процесс опирается на очень сложные функциональные способности наших мозга
и тела, и любой, кто когда-либо пробовал заниматься компьютерным зрением или искусственным интеллектом вообще, может сказать вам, что научить компьютер распознавать физические
объекты — задача далеко не из легких. Так же, как сужение человеком поля поиска какого-либо
предмета облегчает задачу определения его местоположения, задача распознавания объектов
посредством компьютеров облегчается, если мы можем ограничить область активного поиска,
а также тем или иным способом пометить важные объекты.
7 , ,
%
, — $ . 0
, . = !
(RFID1).
#" :
% . 9 .
#
,
. 0
%
. & $ %
RFID. *
RFID
, , . &
,
,
"
1
RFID, Radio Frequency Identification.
, $
. & ,
,
, $
,
. # ,
%
"
,
. + ,
"
, "
RFID
—
.
,
% .
* , , ;,
. 2
, $ % . ;, #3
; + (Tom Igoe),
*-
,
,
. $,
,
— ,
, — , :
; +,
[ $ . '
,
%
Глава 9
442
. ,
,
,
.
. 9
RFID :
,
"
% . 3
$
" ,
, RFID $ . +
.
#
,
: «+ , !», % ?
RFID ,
, ,
,
. ;
—
,
.
Видеоидентификация
& " :
.
,
"
. ;, , RGB2 HSV3
2
RGB, Red-Green-Blue —
,
HSV, Hue-Saturation-Value — ,
.
3
, .
"
,
%
,
$ . 3 CMYK4
. ,
,
,
,
. * . 9.2
% — .
# " , % $ , .
# " $
,
, ,
. & "
,
"
. $
,
,
, USB.
, — $ %
HTML5, , JavaScript.
4 -
JavaScript,
$ , ,
+
, .
& "
, , —
" . & — — , — ,
,
—
% QR5.
4
5
CMYK, Cyan-Magenta-Yellow-blacK — , , ,
.
QR, Quick Response —
.
Идентификация
#
,
p5.js. $
- ,
HTTPS.
&
httpsserver.js
18 ( .
!. «&!
HTTPS» 8). * ,
$
(
)
. $
.
Распознавание цветов
9 — ,
. # " $ .
443
= $
— , . 2 $ , "
" .
9
$
.
,
,
" ,
. *
" , $ "
,
" .
Рис. 9.2. Пример распознавания цветов. Простое отслеживание цветов дает наилучшие результаты, когда распознаются
цвета, резко отличающиеся от фона, на котором они представлены
Глава 9
444
Проект 21
Распознавание цветов с помощью веб-камеры
Скетч p5.js из этого проекта захватывает изображение с подключенной к компьютеру видеокамеры, ищет в нем пикселы определенного цвета и помечает их на копии изображения, которую
выводит на экран.
0 - HTML
$ -
%
.
$ . = - = ,
p5.js,
" - - . # , ,
% $
Требуемые компоненты
,
" - .
. &
% — % $
0 .
.
Пишем код
*% CameraProjects.
=
public, 18. 2 public p5.js
colorTracking. & colorTracking
,
p5.js: index.html, sketch.js,
libraries, " p5.js.
& $
sketch.js, "
public
.
0 sketch.js setup()
.
video
$ API
, trackColor —
, differenceThreshold —
, dSlider — :
/*
& setup()
, video
$ . 2
video canvas :
function setup() {
video = createCapture(VIDEO); // M
//
video.size(400, 300); // $ $-
// $
video.position(0, 0); // $
var canvas = createCanvas(400, 300); // ^ -
// - $
canvas.position(0,0); // -
# ' % #
: p5.js
^ R % .
HTML5
*/
var video; // " $-
var trackColor = [255,0,0];
// #
var differenceThreshold = 10; // $
// $ #
var dSlider; // $ $
Идентификация
445
dSlider = createSlider(0, 100, 10, 1); // \ # $
// $
dSlider.position(10, height-30); //
dSlider.touchEnded(setDifference); // +$ % # '
// $ $
$
}
7 draw()
, , .
=
,
, —
$
. =
$ : , "
«» — . =
" (
):
function draw() {
image(video,0,0); // +
$ R
video.loadPixels(); // $ $
// -
#
for (var x = 0; x < video.width; x++ ) { // Z
for (var y = 0; y < video.height; y++ ) { // Z#
// + $ # '
//
var loc = (x + y * video.width) * 4;
// $ ' -
var r1 = video.pixels[loc];
//
// '
var g1 = video.pixels[loc + 1]; //
// '
var b1 = video.pixels[loc + 2]; // Z
// '
// $ ' // #
var r2 = trackColor[0]; // '
var g2 = trackColor[1]; // '
var b2 = trackColor[2]; // Z '
arrayLocation = x + (y * width) * 4;
2 , ,
",
,
:
=
$ . 9 ,
"
,
,
, .
& ,
differenceThreshold. 4
% ,
. # ,
,
:
// % # ' dist() $ #
// #
var difference = dist(r1, g1, b1, r2, g2, b2);
// $ # -
// $ $ # #
if (difference < differenceThreshold) {
stroke(0); // #
point(x, y); // Z $ #
}
}
}
Глава 9
446
2 $
. / % draw():
// +
% # $ R
fill(255);
text(" #: " + trackColor, 10, height-60);
text(" $ $ #: " + differenceThreshold,
10, height-40);
} // # % #
draw()
'
" % ,
mousePressed(). " $
" $
trackColor:
// Z- #
// ' trackColor:
function mousePressed() {
if (mouseY < dSlider.y) { // $ ,
trackColor = video.get(mouseX,mouseY); //
// $ ' - #
}
}
* ,
differenceThreshold.
+ $
. &
setup()
$ , , " % .
+
differenceThreshold:
// $ , $
// ' differenceThreshold:
function setDifference() {
differenceThreshold = dSlider.value();
}
Исполнение скетчей работы с изображениями
=
$
https-server.js,
$ " :
$ sudo node https-server.js
. 2
, -
:
http://localhost:8080/colorTracking.
" ,
%
. * !, . /
" .
Освещение для распознавания
цвета
$
,
. %
colorThreshold ,
, ( . 9.3).
>% ,
" . =
$ :
Идентификация
447
Рис. 9.3. Распознавание цвета скетчем на p5.js. Пороговое значение равно (слева направо): 10, 32 и 47. Чем выше пороговое
значение, тем больше он показывает совпадений пикселов нецелевого цвета
?
DayGlo6,
"
,
$
$ ;
?
,
, —
,
" .
* , %
35- ( "
),
, . /
,
. ;
%
,
;
?
%
,
. `
,
.
, — $ % . Texas Advanced
Optoelectronic Solutions (www.taosinc.com)
6
# . . Day + Glow — ( ,
, ), "
" .
,
TAOS TCS34725,
Adafruit.
/
,
,
,
, .
Распознавание форм и образов
2
,
. '
, .
« »
. & , «» , — $
$.
,
- .
« » —
. 0
" , ,
,
"
, $ .
Глава 9
448
Проблемы с идентификацией физических маркеров
,
= >% (Durrell Bishop) 1992 . (vimeo.
com/19930744), , " . " %
.
% " , " %
. % " "
, "
" ,
.
" ,
.
>% ,
, " " :
& !
( ! ) , !
! . 4
# # , . ] ,
% ,
, ! . > Apple
'
>%, !
* , !# . 4!,
' , % !
Interval Research, ! ! Dallas
Semiconductor.
' Z ,
& % , , ,
, "
. 0
. '
% , >% , $
,
, .
,
% . 4 , ,
, "
,
" . ,
,
.
Обнаружение лиц
4 , -
,
, $ " . & ,
, .
0 — %
. *% , "
% , " " .
& , % $
% % ,
-
, , .
Q
!
—
, ,
,
-
" .
# " % .
Идентификация
449
Проект 22
Обнаружение лиц с помощью веб-камеры
Теперь, когда мы располагаем основными сведениями в области оптического обнаружения объектов, настало время попробовать определение простых образов. В этом проекте мы воспользуемся методами обнаружения лиц для нахождения лица в захваченном камерой изображении.
= JavaScript "
, $
% " . *
, " , "
. & ,
,
,
. 0
, "
, , . > tracking.js
"
:
?
;
?
;
?
.
# "
. ,
.
= public
CameraProjects
faceRecognition. # $ , p5.js.
2
- https://trackingjs.
com tracking.js, -
Требуемые компоненты
- .
_.
build
libraries faceRecogntion. /
tracking.
js tracking-min.js, data, "
,
.
2 index.html faceRecognition <script>
" :
<script src="libraries/tracking-min.
js"></script>
<script src="libraries/data/face-min.
js"></script>
=
eye-min.js mouthmin.js. # $ , , sketch.js
" .
Пишем код
, setup()
.
2
canvas
tracker $
. setup()
" . =
$ ObjectTracker tracking
" setInitialScale(),
setStepSize() setEdgesDensity()
. & $
. 7 $
, $ .
Глава 9
450
.
$
, -
* , setup() ,
:
[ draw()
,
showTracks(). ,
event.data. 2 for
$
:
/*
# '
: P5.js
*/
tracking.js
var canvas; // -
var tracker; // R$ tracking
function setup() {
// $- $
var video = createCapture(VIDEO); // M
//
video.size(400, 300); // $ $-
// $
video.position(0, 0); // $
canvas = createCanvas(400, 300); // ^ -
// - $
canvas.position(0,0); // -
// ^ #
tracker = new tracking.ObjectTracker('face');
tracker.setInitialScale(4); //
tracker.setStepSize(2);
tracker.setEdgesDensity(0.1);
tracking.track(video.elt, tracker); // \ $
tracker.on('track', showTracks); // +$ % # '
// $
-
ellipseMode(CORNER); // ,
}
function draw() {
// ^
} // # % #
draw()
function showTracks(event) {
clear();
var faces = event.data;
for (f in faces) {
fill(0xFF, 0x00, 0x84, 0x3F); // $ #
noStroke(); // $ #
ellipse(faces[f].x, faces[f].y, faces[f].width,
faces[f].height);
}
}
2
— %
.
$
( . 9.4).
,
( . 9.4, ),
( . 9.4, ). # %
( . 9.4, ). 0
Идентификация
451
а
б
в
г
Рис. 9.4. Результаты исполнения скетча для обнаружения лиц
. 3 % — " , _%
, —
"
( . 9.4, ), , ,
.
> tracking.js ,
- .
Распознавание штрихкодов
: — $ ,
- .
% ,
% , .
# "
Глава 9
452
, % .
%
,
% " , "
. # ,
,
"
,
.
*
% UPC7
. & ,
, "
% ,
%
. * , #3
POSTNET
. #
EAN8 JAN9 %
UPC
" .
% ,
, $ % % ,
, POSTNET "
EAN. / ,
%
,
, , ,
"
.
=
%
,
% %
.
, . 9.5,
, .
#"
% ,
, , .
,
. * . 9.6
% —
QR. / `
,
%
. & ,
— , ,
WeChat. & "
p5.js QR " JavaScript.
Рис. 9.5. Одномерный штрихкод (здесь приведен штрихкод
ISBN10 этой книги11)
9
789781
680458
Рис. 9.6. Двумерная метка штрихкода (QR-кода, если быть
более точным) с ограничивающими пометками по углам. Эти
пометки игнорируются обработчиками изображения, но помогают пользователям центрировать метку для более качественного ее захвата
7
UPS, Universal Product Code —
.
8
EAN, European Article Numbering — .
9
JAN, Japanese Article Numbering —
.
10
11
ISBN, International Standard Book Number — .
+ .
Идентификация
453
Проект «Backslash»12 от Педро Оливейра (Pedro Oliveira) и Суеди Чен (Xuedi Chen)
9
«Backslash»
,
QR-, "
. =
0
. * , " , —
www.backslah.cc.
+ + (Roy Rochlin)
Проект 23
Распознавание двумерных штрихкодов с помощью
веб-камеры
В этом проекте мы с помощью онлайнового генератора QR-кодов сгенерируем несколько двумерных штрихкодов, а затем расшифруем их, используя камеру и браузер. Когда наш скетч заработает должным образом, в качестве домашнего задания вы можете расшифровать рисунки
этой книги, содержащие коды QR.
Требуемые компоненты
- .
QR.
12
Backslash —
« ».
QR-
"
,
. # "
" % " , $
Глава 9
454
. * ,
QR- $
. , +
QR. $
% , . ,
https://webqr.com/create.html
,
QR URL, . + $ ,
%
,
% .
#
% .
= public CameraProjects
qrCodeReader. # $
,
p5.js. 2 - https://github.
com/IagoLast/qrcodejs
qrCodeJS,
qrcode.js dist libraries qrCodeReader.
2 index.html qrCodeReader <script>
" :
<script src="libraries/qrcode.js"></script>
# $ , , sketch.js " .
Пишем код
q
$ $
qrReader
JSON
. *
% % QR,
:
[ setup() $
$
" .
& , ,
$ . ; ,
qrReader
" . 2 $
qrReader, :
/*
QR
: p5.js
$
$
HTML5
*/
var video; // " $-
var message; // Z QR
var qrReader; // $ QR
var config = { // % # " QR
sucessCallback: getMessage, // +$
//
QR
errorCallback: onError,
// +$
// QR
videoSelector: ‘video’,
// \ -
stopOnRead: false
//
//
}
function setup() {
video = createCapture(VIDEO); // M
//
video.size(400, 300); // $ $-
// $
video.position(0, 0); // $
//
var canvas = createCanvas(400, 300); // ^ -
// - $
canvas.position(0,0); // -
canvas.elt.id = "video"; //
R -
qrReader = new QrReader(config); // Z$ R$
// qrReader
}
Идентификация
[ draw()
$
" . 4 % QR, " :
455
function draw() {
image(video,0,0);
// +
$ R
video.loadPixels(); // $
//
fill(255);
text("read: " + message, 10, height - 20);
} // # % #
draw()
function getMessage(result) { //
// QR,
message = result; // ' message
}
function onError(err) { // +
console.error(err); //
R
}
$ ,
.
/ , , , %. / %
, "
-
. & , $ %
,
" %
QR.
*
% % ,
,
. * %,
,
. 2
— " ( . . 9.6).
$ ,
,
. ; %
,
% "
.
0
"
— % . & " %
% , % ,
. * $
$ . 4 -
,
% , ,
$ .
X% % , ,
$, " . & $ % RFID NFC
QR % .
Глава 9
456
Радиочастотная идентификация (RFID)
и ближняя бесконтактная связь (NFC)
Подобно системам распознавания штрихкодов, система RFID предусматривает наличие на объектах меток, обеспечивающих их идентификацию. Но, в отличие от меток штрихкодов, метки
RFID, чтобы их можно было считывать, не обязательно должны быть на виду. Считыватель RFID
излучает радиосигнал ближнего действия, который принимается меткой RFID, передающей в
ответ короткую строку данных. В зависимости от размера и чувствительности антенны считывателя и мощности сигнала, метка может находиться на расстоянии до метра от считывателя,
помещена внутри книги, ящика, коробки, предмета одежды и, тем не менее, быть доступной для
считывания.
; ,
, " RFID:
. 4 RFID
$
% . >
, ,
.
/ $
— -
, . #
, % RFID
( . 9.7).
> %
,
%
$ .
Рис. 9.7. Фотография электромагнитного поля считывателя RFID, снятая Тимо Арналом (Timo Arnall), демонстрирует радиус
действия и форму электромагнитного поля типичного пассивного считывателя RFID. Как можно видеть, это всего лишь несколько сантиметров
Идентификация
& RFID
,
. 3
% ,
,
%. *
. 4
$
, , , RFID. X
E-ZPass13
RFID,
.
7 , RFID ,
13
E-ZPass — $
, %
,
- #3,
% # %
+ .
457
, $
. 0 ,
RFID
, . 3 $
RFID
. & ,
, — $ , .
. 9.8, RFID : , , ,
,
,
. ,
%
,
. , RFID
, $ " , —
Рис. 9.8. Все эти предметы различных цветов и форм оснащены метками RFID. Фотография Тимо Арнала. Дополнительную информацию по исследованиям Тимо Арнала и его коллег в области дизайна RFID можно найти на веб-сайте www.elasticspace.com
Глава 9
458
, "
. /
, RFID
, , "
%
.
Имплантация капсул RFID
>% RFID
( )
. ,
. $
RFID. * $ % ,
$ . 3
RFID,
RFID- .
& RFID
.
,
,
— : 125
134,2 q, : 13,56 7q.
' % , %
.
, RFID
RFID. RFID , , 7 ISO14. #" ISO,
"
RFID. 0 $ , —
. . /
— : I-Code, Mifare Mifare
UL Philips, Tag-IT HF Picotag
Texas Instruments, SR176
ST Microelectronics . #
, , -
14
ISO, International Standards Organization.
. >
, ,
. '
,
, . *
.
* . 9.9
NFC,
.
Пояснение
• NDEF (NFC Data Exchange Format) —
.
• SNEP (Simple NDEF Exchange Protocol) —
NDEF.
# RFID %
.
.
% —
,
,
. & ,
$30
% . #
. *
. * , ID Innovations
125 q
, EM Microelectronics EM4001.
# $ Parallax. #
ID Innovations
"
SparkFun. ~ $
,
Идентификация
459
"
(
" ) —
,
NFC.
$,
, ,
, $
, .
>
? +
? 2
. * ? 4 %,
. 0
,
" " ,
, -
. ;
%
% ,
134,2 q,
.
Ближняя бесконтактная связь (NFC)
# ISO 14443
, "
- "
, %
.
,
, $
" . ISO 14443
, ,
NFC,
Рис. 9.9. Стек протоколов NFC. Эта схема должна дать вам представление о множестве разных протоколов, лежащих в основе
типичного приложения RFID или NFC. Стеки протоколов позволяют достичь определенного уровня взаимодействия продуктов разных производителей, а разработчикам приложений нужно беспокоиться только о работе своих приложений с верхними уровнями стека. Схема выполнена на основе материала из книги «Beginning NFC» («NFC для начинающих») Тома Иго,
Дона Коулмана (Don Coleman) и Брайана Джепсона (Brian Jepson), издательство O’Reilly, 2014 г.
Пользовательское приложение
Пользовательский
интерфейс
Сообщение NDEF
Формат сообщений
Записи NDEF
Формат записей
FeLiCa
DesFire
Logical Link Control
Protocol (LLCP)
УАПП
Mifare
Mifare
Ultralight Classic
ISO-14443A
ISO-18092
Протокол SNEP
Командные
протоколы
ISO-14443-3
Спецификация
пакетирования данных
ISO-14443-2
Спецификация радиосвязи
(13,56 МГц)
Считыватели NFC (IPN532, SCL3711 и т. п.)
Радиоконтроллеры
Интерфейс SPI
I2C
USB
ЦП (Arduino, Raspberry Pi, мобильное устройство и т. п.)
Связь между
устройствами
ПК. Встроенная система.
Микроконтроллер
Программное
обеспечение
Связь между
устройствами
и метками
или между
устройствами
Аппаратное
обеспечение
Глава 9
460
% " RFID. / RFID,
, RFID.
" ,
NFC
.
NFC
NDEF
,
,
-
(URL) . * , NFC
URL, , , "
-
NFC - ,
$ .
& "
,
NFC. *
$
—
Identiv, Adafruit Seeed Studio. 0 %
% ,
NFC. > NFC «Beginning NFC» («NFC
"») ; +, = (Don
Coleman) > = (Brian Jepson),
O’Reilly, 2014 .
Проект 24
Чтение меток RFID
В этом проекте мы установим программные средства для управления считывателями NFC и прочитаем несколько меток RFID, чтобы получить представление о работе считывателей. Кроме того,
мы считаем с метки уникальный идентификационный номер и посмотрим, с какого расстояния
он может быть считан. Это хорошая отправная точка для любого проекта, оснащаемого возможностями RFID и NFC.
~
NFC,
, $
RFID. $ NFC,
%
. + , RFID, " NFC.
RFID-
Mifare Classic Mifare
Ultralight Philips, % "
, ISO 14443.
Philips ,
NFC,
Mifare ,
NFC.
# - SCL3711
Identiv RFID Mifare Classic, ,
Требуемые компоненты
# - SCL3711 USB Smart
Card Reader Identiv.
7 RFID Classic Mifare.
0
Raspberry Pi.
NFC, USB. 0 , " USB, —
Raspberry Pi. '
Raspberry Pi, "
. $
% $ " Raspberry Pi
RFID NFC. & , $
,
" .
Идентификация
461
Установка программных средств
$ , , % Raspberry Pi
Linux ( . !. «Q Raspberry Pi» 1). 9
POSIX,
OS X Apple Linux Ubuntu,
Beagle Bone Debian,
,
, .
;
, %
,
%
Raspberry Pi.
+, Raspberry Pi
" ssh,
$ 1. 4
Raspberry Pi,
, "
. & ,
.
& , " :
?
libnfc-dev —
NFC;
?
libfreefare — RFID Mifare.
> " Raspbian apt-get. 7
npm
node.js. # apt-get
, %
, node.js.
,
apt-get " ,
. = $ Raspberry Pi +
" :
$ sudo apt-get update
/
"
( ) Raspbian . 0
, $ " . % $
" :
Reading package lists... Done
( ... )
;
. # libnfc — :
$ sudo apt-get install libnfc-dev
libnfc-bin libnfc-examples
$ $
" ,
apt-get
, , ,
% .
%
libnfc
libfreefare:
$ sudo apt-get install libfreefaredev libfreefare-bin
2 % ,
. > ,
% ,
NFC.
-
NFC
( . 9.10) :
$ nfc-list
* $
:
"
nfc-list uses libnfc 1.7.1
NFC device: SCM Micro / SCL3711NFC&RW opened
; ,
NFC.
Глава 9
462
DSI (DISPLAY)
USB 2x
USB 2x
GPIO
SCL3711 NFC reader
http://www.raspberrypi.org
Audio
ETHERNET
Power
CSI (CAMERA)
HDMI
libnfc libfreefare
,
,
. = $
:
Рис. 9.10. Подключение считывателя NFC SCL3711
компании Identiv к Raspberry Pi
?
mifare-desfire-access;
?
mifare-desfire-create-ndef;
?
mifare-desfire-ev1-configure-ats;
?
mifare-desfire-ev1-configure-default-key;
?
mifare-desfire-ev1-configure-random-uid;
?
nfc-anticol;
?
mifare-desfire-format;
?
nfc-dep-initiator;
?
mifare-desfire-info;
?
nfc-dep-target;
?
mifare-desfire-read-ndef;
?
nfc-emulate-forum-tag2;
?
mifare-desfire-write-ndef;
?
nfc-emulate-forum-tag4;
?
mifare-ultralight-info.
?
nfc-emulate-tag;
?
nfc-emulate-uid;
?
nfc-list;
'
- $ ,
, "
-h. * :
?
nfc-mfclassic;
?
nfc-mfsetuid;
?
nfc-mfultralight;
?
nfc-poll;
?
nfc-read-forum-tag3;
?
nfc-relay;
?
nfc-relay-picc;
?
nfc-scan-device;
?
mifare-classic-format;
?
mifare-classic-read-ndef;
?
mifare-classic-write-ndef;
$ nfc-mfclassic -h
Чтение меток
+
, libnfc libfreefare,
RFID
NFC Mifare. =
, $ nfc-poll:
$ nfc-poll
#
" :
-
Идентификация
nfc-poll uses libnfc libnfc-1.7.1-150gbf31594
NFC reader: SCM Micro / SCL3711-NFC&RW
opened
NFC device will poll during 30000 ms
(20 pollings of 300 ms for 5 modulations)
2
. "
" :
ISO/IEC 14443A (106 kbps) target:
ATQA (SENS_RES): 00 44
UID (NFCID1): 04 8e 41 62 b7 20 80
SAK (SEL_RES): 08
nfc_initiator_target_is_present:
Target Released
(#_ # _nfc__ :
$ #' )
Waiting for card removing...done.
....
* UID — $
(Unique ID)
RFID % . = RFID — $ ,
.
& RFID UID ,
,
.
4 $ $ % ,
"
—
, . * %
— % , $ . ; ,
% , —
"
RFID NFC. ~ RFID %
, %
$
.
463
Формат NDEF
* RFID,
$ —
. * NFC
%
,
UID. / "
%
NFC —
NDEF. # NDEF RFID NFC " :
?
RFID —
UID;
?
NFC — %
;
?
NDEF — "
NFC .
[ NDEF -
"
,
SD
% . ~
,
%
. > $
SD %,
.
% , NFC
. =
, NDEF "
,
. 0
" ,
.
_ NDEF # $ , "
! NDEF
. *
, URI, "
- , MIME ,
Глава 9
464
. #"
,
. & %
URI.
# NFC
NFC:
?
7 1 —
ISO14443.
$ : Topaz
Innovision BCM20203
Broadcom;
?
7 2 —
Mifare Ultralight (ISO-14443A)
NXP Philips. $ :
Mifare Ultralight NXP;
?
7 3 —
FeliCa (ISO-1892 JIS-X-6319-4)
Sony. $ : FeliCa
Sony.
?
7 4 —
DESFire (ISO-14443A) NXP.
$ : DESFire
SmartMX-JCOP NXP.
& %
Mifare Classic. /
NFC,
NDEF,
, $ . >
NFC $ ,
Android, "
NFC.
Проект 25
Чтение и запись сообщений NDEF
Здесь мы познакомимся с ближней бесконтактной связью (NFC) и форматом NDEF обмена данными для нее и станем с помощью сценариев на node.js записывать и считывать данные с меток.
Для этого нам понадобятся сценарии для записи и считывания меток, которые будут работать
с интерфейсом командной строки.
Требуемые компоненты
# - SCL3711 USB Smart
Card Reader Identiv.
7 RFID Classic Mifare.
0
Raspberry Pi.
#
Raspberry Pi
ndefReadWrite. # $
writeNdef.js. * ,
npm ndef mifare-classic:
$ npm install ndef mifare-classic
, node.
js
NDEF Mifare Classis,
libnfc libfreefare.
/
JavaScript libnfc libfreefare,
node.js.
& " %
" NDEF, "
- (URI).
Идентификация
465
Записываем метку
&
ndef mifare-classic
" NDEF. /
" :
/*
=
URI "
" . 2
,
" ndef.
encodeMessage():
var textRecord = ndef.textRecord("+ R ");
var uriRecord = ndef.uriRecord("http://www.example.com");
ndefMsg.push(textRecord); // ' $
ndefMsg.push(uriRecord); // $ URI
var bytes = ndef.encodeMessage(ndefMsg);
// $
#
Response()
mifare.write(),
" . / % %
" .
function writeResponse(error){ // #
// - #
$
if (error) { // $ ,
console.log(" : " + error); // $
} else { // + -
// #
console.log("Z $ ");
}
}
* ,
"
:
mifare.write()
"
& NDEF
" . #
,
:
NDEF
: node.js
*/
var ndef = require('ndef'); // \ ndef
var mifare = require('mifare-classic'); // \
// mifare-classic
var ndefMsg = new Array();
// & -
// NDEF
//
mifare.write(bytes, writeResponse);
NDEF file is 38 bytes long.
( NDEF 38 .)
Found Mifare Classic 1k with UID 0a64ef28.
( Mifare Classic UID 0a64ef28.
Tag written successfully
(Z $ )
$ node writeNdef.js
* $
" :
;
.
= $ ndefRead.js ndefReadWrite
" .
Глава 9
466
Считываем метку
/
,
" ,
:
/*
NDEF
: node.js
*/
var ndef = require('ndef'); // \ ndef
var mifare = require('mifare-classic'); // \
// mifare-classic
mifare.
write(), "
mifare.read() , listTag().
[ " ,
JSON,
data,
.
, " ,
. & for $ , $ :
* ,
.X %
listTag():
// # $
function listTag(error, buffer) {
if (error) { // + ,
console.log(" : " + error); // $
//
} else { //
var bytes = buffer.toJSON(); // $
// " JSON
if (bytes.hasOwnProperty('data')) { //
// " JSON data,
bytes = bytes.data; // $
}
var message = ndef.decodeMessage(bytes);//
//
for (record in message) { // -
#
// R
,
console.log(message[record].value); //
// $ $
}
}
}
mifare.read(listTag); // Z
mifare.read()
# ,
, :
$ node readNdef.js
"
" :
Here's a string
(+ R )
http://www.example.com
Использование записей NDEF
"
,
. & NDEF -
( 232–1 ). + "
"
$ IP- .
& ,
. * ,
- Android, Mifare Classic,
- ,
. 7 # ,
%
.
Идентификация
467
; ,
node.js
" NDEF, %
"
, $ , Arduino.
Проект 26
NFC и бытовая автоматизация
В нашем с напарником офисе находятся десятки потребляющих электроэнергию устройств: несколько компьютеров, два монитора, четыре или пять ламп освещения, несколько жестких дисков, паяльник, хабы сети Ethernet, динамики и т. п. Даже в наше отсутствие эти устройства потребляют много электроэнергии. Какие устройства включены в определенный момент времени,
зависит от того, кто из нас находится в офисе, и что мы делаем. Этот проект представляет собой
систему, направленную на уменьшение энергопотребления нашего офиса, особенно когда нас
в нем нет. Когда мы заходим в офис, нам достаточно дотронуться брелком с NFC-меткой на кольце для ключей до панели возле двери, и система включит устройства, которые мы обычно используем. Каждый из нас имеет соответствующий брелок, а под панелью смонтирован модуль со
считывателем NFC, который считывает поднесенные к нему метки.
# NFC ,
WiFi $ .
WeMo ( )
Belkin, $
. &
, , $ .
q -
. 9.11. /
WeMo,
,
.
Считыватель
RFID
Интерфейс
SPI
Требуемые компоненты
> , 1 %.
Arduino MKR1000 WINC1500, 1 %.
&
ESP8266.
+ : SPI I2C, Wi-Fi.
7 NFC- PN532, 1 %.
7 RFID Mifare Classic, 2 %.
7 WeMo Belkin, 2 %.
Рис. 9.11. Управляемая посредством NFC
система автоматического включения/выключения электроприборов на основе
модулей WeMo
Беспроводной
канал Wi-Fi передачи
сообщений HTTP
Микроконтроллер
Беспроводной
канал Wi-Fi передачи
сообщений HTTP
Модуль WeMo
Модуль WeMo
Глава 9
468
Схема системы
$
WeMo Wi-Fi,
Wi-Fi.
+ Arduino- MKR1000
WINC1500, ESP8266.
& NFC PN532 NXP Semiconductors.
,
$ . 0
PN 532
NFC/RFID Adafruit,
% NFC
% NFC Arduino Seeed Studio
$
. & , Grove NFC Seeed Studio
.
#
, $ PN532, "
SPI I2C.
7 PN532 "
I2C, SPI X3, %
$
,
"
. & ,
. 9.12 Adafruit
SPI. ;
: ,
.
Протоколы связи
* " NDEF, " :
~ Belkin
"
API
WeMo,
" -
If This Then That (https://ifttt.com),
HTTP. ~ %
, WeMo
HTTP, #
, $ . Belkin
, $ "- .
9 WeMo
,
% . ; WeMo Android
iOS. X , IP WeMo. = $ |
15 ]
& | D
| WeMo, %
IP- .
WeMo uPnP16, SOAP17 — XML , "
" HTTP SMTP.
* ,
,
" SOAP, % .
*
HTTP, " SOAP , ArduinoHttpClient. $
4.
15
?
?
?
;
WeMo,
;
IP-
WeMo.
$
$ " , HTTP "
WeMo.
& ,
, "
.
16
uPnP, Universal Plug & Play — PnP,
$
$
, (
, , , "
),
.
17
SOAP, Simple Object Access Protocol — .
Идентификация
469
Vcc
Модуль
MISO*
микроконтроллера
MOSI**
D4
SCK***
D5
D11
Общий («земля»)
MISO*
Перемычка SEL0:
снята
MOSI**
Модуль
NFC PN532
SCK***
SSEL
К +U
Перемычка SEL1:
установлена
5V
Общий («земля»)
220 Ом
220 Ом
*MISO (вход ведущего, выход ведомого)
**MOSI (выход ведущего, вход ведомого)
***SCK (тактирование)
Примечание
& $ NFC
SPI. 7
SPI Wi-Fi. % SPI
,
. MKR1000 7 Wi-Fi, $
NFC 11. 0
, $ 10 —
Arduino Uno. , I2C. + $
. $ " .
A B
C D E
F
G H
I
J
1
1
5
5
10
10
15
15
20
20
AUX1
P30
AUX2
P31
P32
P33
P34
P35
SIGOUT
GND
SIGIN
RSTPD_N
POWER
PN532 Breakout Board
3.3V
SCK
MISO
MOSI/SDA/TX
25
25
SSEL/SCL/RX
RSTOUT_N
I2C
ON
OFF
IRQ
GND
R1
C15
RXD
ON
NC
OFF
OFF
TXD
OFF
SPI
5.0V
UART
GND
SEL1
NC
SEL0
5.0V
30
OFF
OFF
SEL0
SEL1
ON
ON
30
A B
C D E
F
G H
I
J
FTDICABLE
Рис. 9.12. Принципиальная (вверху) и монтажная (внизу) схемы подключения микроконтроллера к модулю считывателя NFC.
Здесь показана микроконтроллерная плата MKR1000. Для других микроконтроллерных плат, возможно, потребуется использовать другие выводы. При этом необходимо, чтобы подключения интерфейса SPI совпадали. Также следует обеспечить подключение шины «земли» на левой стороне макетной платы к общему выводу питания под модулем считывателя NFC
Глава 9
470
0
" " :
<?xml version="1.0" encoding="utf-8"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"
s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<s:Body>
<u:SetBinaryState xmlns:u="urn:Belkin:service:basicevent:1">
<BinaryState>1</BinaryState></u:SetBinaryState>
</s:Body>
</s:Envelope>
, HTML,
XML
,
$ XML
(Envelope) (Body) " . & " BinaryState
1 0,
.
#" POST, HTTP :
Content-type: text/xml; charset=utf-8
SOAPACTION: "urn:Belkin:service:basic
event:1#SetBinaryState"
Connection: keep-alive
Content-Length: 230
= HTTP ArduinoHttpClient.
= WeMo
URL- : /upnp/control/basiceventl.
7 $
%
HTTP. X WeMo
49153.
Установка библиотек
= $ : NDEF Arduino = (Don Coleman) PN532 # (Yihui
Xiong). + https://
github.com/don/NDEF https://github.com/
Seeed-Studio/PN532 . >
NDEF -
"
NDEF PN532 . * $
7
Arduino, $
" . 2 , ,
Arduino, D | > | ! .ZIP
.
= NDEF
,
.
3 PN532 : PN532_I2C,
PN532_SPI PN532_HSU ( SPI).
% \ |
. & , $ %
NDEF.
=
Arduino
" NDEF RFID, .
Идентификация
471
Записываем сообщение на метку
2 " NDEF. /
"
node.js " ,
$ Arduino.
&
SPI
NFC:
/*
& setup()
:
void setup() {
Serial.begin(9600); // \ # $ '
// $
nfc.begin(); // \ # $ $ NFC
}
& loop()
. "
NDEF, ,
"
:
void loop() {
Serial.println("$ % '
Mifare Classic .");
if (nfc.tagPresent()) {
NdefMessage message = NdefMessage();
message.addTextRecord("Tom Igoe); //
//
$
message.addTextRecord("1"); //
// WeMo
message.addTextRecord("192.168.0.17); //
// IP- WeMo
if (nfc.write(message)) {
Serial.println(" .");
} else {
Serial.println(" $ .");
}
}
3
:
Serial.println(); // + ' #
delay(3000); // $' ,
}
,
,
NDEF
: Arduino
Arduino
*/
#include <SPI.h> // ' SPI
#include <PN532_SPI.h> // ' SPI PN532
#include <PN532.h> // ' PN532
#include <NfcAdapter.h> // ' NFC
PN532_SPI pn532spi(SPI, 11); // \ # $
NfcAdapter nfc = NfcAdapter(pn532spi);
& " NDEF RFID.
Считываем метку
#
, ,
" NDEF. ;
, ,
/*
NDEF
: Arduino
Arduino
*/
#include <SPI.h> //
'
SPI
Глава 9
472
. = tagLed
,
, "
:
#include <PN532_SPI.h> // ' SPI PN532
#include <PN532.h> // ' PN532
#include <NfcAdapter.h> // ' NFC
PN532_SPI pn532spi(SPI, 11); // \ # $
NfcAdapter nfc = NfcAdapter(pn532spi);
const int tagLed = 5; // +
// #
[ setup() ,
" ,
:
void setup() {
Serial.begin(9600); // \ # $ '
// $
nfc.begin(); // \ # $ NFC
pinMode(tagLed, OUTPUT); // -
//
}
& loop() "
,
.
4 " NDEF,
:
void loop() {
if (nfc.tagPresent()) {
digitalWrite(tagLed, HIGH);
NfcTag tag = nfc.read();
if (tag.hasNdefMessage()) {
& for " ,
. + " ,
" ,
. =
WeMo:
for (int r = 0; r < recordCount; r++) {
NdefRecord record = message.getRecord(r);
// $
int payloadLength = record.getPayloadLength();
// $ $ $
byte payload[payloadLength]; // &
// $ $
record.getPayload(payload); // $ '
// $
String payloadString; // '
// payloadString
for (int c = 3; c < payloadLength; c++) { //
// , 3
payloadString += (char)payload[c]; //
// ' payloadString
}
Serial.println(payloadString); // +
// payloadString R
} // # # for $
} // # if tag.hasMessage()
} // # if tag.Present()
*
, :
digitalWrite(tagLed, LOW); // M$ ,
//
delay(3000); // $'
}
// Z NFC
// M$
//
//
// ,
NdefMessage message = tag.getNdefMessage(); //
//
int recordCount = message.getRecordCount(); //
// $
Идентификация
473
' ,
NFC
. 0
,
Arduino " ,
, $ " Arduino.
,
.
; ,
,
HTTP WeMo.
-
,
. 3
Усовершенствуем код считывателя
&
%
Wi-Fi
WeMo
HTTP
NDEF. 7
WiFi101,
"
Wi-Fi.
config.h
(SSID)
:
/*
*
: ,
,
"
Wi-Fi, $
Wi-Fi, , ,
WeMo,
, IP-
" WeMo.
,
SOAP
. =
,
,
(\) :
PN532_SPI pn532spi(SPI, 11); // \ # $
NfcAdapter nfc = NfcAdapter(pn532spi);
const int tagLed = 5; // +
//
#
const int wifiLed = 4; //
// Wi-Fi
WiFiClient netSocket; // C
const int port = 49153; //
String route = "/upnp/control/basicevent1"; // $ API
boolean wemoStates[] = {0, 0}; // 9 WeMo
String username = ""; //
String wemoAddress = ""; // WeMo
int wemoNumber = -1; // WeMo
// 9 SOAP
String soap = "<?xml version=\"1.0\" encoding=\"utf-8\"?> \
<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" \
s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"> \
<s:Body> \
<u:SetBinaryState xmlns:u=\"urn:Belkin:service:basicevent:1\"> \
<BinaryState>1</BinaryState></u:SetBinaryState></s:Body> \
</s:Envelope>";
7 HTTP NFC WeMo
7 :Arduino
WIN1500
*/
#include <SPI.h> // ' SPI
#include <WiFi101.h> // $
WiFi101
//#include <ESP8266WiFi.h> //
// ESP8266
#
#include <ArduinoHttpClient.h>
#include "config.h"
#include <PN532_SPI.h> // ' SPI
// PN532
#include <PN532.h>
// ' PN532
#include <NfcAdapter.h> // ' NFC
Глава 9
474
& setup()
Wi-Fi
,
Wi-Fi,
Wi-Fi:
void setup() {
Serial.begin(9600); // \ # $ ' $
nfc.begin(); // \ # $ NFC
pinMode(tagLed, OUTPUT); // -
//
#
pinMode(wifiLed, OUTPUT); // % !
// Wi-Fi
// $ Wi-Fi,
while ( WiFi.status() != WL_CONNECTED) {
Serial.print("$
: ");
Serial.println(ssid); // # (SSID)
WiFi.begin(ssid, password); //
delay(2000);
}
// $
% Wi-Fi,
"
:
,
#
// :
IPAddress ip = WiFi.localIP();
Serial.print("IP- : ");
Serial.println(ip);
}
= %
loop()
, %
. & %
copyRecords() ( )
"
"
. 4"
Wi-Fi
"
Wi-Fi:
=
copyRecords(),
setup(). [ "
"
. ,
IP- ,
wemoRequest()(
),
POST:
void loop() {
// ... % setup()
Serial.println(payloadString); // +
// payloadString R
copyRecords(r, payloadString);
} // # # for $
} // # if tag.hasMessage()
} // # if tag.Present()
digitalWrite(tagLed, LOW); // M$ ,
//
if (WiFi.status() == WL_CONNECTED) { // `
// Wi-Fi
digitalWrite(wifiLed, HIGH);
} else {
digitalWrite(wifiLed, HIGH);
}
delay(3000); // $'
}
void copyRecords(int recordNum, String recordString) {
switch (recordNum) { // N !
// -
case 0: // %
;
break;
case 1: // % WeMo; $
//
wemoNumber = recordString.toInt();
break;
case 2: // % IP- ; N
wemoAddress = recordString; // * IP- ,
wemoRequest(wemoNumber, wemoAddress); //
//
break;
} // 7 case
}
Идентификация
475
0 wemoRequest(),
case 2. [
WeMo,
SOAP " ,
$ String.
replace(). ;
" , :
void wemoRequest( int thisWemo, String wemo) {
if (wemoStates[thisWemo] == 0) { // * WeMo ,
soap.replace(">0<", ">1<"); //
} else { //
soap.replace(">1<", ">0<"); //
}
wemoStates[thisWemo] = !wemoStates[thisWemo]; //
//
wemoState !
=
POST HTTP,
ArduinoHttpClient, $
4 5.
, , beginRequest() — endRequest() —
% . ;
POST "
endRequest()
http.println().
$,
POST
"
HttpClient http(netSocket, wemo.c_str(), port); // 9
// HTTP
http.connectionKeepAlive(); // ` !
//
http.beginRequest(); //
http.post(route);
// %
//
:
http.sendHeader("Content-type", "text/xml; charset=utf-8");
String soapAction = "\"urn:Belkin:service:basicevent:
1#SetBinaryState\"";
http.sendHeader("SOAPACTION", soapAction);
http.sendHeader("Connection: keep-alive");
http.sendHeader("Content-Length", soap.length());
http.endRequest(); // 7
http.println(soap); //
Serial.println("% ");
Stream:
/ $
WeMo:
while (http.connected()) { // $
,
if (http.available()) { //
String result = http.readString(); //
Serial.println(result); //
#
}
}
}
" $
, NFC
,
. , ,
, "
. / . 0 ,
,
,
"
. , $ ,
"
. $
,
Глава 9
476
, — .
#
% $ — ,
,
( . 9.13). / % % .
Рис. 9.13. При установке считывателя на двери пользователь вынужден убрать метку после того, как он проведет ее
по считывателю. Таким образом решается проблема невозможности считывания больше чем одной метки за раз
& , WeMo
,
HTTP. / ,
WeMo
, —
— " ,
. + loop() "
% . & , "
,
,
,
.
Конструкция
$
- 5. > , %, %
%
.
, —
,
$ . 9
Adafruit, " , , , $
, . 9.12. * . 9.14 9.15
, . 9.13
.
Рис. 9.14. Корпус проекта считывателя NFC в процессе
сборки. Требуется, чтобы антенна считывателя находилась
в верхней части корпуса, что вызывает необходимость двухуровневой конструкции с размещением микроконтроллера
на нижнем уровне. Этого можно достичь, используя стойки
разной высоты
Рис. 9.15. Корпус проекта считывателя NFC в развернутом
виде. Модуль считывателя и светодиоды подключены к микроконтроллерной плате с помощью монтажных проводов
и прямоугольных штыревых разъемов
Идентификация
477
Безопасность устройств сетевой связи
Физические идентификационные данные во все возрастающей мере связаны с сетевыми данными, а сетевые данные во все возрастающей мере становятся уязвимыми к атакам. Поэтому
все должны быть осведомлены об основных методах защиты идентификационных данных, как
своих персональных, так и своих устройств.
% ,
+
% , ,
%
"
$ ,
%
. =
% .
Не выходите за пределы
локальной сети
0 " %
. X ,
"
%
IP-
, +
,
. $
. * "
,
% " ? &
. ; $ ,
- ,
,
%
% . 4
,
$ , %
? 4
,
% , .
Применяйте двухфакторную
аутентификацию
= ,
, . + $
. & ,
" Hue Philips:
,
. 3
%
,
"
. ;
Google. & $
% , % — . 4"
— , iOS
.
=
NFC .
Используйте HTTPS и криптографию
с открытым ключом
& 8
HTTPS
, "
( )
%
"
. ;
.
9 $ " .
# :
. =
HTTPS $ $ ,
Глава 9
478
(
). 4
% " , — % . 4
" ,
, %
"
. _ % " % " , %
. *
,
% " , "
. # , ,
" $
% %
" ,
% % .
'
, , . 0
"
% " , . / %
,
% "
"
,
, "
, — " , ,
. #
- , " HTTPS,
,
, ,
% "
, $
- .
3
, , " % , % " .
7 % !. «:
» 3,
% aes-256-cbc
— %
% . # %
" , ,
% .
Проект 27
Двухфакторная идентификация с использованием NFC
В этом проекте мы создадим систему двухфакторной аутентификации на основе Raspberry Pi
и метки NFC. Эту систему можно использовать в любом случае, когда требуется двухфакторная
аутентификация, но в здесь мы применим ее для открытия замка.
9 — — $
NFC, — . 9 " . ' , - ,
node.js, NFC
, $
.
#
% .
&
" ,
(%
) ,
(%
),
% %
.
, % , —
"
% . =
%
.
0 %
,
,
% .
Идентификация
3
, %
"
. /
, %
,
. /
, - .
,
HTTPS,
18 ( . !. «&! HTTPS» 8) -
$ ,
. 3 "
% .
479
Требуемые компоненты
# - SCL3711 USB Smart
Card Reader Identiv.
7 RFID Classic Mifare.
0
Raspberry Pi.
; TIP120.
9
#
1 0.
.
+
12 &.
9
5,5 % — 2,1 .
* % .
Особенности кода
$
NFC NDEF,
26,
Raspberry Pi. #
,
" node.
js. +
JavaScript
express ndef
,
.
ndefSignature. 9 % , , — . /
,
. *
,
$ .
, , ,
.
+, $ https-server.js https-serverwriter.js, — https-server-reader.js. ;
,
SSL. =
NDEF, — NDEF, — GPIO.
,
- ,
p5.js. , ,
public
p5.js : reader
writer. 2 "
npm " :
$ npm install express body-parser
ndef mifare-classic onoff
# " : writeNdefSignature.js, readNdefSignature.js gpioControl.js.
,
% -
Глава 9
480
. 7 $
SSL
, % -
. *
keys "
openssl " :
$ openssl genrsa -out keys/private.key 2048
$ openssl rsa -pubout -in keys/private.key -out keys/public.key
;
.
Рис. 9.16. Монтажная (внизу) и принципиальная (вверху) схемы подключения считывателя NFC SCL3711 компании Identiv
к Raspberry Pi через транзистор TIP120. Рабочее напряжение соленоида 12 В при токе 1 А, поэтому ему требуется отдельный
источник питания постоянного тока напряжением 12 В и достаточной мощности. «Минус» (контакт «земля») этого источника питания нужно подключить к контакту «земля» платы Raspberry Pi. Но ни в коем случае не подключайте к Raspberry Pi напряжение
+12 В, поскольку это безвозвратно повредит компьютер
К плюсу
источника питания 12 В
Контакты
ввода/вывода (GPIO)
платы Raspberry Pi
Соленоидный
замок
TIP120
1 кОм
GPIO 18
1N4004
1
5
10
15
20
15
20
A
B
C
D
E
TIP120
F
G
H
I
J
1
5
10
DSI (DISPLAY)
USB 2x
USB 2x
GPIO
http://www.raspberrypi.org
Audio
ETHERNET
Power
CSI (CAMERA)
HDMI
SCL3711 NFC reader
Идентификация
481
Управление контактами ввода/вывода (GPIO) на Raspberry Pi
# $ ( . 9.16) %
, 25
26, —
,
/ Rapsberry Pi.
$ « » (
« ») " ( « ») Raspberry Pi.
, gpioControl.js
Raspberry Pi. / / "
(GPIO), $ onoff
node.js.
GPIO Raspberry Pi ( . 9.17)
"
Arduino — ,
:
( X3),
SPI I2C,
+7. , Raspberry Pi
"
.
9
3,3 &, 5-
. > onoff,
" ( : https://github.com/
fivdi/onoff), $
,
$ ,
(
).
Arduino, GPIO Raspberry Pi
% " , , $ . ;, % ,
Raspberry Pi ,
, , ,
.
Рис. 9.17. «Распиновка» контактов ввода/вывода общего
назначения (GPIO) плат Raspberry Pi моделей 2, 3 и Zero
3.3V Power
Питание 5 В
GPIO 2 (SDA)
Питание 5 В
GPIO 3 (SCL)
«Земля»
GPIO 4 (GPCLK0)
GPIO 14 (TX)
Ground
GPIO 15 (RX)
GPIO 17
GPIO 18 (PWM0)
GPIO 27
«Земля»
GPIO 22
GPIO 23
3.3V Power
GPIO 24
GPIO 10 (MOSI)
«Земля»
GPIO 9 (MISO)
GPIO 25
GPIO 11 (SCLK)
GPIO 8 (CE0)
Ground
GPIO 7 (CE1)
GPIO 0 (ID_SD)
GPIO 1 (ID_SC)
GPIO 5
«Земля»
GPIO 6
GPIO 12 (PWM0)
GPIO 13 (PWM1)
«Земля»
GPIO 19 (MISO)
GPIO 16
GPIO 26
GPIO 20 (MOSI)
Ground
GPIO 21 (SCLK)
Глава 9
482
Код для управления соленоидом
, GPIO
gpioControl.js
. 2 GPIO
18
,
lock. +
$
,
:
/*
& ,
,
lock
1, — 0. / open()
close()
. & open()
close()
2 , :
function close() {
lock.writeSync(0); // $
//
}
M GPIO
: node.js
*/
var Gpio = require('onoff').Gpio; // '
// onoff
var lock = new Gpio(18, 'out');
// %
//
function open() {
lock.writeSync(1); //
//
setTimeout(close, 2000); // + $ 2
//
$ $
}
0 if -o
open(). / %
:
//
if (process.argv[2] === '-o') {
open();
}
—
. 2
$
$
. + $
,
HTTPS:
// % #
R #
// $
#
module.exports = {
close: close,
open: open
};
,
-
Проверяем работу сценария управления GPIO
gpioControl.js " :
$ node gpioControl.js -o
&
$ Raspberry Pi 18 -
,
. 4 $ 18
, . 9.16,
. *
. = $ 18
Идентификация
483
,
« ».
2 , .
NFC
" .
$
,
.
X %
18, $ ,
% -
; ,
gpioControl.js, NDEF.
Модули Node.js
node.js
. 7
node.js
$ , node.js
. 9 , $
,
.
7 .
' ,
$ "
require(), $ , . $ , ,
requrie(). * ,
GPIO , $ "
:
%,
$ , % ,
$
module.exports,
$ GPIO. &
" module.exports $ "
.
& ,
module.exports,
$
.
,
node-modules,
. [
, . * :
var lockControl = require('./gpioControl.js');
lockControl.open();
& " .
Разработка сценариев записи и чтения меток NDEF
Сценарий записи метки
; , ,
. 0 writeNdef-Signature.js " . & ,
,
: ndef-js, mifare-classic
NDEF, fs
crypto % % " NDEF:
/*
$ %-
NDEF
% ' ' $ , $
NDEF
$ .
: node.js
*/
var ndef = require('ndef'); // ' ndef
var mifare = require('mifare-classic'); // '
// mifare-classic
var crypto = require('crypto'); // '
// crypto
var fs = require('fs'); // ' %
// fs
Глава 9
484
=
, "
% :
=
. ~ $
,
, $ ,
$
:
0 $
setMessage()
%
NDEF NFC. /
NDEF
25
% .
[ " ,
" mifare.write():
var privKey = fs.readFileSync('keys/private.key'); // Z
// '
var privateKey = privKey.toString(); // $
//
var secret = null; // %$,
// % '
// # $ %$
function setSecret(data) {
secret = data;
}
// # NDEF,
// $ % $ %
function setMessage(record, signed) {
var ndefRecord; // Z $ NDEF
var ndefMsg = new Array(); // & NDEF
if (signed === true) { // $ $ %,
// $ %
var signer = crypto.createSign('RSA-SHA256'); // Z$
// %
signer.update(record); // $
var signature = signer.sign(privateKey, 'hex');
// %
ndefRecord = ndef.textRecord(signature); // Z$
// $ NDEF
else { // $ %
ndefRecord = ndef.textRecord(record); // Z$
// $ % ' $ NDEF
}
ndefMsg.push(ndefRecord); // $
//
var bytes = ndef.encodeMessage(ndefMsg); // $
//
return bytes; // +$
}
0 $
setMessage(), mifare.write(),
. =
mifare.write()
, . [
showResponse() %
$ "
% %
:
// # $ % #
function showResponse(error){
if (error) {
console.log(' ' + error);
} else {
console.log('M-');
}
}
write()
format()
Идентификация
485
# "
, "
writeNdefSignature.js, "
. &
"
process.argv[]. 4
-f,
. 3
, % , " , " % ,
%
:
// ,
if (process.argv[2] != null) {
if (process.argv[2] === '-f') { //
// % -f,
mifare.format(showResponse); // %
} else { // +
setSecret(process.argv[2]); //
$
// ' %$
var response = setMessage(secret, true); // +
// $ % ' ' %$ NDEF
mifare.write(response, showResponse); //
// $
}
}
$ "
. / %
writeNdefSignature.js:
// % #
R #
// $
#
module.exports = {
format: mifare.format,
setMessage: setMessage,
write: mifare.write
};
. 9 Mifare Classic " :
$ node writeNdefSignature.js -f
#
" :
Found Mifare Classic 1k with UID 1e6f5ba5.
( Mifare Classic 1k UID 1e6f5ba5.)
Formatting 16 sectors [...4...8...12...16] done.
( 16 [...4...8...12...16] .)
success
M
, . ; % .
= $ " :
$ node writeNdefSignature.js 'this is my secret phrase'
#
" :
NDEF file is 522 bytes long.
( NDEF 522 .)
Found Mifare Classic 1k with UID 1e6f5ba5.
( Mifare Classic 1k UID 1e6f5ba5.)
success
M
# % ( ) % . 2 ,
" % , % ,
" .
Глава 9
486
Сценарий чтения метки
; readNdef " . /
% " ,
NFC " .
Signature.js
,
. * $ ( ) .
0 $ ,
. , $
%
" ,
:
/*
$ %-
NDEF
Z NDEF, $
' '.
: node.js
*/
%
var ndef = require('ndef'); // ' ndef
var mifare = require('mifare-classic'); // '
// mifare-classic
var crypto = require('crypto'); // '
// crypto
var fs = require('fs'); // ' %
// fs
var pubKey = fs.readFileSync('keys/public.key'); // Z
// '
var publicKey = pubKey.toString(); // $ '
//
var secret = null; // ' %$
[ setSecret() ,
:
// # $
function setSecret(data) {
secret = data;
}
' " " mifare.
read() . *
.
/ " %
:
parseMessage(), " NDEF,
:
// # $
function getMessage(error, buffer) {
if (error) { // + ,
console.log(' ' + error); //
} else { // +
console.log(parseMessage(buffer)); // +
//
}
}
[ parseMessage()
25. 0
" NDEF
NDEF. 2
-$
function parseMessage(buffer) {
var result = null; // +$ $
var bytes = buffer.toJSON(); // $
// " JSON
if (bytes.hasOwnProperty('data')) { //
// " JSON data,
bytes = bytes.data; // $
var message = ndef.decodeMessage(bytes);//
//
%$
Идентификация
487
for (r in message) { // -
# R
// ,
var record = message[r].value; //
// $ $
result = verifyRecord(record, secret);//
// %$
}
} else {
result = false; // Z data ,
// $ $ false
}
return result;
for verifyRecord()
:
}
[ verifyRecord()
" crypto
,
, " ,
. +, ,
% ,
"
. [
% ,
,
,
% :
function verifyRecord(signature, secret) {
var verifier = crypto.createVerify('RSA-SHA256');// Z$
// %
verifier.update(secret); // %
// $ % ' ' %$
// - $ %
var result = verifier.verify(publicKey, signature,
'hex');
return result;
}
=
. " ,
" "
. 2
" mifare.read(),
parseMesage()
verifyRecord(), " NDEF:
// ,
if (process.argv[2] != null) {
setSecret(process.argv[2]); //
$
// ' %$
mifare.read(getMessage); //
//
}
* , , $ "
. / % readNdefSignature.js:
// % #
R #
// $
#
module.exports = {
setSecret: setSecret,
read: mifare.read,
parseMessage: parseMessage
}
Глава 9
488
' , NFC , " " , " :
$ node readNdefSignature.js 'this is my secret phrase'
#
" :
Found Mifare Classic 1k with UID 1e6f5ba5.
( Mifare Classic 1k UID 1e6f5ba5.)
NFC Forum application contains a "NDEF Message TLV".
( NFC Forum "Z TLV NDEF".)
true
( )
,
,
,
%
, " ,
.
"
,
$
. =
HTTPS,
. 2 $
,
GPIO, " .
=
HTTP : — ,
— . /
. *
, .
, , ,
.
Создаем сервер для записи меток
0 https-server-writer.js
" .
2
% .
/*
Z HTTP/HTTPS -% % #
+ %
$
: node.js
*/
# :
body-parser ( 3)
POST. ; require()
. 0 ,
,
,
node_modules,
:
// '
" :
var express = require('express'); // '
// express
var bodyParser = require('body-parser'); // $
// body-parser
var https = require('https'); // ' HTTPS
var http = require('http'); // ' http
var fs = require('fs'); // ' %
// fs
// $
var tagWriter = require('./writeNdefSignature.js');
Идентификация
$
,
SSL,
"
server.use() HTTP
, " . 4
body-parser,
POST HTTP:
& , , % , .
,
,
:
, % ,
,
. ' - , $
:
&
,
. ;
request.
path. #
" " :
.format() .write(),
writeNdefSignature.js. =
,
" % %
. 7 $
— finishResponse() —
processTag(),
% :
489
var server = express(); // Z$ R$
var options = { // HTTPS
key: fs.readFileSync('./keys/domain.key'), // '
cert: fs.readFileSync('./keys/domain.crt') // %
};
server.use('*', httpRedirect); // #
// $ http
server.use('/',express.static('public')); //
// ,
%
server.use(bodyParser.urlencoded({extended: true}));
// N
function httpRedirect(request,response, next) {
if (!request.secure) {
console.log(' $ http $
$ https');
response.redirect('https://' + request.hostname + request.url);
} else {
next(); // $ % #
express.static()
}
}
function processTag(request, response) {
var command = request.path; // $
command = command.slice(1); // N
//
var data = JSON.stringify(request.body);// $
//
// $
response.writeHead(200, {"Content-Type": "text/html"});
response.write('N
...<br>');
// Q
function finishResponse(error, buffer) {
if (error) {
response.write('N: ' + error + '<br>');
} else {
response.write(command + '
.<br>');
}
response.end();
}
Глава 9
490
2 % processTag() :
.format() .write() — .
,
— finishResponse() —
,
.
2
"
NDEF, $ .setMessage()
" NDEF:
* ,
HTTP HTTPS, $ " ,
.
0 : writeTag
formatTag — —
processTag(), :
// ,
:
if (command === 'formatTag') {
tagWriter.format(finishResponse); // $
//
}
if (command === 'writeTag') {
var message = tagWriter.setMessage(data, true);
tagWriter.write(message, finishResponse);
// $
}
}
//
http.createServer(server).listen(8080); // $ HTTP
https.createServer(options, server).listen(443); //
// $ HTTPS
server.post('/writeTag', processTag); // N
//
writeTag
server.post('/formatTag', processTag); // N
//
formatTag
& .
Добавляем веб-страницу для сервера записи
; ,
,
- . & writer public
sketch.js
" :
2 %
: userField,
challengeFiled responseDiv,
:
[ setup() " ,
. =
writeButton
/*
+- # $ /%
: p5.js
*/
var userField, challengeField; // $
//
$
var responseDiv; // $
//
%$
Идентификация
formatButton, $
. &
submit(), " .
& , $ draw():
491
function setup() {
noCanvas(); // ^ , R
-
// Z$ $
responseDiv = createDiv('+
$
' %$ $ .');
responseDiv.position(10, 130);
var userLabel = createSpan('\ $'); // Z$
//
$
userLabel.position(10, 10);
userField = createInput('','text'); // Z$
//
$
userField.position(100, 10);
var challengeLabel = createSpan(' %$'); // Z$
// %$
challengeLabel.position(10, 40);
challengeField = createInput('','password'); // Z$
// %$
challengeField.position(100, 40);
var writeButton = createButton(' '); // Z$
// $
writeButton.position(10, 70);
writeButton.id('writeTag');
writeButton.touchEnded(submit);
var formatButton = createButton(' ') // Z$
// %
formatButton.position(10, 100);
formatButton.id('formatTag');
formatButton.touchEnded(submit);
}
[ submit()
"
POST HTTP.
2 JSON
POST, $ :
function submit(event) {
var route = '/' + event.target.id; //
// %
var data = { // Z$ $ POST
'user' : userField.value(),
'challenge' : challengeField.value()
};
// & $,
// $ '
responseDiv.html(' '<br>')
httpPost(route, data, 'text', getResponse); //
// $ POST
}
[ getResponse()
POST. 0 %
responseDiv:
function getResponse(data) { //
//
responseDiv.html(data);
//
//
}
&
. # ,
.
#
$
+
$
$
POST
- #
$
Глава 9
492
Тестирование сервера записи метки
*%
,
$
% , "
. , . = $ ,
% :
ndefSignature
public
writer
HTML
p5.js
p5.js
index.html
libraries
sketch.js
reader
index.html
libraries
sketch.js
node_modules
https-server-reader.js
https-server-writer.js
keys
domain.key
domain.crt
private.key
public.key
writeNdefSignature.js
readNdefSignature.js
gpioControl.js
, ' npm
%
'
( ) ' SSL
% SSL
' # $ NDEF
' #
NDEF
NDEF
NDEF
GPIO
=
Raspberry Pi
:
$ sudo https-server-writer.js
Рис. 9.18. Веб-страница для приложения записи меток NDEF.
Сообщения сервера выводятся в текстовом разделе внизу
страницы
2
:
https://..raspberry.pi/writer.
$ ..
raspberry.pi
IP-
% Raspberry Pi. 0 , https:// . &
, . 9.18.
Format tag ([ ).
& " :
'
...
formatTag .
Идентификация
493
0 , ( ,
) Write to tag
(2 ). # " :
'
...
writeTag .
4
" :
?
?
?
4 , ,
.
,
-
?
% NFC?
"
writeNdefSignature.js
readNdefSignature.js;
?
,
.
Создаем сервер для чтения меток
# httpsserver-reader.js
https-server-writer.js
. #
,
(
% ,
,
" ).
'
—
, writeNdefSignature.
js readNdefSignature.js gpioControl.js:
=
processTag(). &
, .write() .format()
$
.setSecret() .read()
readNdefSignature.js.
[ finishResponse() . , .parseMessage()
readNdefSignature.js :
/*
Z HTTP/HTTPS -%
+
: node.js
% #
*/
// '
" :
// '' ,
#
// $ https-server-write.js
// $
var tagReader = require('./readNdefSignature.js');
var lockControl = require('./gpioControl.js');
/*
... $ ,
$
https-server-write.js, $ R$ ,
' -
$
HTTP $ $ HTTPS
*/
function processTag(request, response) {
var command = request.path; //
command = command.slice(1); // ' '
var data = JSON.stringify(request.body); // $
// $
//
response.writeHead(200, {"Content-Type": "text/html"});
response.write(' ...<br>');
// # $
function finishResponse(error, buffer) {
if (error) {
response.write(' : ' + error + '<br>');
} else {
response.write(command + ' .<br>');
var verified = tagReader.parseMessage(buffer);
Глава 9
494
if (verified) {
response.write(' .<br>');
lockControl.open();
} else {
response.write('
#
.<br>');
}
}
response.end();
}
// ,
:
tagReader.setSecret(data);
tagReader.read(finishResponse); // $
}
4
POST /readTag
/writeTag /formatTag:
//
http.createServer(server).listen(8080); // $ HTTP
https.createServer(options, server).listen(443); //
// $ HTTPS
server.post('/readTag', processTag); // N
//
readTag
& .
Добавляем веб-страницу для сервера чтения
; ,
, -
.
= .
,
,
-
-
. 9 $
% . q
:
[ setup()
, -
, % ,
responseDiv
:
/*
+- #
: p5.js
*/
var userField, challengeField; // $
//
$
var responseDiv; // $
//
%$
function setup() {
noCanvas(); // ^ , R
-
//
// Z$ $
responseDiv = createDiv('
..');
responseDiv.position(10, 130);
/*
Z' $ $ $
userfiled
$
challengeField
%$
*/
Идентификация
495
var readButton = createButton('~
');// 9
//
readButton.position(120, 70);
readButton.id("readTag");
readButton.touchEnded(submit);
}
0 -
submit()
getResponse():
/*
Z' % #
submit()
- # $
*/
getResponse()
$
& .
Тестирование приложения чтения метки
;
. * $ , , gpioControl.js. X %
,
"
:
Рис. 9.19. Веб-страница для приложения чтения меток NDEF.
Сообщения сервера выводятся в текстовом разделе внизу
страницы
$ sudo https-server-reader.js
2
:
https://..raspberry.pi/reader.
& ..raspberry.pi
IP-
% Raspberry Pi.
0 , https:// . & , . 9.19.
, "
Verify tag (# ). # " :
'
...
readTag .
+ %$.
$
( . 9.20). .
#
" :
'.
...
readTag .
^ '
R
#
,
,
,
POST. & JSON, , % , NDEF. #
,
,
.
Глава 9
496
7
NDEF % . /
,
. *
"
%
. 4 %
, % , , ,
.
*
,
.
~
, " ,
, , , -
. $
,
,
,
.
> % ,
RFID
, . /
,
,
,
. * , , $
- .
Рис. 9.20. Соленоидный замок устанавливается вместо обычного дверного замка
Идентификация
497
Сетевая идентификация
До сих пор мы идентифицировали сетевые устройства по их адресам. Для устройств Интернета
в качестве идентификаторов используются как IP-, так и MAC-адреса. Беспроводным устройствам, работающим по протоколам Bluetooth и 802.15.4, также присваиваются стандартные адреса. Но адрес устройства не предоставляет нам никакой информации о самом устройстве или его
функциях.
& 4. ;
HTTP,
"
.
API , ,
,
$
. $, "
- . * , ,
, " ?
>% +
. / , " . & ,
,
.
3
, ,
$ . =
HTTP
.
— , node.js, HTTP, % , $
.
Пишем код сервера
'
$ , node.js
clientHeaders. #
$
server.js. # "
npm express, "
,
:
/*
Z $ $
: node.js
*/
var express = require('express'); // '
// express
var server = new express(); // Z$ R$
// express
// # $ GET
function respond(request, response) {
console.log(request.headers);
console.log("\ - : " + request.hostname);
console.log("IP- : " + request.ip);
response.end(" , !");
}
server.listen(8080); //
// 8080
server.get('/', respond); // $ GET
Глава 9
498
&
$
" :
{ host: '114.226.112.201:8080',
connection: 'keep-alive',
'cache-control': 'max-age=0',
'upgrade-insecure-requests': '1',
'user-agent': 'Mozilla/5.0 (Macintosh;
Intel Mac OS X 10_12_3)
AppleWebKit/537.36 (KHTML, like Gecko)
Chrome/56.0.2924.87
Safari/537.36',
accept: 'text/html,application/
xhtml+xml,application/
xml;q=0.9,image/webp,*/*;q=0.8',
'accept-encoding': 'gzip, deflate, sdch',
'accept-language': 'en-US,en;q=0.8' }
\ - : 114.226.112.201
IP- : ::ffff:206.175.85.178
, $ % : IP-
-
, ,
,
. & ,
, , HTTP, % ! ;
,
- .
. & ,
%
" - , " ,
% .
4 $
, " %
,
, IP-
$
,
, IP- % . / , %
" IP-
( . 3),
% , % ,
,
% % .
" , ,
, ,
. ~
, , . / ,
% +
% , .
* , user-agent % . * $
:
,
- —
"
. = : accept-language —
,
.
3 IP-
, "
IP- ,
,
.
2
( Chrome $
" , Firefox Safari —
, Microsoft Edge — InPrivate).
& ,
% IP- ,
. & … 3
…
* $ , -
*
%
. ~ " +
Анонимность в Интернете
Идентификация
,
IP-
%
,
+
.
+ $ 4 Tor
(www.torproject.org) — , "
+
. # Tor +
,
- ,
%
. Tor -
Tor,
"
Tor,
$ .
(
!)
- ,
. ; ,
%
-
(
IP
% ),
Tor. * ,
-
499
clientHeaders.js
,
Tor. &
% " +
*- Tor q ,
Tor [ ,
" Tor * .
+ $ Tor *
. 3 nslookup ( . 4),
IP-
, % ,
.
0 " -
Tor . & ,
, %
Tor,
% - . ;
,
Tor, % % - (
) "
+
.
Проект 28
Геолокация по IP-адресу
В этом проекте IP-адрес клиента используется для определения географических широты и долготы его местонахождения. Необходимая информация берется с сайта www.freegeoip.net, который представляет собой общественный проект геолокации по IP-адресу. Полученные от этого
сайта результаты дадут вам определенное представление о том, насколько точным или неточным является геолокация по IP-адресу. Наш сценарий также использует параметр user-agent
запроса HTTP для соответствующего форматирования ответа для разных клиентов.
& - www.freegeoip.net
API, " IP-
" :
. `
$ , IP . =
:
http://freegeoip.net/ <% >/<ip->.
{"ip":"91.200.12.34","country_
code":"UA","country_
name":"Ukraine","region_
code":"","region_name":"","city":"","zip_
code":"","time_zone":"","latitude":50.
45,"longitude":30.5233,"met
ro_code":0}
& % CSV, JSON
XML. = ip- IP-
"
. &
IP-
,
Глава 9
500
Mozilla/5.0 (Macintosh; U; Intel Mac
OS X 10_5_8; en-US)
AppleWebKit/532.5 (KHTML, like Gecko)
Chrome/4.0.249.0
Safari/532.5
Mozilla
Foundation. /
Netscape — & . 4 " Mozilla —
, "
NCSA Mosaic.
> Firefox Mozilla,
« » - , Mozilla
Foundation ,
" &
+
. #
,
"
: , CSS
JavaScript —
Mozilla/5.0
user-agent. +
$
.
= , %
«
Mozilla», $ , , , , -
'
, $
,
.
# "
, IP-
,
. 4
- ,
,
Google Maps,
.
"
% , user-agent $
Mozilla/5.0. * , " user-agent
Chrome
macOS:
Пишем код
# geoIP.
X express,
" . & server.js
" .
& , ,
express
node.js http,
www.freegeoip.net. =
$
express
server,
www.freegeoip.
net ,
,
Google Maps:
/*
Z, '
: node.js
$ # ' IP-
*/
var http = require('http'); // ' http
var express = require('express'); // '
// express
var server = new express(); // Z$ R$
// express server
// Google Maps
var mapsAddress = 'https://www.google.com/maps/place/';
// freegeoip
var geoOptions = {
host: 'freegeoip.net',
path: '/json/'
};
Идентификация
501
, $ // # $ GET
" , function respond(request, response) {
console.log("IP- : " + request.ip);
$ GET,
"
respond(). & $ IP-
HTTP
www.freegeoip.net,
:
& respond()
http.request()
HTTP , " getIPAddress().
/ %
freegeoip "
.
2
respond(),
%
:
% %
finishResponse(). &
user-agent :
function getIPAddress(geoResponse) {
var result = ''; // Z -
//
//
freegeoip
geoResponse.on('data', collectData); //
// -
geoResponse.on('end', finishResponse); //
// $
function collectData(data) { //
// .
result += data; // Z -
// - .
}
// $
function finishResponse() {
var location = JSON.parse(result);
var latLong = location.latitude + "," + location.
longitude;
console.log(latLong);
/* user-agent $ $
( - $ '
Mozilla/5.0), Google Maps. +
$ # ' JSON
*/
if (request.headers['user-agent'].
includes('Mozilla/5.0')) {
response.redirect(mapsAddress + latLong);
} else {
response.end(JSON.stringify(location));
}
}
}
// ^ $ geoIP
geoOptions.path = '/json/' + request.ip; //
// IP- geoIP
var geoRequest = http.request(geoOptions, getIPAddress);
// ^ $
geoRequest.end(); // $
}
Глава 9
502
,
:
server.listen(8080); //
// 8080
server.get('/', respond); // $ GET
" $
Google Maps, IP-
. * "
— , curl,
( . 3),
" JSON.
,
example.com IP-
:
$ curl example.com:8080
#
" :
-
{"ip":"208.113.160.6","country_
code":"US","country_name":"United
States","region_code":"CA","region_
name":"California","city":"Bre
a","zip_code":"92821","time_
zone":"America/Los_Angeles","latitud
e":33.9269,"longitude":117.8612,"metro_code":803}
*
,
Google Maps %
IP- ( . 9.21).
"
"
,
Tor, "
Tor,
%
.
, ,
% .
Рис. 9.21. Геопозиционирование IP-адреса устройства
обычно отображает расположение его поставщика услуг
Интернета. Здесь же в качестве моей геопозиции отображена геопозиция моего оператора — город Сайпресс Хилл
(Cypress Hill) в штате Нью-Йорк, тогда как я в действительности находился в нижнем Манхэттене. Такой же запрос из
того же самого места из браузера Tor поместил меня в западный Техас
Идентификация
. 9.21, IP-
. q
IP-
" IP- . *
$ ,
, " % % % " +
,
% . > ,
,
- ,
% . $ " ,
: «7 IP- . 0
»,
$ : «* , ! ; %
" +
».
= "
$
user-agent.
'
,
user-agent HTTP, ,
, ,
user-agent. * ,
, %
Arduino ,
" :
503
// Z$ HTTP
HttpClient http(netSocket, server, 8080);
http.beginRequest(); // ^ $
http.get(route); // $ GET
// $ user-agent
http.sendHeader("user-agent","arduino");
http.endRequest(); // $
2
user-agent
curl . =
Mozilla user-agent:
$ curl -L -A 'Mozilla/5.0' example.
com:8080
[ -L curl
, - , " useragent.
+
user-agent
%
, , $
" ,
, .
Глава 9
504
Заключение
В этой главе мы рассмотрели несколько примеров
сопоставления физической и сетевой идентификации. Граница между физической и сетевой идентификацией всегда порождает возможность путаницы
и недоразумений. Никакая система для перемещения информации через эту границу не обеспечивает
стопроцентной надежности. Определение идентичности, возможностей и действий — это сложные задачи, результаты решения которых предрасположены к ошибочной интерпретации. Так что, чем больше информации от людей вы включите в ситуацию
и чем больше прозрачности и помощи предоставите вовлеченным людям, тем лучшие результаты вы
получите.
0 "
, $ ,
%
, . & +
" - " ,
$
% . & ,
,
$ , .
, . " ,
%
$ , ,
. * ,
" . * ,
- -
, - " — $
. 9 % $ ,
% .
* ,
, ,
% % . $
,
.
Идентификация
505
Глава 10
СЕТИ МОБИЛЬНОЙ ТЕЛЕФОННОЙ
СВЯЗИ И ФИЗИЧЕСКИЙ МИР
Технологии Ethernet и Wi-Fi удобны для общения людей и объектов
по Интернету, однако намного больший охват имеет мобильная
телефонная связь. Тем не менее, в настоящее время телефония
и Интернет настолько переплетены, что не имеет смысла
рассматривать их отдельно друг от друга. Подключать к сетям
мобильной телефонной связи не только мобильные телефоны,
но и другие физические устройства становится все легче. В этой
главе мы рассмотрим, как совместить Интернет и сети мобильной
телефонной связи и как извлечь из такого совмещения
максимальную пользу.
ohai lion, how r u??? txt me l8r!!!1 (привет, лев, ты там как??? кинь мне потом смс-ку!!!)
/ SMS-. Groundlabs « » «2" »
$ " %
GPS/GSM "
SMS
. Z $
— "
"
, " ,
, "
.
0 Groundlabs.
1
l8r — $ , % «later»
( . — « , »). Z
— «eight» [¬t]
«later». $ " ,
$ ( https://thequestion.ru/).
Глава 10
508
Компоненты для проектов этой главы
Многие основные аппаратные компоненты, используемые в проектах этой главы, вам уже знакомы. Однако здесь нам придется также работать с переменным напряжением номиналом 120 или
220 В и с проводящими тканями и нитками.
Коды поставщиков
?
A — Arduino Store, http://store.arduino.cc
?
J — Jameco, http://jameco.com
?
AF — Adafruit, http://adafruit.com
?
L — Less EMF, www.lessemf.com
?
D — Digi-Key, www.digikey.com
?
RS — RS, www.rs-online.com
?
DL — D-Link, www.dlink.com
?
SF — SparkFun, www.sparkfun.com
?
F — Farnell, www.farnell.com
?
SS — Seeed Studio, www.seeedstudio.com
Рис. 10.1. Новые компоненты для проектов этой главы: 1. Raspberry Pi Zero с камерой Pi в Pi-корпусе. 2. Блок розеток для бытовой электросети со шнуром достаточной длины. 3. Толстовка с капюшоном. 4. Переключатель PowerSwitch Tail. 5. Проводящая
ткань. 6. Сотовые модемы. 7. Пришиваемые к ткани кнопки. 8. Держатель батареек. 9. Оптоизолятор. 10. Датчик температуры
и влажности DHT11. 11. Реле переменного тока. 12. Адаптер USB MK20. 13. Плата Bluethooth BLE Nano. 14. Штыревые разъемы. 15. Токопроводящие нитки. 16. Нитки для вышивания
3
5
4
2
15
11
12
13
16
6
14
8
1
10
9
7
Сети мобильной телефонной связи и физический мир
509
ПРОЕКТ 29. Возвращение сетевого кота
C , 1 +.
D: 438-1045-ND, J: 20723 20601, SF: PRT12615 PRT-12002, F: 4692810, AF: 64,
SS: 319030002, 319030001, %
AF: 2077, A: TSX00083, SF: DEV07914
% SF: PRT12044, AF: 65, D: 923273-ND
Arduino MKR1000, 1 +.
AF: 3156, RS: 124-0657, A: ABX00004, GBX00011
(3 4#), D: 1659-1005-ND
&
ESP8266.
SF: WRL-13231, AF: 2471
A > IP- , 1 +. (
Raspberry Pi).
DL: DCS-930L, DCS-5222L, DCS-960L
& $
DCS-930L,
DCS-5222L DCS-960L D-Link,
Raspberry Pi
Pi Cam ( ),
"
:
• Raspberry Pi SF: DEV-13825, AF: 3055, SS:
114990584, RS: 896-8660, F: 2525225
• Pi Cam SF: 14028, AF: 3099, SS: 113990214
• Pi Zero W Camera Kit A: 3414
!
A
1 +.
AF: 386, J: 2245415, SS: 101020011
DTH11,
, 1 +.
SparkFun , " . &
Power Switch Tail.
SF: KIT-13815
> PowerSwitch Tail, 1 +. /
. &
240 & - www.
powerswitchtail.com.
SF: C0M-10747, AF: 2935
( 1 , 1 +.
D: 1.0KQBK-ND, J: 690865, F: 9339051, RS: 777666
( 100 , 1 +.
D: 100QBK-ND, J: 690620, F: 9337660, RS: 7550707
4N35, 1 +.
J: 41056, F: 1244500, D: 160-1304-5-ND, RS: 597302
&
SparkFun.
SF: BOB-09118
.
.
# ( ).
ПРОЕКТ 30. Звоним термостату
# +
N
29, 1 +.
Twilio, 1 +.
%& , 1 +.
ПРОЕКТ 31. Мобильный регистратор личных биометрических данных
N D Android iOS, 1 +.
RedBear BLE Nano
+ .
USB- MK20.
MS: MKRBL5, SF: WRL-14071
& Arduino 101, -
%
% .
D: 1660-1003-ND, J: 2239331, SF: DEV-13787, A:
3033, F: 2520713, RS: 913-9999, SS: 114990575,
A: ABX00005, GBX00005 (3 4#)
Глава 10
510
H ) +
2,5 A + .
-
AF: 400, SF: PRT-12693.
&
-
-
(IC-hook with pigtail).
SF: CAB-09741 CAB-00501
! A
.
SF: DEV-10730 DEV-13883 PRT00338, AF: 1870 1871 654. 4
%
,
— SF: DEV-11893 PRT-13851.
( 270 , 1 +.
J: 691446, D: CF14JT270KCT-ND, RS: 845-7577
% $ .
AF: 603, SF: DEV-11791, L: 304
% $ .
AF: 1168, L: 1220
+
A
5 .
% >+ , 1 +.
] + . =
.
D
• Adafruit Fona 800.
AF: 3147 (#3), AF: 2691 (4 )
• Adafruit Fona Feather
AF: 3027
• Seeed Studio Xadow GSM+BLE
SS: 102040005
• XBee Cellular
D: 602-1976-ND,
• Particle Electron Kit
SF: WRL-14211 (#. . 3 /3 ),
SF: WRL-14212 (3 /3/4 )
AF: 1126, SF: DEV-11347
Одна большая сеть
Телефонная сеть возникла задолго до сети Интернет. Все соединения в ней осуществлялись аналоговыми электрическими схемами, и все телефонные звонки были коммутируемыми, то есть
между абонентами устанавливалась временная выделенная цепь. Затем появились модемы, которые позволили компьютерам обмениваться данными по тем же самым телефонным аналоговым цепям. Постепенно телефонные коммутаторы были заменены маршрутизаторами, а новые
телефонные сети стали делать цифровыми. Теперь абоненты соединяются виртуальными цепями, и сценарии телефонных звонков почти не отличаются от сценариев электронной почты или
чата: между абонентами устанавливается сеанс, происходит обмен битами и осуществляется обмен сообщениями. Различия между телефонным звонком и электронной почтой сейчас заключены в протоколах, обеспечивающих каждый вид связи, а не в структуре электрических цепей.
- —
Asterisk (www.asterisk.org),
, Twilio (www.twilio.com), Google Voice
(www.voice.google.com), Skype (www.skype.
com) .,
+
. /
, « »
. 0
% ,
,
,
, " IP- .
Сети мобильной телефонной связи и физический мир
X +
% % , " . * ,
SMS-%, "
" $ , "
SMS, " SMS,
" $ . # Google Voice
,
" ,
" , . 0 , " ,
,
.
511
" , . .,
,
. $
$
%
.
9
—
. + $ ,
, %
—
:
?
?
;
$ ;
?
?
Bluetooth;
?
;
USB;
Компьютер у вас в кармане
?
;
#
—
—
,
. ;
—
iPhone 0# Android — $
" , "
.
&
"
,
— $ %
,
, % . >%
"
,
: , , "
GPS. +, , . * ,
$ — -
?
;
?
GPS.
* $ ,
,
: Wi-Fi
—
Bluetooth — . &
IP- ,
+
: HTTP, $ , SSH,
FTP . .
* . 10.2
,
+
.
+
%.
Глава 10
512
Сеть мобильной связи
Базовая
приемопередающая
станция (БПС)
Базовая
приемопередающая
станция (БПС)
Контроллер
базовой станции (КБС)
Базовая
приемопередающая
станция (БПС)
Смартфон
Контроллер
базовой станции (КБС)
Шлюзовый
коммутационный центр
мобильной связи
Узел поддержки GPRS
Коммутационный центр
мобильной связи (КЦМС)
Интернет
Поставщик услуг
Интернет
Телефонная
коммутируемая сеть
общего пользования
(ТКСОП)
Проводной
телефон
Поставщик услуг
Интернет
Домашний
маршрутизатор
Персональный компьютер
Рис. 10.2. Взаимодействие сети мобильной телефонной связи с сетью Интернет
Поставщик услуг
веб-хостинга
Сети мобильной телефонной связи и физический мир
513
Определитесь, как это должно происходить
$ " : , ,
, , ,
$ % . & ,
? + , " , , — , %
- ? ,
.
*
, 5,
? X
—
Bluetooth
USB? 4 $
,
,
? 7
? "
SMS $ , ""
?
,
" . X ,
,
. 4 Wi-Fi?
? Ethernet?
& %
" Bluetooth
Wi-Fi?
Интерфейсы на основе браузера
4
, $
+
. ;
— , , $
HTTP -
.
>% ,
$ ,
.
Интерфейс на основе своего
приложения
4 -
,
,
" Bluetooth, , USB " SMS. 7
$ . "
—
" . * —
,
$
.
,
,
, $ .
Интерфейс на основе сообщений
SMS или электронной почты
&
. 4
,
, — ,
% " , — " SMS $ . ;
$
, " SMS
GPRS,
,
" " " $ "
"
Глава 10
514
+
.
" $ ,
" ,
, —
"
SMS $ .
Голосовые интерфейсы
*
—
. q
,
% —
Asterisk Twilio.
Телефон как шлюз
*
.
+
. &
— "
Bluetooth USB,
. =
$ , ,
, %
.
Проект 29
Возвращение сетевого кота
Если в состав программного обеспечения вашего смартфона входит браузер, вам нет надобности знать, как его программировать, чтобы создать мобильное приложение. В этом проекте мы
создадим вариант проекта сетевого кота из главы 3. Но на этот раз мы воспользуемся новым протоколом — MQTT — и IP-камерой, для подключения которой к Интернету компьютер не нужен.
Требуемые компоненты
> , 1 %.
Arduino MKR1000, WINC1500,
ESP8266, 1 %.
+ : GPIO, Wi-Fi.
IP- , 1 %.
=
, 1 %.
, 1 %.
9
1 0, 1 %.
9
100 0, 1 %.
0 , 1 %.
# , 1 %.
.
.
2 (
).
X
, _, , q . X _
% .
0 ,
, . 0
, ,
. ;
%
(
), _
. '
,
. 7
" : _
-
" ,
. 2 " , , - .
Сети мобильной телефонной связи и физический мир
4
% ,
, % — .
_
.
%
,
, % ,
, . *
. 10.3 - ,
. 10.4 —
.
Рис. 10.3. Блок-схема системы связи
для наблюдения за котом и управления
кондиционером
515
#
— $
. 9
Wi-Fi MKR1000 SPI.
=
,
220 &
— . > IP- $ " Wi-FI, $ ,
, — $
% .
-
% ,
% .
Мобильный
клиент
Компьютерный
клиент
Мобильная сеть
Сеть Ethernet
или Wi-Fi
Интернет
Подключение DSL
или кабельное
Камера
Wi-Fi
Домашний
маршрутизатор
Wi-Fi
Датчик
температуры
Интерфейс
SPI
Цифровой
ввод
Микроконтроллер
Реле
Цифровой
вывод
Радиомодуль
Wi-Fi
Глава 10
516
Веб-клиент
GET
index.html
image.jpg
Поставщик услуг
веб-хостинга
OK
index.html,
image.jpg
Сервер HTTP
Подписка MQTT: все
Публикация MQTT:
setPoint,
mode, update
Брокер MQTT
Передача файла по FTP
Публикация MQTT:
все
Микроконтроллер
Датчик
температуры
Считываем
показания датчика
Подписка MQTT:
setPoint, on,
mode, update
Камера
Включаем или
Реле
выключаем реле
Рис. 10.4. Блок-схема взаимодействия системы наблюдения за котом и управления кондиционером и собственно контроллера управления кондиционером
= -
-
p5.js — %
FTP
" - . =
, "
MKR1000
ESP8266. *
node.js,
% - , —
- , .
Протокол MQTT
7 -
, (
3),
" IP- . 0
. & $
- " - , $
— MQTT2.
2
MQTT, Message Queue Telemetry Transport —
" .
Сети мобильной телефонной связи и физический мир
X "
"
MQTT (http://mqtt.org)
,
. #
MQTT . =
3
, # 4.
X
" ,
" . 0
" . / , MQTT
5.
* , $
%
(airConditioner) ,
airConditioner/ " :
?
airConditioner/on — :
;
?
airConditioner/mode —
:
, , ;
?
airConditioner/temperature — "
;
?
airConditioner/setPoint —
,
.
"
/temperature, -
" /setPoint,
, " /mode,
.
,
- "
. * MQTT
.
3
4
5
0 . topics.
0 . messages.
0 . Publish & Subscribe, PubSub.
517
* ,
,
"
,
,
$
. $
" :
?
airConditioner/connected —
;
?
airConditioner/update — -
"
.
Схема системы
; ,
" ,
.
. 10.5, — . 10.6. & ,
, —
$ , .
9 % $ , .
% ,
,
,
.
( . 10.7). 0"
. 10.8.
0 $
, .
0 .
,
" , $
$ , ,
. 0
$ . ;
""
$ . X
" % ,
5 &.
Глава 10
518
«Плюс»
питающего тока
«Плюс»
питающего тока
Выходной
сигнал
Датчик
температуры
DHT11
Модуль
микроконтроллера
10 КОм
D4
N.C.
D5
Общий
Общий
100 Ом
Управляющий
сигнал
Э
Общий (Эмиттер)
В электросеть
Реле
К
(Коллектор)
Оптоизолятор
Розетка
для кондиционера
Рис. 10.5. Принципиальная схема системы удаленного управления кондиционером
Рис. 10.6. Монтажная схема системы удаленного управления
кондиционером, собранная на микроконтроллере MKR1000
A B
C D E
F
G H
I
J
1
5
5
10
10
15
15
20
20
25
25
LOAD
1
30
A B
C D E
F
G H
I
J
Gnd Cntl. 5V
30
Сети мобильной телефонной связи и физический мир
519
9
$
, $ —
$ —
,
. 4
,
,
PowerSwitch Tail 240 & (www.powerswitchtail.com),
Adafruit
SparkFun. , $
WeMo,
9.
*
, SparkFun % PowerSwitch Tail. &
, ,
LOAD (* )
.
* . 10.7
. &
« », +5 & . =
$ , . 10.8,
* # (Nathan Seidle)
www.sparkfun.com/tutorials/119.
' $ ,
%
"
. 0 % -
( )
. 3
( ,
)
. ;
, +5 &, $ . 3 « » $
.
Рис. 10.7. Контакты платы реле подключены к разрыву в
одной из жил кабеля питания
Рис. 10.8. Блок розеток, включающий реле, провода управления которым подсоединены к модулю Arduino, — так
обеспечивается безопасная работа с питанием от электросети. Можно было бы также воспользоваться модулем
PowerSwitch Tail
Глава 10
520
, . = $
D1
«7» (Blink) 1 —
.
0 % $ . 4 ,
$ , $ — "
. _% $ . $
,
. 2
, , , ,
" . X $ ,
$ , ,
% .
Пишем код для этого проекта
Назовем скетч для этого проекта AirConditionerArduino. Так как скетч весьма сложный, мы будем
создавать его по частям.
Проверяем работу датчика температуры
&
DHT11. /
,
, , . &
OneWire Dallas
Semiconductors. =
7
Arduino
DHT Sensor Library
Adafruit Unified Sensor
Adafruit.
/*
MQTT #
: Arduino
*/
#include <DHT.h> // ' DHT
const int sensorPin = 4; // ^
//
DHT dht(sensorPin, DHT11); // Z$ R$
// DHT
void setup() {
Serial.begin(9600); // ' $
dht.begin(); //
}
& DHT,
, "
, loop() :
& loop()
$ . [
readTemperature() Z ,
[ $
true — readTemperature(true).
& %
Z :
void loop() {
float temperature = dht.readTemperature(); // Z
// $
float humidity = dht.readHumidity(); // Z
// $
Serial.print(temperature);
// +
// $ R
Serial.print("°C ,");
Serial.print(humidity);
Serial.println("% rH");
}
Сети мобильной телефонной связи и физический мир
521
Управляем реле
X % ,
,
(
,
,
% ). & ,
. ;
,
" ,
setup()
:
& setup()
:
& loop() ,
,
"
". 4 ,
$ " , "
" .
"
: , , . &
.
* ,
deviceIsOn.
9
" ,
,
loop() 2000 :
/*
MQTT #
: Arduino
*/
#include <DHT.h> // ' DHT
boolean deviceIsOn = false; // 9
int temperature = 0; // C
int lastTemperature = 0; // $
//
int setPoint = 18; // $
int mode = 3; // ! — , ,
// (1, 2, 3)
boolean deviceConnected = false; //
//
const int sensorPin = 4; // ^
//
const int relayPin = 5; //
DHT dht(sensorPin, DHT11); // Z$ R$ DHT
void setup() {
Serial.begin(9600); // ' $
dht.begin(); //
temperature = dht.readTemperature(); //
//
pinMode(relayPin, OUTPUT); // 7
//
// !
}
void loop() {
temperature = dht.readTemperature(); // Z
// $
if (abs(temperature - lastTemperature) > 0) { // $ ,
//
Serial.print("C . C : ");
Serial.println(temperature);
}
lastTemperature = temperature; // 9
//
if (mode == 3) { // !
checkThermostat();
}
digitalWrite(relayPin, deviceIsOn); //
//
delay(2000);
}
Глава 10
522
& : checkThermostat().
. 4 % ,
,
,
% — :
0
void checkThermostat() {
if (temperature > setPoint) {
if (!deviceIsOn) {
deviceIsOn = true; //
}
}
if (setPoint > temperature) {
if (deviceIsOn) {
deviceIsOn = false; //
}
}
}
$ , ,
.
— . X % ,
,
MQTT.
$ $ ( )
setPoint. % , " ,
, .
; , —
, ,
,
-
= MQTT Arduino. 7
Arduino
,
MQTT =$ q (MQTT
by Joel Gaehwiler). X $
Arduino "
7 . 4
$ , : https://github.com/256dpi/
arduino-mqtt.
Добавляем учетные данные
,
.
= $ Arduino
config.h,
$ ,
D | ! &.
(SSID)
, $
MQTT. &
MQTT. 2 ,
" % , % $ ,
, MQTT:
/*
MQTT #
: Arduino
*/
char ssid[] = " _ "; // \ (SSID)
char password[] = " "; // -
// '
char mqttUser[] = "airConditioner"; // \ $
// MQTT
char mqttPass[] = "_mqtt"; // $ MQTT
Сети мобильной телефонной связи и физический мир
523
Подключаемся к сети
, MQTT
Arduino. 7 Arduino
, MQTT
=$ q
(MQTT by Joel Gaehwiler). X $
Arduino " 7 .
4
$ , : https://
github.com/256dpi/arduino-mqtt.
+,
(
% ):
/*
MQTT #
: Arduino
*/
#include <DHT.h> // ' DHT
#include <SPI.h> // $
SPI
#include <WiFi101.h> // $
WiFi101
//#include <ESP8266WiFi.h> //
ESP8266
//
#
#include <MQTTClient.h> // $
MQTT
Client
#include "config.h" // $
WiFiClient netSocket; //
MQTTClient client; // MQTT
char serverAddress[] = "192.168.0.15"; // MQTT.
// `! # IP- ,
//
boolean deviceIsOn = false;
// ... ' $ $
& setup()
Wi-Fi,
" . ;
config.h:
void setup() {
// connect to WiFi
Serial.begin(9600); // \ # $ '
// $
// $
Wi-Fi,
while ( WiFi.status() != WL_CONNECTED) {
Serial.print("$
: ");
Serial.println(ssid); // # (SSID)
WiFi.begin(ssid, password); //
//
delay(2000);
}
// $ ,
#
// :
IPAddress ip = WiFi.localIP();
Serial.print("IP- : ");
Serial.println(ip);
//
// $
dht.begin();
temperature = dht.readTemperature();
& setup() MQTT client.begin(),
mqttConnect(), :
pinMode(relayPin, OUTPUT); // %
//
// .
// %
MQTT
client.begin(serverAddress, netSocket);
mqttConnect();
}
Глава 10
524
& loop()
,
,
, ,
:
void loop() {
client.loop(); // $
if (!client.connected()) { // *
// ,
Serial.println("7 ");
deviceConnected = false;
mqttConnect(); // $
}
-
$
. = $ , "
,
.
0 loop()
:
temperature = dht.readTemperature(); // Z $
//
if (abs(temperature - lastTemperature) > 0) { // ,
// $
Serial.print(" $ .
: ");
Serial.println(temperature);
client.publish("airConditioner/temperature",
String(temperature));
}
lastTemperature = temperature; // Z- '
// '
if (mode == 3) { //
checkThermostat();
}
digitalWrite(relayPin, deviceIsOn); // +'
// '
}
& checkThermostat()
client.publish()
void checkThermostat() {
if (temperature > setPoint) {
if (!deviceIsOn) {
deviceIsOn = true; // +'
client.publish("airConditioner/on",
String(deviceIsOn));
}
}
if (setPoint > temperature) {
if (deviceIsOn) {
deviceIsOn = false; // +'
client.publish("airConditioner/on",
String(deviceIsOn));
}
}
}
.
MQTT
, " ,
$ "
.publish():
;
mqttConnect(),
.
&
"
%
. 3 %
,
,
publishAll(), " :
// $
void mqttConnect() {
if (!client.connect("airConditioner", mqttUser, mqttPass)) {
return; //
}
Serial.println("$ ");
deviceConnected = true;
// $ ,
//
client.subscribe("airConditioner/on");
client.subscribe("airConditioner/setPoint");
client.subscribe("airConditioner/mode");
client.subscribe("airConditioner/update");
publishAll();
}
Сети мобильной телефонной связи и физический мир
[ publishAll()
" /
.
update,
0
:
* ,
" "
MQTT. #
, $
messageReceived()
,
topic ( ) message ( " ). *
. *
$ / " ,
$
: deviceName (
) property ( ).
4
update, " all, publishAll().
4
"
(int) "
. $ checkThermostat()
.
on setPoint,
3
(int)
" . [ loop()
mode
, checkThermostat().
mode,
/ % messageReceived() :
525
// $
void publishAll() {
client.publish("airConditioner/on", String(deviceIsOn));
client.publish("airConditioner/temperature",
String(temperature));
client.publish("airConditioner/setPoint",
String(setPoint));
client.publish("airConditioner/mode", String(mode));
client.publish("airConditioner/connected",
String(deviceConnected));
}
void messageReceived(String topic, String payload, char
bytes[], unsigned int length) {
Serial.println(topic);
Serial.println(payload);
// parse the topic
int divider = topic.indexOf('/');
String deviceName = topic.substring(0, divider);
String property = topic.substring(divider + 1);
// * ,
if (property == "update" && payload == "all") {
publishAll();
}
if (property == "on") {
deviceIsOn = payload.toInt();
}
// * setPoint,
if (property == "setPoint") {
setPoint = payload.toInt();
}
// * mode,
// — , ,
// !
if (property == "mode") {
mode = payload.toInt();
switch (mode) { // $ mode
case 1: //
digitalWrite(relayPin, LOW); //
// ( )
deviceIsOn = false;
client.publish("airConditioner/on", String(deviceIsOn));
break;
case 2: //
digitalWrite(relayPin, HIGH); //
// ( )
deviceIsOn = true;
client.publish("airConditioner/on", String(deviceIsOn));
break;
case 3: // !
checkThermostat(); // $
break;
}
}
} // 7 messageReceived()
Глава 10
526
+
$
" - ,
, , -
.
X Mosquitto %
Linux,
- Raspian,
" apt,
$ 9:
$ sudo apt-get install mosquitto
Брокер MQTT Mosquitto
& ,
MQTT,
Mosquitto.
/ , macOS, Windows
Linux. #
http://mosquitto.org. 2 $
" - .
& Windows http://mosquitto.org. *
,
( . readme ). + $ ,
" % Raspberry Pi.
X
%
macOS
" Homebrew — $ . = Homebrew
- https://brew.sh,
" :
$ /usr/bin/ruby -e "$(curl -fsSL
https://raw.githubusercontent.com/
Homebrew/install/master/install)"
X Homebrew,
Mosquitto :
$ brew install mosquitto
7
$PATH. = $
:
$sudo nano /etc/paths
%
: /usr/local/sbin/ ,
.
X Mosquitto, %
. X IP-
, ,
serverAddress "
.
> Mosquitto
" :
$ mosquitto
& $
" :
-
1489964660: mosquitto version 1.4.11
(build date 2017-03-14
19:27:44+0000) starting
1489964660: Using default config.
1489964660: Opening ipv6 listen
socket on port 1883.
1489964660: Opening ipv4 listen
socket on port 1883.
9
"
% <Ctrl>+<C>.
4 Mosquitto
" % , $ ,
.
& %
( .
! «|
»)
.
4 , "
,
, ,
Сети мобильной телефонной связи и физический мир
Mosquitto, " " :
New client connected from 192.168.0.14
as airConditioner (c1, k60, usomeone)
( ' 192.168.0.14
airConditioner (c1, k60, usomeone)
/ , Mosquitto
, % . +
IP-
" .
7 Mosquitto , - ( . . 10.4).
& - - ,
,
% $,
. X Mosquitto ,
,
.
+, , Mosquitto, $
catCamDeux, —
mq-local.conf "
:
527
port 1883
listener 8888
protocol websockets
password_file mq-pwds
log_type all
allow_anonymous false
# $ ,
Mosquitto mq-pwds : airConditioner — webClient — - ,
. [
- :
$ mosquitto_passwd -c mq-pwds
_$
= " , -
.
. & mqpwds , % .
# , - - . = $
p5.js public,
httpServer.js.
Завершение работы демонов и других процессов
* Linux
Mosquitto ,
,
. 4
Mosquitto
" % Error: Address already
in use, $ , , % .
= $
— ,
" .
"
" :
$ ps -u
_$
_$
Linux. & " :
PID TTY
744 ?
746 pts/0
1461 pts/0
1902 pts/0
TIME
00:00:00
00:00:01
00:00:01
00:00:00
CMD
sshd
bash
mosquitto
ps
"
"
ps -e. + , $
.
Глава 10
528
2 %
" :
$ kill _#
_#
, %.
& " "
Mosquitto
1461.
0
, -
2 ( Proto),
( Local
Address),
( Foreign
Address)
,
( State),
, "
( PID/Program name). *
" $ :
tcp 0 0 *:1883 ... LISTEN 844/mosquitto
+ , Mosquitto % 1883 844.
# , % $ " :
$ sudo kill 844
, . * - —
Mosquitto %
1883,
, netstat:
$ sudo netstat -atnp
2 " : "
(-a), TCP (-t), IP- (-n)
(-p). & " :
; , " ps kill
, ,
% . 4 ,
" ,
, ps
grep:
$ sudo ps -e | grep 'mosquitto'
0 : ps kill —
.
, man ps
man kill
. *
% ,
, $
.
* sudo ,
"
, ,
%
.
Создаем веб-сервер
*% -
. X , ,
" npm express,
httpServer.js
" :
/*
Z - %
: node.js
*/
var express = require('express'); // '
// express
var server = express(); // Z$ " server,
// $ express
Сети мобильной телефонной связи и физический мир
# " - , MQTT.
529
server.listen(8080); // $ HTTP
server.use('/',express.static('public')); // ,
// ' %
Выполняем разметку
= - — mqqt.js, :
https://unpkg.com/mqtt@2.5.0/
dist/mqtt.min.js. #
libraries p5.js, index.html, <head>
% . 0
:
<script
<script
<script
<script
<script
src="libraries/p5.js"></script>
src="libraries/p5.dom.js"></script>
src="libraries/p5.sound.js"></script>
src="libraries/mqtt.min.js"></script>
src="sketch.js"></script>
Создаем веб-клиент
&
-
,
Arduino.
clientOptions
MQTT. +
,
:
/*
device
,
:
var device = { // Z
on: false,
temperature: 24,
setPoint: 18,
mode: 1,
connected: false,
name: 'airConditioner'
};
;
$
.
2
$
HTML: img —
, timeStamp —
, deviceStatus —
,
connectButton —
,
:
+- % mqtt #
: p5.js
*/
var clientOptions = { // MQTT
port: 8888,
host: self.location.hostname, // IP- -
// '
username: 'webClient', // \ $ MQTT
password: '_mqtt', // MQTT
};
var
var
var
var
var
var
client; // mqtt
webConnected = false; // Z '
img; // \$ $ -
timeStamp; // $
timeStamp
deviceStatus; // R #
connectButton, modeControl; // + "
// #
530
Глава 10
& setup() " $ . = $
%
touchEnded(), . 3
changed(),
:
function setup() {
frameRate(0.033); // $ 30
noCanvas(); // $
deviceStatus = createSpan(device.name); // & % #
//
deviceStatus.position(10, 10);
connectButton = createButton('Connect'); // '
connectButton.position(10, 100);
connectButton.touchEnded(connectMe);
setPointSlider = createSlider(10, 40, 21, 1); // $
// $ setPoint
setPointSlider.position(180, 100);
setPointSlider.touchEnded(changeSetpoint);
var sliderLabel = createSpan('Setpoint: ');
sliderLabel.position(100,100);
modeControl = createRadio(); //
// '/'
modeControl.option('off', 1);
modeControl.option('on', 2);
modeControl.option('auto', 3);
modeControl.style('width', '65px');
modeControl.value(device.mode);
modeControl.position(220, 10);
modeControl.changed(changeMode);
timeStamp = createSpan(new Date()); //
// $
timeStamp.position(10, 160);
img = createImg('./image.jpg?');
img.position(10, 180);
}
[ draw() $ . +
,
, $
3,
:
function draw() {
var now = new Date(); // '
img.elt.src = './image.jpg?' + now; //
// $
timeStamp.html(now); // $
}
&
update(),
,
MQTT :
//
$
// $
function changeSetpoint() {
update('setPoint', setPointSlider.value()); //
// $
}
//
'
function changeMode() {
update('mode', modeControl.value()); //
// $
}
Сети мобильной телефонной связи и физический мир
531
&
connectMe()
- MQTT.
4 (
if), ,
$
mqtt.connect()
,
. [ mqtt.connect()
announce(), .
" .
( else) client.end():
// connect button event handler:
function connectMe() {
if (!webConnected) { // '
client = mqtt.connect(clientOptions); // '
client.on('connect', announce); //
// '
client.on('message', readMessages); //
// -
} else {
client.end(quit); // '
}
}
&
announce() mqtt.
connect()
- updateInterface(),
. ; update()
/update,
:
// '
"
function announce() {
connectButton.html(‘Disconnect’); //
// '
webConnected = client.connected; //
// '
// -
#
for (property in device) {
client.subscribe(device.name + '/' + property); //
// }
updateInterface(); //
% $
update('update', 'all');
}
[ quit()
client.end(). 0 ,
webConnected:
// '
'
function quit() {
connectButton.html('Connect'); //
// '
webConnected = client.connected;
}
[ update()
" :
//
- -
function update(property, value) {
device[property] = value; //
var topic = String(property); // $
// $ % #
.publish()
var message = String(value);
if (webConnected) { //
'
client.publish(device.name + '/' + topic, message);
}
}
Глава 10
532
" , " , " readMessages(). /
,
. 2 "
" :
temperature, mode setPoint —
,
—
. &
readMessages() $
updateInterface():
// Z - MQTT
function readMessages(topic, message) {
topic = topic.toString(); // $
var strings = topic.split('/'); // $
//
var origin = strings[0]; // \
//
var property = strings[1]; // — .
if (property === 'temperature' || //
// $
property ==='mode' ||
//
property === 'setPoint') {
device[property] = Number(message);
} else { // + —
// & $ :
device[property] = (String(message) == '1');
}
updateInterface(); //
% $
}
+, , updateInterface()
$ ,
:
// # R $ %
function updateInterface() {
var onState; // Z ' #
if (device.on) { // ' (on === true)
onState = 'on'; // $ true 'on'
} else {
onState = 'off'; // $ false 'off'
}
//
, '
$
// :
deviceStatus.html(device.name
+ '<br>' + onState
+ '<br>temperature: ' + device.temperature
+ '<br> thermostat setpoint: ' + device.setPoint);
setPointSlider.value(device.setPoint); //
// $ $
modeControl.value(device.mode); //
// '
}
& .
;
: ,
HTTP - . '
" , Mosquitto
:
$ mosquitto -c mq-local.conf &
# , . ,
mq-local.conf,
.
* %,
,
HTTP:
$ node httpServer.js
* $ "
%
" Mosquitto. 2 %
Сети мобильной телефонной связи и физический мир
, , % <Ctrl>+<C>. 3 %
Mosquitto kill,
! «| ».
2
, ,
-
: http://.:8080 — ,
. 10.9, .
Mosquitto " Connect (
, . 10.9 Disconnect ).
& " ":
1490449929: Config loaded from mq-local.conf.
1490449929: Opening websockets listen socket
on port 8888.
1490449929: Opening ipv4 listen socket on port
1883.
1490449929: Opening ipv6 listen socket on port
1883.
1490449930: New client connected from
74.72.23.0 as mqttjs_
ce14eb0b (c1, k10000, u'webClient').
1490449930: Sending CONNACK to mqttjs_ce14eb0b
(0, 0)
1490449930: Received SUBSCRIBE from mqttjs_
ce14eb0b
1490449930: airConditioner/on (QoS 0)
1490449930: mqttjs_ce14eb0b 0 airConditioner/on
1490449930: airConditioner/temperature (QoS 0)
...
1490449948: New connection from 74.72.23.0 on
port 1883.
1490449948: New client connected from
74.71.6.0 as airConditioner (c1, k60,
u'airConditioner').
1490449948: Sending CONNACK to airConditioner
(0, 0)
1490449948: Received SUBSCRIBE from airConditioner
533
1490449948: airConditioner/on (QoS 0)
1490449948: airConditioner 0 airConditioner/on
/ ,
" . +
- ,
- $ .
Рис. 10.9. Фрагмент снимка с экрана результатов исполнения скетча удаленного управления кондиционером, сделанный на смартфоне с ОС Android
Глава 10
534
Сетевые камеры
; , , . / %
: IP-
.
+
,
. 2
$60 %
Wi-Fi,
.
$ — D-Link DCS-930L — % $70. 0
, $
D-Link .
, %
FTP6 SFTP7.
& , $
DCS-5222L DCS-960L
D-Link.
* " .
, ,
Ethernet
. *
$
Wi-Fi,
,
,
.
, ,
FTP SFTP. # "
$
"
. ~
, ,
6
7
FTP, File Transfer Protocol —
SFTP, Secure FTP —
FTP.
.
" ,
"
- . &
SFTP, , $ %
$
.
*
public % ,
HTML JavaScript
p5.js. &
$
.
IP-
,
Pi Cam Raspberry Pi. Raspberry
Pi Zero W Pi Cam
,
, $
%
.
+
: www.raspberrypi.org/products. Adafruit $ Pi Zero
Camera Pack (www.adafruit.com/product/3414)
Raspberry Pi Zero W,
Pi Cam .
Raspberry Pi
Pi Cam
.
IP-камера на Raspberry Pi
# IP-
Raspberry Pi
$: $ %
HTTP — , $
3. 3
$ Raspberry
Pi,
.
7 httpServer.js, " % - ,
Сети мобильной телефонной связи и физический мир
" . / , $
3.
2 Pi Cam Raspberry Pi
, :
535
& Interface Options | Camera
. $
Raspberry Pi piCam.sh
. # , $ ,
.
$ sudo raspi-config
Код для загрузки изображения
'
httpServer.js ,
multer, 3:
$ npm install multer
; .
multer,
catServer.js 3.
2
% .
=
" diskStorage() multer. & , public
:
/*
Z - % node.js, '
$ %
Z - public.
: node.js
*/
var express = require('express'); // '
// express
var server = express(); // Z$ " server,
// $ express
var multer = require('multer'); // $ ! $N
//
// %
!
var imgStore = multer.diskStorage({
destination: __dirname + '/public/', // $
//
filename: saveUpload // Q
//
});
=
$ multer
image ( ).
POST
, image :
//
,
//
var upload = multer({storage: imgStore});
// %
: image
// (7 !
! ! ):
var type = upload.single('image');
&
POST ,
getUpload():
// Q
//
function getUpload(request, response) {
//
#
var fileInfo = JSON.stringify(request.file);
console.log(fileInfo);
response.end( fileInfo + '\n');
}
Глава 10
536
;
saveUpload(),
:
// Q
function saveUpload(request, file, save) {
// multer,
save(null,file.originalname);
}
* ,
POST:
server.listen(8080); // $ HTTP
server.use('/',express.static('public')); // ,
//
%
server.post('/upload', type, getUpload); // %!
//
Автоматизируем захват и загрузку изображений
/ raspistill,
"
,
image.jpg, -
" curl:
while [ : ] # #
do
# -
$ , 100 ,
# $ 400-300, 80%, $
raspistill -t 100 -w 400 -h 300 -q 80 -o image.jpg -n
# Z ' curl $ $- $
curl -F "image=@image.jpg" 'http://example.com:8080/
upload'
# \$ $ example.com IP-
--
# +
$ $
echo "\$ $ "
# $ 30
sleep 30
done
# , " chmod %
:
$ chmod u+x piCam.sh
7 " ( Raspberry Pi)
. [
" :
$ ./piCam.sh
+ " 30
. "
-
- ,
. 10.9.
+
,
. 7
"
HTML5.
, $
. +
,
, ,
, HTTP. 7
$
% " .
Сети мобильной телефонной связи и физический мир
537
Проект 30
Звоним термостату
Мы вложили в только что созданный проект много труда. К счастью, он не пропадет даром, и мы
воспользуемся его результатами в этом проекте. Оборудование для него будет то же самое, что и
для предыдущего, но мы внесем в программное обеспечение некоторые изменения, чтобы создать интерфейс, позволяющий нам позвонить термостату по телефону, прослушать голосовое
сообщение о температуре в квартире и статусе кондиционера, а также задать пороговое значение термостата с кнопочной панели телефона.
7 _ —
, , — ,
- .
«* $ ! — . — *
-,
% ?» & $
—
,
" .
&
IP-
%,
" - .
#
— Google
Voice Asterisk —
:
"
(;#0) +
. /
SIP8
,
$
. ;, SIP
, " , % " . . +
SIP
,
, . 3
,
,
.
, $
8
SIP, Session Initiation Protocol —
.
Требуемые компоненты
2 %
29.
X Twilio.
; .
21- .
,
$
SIP,
"
:
.
4
,
, "
SIP. 0 ,
,
, , " .
— —
HTTP
GET POST,
.
,
" ,
. 4
SIP
, ( ,
: «= %! = %! `
!» — $ ), % ,
.
Глава 10
538
& $
SIP Twilio
" . Twilio
VoIP9 —
,
-
. 0 $
,
, $
, .
. * $
,
,
,
$ .
* $ Twilio
SMS . X ,
%
, : https://support.
twilio.com/hc/en-us/articles/223183068-Twiliointernational-phone-number-availability-andtheir-capabilities. ,
,
;#0 "
+
, — , . /
$
,
. 4 VoIP SIP,
«Asterisk: The Future of Telephony»10 O’Reilly, : = & 7
(Jim Van Meggelen), = # (Jared Smith)
_ 7
(Leif Madsen).
Каким стандартом пользоваться?
, SIP VoIP
" , .
0 $
"
" .
9
VoIP, Voice over IP — IP- ,
, ,
- .
10
«Asterisk. >" », https://www.ozon.ru/
context/detail/id/4878006/.
&
, " ,
:
, " SMS
—
. *
"
API
. * ,
Twilio (
$ )
— Tropo, Google Voice
, "
$
.
#
"
:
?
?
?
?
?
?
,
?
-
?
`
Twilio $
-
TwiML,
,
Twilio
,
, — , node.js: "
GET POST. # Twilio
node.js,
%
, $
. Twilio
%
. +
,
, — , , , , " %
" .
= $ - www.twilio.com.
,
Сети мобильной телефонной связи и физический мир
Twilio. , , ,
" . ,
.
*
(URL)
Arduino " .
* ,
IP-
%
63.118.45.189,
$
http://63.118.45.189:8080/voice.xml.
+, Twilio
( . 10.10).
'
, "
All Products and Services (& ), — Phone Numbers.
,
(Buy a Number).
539
/
% % Twilio,
HTTP IP . ; "
. ¥
$
Phone Numbers, —
Verified Caller ID ,
Twilio.
= CONFIGURE WITH — Webhooks/TwiML.
; , "
Twilio POST
TwiML . 0
A CALL COMES IN
. # % $ , XML
,
.
Рис. 10.10. Панель управления Twilio. Введите адрес (URL) вашего сервера Arduino в поле A CALL COMES IN
Глава 10
540
Краткое введение в XML
}! ! # ! XML11 -
. 0
% . >
$
,
< >. ; %,
,
. /
$ . * , $ <body>
$ <paragraph>:
<body>
<p>
</body>
%</p>
& , " " , $ . /, , ,
, %
.
$ "
" , :
< $ ="10" />
# , , . & "
$, $
10 . # " $
.
4 , $
HTML, . ` XML
HTML
,
XML "
.
Схема разметки TwiML
# Twilio — TwiML — Twilio
XML. ,
, " Twilio.
11
XML, eXtensible Markup Language —
.
%
# $ SMS- " . # $ :
? q $ :
• <Dial>
<Client>
<Conference>
<Number>
<Queue>
<Sip>
• <Enqueue>
• <Gather>
• <Hangup>
• <Leave>
• <Pause>
• <Play>
• <Record>
• <Redirect>
• <Reject>
• <Say>
• <Sms>
? SMS-$ :
• <Sms>
• <Redirect>
2 $ $ -
Twilio (www.twilio.com/docs/api/twiml), ,
, % .
= $ $
<Response>. & $ $ $ <Gather> — . /
<Gather> TwiML-
HTML, $ action
method,
$ ,
. 7 $
<Say>, , .
/ XML %
- , $
HTTP
Сети мобильной телефонной связи и физический мир
node.js,
" . &
$ .
& , node.js — mqtt. /
541
, . X
, ,
" npm:
$ npm install mqtt
Выполняем разметку
= $
TwiML.
,
.
,
,
. #
voice.xml public
" (
,
% , . /
% ,
% ):
, $
,
" :
#temperature, #setPoint #on.
# ,
$ HTML.
~ % (#)
" . 7 , $ ,
.
&
TwiML —
set-temp.xml — public (
,
, ,
% ,
). & , , $
,
<Gather> .
+ , $
,
, :
<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Gather numDigits="2" timeout="5" action="set-temp.xml"
method="POST">
<Say>
The current temperature is
#temperature
degrees Celsius.
[C :
#temperature
.]
The thermostat is set to #setPoint degrees Celsius.
[C
#setPoint .]
The air conditioner is set to #on.
[K ! — .]
If you would like to change the thermostat,
please enter a new setting.
[*
,
.]
If you are satisfied, please hang up.
[*
, .]
</Say>
</Gather>
<Say>
You didn't give a new setting,
so the thermostat will remain at #setPoint degrees. Goodbye!
[
, #
#setPoint . !]
</Say>
</Response>
<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Say>
The thermostat is now set to #setPoint degrees.
[C
#setPoint .]
The temperature is #temperature degrees.
[C : #temperature .]
Thank you. Goodbye.
[ !]
</Say>
<Pause length="2"/>
<Hangup/>
</Response>
Глава 10
542
3 " :
Twilio,
POST voice.xml. #
Twilio. #
TwiML,
,
% . 4
, "
<Gather>.
&
POST, $
set-temp.xml. #
MQTT,
Twilio XML,
. + , % . & %
,
$
, %
.
,
=
Twilio. & ,
:
POST XML, $
,
,
MQTT " .
Модифицируем сервер
0
http "
,
% . &
fs (
) mqtt. 2
clientOpitons device,
- . * ,
-
localhost. / ,
node.js
MQTT ,
Mosquitto:
Server.js
/*
Z - %
TwiML
MQTT
: node.js
*/
var express = require('express'); // '
// express
var server = express(); // Z$ " server,
// $ express
var multer = require('multer'); //
// $ $ %
var fs = require(‘fs’); // $
//
var mqtt = require('mqtt'); // $
// MQTT Client
var clientOptions = { // $ MQTT
port: 1883,
host: 'localhost',
username: 'xmlClient',
password: 'something',
keepalive: 10000
};
var device = { // 9
on: false,
temperature: 24,
setPoint: 18,
mode: 1,
connected: false,
name: 'airConditioner'
};
Сети мобильной телефонной связи и физический мир
543
&
POST XML. saveUpload()
POST
postFile() $ . /
output. 2 "
JavaScript
% (#)
device. 0
Twilio:
function postFile(request, response) {
var fileName = __dirname + '/public/' + request.path;
var data = fs.readFileSync(fileName);
output = String(data);
for (property in device) {
var searchTerm = new RegExp('#'+ property, 'g');
var value = String(device[property]);
output = output.replace(searchTerm, value);
}
response.writeHead(200, {'Content-Type': 'text/xml'});
response.end(output);
}
,
MQTT " . = $
"
announce() readMessages() - :
function announce() {
for (property in device) {
client.subscribe(device.name + '/' + property);
// $
}
}
&
POST
XML, "
postFile()
. ;
mqtt.connect()
" " :
server.listen(8080); // $ HTTP
server.use('/',express.static('public')); // ,
// ' %
server.post('/upload', type, getUpload); // %
//
server.post('/*.xml', postFile);
client = mqtt.connect(clientOptions); // $
client.on('connect', announce); // N
//
client.on('message', readMessages); // N
//
function readMessages(topic, message) {
topic = topic.toString(); // $
var strings = topic.split('/'); // K
//
var origin = strings[0]; //
//
var property = strings[1]; // — .
if (property === 'temperature' || // !
//
property ==='mode' ||
//
property === 'setPoint') {
device[property] = Number(message);
} else { // —
//
device[property] = (String(message) == 'true');
}
}
/ %
.
Глава 10
544
&
,
,
Twilio. # ,
% . 4 , % ,
.
2 , % . 2
MQTT - , .
, ! ,
$ % ,
. & , , — $
TwiML
HTTP
POST
MQTT, . , " %
API node.js,
TwiML,
"
% ,
.
Интерфейсы на основе текстовых сообщений
Обмен текстовыми сообщениями быстро стал одним из наиболее распространенных применений мобильных телефонов. Многие считают текстовые сообщения не столь раздражающими
вторжениями в их личное пространство, как телефонные звонки. Текстовые сообщения позволяют быстро передать информацию, не тратя времени на разного рода предварительные разговоры. Кроме того, сообщения электронной почты легко посылать как SMS и наоборот — эта
возможность не зависит от какой-либо конкретной платформы. Все, что для этого нужно, — это
мобильный телефон и учетная запись электронной почты. А для ситуаций, когда требуется немедленное и малозаметное извещение, или для предоставления простой инструкции, SMS-ка —
самое то.
# SMS
. + ,
"
,
. /
" , "
"
" . * SMS
, % . #" SMS
160 , $ 160 % .
% SMSemail, $ , " SMS
". =
$ " ,
,
$ . & % ,
" MMS12
" SMS.
" —
% " . 3 %
SMS- $ — $
$
, @ $
. =
" SMS $
#3,
4 :
12
MMS, Multimedia Messaging Service —
" .
Сети мобильной телефонной связи и физический мир
? AT&T: phonenumber@txt.att.net;
? T-Mobile: phonenumber@tmomail.net;
? Virgin Mobile: phonenumber@vmobl.com;
? Sprint: phonenumber@messaging.sprintpcs.com;
? Verizon: phonenumber@vtext.com;
? Bell Canada: phonenumber@txt.bellmobility.ca;
? Telenor Norway: phonenumber@mobilpost.no;
? Telia Denmark: phonenumber@gsm1800.telia.dk;
? Swisscom: phonenumber@bluewin.ch;
? T-Mobile Austria: phonenumber@sms.t-mobile.at;
? T-Mobile Germany: phonenumber@t-d1-sms.de;
? T-Mobile UK: phonenumber@t-mobile.uk.net.
545
* %
- www.emailtextmessages.com
( ,
$ ). & , ,
" (
phonenumber), .
,
$
. [
E.164 +nnnnnnnnnnnnnnn. >
n ,
12 15, ,
— $ . ;
,
,
#3 $ .
$
%
.
Отправка SMS через Twilio
# "
node.js
HTTPS,
Twilio " SMS. /
% SMS
. #
TwilioSms, — :
smsClient.js twilioCreds.js. [
twilioCreds.js
, "
API Twilio,
. & $
Twilio. #
"
(
%
):
module.exports = {
apiKey: 'Axxxxx', // ' % API Twilio
auth: '1xxx', // % # Twilio
number: '+15555555555' // ^ % Twilio
}
Защитите этот сценарий
& " $ % "
%
. 4
- -
,
.
Глава 10
546
Сценарий для отправки SMS
'
SMS
Twilio,
HTTPS POST
API
Twilio. &
node.js
https querystring.
JSON HTTP,
twilioCreds.
js. * :
/*
[ " SMS
— "
: To (),
From (0) Body (; ,
" ). ;
"
%
1600 . *
E.164.
postData
"
:
var message = { // SMS
To: recipient,
From: creds.number,
Body:' !'
}
HTTPS
HTTP,
.
# Twilio
API
. ; "
, querystring:
// $ HTTPS
var options = {
host: 'api.twilio.com',
auth: creds.apiKey + ':' + creds.auth,
port: 443,
path: '/2010-04-01/Accounts/' + creds.apiKey + '/
Messages',
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
‘Content-Length’: postData.length
}
};
, HTTPS "
confirm()
. /
% : data
end. 0
, $ gather() $
// # $ $
function confirm(response) {
var result = ''; // Z -
function gather (data) { // response 'data' callback
// function
result += data;
}
HTTPS % API
: node.js
SMS Twilio
*/
var https = require('https'); // ' https
var querystring = require('querystring'); // '
// querystring
var creds = require('./twilioCreds.js'); // ' %
//
Twilio
var recipient = process.argv[2]; // ^ % $
// $
// $ $ HTTP
var postData = querystring.stringify(message);
function printResult () { // # $
// end
console.log(result);
}
Сети мобильной телефонной связи и физический мир
, printResult()
$ :
547
response.on('data', gather); // Z
// # $
response.on('end',printResult); // +
// $ R
}
* ,
HTTPS. ; , end() % :
#
"
:
// $ HTTPS
var request = https.request(options, confirm); // ^
// $
request.write(postData); //
request.end(); // $
$ node smsClient.js +15555555555
2 $ ,
% , ,
"
SMS. &
Twilio
XML,
"
« !». ; ,
,
Twilio % , " SMS
Twilio .
= XML
" : , , ( , . .) .
TwiML, Twilio
API REST,
%
" ,
% .
~ %
, $
node.js, %
.
;
- ,
" SMS.
Получение SMS через Twilio
& " SMS, , . & " Twilio. ' , %
" . # smsServer.js
SMS. = express body-parser. 0 $
:
$ npm install express body-parser
2 Twilio,
" All Products and Services
(
%
), %
Programmable SMS " Create
New Messaging Service (#
" ).
Create. & %
PROCESS INBOUND
MESSAGES ( " " ), REQUEST URL
(URL) - ,
, : http://. .. :8080/sms. *
Save. 2
Numbers
,
Twilio.
;
SMS- "
Twilio. /
express node.js POST /sms
TwiML.
Глава 10
548
Сценарий для получения SMS
, POST
,
getText(). /
$ From
Body " ,
request.body —
,
Twilio
:
& HTTP,
"
POST " SMS:
/*
Z
TwiML
: node.js
*/
var express = require('express'); // '
// express
var server = express(); // Z$ " server, $
// express
var bodyParser = require('body-parser'); // '
// body-parser
function getText(request, response) {
console.log(request.body.Body);
var twiml = '<?xml version="1.0" encoding="UTF-8"?> \
<Response> \
<Message to="+15555555555">Z $ </Message> \
</Response>';
// + $ +15555555555 %
response.writeHead(200, {'Content-Type': 'text/xml'});
response.end(twiml);
}
server.listen(8080); // $ HTTP
server.use(bodyParser.urlencoded({extended: true}));
// $ $
server.post('/sms', getText); // $ /sms
2 $
,
" Twilio.
Микроконтроллеры в мобильных телефонных сетях
Напрямую подключать микроконтроллеры к мобильным телефонным сетям позволяют сотовые
модемы. С их помощью микроконтроллеры могут подключаться к Интернету так же, как это делает любой смартфон. Обладающий собственным телефонным номером модем может посылать
и принимать сообщения SMS, осуществлять запросы HTTP, — в общем, делать в Интернете все,
что можете делать вы сами. Модемы имеют определенные ограничения, но без них не обойтись,
когда нужно организовать связь при отсутствии сетей других типов. Поэтому весьма полезно
иметь хотя бы базовое представление об их работе.
&
. & 2000-
+
"
. & "
$ % . ;
,
Сети мобильной телефонной связи и физический мир
549
,
%
,
% ,
.
. =
% % 4G LTE17 100 7/ "
50 7/ ".
0
"
"
, $
$
.
. & (2G)
" SMS.
0 2G GSM13. ~ GSM ,
. * $ %
GPRS14,
(
3). & (3G) UMTS15,
GSM. $
,
,
. /
EDGE16. &
(4G)
, IP- , . &
% +
,
,
,
. ;
,
$ "
"
2G GPRS HTTP "
$ . / ,
" 2G
. *
3G LTE,
% .
,
" SMS, 2G.
13
GSM, Global System for Mobile Communications — .
14
GPRS, General Packet Radio Service — "
.
15
UMTS, Universal Mobile Telecommunications System —
.
16
EDGE, Enhanced Data Rates for GSM Evolution — %
GSM
.
* , , $
,
. $, , ,
, %
. & , %
«
»
, % .
, , " , "
2G,
, $
$
SMS,
.
17
LTE, Long-Term Evolution —
.
Глава 10
550
Рис. 10.11. Сотовые модемы (слева направо): Fona 800 и Fona Feather компании Adafruit, Xadow GSM+BLE компании Seeed
Studio, Cellular компании XBee, Electron компании Particle. Обратите внимание на антенны на модулях Fona, Xadow и Electron,
которые нужны, чтобы обеспечить уверенный прием радиосигнала
7 . >%
AT,
Digi 7. 7 ,
Digi , " 4G LTE.
& GSM
SIM- 18. /
IMSI19.
;
IMEI20.
* IMSI IMEI
,
.
18
SIM, Subscriber Identity Module —
.
19
IMSI, International Mobile Subscriber Identity —
.
20
IMEI, International Mobile Equipment Identifier —
.
Сотовые модемы
*
%
, " $ .
* . 10.11 %
.
7 SparkFun GSM/
GPRS SM5100B Spreadtrum Technologies. 7 AT,
SMS- "
. 0
" / " ,
, , % . 7
%
$ , SIM-
" .
7 Adafruit
Fona,
SIM80x 2G SIMTech,
Сети мобильной телефонной связи и физический мир
SIM5320 3G. &
"
SIM-
, Feather Fona " M0.
Seeed Studion
GSM RePhone,
SIM80x SIMTech. 7 Core
2G-AtmelSAMD21
RePhone,
Feather Fona,
M0,
- .
0 %
Xadow
GSM + BLE AT, SIMTech. *
$ ,
"
.
Libelium (www.libelium.com)
Cooking
Hacks (www.cooking-hacks.com), $
$ SIMTech. 7 Cooking
Hacks
.
Digi
XBee
- AT, ,
7. / ,
$ ,
.
, 4G LTE,
+
.
* Digi XBee Cellular SIM-
. +
, , , %
.
Particle (www.particle.io) Electron.
IDE
API,
Arduino, $
. '
Electron,
, —
$ . #
551
Electron
« »
MQTT,
$ .
+ %
% Fona RePhone. & "
AT SIM800,
$ .
+ $
: " $ . * ,
SIM800
.
$ ,
, ,
. =
$ % — ,
"
- (LiPo) .
= $ "
SIM- . +
- % , GPRS
. 3
,
. * $
, $
% .
Глава 10
552
Отправка SMS с сотового модема
& $
, SIM800 " SMS. /
, % . 0
" ,
"
$ . = $
SIM80x.
* . 10.12
( ) ( !) Fona800
Arduino 101.
2
Feather Fona —
$
. 7
, —
.
& Fona Adafruit RePhone Seeed Studio "
LiPo- .
= ( Fona Feather),
$ ,
. '
, 1200 3, — . +
,
" « »
« » —
.
&
,
" ,
.
SIM- (%
,
)
—
,
—
"
. =
TX RX USB/
Serial, RX — TX. ; « » ,
. , , 9600
:
AT
2
, % <Enter>. &
:
OK
7
AT OK ERROR. = " % :
AT+CMEE-2
=
,
:
AT+CBC
0 +CBC: 0,100,4214.
/ , 100%
4,214 &.
2
IMEI :
AT+CIMI
&
15-
,
IMEI % .
AT+GSN
IMSI:
Сети мобильной телефонной связи и физический мир
&
.
553
15- -
- :
+COPS: 0,0, "T-Mobile USA"
; :
( ,
:
AT+COPS?
, ),
+COPS: 0
Рис. 10.12. Принципиальная (вверху) и монтажная (внизу) схемы подключения модуля сотового модема Fona800 к микроконтроллерной плате Arduino 101
+3,3 В
Общий («земля»)
Reset
9
TX
8
RX
Модуль
микроконтроллера
15 кОм
Светочувствительный
резистор
+3,3 В
Модуль
SIM800
«Плюс» питающего тока
5
4
A4
Кнопка
10 кОм
Общий («земля»)
A B
C D E
F
G H
I
J
1
1
5
5
Bat
GND
10
10
Key
5V
+
SPKR
-
Ant
ADC
Rst
PWR
PS
15
Net
Buzzer
TX
RX
PWM
NS
20
20
Vio
2.8V
25
25
30
30
A B
C D E
F
G H
I
J
2000mAh
RI
Mic
+ -
Key
15
Глава 10
554
,
% .
7 :
AT+CSQ
0
4 , "
SMS. ' " SMS, :
AT+CMGF-1 OK
AT+CMGS-"+15555556666" ( R
%)
> .
:
+CSQ: 18, 99
,
"
" .
* " ,
% <Ctrl>+<Z> (ASCII 0x1A). 4
" ,
" .
Сценарий отправки SMS микроконтроллером
+ $
Feather Fona,
Arduino, " TX, RX
(Reset).
2
(+15555556666)
. 4 % Twilio,
" SMS
,
"
.
=
$
SoftwareSerial —
" :
/*
: Arduino
SMS
GSM SIM80
*/
#include <SoftwareSerial.h> // '
// SoftwareSerial
const int sim800Tx = 8; // TX
//
RX SIM80
const int sim800Rx = 9;
const int sim800Reset = 4; //
// (reset) SIM80
const int pushButton = 5; //
// '
int lastButtonState = HIGH; //
String phoneNum = "+15555556666"; // ^ %,
// '
// Z$ - TX RX:
SoftwareSerial sim800 = SoftwareSerial(sim800Tx, sim800Rx);
Сети мобильной телефонной связи и физический мир
555
& setup()
. = / . 0
, "
Arduino,
:
void setup() {
Serial.begin(9600); // '
// ' $
sim800.begin(9600); // '
// ' $
pinMode(sim800Reset, OUTPUT); // %
// /
pinMode (pushButton, INPUT_PULLUP);
& ,
,
. 2 " OK OK,
.find()
Stream. 4
" , "
, "
false ():
digitalWrite(sim800Reset, LOW); // +
delay(200);
digitalWrite(sim800Reset, HIGH);
delay(5000); //
$
while (!sim800.find("OK")) { // '
sim800.println("AT");
}
Serial.println("& GSM .");
}
& loop()
" , $
"
( ,
6). 4 ,
"
"
sendSMS(), " .
void loop() {
// Z
int buttonState = digitalRead(pushButton);
if (buttonState != lastButtonState) { //
$ ,
delay(100); // , - $
if (buttonState == LOW) { //
,
int reading = analogRead(A4); // Z
//
String sensorReading = "{\"Sensor\":X}"; // Z$
// % JSON
sensorReading.replace("X", String(reading)); //
// $
Serial.println("sending..."); //
// SMS
int result = sendSMS(phoneNum, sensorReading);
Serial.println(result); // 1 = }
}
lastButtonState = buttonState; // Z-
// '
}
2
.replace() String
JSON. ; ,
$ "
TwiML "
:
Глава 10
556
=
" SMS sendSMS(). & $
,
. # AT+CGMF=1 OK. 2
AT+CGMS= %
>. , , "
<Ctrl>+<Z>, 0x1A ASCII.
/
" :
// SMS
int sendSMS(String phoneNumber, String message) {
sim800.println("AT+CMGF=1"); // %
if (!sim800.find("OK")) { // OK,
return -2; // $
}
sim800.print("AT+CMGS=\""); // ^
//
sim800.print(phoneNumber); // %
sim800.println("\",145");
// %
// ( $ #
)
if (!sim800.find(">")) { // >,
return -1; // $
}
sim800.print(message); //
sim800.write(0x1A); // <Ctrl>+<Z>
// $ %
return 1; // +$ $ -
}
& .
Советы по программированию модемов
$
phoneNum
. 4 % (
),
"
" :
{sensor: 234}
,
" .
#
$ ,
, "
AT.
OK
% , Stream API Arduino
. & -
, .find() $ " true ( )
, "
.
.findUntil():
.findUntil("#_", '\n');
/ ,
.find(), ,
,
(
$
\n). / , " .
Stream .timeout(),
.
2 - 1 . ; ,
.find()
,
Сети мобильной телефонной связи и физический мир
0 (false — ). 2
-
" :
sim800.timeout(5000); //
// - 5
4, Stream
,
Serial, SoftwareSerial, Wi-Fi .
557
[ sendSMS() % "
: -2, -1 1. & "
%
.
& % -2 %
CGMF, -1 — %
CGMS, 1 — %
. ~ $
" ,
.
Отладочная программа
"
,
,
,
, . /
,
«" !
Arduino
USB/TTL-Serial» 2. ;
Arduino
,
. = $
%
Feather Fona
SIM800. ~ ,
setup() "
:
/*
: Arduino
*/
#include <SoftwareSerial.h>
const int sim800Tx = 8; //
// TX
RX SIM800
const int sim800Rx = 9;
// Z$ // TX
RX:
SoftwareSerial sim800 = SoftwareSerial(sim800Tx, sim800Rx);
void setup() {
Serial.begin(9600); //
//
sim800.begin(9600); //
//
}
'
' $
'
' $
void loop() {
if (Serial.available()) { // Z
//
sim800.write(Serial.read()); //
//
}
if (sim800.available()) { // Z
//
Serial.write(sim800.read()); //
//
}
}
Глава 10
558
Приложения для операционных систем мобильных
телефонов
Хотя интерфейсы на основе веб-браузеров и SMS-сообщений предоставляют много возможностей, для некоторых проектов мобильное приложение может оказаться более подходящим, чем
интерфейс на основе веб-браузера. Но если вы задались целью создать приложение для всех
типов смартфонов, вам придется изучить все их операционные системы, а также используемые
с ними программные средства. Однако существуют и более простые подходы к решению этой
задачи.
&
,
, %
. *
Android Google iOS
Apple, %
. +
Gartner
Group (www. gartner.com/newsroom/id/3609817)
,
2016 Android ,
81,6
,
iOS % % . 9 Android
$ 35 ,
2010 . ; ,
,
Android iOS.
=
iOS
, , Apple ID https://developer.apple.com.
>
USB ($
sideloading21),
App Store.
=
Android
21
> « ». =
iOS
USB, Bluetooth, Wi-Fi
, . = 0# Android $
APK Android.
. & , $ , —
$
,
.
Платформа PhoneGap
4
,
JavaScript, PhoneGap (www.phonegap.
com). PhoneGap , $
HTML5 JavaScript. 9
(
HTML5),
(,
)
,
% . 9
: Java — Android, Swift —
iOS. /
, . 2
HTML, CSS JavaScript,
.
$ .
& " PhoneGap Adobe, Adobe
Apache
Foundation Open Source
Сети мобильной телефонной связи и физический мир
Cordova (http://cordova.apache.org). *
$ . PhoneGap Cordova
,
% .
, PhoneGap
,
% . & , - PhoneGap Build
(https://build.phonegap.com)
— HTML, ,
. ; ,
PhoneGap Build $
. 3 PhoneGap
Desktop
HTTP. &
-
— , $
node.js p5.js. 2
PhoneGap Desktop
" " PhoneGap Developer. & %,
, Build,
"
Adobe, ,
" PhoneGap
Desktop PhoneGap Developer,
. ' ,
"
" . X
.
p5.js PhoneGap Android iOS.
,
iOS -
559
Apple, , ,
iOS,
Android. & "
PhoneGap PhoneGap p5.js. 3
.
Проект будет сложным!
/ ,
. /
,
:
22
PhoneGap, SDK iOS
Android, p5.js, — ,
Bluetooth LE
$ .
/ ,
,
.
X
!
Установка набора средств
разработки PhoneGap
*
PhoneGap
PhoneGap, SDK Android iOS, .
PhoneGap
npm "
" :
$ npm install -g phonegap
X PhoneGap,
SDK
(Android
iOS), .
22
SDK, Software Development Kit —
0.
Глава 10
560
Набор средств разработки для iOS
iOS macOS
XCode,
App Store
Apple. $
XCode . / , "
:
$ xcode-select --install
, iOS
Apple,
- https://
developer.apple.com. #
Apple
XCode.
;
" :
$ npm install -g ios-deploy
Примечание
4
node nvm n, " :
$sudo npm install -g iosdeploy --unsafe-perm-true --allow-root
=
Cordova/PhoneGap iOS
- cordova.apache.org/docs/en/
latest/guide/platforms/ios.
Набор средств разработки
для Android
Android
macOS, Windows Linux,
"
SDK Android. * SDK
Android Studio,
: https://developer.android.
com/studio/. =
Android Studio "
. ;
r25.2.3 . 2 $ " " :
http://dl-ssl.google.com/android/repository/
tools_r25.2.3-windows.zip
http://dl-ssl.google.com/android/repository /
tools_r25.2.3-linux.zip
http://dl-ssl.google.com/android/repository/
tools_r25.2.3-macosx.zip
X Android Studio,
"
Configure
SDK Manager. & % SDK
Manager System Settings "
Android SDK. 0
ADK. &
" Android 5.1 Lollipop, . X Android
, ]
|
D | D ( )
] | + ( % ).
* . 10.13 $ 0
% .
X Android SDK,
PATH, , PhoneGap, ,
. 0 $
.bash_profile — $ %
( bash):
$ nano .bash_profile
Сети мобильной телефонной связи и физический мир
561
= $ " :
?
macOS:
export PATH=$PATH:~/Library/Android/
sdk/tools:~/Library/Android/sdk/platform-tools:
?
= Linux:
export PATH=$PATH:~/Android/sdk/
tools:~/Android/sdk/platform-tools:
?
= Windows 10 Cygwin:
export PATH=$PATH:/cygdrive/c/Users/
username/AppData/Local/Android/Sdk/
tools/
'
, % <Ctrl>+<X>, % <Y>
, , % <Enter>. '
, ,
.
* , ( )
tools. = macOS
$ : ~/Library/Android/sdk/,
Linux — ~/Android/sdk/, Windows —
C:\Users\ _ \AppData\Local\
Android\Sdk. 4 tools, . +
,
PhoneGap Cordova. ;
PhoneGap.
Рис. 10.13. Пример экрана About tablet (О планшете) с информацией о версии Android
Подготовка устройства Android
Android $ $ ,
D
. = $
,
Android 5.1 .
' Android $
, (A ,
USB. = $ Android
] .
D (
: & ,
+ . .). 0 % (
. 10.13) % . &
' % ,
Build number (*
) ,
" , " , .
; ]
.
* $ " $ USB (USB Debugging).
;
.
Глава 10
562
Создаем проект PhoneGap
'
, PhoneGap
SDK
p5.js, , " $
. = $ PhoneGap,
"
:
$ phonegap create buttonApp com.
example.buttonapp ButtonApp
' $ ?
PhoneGap
buttonApp. 0
. #
, : com.
example.buttonapp — ,
% . 2
com.example
. * ,
: ButtonApp — $
XCode Android Studio.
=
buttonApp " :
. *
p5.js,
$ . 0 ,
$ <platform name="ios">
<platform name="android">,
<icon> <splash>, PhoneGap
.
; ,
, — Windows
Windows 8.
platforms " .
+ ,
" :
$ phonegap platform add android
$ phonegap platform add ios
$ PhoneGap
SDK,
platforms
. X " :
phonegap platform rm
$ls
Вниманию разработчиков iOS!
=
"
:
CONTRIBUTING.md
config.xml
platforms
www
README.md
hooks
plugins
[ config.xml . 0
package.json node.js
, ,
,
,
. & %
,
$ " PhoneGap
iOS,
XCode .
platofms/ios/ XCode ButtonApp.
xcodeoroj — . ¥ , . X
(developer team)
(individual developer),
. #
.
# PhoneGap
% Bluetooth,
. . plugins. 7 , $ , $ $ . 3 hooks . & $ hooks .
Сети мобильной телефонной связи и физический мир
# HTML, CSS
JavaScript " www.
=
$ PhoneGap
% ,
p5.js. * $ HTML. X www
p5.js
www. #
p5.js. +
p5-manager,
www p5.js
" :
$
$
$
$
rm
p5
cd
p5
563
; .
index.
html p5.js ,
. /
p5.js ,
,
,
% .
-rf www
g -b www
www
update
Создаем свой файл index.html
# " index.html
index.html
p5.js. ; meta head
PhoneGap . 0
,
,
JavaScript
.
;
cordova.js,
PhoneGap
. 2
p5.js JavaScript.
0 , $
body
,
head.
# PhoneGap
$ , :
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="format-detection" content="telephone=no" />
<meta name="msapplication-tap-highlight" content="no" />
<meta name="viewport" content="user-scalable=no,
initial-scale=1, maximumscale=1, minimum-scale=1,
width=device-width" />
<meta http-equiv="Content-Security-Policy"
content="default-src 'self' data:
gap: 'unsafe-inline' https://ssl.gstatic.com; style-src
'self' 'unsafe-inline';
media-src *" />
<title>ButtonApp</title>
</head>
<body>
<script type="text/javascript" src="cordova.js"></
script>
<script src="libraries/p5.js"></script>
<script src="libraries/p5.dom.js"></script>
<script src="sketch.js"></script>
</body>
</html>
Глава 10
564
Создаем и исполняем приложение
= " ,
.
/*
= sketch.js "
1. # "
$ :
$ ( ),
— touchEnded ( " )
$ ( responseDiv).
=
:
var myButton, responseDiv; // DOM
; " $ .
.
M'
: p5.js
,
'
*/
function setup() {
createCanvas(windowWidth, windowHeight); // Z$ -
myButton = createButton('click me'); // Z$
myButton.touchEnded(changeButton); // % # '
//
myButton.position(10, 10); //
responseDiv = createDiv('catch me'); // C$
// $ div
responseDiv.position(10, 40); //
}
// \ ' R:
function changeButton() {
var x = random(windowWidth) - myButton.width; // ^
// var y = random(windowHeight) - myButton.height; // ^
// y
myButton.position(x, y); //
responseDiv.html(x + ',' + y); // $ responseDiv
}
Устройство под iOS
platofms/ios/
XCode ButtonApp.xcodeoroj. ¥
ButtonApp,
.
& Signing iOS,
, :
ButtonApp > Generic iOS Device. ¥
"
, " % . &
, Signing.
&
iOS -
$ Run
XCode, — " % XCode.
Устройство под Android
—
% USB $ . *
Yes.
&
:
"
$ phonegap run android --device
=
iOS
android ios. 4
,
phonegap build. 4
,
Сети мобильной телефонной связи и физический мир
565
PhoneGap
" . &
$
" ,
% %
. %
PhoneGap % .
4
, Android
. 10.14.
Рис. 10.14. Результаты исполнения приложения на устройстве под Android
Где исполняются приложения?
9
" , $
. / ,
" .
XCode iOS,
Android
Studio $
, " "
. ' $
iOS,
XCode ,
$ . 3
Android Virtual Device Creator,
android avd. *
$ Android Studio SDK Manager
SDK. , $
,
" . ~
% $
,
"
iOS Android
.
" .
Подытожим…
7 ,
%,
. =
%
,
" :
1. # "
PhoneGap .
2. 0
config.xml.
3. =
.
4. = iOS
5. X www
p5.js www.
6. 0
index.html.
.
7. *% .
8. &
.
9. 2
.
/ %
% .
Глава 10
566
Проект 31
Мобильный регистратор личных биометрических данных
Одной из причин популярности разработки собственных приложений для смартфонов является
возможность использования беспроводного канала Bluetooth для организации связи смартфона
с другими устройствами. Это позволяет использовать смартфон в качестве шлюза для отправки
данных на какой-либо веб-сайт в Интернете. В этом проекте мы будем с помощью микроконтроллера замерять гальваническую реакцию кожи, отправлять полученные данные по Bluetooth на
смартфон, а затем сохранять их в файле в Интернете.
Требуемые компоненты
X 0# Android iOS, 1 %.
7 RedBear BLE Nano, 1 %.
+ :
/ , Bluetooth LE.
USB- MK20 RedBear BLE
Nano, 1 %.
%
2,5 % .
-
= .
. .
9 270 0, 1 %.
%
.
; " %.
0 "
13 .
Shieldit Super,
& " $
:
,
% . 2
Quantified Self23 (http://quantifiedself.
com),
, $ ,
FitBit (www.fitbit.com)
Apple Watch, " . * "
.
/ ,
,
.
2 «».
; % , 1 %.
* % .
Рис. 10.15. Мустафа Багдатли с устройством Poker
Face24 — регистратором биометрических данных, связанным со смартфоном. Фотография предоставлена самим
Мустафой Багдатли (Mustafa Bagdatli)
23
* : «[
]
». & : « `».
24
Poker Face (* ) — , , % .
Сети мобильной телефонной связи и физический мир
*%
7 > ( . 10.15). 7 % -
(q9)
,
, , —
q9. 4
Poker Face ( . 10.16) $ " Arduino LiliPad Bluetooth
,
+
.
> Poker Face
- 7 : http://
mustafabagdatli.com.
7 ,
7 , — " —
. &
q9
, % .
* . 10.17 - . 7 , "
Bluetooth LE,
,
, -
Рис. 10.17. Блок-схема системы проекта
мобильного регистратора биометрических
данных
567
Рис. 10.16. Напульсник из проекта Poker Face с пришитыми
контактами датчика крупным планом. Напульсник показан
вывернутым наизнанку, чтобы контакты были лучше видны.
Фотография предоставлена Мустафой Багдатли
, $
6. .
.
Upload (& ) HTTP GET
node.js,
- ,
"
.
' % $
, %
.
Файл
для данных
Связь HTTP
по GSM или LTE
Смартфон
Интернет
Сервер
на node.js
Веб-сервер
Канал Bluetooth LE
Аналоговый
сигнал 0–3 В
Датчик КГР
Микроконтроллер
Глава 10
568
Схема системы
7 $
. 10.18, " — . 10.19. ,
$ .
Vdd
A4
-
-
+
+
LFT
D0/RX
Vin
GND
D2/CTS
D3/RTS
D1/TX
GND
SWCLK
A3
SWDIO
Рис. 10.18. Монтажная схема мобильного регистратора биометрических данных. Контактные
площадки датчика выполнены из токопроводящей ткани. Кнопки пришиты к ткани токопроводящими нитками. К кнопкам и к компонентам припаяны провода (красный, синий, черный).
Наличие отстегивающихся кнопок позволяет снять электронные компоненты с одежды для
ухода за ней — например, для стирки
Рис. 10.19. Принципиальная схема мобильного регистратора биометрических данных
+3,3 В
+3,3 В
Держатель
для таблеточной батарейки
Модуль микроконтроллера
с возможностью связи Bluetooth LE
Контактные площадки
из токопроводящей ткани
A4
Общий
(«земля»)
270 КОм
Общий («земля»)
Сети мобильной телефонной связи и физический мир
569
& ,
-
, — $ % . ' $,
. & ,
— .
& -
, ,
.
& ,
.
, , . & $
% .
, , %
% ,
, ,
,
.
& $ BLE Nano RedBear Labs,
" ARM M0,
"
Arduino IDE, Bluetooth LE
51822 Nordic Labs — Bluetooth, Arduino
101. $
Arduino 101, "
BLEPeripheral
CurieBLE. *
-
Arduino 101
% % . ;
, $
BLEPeripheral,
Arduino
Bluetooth nRF51822
nRF8001 Nordic Labs —
Bluetooth LE
6. =
BLEPeripheral CurieBLE $ .
,
, % ,
270 0
( . . 10.18 10.19). 9 ,
,
% %
. * $ ,
% 10 0
.
& ,
LilyPad Coin Cell Battery Holder SparkFun. 4
%
,
LilyPad Simple Power
$ , "
LiPo USB.
=
" " . 9
"
$ , $ $
,
, % .
& 7 " , %
( . . 10.16). `
"
Shieldit Super .
Подготовка схемы к тестированию
& %
, % ,
. ~ $
LilyPad Flora,
, , %
. $,
%
,
, - Bluetooth LE — LightBlue
iOS macOS nRF Connect Android.
Глава 10
570
# Bluetooth
LE $ ,
q9,
%
%
.
= BLE Nano
%
,
" USB/Serial MK20 USB. *
%
,
. # ,
,
$
MK20 USB. /
%
%
( . 10.20). &
BLE Nano MK20 USB
- .
Рис. 10.20. Подключение платы Bluetooth BLE Nano к адаптеру MK20 USB без припаивания штыревых разъемов может
быть сопряжено с трудностями. Эти трудности можно преодолеть, используя длинные штыревые разъемы и устанавливая плату на адаптер с некоторым перекосом, обеспечивающим надежный контакт
& BLE Nano % "
, $
%
. = $ %
- ( . 10.21), "
, $ « ».
*, , -
%
.
Начинаем разработку кода
& $ ,
%
. 2 , , " ,
.
4 $
BLE
Nano,
Arduino " . = $
Рис. 10.21. Сборка проекта для тестирования с помощью
крючков-клипс
Сети мобильной телефонной связи и физический мир
571
Носимые микроконтроллеры
4
$
, " . _
LilyPad, _ > (Leah Buechley) SparkFun, , ,
$ . Adafruit
Flora . X LilyPad
" /
" , Flora $ %
I2C
WS2812
. 0
,
,
. Seeed Studio $
%
, , , Pebble.
0 $
Bluetooth LE
Flora Bluefruit LE, Adafruit. , $
\ | ]
! " A %
]
http://redbearlab.github.io/
arduino/package_redbearlab_index.json. &
BLEPeripheral
# 7 ,
,
BLE Nano,
/ ,
. & %
$
Flora. ; ,
" BLE
Nano, % % ,
%
, %
. , $
$ ,
LilyPad Flora.
=
" _ > «Sew Electric»
( HLT Press), # (Syuzi
Pakhchyan) «Fashioning Technology: A DIY Intro to
Smart Crafting» ( O’Reilly)
~
-X
(Hannah Perner-Wilson) http://www.plusea.
at. , - >
(Becky
Stern) https://beckystern.com
.
12 6. X
$
Arduino
" .
=
-
https://github.com/sandeepmistry/
arduino-BLEPeripheral.
Пишем скетч для чтения показаний датчика КГР
,
. ;
:
/*
Z -
: Arduino, nRF51822
*/
#include <SPI.h>
#include <BLEPeripheral.h>
#
nRF8001
Глава 10
572
// ($ $
// /)
#define BLE_REQ 10
#define BLE_RDY 2
#define BLE_RST 9
int lastInput = 0; // $ $
int threshold = 10; // $ $ # $
//
2 %
BLEPeripheral,
:
BLEPeripheral blePeripheral = BLEPeripheral(BLE_REQ, BLE_
RDY, BLE_RST);
=
, ,
.
// Z$ - $
// $ :
BLEIntCharacteristic sensorCharacteristic( \
"0927ADA8-3588-11E7-A919-92EBCB67FE33", BLERead | BLENotify);
BLEIntCharacteristic thresholdCharacteristic( \
"0927AF9C-3588-11E7-A919-92EBCB67FE33", BLERead | BLEWrite);
// Z$
BLEService sensorService("0927AA6A-3588-11E7-A919-92EBCB67FE33");
= $
25
UUID ( ),
Android 7
UUID:
& setup()
. = ,
,
,
:
25
UUID, Universally Unique Identifier —
.
void setup() {
Serial.begin(9600); // \ # $ ' $
// "
% UUID
//
blePeripheral.setLocalName("BleNano");
blePeripheral.setAdvertisedServiceUuid(sensorService.uuid());
// add service and characteristics to device
blePeripheral.addAttribute(sensorService);
blePeripheral.addAttribute(sensorCharacteristic);
blePeripheral.addAttribute(thresholdCharacteristic);
// set initial value for threshold, and begin:
thresholdCharacteristic.setValue(threshold);
blePeripheral.begin();
Serial.println("BLE LED Peripheral active");
}
Сети мобильной телефонной связи и физический мир
573
& loop()
. :
,
. 4 "
" %,
,
:
void loop() {
BLECentral central = blePeripheral.central(); //
// '
//
'
if (central) {
Serial.print("Connected to central: "); // +
// #
Serial.println(central.address());
// # '
while (central.connected()) {
if (thresholdCharacteristic.written()) {
threshold = thresholdCharacteristic.value();
}
int input = analogRead(A4);
if (abs(input - lastInput) > threshold) {
sensorCharacteristic.setValue(input);
Serial.print(threshold);
Serial.print(",");
Serial.println(input);
}
* "
lastInput — " "
:
lastInput = input;
}
* ,
, "
" :
// '
Serial.print("Disconnected from central: ");
// ' # :
Serial.println(central.address());
}
}
Тестируем код скетча
2
, -
Bluetooth LE ( , LightBlue
nRF Connect) % . % . "
,
. 4
, % " LightBlue
nRF Connect
, ,
. ; — %
. *
$ "
.
Монтаж компонентов проекта
в толстовку
= $
, " , "
,
" . 2
, $ ,
. & , " "
.
7
% ,
% ,
Глава 10
574
. %,
30AWG ( ,
3). , " ,
, — $
.
; "
"
%
(
). , " (
), — , %
. 9
. 10.22 (
, ,
, . 10.18).
4 % "
(, , LessEMF),
" . 9
%
, , . * . 10.23
.
% . > ,
%
,
.
$
. '
"
$,
"
LightBlue nRF Connect,
.
X % ,
, .
Рис. 10.22. Размещение компонентов на внутренней стороне толстовки: микроконтроллер и держатель батарейки пристегиваются кнопками. Пайка кнопок
не представляет никаких сложностей, но ее следует выполнять на защелкнутых
кнопках, чтобы припаиваемые части не деформировались от тепла паяльника.
Постарайтесь не пришить кнопки питания к контактам датчика на внутренней стороне толстовки, что может создать короткое замыкание
Рис. 10.23. Контактные площадки из
токопроводящей ткани внутри кармана толстовки
Сети мобильной телефонной связи и физический мир
575
Мобильный клиент на PhoneGap
Z
$ PhoneGap, ,
. 7 % $ . * PhoneGap, :
$ phonegap create BleDatalogger com.
example.bledatalogger BleDatalogger
$ :
$ cd BleDatalogger
2 config.xml,
<icon> <splash> $ <platform name="ios"> <platform
name="android">,
. #
, , "
( iOS
android ios):
$ phonegap platform add android
$ BLE Central
PhoneGap Cordova:
$ phonegap plugin add cordova-pluginble-central
Рис. 10.24. Внешний вид готового приложения для Android
+ www p5.js:
$
$
$
$
$
cd
rm
p5
cd
p5
BleDatalogger
-rf www
g -b www
www
update
Примечание
= BLE
Central . - github.
com/don/cordova-plugin-ble-central.
9 iOS, /platforms/ios/ BleDatalogger.
xcodeproj
.
; , ,
index.html sketch.js. * . 10.24
, $
Android.
Глава 10
576
Создаем страницу index.html
=
index.html . 0
$
"
PhoneGap connect-sic
Content-Security-Policy,
:
Вставьте IP-адрес своего
веб-хоста
Замените выделенный полужирным шрифтом IP-адрес на IP-адрес
своего веб-хоста. Наше приложение
будет подключаться к нему, чтобы
сохранить полученные от датчика
данные.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="format-detection" content="telephone=no" />
<meta name="msapplication-tap-highlight" content="no" />
<meta name="viewport" content="user-scalable=no, initialscale=1, maximumscale=1, minimum-scale=1, width=device-width" />
<meta http-equiv="Content-Security-Policy" content="default-src
'self' data: gap: 'unsafe-inline' https://ssl.gstatic.com;
connect-src
http://192.168.0.10:8080; style-src 'self' 'unsafe-inline';
media-src *" />
<title>ButtonApp</title>
</head>
<body>
<script type="text/javascript" src="cordova.js"></script>
<script src="libraries/p5.js"></script>
<script src="libraries/p5.dom.js"></script>
<script src="sketch.js"></script>
</body>
</html>
Пишем код скетча p5.js
# p5.js $ . *
,
,
.
,
—
. 4"
$
.
* ,
,
,
(URL)
JSON :
/*
Bluetooth Central PhoneGap
:p5.js PhoneGap
\$ (Don Coleman)cordovaplugin-ble-central PhoneGap/cordova
*/
// % $
var deviceList, responseDiv, dataDiv, autoUpload;
var scanButton, connectButton, disconnectButton, uploadButton;
var autoUploadTimer; // $ $
var connectState = false; // Z '
// %
//
var dataServer = 'http://192.168.0.10:8080';
var readings = new Array(); // $ $
// % BLE
var myDevice = {
serviceUUID: '0927AA6A-3588-11E7-A919-92EBCB67FE33',
sensorCharacteristic: '0927ADA8-3588-11E7-A91992EBCB67FE33',
id:''
};
Сети мобильной телефонной связи и физический мир
& setup() $
. ;
,
$ .
577
function setup() {
// Z$ , ' , '
//
$ $ :
scanButton = createButton('Scan for devices');
scanButton.touchEnded(scanForDevices);
scanButton.position(10, 60);
scanButton.size(80,40);
connectButton = createButton('connect');
connectButton.touchEnded(connectToDevice);
connectButton.position(100, 60);
connectButton.size(80,40);
disconnectButton = createButton('disconnect');
disconnectButton.touchEnded(disconnectFromDevice);
disconnectButton.position(190, 60);
disconnectButton.size(80,40);
[ draw() $
, $ ,
$ .
uploadButton = createButton('Send to Server');
uploadButton.touchEnded(sendToServer);
uploadButton.position(10, 250);
uploadButton.size(80,40);
// Z$ % $ $
autoUpload = createCheckbox('Upload every two minutes', false);
//
autoUpload.position(100, 250);
autoUpload.changed(setAutoUpload);
$ ,
setup() ,
Bluetooth:
// Z$ $
responseDiv = createDiv('tap the scan button to begin');
// ^ ,
responseDiv.position(10, 150);
responseDiv.style("font-size", "14px");
dataDiv = createDiv('');
dataDiv.position(10, 200);
dataDiv.style("font-size", "14px");
// , ' $ BLE
ble.isEnabled(scanForDevices, bleError);
}
[
Scan for Devices .
# $ deviceList
,
. 2
$ ,
" ,
:
// \ # BLE
function scanForDevices() {
responseDiv.html('scanning for devices.');
// $, ,
// :
if (deviceList) deviceList.remove();
deviceList = createSelect(); // Z$ R
deviceList.position(10, 110);
deviceList.size(150, 30)
deviceList.option('Pick a device', ''); //
//
'
deviceList.changed(selectDevice);
// + 5 serviceUUID
Глава 10
578
2 $
deviceList, BLE,
ble.scan(). >
Cordova ble,
% $ BLE.
, scan()
,
: myDevice.serviceUUID.
= "
-:
ble.scan([myDevice.serviceUUID], 5, discoverDevice, bleError);
// $ - " $
// :
setTimeout(ble.stopScan, 5000, scanFinished, bleError);
}
ble.scan()
,
discoverDevice(),
$ $
deviceList. + ,
$
MAC-
(, , ) :
// \
function discoverDevice(device) {
var result = device.name + ' ' + // Z$
//
'RSSI: ' + device.rssi;
deviceList.option(result, device.id); //
// R
}
[
- responseDiv:
function scanFinished() {
responseDiv.html('scan complete. Pick a device.');
// Z $. + .
}
[
$
deviceList. 0
" ,
MAC-
:
// # $ $
// $
function selectDevice() {
myDevice.id = deviceList.value();
responseDiv.html('Selected: ' + deviceList.value());
}
scanFinished()
selectDevice()
Сети мобильной телефонной связи и физический мир
579
[
connectToDevice() connect. 4
,
.
% onConnect(),
—
bleError():
// # $ ' connect
function connectToDevice() {
if (!connectState) {
responseDiv.html('connecting to ' + myDevice.id);
// '
ble.connect(myDevice.id, onConnect, bleError);
connectState = true;
}
}
[
% %
. &
ble.startNotification()
,
responseDiv:
function onConnect() {
// -
ble.startNotification(myDevice.id, myDevice.serviceUUID,
myDevice.sensorCharacteristic, onData, bleError);
responseDiv.html('Waiting for data from ' + myDevice.id);
// ...
}
[ onData() ,
. =
ArrayBuffer,
16-
(Uint16Array),
$ $ . # JSON, "
, "
readings,
dataDiv:
function onData (data) {
var input = new Uint16Array(data); // $
// $ " ArrayBuffer
var reading = { // Z$ " JSON
timestamp: new Date(), // Z$
value: input[0] // $ $
}
readings.push(reading); // $
// readings
dataDiv.html('latest: ' + JSON.stringify(reading));
}
[
sendToServer()
Send to
Server while
$
readings,
GET HTTP
. [
" GET: http://exam-
function sendToServer() {
responseDiv.html('uploading data...');
// + ...
while(readings.length > 0) { //
// $ ,
var reading = readings.pop(); // $
// $ readings
// $ GET
var path = '/data/' + reading.timestamp + '/' + reading.
value;
//
httpGet(dataServer + path, serverReply);
}
}
onConnect()
ple.com:8080/data/timestamp/
sensorValue.
-
,
%
:
Глава 10
580
[
,
sendToServer()
, $ :
function setAutoUpload() {
if (!autoUpload.checked()) {
responseDiv.html('Auto-upload off');
// $ $ '
//
clearInterval(autoUploadTimer);
} else {
responseDiv.html('Auto-upload on');
// $ $ '
// set timer to upload every 2 minutes
// M $ $ 2
autoUploadTimer = setInterval(sendToServer, 2*60000);
}
}
[ serverReply()
HTTP GET
dataDiv:
function serverReply(data) {
dataDiv.html('');
responseDiv.html('Server said: ' + data);
// :
}
[ disconnectFromDevice()
disconnect. [
onDicsonnect(), responseDiv:
function disconnectFromDevice() {
if (connectState) {
ble.disconnect(myDevice.id, onDisconnect, bleError);
connectState = false;
}
}
* , "
% bleError()
%
" %
responseDiv:
function bleError(error) {
responseDiv.html(' there was a BLE error' + JSON.
stringify(error));
// $ BLE
}
setAutoUpload()
& . # ,
PhoneGap
,
:
$ phonegap run --device
function onDisconnect() {
responseDiv.html('disconnected from ' + myDevice.id);
// '
}
Сети мобильной телефонной связи и физический мир
4 ,
Bluetooth LE, , . * . 10.25
, $
. 3 . 10.26 $ -
581
, % .
.
4 $ $ ,
.
Сохраняем показания на сервере
#
server.js,
,
,
-
IP-a ,
dataServer " . ,
" npm express.js, data.csv.
# $ , $
. #
GET :
Рис. 10.25. Толстовка регистратора личных биометрических
данных в действии. Сколько радости и какой уровень возбуждения приносит его создателю такая возможность? Это
можно узнать по его данным КГР в файле data.csv
Рис. 10.26. Приложение регистратора личных биометрических данных в действии
/data/timestamp/sensorReading
Глава 10
582
0
,
data.csv (
).
2
,
:
/*
: node.js
$ GET HTTP
timestamp/reading
*/
% /data/
var express = require('express'); // '
// express
var fs = require('fs'); // ' %
// fs
var server = express(); // Z$ " server, $
// express
function log(request, response) {
// % $// $
$
var newData = request.params.timestamp + ','
+ request.params.reading + '\n';
// %
//
fs.appendFile('data.csv', newData, confirmSave);
response.end('Last upload at ' + new Date());
// $ $ ...
}
[ confirmSave()
fs.appendFile()
"
:
function confirmSave(error) {
var now = new Date(); // Z$
if (error) { // + $ ,
console.log(now + ': ' + error); //
//
} else { // - ,
//
'
console.log(now + ': ' + 'Saved to file');
// Z- %
}
}
server.listen(8080); // $ HTTP
server.get('/data/:timestamp/:reading', log); //
// $ GET
Диагностика
0
" ,
Send to Server, —
, Upload
every two minutes. *
,
"
. #
data.csv " :
Sat Apr 15 2017 14:59:47 GMT-0400 (EDT),20
Sat Apr 15 2017 16:48:41 GMT-0400 (EDT),20
Sat Apr 15 2017 16:48:41 GMT-0400 (EDT),22
Sat Apr 15 2017 16:48:40 GMT-0400 (EDT),18
Сети мобильной телефонной связи и физический мир
4
" :
?
?
?
?
,
-
D
A A ? 4
,
PhoneGap ,
.
A>
A
&? 4
,
sketch.js %. $ ,
index.html . $
Bluetooth
, $
.
C A
? 4 , ,
.
7 scanForDevices() myDevice.serviceUUID
Bluetooth.
?
4
,
URL Content Security Policy in
dataServer
dex.html
sketch.js.
Рис. 10.27. Окно браузера Chrome
для исследования устройств
583
Удаленная отладка
4
, , , % , JavaScript Chrome
Windows Safari macOS, " . =
, $ .
USB ,
Chrome
: chrome://inspect. 0 ,
. 10.27.
& , % . 0
,
HTML JavaScript.
0 " , $ ,
" , ,
JavaScript - .
Safari iOS. =
-
Глава 10
584
Web Inspector —
Settings
Safari | Advanced | Web Inspector. 3
Mac Safari,
Preferences | Advanced Menu
Bar Show Develop Menu.
2 PhoneGap iOS,
Develop | Phone | Apps | index.html.
X
"
, % % ,
PhoneGap.
Подытожим…
*%
,
$
: ,
HTTP,
JavaScript,
Bluetooth LE. 4 $
-
" , —
.
0
+
% % ,
. * $ ,
% ,
, .
& "
, $
% , .
; ,
, .
*%
,
. #
- "
— SMS
HTTP,
.
Заключение
По определению, сетевые устройства не болтаются в безвоздушном пространстве сами по себе.
Поэтому, если устройство уже подключено к Интернету, следует воспользоваться предоставляемой им мощностью. Чем больше протоколов и инструментов вы знаете, тем легче и приятнее
будет ваша работа. Обратите внимание на преимущества, предоставляемые серверами с общедоступными адресами и излишком вычислительных мощностей. Предусмотрите совместное использование проводных и беспроводных протоколов, чтобы оснастить разрабатываемые вами
проекты максимальными возможностями реагирования на окружающую их физическую среду.
" ,
. 0 ,
$ ,
$ . 0
,
-
- ,
. * $ ,
.
& "
, "
24/7 (24 7
).
Сети мобильной телефонной связи и физический мир
0 " , # ,
$ "
. 0
,
, — ,
. *
,
. 2 .
2
. = , ? ' $ % $ ?
585
'
,
- "
,
. +
% :
?
% % , ;
?
;
?
;
?
.
+
" % ,
$ " % %
% .
Проект SIMbaLink. Разработчики Мередит Хэссон (Meredith Hasson), Ариэль Неварес (Ariel Nevarez) и Нахана
Шеллинг (Nahana Schelling)
SIMbaLink
%
$ , "
,
- SIMbaLink GPRS. 9
$ /,
SIMbaLink "
% $ Awassa /. # " 10 ,
. /
, $ . 0
* =%.
Приложение
ГДЕ БРАТЬ КОМПОНЕНТЫ
И ПРОЧЕЕ?
В книге упоминается много разных поставщиков аппаратных
устройств и источников программного обеспечения.
В этом приложении приводится список всех используемых
в книге компонентов и краткое описание их поставщиков.
Приложение разбито на три раздела:
? компоненты;
? поставщики аппаратных компонентов;
? поставщики программного обеспечения.
Приложение
588
Компоненты
В этом разделе приводится список всех компонентов, используемых в книге. Для каждого компонента указываются проекты, в которых он задействован. Со времени предыдущего издания
этой книги ситуация с поставщиками претерпела некоторые изменения, поскольку одни компании получили новых собственников, а другие прекратили свою деятельность. Но, к счастью, на
рынке все еще достаточно небольших поставщиков электронных компонентов, предлагающих
интересные решения.
Поскольку возможны обновления этого списка, посетите веб-страницу http://oreilly.com/
catalog/0636920010920, чтобы ознакомиться с ними.
Коды поставщиков
?
A — Arduino Store, https://store.arduino.cc
?
L — LessEMF, www.lessemf.com
?
AF — Adafruit, www.adafruit.com
?
MS — Maker SHED, www.makershed.com
?
AMZ — Amazon, www.amazon.com
?
P — Pololu, www.pololu.com
?
B — Belkin, www.belkin.com
?
?
D — Digi-Key, www.digikey.com
PS — PowerSwitch Tail, www.powerswitchtail.com
?
DL — D-Link, www.dlink.com
?
PX — Parallax, www.parallax.com
?
F — Farnell, www.farnell.com
?
RS — RS, www.rs-online.com
?
ID — Identive, www.identiveusa.com
?
SF — SparkFun, www.sparkfun.com
?
J — Jameco, https://jameco.com
?
SS — Seeed Studio, www.seeedstudio.com
Инфраструктура
> . +
.
" Arduino 101. + -
N >
Wi-Fi. + % .
. +
.
-
$ 1,5 . + 8, 9, 26 27 .
> , $
Bluetooth. + 3, 12, 18
31. 4 %
" Bluetooth, % Bluetooth. AF: 1327, RS: 8077742, SS:
113990026
N
D Android
31.
Микроконтроллеры, шилды
и макетные платы
iOS. + -
% . D: 1660-1003-ND, J:
2239331, SF: DEV-13787, AF: 3033, F: 2520713,
RS: 913-9999, SS: 114990575, A: ABX00005,
GBX00005 (3 4#)
" Arduino MKR1000. +
% . AF: 3156, RS: 1240657, A: ABX00004, GBX00011 (3 4#),
D: 1659-1005-ND
" Arduino Uno. +
% . D: 1050-1024-ND, J:
2151486, SF: DEV-11021, A: A000099, AF: 50,
F: 1848687, RS: 715-4081, SS: ARD132D2P
"
ATtiny84. +
4. D: ATTINY84A-PU-ND, SF:
COM-11232, F: 1455160, RS: 738-0684
= ESP8266.
Adafruit ESP8266 Huzzah!
Adafruit ESP8266 Thing Dev
SparkFun. SF: WRL-13231, AF: 2471
Где брать компоненты и прочее?
> Raspberry Pi.
+
. ;
BeagleBone Green
Linux. SF: DEV13825, AF: 3055 3400, SS: 102010048
114990584, RS: 896-8660, F: 2525225
C . +
% . D: 438-1045-ND,
J: 20723 20601, SF: PRT-12615 PRT12002, F: 4692810, AF: 64, SS: 319030002
319030001
589
D RFID. + -
24, 25 27.
• D
SCL3711
-
SCL3711.
" NFC- PN532. AF: 364,
D: 1528-1781-ND, SS: 113030001
"
RFID Classic
Mifare.
+ 24–27. AF: 359
360, SF: SEN-10128 SEN-11319, SS:
113990013
Arduino. ;
, $
% .
AF: 2077, A: TSX00083, SF: DEV-07914
A > IP-
• " + . SF: PRT12044, AF: 65, D: 923273-ND
&
H
&
. + 8, 9 27. AF: 1609, D: V2018ND, J: 616673, F: 4903213, RS: 159-5420
Модули связи
USB/TTL-Serial. +
. SF: DEV-09716 DEV14050, AF: 3309 284, SS: 317990026
" Bluetooth Serial. +
3 18. AF: 1588, SF: WRL-12580
WRL-12576
( XBee
XBee Pro S2C
802.15.4. + 14. AF: 128,
D: 602-1892-ND, SF: WRL-08665, J: 2253722,
PX 32416
( SX1276
HopeRF
RFM95W
Semtech. + 11. AF: 3072, SS: 113060006
USB/XBee- . + 14.
J: 32400, SF: WRL-11812, AF: 247, PX: 32400
( Bluetooth LE. 7 -
12 Arduino
101 BLE Nano. AF: 1697
BLE Nano
RedBear USB MK20. + . +
31 (
12). MS: MKRBL5, SF: WRL-14071
ID:
D-Link (
Raspberry Pi
Pi Cam). +
29 30. DL: DCS-930L, DCS5222L DCS-960L.
, IP Raspberry Pi
Pi Cam:
• Pi Cam. SF: DEV-14028, AF: 3099,
SS: 113990214, RS: 913-2664
• ] Raspberry Pi Zero
W. A: 3414
D
• Adafruit Fona 800. #3 — AF: 3147,
4 — AF: 2691
• Adafruit Fona Feather. AF: 3027
• SeeedStudio
102040005
Xadow
GSM+BLE.
SS:
• XBee Cellular. D: 602-1976-ND
• Particle Electron Kit. #. . 3 /
3 — SF: WRL-14211, 3 /
3/4 — SF: WRL-14212
Адаптерные платы и разъемы
.
+ 14. SF: B0B-08891,
P: 1479 1639
% =
A JST- ). + 13 15. SF: SEN08733
()
« » 9 '.
+ 3 13. D: 15681237-ND, J: 2207056, SF: PRT-09518, A: 80,
F: 1650675
Приложение
590
)
2,1 , 5,5 + . + 3 27. D: CP3-1000-ND ,
J: 28760, SF: PRT-10287, A: 369, F: 1737256
A . + 5 31. D: K386-ND, J:
22577, F: 09WX4670
A . + 5. D: K445-ND
WSU-30M, J: 2150361, F: 441089
H
+ 2,5 .
+ % . D:
A26509-20-ND, J: 103377, SF: PRT-00116, F:
1593411
) + 2,5 . D:
ED7102-ND, F: 1122344, SF: PRT-00115
XBee.
+ 14. SS: 113100001,
SF: BOB-08276
H ) + +
2,5 . +
. AF: 400, SF: PRT-12693
) + 2 . +
14. SF: PRT-08272, D:
3M9406-ND
D . + 7–9,
Общие компоненты
100 \. + -
D
100 . + 8, 9, 29 30. D: 100QBK-ND, J: 690620,
F: 9337660, RS: 755-0707
D 220 . + . D: 220QBK-ND, J: 690700,
F: 9339299, RS: 707-7612
D 1 . + . D: 1.0KQBK-ND, J:
690865, F: 9339051, RS: 707-7666
D 10 . +
2, 6 10. D: 10KQBK-ND, J: 691104,
F: 9339060, RS: 707-7745
47 . + 14. D: A105657-ND, J:
254028, RS: 186205
10 . + . J: 29082, SF: C0M-09939,
F: 350072, RS: 249-9294
D 270 . +
31. J: 691446, D: CF14JT270KCTND, RS: 845-7577
11, 14 26. D: 160-1144-ND 160-1665-ND,
J: 34761 94511, F: 1855510, RS: 228-5972
826-830, SF: COM-09592 COM-09590
% = $ .
+ 1 4. D: 754-1492ND, J: 2125181, SF: COM-00105, F: 2290374,
RS: 861-4290
&
. +
10 12. J: 106526, A: 387, SF:
C0M-09469, F: 1716710, RS: 577-538, SS:
MTR102A2B
D
A 5 '. + 14. J: 51262, D: LM7805CTND, F: 9756078, RS: 918-1971
D
A 3,3 '. + 14. D: 497-1491-5-ND, J:
242115, F: 1703357, RS: 438-4885
, 1 \. + -
14. D: 1189-1324-ND, J: 94161, F: 8126933,
RS: 475-9009
10 \. + 14 15. D: P11212-ND, J: 29891, F:
1144605, RS: 762-1736
14. D: P10269-ND, J: 158394, F: 1144642,
RS: 762-1746
!
NPN TIP120. + 14 27. D: TIP120-ND, J:
32993, F: 9804005, RS: 808-0502
C
« », 9 '. + -
3.
9–12 '. + 14. SF: T0L00298, AF: 798, J: 170245, F: 1176248
C
3,5-5 '.
+ 13. AF: 771, D:
BC4AAW-ND, SS: 320180002
< -
. + 3 13. SF: PRT-13813
PRT-08483; AF: 258 2011
! A
(CR2032)
. + 13.
SF: DEV-10730 DEV-13883
PRT-00338, AF: 1870 1871 654.
Где брать компоненты и прочее?
Специальные компоненты
' . + 13. SF:
T0L-10285, F: 1015878, RS: 244-890
&. + 13.
SS: 109990013, SF: T0L-11702, AF: 468
-& . +
10 12. D: 365-1068-ND, RS: 654-8542
WS2812
(NeoPixels). + 13. AF:
2226, 2858 2859, D: 1528-1610-ND, J:
2247947, SF: BOB-13282, SS: 104990139
"
WeMo
Belkin. + 26. B: P-F7C027
]
>$ .
+ 29 30. SF: KIT13815
D . +
27. AF: 1512, AMZ: «uxcell DC 12V Open
Frame Type Solenoid for Electric Door Lock»
>
PowerSwitch
Tail.
3 , 29 30. SF: COM-10747, AF: 2935, PS:
240vac Kits ( 240 & . .)
, 4N35. +
29 30. J: 41056, F: 1244500, D: 1601304-5-ND, RS: 597-302. 3
SparkFun S: B0B-09118
Датчики
!
. +
2 3. D: 905-1000-ND, J: 150551, SF: SEN10264, AF: 182, RS: 708-1277
>
&
A . +
2, 8, 9 10. D: GH1344-ND SW400-ND,
J: 2231822 119011, SF: C0M-09337, F:
1634684, RS: 718-2213
!
( )
. + 8 9. AF: 377,
SF: C0M-10982 BOB-11722, SS: 311130001
(
400
Interlink. + 5. D: 1027-1001-ND, J: 2128260, SF: SEN09375, A: 166
591
'- ) USB. +
5, 21, 22 23.
\
( ). + 6. D:
PDV-P9200-ND, J: 202403, SF: SEN-09088,
F: 7482280
!
Hanwei. + 14. SF: SEN-09405, P: 1481,
PX: 60500009
&
GP2Y0A21YK
Sharp. +
12 14. J: 2150256, D: 425-2063-ND, AF:
164, F: 1243869, RS: 666-6564
N
HC-SR04,
SRF04 . +
16. SF: SEN-13959, D: 1568-1421-ND
GPS
. + 18.
AF: 746, SF: GPS-1275
• GPS Garmin GLO - https://www.garmin.com.
• GPS Bad Elf GPS Pro+
- https://bad-elf.com.
&
LSM303DLH
ST Microelectronics. + 19 20. AF: 1120, SF: BOB13303, P: 1250, SS: 101020081
D
. + 8 9. SF: COM-10443
BOB-10467
!
A DTH11.
+ 29 30. AF: 386,
J: 2245415, SS: 101020011
Разное
(
. D: 3M156065-ND,
RS: 120-6041, J: 2119718, A: 550 , SF: C0M10594, F: 1165068
H
18
"3 =. + 8, 26 27. = %
,
,
,
. D: 362204-ND, RS: 123-6835, F: 2301244
Приложение
592
'
"3 . D: 36-9300ND, RS: 274-5086, F: 2500400
"
1.
. + -
]+ +
+
" . + 2 3.
+
. + 5,
29 30.
. + -
5.
&
. + 5.
D& . + 6.
-
. + 10 12.
"
10 . + 13.
K
- & 10 . + 13.
+ + J
. + 14.
>
-
(IC-hook with pigtail). + 31. SF: CAB-09741 CAB00501
+
A 5 . + 31. AF:
1126, SF: DEV-11347
%
$ . +
31. AF: 116, L: 1220
%
$
. + 31. AF: 603, SF: DEV-11791,
L: 304
% . + 31.
]
+
31.
. +
Поставщики аппаратных компонентов
Следующий список содержит всех поставщиков аппаратного оборудования для проектов из текущего и прошлых изданий книги, которые продолжают заниматься бизнесом.
Abacom Technologies
Adafruit Industries
Abacom , ,
Ethernet/
TTL-Serial.
Adafruit
$
« » ,
AVR, MP3-
.
www.adafruit.com
sales@adafruit.com
www.abacom-tech.com
abacom@abacom-tech.com
Acroname Robotics
Acroname %
$ . 2
—
,
,
. * " % .
www.acroname.com
info@acroname.com
Arduino Store
7 Arduino
% Arduino,
Arduino.
store.arduino.cc
Atmel
Atmel
AVR, Arduino, Wiring,
BX-24 . & " Atmel Microchip.
www.atmel.com
Где брать компоненты и прочее?
593
Charley Chimp
ELFA
~ %, %, $
$ ,
" " ?
ELFA — " $
# + .
charleychimp.com
customercare@charleychimp.com
www.elfa.se
CoreRFID
Farnell/Element14
CoreRFID % RFID RFID.
Farnell $
4 . *
, Newark #3, $,
3 , Farnell
.
www.rfidshop.com
info@corerfid.com
D-Link
D-Link USB,
Ethernet Wi-Fi, Wi-Fi, 10.
www.dlink.com
sales@dlink.com
Devantech/Robot Electronics
Devantech
, $
, ,
,
.
www.robot-electronics.co.uk
sales@robot-electronics.co.uk
uk.farnell.com
sales@farnell.co.uk
Figaro USA, Inc.
Figaro ,
, ,
.
www.figarosensor.com
figarousa@figarosensor.com
Future Technology Devices
International, Ltd. (FTDI)
Digi
FTDI
USB/TTL-Serial, FT232RL, "
$ .
Digi XBee,
Ethernet.
www.ftdichip.com
www.digi.com
sales1@ftdichip.com
Digi-Key Electronics
Glolab
Digi-Key —
$
. X
% : ,
, , , , , .
Glolab $
,
-
, .
www.digikey.com
lab@glolab.com
www.glolab.com
Приложение
594
Gridconnect
Gridconnect
, Lantronix Digi.
international@jameco.com
custservice@jameco.com
Lantronix
www.gridconnect.com
sales@gridconnect.com
Lantronix Ethernet/
TTL-Serial: XPort, WiPort, WiMicro,
Micro .
Images SI, Inc.
www.lantronix.com
sales@lantronix.com
Images SI
$ . 2
%
RFID, , ,
,
$ , ,
$ ,
.
Libelium
Libelium
XBee
.
www.libelium.com
Linx Technologies
www.imagesco.com
imagesco@verizon.net
Linx , .
Interlink Electronics
www.linxtechnologies.com
info@linxtechnologies.com
Intelkink
,
.
Low Power Radio Solutions
www.interlinkelectronics.com
specialty@interlink electronics.com
IOGear
IOGear
. & ,
%
USB/TTL-Serial,
Powerline Ethernet.
www.iogear.com
sales@iogear.com
Jameco Electronics
Jameco $
, ,
,
$ $ .
www.jameco.com
domestic@jameco.com
LPRS , .
www.lprs.co.uk
info@lprs.co.uk
Maker SHED
Maker SHED
MAKE % . & "
, -
.
www.makershed.com
help@makershed.com
Maxim Integrated Products
Maxim ,
, $ . 4
Где брать компоненты и прочее?
Dallas Semiconductor.
# $
,
, . .
www.maximintegrated.com
info2@maxim-ic.com
Microchip
Microchip
PIC. 4
" . 4 Atmel.
www.microchip.com
Mouser
Mouser
$
#3.
& %
,
$ , — , ,
. X
-
USB/TTL-Serial FTDI.
www.mouser.com
help@mouser.com
NetMedia
NetMedia
BX-24 Ethernet
SitePlayer.
www.basicx.com
siteplayer.com
sales@netmedia.com
Newark/Element14
Newark $
#3. *
, Farnell/Element14 4 , $,
3 ,
595
Farnell Newark
.
www.newark.com
order@newark.com
New Micros
New Micros
. 0 USB/XBee, "
XBee Digi. /
"
XBee .
www.newmicros.com
nmisales@newmicros.com
Parallax
Parallax Basic Stamp
Propeller. 0 %
, ",
,
" ,
$ .
www.parallax.com
sales@parallax.com
Phidgets
Phidgets
.
www.phidgets.com
sales@phidgets.com
Pololu
Pololu
$
.
www.pololu.com
www@pololu.com
Приложение
596
RS Online
SparkFun Electronics
RS Online —
$
, "
.
SparkFun
$
. 0
,
" , %
.
www.rsonline.com
general@rs-components.com
www.sparkfun.com
customerservice@sparkfun.com
Samtec
Samtec
$ . &
% ,
$
,
.
, ,
www.samtec.com
info@samtec.com
Seeed Studio
Seeed Studio
$
. 0
$
,
.
www.seeedstudio.com
order@seeed.cc
Symmetry Electronics
Symmetry
ZigBee Bluetooth,
Ethernet/TTLSerial, Wi-Fi,
$
.
www.semiconductorstore.com
TI-RFID
TI-RFID
RFID Texas Instruments. 0 RFID
.
www.tiris.com
Trossen Robotics
SkyeTek ,
RFID. 0 Jadaktech, OEM-
.
Trossen Robotics %
RFID , % ,
Interlink,
,
Phidgets, RFID, % RFID.
www.skyetek.com
www.jadaktech.com
www.trossenrobotics.com
trsupport@trossenrobotics.com
SkyeTek
Smarthome
Smarthome
%
,
% — ~10, INSTEON.
www.smarthome.com
custsvc@smarthome.com
Где брать компоненты и прочее?
597
Программное обеспечение
Большинство используемого в проектах этой книги программного обеспечения распространяется с открытым исходным кодом. Многие из включенных в список программных платформ в
этих проектах не задействованы, но, в целом, весьма полезны.
Arduino
CoolTerm
Arduino — $
AVR,
Processing. 7 Windows, Linux macOS.
> (
)
Windows macOS. 3 9 7
(Roger Meier).
www.arduino.cc
freeware.the-meiers.org
Asterisk
Cygwin
PBX1
+ Linux UNIX.
.
www.asterisk.org
AVRlib and avr-gcc
> C
AVR. 7 Windows,
Linux macOS
avr-gcc.
www.nongnu.org/avr-libc
GNU avr-gcc — $ C AVR. 0 Windows, Linux macOS.
Windows "
AVR Studio (www.
atmel.com/tools/atmelstudio.aspx).*
Linux :
www.atmel.com/tools/atmelavrtoolchainforlinux.
aspx, CrossPack AVR macOS —
: www.obdev.at/products/crosspack.
*
avr-gcc
Arduino, $, $
, avr-gcc.
ble-central
7 Bluetooth LE
PhoneGap Cordova.
+
POSIX
Windows. Windows
Linux.
www.cygwin.com
Dave's Telnet
telnet Windows.
dtelnet.sourceforge.net
Eclipse
# IDE2
. 9 % ,
% .
+ Windows, Linux macOS.
www.eclipse.org
Express.js
> JavaScript node.js
- .
expressjs.com
GitHub
~ git —
.
+ git github
" .
github.com/don/cordova-plugin-ble-central/
git-scm.com
github.com
1
2
PBX, Private branch exchange — .
IDE, Integrated Development Environment —
.
Приложение
598
Java
noble
` . 7
Windows, Linux macOS,
. Sun Microsystems,
Oracle.
+
API Bluetooth node.js. = API
Bluetooth LE.
http://www.oracle.com/technetwork/java
Node.js
JavaScript
JavaScript
.
> "
. JavaScript — HTML CSS —
, "
+
. JavaScript, node.js,
.
developer.mozilla.org/en-US/docs/Web/Java
Script
libnfc
+
API NFC. 7
Windows, macOS POSIX.
nfc-tools.org
Max/MSP
- . ,
. Max
MSP
Jitter
. 7 Windows
macOS.
www.cycling74.com
github.com/sandeepmistry/noble
,
-
nodejs.org
Nodemailer
> $
node.js.
nodemailer.com
node-serialport
>
node.js.
github.com/EmergingTechnologyAdvisors/
node-serialport
npmjs.org
~ " Node Package
Manager. # %
node.js .
npmjs.org
onoff
> node.js / " .
www.npmjs.com/package/onoff
p5.js
7
( ) MQTT.
Windows, macOS Linux.
JavaScript Processing.
. ~ %
.
mosquitto.org
www.p5js.org
Mosquitto
Где брать компоненты и прочее?
599
PEAR
9
%
PHP. # %
PHP.
http://pear.php.net
PHP
` ,
- . #
HTML.7
Windows, Linux macOS.
. 9
Max — 7
(Miller Puckette). 7
Windows, Linux macOS.
http://puredata.info
PuTTY SSH
telnet, SSH
Windows.
www.puttyssh.org
www.php.net
PicBasic Pro
QRCode.js
> node.js QR.
BASIC PIC. + Windows.
https://github.com/IagoLast/qrcodejs
melabs.com
Dan Shiffman's Libraries
PhoneGap/Cordova
= (Dan Shiffman)
Processing
p5.js. 0
" .
PhoneGap
HTML, CSS JavaScript.
Cordova $
PhoneGap.
Adobe.
https://phonegap.com
https://cordova.apache.org
Processing
`
, ,
" % ,
" , .
0
Java,
Windows, Linux macOS.
www.processing.org
Puredata (PD)
q
-
. ,
https://github.com/shiffman
www.shiffman.net
Tor
> , " " - ,
.
www.torproject.org
Tracking.js
> node.js .
www.trackingjs.com
Twilio
" IP- .
API, "
.
www.twilio.com
Приложение
600
Visual Studio
ws
0
IDE
Microsoft Windows.
& "
Community Edition —
,
,
.
> WebSocket node.js.
www.visualstudio.com
Wiring
# AVR,
Processing. 7
Windows, Linux macOS.
www.wiring.org.co
https://github.com/websockets/ws
XCode
0
IDE
Microsoft macOS
iOS. ,
,
,
.
https://developer.apple.com/xcode/
ПРЕДМЕТНЫЙ УКАЗАТЕЛЬ
3
OAuth2 163
3
MK20 USB 570
USB/TTL-Serial 96, 99
3
IP 144
144
% 145
"
146
145
144
145
144
localhost 148
MAC 144
144
144
144
148
148
% "
148
3
416
3
RFID 457
3 38
36
36
3 73
3
267
3
144
3 477
3
93
C
> 391
>
38
>
ArduinoHttpClient 221, 468
BLEPeripheral 571
323
Bluetooth 319
body-parser 159
Button 263
CurieBLE
323
CurieIMU 421
dgram 342
Encoder 263
ESP8266WiFi 205
L3G 428
libfreefare 461
461
libnfc
461
libnfc-dev 461
LSM303
424
mqqt.js 529
MQTT 522, 523
MulitCameraIR 295
multer 185, 535
NDEF Arduino 470
net 191
noble 329
node.js
multer 180
nodemailer 162
onoff 481
p5.js 55, 274
PN532 470
Processing
net 188
video 188
querystring 546
SoftwareSerial 127, 132, 134, 170
Stream 208
208
TextFinder 208
tracking.js 451
WiFi101 206
, Client 206
, Server 206
WiFi101 205
>
355
355
>
354
>
381
>
421
> " 267
>
NCSA Mosaic 500
Tor 499
> MQTT 517
> MQTT
Mosquitto 526
'
&
51, 152
dateServer.js 154
& -
DCS-960L 534
DCS-5222L 534
& -
If This Then That 468
&
311
&
- 43
&
" 293
& " 420
& " 360
&
69
& 363
& 64
64
+7 64, 101
Предметный указатель
602
2
305
q 421
q
q 421
q
q
q
393
38
334
54
!
=
=
36, 38
36
36
169
TAOS TCS34725 447
LSM303 423
DHT11 520
=
112
=
% 452
= 341
= 73
= 122
= 527
=
301
= 38
= node 52
#
2
Connection 273
HTTP 153
Upgrade 273
114, 150
$ 163
2
82
2 426
2
NDEF 463
463
2
HTTP
156
155
157
HTTPS 416
2"
366
+
SSID 207
Bluetooth LE 323
323
+
441
+
35
+ 258
+
404
+ 300
+ "
366
+
API
- 220
API REST 547
I2C 64
navigator 414
SPI 64, 129
28
28
$ 28
+
53
Ethernet 36
USB 35
USB/TTL-Serial 98
SIM 550
258
Stream 556, 557
.find() 556
.findUntil() 556
.timeout() 556
[ 301
152
51
36, 38
36
36
258
148
arp 147
arp -a 147
ifconfig 79
iwconfig 79
iwlist 79
LoRa.crc() 318
ping 147
Processing
image() 189
ssh 44
sudo 79
traceroute 361
49
42, 43
143
151
Groundlabs 507
Twilio 538
423
Pi Zero Camera 534
30
30, 35, 75, 76
Raspberry Pi 76
Raspberry Pi B3 76
Raspberry Pi Zero W 76
30
%
30
31
30
37
. &.
157
420
477
477
478
420, 426
421
<
_
_
369
421
Предметный указатель
_
258
258
_ 84
"
7 420, 423
7
421
7
36, 38
7 195
7 % % 253
7 % 143
IP-
145
" 150
7 145
7
381
355
7 ArrayList 255
7
206
Homebrew 526
7
POST 158
request.query 156
sendPacket() 345
Serial1.print( 124
Serial1.println( 124
Serial1.read( 124
Serial1.write() 124
serialEvent() 111, 116, 121
Serial.print() 109
Serial.write() 109
server.get() 157
server.post() 157
7 432
121
7
396
396
396
7 301
7
ATmega 328T 127
Atmel 16U2 99
ATtiny84 127
BASIC Stamp 98
603
7
Arduino 61
% 66
Arduino 101 63, 65
Arduino MKR1000 63, 65
BLE Micro 63
BLE Nano 63
ESP8266 63, 65
ESP8266 Thing 66
7
30
8-
60
32-
61
ARM 61, 63
30
7
30
7
75
7
ESP8266 99, 205
FT232RL 98
7
408
7 OSI
93
Ethernet 150
IP 150
150
150
7 143
SM5100B 550
7
BLE Central 575
BLE Nano 569
Bluetooth 122
WiFi
ESP8266 204
WINC1500 204
WINC1500 205
7 122
% - 217
7
" 249
7 35
7 302
302
302
]
*% % 253
*
421
*
82
*
419
*
317
*
270
* " 293
*
IMSI 550
- 152
$. 152
*
152
152
0
93
32
93
0
bash 560
49
0
module.exports 483
0
31–33
0
30,
75, 76
0
Processing
Contribution Manager 188
583
0
IP- 145
0
355
355
0
82
0 441
0
517
0
Electronic Frontier Foundation 419
0 420
0 35, 84
DSO Nano 84
0
420
" 420
" 420
Предметный указатель
604
" 420
420
" 420
420
420
0 %
/% 318
0 258
0
426
0 355
0 "
35
HTTP 155
RFID 456
292
369
426
request 155
response 155
Processing
41
54
426
426
USB/TTL-Serial 35
" 115
BLE Nano 570
ESP8266 Thing Dev 205
Feather ESP8266 Huzzah! 205
MKR1000 204
node.js 50
36,
38
355
%"
72
478
145
304
426
"
72
$. 152
152
152
57, 59, 71
, Mac Os 71
, Windows 71
134
152
64
64
" 230
120
57, 59, 71
, Mac Os 71
, Windows 71
134
36, 38, 74
NMEA 412
267
292
,
64
29, 292
apt 81
Bluetooth GPS 413
PhoneGage Desktop 559
PhoneGap Developer 559
404
REST 234
84
38
37
37
35
Camera 188
Cheese 188
CoolTerm 57, 59
curl 80
Cygwin 44
forever 195
GNU screen 58
less 47, 48
48
nano 47
48
netcat 346
OpenSSH 44
Photo Booth 188
Processing 39
PuTTY 44, 45, 58
wpa_cli 79
159, 274
134
42
OpenSSH 44
PuTTY 44, 45
42, 43
ANT 307
ASCII 105
Bluetooth 122, 307
DHCP 150
DNS 150
EDGE 549
GSM 549
Hayes AT 363
HTTP 153
I2C 421
IMAP 162
LoRa 307, 310
LoRaWAN 310
MQTT 514, 516
517
517
NFC 459
NMEA
412
NMEA 0183 410
OneWire 520
POP 162
RFID
Mifare Classic 460
Mifare Ultralight 460
RS-232 97
97
SIP 537
SMTP 162
Предметный указатель
SOAP 468
TCP 150, 252, 341
TLS 419
UDP 150, 253, 341
webSocket 272
webSockets 253
WiFi 307
XBee 362
ZigBee 307
112
32
USB
95, 96
;;_
95
29
29
29
112
Bluetooth
GAP 319
GATT 319
SPP 319
174
HTTP 157
(
9
441
9
TwiML 540
9 %
46
47
9
DB-9 97
D-sub-9 97
ICSP 129
« » 35, 38
35
9
38
%
36, 38
9
Arduino Uno rev3 66
9
396
396
396
605
9
81
9
35, 37
9
317
9
169
9
%" 72
" 72
9
36, 37
9 . &. %
9 420
D
#
157
#
69
101
101
#
341
#
354
C 253
341
C
93
C TCP/IP 253
# 151
#
DNS 150
node.js
, 54
152
dateServer.js 154
252
30
51
#
SMS 544
#
419
416
#
416
#
30
204
#
31, 32
32, 33
# 89
142
142
304
305
#
408
129
#
270
110
#
OAuth2 163
UMTS 549
Wireless E91 391
OAuth2 163
" , Hue 477
Arduino
& - AirNow 223
Bluetooth Central PhoneGap
576
Camera 189
Processing
& 268
q 415
2 " NDEF
Arduino 471
+- 399
HTTP NFC
WeMo 473
MQTT 520, 523
0
557
0 430
110, 111
108
& - AirNow 221
# HTTP/HTTPS 417
#
TwML
MQTT 542
# " 208
Предметный указатель
606
#
CurieIMU
427
# -
571
# LSM303 L3G 428
X " 564
X 402
X 103, 104
' QR, HTML5 454
' " NDEF
Arduino 471
# 40
#
71
421
#
53
#
310
# "
420
420
420
#
307
#
416
# 252
#"
NDEF 463
360
#"
% "
146
#
Arduino IDE 1.8.2 62, 67
Processing 39
#
7 69
7 71
174
#
IEEE 143
IEEE 802.3 143
IEEE 802.11 144
IEEE 802.15.1 144
LTE 549
E.164 545
# 391
# 204
# 37
# 420
#
ageCheck.js. 156
ageCheck.js, REST 237
AQI client 232
aqiClient.js 233
dateServer.js 154
getParameters.js 155
js
# 155
mailer.js. 162
node.js 54, 180
# UDP 343
p5.js
56
restAgeCheck.js 237
wsExpressServer.js 274
& - / 490
& -
494
2 " NDEF 465,
483
HTTPS
API SMS
Twilio 546
9
582
# Bluetooth LE noble 330
# HTTP/HTTPS 488
# webSocket
Express 274
#
497
#
TwiML
548
# +X# 405
# , "
IP- 500
#
528
#
node.js, " 535
X GPIO 482
' %
" NDEF 466, 486
# 395
#
NFC
SCL3711 460
PN532 468
%
; ARP 147
; 420
; 112
;
% 514
;
cd 46
cd,
46, 47
exit 49
logout 49
ls 45
mkdir 46
pwd 45
rm 46
45
; 35
;
GPRS 549
PhoneGap 558
uPnP 468
;
142
142
304
305
; 38
IRF520 36
TIP120 36
; 410
; 84
; 409
N
X3 64, 134
$ 134
X 421
X 431
X
OpenSSH 44
PuTTY 44, 45
42, 43
42
Предметный указатель
X
Tor 499
X
64
X "
Hue 477
152
X " 230
X
404
X
OSI 93
Ethernet 150
IP 150
150
150
X
421
X
libfreefare 461
libnfc 461
355
\
[
package.json 195
59
[
% 46
47
[ 356
[
IP- 144
MAC- 144
NDEF 463
CSV 229
TSV 229
[
426
426
[
307
[
.addAttribute() 325
available() 358
broadcast() 278
compare() 354
.connect() 267
connect() 207
connected() 207
607
connectToServer() 225, 267, 282
.c_str() 222
digitalPinToInterrupt() 267
find() 208
findUntil() 208, 226
fs.readFileSync() 417
.get() 158
getCurrentPosition(), 414
httpGet() 333
http.request() 233
http.stop() 226
IRPulse() 299
JSON.parse() 232
JSON.stringify() 232
keyReleased() 256
map() 117
movieEvent() 269
newClient() 277
onReceive() 316
parseFloat() 208
parseInt() 208, 226
parseMessage() 281
parsePacket() 358
.post() 158
printWiFiStatus() 243
Processing
Capture.list() 188
loadStrings() 183
readButtons() 266, 282
readBytesUntil() 208
readEncoder() 266
readMessage() 255, 278, 280
readMessages() 256
readString() 208
readStringUntil() 208
request.end() 233
response.on(‘end’) 233
scanNetwork() 208
scrub() 269
sendIntro() 279
sendJsonMessage() 283
serverEvent() 256
setLeds() 226
setMeter() 226
shutterClick() 298
stop() 207
String() 222
tcpSocket.connected() 265
toCharArray() 222
watchPosition() 414
WiFi.begin() 211
WiFiClient.Connected() 226
WiFi.encryptionType() 209
WiFi.macAddress() 209
WiFi.scanNetworks() 209
WiFi.status() 226
" 267
267
~ 143
Z
419
Z
for-next 41, 42
Z
72
423
'
311
' " 115
H
113, 114
66
"
"
146
"
148
-
(+7) 217
SMS 511
514
451
452
QR 452
36, 38
{
/
" PHP 162
163
/
TwiML 540
/
X3 134
/
408
Предметный указатель
608
H
P
`
TwiML 538
`
53
`
CSS 54
JavaScript 50, 54
53
` 305
`"
249
HTML5 54
HTTP
153
156
157
153
PhoneGap 558
PHP
$ 162
Processing 39, 40, 41
42
draw() 41
setup() 41
41
41
41
if-then 41
for-next 41
A
ASCII 110
B
Bluetooth 89, 121
Smart
LE. &. Bluetooth
LE 123
BlueMan 123
Serial Port 123
Bluetooth LE
323
323
C
Chip Select. # SS
CS. &. SS
D
DHCP
150
DNS
150
150
I
IP-
143, 144
144
% 145
145
144
144
IP- 510
J
JitterBox 136
L
localhost 148
M
MAC-
144
144
144
MISO 129
MOSI 129
MQTT
Mosquitto 526
N
Ethernet
36
NDEF
463
463
" 463
NFC
SCL3711 460
PN532 468
G
O
GPS 395
OpenSSH 44
E
R
Raspbian 77
78
raspi-config 78
78
RFID 441
457
456
Mifare Classic 460
Mifare Ultralight 460
RS-232 97, 98
S
SCK . &.
Sideloading 558
Slave Select. &. SS
SMS
544
% 511
SS 129
T
TCP
150
U
UDP
150
Unicode 110