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

Том Иго

УМНЫЕ ВЕЩИ
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 (англ.) © 2017 Maker Media, Inc.


ISBN 978-5-9775-3970-8 (рус.) © Перевод на русский язык, оформление, ООО «БХВ-Петербург», ООО «БХВ», 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
Оглавление 9

Глава 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


ПРЕДИСЛОВИЕ
Несколько лет тому назад Нил Гершенфельд (Neil Gershenfeld)
написал толковую книгу, названную им «Когда вещи начинают
думать». В ней он рассматривает мир, в котором обыденные
вещи и устройства наделены вычислительными способностями,
то есть мир сегодняшний. В частности, там обсуждаются
последствия обмена между такими устройствами информацией
о наших с вами личностях, возможностях и действиях.
Книга хорошая, но ее название, на мой взгляд, — неудачное.
Я бы назвал ту книгу «Когда вещи начинают общаться»,
поскольку — давайте признаем это — даже самые
захватывающие идеи чего-либо стоят лишь тогда,
когда их обсуждаешь с кем-то другим.
И моя книга, подзаголовком которой мог бы стать девиз
«Пусть вещи общаются!», — рассказывает, как создавать вещи,
способные общаться друг с другом, и как предоставить людям
возможность использовать эти вещи для общения между собой.
12 Предисловие


      &
  
 

 

       
 - $ 
   :
 ,   -


   
 
  -
, 
 , 
,    (
    

 

   -    ) 
%  . . ' -
  ,  
 

  

-      $ 
   
 ,

 
     .   
 
       
   ,     -      ,      
     ,        
     "  
 
-
 
 —  ,  
   ,         "  -

 .     
  
- % . *     . +   

    — ,  "     
 $ 
  
 
. 

     -  
    . 
  ,  
-
       
  
     
    ,  
   . 

   - 
     . /   
  
 
,   
 
  -

 

  — 
    ,   
1. 0     
 -

  
                -
 "      (  ,  -  ,   
    

    " 
   
- 
, —     
   
 -
). # , 
      ,   ,    
, 

 $ 
  -
  , 
 
, — 
  ,     %        .
          
- &          ,
. 

    $ -  
 ,       -
,      
 "   " . /    
   
-


  
%   
-  
  ,     
 ,
 

   .   "
  " .
1
& 
  : «object-oriented hardware».

Для кого предназначена эта книга?


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

0    
 , 

- 2        
 


    "     
 , 
    


  
%
      ,  
  -    
    "  
 
-

,  -

 
 

— 
 ,        
 -

%  
,  
   . #  
 , 
    -

 "        
 .      
 ,    
Предисловие 13

"  "    %. +   
       

$ 
      -     
 ,   
  
 
  
   
-  
   $ 
  
-
   (     
    , $    
  . 0 


 ) 
    
          

  

 %
      -        - , 
 
-
 , 

  
 - "   


   
  -
   


   
 -     
 .


.
&
 ,     , 
 
-
3  ,  " 
 
- 
           ,  $

 

, 
  -    ,  ,    ,  " -
%      $  
  -  . &  
  

  
    
  
" Bluetooth    TCP/IP,   


 
 ,   " 
    
    

 Ethernet.
   
   ,     
- 9 
        
 
    
. 4    -   
   
  , -
 -, 

,   BASIC Stamp2     . 0  
  "
 LEGO Mindstorms3,   ,  %
     -
 
 

  , 

    %
2
7
 

%  
 
  
      . ; 
 


   BASIC (PBASIC),  
 
 ROM.

    ,   
3
 

( 

      $ 
 -        —    " -
 )    


 
    "     — 
( . http://ru.wikipedia.org/wili/LEGO_Mindstorm).  
     .

Что вам нужно знать?


Чтобы извлечь для себя как можно больше пользы из этой книги, вам необходимы базовые зна-
ния аппаратной и программной части микроконтроллеров, определенное представление об
Интернете и доступ к тому и другому.

7     ,  




    
 
   , -

 

, 
   - 
  ,      %   
   


,   ,     


  -

 $      
  . &   
  
   
-
         
- , 
     ,   

 

  
 

  
- 
     
  
 .
   
. ;     
      

  4   
     
-
 $ 
 
     

,  
 ,   
 
   
  ,  
 - 
   ,     


. 4   
     -  $   
    -
     
 — $     . . + 
   
  
-
  
   
     "   «Physical Computing: Sensing
14 Предисловие

and Controlling the Physical World»4 ( -    $  ,  
   -
 Thomson),       =    
 


  Processing,
0’#  (Dan O’Sullivan). &     
  
       -
      $ 
 , 
 
-   : www.processing.org. ;    -

  
 
    - 
  
   "  -
 . +   -     $ 
   
 . #
 


-
  
    "    -   Processing    
 , 
  
,
 
   "    


  , -
     -
   . 

 % $   , 
&                
    " , 

   7  >  (Massimo Banzi)


  "   
«Getting Started With Arduino»    
  .
Make.

 $,           
 

  



 . 4        


 . / 

-
4
 
  , ,     ,
 $,   
   
     ,
   
     ,  
   
     , "  -
           
- ,  - 
       
     -
       .  , 
    
.

Содержание книги
В книге представлены основные принципы создания объектов сетевой структуры, а также при-
водятся примеры, их иллюстрирующие. Каждая глава содержит инструкции по созданию рабо-
тающих проектов, основанных на изложенных в ней концепциях.

?  1. 2       
- •  3. 
        -
  


 ,        — + 
. 2  -
   ,  
  



    
 ,  
«Hello World!» («2
  , 
!»)   
 ,     -
  .     $  
 . 9 -

  " ,  "   -
?  2. 
         
  
 
 
 -
    ,   
 
,         
 
   
      -  + 
 ,  
   
 
"  
 
. 2 
 
  
  "  . 0   -


 , 
   -  
   

  -


  ,    , 
 
 + 
     -
     $      -      .
    
  
 . &  


  ,     ?  4. 2     
 -

   , 
   
-     
 ,   
    
  
   - # .        

             #  "
 

 

  
   -      
,   -

   
  Bluetooth.   
 

  -

,
#
  
  
  ,     
 -
    
     
.     
 .
Предисловие 15
?  5. # " %    - 
 $      -
   #  —
 
  -   
    
  
    , 
       —    " -
     . 2   -  
.
% 

 

,  

?  8. 2 
 

      
 ,
 
   
     -
 "     # .  
  
     
 -
 $ 

  "     

  ( ), 
  

   
 
,   -

       -

 

, —    -
 
         
, 
   
  
 .
  
  
 
   


. ?  9. 2 
 
  

       
?  6. 
       

 
  . +     
 
  . 0  

 

        


   
  , -
 
     
     
  . 2 


 . * 
     -
  
 % 
 , -
  
   

    
" 
 $
 «Hello World!»
 
 .
(«2
  , 
!») 
 
 . ?  10. 2 
 
 -
          , 
?  7. 2        
-
     "  
 , "   " -
    ( 
 )     
      ,
 
-
 .
      5. /    

   "  
 — &    
    
-
  
 UDP ( + 
)  
          
-
 802.15.4 (  
   ).  ,      ,  -
&      -

, -  
     

+ 


  " 
 "  ,  -  
  .

Приобретение деталей и компонентов


Для реализации проектов, описанных в книге, потребуется много деталей и компонентов,
вследствие чего вам придется познакомиться с их поставщиками. Поскольку в моем городе нет
больших розничных центров продажи деталей электроники, я покупаю все мне нужное через
Интернет. Если вам повезло, и у вас есть возможность покупать необходимые детали в обыч-
ном магазине, тем лучше для вас. В противном случае познакомьтесь со следующими интернет-
поставщиками:

Jameco (http://jameco.com), Digi-Key (www. com), 


  
 -
digikey.com)  Farnell (www.farnell.com) —  , 
     
   
$
   "   $ 
-
 
 
 .  -
, 
"        " 
  


.
 
    . 3   ",  4     -  ,
SparkFun (www.sparkfun.com), Adafruit (www. 
  
%   ,    $  
adafruit.com)  Seeed Studio (www.seeedstudio.    .
16 Предисловие

X ,     


 + 
       
   
 ,  -

    
   ,   -     
  -    -
      "  
-     
     
     

    -  -   %  
. #
 , 
. ;    

 - 
          % -
     $     . 0   
    "     
 ,        - , 

  .

Использование примеров кода


Эта книга предназначена для того, чтобы помочь вам реализовать свои проекты. Соответственно,
код из нее можно использовать в своих программах и документации без необходимости запра-
шивать какое-либо разрешение, если только речь не идет о коммерческом воспроизведении
значительного объема кода.

*

,     
 -    ,  
,    ISBN  -
   $     



- . *

: «Making Things Talk: Practical
%  
 ,   
 
 
- Methods for Connecting Physical Objects, by Tom

    CD-ROM 

    Igoe. Copyright 2011 Maker Media, 978-14493-
   OYReilly

%  
  . 9243-7»5. 4   
  ,   -
Z
     $  ,  ,    

      


%  
 ,     -
 
  
     -
               


%  ,   
  
 
 

% .   $ 
 $ 
   

 permissions@oreilly.com.
7   
 
   - 5
&    "  
 $   
     
 
  
 
    
   
    
$  . [
     -  .

Использование примеров схем


Для сборки проектов из этой книги вам придется разбирать или даже ломать те или иные устрой-
ства и нарушать условия их гарантии. Если вам это не по душе, закройте книгу и займитесь чем-
либо другим. Эта книга не для тех, кто дрожит от мысли, что если они разберут вещь, то не смогут
собрать ее обратно.

&
 ,  
         
        
-

    ,       
     
.
  
 
    

-
 
     
 *      ,  
  

 
    .  
   $   
    
 
     
        . ;    , 
-
    —  

   
  
  "  ,   
 ,
        
 
 . $
 
  
    -
0       ,         , 
  , 
Предисловие 17
$ 
   
     
-     - " , 
  ,

 
,  $  
 
-      
  $  -
 . 4   

 
       .

Примечания ко второму изданию


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


           
-      
  Arduino,   -
  "   ,        ,  Arduino     -   -
    "  
 . _   -       
 ,
                 $ 
  
   
-
    -  
    ,  ,      
    
 $            - 
     ,  
 


. = 2005   
   
 -    . ` ,  
%  
,   ,   
    $       
 
 
   
 ,   ,      
 -
        «     ».  
 Arduino
 
 
   
&  "  
   , 

,  
       . /  
 

Wii  Kinect — $  
 ,   "     
    -


 %
    -  
  , %,   
-
    ,     
        
 , 


. #    
             -
$ 
   
 , %   -     . '   ,  

    # . 
    $ 
  
 , -

 
 
 , 
   %
   $      $  
,   $ 
-
    %  
 ,   "    
    .
  " ,  $    -
%
 
 
      
  
     %   
    . _ 
    -  Arduino    
,  

  
  Kinect  
,   
            
   
 , "  
 -           
      . 0    


      -

  
  

 Wii,  
 - , —    
    " -
   
      
-     %   . 0 
 . _ 
   ,     
  
        
         $ 
 -   
  
   -
  
 ,    $.  , $         
18 Предисловие


 
 ,  "    
   
   
  -
$ 
        
-  

 ,  
 $  -
 . &   ,  "   
     ,    ,    


 
%  ,   
,   
    ,   
 . >
   
"   . # - , 
  $ 
%  

 ,  -
%      
%   -  
        -
   , 
   «   -  
   % 
 
. `   ,
 "». ;  
  ,   $          
   
  
  - 
        
.

Примечания к третьему изданию


Переписать эту книгу в предыдущий раз меня побудили две обнадеживающие тогда тенденции:
развитие движения за открытое (open source) оборудование и рост культуры прямого участия,
в том числе и в деле создания интерактивных устройств. Тенденции, которые толкнули меня
переписать книгу в третий раз, не столь оптимистичные: распространение бытовых устройств,
которые собирают данные обо всех физических аспектах нашей жизни, а также постепенное со-
крытие информации о том, куда в конечном итоге эти данные попадают и для чего используются.
Такие устройства предлагаются на рынке под ширмой продуктов и услуг, обеспечивающих нам
простоту и удобство их использования. Указанные тенденции и их последствия требуют внима-
тельного рассмотрения. Понимание технологий, лежащих в основе этих тенденций, поможет нам
принимать обоснованные решения о том, какую роль им следует играть в нашей жизни.

&
 ,         " ! 
 RFID
 
 !  -
$   ,     (
     ## 




  -
 %     ),    + 
 ,    
  ! 
 
  -
 " . + ,  "    $  ,  #
 
!   ,
#

 

  , 
  
   ,  
».
      
  $  -
0      ,   -
. q
,  
  «+ 
  " »

,      
   
  
   1999     3% 
%
      , 
(Kevin Ashton), 

  
 Auto-ID
%  % ,   ,
7         .
        
,  

&   
 «That “Internet of Thins” Thing»6
 
   ,    
-
(www.rfidjournal.com/articles/view?4986)  -
    .

"      ,  %  -

     
  + 
   
- +   ,  3%   
     . =  
 ,  
     % ,
       
"-   ,  
     -
  ,       
   -
,  $ 
  
  .
  $  . 0 
 ,      + 
    
 -
$  «     
  
  
  %   -
     
  

,   ,  
 ,  % —  -
 
 


,  
- " ,  ,   
  
 
     ! 


.  

%    , —   
6
'   
  

 : «'  % $  

     %  % 
“+ 
  " ”».   
      .
Предисловие 19
/    ,      
,   
  
. #  2016  — 
   ,   
 ,       Mirai      

 ,   
     % 
     
 —
 %  
   $  .   ,  + 
 % -
  ,  
  

   "  
 ,        

   
    , 

. *
      -
 $  
%   %  .   ,   
  
  
    %     ,  
7 
  Nest   ,   

          . &  "
 
,    
  
  ,     + 
, -
,     
    "   Hue        
    -
       "  ,   -        ,  "

"   ,      
-        . ~    
 

 "  Alexa    #       $  ,   -
 
,     
 %.
       -
7 
,   
  $ "     .
,    «
     ».
* «» — $       , '    + 
     
    . ' ,  $ 
%-  ",  $      
 -




, 
  " -   
   ,       
, 
                 -
 % . ` ,         ,    ,  .


   $  % ,    =  
   

  %-
%  , 
 $  
   
 %
     -
 , 
  
    -  , 
%    
  
 
 
.  
    . ~  -
   
    
-
` ,    ,  
 $  ,  
,      


 
  

  %   $   ,     
 
-
  ,    
 $  
- 
"  
    
.

,    $    .  3% 
: «$   
 #


$ 
        % 
-  ! 
, 

». / 
 %
    « »        ,   
%  


    
 . + 
 (& 
 -   %   ,   #
.
 ,  
  # )  
 
 
-
     

   
,
  
 IP7  HTTP8. &   - О программном обеспечении


   $  
, 
   # 
  
      
  « »  , "-  

 
 
 
-
  .  "     .

2  , 
% %  
   * 

 , 
   


   $  , + 
   
    ,     -
       ,       . =
 —   Arduino
7
 Processing — 
   ,
Internet Protocol —    
 + 
.
8
Hypertext Transfer [Transport] Protocol — 
 
-    " 
     
 
  . 
 ". & 
,     
20 Предисловие

 
    - 

 
 , 
  $     
 Arduino 101


   -      -  MKR1000. >%   
   
  / %  
.      
   Arduino
Uno,  
   
 
+        
  
     . = 
   -

 " gitHub  
 https://github.com/   
%      , -
tigoe/MakingThingsTalk2    
    Arduino,       -
 . + "       -  
    
 

 ARM
    www.makingthingstalk.com. Cortex-M0  ESP8266.

   

 
   
 -
Об используемом оборудовании  

       Linux. = $
'
          - 
      
 Raspberry Pi,

     
 ,  %  
     
     
 

 - 
   
 BeagleBone.

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

`  %        
   ,  " 
 


  
      9     .
     Tisch10 *-
 
 
  —   ,     - 7   = 0Y# , 
-
        %      

,    
"        .      ,     -
+        
 
 % 

%      
-
«#     », 
 
   $     



      . `   ,  -  

  
     -
    
   $ -  . 0        
 ,
     
     -            
 
  
  .
. >%   $   
 -
      = . + 
 -
0     9  >€
 (Red Burns)  
         ,  
    
     % .

  $  . 0   
    ,   
  , * 
    $      

%   
"    
  
-  %   "  -
 
  . 0  

    
 ,    
   ,
  
   ,     
    .
  
    , 
9
& 
  : «Interactive Telecommunications Program». &    , 7
    (Marianne Petit),
10
& 
  : «Tisch School of the Arts». $ 
 (Clay Shirky), =$ $ 9
Предисловие 21
(Daniel Rozin), =  (Dan Shiffman), Hebron), _ % ~  (Liesje Hodgson), ;
 &$ /
 (Shawn Van Every), >   q  (Todd Holoubek), =
  = 
   (Benedetta Piantella), 7  (Mimi (Jeremiah Johnson), 
  (Craig Kapp),
Yin), /  $
% (Allison Parrish), q
  

 (Peter Kerlin), $   

>
- (Gabriel Barcia-Colombo), _ (Kacie Kinzer), 9 

 (Raffi Krikorian),
= (Luke Dubois), 
 = (Katherine =  _ (Jihyun Lee), 9 7 (Rune
Dillon), *$  ~$ 
(Nancy Hechinger), Madsen), 3 7
 (Adi Marom), 2  7
%
7
  2
 (Marina Zurkow), † -7
 (Zannah Marsh), #
 7 (Surya Mattu),
q (Jean-Marc Gauthier), =
 3 
 7 (Carlyn Maw), 
 7 %
(Corey
(George Agudow), /
 q
 (Edward Menscher), 3
$ * 
 (Ariel Nevarez),
Gordon), 7
 `  (Midori Yasuda), /
 =$  * (David Nolen), 9
 * (Rory
9  (Eric Rosenthal), 7  = 
 Nugent), 7  0  (Michael Olson), 7$
(Megan Demarest), *$  _ (Nancy Lewis), 

(Matt Parker), =  9
 (Dustyn
9
 9 (Robert Ryan), = =$ (John Roberts), 7$ 9
  (Matt Richardson),
Duane), > _  (Ben Light), 7
 /  9 (Paul Rothman), 7
 
(Marlon Evans), ;  Z  (Tony Tseng), >
  # (Maria Paula Saba), =   (John
 (Brian Kim), q
 #  (Gloria Sed), Schimmel), 7    
(Michael Schneider),
7$ >

(Matthew Berger),  -3 ' q
$ 
(Greg Shakar),     (Yining
(Yen-An Chen), 3 3
% (Ahmad Arshad), Shi), /  2
(Andy Sigler), $  # (Peiqi
=  = = (Dante DelGiacco)  3  Su), =   # (Deqing Sun), =  ; (James
q
(Anna Gallagher)      Tu), ;  ; (Tymm Twillman), 
 &

       
 - (Karl Ward), 3   &
  (Antonius
 
   
   - Wiriadjaja), 9  (Rosalie Yu)  Z 
         
, ' (Jingwen Zhu).

 
   
   -
,     . =

 
  $     -
 

       
  ,
7  
  
 
-
-

        -
    ,  
   - . $  9 (Casey Reas)  > [
 (Ben
         $   . Fry)        

-
#
        % -   ,  
 Processing 
: =  3 (Jamie Allen), 7  "  Processing (processingfoundation.
> (Mustafa Bagdatli), 7$ >  
org).      p5.js,

 -
(Matthew Belanger), + >  (Ithai  _
7
 (Lauren McCarthy), 
Benjamin), =$  >  (David Boyhan),   
    $ -
$
 >
 (Caroline Brown), 
     ,   
   
  
#

 (Christian Cerrito), =  


  " 
  
 . * 
(Dennis Crowley), =  (Jody Culkin), 
          
= = (John Dimatos), 
 =
  Arduino 7  >  (Massimo
(Patrick Dwyer), 2 +  (Zach Eveland), Banzi), =  7
  (Gianluca Martino),
9
 [ (Robert Faludi), =
 [ (Doria = 
  (David Cuartielles)  =
Fan), = [

 (John Farrell),  7  (David Mellis),   /


  >
-
[  (Xiaoyang Feng), =  [ 
(Jeff
 (Hernando Barragan) —   Wiring
Feddersen),#[
 (Scott Fitzgerald),  * 2  (Nicholas Zambetti),  -
; q

 (Thomas Gerhardt), q
  %  $ 
 . 7  
q

(Gabriela Gutierrez), 7
 ~$ 
 $ ,      
(Meredith Hasson), 
 ~ 
 (Patrick    
  

22 Предисловие

   
 , %  +
13   +   
   
     Arduino  
    14. #  7
 ~  (Mark
 . Hansen)  7  
% (Michael Krisch)
 Z 
 >
     #7+ 

`   
     -    
  15  
  -
",  
 
       .         
 
* 
 , 
 
 ,  $   .
      , — $ * 2 
(Nathan Seidle)  Spark Fun, _
[
 (Limor +       $   -
Fried)  [ ;

 (Philip Torrone)     


      .
Adafruit, X   0 $ (Windell Oskay)  _ 
` 
  
  
 $
/ (Lenore Edman)  Evil Mad Science Labs 
 , 
      -
 /
  (Eric Pan)  Seeeed Studio.  

: ; 3  ;. * (Tuan Anh
T. Nguyen), =    (Joo Youn Paek),
>%    
    =
 [$ (Doria Fan), 7
  7 

   : =   (Don Coleman), (Mauricio Melo)  =   (Jason


#  7 
 (Sandeep Mistry)  3 
Kaufman). ;
 
 (Tarikh Korula) 
3 (Alasdair Allan).       =% 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
 >
-

    Fritzing. /
  - (Gabriel Barcia-Colombo), $  ~
 (Kate

      $ 
  Hartman),  _  (Kati London)  #
    
  -   www.fritz- #
  
 (Sai Sriskandarajah). [
 
ing.org — 9  &  (Reto Wettach), 3 
_  (Frank Lantz)    # (Kevin
 
 (Andre Knorig)  =  $ Slavin) — 

  «;


/».
(Jonathan Cohen)      - #
   (Sarah Johansson), >  

  

    . #     (Benedetta Piantella)  =  =
=
 0
 (Giorgio Olivero)  = (Justin Downs)  Groundlab; 7
 ~$ 
 (Jody Culkin) 
  ,  (Meredith Hasson), 3
$ * 
(Ariel
 $   . Nevarez)  *     (Nahana Schelling),
; 3
 (Timo Arnall), / 
# 
7 
    
 - 7
  (Elnar Sneve Martinussen), =

     , 
 
-   (Jrn Knutsen), 7  >
  

 «+ 
  » (Mustafa Bagdatli), [
 q
 (Frances
 
        11, Gilbert)  and =  (Jake),  
 0

 

 «Z
 #7+    » (Pedro Oliveira)  # ' (Xuedi Chen). 3 
 
   
   _ -3 - ' , 
   ,   
  12,  

 «+ 
 - ;   (Tali Padan)     .
 »    
 
  
0 ,  +   
    13
& 
  : «Interaction Design Institute Ivrea».
14
& 
  : «Copenhagen Institute of Interaction Design».
11 15
& 
  : «Royal College of Arts». & 
  : «Brown Center for Media Innovation at Co-
12
& 
  : «University of California in Los Angeles». lumbia University».
Предисловие 23
#  = q  (Giana Gonzalez), 0   
 MAKE, =$  =

Š   (Younghui Kim), = 
(Dale Dougherty), 
    ,
7  (Jennifer Magnolfi), = - 7           % -
(Jin-Yo Mok), 7$ 

 (Matt Parker), 
  
    ,  
/ 
   
 (Andrew Schneider), q   
 -  . 9
-
_  (Gilad Lotan), 3    (Angela 
 >
   =    (Brian Jepson)  -
Pablo), =   >
 (James Barnett),
 = ~  (Patrick Di Justo)     $
7
  *$ (Morgan Noel),  _% 16     
    . # [ -
  7
 %   
   
-
 (Scott Fitzgerald)    
 .    

,   
"    "     
-
#      ,  %     
   . 3 *$  

        
- (Nancy Kotary),   X  (Katie Wilson)
 : 7    (Michael Shiloh), 7  ; _ (Lillis)    

~
 (Mikal Hart), 7  7
  (Michael  
   . >
 

 ~
Margolis),  #
  (Paul Stoffregen), (Sherry Huss)    Maker Faire $  
3
  7Š  (Adrian McEwen), 3   -       %
 
 -

 >
 (Alexander Brevig), 9  7-   . & " ,      
-
  (Ryan Mulligan),    (Keith  MAKE. ;      
Casey), >    (Bonifaz Kaufmann), «# >».
3 
  q
   (Andreas Goransson), ~ -
 >  (Helena Bisby), 7  3  #     ,      -
(Michael Adams),  =$ q 
 (Joel     

, -
Gahwiler). 9
 [ (Robert Faludi)  - 
 , 
     
,  
        ,   $  ,    
 ". = 
  «Digi International»    - ~$  (Denise Hand), > _  (Ben Light),

 XBee and Digi. `     ;  (Clive Thompson), = ~ 
     
  Lantronix: (Joe Hobaica), 7 X  (Max Whitney)
q

 7

  (Garry Morris), q$
 7

  = 
7  (Jennifer Magnolfi)  -
(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
  *
  
$  .
24 Предисловие

Мы хотим знать ваше мнение

4      -     «Maker Media» — 


    -

  $   ,       «OYReilly Media»,     -
    "  
: " 
 %
"   "  
-
    , 

,  
Maker Media, Inc. -   
,  $    -
1700 Montgomery Street, Suite 240 . 0
  "
   «  
San Francisco, CA 94111 » 
  
    
-
     
.
#   , 

   -
  
    
   =     
  «Maker Me-
 -    
: http://shop.oreilly.com/ dia»     : http://makerme-
product/0636920031369.do. dia.com.

0   
      -
 
      $ 
 
  
: bookquestions@oreilly.
com.
Глава 1

СРЕДСТВА

Эта книга представляет собой что-то вроде сборника кулинарных


рецептов, и в ее первой главе я познакомлю вас с основными
используемыми при готовке ингредиентами. Описанные здесь
понятия и инструменты найдут применение во всех остальных гла-
вах книги. Для каждого инструмента дается достаточно
информации, чтобы вы могли сказать «Здравствуй, мир!» с его
помощью. Скорее всего, некоторые из рассматриваемых в этой
главе инструментов или подобные им вам уже приходилось держать
в руках. В таком случае вы можете спокойно пропускать знакомый
вам материал и переходить к инструментам, с которыми вам еще
не приходилось сталкиваться. Использование этих инструментов
в проектах, представленных в следующих главах, демонстрирует
для большинства из них лишь малую толику того, на что они
способны, поэтому рекомендуется самостоятельно разобраться
с менее знакомыми вам инструментами, чтобы получить более
полное представление о том, что с их помощью можно сделать.
Для этого в книге приводятся ссылки на материалы для дальнейше-
го самостоятельного изучения инструментов, которые вам не столь
хорошо знакомы.

Happy Feedback Machine1, созданная Туаном Анхом Т. Нгуеном (Tuan Anh T. Nguyen)
0     ,      $  
 ,
  "   
  
" 
 . 0   , 
 

 $ 
, — 
 ,  %   ,   
",
   "" ,      .
1
/     
   
  : «7%      

  ».
28 Глава 1

Все начинается с прикосновения


Все рассматриваемые в этой книге объекты — как осязаемые, так и неосязаемые — демонстри-
руют определенное поведение. Программные объекты отправляют и получают сообщения, хра-
нят данные или делают и то, и другое. Физические объекты двигаются, светятся или издают звуки.
Первый вопрос, который нужно задать об объекте, — что он делает? А следующий вопрос — как
принудить объект делать то, что он должен делать? Или, иными словами, какой у этого объекта
интерфейс?

+ 
      
  -       
     
. 
   — 
!


 -   ,     . *
. / ,     
   :
,    
      -

  ,    , - "   ,     



  %  .   ,        . 7  -

     ,         
    

-
     
 . [     >... ;    —  -
 
             

   
     
  . +       -

      
 -
  
      

  ,  
      ,  

     
 . 
     
 . /   

    % ,   
  - %   
 . +  - 

,  %  $
 ,   
  -   
         ,
,         ,   % 
  

  -
       
   . & -    $  , 

 
      
   - ,     
"   
 
 ,   $    -   
 .
 
 , 
   ,
  %  
,      * , 
   — %


  
" . #   , - -
 , 
 "  
      
  
  $ 
  $
, 
    -
    .   
   
  " 
-
     
. 4   
# "    
  — -

         
 
 :   ,      ,   
    
 ,    
. &
   $  
 . *   

    

   
-

  "   ,   , 

  
 ,  
 —  -      %
-
  " " . *% 
-    $ 
   
 ,  
-

  
  
  
  ,   

     
  .
           ,

  
  
 .
  ,  

  
 -
 
  ,      , $
   
 $ 
 
-
 ,  

    
,     %      .

    

   
 -
Средства 29

Несколько слов об импульсах


Для взаимодействия друг с другом объекты используют протоколы связи. Протокол — это
набор взаимно согласованных правил для взаимодействия между двумя или несколькими
объектами.

    
 —  
 
"   
 
-
USB, MIDI        USB-      %  %
HID (Human Interface Device,  
  -  
. =       -
    ) —    
    
  

    
 
 
, $ 
   . =  
 -

    , 
,  % 
          
 -
 
 

   
 . #              

 —   Ethernet    
- 
      -
 TCP/IP —           ,  
  

 
 
     - 
        . 3 
 (  

),

 (
%
-
      -

)  
.    ,   
  -
"    
 
    -

       
   -      "
  -
 " ,      -  
 .
"         . 

      
   
 $     , 
   -
$ 
  

      " $ 
   ,  
  
     .    ,  
   
 , —
            
        -   
      
-
     
   ,     -   , 
 
  
  
        
 . X ,   

         — 
  "          -

         -    (   - 
 ,
 
. * 
  ,  "       $ -
 
        , — $  ),   
   
-

   

   - %   %      .
 

 ,        

 .

;      
,  
  -
% , 
 "      -
 
  ,    , 
  
 
    
 -

,   "    —     
    $ 
 : 

 
      
 ,  -

 $ 
   (   )
  "     . ;, -
" $ 
   "     -
30 Глава 1

Компьютеры всех видов и размеров


В этой книге мы встретимся с несколькими разными типами компьютеров, сгруппированными
по их физическим интерфейсам. Самый знакомый из них — это персональный компьютер. Будь
это настольный компьютер или ноутбук, персональный компьютер имеет клавиатуру, экран и
мышь, и вы, скорее всего, пользуетесь им каждый божий день. Эти три элемента — клавиатура,
экран и мышь — составляют физический интерфейс персонального компьютера.

 
 
       
 - 3. #         

, 
-
, 
      
 -  ",       -
   , — 
   %      .

. ~ 
 ,
 "  -
%  
 %     
- 7
 

     
-
 
, 
  
 -      ,  
     
 -
 ,    "     %    

 . +  , -

 :   " 
  -    

  
 
 -

 
   %   
- 

 
      .
    ,   

 &    ,   
    


     . +  $
- 
 

  Arduino Uno, 
     
"  ,  "

-    
  Arduino   
 

         -   , 
  
    
-
 
           $   .
   
  ,   
 %  ,   "  %  2     
   
-
      .  

  
 ,     -


   
   -
;
  
,
 
  
  
, — 

, Raspberry Pi.
 $   , — 
   , - ~   %     $  
 
"    
 , 
   
 

,    ,

   
         " ,   
 
 . /   % $ 
 -        
 

        ,   .
 
     
  
$ 
    . &  -       
 -

 

  "    "   
  

   ,    -

% 
 
: 
   
,
 
  
 $   , —  
  
. /,
1.   
 

 -
 
  ,      -
  , 

"

-
 

      : 
,        
,
  ,     $
   
  %. 9     ,
      —  $ 
-         ,    
  $
. 
  
,     -
     "      
2.    
 

 -  . _ 
    
  ,    
  
 -    

. = $  %
, 

" $ 
  $
-   


     -
      . 
   .
Средства 31
>%     
     
 , 
  "


    
 ,  -       
 , 
      ,  -
  

 ,  %  
   
      
  
  .
    
 . 
 $    ~          
 
   ,      
 -   
,        


  %     -   . ; , 
 
 $
     

  
 .  
      
 , 


    , -
# " 
 
 — $       ,     —   
  
:     
, -        —     -
  
,  

   . . 
 .
* 
     

Обзаведитесь хорошими привычками


Взаимодействие сетевых объектов в чем-то схоже с личными отношениями: вы не знаете, о чем
думает ваш партнер, — вы только слышите, что он говорит. Основная проблема и тех, и других
заключается в том, что, посылая сигнал, мы никогда полностью не можем быть уверены, пони-
мает ли получатель, что мы хотим этим сигналом сказать. Поскольку нам неизвестен внутренний
процесс мышления получателей сигнала, мы никогда точно не знаем, как они истолковывают
наше сообщение. Все что мы знаем — это как они реагируют на него. Кроме того, существует бес-
численное множество вариантов потери сигнала или искажения его значения при передаче.

;    ,      ,  - #% —   
 ,   
.
"  
  % 
,    - q
     
,   -

 ,        ,   
- ,       ,  %  -
"  $ "  
    
% - ,   
    %   ,     .  
 %. 
       
$,         -  %  $   ,    
    
 (      

 , 
%   
-
 %      ),   

-    
 " ,  
-
   "  
 
 :    "  % , 
$ . 0
 "   -
? %  % ,   
 ;         ,    ,
?    ,   
     ,  $ 
      
  %   ,   ;  
 
  . 0
  

"      ,  
? 

   
   

    
  
 .
   
 ;
? 
     " .
Никогда не предполагайте
#%     % , ,   -
Слушайте больше, чем говорите   ,   
 . +  
  $
# %   
 
   
     % ,
 %  — $   
% %  .  
   $    
 
32 Глава 1


 . 4  
  ,  %  . 3   

   , 

"             
  
 
 

 .
     ,  
   
$ 
 ,    
-
 . *       

 -
Установите правила обмена
         %, 
 - информацией

 
 " ,    - & 
%    %  
  -

   
         .  "  ,    "   -
#  
       ,    . 7 
   
   
    $  % . ,  %         
    ,  
    -
  , 
      
   
 
 
" ,  

 ,     
  -  , 

  
  .
  % %. >%  %



  
  
  
       
-
  
    . &             
 

     , - "     , 


 
  "   «2
  ,     
. +    -

!», 
   

      
     
    
 . =
 
-    ,  
     -
 
  
 $ "  
-    " " 
 . 

-
 —   ,   
   
-   " " 
   ,

     .           , 

        " -
* 
     " - . 4             
 —    %  , 
 -     
, 
 
 
%. = %  
  $ 
       
 

  
      , 
-     
   
 , 

  $ 
     
-   . *

, 
%  -
 . +     
 
 
   
, 
  


  
%, 
%   


 -   -

,       
 
 ,    
  ,   
 

. *   
 , -
 
         . ` - 
          
    

   , 
        ,
  
% 
  
 " -   

    
-
,     
,  
-     , 

"  
     -        .
       " .
*    ,  
   
    $      , 

Попросите разъяснений
 %     . 
 
, 
  "       -
         $   , -          
 .

       ,    , *



,   % -  -
          
    , ,    ,

     -
 . &  
  
   - %  ,    $  ,  
" ,               ,  %       

      

       . $,   
Средства 33
    %, % -
      . ;      
 
      . ;         . *

,  
      
  
  
          
  

,        "   
,  ,    
 -
" ,   
   
% , 

,   . $,

 
. 0
 "  ,  -   
    " -
 
   
 ,     - , 
 "  
. *  -
   
 ,   % ,   $ %  
,   
 -
  $ 
%. =   ,    "   
     
   .
        ,    
 
 
  "   
- . 7  
    %    % ,      $ 
    

   
 ,   
     


 -
 

  , ,       .

Инструментарий
Учитывая, что в дальнейшем вы будете иметь дело с физическими, программными и электриче-
скими интерфейсами объектов, вам потребуются «физические» инструменты, программное обе-
спечение и компьютерное оборудование.

«Физические» инструменты О поставщиках деталей


& $        -
4  
 
 
 $ 
-
"   . `     
-
  
 

,   , 
  " —      , 
 ,     
 
  . *     
    

 . 1.1   
   
   - 
       . X
,    
   
-  . 1.1  "      -
 
   $  . ; —      ,       -
  —  
    

      
  ". *
    " ( -   - 
 $  
       .
  . 1.1). 0    

      -
" —      
       -


    
   . 4 

  
 ,  
   -          ,   


      
  $ 
 -    $  .
     . 0   
  -
 . 1.1    
  &    
     -
    "  ".  , 
      
  $  .
7   ,     " ;,    ,     
     
     ,  
      -
$    
    - ".  
       -
  
  

  - "  
  $      
". 


.
34 Глава 1

8 10
7 9

6
18
11

16
1
12

34 15
5 13

19
3 33
4 31
25
2 32
24
27
29 28
30
14

17 26 20 21 22
23

Рис. 1.1. Инструменты и детали, используемые в проектах этой книги. Их краткое описание дается далее (обратите внимание:
после указания поставщика приводится номер детали по его каталогу)

1. 
. = %     
   3.   

. + 
 , -
 
,     
        . Jameco: 2214889;
   
  Hakko FX-888D, Adafruit: 148; Farnell: 1792724.
Weller WLC-100    SP 

  -
4.       



, -
 
 $ 
    -

, 
. *     

%

. *       -
«
   »,         
  
 
 
. 



 . /  
   
       
, 
  

 
 ,  
%  
 -

       $ -
 $   
 ,   

     
 

.
$ .
 ": Digi-key (www.digikey.com): 1691-
1083-ND; Adafruit (www.adafruit.com): 1204; ?       



: Jameco:
Farnell (www.farnell.com): 2320747. 159291; Farnell: 609195; SparkFun (www.
sparkfun.com): TOL-12630;
2. 
. _%     

21.23 AWG2. 4     ,  - ? 
: Jameco: 161411; Farnell: 3125397;
      
 , 
 SparkFun: TOL-10447;

  
. Jameco (www.jameco.com): ? !
: Jameco: 217891; Farnell:
2210116; Farnell: 419266. 3127199; SparkFun: TOL-08793.
2
AWG, American Wire Gauge System — 
  - 5. "

-  . 

  
 -
    
 (  
    
). -  
 — 

    -

   .  : http://ru.wikipedia.org/wiki/
-  . 0         .
 
_ 
 _ . Jameco: 127271; Farnell: 4431212.
Средства 35
6. #$
  
. 9       Adafruit: 80; Digi-Key: 1568-1237-ND; Jameco:
 
   , 
      
- 2207056; Farnell: 1650675  1737256.
   
 . SparkFun: SWG-11046;
13. <

- 
  (LiPo)   . =
Farnell: 1696193.
   
   $      -
7. «%   ». / 
          
 (

-
   
    
    
-   ) 
 LiPo —   
-
 
. Jameco: 681002; Farnell: 1367049;           
SparkFun TOL-11784. . 0  
   %
 


, 
     ,    -
8. "
 . *     

    
       
-
 
 . ~  , 
-
 
   3,7 &    800–2000 3.
  
 
  , , 
 
SparkFun: PRT-13813  PRT-08483; Adafruit: 258
 $ 

  . Jameco: 220759; Farnell:
 2011.
7430566; SparkFun: TOL-12966.
14. USB- 
. = 
  $    -
9. 
 &. 
    
-
  USB-    3- -B (  -
   
 ,  DSO Nano   

 USB- ),    A- - -B
%  $100 —      -
(USB- ,     
  -
 
 . SparkFun: TOL-11702 (v2); Seeed
Studio (www.seeedstudio.com): 109990013; 
). SparkFun: CAB-00512, CAB-13244; Farnell:
Adafruit: 468. 1838798, 2444222.

10. 
    9–12 '. 0   15. % 

 )


    . *     «  
». X
   
   —      - 
 
 
 
    
   - $ 
   
 .   — $ 
     -
&    
 
  
-  . Jameco: 10444; RS (www.rs-online.com):
 
 ,     
- 161.6511; SparkFun: PRT-12978.
 
    -    16. 


   
  
  . >%   
   
  
 
 ,   "  
  «
-
 
       , ». Jameco: 135299; SparkFun: CAB-00501.
 
    % 
 

17.  =
USB/TTL-Serial. 

  
 
 2,1    %  — 5,5  ( . -
USB-      TTL. / 
  
-
 11), $ %      -
   
     
 -
    "
   

.
. SparkFun: DEV-14050  DEV-12935; Adafruit:
Jameco: 170245 (12 V, 1000 mA); Farnell: 1176248
3309  284; SeeedStudio: 317990026.
(12 V, 1000 mA); SparkFun: TOL-00298.
18. " 
    . *
 . 1.1 -
11. () (+  )



  -
 
 

 Arduino Uno,

  
 2,1    %  — 5,5 .
Arduino 101  Arduino MKR100. SparkFun: DEV-
/   
      
-
13787; Digi-Key 1660-1003-ND  1659-1005-ND;
 

         
RS: 913-9999  124-0657. ; . https://store.
   . 9

  
arduino.cc.

      , 

     
 ,
 
   19.      > . *
 . 1.1 
 $   . 
   % 
 

 
 Raspberry Pi Zero W,

 
    

   - Pi 3  BeagleBone Green. SparkFun DEV-13825;
"  
 . SparkFun PRT-10288; Adafruit: 3055  3400; Seeed Studio: 102010048
Jameco: 159611; Digi-Key: CP-024A-ND; Farnell:  114990584 RS: 896-8660; Farnell: 2525225.
3648102. ; . www.raspberrypi.org.
12. ()   

 «  ». / 20. (  A
. 9 

-
  
 ,             -

    
. SparkFun: PRT-09518; 
   
     , 
36 Глава 1

        


  25. (
 . =
 
  $  -

 
, 

" 
 -     
 

  -
    . * 
   . * 
     -

     
  $  :  . 1.1.
5 &  3,3 &. >  
 
  -
26. H  ). /
   
   

. 0   
  
, $     
    

 ,   
  
  
 ,  -
     .
   "
    .
? 3,3 &. Digi-Key: 497-1491.5-ND; Jameco: *  %      
 
242115; Farnell: 1703357; RS: 438-4885   %
. Jameco: 103377; Digi-
? 5 &. Digi-Key: LM7805CT-ND; Jameco: 51262; Key: A26509-20-ND; Farnell: 1593411.
Farnell: 9756078; RS: 918-1971. 27.   

(

 
).
21. %  
 TIP120. ;
  
  - #"      
 
 


  
 
 ,   

     .

     
  X        
  
"    %   
-     ,      

  . #"    
   
 -  
   . =     -
 
,   
  $    -    

   / 

.
  
  
TIP120. 0
    , ? !



. Jameco: 150551; Adafruit:
  % $ 
  
    182 SparkFun: SEN-08606;
  , 


 
 
( . . 20). +  $ 
   ? !


 
. SparkFun: SEN-

         - 09375; Adafruit: 166; Digi-Key: 1027-1001-ND.
 
 , $,  
  - 28.  
. = 
  $   
% -
    ,  
 
 
-      : 
 — 
  -

   
 . Digi-Key: TIP120-ND;    
     
Jameco: 32993; Farnell: 9804005. ( 
      Arduino
22. "-  
 IRF520. / 
  
 Wiring), 
 % 
    -
    
 ,   -            -
     
  
 TIP120  
 ,  
 — 
   
 
 
 ,  $      
    , 
  
  . Jameco: 209226 Digi-Key: IRF520IR-  $    
      -
ND; Farnell: 9103031.   . *,  
  ,    

     .
23. C      . +  
  
  % . _   ? !  

   = =.

      %  - Digi-Key: SW400-ND; Jameco: 119011;
 
 ,       SparkFun: COM-00097;
 « »     
 . Jameco: 20723 ? !  

   =. Digi-Key:
(2 %  
 ); Farnell: 4692810; GH1344-ND; SparkFun COM-09181.
Digi-Key: 438-1045-ND; SparkFun: PRT-12615
 PRT-12002. 29.  
 .   
(


 
)    
  
 -
24. D
   


 . = 
 
 . Jameco: 29082; SparkFun: COM-


 
   
    09939; RS: 91A1A-B28-B15L; Farnell: 350072,
   ,  
   

- RS 249-9294.
 

     . 0  
 
 
   
    30. 
Ethernet. ~   " 
  -
    
   .    %
   
 
$        
 -  
    Wi-Fi,     
   . Jameco: 333973;   
 
      . Digi-
Farnell: 1208851; Digi-Key: 160-1144-ND. Key: N002-004-BK-ND; Farnell: 1526202.
Средства 37
31.    ,  , 

A- 32. " A   A
  . 3
-
 . =                  
, 
 %      
  
      
  
 . + -
22 AWG. 2  ,  
 
, 
     
 , $ 
        
  -        
. Jameco:
  ,  
—  " . *   20723, SparkFun: PRT-12796; RS: 791.6463;

        
 Adafruit: 759.
        .
33.    . =
 
  $
? J  — Jameco: 36792.         

-
? D

 — Jameco: 36768.   . * 
   -
   . 1.1.
? #  — Jameco: 36822.
?    — Jameco: 36856. 34. N

   . &    

       % 


? K — Jameco: 36920. $ 
   , $  -
? (   — Jameco: 2153705, SparkFun              
PRT-11375. 

. 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  D — 100QBK-ND, J — 690620, F — 9337660, RS — 755-0707
220  D — 220QBK-ND, J — 690700, F — 9339299, RS — 707-7612
470  D — 470QBK-ND, J — 690785, F — 9339531, RS — 707-8659
1K D — 1.0KQBK-ND, J — 690865, F — 9339051, RS — 707-8669
10 K D — 10KQBK-ND, J — 691104, F — 9339060, RS — 707-7745
22 K D — 22KQBK-ND, J — 691180, F — 9337814, RS — 739-7140
100 K D — 100KQBK-ND, J — 691340, F — 9337695, RS — 707-8940
1M D — 1.0MQBK-ND, J — 691585, F — 9337709, RS — 131-700
Конденсаторы
0,1’F 
  D — 399-4151.ND, J — 15270, F — 3322166, RS — 716-7135
1 ’F $ 
  D — P10312-ND, J — 94161, F — 8126933, RS — 475-9009
10 ’F $ 
  D — P11212-ND, J — 29891, F — 1144605, RS — 762-1736
100 ’F $ 
  D — P10269-ND, J — 158394, F — 1144642, RS — 762-1746
Регуляторы напряжения
3,3 & D — 497-1491-5-ND, J — 242115, F — 1703357, RS — 438-4885
5& D — LM7805CT-ND, J — 51262, F — 9756078, RS — 918-1971
38 Глава 1

Таблица 1.1 (окончание)

Деталь (компонент), номинал Код поставщика и номер детали по его каталогу


Аналоговые датчики
+ D — 905-1000-ND, J — 150551, RS — 708-1277
=  D — 1027-1000-ND, J — 2128260
Светодиоды
5 ,   , 

 D — 160-1144-ND, J — 34761, F — 1855510, RS — 228-5944
5 , 
 , 

 D — 160-1665-ND, J — 94511, F — 1855570, RS — 848-6480
Транзисторы
2N2222A D — P2N2222AGOS-ND, J — 38236, F — 1611371, RS — 295-028
TIP120 D — TIP120-ND, J — 32993, F — 9804005, RS — 774-3653
IRF520 D — IRF520IR-ND, J — 209226, F — 9103031, RS — 541.1180
Диоды
D — 1N4004-E3/54GICT-ND, J — 35991, F — 9556109,
1N4004-R
RS — 628-9029
D — 1N5226B-TPCT-ND, J — 743488, F — 1700785,
3,3 & 
 (1N5226)
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
Набор монтажных перемычек
J — 20723, SF — PRT-12796, F — 2396146, RS — 791-6463,
9
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.  ,   -


 .   ,
 Processing     Java,
 

 Processing    
Среда Processing      Java. #
     -
0   

 
 , 
   macOS, Windows  Linux. #"  
 
        $   ,     
 Processing  Android. 4  
    

 
,     - 
 
 

Processing. /    
  - 
 Processing,      
-

     ,     
-    $   

  -
  -   www.processing.org. #
  
          -
Processing     
 Java  
-   

  
 , 
 
        , 
-   
  .

   
    -
      


  . 2
    
 Processing   
;   , Processing —     
,       . 0-
 
      
  
- 
    ,    
 . 1.2.

Рис. 1.2. Окно редактора кода


среды Processing
``Панель инструментов.
Содержит элементы управления
для запуска и остановки скетчей

``Окно редактирования.
Сюда вводится код скетчей

``Панель консоли.
Здесь выводятся предупреждения
и сообщения об ошибках

Пишем код
; 
    % 
- println("
, !");
 

  Processing. & -
   

  "
  ,       Run
(+  ) —     
    
  Processing.
40 Глава 1

*   

,  $  - 
. &
 ,    
  
  
 

    -       
 . 9 

 


 . +   $ 
- Processing   
   
 -

     : # , 
!   -  «
 »,  "    .
       

.    
 

   
 ,    .            
  , 
 " "   , -


 Processing     

     $ 

   
(sketch),            Java. 
 ,     $ -

    
   - 

      
  .
    Processing 

Пишем код
9 
  
  - /*
       
 

, 
   -
: Processing


  
          

  .





          
  .
Processing. */

// "  :


Контекст использования float redValue = 0; //     #
кода float greenValue = 0; //    $ #
& 

  $   float blueValue = 0; //      #

   
-
//  setup()    $    :
,  " ,
 
     - void setup() {
 : Processing, Arduino, size(320, 240); //   $     
node.js  . . 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() —     

 ,   . *

,  
  
  "  

 ,     - byte 
      ,  int —
 
.  
   . .   , 
 

        $   , 
 -
= 
  Processing     
   , 
 


  . & 
     
-       
  , $

 
 redValue, greenValue 
       
 
 blueValue — "   (float), . .           
 .
   
   " -
 . =

 
 
        Java  JavaScript,   

 , 
  
  
- 

 
 Processing   
, $:        #.   
 , 
          ( 
? int —      ;        void — . .  
? char —        
"     
  -
ASCII;  ). & 
    -
    ,    -
? boolean —    true (  ) 
false ();
   
. X  


(if-then), 

 (for-next), -
? string —   ;  
         #.
? byte —  . 2      for-next,  $  -


     
  

`  


  Java,     , 


   
 .
 
     Processing -

3 

 for-next for (int myCounter = 0; myCounter <=10; myCounter++) {
  

     "  println(myCounter);

  :

     
    $ .
=       -
    New   
File
 Processing.
42 Глава 1

Пользователям 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 —     $  -     $   $  9



 
 ,       >  [
 ,     
  -
 
   
  
. 0  «Getting Started with Processing» ( -
            O’Reilly). ;     



     Java   -       " «Learning
". 4      Java,    Processing» (   Morgan Kaufmann),
   Java 
    

-    = $    (Daniel
 Processing. &   Processing  Shiffman).
 
 %
 "    -
   , 
    
+ 
 . Интерфейсы командной строки
и удаленные серверы
 
 Processing 
     0    $    
 ,
       
    - 
       
     ,     
  $  ,    

 -
   
 $    -    , "   
  
  —         
   

. 4 
 
  . /       
 % 
 


,  
 $        
     
, $
 

    


 ,         ,  
-
    $   -       . 7    -
    
  .   
    
  
-
   
,    -
=     
            -

   
 
Processing     
  , 
 
.
  
  -   www.process-
ing.org. X  %  


  * 

 $

   
-
 Processing       «Processing:     "  " ,
A Programming Handbook for Visual Designers     
  " -
and Artists» (   MIT Press), -   
   
    
Средства 43

. 7      


-
      
  - Виртуальные
      
 ,   $ частные серверы
 
  $  
  
 ,
      $   ,  - 7 
 
   $   

-
 
    -

, 
-
%    . + 
  -  
 
    - . #

 
 
    %  -  -

  
       -
   

 
,   
- . +        - ,  
   
 , $      
    "    -  ,
     "  
 "   
    
 
  
 
  
 
-

 (&'#). X       
-

.   -

,    
   
  . &
  -

 
-

   

    -

  
-
*
 
 
  
  
     ,    -  

 
   
      
 -         
 
-
       UNIX,     -

,      
  

    ,  BSD, Linux, macOS       -    

 
 . 0
    ,  
  -

    
 . #"  
   
  
 
  
  "    -  , 
 -

,      


 - "   
    

 
   "    — 
  -


 POSIX3. &  
"   $
 
    -
  %

.
   
    
 
- *

,   "    -  ,
     
      Digital Ocean (www.digitalocean.com), Amazon

    $  . Web Services (aws.amazon.com), BlueHost (www.
bluehost.com)  DreamHost (www.dreamhost.com),
Доступ к интерфейсу командной 
    &'#     

  . * 
 "    -
строки     
    
-
=    
     
  -   /  ,      


   
 

 $-  $   .
 
 . 4  
%      -
"  -     

В macOS и Linux  -

, 
   
 
& macOS $ 

     Terminal   
      . / -
     Utilities       ,   
     -
"    -    
 
Applications. & Linux $
   
-

      -

   " .
      xterm, rxvt, Terminal  *   
   -   
   -
Konsole.
   
     
-
 


    
  , 

В Windows      ,    ,    
+ 
    
 Windows          -

,  -


  % 
 . 
 $
 DOS       
   -       ,  
    
 
,      
    
     
     -
     POSIX. *  

 - 
   "    -   — -
   
  Windows  , 
 cmd 

  ,  
. ;
3
,    $  , 
   -
POSIX, Portable Operating System Interface —  
  
 ".

  
     .
44 Глава 1

       .      - ,    


  

 -
$  ,   Microsoft     - 
. >%   "  -  

    
   POSIX    Linux, BSD, Solaris  

Windows 10 (      
 : bash UNIX-  
    .
 Windows 10) —   " 
  -
  


,   = 
 Windows "   -
    "" .   -  

    ,  

     (       

 PuTTY, -
"      
    
) 
   
  
 www.put-
  POSIX  Windows  ,   - tyssh.org. 
 
      —
 

 Cygwin (www.cygwin.com).   -   

 
   "

  , 

$    - Windows         -
      
  Windows  . * 
  macOS  Linux 
  
 
  Cygwin           
-

    . & 
   - 
 OpenSSH, 
      -
 Cygwin     
  
  $ 
    . 2  
      Net (          

 Terminal -
$
  Packages   "),   "   ssh.
          
-
  ,  "  POSIX. В macOS и Linux
0
  

 
 . 0   
-
Подключение к удаленному   
   
      
веб-хосту 
      " :
~  
    
    -
 
     - Last login: Wed Feb 22 07:20:34 on ttyp1
ComputerName:~ username$

,  $          


      
:  &    POSIX  $    
 -

    
.   $ -
Рис. 1.3. Главное окно программы PuTTY     " 

, $   ,
         . &  
,
 
  $   ,   -
 
       ,     
$ .

'    
   -

,
       
  :
ssh _$@ _-.com

9  ,   
 
 _$-
  _-.com    
  ( _$)  

 -

 ( _-.com)    .
&  
, 
  
  -
  -

,      -
 .
Средства 45

В Windows
2  

 PuTTY (
 . 1.3). &  
      
   -

   -

 ( _-.com)         ssh. /  
Host Name,    
  Connection  
, 
 %  -
type 
  SSH     
  
 %   
 -
Open. 2      

,   "    . $   
   "  
%          $ .
     
.

Работа с командной строкой 


 
–l 
   ls    list
X         -
 - long — 
    
 -

,   

  "  : . &
    $    -
  

   :
Last login: Wed Feb 22 08:50:04 2016
from 216.157.45.215 total 44
[userid@myhost ~]$ 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 drwxr-xr-x)   

% 
   $  :   ,
/      
   
       ;
print working directory, 
    ?  
 $   (13)    
«
  
 ». 0         $    


 
     "       ;
. (7    POSIX   
- ?  
  $   (igoe)    
 —       . # 
     ,    
 (users) —

 , 

  
 - 
   ;
 .) &  

       ?   $   (4096)    


 "   —     :  ,   %  (Apr 14 11:42) — 


 
      ;
/home/igoe
?  ,      $   (public_
html)       .
/ 
 ( 
)       -
 

. =       - &
 POSIX    ,   
 -
       ls (list):    ,  "   
-
 . / 
    
   
$ ls -l.   — , 

,    

  
   . ' 
 -
Точки в конце команды 
 
 ,   
-
   ,   ls    
;         « " -

 
: -la:
»,    — «
     -
"  ». $ ls -la
46 Глава 1

=       : = 


 "       

mkdir (make directory):    cd (change directory) — -
  . *

, 
  
-
$ mkdir directoryname
    html  ,   
/         "   "  :
 .   ls –l,      $ cd html
   , 
 $ -
   
       "  ' 
     
   %
. 
 
 

    

 ,       :
 (      )
"   ls -la     $ cd ..
 
: = 
  %  (
 ) 
   cd    
 
~ ():
drwxr-xr-x 2 tqi6023 users 4096 Feb
17 10:19 . $ cd ~
drwxr-xr-x 4 tqi6023 users 4096 Feb
17 10:19 .. &
   %    , 
-
      cd   
 
.

 
 —       — $
   ,  
 —  = 
    $ -
    —  
   -       
   
. ;       - 
   
 / ( $%). *

, 
  ,    . 
   html  %   ,
       cd~/html. ' 
'  ,    rm (re-      


move directory)    ,  -
(
    root — 
 ),  
"   :          
 — /.
$ rmdir directoryname      
      


.
X      , $

         Управление доступом к файлам
 
 —    ,   
.   rmdir       - &     ls –l,     -
 ,   
   
   ,     "  , 
 

$      
    -  ! 
   .
 . *        
       , 
- *

,    :
  . drwx ------

& %   -     -     ,        (d —
       %- directory),  %    (-
 , 
    html  pub-
      )   
-
lic_html, — 
 "      HTML 
    (r — read),  -
 "   . 4   %   -

   (w — write),      
  ,    " (x — execute). 9 
 
 


-
  mkdir:
% :

$ mkdir html -rw-rw-rw


Средства 47
=      ,       (execute). 2  + ( )    
  
  ( ),       ,

%  ,    – (  ) — %  .

    (         >  
 ,    %
  $ 
 ),    
 ,

%    ( ). 

       ,   
 
 , 
  
  
 
        . 
 $ 
-       
  
, 
 
 rw-  

%   ,   $   , —  
-

 — 
 ,  
 —     .   "    -    
&         

% -   

   
  -
 "   chmod:  —     .

$ chmod go-w _%


 Создание, просмотр и удаление файлов

 
$     - =
    
  "
  , 
   
 ,      

    
: nano  less.


% . & 
   

 - 

 nano — $   

, 


%     (-w)  
 (g —   
 

, $    
group)         
 (o —
 %

       -
others), 
    . 3   "  
" - 
, 


 
   
     -  ,

,    
 -
  
  
   :     

. *  % 


 



 nano  .
$ chmod go+wx _%
 '  " nano   ,
    "  :
    ,  
 
  
chmod  u      (user), g — $ nano _%
.txt

 (group),  o — 
 (others). 7 
  ,   r   

%    0
    

 (
 . 1.4).
(read), w —   (write),  x —   

Рис. 1.4. Окно текстового редактора


nano. В нижней части окна имеется
список доступных команд, которые ис-
полняются по нажатию клавиши <Ctrl>
совместно с клавишей буквы англий-
ского алфавита, указанной слева от со-
ответствующей команды. Например, на-
жатие комбинации клавиш <Ctrl>+<K>
выполняет операцию вырезания (kut)
выделенного фрагмента текста
48 Глава 1

&   


  nano   -    .   
    
-

   % <Ctrl>. *

, 
      
 
,  "  
    

    -   :
  % <Ctrl>+<X>. *  

       - $ head -5 _%
.txt
  

.
& $   
 
 
X      "  - 
   _%
.txt.   
-
 rm (remove):   :

$ rm filename $ tail -10 filename.txt

    rmdir,   rm  -    $


       
  
 
   
     , _%
.txt.
$      
    -
 .   cat, head  tail     , 
      

   .
* 

nano    
 / 
 

 
    " 
  

  %   -
  .
   ,        -
 
% 

less. /
- Объединение нескольких программ


          в одну
$
  
. = 
 
     
 less   
     $

, 0
     UNIX

  
   
   :    « 
     
  ». +  ,  -
$ less _%
.txt        
 

 (-
 

       
,
&
 
      -    

      
$
 , 
%       (:)    
 )     
   $
 . * % 
   -    ,     
%.
  " $
   . ' 
- 
 ,   

 -
%
 

 ,  % <q>.       -
0
  ,     
       
  

 less  ,       

.  


 — 
 
     —   

    
  -

   «   ».      ,     


         
-
= 
 
        -  . *

, 
    

 ls
   cat, head  tail.   %    ,
          $
 
  cat     $
  
-   "  . *   

-
    
    
  :  ls   
 

 less, 

        ,  "-
$ cat _%
.txt "   $
 . =    $  "

:
3   head  tail     
-

        , - $ ls -la . | less
Средства 49
&  
     
 


-
         
  
 (|)          -  - 
 
. 7 -
  , 
  
     


 
 
  

 
    
  $      .
  % 
.


 
, "     
-
&     $
    
-      
5. #  -

    

   -  
     ,   
 
   — 

,   . ;,  
    help,   
 
       
  
     —     :
  ,     "  :
man _ 
$ ls -la . >  _%
.txt
' 
   

 
/        _%
. 
% 
 
   -
txt  
         ls. 4    
,     
      "  ,  - logout. & 
 
  Linux  $-

         ls.      loguot     -
&   
 " "    exit.
 ,       
  : * %  
      
POSIX —   %   macOS, Linux 
$ ls -la . >>  _%
.txt
  
—   
 -

  
  
-
0   
 ,  
  


 
    %   ,
   ,     , 
  
   



POSIX-   
 
    
  ssh. >%  $  
 
 ,   
  

  
 Cygwin  %  
     
. *

,  -
Windows. +       
  $
          
   
,    -
    — standard out,
  $  .
 stdout. 3    
  -
   
    
  — standard in,  stdin. [  - =     
 
  -
      , 
   
     
 
 
" 

    

 -    UNIX  Linux     , -
    "         

,    3
  * (Aaron
(stdin)      (stdout). Newcomb) «Linux for Makers» (  
Maker Media).
     
    
 ,
 
       ,   -
  
. ; 
, 
 -
"   
   
      
. ; 
  /    -
 FIFO4: 
   — 
    .
/     

 

4 5
FIFO, First In, First Out — 
  % , 
  0  . command shell — 

, 
 
 -
 % .      
     
.
50 Глава 1

2
 

   " node.js
Платформа node.js   https://nodejs.org/en/    
>%  

   -

  $   
. 2  
    
-
       
 (
- 
 
 ,      
 " 

) node.js, " 



  ,      :
 
        JavaScript.
$ node –v

     JavaScript 
  -
       -

, - &    $
         -
 
       "    " :
   - 
 , 

v6.9.5
   
  HTML6. & 

  
    


  / "  
  
  
-

    -

. & 2009   node.js,      
. 
9  = (Ryan Dahl) 
 

-  
  $       

    Joyent
%   node.js 6.9.5, $       -
  JavaScript 
  

 
- %  
        $

,      

 
     
 node.js.
node.js. &    $ 
 


% 
   


 


 
  ,   %   Установка набора

 
  .
средств разработки
&  
   ,    - =   

  node.js 
   -
   
 node.js 

  
 
 

 
 

,

      " 
-
         
  -

 . ; 
   
,

, 
  $     -
   

       -


7. /      
 
     
  8 ( 
 -
   
              ). = -


 , 
   
    - 
  Windows %  $  
-
 . 
 node.js    -          

 

  -


    -

 Microsoft Visual Studio,   macOS —
   %         

 


 XCode.
   + 
. ' 
 
  Visual Studio  ,   " -
   

 $  ,  % -      
 Community Edition.
     

   - 2
  
  ,   -
   
.  ,    
: www.visualstudio.com/
downloads/.
&  
 Processing,  

  XCode   
    
-
node.js "    
  
 -
  Mac App Store.      $
  
   . 9
         
 
     "    
. XCode 
     
 . / -
6
HTML, HyperText Markup Language —  
  -   ,     "  :

     . $ xcode-select --install
7
2   $           
   ,                 

 
  


,     

        node.js.

   

 

 — PHP, 
-
8
    -

 — 

, Apache. 0  . toolchain.
Средства 51

Пишем код
+,   node.js 
 console.log("Hello world!");


. 2    -


,    
 " :
 
      
hello.js    
.
2    

 
- $ node hello.js
   
  , 

  
  

-
. 2  

   -
  ,     :

&
    $ Hello world!
   $
     
 "   :



    " ,  % 
-   -

 
  
 HTTP10.
    Processing9,  ? &    $ 


   -
   HTML, 
  ,   
-
 $    -  . *

, %  -
Веб-сервер на node.js 

,   "
  ,   -

 node.js 
   
  -     

  
% 
       -

,     - 
 . #

 

 
  
" %              

-
 

 .  (. . 

)   , 
 " $
 - 
 .
&  — $ 

, 
 
 -
   
 
 

, - 
 HTTP,

  
 
-

   
 
.    -    
     3,     -
     
 

 node.js.
9
  ,
     
 
10

 node.js 
 , $    HTTP, Hypertext Transfer [Transport] Protocol — 

«2
  , 
!»    . 
 
  .

Пишем код
#     %  -
     
simpleServer. 2  
   -


,    

    

-
  
     server.
js   simpleServer.

9 
  
 ,
   ,    -
" 

 

 node.js:
52 Глава 1

// '    " 


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      : 0
   - 

    
-
 
:
$ npm install express

/       npm —   


 http://localhost:8080
  node (node package manager)   - &
   
  
 , -
   express.js, 
 -    
 . 1.5.
 


. & 
   
  
    
  , 
 $       
  
    

  ,   - 
  "    " :

%      
"   -
   
. ; 
     " Got a request! ( 
 !)
 :
$ node server.js +    
  -




          


.
&
    $    $
 +     
  
 

      "   :  -

  

  
 , -
  
    
 favicon — -
Server is listening on port 8080 (#

%      
 
  

 %  
 8080) 
 
  -

.

  $ 
     
 ' 
%
 

  -
     ,  ,  

,   
 
 

    hello.js,    - % <Ctrl>+<C>.
Средства 53

Рис. 1.5. Результат исполнения программы


сервера node.js в браузере

Структура программ node.js    listen()   server, 



#

 

 node.js (
  
 %  
 8080     -
   
 
 

)  , 
    .
     Processing. 9 
 -

 $
 . ;
 , 

 JavaScript    

 . /   ,    

  , JavaScript (,    ,       
     
node.js)           
 " ,   
%   -

  . /   ,  
  -  . 
       
-
 
          
   ! , 
  -
  —      "    ,        -
   var. 3 JavaScript   -
 . 

     -
  
     
   -       
 
   
      
 .  

 server.js —   server.
get() 
   
   
&
 , JavaScript    
  respondToClient(), 
      

  


 . ;  
     
    -
   
    ,   . >
     
   
-
 . &       ,  
 JavaScript,

   
 
 
 $ 
   
-     
 ,   -
 .  
  

  -

    
%     ,  

 " 
 . & 
 
 

-    
 .
     (
     %!-
 )   node.js express, 
 &   JavaScript       

     
  express. [      #  Java. &    , 


$            - ( 
)      ,

  http. & 


 
          
.
express()   $ 
   #       #      
express, 

     
     

 if-then  


server. = ,    

 ,    -  for.
54 Глава 1

# 


  node.js      &    $ 

   
 

: 

 server.js.

1. # "   require() - =     


     
     . node.js     
  , 
 -
2. 0  
 ,    -  
  -   www.nodejs.org. >
 
      

 
  


     
(   ). node.js         $
(Shelley
Powers) «Learning Node: Moving to the Server-
3. 0    
   , Side» (   O’Reilly). 3   / 

        >
  (Ethan Brown) «Learning JavaScript» (-
 .    O’Reilly)      
4. +        .   JavaScript.

 
  JavaScript      
HTML5 и веб-приложения $    
  , 
   


#     
  
   - 

 

. 7 
-

  
  — HTML5 — 
       ,      -
      
  

   ,  $ 
  
   -
 
  
  . 0   %    %
 
  
       
  
- 
    
,    
    
         -   , 

   
 

 ,   
 " 
 $  -       
   
 -

. *  ,     HTML5  -    ,   

,   

   
 ,        —     
  , 
 
    -      

.
  JavaScript   
   
  CSS3. 
 
 ,   "    -


,     
     -
  
 HTML5, JavaScript  CSS3 
      
,  


 "? X
",   ,      . 9
 
 
HTML 
     "   ,       

% 
-
CSS — 
   
,  JavaScript —     + 
 
  
 ,  
             , 
, 
  
   . `  HTML     
 
      
.


 
   $    : 
 , &  
- 
!     ,  
,
$   ,      
. 0  -    
  
   
"   
   , 
 + 
, $ 
  %      -
   - 
  :   ,  ,  
%. ~ 
 
   


 . ., —    HTML          ,   " 
  
"   DOM11.   
 
   
   
-
 CSS       

-  
         

.
   $  :  , %
 , &    
,  % 
" 

     $    . . 3         + 


 —  
11
DOM, Document Object Model —      -   -          -
 .  
 "    Google Docs 
Средства 55
Dropbox. >

      
- >  p5.js    
   -
"        ,      . 
   
  $
%      # .   ,     
  -
       https://p5js.org.
9  
        
- =     
   

  "     —        _
7
 (Lauren
  % ,  
 

- McCarthy) «Getting Started with p5.js» ( -
     
 . # 
  Maker Media).
HTML5  JavaScript, 
"   
   
 
   
  =    

  p5.js    -

  
 ,   $ .     

, 
&   "  
 
 
-  
    $   . ' 
  
 
 ,    GPS12,
   , 
   -
 
 
  
 
.   (  Complete Library)   
https://p5js.org/download.
*  $    
  
  —



 

  "   - &       

      . $
 -  empty-example, 

 

           
  p5.js  
-


,   , 
  ,        . #
  $ 

  
   . & " ,  
 , 
   , 
 ,      
    ,      


 
    %   
  
  
    ,
 
  -
   
,       -    " : HTML-
   
   
   
- 
  index.html  
%  
 ,
      .    libraries    p5.js

 %
 (addons): p5.dom.js ( 
-
Библиотека p5.js     DOM  HTML- 
  )
    -

    p5.sound.js ( 
   -
" 
 node.js,    - ). & 

     
   
      - 
 , sketch.js —  ,  
     
  "     
 -    .
. =  
 $    

    -


  HTML '    
   p5.js
  " JavaScript. #"  - (  
  
 JavaScript) 
-
       
 JavaScript
   HTML- 
  ,   
-

 

.     -      <script>,    
,    
 

-  
   
. /    
  
  
 . ; ,       URL-
 
    -
  Processing,       % ,        
, 
 " -
  p5.js,       

. =    
" 



    -     
  
  
    Processing. #   ,   <script>. 0
   index.html  
     
  $      example-project,    ,   
-
 .         
   p5.js,
12
Global Positioning System —   (  )         

  -
   
     .    sketch.js:
56 Глава 1

<!DOCTYPE html> $ p5 generate --bundle myProject


<html>
:
<head>
$ p5 g -b myProject
<meta name="viewport" width=device-
width, initial-scale=1.0, maximum- ~   p5.js     Processing
scale=1.0, user-scalable=0>          ,  
<style> body {padding: 0; margin: 0;}  

 .      -
</style>  Processing,  
 p5.js 
  -
<script src="../p5.min.js"></script>  setup()  draw(),     
<script src="../addons/p5.dom.min.js">      Processing,  
</script> p5.js     JavaScript. &    ,

<script src="../addons/p5.sound.min.js">   
 p5.js         
</script> JavaScript,    Java, 
  
<script src="sketch.js"></script>   "    var,
</head>   — " myFunction()  . .
<body>
</body> 7   
 p5.js   -
</html>    Processing:

/        % - function setup() {


//   $ $  #
 
           
}
  . =
 
 , 
  
    , 
     - function draw() {
   , —     - //  ,
  $         " . //    #
}

  p5.js       
   %     
-

 . = $ "   
 -
   - 
  
      ,
  node        p5-
  draw() 
       -
manager:
,   
       -
$ sudo npm install -g p5-manager     -  
  -

,       .
  $      $    
 p5.js 

    
  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$  :
Средства 57

#
   ,    - myButton.touchEnded(changeButton); //  % # '
//    

    index.html 
 
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 
%     
         % (
 
   - 
 ,       $
      
  ).
$.   "        %
(   
 ,  
 )   
 "- 
   
     p5.js -
   
    $
 ,     
-    
  
    
  
     
  - 
: https://p5js.org/reference.

  . &  , 
 , 

    ,   $  
   - 7 "  
    p5.js  -
   draw(),        "   .

Инструменты для работы   



 $ 
   
" , 
      
через последовательный порт "  
   $
9 

 ( . !. «'      . &  " 
   -

     
») 

   
  %    $-
%

 
    - 
  

  
 
  
    
 
 + 
,  
   
  USB 
     $  
  . 
 

   
 . '


   

   -       
  " -
         
  -    


  
 

,

. #
       %  -         
.
    + 
  "  

  - %
     , & 
  $      
-
 
        "  

       
 -
 ,         
     

 
-

 
. 3  

 - . #"   %   
  

       

 —   ,     .
 
       - 0            -

 (bulletin boards, BBS)  "      

 CoolTerm,

 
58 Глава 1

9
 7
 (Roger Meier), 
 
 PuTTY (
 . 1.6),  , 
 -
  
  -   http://freeware.    ssh,      

the-meiers.org. 


    -     
 . &   


  macOS,    Windows, —    
   —     -
 $     

.   

 Screen (  
4  
%   ,   GNU),   "    
 . /

      
  ,   

        -



      
. 
   OS,       %
=   Windows 
% 
-     ,   

 CoolTerm.
      
 
-

Рис. 1.6. Установка типа подключения и последовательного порта в PuTTY

Рис. 1.7. Окно программы терминала CoolTerm


Средства 59
   
 

,     
-
Кто получит порт? . ' 
 
    
;   
     
  
 

,    Connect 

      
. +  -    
      

-
,      
 
    . '  
 

 -


 ,  
 

   
 
,    Disconnect.
     ,  
 



% 
 $ 
.  
-

     
     
, Программа GNU Screen
  
%      
    Linux  macOS 
 -
. 
 $            -     
    -
  ,  "    
 
,  

 CoolTerm ( .
 . 1.7)  
 
  
        $ 
  

 GNU Screen.
    . 2
%
   -
   
, 

   
. * Ubuntu 
 15 

 GNU Screen
+  
  

 ,
"   -
    ,     :
   
, 
     
 -
      
 

. & 
$ sudo apt-get install screen
     



   

 
     , ' 
 GNU Screen  macOS 
    
. &
 ,    -
Linux, 
    
     
,  
       -
  "  :
  ,  
 
   ,  $
    . &    $ 
- $ ls /dev/tty —* # macOS
    
      
 $ ls /dev/tty* # Linux

 
    
 ,  -
"  ,  
 . 4  
 - &
    $    
-
    
,  
   
             


 
. 
,        . [
  -
    
  macOS  Linux 
 ,   
 COM1, COM2  . .,  -
Программа CoolTerm    Windows,    

2  

 CoolTerm (
 . 1.7)   $ 0#      . & 
 -
"    %    Options. & 
-      
    -
%     Connection Options   :
 
 
 
"     Port
$ screen  _ _ 
    
,  
 -
 
 

Arduino. +  

*

,  
    
 macOS 
   
 :

  macOS     
 -


 Arduino  
  9600   -
/dev/ tty.usbmodem1441
 ,       :
& Windows 
    COM1, COM2, screen /dev/tty.usbmodem1441 9600
COM3  . . '   
,  -
 
    % 
 

#  "    Linux  
Arduino, 

   
 
   -   :
  
  ,    — 
   -
. 
, %       - screen /dev/ttyUSB0 9600
60 Глава 1

&
         
 
  , $ 
-

  "  ,      -   , 
  ,    

  
 

     - $  , 
      -
 
   ,     
 ,
     .

    
    

. 
 $      $
 & 
 


 "

  ,   
,     . 0     %  -
    
  
 

,
,         -

    $
    ASCII.   
   
    
' 
     
, -          -
   % <Ctrl>+<A>,    —     . /   ( 13)
<Ctrl>+<\>.      
 /   #
 ! 
. &   
 
 
&  " 
  
 
,  -     
    GPIO (
  
 

 
 -  . General-Purpose Input and Output) 
   
 "   - 
  I/O. 7  
 

-
" 

 .      
  
         ( )
GPIO,       

-
Оборудование  
,  

    $ 
 
& 
  , 
    -   "  
 ,  " 
    " 
 ,  
   -
  

 . &
 "  
: 
 

  

 
 "  
?
     
  
-   
 
      -
  —    
 . 1.1; . 7
 


  -
? $ 
   ,    -  ,       
     , 
 " - 
 

 : 
 
, 
       (RAM14  ROM15),   
  -

      ;     —    
,
?    
  


   


   
  
 
  —     
, .

   
 ;
? 
 

 

 
. =  
  
  
 -

 
    8-

 
-
 

,   
 

, -
Микроконтроллеры

 
     

 
  
"   
 . 


  8  (

). 0 
4   -  
   $ 
- 

        
     
        ,  
 
 
,  , 
 ,  "  
- %     "  , — -
 

. &% $ 
    

,       -
" , 
 , 
 ,     
  $ 
 .
        —
13
%    
      
- 0  . pin —  .
14
Random Access Memory —  
  -
 
 

. 7
 

, 02X.

    
 - 15
Read-Only Memory —       -

, 
  
" , 2X.
Средства 61
*     
   32-

  Arduino, Wiring и подобные

 

 (

   микроконтроллерные модули
32  
)   ,    -
    8-

  
 . & - = 
  $        -
%  
   
, 
 ,    
 

 Arduino.
    64-

 
 
,   - 7 Arduino (www.arduino.cc), 
 
-
     — 32-

 .  
 

   — Wiring
(www.wiring.com),  

  + 
*
 
   
   
       


 

. &   
 - +
 (Ivrea)  2005 . 0   

 
               
 
 -

 

PIC   Microchip
 ATmega   Atmel (www.atmel.com),
(www.microchip.com), AVR   Atmel   


   
   
(www.atmel.com)  MSP430   Texas   « »   C/C++. / « »
Instruments (www.ti.com), 
%
      Processing,   ,    -
    
 %       




 IDE (  .
 
 . #
 
 

 Integrated Development Environments), -
32-

  
 
   " 
 " 
 $   " -
    % 
  
-    "  . &    , 
 IDE
 

  ARM (www.arm.com).  Arduino  Wiring    

/    
 

 $     Processing —    
  
  ,  - setup()  loop()16,   map()  
 .

    
 .     , 
  
   ,  Intel (www.intel.    
   $  ,
com),     
 

, "    
  Wiring,   -
   
  
    $
  
  Arduino   -
  , 

  
 
 -   . &  " 
 " 

 ARM, Atmel AVR  


.       Arduino, -
 "  
 
 


~  
 


    - 
 
. ; "   

 ( $1  $10  %),   - 
 
 Wiring,     

     
 
   
     Wiring S. 
 ,
     
      
   
 




 ,   
          Arduino. *
 . 1.8 

 ,   

     ,     
%,   -
    ,       $ . ~ " -
 % ,    
  
 ,
 -  

   
  

    $   . / 
    %   Arduino   , %   

%   
   
 

   Arduino   
 
  

,          - %    . &   -
  $ 
 . 
 Basic Stamp 2  ,  $    . =
 

(BS-2)   Parallax, PICAXE, Wiring,  
  
 API17, 
 "
Arduino   , 
    - Arduino  Wiring, $  " 
-
  
  $  ,  "  -  

 ,   Arduino  Wiring,
 
    
 

, 16
7  draw()   Processing      
     
   -
loop().
  

 . 17
API, Application Programming Interface —  


  


 .
62 Глава 1

2
3
1
4

15

16 14

11
13
12
10
5

9
7
6
8

Рис. 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,   -  ,     
- 
    
 

. =
 ,     %   
   $      
-

 .      
 

 
  ,    
  . 
&       
  $ -    
     
 
-
  
%    ,  " -


 Arduino IDE 1.8.2  -
32-

  
 

    
 , 
   


 

   
  -  
 www.arduino.cc.
   
  .   
Arduino Uno,  
 
 
  
- 3
   

      
 
 "   ,   
 - Arduino, Wiring         
  Wiring S  " 8-

  
 ,     
  
-
Средства 63

   " . # - ;


 ,    


   

        ,     ,   %   $  -

    ", 
 
     
    , 


 

 ,   
  
- 
 

  "     -


. 3  , 
    
   


    
 
   
,  
 ( #)  "     
. *
         
       %   
  
-
 
 . 0    "  -  

     
%  

  ,    


      -
%       
 ,  
  —   Python  JavaScript,
   
 
    
-   
     " 
-
     . '    
    .   32-

-
$   ,     
    2  
 

 (  

 -

 
   
 Arduino-     ARM)     
,  -
           . % $   . 7

 

  ARM    
   -
0     %    Arduino 
,   MicroPython, BBC Micro Bit,
 Wiring — $ ,   
  - Espruino  NodeMCU. +     Python
  
 
 Windows, macOS  JavaScript,   
    
 Linux, —     
 

- $ 
 .



     . =

     $  
  - 0     
 

  -
  
 %
   
. ;    ,    
   "   
 -
  

  Processing   
. ;    
   
    Java,  

 ,        
 
 ,

 IDE  Wiring  Arduino,    -        % 
 

-
  C/C++,   
       "   
 
 
  C — AVR-C. =     
-
 .   MKR1000,   
  $ 
         Arduino 101  "  
 
 
$  .
  —  
  Ethernet (Wi-Fi)
 Bluetooth LE18    . #
 
3     Arduino  
 -
    "  
 
-
     


 -  

 — 

, 
     «Getting Started with Arduino» ESP8266   Espressif    

(   O’Reilly),    7  Wi-Fi,   BLE Micro  BLE Nano  
>  (Massimo Banzi). RedBear Labs — Bluetooth LE. 4    -
  
 ,  
 

-
Другие микроконтроллеры 
    
  

-
&        
 
-    
 

.

 
    $ 
 
   
 . 
 $  - Функциональные возможности
   "   $
  микроконтроллеров
     :     - 7
 

— $   % -
   
 

   

- % 
. +    -

     
   %
 
,    "
     ,
   , 
  


 
 . 18
LE, Low Energy —  $

  .
64 Глава 1

а Arduino 101 б

Кнопка Разъем MKR1000


Разъем питания полного USB
Разъем
(пост. тока) сброса
USB
Кнопка
сброса
Разъем
Кнопка
2C для подключения
I сброса
LiPo-батареи 5В
Aref (ввод питания)
A0 +5 В (вывод) Выводы
~Выводы ШИМ A1 +3,7 В (вывод)
Выводы Аналоговые A2 Общий («земля») питания
(3, 5, 6, 9) A3 Сброс
питания вводы A4 14 –> TX
A5 13 <–RX УАПП
Цифровой A6
0 WiFi
12 SCL
11 SDA I2C
Аналоговые ввод/вывод Выводы ШИМ ~2
1 Radio 10 MISO
9 SCK SPI
(in processor)
вводы (0 – 13) ~3 8 MOSI
Цифровой ~4 7
(A0 – A5) ~5 6
ввод/вывод
УАПП (0 – 14)
Bluetooth LE Разъем SPI
Радио, акселерометр
(на микросхеме
процессора)

Рис. 1.9. Функциональные части плат Arduino 101 (а) и MKR1000 (б). Обратите внимание, что номера функциональных
выводов — т. е. аналоговый А1, цифровой 2 и т. п. — не соответствуют номерам физических выводов платы. В технической
документации обычно имеются в виду номера функциональных выводов, а не физических

     


   -   %  USB 
 -
  
  
 . *    
   

  USB/

 . 1.9      - TTL-Serial.


" 
 

  Arduino 101
 MKR1000. 0 $   
  >%    
 

 -
    ,           , . .   
/  "     (GPIO),   


    
  

    
      -   
   
 . *

,
  . =
      -      
 , -
      
        (~), 
 -
     : 
  (
 

    
 

 
  
    ) —     , 
      -

 
   
 
-     
  ,
    
  
 (X3)19    
 : 
       . /
 
 SPI20   
 I2C21. 0 $  -       
-
  -

 
 
   
   
 (+7)22      , -
  2. * 

 

 

, 

  
    
   

  
      
  
"  $ 
-
% USB. =
 — 

, Arduino Uno,  .
19
0  . UART, Universal Asynchronous Receiver-Trans-
mitter. *     
  
 

,
20
SPI, Serial-Peripheral Interface —      -      -  

 

   
 .  "      :
21 2
I C, Inter-Integrated Circuit communications —   -
22
   
   . 0  . PWM, Pulse Width Modulation.
Средства 65
? /  "    ; 
 
: 
 
86  
 
ARC23,
?   ;
"   . 9  24 $ -
   ,     Arduino Uno. 

?   +7 (PWM);
,      
 
 ,   -
?      :
 
, 
  
  
 
• X3 (UART) —   
 ; Bluetooth LE.
• SPI —  
 ;
&
  — MKR1000 —      -
• I2C —  
 . 

SAMD21 Cortex-M0+   Atmel.
&    

   , 
/   %  
   " 

 

    %
-
     LiPo-
   -
     , 
 —  . & -  
,         
%

 
 

   
 ,  
 
   
   ,      -  
 .      
 

  
    

Wi-Fi.
     .
;
      
   ESP8266
Какую микроконтроллерную плату   Espressif. * 
    
выбрать?  , 
     32-


= 
  $   
% 
 - 
 
  "   

 Wi-Fi.
  %           /  $ 
 Arduino        

    % ,    
 "  .

 

. * $   ,  - * $  
%   
  ,
    $  , - 
 
       / -
  
      
  ,      

 Wi-Fi  
-
   
. *   
 $   -  
 

.
  ,  —    —   %
    
 ,          $ 
   -
   . 
   , ,       ,

        
 . *    $   -
О напряжении питания плат "     
   ESP8266
= 
   
 "           Arduino,  

    Arduino 
       
  
  $ 
  5 &,            - 
 
  . +    ESP8266,
  %      
 
 
,     

    5 &. *   ,  -
  Huzzah! ESP8266  
   
  $  ,
 Adafruit  ESP8266   SparkFun.  -
 
  3,3 &. * 
 , 
-  ,    
  "

 Arduino 101,   
 
   
 $ 
 .
5 &,         
$   %      23
ARC, advanced RISC Computing —     

     
  
 -  
%   RISC-
.
 3,3 &. 24
= 
  
    
   , 

  «
  »   
  ,
    
 «  
     /
 ». 7 ,   ,      
-

  $  — Arduino 101 —  -     - 
  « »,   
%  
   

Intel Curie. /  

     % $ $ 
     -
      
  32-

  
        % 
 .
66 Глава 1

*

,   Adafruit 
   

   Huzzah! ESP8266 breakout
Feather Huzzah! ESP8266     %  board  ESP8266 Thing 
    

  Huzzah! ESP8266 breakout 
  USB/TTL-Serial. 4   
-
board. 3   SparkFun 
   ,    
,   Feather
ESP8266 Thing  ESP8266 Thing Dev Board  Huzzah! 8266  8266 Thing Dev Board.
      . #  Feather Huzzah!
ESP8266  ESP8266 Thing Dev Board  &
 
      


"
,      

- 
    ,  $ 
 -

 
  

  USB. 3  
-    .

Шилды Arduino
0        Arduino, 
 # 
    
   $   

    
,   -
    
 

-

 %
,    
 
(shield), 
 
  
-
. &


       $
  

 
  
-
Arduino        . &    %,      
 Arduino  %      
     . *
 . 1.10  -

  ,      
 %.  


  %   . & % -
*    $   , 
    
  $      % , -
Arduino Uno rev3       
 
          , -

 

 
. = %            -
,
%  
      Arduino    $       —  Arduino 101,
   , "  % ,    MKR1000.

       

-
. +  "      % 0    
 ! *  %  -
      
 
 
 
 -    . 0  
 
 
 
  Arduino.    

 
     
    
 
       
 
  
,     
  
  ,  " " -  
  5 &  3,3 &. $, 
  
  
 $ 
  . + 
  

 %      , 
-
    

  %     
     

    %
 -   www.arduino.cc.  ,    ,      .

Рис. 1.10. Шилды и внешние модули для широкого диапазона приложений


Средства 67

Создаем первые программы для микроконтроллера


Загрузите последнюю версию программного обеспечения для Arduino с сайта www.arduino.cc
и установите его на свой компьютер, следуя приведенным далее инструкциям.

Установка на macOS Начало работы


9   
  ,     ; 
  
 Arduino. -
   "   %.  -      
 USB 
 

  
   
 
 - "      Arduino IDE   " -
 Arduino. ,    
  . 0
  
 

  (
 . 1.11).

" 
    Arduino.
X  


 Arduino,   #


 Arduino    


  
  
 .

 Processing:     
 -
  

 
   
D (New),   (Open)  D= 

Установка на Windows 10 (Save). ;        
-
2
   " Windows,
    
   —  
 (Verify)   
       . & 
   - #   (Upload). *    

    
 
 

%      
  

 , 
    
  
 
 USB. 

   %    ,
9
%    $  .    #   — 
    -

     
 

. 

 
%     
 


- ,  
 
    
 

 Arduino IDE    


 .
     "
   (Serial
Monitor), 
 
     -
           
Установка на Linux  
  .
&
 

 
 Arduino  Linux
       
 Linux.
= Ubuntu 14     
 
-
     www.arduino.cc,
  
, 
    
       - Внимание!
"   : 

       Arduino  
   . & $      

$ sudo mv arduino-1.8.2 /opt
$ cd /opt/arduino-1.8.2/ 
 Arduino IDE 1.8.2. *   
 -
$ chmod +x install.sh ,       , 0   -
$ ./install.sh   , $ 

    Arduino
(www.arduino.cc)  
      -
 
% 
  
   "   .

       Arduino 
  
 . 
 $,   
     
 dialout, 
    
   -
  
 :

$ sudo usermod -a -G dialout $USER


68 Глава 1

``Панель инструментов.
Самая правая дальняя кнопка —
Монитор порта (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)   
  macOS  Linux     -
(Board)   
     . 4   
   
 :
%     ,  - /dev/tty.usbmodem1421 (Arduino 101)
"   " A  ( $  ,
    ! «*  »  ). * 
  Windows    -
2    
            
   
  COMx, 
     (Serial Port)    - x — - 
. *

, COM5.
Средства 69
Порты Windows    

    " 
* 
  Windows 
 
 #      ,      -
COM1  COM4    


  "  
    " " 
 
       
 — - 
 :
   ,          
Z $  928 
 (2%)  
 
 . 
. +   32256 
.

Менеджер плат 2  

        
       
   -
7   ,  
  -    .
   
  $      -
     % 
 Arduino IDE.
  
     
% ,
'
  ,    
      
. =    $ -
 
    ( 
"
  " A  Arduino IDE, -  L25)      


 
   ( Arduino 1.6.6       . &    
 

-

)             $  

 «2
  , 
!».
    |  | " A .

& 
%      
  
  Программа не работает
 . 4       ,     - 4    - 
 


-
  : N  . & 
    -     
,    
 

   "        
  
  ". 7      
     N  .      
  Learning  -  
Arduino (www.arduino.cc/en/Tutorial). 

=     
  
  -
,  
 Arduino (www.arduino.cc/forum)

         %,   -
   , 
    
 —  
(URL) 
 " 

-
 ".
       Arduino IDE. *

,
     
   ESP8266,
             ~            -
\ | ] 
   
    /    
,  $  -
! 
  
 " A  .  
 ,  
   -
=  ESP8266  
  : http:// ,     LED_BUILTIN,  
arduino.esp8266.com/stable/package_esp8266com_          ,
index.json. 2     OK  
- 

    
-



.   $     . *

,   Arduino 101
   
                Uno  
  -
. ;  
 
 
      -
     13,   
  
  
  
  .
MKR1000      6. 0 
& 
 
              LED_BUILTIN

,     
,  - 


    
   ,

  

 .     %    
      " 


%  
   
 " -       
  . & 
      

             
  -
"  

  + . ; 
  —  ,      , $ , 
   #  ,  
   "   
     

   
 

.         
-
2
      .  
-  

 .
%  
     "  25
0  . L, LED —  .
70 Глава 1

Связь по последовательному       ,  , 


-

, 
  

 
  
порту 
 
 - -
0    
 
 
  , -     

  

     
 

 
   
    ,   
$  ,    
   
 
  
 .

Пишем код
&  "    
- /*
 
  

 : 

 
: Arduino
      
&   
;     


      
- 
    #   . ƒ  '
 
 ,      -    
 .
    ,  " */
 
  
 ,    -
  
  
   
 - int inByte = 0; //    -   -
// -
  
   $
long blinkTimer = 0; //    ,  

 —      //  '   
   
    - int blinkInterval = 1000; //   ' /'  —
   . //   

/   Arduino   - void setup() {


    
   - pinMode(LED_BUILTIN, OUTPUT); //   13,
//  
  
. 0   
Serial.begin(9600); // $   
        //  
 
 
 
 , //  9600  /
 

    - }
 (    ,
   
 "  

), void loop() {
 

  
   // †  -  :
if (Serial.available() > 0) {
  .
inByte = Serial.read(); // Z  

:
Serial.write(inByte+1); // M   $ 
//    # 
// :
}

//      .


// +'      :
if (millis() - blinkTimer >= blinkInterval / 2) {
digitalWrite(LED_BUILTIN, HIGH); // '  
}
// Z    '   
// 
:
if (millis() - blinkTimer >= blinkInterval) {
digitalWrite(LED_BUILTIN, LOW); // '  
blinkTimer = millis(); //  

}
}
Средства 71

Инструмент Монитор порта


+ 
  "
  
 Arduino IDE &     
   -

  
     " -     
 ( % <Enter> 
  Arduino. =   
   
). 7    "  -
    
  
 
-
  . & 
  — -

  
  

  -  
  ,  

  
 

. 2       ASCII26        
  "
   (   
 
    
 
.
   
 ) — 
      - 26
ASCII, American Standard Code for Information Inter-

 
 (
 . 1.12).    
  change —    (
, 
),  -
            
 

 
 
       -
9600    .        .

Куда делся мой последовательный порт?


    
,          
  -
Arduino,          

  
       
   

 
, 

   
  - 
   
    . /
     
           ,  
   
 
       
  
  ,   
  

-
Arduino 
 
 USB. 
      
       ,     
 -

 
 
        
   
, — 
 ,  
   
         
. 
 ,     % ,    
.

      
 
    
  
 

. * - *       
   
  -

  Windows $     
 
        
! — -
COM-
,   
  macOS        
 

,  " $
 -
     
 
.     
 ( %   —  


). +    
   
  
     .

Рис. 1.12. Окно монитора порта среды


Arduino при исполнении предшествующего
скетча: пользователь ввел буквы ABCDEF
72 Глава 1

Подсоединение компонентов Цифровой ввод


к плате Z
  
 

 — $  -

   / ,  Arduino  % 
  ( 

,  ),
 Wiring  "  

-       
 
, $   
    -    
  
 
-
     
 ,  "   
,      "     -
   "   (    
  («  ») 

 


),  
        -     (10 0     ).
 . *
 . 1.13  

 - /
 
    
 #
 !
-
          . 7     «  »
Arduino   $ 
    .   , 
 
,    -
 
  
 

, —
          .
Базовые схемы ввода/вывода & $ 
 
      -
& 
  $        - #
.  %"   "
 

       
   - 
       
 . 4            
     
 -


 
 

  
 , 
     
 . 
$         . 7 
-     
 ,    
      $  ,     -
 . 1.14,          -
    ,    . =    
  (   
-
     
     -   )    . 3 
 
 
 , $        :        " ,
       — 
   , 
 
        -
          -   — 
        
,  " . 
       
 .

Рис. 1.13. Подключение элек-


тронных компонентов к плате
Arduino с помощью беспаеч-
ной макетной платы. Питание
(+5 В и общий) подаются от
модуля на крайние ряды гнезд
макетной платы, называемые
шинами питания. В результате
все датчики и приводы име-
ют общее питание с модулем.
Сигнальные и управляющие
контакты каждого датчика и
привода подключаются к соот-
ветствующим контактам вво-
да/вывода платы. В этом при-
мере две кнопки подключены
к контактам 2 и 3 цифрового
ввода физических
Средства 73
A B C D E F G H I J
К плюсу 1 1

К общему

5 5

Входное напряжение
К цифровому вводу 10 10
микроконтроллера Кнопка
К цифровому вводу
микроконтроллера
15 15
Понижающий
резистор

20 20

25 25

Рис. 1.14. Цифровой ввод на микроконтроллер:


30 30 общий вид макетной платы (слева); принципиаль-
A B C D E F G H I J
ная схема соединений (справа)

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

Рис. 1.15. Ввод в микроконтроллер аналогового сигнала: общий вид макетной платы (слева); справа показаны принципиаль-
ные схемы двух способов получения входного аналогового сигнала: с использованием в делителе напряжения светочувстви-
тельного резистора (вверху) и с использованием потенциометра (внизу). Эти сигналы можно подавать на два разных контакта
аналоговых вводов микроконтроллера

Аналоговый ввод
# , 
   
 . 1.15,   -   . *  
      -
 
  
. & $   
- 
 
 
     %    -
        
 ,  $ 
  . *

, 
 -
   
    ,  
 — 
-           
74 Глава 1


  
      - &   
 . 1.15 ( 
!)    -
  
     
 .
 
 
, 
    -
3 
        
 - 
 .   

   

, 

, 
   1  2 0 (
  
 
,  
" 
 -
 
   

 
), 
-  
     . 

   $   
  2/3   . 
 "    
   
4     
 
  
         -
  -
 

  
-     
 
. & 
  ,  -
 

,  "    "  
— $  
 
 
   
 
   ,     -  . 4       
  
  
   
-   ,  
 —  " ,  
 
 " -
  
 
 
. +        
        .

 
 : 
 
, 
 -

,   ,    . . &   " 
      
-
  ,  $      ,  -

      .

Документируйте свою работу


/     
    ,
  
 . / 
%  
 
  -   

,     -      
    , -

  . . 
   $   
   
    ,   
    , $     
 

-    ,     
 -
 ,       ,  
,   -     
  . = 


   
 
,   
-    
%    
 

  
  $. 
  $ $ 
   , 
   
         
  
      
 

  


 
 ,   
 
- 
,        
 -
     
  
 : "     

  
   
        $ 

• Adobe Illustrator (www.adobe.com/products/illus-


.
trator.html). / 
  
 


,    
  
  /
  28    "   $

 ,    
%  - 
 

,    " 
  
 . = $ 
 

  
,  =  (Jody Culkin)
"          -  =
 0
 (Giorgio Olivero), -
 $ 
   , 
  -  
 
   3 
 
 (Andre

  # . Knorig)  =   $  (Jonathan Cohen),  -
• Affinity Designer (https://affinity.serif.com/en-us/    

 Fritzing.
designer/) —     
 
-
*     ,      ,   -

 ,    
  $  -
     
,    
 
  Windows   "   - .
   %  . _    
/ 
 

    % -


      :  
  
  ,  

   

 Wordpress (www.wordpress.org)
 -
SVG27 % ,   Adobe Illustrator. ;   -
"    -   www.makingthingstalk.com,

 .
http://tigoe.net/blog  http://tigoe.net/pcomp/code,
• Fritzing (www.fritzing.org) — 

 
- 
 "  github (https://github.com/tigoe)  -
      Fritzing 
       
 Maker’s Notebooks (www.makershed.


,  
     $ - com, 
 › 9781449358976).
27 28
SVG, Scalable Vector Graphics —  %
   - +    
    
    

 
.         .
Средства 75

Специальные схемы и модули Ознакомьтесь с техническими характеристи-


ками компонентов
&   
   
    
& 
   $       
 . 7    

     . $ -
      
 . & $              

-

      ,            

 . 1.13–1.15,     
    ,   % 
    
 , 
  . *

,   
,      .
    
    ,
  
  
     -
 
,    
  . Одноплатные компьютеры
& $   
   
    &   
 

, 
  
    
     -    

 
    
-
" 
     ,       
       
  —
 
    
   $ -  ,   /   -

         .  
 
 — $    

    
 -     %   
 . *  -
 
       ,     
   

    -
 $ 
     
 
. ,  
 ,
 " 
 
-

 

 
,     
  
       
-
  . &    ,        
  Arduino    ,  
 -      $ 

 

        
  ,  " "     -
    ,  
 -    ,  
   -
        .         

Рис. 1.16. Одноплатные компьютеры (слева направо):


Raspberry Pi 3; Raspberry Pi Zero W; BeagleBone Green;
Arduino Yuún
76 Глава 1

     %    
    $ - 
  
   
  -
,       -      

 ,
    $ 
 . 0     ,
   
 


  ,   
 
-     / ,   

 . 0   
   -     
 
  

 
  
     ,  -  
  —   Wi-Fi, 
, 

      ,      . . +  $       -
 
    , 
    -  

    ,

     
. & -        
    
  
      %  
  
 . & $  -
      -
 - 
Raspberry Pi       % 
 .
  Linux,    
 Windows 10,

       -

. >%  $  


   " - Плата Raspberry Pi
   
 /  0  
Raspberry Pi  % 
"    ,  %          
 2012 . 
 
    / . 
 -  
  35 
,  
 
,   /    

-   "    $ 
 -
 
  

 
- ,   
  $ 
 
  
  3,3 &     , $, 
   
     

-
  

  
  ,  - 
  
  . #   
 %
      

 .  %  
   , 

  Raspberry Pi 3    
& 
  $         
 ,        -
  
Raspberri Pi, 
 "  ,    %   .
  " 
        
       


 . *
  
-  
      
     
     - $

   Pi Zero W  

,   BeagleBone   Texas 10 


. 
   $     
Instruments 
  
     -  "   
   

 Wi-Fi.
  

 ,
   Raspberry
Pi. #       % - &
 ,  
 Raspberry
 

 
  $   Pi  35 
   
 . '
 
   BeagleBone.      
   -

,      -
 Raspberry Pi 3   &  "  
-    

  
  :  
,

 
 ARM Cortex A7   Broadcom 
     ,      

   1,2 qq,     "    
. *   
-

 1 q   RAM. 
 ,      Raspberry Pi  

-

    
 
,   -    . &    , 
  
 
 HDMI,  
  Wi-Fi  Bluetooth.  
        -
&   
             
  
 

 Linux,  "  Raspbian, -    
   .
  
  "    
  /  
 ,   ,   



   
  " 
       
  
 
    
   -  
    
   -

.
  "   
. $    
 
 
-
Средства 77
 Raspberry Pi  %  
 
    
  Raspberry Pi, -
 

   . #   -   , 
     
 



 

,    
     ,    
  
 

 
  -  %  .
,    "   $ 
  . 

      
    Основы работы с Raspberry Pi
 
   ,   
    
 ,     ,  
-

   .   Raspberry Pi, — $ 
 -
     
  
 Linux 
'   

 - Raspberry Pi (      Raspbian)  -
 Raspberry Pi  
  $  ,  -  www.raspberrypi.org/downloads/raspbian/.

   "  
 : 2
    
 Raspbian Jessie 4.4
   . = 

 $  
?



  A
 5 '     
 Lite, 
,    ,
 ) 
-USB. # ,  -         . 9  
  $   ,     -  
     ,  "  
 2 
. = $     $    ,    
  
-
  
   
  -       
 MicroSD,  
  "
  USB; 
  
   
  
?    MicroSD      ,       
  USB/
8 q ,  " % — 16 q . +  , TTL-Serial (
 . 1.17),   
  -
 ;  
    
 USB 
.

? -  =
USB/TTL-Serial. /
  
        
- Внимание!
     
 
 - '

%      -

,   "   . *    
,  
 Raspbian,  " -
,   1 
 2017 , 

    "



  
  . =
  ,   -
  USB/ $ 
  ,  

   
-
TTL-Serial  Raspberry Pi (ID: 954)  -  MicroSD 
    , 
  

  FTDI Friend (ID: 284) -   

"    
  Adafruit; config.txt        " :

?    Wi-Fi,    [code style]


USB-
  (       Rasp- enable uart=1
berry Pi 3  Zero W). &
 ,   

%

      X    
  USB/TTL-Serial -

  ,   

  
 
,      
-
        "  ,         
  


     Wi-Fi    CoolTerm  
     
-
 . = Raspberry Pi 
    - 
      . X  
    
        
  115 200   -

Wi-Fi (AF: 2638),         
 % 
 -
  
,  
,   . * $
   
  
% -
Miniature WiFi (802.11b/g/n)  Adafruit (AF:       :
814),  
      Wi-Fi
  Realtek. 
   

 Raspbian GNU/Linux 8 raspberrypi ttyAMA0
  

  
 , raspberrypi login:
78 Глава 1
BLACK
GND ,    Ethernet  "  -
CTS
VCC .          
TX
RX 
    ,  
   -
RTS TX RX
GREEN  
    
 Wi-Fi.

Подключение через сетевой кабель

USB 2x
GPIO
     
     -
   
   ,  
 —   -

  
%

. 4  % 
%-
DSI (DISPLAY)

USB 2x


 
 
    


  DHCP (  %  
-
  
%

 $  
  
CSI (CAMERA)

 ),    


  
ETHERNET
Audio
HDMI
Raspberry Pi   
. 

 $ -
Power ,     :
$ ifconfig eth0
Рис. 1.17. Плата Raspberry Pi 2/3 B с подсоединенным пере-
ходником USB/TTL-Serial. Контакты последовательного вво-    
     -
да/вывода одинаковы на всех моделях плат Raspberry Pi
" :

eth0 Link encap:Ethernet HWaddr b8:27:eb:63:37:4a


= 
     Raspbian  -
inet addr:192.168.0.17 Bcast:192.168.0.255
  (login)    pi,  
 — Mask:255.255.255.0
raspberry. &        $
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

  Linux,      frame:0
Linux, 
 
 !. «+  TX packets:103 errors:0 dropped:0 overruns:0
    »
 . carrier:0 collisions:0 txqueuelen:1000
RX bytes:38147 (37.2 KiB)
0    "   raspi- TX bytes:12819 (12.5 KiB)
config   
     
.
= $     : /   ,      
Ethernet 
 
  
 Ethernet (  -
$ sudo raspi-config "  eth0)   
    

192.168.0.17. 4    
   ,
0
    ,    
 -
 
 "  " %- 
-     . > 
  -
,      
,  - 
 

   

 
-
% <Enter>. #   
    1.      3.
Expand Filesystem,   
%    -
 —  2. Change Password     Подключение через адаптер Wi-Fi
 
        . 4           

    
 Wi-Fi,  
  -
* $ $    %  
       Raspbian Jessie
 
 
         . '  
   $,
Средства 79
  
 USB-
      Настройка Wi-Fi с помощью wpa_cli
 "  : 

    
 wpa_cli -
 ,   
  
 

$ iwconfig wlan0
 
 . #     
   ,       ,  -
4   
     -

    ,       
" :

, 
     
     -
wlan0 IEEE 802.11bgn Nickname:"<WIFI@REALTEK>"

. 

    



 ,       
  ,    
%
-
$   ,   Wi-Fi    -
. '   

,   

 . ' 
 
   -
 :
   Wi-Fi,     "
 :
$ sudo wpa_cli
$ sudo iwlist wlan0 scan

* $
         "   О команде sudo
  Wi-Fi   "     . &     POSIX   sudo 
-
&      "       
   

%  
$
 , " 

   
      , 
    
    scan    less, 
-       

(   
   
  :   ! ). * 
    -
  ,    
 sudo,   
$ sudo iwlist wlan0 scan | less 
    
. & %   , -
 

 wpa_cli    
-
= 
 
  " 
     
  ,        
% 
 ,   
%   -

%  
 . * 
Raspberry Pi %      
   — % <q>.

 sudo.

X 
   — ifconfig  iwcon-
fig — 
     
   

      
 . *

,
  ifconfig       
- * $
       
  


  
  ( 
    - wpa_cli,    
    "   :
: InterFace CONFIGuration). 3 
  Selected interface 'wlan0' // 
$   
 
: eth0  wlan0 — - // %
 'wlan0'
     
 
: 
 Interactive mode // \ 

// 

   Ethernet  
  
 
>
  29. /    

 -

   
      ,  # >  
%     -
    
,     -  . &   "  :

  
 Wi-Fi. = $  
%
add_network
 "   
 Raspbian
 
     
,  "  &      
   , 
-
wpa_cli. 
    :
29
WLAN — Wireless Local Area Network. 0 >
80 Глава 1

/ 
,  
     - Проверка сетевого подключения

 
 
. =   : с помощью curl
> set_network 0 ssid "_SSID" _    
   -
> set_network 0 psk " "
    — 
    Wi-Fi — -
&  _SSID                .
Wi-Fi  
    . 4   - 

       -
   
    ,   -  
   -
 , %
-
" :   
 
   


> set_network 0 key_mgmt NONE    
 curl. / 

 -
  -

  
    
2    : 
. 2  

,     -
> enable_network 0 // ˆ   "  :
// 
> save_config // Z-  $ curl http://www.example.com
// %  #   

; 
, 

%  Raspberry &    $
  
    
Pi          - HTML,      
    -

  
 
  
  $ " 
:

 
  . ' 
%



 wpa_cli,      quit. <body>


,           <div>
   ,   "   <h1>Example Domain</h1> (ƒ
 )
ifconfig wlan0  iwconfig wlan0,    - nts. You may use this domain in
 
 . * $
   ifconfig - examples without prior
 
   
 Pi,    coordination or asking for
permission.</p>
iwconfig —  .
(‰    $
  - $  
     $ .)
Подключение к одно- <p><a href="http://www.iana.org/
платному компьютеру по ssh domains/example">More
information...</a></p>
   
 ,  -
((Š  % # ...)
     
    -
 ssh. = $       
, </div>

  
    
  - </body>
 "   ifconfig. 0
    </html>

          ssh _
$@xx.xx.xx.xx. 2  
 
;
   ,    -
_$   


    
    
,  -
 . =  Raspberry Pi $   pi,  
 ,  %  Raspberry Pi  
  
  — root. 3 
 
xx.xx.
xx.xx      

-  + 
.   curl 
"   -

  . *

,   Pi       - 
 ,   
 

 192.168.0.23 $         ,    -

,      — . .
: ssh pi@192.168.0.23.  
   - 
  HTML-. '   
 -
 % 
,    
     
 
  ,   URL-

  ,    
  -  
 
 

.


.
Средства 81

Упорядочивание системы X    


 node.js 6.9.5:
       Raspberry Pi  - $ nvm install v6.9.5

         
  + 

      
- #     
   node 
          " 
-   
   node (npm)    
 
 node.js. = 
  - 
:
      , 
   
    Raspberry Pi. $ sudo ln -s /home/pi/.nvm/versions/
node/v6.9.5/bin/node/usr/bin/node
$ sudo ln -s /home/pi/.nvm/versions/
# " 
  apt (  
  - node/v6.9.5/bin/npm/usr/bin/npm
 

       Raspbian)
       

   - * ,     Processing:
  :
$ curl https://processing.org/download/
$ sudo apt-get update install-arm.sh | sudo sh
X  

 
 node.js: 

 . ; 
,    Pi,
$ 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 $ sudo poweroff
&          ,    
    
 
      " -
  :
 ,     , 
   -
$ sudo logout raspberrypi login: pi          
.

Как выбрать правильную плату?


Выбирая микроконтроллер или одноплатный компьютер для какого-либо проекта, нужно при-
нять во внимание несколько факторов.

  ,        -  
   
. &

-
 — , 
  
     
     
-
  ,  
? 
     
       
   

    -      
   ,   
     
 , 
    -      . 7   

 ,        . 3 
 -

   
 , 
   -
   
     

-  
     ,   -
     
     $   
 
   
. &  -
 
 .    
     ,

  
       
#
     
        .
 10  30   ,      
82 Глава 1

Операционные системы 

,       
 . &        , $ -
и «реальное время»        , 
 ,
& 
    
-     -    ,   -

,  
 

      ,       $     
  

. /   ,   100%   . '    
  


  
 
     $ 

-

 ,       
-
 . /,   
,   ,  $ 
-  

, 
,     ,  

      
:  
     ,     
            
    
 
  -
          —  
(0#9&)31.
   
 

  
 %   $  . ;     
 
 
 


    / , 
    
  %          -
%      " 
-  
    . 0 ,  
,
 
,    
  
     
 / , 
 
  
 
. 0
    -  
    % . & 
 

 — $ 

, 
 
  -  
 0#9&    
 -
  
  
 
. ;   - 
      

   
-

        
 #
 !  , .    : 
 

 

-


    

  
-   Arduino 101     

 
,    
  
   -  
   
    
 -
   %   
  —      
 . 0#9&    ,  
-
 SD-
 ,    !  
  /    
       -
  (>#&&)30, 
      -  ,      
,  

  

   
        
 
  

 
, 
    $
 . 
 
   
   .
2             !  !-

, 

    % >%  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.
Средства 83

 
   
   
-         . .? >% 
  , 
 "  

-     
%  
  

  . *       
    , 
     


 , 
"    %  
 .

 : 
    
  ,

    , 
  
  -    "   ,

    
 , 
     + 
, %  -

% 
    

    . &  
-
   . =        
   "    .

   % 
 ,      2 % , 
   
 

   
,     
- % 
        
     0#9&. =
%     ,      %  -
 
     - 
,   
    
-

      
 -  

 , 
   
    . 2 

     ,       



     , 
  -   
      .
    
     " - & + 
         

"
     
?   "   
  
-
,      
     
 ,
&      
   -
"  
    
   -
        
    . X     -
 
 ,    - 
          .
 
  - 
  ,  
 ,    
 


  0   
"   
    
-


  
 . =
%  -          %  
         

     , 
 
 -
   
 -  %        
 -
  
 
      . *       
%
 
 . /  
     -  

    
 ,  $
       . &% 
   %, 

      
"  

 , 
  
 
 -   
  . 0       

,   "    


 -   "     
    % 
 

   " 
        .
USB- 
  
  
 


, 
  
 
    ,   
 "
 
-
  . /   —   
 
     -
 
  -

 

      -
 , 
 

     

 —           "  


 ,   "   

   $   .  
  . *

,  
  $  
   
  Wi-Fi, 
  -



       
 
-
Безопасность
. 3       
2      

,   -         , 

"   %  
?  -  
 
 

.
         
 2 $   
     %
 

     ,  "       
  

-

     
, -     . * 
   
 
84 Глава 1

     




   
     
-
      
  Wi-Fi,
-  

, 
  
 
"     
 

,         0#9&,    
 ,    

   
- 
    . 4   
 , 
        
. / 
%         
      
 ,  
     
  

      .

Работа с осциллографом
Большинство проектов этой книги содержат схемы, которые отслеживают меняющееся во вре-
мени напряжение. Независимо от выполняемой микроконтроллером операции: будь то отсле-
живание состояния цифрового или аналогового входа, управление скоростью электродвигателя
или отправление данных на персональный компьютер — он или считывает или генерирует из-
меняющееся во времени напряжение. Частота событий, с которыми работает микроконтроллер,
настолько высокая, что она находится вне диапазона человеческого восприятия. Например, при
последовательном обмене, который мы недавно рассматривали, импульсы электрического тока
подаются со скоростью 10 тыс. раз в секунду. Эти колебания тока невозможно определить с по-
мощью мультиметра. Для этого требуется осциллограф.

0 
 — $ 

   - 
   
    
    $ 
     
   ,      
-

 . =        

      
  

   
,   $
 . 0 
      -
      
 
  
  1 7q,        
(        
  
 %  
      -
% )   
    
  (  -   . *
 . 1.18   
 
,     
    -  
 Nano   «2
  , 
»
    
   % ). ; 
 

 Arduino.  
      
   
    
    
  
  —    
 
     .  
    
-

 ,       
  ,   
  ,   
   — 
-
 
  ,     
  - . & 
   
 

% 

  
   
   
- 
   %
  200 
  
    (
 ).     % ,  
  — 1  
   % . 0 "  
 -
4"
       
      "  («  »)   
 
  %    ,   - Arduino,  
 —  
   1,
" 
 
     
 "         

   . +       
.

   
 DSO Nano, -
    Seed Studio (
 . 1.18).    
,   
 

    $100 $  
  
     
 Logic -
  
% 

     -   Saleae (www.saleae.com)    -
$   $ 
 . ~   -
    
    -
       
  - . *

,    
  

  
,         
"  
 " -
Средства 85

Рис. 1.18. Отслеживание последовательного потока данных на осциллографе DSO Nano

        . *,  - ,    . 



  
-
   
,   
   
  
     
   
       

 ,   
   -

  

  
 -  

 , 
   
. *
. # 
     Logic — $   
 "    -
Logic 4 —  
     ,    %   
  
   
 DSO Nano,    - ,        
 
.
    
   %  

-  $ 
 
   -
 
   
 .  
  
 . *   
  
 

  -

 
 
   
, 
,  #      %   -
"     

  —   -     
     .
86 Глава 1

Прикосновением все и завершается


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

*      
    *      
    " —
, 
                    /
-  
. *  ,   -   
    
  .
 ,  " % 
 ,  , 
  

   
   
,
 ,    , 
    ,      
    ,   
 %   
  
  . & 
,   . #   ,   -
 
 
      -  $   
      
 ,     

-           .
   
. $     
          , -
 
   

    - 
    

 ,   -
  
 ,      " -  
      
-
 . + 

   
    
   $   . &
  ,          -    ,    %
,  
 %  
 ,     
 ,    ,  -
    .   $  
  
-
     . +  ,
* 
  , 
       , 
   
% " 
 
 ,      . *

,  


 $   
 , -
         
 -    
 
,    
          
-     «%  ». *  
-
. =,  
 , 
 " $
 , %        . &  -

    

 -    
 
  ,    
        " %   
   .

 
  
   . + 
    , 

   - X    
    
  -
% 
   ,   
  -     ,   
% -
   " ,    - 

  , 

 
% 

 
   
  ,    %      ,    -
   . /     ",          . &   


, 

  
       ,    
 ,  
 
         .  "   "    "  


, — $  %   " -
         -  
 
 .
   — $ %
%  , 
   
    -  -
         
  
 .
Глава 2

ПРОСТЕЙШАЯ СЕТЬ

Самая простая сеть — это соединение двух объектов один


к одному. В этой главе подробно рассматривается двусторонняя
связь, и начнем мы с характеристик, которые нужно оговорить
прежде всего. Мы познакомимся с некоторыми логистическими
элементами сетевой связи: протоколами данных, управлением
потоками и адресацией. Эти теоретические понятия мы применим
на практике, создав два устройства, реализующих примеры
использования последовательной связи между микроконтроллером
и персональным компьютером. Мы также рассмотрим
модемную связь и узнаем, как заменить кабель, соединяющий
микроконтроллер и компьютер, на приемопередатчики
беспроводной связи Bluetooth. Наконец, мы научимся
программировать микроконтроллеры низкого уровня с тем,
чтобы распределять вычислительные потребности наших проектов
между разными процессорами.

«Молниеносный» оркестр Джу Йон Паэка (2006)


/     
    
      -
"       -  . 2       
 -


 
" ,  
 

   
      
     
,  
-
"             . 0 -
  ' 1 4 % (Joo Youn Paek).
90 Глава 2

Компоненты для проектов этой главы


Коды поставщиков
? 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

17
9
14
8

16 6
7
13

10

11
12
15
Простейшая сеть 91

ПРОЕКТ 1. Управление яркостью  Arduino . & 


  
 

    MKR1000  Arduino 101, 
трехцветного светодиода  Arduino Uno   
   
 .
с клавиатуры MKR1000 — AF: 3156, RS: 124-0657, A: ABX00004,

"
     , 1 +. = $ GBX00011 (3
  4#), D: 1659-1005-ND

     
    - Arduino 101 — D: 1660-1003-ND, J: 2239331,
 Arduino . & 
  
 
 SF: DEV-13787, AF: 3033, F: 2520713, RS: 913-
    MKR1000  Arduino 101,  9999, SS: 114990575, A: ABX00005, GBX00005
 Arduino Uno   
   
 . (3
  4#)
MKR1000 — AF: 3156, RS: 124-0657, A: ABX00004, Arduino Uno — D: 1050-1024-ND, J: 2151486,
GBX00011 (3
  4#), D: 1659-1005-ND SF: DEV-11021, A: A000099, AF: 50, F 1848687,
RS: 715-4081, SS: ARD132D2P
Arduino 101 — D: 1660-1003-ND, J: 2239331,
SF: DEV-13787, AF: 3033, F: 2520713, RS: 913- 
(

  



, 2 +.
9999, SS: 114990575, A: ABX00005, GBX00005 D: 905-1000-ND, J: 150551, SF: SEN-10264,
(3
  4#) AF: 182, RS: 708-1277
Arduino Uno — D: 1050-1024-ND, J: 2151486,
SF: DEV-11021, A: A000099, AF: 50, F 1848687, 
 
 &


, 2 +. +    -
RS: 715-4081, SS: ARD132D2P    
  . &
 , 
 %   
 .

% =  
  $
 ,
1 +. /,  , 
     ! 0 D: GH1344-ND  SW400-ND, J: 2231822 
     
 ,     - 119011, SF: COM-09337, F: 1634684, RS: 718-2213
  . 
(
   10 , 4 +.
D: 754-1492.ND, J: 2125181, SF: COM-00105, J: 29082, SF: COM-09939, F: 350072, RS: 249-
F: 2290374, RS: 861-4290 9294

(
 220 , 1 +.

C      , 1 +.
D: 220QBK-ND, J: 690700, F: 9339299, R: 707-
D: 438-1045-ND, J: 20723  20601, SF: PRT-
7612
12615  PRT-12002, F: 4692810, AF: 64,

C      , 1 +. SS: 319030002  319030001
D: 438-1045-ND, J: 20723  20601, SF: PRT- 
     > .
12615  PRT-12002, F: 4692810, AF: 64,

]=
  =

    -
SS: 319030002  319030001
    
 

   -

     > .
. ;  ,    
 "  
 .

]=
  =

    - 
]+  
 +  

" -
    
 

  - +
, 1 +. (  —   

. &  
    $   - 
  ).
 Arduino — $ %     USB.
* 
  
   
 ,  
  %  . ПРОЕКТ 3. Беспроводной

"
   
, 1 +. 7  мартышкин пинг-понг
     
  
.

# +    «" +

-
 »
   2.
ПРОЕКТ 2. Мартышкин пинг-понг 
C    9 '
    ) 
(Monski Pong)   )

, 1 +.

"
     , 1 +. = $ D: 1568-1237-ND, J: 2207056, SF: PRT-09518,

     
    - A: 80, F: 1650675
92 Глава 2

=  MKR1000   


  9 &  D: ATtiny84A-PU-ND, SF: COM-11232, F: 1455160,

   

- 
    , 1 +. RS: 7380684
SF: PRT-13813  PRT-08483; A: 258  2011 
% =  
  $
 , 1 +.

  )

 2,1      ;  ,     1.

 , 5,5   + . 4     - D: 754-1492.ND, J: 2125181, SF: COM-00105,


   Farnell,   $   F: 2290374, RS: 861-4290
  .

(
  220 , 1 +.
D: CP3-1000-ND, J: 28760, SF: PRT-10287, A: 369,
D: 220QBK-ND, J: 690700, F: 9339299, R: 707-
F: 1737256
7612

   Bluetooth, 1 +.

C      , 1 +.
AF: 1588, SF: WRL-12580  WRL-12576
D: 438-1045-ND, J: 20723  20601, SF: PRT-

       
   - 12615  PRT-12002, F: 4692810, AF: 64,
,  

 Bluetooth, 1 +. SS: 319030002  319030001

    
.
ПРОЕКТ 4. Arduino-совместимая J: 20723, SF: PRT-12796, F: 2396146, RS: 791-
плата своими руками 6463, AF: 759


"  Arduino, 1 +. _%   -
   Arduino Uno, MKR1000  Arduino Для всех проектов
101. 
  USB/TTL-Serial. /  
   
MKR1000 — AF: 3156, RS: 124-0657, A: ABX00004,       

 
GBX00011 (3
  4#), D: 1659-1005-ND       
 . *   -
Arduino 101 — D: 1660-1003-ND, J: 2239331,    
    -
  USB-A 
SF: DEV-13787, AF: 3033, F: 2520713, RS: 913- USB-Mini-B   USB-Micro-B. 0  
9999, SS: 114990575, A: ABX00005, GBX00005         ,  , 

(3
  4#)    
 USB/TTL-Serial, 
       
 
  .
Arduino Uno — D: 1050-1024-ND, J: 2151486,
SF: DEV-11021, A: A000099, AF: 50, F 1848687, D: 36-84-4-ND, J: 216452, SF: DEV-09716 
RS: 715-4081, SS: ARD132D2P DEV-14050, A: 3309  284, SS: 317990026.

"
    ATtiny84, 1 +. 4   -
  
  $ 
 

, 
    
    .

Рис. 2.2. Адаптеры USB/TTL-Serial


(слева направо): Adafruit FTDI Friend;
Adafruit CP2104 Friend; SparkFun Serial
Basic Breakout CH340G
Простейшая сеть 93

Уровни согласования
Прежде чем мы предоставим устройствам возможность общаться друг с другом, нам нужно
определиться с основными вопросами такого общения. Эти вопросы можно разбить на пять
уровней, каждый из которых основывается на предыдущем.

? \


.  
    -  
         , 

   
         $ 
  .

? #    -
     
   -         , 
     " ?     ,     $ 
 -
? { 

.  
  
 -   
  — $   % $ 
-
    
       . X 
 ,  " -
 ? 5 &? 3,3 &?  - 
 - "         

  ?  ,      $ 
 .
? <

.      -  "  
     
  -
 —     
- 
     "   
 -
  ? # , 
 
     
 
 ,   

  
  
    -  
 
       .
 1,   —   0,     ' 
    0  1 
 

,      
 , 
     
  
 ,
 

 :   
  
 -    
   
   
 
     0,   —
 :      .
  1, — 
 .
? N    =.   "    0
        -
 
  ? #   
  
    -
    
: 8, 9, 10  % ?  (
 . 2.3). #
  
    -
0    
   
           
       ?
    
      
 -
? N  
A
.  
  -
   (  
:  
) 
-
  
     " -          
  
.
 ?  
   "  3 
  
       -
 ,  -  ?     
   
  , -
/ 
"  
   
 
       
 
   ,  "    OSI1. (
 )       ( 
 . 2.3
&             
   
    -
   
 ,    
 -     :  
 SPI   

 
       
- I2C). # 
       -
         
       
       

   .    %   
-   

    ( 

,  
  
         
 
 
   
  
  
 
       ). & $ 
 
   
  
       -
1
OSI, Open System Interconnect,   
- ,     $      
     (&0#). # 
    


  , 
  ISO (  
 ISO-7498)
       , 
  " 
 1984 .        
  $  :  Ethernet-     

  .   
 
 .
94 Глава 2

Асинхронный обмен данными


Передатчик Приемник

RX (Прием) Направление данных TX (Передача)

Направление данных
TX (Передача) RX (Прием)

Общий Общий
(«земля») («земля»)

Асинхронный обмен данными: каждое устройство использует свой собственный генератор тактовых (синхронизирую-
щих) сигналов, обмен данными осуществляется с заранее согласованной скоростью.

Синхронный обмен данными (интерфейс SPI)


Master (ведущее устройство) Slave (ведомое устройство)

Chip Select (CS) Chip Select (CS)


Выбор схемы Выбор схемы
Выход ведущего, Направление данных MOSI (выход ведущего,
вход ведомого вход ведомого)
Вход ведущего, Направление данных MISO (вход ведущего,
выход ведомого выход ведомого)
Направление сигнала
Clock (CLC) тактирования Clock (CLK)
Сигнал тактирования Сигнал тактирования

3,3 В
Тактовые импульсы

Синхронный обмен данными (интерфейс SPI, Serial Peripheral Interface): ведущее устройство подает сигнал тактиро-
вания на ведомое устройство и инициирует обмен, подавая сигнал выбора схемы. Обмен данными происходит по смене
уровня напряжения сигнала тактирования на обратное.

Синхронный обмен данными (интерфейс I2C)


Master (ведущее устройство) Slave (ведомое устройство)
Обмен данными осуществляется
Serial Data (SDA) в обоих направлениях SDA (последовательные
Последовательные данные)
данные

Serial Clock (SCL) Направление сигнала тактирования SCL (cигнал последова-


Сигнал последовательного тельного тактирования)
тактирования

3,3 В
Тактовые импульсы

Синхронный обмен данными (интерфейс I2C): ведущее устройство подает сигнал тактирования на ведомое устройство, вы-
бирая ведомое по его адресу. Обмен данными происходит по смене уровня напряжения сигнала тактирования на обратное.

Рис. 2.3. Типы последовательной связи


Простейшая сеть 95

Устанавливаем соединение: нижние уровни


Мы уже знакомы с одним примером последовательного обмена данными — между микрокон-
троллером и персональным компьютером. В частности, в главе 1 мы подключили микроконтрол-
лерный модуль к персональному компьютеру через порт USB. Это подключение является при-
мером асинхронного последовательного обмена данными с использованием двух протоколов
последовательной связи: TTL Serial и USB.


   — $ 
,     Arduino Uno, 

  USB  

 

,       -    ;;_
     
 778 (TTL2 Serial). / 
 
   . * 
  — 

, 
 
    "   - MKR1000  Arduino 101, $     

 :  
   
   
 

.

? \


. 0
     ,  - 0
 

   
 USB -
   

     -   "        -
. &  Arduino  
 -   "  
 USB3, 
  -
    ,   RX (      
     
Receive, 
 ),  
   ,
  TTL. 0
     "  -
   TX ( Transmit, 
).
  
 :
? { 

. 0
   
 
 
     . & - ? \


.   USB    

 
 

 
    - 
  
  : Data+ 

  3,3 &,  
 — 5 &. Data–   
   (+5 & 
? <

. &  
  
  " ).
(3,3  5 &) 
      - ? { 

. #     Data–
  1,   (0 &) —    -   
     
  0. Data+, 
    
 
? N    =. 0      $    
  . /
 "     
  9600           
  
 . = 
       

   %

     , 

 $ 
    —  $ 
8   ,   
  -    
    $   .
  (
    4    
  ,
 ). 
   
     .
? N  
A
. * $ 
 ? <

. _     1 
-
 
        
-      
  +5 & ( 
 

, 

       Data+)  –5 & (    Data–),

"      .       0 —   
-
  0 &.
* $ "  . + 
  ? N    =. X
    -
   
. #        
 USB   ,  
 TTL/USB-
     , 
 
-   " 
  


       TTL-          ;;_. & USB
     USB-   . * - 
         

 
 

  — 

, 480     . 0 
2 3
TTL, Transistor-Transistor Logic — 
  
- USB, Universal Serial Bus (protocol) — 
  
-

  
  (;;_).        % .
96 Глава 2


       , 
- ? N  
A
. * 
 
-

 8   ,   
   

  USB/TTL-Serial
   . *   
  USB   Arduino 
  
 -
 
           
   ,
          
   
 . 0
-

 ( 

            $   
      
).   ,     

-
   %          
 
, 

 

-
  
 , 
              -

     $  
   $  
 .
   
     
           & $ 
  

    -
%  
      " ,    

USB 
 
-

    
.       , 

  

USB — неисчерпаемый источник последовательных портов


0   
        
 - modemXX  "
  /dev/cu.usbmodemXX. /


 —    ,           
 $    -
   
       . *

,   : 
 TTY4   
 
  %      "  ,  CU5 —   ". =


   

,    
  USB/TTL-Serial, 

  

 

    
   -  $   ,     
   -
,         "     .

 

. 3   
 $ -
   
  
  
, * %   Windows $ 
  
-
     ,       -  , 

, : COM8, COM9, COM10.
  $  
 

—  
-
 
          >%  
  
 



. 0  
 % USB     "  
    

 -
        
   -  USB/TTL-Serial. =   , 
 
 . 4  
 

 " 
  
  

 , 
 
-
USB,         
        
 $15–20. 0
USB 
,    
     -   
  

 

     
  "  -
      , 
   -
   
. 3  
  USB        
 ,  " -

    ,            
    
  USB-  

(). TTL,       FTDI (Future Technology
Devices International),   
   
*

,   
     
 - 
 www.ftdichip.com. / 

 
 Arduino 
 USB-,  
    -   

 
        -
   
        
. *    
 Maker SHED, SparkFun, Adafruit
%   Mac OS    
  
-    
. =     
: 5 &

 :  3,3 & —        
/dev/cu.usbmodem1441   
  $  .  -
  USB/
/dev/cu.usbmodem1461
TTL-Serial   FTDI  
 . 2.4, 
 -
  
  TTL — 
 . 2.5.
/dev/cu.usbmodem1471

&    POSIX,  macOS, 


   4
TTY, Teletype Unit —       
 .
    : 
  /dev/tty.usb- 5
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   "  
 —    - ? \


. = 
  RS-232
 
 

 BASIC Stamp 
 
      2,
 
 
 

  -  
    3.   5 —

   ,   USB,  , 
 , « ».
 " 9-  
   - ? { 

. =   
 RS-
   
   
 USB/RS-232 232 
   
  
 -
(
  
  USB  RS-232   :  +3 &  +25 &   –3 &  –25 &.

 . 2.6). /
      DB-9  ? <

. &  
  
 -
D-sub-9      
 
    ( +3 &  +25 &) 
   -

      
: RS-232.      0,   ( –3 & 

 RS-232    
    - –25 &) —      1.   
    
  
  
-  , $    
     
-
 USB   "  
    
   (  

  ) .
 
  

   
 - ? N    =. ;  ,    
-
. / 
     "  TTL, — 8-     -
    
 :    
     .
98 Глава 2

1 2 3 4 2 1 1 2 3 4 5
1 — +5 В 2 — Прием на ПК
2 — Данные – 3 — Передача с ПК
3 — Данные + 5 — «Земля» ПК
3 4 4 — «Земля»
USB тип A USB тип B 6 7 8 9
RS-232 (штекерный разъем)
1 2 3 4 5 5 4 3 2 1
1 — +5 В
2 — Данные –
3 — Данные +
4 — ID
USB тип Mini-B USB тип Micro-B 5 — «Земля» Рис. 2.6. Распиновка разъемов USB и RS-232

#
%  ,    
(    
        8)

 

— 

, BASIC Stamp,  "  
  TTL-Serial. = -

         
 ,   
      
 
RS-232?   
 

   $ 
   
 , 

  USB/
  
  
 , TTL-Serial         
 

       ;;_  
 .

 

  
  RS-232     -
         
  . *
  
 
   

-

 RS-232   
" ,   
   USB/Serial. 0    -
USB, ,   ,  ,  %  , 
    
   FT232RL,
   
. >%  
  -     
 -

 

  "  
  
-  FTDI. *   $ 
   -

   USB/TTL-Serial.      -


 , 
 -
    $ 
   
& %      
 -   -

  .  -
     %  
,   
    FTDI ( .
 . 2.4) 
-
  
        
  
 ,  
  
$    " 

 . ( .
 . 2.5)   
      -
;   ,            
 
    $ 
 -
 
    $ 
  -           
 .
 ,  
     
   -

   . 
  -

    FTDI,


    -
  ,  Adafruit, SparkFun, Parallax 
Преобразователи USB/Serial
 
. 7
   FT232RL   -
>%  
  $ 
  - "     
 ,  

 , 
  
      , XBee   Digi   - Arduino
, 
 ,  " - - RedBoard   SparkFun.
     
    -
 
 

. # 
 
- / 
      ,      -

      TTL-  

     
     -

  
  : 5  3,3 &.  
   TTL- 
 — TTL-Serial.
SparkFun     

*

, %      GPS6
   
 ,    FTDI
6
GPS, Global Positioning System —      Friend   Adafruit     
-
 
 . 
 

 
  , 

Простейшая сеть 99

   
 
   — 

,   Prolific (

   
   
   - PL2303), Silicon Labs (
CP2102), Jiangsu
    . 
 , $  - Heng Qin (
CP340)  
. =
 -
   
 
  
  
    
  $
  RS-232. =
 RS-232 
 -     
   "  -
    
    Parallax,  :
 "    
  DB-9.
? www.ftdichip.com/FTDrivers.htm (FTDI);
+   
 USB/TTL-Serial ? www.silabs.com/products/mcu/Pages/

       .   USBtoUARTBridgeVCPDrivers.aspx

 (TX) $ 
       (Silicon Labs);
   
  (RX)  
   
. ? www.prolific.com.tw/US/Show-Product.
0" («   »)    - aspx?pcid=41 (Prolific);
     "     
 ,
 
    
   
 - ? www.wch.cn/download/CH341SER_ZIP.
     VCC      html (Jiangsu Heng Qin).
     
 . 
   - &  Arduino Uno    
 USB/
   
   
,  TTL-Serial     
 

-
    ,   
   
 "     Atmel 16U2, 


-
 
 
 ,   
.   $ . = $ 

*
    %  
 
  
 
 macOS  Linux,  
 -
USB/TTL-Serial    5 &,    - 
USB  Windows     -

  
     3,3 &. &   1     " Windows. + 
  ,  " 
 USB/TTL-  
 USB/TTL-Serial  Arduino Uno
Serial   FTDI   
 -   
   hardware/ardu-


   Raspberry Pi ( .
 . 1.17). ino/avr/firmwares/ATmegaxxu2


*     
 

 - https://github.com/arduino,     
    
  .  
   
  
  USB
      -   www.usb.org/develop-
'   
  ers/usbfaq.
 
 USB/Serial,  
 
   
 

   $ - 
    
 USB/TTL-Serial

.  
 
 USB/TTL-Serial  


  
 

 ,
         
 
. 
 ,         -
=
 
  %   
    -  CTS (clear-to-send,     
-
      
.  )  RTS (request-to-send, 
  
).
$       
,  >%  
 

, -


  
    ,  - "   
USB/TTL-Serial, —  ,
    
  
  -  
  Huzzah!  
  

. & $  %          ESP8266   Adafruit   ESP8266


  FTDI — 
 
 $   Thing   SparkFun,  "  -
  
     
   $  ,     
 " 
 Windows, macOS 
      $. =     
-
 
 Linux.      
 USB/TTL-
Serial  


  
 
 -
* 
   FTDI, 
USB/TTL-
 " 
   


 
Serial    
  - %  .
100 Глава 2

Использование платы Arduino в качестве адаптера


USB/TTL-Serial
4     
    
 USB/ 7
 

 
  — 

,
TTL-Serial,         - Arduino Uno,    
 
  
-
  Arduino  , 


  USB. $,    
  
.   
 
 
 USB,
   "     
   

&    ,  $      USB/TTL-Serial. &  
 (TX)  -
MKR1000  Arduino 101. 0    
       
  (RX) 
 -
  
 
,  "  
 - 

  
. /   ,     

 
 USB,        
 

 
  

 $ , 
    

,  Arduino    
 USB/TTL-Serial.
 
    
 
. = = $  
 

  
  ,

"     TX (
)  RX (
- 
    :
)           Serial1.
= 
    
 $ - void setup() {}
. &    
 USB 

- void loop() {}
     
  (RX)  ,    
 
USB —    
 (TX)  . ; - 2      
      

,  


 

   
-  
   " 
 (
  -
 

  
 
 
  :  
     ,  -
USB 

"    
USB/TTL-Serial.         
):
void setup() {
//  #  $     •   
   %   
  —   -
// ' :  RX (0)  Arduino;
Serial.begin(9600); // USB •   
  %   
  —   -
Serial1.begin(9600); // TTL  TX (1)  Arduino.
}
; 
 %  
        -
void loop() {  
 
 USB/TTL-Serial 
//   RX TTL,   USB: Arduino,  
 

.   
if (Serial1.available()) {       
 

, 
-
char c = Serial1.read();       
   
 
 
Serial.write(c);  .
}

//   USB,   TX TTL:


if (Serial.available()) {
char c = Serial.read();
Serial1.write(c);
}
}
Простейшая сеть 101

Отправка сообщений: уровень приложений


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

Проект 1
Управление яркостью трехцветного светодиода с клавиатуры
В этом примере мы будем управлять микроконтроллером нажатием клавиш клавиатуры ком-
пьютера. Это очень простой проект — в нем используется минимальное количество деталей, что
даст нам возможность сосредоточиться непосредственно на обмене данными.

=  
 ,   
    
  , 
     
- Требуемые компоненты
. =    ,  
  
;
  (RGB)   " -
  , 
 ,   
 , , 1 %.
       ,   
9  
 220 0, 1 %.
«  ».

#  Arduino  ( 
 . 2.8,  -
,    MKR1000,  
! — 
/ 
   
    - Arduino 101), 1 %.
 Arduino  — 
  ,   
 "  
   
  - +       : X3
(UART),   +7 (PWM).
, 
      
analogWrite(). ;      
>       , 1 %.
  
:"* 7,       - 

  
.
            
7       , 1 %.

 (     
  -
), ,  
,   
  "   
 .

= $ 
   
    
 
  220 0    « »
,      
   - 
 

  ,    

. `
        $    —    +7,    
    
   
.
 . 2.7 (  MKR1000 — $   3,
;     
  5  4,    Arduino 101 — 3, 5  6).
 , 
      
-
   
  : 
 ,   -         , 
 

   ,   "  
 . % 
      —
  $         %   
,    
 -
      ( - ,       ,   
),       (
  ) 
 . 2.8. 7      

  " .      -
  
 "  
. 4   -
 ($             
   %-
 
  " ) 
      
 ,   , 

7
+7, %
 -  . 
 
       .
102 Глава 2

Макетная плата с модулем MKR1000

A B C D E F G H I J
1 1

5 5

10 10 Рис. 2.8. Светодиод с надетым на него теннисным мячиком,


играющим роль светорассеивающего абажура

15 15

+3,3 В Принципиальная схема


Показаны только
20 20 задействованные выводы

Модуль
25 25
микроконтроллера

ШИМ
30 30
ШИМ
A B C D E F G H I J ШИМ 220½ Ом
Общий («земля»)

Макетная плата
Макетная платассмодулем
модулем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 Ом к контакту «земля» платы
Простейшая сеть 103

Создаем коммуникационный *



,   ( %  0  9) 
протокол 
    
  
  — 5, 
   — 3     — 7,     -
+,    
,  
  
%,
" :
    
 
 -

,  
  . = $- r5g3b7
  
     

, 
 %       &    
 — 
   
 . *

  :  "    

  
-
?   
    ,     

, 
        

  
      
,   
% ,    —    

 
: r, g  b;        .
?   
  
   
 
 ,    
:  0  9.

Пишем код

  ,   - /*
 ,  
  
- 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();
104 Глава 2

4   - " //      $  'r', 'g', 'b' 


// '0'  '9'.
  ,  
-
//    '    $ :
       if (inByte == 'r') {


     .;, currentPin = redPin;
    
    }
   ,     
- if (inByte == 'g') {

if,   
 - currentPin = greenPin;
     
 : }
if (inByte == 'b') {
currentPin = bluePin;
}

+,  ,     "  if (inByte >= '0' && inByte <= '9') {
 
    (   ) //  $  - 

//  $   analogRead():

  
  
  -
brightness = map(inByte, '0', '9', 0, 255);
"   analogWrite(): //   $ '   
// :
analogWrite (currentPin, brihtness);
}
}
}

2
 $    
 

,  - 
    ,      
  
   

, "    -   . =   :
  "        
 
g0r0b8
 

 (
 . 2.9).
7        . &! 7
& 
     
 
  -       
 
 -
  "            .
 
:
r9 4         -
 ,   
,  , 
 ,
;        
 - 

     ,  -
  . ; 
 
   :        
 ,    

r2g7

  . / 
   
%   
-


   ,    -

      .
Рис. 2.9. Значок монитора порта в панели инструментов
среды разработки Arduino
= 
      

      
 

 Arduino
IDE. _ 
  ,    

     
,    
 Arduino   
   . ;
,    " 
 , 
 
     

 
 
  
 Processing.
Простейшая сеть 105

Несколько слов об ASCII


 ,  
     ,   -    ASCII  ‘0’ 
  -
  
   

          48,   ‘9’ —     57.
 
  ? / ,    
     
  
$ 
        ASCII.       ASCII     -

 ASCII        
     

 ,   -


    . *

,       . & 
 

   ASCII   'r' — 114,   - 
   

      
-

'0' — 48. 2    


-      ASCII  
 ,      
 

  -   
  ,   
 —   
  ,      ASCII. ASCII $ . &       
*

,  $ 
 :   
  

,    
brightness = map(inByte, '0', '9', 0, 255); 
 
 . > 
 
 
  ASCII      !
    $ : «;   ASCII?»   $  .
brightness = map(inByte, 48, 57, 0, 255);

Усложняем задачу
В предыдущем проекте мы управляли микроконтроллером с компьютера, используя для этого
очень простой протокол. На этот раз уже микроконтроллер будет управлять анимацией на ком-
пьютере. Коммуникационный протокол для этого проекта будет более сложным.

Проект 2
Мартышкин пинг-понг (Monski Pong)
В этом проекте мы, по сути, создадим аналог компьютерной мыши. Ведь если рассматривать
мышь в качестве объекта данных, она будет выглядеть, как показано на рис. 2.10: есть сигналы
на входе, есть реакция на выходе.
Требуемые компоненты Рис. 2.10. Представление мыши в виде объекта данных


9    , 2 %. Вывод: 4 значения:


    , 2 %. — координата Х, 10 битов
— координата Y, 10 битов

9  
  4 0, 4 %. — кнопка 1, 1 бит
1 2 — кнопка 2, 1 бит

>       , 1 %. Ввод:
движение Кнопки ввода

#  Arduino  ( 
 . 2.11 по оси X
     MKR1000,  
! —
 Arduino 101), 1 %.
+       : 

,   , X3 (UART).


  
.
Ввод:

* %  
% 
 %, 1 %. движение по оси Y
106 Глава 2

Макетная плата с модулем Arduino 101/Uno

10

15

20

25

30
1

5
J

J
I

I
G H

G H
F

F
C D E

C D E
A B

A B
10

15

20

25

30
1

5
Принципиальная схема
+3,3 В +3,3 В
Показаны только задействованные выводы
+3,3 В
Резистивный датчик изгиба
сброс подача
сопротивлением 15 кОм

Модуль
микроконтроллера 10 кОм
10 кОм Analog0 4
Резистивный датчик изгиба 5
сопротивлением 15 кОм 10 кОм
A1

10 кОм Общий («земля»)

Макетная плата с модулем MKR1000


10

15

20

25

30
1

5
J

J
I

I
G H

G H
F

F
C D E

C D E
A B

A B
10

15

20

25

30
1

Рис. 2.11. Монтажные (вверху и внизу) и принципиальная (в центре) схемы проекта «Мартышкин пинг-понг». Датчики здесь —
для удобства вычерчивания — показаны с короткими проводами, но для реального проекта датчики нужно подсоединять
проводами значительно большей длины
Простейшая сеть 107
' 
       % 
 "       -
 ,    
 . & %  
-    (
 . 2.12). 9 "  
     
 % 
   -   
 %       
 , 
. 0      - 
,        -
  
 
           . +    
-
    
 . 
   
   -   
  ,       
    -
     
    
     , —  
  
,       
%    
  
-
  % 
 
 %   -  . X  ,     -
  " 
 

  . 
   
        -
+    
    -
 ,   
  
 

  . 
     —   
  . ~
% -


,    
  
       
 
 .  —  
%   
  -
 

   $ 
 ,
2
                 . = $ -
  
  —  
        
       -

       
      .

 .    : «#
 »  «».
   
 

,  & " , 
    
 
  
 . 2.11. 

 ,        -
 
      $ 
 


 % 
   %    . 9
  
  
 -

 %,         $ 
      

. &
 ,   
 
- 
 .
 %,    

 


Рис. 2.12. Закрепите датчики


изгиба на какой-либо плотной
основе и прикрепите их к рукам
мартышки
108 Глава 2

Пишем код
; 
 
     /*
 Arduino  " , - Z  $
 
: Arduino
 


 
. Z  $    - - -  -
# %- -   - $ .
&   
 


Arduino —  
  - ' :
ˆ   —     A0 A1
  

 
 
 —   # %  4 5
       - */
  
   
9600    ,  
     1 —   - const int leftSensor = A0; // 
  
 
      " - const int rightSensor = A1; // 
  
 
 : const int resetButton = 4; // # %
   
const int serveButton = 5; // # %
   

284,284,1,1 int leftReading = 0; // $    


 
285,283,1,1 int rightReading = 0; // $    
 
286,284,1,1 int resetReading = 0; //   
289,283,1,1 int serveReading = 0; //   

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);
}
Простейшая сеть 109

; 
 
    Serial.write(leftReading);

  , 
  Serial.write(44);
 $

 ,  " Serial.write(rightReading);
: Serial.write(44);
Serial.write(resetReading);
Serial.write(44);
9     $
/*   R  $      '
    
 
  % # printlin(),  
 $ - $



 :   
:
.,P,, /*
(,F,, Serial.write(serveReading);
(,A,, Serial.write(10);
),I,, Serial.write(13);

Возвратите прежний код



   
   " 
 ,
 
   

   $ 
-

     
 Processing, 
-
       
  


  .

'    
 ? &      65.       ASCII 


      Serial.print(),          www.

   $
    asciitable.com.
       ASCII,  
-
  "   Serial.write() 
    
    
 ,
   $
 «
»    .  

      -
7 

 ( 
 

 
-  —  


 («
») -
      ) 
 ,        ASCII? /   
        -       , "  ,
 ASCII, $  
            , 
 -
 
   ASCII    
  
 
 . 

 
 «
»     . *

, 
   
       
   13  10    

  


   -
ASCII «
 
»  «  
»,     . *     
 ,
   44 —   . /         $   ,    ASCII.
          - 
 ,  ASCII   
  
   . +   ,           
     
    
 " $ .
   (leftValue, rightValue, = 
  «7
 %  - »   -
reset  serve). & 
 
  ,    

  ASCII (
 -
     
   
- ) ,    ,    , -
, 

, 65,    «A»,    $ 
  
.
 $  ASCII      -
110 Глава 2

Что такое ASCII?


 ASCII (American Symbolic Code for Information
     ASCII 10  13    .
Interchange, 
   
   - ; 
,   "     
-
   
 )     1967 . 
 -       
  
 
 American Standards Association8 (
  
 
 . /     
  

    ANSI9)   
 , 
 -  
    
 32    

         "  ASCII (ASCII 0–32).
  
,     
-
     . /  
       =  128    ASCII  
 -
    , 
   
   -    , 
   
     -
  . &  
-  ,   
"  . *
 

    
  , 
- $        
   
      ,  $ 
   
-    ,   "  

    
      . 
 
  
     -
, 
   
  ,    ASCII   
     
  -
 
  
     -     
 . $   "
, 
 "   

  
- 
   ASCII      

 — 


 
          "     

  
 
 (  
), - 
 , 
    Unicode 
8
3
  
    
.       ASCII. Unicode 

9
ANSI, American National Standards Institute — 3
-  
 , " 
-
       
.      .

4   " $  ,    $   



, 
    
-
 

 «#     - 

   
   - . /
»        ,   
  

        
,
  
. =%    -  
    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);
}
112 Глава 2

Текст или двоичный код?


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
код

7   ,      %   


 %   
 " -
      ,  $     
, . &    ,  
   
 
-
     ,  
   -    36  ,  
 9   -
    
    -  . *  
     

. 3     
  
    -     
 , 
     %
 
 
? =  . & $    . ; ,  
    -

 80 . = ,   
       ,
    ".
      TTL-   
  &      ,  
 
9600    . 4      -      ,     

 
    ( $   -    

      
. _%
      
 TTL  RS-232),     
      ( 
-
  
 96 ,  ,   
, $ 
    
  ),   
  
  $ "    
- 
   ASCII  Unicode. &
 ,
  1/100    . & " -,    
   %    , -
 
.
  $    ASCCI  Unicode  
      ,   % -
*,         ,  
   
-  

 
       
    "  ?    
       


   
   
      RGB,         ,         

        0  255:   . #   :

102,198,255,127,127,212,255,155,127, •    
 %     
 , 
   
 ( 
-
7   ,    "   
-
 )   
 ;
      (    0  255

 256    ,  28,  8 ), $- •    
   
 ASCII  Unicode;
      
    % 
 •   %     
 . * 
 
      
 ,  , 
        
   
     ,  - 
 .
Простейшая сеть 113

Интерпретация двоичного протокола


   $            - 0  ,   
      -
      
,  
- ,         ,
   "   
   

 -       . *

, 
 -
,  "   . *    
- 
     7 
 API 
 XBee
   
         ,     2-      ,  " 
"      , $      Channel Indicator, 
      -
      
 
   
 -   
  . & $ 16-    -
,   
  
 . $  9 %  
  
 -
  
    .  ,  " 6  — 4    ,  -
 
%    . +  
= 
   
     - $   
 
    
 
       
      "   . 4  

    
 . +      
 $         
 ,
    
     
- Channel Indicator      "  
 . >%   
  SPI  I2C   -    :
% 
 . +      -

       
 
   0111111000000000
     .   $ 
   
    %  
         ,   9- % ,

      ,   
. 7  - 
 " 
   ,     
   $   %  
  (  16) 0,     " 6- , 
 -

      .   ,  % - "     ,      1,  -

        0x, " ,  $   
 . &  
    Arduino,      C, -            $
   0b, 

: 0b10101010. 2-     —        ,
 $      ,   
; 
     ,  
   - 
 ,     .
"      %    ?
+              
$2,508 16-     ,   
   —   
64-     . 

    -
0    — 
 2,     
           
 / -
 %   —   ,     -
 

  


  103. ;  
 2      -
 XBee. 9
%   
   
 -
 
% 

 . '   $ 

-  3Z    10 , $  
   
  
  ,      
 



    . ; -

  
           
-
,          

 .    
%   " 
  1023. 4 
 
      ,
    ?       
     3,  -

 — 255. & %  
  
  
0b10010110 $         0x3FF. ' -
       ,    
  
#  
%           256 (3 × 256 = 768)       -
 ,     
     
  -      
   (FF = 255), 
   128,  27. 
    1023 (768 +255 = 1023).
+  ,    
 
 
   256.
114 Глава 2

Польза шестнадцатеричного представления


      
   - 
 .   
      -
  
  ,  , 
 ,    
    
       -

 ,      %  
  "  : 
  (r — red),   

   ? / 
   ,     , - (g — green)    (b — blue). *

:
   
 
  16. *

, 
-
 MIDI 
     
 ,  
= 0xFF0000
 
 
 128  
 ,    $
= 0x00FF00
 ,  
   
   
-  
= 0x0000FF
 ,      16. &   " 
-

.   
     0x9n 
 - 2  $,     
     -
      (Note On),  n    
    "     

   0  A  %  
  
- %  
    . *

,  
 . ;,   0x9A        0x26B0E7 

     
 
  3 (    10     
 ).  " (0x26,  38    255),
3   0x8A        (note off)        (0xB0,  176)   
   3. ; 
,     ,   
 -     (0xE7,  231). /   -
 MIDI 
   
  16,          
    -
   
   %  
    .

Пакеты данных, заголовки, полезные нагрузки и «хвосты»


; 
,     
       
  (
 

 
 
 % )  
-
 (
,   "  

 Processing),
 
         -
   , 
  
 . 0  , $          " 

:

Датчик левой руки Датчик правой руки Кнопка сброса Кнопка подачи Символ возврата каретки,
(0-1023) (0-1023) (0 или 1) (0 или 1) символ перевода строки
1–4   1–4   1   1   2  

'  $      


      
  "     , $

    ASCII 44,    . 7   
    " ,     "  
 "  
 
  . >   " .
    
 "   —
&   
     
    -
$ !    ! ,   
 

  "  ,   $.   -
 
 
 — « ». 2  !-
 
   "      


. / 
   ,      ,    
 ,  -
  
 
 —  . , « ». =      " -
2 — $        , 
   
  !  . & %  




  
   

 
 
 
   "   ,  

   
     -
  
    $  . &  
    . #
 Processing  


 ,       "     

  


    
     
 ,     ,   % 16-    
 -

 

 ,   ,        . #"   -
 ,  
 . ; 
,   
   % 

  
%  
 
   
  ,     ,    
   

 ,       "  . "      . &  
* 
      
  -      
  
, 
 —          ,  -    ,  
   -
"   " . & %  

,          " .
Простейшая сеть 115
0     
      
-
 
    "   . 0  

     
 
 (   -
  
,      



 
       -
),        


. ; 
    % 

-
 Processing. 4    
 
%,              Рис. 2.13. Вывод списка значений датчиков в окне апплета
       , 

-

  
 . 2.13.

; 
     - float leftPaddle, rightPaddle; // 



  

 $  ,  
 //  
int resetButton, serveButton; // 



  
  - . 
  , -
int leftPaddleX, rightPaddleX; //  

  
  // 

    Processing — int paddleHeight = 50; // 
  
 


   setup() —  - 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];


    
//  
:
"  (floats),
myPort = new Serial(this, portName, 9600);
  
   
      -
//   
   %,   
 
      . *

,
//     (ASCII 10):

       -
myPort.bufferUntil('\n');
: 480  400 —   1,
 1,2. ;      
//  
 
 :
         : leftPaddle = height/2;
400  480 —   0,  0,833. rightPaddle = height/2;
#   ,     resetButton = 0;
       
- serveButton = 0;
       
 
 . +  $ //  
 
 
:
  
     - leftPaddleX = 50;
  %
  - rightPaddleX = width - 50;
 map().
// 
 
  :
noStroke();
}
116 Глава 2

; 
     void serialEvent(Serial myPort) {
serialEvent()  " 
- //  

 

  
:
 , 
  "  - 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;
}
}

* , 
  void draw() {
  draw(),    // $ # % $    :
 
  
  ( - background(#044f6f);
     
 fill(#ffffff);
%
).
// 

 
:
rect(leftPaddleX, leftPaddle, paddleWidth, paddleHeight);

// 
 
:
rect(rightPaddleX, rightPaddle, paddleWidth, paddleHeight);
}
Простейшая сеть 117
     
      -
9   
     
,         ,  
   -
      ,    . 2
  

. .    
,     . & - 
 %,     

, 
   ,     
         
-


 
 
 %,     -  . 2%      -
    
,           
. 2  
-
   
 . [  map()   $    
  leftMinimum,
         leftMaximum, rightMinimum  leftMaximum  -
   
 ,  -  setup().  $ 
  

     " 
 .   
, 
  
 
 %-
= $  ,        
   
  
   

 
 
 %,    $
 .

* ,   
 - int ballSize = 10; // 
 
  

   - int xDirection = 1; //   


!

. 0   
 "    // 

   . 
 - // 
: –1, : 1
   
     int yDirection = 1; // 
 


!


  $
      // 
    
  
- // 
: –1,  : 1
   .     int xPos, yPos; //   
 
 

   
 
 $
  // !


 
"     
. 

     
  
       
 -
  
   .
=   $  
  
    
 
   , 
  

   setup():

3      setup() - //  


   

 :
   - xPos = width/2;
    
 : yPos = height/2;

; 
      - void animateBall() {
   : animateBall()  //
  !
 
:
resetBall(). /     - if (xDirection < 0) {
//
   
  
 

     draw():
if ((xPos <= leftPaddleX)) {
//
  
! 
   


:
if((leftPaddle - (paddleHeight/2) <= yPos) &&
(yPos <= leftPaddle + (paddleHeight /2))) {
// 



  
!
   
:
xDirection =-xDirection;
}
}
}
118 Глава 2

//
  !
 :
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    - boolean ballInMotion = false; //  !


?
   
. *  int leftScore = 0;
       int rightScore = 0;

    . =
   ( 
  

   setup()   

   
 -
) "   
 , -

     ,   


 . =  " 

      .
Простейшая сеть 119

7    //  



 !

   

:
   . if (ballInMotion == true) {
animateBaH();
0  " $  - }

      
draw(): 
 

if() //
 !   , 
  !

:
       
 if (serveButton == 1) {
    , - ballInMotion = true;
}

 

if() 
 " 
"  ,  , //
 !   ,  

  


 

if() 
"- //   !

:
  
    
   if (resetButton == 1) {
leftScore = 0;
     
   - rightScore = 0;
 
 : ballInMotion = true;
}

7
    ani- //    -  $   :
mateBall(),    if (xPos < 0) {
 ,      rightScore++;
resetBall();

       
 }
(     - //    -  $   :

 %
): if (xPos > width) {
leftScore++;
resetBall();
}
=      int fontSize = 36; // 
   !
 


   setup() 
  
 :
=      // 
  

 ,   

:
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. Игра «Мартышкин пинг-понг» на экране ком-


пьютера
120 Глава 2

Управление потоком данных


Возможно, вы заметили, что ракетки на экране не всегда плавно повторяют движения мартыш-
киных рук. Иногда ракетки движутся с отставанием от них, а могут на долю секунды и застывать.
Причина этому — асинхронная связь между компьютером и микроконтроллером.

~  $  


  

   - $
 ,      "  -
 
     , $        ,     
-
  ,  "  

  

 
 
 
, -

      

      
     -
       .  

  
   

 .
#   ,        
&"        
- 

 ,    
   ,   -
      
  
 -    
   
.
     
    
,
 "      , #"      
 -
 

     
 .       
 , 

   %  % $ 
  .
& %  
   
 &    ,  

 Processing -
      
    -   
%   , 
   
, 
        ,   
 



       .     
      


, 
    $     ,  
   
(Processing  %   ),  
  - 
  
 

   
 , —   

    .

=
 $   while (Serial.available() <= 0) {
   "  Serial.println("hello"); // 
 



   startup()   Arduino }


( .   «&
  -
 ! 
  
 »  
!. «4  2. * 


- »). +   $ ,
Arduino    "  
  
,    
 Processing:
2        void loop() {
loop()   Arduino  - // 

,
      

//  

  

:
 

 if(),   
if (Serial.available() > 0) {
  (     //  

 

  
:

 %
): //  




  
 —   

// :
int inByte = Serial.read();
//      #   '
// ...
}
}
Простейшая сеть 121

*  "  %  void serialEvent(Serial myPort) {


   
  // '  
 
     serialEvent() myPort.write('\r'); //  
   

}
  Processing,
" 

 «7
 %  - »:

+     Processing   


; 

   $
 
     serialEvent(). *%  -
       . *%    
    
  
-

% 
   " 
: 
-  

, 
,    ,
 

   
 "hello"    
, 
  
    ,   
   -  ,     
  . ; 
,    
         . /  
 
 Processing  -
      
   ,       
      -
       
, -   .

    
,     

  
  . 4     2     
 


 ,      
 .   "  . /    %
     Processing,  ""
;  
 
 Processing     
 

,     


,  "  .    . * "    " 


    
,  - "hello",    
 

, -
"    
,         %   Processing 
 -
  serialEvent(),  $    
 .
,  
" 
 
  -


    
 ,    -   , $ Processing 
   

 

  ,
  
   , . ;   
    
     , — 
 $  -          
 
    . 4  
 
   !
  . /       -
( 

,  $ 
 "hello"), 

-              

 Processing     . 
    .

Проект 3
Беспроводной мартышкин пинг-понг
Игра «Мартышкин пинг-понг» могла бы быть еще более занимательной, если бы сам Мартышкин
не был привязан к компьютеру кабелем USB. Этот проект ликвидирует проводное соединение
между микроконтроллером и персональным компьютером и вводит новые сетевые понятия:
«модем» и «адрес».

Приобретите адаптер Bluetooth


4  % 
 "  
  
 Bluetooth,  
     "
 %  
. 4   

  %  
  .
122 Глава 2

Bluetooth: многоуровневый сетевой


Требуемые компоненты
протокол
& $ 
       
- 
2
%    2. " +

-
 .
  —  Bluetooth,  " 
 
 :   
     - 
#  Arduino  ( 
 . 2.15
 
,           Arduino 101/Uno,  
-

 

 
   RX (
- ! —  MKR1000), 1 %.
)  TX (
),  
 
, +       : 

 " 
  
   ,   , X3 (UART).
Bluetooth. ; 
 
  -

>
  9 &  
 
 

   , 

         
,  "

 Bluetooth      
 
  %  , 1 %.
    
  
 .

q 
    2,1   


 
   

   
, 5,5   % , 1 %.
        , 

- 
7 Bluetooth Serial, 1 %.
        . 

 

          
- 
  
 , 1 %.
,  
  

  — 
-
. ; 
     
 
, 
 
  :  
  
  
, 


  
-
  
      
 
"  + 
         - 
       Bluetooth.
  ,      
 , 
- #   ,  
 Bluetooth  
-

" 
   
  ,

 
     
 
 
    .      
       -

   ,       
7 
  
  Bluetooth        . & $ 

     
 
  
- 
 Bluetooth  
 RS-232
      
 . 
 $  USB, 


  -

    
 —

 %     $ 
 -

 —       "    
 

  
-
 
  . # 
   
    
    

  
Bluetooth — $  
      -     .
    ,    -
  $ 
  ,
" 
- +,      Bluetooth    
 Bluetooth Serial Port Profile, SPP10. =
  
  «7
 %  - »,  -
 
  Bluetooth
  
   
 . 2.15 (    
! —  

:  
  

 — -   ,   — 
  ). &  

 HSP11,   
  %  -    Bluefruit EZ-Link -

— 
 HID12.    
   Adafruit,       
Bluetooth   
  
- Bluetooth Mate   SparkFun. 
 $ 
,  "   -
        "
  
 
 13, " -
        :   VCC
 —  +5 &  ,  "   -
10
SPP, Serial Port Profile — 
       (GND) —  "   (–). #  

.
11
  TX  RX  Arduino  -
HSP, Headset Profile — 
 % .
12
HID, Human Interface Device —  
 «  -  RX  TX  Bluetooth    -
% ». .     
,    
13
Service Discovery Protocol.
.
Простейшая сеть 123

Стойте, разве плата Arduino 101  


 ,      Show
не имеет встроенного адаптера Bluetooth status in the menu bar (0

 Bluetooth     ). 
Bluetooth?   ,  
   
0
    . * $ 

-       
  Bluetooth.
  
 
 Bluetooth 4.0, 

     Bluetooth LE  Bluetooth 3  %  Windows 10    
Smart. / 
 
 
  
      
 Bluetooth Settings

        
- (
 
Bluetooth) — 
    
   $
 
 . 
 , 
 ,           
 Bluetooth 4.0     
   -  
          
 .
   
 Serial Port, 
  
 
    . +   &     
 Bluetooth  Ubuntu

 Bluetooth 4.0
 
    Linux  
  , $ %

     "   .         
BlueMan
(Bluetooth Manager). = $ 
  Z 

3 
      
 Serial Port 
  Ubuntu,    
  

 
 Bluetooth 2.2, 

 BlueMan     $ 

. X  
 
  Bluefruit EZ-Link  BlueMan, 
    
  D
.
Bluetooth Mate,      ,   - & , 
   
  Bluetooth, 
"   
                -
     
  TTL-Serial,  - 
 Bluetooth Manager. 0
   — 
-
 
 . & $        
     
    -
 . +    
 Bluetooth    
  Bluetooth,  
% 
 
 

   
   - 
 
    
 .

 Bluetooth      


 , 
         
 #   $   
  
  
 %   Bluetooth,   - 
   
  00:3A:45:6C:9A:
"        
. 
 06 — $ 
 MAC-
14  
 
, $ 
   
   -  
 . &        
 
  Arduino 
 

,  -  
       -
"   
    
  
 -  . 2  
 
     -

 (X3).    . &    ,  
-
 
Adafruit-EZ-Link-XXXX,  XXXX —
     


 . 4 
Сопряжение компьютера с модулем  
    

Bluetooth  
  Bluetooth, $    
'   
        Bluetooth —    
 . 4    -

    Bluetooth, -  
  
,   1234,    -
    
  $  
 . =    ! —      -
$ 
   
  
 -   
        .
 Bluetooth, "     
   
  Bluetooth. * 
 macOS   
  
     
 Adafruit-EZ-Link-XXXX-
* %  macOS      SPP,   Windows —  
    COMX
  System Preferences,     
 (    $   
 COM14).
 Bluetooth. X  ,   - 14
MAC, Media Access Control —   

   Bluetooth         
 .
124 Глава 2

      


    
   Bluetooth,
Ubuntu "      ]   — -      TX  RX  ,

     
 ,      -     
     
        
. * 
  Serial  Serial1. * 
 $
  '  ,       
  
      

     
  %  -    
 
.
 Bluetooth: /dev/rfcomm0.
 
 


    -
Модификация программы      Bluetooth, 
  
микроконтроллера     . 3 
   -
   
     
' %     «7
 %  -

 
  .
 » 
   Bluetooth,  -
   
 
.
 
        - Модификация программы
  Arduino. «Мартышкин пинг-понг»
  
  
  

 
 
  Arduino   - Bluetooth      , 
 —   Arduino Uno  Mega,         
. 2   
   RedBoard   SparkFun, «7
 %  - »      
-
 "  
 
  USB, - 
        
.
$           /    
 
 % 
   
   

  USB/  Bluetooth. 
   
$ 

TTL-Serial. *     X3 
- 
  portName    setup():
 
    

 
USB/TTL-Serial,      TX (
) String portName = Serial.list()[0];
 RX (
 )  . $ 
  -
 $  
    - *

,      
  
 -
 . * 
 
     -  Bluetooth        , -
   Bluetooth    
  
      
  :
TX  RX  ,    % 
 .
portName = Serial.list()[8]
3 
 

  
 
-
&  
     ,   

 USB —    Arduino 101 
   
  USB- 
MKR1000, 
   USB  -
 
.
 
 X3, 
 -
  
    Serial. & 
TX  RX        Завершающие штрихи:
X3,  
   
 

,   упорядочиваем и закрываем

"        Serial &        
  «> 
-
      Serial1. ; -  
 %  - » 
   -

, "  ,  "   -  . = $  


    
  
 RX  ,     "    % ,    
 . 2.16 (  
  Serial1.read(),  
   -        ,   
 . 2.15).
      TX "
  Serial1.write(), Serial1.print() &   
       -
 Serial1.println(). $,  % %  
 "   
.
Простейшая сеть 125
Макетная плата
с модулем MKR1000

3Vout
STS

3Vo
V
GND
DSR

>RXX
<TXX

DTR
Vin

10

15

20

25

30
1

5
J

J
I

I
G H

G H
F

F
C D E

C D E
A B

A B
10

15

20

25

30
1

Принципиальная схема
Показаны только задействованные выводы
+3,3 В +3,3 В
+3,3 В
Резистивный датчик изгиба
сопротивлением 15 кОм
Модуль сброс подача
микроконтроллера
10 кОм
10 кОм Analog0 4
5
Резистивный датчик изгиба
сопротивлением 15 кОм TX 10 кОм
A1 RX
Общий («земля»)

10 кОм
RTS
Модуль RX
Bluetooth Bluefruit TX
Vin +3,3 В
CTS
Общий («земля»)

Макетная плата
с модулем Arduino 101/Uno
3Vout
STS

3Vo
V
GND
DSR

10 X
>RX
<TXX

DTR
Vin

15

20

25

30
1

5
J

J
I

I
G H

G H
F

F
C D E

C D E
A B

A B
10

15

20

25

30
1

Рис. 2.15. Монтажные (вверху и внизу) и принципиальная (в центре) схемы проекта «Беспроводной мартышкин пинг-понг»
с подсоединенным модулем Bluetooth
126 Глава 2

# 
  , 
 
 
    
 $ 
    
-

 
      
,  -  (
 . 2.17).
"   ,       

Рис. 2.16. Сборка проекта


«Беспроводной мартыш-
кин пинг-понг» на макетном
шилде

Рис. 2.17. Проект «Беспроводной мартышкин пинг-понг» в завершенном виде


Простейшая сеть 127

Проект 4
Arduino-совместимая плата своими руками
Иногда в проекте требуется задействовать больше одного микроконтроллера, или — наобо-
рот — для работы проекта достаточно только одного или двух выводов общего назначения
микроконтроллера, что делает излишним включение в такой проект микроконтроллера с ши-
рокими возможностями. Бывают также ситуации, когда вместо использования одного микро-
контроллера для выполнения ряда задач проще задействовать несколько микроконтроллеров,
возложив на каждый из них ответственность только за одну задачу. Для таких случаев прекрасно
подойдут микроконтроллеры Atmel семейства ATtiny. Эти небольшие микроконтроллеры ценой
всего лишь несколько долларов можно программировать с помощью платы Arduino или ее кло-
на по синхронному последовательному протоколу SPI.


    
 

, 
-
 

 ,   MKR1000, Требуемые компоненты
Arduino 101   Arduino Uno,   
#  Arduino  (Arduino 101/

 %   
  - Uno  MKR1000), 1 %.
. >%  $      +       : X3

         !  (UART), SPI.
 

    
  
- 
7
 

ATtiny84, 1 %.
 
. 7    "  

>       , 1 %.
 
, 
  -
   
   
  

 
 .
   ,        
;
  (RGB)   " -
 
 
, 

" , 1 %.

     . * 
-

9  
  220 0, 1 %.
 
 
USB/TTL-Serial,  
-
 —   MKR1000  Arduino 101 —
       

   
  . , 
 , 
 

ATtiny84
 ATtiny85. 0 $ 
 

  
'  %       -    /  "  -
  ,   
 
 

,       (GPIO), 
   
 % —    %  .   ,

    
 ,  
%  
  
 

    +7 (
 . 2.18). + -
%               
  
  

. ;   , 
  "  -  

     ,   

8-

 AVR-
 
-       
 
-

  Atmel  
  
-     ,      -
 DIP15,      
 
-     
  +7. ~
 "       . 0          
  X3,  
-

 

    ATmega328T,     
       

     Arduino Uno. * 
- 
    SoftwareSerial. 


            
        -
15
DIP, Dual-in-Line Package — 
  
 

 

,       
(
 )
      (   -  "  
 
   
 -
 
 ).  "   .
128 Глава 2

& $ 
    ,  " 
    , —  ,

 

     
  $        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 2 (аналоговый ввод 2)

8 (PWM) 3 (аналоговый ввод 3)

7 (аналоговый ввод 7, PWM)* 4 (аналоговый ввод 4, SCK)*

6 (аналоговый ввод 6, PWM, MOSI)* 5 (аналоговый ввод 5, PWM, MISO)*

*Здесь:
• SCK — тактирование;
• PWM — ШИМ;
• MISO — вход ведомого, выход ведущего;
• ARef — опорное напряжение; Рис. 2.18. Распиновка микроконтроллеров ATtiny84
• MOSI — выход ведомого, вход ведущего. (вверху) и ATtiny85 (внизу)

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



   Arduino Un    
    

. >
 $-
    
 

    
   

  

    % 

- Arduino 
 
 USB.
, 
     !  !
 (bootloader)
 
,       * 
 

      


,       
 .     
. &  $  
4    $ 

   


      
  -
      X3 (UART). 4  $  


 ICSP16   
 
  

   

 , - 16
ICSP  ISP, In-Circuit Serial Programmer —  
-

           
-       


.
Простейшая сеть 129

Введение в интерфейс SPI


=  
    


  $ 
 -        CS    

  
     
     -  "  
 . '  
 
 -

        
 ,  "      
 ,  "  
 
  SPI17. + 
 SPI   
 -      
   $   .
     
  
 I2C18 (- 4   $        
-

        
  TWI19)  ,  
     % .

    
 
 
 - Master Slave 1
      
, 
 
- 
      . /  
 Chip Select 1 CS
    
     MOSI MOSI
 
 
   — 

, - MI SO MI SO

 Wi-Fi   MKR1000  SD-
 Clock CLK
,  
 
 .
Chip Select 2
             
 - Slave 2
 
    
"  
 ,

 

       
- CS

 (
   
 
)   - MOSI
"         . MI SO

"        
  
-
CLK
    ,     
 %   
   
    -
    

.    
 SPI     
 
  


   

 AVR,
+ 
 SPI
   
   
 - %    $  

, 
   
"  
  ( " Arduino Uno  
   ,  "
-
 
 ,   
)  

  ( -  ICSP,  
     SPI. /
 )  
 :
     " 
:
• 
   

 (SCK) —  ,  - Белая точка обозначает вывод 1

 "  
   

-
 
  (  
 ); 1: MISO 2: Вход напряжения питания
• = $, =  (MOSI, Master 3: SCK 4: MOSI
Out, Slave In):  $    "  
 
   
      - 5: Сброс 6: Общий («земля»)
   
 ;
• = $, =  (MISO, Master In, 4  %   
  ICSP,     
Slave Out):  $      
   
,  
      ,  -
  
       
   . *   SPI 
  
 -
 "   
 . 4     
  

     
   .
        " ,  - &  "      
   
 MISO    ;   SPI     Arduino Uno, 101 
•   (SS, Slave Select)   =- MKR1000:
 (CS, Chip Select) —    %  
         
 , Функция Uno 101 MKR1000
MOSI 11  ICSP4 ICSP4 8
17
SPI, Serial Peripheral Interface —      - MISO 12  ICSP1 ICSP1 10

 

   
 .
18 2 CLK 13  ICSP3 ICSP3 9
I C, Inter-Integrated Circuit — %     
  
   . CS 10 10   

19
TWI, Two-Wire Interface — 
   
 .  
130 Глава 2


 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

A B C D E F G H I J
1 1
10 10

5 5

15 15

10 10

20 20

15 15

25 25

20 20

30 30
A B C D E F G H I J

25 25
Принципиальная схема +3,3 В
Показаны только задействованные выводы

30 30
Vin A B C D E F G H I J

К выводу CS программатора Сброс ATtiny84

4 К выводу SCK программатора

К выводу MOSI программатора 6 5 К выводу MISO программатора


Общий («земля»)
Простейшая сеть 131
 Arduino  ICSP-


. 0
  = $      
 
$   

  ,    - ATtiny24/44/84, 
       -
       \ | 
  |          
ArduinoISP,    
   , - Micro. &   $   
 $  

       
- ATtiny84@8 MHz (internal oscillator; BOD


. 2   
 
- disabled),        
  ,

ATtiny84   Arduino,           


.

 . 2.19.
            

*  
 

ATtiny84         
    -
  


,      Arduino as ISP — 
 


-
 
   


 Arduino.          % 
;  ,     $    1 ( . ! Arduino    


 
 -
«*  »),        

 ATtiny.
\ | ] 
       
! 
  
 " A  2       
  #

  " 
: http://www.leonardo-  
(Burn Bootloader),   
-
miliani.com/repository/package_leonardomil-
 
 .  
%   
-
iani.com_index.json.
  
        
-
 "  #
  
  + 
2     OK  
  (Done Burning Bootloader). ; 
   



. &
     
    
 

ATtiny84.
       |   
-
   ATtiny. =
 
 
 - 4     , 
  
     
-

  AVR        


 ATtiny84    ATtiny84@8
 . *

,  

 
 MHz (internal oscillator; BOD disabled). /
ATmega328P     
      ,     
  
-
 Arduino Uno,   ATmega2560 — 
-  
       %  
-
     Arduino Mega.   

,   
   


  
 . 
   
-
= 


  
 

  
 
 
 

 ATtiny  ,
ATtiny       
 
.     
 , — $   
/ 
 

    
    -
 
  ( +3 &  +5 &),  
        

 -    
  
  %"
 
20. 
  $ 
    
 
    . &   $ -
 
 

 

, 
-  ,    
  
  -
   
 , 
   . . 
 

  Blink («7»). *  -
&           ATtiny84
 
   
    


  
 
:   
    13-  6-
           
? : ATtiny;   D  | # 
    -
 . &

 


 
? Processor: ATtiny84; Arduino    %  Arduino   -
?  : 8 7q ( 
 ).   
    


  -
 

  
 

ATtiny. 4 
?  : 
,     ,  
 -
    


.  
    6 
 

 ATtiny
  ,    , 
20
0  . fuse —  

  .  
 

    .
132 Глава 2

Библиотека SoftwareSerial = $        -


      /  6, 7  8
и управление яркостью
ATtiny84. /       
светодиода с помощью ATtiny      +7 —    
7
 

ATtiny     - +7  Arduino 101  MKR1000,    -
           $
 . 2
 



  
   $  —   Arduino   «X
  
    -
 
     
 
 : 
 - »  
 
      ,
 
    
.  $ 
   .

Пишем код
=  
   - #include <SoftwareSerial.h> // '   
   —    SoftwareSerail:
    SoftwareSerial
SoftwareSerial swSerial(0, 1); // RX, TX
   $ 
 $ -
   
   -
       
      " 
/  (GPIO). 7  -
    0  1:

;    
   //   -       
 
   :   :
const int redPin = 8;
const int greenPin = 7;
const int bluePin = 6;

=          


,       « »  «-
Serial  swSerial. >  SoftwareSerial " » 
    "  

     print(), println(), 
 

.
read(), write()  available(),     
  Serial. 2  

 CoolTerm  
  -

   

,      -
2
 
    
-    
 
     -
 

ATtiny84,    Arduino   
  
 ,   $  
  


,   
,   
 
  . *

:
 
   «7». 2  -
 
 

      - r5g3b7
 
 

   

USB/TTL-Serial (
 . 2.20). &  TX `
         -

       0 ( -      ,    
 
  . 0 
,     ) 
 
-    ,   $   

,    RX —    1.    
 , 
   
 

 

     -   %  
 

.
Простейшая сеть 133
Макетная плата с установленным на ней микроконтроллером
ATtiny84 и подключенным адаптером USB/TTL-Serial

A B C D E F G H I J
1 BLACK 1
GND
CTS
VCC
5 TX 5
RX
RTS TX RX
GREEN

10 10

15 15

20 20

25 25

30 30
A B C D E F G H I J

Принципиальная схема
Общий («земля»)
Показаны только задействованные выводы
CTS
Vcc*
Адаптер USB/TTL-Serial
TX
10 кОм RX
RTS

Напряжение
Сброс 0
питания
микроконтроллера 1
ATtiny84

ATtiny84
8
7
6
220 Ом
Общий («земля»)

*Напряжение питания с адаптера USB/TTL-Serial

Рис. 2.20. Монтажная (вверху) и принципиальная (внизу) схемы реализации проекта управления яркостью светодиода с кла-
виатуры на микроконтроллере ATtiny84. Питание на микроконтроллер и сопутствующую схему подается через адаптер USB/
TTL-Serial из порта USB компьютера. Поскольку микроконтроллер ATtiny84 и светодиоды могут работать на напряжении ве-
личиной как 3,3 В, так и 5 В, величина подаваемого адаптером напряжения не имеет значения. Подключенный к выводу
сброса микроконтроллера повышающий резистор номиналом 10 кОм не допускает произвольного сброса микроконтролле-
ра, удерживая на этом выводе высокий уровень напряжения. Сброс микроконтроллера осуществляется кратковременным
замыканием вывода сброса на землю
134 Глава 2

Эмуляция последовательных портов:


библиотека SoftwareSerial
X 
   
 
 
 0   
    $   -
(X3) 
 

 (
             
 
0  1,   RX  TX)     -   
 

    $

"          - X3. >     " -
,    ,      $ 
  -   $  ,   
  
 "    . /   ,   "   .   
  
     
     -   SoftwareSerial X3
   
-

   X3           
 ,          -
       . *   , 
      ,   
 X3,
 
     Arduino %   
  
%  
    
 
    
       ? 4800 /  57,6 / . /     
  -
/     
%   "   
-   
 

 
  -
 

   
  X3. *-     — 

,   ATtiny.


,  Arduino Mega2560    
- &
 , $          -
 X3. *         
 

    
  
 
$       X3  - X3 — 

, Arduino Uno,  , 
   ,   
   % 
        
    -
    
. &          
   
 $    
-

   "    SoftwareSerial. X3    
.

~    


    
-  . &      $  
 

    ,  
    
 

,   
-
             


  
 ,
  

 


    .   

 .
*

, 
 

ESP8266, -

      $    , 


- # "


 Arduino  

    
      
    



 
-
 Wi-Fi,      %   -  

   AVR, 
   

 ,   
 
    -         
    1 . $  
 -  
. +  
 
 
, 
 
       , 
 
 


-
 — 

,  «7
 %   -   Arduino     
 
 », $         " 
 

:

 . *  
   
          ?  ATmega328P — " Arduino Uno;

 
 

ATtiny84  ATtiny85. ?  ATmega168 — "  Arduino
Diecimila  Duemilnove;
&
 , 
 ,  
    
     
   
 
- ?  ATmega8 — "  Arduino NG
  
 ;

, 
       -
      . *

, ?  ATmega2560 — "  Arduino
 
    
        Mega2560;
  
      
  ?  ATmega32U4 — "  Arduino
 
  
     Micro.
Простейшая сеть 135
3   
     $ 
 - 
 
, 
     
,    


  " Arduino Uno, 
     

 

:   Arduino-
 ,  
 + 
 .
? ATtiny84;
? ATtiny44; *
 . 2.21      
 -
? ATtiny 85;      
      -
? ATtiny45.   Arduino Uno 
 

-
  
 . 2
      
+       
 
-     ,   
  
 -

    , 
 ,  

   ATtiny:    

 

  ATtiny  
 - SPI 
 

   


,


ATmega328P. 
   %  
   Arduino Uno,     -


    %  ,  
  "  
.

Макетная плата с установленным на ней микроконтроллером


ATmega328P и подключенным адаптером USB/TTL-Serial
RX
TX

78xxl
10

15

20

25

30
1

BLACK 5

GREEN
VCC
CTS

RTS

Принципиальная схема
GND
J

J
RX
TX
I

Показаны только задействованные выводы


G H

G H
F

ATMEGA328 Общий («земля»)


C D E

C D E

CTS
A B

A B

Vcc
Адаптер USB/TTL-Serial
10

15

20

25

30
1

TX
RX
RTS
Стабилизатор
напряжения
7805

In* Out** +5 В
+9-12V
10 кОм
Напряжение
Сброс питания

0 (RX)
*Входное напряжение
**Выходное напряжение 1 (TX) ATmega328P
22 пФ
Кварц

Кварц
22 пФ
Общий («земля»)

Рис. 2.21. Монтажная (вверху) и принципиальная (внизу) схемы для сборки на макетной плате совместимого с Arduino Uno
микроконтроллерного устройства на основе микроконтроллера ATmega328P и адаптера USB/TTL-Serial
136 Глава 2

2   
 


,  -   5 & 
   ,    -
   


,   
    %       -
USB/TTL-Serial, —     
 
   9–12 &. 9   
 
-
$ 
  
 

 - 
 ATmega328P      
: www.
   
 . 
   
 . 2.21 arduino.cc/en/Hacking/PinMapping168.
   
 

 -

Заключение
Проекты, рассмотренные в этой главе, поясняют несколько понятий, являющихся базовыми для
всех типов сетевого обмена данными. Прежде всего запомните, что обмен данными основан на по-
следовательности уровней соглашений: первым идет физический уровень, затем электрический,
логический, уровень данных и, наконец, уровень приложений. Имейте эти уровни в виду при разра-
ботке и диагностировании своих проектов, так как это облегчит вам задачу локализации проблем.
? ' :   ,      ? :   
 ,  "
   
   
         %   -
ASCII,    
 


 - ,   

  

 («
»)    .    
 USB/TTL-Serial   
-
$     
,        
  Bluefruit. &   -
   ,    
    -     
     -
  
 . *

, 
   
  ,   



     
 
    
       , , 

, 
        ",
   %
 


- 
   % .
 
  
  
? ]  ,
 
    
-

 ASCII.
  
  
 
 -
? % : 
  
    
       ,    
 " , 
  
, 
 

. #       ,
   
  , 
-  


   
-
 
 %    
   -   
 

,  
 -

. /    %    .  
 

   ATtiny,
   
      -    
    
  
 : ,
  -  
    
    -
  « »,         . /     
     . 
       

 

   "
? J :
 
      -
 
 .
"          -
  %   
 - *   ,  
 
   -
 
      . 
     
  
   -
  « - »      
 

. & $  -
       .   " " 
 


      .

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 
   
   
    -  , 
 
      
  "   .
140 Глава 3

Компоненты для проекта этой главы


Коды поставщиков
? 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. Листы толстого картона или фанеры для
основания под датчики давления

1
2

ПРОЕКТ 5. Сетевой кот



"
     , 1 +. = $ Arduino Uno — D: 1050-1024-ND, J: 2151486,

     
    - SF: DEV-11021, A: A000099, AF: 50, F 1848687,
 Arduino . & 
  
 
 RS: 715-4081, SS: ARD132D2P
    Arduino 101,   Arduino 
"
    ATtiny84. '  
Uno,  MKR1000  
   
- 
    ,    
 .  $ 
 

.
MKR1000 — AF: 3156, RS: 124-0657, A: ABX00004, D: ATTINY84A-PU-ND, SF: COM-11232, F:
GBX00011 (3
  4#), D: 1659-1005-ND 1455160, RS: 738-0684
Arduino 101 — D: 1660-1003-ND, J: 2239331, 
(

  


 

400 -
SF: DEV-13787, AF: 3033, F: 2520713, RS: 913- 

Interlink,  2  4 +. & 


   -
9999, SS: 114990575, A: ABX00005, GBX00005      402,   
(3
  4#)
 400  
   
 .
Более сложная сеть 141
D: 1027-1001-ND, J: 2128260, SF: SEN-09375, 
 &  

   , 2 +.
 -
A: 166
 
   

   .

(
 
 1 , 1 +. _ . 
    A   .
D: 1.0KQBK-ND, J: 690865, F: 9339051, R: 707- D: K386-ND, J: 22577, F: 09WX4670
7666

(
  
.

C      , 1 +.
D: 3M156065-ND, RS: 120-6041, J: 2119718, A:
D: 438-1045-ND, J: 20723  20601, SF: PRT- 550, SF: C0M-10594, F: 1165068
12615  PRT-12002, F: 4692810, AF: 64, SS: 
      A   .
319030002  319030001
D: K445-ND  WSU-30M, J: 2150361, F: 441089

     > .

H  ).

]=
  =

    -
    
 

  - D: A26509-20-ND, J: 103377, SF: PRT- 00116, F:

.    
 " 
 . 1593411

  USB/TTL-Serial. 
  , 

'-  , 1 +.

 
    
 

ATtiny.


. 4     ,      .
SF: DEV-09716  DEV-14050, A: 3309  284,


   , 1 +. SS: 317990026

Сетевые топологии и сетевые адреса


Задача отслеживания маршрутов сообщений из предыдущей главы была простой, так как соз-
данная нами сеть состояла только из двух узлов: отправителя и получателя. Но в любой сети,
состоящей из более чем двух узлов: от трех до трех миллиардов — нужна карта сети для от-
слеживания объектов, с которыми установлено соединение. А чтобы сообщения доставлялись
по месту назначения, требуется схема адресации.
Сетевые топологии: "      
 
 
    
. 
  
 
как соединяются объекты?     , 
    
0
        -    
 
       
     
%
 "          (
 . 3.2,  ).
 . 
"     —    - #"    
  —  -
 
 
    . ; -    
   (  

)

Рис. 3.2. Три типа сетевой топологии: полносвязная (слева), звездообразная (в центре) и кольцевая (справа)

Прямое соединение узлов сети Топология «Звезда» Топология «Кольцо»


142 Глава 3

  "   "    (       


). 

     
 . ;  $    
    % 
    ! ! ! (
 . 3.2,  ) 
           -

  

 ,     
,   -   $  
 , 
   -

  
   

. 
 , "      
 
  %
        -        
 
 

,    %   
,   
  .
 
  
  " .
;
 
 —      ;          -
   (
 . 3.2,  ). 
  ,            

         -   ,    
" 
   ,   "   - 
   
     "   -
         
  ,         
  -
"    
    
 - , 
    
  -
  
  %   , -   -   
   -
 
      . "   
     .
#         
* 
 ( + 
) %    
    
 . 4   -

   
   
         
,   "
 (
 . 3.3). &           
    .
 
     
  ( * 
 %       ,
      
)           
    
     (   - 
 ,  

     -

%  
). 3    
-            
    
        .     ,   
  
   
    %  
   
  ,  
    -
 %  
 , $    -
      ,    ,
Рис. 3.3. Сложная многоуровневая звездообразная сеть       

,  -

%         
     
    

       
  .

; ,     


     -
 + 
,   
    -
 
    $ . * 
       ,   -
  
     , 
 
   , 
 %   -
 
 % 
 . = 
   -
      
      
     ,   
 . 3.2, $-
  
   . *   

  

   ,   -
 ,   
  $    

  
   ,  -
" + 
.
Более сложная сеть 143

Модемы, хабы, коммутаторы и маршрутизаторы


=       
   -  
" 
  " ,  

   ( .
 . 3.3),      + - 
    $ "   " -

,       
 .   , 

    . ~ -
*
 
 
      ,  
      ,   
 (  

), 
 
%
- 
      
 

(

). &     
  - 
  .
% ,        

$  
 . 9 
 
 
 >      ,  
 -
     ,      %    
  
"

     . 
    . &    , -


  " ,  "   
* —  
 , 
 

         
 ,     
 -
    
          
 - , 
   
 .
 
. &   

    -
   DSL- ,  " + 
 0    ,   
,  
-
 % 

. /       - ,         
 (

   %  %  
  
   %    DSL-  , 
  , 

     , 
   ),     
!     
  
         -   
   
  
  .
   ,  
      
 0     
     
   ,     %   -  
       . 7
%


"   + 
.  $ 
    
     
     
  
  Bluetooth, 
  - 
,  "      
 -
      2,     

       
 ,  
  
$ 
    
    
.     
 ,    $  
  
%

. 7
%


=  (  

)      
 ,    
  IP-
  
 ,

     (  
 )    "  , 
 
   -
  
   
     "      
%

. *    

      
  . = - %     + 
 —  
     ,  
   " -   , DSL-     -
, —   
  
    
 -  , — %   
   $  -
. &     
           
%

.

     
   -
Адреса аппаратные и сетевые  
 Bluetooth. 3   
*       : 
   -  
   + 
  
 
-
  ,  
    
 -  IEEE1, ,     , 
   -
  —           IEEE 802.x. *

, % 
%


  
 
   -            , 


  
 . 
    -  ,  
     Ethernet,
          
  
       
      
. 
  
 IEEE 802.3. 3 
*  
  $      -   
  
 Ethernet — Wi-Fi —
   " "      1
IEEE, Institute of Electrical and Electronics Engineers —
       
 $  - +   
  $ 
   
$ 
-
 . ;,  
  Bluetooth    2  (#3).
144 Глава 3


         
  
- Ethernet-
  
 Wi-Fi. 0
 IEEE 802.11: 802.11a, b, g  n. #
 $ 
    
 

%


  $ 
- IP-
,   
 ,  

. ;    
  
          
 . *
 Bluetooth 
     
 IEEE   Advanced   
, -
 
  Hardware,  

802.15.1. &   
  
 802.
  
 
 MAC-

,
        
    TCP/IP,  
  
  MAC-   2. MAC-
,  - 
 
 IP-

,  -
  , 
      
  ;
6-    , 

?  %   Window 10 
   

     
    -

  ( 

,     -
     $  
     
   |    
),   
 
  Ethernet    . = 
     
  "    
MAC-
  
 
  D
  . 0
    -


    IEEE    -    Wi-Fi,  ,  -
 MAC-
. MAC-
 
  
   %  
 . 
-
             
  
      "    -
  .  ! 
    . 0


     — 
 
=    
  Ethernet  Wi-Fi D, 
"  
 

 + 
     
  -  IP-
 
 ;
 IP3. IP-      - ?  %  Ubuntu Linux  


 #


!  
 ,   D
,  
     
    , . . MAC-  ,    
  ] 
| D
  ,  !
  
 >
. 0
    , 
-
 

  . 4
- "       
 . &  -


   


,
 !#
        -
IP-   
,  #    
!     ,      

,  
 
  
-
%  
  *G&-  ,
 -
 
.

! 

    IP-  .
'        - *
 . 3.4    
 
  -

!   
  
  
      %  macOS ( )

 IP-  
 MAC-   .  Windows (). *      

     , MAC-
 IP-

4   "    ,    IP-
   " 
 :
 MAC-
  
, $  
   " 
: ?       %  

%  
    — 

:
?  %  macOS 
    00:11:24:9b:f3:70;

  ,      -
        System Preferen- ? IP-       
 
  -
ces | Network. /   
      ,
   , — -
       
 , 
- 

: 192.168.1.20.
 
 
  -
   + 
. #
 , % - 
     IP-


    "  
   ,  
   " -
2
,  
%

,  
 

MAC-
(  . Media Access Control) — 
 -
   
 .  ,      MAC-
, 
3
IP, Internet Protocol —  
-
. 
   IP-
. $,  
Более сложная сеть 145
а б

Рис. 3.4. Диалоговые окна параметров сетевого подключения для машин под macOS (а) и Windows (б)


    
 ,     XXX.XXX.XXX.1.   $ 
%
-
 
     
 , 
 -
  %  

     

   . 
 217.123.152.XXX. +  
%
-

     % 

 
Улица, город, область, страна:  
   ,   
  
   
%

. ;  -
структура IP-адресов     
217.123.1.1.
 
  
  
 
  %   ,   -    
%

 
 
 "  ( 
 )     
-     
     -
 (     
).       
.  
  
, IP-
    - 
, 
 
%

-
 
 . * 
    IP-   
, 
       -

 —    ,      

. ;        :
 
  
. 
% " 255.255.255.0.
  IP-
 
   ,  -

  
. 7
%

       
 
       ,   -      . 9
    
   
,   IP-
$   ,  
     
  ,          .   . ' 
  ( ) 
-
q
 IP-
     
, -  32 .  ,    
  
     
-  ,         -
. & , 

, 
IP-
     $  .  ,
217.123.152.20. 7
%

,  
  
      
 $ 
,  , 
 ,   ,         -
  
217.123.152.1.           
255.255.255.255. *

,    
2             255.255.255.255   

 0–255,  

  -     —  
%

. 4 
% 


        .           0 ( . . 3.1),
*

, 
%

     
$     
 — 
 
146 Глава 3


%

 —   255  (
        ,     -
.255 


  %
 "      
     
"  ).     255.255.255.192     %. & . 3.1 
-
  
 62   
%
-   "  

     

(255 – 192 – 1 = 62)    . *        "     -

     
  


-   
   .

Таблица 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-адреса


*   
   + 
      *   ,       


  
 . +      - 192.168.1.45, 
%   - 
   -
  
 %     , 
%-    -

. / 
  
-



  
        
%

  % . =
 , 
   " "     %  
%


  -
 
,    $   "      
 192.168.1.1,    
 
%

. &   IP-
 
- 
 + 
   
    " -
   
 


    
 66.187.145.75. 7
%


     . /, 



,  
 
  
    
    " -
   192.168.XXX.XXX, 10.XXX.XXX.XXX    
, 
   
 ,
 172.16.XXX.XXX  172.31.XXX.XXX. ;        $  "  
 
       
%
- 
.      -

, 
%
-

 %   . &  
  % 

     
    
%  , 
 ,   
  ( ) 
 192.168.1.45. ; 
-
   $  . * " ,   - , 
       
   
 %  
    %  ,   ,     
   " -
  ,        
     "    IP-
,   -
"    IP-
 
%

. ;       "    ,
  
     
      
    + 
.
NAT-  ! 
4. + 
,   % -
 , 
     
.
4
NAT, Network Address Translation — 

 
   
.
Более сложная сеть 147

Протокол ARP 
 
     ARP, 
-
3
      
    "     
  -

  " 
 ARP5. &  -     73#-
   -
 ,   POSIX arp      " IP-
. ; 
, "
  arp     IP-
 

5
ARP, Address Resolution Protocol — 


%   
   % %   ,

.  
    
   

.

Просматриваем таблицу ARP


0
  
   - $ arp -a
 
 (
   macOS
 Linux,      
-
   bash  %-
  Windows)     
  "   ( -
,   $     ? (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]
0      - ? (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-
 
 ,   Команда ping: вы там?

 (  at) —  MAC-
. &     arp     ,    
-
  arp -a, 

 
  $    
 ,  
   -
  
  
   IP-
- 
,    
     -
  .   ,     73#-     
   
  $

 %   
   IP-
. 
. # " 
 

 -
   
 — ping —   


# (incomplete)   ,         
   IP-
.
    —   ,   
  /   
  
    
$ 
      ,   - "   «& ?»,       .

Ограничения p i n g и a r p
0       — 

, % ,    
 ,     -
    
  ping. *  
     , 
    -
 $  ,   
  
       —     arp —   
       

  
      
 . 4 
    

  ,        $
 ,    
  %
     
  . &   
       -
 

 — $   
  %
     
 .
148 Глава 3

0
  
  - $ ping -c 3 127.0.0.1
   
    
  "   ( 
%   Windows  

 
-  –n. +,   ,
 $    —
$   
%   
 ):

/   


   

127.0.0.1 "    
 . 
,   

,    "  ,
    .
PING 127.0.0.1 (127.0.0.1): 56 data bytes
64 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0.056 ms
0      

  - 64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.056 ms
" : 64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.072 ms

&      ping     0  


    
   -
   
  
  —     
        
  
  
    
 

   

     
-c ( macOS/Linux)  -n ( Windows).     
       -
    
%   -  .

  
  
 , 
  
  
         - Специальные адреса локальной
   "   .   
 сети
     
      - 3
127.0.0.1 — $   
, -
    
    " :  "      (loopback ad-
--- 127.0.0.1 ping statistics dress)      ! (localhost
--3 packets transmitted, 3 packets
address). #" ,     $
received, 0.0% packet loss 
, 
  
 
round-trip min/avg/max/stddev =  . &    
 
    -
0.056/0.061/0.072/0.008 ms  
localhost. # " 
-
 localhost        
 
&
    
    -      
   
  -
  
%
         
     . = 
   %     
 , $  
 
    $

    $. &    ,  
,          

 
  
        

   

,  
 —

         ,       .
  
  —    ,   

 
    
 , &     arp      "
 
 
     -    
: X.X.X.255 ( X.X.X.
 $   . &     -   
 
   
 -
 ping       ,    ). / 



   -
      % .  
 # . #"  
Более сложная сеть 149

 
       +  %
 "  
 -
. 
 "  
    ,    ping,     
  


, ,   
  -    ,      -
        ,    "  

.

%

   
   -

      
 .

Пробуем ping с широковещательным адресом


0
  
     $ ping -c 3 192.168.0.255

       -
"   (  — 
64 bytes from 192.168.0.12: icmp_seq=0 ttl=64 time=0.102 ms

  Windows — -
64 bytes from 192.168.0.4: icmp_seq=0 ttl=64 time=1.457 ms
  -  -n): 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
0      - 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 (
 %   
  
   

    ). > 
  Ethernet   
  Wi-Fi.
 
  $ 
    
 %      

.
* 
       -
   $    %
 " -
0
     ,   $ 
 - 
 
 . /     -

     
 192.168.0.255, 
 
 
  ping,    %  -
     
  73#-
. . 4     %
 "    
7
%


  "  
- ping 
 
   , 
,
 192.168.0.255   
  
  -      ,     % , -
  6. $   
%    
      
   5-
$ 
  —  
    ,  7-   
 ,   
.
 
,  
    -
   ping. ; 
,  
         %
- Примечание
 "     ping,    $ *     
  
 " 
 ,     IP-
    %
 "   
 ,  

     $    -
6
3
     $ 

. =  -    % % 
  
-

     
 
   
         .
 .
150 Глава 3


 ,   IP-
 
       ,       %
,     
 ping 
  - 
  
       .
 $ . /,  , %   -

Преобразование числовых адресов в имена


& , 
 ,   ,   $ 
  
        
    ,    + 
   -  ,     
,    -
     -    www.makezine.   

   !  , 
" 
com  www.archive.net. /     - 
. 
 
       
 ,            
   
  

  
    IP-
,   
"    ". ; 
   ,  ,    
. 2 $        ,      IP
   
       

   "  ,
DNS 7, 
      -   
" 
 "   
-
    IP-
. / 

- "  . 0
 "     -
      
 —  -  , 
      


DNS 8, 
  ,    
,      -
      
. 0     
.   
 
 
    
 
,
    "         -

,    


 DNS. * . /   
         -
   
 
              .
$ 
  
%

 " = 
 

    + 

 DHCP 9, 
 
 -        
: TCP10
 IP-
,      $     UDP11. 7
 
 $ 
 
 . 
   $    . 0  
 
      ,  
 TCP
Коммутация пакетов: 
  
 , 
 
" -
  , ,     $,
 
как сообщения путешествуют    ,   
 UDP, 

по Интернету? 
 
     ,    -
    
.
;   
 "    
 
   
   
? /  
%

    "

  
  
  -   
     
%-
 ,  ,    . =      -

. 4  
%


 
   % % ",  
-    " 
%

12,

      
     
      , 

  "  %

. '-   . ; 
,
  -
  
   
 
 " -    "   
  
  ,   
 Ethernet (

  " 
%

, 

          ) " -
10
TCP, Transmission Control Protocol — 
 
 -
7
DNS, Domain Name System —       -  
 .
11
 . UDP, User Datagram Protocol — 
 
  -
8
DNS, Domain Name Server —

   . 
  .
9 12
DHCP, Dynamic Host Control Protocol — 
  - & " 
%

— 
%

, 

   

  . % 
%


   " " .
Более сложная сеть 151
  
 $  
  - =

     
  " 
%

. &
            
   
             
  -

  
%
, 
"
   — 
        
    (
%

) .     
    . #  
 
          - $ 
   
,   -
" 
%

   -  

,     
 -
  
        "  .   . +
  
%

0    
 "  -        %
 ( )  
  
%-            .

      
  . 

$       $    -
     .

Клиенты, серверы и протоколы управления связью


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

Как веб-страница попадает




,   -


  
% 
на компьютер? 
  

.   
%
 

*
 . 3.5   -      -    "    
 
 

   
 : 

 
 
  ,
 
 , 
  -
     
 
   - ,   
%
 "  .

Рис. 3.5. Путь веб-страницы от веб-сервера к браузеру поль-


Сервер зователя. Географическое расположение физических компью-
веб-сайта теров не имеет значения, если известны адреса веб-сайтов

Поставщик сетевых
услуг веб-сайта

Интернет

Поставщик сетевых Ваш


услуг веб-сайта Ваш поставщик Ваш кабельный
маршрутизатор Ваш компьютер
сетевых услуг или DSL-модем
Сервер
веб-сайта
152 Глава 3

# -  — $ 



,   - 1. &   
 
 
 -
"   
,
    - 
 
(URL)  -  : http://www.
+ 
 ,  
 " 
 example.com/index.html.

 

  # . 
,  - 2. 

 

      

     

 

,  
 www.example.com  
 80.
      ,      , 
      #       - 3. #

 

 
   -
 , 
 
  

 .   .
& -


        4. 

 

 
%  
-
HTML, 
 ,    
     -  : index.html.
$   
 "     -     5. #

 

  
% -
      + 
.        
   , 
   

   -
>
 — $  

 , 
     
  $
   , 
   
-   .

. *

, % 

,   

 ,       
 - 6. >

     ,  -

,  
   - 
 . #

      
     


 
       -  -   
   (
  ,
     

 (  

) -    ,    . .)
 
  
 
    
  , 
 "  - 
  , 
-
$  ,       -
%  .

     
. 
    , 

  -
#



    IP-

     
  -
     "   

-

  
 .
 

, 
   


    . *

, 

- & 
 

 

,
    
  -

 
    

 80,  

 

 (     -
  
  $ 
 
  
      ), 
 -
 -

. 3 



 $ 
 -   
  
   . X  $
  
    

 25,   
     ,      

  $ 
 
   . 
 . 0
  

 
 , 
_ 

    
  -  $  
 ,    

-
      
,  
    ping. * %   Windows  -

     

 . & $   

 PuTTY.
 %    
    
     
. 7  %

 
 
 
 
 
 


 — ,  

 $ - Версия telnet для Windows

   , 
   (FTP), telnet &
 telnet, "    Windows,
  -

. #
% 
 
         . *-


,       localecho,
 ,     
  
    
    $
 ,
   
  (   
  
    
 " 

  ). > 
  
 -

 Trying... Connected. $ 

 
   
    - 
   -      

 PuTTY.
  " 
:
Более сложная сеть 153

Обращаемся к серверу
&      
  - $ telnet www.example.com 80
"    %
<Enter>.

#

    -
" 
:
Trying 64.233.161.147...
Connected to www.example.com.
Escape character is '^]'.

=    "  GET /index.html HTTP/1.1


(       , Host: www.example.com
Connection: Close
  , 
 

.      

  % <Enter>
 ):
* $

  
-

   :
HTTP/1.1 200 OK Выход из telnet
Cache-Control: max-age=604800
4  

 telnet 
    -
Content-Type: text/html
  ,    % <Ctrl>+<]>,
Date: Hon, 11 Apr 2016 15:51:58 GMT
 
  
 
%  telnet
Etag: "359670651+gzip+ident"
      quit.
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 — $ HTML- 
 
- HTTP. 2 HTTP 
  
,
 
   -   www.example.com. "" 

,     -
+   

  -

 -   , 
 $     
 
 
 — "   - 
 .      $  
-
 
 HTTP13. 
 http://     
  ,        
  -
 
   

  -  
        -
 $ 
 
    

.
 

. #
, 
% -
13
HTTP, HyperText Transfer Protocol — 
 


  .
154 Глава 3

Создаем веб-сервер
  

 -

, 
 - #

 
"   
-
 " node.js    1? ~  - %   —       
   
   ,    , $   
   
" -
   "  -

,
" 
- 
. & $
    -
 HTTP. $     
 

   ,  

   
,    
  
 - 
    ,    -
   
    -

   -       
 
 
 .


.

Пишем код
&     

 - /*
" 
  
- Z 
: node.js


 server.js  
 
*/
    dateServer.js.
var express = require('express'); // '
2    ,      //    express:
var server = express(); // $ " server,
  1,     
 -
// $     express
  $  
   -
 : //  % # ',  $
//    $   :
$ node dateServer.js
function respondToClient(request, response) {
; 
 
  "     //      :

 ,    tel- response.writeHead(200, {"Content-Type": "text/html"});
net  localhost (  127.0.0.1)  response.write("< " + new Date() + ">"); response.end();
}

 8080  
  $  
    
. &   //   :
 $
  
  server.listen (8080);
     " , 
- //  
     $  :
"  HTTP   " 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)>

~  - 
 ,    
,       
 , 
 HTTP
 
 ,  
 " 
     
    —


,          ,       
 
 %  

  Processing 
 
, 

 

 
 
  

 
 

. =       . =   
 

$   
  
  
      
    
   -
   <  >. %    
  
 
. 


Более сложная сеть 155


  
 
  
 HTTP         
  " 
 : 

. & 

      

  request,  req, 
 
-
http://localhost:8080/?name=tom&age=14    " 
 : 

%-
"   
 ,   
 ,  
-
2    
      -       

 
%" 

 
: name  age,    
 tom   
 , 
 
,   
14    .  
 
   
 ,   
  . 7    
    
 
,
- 
 "  

$ 
 ,  
   "  
  (&).   

 response (
  -

 

  HTTP    
      res), 
"  -
«-! 
». "  

.

>  HTTP 


 node.js 
 = 
  


  HTTP GET,
 
 

 , " 
""     
 
,  -
    $ 
 
   
   
     
 .

Пишем код
# "  
 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);

#
    $  
 http://localhost:8080/?name=tom&age=14
    getParameters.js,
       , 
     
 



 

 
:

&     


  
- request: {"name":"tom","age":"14"}
   " 
 :
156 Глава 3

/ 
    - HTTP/1.1 200 OK

   -

" X-Powered-By: Express
Content-Type: text/html
 telnet  

 Date: Mon, 11 Apr 2016 17:16:48 GMT
PutTTY,   $  
- Connection: keep-alive
, —   - Transfer-Encoding: chunked
    
   GET

 
 
: request: {"name":"tom","age":"14"}

?name=tom&age=14
;  
    
.:
GET /get-parameters.php?name=tom&age=14
&    $ 
  -


 
 

(  HTTP), -
   " :

Методы HTTP GET и POST


#   

    
 
, HTTP 
    
    
    
 HTTP, 
    
 
 : GET, POST, PUT  DELETE.

 
   . *

,   *     



  
 , 
,        PUT  DELETE,     
 
       ,    
 
,    GET  POST.
 
 
 "  $ 
 
 ,   
 
   " . & node.js 
 

  GET   -
= $ 
     
 
    
  $   "
   
 (URL) 
 , 
   -   request.query.  
 "  
-
  " node.js,      
      
     -
$          "  JSON,    "  

 -

  

 
 "      
 
, 
   -
$ 
   .       .

Пишем код
    

- /*

  %

,      $
: node.js
      
Z#
   $ HTTP   :
 ,   
   - name ( )
  $
    
 - age (#  )
. &   "   +$  $   ,  
 -   

 $    $ ($    age).
*/
 
      
ageCheck.js.
var express = require('express'); // '   
// express:
var server = express(); // $ " server,
// $     express
Более сложная сеть 157

2  $  


  //  % #  $   $:
     : function respondToClient(request, response) {
// Z  '  JSON.stringify $
node ageCheck.js //     :
var request = "request: " + JSON.stringify(request.query);
   


 
 //      :
  
 
 
, response.writeHead(200, {"Content-Type": "text/html"});
   
 "   
,  response.write(request);
: response.end();
}
?name=tom&age=14
function checkAge(request, response) {
; 
 
 
   - var name = request.query.name;
" 
 
: var age = request.query.age;
/check/?name=tom&age=14 var responseString = "";
if (age < 21) {
* ,      - responseString = "<p>" + name

 
 age    % , + ", +    ,  
 .</p>\n";
  21. } else {
responseString = "<p>  , " + name
/ 
  


 - + ". +  $
,    
'  , ";

    
  responseString += " 
  R
   
 
- $ .</p>\n";
 
 . #

  - }
   
 , 

//      :
   
  , . .: response.writeHead(200, {"Content-Type": "text/html"});
http://localhost:8080/,    response.write(responseString);

  
  
 , response.end();
. .: http://localhost:8080/check. }
&

 
  $ //   :

    
! - server.listen (8080);
 . , 
 - //  
     $  :
    
 (/),     server.get('/', respondToClient); //    
// /? 
       server.get('/'check', checkAge); //    
 . // /check/? 

>  express.js 
"  


- +   
  
  

 

,      
  
: http://localhost:8080/
GET  POST  
    -  http://localhost:8080/check —  
-
  
  . 
 $    - 
  
 
  -

 GET 
   "     
 
. /   
  ,
server.get(),   POST — c "    
      


.
server.post(). > 
   $   9   
 
 


   
    4,  "  
-  , 
   

-
 
      
 
      .
(REST)14.
14
#  
 
 
 
 

REST, REpresentational State Transfer (  : 
-

 

     
    
  ) — 
 

     
 
   
-  . *     $ 
 

 . 
,  

    
158 Глава 3


  
 . =      -    
 
 —  
    URL,

    
      POST. &      URL  
     
  
 
    
 (URL),   . &   
 
  GET
 $      GET,   POST -    
 
, 

  POST
        
  HTTP. 
    " 
:

 
    
,  
 POST http://www.example.com/check
  
    
 -

 —    


. 3 
 
 
      -
  ,   
  POST 
 -  POST. =
 
  ,  -
     %  
 , 
 
 " 

, 


 $        


 
-      
 : GET  POST.

Пишем код
'

    var express = require('express');// '   
// express:

 POST,   
var server = express(); // $ " server,
 
  
  // $     express
(     - var bodyParser = require('body-parser'); // 


 %
). #  - // 
   
 
// 

      

URL:
 
 
   
server.use(bodyParser.urlencoded({ extended: true }));
 
:
// ...    - $ 
  % # checkAge

= 
    function checkAge(request, response) {
checkAge —     
- 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 = "";

//        # # .

* ,     
 - server.get('/check', checkAge); //    
    
 , 
- // /check/? 
server.post('/check', checkAge); //  !
 
 
 "   POST   // POST
/check. /       
   
   ,
    GET. [  .get()
 .post() "    -




 ,  
     


 " 
 GET
 POST.
Более сложная сеть 159
* 
   $  
   , - ;  ,   
      express,
 "   
   npm   -    
   
   -
    body-parser. = $ ,  

" "  ,

     
, 
               
-

, 
   
   - %     
. ; 
  

       "  : body-parser       node_mod-
ules,  
  
  
$ npm install body-parser   .

Тестируем код
      -
- POST /check HTTP/1.0

 "  telnet Host: example.com
 
 127.0.0.1  
 8080 Connection: Close
Content-Type: application/x-www-form-urlencoded
 
  
 Content-length: 16
   
 

" -

 . *  $
    $ name=tom&age=14
"   POST:
Примечание
&     ,  9

 (    $   Content-
 
      GET, length:) 
      
  
 
  
  
 
-  
 
. $,     -
        —
 ,   
  ,  
  %   % ,  
   
 .  
,       
  -
" 
.

    . = $  


Доставка файлов 
  HTML 
 ,  
 -
& ,         - 
 ,          
 ,   
 ,  
  

  $ 
         /check
 -
HTML, 
   
  

 " 
  POST. *   
 - 
  ,

    
  
   checkAge, -
      
   

.    
   , 
" 
-
9 
  $  

-    $ HTML- 
 .


 "    
   ,   

  & 
 " 
  
   -
    . 
 $        body-parser     -


,   
 node.js,  
 
  %  
  POST. &  $
       

      "   "  -
(    
 ),     -  server.use(). /      
   .     
-
 (middleware),    
   
    
 ,      
      

.
 
 

 
 
 
- & %   "   
   -

   . *  
"     "   
    -
$   
, 
 %  
   — express.static, 
    
   
     - ,  
 %

node.js  
160 Глава 3

      . /  - 


  . *   "  


     , 
"     
          -


,          -  
 ,      
 
      . =            
         
: http://localhost:8080/
_&.html.

Пишем код
#    ,  
 <html>
     

 - <body>
<form action="/check" method="post"

,    -


enctype="application/x-www-form-urlencoded">
  public. #    - Name: <input type="text" name="name" /><br>
  , 
    Age: <input type="text" name="age" />
    
 - <input type="submit" value="Submit" />
   $   - </form>
  index.html. </body>
</html>

+,  
    index.
html   public. :
form action="/check" method="post"
  ,     -
 
 
  
ageCheck,  
 
  
  POST. ; 
,

    Submit 
-
 %  
 POST  
/check,  
%




    
.

=   
 checkAge.js // 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'));

;   
      re-
spondToClient()    "  
server.get(). /   %  ,
Рис. 3.6. Форма для проверки возраста   
 

        .

#
     
       -
  . &   
 
 



: http://localhost:8080/index.html —
 

  
  
 , -
  
 . 3.6. # 


   
 
    
   -
    
 GET,      -
 

 
   
 POST.
Более сложная сеть 161
&   % 

 
 - 4    
   , 
-
 $ 
  
 . 7    -   

, — 

,   /
   - 
   - check,

   $  , 
  -
 ,     
 
 ,    
       ,
    -  , 

  
 - "    
 .
    , "    public.

Отправка запросов с помощью curl


+
 
  $   

 < X-Powered-By: Express
   

  
 
- < Content-Type: text/html
 HTTP, 
 
     < Date: Tue, 12 Apr 2016 17:58:46 GMT

 " 

 telnet. &   - < Connection: keep-alive
,    
   
< Transfer-Encoding: chunked
  

. * 
 -
<

   
    .   ,
$ 
   
%,    * Connection #0 to host localhost left intact

 
  POSIX-  curl, - <p>tom, +    ,  
   
  
 Linux  macOS  .</p><a href="/index.html">  
 '. </a>
( 

 
   
Raspberry Pi    1). + 
   

 Windows 10 
      curl 
   %
-
curl,       
 Cygwin  ,    
     
(
  ,  
    $
 ,  $
 ,     : man curl. =

 
     1,      
      
  Net). 2
 POST  % 

 -    . +    $    
"   curl       "   
  
.

:
? 
   (
   -
$ curl -v -d "name=tom&age=14" ):
localhost:8080/check
curl -v http://www.example.com
3   

      : ? 2
 POST  :
* Trying ::1... curl -d "key=value&key2=value2"
http://www.example.com
* Connected to localhost (::1) port 8080 (#0)
> POST /check HTTP/1.1 ? 2
 GET  
 
 
:
> Host: localhost:8080
curl -G -d "key=value&key2=value2"
> User-Agent: curl/7.46.0 http://www.example.com
> Accept: */*
> Content-Length: 15
? 0
  

  :
> Content-Type: application/x-www-form-urlencoded curl -L http://www.example.com
>
* upload completely sent off: 15 out of 15 bytes
< HTTP/1.1 200 OK
162 Глава 3

Принцип работы электронной почты


0 "  $ 
   -  
    " . 0


  "    "    - $ 
          -


. & $ 
 
     
 ,    " 
 

 : 

 $ 
        .
 
    ,  
-

$ 
   
   - = 
 "  $ 
  
 .  

 
  - 
     SMTP 15. Q 
   
  "  ,  

    -

"  
,  ",  
 #
:  POP 16

$ "  $ 
   , 
 - IMAP 17. 4  HTTP, % -

     "     -  .
" . 2   

   -


 $ 
   
 ,
15


  " 

 $ - SMTP, Simple Mail Transfer Protocol — 
  
-
 
 ($ 
  )  .

    .    16
POP, Post Office Protocol — 
   .


   ,   

 17
IMAP, Internet Message Access Protocol — 
 -
    

 $ 
     ($ 
  )   + 
 .

Пишем код отправителя почты


= 
   

-

  node.js  
 - *     

-
"  $ 
   . #-  
 
    ,  $  -
/*    . 
  
  

    $  
         ,   $    , 
   mailer.js. X   : node.js
 
   " 
  .
   nodemailer: */
npm install nodemailer // '    nodemailer:
var nodemailer = require('nodemailer');

&  "  
    //   ' $    :
  
   
  var account = {
    %  
- host: 'smtp.gmail.com',
Измените на действи-

 
 
     - тельный SMTP-сервер, если вы
port: 465,
    
    secure: true, не используете Gmail
% 

    auth: {
 
. 
 465    user: '_ _@gmail.com'
 
  
  
- Измените на свой
   SSL- 18. pass: '_ ' действительный адрес
/      %
- } электронной почты
};
 
  " ,
    
 -
   
  
     .
18
SSL, Secure Socket Layer — (
-
 ) 
      .
Более сложная сеть 163

&  "  
  - //   :
Измените на действительный
    
   var message = {
адрес электронной почты адресата

      " . from: account.auth.user,
to: '
 @gmail.com',
=       - subject: '  ',
   $ 
  - text: '
, ',
 . 0  : to };
(), from (), subject ( )
 text (  ). &    
-
 
     " :

* 
  "  
- // $ % # '  $   
//  $ '  :
   ,  " 
function confirm(error, info){
 % . $    if(error){
      
- console.log(error);
   $   : } else {
console.log('Message sent: ' + info.response);
}
}

0
   
% " // $   $     
$   , "   //  :
var client = nodemailer.createTransport(account); client.
createTransport   - sendMail(message, confirm);
,    
  -
"  . [  sendMail 
-
     
 


  "    -
 
      - Авторизация в Gmail
  
%  
   Gmail 
        
" :

%    
 
    . = 
-
   
           -
      OAuth2. '

%     
~  

 $    -  %   
,    %      Gmail, -
     $ 
 - 
  
   
  My Account (3  Google), " -
  nodemailer, " -   
  Sign-in and Security (>     ) -

 
 
%    Apps with account access (
 ,  
  -
node.js  
 "     )   $ 
     
 
Allow less secure apps (9
%   
 )
$ 
   . 

   ON (& ).  
% 
  -
node.js      -   
     $ 
  
    -
  
     -     OFF. > ,      %
   
  —          Gmail     
,  
   
 . =     
 

 -
 $    Processing,   ""    $ 
      

 
 

-    OAuth2      
 http://nodemailer.com/
 
 , 
smtp/oauth2/ (  $ 
        ).

 
     .
164 Глава 3

Шифрование паролей
& 
 "   
 
   
   %
  
 %
-
       
  -   
   .

    ,  
  
  

      ". = ' %
   , 
   

  
     
 
  %
 ,   %
 
 %
-

   ,   % , 
   ,        %
 . &  -
     $  . =   - "  

     

 
  ,   , 
   "  %
    " 
       %
 " %
 , 
     -
- 

  
.  
,  %
  "  
-
#"  
  
      -         . /     
   

  
, -   
        -


    
 , 
- " 
  
 — 

, -
       . 
 
   
 
   .
node.js 
   crypt, "

Пишем код шифрования


#
    $  
 /*
 

    Z#
 % 
: node.js
encrypt.js. &    
*/
 
     -
   
   - // '    crypto fs:
 node.js, $  var crypto = require('crypto');
       - var fs = require('fs');
 
  .

#    "  
- // Π $  
 :
     process. var key = process.argv[3]; // ’
R  
//  

argv[]   
  
var message = process.argv[2]; // ƒ
R  
   (     - //  


)  
   node.
js     
. & % 


   
  
"    %
 ,

     

 .

2        //    %


  -  $ %
  ,  
   
- :
var fileName = 'info.txt';
  %
  " -
 . & %     
-
       ,  
 
 %
 :
Более сложная сеть 165

= "  - // Z$  %:


  %
,       var cipher = crypto.createCipher('aes-256-cbc', key);
,    "  . // Š   %   $ #:
  $ 
%  
 var encryptedMsg = cipher.update(message, 'utf8', 'hex');
%
 :


     write- // • #   $  % # writeFile():
File() 
     - function success(data) {

   , $  console.log('I wrote to the file: ' + fileName);
}

     19:
* ,       //   $ %    %
:
writeFile(),    - fs.writeFile(fileName, encryptedMsg, success);
%
  
   :
19
 ,  node.js    
   . 4    -
"  
 ,  
  

,  "     -


  

. 
 $  
 
    -
%
   "   .
9 %
  "  
-
    
.

# 
          - 
     
   " -
"   :          info.txt, 

$ node encrypt.js   '
     
  
% 
   . #
 $    
#    ' 
 ,  -     
 
  

 , "      %


  (   ). 
 %
-

 %
. #"         "    "  -
      
 . "   
.

Пишем код расшифровки


#
    $  
 /*
 

    Z#
 %
: node.js
decrypt.js. # 

 %
-
*/
    ,    -

 %
 :

     , var crypto = require('crypto'); // '    crypto


    
 %
 : var fs = require('fs'); // '    %


//    fs

&   process.argv[] - // Π $  


 :
 
        var key = process.argv[3]; // ’
R  
//  
 :
%
 ,   -
var fileName = process.argv[2]; // $   %

 
: //  $ %  
166 Глава 3

# "    // 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,   - 


 
    
   , -

  %
 ,       , 
    %
   
 " 
     

 %
,     
. 2%
 
 $ 
  -
         " 
:  , 
           


 %
   
  
 " -
$ node decrypt.js _%
 '
 $ 
   ,     -
%     
. /   

* $
        : _%
-
      
 
-
  ' — 
    , 

  , 
"  %     
 
 %
,   
 %


     .
   .
; 
,        
9      
   
  
  HTTP  
 $ 
 -
 ":
 "  ,      %
-
I read this from the file:   ,    
    
   -
(   $ %
:) "  
  .
Более сложная сеть 167

Проект 5
Сетевой кот
Людям очень просто выполнять такие задачи, как просмотр веб-страниц или работа с электрон-
ной почтой, потому что для нас созданы компьютерные интерфейсы, очень хорошо взаимодей-
ствующие с нашими руками: клавиатура отлично подходит для работы с ней пальцами, а мышь
удобно помещается в ладонь. Но, например, для кота отправить сообщение электронной поч-
ты — задача не из легких. В этом проекте мы попытаемся исправить такую дискриминацию
котов, одновременно демонстрируя создание нашего первого физического интерфейса для
Интернета.

4     ,     ,   -


    , , 
%  Требуемые компоненты
, 
        . 
9     
 400 -

     ,      Interlink, 2–4 %.

 "   ,     
- 
9  
  1 0, 1 %.
  ,      
- 
>       , 1 %.

  . 3    
-

7 Arduino, 1 %.
    
 ,     $

 
 (    
 $   - +       :  -
 , X3 (UART).
 ), — $ 
   " %   -
 . +     
 ,   %  

  
.
 "   $ 
   ,   
& -
, 1 %.
  
 ! *%  
   - 
   , 1 %.
 $  .

0 .
#  
   " 
:  
  
   
 , 2 %.
-
   
 "    - 
 
   

 
 .
 
 


  
  — % 
   ,  - 

    
 .
" 
    $ 
  


  .

  . 7
 

 
9   .
 
   
,  

    -
.     
 ,        . / 
 
    :
/ 
  
 

, 
- ?     Arduino     
      Processing  
 -
 "       -
 
, 
,   
, -   
    
  
 HTTP GET   -

.            
-
$ 
 ,  -


   " - 
 Processing;
 $ 
   ,  

  ,  ?     Processing    
%       
 "          
 -
  
    .    - 
  HTTP GET;
    ,   Processing   ?  

 node.js    -
       -
  
    HTML- 
    

   -

"   HTTP $ 
   
   
 
POST. HTTP GET;
168 Глава 3

?    - 
  
 "    $ 
    ,  
  -
; 
 " , - ,     -
?
 %
    

  -   
  

   -
    
 
    -
,      
   , 
-

  ; "        
?
 %
       Processing    
 
. + 
 . 3.7
 
   -


,          # 
   $ 
 HTTP POST. 
  .

Рис. 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 GET HTTP POST


/ почта / загрузка снимков

Персональный компьютер
Sensor

Программа загрузчика
Входное аналоговое
напряжение

Камера
Программа
считывания
показаний датчиков Данные TTL-Serial по USB Видео по USB

Микроконтроллер
170 Глава 3

Рис. 3.9. Поскольку резистивные датчики при пайке лег-


ко пережечь, вместо пайки я применил монтаж накруткой
проводом диаметром 30 AWG. Инструменты для монта-
жа накруткой стоят недорого, не требуют особого умения
для пользования ими, но создают надежное соединение.
Подсоединив провода к датчикам давления, я изолировал
места соединений с помощью термоусадочного кембрика
(кембриковая изоляция на рисунках не показана)

=         


   Arduino 
 
- Номиналы резисторов

. *      %   &         %
      
    -            -
   , $      - 
   
     
 . 3.10
  
 

ATtiny ( .   2)   
  
    -
   SoftwareSerial. *
 . 3.10 
-    (    
 
-
  
        1 0). 4  $
 
  
-
%   , 
 
 
 
  
 

,    -
4,7  10 0.
   
 

 MKR1110,
Arduino 101/Uno  ATtiny84.

'     



   
 

. 2  



   ,
  
 
        
       :  - ( .
 . 3.11,    
!  ). '  -
 , 
, 
       
      

 "  
 (
 . 3.11). *    , 

  
    $   
 - 

   ( .
 . 3.11, 
-
  —  %  ,   - !  ),      "-
     
 :         (   

 
     
     , 

   
 
  
         ,     
). ; 

-
 -    

-     
  
   

. &  $ 
  "      
   ,   % 
.
  
   ,     . 2   
      -
  
     
 -

    
   
   - "      
, 

      % 



,   
     ,    
   . 
      , 
       -
   
,     -  
 "    .
   %   ,   
  4  
    %  ,
Более сложная сеть 171
Принципиальная схема
Показаны только 3,3 В
задействованные выводы Резистивные датчики
давления, 4 шт.

Модуль
микроконтроллера

Аналоговый ввод 0

1 кОм
Общий («земля»)

Макетная плата с микроконтроллером ATtiny84


Макетная плата с модулем MKR1000
Вывод сброса микроконтроллера нужно подключить
к плюсу питания через повышающий резистор номиналом
10 кОм. Для подключения к порту USB компьютера понадо-
1
A B C D E F G H I J
1
бится отдельный адаптер USB/TTL-Serial (слева вверху). Этот
адаптер здесь также используется для подачи питания на
5 5
микроконтроллер

10 10
RX

15 15
TX

A B C D E F G H I J
1 1
GREEN
BLACK

VCC

20 20
CTS

RTS
GND

RX
TX

5 5

25 25

10 10

30 30
A B C D E F G H I J

15 15

20 20

25 25

30 30

Макетная плата с модулем Arduino 101/Uno A B C D E F G H I J

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

Рис. 3.10. Принципиальная (вверху) и монтажные (внизу) схемы подключения датчиков давления к микроконтроллерам.
Поскольку все резистивные датчики давления соединены между собой параллельно, от них отходят всего два контакта
172 Глава 3

Рис. 3.11. Сборка панели датчиков: размещение датчиков по углам нижней пластины (вверху); резиновая накладка, пере-
дающая давление верхней пластины на датчик (внизу слева); датчик давления, смонтированный на нижней пластине (вни-
зу справа). Все четыре датчика давления подключаются параллельно. Обратите внимание на резиновые накладки, которые
передают на датчики давление верхней пластины. Обязательно изолируйте все соединения перед тем, как скреплять панели.
Выводы датчиков соединяются с проводом, ведущим к микроконтроллеру, обычными разъемами типа «мама»
Более сложная сеть 173

         - 7
 

   
 ,   %  ,    
   
 " -
         
 ,  -     . $,   -
  
  .    
 

ATtiny84  

 
 

   
  -
7     ,  
 USB/TTL-Serial,      $
       
 -          
 
   % ",     , ( .
 . 3.10, 
!).  Arduino Uno/101
    
 ,  MKR1000     


 $ —  
   . = $ - 

  USB 
,   $ 
   
       
 .
 
 

 
  ,   
   
 ,     
 - #
        
    , 
   
 . 3.10,  -  
 

,     
, — $      
   Arduino  " ,  


-
   .  .

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


4      
 
- /*

ATtiny84   
 Z  $
-  
: Arduino

 

   
 -
 X3,       - Z   $      Analog 0
   SoftwareSerial,    R $       $ 
  $      2.  %  ASCII.
*/
' 
 

 ,
void setup() {

   

  - //  
  

  9600    . 2  // 9600    .


      - Serial.begin(9600);
        }
    $
   
void loop() {
    . X

// Z  
:
        int sensorValue = analogRead(A0);
   ,    // +    $   R:
      . 
  Serial.println(sensorValue);
     }
 -  %  
 % ,   -
      
 - 
. X % , 
  
    
-
,       
      ,  
   ,   
-
 
  " 
$ 
 .
174 Глава 3

Датчики и события
*% 
   
 "  — 
"        .
$ 
   ,      - 7  $  
   

   
   . = $        %  -
       
 
-   , 

   
. ;

        - ,        -
 . ' $  ,          
     % , 
             

.     ,
  ,    
   
   -          
   %      
       
,

%. +        
-  
  
    
    . +       :      ,    
   
" ,     ,      
 
  .

 ,   
      ' 
  
      -
,    ,
 
   $  ,    
 

,  . . 3 
"           
    
    ,   
   - .       

 ,   ,          
  
    
 
  
 . 
  ,   % 
   .
3         
&      -  
  
   , $  
 "
    -  ,      ,    
  

>


 % 
   .
Arduino IDE. 2  $
 ,  
 -
  "         * 
       
-

 ,    
%         
,        
    -

        
-  

   
 . 7  -
 .        , 
 ,  
   
    

 ,       , $    

 . 3.12.         $ 

.
;        -
+,   
      , ,       
   
 -
  

   
,    
   

     .

Рис. 3.12. Вывод программы графического отображения


значений датчиков давления
Более сложная сеть 175

Пишем псевдокод
*%    Processing  /*

     -  $    


: Processing
   
 
   -
*/
  "  . 

,       - // \      
      
 -
. ;   
  


  $  
  :

7   ,     - void setup() {



   setup(), - // \ #  $    ' $
    // M     

}


 . 3   draw()
     
void draw() {
 $
 . // + $      R
// †    ,   R
// †   -    ,
// $   
}

#       - void serialEvent(Serial myPort) {


 "    - //     - -
  ,    $ // †  -    :
// - $      
  serialEvent(). 0  // -    R. 
        }
    :

= ,     

- void sendMail() {
 ,   
  - // †      
// $ R. :
  . = 
// -  $ HTTP GET    
    ,     // R. 
 ,    ,    // -    
 : }

void uploadPicture() {
// †      

// $ $ :
// -   
// -   $ HTTP POST  $ $  
// -    
}

' ,  
    "
 

 ,    
    
-
 .
176 Глава 3

Пишем код
=    %  - /*
  "    -  $    
: Processing
        - */
 
. /   
 
   ,    // \      
    
 - import processing.serial.*;
 «7
 %  - »  Serial myPort; //    
  2:
void setup() {
// \ #  $    ' $
&
    $ // \$   0     ,
     //   '  :
String portName = Serial. list()[0];
     

 myPort = new Serial(this, portName, 9600);
     —    // Z$ serialEvent()      
 ,   
   
 // 
 :
myPort.bufferUntil('\n');
 
    -
}
  
  «7
 %  -
 ». *      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

' 
 ,  - Serial myPort; //    
     , int threshold = 400; // $
 


int lastSensorValue = 0; // $
 
  

 
  
 " // 
   ". = 
- boolean catOnMat - false; //   
?
 $     
   ,
   
  
    -
   
, 
 

 : lastSensorRead-
ing, threshold  catOnMat (-
       -
  
 %
):

2       - void serialEvent(Serial myPort) {


 SerialEvent  " //     - -
. &  
    - String inString = myPort.readStringUntil('\n');
"     - int sensorValue = 0;
 
 "  
   if (inString != null) {
 "    
 - // M    :
 
 "    inString = trim(inString);
lastSensorReading   - // $  int   R:
" 
 . 0

sensorValue = int(inString);
println(sensorValue) % // println(sensorValue); %

!  .
 , $  - }

  .
// *   
"  
"
if (sensorValue > threshold ) {
Избавляемся от проводов //
 


 
>   

с помощью Bluetooth if (lastSensorValue <= threshold) {
//  
 

 
<   

* 
      -
catOnMat - true; // #  
,    
    
 
//  
  

 

,    
println("7    
  ");
        -
// %!
  , 




    Bluetooth —  


// #.  :

  «7
 %  - »
uploadPicture();
   2. 9  
 
sendMail();
    ,  


 
    }
 . } else {
//
   
" 
  "
if (lastSensorValue > threshold) {
catOnMat - false;
println("7    
  ");
}
}
// 9 



 
 

 :
lastSensorValue = sensorValue;
}
178 Глава 3

* ,    - void sendMail() {


  
 "  // ‰ % #    $ $ HTTP GET
//     R. 
$ 
    

println("     R. ");
. *     }

 "   $ - void uploadPicture() {

      
  // ‰ % #    $ $ HTTP POST
       . //  $ $  :
println("  $   .");
3   $   
}
   
  " 
"  $ 
   .
;  %    
-

  "   :


    

      -     
 , %    -
     "   ,       ,       
%        ,   ,    ,   ,     
    
  "  $ 
 - 
 
  
    -
  .  , 
     . /    
   
 %     
-
4  
        -  
   ,     , 
-
   
  %    %     "  $ 
   .
 , %   
   '   
,     

. =   
    
,    
  
%  
    , "   
 - "  
%  
  
 
-
%" ,    ,    , 
   
 
 . / -
    . * 
 $       , 
   sendMail()

 %      ,   ,    ,    
 -
      .     "  . 2  
-
    
  uploadPicture().
=  ,  $    .

Дорабатываем код
0
 "  $ 
 - int currentTime = 0; // 



   
  , 

   - int lastMailTime = 0; // 
  
 


  
 
. = //  
int mailInterval = 60; //    


!
  

 
  // 
   
 
 $   ,   " int lastUploadTime = 0; // 
 
 
 
 
   
 - int uploadInterval = 120; //    


!
      : //    
 

=    draw() void draw() {



      - // C



  
  
     
  currentTime = hour() * 3600 + minute() * 60 + second();
}
currentTime (    -

 %
):
Более сложная сеть 179

; 
 
    void sendMail() {
sendMail()  uploadImage() //  
,    

 

 " 
 ( - //  

  #.  :
int timeDifference = currentTime - lastMailTime;
    

if ( timeDifference > mailInterval) {
%
):
println("     R. ");
    , $   // 9 

  #.   


// :

   " 
 
-
lastMailTime = currentTime;
 " —   


}

      
}
serialEvent(). 

mailInterval  uploadInterval
void uploadPicture() {
 
 
 " - //  
,    

 

 $ 
    
 //  

      
  -
. 2   int timeDifference = currentTime - lastUploadTime;
      
 
- if (timeDifference > uploadInterval) {
%      : %  println("    $   .");
% ,   
 . & %  // 9 

   

 
:
  

     lastUploadTime = currentTime;
     " , }
  
   

. }

2  


     -
      ,  
  
  
    . + 
 ,    
  "  $ -

    
  .

Отправка сообщений от кота


  

 %    = 
   ,  
 
-
Processing,   
      - 
 
  ,     

-


  node.js,      , - 

     $ . &  -

  $  ,      
  ,     
    
  express.js    1. /     :
 
  
 "  $ -

       
 GET. ? crypto —  %
 
 %
 -

 $ 
   ;
*%

    
 : ? filesystem — 
    -
? 
 "  $ 
       ;
    
 HTTP GET; ? nodemailer —  
 "  $ -
? 
  , 
     
   ;
Processing ( $     ? express —  
    -
-
 ); 
.
?       HTML  -

   .
180 Глава 3


 $,  
    *   
  $  
 -


        -   
      $ 
  -
 — multer.  ,   
 
     
-
. = $ %
  
 "
#    


    
  
 %
 ,  
  catServer,    —       %
  
    info.txt
catServer.js.  
    

 catServer.

Планируем сценарий сервера


* ,   $  
 , cat server
    - : node.js
% 

.     , // '    :
// crypto, filesystem, express, multer, nodemailer
 

   

,
      1. &  -
    :

=    


- //      % :
  
 
  %- // -   %
// - $   %
  $ % 

,

   
- //       :

 : // - $     - %

// -   $ - %
   - - 
// -   %
, $-  $ $
//      
 :
// -  $ 
// -    

2  
     - //  % #  $   
:

     


 // -   GET   
// -   POST  $ $  
" 
   :

* ,      - //  %


    % 
    , 
 //   
  
 ,  

//   -  $    
  " 
 :

Задаем конфигурационные параметры


#    
  // '    :


   node.js. var crypto = require('crypto');
//    % / %
        
var fs = require('fs');
      
: //   %

  
var express = require('express');
// -
var nodemailer = require('nodemailer');
//   
Более сложная сеть 181

2  
   
 - //   $  
 '   % %

//   :
      
var key = process.argv[3];

  
 %
- // Z %
 -    # :
   
  —   var fileName =__dirname + "/info.txt";
,  $   
  // Z$  %:
 
 encrypt.js  decrypt.js: var decipher = crypto.createDecipher('aes-256-cbc', key);

= ,  

  - // Z$    '    express $
    express  //   -    - %
:
var server = express();

   ,  -
serve r.use('/',express.static( 'public'));

  
  -
    HTML, —  
,  $      



 
  checkAge.js:

2    ,    


- //   ' $  R
:
, 
   
  var account = { Замените на адрес своего
  nodemailer. + - host: 'smtp.gmail.com', почтового сервера
      - port: 465, //  SSL 
   
 —  $   secure: true, // Š   $ 
 
 : //  $ - 
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
   
 // • #   $     $
//  
R. :

 , 
    -
function sendMail(request, response) {
 
   . 
 - // • #   $   
     
  //    %    :
" 
 GET   / function confirmMail(error, info) {
mail, 
 "  $ - if(error){ console.log(error);

   . response.end("’-   . 

  $    .");
} else {
#

     response.send("Z   : " + message.to);


% 

 }
node.js. #     }

      , 
182 Глава 3

       // Z$ 


    :

   "  . [  var mailClient = nodemailer.createTransport(account);
var responseString = mailClient.sendMail(message,
 
    - confirmMail);
 
    confirm- }
Mail()  

-
     sendMail().
&     Processing
(
  
 -
  Java)  Arduino (

  
     -
 #),  JavaScript   
 -
    
   :

= 
     // • #   $   %  $ %
:

    
 %- function decryptFile(error, data) {
// † $ %
   
  ,

 
   . /,  //   % :
,    , 
 if (data){
     
 var content = data.toString();
decrypt.js. 9 %
 
, var decryptedPassword = decipher.update(content,
  
     
  'hex', 'utf8');
decryptedPassword += decipher.final('utf8');
account.auth.pass  
account.auth.pass = decryptedPassword;
nodemailer: // †  $  ,   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(" ' - .");
 

:

#
     
, 
    
- X    ,    

-
   
  ,  
 
- 
     :
 
 . 2      $ node catServer.js __
 ,     "  :

 @_

_.com  

$ npm install crypto express nodemailer 2  


 
_ _$@
_
_ .com  '   

=  
  node     
 - $ 
    ,  
 ,   
 
   . +  %
    
 .   -
         ,    -  

 
  " -

 ,     $ 
   npm. "  :
Более сложная сеть 183
M   __ X % , 

  %  
 


 @_

_.com "  $ 
   ,    -
 .
 ' - . 
   Processing,   

  
 POST.
; 
   

   
:
http://localhost:8080   
 
. &   Processing    
-
&  



    "  ,    ,   
   load-
"  $ 
     
- Strings()  
 
  HTTP GET.
 . 

   ". &  /      
    -
     " "  :   Processing 
 
  - 
 .
+      POST 
 
From: _ _$@_ 
   . 7
 
,

_ .com  $    ,  . 3     -
To: _ _$@_ "      sendMail()

_ .com
Subject:   
     Processing,     

Date: Wed, 27 Apr 2016 23:30:42 +0000 


.
   ! http://www.example.
com/catcam.html

Модифицируем скетч
=  "  /*

    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;

  
 HTTP GET  String[] response = loadStrings(mailUrl);
$ 
.     
 println("K
   

:");
     $
 printArray(response);
 

. [  load- // Z-    R.    '
// -:
Strings() 
"   
lastMailTime = currentTime;

 —      }

  

: }
184 Глава 3

#     


  -

 (  * %  "    
 
catServer.js),        Processing "   . 
 ! &  -
         
,          

  " ,  
.   %   ". 
 -
; 
   Processing %  

 - %   
    . ; 
  

, 
 
 
           - 
   

"  Processing 
   "    -
.
" :

   $   


$   :
Z   : _ _
$@_
_ .com

Создание веб-страницы для размещения снимков с веб-камеры


*  
   - 
  
- _ HTML-   
 , -
 "    ,     - "   $  ,   
  

 . *%

 

  - 

,     
 
  -
 
       
- " 
:
 , 
 "    public

.
http://localhost:8080/ _%


#    , 
"     -
Рис. 3.13. Страница сетевого кота в браузере

  -

 catServer.js,  public.
#    , 
     
catcam.jpg  
  $     pub-
lic. 2   


    
    
 
 

 
:

http://localhost:8080/catcam.jpg

#   


    


(
 . 3.13). ; 
   - 
 , -

   


  $ .
Более сложная сеть 185

Создаем веб-страницу
#
     index.html  <!DOCTYPE html>
 public  " : <html>
<head>
<script type="text/javascript">
 JavaScript    
- // • #   $     
 
     up- //    #:
date(), 
     function update() {
//     '   :
$    - 
  : 
-
var now = new Date();
  (img)    
  //   R   #: $ 
(div). // 
$:
var timeLabel = document.getElementById('timeLabel');
var catPic = document.getElementById('catPic');
// $ $
 URL, $ 
//     ,  $
2         //    #:
setInterval(), 
  - catPic.src= "/catcam.jpg?" + now;
    update()
  //     $:
 . timeLabel.innerHTML = now;
}
; 
, 
   // $   $ % #  
    

 - //  '   :
       - setInterval(update, 60000);
. &   
  </script>
       -
<title>CatCam!</title>

  ,  
 $  
</head>
 JavaScript  $   - <body align=center> <h1>CatCam!</h1>

  img     div , <img src="/catcam.jpg" id="catPic">
   . <div id="timeLabel"></div>
</body>
</html>

Загрузка файлов на веб-сервер с помощью node.js


*  "  %    
  
 ,    
"  
 

 
  

. 2
  - 
     request.file.  
     "    
  
   %  
 
  $    -
HTML   
  HTML POST.           . > 

 %     
 - 
   

     ,
 

      (middleware) 
       ,    

 
,    " multer. X   $    "

 
    ( %  - 
:
 : application/x-www-form-urlencoded) 

"  
% $   
 $ npm install multer
  request.body.    
 -
 ,         
 - ; 
      
  

  0,    
 , 

  
 
  .
186 Глава 3

Пишем код для загрузки снимков


=   " "  - /*


 require  
 catServ- cat server
er.js  " 
  (  context: node.js
*/
    
  -
// ... '      ' ...
  
 %
):
var nodemailer = require('nodemailer'); //   
var multer = require('multer'); // 
! 
$N
//     



2      - var server = express();




  
  
 - server.use('/' ,express.static('public'));
     
  "   //  
  
 !
  

 :
 
  
   0 var imgStore = multer.diskStorage({
multer. 
  imgStore - destination: dirname + '/public/', //  
      
- // 
 
 


  filename: saveUpload //    


 
 ,      //  
 
});

   , 
  
   
  .
//  
  
!  multer,

  upload    $- //   



 
 :
 
   multer, - var upload = multer({storage: imgStore});
  ,  
  server // 
 :    "image"
   $ 
   // (
 !
!   !
):
express.     - var type = upload.single('image');
      .
   
  
   ,   -

     Processing:

; 
     // % #   $  $ $ $ %
:
  
    save- function saveUpload(request, file, save) {
Upload(), 
    // $ % #    multer,  - %
:

  imgStore. 9  save(null, file.originalname);

   $     }

   
  

       
sendMail(). ; 
, 

     
-
    ,   
-
 — destination —   -
 
 
   
 
imgStore,     ,

     .

4"      server.get(7mail', sendMail); //   




,  
   - // R. 
 
   . = $ server.post('/upload', type, getUpload); // !

       server. //  


post()
      console.log(" ' $ - .");
  server.get()    -
   
:
Более сложная сеть 187

* ,     // Q         


   
  //    :
function getUpload(request, response) {
$ . 9  
  -
//    #     
 :
 $     
 - var fileInfo = JSON.stringify(request.file);
    sendMail(): console.log(fileInfo);
response.end( fileInfo + '\n');
}

; 
 %

 
  
-    
  $  . 2

     . *   "      

" curl  " -
 
   

. *  ,  -    " 
:
       curl, 

$ curl -F image=@path/to/catcam.jpg 'http://localhost:8080/upload'

& $       path/to/cat- 


  ,        


cam.jpg      
  
-  
  index.html, 
  
 ,     URL-


 
 . * 
    
  
 . 2
 

 JPEG- 
  
  .

Анатомия составного запроса POST


[
 HTML, 
  
 HTTP  
  ,   
  
 
POST    
    : 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--
188 Глава 3

Захват и загрузка изображений с помощью Processing


; 
,      
  
-
      

 Photo
 
  

,       Booth,  Windows 10 — 

 Camera,  
  


,    Ubuntu  
 
 Linux 
%
-
   $  
     

 Cheese. 4   %  
 
. 9  
  
 - 
 
      
 
  -
 "    - 
  ,      
  , 
 ,   —        — Processing          .
      
  -
  . +   
 
,    '      video  Proces-
$ "
 Processing,    sing, 
    Contribution Manager,  -
 %   : video ( )  net ( -    $        
 ). >
   ,     Sketch | Import Library | Add Library.
 Processing 3.0,   $   - &    Filter  video,  
-

  
     
 -      
   
        
.   Video 
 The Processing
Foundation (
    
 -
Захват изображения  : Author)     Install. X  
=  
     
.    
 
,    
4  % 
 "  
  - 
    + 
.  
%   -

 ,     
   %   -
,  
    Contribution Manager,
   USB. 0    ,    —         -

     %  
 - . ; 
       %   -

  -
  
  -           -

 . * %   macOS    


  
   -
.

Пишем код для проверки вывода видео с камеры


9   video - /*
   
 - -  
  Serial. ;  ,    : Processing */
Serial,      -
import processing.video.*; // \       video
 video   

  Capture myCam; //     
 $ 
:
void setup() {
#       - size(400, 30020); //  $  

     - //     '-   '  


"   Capture.list(). String[] devices = Capture.list();
=    
  printArray(Capture.list());

    $- // \$   '     
 
  Capture — - myCam = new Capture(this, width, height, devices[0]);
  ,   $  , myCam.start();

   Serial: }


20
/

%    
  % 
 ,  Processing
      " "   % . &   -

 

%  800×600  640×480.
Более сложная сеть 189

= 

   
- void draw() {
        - // + 
$-
  R
image(myCam, 0, 0);
 image(). 
 
 

}
  — myCam — 
 -
      
.
3 
  
 
 


  
 
-
 "      
 
 
 :
  
  // R    - ,     

// 
  :

 ,    
void captureEvent(Capture MyCam) {
 $ 
  cap- myCam.read();
tureEvent(). +
  - }

    "
  myCam.read():

#
  $     
Camera       -
 . &      -

    

 .

Пишем код захвата кадров


; 
,     , 
- /*
   video,  -  $    
: Processing
   %    
-
*/
  .
// \      
#   
  import processing.serial.*;
 
   video import processing.video.*;
(       // ...    ' $ $ 
.
Capture myCam; // $


  

   
 %
).
String fileName = "catcam.jpg"; //     
3   —    //  
   

 :

=     set- void setup() {


up()  "   
- size(400, 300); // %

  
// ` 




  
 21: //        Processing  
  
//   
,  

  

String[] devices = Capture.list();
printArray(devices);
21 // %

0  devices[0]  
 
 
 :
X     

% 
(400×300)   
  myCam = new Capture(this, width, height, devices[0]);
% 
 ,  Processing    - myCam.start();
   " "   // ... 
 % # setup()   ...
% . &   
 
- }

%  800×600  640×480.


190 Глава 3

&   draw()  void draw() {


// ƒ         :

   
  -
currentTime = hour() * 3600 + minute() * 60 + second();
   
  : //   !

 
   
image(myCam, 0, 0);
}

=    capture- // #  


,   

  
Event()     - //    
:
void captureEvent(Capture MyCam) {

  :
myCam.read();
}

&   uploadPicture() - void uploadPicture() {


  
 println(" // +  ,      
//  $  $ $  
   $   "); int timeDifference = currentTime - lastUploadTime;
 "  
 if (timeDifference > uploadInterval) {
: PImage img = get();
img.save(fileName);
// Z-   $ $   '  :
lastUploadTime = currentTime;
}
}

#
  
  
- 

"   
    -
           . 
     
 uploadInterval. &  -
     , 
-     $  
     
" % %   ,   upload- 120   (   ). 4   
-
Picture() 
        ,        
 
catCam.jpg  
. 0
  - uploadInterval. *     %-
  

    $  .      —  
     -
0

     uploadPicture()     .

Ставим метку времени на снимки


>        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 
  
:
draw()       fill(15);
text(timeStamp, 11, height - 19);
image():
//      

 

:
fill(255);
text(timeStamp, 10, height - 20);

    
- }
    
  -
       
 -
,    
 . 3.14.
Более сложная сеть 191

Рис. 3.14. Вывод изображения кота с мет-


кой времени

*  "  %  POST /upload HTTP/1.1


    , 
Host: localhost:8080
     
 HTTP Content-Length: 19006
Content-Type: multipart/form-data; boundary=H4rkNrF
POST. +  $    -
    Processing — --H4rkNrF
      Content-Disposition: form-data; name="image";
    , filename-"catcam.jpg"
  $       Content-Type: image/jpeg
loadStrings(). #   -
['     
 %
]
  net 
   
----H4rkNrF--


  
   -
   
  -

 ,  %  -
    ,   

 POST, 
  -

 
  . #


$ 
      


,
 


 ! «G 
  -
 !  POST», —  -
  
 
-
     ,  
     
   
    
 

-
  . *  % 
 $ 
   -
      —   ,
    " 
:
192 Глава 3

Пишем запрос POST


=   
     // \      
     , 
- import processing.serial.*;
import processing.video.*;
"      .    ,
import processing.net.*;
  
     
 , 
     - // ...      ' $ $ 
...
 
    
. Client thisClient; // 

 

; 
,     String uploadRoute = "/upload"; //  

  
  
 
 , - String boundary = "H4rkNrF"; // 9  


//   POST
   

  -
     ".
&  
  

 
  net   

 ,   -
     

 :
; 
  
      void postFile() {


   
 - // %!


!

  :
byte[] thisFile =loadBytes(fileName);
 
  POST. = $
// N 



 

:
 
  
  thisClient = new Client(this, serverAddress, port);

      , 
  
   -
  new Client 

:
3   
   

- String request = "";
 
 . #    // N

 POST HTTP:
request += "POST " + uploadRoute + " HTTP/1.1\r\n";
  
 :
request += "Host: " + serverAddress + ":" + port + "\r\n";

2  

     // Q 
 
 :

 . /    
 , - String boundaryHeader = "--" + boundary + "\r\n";
boundaryHeader +="Content-Disposition: form-data;

    
  
name=\"image\"; ";
         boundaryHeader += "filename=\"" + fileName + "\"\r\n";

  : Content- boundaryHeader +="Content-Type: image/jpeg\r\n\r\n";
Type:

  $ 

    // 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);
"   thisCli- thisClient.write(boundaryHeader);
ent.write(): thisClient.write(thisFile);
thisClient.write(boundaryTail);
}

2      $ void uploadPicture() {


      up- // ‰ % #    $ $ HTTP POST
//  $ $  :
loadPicture() (   - // +  ,      

 %
): //  $  $ $  
int timeDifference = currentTime - lastUploadTime;
if (timeDifference > uploadlnterval) {
PImage img = get();
img.save(fileName);
postFile();
// Z-   $ $   '  :
lastUploadTime = currentTime;
}
}

'    


 - text(timeStamp, 10, height - 20);

,    " 


//

 
  

   POST,  

  draw()     //  # :
  
 , 
 if (thisClient != null) {
 
 . 4  - String result = "";
 thisClient 
 - while (thisClient.available() > 0) {

  -   , $  result += char(thisClient.read());


}
       $
  
if (result != "") println(result);
  : }

* ,     // *  !


    
,
!
  


 
 ,
if (catOnMat == true) {
      - //
   

 . * 
  ,    - uploadPicture();
      
, }
  

   }
uploadPicture(), "  -

   
,   

   

    . =
$ 
      
draw():
194 Глава 3

Тестируем всю систему   


   
"  
 . &     Processing -
' 
 
   , -  
  "  ,   % 
   -

, 
   

 -  . 

 ,      

             - 
  ,      .
   . 
     +     ,   
-
          -       ,   ,  
  -
  
  

, ( )      . 7  
  
  
  "  $ 
 -     
    ,  
  . 

   "          
. 0
  -

   " .        ,    
  
   
-
 - 
     
     
  
. 7  
 
  
 .  
      
 , 
    ,   
  — 
 
  (    )        
"   

.
  ,         -

    -

    . * 
%"   $ 
  
 -
       
 
 -  %



"   
,      ,  - IP-
.

Размещаем сервер на ресурсе с общедоступным IP-адресом


*%      Processing   -



,  
     
-

 node.js  "         ,     . *

, -
   
,         -   
 Amazon Web Services EC2
  ,  


   localhost. 
   
 Elastic Beanstalk, -
+   
    


  
      node.js,

 ,     
 ,    Python, Ruby on Rails    
 
-

 
  ,     


 . 3     Digital
      .  - Ocean    
  
 
 . 3.7,  -

   

droplet22  %   ,  -
  
 + 
. ; 
         -
   "   IP-
,    

  
. 

  
    
"    - 
     "   , 
  + 
 
.            $ -
  
 node.js.
7   "    -   
-
     %    Установка сценариев на сервер

  -
,    
         



% 

 
 
 node. node.js,         
js      
   .  
 node.js     
  
   
    1,  %   ,        
.

%   
   -

 — $


    
     22
=   —  .
Более сложная сеть 195
*

,         - Подключение к общедоступному

 catServer.js,     


  $  
,    
 
серверу
   
  $ . 2    ,   %  
       "  -
 $      
,  - 

,      ,     ,
 
     :     IP-
$

. *  
 
 


 —     -
$ npm install crypto express nodemailer  — 
       
 -
 serverAddress    Processing  

  ,    
      

,  %     -
 ,  
           .    
,   -
  ,      
.  

 
   -

,  
 
 
 

 
:
http://server.address:8080
 server.address    
% 
 -

.

Управление библиотеками node.js


с помощью файла package.json
   
 node.js      
 
  
         package.
 ,       
 ,   json. 2       ( 
  
    , 
"  )  
     ,   
    
      . ;    :
      . #     
"        
   $ npm install
npm.   
         -
 ,    $  : =  
  
 $      
package.json            -
$ npm init .

& 
     
 
 ,     =  
  node.js,
 
 
  
  npm      -  $   , "     package.json, -

      package.json, 
 
        
 "  
    
. [  
   
    
:
 
,   , 
   
        (

- www.github.com/tigoe/MakingThingsTalk2/tree/
    node_modules). ; 
,   master/3rd_edition.
  
  
  
 
,

Использование программы forever


X      -


 node.js,
        "  

-
    
 forever, " 
       
    -

  node.js. X     

 
   
  npm   ,    -
, —      "   ( Windows 
  
  sudo):

$ sudo npm install -g forever


196 Глава 3

# 
 " 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 подсоединен к компьютеру (компью-
теры проекта здесь не показаны). В обязательном порядке
основательно обезопасьте все провода, чтобы кот, ласкаясь
об электронику, случайно их не погрыз (внизу слева)
198 Глава 3

4     %  


 ,  -   "    
 . &  -

    "  ,   



" 
       
 :
node.js,   "   %   -

.    
    "   
/
 
 
   
 
  + 
 ,       ? & -
   + 
  
 .    , + 
    "  -
&   ,  
 , 
  -  
 
 ,   ,     
 -
   %    
 
  ($,  -     
 + 
,    
,   ),   
 "      
,   $  .
 
    
 



Заключение
Полагаю, что прочитав эту главу, вы лучше поняли организационную структуру Интернета
и принципы работы сетевых приложений.
+ 
,  , — $   ,  "     "   . 7  -
   
 . =      
 - 

 

  
  
  " ,  
 
, 
  
 

, 
-
   
%
  + 
  - " $   ,       
 
 

.    

 
- «#   ». ; 
,      , -
    
 
    " -  
      " ,
   , 
      ,   
      


 $ "      
       
    -
  
 . =    
, —   "    
-


     
 .  

 + 
 
 "
 $ 
   ,    - 
   
  Ethernet  
-
      "     -  

.
 

 
    telnet,  -
Глава 4

«ГЛЯНЬ, МАМА,
ЗДЕСЬ НЕТ КОМПЬЮТЕРА!»
МИКРОКОНТРОЛЛЕРЫ
В ИНТЕРНЕТЕ
Первая мысль, которая приходит многим людям в голову после
создания проекта наподобие подключенного к Сети места отдыха
для кота из главы 3, — Замечательно! А как бы вообще обойтись
без компьютера? Подключать к настольному компьютеру или даже
к ноутбуку микроконтроллер лишь для того, чтобы он мог получить
доступ в Интернет… В конце концов, как мы видели в той же главе 3,
протоколы управления связью в Интернете — это всего лишь
текстовые строки, а микроконтроллеры могут обмениваться
короткими текстовыми сообщениями без каких бы то ни было
проблем. Использование микроконтроллеров совместно
с периферийными модулями, которые могут подключаться к Сети,
придаст и им эту полезную способность. В этой главе мы узнаем,
как подключить микроконтроллер к Интернету с помощью
периферийного устройства беспроводной связи Wi-Fi.

Необычные проекты
X 
  YBox (http://uncommonprojects.com/site/play/ybox-2)  -
  RSS-
   %   
,    $ Ethernet-
     
 XPort  
   Propeller. 0 
 -
    
! 
 Uncommon Projects.
202 Глава 4

Компоненты для проектов этой главы


Коды поставщиков
? 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. Вольтметр. В принципе подойдет любой, но для лучшего эффекта желательно найти вольтметр как можно
более «антикварного» вида

ПРОЕКТ 6. Привет, Интернет! Веб-сервер цвета дня



Arduino-
  MKR1000, 1 +. 
N   >
    -
 Wi-Fi, 1 +. 4      
AF: 3156, RS: 124-0657, A: ABX00004, GBX00011  + 
 
 Wi-Fi,   $    
(3
  4#), D: 1659-1005-ND   . 0      
&   
      Wi-Fi  
    .
   
   ESP8266. 
(
  
 10 , 3 +.
SF: WRL-13231, AF: 2471 J: 29082, SF: C0M-09939, F: 350072, RS: 249-9294
«Глянь, мама, здесь нет компьютера!» Микроконтроллеры в Интернете 203

\

(
  
- 
D&
 , 3 +.: 
 ,    -
), 3 +.  . +   

      -
   
     .
D: PDV-P9200-ND, J: 202403, SF: SEN-09088, F:
7482280 
     > .

C      , 1 +. 
]=
  =

    -
D: 438-1045-ND, J: 20723  20601, SF: PRT-     
 

  -
12615  PRT-12002, F: 4692810, AF: 64, SS: 
.    
 " 
 .
319030002  319030001

ПРОЕКТ 7. Сетевой измеритель качества воздуха



Arduino-
  MKR1000, 1 +. 
' , 1 +.      
  
  
% 
 %  
 -
AF: 3156, RS: 124-0657, A: ABX00004, GBX00011
 
. &   ,        

(3
  4#), D: 1659-1005-ND
  
 0–5 &   $.
&   
    
SF: TOL-10285, F: 1015878, RS: 244.890
   
   ESP8266.
SF: WRL-13231, AF: 2471 
D
, 1 +.

N   >
    - D: 160-1144-ND  160-1665-ND, J: 34761 
 Wi-Fi, 1 +. 4       94511, F: 1855510, RS: 228-5972  826-830, SF:
 + 
 
 Wi-Fi,   $     COM- 09592  COM-09590
  . 0       
(
 
 220 , 1 +.
 Wi-Fi  
    .
D: 220QBK-ND, J: 690700, F: 9339299, R: 707-

C      , 1 +. 7612
D: 438-1045-ND, J: 20723  20601, SF: PRT- 
     > .
12615  PRT-12002, F: 4692810, AF: 64, SS: 
]=
  =

    -
319030002  319030001     
 

  -

.    
 " 
 .

Введение в сетевые модули


В течение последних нескольких лет на рынке появилась линейка коммерческих устройств,
способных выходить в Интернет без участия персонального компьютера. Такую способность им
придают встроенные микроконтроллеры — подобные рассмотренным в этой книге ранее — об-
ладающие возможностью устанавливать связь по сети Ethernet или по беспроводному каналу
Wi-Fi. Простейшие из них могут обрабатывать одну транзакцию за раз, запрашивая информацию
у сервера, а затем ожидая ответа, или отправляя простое сообщение в ответ на какое-либо со-
бытие. Эти устройства обычно играют роль клиента удаленного сервера, но некоторые из них
также могут функционировать и в качестве сервера локальной сети.

  D-Link, Sony, Axis    % . 3   Belkin 


 

   
 ,  "   
  ,  
 -
    
 , —  Ethernet,     
  
  
 

Wi-Fi.   Nest 
 
     
 ,    -
  ,  "    -    + 
. & $
 

   + 
.   Philips -  
     
   
 -
   , 
   
  

, 
    $   .
204 Глава 4

= 
 

     
- 
  
 
. & 
 "

, 
   
   $   $   %
   
   :         
   Ethernet,     
       
  - 
  
   Ethernet — ,  
  
     
,    Wi-Fi, —   
 
 
-
  SMTP  HTTP. /   -  ,      Wi-Fi   ,

   , 
        
   Wi-Fi 
  -

 ,        -  
    .
     ,        .
0         
          - Сравниваем два модуля 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,
    
       Wi-Fi   Thing   SparkFun 
 
-
 Ethernet. ;  
   - .  Thing Dev   SparkFun,
     Bluetooth, 
  MKR1000  Feather Huzzah! ESP8266  
      2,        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

3.3V
Pwr
TX
RX

D5

NC

GND GND GND

3.3V Vin A0 VBat


NC En
D2 D5
NC VUSB
D14 D0
NC D14
RESET D4
NC D12
TX D13
NC D13
RX D12
SCK D15
5V D16
MOSI D0
NC A0
MISO D16
GND D15
RX D2
Antenna TX SCL
CHPD SDA
D2
«Глянь, мама, здесь нет компьютера!» Микроконтроллеры в Интернете 205
+ $   : ESP8266  WINC1500 — 
  $     
 
 WINC1500,     MKR1000,  "    WINC1500, 
 
     %
 ,          
 
       

,  - 
 
    -
"       .    . = $     
 WINC1500 
         
  
 

 TCP/IP,     
     Arduino IDE   , 
"  
   
 

. 0  : 
"  .
MKR1000  Feather M0 c WINC1500 —  -
" 
 
 Cortex M0   Atmel, >  WiFi101  
  -

     Wi-Fi -   WINC1500    ESP8266WiFi

   
  SPI.  Arduino  %    

 
. /   ,    
3 
   ESP8266 
    MKR100   ESP8266     
-

 

  Wi-Fi  «  -     . & ,     
 ». 0 
   
   
-      $  
    
  
  (0#9&), 
 , — $     

-
   


,  
- 
       .

 


 ,  # , 

  ESP8266
Arduino. * $ 
 

   -  
  
,   -
  %     /    
  
 . ; 
"    ,    MKR1000   ,  ,      -
Feather M0 c WINC1500.
 
    ,  
    /  "  -
7
   ESP8266 
   
-         ESP8266
 USB-Serial,                
TTL- 
 . 0   ESP8266 Thing  MRK1000.
Dev   SparkFun  "   
 -
 USB/Serial  
 FTDI,   Feather 0
     ,    -
ESP8266 Huzzah!   Adafruit —  
-    


  USB/Serial   Silicon Labs, -    
 802.11n (  5 qq) 
$ 
 $  
  -    API- 
    
      " 
 
,  

  .
 $     !. «4  ! 
USB/
Serial»   2.

 , 
    
   -
  ESP8266 Thing  ESP8266 Thing Dev
 % ,      Feather ESP8266
Huzzah!, $ $ 
 -
     %    .  
SparkFun 
   
%
 
    ESP8266 —     
 
: https://learn.sparkfun.com/tutorials/
esp8266-thing-hookup-guide/installing-the-
esp8266-arduino-addon.
206 Глава 4

Проект 6
Привет, Интернет!
Из предыдущей главы мы узнали, что сетевые устройства могут работать как клиент или как
сервер. В этом проекте мы на основе Arduino-совместимого микроконтроллера создадим очень
простой веб-сервер, предоставляющий веб-страницу, чей фон меняется в соответствии с цветом,
освещающим подключенные к микроконтроллеру датчики.
! 
  
 " A 
Требуемые компоненты
 $    http://arduino.esp8266.

#  Arduino 
 

, com/stable/package_esp8266com_index.json.
 "      Wi-Fi, 2  
    " A     -
1 %., —  MKR1000       
   esp8266 by ESP Community.
 
   ESP8266.
/ 
   
    -
+       : Wi-Fi,   SparkFun,     Adafruit.
  , X3 (UART).

X 
     + 
 
 = 
     "   
Wi-Fi, 1 %.        
 ,

9  
  10 0, 3 %. 
      
:

 ,      . / 
-

[ (    
 -
 

         

), 3 %.

  
    -

>       , 1 %.     
. * -

# 
, 3 %.: 
 ,          

   .     

   -
  "   . & $ 
  
 
  .     -
Установка соединения    MKR1000   
 . 4.3.

   $ 
 , 
     
  ,  


 Arduino IDE
  
      .
Как работает библиотека WiFi101?
 
 , 
      MKR1000 
   
  
    -
       | ,   ,  
 ,      

  


  "  
 1.      WiFi101  Arduino
2  

 , 
    -  

   

 (
    $
  D  |  >
 

  - 

 
   
    -
  WiFi101. 4  ,  

    ESP8266 WiFi). >  WiFi101
"  
  2 
     
   WINC1500 -
D  |  >
 

  | N 
   ,    , 



 
. =     
- 
           -
  ESP8266 
   \ | ] 
  
. 7      

    ] 
     $  : Server  Client.    -


,

    
1
 MKR1000           Ar-    
 , "   - 
duino SAMD Boards.
2
+ 
 ,        -
'       $  ,     -

     "    %
     -  Wi-Fi. 3    
   
 Arduino,     % —    Wi-Fi 101.     
 , 
   -
«Глянь, мама, здесь нет компьютера!» Микроконтроллеры в Интернете 207

          $ 
-
. 

,      

      
   ,
    : read(), write(), print()
A B C D E F G H I J
 println()    Stream,  
 1 1

     Serial,   


Client  Server.  Client, 
 ,
- 5 5

    connect()   




,   connected()  
-
10 10
           
  stop() 

  . 7
 

   $   - 15 15

 — 
     

. 0  Красный
светофильтр
       % , 
    

  - 20 20 Зеленый
светофильтр
   . >  ESP8266 WiFi,  -

     $    - 25 25
Синий
светофильтр
 Stream, 
 $     .

0
       
 - 30 30
A B C D E F G H I J

, 
 %  Wi-Fi  
   + 
. &    , 
   


  %  - Фотосопротивление 200 кОм
 Wi-Fi (
  
, %  
%
-

) —      
 

(SSID)3, 
        -
  %
 . 
 , 
  MAC-
%   Wi-Fi, -
10 кОм 3,3 В
  
  $ 
 

-
       
  
 - Фото- Модуль
сопротивление микроконтроллера

 
%

. 4  % 
%

200 кОм
 
  
  MAC-
, Analog 0
    MAC-
%   Analog 1
  

%  MAC-
 
  -

   

 
%

. = Analog 2
10 кОм
$     
   

 
   
%

,   
  Фото- Общий
сопротивление
  . X  MAC-
   200 кОм
  "  , 
 
 
  ,  !. «& 
   ».

4           Wi-Fi


10 кОм
/ MAC-
   
 ,   -

      
  
-
"    
 
     - Рис. 4.3. Монтажная (вверху) и принципиальная (внизу) схемы
подключения RGB-сервера к модулю MKR1000. Обратите вни-
3
SSID, Service Set Identifier —    
мание на три цветных светофильтра, установленные на фото-
[ 
  ]  
   [ 
  ] . датчиках
208 Глава 4

  . =
 $               
-
     scanNetwork()    
   ,  -
  WiFi101. / 
%      
     
  
   ,       
  MAC- $. #   ,       

  !. «& 
   » —   -  
        % 
  $
  MAC-
%   (SSID)  
    ,   
-
Wi-Fi,         .  
 .

    %   Wi-Fi  


    ,   
-
     
     

  . &   $  
  -

Библиотека Stream для Arduino



     Arduino, 
  >  Stream  
     -
 
,  
 Serial, SPI, I2C   -    TextFinder 7  7
  (Michael
Wi-Fi Client  Server, 
    - Margolis), 
         
     , 
   
    . &    ,   readString() -
    
  . /   Stream,       
   string.

  
       - 3   readBytesUntil()    
 
,            ,   
  
  -
(stream)  . , — 

: readByteUntil('\n’). [ 
readStringUntil()
    
, 
&   1  

      
,  - 
" 
  string. >  Stream

  , % %  
 
       ,  

    
   .
   
   
. 2     [  find()  findUntil()    -
( 

, 
    Serial.write())       
    
,
          
 ,        parseInt()  parseFloat()  

  ( 

, 
    Serial.read())  " 
 
    

 -
       
   .      "     . /  -
        
 
 -
>  Stream 
   read(), write(),    
  ,   
  HTTP. [ 
available(), print()  println(), 
   Stream     $     -
    
 . & 
     . =     
    Stream
  
   ,      Stream.      
  www.arduino.cc/en/Reference/
HomePage.

Сканируем адреса
= 
  %   /*
Wi-Fi     - Z 

      SPI  : Arduino    WINC1500


*/
WiFi101. 2    - #include <SPI.h>

       , #include <WiFi101.h>


      
-
  
   $
 . void setup() {
=   
   ESP8266 Serial.begin(9600); // \ #  $    ' $
  
  WiFi101.h  }
ESP8266WiFi.h:
«Глянь, мама, здесь нет компьютера!» Микроконтроллеры в Интернете 209

&   loop()     void loop() {


printMacAddress(); // +  R &ˆZ- 
  :       
 Wi-Fi
$
 73#-
 %  - listNetworks(); // Z       Wi-Fi
,  
 —   
  delay(10000); //  '
 $ 10  
    
 .
*         -

  %  ,  -


 $ 
      
   
   

   $  :

'  MAC-


- void printMacAddress() {
 Wi-Fi,       Serial.print("MAC-: ");
WiFi.macAddress(), 
 byte mac[6]; // &   -  MAC-
WiFi.macAddress(mac); //   MAC-

" 
    for (int i = 5; i > 0; i--) { // #   5  1


 6  .  if (mac[i] < 0x10) { //  
 ,
 
 MAC-
 - //  1 #  # %,
   $
   - Serial.print("0"); //   

 printMacAddress() }
Serial.print(mac[i], HEX); // +  R
(  ESP8266WiFi - //  '

 MAC-

"    MAC-
  - Serial.print(":"); //   R   $

  
 , $  }
       0  5  - Serial.println(mac[0], HEX); //   R
      5  0): // 

 MAC-
}

[  WiFi.scanNetworks() void listNetworks() {



"       Serial.print("+     - 
:");
 
   ,    int numSsid = WiFi.scanNetworks();
if (numSsid == -1) {
 , 
      Serial.println("^  '    Wi-Fi");
%
 : return; // +$   
# 
}

[  WiFi.encryption- // +    - - 


:
Type() 
"   , 
- Serial.println(numSsid);
"  %
 : // +    
 
 :
for (int thisNet = 0; thisNet < numSsid; thisNet++) {
1. WEP String message = WiFi.SSID(thisNet);
2. WPA message += "\tM  : ";
message += WiFi.RSSI(thisNet);
3. WPA2 message += " dBm \t˜ % :";
4. *  message += WiFi.encryptionType(thisNet);
Serial.println(message);
5. 3     }
>  ESP8266WiFi 
- Serial.println();
}
"       -
    : 1 — %
 

     0 — %
-
 
   :
210 Глава 4

Планируем сценарий веб-сервера


# 
   -

, - /*

   ,  +-


        - : Arduino    WINC1500
*/
" : // '    " %  #   
?    ;
?      ; void setup() {
// \ #  $    ' $
? 
   HTTP.
//   '      Wi-Fi,
 %

   - //   ' 
  $   ,  //    ' , $  
//   R    

    
- }
      
    
  
- void loop() {
. = 
    // ™ '
 
    -

: //    ',
//   -  
,
//   -  
  
 $ $
     
 " //   '   R.
 , HTTP-
   // †    ((\n  \r\n)
     
 . //   HTTP
// Š   ,     
$     
// †     ',
  
  
 - // ' .

     . 0   }




   ,  -
,   HTTP,  

     
:
HTTP/1.1 200 OK

*%    
   
 .
*,   
   
 "  ,

   $  
    -

     
    . #
%
%  $ 
  —   $
 
,     
 
 

#include. = $ "  
  
 , 
-
   
    


 
   
 
 (
 . 4.4,  ),   -

  New Tab (* ). 2 

       (
 . 4.4, 
-
!) — 

, config.h. &
 $  -
          
$  . #
"   $  

Рис. 4.4. Создание новой вкладки в среде разработки Arduino (вверху) и присвоение ей имени (внизу)
«Глянь, мама, здесь нет компьютера!» Микроконтроллеры в Интернете 211
          ,  ; 
         
 -


#include "config.h"    .  "   
 ,   

%  
    % . *
#  ,     -        $   
" ,     
 
ssid     config.h.
   SSID  
 % :
char ssid[] = "ssid"; // \  (SSID)
&  %    
 "   -
// 
 Wi-Fi    
 —    config.h —  
char password[] = " "; //   
  
 
    Arduino.
//  -  

Пишем код веб-сервера


+, 
      /*
  %      +-
 -

. : Arduino    WINC1500
*/
#include <SPI.h>
&     
#include <WiFi101.h>
     #include "config.h" //     ssid[] password[]
%   config.h. ;  

    
 WiFiServer server(80); // Z$ R$   

   
  $ -



. #

 
-
  
 80,  
 
  -

:

&   setup() 



  - void setup() {
     Wi-Fi Serial.begin(9600);// \ #  $    ' $
,    ,     //   '      Wi-Fi,
      , while ( WiFi.status() != WL_CONNECTED) {
Serial.print("   '      : ");
  . > 
Serial.println(ssid);
WiFi101 
    WiFi.begin(ssid,  ); //   ' 
%
 : WEP4  WPA/WPA25, delay(2000); //    $  2  
     
  //   '


. ; %


   
- }
          -
   WiFi.begin(). =
WPA  WPA2 $     -
    " 
: WiFi.
begin(ssid, ); (
 -
  ). 4  %
 
 "   , 
 
  
   . ; %
 
WEP    
 -
      :
4
WEP, Wired Equivalent Privacy —  -
  ,    " 
-
  .
5
WPA, WiFi Protected Access — "-
"    Wi-Fi.
212 Глава 4

&     - server.begin(); //    ' , $  
//   R  IP-
  ,   

  - Serial.print("Š -  - %
 R 

  $
 IP-
, 
   : http://");
  ,   
  IPAddress ip = WiFi.localIP();
  : Serial.println(ip);
}

&   



 
 void loop() {
      - // ™ '
 
  . 
   WiFiClient client = server.available();
while (client.connected()) { //    ',
     HTTP-
 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-
 ,       ,    -
, 
    
 
.     
,  
% 
 .
&  

       2  
 
   ,    -
$ 
 HTTP,       
 
%    
   
 -

,  
 %    

. / 

,      
 
 , 
  

,   
    GET/. & %   
-
  
 HTTP    3. ; 
 "    
,    -
      
 ($ 

-   

, 
  -

      "   curl):   $   
   
 —   -
GET / HTTP/1.1    
  —

 .
Host: 192.168.43.184
User-Agent: curl/7.46.0 ' 
   

   


Accept: */* - 
 ,  , 
-


"     -  HTML.
>%   
 
 
  HTTP =  ,  $  .

      
, 
«Глянь, мама, здесь нет компьютера!» Микроконтроллеры в Интернете 213

Недостаток аналоговых вводов в платах ESP8266


& $      
     ,    
  
WSP8266         .

Дорабатываем скетч веб-сервера


&      - String makeResponse() {
      String result = "HTTP/1.1 200 OK\n"; //  HTTP
makeResponse(), " result += "Content-Type: text/html\n\n"; //  
//   # $

  
  . result += "<!doctype html>\n"; // ƒ    HTML
&  
 
  - result += "<html><head><title>"; // ƒ HTML, head title
 HTTP,     —   result += "    Arduino</title></head>"; // #

 (  \n\n 
 - // $ HTML
result += "\n<body>\n"; // ^    HTML
    
).
2       
HTML:

&     HTML  - // + $     :
   $
    - for (int analogChannel = 0; analogChannel < 6;
analogChannel++) {
    
result += "    ";
MKR1000. = 
 
- result += analogChannel;

  %   result += " ";
      - result += analogRead(analogChannel);
         result += "<br />\n";
analogChannel: }

* ,   


- result += "</body></html>\n\n"; // #   
"   </body>  </html>  //   
return result;
  
,  
%
}
  HTML  


:

&      loop() if (request.length() <= 2) {


  

client. //client.println("HTTP 200 OK\n"); //   HTTP
String response = makeResponse();
println("HTTP 200 OK\n") 
client.println(response);
 "  
  ( - delay(10); // Š    ,     
  
 %
):

&    
 -
  ,   
    ,     

 Wi-Fi  


 

.
214 Глава 4

*%

Arduino  
 
 
; 



  
 . 
   
 
, -
  $  
   
 ,   
   
    —
     
   "  -        
-

  ,   -

     + 
. *   

      



    ,    % 
 , 
-
Arduino    
 «  "»  -       . *, %   -


. &   makeResponse()   -     
      
  HTML   
 —   makeResponse(),  
  %

   
   
 ,       

-

 "   


,        - 
    Arduino -
  ,  
   
 
   Wi-Fi. = 
  -

   
 

 
 -  

,  ",   
 
   
  .
 
  
 $  .



 
    - result += "    Arduino</title></head>"; // #


,    - // $ HTML
result += "<meta http-equiv=\"refresh\" content=\"3\">";
     . *
  ,   
   $  
-
    ? = $ -
    makeResponse()
  
, 
 
-
  
"   </head>,
 " 
  (  -
  
 %
), 
  

 
 :
; 
 
    -
  

  

   .
&  

    - result += "\n<body>\n"; // ^   
 
 
  . // %

 
     :
&    $  - result += "<body bgcolor=#";
// 9 
  
    :
,    % int red = analogRead(A0) / 4;

 , 
   - int green = analogRead(A1) / 4;
     - int blue = analogRead(A2) / 4;
 . = $      // N!
    
//  
 
   
:
makeResponse()   for
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);
2
%
  %
-
result += "</body></html>\n\n"; // #   

     " ,  - //   
   ,   " - return result;
  
   . }
«Глянь, мама, здесь нет компьютера!» Микроконтроллеры в Интернете 215

Предоставление доступа из Интернета к устройству


с частным IP-адресом
=  
 %  
-
 
 0
    ,  
%

 
-
%         
- 

 

      -
  
    . 3    . *

,  

 
 80, 
  
 
 ,  
    
-  
%

   $ 
   
 ,  %  
           
 . $    
+ 
         
   .    
 — 

, 8080. ;  -
 "     
"     -      $ 
   
  ,        %  -  %

  node.js   
 8080.
%  
%

      IP-
,     -


  
-
     
  
   %  
 80,  
   
  
% . ' 
  $ 
  , 
,   
   


:
     ,    
 
%-


 
 %   " - http://www.myserver.com:8080/
"   
  . ;     "      
 -


%

    Wi-Fi % 
= $ 
   
   
- 
 . *

,   IP-
% -
 
%

 203.48.192.56,    

 %  
%

      $ -


    
 
  -

 -
  
      Port forwarding
   
http://203.48.192.56:8080.
(

  
)  Port mapping (0-

  
). + 
 
%

 - &  
    

   
-
     
      ,  

  
 
%

 Apple
    $  
        - AirPort Express   
 . 4.5,   
 
  . = 
   
    
- 
%

 Linksys — 
 . 4.6.

      
 80, $  
 

%

,   
 80 %   Будьте осторожны!
Wi-Fi   
 8080 
%

 (  &          , 
-
  
   %  
%

"   

% 

  
 
 ).      $  
          %  
 !
" 
       / 

%        
IP-
 
%

   
 8080   + 
 . &     ,   
-


      IP-
  Wi-   %  
  (,   "   . .),
Fi   
 80. $      .

Рис. 4.5. Настройки перенаправления портов маршрутиза- Рис. 4.6. Настройки перенаправления портов беспровод-
тора Apple AirPort Express ного маршрутизатора Linksys
216 Глава 4

Приложение встроенного сетевого клиента


Теперь, когда наш сервер готов, пора создавать клиента. Это будет встроенный веб-клиент, за-
прашивающий данные у веб-сайта, отслеживающего качество воздуха, и выводящий эти данные
на физическое устройство — стрелочный индикатор, в роли которого выступит аналоговый
вольтметр.

Проект 7
Сетевой измеритель качества воздуха
Кроме вывода на веб-страницы, всевозможные данные могут отображаться многими иными спо-
собами. В наших домах, например, имеются часы, барометры и термометры, служащие в качестве
как информационных, так и декоративных устройств. Но чтобы физическое устройство могло
показывать нам полученные из Интернета данные, оно должно уметь подключаться к серверу,
запрашивать эти данные и преобразовывать их в цифровой ряд, управляющий устройством их
отображения.
& $ 
      
 .
Требуемые компоненты
= $  
      -
  
 - %  
#  Arduino 
 

,
 

:  
    -  "      Wi-Fi, 1 %.:
. ` 

   
 
 
 , • MKR1000;
           % •  Arduino Uno-   
 
  $ 
   
    % WiFi101;
% 
. 7 ,    - •      
  
  ,  
 ,  , ESP8266.
      
 ,      +       : Wi-Fi,
, 
  
     % . +7 (PWM), X3 (UART),  / 
"     (GPIO).
7
 

      -  , 
X 
     + 
 

   #  "  Wi-Fi. Wi-Fi, 1 %.
2           -

>       , 1 %.
 
  , 
  
   
  
,   
& 
, 1 %.
 "   analogWrite() 
- 
# , 1 %.

        -

9  
  220 0, 1 %.
  
  ,   %
 -
   (+7) $  .
" 
% 
  
7     
  
   
,   

  
  
  - 
 ,       
  
  HTML  CSS. ;  

   HTML    
 -    
  API7.
  
    (    -
 -
! 
  6), ,   ,  -        - 
 
" 
 %  
 " AirNow — 3    
 
"
  -    "   
 ,
7
API, Application Programming Interface —  

6
0  . web-scraping. 
  


 .
«Глянь, мама, здесь нет компьютера!» Микроконтроллеры в Интернете 217

 #3 (www.airnow.gov). * $  - Для жителей других стран

  
       =  ,     #3,  -

-
    
 #3. C "    AirNow — Sonoma Technologies —
 -
 
%  
      %
  
         -
 
        

  
 . 4       AirNow-I 
    $        ,
(
  ,     #3)   -
;    

   7  . = -
  
, 
    $        
    
 - 
  . www.sonomatech.com/project.cfm?uprojectid=1102
 
   
    .

Управление вольтметром с помощью микроконтроллера



  ,  
   
          
   " 
 
 -  , "    " 

 

  "  
  . " ,   30
   . 3    -
7
 


    - 

    "  
-
     ,      -  

   , $ 
%


              
   -
 , 
 
  -  +7.        
 
  
  . '   % -  
    
 

,  -
%  
       -
  —  " ,  ,  -
    
   ,        
 

 +7-
 %
 
  . /    -   
% 
       -
  
-
  
 (+7)8. 
 
.
'   +7      
  
 , 

  - *
 . 4.7   
     -
 , "  ,     -     $ 
 . 
  
,
     ,     -   
   :  —  
-
. *

,     +7    MKR1000,  
 —  %  ,
 ,    ,   
  ,     4. /    -
8
    
  
 .
0  . Pulse-Width Modulation (PWM).

Скетч для проверки работоспособности вольтметра


# " 

   - /*
 

,

   -   
 
     - \$    analogWrite()      .
: Arduino    WINC1500
: */

const int meterPin = 5; // Š    - 


// ESP8266   $  
# %


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

void loop() {
//          
//    -  :
218 Глава 4

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 C D E F G H I J

3,3 В
D6 Рис. 4.7. Монтажная (вверху) и принципи-
альная (внизу) схемы подключения вольтме-
тра к микроконтроллерной плате MKR1000.
Встроенный
Встроенный светодиод подключен к цифро-
светодиод
вому выводу платы 6 (D6)
Модуль
микроконтроллера
Цифровой вывод 4

Цифровой вывод 5 (ШИМ)


Общий

Светодиод
V Вольтметр
«Глянь, мама, здесь нет компьютера!» Микроконтроллеры в Интернете 219
=    
  pwmValue -  
   
 0–3 &,
 


      - $    
  
  
 
    %   
. & 
, 
  pwmValue     230, 
 -

   


 $

    
   

 ,  
  
 .  3 &,  
      -
= 
  
, 
  -      . 0
   -
     ,    0–5 &,           
 
 $   
 "  
  
 pwmValue     
 $ 
 -
 
     
 ,  -    . /    
  -
       
            -
MKR1000
  3,3 &. *  « 
»  % %   
.

Запрос данных веб-страницы через ее API


*
 . 4.8   
   -      - 
  AirNow 
AirNow  
 *-
 (www.airnow.  
 ,
    
 
 -
gov/?action=airnow.local_city&zipcode=10003
. 7
 

    
-
&submit=Go).  
  ASCII  

 
    . 0     -
/ 
  

    

  -         - 
    
   -       -    ,  $    -
"     (AQI9)        . *,    
 
    . *  - 
     ,  -   AirNow

    
     
9
AQI, Air Quality Index —       (+&).    — "   - 
 

Рис. 4.8. Веб-страница AirNow отобра-


жает текущее качество воздуха для гео-
графического местоположения, опре-
деляемого почтовым индексом США.
Однако в интерфейсе API веб-страницы
географическое положение определя-
ется широтой и долготой точки замера
220 Глава 4

API,     


 docs.airnowapi.org. 
 
, 
      -
=    API- 
    
   
  %     .
        , 
 -
      500 
   API   . #       API- 
 
 -   AirNow, 
   -   AirNow
;  - 
 API (  
 API  

,     Current Obser-
 -   AirNow     ) 
   - vations by Reporting Area 
  By Latti-
 
   -  , 
 "  - tude/Longitude  "      
 
  ,   HTML. 2
   - Query Tool (https://docs.airnowapi.org/Current

  API    " 
 ObservationsByLatLon/query). 0
   
-
HTTP      
   
 
, ,   

"  
 
-
     ,   $    - 
 
  
 API- 


   
 «

" 
 »   -         
 -
 3. 4    ,  API- 
 
-       %
   .
 
 
  , % 
- #
       
 , -
   
   
    "  
 ,    %  -

 
 
 . 7  API- 
    , ,  
   -
 
   
   API, - 
   ,
     
" 

" 
   
       
 
%    .
%  
 .  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  $    
-
    
  
 
PM2.5 —
    
   :  
  -
        
       ,    PM2.5,   
  . >  , $      -    
  "    -

    , ,    
  
 (AQI). /        % 

  
 10 
   %  "     Arduino.
     . =   , 
-
«Глянь, мама, здесь нет компьютера!» Микроконтроллеры в Интернете 221

Планируем чтение параметра PM2.5


; 
,  
   -     
 HTTP. = $   -
 Wi-Fi  # ,      AirNow         6 ( 


      
  , -  )     4 (  ).

  
   "  
& 

       -
 :
  — ArduinoHttpClient. >  $


  3
  7Š  (Adrian
1. 0
      -

.
McEwen),
 %
 #  7 
 (San-
2. 0
  
 HTTP GET. deep Mistry)  
     HTTP-
3. †   . 
  GET, POST, PUT  DELETE,   -

    . # " $
4. 0
    .        
 
5. *               HTTP,    

  
. HTTP,   
  
   -
6. &     "  
   .

  
 
. Версии библиотек HttpClient

  %  
   "  $
- #" 
 
   HttpClient.
*   , 
      
,  
   
  
ArduinoHttpClient.
 ,         

>       /*
"  
 - +-  AirNow
    ,  
   -
: Arduino    WINC1500
  
  
-
*/


 Arduino. 0
  // '       %  #  %

  D ,  
  //    / " 
 >
 

  | //  
N  

 
,  -
void setup() {

%    " A 
- // \ #  $    ' $

     
 // \ #  $    
(     
   //   '      Wi-Fi,
%)    ArduinoHttpClient, //   ' 
 
 
  - // &     # '   
// '     ,   R 
      N- //   


. }

  

   void loop() {
    : //  HTTP-$    
// M      HTTP-$
}

void connectToServer() {
//  $ HTTP,  ' 
// †     ,     "PM2.5",
//   $  $    PM2.5
//   

222 Глава 4

>-   $ 


 - // †   $    $ - (\+),
//  $    , $ $,


 

   // -   R $ HTTP

 . 4.9. 0 
%  }
(

if   )  -

,    " void setMeter() {
  — 
 . // Z  $  PM2.5   $
//   ,  $    
9    

- }
   -    
    
,  
 - void setLeds() {
    

 . //  '   , '    #
// '   
/    ,   -
//  '  TCP, '  
    ,    // '   -

 
       - }
 true (  ).
void blink() {
// &   
}



    

 API  -       , 

 -
      . 4     
    
    .  
      , 

 

   

,   ,
           "  $ 
    - 
 ,  

    
. &  
   
  
    —  
.

Сочетание в строке данных разных типов




 

  -    
- * 
        -
        
     -   (    char),  


  . 7    $ - (    string). &   
-
   % 
 "

 

 ,       

    -
     HTTP, 
     
 "   "  
     $   
. &    
- toCharArray(). = 
  



   
        

 :

  $   ,   API,  -
String myString = "/some/server/route";
 , %
  ,  
 
char stringArray[myString.length() + 1];
  
  . 9  $ 
myString.toCharArray(stringArray, myString.
    
    Arduino
length() + 1);
String. # "   
     

  
 , 
  
 . 3 

- 
 $    ,  
    -
            - 
             
"   
  ,     0, $   $      
-


  String(), 
  
    

   
  
  

 

 . >       % ,      $
  

        
. #
       

-
   %  
  
   ,      "  "
   $ 
BIN  HEX.   .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       //    / " 
//  :
     (  const int networkLED = LED_BUILTIN; //   
 
   ESP8266  - // ' 

    
), 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 netSocket; // 


  

 : WiFiClient  const char serverAddress[] = "www.airnowapi.org"; // 
// 
 ,    
String route = "/aq/observation/latLong/current/"; //   API



, 
  
- long lastRequestTime = 0; //    $  
    API    -
  
   
 
    
 :

&   setup()  - void setup() {



       , Serial.begin(9600); //  #  $    ' $
pinMode(networkLED, OUTPUT); // %     
 

      //  '   
 #
      
  //      
,   ,   $ pinMode(connectedLED, OUTPUT); // %     
  

 

 . //  '    # ' 
//        
2 ,  ,   
- pinMode(meterPin, OUTPUT); // %     
 :  
   - //          
    
   //   '      Wi-Fi,
      blink()  while ( WiFi.status() != WL_CONNECTED) {
      Serial.print("   '      : ");
Serial.println(ssid); //   R   (SSID)
 . 0
   $ WiFi.begin(ssid, password); //   ' 
        blink(networkLED, 5); //     #


 : // '   
}
// '     ,   R   
// 

«Глянь, мама, здесь нет компьютера!» Микроконтроллеры в Интернете 225

IPAddress ip = WiFi.localIP();
Serial.print("IP Address: ");
Serial.println(ip);

&     setup() - //       ' API:


    
 
  - route += "?format=application/json&latitude=40.7296";

  ,   route += "&longitude=-73.9936&date=2016-05-10T00-


0000&distance=10";
 URL-
, 
 route += "&API_KEY=";
 "  

 route += APIKey;

  API- 
    - }
 AirNow. #     

      , 
 $ 

   ,
     


 
 
 
 
     
 
 .
*

,    
%
     % 
 
 ,     
 
   :

&   loop()  - void loop() {


     . //  HTTP-$    :

 — $ 


 - if (millis() - lastRequestTime > requestInterval) {
connectToServer();
   
      }

  (   
  // M     :
lastRequestTime)   " setLeds();

  (  millis()), }
 
 , 
% 
   
   
-
  "  
 . 4  ,
      connectTo
Server(). 3 
  — $
    setLeds() 
      
 . 4  
 
 

   :

[  connectToServer() void connectToServer() {


    
   - int AQI = -1; //   $ \+
 

  . &  HttpClient http(netSocket, serverAddress); // $
//   HTTP
  
    http.get(route); //  $ HTTP
HTTP (
  HttpClient), http.skipResponseHeaders(); //    $
      
 HTTP GET, // HTTP-
 

   :
226 Глава 4

   
- //  '   :

,      while (http.connected()) {
setLeds();
    ,   
//      :
  setLeds(),   
- if (http.available()) {

 ,    . 
 - http.findUntil("PM2.5", "\n"); //   
        //  "PM2.5"
findUntil()    
- AQI = http.parseInt(); //   $ 
// $    PM2.5
 $ 
 
 "PM2.5",
http.flush(); //   

   "   }
parseInt()     - }
"    
  if (AQI > -1) { // †   $  


      - //  $ - AQI (\+),
     . 
   Serial.print("PM2.5: ");
Serial.println(AQI);
       +&
setMeter(AQI); //  $    
(AQI)       set- }
Meter()      -
 
:

2  
    http.stop(); // $ $


,     http. lastRequestTime = millis(); // -   R
// $ HTTP
stop(),  
    " 
- }
  
  lastRequest-
Time:

&   setMeter()   - void setMeter(int level) {


    map(),  - //  $  $ '  - 
//  $   :
  
  +&  - int meterSetting = map(level, 0, AQIMax, meterMin, meterMax);
"      
  //  $    :

     


. analogWrite(meterPin, meterSetting);
2   
 
 
"  
analogWrite():

&   setLeds() - void setLeds() {


       - //  '   , '  
//  # '    :
, 
   % -
if (WiFi.status() == WL_CONNECTED) {
# WiFi.status()   , digitalWrite(networkLED, HIGH);
  Wi-Fi   } else {
,       
- digitalWrite(networkLED, LOW);
  .    - }

    WiFiClient. //  '  TCP, '  


// '   -
 :
Connected() 

  - int connectedToServer = netSocket.connected();
  

    digitalWrite(connectedLED, connectedToServer);
  "    - }
 
   
-
 :
«Глянь, мама, здесь нет компьютера!» Микроконтроллеры в Интернете 227

* ,   blink() void blink(int thisPin, int howManyTimes) {


    "  - // &    :
 
  200 - for (int blinks = 0; blinks < howManyTimes; blinks++) {
digitalWrite(thisPin, HIGH);
  . *
 ,  - delay(200);

   ,  digitalWrite(thisPin, LOW);
    
  delay(200);
     
 
, }
       - }
   
:

&       - . #


         "  -
   AQIWebClient  
    ,  
         
MKR1000. 
                  
  
       

  
(
 . 4.10).

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


228 Глава 4

Определение 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:
Команда nslookup также возвращает адрес сервера
Name: makezine.com
DNS, который она использовала
Address: 104.25.45.28
  IP-
           
   , $   
  .

Послесловие к завершенному проекту


& 

  $ 
   
- ? ' :    $     ,
%     
  ,   %  
  ,      


      
 ,  - 
  ,  
     " 
   
 

. &       
  
   
 $       "   -    , -      
 
 ,   
      
 .
  
    . +   
?  :  
           "  
 
      ,   ,    


$  ,      ,      $ 
  
 , 

. =   ,          
         
   

. +   
 " 
     

     ,   ,   
           .         


  
,       
 ,        
    
 
   , —  ,         
 
    " 
   -   
 ,
 
  
 . &     $  
    
  .
 
   %   
 ? % :      
 
  , 

     
  ,    

 
      , %   
   
, $ %

     .     
  . &  
 
«Глянь, мама, здесь нет компьютера!» Микроконтроллеры в Интернете 229
       
 
    "   Hue lighting hub
  ,  

,  
    Philips. 0   Wi-Fi
  ,    
   WINC1500  ESP8266    -
API- 
 ,   

  
       
-
%  
  ,        
          -
          
 
    


, 
    
"    . 
  ,  -
   

,  
          ,     
  %   
 .     
 ,   ,
  
       
& 
 "  
     
        
   
  

, 
     
 , 
 ,         ,
   
  
-
 $      
% -
  "  %   
  -
 ,     
    .
    . &  
 
+    "  
 -
 
  $      ,
    
 

   
       



        
-
    
  
 
% 
  "   
 
   

. $ %  
    . / 
   %  
    
 -

     
   
 -
      
   .
 — 

,    


Форматы данных
Разбираясь с проектами этой книги, мы уже познакомились с рядом существующих протоколов,
основанных на передаче текстовых данных, и даже создали несколько своих. По сути, прото-
кол — это средство для структурирования данных при организации связи. Некоторые протоко-
лы просто передают информацию, а другие отдают команды — явно или неявно — посредством
запросов. Далее нам придется часто работать с разными протоколами, поэтому сейчас было бы
полезно подытожить наши знания о рассмотренных к этому моменту форматах данных.

Простые форматы данных


& 
  «7
 %  - »  -  . 7     


 
   ,
  - 
     
 «-   ».
 . [
 CSV10  TSV11     %  ,       ,
    — 
 
 CSV       
    (   
     
 
  ), 
    
 
.
  
 
,   - &    , 
 
«-   » -

 
. ~
% 

 -   
  HTTP,   , 
 
 CSV  
   
  
 

  HTTP. [
  

NMEA-0183, 
     
  -    
 ,         
 GPS.   $ 
  -
     
  ,  
10

— 
. *

,   " 
-
CSV, Comma-separated values —   ,
 
 .
       
    -
11
TSV, Tab-separated values —   ,
  -  ,  
—  :
 .
230 Глава 4

"DateObserved":"2016-05-10 ","HourObserved":0,"LocalTimeZone":"
EST","ReportingArea":"Newark","StateCode":"NJ","Latitude":40.7267
,"Longitude":-74.1442

3   "  

    
- & 
     
 -
    
  (=),  
— - 
 
 :  
   
 , 

  (&).  ,  
   ,



. 3     
  -
?name=tom&age=14
  
 
 
:   
 .
3  "  


 
«- ' 
    

   -
   », 
   
. 2    

   
   
    
     ,     
   $ $  

—  
 : 
    

 ,     
   $  .
Host: localhost
Content-Length: 19006
Content-Type: multipart/form-data Примечание
7     
 &   


  Java, JavaScript  C
      + 
 — 
-     ,    
,
 HTTP12  SMTP13. 0     " 
 
   , 
-

:        GET         #
 -
  " 
:
POST,   
     
 

  ,   
 
- •  
 — \n
      
 . 2  -
• 
 
 — \r
         "  
 
 
,   "  •  — \t
    
     *  
 
 $   -

 
. _  "  -    ,  
  
 
  
      
" %  " . &    -
«-   »,  
    -   
  
"
     ,  $      
-       .
  
   
  (&).
& ,  

,  " 
 HTTP
POST    2:

POST /check HTTP/1.0


Host: example.com
Connection: Close
Content-Type: application/x-www-form-
urlencoded
Content-length: 16

name=tom&age=14

12
HTTP, HyperText Transfer Protocol — 
 


  .
13
SMTP, Simple Mail Transfer Protocol — 
  
-
 
 [$ 
  ]  .
«Глянь, мама, здесь нет компьютера!» Микроконтроллеры в Интернете 231

Форматы структурированных данных


=       ,   & $       
   -

    
«-   », 
    $        
«-
- 

. 9 
, 

,    ». &     ,   

  ,
   
   - «-   »     
 -
 %   (. 4.1).  ( , 

, :3, $ :23).
&   
  
    
Таблица 4.1. Массив датчиков, расположенных  
   . = 

-
в разных местах дома

     $    -
Последнее 
     
    
Адрес Размещение Значение
чтение JSON14.
1   12:30:00 60
2 q   05:40:00 54 14
JSON, JavaScript Object Notation —   
3 &  01:15:00 23 JavaScript.
4 #  09:25:00 18
5 

06:20:00 3

Формат 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}]

/
    
    

- "$  ":" ",
   . /  
    "   ":"05:40:00",
" ":54
  ,        },
   
   ,   - {
    $         " . "ˆ":3,
  $    
,    - "$  ":"",
   ,   % . # "   ":"01:15:00",
" ":23

 , 
 
   - },
  

 JSON, $ 

  {
           "ˆ":4,
 " 
: "$  ":"",
"   ":"09:25:00",
[ " ":18
{ },
"ˆ":1, {
"$  ":" -", "ˆ":5,
"   ":"12:30:00", "$  ":" ",
" ":60 "   ":"06:20:00",
}, " ":3
{ }
"ˆ":2, ]
232 Глава 4


"   
    - 
   , 
 $ 
   
,  JSON,        —   $    
   


  ,   


   , -  . =  
 JSON    -

  
, 
    -      
  HTTP,  
 
        . ;   

 (
 )     

, 


 
    
       .

    %    ,  

JSON и JavaScript
        , 
 7   -      
 JSON
JSON 
    JavaScript, $   API- 
 ,     


  JSON      - 
"   
      -
,    
  " $  .  ,     
  
> ,  
 JavaScript - $ JavaScript. & -

  AirNow,  -
  " JSON. *  
  
  
 
   7, -

 
  
 .  
"     
 JSON. =
&    ,   
     
  

 
  node.js 
   
      - 
  $  .
,           
JSON.

Парсинг ответа сервера с помощью сценария на node.js


# "  
 
        JSON,  
  
JSON.parse()     
   
-   
 
.   

   
 
   $
 .   — JSON.stringify() — 

 -
[  
      
 
      JSON  
.

  
 JSON  

  

>  http    - /*


 
 node.js, $   AQI client
: node.js

      -
*/
      .
   http,  var http = require('http'); // '    http:
    
 

 
 . 0
    ,  // $   $    R  " JSON:
 

  $   
- var options = {
 
 (
  options)  host: 'www.airnowapi.org',
port: 80,
   JSON. & $  - path: '/aq/observation/latLong/current/?format=application/
 
 
 
  - json&latitude=40.7296&longitude=-73.9936&date=2016-05-10T00-
 
«-   »,
- 0000&distance=10&API_KEY=0000AAAA-0A0A-1111-A123-11223344AA55'
   . 2  };
   API  
 
    (   
-
 %
)     :
«Глянь, мама, здесь нет компьютера!» Микроконтроллеры в Интернете 233

[  
    function handleResponse(response) {
 
 
 , 
 var result = ''; // Z    -  
       han-
response.on('data', function (data) { //     ,
dleRespons(), 
  -
result += data; //     $ 
  ,   - });
    
   .
 "     - response.on('end', function () { //  $ '

   
  result. //    ,
3   response.on('end') var response = JSON.parse(result); //   
// $ 


  
  - console.log(response); //    R
 JSON , 
  
- });

,     $
 : }

* , 
 
 - var request = http.request(options, handleResponse); // ^ 
     http.re- // $
request.end(); //  $
quest()  
%    
  request.end():

#
  $  
   
  aqiClient.js   
     :
$ node aqiClient.js


  
     
 - /  
      


,
    -

   ,         -
 JSON     $
   
-        $   
-
 . 0    
     , 
  API- 
   
   -
$ 
      $
  , 
 "     

$   response [0],    — $   JSON. #  "      
response[0].AQI  response[0].Longitude.   
 HTTPS, 
   
&     
  
   
 
   require('https');
  ,   .   %  
 443.

Принцип REST и интерфейсы API для Сети


Протокол HTTP основан на принципе передачи состояния представления REST15. REST — это не
протокол, а, скорее, архитектурный стиль для обмена информацией. Он часто используется
в Сети в интерфейсах прикладного программирования (API). И хотя принцип REST берет свое
начало в веб-приложениях, он нашел применение и в иных областях. Некоторое представле-
ние о REST не только поможет вам понимать другие системы, но также и разрабатывать свои
собственные коммуникационные протоколы. Усвоив этот принцип, вы уже не сможете в своей
жизни без него обойтись.

15
0  . REpresentational State Transfer — 
    
  .
234 Глава 4

0     REST      " : & $          


 -  #      -   ( -              -
    ). & , $   ,     255. & %   
,    , $ 
 

, 
- Arduino       


,
" %    

. 7  
 "   
    
     "    ,  -   ,       .
  $    . 
  REST 
    ( 
)    $ 0  
    
 

   #   
 $ 
    :
   .
1. 
   (
    -
7    REST — $  
 -   )   

  
,  
   
 HTTP.  $%.
    
   
2. 2
     —   
      ,     
 GET, 
  
      

  POST         .
       ,    
X       % 
 
. 2
 HTTP    

         ( 

,
: GET, POST, PUT  DELETE. 2


  HTML    
 . 4.8
GET        , PUT — -

   -   AirNow.gov, 
-
    , POST —   
" 
      
 -
" "  ,  DELETE — -
),     $    ( 
-
 " "  . +   $ -

,    
  
   

 , GET  POST    
  " ).
 .

   REST 
   URL- 3. /         

 —  "   , 
-   . #   


   ,  
 —   ,     ,    -

,  -

   "   . " 
  HTML    XML,
& URL-
      -  
 node.js,  "  

 
     $% (  
-  $
 , 
  

 
 
). *

,
 
   - PHP  Ruby, 

 C/C++,  -
    REST    
  - "   Arduino,      
-
   , 
  
    . ;       
   2. X     
     
:  
    
 , 

, 
 Arduino  -     ,   
  $
" 
 :    —  

.

GET /color/r/ &  


         -
  ,  
  REST    -
#          0  
     
 
 255, 
 " 
     - 
 . ;, 
  REST   
 
   . 3       
 
      
-
    ,  , 

,  "   OSC16, 

    

: MIDI. 
  REST      -
  
 

    
  
POST /color/g/255
16
OSC, Open Sound Control.
«Глянь, мама, здесь нет компьютера!» Микроконтроллеры в Интернете 235
 
    Ethernet,   - Традиционная веб-служба
      
    -
 
  . 
 ,   = , 

   " 
 REST,   
    
 -      ,  
     -
  
 
 
     -   
 
  
  .
     ,      = $          

    " ,     

  
  
 
   ,  
 
    
    :   ( ,    ),  -
 
   
.    
 
 . URL-
 
-
 $ 
  
  31  -
4"   
"  REST    , 
 2012       "
 
   

 
 ,  - 
:
 "
  ,  URL-
 ?    
   31  -
  
  .    - 
 2012 :

 %
    html, $ 
  ,   
  


- 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

  REST,      

-
 ( 

,  -     0 
 , 
    
 
 )  
    ,   
 
,  
 , 
   
   
 
    $    ,   "       ,
  
   
. 
 $   -  
 GET (  )     -
     REST:     
 
,  
 PUT  POST
(  )          -
? /"/   —     -    
 
.
  
;
?  /"/  /  — 
      .
Физическое веб-устройство
= ,     
   
-

     
 —           %   . & 
 
 — 
       -   12  ,        -
     PUT  POST. >  . &        
   
    
         1  10.   

  HTTP.          
  . URL-
  -
= 
   

 
   -           
 
. 0   — 
      " 
:
 - ,  
 —    
 
 . ?       :
GET /mywindows.example.com/windows
236 Глава 4

?         / 


       .
  (    —   2): URL-
,  
     -
GET /mywindows.example.com/window/2/    

,     -
,     
:
?          
-
  : http://myrun.example.com/?runnerName=George
POST /mywindows.example.com/window/2/height/5 &day=31&month=1&year=2012&distance=12.56
? 
  :
  REST — $ ,  
,
POST /mywindows.example.com/windows/height/S
      $     ,
#
  
    
  -     ,   ,     
     %  
 . 7  . *   - 
 
 
 
 
  
   , 
 


     

-

    ,    
-   REST. *

,  -   AirNow.gov,
  $
      
 .  
  
"   %  
 
3
 
 REST  
  ,   -       ,   
 -,       .    
  REST,     -

 . 7      
-
3
   REST 
     -   
  REST   " 
 -
 
  
. & ,     -  $  .
  
  
, — $
  -
" 
   
 
 " &    ,   
  
  
$%, 
 ,  
   
 
      
 
  
,       - HTTP   REST,    
 node.js
"     "   
.    Arduino.

Работа по REST в node.js



 node.js  express.js

 - "  
 
    /age/,  
    
  REST, $  
 
   
 . 7   -
 $
 " 
 , 
   "    
  
 
:
  REST,    
   . ;,

   " express.js   server.post('/check/name/:name/age/:age',
checkAge);


,      
 
, -

   . *

: * 
 
,    
server.post('/check/age/:age', checkAge);

 
    
    -
  
  REST,  $
% , 
= $   
     - 

 . 4  

 
 -
" 
 POST:  
,
 express.js     
-
  
 .
http://www.example.com/check/age/21


   
  "  
 
  

    request.params.
age, 
   21. _    ,  -
«Глянь, мама, здесь нет компьютера!» Микроконтроллеры в Интернете 237

Модифицируем код сценария «Проверщик возраста» в стиле REST


= 
  
  - /*
RESTful age checker

 «

" 
 »
  $    REST
( .   ageCheck.js   - : node.js
 3), 
   - */
 
  REST. *  var express = require('express'); // '   
   
 %
. // express:
var server = express(); // C$ " server,
#
  $  
  - // $     express
        - function checkAge(request, response) {
 restAgeCheck.js,     - var name = request.params.name;
 express.js: var age = request.params.age;
var responseString = "";
$ npm install express if (typeof age === 'undefined') {
responseString = "<p>9!
,    
?.</p>\n"
} else {
& $ 
  
 
if (age < 21) {
   
 : request. responseString = "<p>" + name
params.name  request.params. + ", +    ,    ..</p>\n";
age —     - } else {

 . ;   
 responseString = "<p> Hi " + name
+ ". +  $
,     '  , , ";


  
  
responseString += " 
  R $ ..</p>\n";
   
  —   , }
   
  $ }

 
: //      :
response.writeHead(200, {"Content-Type": "text/html"});
response.write(responseString);
response.end();
}
2     
  // 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);

& ,   
 ,    
- 2     
 
,   
-
 
 
     
 GET. 9  
 

 
   " :
 REST   ,     
 
http://www.myserver.com:8080/check/

 POST  PUT? # 
   
- name/tom/age/42
 $ ,    
 GET  -
   ,          3
 , 
       -

  
 
 

. X % ,  
  "   curl:
 

    
,   - $ curl http://www.myserver.com:8080/
 
         check/name/tom/age/42
server.get()  server.post().
&     www.myserver.com
# 
           -  
 

   localhost, 
 
  " 
:


 "    
.
$ node RestAgeCheck.js
238 Глава 4

Работа по REST в Arduino


'  
    REST 
 Arduino  ,      Serial,  Client

    ,    node.js.  Server   WiFi101   $ -
= $    

,    
   Stream).
     6. #

   
   ,     ,  [  setup() 

   REST
    
 . 2     -       6    
       Stream,       ,    loop() 
-

 
  $ 
 (  -    .

Пишем код Arduino в стиле REST


*  
   
 void loop() {

 
  HTTP, 
 // ™ '
 
WiFiClient client = server.available();
      "
while (client.connected()) { //    ',

: if (client.available()) { //   -  
,
GET /check/age/21 HTTP/1.1 //    '    -  ,
//       $:
#    
 
 - String request = client.readStringUntil(' ');
,     
 : GET // check if the request is GET or POST:
 POST: if (request == "GET" || request == "POST") {

= 
     //          /   :
while       String lastToken = ""; // 
 

while (!lastToken.endsWith("HTTP")) {
,      
String currentToken = client.readStringUntil('/');
 $% (/). 4  
 - if (lastToken == "age") {
" 
    int age = currentToken.toInt(); // ƒ  
 
  
  
 
, Serial.print("age: ");
  "     Serial.println(age);
    : }

&    while 


   //       
 "       lastToken = currentToken;
}

   "
,   
 , 
       -


:

    :



 $   client.println("HTTP 200 OK\n\n"); //   HTTP
     ,  if (client.connected()) { // †     ',
  
 node.js. 
   - client.stop(); // ' .
      
 
- }
         }

 . }
}
}
«Глянь, мама, здесь нет компьютера!» Микроконтроллеры в Интернете 239

Инструменты для программирования


и диагностирования встроенных модулей
При попытках подключиться к сети в проектах этой главы вам, возможно, пришлось столкнуть-
ся с некоторыми проблемами. Не исключено, что самым трудным моментом их диагностирова-
ния было то, что модуль Wi-Fi очень скудно информировал вас о проблеме, если предоставлял
какую-либо информацию вообще. Такая ситуация является нормой взаимоотношений со встро-
енными модулями в собственных разработках. Чтобы помочь вам в решении таких проблем, мы
рассмотрим несколько моментов, которые нужно учесть в подобных случаях, а также несколько
инструментов диагностирования. Эти методы применимы как при работе с модулями Wi-Fi, так
и с другими сетевыми или коммуникационными модулями. Мы будем постоянно использовать
эти методы в последующем материале книги. Они вам также пригодятся и в других ситуациях, не
связанных с нашими проектами.

Три самые распространенные ошибки

Проверьте линии питания Проверьте соединения


&         
  - 
     
 


     :       (-
      
  
  
" ). /   
   %     
      
-

           . X  ,        
  
  MKR1000  ESP8266.   ,   

 ,   -
*  
      % Wi- , 
  "    
, -
Fi  - 
    -     , 
    
 ,
 ,   
    (  
. &   
    -
 )   %
          ,     
$. 4     ,     
"  (  
 " )  .
   "  
  ,

"  
 
 
 . Проверьте конфигурацию
*    ,      - 4   
 
    
  , 

 
       , 

  
   
 ,
      (")  ,       ,      
.
    
       &    , 

 
     -
 
 .  IP-
  
 ,    (SSID), -

  


. ; 

 
 
  Wi-Fi,     .

Средства и методы диагностирования


X % ,   
 
  
-  
   

, 

, 


        -   ,  
    
.
"  ,     % 
  .
&     
  
 , $ &   
 

  -
            -     
   ,   -
 , $
      
     .  
,  
240 Глава 4

      / Использование


       для диагностирования
   
   

-
     
   , 
  -
последовательного обмена
  $  . 


 - 
      
-
,
  ",  
  
 . 4   Wi-Fi, 
    
-  ,    " $  $  ,   
   -


,     "
 . ,  "
 . *

,
    ,     
Физические методы 
 

 
   
 -
диагностирования       ,   ,  
#   
   -   
     
  

     . *  $  -    
 "  ,  
-
  ,
    
 , 
"      

 , 
 
 

 
 . ' $     
 "  

. =
    
 ,      
      $  -
   

 , " -    
     

  -

    . ;     " , 
  
   ,  %            .

 . &     
  $  
 ,         
 $    ,      


   ,       %-     
.      -

      
 ,  $           .
 
   "  - 7
 

   
  
 . &   — $  
     
,   
-
      , 
   
    
    

 . ~ $

 

. /  
" ,   - 
    
 ,    

   " . $ 
-         
      ,    ,    . $  

   ,     %             -

   . +       -     ,    %  
 .   .

Используйте отладочные команды


0     — const boolean DEBUG = true;
   
  , - void setup() {
Serial.begin(9600);

       

-
}
 ,      " 
 . 4     void loop() {
  
%   

if (DEBUG) Serial.println("‰   ");
  if (DEBUG),   - }
    , 
-
 
  DEBUG   -
 false:
«Глянь, мама, здесь нет компьютера!» Микроконтроллеры в Интернете 241

Объявляйте вызовы функций


   

 - void connectToServer() {
     
 if (DEBUG) Serial.print("\ % # 
connectToServer()...");
 
    . 0
- // Z'  
 % #
 ,         }
$   ,  , $ 

   
    void setMeter() {
    "     if (DEBUG) Serial.print("\ % #  setMeter()...");
// Z'  
 % #
 . = $    -
}
       -


Serial.print()   - 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(); //   



,     - }
   
    , }
    "  " -
,      " 
 :

Проверьте вложенные операторы


#
       int AQI = -1; //  
  $  \+
      - HttpClient http(netSocket, serverAddress); // $  
// HTTP
  
. X   
 http.get(route); //  $ HTTP
     %    while (http.connected()) { //  '   ,
  . 4   ,
- if (http.available()) { //     
"   . *

, //   $  $  \+
        
// ...  $     $   ...
}
      -
}
          if (AQI > -1) { // †   
  $  \+,
,      setMeter(AQI); //      $
 . $
 - }
 $   ,   
  "   :
242 Глава 4

Разделите код на части




   $ - if (client.connect()) {
 , $      - // † '  ,   

// $ :
"       Serial.println(" '  ");

 . *    - }
 
    
 else {

  . *

,  " // †   '    :

         Serial.println(" '   ");
}
  
   
client.connect(),    
-

        -
     

:

X   $     - client.connect(); // connect


  
  ,    - delay(1); // wait a millisecond
       if (client.connected()) {
// † '  ,   
$ :
   

    %  
Serial.println(" '  ");
$  .  ,   - }
  

      else {
 
    - // †   '    :
    %
 . Serial.println(" '   ");
* %  
 

- }
 
 

.
= 
  $  $-
  , 
 :

Просто наблюдайте
+        % // † ', -  -  
   :
    
 
- if (client.connected()) {
if (client.available()) {
   
    
char inChar = client.read();
  
,  Serial.write(inChar);
    . 0    , }

    
  }



   
-

,    
   -
  $
  ,   
  . /   
   
 
 

  . 0"" ,  
    
%   ,
  
    
,     . $
 
    ,    -
     , —  -
  ,     , -
   .
«Глянь, мама, здесь нет компьютера!» Микроконтроллеры в Интернете 243

Создайте программу проверки состояния сети Wi-Fi



              
 Wi-Fi,       


,           ,  %  —   
 
  . = $    - $
 IP-
 MAC-
  Wi-Fi,
  MAC-
%   Wi-Fi,     . /     
      
   ,      
,  
  
         -      
   .
. # "      $
 
-

Скетч для проверки параметров сети Wi-Fi


  $   
 ,  /*
$     

- WiFi Status check
   Wi-Fi
      config.h, 
- Context: Arduino, with WINC1500 module
" SSID  
  
- */
 .
#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("&  : ");
244 Глава 4

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-    


     $
   // +  R MAC-   Wi-Fi:
byte mac[6];
      -
WiFi.macAddress(mac);
  Wi-Fi (  Serial.print("MAC- 
: ");
ESP8266WiFi 
"    for (int i = 5; i > 0; i--) { // #   5  1
MAC-
  
  
- if (mac[i] < 0x10) { //  
 ,  16
// (0-0ˆ  #  % )
 , $       Serial.print("0"); // +  R 0:
  0  5     }
   5  0): Serial.print(mac[i], HEX); // +  R 

// MAC-
Serial.print(":"); //   
Внимание! }
Serial.println(mac[0], HEX); //   R 

Разные библиотеки // 
 MAC-    

#      -
  ESP8266WiFi   - // +  R IP-   Wi-Fi:
IPAddress gateway = WiFi.localIP();
   
    .
Serial.print("IP- ");
= 
    Serial.println(gateway);
macAddress()  BSSID()  -
   $   // +           Wi-Fi:
     "- long rssi = WiFi.RSSI();
 

, 
  Serial.print("M  : (RSSI):");
   # . Serial.print(rssi);
Serial.println(" Π");
Serial.println();
}

Создайте тестовую программу клиента


_    
      

-     

 . # "
 ,     % 
  
 - 

 
  
  
 HTTP 
       . 7      $
  ,       



     
-

:   
. / 
%  

    
 . #
 Arduino 

, 
 

 , , 

      ,       ,   
.
«Глянь, мама, здесь нет компьютера!» Микроконтроллеры в Интернете 245

Пишем код вывода ответа сервера


/ 

 
%   , /*
   

  Test HTTP Client
"  
 , 
 ƒ     HTTP
        
  : Arduino    WIN1500

. 4    
- */
  
,   ,
 ,      , // '       %  #  %

#include <SPI.h>
   %      
#include <WiFi101.h>
.
#include <ArduinoHttpClient.h>
#include "config.h"
  $   
 , 
WiFiClient netSocket; // 
  
$     

 -
const char server[] = "myserver.com"; //  
    config.h, 
 -
String route = "/foo"; //   API
" SSID  
  
-
 . 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  
}
246 Глава 4

Создайте тестовую программу сервера



 " 

    -        ,   
    

  


-      ,    
         " . "    

. '
* 
 $ 

   , 

 $    ,   
$      
 ,   

 

,  

    % " . 4       .

= 
  
- /*

 

  node.js, - test web server

       - ƒ
-
: node.js
 
   
. */




   -
"      // '    "   :
 $
 " ,   var express = require('express'); // '   
      - // express:
var server = express(); // C$ " server,
. ;   
  
- // $    
   HTTP. 

 - // express
 

, 
 
  node.js,    //  % # '  $,  $
//    $   :
 $
 
   
function respondToClient(request, response) {

   . 9 %  ,  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

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


"  $     ,  0  
   $  
 
      

,     
  ,    " 

 " "  -
   ,  
   " 
-
 
   . # % —    . *       -
   
   
 node.js, -       
  ,   
 "   "  
 
    
 ,
 

" "   -  . ;   -  $  . #      
-
   
  

 
-      

   
 -
 

, 
  %           %  .
    -

 ,  -

 , ;   

   -
 
. /         ,  
 ,    




 


,     " $ ,  
  ,
    
    ,  
   
  .
  .
Глава 5

СВЯЗЬ В РЕЖИМЕ РЕАЛЬНОГО


(ПОЧТИ) ВРЕМЕНИ
До сих пор большинство рассмотренных нами коммуникационных
проектов использовали для работы веб-браузер. Наше устройство
посылало запрос удаленному серверу, сервер исполнял программу,
а затем отправлял устройству ответ на запрос. В процессе этой
транзакции клиент устанавливал подключение к веб-серверу,
происходил обмен информацией, а затем подключение разрыва-
лось. В этой главе мы узнаем, как удерживать такое подключение
открытым. Для этого мы создадим две разные серверные
программы, которые позволят удерживать подключение открытым
с тем, чтобы обеспечить более быстрый и надежный обмен данными
между сервером и клиентом.

Музыкальный ящик Джин-Йо Мока (2004)


7  "   

 -
 
 + 

"  TTL-Serial/Ethernet. 

 
   
   "  , 
  
. # 


  
    

 -
     "-
   %        
 . 0 
 -
  '
-1 * (Jin-Yo Mok).
250 Глава 5

Компоненты для проектов этой главы


Коды поставщиков
? 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

ПРОЕКТЫ 8 и 9. Управление воспроизведением видео



Arduino-
  MKR1000, 1 +. 
N   >
    -
 Wi-Fi, 1 +. 4      
AF: 3156, RS: 124-0657, A: ABX00004, GBX00011  + 
 
 Wi-Fi,   $    
(3
  4#), D: 1659-1005-ND   . 0      
&   
      Wi-Fi  
    .
   Arduino Uno   - 
C      , 1 +.
  % WiFi101      D: 438-1045-ND, J: 20723  20601, SF: PRT-
WINC1500. 12615  PRT-12002, F: 4692810, AF: 64, SS:
AF: 3033   2891 319030002  319030001
Связь в режиме реального (почти) времени 251

(
  
 220 , 5 +. 
!
   (†  )   ,
D: 220QBK-ND, J: 690700, F: 9339299, R: 707-7612 1 +.
AF: 377, SF: COM-10982 BOB-11722, SS:

 &
       ,
311130001
1 +.
AF: 1609, D: V2018-ND, J: 616673, F: 4903213, 
  , 1 +.
RS: 159-5420 D: GH1344-ND  SW400-ND, J: 2231822 

H
      18    - 119011, SF: COM-09337, F: 1634684, RS: 718-
    "3   =, 4 +. = - 2213
%   
  
      
H  ).
  
   ,     - D: A26509-20-ND, J: 103377, SF: PRT-00116,

       . F: 1593411
D: 36-2204-ND, RS: 123-6835, F: 2301244

  ).

'
 "3     
 6 ,
D: ED7102-ND, F: 1122344, SF: PRT- 00115
8 +.
D: 36-9300-ND, RS: 274-5086, F: 2500400 
    , 1 +. (  . 
    ).

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

Интерактивные системы и цепи обратной связи


В любой интерактивной системе имеются цепи обратной связи: пользователь предпринимает
действие, система реагирует на это действие, пользователь видит результат реакции (или изве-
щение о нем) и предпринимает другое действие, возможно, зависящее от результатов предыду-
щего. В некоторых системах реагирования цепь обратной связи может быть весьма «неповорот-
ливой» — со значительными задержками между действием и реакцией на него, в то время как
для других приложений реагирование должно быть быстрым.
*

,  
   «   » _   , 
"    
   3              
 ,    
" ,  
    ,    
   
  . & , 
-



       
,      
 .   
    
 . *   
-  
, 

    .
,       ,    - & $        -
, — $        , 
      
 ,  
    . 3      

 
  
-
   
 
 %  -   (  
 ), —  ,  
 -
( . 
     2),      -    
  
 "  .
  
 


    
- &        

 , —  
    - 
   
    
   
      
  
 
  $   .
7
 % , 
     
 
- =    
    -
 . ; 
, 
  

-  
   
   . 4  % 
-
   
   
    -   

    , 
 -
% 
 , 
      .  
 
     
252 Глава 5


  
"   , 
 
- 

 

 
      ,
    . = 
 -      
 %
  
 
  , 
    .
   
   
   
(  ,  $    
 HTTP), & %   ,     -
      $  .  
      ,  
    
 "  
 
         

. # 
 
 
  


    , 
   
 

   

   -
  
    . *  - "       
 -
 , $     
 .    
  Skype  Google

  ,    
    - Hangout. #



 , 

-
     
    "     
     . 2 
   $ 
       " 
,     
   
    

  
 ,  

 
  


? +       
    

,
$   ,      -   -  
(  . chat servers). & $
   ? 3,  ,        % 



 , 
-
 
 «  -- »,  
 " 
      -
     
      -

. #

   

  ?   $  -      
  

 -
     
 

- "      "-
    
  . &  
      .     -
           
  
  "   + 


,   


,  - 
 
 ,  " 
"  $  , 
   . &     . * 
   
    
    -  
        -
 ,     "   ,   

, 

   -
       
   -
      
,   


   
. 3        .

Протокол TCP: сокеты и сеансы


Работа каждого открытого подключения клиента к веб-серверу обеспечивается протоколом
TCP1. Протокол TCP определяет, каким образом объекты в Интернете открывают, удерживают и за-
крывают подключение, связанное со множественными обменами сообщениями. Подключение,
установленное между двумя объектами с помощью протокола TCP, называется сокетом (socket).
Сокет можно представить как канал, соединяющий два объекта. Сокет позволяет передачу дан-
ных в обоих направлениях в течение всего времени удержания подключения. Для нормальной
работы подключения обе стороны должны поддерживать его открытым.
9 
, 

,        
%  . 4   
 
 -  

  
    
      —   
-

 " .   
  ,       ,    



     ,    - 
    
        
 
     
, 


-   .
1
TCP, Transmission Control Protocol — 
 
  
 .
Связь в режиме реального (почти) времени 253
2        
 - , 
 ,  
 "  -
     . 0   , 
-   ,   
  -
" 
   TCP,      -          .
     
  
 . & $  
     0   #  
 
 
  -
 ,   
 
     
   
 
  
-
%  
%
    
   — $  UDP 2. &  
 
     . 
 TCP      "
    , 
 UDP 
  
%   . > 
  

О «наилучшем» маршруте UDP
 
      7.
0
   

     
 -
  — 

 
    -
 
%
 
      
Сокеты TCP и веб-сокеты
   -
 ,  
 
-     3  " 

 tel-

 
,       net     -

,  

      ,        

 
   TCP,

           
    
 HTTP
  


%
.    . *       -
        -

,  ,

 
    
      - 
 ,  %   

 %   
        webSockets,        

(session). &      

, 
- HTML5. 
 webSockets ( -   )
"  ,              

 HTTP  -
(
    
)  

, -        -
     
    -     — 

,    
  ,
 

        
 
 
  , 
 
  
 
    
    
  -   
 

    
 
.
  
  
 ,    

   
 
 ,  
&


 

, 
  -
      
   , -
  $  ,       -  ,

%  
 
. & $  -  
 —      TCP.   
    

      
 
 

      -

 TCP/IP,
   -    
 
 .
 Net  Processing  


 
      Wi-Fi, 
 
      4.

#   
 TCP 
   

 
   . *

,  -
"  $ 
      —
$  
    . 
  ,

  
 
 " ,  -

 
     
. *

 


   
  % 2
UDP, User Datagram Protocol — 
 
  -

 TCP    
- 
  .
254 Глава 5

Проект 8
Управление воспроизведением видео на основе сокетов TCP
Разработка приложений для управления мультимедиа предоставляет хорошую возможность
изучить подключения, осуществляемые в режиме реального времени. Следующий проект пред-
ставляет собой сетевое видеоприложение, которым можно управлять с помощью физического
устройства (пульта). Сервером будет программа Processing, а клиентом — пульт, оснащенный
микроконтроллером, подключенным к Сети по Wi-Fi. Экраны клиента и сервера должны быть
расположены вблизи друг от друга, чтобы пользователь мог их видеть. Здесь мы используем се-
тевую связь потому, что она предоставляет гибкость в работе с множественными подключения-
ми, а не ради ее возможности подключаться к удаленным устройствам.
_  
    "  
- ,      , 
-
   $   
 :   
    "   
 
  / ,    
 
-          %   -

 
  ,   ,  ,  -    ( $     ). 4 
  
 
 
.   -  
      
%   

   
" :     ,       "  -
    
  / ,       

, %    -

 
 
,      
 " .
     

.
*    
   
  
3

     " :      $ " ,  

   
.     
1. & 

 
  .  
 
 «-   »,
2.        

     $ ,
    
  TCP.      . /    -
  

  


 
3. 
    


-
 
   . #"    -
   
 
  .
   " 
:
4.        " -
  : ? 
  

 — connect: n
2  n 
   
  
•  
      ;

;
• 

 N-   
 ?  
       — play-

  ; ing: n
•  . 2  n  1,  0 (    );
5. 2     
  ,

- ? 

     — position: n
     
 "  .
2  n 
      
0
    ,    
     
.  -

  
     
-     

 
,  -
    .    

  — ;


 
  ,     
 ?     — exit: n
TCP-  

      - 2   n=1   

 
 
  
    "  ;
"   
 ASCII.      ?  "     
      
     
 (\n).
Связь в режиме реального (почти) времени 255

Тестовый чат-сервер

  ,    

. #   $    
    .
  
     
  - 0       
 ,    %   
 ,  ,    
  " ,
      

        , 
 
  

  " . = 
  
   

 .
 

    Processing, 
"

Пишем код чат-сервера


# 

   - /*
   ,  - ƒ   
: Processing
  
   
 .
Z$ , 
  '   
&    ,   -    R -  . ƒ 
  net, 
 
      ,       .
        */
  . 0  
 -
// '    Net:
: $ 
  Server, import processing.net.*;


  
   int port = 8080; // ,  
  

     ArrayList  // ' 
     . * Server myServer = new Server(this, port); // " 
$ 
Server  ArrayList ArrayList clients = new ArrayList(); // Z   
     , 

  
 , 
    setup():

&   setup()  


- void setup() {

 : size(640, 360); //  $  
}

7  draw()    void draw() {


"        - //   $   :
Client currentClient = myServer.available();
    readMessage()
// †      ,   :
  
: if (currentClient != null ) {
readMessage(currentClient);
}
}

Массивы типа ArrayList


& $ 

        , 
  ,  , "  
 :
ArrayList. /   
 
,      .   $    
 ArrayList  
 ,        $       


 . ;       ,  
      $  , -

 
  
. & $ 
     ,       , $  

         ArrayList,      %  
 . `  Processing     $       Java. 
   
   -
    ArrayList       -   Processing  
 www.processing.org.
`  JavaScript  
        ArrayList,  ,   ,  -
   Arduino  #.
256 Глава 5

[  readMessages() - void readMessage(Client thisClient) {

    " - // Z    '   '      
//    R:
" . 0  
     String message = thisClient.readStringUntil('\n');
"  ( 

, 
, // †    ,   
 % # :

"   - if (message == null) return;
 
)     $
 // +  R   IP-   :

  " ,  println(thisClient.ip() + ": " + message);
 IP-

 . 4  if (message.contains("exit")) { // †   
// ' ,
      "  , myServer.disconnect(thisClient); // '  

"  
 "exit", clients.remove(thisClient); //   $


      //    .
    : }
}

[  serverEvent() - //    ' 


 ,
  "  ,  

 //  -     ServerEvent.
     . void serverEvent(Server myServer, Client thisClient) {
println("^
 : " + thisClient.ip()); // +
[   "    - //  R IP-  
        clients.add(thisClient); //      
 . 0   
  //  
   "  
- thisClient.write(" :" + clients.size() + "\n");
//     
  ,       }
    ArrayList:

* ,   keyRe- void keyReleased() {


leased() 
   myServer.write(key);
 

% }
     .
/        
 
  :

2  



         

  ,  -
 
      telnet (  -     telnet,   
    
%   Windows 10 telnet   
- 

,   ,      
   
     $ -  

,   
   
 ). 4  IP-
%  
,    . 
  
 -


, 192.168.1.45,  ( 



 " : playing, position
     
 8080)  -  exit.   exit:1  



         :     .
telnet 192.168.1.45 8080
; 
,  

 


,
  

    -    
     
 -

,  
      ,  " -

       .
     :
telnet localhost 8080

telnet 127.0.0.1 8080.
Связь в режиме реального (почти) времени 257

Клиент пульта управления


Клиент пульта управления видео отслеживает как локальный, так и удаленный ввод. Локальный
ввод поступает от пользователя, а удаленный — от сервера. Клиент постоянно ожидает ввод от
пользователя, а от сервера — только тогда, когда тот подключен к нему.
=          
,    
    
  " :    ,   

  
  ,   
   , -
?        -


,    /  -
  . ;         ,
       ;
 
    "   . $
 
   ,  
" 
?        

;  ,   , ""     % 
?         
-  . &      
 
        
  . $     
 ,  -
   
    

 
=  

             
 . #  $
    
  
    " : 
  
  
 , 


  
   , -
?     
  ,   $     
  .
  

;
?     
  ,  &      
   
-
 
    ;   ,  "   
?     
      -      
   
    

.     :  
   
    
  . 4    
†       "            -
  ,    "    ,   
  %  
 . = $          
    .
  . =     
-

Схема клиента пульта управления

Требуемые компоненты

Arduino-   
 

,  - 
>       , 1 %.
"      Wi-Fi, 1 %.:

9  
  220 0, 5 %.
•  MKR1000;




        , 1 %.
•  ,   Arduino Uno,
   % WiFi101; 
#  , 3–5 %. (  .      ).
•      WINC1500. 
 , 1 %.
+       : Wi-Fi, -

=  
 ($ 
)   , 1 %.

 / , X3 (UART).


  
 , 1 %. (  . 

X 
     + 
 

    ).
Wi-Fi, 1 %.
258 Глава 5

#    
   
 

       
  

 MKR1000. *    /  . 0  
  

  "         
     $ 
 
   ,   

   - Adafruit, 
 
    
-

  .     -
"  
  .

   ESP8266      $

      / , =     

  -
$,              
       
 ,  
         . /        -
     ,    -        

 -
  
      
    $   
  
  . ;    
     . &      -
           /      ,    
    -
 .         
 %   .
&     

   
   
   
,         ,   
 
       %  
 . 
  ,   
     % . =  «" »   ,  « ». &
-

  "       
       

 , 

"   360°. 
   
 

    -

" 
           (LOW) 
  
 .
   
 . /  ;       

  (

   
 
,   , 
   )       -
        , 
-   ,  
    ,
  
  
" 
.   -          
          $ 
  " 
 
. & 

  -
         (gray code).  
 

  ,  
 -


      $ 
   ,   
 
       
  
.   pinMode(pinNumber, INPUT_PULLUP).
9 $ 
 
 
  >%  
 

   
 
     . ;, $ -    /  "    -

,
        $  (GPIO)  
 " (pullup)

  ,   24     

 
,         -

. /   ,    


       
 .

 
    24     

  
     / .        -
,   
   « » -

 $ 
  
  
 -  . 
         ,
  
   —   $ 
,
-      «" »  
    $ 
 . ;    , 
     
  .
           = $     — 
 -
 /    
   
 -      
   

 

       
  .  , 
      -
/ 
  SparkFun, 
 ,
  , ""      -
 " "   
  
     . #     $ 

 ,     
 -        
.
Связь в режиме реального (почти) времени 259
*
 . 5.2       +   


    

            -            -
 ,  
 . 5.3 — 
     $     
   
    % -
. 7     
 , 
   

. 0  
    


-



      ,          
  %

 . 5.4 (  


   )  
 . 5.5 
  ,           -
( 
  
 ).  , $
      


10

15

20

25

C30

35

40

45

50

55

60
B1
B2
1

A
J

J
I

I
G H

G H
F

F
C D E

C D E
A B

A B
10

15

20

25

30

35

40

45

50

55

60
1

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

Рис. 5.3. Принципиальная схема пульта управления видео

220 Ом 220 Ом

Энкодер 3,3 В

Digital 0
220 Ом
Digital 1

Digital 2 Модуль
микроконтроллера
Digital 3
Кнопка подключения Digital 4
к серверу
Digital 5

220 Ом 220 Ом Общий

Светодиод индикации
состояния воспроизведения Светодиод индикации
подключения к серверу
260 Глава 5

        . * 
    
 . *
 . 5.6  5.7  
 ,
   
     - 
     
   
   
       

- ,  
 . 5.8 — %    
 -

      ( .


 . 5.4  5.5),  . 4        

-
          ( .
 . 5.3),  —  ,   , ,  

      
     ,
 ,  
   
   
-

   .   "   
 . #  
     % 
 %-
=     
  
    
 ,       .
   
   
 . 7  

- 0
   "  
   
 
  
    
- 
 
    73, 
 
 
 ,        . *

, % 
  .
   
 % , 
  
-

    
, 
%  - 
  
 %  
  
   $  . 
 
  
% -   
  
  
  -

  $   
    - ,        
 .   
,    
 
,  
 ! 
    
  
    -
3    
   
 , 
    

     
   
   
  - 
  
.

Рис. 5.4. Монтаж схемы пульта управления видео на перфо- Рис. 5.5. Монтаж схемы пульта управления видео на перфо-
рированной печатной плате (вид сверху). За исключением рированной печатной плате (вид снизу). Здесь хорошо видны
резисторов, все компоненты схемы подключены вставкой их соединения пайкой монтажных проводов, резисторов и гнез-
штыревых контактов в гнездовые разъемы платы, чтобы их довых разъемов на обратной стороне плат
можно было легко извлечь
B1
B2
A
C
Связь в режиме реального (почти) времени 261

Рис. 5.6. Пульт управления видео, смонтированный в корпусе из твердого картона. Высота расположения деталей схемы
рассчитана таким образом, чтобы светодиоды и ручка энкодера слегка выступали над верхней панелью корпуса. Прежде
чем приступать к изготовлению корпуса для пульта, соберите и смонтируйте его схему, чтобы знать, какого размера корпус
делать

Рис. 5.7. Cхема пульта управления видео, собранная на перфорированной печатной плате и подготовленная для упаков-
ки в корпус. Монтаж на эту плату светодиодов, энкодера и светодиодов осуществляется с помощью гнездовых разъемов.
Использование дополнительных удлиняющих разъемов намного облегчает задачу подгонки высоты компонентов под кор-
пус. Откусывайте выводы светодиодов понемногу, пока не будет достигнута требуемая высота, а затем вставьте их в разъемы.
Шестигранные стойки позволяют приподнять плату над днищем корпуса, создавая пространство для LiPo-батареи, которая
удобно подключается к специальному разъему в плате MKR1000. Для проекта необходимо использовать батарею емкостью
минимум 1000 мА
262 Глава 5

83,8 мм
8,9 мм 101,6 мм

Ø 5,2 мм
Ø 3,2 мм

34,9 мм
24,3 мм
Ø 3 мм
73 мм

Ø 8,3 мм
Ø 5 мм Ø 7 мм

33,5 мм
55,6 мм
61,2 мм
68 мм
74,9 мм
52 мм
8,9 мм

5 мм
76,2 мм
73 мм

7,6 мм 12,6 мм
Диаметр всех нижних
отверстий 3,2 мм

5,8 мм
8,9 мм

52 мм

Ø 3,2 мм
5,2 мм

Вырежьте по сплошным линиям


52 мм
Сделайте насечки и согните по пунктирным линиям
34,2 мм Линии с засечками служат только для указания размеров

Рис. 5.8. Шаблон для выкройки корпуса пульта управления видео. Заготовку можно вырезать из плотного картона,
а затем согнуть по линиям разметки и склеить. Размеры шаблона будут зависеть от вашей сборки схемы пульта, поэтому под-
гоните их по месту, как потребуется. Несмотря на то, что на рисунке все размеры выглядят рассчитанными точно, в действитель-
ности они взяты с готового корпуса
Связь в режиме реального (почти) времени 263

Код клиента для управления воспроизведением видео


&     , 
"   
-  $ 
    "  / ,
     ,      -  
   ,  
"   -
 : Encoder,

    #-  %  
  
"   .

  (Paul Stoffregen)  Button,



 - 3   Button  
 -
 7  3  (Michael Adams). /      "  / 
        
-  . 0     
    
 ,   $  
 % 
          " -
 . >  Encoder   -        : -

 
  $ 
. &   -   , "   
   
 
,            -   .

Разрабатываем псевдокод сценария клиента


  , 
"   - /*

     ,       
: Arduino
    (  $ -
*/

   )    


. 
  - // +'   -     :
  

   - // \ #  $     :
   
 


. void setup() {
// '   

// \ #  $   # %  :
&  "     // \ #  $    ' $
     
 }
  


 
    : void draw() {
// Z       
// Z    
// † '   ,
//   -    
// † $         ,
//  $    
// † $      ' ,
// '   ' 
// † $       $ ,
// '    $ 
//       
}

Пишем код сценария клиента



       // config.h
    config.h  
 - char ssid[] = "ssid"; // \  (SSID) 
 Wi-Fi
     (SSID)  
- char password[] = "s3c3r3+!"; //   -  
     
 
,   ,  $    
  Arduino    4:
264 Глава 5

&   



  // '       %  #  %

  : #include <SPI.h>
#include <WiFi101.h>
#include <Encoder.h>
#include <Button.h>
#include "config.h"

0
    
- const char serverAddress[] = "192.168.0.12"; // IP- 
  
  IP-

(IP-

,  - int port = 8080; //   
WiFiClient tcpSocket; //  

      


-

)  


,   Замените указанное здесь значение
  $ 
  на IP-адрес своего сервера
WiFiClient. / $ 
 -
      -
  TCP 

   
  :

2    $ 


Encoder myEncoder(0, 1); // ‰$     Encoder
  Encoder  Button  Button playButton(2); // ‰$     Button

 $ 
   - Button connectButton(3);
const int playLED = 4; // ^    ' 
. 0
       //  

  ,  
 const int connectLED = 5;
   ,  boolean playing = false; //     
      . * , //  $   
 
     
  long lastPosition = 0; //    $ # 
// R
         -

       

   
  -
  
  
$ 
:

&   setup()   void setup() {


Serial.begin(9600); //  #  $  
     / - //  ' $
   
  $ - pinMode(0, INPUT_PULLUP); // \ #  $   

 . 0
  - // '  R
 ,      ,  pinMode(1, INPUT_PULLUP);

  $ 
, - pinMode(connectLED, OUTPUT); // \ #  $   
// '   

 INPUT_PULLUP. ; 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);
     
,  }
 $        4:
Связь в режиме реального (почти) времени 265

О прерываниях
=          Encoder      

 

 

. 3
 

    

 

   
   "    "    
      
  
  . 4  

   %   
 
  MKR1000 -
    Wi-Fi,    ,   
:
#define ENCODER_DO_NOT_USE_ INTERRUPTS

  
    .

// '     ,   R 


//   
:
IPAddress ip = WiFi.localIP();
Serial.print("IP-: ");
Serial.println(ip);
}

[  loop()     void loop() {


       : // Z    :
readEncoder()  readButtons(), readEncoder();
readButtons();

    .
//     - - -  :

       - if (tcpSocket.connected()) { // † '   ,
 $ 
,  
 —  - if (tcpSocket.available()) { //    
. 2  

   //  ,
  

 ,  String result = tcpSocket.readString(); //   
  , 

  - Serial.print(result); //   R
// (   #-    )
 

    - }
. 
     - }
         -

 
. //     :
digitalWrite(connectLED, tcpSocket.connected());
* ,     - digitalWrite(playLED, playing);
   . #    - }
  
  
      
 , $  

      
   , 
"   -
tcpSocket.connected(), -

     1 (  ) 
0 (). 3    -

     
  
    
,  -
 
  playing, -

   
     1
(  )  0 ():
266 Глава 5

[  readEncoder() - void readEncoder() {


        myEn- long position = myEncoder.read(); // Z  R
coder.read(), 
 
"- long difference = position - lastPosition; //  
   

  - //  
$ # 

 $ 
.   if (difference != 0) { //  $ #  $  
     
"  - if (tcpSocket.connected()) { //   ',
tcpSocket.print("position:"); //  '
 $ 
    
 ,
tcpSocket.println(difference); //  $ 
 
  — 
. #
-
}
   "   -
lastPosition = position; //  $   

   
 , , 
 // 
$ #
      }


, 
 
   }


. 2  
    "
  $ 
   -
" 
 :

&    readBut- void readButtons() {


tons() 

     if (connectButton.toggled()) { // †   
  Connect ,    - // '  $  ,
  ,    ,  if (connectButton.read() == LOW) { //  ,
 ,    . 4  - if (!tcpSocket.connected()) { //   '
,     
 - //   ,

,      . 4  connectToServer(); // '   


 , 
    } else { //   '   ,
exit:1, 

 . tcpSocket.println("exit:1"); // ' 
}
&   

,   - }
      - } // # % # connectButton.toggled
  (   connectBut-
ton.toggled()
  true),  
 " 
     $
   (connectButton.
read() == LOW),    -
    , 
        . 4 


,     
,        -
      ,   
:

& 
     if (playButton.toggled()) { // †   
readButtons() 

   - //  $  $  ,
    
   Play. if (playButton.read() == LOW) { //  ,
;  ,      - playing = !playing; // $  $   

 ,  $   



  // playing   
    ,   if (tcpSocket.connected()) { //  '
  . 4      - //   ,
 ,       
 - tcpSocket.print("playing:"); //  '
     
   tcpSocket.println(playing); //  $ 
playing  
  , , }
  

, - }
} // # % # playButton.toggled

  "    " 
} // # % #    readButtons()
   $ 
  :
Связь в режиме реального (почти) времени 267

* , 
    - void connectToServer() {
 connectToServer(), 
 Serial.println("   ' ...");
//   '     $  :
      
    - if (tcpSocket.connect(serverAddress, port)) {
 readButtons(). /   Serial.println(" '  ");
  
      - } else {
 .connect()   Serial.println("^  ' ");
WiFiClient,     }
     
 - }

. / 
"   —
     


      
  
,      -
    . #
 -
,    
  
      -
   
  
 
 
:

2
  $    
 

,   % <Enter>, $    
         

 
     
 
 Arduino.
Processing -

, 
   4   
 ,    ,   -

 . 0
     
 
,  
    
   .
      " .
    
 

   - 0


  "  , -

       , 
   $ 
    -

   
 

 - ,   
   

    

. *   

,    
    .
 
    
   $ - X % ,  

 
 $

,       Processing  -  ,   
  
  -
    " . 4    
-    
 

  
-

   Processing    -      .

Аппаратные прерывания
G    
   

 Uno,    
  

  (0  1), 


       "    - 
    
   2  3
"    
         . *  Arduino 101  

-

     . & 

  -        
   -
     Encoder   
- . 3   MKR1000  

  -
 

   $    
 . >    0, 1, 4, 5, 6, 7, 8, 9, A1  A2. [ 

   
  
  

- digitalPinToInterrupt(
) 

-
        Arduino  
 www.    

    


-
arduino.cc/en/Reference/AttachInterrupt. &
   . *

,   Arduino Uno  

 
   
 
  - digitalPinToInterrupt(3) 
"    -
  
  

  . ;, 
 -  1. * $  
    Arduino

ATmega328,  
     Arduino 101,    $    
  .
268 Глава 5

Доработка видеосервера
0     

    +   "   :
  -

    ,  - ?   movieEvent()—     , -
 

    
  "         
 ;
         
-
  
   
     . ?   scrub() —      
-
      .
   

   
 
  "      ,   -

, >  video   
    
$,    

,     ,          3.
    
 "   Processing 0     
 %
 
      " . 
  
, 

 Processing
-
$ 
       " -   
    
 H.264.
     : 9       
 
    -
   %

 — 
?  
 —  -
640×480  . 4        
    
 

 ;   
  ,     
   

,      -
?   setup() —     . &    
   
   
  

             data.
 ;
?   draw() —    -

  
       
  ;
?   serverEvent() —     ;
?   readMessage() —   -

«-   »   
  -
"        "
  .

Добавляем в скетч код для работы с видео


&      - /*
  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() - void setup() {


      size(), size(640, 360);

    

myVideo = new Movie(this, "movie.mov"); // ‰ 

// #
 Š
 Movie:
    
    . myServer = new Server(this, port); //   
&   
 
   scrub(0.0); // $

   

size() 
  %
    - }
 (  )  ,  
 -
   $ 
 movie
        .
0
     scrub(),

  "   

 
   
  ,
     :

&   draw()  void draw() {



   
  //   $   :
Client currentClient = myServer.available();
      
  .
// †      ,   :
2 ,   $    
- if (currentClient != null ) {
 «   »    3, 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); //    

}

=     - void movieEvent(Movie myVideo) {


: movieEvent()  scrub(). myVideo.read();
[  movieEvent()   - }
void scrub(float newPosition) {
    
 
myVideo.loop(); //  

  
  . & myVideo.jump(newPosition); // $

   

      — $     // 
  .read()   vi- if (!playing) myVideo.pause(); // * !   
deo     
. // 


,  


}

[  scrub()    



  
  
 . *     -
    .loop() 
 
      %
  "  

   "
  .jump(). 4   

    
  
 ,     .pause():
270 Глава 5

* ,      void readMessage(Client thisClient) {


readMessage(), 
   // Z    '   '   
//       R:
" "   ,
String message = thisClient.readStringUntil('\n');
  ,    // †    ,   
 % # :

 %
. * if (message == null) return;
     

  - // +  R   IP-   :
       -
- println(thisClient.ip() + "\t" + message);

, 
    : if
(message.contains("exit")):


  , "  - message = message.trim(); // `




 
 trim()     
 String[] decodedMsg = split(message, ":"); // K


// 

 

  « 
»: %   String property = decodedMsg[0]; // $
  — 
,  
   - int value = int(decodedMsg[1]); //   —  


 
. /  -
       


  
. * 
  
    

     ( 

,


Arduino printlin() -
     
 -
 \r\n — 
 
 
 
    ),
     % 

-
  
  
 
-
  .
2  "  
split()
   
 
      -

: 
  
 — $
   " ,  -

 —     :

+    
 
   // * 


 
!  

,
     ,    // 

 


   

if (property.equals("playing")) {

    

 (
-
playing = boolean(value); // $
 
 



if),  

  - //  

  "   . if (playing) { // *  ,
myVideo.loop(); //  





#  playing ( 
 - } else { //    

myVideo.pause(); //  






  )       -


}
   
    : }
#"   position // * 


   (position),


      - //


  
:
      
  - if (property.equals("position")) {
  "  
  . float frames = value * 0.033;
Связь в режиме реального (почти) времени 271

=      


 float videoTime = myVideo.time() + frames;
scrub(videoTime); // $

  

 
      0,033 - // ()
  : }

3   exit ( )   // * 




  

(exit),
// 

:
 

  -
if (property.equals("exit") && value == 1) {
: myServer.disconnect(thisClient); // N


clients.remove(thisClient); //  

  
// 
.
}
&     
   - // 9 







 

"       //   
  # :

  ,      - lastMessage = thisClient.ip() + ": " + message;
   draw() - }

   $
 :

#  
   $     

      
      ,   -

.  ,        "  -
2        ,         . *    
    "   - $ , "   
%   
-
 
   
  telnet,    -         
  
   $. *  
     "   

       . / 
-
     
  
       
%,   


 . *
 . 5.9  



-      %
 "   
-

 — 
  
  ,       ,       . 

"    . $          -
      

  
 " .  
 ,    
  
  .

Использование Raspberry Pi для управления видео


&    
       $ 
-     1. #    
 Processing
 
  
 
  - Raspberry Pi    
  
 
-
. =   

     Raspberry    
 ,       
.
Pi  
   

.   2   
  
 
   

    HDMI- 
   - Raspberry Pi "    Programming,

        Processing. &
         processing  -
Raspberry Pi 2  3 
  $  -    
 .
  .  
  HDMI  
Raspberry Pi  
   
,  
  &
 Processing  Raspberry Pi  
  -
USB — 
   %. 2         , 
  
  

 ,
 
 
   
  .  
   video,   
 $    
.   
-
'     


   
 Processing  Raspberry Pi  
Processing,     
  
    
: https://github.com/processing/pro-
   
,        cessing/wiki/Raspberry-Pi.
  
 
 Processing 
 -
272 Глава 5

Рис. 5.9. Снимок экрана воспроизведения видео серве-


ром Processing. В нижнем левом углу изображения мож-
но видеть IP-адрес клиента и его последнее сообщение

Проект 9
Управление воспроизведением видео на основе протокола
WebSocket
При работе скетча видеосервера из предыдущего проекта вы, наверное, заметили некоторую
задержку между моментом воздействия на элементы управления пульта и моментом, когда в
Processing начиналось воспроизведение видео. Объясняется это тем, что для воспроизведения
видео требуются значительные вычислительные ресурсы. Так что было бы предпочтительней от-
делить серверную часть скетча, которая обрабатывает сетевые транзакции, от части, которая ра-
ботает с видео, чтобы серверу не приходилось выполнять объемные вычисления. Здесь мы это
и сделаем, создав веб-сервер в node.js — вместо сервера Processing, и веб-страницу — вместо
клиента дисплея на Processing. Клиент пульта будет управлять видео на клиенте дисплея, а сер-
вер станет управлять сетевым обменом. Постоянное подключение между клиентами и сервером
будет поддерживаться с помощью веб-сокетов (webSockets).
&     
 :     HTTP      
% -
 HTTP-

,  $      -     
,   
 4? &           - 
     
 ,   -

 ,  ? &      -  

  "   

 ,    ,  ,  
 

   . &
   -
  
    "        TCP   
 
  
     
  HTTP     


  

  
  . * 
  ,  . $ 
 webSocket   -
 
 HTTP  
 
 -   
 
  , 
"

 
  ,    $     
 

    
 
    
 
        

.

  
  —  % 
 

,       *
 . 5.10 
   -    

 

    
  
- 
 . #

  
 
  
  .   —     
 ,
      . 4  
  

  
 HTTP    -  
,     
   

    
 
     
"    
-

  
 
%            .
 webSocket. /
 %
 
-
Связь в режиме реального (почти) времени 273
0 
  -     ,          
-
     TCP-  . #    
 

      .
 
 
 HTTP,   - *

 ,      %-
 
   " :
  " ,   
,
Upgrade: websocket
    
 webSocket. =
Connection: Upgrade\r\n %  
 "   -
Sec-WebSocket-Key:  webSocket, 

 

dGhlIHNhbXBsZSBub25jZQ== 

    . &  " 

Sec-WebSocket-Version: 13  -    
  HTML5     
2 Upgrade  Connection  

  JavaScript,         -


 ,      
  -   
  HTML. ; "  

 ,    
 Sec-WebSocket-Key    

   webSocket
        

,  node.js. &    ,  $ 
   -
 
 Sec-WebSocket-Version  

          —  
 
 
 webSocket,    ws. >   Arduino, 
  -
 . 0 

      -    ,      webSocket
  " :   ArduinoHttpClient, 
   -
  
 "  
  .
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade О взаимодействии библиотек webSocket
Sec-WebSocket-Accept: 7    webSocket
 
-
s3pPLMBiTxaQ9kYGzzhZRbK+x0o=
     
   -

 
Sec-WebSocket-Accept   
   , 
     
  
   
   

   , %
   -
    


 . *   -

  
 
 webSocket,  -
 $     ws  node.js -
    

  
 

. 
  % 
   
Arduino  HTML5. 4      -
Рис. 5.10. Блок-схема видеосервера на веб-сокетах. Сервер %        , 
 
предоставляет видеостраницу HTML и видеоресурс для брау-  
  ,     
 -
зера посредством HTTP, затем посредством заголовка HTTP   
     .
Upgrade подключает веб-сокеты клиентов пульта управле-
ния и дисплея. Этот сервер может одновременно поддержи-
вать несколько клиентов обоих типов Устройство
видеоклиента
Устройство
Программа видеоклиента
Веб-клиент
клиента
webSocket Веб-клиент

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

Программа клиента Серверная программа


Веб-клиент
webSocket на node.js

HTTP GET/ HTTP GET Устройство


1 1
Микроконтроллер Upgrade: websocket Веб-сервер index.html видеоклиента

position: n 2
HTTP GET
2 playing: n /movie.mov
exit: n
3
HTTP GET/
Upgrade: websocket
274 Глава 5

Сервер и клиент браузера


Серверы webSocket создаются поверх серверов HTTP, поэтому нашим начальным сервером для
этого проекта станет HTTP-сервер на основе библиотеки express node.js (вспомните сервер, с ко-
торым мы работали в главе 4). А клиент браузера будет страницей HTML, отображающей и управ-
ляющей видео с помощью библиотеки p5.js языка JavaScript.

Пишем код сервера на node.js


*    
- /*

,    $ - Z webSocket   express
  express.js. #
    : node.js
*/
 
     
   wsExpressServer.js, // '    :
a        var express = require('express'); //    express
express,   $  
 : var http = require("http"); //    http

$ npm install express var server = express(); // c express


var httpServer = http.createServer(server); //  http
#    , 

-
   $

,  //    %
  $ -   /public:
    public server.use('/',express.static('public'));
 
 ,    -


    4,   
//   :
httpServer.listen(8080); //   '  http
 $  .

>  webSocket  -


    $ 
  -
 http node.js, $ 


  $ $ 



express,        
   :

~

   ,      ,
  
,       .
*    - 
 , 
   

 . '  $  - 
 ,
    
 p5.js.

Промежуточное программное обеспечение


[  express.static() 
     

     ,  "   -
. /   
    
 HTTP,    
      

  —   http.get()  http.post(). &   "    
 
   
   

     . [  .use() 

   -

 , 
    
 
 
, 
 
   0,    


 
.
Связь в режиме реального (почти) времени 275

Добавление интерактивных элементов с помощью p5.js


&   1  
    
- 4     
     

 JavaScript p5.js, "     - p5.manager,   
  p5.js     

   - 
    ,  -     
  " 
:
"  Processing. ; 
   % 
-
$ p5 g -b public
 
 ,   $ 
. # 
  
  ,   2  
   public    -
public  
       
    p5.js      
 :
  

 p5.js. = 
  

-
    , 
     $ p5 update
 : &   "   
     -
public/     

: 
  node.js, -
index.html " 

,  public, 
-
sketch.js " 
  p5.js. #     
libraries/ node.js  p5.js 
     -
p5js     .
p5.dom.js
p5.sound.js

Пишем код

 
 
   
- <!DOCTYPE html>

  index.html  - <html>
 %  
  p5.js,  <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(); // + $  
}
276 Глава 5

#
         2  
  

     
-
public, 

  
 .  
  " 
:
http://localhost:8080
; 
    %

 

-
   
 
. 2  &  

      
  -


    
:   .
$ node wsExpressServer.js

Добавление функциональности webSocket


; 
,    
 HTTP-

?  
       — play-
 HTTP- ,    
  - ing: n
         2  n  1,  0 (    );
webSocket. =  

  -
? 

     — position: n
   
  
   -  

 . 5.10     "    2  n 
      

" ,    -   


     
.  -

 
 1  2, —   %

-     

 
,  -

  — ;
  
  
  index.html  -

   . 
% 

 ?     — exit: n
 
  3. # %  
- 2   n=1   

 
%  $  —
    ;


       webSocket, ?  "     

        
 -  
 (\n).


. * $
,   

,    


    JavaScript, "  -
  
  $
 - 
   
 JSON,    

   ,   



  
 "  JavaScript       
 . /  -

 . + "        -  ,  "      
-
" 
: ,    —   ,  

? 
  

 — connect: n «-   »
   . 2 
 

  $ 
 
   
2  n 
   
  
   
      -


;
 JSON.parse()  JSON.stringify().

Пишем код для webSocket


&   


    %
). >  ws    
-
  ws   $ 
(  
         
:
      
 $ npm install ws

*   
  - /*
Z webSocket   express


    
: node.js

 ,  $  
  */
  . 
 
 , var express = require('express'); // '   
server,    $ 
 // express
Связь в режиме реального (почти) времени 277

express.js, 

 - var http = require("http"); // '    http
  

   - var WebSocketServer = require('ws').Server; //  Server
// 
 ws
   . &
 
 , var server = express(); //  express
httpServer,     
- var httpServer = http.createServer(server); //  http

, 

  
- var wss = new WebSocketServer({ server: httpServer }); // 


 HTTP. + 
 
 , // websocket
wss,     , 

-
  
 webSocket:
&   
 
 
 //   :
     
 - httpServer.listen(8080); //   '  http
    

wss.on('connection', connectClient); // N!


// webSocket:
HTTP. ; 
  


webSocket 
 %  -
     "
  webSocket:

=  

 

express  
-   webSocket     "
          : 
 "  , 
 -
public,        newCli-     
 %.   $ -
ent()  
 "     
   
  
webSocket. /   
       ,   
 %   

 %    , 
       
   connect-
 . 
      
- Client(). ; 
      
%    
     
   : readMessage(), readError()
$  .  disconnect().

&     connect- // serve static files from /public:


server.use('/',express.static('public'));
Client() 
   

 
   - function connectClient(newClient) {
// 7    
 
 

webSocket:
: 
   "  function readMessage(data) {

    
  . //  

 #    

+   

 .size, }
 .length      , // if there's a webSocket error:
   wss.clients  - function readError(error){
console.log(error);
    set. & JavaScript }
$   set    -
// $  

 
 webSocket:
 ,   $    function disconnect() {
    . &   console.log('Client ' + newClient.clientName + ' ');
ws   
    $ - }
  set,  "  wss. // 9


  
clients: newClient.on('message', readMessage);
newClient.on('error', readError);
newClient.on('close', disconnect);

// 7  

 
   
,
// 



:
var greeting = {"
": wss.clients.size};
newClient.send(JSON.stringify(greeting));
}
278 Глава 5

+ 
   
  // 7    
 
 

webSocket:
    readMessage() function readMessage(data) {
var result = JSON.parse(data); //   
 
  ,   // 
 JSON

   " " - if (result.hasOwnProperty('clientName')) { //


 ,    
%,  // clientName,
  . 2  «%- newClient.clientName = result.clientName; // 

//
  
» 
   $  ,
}

  
 , $ . if (result.hasOwnProperty('playing') || //


//  playing,
 " "  - result.hasOwnProperty('position')) { //  

   playing  po- broadcast(newClient, result); // 




sition,    
   //  




  ,    - }
 


   if (result.exit === 1) { //
 

exit,
console.log("
 " + result.clientName + " 
");
  . [  broadcast()
newClient.close(); //  
webSocket
 $ 
  
 - }
   . 4  " console.log(result); //    #   


"  
   }
exit,    

 
1,  
   
webSocket  $  :

[  broadcast()  - // $




 




     connectCli- // 
 webSocket:
function broadcast(thisClient, data) {
ent(). 0  

  
function sendToAll(client) {
     web- if (client !== thisClient) {
Socket —   
 console.log('‹

 


:' +
$ "  . 4  ,  client.clientName);
    %
 "   client.send(JSON.stringify(data));
}
"  . =    
}
sendToAll()    $ - //   
  sendToAll()  ! #


      //  wss.clients:
  wss.clients 
 - wss.clients.forEach(sendToAll);
    .forEach(): }

#

webSocket    
%   " "      
    

 Processing    readMessage()   Processing,
  % . &-
 ,

webSocket           
-

            
     . *   -
clients,   

 Processing,  %      
  
 
  
     -   ,   

 Processing -
 ArrayList. &-
, $

,  ,   
   , 

.
 
   " "  
  —  
  

     +,      , 
    
  
   
-


  
 webSockets.
  .   -   
- 

 ,        ws,
Связь в режиме реального (почти) времени 279
     
   $  
 
        
    . *   
- 
  -  . =   
  
 
     - 
  ,    $  
       .
 
 sketch.js  $ 
  "

Модифицируем сценарий sketch.js


&   
   - /*
     Video client

   
  - context: p5.js
*/
      ,
      " - var myVideo; //    
, 
  -

   - var socket; // 
-

"  " . & 
  var lastMessage; // $






 


message     client var host = document.location.host; // Œ
 


   browser, 

var message = {"client": "browser"}; // 9
! 
,
// 




 ,     
   . ~  $ 
 


      -

,       -
      :

&   setup()   function setup() {


     HTML  myVideo = createVideo("movie.mov"); // \ #  $  
// R$  " Movie:
  
  div,   myVideo.size(640, 360); //  $  
 $   createDiv(). //  $ 
& $
   
- myVideo.position(10, 30); //    
  "  

. myVideo.loop(); // + $    # 
2      - lastMessage = createDiv(''); // 9

 div 
//   

 webSocket 
  

. lastMessage.position(10, 10); // %

 !


; 
      socket = new WebSocket('ws://' + host); // $

 
 %    : //  


  —      %  socket.onopen = sendIntro; // $
 

// 


  ,  
 — 
socket.onmessage = readMessage; // $

  "  : // 
 

}

   


 ,  function sendIntro() {
      // $
 
Š
 
  
//  

:
draw(),     $
socket.send(JSON.stringify(message));
 
 
     }
 ,    web-
Socket. [  sendIntro()

     "  
-
  

 
 

  :
280 Глава 5

[  readMessage() - function readMessage(event) {


        // ~


 

:
 
. 0    " var msg = event.data; // 9 

  
// onmessage
" , 

    var videoTime = myVideo.time(); // $

 
   JSON,    "  //  

  
   : play- var message = JSON.parse(msg); // $
 

ing  position. 
  // 



 Š
 JSON
$        // * 


 
!  

,
  
   
 - // 

 


   

    ,   ,  $ if (message.playing) {


    readMessage() myVideo.loop();


 Processing. &   } else {
myVideo.pause();
  readMessage()   -
}
"  

  -
  
   "     - // * 


   position,

 : //


  
:
var value = parseFloat(message.position);
#
  
 if (!isNaN(value)) { // * # 
 

,
var frames = value * 0.033; // 1   . 
 
 
   sketch.js,
//    30   
 


 , 

 " videoTime += frames; // 



 



 ,  

 
- // 


  

. &   

 myVideo.time(videoTime); // ` 
 

 
  
  }
 
  "  
-
// 9 







 

   

 (
 . 5.11). //   
  # :
3   

   - lastMessage.html(JSON.stringify(message));

      }
   
 " 
{ client: 'browser' }. ; 

  
    
   
 .

Рис. 5.11. Кадр видео в окне браузера


Связь в режиме реального (почти) времени 281

Клиент пульта управления WebSocket


Клиент пульта управления для этого проекта физически такой же, как и клиент пульта управле-
ния предыдущего проекта. Для него можно использовать ту же схему, изменив при этом только
программу микроконтроллера. Единственное различие между этим клиентом микроконтролле-
ра и предыдущим состоит в том, что вместо подключений сокетов TCP этот клиент должен от-
крывать подключения webSocket. Для этого мы воспользуемся библиотекой ArduinoHttpClient,
опыт работы с которой у нас уже имеется. Эта библиотека содержит класс webSocket, благодаря
которому задача открытия подключения не представляет никаких сложностей.

Пишем код клиента пульта управления


*      - /*
   Arduino  
 -   webSocket      
"  
 . & 
  - : Arduino    WINC1500
*/
      % 
       #include <SPI.h>
    Ardui- #include <WiFi101.h>
noHttpClient. ;    - #include <ArduinoHttpClient.h>
  
      #include <Encoder.h>
Замените указанное здесь значение
    #include <Button.h> на IP-адрес своего сервера
  $ 
 webSocket #include "config.h"
(     
   
 %
). const char serverAddress[] = "192.168.0.12"; // IP-
// 
>%    
- int port = 8080; //   
WiFiClient tcpSocket; //  
    
   -
  . [  setup() // 
#
 webSockt
" 
    - WebSocketClient webSocket = WebSocketClient(tcpSocket,
 : serverAddress, port);

[  loop()    - void loop() {


  
 " 
  . readEncoder();
7 
     TCP-   readButtons();
 webSocket,      // $ 

-
, !


:
        . [  if (webSocket.connected()) {
int msgLength = webSocket.parseMessage(); // $

parseMessage()   webSock-
//   

et     
  "  if (msgLength > 0) { // if it's > 0,
"   
"   - String message = webSocket.readString(); // 

    . X %   // 


  , "  - Serial.println(message); //  


  #
  "    }
    Stream  }
read()  readString(). //     :
digitalWrite(connectLED, webSocket.connected());
;  

- digitalWrite(playLED, playing);

      


- }
      
-
    
connectLED,    -
      web-
Socket,  TCP-  :
282 Глава 5

&   readEncoder() void readEncoder() {


     :  - long position = myEncoder.read(); // Z  R
 

   - long difference = position - lastPosition; //  
    TCP, 

- //  
$ # 

if (difference != 0) { //  $ #  $  ,


     -
if (webSocket.connected()) { //  

-

 . 
   - sendJsonMessage("position", difference);
        // 


JSON
sendJsonMessage()  
- }

   
 " - lastPosition = position; //  $ 
  webSocket. #   //  

$ #
sendJsonMessage() 
  - }
   : }

+     read- void readButtons() {


Buttons()    if (connectButton.toggled()) { // †  
//  '  $  ,
   readEncoder(). 
 if (connectButton.read() == LOW) { //  ,
     
  if (!webSocket.connected()) { // 

connectButton   

 // 
 


     TCP- - connectToServer(); // '   
} else { //   '  
      

  - sendJsonMessage("exit", 1); // 

     -  , }
 
      }
      connectTo- } // # % # connectButton.toggled
Server(). 3 
  -
if (playButton.toggled()) { // †   
  
 

 //  $  $  ,
"  exit,   - if (playButton.read() == LOW) { //  ,
  . playing = !playing; // $  $ 
//  
playing   

        if (webSocket.connected()) { //
 

//  

,
 
   

   - sendJsonMessage("playing", playing);
     -  , // 



 
    - }

  "      }
} // # % # playButton.toggled()
 
  : } // # % #    readButtons()

[  connectToServer() void connectToServer() {


      

 Serial.println("   ' ...");
    ,   
 " boolean error = webSocket.begin(); // $ 

//  

. * 
   -
if (error) {
   webSocket.begin()
Serial.println("‡
  ");

"     1, $ } else {
    , 
  Serial.println("$ ");
 
 "  . / sendJsonMessage("", 0); // N
  


    
  //  
  



    "  }

     . = }
$      
sendJsonMessage(),
  

      :
Связь в режиме реального (почти) времени 283

4      // 9


   "- 

" 

 JSON
 $ 
    — //  :
sendJsonMessage(). 0  
- void sendJsonMessage(String key, int val) {

  "  JSON  - webSocket.beginMessage(TYPE_TEXT); //  
: text



. 
 
 webSocket.print("{\"clientName\":\"MKR1000\"");
"   webSocket - if (key != "") { //

 , 
   
    " , webSocket.print(",\""); //    
//  
   $  
webSocket.print(key); // 
webSocket.beginMessage() .
webSocket.print("\":"); //    

  $   - //  


     "  —  - webSocket.print(val); //  




    
 }
webSocket (   
 - webSocket.print("}");
  : text, binary, ping webSocket.endMessage();
 
.). 2   
   }
     "


 print()  println().
* ,   webSocket.
endMessage() 
  -

  
  
" :

2
 
   - / 
  

 
  -
 
 

  
            -
 
 
. 2 

   -   
        
 
        . 
   

 (
 . 5.12). 0 
&   

   
  
 $     
 
"  :    
      -

   
  . *  
,
{ clientName: 'MKR1000' }     " 
   

#   
    -    ,    
   

 ,     
 
   -
  $   .

  "  
   :
{"client":1}

4    

 -
 , 

  
$ 
    
 
     —  -

      

 .

Рис. 5.12. Один клиент пульта управ-


ления может одновременно управлять
несколькими клиентами браузера
284 Глава 5

Заключение
Базовую структуру клиентов и сервера из проектов этой главы можно использовать всегда, ког-
да вы хотите создать систему, которая управляет одновременными подключениями нескольких
сетевых объектов. Основные задачи сервера состоят в ожидании подключения новых клиентов,
отслеживании уже подключенных клиентов, а также в обеспечении передачи сообщений без
ошибок соответствующим клиентам. Из них первостепенной задачей сервера должно быть ожи-
дание попыток подключения клиентов.



         2  
 
 
  
    "  

,   
     -

 
 " 
       - 
 

    
  .
    

   - & 
  
   -
      .     

     "
       


    TCP,   
    $-
            -   (webSockets). 
 
   .  
       , 
 —   , 

— 
 
-
 
     

,     TCP-  . # 

   
 
% ,    - 
 ,       -  
           
%     " -
   ,      , " 
  HTTP,   -
         -   -

    .
" . 0   
 
 ,  $
,   — 

, "   $   
 
 

-
client  exit,    
  -    

    
-
   $ 
  . #"       
 

    
-
  
  ,  
   ,   (    HTTP    4)   

. 9 
 
    - 
  (     $  ). 
 
  
, 
 " %
  $  
  ,      -



 ,   ,   -  
   
 

  -
   $ 
  
 JSON.   . &  "  
    + 
 
 


  
  .
Связь в режиме реального (почти) времени 285

Исходный эскиз музы-


кального ящика Джин-Йо
Мока

Композиторский интерфейс музыкального ящика


Глава 6

БЕСПРОВОДНАЯ СВЯЗЬ
Полагаю, что вас, как и многих людей, интересует эта область, и вы
приобрели мою книгу, потому что мечтаете создать устройства,
взаимодействующие друг с другом по беспроводной связи.
Возможно, вам так не терпелось разобраться с этим вопросом, что
вы «перепрыгнули» через весь предыдущий материал прямо сюда.
Если вы действительно это сделали, возвратитесь к началу
и прочитайте все, что пропустили! В предыдущих главах мы
познакомились с такими распространенными видами
беспроводной связи, как Wi-Fi и Bluetooth, но, что более важно,
в них мы также рассмотрели некоторые принципы цифрового
взаимодействия, на которых основана беспроводная связь.
В частности, если вы не знакомы с последовательным обменом
данными между компьютерами и микроконтроллерами, вам надо
обязательно изучить материал главы 2. А в этой главе беспроводная
связь рассматривается более подробно — в ней мы встретимся еще
с двумя типами беспроводной связи, а также создадим несколько
работающих проектов.

«Зиготы» Алекса Байма (www.tangibleinteraction.com)


«2 » — $   % %
,  
" -

 
  ZigBee. 
      
  -
,   
         
     
  .
0    %
,     ,  
-
       ,      ,  

 
   % $
  . 0 
   G
Z  (Alex Beim).
288 Глава 6

Компоненты для проектов этой главы


Коды поставщиков
? 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) —   
 ,   " %    
 /
 

   $

 .

4
Беспроводная связь 289

ПРОЕКТ 10. Инфракрасное управление цифровой фотокамерой



"
     , 1 +. = $ 
(
 
 220 , 1 +.

     
    -
D: 220QBK-ND, J: 690700, F: 9339299, R: 707-
 Arduino . & 
  
 

7612
    MKR1000  Arduino 101, 
 Arduino Uno   
   
 . 
(
 
 10 , 1 +.

•MKR1000 — AF: 3156, RS: 124-0657, A: D: 10KQBK-ND, J: 691104, F: 9339060, R: 707-


ABX00004, GBX00011 (3
  4#), D: 7745
1659-1005-ND 

 &.
• Arduino 101 — D: 1660-1003-ND, J: 2239331, SS: 109990013, SF: TOL-11702, AF: 468
SF: DEV-13787, AF: 3033, F: 2520713, RS: 
-  
 
   
 -
913-9999, SS: 114990575, A: ABX00005,  (  .      ).
GBX00005 (3
  4#)
• Arduino Uno — D: 1050-1024-ND, J: 
-&  
 , 1 +.
2151486, SF: DEV-11021, A: A000099, AF: 50, D: 365-1068-ND, RS: 654-8542
F 1848687, RS: 715-4081, SS: ARD132D2P 
C      , 1 +.

 &    
, 1 +.
D: 438-1045-ND, J: 20723  20601, SF: PRT-
J: 106526, A: 387, SF: COM-09469, F: 1716710, 12615  PRT-12002, F: 4692810, AF: 64, SS:
RS: 577-538, SS: MTR102A2B 319030002  319030001

  , 1 +. 
     > .
D: GH1344-ND  SW400-ND, J: 2231822  
]=
  =

    -
119011, SF: COM-09337, F: 1634684, RS: 718-     
 

  -
2213 
.    
 " 
 .

ПРОЕКТ 11. Дуплексная радиосвязь


C      , 2–3 +. 
(

HopeRF RFM95W

Semtech
SX1276, 2–3 +.
D: 438-1045-ND, J: 20723  20601, SF: PRT-
12615  PRT-12002, F: 4692810, AF: 64, SS: AF: 3072, SS: 113060006
319030002  319030001   , 2–3 +.

"
     , 1 +. = $
D: GH1344-ND  SW400-ND, J: 2231822 

     
    -
119011, SF: COM-09337, F: 1634684, RS: 718-
 Arduino .
2213
• MKR1000 — AF: 3156, RS: 124-0657, A: 
(
 
 220 , 2–3 +.
ABX00004, GBX00011 (3
  4#), D:
1659-1005-ND D: 220QBK-ND, J: 690700, F: 9337792, RS: 707-
7612
• Arduino 101 — D: 1660-1003-ND, J: 2239331,
SF: DEV-13787, AF: 3033, F: 2520713, RS: 
D
, 2–3 +.
913-9999, SS: 114990575, A: ABX00005, D: 160-1144-ND  160-1665-ND, J: 34761 
GBX00005 (3
  4#) 94511, F: 1855510, RS: 228-5972  826-830, SF:
• Arduino Uno — D: 1050-1024-ND, J: COM-09592  COM-09590
2151486, SF: DEV-11021, A: A000099, AF: 50, 
     > .
F 1848687, RS: 715-4081, SS: ARD132D2P

]=
  =

    -
    
 

  -

.    
 " 
 .
290 Глава 6

ПРОЕКТ 12. Управление фотокамерой с помощью Bluetooth LE



 Arduino 101    - 
C      , 1 +.
 Arduino     
D: 438-1045-ND, J: 20723  20601, SF: PRT-
Bluetooth LE  nRF8001  nRF51822 -
12615  PRT-12002, F: 4692810, AF: 64, SS:
 Nordic Semiconductor, 1 %.
319030002  319030001
MKR1000 — AF: 3156, RS: 124-0657, A:
• 
 &    
, 1 +.
ABX00004, GBX00011 (3
  4#), D:
1659-1005-ND J: 106526, A: 387, SF: COM-09469, F: 1716710,
RS: 577-538, SS: MTR102A2B
• Arduino 101 — D: 1660-1003-ND, J: 2239331,
SF: DEV-13787, AF: 3033, F: 2520713, RS: 
(
 
 220 , 1 +.
913-9999, SS: 114990575, A: ABX00005, D: 220QBK-ND, J: 690700, F: 9337792, RS: 707-
GBX00005 (3
  4#) 7612
• Arduino Uno — D: 1050-1024-ND, J: 
 +   > ,  &

,
2151486, SF: DEV-11021, A: A000099, AF: 50,  $  
 Bluetooth LE, 1 +.
F 1848687, RS: 715-4081, SS: ARD132D2P 7   
 ,         

N  Bluetooth LE (Bluetooth 4.0), 1 +.   ,  "
 Bluetooth LE.
4      ,  "   %  
 
AF: 1697
  ,   $  
-
&   
     "   .
  RedBear BLE Nano " 
  USB- MK20. 
]=
  =

    -
    
 

  -
MS: MKRBL5, SF: WRL-14071

.    
 " 
 .

Почему не вся связь беспроводная?


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

? C   


   ? C    ,  
,
 A ,   . +    =    
  
=  -
 
  ,  
 
  =  . # , 
 
    

   
-   

   
 ,
 . [  
   -  
   
  
 ,

  $
 
, 
    "   "    
   

      -   . +  $   , 

    , —       
"  
   

         ,          
-
$  
 
, -   
 . *

,  
 
   
  %     , Bluetooth, %   
  Wi-Fi
          (  
 802.11b, g  n)  ZigBee (  -
(   " ) "   
 802.15.4) — 
   
    .        2,4 qq
Беспроводная связь 291
(
  
 802.11n 
     
  -
 5 qq). +  
 
 -   
 
 . 0   

 ,        
 
 ,  -

 
 %   ,   - "   
,   
%    
  ZigBee   
 
 

,  ,

       ,  , -    ,        


,      Wi-Fi, -  
  $ 
  . $,  
       
.

 
   
  ,
      
    
? C     
>    
 ,   

$
$ . #
  
        $ 
 ,  
    
,   
 .       
   

 "   "    
-       
.
    ,    -
 
    
 
   - ? N     
 -
 %  
   
 
> †  
 

.

  
   ,   *   ,    -
 $  . #
      
 
   
 
     
  $ 
   $
,
 -

   $ ,   $   
  
 
    
  
   

 . /   $
, 

  %
 , ,    ,

  % "  
 
     ,   
   
  %    + 
.
   

      + 
      

 % ,   
 . 
, 
 
  -
 $ 
   $
  -
? C        -    
 
  
 

. X 
   
-   ,     
    
 $ 
  %       
-
 ,   
 . 3       ,   $  -
    «
 »,  
-  ?
     
. >
  -
   
 ,     ? D    >  
>.
  
  . 0 
 
 9 
   $ 
-
 
  
       -   

 
 
 -

 %, 
  
      
 ,   
%    - 
 .  
   
 " ,  
   

 $    $ 
   
  
«   %
 ». #    . $, 
    "
  , 
 
   
      -

 
      - 
  ,     -

  $ 
$
 
   
       
    
,  $      
   
-
    %   
     .
    . 4    

    
 
 
  $    ,   
-
         %,
292 Глава 6

Два типа беспроводной связи: инфракрасная и радио


Большинству людей в своей жизни и работе приходится сталкиваться с двумя видами беспро-
водной связи: посредством инфракрасного излучения и посредством радиоволн. С точки зрения
пользователя или разработчика, основная разница между ними состоит в их направленности и
радиусе действия.

     


     -        .   

       

  .   ,   
   

  
&  
 ,  

        
 , $
     
  
  
    « »   
-

  , 
    -   . X 
   
 
 
   
 
    
  
 
 , -
 
   $  . +   -        
  
 


    
,   -        
-

    
   
  ,  . = 
     
 -
  
    

 
-
Рис. 6.2. Сигнал от инфракрасного светодиода распростра-
. & %        
няется в виде направленного луча (слева), а сигнал радио-   
  . +  ,
-
антенны — во всех направлениях (справа)  
     
. 

$,      "   

      
  ,
 
 -
       %

 ,    

 . #   ,
 

      
    
  %
     

 
      
 -
, 
  —    
   .
9    
   

 
   
 
  -
 
 . 6.2.

Передатчики, приемники и приемопередатчики


  

 , 
     -       
,
 
 "   
 :   

,   $          

  ,   
 -   ,  
  . =   
-
 ,


, 

  -    %    
 
-
,    , 
  - 
    
  %, 
  
-
 

, 
    ,  
 .  "  
,  
  
7    
 ,   
   . ;
, 

, 
    
  
 
,     
    
. /
  $     
 ?          
 .
    
 
 
 ,     
    
  ;   ,     

 
 -
    . & 
 
 , 
-   "       
 
-

,    ,  
   ,     
 


Беспроводная связь 293
 
   
      - 
 
. 2   —  
 
. *

,   
   %  
   
  ,  
Bluetooth  Wi-Fi      .        
 ? =  -
0 
  
  
    
 

 ,     -

  
 ,  ,     . #   
   


 
 , 
 
-
  
,   
 
  -
 %  ,     " 
 
-  "  ? 7  
% $ 
 -
. , 
 "     
,   
   ? 
      

  
   
   

 - $ 
  ,  ,      
-
  
   ,     $
 -      

-
  
   
 
  -
  
  $     .

Принцип работы инфракрасной связи


X 
   

  
,  ,  
   % $
. &
 ,

       

   -  
, 
 
    
    

     %  ,  $
$    -

        $ -   , 

  "   -
    

   . 

  
. ;   ,  
-
/         ,  
   
     

  "    



 - $   $
$  
 
       $ 
 -   
      
-
.   "     
 
-    
 , "    

      

     
  
  .
(   ,       ,
       . .),   - 
 
     

 
 
    

       
  % -
         -   
    $ 
   
   . = $, 
   - 
 
 . '
 %

          - ,     "  , 
"  ,      

 

 "  . >%  
-
   
     . #     

   
  
 
$ 

  ,    #
    "   38 
, 
        40 q. '  "  
  
     . 
   
- 
  
    , $ -
    

    ,  -
  
     

  

    ,        -       —  
,  500 
 "  . 2  
    2000    . = 
 %
   "   ,        $    ,  
   . ; 
   
       
-

   

       -     
  
  . & -
    %       
-   
      ,

     
   . 

 
  $  
 ,
 
  

    
*
    

     8- 
  . &    , 
-

 
 ,     %  ,  
- 
, 
 Control-S   Sony  
294 Глава 6


 
 : 12-, 15-  20- . 3 %-  . 3  
 EPanorama (www.epan-

         - orama.net/links/irremote.html)      -


  
  
 RC5           
 
 
-
Philips    14- 
.  
  

  .

4      

      - 4      
,  
  , 
  
 ,  + 
     %    
 —   

%  , 
"  
 %  

, 
 
  

  
  

  . + - 
        -


  

  - "  

  ,  
  ,
  
   

-  
  "     -
$ 
   ,  SparkFun, Adafruit,
     . *    
-
Seeed Studio  
.   SparkFun    
  "  

Adafruit  

   
-      .

Как увидеть инфракрасный свет?


'          

   
      

 ,  $ 
  
 
  - 
,     
 $    
    . '   ,  % -      . * 

 "-
"  

  
 , — -    
   

  
, $-

   
  -
. 4    , 
   


  

 

 ,  -
 $  . *
 . 6.3 -    -
 ,  

 
  

       -  -
         

 -
 
 , 
 
  
  -
,  ,    $    

   
   
: -     

   , — 

,
—     ,  —  . # -      
 .
"   

     

Рис. 6.3. Вид инфракрасного светодиода через веб-камеру: слева — светодиод выключен, справа — включен
Беспроводная связь 295

Проект 10
Инфракрасное управление цифровой фотокамерой
В этом проекте мы будем управлять цифровой фотокамерой с помощью инфракрасного свето-
диода и микроконтроллера. Этот простой проект позволит вам получить общее представление
о работе инфракрасных устройств дистанционного управления.

>%       


  Чтение ИК-сигнала

  (SLR2) 
  

    "  

  . =      

  


  
        
   
 -

   


 ,    
    
 . +
              
 $  
% 
-
 :   
. & + 
 -  
    
 DSO Nano.
     
%
 ,
 - ;        
 "         
  Logic 4   Saleae (www.sale-
     
  
 - ae.com), 
 
   
 
. &  $ 
   
   ,    
 Nano. 0 


 ,      
- DSO Nano,   
    
 . =     
 -  
 ,     
   
    Adafruit  
     

  
 -

 https://learn.adafruit.com/ir-sensor       $
 (
 . 6.4). 3  -
   MulitCameraIR,

   
   Logic 4 -
#    2   (Sebastian Setz). ~ $   
,        
    
  
     ,    
  



 Arduino,   
  $
 
.
 
   
 
 
 -
 
. =     

   
  
       " 
& %  
        - $
 
  
,  
  «  »


       
-
   
  
Canon RC-3
Рис. 6.4. Отображение начальной части ИК-сигнала пульта
 Nikon ML-L3. ; ,     - дистанционного управления камеры Nikon на экране осцил-

 
 Nikon  Canon,  
 - лографа DSO Nano
   
 %
   

 ,   $ 
%  
 
 . *    
 
,
  " 
  
  

-
     
 %
  
-

    "  

    
.

2
SLR, Single Lens Reflex —     
 

.
296 Глава 6

(" )    


  
 
 
    . ;
 
    
 .    -    "    "  

 
    ,  
  %  
 .  
   


   
   
,  Canon
     32,7 q,   

    
%
 ( $  , Nikon —    38 q. '   -
%  
   
  %     
     
.
 
). >%   
 & . 6.1        -
  
   
 -    
     

  ,  
  
 
 
Canon  Nikon. /      

            $ 
 
  
 . X  
  

  -
 
,   
-
    ,      ,     .      
  
 , 

   %   
     ,
  

    .            -
" 
   . /  
 
&          
-   ,  
      
              
 .

Таблица 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 %.
/ .

9  
  220 0, 1 %.

+ 

 
  
, 1 %.

9  
  10 0, 1 %.

+ 

      
 -
 
 , 1 %. 
>         %  
-
, 1 %.

0 
, 1 %.
Беспроводная связь 297

A B C D E F G H I J
1 1

5 5
3,3 В

10 10
Модуль
микроконтроллера
Кнопка
15 15

Цифровой вывод 7
20 20
Цифровой вывод 4

25 25

220 Ом
Общий
30
A B C D E F G H I J
30
10 кОм

Рис. 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); //  \- 

 
    - //     
    : }
298 Глава 6

&   loop()    void loop() {


     
   // Z      '

:
buttonState = digitalRead(pushButtonPin);
 
 ". 4   -
   ,    - if (buttonState != lastButtonState) { // †  
   
,    //  $  ,
$   shutterClick(), if (buttonState == HIGH) { //  

  
   - shutterClick(CAM_NIKON); //  \- 
//   $
 . = 
Canon  
}

  $   - }

 
 CAM_CANON. 2  - // Z-        '  :

    "     - lastButtonState = buttonState;
   " 
 : }

[  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 (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   
}
}
}
Беспроводная связь 299

'  

  - //  \-  $
      
  :
      
void IRPulse(unsigned long interval, unsigned long
  ,  shutterClick() frequency) {
      IRPulse(). unsigned long now = micros(); //      
/   "  
- //   -
   Arduino tone() tone(IRPin, frequency); //    IRPin
//   $

     
 
- while (micros() - now < interval);//    

   +-  - //    $  
   "   , noTone(IRPin); // '  

     % }
        

    
 -
 ,        .
  tone()   
 
  

 
  delayMicroseconds(),
$ $    -
     
   :

Рис. 6.6. Это устройство создано с использованием только что описанного подхода. Микроконтроллер Arduino в корпусе,
стоящем рядом с камерой, улавливает изменение показаний пассивного инфракрасного датчика А и посылает камере инфра-
красный сигнал с командой сделать снимок

А
300 Глава 6

Принцип работы радио


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

9   ,  
   
 ; 
,      

  ,    "    ,    , 



, 915 7q,  
 :
     
  ,    , 
    
     . 1/915 × 106 × 3,0×108 × 0,95/2 = 0,1557382 
'           -

  ,   %    
 - + 
   15,6 .  
    
  
  .   , 
  
  , -
0 
 
  
 "   
 
 
    -
 "    
    
-  . > 
   
  $

   . 3        
            
-

 ,  
 
 
- 
   
     
 % ,   
 . * 
  
 
 . =      
    
,     

 
    
  

      .  

       
%   .
  
        
 , $
 
 $ 
 
  
    . *   Аналоговая и цифровая

     
   
 радиопередача

    :
     
    
 
-
€   
= 5,616 '
 /  
,    
    
 &š# = 14,26606  /   &š#  

 . &  
-
  
   
   
/ 
  
  «American $ 
    ( 

,   )
Radio Relay League Handbook»3 1929  -       "
 4.
       
    - /
  
 
 "  ,
. &    $ 
   
       -
 
  
    - . & 

   "  -
 . /     ,  
      
   , $

 
 
 
    
    
    
  -

    5%  ,     ,     " 
  
 
 
  
   . =   -  
  
 
  $ -
     , 
    ,  
  . +  ,  
  


 
 
       3,0×108 / .
4
*       "    -
3
#
  
 

  .     .
Беспроводная связь 301

 ,  , 


   -  $     [
 . 9 " 
  , 

 " 
    
     % 
  
   , 
   —
 . /       -

   
  . ,      
   -
. &   

-
 .
Радиопомехи
~   , 
     & $ 
   
     -
 
  $  ,    
-   $  
  $ 
-
 ,
  
  
-    . _ 
 "  
-
 , "    ,  -   
    


    . ;, %  -
  ,   $ 
 ,
    
  , " " $ 
   
    
 
 , 
   "      
 . &      % -

  . /      -     , 
   

    
 
 
    ,   
   
  , — 

    



    
    
  

$
 . 4 

 
 ,   
  ,     
-
   ,  
   
  -        .
     . /  
-
  $
 
  . Z  $
 
  9 Wi-Fi
      
-
   " 
    
     , 
     
          - 
    
!,    
  
 
  . /
  $     
 
 -
       %    
       .
 . 7    , 
   7
     
 
 
       ,    " 

  $   


  . >
" $-   "  , 
    
     
  $
 
"  -  
       " , ,
      , 
     -   
,     
 .

. &     

 0
  ,   ,   
-

      
     $
   
    
 -
 " , 
 
   $
-   ,      
   

        . ; $
  -
   
     .
   " $    
 0  —     7  0   
   
 
[
 , 

  
  

   $ 
     
-
  
 . 
. 
 
 $  
  
    . = $   -
+ 
    
  -   (

)
 "    ,  

 
 $
 . 4     - 
— 
 %. 
 
-
   
  
  
 -    $ 
   
 %
, 

 ,     
   

       , 
 
-
 
 -      
       , -

  % "  
 
.  ,  
   
 , 
-
*          
  " . 3  , 
 
"  -
 
 ,             
    
302 Глава 6

$ 


  %   $ - + 
 ,       

  . ; 
, $ 
      , $ ,   
   

    
. ;    
  "
 


, 
 -     %        
-



      
" -    
 . +  ,   
-
. ; $     -  
 
       
 -
  
  
   
 . 9 
    
    -

 .  



 
  
 
 
 — 
    
  
#"     
    - (     
 ). 
 $ -

        -  
 
     
-
     %
 
 
    
   
.
  
  . $ 



 
         9     $   ,     , -
   
 . 2  
 -     
    
.

 
    
   - 3 
     
  
 
 "         
-   
   "  

  
   
  
 
-    
%,  
 
 
.   
    % 
 ,  

  (
  
 
   


% 
  ,       1: -
Мультиплексирование %  % ,   
 ). +  ,
и протоколы   
 
 
  

 
       
-          -
  ,      "  ,     
 
  , 

  . #  
    
 - %   () "   
 
, $,   

  

     .
   
  
 , / " 
    
 
-
   
 
  . & $  -     "  
   (
-
  %  
 :      
 
 )    -

      ,  
 -        
 .
, 
  . & 
-
  $, 
 
     * 
   %  . 4   -
     
,     
  "  
  
   $ 
      
  ,   
 
 
   
    . #
- 
"       . & 
 
-
  
  . /     $     

 


       -  !
   (     -
   ,       -  ). /   ,  
     
. 4      ,      
  
   


 ,       -
   . +     
 
-

 ,   
  - "  
 , 
       -
"   
     
-  

  
  ,  

   
              $  .
 

. +  ,    
   
   
 &     

  
-
.   
   
  
Беспроводная связь 303
    . *  %  - *
 
     
 
-
   $   
  ,   
 
  . # 
-

%         
- 

 
  
 
 . 
         
-
  
  
 

. &   -
7  
      $-    ,       
   
 ,    
 
, 
   
  ,
 
 
    ,      
   ,   
  ,

    
 
.        
 . ; 
 -
/ 
     
 . 
   ,   
-
;    ,     
   ,     
   
   

 
  
  
  . 4  
   
    -
 
. 
 
   - ,  "      . 3   -
    
   
 .  
    
     
*

, Bluetooth, ZigBee  Wi-Fi — $  "   
 
 -
   
  
     ,
"       -
 ,  

  . .   , 
      
& $ 
 
        

 
     
    
   
 
 ,   
    
 (  
   
 Wi-Fi —       . * 
$    
  Ethernet). 0         .
$ 
      
-
 
   ,   
- &  " 
 %  
 
-

    
    ,  

   
-
   
 
. 0    , 
        .
      
      *

,   Bluetooth  
    -
   
 ,        2  

    
  
 

     
   
  Bluetooth,   ,     
. 3
 
      — 

 %. 9 
 , 


    
   %  
      " 
 ,  

    
 . 0    -       
 . =
 
     " 
 . 
       % 
-
       
,   
     
 %  -
Радио: передатчики, приемники %   .
и приемопередатчики
 

  
  ,
- # %
      
-
%,  
 , 
 
-
    
   
   
 
-
  
 
 
? 
"  -      ,    
  ,     
 , 
  
        
. /
    
, 
   
  ,   ,  
%,  " -
   
 
 
. & -     -  
   
 -
%        . > ,      ,     " -

,    
  (, -       
  
  .
   , 

 ) 
 
-
 
   , 

-

    
  
 
 .
304 Глава 6

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

Топологии радиосетей
9 
     3    
     
 . 

  
  
 . = 
 -  
  
      ,  

     
   
   
   
 -
   ! ! !      
    . ;   
. & 
                 
-
   "    
  . &
 ,
" 
-
 $  (
 . 6.7,  ),   
 —  ,   %
 "  .

%
 "      -
       
   (
 . 6.7, X      ( .
 . 6.7,  )
 ). &
 ,    
  
-   "   
. 0  
 ,  
   
    -   
 %
 "  

  
%
 "  
 
  
    
   
(
 . 6.7,  ). ,   ,       
-
        % .
#  
   
     %-        
 

 "  . X $    -  


  Bluetooth.
   
,     " 

Рис. 6.7. Три типа топологии радиосетей: полносвязная (слева), звездообразная (в центре) и ячеистая (справа). В первом типе
все узлы соединены друг с другом напрямую, во втором — обмен между периферийными узлами реализуется через один цен-
тральный узел, а в третьем — сообщения могут передаваться от одного узла другому через цепочки промежуточных узлов

Прямое соединение узлов сети Топология «Звезда» Ячеистая топология


Беспроводная связь 305
&
    
   ( .        
-

 . 6.7,  )    
   
 -   
 . 
     $
     
 
  
    
        

     
%
 "     
 ,        
,      
 . /  

" . 3
 ,     

     
   
         
 (

 Wi-Fi,  

  
   "  ),   "   -

  
%

(

).  
   . 
 $    
 -
   
    " 
&      ( .
 . 6.7,
         -
 ) 
              

%
 "   
  —  .
     "  , 
 
-
   ,  
   % . * 3  
       -
 
 "       ,  
, 
 

 , -
                 % ,
  
 
, $      -   
       
       
%

"     
 
  
   
  , 
 
"    
  . # Bluetooth, -

 
%

. 
   - 
        2, 
-

    


  ,   "   
  ,      -
$        
  -         
  -
 . 7
%

"           
 
  
.
 
  "   
 , X 
   
   Wi-Fi 
-
      
              ,   
,    

  
 $  
 UDP,      

%

  -
 
. 
  ,    $  
 TCP.
$  %   $

  
- =  


   
 
"  
 " ,        
  .
       
 ,  
     
    "  . 9         
(  ,   TCP    ,
`        
   -    UDP),  
    -
 
   ,   

 -      $

 . 3 

      .      ( "  )    
4    
,   %    $
$  ,  
 $   -
     %    . * 
    "  -
      ,   
 
  
  " 
%       
   - 
          
 .  %     .     -

  
  
  " 
 
 
 
  "  ,
Сеансы и сообщения 
"  
      ,
#     
     -    
 " ,    
,
   
   ( ) — -   
 "  
  -

 
 
  
 "  . 
    " .

 $    
      
-
306 Глава 6

Стеки протоколов беспроводной связи


;       

  #  
   
 
-

  


     -  .*    ,
 " 
 
 
 . / 


       
 , $
-
           - "     
 
 
 (    
,
 -  
 
   
 
, 

    4),     
         


   —    
   
 $  . #  
-

   
  "         %   
 
  , 
  
  
 - 
. *

,  
 
  
-
  
     
     : Wi-Fi, Bluetooth  ZigBee —  -
   . 
 
 -  
  
     

  "         
. & $ 
  
  , $ 
  , 
   IEEE 802,  

 
  
 "    -     Ethernet. #  Ethernet 
-
  
 

     ,      
 802.3, Wi-Fi —  

    

  . / 802.15.1,  ZigBee —  
 802.15.4. 0 
     , 
   
-
  
 "     -
     
   
-      
  


   
  
     -  . *   
  Wi-Fi  Bluetooth
 ,    
 
  
 
   
 
,  
   8.   $    

 
" -
  $   " .

Физические радиоинтерфейсы
Z

 
  
  -  
 , 
    
 
-

  
 

 
-        
.
 
       - 9 
       -
    
      , 
 
 , 
     ,

    
 :   
   
      
 ,
     X3, SPI  I2C     ,    
  


 
 , 
    
- " 
 
  .
 
 

,  USB 
-

Выбор и приобретение радиоустройств


В настоящее время доступно много разнообразных протоколов цифровой радиосвязи для раз-
ных промышленных, бытовых и прочих приложений, и каждый год появляются все новые про-
токолы. Все эти протоколы предназначены для выполнения разных задач и имеют различные
ограничения. Поэтому, прежде чем приступать к работе над каким-либо проектом с использо-
ванием радиосвязи, следует внимательно рассмотреть доступные варианты. Далее отмечаются
несколько моментов, которые следует принять во внимание при выборе радиоустройства для
своих проектов.
Беспроводная связь 307

  
   
   =       $ 
 -

%     . +  -
  . *

,
 
 
 $     , 
 ZigBee
 XBee   802.15.4 -
  
           Digi   
-
 . *    
  
  
 ZigBee 


   


  
       ,       -
      

  
 Wi-Fi  Bluetooth. /
  Digi 
      
-
         %
 
 - . /    
 ,  
            -         

       
  ( ,
 
    Digi. 0  
 %  , 
 ), 

   
 - 
  ,  
  
  Wi-Fi
 (
 
,  %, 
,  -  Bluetooth  %
 
  ,
  . .)  + 
. &   
          .
         —  
   
  $ 
-
   "    — 
-    %     -
     

  ZigBee.        
 ,
3 
 ANT  "   
  $  
  Bluetooth  
Nordic  Texas Instruments   

 
   
-
     
  Bluetooth
 — 

,    
   - %     %   -

      


 

 
,     
 . =  " ,
 
 . =  % 
- 

 , 

 
    "   
   
   
,    
-

    
 
  LoRa.  %     -
  .
~         
- 0   %
%  
 
    % 
,  -        — $ -
    
 , 
  $ 
 
    
 

  
 , 
  
     .      
-
     
  . 4  ,   -    
  
  
   
 
  % 
 — 
%     .

. 3  % 


"   " &      

   

 
  
  ,   - 
 ,   
   -
     

   %        ,  $ 
     
 .  
  . ;     

    
 
 -
,   , 

  
? \



 & 
    
    
   ,
 
 
   -
  %  
 
 

  
 

. 
  


 
  "  , 
 - « »,      %  
 
    %  
-   
%  ,      
 

:        
 - $       
   

, SPI  I2C. ;   , 
- 
 
. 4   
 
 
 
 
   -
 
  ,    , -

 
   
            
 
 . 

 . 3    
 
 
 
 , 
-
? \ 
   
. >     ,    ,   %

 
    
   
 
   -


 
  
?  .
308 Глава 6

? (
 

†    
 ,     
  
     
   
  .    . 7  ,  
* 
      
 $ 
 
 ,  
" ?  $

 
- 
    
 , 
 
 ,
 
    $ . =      -


 ? #   %       
   
  
     
  
      

,  
$
      
 -  
     -
? X  ,  ,  
 
    .
"   
   -
  ,      - ? ˆ ,     ,      -

       ,  - 
,     
  
 %    %
% . +   
  -

,      .     ,  "  -

   % 
 
 ,
? 
  ,    
  $ 
 . 


 ,  
        ,
      
  
  
  $         
 
 , 

 
 . *

,    
   .
 %  
    
  
 
 
 ,    & . 6.2 
      

-
  
    Wi-Fi -    

-
    
  %  
. =  
 , 
     
 

-
  
 
%  
 
 . &       -
       ,  ,
 
         
 
  
 
-
  ,

"  %
 "  
 . 

 $
 
  

 
3   
  %       .   % 


 
        -   $  ,
 
  XBee

   
      Digi   % 
-
 
 
%      -   
        ,
    
  .   - 
       
-
. *     
     
? 

    
  
 
   
. = 
 ,     
   -

  
     - 
   + 
,  
  
"  

     
  
  
  Wi-Fi  Bluetooth. 0 
    ( "  ),  ,   
  Bluetooth 
   

        ,   
,   Wi-Fi,    ,
"   
     Bluetooth SIG5 
  
 
 .        
  
? D    
, 
   
- 
 
,     Wi-Fi Alliance6 
 , ,   ,    
- .
  ,       

 
 . &    
-   HopeRF      
-
   
    
  .  
 , 
  
 
0  
 
 
  
  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 _ (TCP  UDP)
*   " 
Digi Xbee 802.15.4,    ,
2,4 qq X3 (   
 
802.15.4 [
   
  X3)
HopeRF 433, 868,
[
     SPI *   " 
RFM69 915 7q
HopeRF 433, 868,
LoRa     SPI *   " 
RFM95W 915 7q
Nordic 51822 Bluetooth LE 2,4 qq     SPI *   " 
Cambridge
Silicon Bluetooth LE 2,4 qq     USB *   " 
CSR8510

 "- *    
RF Link TTL Serial 434 7q X3
   (   X3)


   %  ,  $
- 
  
 
  "   -

   %
   . +
-  
 
  
 
-
 
 ,    
 LoRa, . 

   
    -
   

   
-  
 

Curie   Intel 
 LoRa Alliance7,   "  -  
 
  Bluetooth  

,  $ 
 
     - Nordic Semiconductor,  "    
  

,   
 
   Arduino 101. 3 
   ESP8266,  -

   

.
   
 , 
  
-
 Wi-Fi. X   $,  
  SparkFun  Seeed Studio 
      
      
-
  
 

-
    
  
,  $ 

 
  
    
 -  
 
 , 
  
 X3. * $
 
  
  -    " % 
 

.
 
    
   

   
 
 &  "  
  
 
 -
    
 , 
    -   
     
 -
      ,   
 

,
  
 
 -
  

 
 . =     
 LoRa,     
%    "  
   
. 
 

, 
    -
7

     
 , 
  -
LoRa Alliance (3  LoRa) — 
 -

   ,  " 

   
  Bluetooth LE.
LoRa- 
          .
310 Глава 6

Проект 11
Дуплексная радиосвязь
В этом проекте мы подключим радиоприемопередатчик и кнопку к микроконтроллеру. Для соз-
дания канала связи потребуются два таких устройства. Каждый микроконтроллер при нажатии
его кнопки будет посылать сигнал другому. Когда один из микроконтроллеров получает сообще-
ние, он реагирует на это событие, зажигая светодиод, а также отправляет сообщение по каналу
последовательной связи.

 Bluetooth  Wi-Fi      - 0   %  
    
,       -      
, 
  -
" "       
 - 
 
     

,      ,   
    " 
 #   .
   
 
-
 
 - #" ,  
  



, 
   "  
 -  
      %
 " -
 
%

  
. /   
,  
   .
 
%  
 
  - /     
  

 
       -      .
. 

 
 
  -
  
  $
- 


 
  LoRa  -

  ,       HopeRF     
, 
 

 Semtech. & $ 
     - LoRa       
 
! 

(sync
" %     . word), 
 
    
" , 
   $ .
9 
 
 RFM9x  
HopeRF 
 SX127x   Semtech  - &    
 , 
-


 LoRa. /
  -  
   " ,   
  
, 
    
-    
. [

 
  
 
   %
      ,   " 
 
 -
"  
   $

-    
     -
  . 0       %
-  ,    %
 
 .
 
   !   , *

,      
  
    
      -       125 q,  
 
      ,  -  
   — 915 7q. [

  $      


 
   
  ,   % -

 . 

    "  
 
 
    -
    ( "  ), $      125 q  
   

         - 915 7q. [

 
    $
-
 ,          -  
       6  12,   -
 
.      7. >   


 
        
 -

 LoRa  
         

  
, $ 

, 
    .          -
/ 
 
       -  

 
  .
     
 
 

. 0       

 
 LoRa      LoRaWAN.
Беспроводная связь 311

Схема организации дуплексной радиосвязи



  (SCK)   
   (CS),
Требуемые компоненты       
  (RST)

Arduino-   
 

, 2–3 %.
 
     
  

 
+      : 
 (IRQ  G0), 
  
    
/ ,  
 SPI.  

 
 

  
 . 0
    ,    

-

>       , 2–3 %.
 
 (G0)      

9 HopeRF RFM95W D1  MKR1000 ( .
 . 6.10  6.11),  
 Semtech SX1276, 2–3 %.   D2,    Arduino Uno  Arduino

 , 2–3 %. 101 ( .
 . 6.8  6.9),    $ 

#  , 2–3 %. 
 

   
 
 .

9  
  220 0, 2–3 %.
'  
% 
   ,
-
* 
 ,   , 
-         . 
"
   
 

. 3 ,    $ 
%,  
 

   
 
 ,  -             
 $ 
 
   -
 
 (ANT). [
   -
  ,       -    
        -
   "   . & $ 

  !. «4

 
» $  .
   
 
  - &    ,       915 7q

  RFM95W LoRa Radio Transceiver         7,8 . /    -
Breakout   Adafruit. *  $ 
- 
   , $      -
  
  % Dragino         


-
LoRa  Arduino,   Wireless SX1276   (       
  Modtronix 
 - ,         
 Seeed Studio. /
 
   -      —     ). 7 
      : 868–915 7q   $
   


 433 7q. 
    -     . 
   —  -

    915 7q,  -     
  — 
%   -

     
  . X 
  
 
 $
 
   
  
 

 -     
. &  $ 
 -

   
  SPI, $  
-   
  " ,   
  
-
   
       -     ,    

"   
 

 (
 . 6.8–6.11).   30–50  
  
 



     MOSI, MISO, 
   
  .

Полосы радиочастот ISM


& ,   ,  %
 
  7  
   $ 
     

  
      .
  
  
 . = 
 
/         - LoRa     "  :
  ISM,      
 
 % ,
      
  8. =
- 
4
: 863–870 7q  433 7q
     $  
  
- 
#3: 902–928 7q

% . =   ISM     
3 
: 915–928 7q
8
ISM — Industrial, Science, Medical. 
 : 779–787 7q  470–510 7q
312 Глава 6

A B C D E F G H I J
1 1

Антенна
5 5

10 10

VIN G1
GND G2
15 EN G3 15
G0 G4
SCK G5
MISO
MOSI

20 CS 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 Модуль
7,8 см
D11 MOSI RFM95W

CS
Микроконтроллерный модуль
Arduino 101 или Arduino Uno RST ANT
D7
Общий
D6
D5
D4
D3
D2

220 Ом
Общий
Беспроводная связь 313

Антенна

G1
G2
G3
G4
G5

RFM95 Radio
10

15

20

25

30

SCK 35

40

45

50

55

60
1

MISO
MOSI
GND

RST
VIN
J

J
G0
EN

CS
I

I
G H

G H
F

F
C D E

C D E
A B

A B
10

15

20

25

30

35

40

45

50

55

60
1

Рис. 6.10. Монтажная схема подключения адаптерной платы c радиомодулем RFM95W к плате MKR1000. Обратите внимание
на подключение антенны, длина которой должна быть около 7,8 см для частотного диапазона 915 МГц и 16,5 см для 433 МГц. Обе
антенны четвертьволновые

Рис. 6.11. Принципиальная схема подключения адаптерной платы


c радиомодулем RFM95W к плате MKR1000 +3,3 В

+3,3 В
Напряжение
G0 питания
Напряжение
питания SCK
MISO Модуль
D10 MOSI RFM95W 7,8 см

D9 CS
D8 RST ANT
Микроконтроллерный
D7
модуль Общий
MKR1000 D6
D5
D4
D3
D2
D1
220 Ом
Общий
314 Глава 6

Код для проекта дуплексной радиосвязи


=
 %
 
  -   LoRa,  
      -
   
   
   LoRa by Sandeep Mistry  -
Arduino. *          -      . =     -
  Stream —   ,  "   - 
 
 $    
  
   , 
   , 
 
   

 

 , — $    
 https://github.com/sandeepmistry/
LoRa. =    $   
 - arduino-LoRa.
    
  ,    


Пишем код
   ,     - /*
      Š  $ LoRa

        - : Arduino

   
 

. */
2  
  
 


  (   irqPin) #include <SPI.h> // ''    :
 
,     - #include <LoRa.h>
%  
 

. *

const int buttonPin = 4;
  

  
-
const int receiveLED = 5;

 
     5 const int csPin = 7; // + -    LoRa
( .  ! «G  const int resetPin = 6; // Z   LoRa
  
»). &    ,  const int irqPin = 1; //   
Arduino Uno  101 $   2,
    
 

int lastButtonState = HIGH; // \-   
Cortex-M0   ARM ( byte msgCount = 0; //  - - 

MKR1000) —   1. byte localAddress = 0xBB; // ˆ  



byte destination = 0xFF; // ˆ  

= 
   
  byte syncWord = 0xB4; // Z - $  '  (   )

        - byte spreadingFactor = 8; // %   (6-12);

 

 
 . + -
  
 
 
      :

&   setup()  - void setup() {



       , Serial.begin(9600); // \ #  $    ' $
 

    
- LoRa.setPins(csPin, resetPin, irqPin); // %    
//  CS,  IRQ
 
    
- if (!LoRa.begin(915E6)) { // \ #  $  
  
   //   
     $ 915 &š#
915 7q. 0   91543 Serial.println("^     #  $# '
    
   - LoRa.    .");
while (true); // †  #  $#   
   $      }



  #. 2  $ LoRa.setSyncWord(syncWord);
   915×103. 2    LoRa.setSpreadingFactor(spreadingFactor);
  
   
LoRa.setTimeout(10); //  $  10  

 
   
 
 - // 
-  Stream
Serial.println("\ #  $#  LoRa .");
. * ,    
- //     :

   
 - pinMode(buttonPin, INPUT_PULLUP);


,  
   pinMode(receiveLED, OUTPUT);
    : }
Беспроводная связь 315

[  loop()     void loop() {


        - int buttonState = digitalRead(buttonPin);// Z 
. 4        
- //   
  
 "   ,   if (buttonState != lastButtonState) { // † $  ,
   
 , $ - delay(3); //  ,   - $ 

 ,     if (buttonState == LOW) { //   $

//   ,
   . 0
  - String message = "HeLoRa!"; //   
  ,   $    - sendMessage(message);
    
 - Serial.println(message); // +  R  
"
 
. 2
  - //  
 

     
- }

 
      lastButtonState = buttonState; // Z-  
 
  
    // 
        - }
       . 4 
    , - // +    $ % # ' onReceive:
  "  ,    onReceive(LoRa.parsePacket());
$   sendMessage(), }

   
   -
   . 2  
  
      
 
lastButtonState 
 
  "   .
&         -
   onReceive(), -

 
       
 . /     -
" "     
 $
 . *   
  
    "
  LoRa.parsePacket(),

      
Stream, 
   -
     4. /  
    
 
-
     " -
 . 7      
   7  
 " -
 UDP:

[  sendMessage() -


      
, 
    
 " .
&    ,    -
,  "  
  -
  (destination — 1  ),

 
  (localAd-
dress — 1  ),    -
  "  (msgCount —
1  ),  "  (out-
going.length — 1  ),  
316 Глава 6

    "  . void sendMessage(String outgoing) {


2   
 
     LoRa.beginPacket(); // ^  
"  . ~ $ 
  « - LoRa.write(destination); // Š   
  » 
,    LoRa.write(localAddress); // Š   
 $  , 
   - LoRa.write(msgCount); //  
 
//  
   
    
LoRa.write(outgoing.length()); //  $ 

 . &   on- //    
Receive(), 
 
    LoRa.print(outgoing); //     
 ,  ,   - LoRa.endPacket(); // $  
" 
 " : //  
msgCount++; // M   $    

* , 
    - void onReceive(int packetSize) {
 onReceive(). 
   - if (packetSize == 0) return; // †  ,
   ,   " // $    # 
"  " , 




 . 4  $    digitalWrite(receiveLED, HIGH); // +'  
//       

  0, 

"   % // Z  
 $ :
      
- int recipient = LoRa.read(); //   
"        loop(). byte sender = LoRa.read(); //   
4   "  ,  - byte incomingMsgId = LoRa.read(); //  % 
   $,   . // -  
2         byte msgLength = LoRa.read(); //   -
:  , 
- //  
 ,  
"  String incoming = LoRa.readString();//    
"  (
 

" ),   "  ,


 ,  "  :
2  
      if (msgLength != incoming.length()) { // 
  "    . //      
4    , 

- Serial.println(" :      . ");
"         - return; //   
 % #
 "   % . - }
   
 

 , // †   R 
   
,
if (recipient != localAddress && recipient != 0xFF) {
    
 
Serial.println("‰     .");

 $
 
 
return; //   
 % #
  $ %
 "  }

. 4  
 
     ,  
, 
-

"      
 
"     :

=    $
  $ - // †    R 
 
  " . 
 $  -  ,
,       - //   :
,   LoRa 
- Serial.print(" : ");
    
    Serial.println(sender, HEX);
Serial.print("  : ");
$  :  

  
-
Serial.println(recipient, HEX);
      % 
Serial.print("ID  : ");
 /%.
Беспроводная связь 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, -  $ 
 
. 0
  -

     
 
     -       
 
 ,
 
    ( CoolTerm       
 
  


    
 
          $  
 
     
)  
  -     .

Широковещательные сообщения  
. /    ,  

-
 
    onReceive(), 

4       ,  
    
         -


 
 ,    $  
-   " . &     
  $  
   -  - 
   
  , 
 
 % 

(
  localAddress),  
 
  " , 
, 
  
      0xFF. 
   
   
!
 
9. /

    onRecieve()          
 ,   
"    "  ,     
  
    .
  
 $
 
 .

* 
  
 
 
    - Слова синхронизации

   
 
 
,  - и фактор распределения
 
  %
 "   
,
  
 ,   . 0  
  &
 
     

  "   
   
    "  

 
 , 
      %
- 
,  
  "  
-
 "   
,       -  
      
 .
"    "   
   /           ,
 
 . &            
   
$ " ,   
    9
0  . promiscuous mode.
318 Глава 6

LoRa   
  . =   ,  Отношение сигнал/шум
  
    
  -
=
 

  ,     ,
   . 
    
   
 
 /11. /   
 
     
 
     ,    
    
 
 ,  $     $ .       
   -
,   —

   ,
&  
  
 "    %. '   %    $ -
     

 
 - % ,     
. 0    
 . 9 
 
  
     %   /%  

 
     "  
  
  
  ,  -

  
. 
    
 
  
   % 
 

 
      
 
      "  " . *  -
%          
 
 
 ,   , — 
  


 
  , 
     -
      %    .   
  
 .
~ 

 
   
% 
 -
 $  ,  
     - Циклический контроль
    
  
. избыточности
0         
- &   
   

  -
 

 : 
    -       
    



   
  
  —  -  
!
12,
 LoRa 
 
  
   . /  

. 7       
!-

 
 
 
    
-   
     
-
 
 
 
    
   
    
#

!#-
HopeRF  Semtech, 
 
   
 !  

 

 
     . 4

 !   -
PDF   
  
: www.hoperf.
   #
  
   -
com/upload/rf/RFM95_96_97_98W.pdf (
- 


 

 !  
.
 RFM95W   HopeRF)  www. &  #
 ! 
 !  ,   
semtech.com/images/datasheet/sx1276.pdf (
-


, 
  
 SX1276   Semtech). 0 $      


 -

 
        . . 4    
 #
,   
 
,       -

 

  
!
. 
Уровень принимаемого сигнала  !      !-
0   

 , 
    - 

    %   ,
   
  
,   

 

 !   LoRa.crc(). /   -
  

  
  (+X#)10, -     
,     -
   
  .

    "       
 
 . > 
  $ 

 
-
* * *
      8.   
 
 $ -
9 
  LoRa 
  

   $
, "     
        
  -


  %   

-   

 . +  $
   

    
.  
  
%   ,   -
$ 
 
  ,       %
  
,     -
$, 
 "
 
     
 
    "  .
  

 
   .
11
0  . SNR, Signal-to-Noise Ratio.
10 12
0  . RSSI, Received Signal Strength Indicator. 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     
 GAP (General
,    
  
 %
, Access Profile, 
 "   ),  
     
 
 . &
-           
  -
 ,   ,       
      

 ,     
 $  GATT (Generic Attribute Profile, 
 "
    
      - 
). &   «Make: Bluetooth» ( -
 — 

,  
    %  -  «Maker Media»),    3  

 
. /      - 3  (Alasdair Allan), =    (Don

 
     Bluetooth. Coleman)  #  7 
 (Sandeep Mistry),
#  Bluetooth 4.0 (Bluetooth LE)     
     
 "  -
 

  
 
       Bluetooth LE.

 .
Bluetooth LE: центральные
 Arduino 101   " 
 
Bluetooth LE,     

    
и периферийные устройства
 $ 
 . * 
       X 
  Bluetooth LE
    
   
  . >  Bluetooth, " 
 :    

.

       , 
- 

   
   

   
-
   
  Bluetooth   
-     
 ,   

 nRF8001  nRF58122   GAP (General Access Profile, 
 " 
Nordic Semiconductor. /  
     ). Z 
  
  
 %-

    
 %
   

  
 ,    
 -

 

 ,     
 
  
 . 
 
    , —  , 

, 
        

,
 BLE Nano   RedBear Lab. 4  
       ! 
. =
     
 
-   
   

   
-
  ,  
      

-  GATT (Generic Attribute Profile, 

 
  Bluetooth LE, 
  " 
). ;,  " Bluetooth
    . LE      
  

 —  

, Z,  "  
-
& 
 4.0   Bluetooth 
- 
 : ›  . * 
  %
  . Z  $ -    

    
    —     
  — " 
   ,   
 $ 
  
  $
$  ,   . 3    
  -
         -  
  
 ,    
  
  Bluetooth. ; 
   
- 
 

  — 

, +. 
 SPP (Serial Port Profile, 
   - $ 

       \ ,  
   
)     
      
 ,      
320 Глава 6



  ›,  ,   
 
      -
    

  .   
.  -    


, 
 $ , 
 SPP 
-
*  
 GATT     
  . &      
SPP  
 ? 
    
       
    
SPP         
  
  «
 %  — 
  % »,
 
  Bluetooth 
,     

 
      
      
 . 2   
  
      . & 
-

   
   , -    $, 
 GATT   

Рис. 6.12. Устройство Bluetooth 2.0 (схема вверху) — в нашем случае светильник — предоставляет профиль SPP. При подклю-
чении к устройству весь обмен данными происходит через поток данных последовательного порта. Центральное устройство
(планшет, смартфон, ноутбук) считывает все три элемента данных и выбирает требуемые.
Светильник на Bluetooth 4.0 (Bluetooth LE), показанный на схеме внизу, предоставляет сервис Z, имеющий три характери-
стики. В зависимости от свойств этих характеристик центральное устройство может выполнять операции чтения, записи или
подписки с любой из них

Bluetooth 2.0: профиль последовательного порта (SPP)

Сопряжение

Поток данных

Яркость, Оттенок, Вкл \n

Планшет, смартфон, ПК
Светильник

Bluetooth 4.0: профиль общих атрибутов (GAP)

Сопряжение

Свет
Вкл
Яркость
Оттенок

Планшет, смартфон, ПК
(центральное устройство)
Светильник
(периферийное устройство)
Беспроводная связь 321
  

. 

   % ). & 
   $,  
 
 
  (   
    
- Bluetooth 4.0 (LE)  
  -
  ),        
 
 
 .  , %  
  -
  
 ,   
    
  
  Bluetooth LE 
-
   

 . / 

  ,   ,
 
  
   ,      - 
  
 
     -
    . 
     
 
 ,  , 
   


  

   
  -  
     ,     
      ,    

 
  
  
.
   . &  ,      
    ,    
 0 
    


  

    "  Bluetooth   

  
 . 6.12.

       .
~

  

   
  -
X 
  Bluetooth 2.0    
 -      ,    -
  
 . *

,
 
 -        ,   
 Bluefruit,
 
    2, 
   "       -

  
 SPP, %  Blue- 
   
 ,      
tooth — 
 (Audio Profile),   
-    ,       . 7 ,
  %  
— 
 HID   "        

-
(Human Interface Device,  
   --    "    $ 
 .

Схема управления фотокамерой с помощью Bluetooth LE


=  Arduino 101     
    ,     10 Требуемые компоненты
( .
 . 6.5),   $   "  
 Arduino 101    
 
 
 
  Bluetooth LE. Arduino     
3   Arduino Uno    - Bluetooth LE  nRF8001  nRF51822 -

 nRF8001   Nordic   Nordic Semiconductor, 1 %.
Semiconductor  
 . 6.13 ( - +       : 

)  6.14 (
  ). 7
- / ,  Bluetooth LE.
 
  
   
 

 
+ 

  , 1 %.
  
   
  SPI,  - 
9  
  220 0, 1 %.
  $      .

    $ 
    
>         %
    
  Arduino  
, 1 %.
   
 

 ATmega328  
 %  
, 
  ,
Cortex-MO — 
    
  "
  Bluetooth LE, 1 %.
  SPI  
,   "  -
   .
 

    
-
~ 
 $    

-   Bluetooth nRF8001  nRF51822 -
  Arduino Uno, Arduino 101    Nordic Semiconductor  

MKR1000,    Arduino 
-   ,     $ 
  .
322 Глава 6

A B C D E F G H I J
1 1

5 5

10 10

SCK

15 MISO 15
MOSI
REQ

Bluetooth LE
nRF8001
RDY
UNO

ACT

20 RST 20
3Vo
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
Модуль Модуль nRF8001
микроконтроллера D9 RDY
Act
Reset
D7
Общий
D2

Общий 220 Ом

Инфракрасный светодиод
Беспроводная связь 323
+ 

      
-  
 , 
 
  
 -
  
     

  -   
 UUID,    

-


   
 , 
 "    
 
 
,   $
 
 , — 
  
 .  
. = 
   
 
*  $
 cameraService. #
        128-  -
     

  — 
- 
UUID,    -
  
, 
     shutter  " "
 . 0 
  

 ,         "   $ 
   
   -

   
 .      16-  
.
$ 

 
  1,    

   

     - Код для управления камерой
 
.  
%  
   по Bluetooth LE
 
   

  shutter  -
  0. & $ 
       
BLEPeripheral,

 #  7 

X 
  Bluetooth LE,  

 - (Sandeep Mistry). =   , 
 Ardui-
 
  
   128- no 101,      "  -
    
UUID13 — 
- 
  . &
    

: 2f45c1ee-5048-11e6-beb8-9e71128cae77 Arduino 101     CurieBLE    -
( %  
  
 ). * 
      
    
 
 
  — 

,
- 
  
. =   -
  
 
 
 — 
     CurieBLE     
: www.
 
 , 16-  
arduino.cc/en/Reference/CurieBLE,   -
UUID, 
 
Bluetooth SIG (   BLEPeripheral —  
: https://
   
 UUID   
- github.com/sandeepmistry/arduino-BLEPeri-

       
: https:// pheral. 0       -
www.bluetooth.com/specifications/gatt/services).  ,  
        
#
  
 
 
   
( 
       ,
0-180F,    ,   

  
 Arduino 101,    

13
%
).
UUID, Universally Unique Identifiers —  

    
.

Пишем код
   ,     - /*
    - M   
  ' Bluetooth LE
. !  Arduino 101 - : Arduino 101
/*
> 

  CurieBLE:
#include <CurieBLE.h>

Внимание!
' $ 
  Arduino 101,  
 2.0.1
(   ) 
    Arduino 101. 


    
   
     
    "  
 .
324 Глава 6

!  
=   † /*



 > 
- Bluetooth LE IR Camera Control


SPI
BLEPeripheral. context: Arduino Other
/*
2  
      

    
- #include <SPI.h> // €    


 "  
 
 - // SPI  BLEPeripheral
 Request (2
 ), Ready #include <BLEPeripheral.h>
(q  )  Reset (#
 ). // 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);


    - //     %  UUID    :

UUID
  
 - BLEService cameraService("F01A");


  
. 9 //     %  UUID -   $


   
- BLEIntCharacteristic shutter("F01B", BLERead | BLEWrite);
     : BLEInt- const int IRPin = 7; //  ,  
Characteristic (  $ // ' \- 
 ) —       - const int CAM_NIKON = 1; //   # %-  
   
 , BLEFLoat- const int CAM_CANON = 2;
Characteristic —   - int buttonState = 0; //     
int lastButtonState = 0; //     
 
 "  ,
BLECharCharacteristic — 

 ASCII  . . 
 
 
  $ 
 
       -
  .
  $   -

     -


    10:

!  Arduino 101  void setup() {


  setup() 
   Serial.begin(9600);


   
  - BLE.begin();
  ,       //      %
 

//   "      :
 , 
   
 - BLE.setLocalName("irRemote");
   
   
 . BLE.setAdvertisedServiceUuid(cameraService.uuid());

     
// Š   -     

 . 2     - //     %
 
:
      

 - BLE.addService(cameraService);
 
 shutter,   cameraService.addCharacteristic(shutter);
 $   .setValue(),
BLE.advertise(); //   "   
        //    
   
 ,   shutter.setValue(0); //    $ 
  .begin(): //  -   $
Serial.println("^   ");
}
Беспроводная связь 325

!  
= ,
 >- void setup() {
$
= 

  BLEPeripheral, Serial.begin(9600);
       $ - //      %
 

//   "      :

 blePeripheral,   -
blePeripheral.setLocalName("irRemote");
   
 
blePeripheral.setAdvertisedServiceUuid(cameraService.uuid());
 

   
 
// Š   -     
    .addAttribute().
//     %
 
:
& $    
blePeripheral.addAttribute(cameraService);
blePeripheral.begin() 
blePeripheral.addAttribute(shutter);
      
blePeripheral.begin(); //  
Š
   
 : //    
 

shutter.setValue(0); //    $ 
//  -   $
Serial.println("^   ");
}

    loop() 


 - void loop() {
%  $
  - //    %
 
    
//   :
   
   
 ,
BLE.poll(); // Š  Arduino 101 $  R 
   $  - // blePeripheral.poll(); // ‰ 
# 

   .poll() ( // 
 BLEPeripheral
 , 
     - // † # 
  % # 
    
- // -   $:
if (shutter.written()) {
   
  ).
// $  -    1:
/      if (shutter.value() == 1) {
  .written()  shutterClick(CAM_NIKON); //  \-   

 ,   
  // $
 
      - Serial.println("œ");
         - shutter.setValue(0); // Z $   0
}

  

 ,
}
  %      }


  
 shutter.

      -
      

 -
  
  

shutterClick(),     -
  
    

-
   " 

.

&       



     shutter-
Click()  IRPulse()   

   

  

  
 :
326 Глава 6

Приложения диагностики для Bluetooth LE


; 
       
 — - (
 . 6.15)        -
   
   
   - 
  . 0 
  
  
-
%      

     
  . 
 "   $
 
  
  
  Bluetooth   -  
   

LE. 
       $  
  
 . ¥  
 
  ,        
 
   

   
-
 
  , 
    -   ,  "   

   -
    . #"     -       
  .
   
  ,   "
 
 
  Bluetooth LE  - *% 

   
    
-
   
 ,      -    $     irRemote, -

  
  
  . 7 
  
       

   "   
-  . ;  ,      
-
  $ : LightBlue   
      Arduino 101-XXXX,  
macOS  LightBlue Explorer   
   
   
    
MAC-
iOs — 

   Punch Through 

 
  Bluetooth. ;  -
Designs. 3   
   Android    -        , 

 
  nRF Connect

 
    

   
  -
  Nordic Semiconductor. & $ 
-   ,    
    .
        
   ¥    
 ,    ,  
macOS, iOS  Android. X          
UUID, 
 
-
   
 ,      % . 
  cameraService. = "  -
&  " 
  
 
,   -   

  (
    -
 $ 
    
  
UUID, 
  shutter). = $
 
   %  

   
 - 

       

   
  .     ,    Read  
-

             -
Приложение LightBlue для macOS   ,    . 2     

  LightBlue 
      %  
  
 

  
 
  Bluetooth LE. 
   
 ASCII. &      
  

 
    - 

     0-01   -
  
,  "   
  % <Enter>. 

 LightBlue 
 

Рис. 6.15. Рабочее окно приложения


LightBlue для сканирования устройств
Bluetooth LE. В окне выводятся обна-
руженные устройства Bluetooth LE,
и там же можно просматривать их па-
раметры
Беспроводная связь 327
$    

  
 -

   
 , 
   
%   

   
  
 
.   $
  "   

 
 
     
  $


     0,  

        -
 $    .

Программа LightBlue Explorer


для iOS
~ $ 
     -
 ,      
,    
       : 
$
       
 -
  
 ,  "    
 -
 
  
 . 0
 , "  
 
  


  (
 . 6.16).

;  ,       


 
-

 ,    $ 

 
      . *
  
      

-
  %  
  

  
    

0-. '     , - Рис. 6.16. Приложение LightBlue Explorer для iOS — здесь показан экран
    Hex  
 
  просмотра характеристик
 $
  
 
 

 ,
 
   ,  
  
   
    .

Приложение nRF Connect


для Android

  nRF Connect   Nordic 
 
 ,    
  
Semiconductor 
       -     ,  $

% .
 " " 
   2         
Android,     
  
   ,         

Bluetooth LE. 
  
      . =    

 -
  ,    
 "
 
-   
   
    UINT 8
  

  
  Bluetooth ( .
 . 6.17, ),         1
LE. * 
 $
 (
 . 6.17, )    (
 . 6.17, ). * Send,  

 
   
   
 ,  
  
      
 

 -
(
 . 6.17, ) —  
   
      
.
 
 ,   
  (
 . 6.17, ) — 
-
328 Глава 6

а б в г

Рис. 6.17. Приложение nRF Connect для Android

* * *
*    ,  
  Bluetooth
   " 
 . &  %
LE   
 
  $ 
  
 Bluetooth LE      
 -
   
  
 , 

     
  



 
   
% 
   
  .

          

Центральное приложение Bluetooth LE на node.js


=  
   

  

-  - 
 .    $ 
 
 
  Bluetooth LE       p5.js, 
 

 
 ,      
.  
 "  .
~
 

 
  Bluetooth
LE " , 

,  Windows,   Установка библиотек noble и express
          >  noble        -

 $   . #"   
   node.js. 
 , -
  Bluetooth LE   macOS, ,         express, -
  ,         -
 
   

   
 .
"  
 . 0      #    
 ,  , -
node.js, 
 
    macOS, Linux 

, NobleCameraControl,      
 Windows. >      noble 
- 
   ,     :

       #  7 


.
& 
%"   $ 
   - $ mkdir NobleCameraControl


 node.js, 
   $ cd NobleCameraControl
 %  

   
   
 - $ npm install noble express
      
 
  
Беспроводная связь 329
&         
-      noble     
       
   - 
  
 "  
 https://github.
       
 . com/noble/noble. ;     

;,  %  macOS      
     $   
 ,   % 
 
 Linux. #   
-
 2012 , 
 
  Bluetooth        noble,   
-
  Bluetooth LE. = 
      .
 Windows  Linux,  " 
-
 
 ,    Bluetooth LE, Код сервера node.js
     CSR8510 - / 

 
   


 Cambridge Silicon,      HTTP,           -


$  ( . . 6.2). =
 
 $ 
    "  - 
 

 
        
   
  Bluetooth LE.
Windows. =
 
      -

  Linux,  Raspberry Pi, - 
    

 
     "   :  
  
 
  
 " 
-
$ sudo apt-get install bluetooth   :  
  $
  
    -
bluez libbluetooth-dev libudev-dev   

   
 ,  
 
     
  
  ,  
 
= 
  Windows      
  
  

-

    
 
USB  ,     ,     -
Bluetooth,    noble  
-     . / 

   
 
 
 ,   $  
 -    
  

 node.js     
  
  . #
  $  -       , $ -
  

 
  Zadig,       
 

,  
 
 http://zadig.akeo.ie,   
   .

Создаем псевдокод
= 
    - // ''    :
// '   
, 


   -
 %  node.js:   // †   
 ',   

     

- //     %
 

// †    %
 
,
         . //  
   ,
  
,  // '     

  
     //      -  

    ,    -
// † '      -  
     : //  %
 
:
//  -  
//    -     -
// -   $ shutter
// -   
 

// †   HTTP  $ GET  #


//   $:
//      
 
// -   shutter:
//   $ 
//    HTTP $ 
330 Глава 6

Пишем код
&   
   /*

    — noble Z Bluetooth LE  noble
 express. 2    $ - : node.js



  express: */

var noble = require('noble');


var express = require('express');
var server = express(); // C$ " server,
// $     express
=     - var cameraUuid = 'f01a'; // \ %  UUIS  

  
   - //  

 UUID
   - var shutterUuid = 'f01b'; // \ %  UUID
// -   $


  %  
 -
var shutter = null; // -   $

   
 ,   
var clickCount = 0; //     $  
 

 . 4"   var device; //  %
 


       -
     
. //    %
  $ -   /public:
server.use('/',express.static('public'));
2     public 

     ,
 
    
 -
  " express.
use(). #   
 :
&   

   // Z    %
 
   -
 
 %    . //  %  UUID    

       noble.on('stateChange', scanForPeripherals);
noble,    
   noble.on('discover', readPeripheral);

 (.on('stateChange')), 

 —    
  - server.listen(8080); //    express

  

   
 - server.get('/click', click); //     
$ GET
 (.on('discover')). 
        
-
  , 
 
 -
   .
  $   

ex-
press  
 %  
 
GET    
 /click:

    
 -
         -
, 
  
   
  
    

   stateChange.
    ,       

       -
      

 Bluetooth state-


Change.
Беспроводная связь 331

&  ,   


- // • #   $    stateChange:
        - function scanForPeripherals(state){
 

   
 , if (state === 'poweredOn') { // †   

// Bluetooth ',
   
  
noble.startScanning([cameraUuid], false); //   
    
 , 
 //  %
 
   -
       
 - //  %  UUID    
 
 . ; 
 console.log("+   ...");

    .startScan- } else { // †   
 Bluetooth ',
ning(),  
   noble.stopScanning(); //    
 
UUID
  console.log("M
 Bluetooth  .

:   .");
process.exit(0); //   .
}
}


  
  

 - // • #   $    discover:
  
 , 
   function readPeripheral (peripheral) {

 ,      console.log('  ' + peripheral.advertisement.
localName);
  
    read- console.log('M  : ' + peripheral.rssi);
Peripheral(). /   
- function readServices() {

"   
       device = peripheral; // Z-  %

    
  // 
  
 

 
   
   %  - console.log('   : ' +
        - peripheral.advertisement.localName);

    readServices() //       - -   .


//    - $ % # ' explore:
   
    
 -
peripheral.discoverAllServicesAndCharacteristics(explore);

 . 

  }
 
  
     - noble.stopScanning(); //    
  
  device, - peripheral.connect(); //   ' 
     

  - //   %
 

    % : peripheral.on('connect', readServices); // 
// '      
}

#     
- // • #  explore       -  .
  

 ,     //       -  ,     %.
,      
 - // 
, R   ,   
// 
  '  % # readPeripheral().
   explore()   
function explore(error, services, characteristics) {
.discoverAllServicesAnd-
// Z    -   -  
Characteristics(). /  -
console.log('Z : ' + services);
 "      
  console.log('   : ' + characteristics);


  

  //   %  UUID 
-  
 
 UUID  
- //     UUID -   shutter

    
 shut- for (c in characteristics) {
ter. *   ,   if (characteristics[c].uuid === shutterUuid) {
        - // ‰ -  , 
  
 $ 

 ,  shutter = characteristics[c];
 $ 
     }

  -

. $  }

   

   - }
  
  ,   
  
     :
332 Глава 6

* , 
    - // • #     HTTP  $ GET 
//   $:
 
     - function click(request, response) {

  GET HTTP. & $   var result = "^  %
 
"; // Z ,


 ,    //    
// † '  
  ' -   :
" 
 

 - if (device.state === 'connected' && shutter != null ) {
  
 ,     - //   $  -   :
     

  var output = new Buffer([0x01]);
shutter.write(output, true);
shutter,      
 - clickCount++; // M   $   

      
. //   $
&   
    result = "Click count: " + clickCount; // \$  
}
  HTTP    
- response.end(result); //    HTTP
% % : }

&     . #


      server.js      
      -
  NobleCameraControl      

   
  Bluetooth LE.
   ,     : 4  %  
      
node server.js  
 
 
 ,  $
    -
  "  
:

+   ...


  irRemote
  : irRemote
Z : {"uuid" :"f01a","name" :null,"type":null,"includedServic eUuids":null}
   : {"uuid":"f01b","name":null,"type":null,"Z
:":["read", "write"]}

     ,  


  
 -      p5.js  
  


  
  

       p5.js,   $      5. + 
,  
 


  
 . +  -
  
  p5-manager, 
  p5.js

          ,        


  -
   
   
   
  " 
:

  $ ,  
    $ p5 generate --bundle public
  . =   ArduinoBLE
  
       Arduino, 2  
   public    -
    CurieBLE — ARDUINO 101-   p5.js      
 :
XXX,   XXX 
    - $ p5 update
  
%  
 
MAC- *% 
  HTML      

  
 . $  :      
  div
 
    "  

.
Веб-интерфейс 0 $ $     " 
     % 

  
- JavaScript, 
%  " p5.js.

   %   ,     " 
    

   -
   "  - 
 . = -  
 GET,   

   
-
   
     ,      
  .  HTML %
 
    
   
, 
  index.html   


  $    
 

   - p5.js 
   
    .
     5. = $  

 7   $         
NobleCameraControl    public,      %    JavaScript, -
—  
  p5.js. #
    

     sketch.js.
Беспроводная связь 333

Пишем код веб-страницы


&   
 sketch.js - /*
    
 - Z # \-     p5.js
: p5.js
      : */

var shutterButton; //    $


var messageDiv; // ƒ
$    
// 

&   setup()   function setup() {


     
 . / // Z$    $, $     #
// $   % # '  $ getShutter()
$    
   shutterButton = createButton('shutter');
   
  . = - shutterButton.position(windowWidth/2, 20);
  touchEnded    - shutterButton.touchEnded(getShutter);
  
    
- // Z$ 
$ $     #:
messageDiv = createDiv("   
...");
   getShutter(). 7 messageDiv.position(20, 50);
   $     
: }

[  
    // • #   $  % #    $
getShutter() 
  - function getShutter() {

 GET HTTP,    httpGet('/click', 'text', clickDone);
$   p5.js httpGet(). }
&   
 
  
// • #   $  $ httpGet()

  ,     function clickDone(data) {
         messageDiv.html(" : " + data);
      

. }
=
   
   -
 — clickDone() —  
 

    
 -
 
  :

&     
 . #
  , 

 , Рис. 6.18. Страница веб-интерфейса для сервера централь-
 % 

   
   , ного устройства Bluetooth
        

 -

 server.js,       


 



 
: http://localhost:8080, 
        
  


. &      

    "    
 
  
   
 ,    


  
  
 ,   

 . 6.18.

#       "    



...,  
    —  -
      :     
   

     
- $. 
       - 
 
,     -    
 -

  

   
    - 
 .
334 Глава 6

*%     
%  
   -

 node.js  

  
   -
      
  ,
 -  ,     
 
 -

   $  :  

  
,  %    
,   -
        -
, -   
      

,


 
  
 " . 
       IP-

#   

   
  
- %  
. / 
    

   
 Bluetooth LE  
     " 
 .
 

  
  
 . *

Заключение
Беспроводная связь в некотором роде значительно отличается от проводной. Вследствие ослож-
нений, связанных с природой беспроводной связи, нельзя рассчитывать на бесспорное прохож-
дение сообщений, как в случае с проводной связью, поэтому нужно определиться со способами
решения подобных проблем.
4    
 
    %          , 
-

% ,   
 %   - 
" "   %,   "

  
   ,  -  
 
 ,   Bluetooth
" 
 
-
  ,  
  Wi-Fi, 

 
-
"   
 
,   ,   $,   , 

-
           .  $ 
 , 
     -
&  %   ,   
- 
  %.
       ,  

    
%   
 ;  ,       ,


  
    . &  - 
  —     —     2, 
" 
         
-   $       
-
 —       
     
 
 
  
.

 
-
      %- 7  
     
 -
"      $  
 .   ,       
 
*     
     
- 
%

,  
    
  ,        ,   "    
  $

    . &  ,  
 
  

 
-
 

              "  ( ),
          ,    
     , -
  
           
   TCP   -
   $ 
    :   . &  "   
 -

      $ 


   
     "  .
      . =     -

Городской сонар. Авторы Кэйт Хартман (Kate Hartman), Кэти Лондон (Kati London) и Саи Срискандараджа
(Sai Sriskandarajah)
& 
 %  

       . 7
 

 

    Bluetooth       (   
%  ). &
 

   
 
 ,  

  , 

      
,
 "      
   $   
 
 ,  " 
    
   
, 
 
         
    + 
 .
Беспроводная связь 335
Глава 7

БЕССЕАНСОВЫЕ СЕТИ
И ДВОИЧНЫЕ ПРОТОКОЛЫ
Сетевые подключения, с которыми мы до сих пор имели дело,
были в основном выделенными соединениями между двумя
объектами. Для последовательной связи требуется управление
последовательным портом, а для подключений почты, браузера
и telnet — сетевой порт. Во всех этих случаях присутствует
устройство, которое предоставляет порт (обычно это сервер),
и устройство, запрашивающее доступ к порту (так называемый
клиент). Классическими примерами этого подхода были проекты
главы 5. В этой главе мы рассмотрим, как организовать прямое
взаимодействие любого сетевого устройства с другим сетевым
устройством или одновременно с несколькими другими
сетевыми устройствами.

Все рассмотренные нами ранее протоколы были текстовыми.


Но некоторые протоколы требуют умения интерпретировать
цифровые данные в виде чисел или битов. Эти вопросы мы также
рассмотрим более подробно в этой главе.

Туфли-дирижеры Эндрю Шнайдера (Andrew Schneider)


;         
 
-
 Digi. 
        «»   
  
 
-
  
      
.
338 Глава 7

Компоненты для проектов этой главы


Коды поставщиков
? 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-to-
Serial. 6. Одноплатный мини-компьютер Raspberry Pi. 7. Конденсаторы. 8. Стабилизаторы напряжения на 3,3 и 5 В. 9. Транзистор
TIP120. 10. Инфракрасный дальномер Sharp GP2Y0A21YK. 11. Гнездовые разъемы. 12. Программируемые светодиоды WS2812.
13. Матовая пластиковая трубка диаметром 10 см. 14. Жестянка из-под леденцов. 15. Игрушка шимпанзе Чарли

15

14
4 5
13

3
11
12

6
2
1

10
9 8
Бессеансовые сети и двоичные протоколы 339

ПРОЕКТ 13. Сетевые светильники


Набор компонентов приведен для каждого отдельного светильника. Проект выглядел бы более
эффектно с большим количеством светильников (от 6 до 30), но разобраться в его работе можно
и всего с двумя.

Arduino-
  MKR1000, 1 +. 
C      , 1 +.
AF: 3156, RS: 124-0657, A: ABX00004, GBX00011 D: 438-1045-ND, J: 20723  20601, SF: PRT-
(3
  4#), D: 1659-1005-ND 12615  PRT-12002, F: 4692810, AF: 64, SS:
&   
     319030002  319030001
   
   ESP8266. 
C   3,3 '

5 ', 1 +.
SF: WRL-13231, AF: 2471
AF: 771, D: BC4AAW-ND, SS: 320180002

 &      Sharp GP2Y0A21YK,

" 
    
 
1 +.
10 , 1 +.
JJ: 2150256, D: 425-2063-ND, AF: 164, F: 1243869,

K    
-   &  

RS: 666-6564
10    - 
 " 

  
 
 WS2812 
  
 .
(NeoPixel), 3–7 +.
AF: 2226, 2858  2859, D: 1528-1610-ND,
J: 2247947, SF: BOB-13282, SS: 104990139

ПРОЕКТ 14. Предупреждение о наличии в мастерской токсичных испарений


Для этого проекта нужно собрать три отдельные схемы. Наборы компонентов приведены для
каждой из них отдельно, хотя для программирования радиомодуля используется один адаптер.


XBee-to-USB   , 1 +. 



     9–12 ',
1 +.     
,   
-
J: 32400, SF: WRL-11812, AF: 247, PX: 32400.
   $ 
 .
4   
    
  
 -
SF: TOL-00298, AF: 798, J: 170245, F: 1176248
 XBee,
      

 XStick 802.15.4   Digi. 
     XBee, 1 +.
D: 602-1200-ND SS: 113100001, SF: BOB- 08276

Компоненты для схемы датчика 


!=   +  

, 2 +.

C      , 1 +. D: A26509-20-ND, J: 103377, SF: PRT-00116,
F: 1593411
D: 438-1045-ND, J: 20723  20601, SF: PRT-
12615  PRT-12002, F: 4692810, AF: 64, SS: 
!=     ), 2 +.
319030002  319030001 SF: PRT-08272, D: 3M9406-ND

(
 XBee

XBee Pro S2C 802.15.4.

   1  \, 2 +.
AF: 128, D: 602-1892-ND, SF: WRL-08665,
J: 2253722, PX: 32416 D: 1189-1324-ND, J: 94161, F: 8126933, RS: 475-
9009

D

  A
 5 ', 1 +.

   10  \, 2 +.
J: 51262, D: LM7805CT-ND, F: 9756078, RS: 918-
1971 D: P11212-ND, J: 29891, F: 1144605, RS: 762-

D

  A
 3,3 ', 1 +. 1736

D: 497.1491-5-ND, J: 242115, F 1:703357, RS: 


!
  

Hanwei, 1 +.
438-4885 SF: SEN-09405, P: 1481, PX: 605-00009
340 Глава 7


     
 , 1 +. 9 - Компоненты для схемы
   Hanwei « 
»   -

     ,  $  
-
исполнительного устройства
   «
». (шимпанзе Чарли с ударными
SF: BOB-08891, P: 1479  1639 тарелками)

D
, 1 +. 
C      , 1 +.

D: 160-1144-ND  160-1665-ND, J: 34761  D: 438-1045-ND, J: 20723  20601, SF: PRT-
94511, F: 1855510, RS: 228-5972  826-830, SF: 12615  PRT-12002, F: 4692810, AF: 64, SS:
COM-09592  COM-09590 319030002  319030001

(
 
 220 , 1 +. 
(
 XBee

XBee Pro S2C 802.15.4.
D: 220QBK-ND, J: 690700, F: 9339299, R: 707-7612 AF: 128, D: 602-1892-ND, SF: WRL-08665, J:

    
 
 47 , 2253722, PX: 32416
1 +. 
 +  +
   J 
  
 -

, 1 +.
D: A105657-ND, J: 254028, RS: 186-205

D

  A
 3,3 ', 1 +.
Компоненты для схемы сервера

     > Raspberry Pi, 1 +. D: 497.1491-5-ND, J: 242115, F: 1703357, RS: 438-
    BeagleBone Green   4885

   
 Linux. 
     XBee, 1 +.
SF: DEV-13825, AF: 3055  3400, SS: 102010048 SS: 113100001, SF: BOB- 08276
 114990584, RS: 896-8660, F: 2525225 
!=   +  

, 2 +.

(
 XBee

XBee Pro S2C 802.15.4.
D: A26509-20-ND, J: 103377, SF: PRT-00116, F:
AF: 128, D: 602-1892-ND, SF: WRL-08665, J: 1593411
2253722, PX: 32416 
!=     ), 2 +.

XBee-to-USB-  , 1 +. 0  

SF: PRT-08272, D: 3M9406-ND


      

   

 
  XBee. 
D
, 1 +.

J: 32400, SF: WRL-11812, AF: 247, PX: 32400. D: 160-1144-ND  160-1665-ND, J: 34761 
94511, F: 1855510, RS: 228-5972  826-830, SF:
COM-09592  COM-09590
Об источнике питания для игрушки 
(
 
 220 , 1 +.

4   % 
% 
      D: 220QBK-ND, J: 690700, F: 9339299, R: 707-7612
  
   3 & ( 

,  - 
  ! 
   NPN-  
  TIP120,

   D), 

   1 +.
3,3 &   . * 
 $  D: TIP120-ND, J: 32993, F: 9804005, RS: 808-0502
      
 
 
 . 4  
   
  - 
(
 
 1 , 1 +.
  
 
    
 D: 1.0KQBK-ND, J: 690865, F: 9339051, R: 707-
  , 
      «» 7666
  $
     
%. & -
  
        - 
   100  \, 1 +.
       . D: P10269-ND, J: 158394, F: 1144642, RS: 762-
1746
Бессеансовые сети и двоичные протоколы 341

Сеансы или сообщения?


До сих пор большинство проектов связи из этой книги работали, открывая выделенное соедине-
ние между двумя узлами на весь период обмена данными. Такой тип связи называется связью на
основе сеансов (session-based). Но иногда требуется организовать между объектами более сво-
бодный вариант обмена данными — когда они могут менять партнеров по общению «на лету»
или даже отправлять сообщения целой группе узлов, если ситуация того требует. Для этого ну-
жен протокол, основанный на сообщениях (message-based).

Так сеансы или сообщения? 


 
  
  
-
 
 ,      " .
&   5     

TCP,  
   
 - ;    ,  
 UDP -
%        + 
 . =        « -- »   -
  " 
 TCP    
      , -
   
    
   -   
 %
 "  " -
  
. &     
 
    
      . ;,
 
  
    
,  -      
 192.168.1.45 
-
      . 2        "  UDP  
 192.168.1.255,
  ,  
%  
 - $ "    
    

  
  . &  $    -  $  . '   
  «
 —   —  — -     ,  


-

 »       (  ). 4     %
 "  
:
       - =.=.=.255,   =   

  
 ,       
   
  . / 

-

     . #           
  

 
     - ,  
 
   
"
  
 TCP.  ,   
 "     

  
  . ; 
 
*                     
 . & + 
     "  ,       " 

 — UDP1.   
 UDP,    .
   "  ,    
  -
, 
        . 
"  
 UDP   
    
  
  " -
&         
-  ,          

-
 TCP, 
 UDP    "    
    
. 
 , 
(message-based). #"  
 UDP     
    
 
      
. =   -   . 3       , 

     
  ,       
 
  ,  
   
 
       
   
  
.

  ,          - 
 UDP    
   

  . = 
          , 
" % -
  
       
 $  
"   
, —  
    . 0      ,     . 
    -  -
    ,  
   -           %
1
UDP, User Datagram Protocol — 
 
  - 

     , " 

  . "  
 
   .
342 Глава 7

#
 
 TCP  
 UDP
  
 
   - Широковещательные UDP-сообщения
   
 (SPP) Bluetooth, 
 в офисных сетях

 
    2,  

 -
&  " 
      %-
 LoRa, 

 
    6.
 "   UDP- " . 4 
9 LoRa 
  
 
 - 
    %  
%
-
"   , 
  
,       $ 
 .   
 TCP, 
 
 . *      -
Bluetooth    ,     -
      

 -
   
,  
     %
 "   
 UDP-
   
 ,       , "  . $,  
    -
     
 ,   
 LoRa.    , 
   
  
& $  
 
  
  $ 
 
  %
 "  
UDP- " , 
     -
  "  ,  "  
-
  

  
     
 
   
 802.15.4, 
     . &
 , 
 UDP, %

  Digi.     + 
  
   -
   ,  %      
 - 
  
 ,  %-

 "   "  .

Широковещательные сообщения или направленные?


Первое преимущество бессеансовых протоколов, таких как UDP, состоит в том, что они позволя-
ют передавать сообщения одновременно всем узлам сети. Впрочем, все время делать это неже-
лательно, поскольку это наводнит сеть сообщениями, которые нужны далеко не каждому устрой-
ству, но такую возможность полезно иметь под рукой, когда надо узнать, какие еще устройства
имеются в сети. Для этого нужно просто отправить широковещательное сообщение с вопросом
«Кто там?» и ожидать ответов.

Кто здесь, кроме нас? — выявление других устройств с помощью UDP



 node.js 
   dgram %       
 . 0

 
     
. =  %
 "  
   -

   
 
  UDP-

 "  
  node.js.
    $  . # 
-

     "    
      -
  
 , 
   -  MKR1000      
  
  + 
  
 UDP-  . ESP8266 
    . 0

%
 "  UDP- " ,  
>  WiFi101
 Arduino  
       "
  -
   
      
 netcat      POSIX,

      UDP. / - 

 
      $
 .
   
   , 
  

 netcat  
  
%
 "  "          
 Raspberry Pi 
. ;          , BeagleBone, 
      -
     
    
.
Бессеансовые сети и двоичные протоколы 343

Пишем код сервера UDP-сообщений


# "    node.js - /*
  %
 "  UDP- Z UDP
"     " : node.js
  UDP    
 8888. */
/ 
 
  -
var dgram = require('dgram'); // '   
   
 ,     //  
 dgram:
    

 - var UDP_PORT = 8888; // ^  $   

 
  
  var udpServer = dgram.createSocket('udp4'); // Z$

 . // UDP-
var broadcastAddress = '192.168.0.255'; // ˜ 

# 
 
  %
 - // .
"  "   
//        
=.=.=.255, 
   //      


     " -
function udpBegin() {
 . ' %
 "  udpServer.setBroadcast(true);
"     
 - console.log('Z UDP $ ');
 %  ,   
- }
 
   $ 
 
  "   
 function readMessage(message, sender) {
  . *

,  console.log(sender.address + ':' + sender.port +' sent:
IP-
%  
%

 ' + message);
192.168.0.1, %
 "  }
"       
udpServer.bind(UDP_PORT); //     UDP

 192.168.0.255.
udpServer.on('listening', udpBegin); //    UDP
&     " - udpServer.on('message', readMessage); // \
//    '  UDP
        ,
     ,  $ //     :

  
    - var data = "  ";
 ,       udpServer.send(data, 0, data.length, UDP_PORT,
    , "  broadcastAddress);
UDP 
     -
   " : udp.send(),

 , 
    -
" ,  
 


   :

Пишем код скетча, ожидающего сообщения UDP и отвечающего на него


# "   Arduino - /*
  "  UDP       $ UDP
: Arduino

 8888      .
*/
2
    MKR1000
      
- #include <SPI.h>
  ESP8266 (

   #include <WiFi101.h>
    WiFi101  // #include <ESP8266WiFi.h> // Š   -  ESP8266
// $  R 
  ESP8266). =
-
#include <WiFiUdp.h>
   
    #include "config.h"
     .
344 Глава 7

9    - WiFiUDP Udp; // Z$ R$     WiFiUDP
       const int port = 8888; // ,     
//  

 ,    
setup(),      - void setup() {
 , —    
 - Serial.begin(9600);
   

 
- //   '      Wi-Fi,
 Wi-Fi. *      while ( WiFi.status() != WL_CONNECTED) {
    Wi-Fi   Serial.print("   '      : ");
  ,      
 " Serial.println(ssid); //   R   (SSID)
. 0
     WiFi.begin(ssid, password); //   ' 
,     
   delay(2000);
}
    
 
  
  
       // '     ,   R 
config.h ( 
  $    //   
:
-  
 " 
- IPAddress ip = WiFi.localIP();
). 0    $ Serial.print("IP-: ");
      
 - Serial.println(ip); Udp.begin(port);
"    ,   - }
   UDP, 
" -
  "    UDP,
     WiFiUdp:

Z loop()   - void loop() {


"   UDP    // †    ,   

,  
  node.js if (Udp.parsePacket() > 0) { // +  
// - :

  %
 "  String message = "";
" . Serial.print(": "); // +  R 
//  

     UDP Serial.print(Udp.remoteIP());
      - Serial.print("   : "); //  
Serial.println(Udp.remotePort());
   TCP.   
while (Udp.available() > 0) { // +  
UDP 
   - //   

  ,  
 message = Udp.readString();
 
    
 . 
 }
    $  
- Serial.print("Z : " + message); // +
//    R
      . sendPacket(message); //  
/         }
parsePacket()    }
WiFiUdp,    
-
      . # 
" $     -
  $      
" . 2  "
  Stream (  $  -
 readStream())   
 "  ,     -
   TCP    -
   
:
Бессеансовые сети и двоичные протоколы 345

7  sendPacket() 


- void sendPacket(String message) {
     . & %  - // ^  
:
   
      Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
Udp.print("   : " + message); // -  
IP-
 
, 
 -  

 

 " - Udp.endPacket(); //     
 . 0     %
- }
 "  ,  
 
"  ,    
  
  " :

    ,  "   &      


,  
  

 UDP       - "  


,     
"     
 TCP.   " :
  "     
-
%. 
      beginPacket() Z UDP $ 
192.168.0.4:8888 sent:  
     Wi-Fi    
-
192.168.0.3:8888 sent: Received:  
  " 
     
,          endPacket() 2  
 
     
-
 
%   , $   -  —    , 

  
 
 
   . &       %
 "   "  .
 . &
 
 —  
 

. 4 
    
 
 -
2
   Arduino     -
       $  ,  
          "      . ;   $ 
 -
 
 
.   Arduino 
   

   %  ,   -
IP-
,    
 
    -      .
   " "  :

  '      :


* "   
 

 %-
myNetwork
 "  ,  
 —  
Connected to wifi 
, 
     " -
SSID: myNetwork  . /    ,     

-
IP-: 192.168.0.3    
    
signal strength (RSSI):-36 dBm "   "  
 
 -


,  
      
-
; 
        

-


 "   node.js.

 "   node.js. &   


 Arduino   
   "

           -
"  :
   
 , 

: 192.168.0.8   : 8888  . & 
    
  -
Z :     $ 
UDP  
  
 %-
 ,    sendPacket ()  

3
 "    IP-
 %   
 

,   -

. 3 
   
 
-    %   
 ,   
 -

 "  .  %
 "  
 .
346 Глава 7

Программа netcat
= 
  
  UDP- "   * 

 netcat     % ,  
  
   
   
- 
  
 %   "  .
      POSIX    - &    , "   

 

    
 netcat. / 
 " ,    "
 
  
   TCP-,  :
  UDP-  ,     
- $ nc -u 192.168.0.4 8888
   ,   
  . /   
    
      
-   $        -
       . "    % <Enter>. 


    ,       
' 
  $ 

    
 " , 
  
"  , 
  %

 -   .
"   node.js,     "  -
       
 (     0
    ,  
 
 " -
    
 
,   ,  -     Arduino " netcat,   

       


,    
  "      
$

    
 8888): 
 
,  8888. /      , 
$ nc -u -l 8888  netcat 
  "   
 8888
 , 
       
* Raspberry Pi $  , 
 , - 
, 
   
.
    
   sudo:
$ sudo nc -u -l 8888
*
  
     


netcat
   -
 . *

,
  ,  $       
-  Linux %
 "  "  
-
 

, 
       -   
     -b,   macOS
  
 ,  
       ,    
 %
 "   -

 % 
 8888     "  
  . 
   -
" "  . 0 -u   , 
 
 $ 

  
     
 UDP,  - ,     :
 -l —    
 %   $ man nc
" "  ,  
 " -
. &   $       

 netcat 
    Windows,

(Raspberry Pi, BeagleBone  . .),  " 
    -
      


  
- 
 
  Windows, 

-
  
.   


    ,      .   Net
%
 "   "     -  Cygwin   bash  Windows 10,
   
    
 - 
     $   -
 
   "   :      -
,  

 
 
 netcat.

4        
    ,
 
        

 
 ,  
       



. 9 

 

"   -
    % <Ctrl>+<C>.
Бессеансовые сети и двоичные протоколы 347

Перенаправление вывода в сообщении UDP



 

 netcat,      POSIX ;  
   macOS
"    
   
    Linux,    
     POSIX.
UDP       
. 
 $   

   
-
  

       -      Net  Cygwin    -

  " 
:  bash  Windows 10, ,   -
,  
  
 Windows.
$ echo "&  " > /dev/
udp/192.168.0.4/8888
  
 node.js 
  
& $       echo      POSIX, ,     ,   
$
  

     
  /dev/    
     
udp/<IP->/<>, 
 
  UDP. *        
  
 
 ,    . 
      UDP   
/  
 ,    
  ,       
 
-
   

   
  - 
.
"  UDP. *

,     date:
$ date > /dev/udp/192.168.0.4/8888

Проект 13
Сетевые светильники
Протокол UDP удобно использовать для реализации сетевых проектов, в которых большое коли-
чество устройств выполняют обмен данными между собой или с сервером, причем такой обмен
осуществляется нерегулярно и в течение короткого времени. В этом проекте мы создадим набор
мерцающих сетевых светильников, которые обмениваются сигналами друг с другом, когда над
каким-либо из них проводят рукой.

* 

 Wi-Fi  


 -          . #  
   —     
  -     "    
 
  
     %  
 "  UDP:    %     -
    
. &      
  %
 "   "  UDP,

     $  
 ,  -  
    
      -
 
$ 
    ,  - . #"    
  -
    
 . 2    
-      

. >

   $ 
 . 
 UDP,    
 

     ,  
#    
   -   
 
 ".
"    , 
  


   
  ,   +   
 UDP      -
 
    (
 . 7.2). 4    -    
$ :    
 
 
 ,               %
 "-

     , 
         "  . &  ,  

       . &   ,  - UDP 
 
      .
      
   , /   ,     , 
348 Глава 7

     "  .


&   
        
Требуемые компоненты
  
 
%

, 
  =     (     -
  + 
.   $       6,  % — 30) -
    
  ,   
 :

 
     , ,   ,
    $   
  - 
 Arduino MKR1000,  WINC1500, 
 ,   

       
   ESP8266.
 
 $. 3      - +       : Wi-Fi,
"         , - 
 / ,   /
 %      
  
  .
TCP,  
       
+ 

  
Sharp GP2Y0A21YK,

    . 1 %.




    WS2812
(NeoPixels), 3–7 %.
Рис. 7.2. Сетевые светильники

>         %  
-
, 1 %.

>
 
   3,3–5 &, 1 %.

7   
  
 10 ,
1 %.

†   
 -     

10 , 1 %.

#       ,  


   ,     
-
  
 . `   
.  
    % %     
$ ...

Схема устройства светильника


       
     -
" 
 

    Wi-
Fi  
 


    
WS2812   Worldsemi.   Adafruit

     

NeoPixels. # 
   

  SparkFun  Seeed Studio. = 

   (RGB)   
   (RGBW)

 $  . = 
  -
    
    
,  
  
"      
-
            ,
   
  %   -
        (« »
Бессеансовые сети и двоичные протоколы 349
 " )     
 

.  %  1 &. /   ,  
  ,  -
> 
   
2  $  -      $   -
      
: https://learn. ,   
 % 1 &,  
 
adafruit.com/adafruit-neopixel-uberguide.       
 .

   
     ,  + 

  
,  

     
 

.
 . 7.3–7.5,   

  
&  
  MKR1000 (
 . 7.3) "  10  80 ,  
 
 "   
    , $    Wi-Fi  
  $
        -
   
   ESP8266 (
 . 7.4  7.5).    "   
 
&   
           0  5 &.    
 . *   
    $     ESP8266  
 
      
 .   
 , 
 %" 1 &, 
  
   ESP8266          
  -
    (  ADC  
,   %    $ 
    SparkFun,     
   
  .   
Adafruit),
 
  
 
-
 . 7.4,  ,      
  -
  
      -
2
  ,        . 
     , 
 %

Рис. 7.3. Монтажная схема проекта сетевых светильников (версия для платы MKR1000). Слева здесь показана LiPo-батарея,
обеспечивающая электропитание всех устройств проекта. Емкость батареи должна быть не менее 800 мА, а еще лучше —
1200–2000 мА. Это необходимо для питания как электронной части проекта, так и самих светодиодов, потребляющих значи-
тельный ток

A B C D E F G H I J
1 1

5 5

10 10

15 15
2000mAh

20 20

25 25

30 30
A B C D E F G H I J
350 Глава 7


 $ 1 &. * 
    $ 470 0. 0  
   
 ,
  
 

, 

  -  

 
 $ 
 ,  -
      
  "   
 
 
   
 
,   
 ,    - 
      
  , 
      
 .  , 
 ,      , 
      %  .
=    
,     -
 NeoPixels,    
   
  =   
   
   
5 &,    
,       %       ,
  

   
  4,5 &,    
       . =

 
  33,    3,7 &,
 
    
 
   
-
    $    
 LiPo.   NeoPixel Jewel   Adafruit, -

 
   3,3 &   
,   - 
     . &   
 
 

"
,    
 -        ,
  
 

,          ,     -

         " 
 
"  
 

     
.   . 0   ,    
NeoPixel   
  60 


    
   
  5 & - , $   ,  %    -
  Adafruit
        -         
        -      , 
 
 NeoPixels    
 

 
    .

    
 
 

Рис. 7.4. Принципиальная схема проекта сетевых светильников. Максимальное рабочее напряжение аналогового ввода плат
на микросхеме ESP8266 (обозначен ADC на платах компаний SparkFun и Adafruit) составляет 1 В, поэтому используйте делитель
напряжения (см. его схему справа), чтобы уменьшить напряжение, подаваемое на него с выхода инфракрасного датчика рас-
стояния, до допустимого уровня

+3,3 В
Напряжение Для плат на микросхеме ESP8266
питания (Vin) +3,3 В используйте делитель напряжения,
чтобы уменьшить максимальное
выходное напряжение
Вывод Напряжение питания (Vin)
A0 инфракрасного дальномера
до величины, не превышающей 1 В

Общий +3,3 В Напряжение


питания (Vin)
Модуль 10 кОм

+3,3 В
микроконтроллера ADC
Вывод

Программируемые Напряжение
светодиоды питания (Vin) 220 Ом
(NewPixels) Общий
Выходные Входные
данные данные
D5
Общий

Общий
Бессеансовые сети и двоичные протоколы 351

OFF
ON
- +

A B C D E F G H I J
1 GND GND 1
3V3 VIN

SDA 5

SCL 0

5 DTR 4 5
TX 13

OFF-ON RX 12

5V XPD

NC ADC

10 GND EN 10

3 x AAA 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

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


= 
      - 
 
numPixels  neoPixelPin 
   NeoPixel   Adafruit.            -
>        
  -     (
 ,  
 — 
  
  Arduino. 
    ")  
  -
          
 -   ,  
     

 "   ,   , 


.     
 
   
  
.   . & 
    (NEO_GRB)   
  ,     NeoPixel
Работа с библиотекой NeoPixel  
  . = 
 
      RGB (
 ,   ,

 ,        
  ),  
 —  GRB (  , 
 -
NeoPixel, — $  
 %  -
,   ),    , 
 -
 :
  RGBW (
 ,   ,   ,   ),
   
  
 ,   ,  -
Adafruit_NeoPixel candle = Adafruit_
NeoPixel( . & 
         
numPixels, neoPixelPin, NEO_     GRB  GRBW. + 
 
GRB + NEO_KHZ800);       
 
 
352 Глава 7

 , 
     ? 
 
         -
 . & 
      
 -           -

   (NEO_KHZ800)      -   %  
  
 — -
     , 
      ,      HTML:

  
   . & %   candle.setPixelColor(( , #));
    
  
&   
     -
800 q.            

 . *

,    0xFFFF0000
X                 
    -
  :     
 . 4    
-
     
   
?          :  ",
   , 
 

 ,      :       
 .
candle.setPixelColor( , &  "        -

, $
,  
);      
   %  -
=  
     $ 
   .
     
:
candle.setPixelColor( ,

, $
,  
, 
);

Познакомимся с библиотекой NeoPixel поближе


= 
  , 
   ? 
 : 0xFF0000

   NeoPixel — 
  - ?   : 0x00FF00
  
        . ?   : 0x0000FF
X % ,  
    
-
, 
        , 2     
  "  
  ,    -    ( )        0 
 . 255 (0x00–0xFF  %  
  
 ).
*

,    0x2375FF   

      HTML,    -   .
          -
" 
:


         /*
  
   -     -  
: Arduino
   ,   -
*/
 ,      . & 
   .show()  - #include <Adafruit_NeoPixel.h>
       -
  
 ,  $ const int neoPixelPin = 5; // +    
const int numPixels = 7; //   $  -  
      

Adafruit_NeoPixel candle = Adafruit_NeoPixel(
         numPixels, numPixels, NEO_GRB + NEO_KHZ800);
 .   .clear()
    0x000000    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    $  
-            
-
    . # 

    -   
     .
  
      

 . *
      ~
 
      (
 -
   
      - ,   ,     ,    -
        "  -   )   4-     
    
  
 
  . $  ,     ,
-
9 
  " " $ 
 
.      
   . 
     
 
 
      
 " 
 , -  , 
       0xCB500F,

 

       -  
    , 
     -
 
   ,   
 

  0x853E0B,  
  
   % 
   
 %   
 ,        "
  "      - (. 7.1). +        
-
,     $  
 . +   
  

  
 ,
 $ $ , 
  
 -        "   
  (   
        ,      
-

 
   
) % - "  
      "


 $  
            %     
             .
  . 
 $      

     —   
    
  Таблица 7.1. Составляющие текущего
  
. 2       - и целевого цветов
            Красный Зеленый Синий
 . 
  
     -
Текущий 0xCB 0x50 0x0F
 

 
    "  -
        . 4  
 Целевой 0x85 0x3E 0x0B
354 Глава 7

9       
 ,    (

    ). 2   
 
    "  "    -     
     -
"  ,    
  
.   
,    
   -
/     
   "        %  .
        ,   -      
     -
    
    ,  - "   
  .  
   %   . /     -   
    
 -


     "    . '     ,  
     

     
     
  %       
  ,
4-           .     
  .
;   
 
  byte

Пишем код для сравнения составляющих цветов

# "       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; // Z    
     $   //   


    
  byte targetG = thatColor >> 8; // Z    
   
. 7 
  //    

$       byte targetB = thatColor; // Π 



   
   -
// + -  #  
:
:
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

Битовый сдвиг и побитовое маскирование


'         
  • AND (&): 4      ,
 -
           -   1. & 
   $ 0:
 
  . 7 Arduino 
   1 & 1 = 1
            : 0 & 0 = 0
// Š   $   : 1 & 0 = 0
myBit = bitRead(someByte, bitNumber); 0 & 1 = 0

• OR (|): 4        1,



// Š $  $   :  1. & 
   $ 0:
bitWrite(someByte, bitNumber, bitValue);
1 | 1 = 1
& 


  
       1 0 | 0 = 0
       
 3,     0 — 1 | 0 = 1
 
4. $ "    0 | 1 = 1
  :
• XOR (^): 4    
   ,
-
   1. & 
   $ 0:
//      $  1:
bitSet(someByte, bitNumber); 1 ^ 1 = 0
0 ^ 0 = 0
//      $  0: 1 ^ 0 = 1
bitClear(someByte, bitNumber); 0 ^ 1 = 1

+       


  
  # "  ,  
 , 


 . ; 
       
          

  
. /     "       ,    "  

:

     
,      -
 C, Java  JavaScript. 0


   (<<) 0b00001111 & 2; // $ 
// 0b00000010,  2
           ,
0b00001111 | 0b10000000; // $ 
 
  (>>) —     
. // 0b10001111,  143

0b00001111 << 2; // $  0b00111100 *



,      
 ,    
0b10000000 >> 7; // $  0b0000001            
 -
  "   
 
    
/  
    : NeoPixels    " 
:
0x00FF00 >> 8; // $  0x0000FF //  $  
 $ #:
0x0000CD << 16; // $  0xCD0000
unsigned long myColor = 0x1A3CFF; // 

0
       ,    // #  -$

   
       
   - unsigned long green = 0;
  ,  $ 
    $ 
  . //  $  $ 
:
green = myColor & 0x00FF00; // $ 
_  

+ (AND), +_+ (OR)   - // 0x003C00
" +_+ (XOR)      -
     . ; 
  -
 
   
 
: &   $    
  
      

3
0  . Setting the bit.   
        -
4
0  . Clearing the bit. .
356 Глава 7

Активация вспышки светильника


&   
  $ 
  — "   
,      -


     
 -    
   
 % 
 — 
      : 
    . /    -
      ,    -  

       ,
     , 
 %  
   
    
 " 
-

    , 
  
   . X
      

 
  $     
  %
-         ,   -
 "   UDP- "  .   $ 
-
   triggered  
  -
    
  triggered   -     false (). &  "  
 true (  ),      ,    $    ,      
 
  
   %   .        
     
+    
 
  -  . #  
  $ ,   
   
!  
   
. & -  
 ,   ,  $     -
%   "  triggered  
% 
 .


"  
 %
 "  

Собираем все части скетча воедино


#
      /*
  
%  .  Z
  
: Arduino
  ,    
*/
      
config.h, 
"    #include <SPI.h>
(SSID)  
 ($  #include <WiFi101.h>
  ,    
 "  // #include <ESP8266WiFi.h> // Š   - 


): ESP8266
// $  R   
#include <WiFiUdp.h>
#include <Adafruit_NeoPixel.h>
#include "config.h"

=     


- WiFiUDP Udp; // Z$ R$     UDP
  
  IPAddress destination(192,168,0,255); // IP- $ 
const int port = 8888; // UDP-
  UDP, %
 "-
   
  
  const int neoPixelPin = 5; // + 
  "  .    //     
 

      const int numPixels = 7; //   $  -
  NeoPixels:   //  
// Z$ R$     NeoPixel:

 

  
 -
Adafruit_NeoPixel candle = Adafruit_NeoPixel(
      numPixels, neoPixelPin, NEO_GRB + NEO_KHZ800);
 ,    $ 

candle   NeoPixel:

2      key- // ž     #  RGB- :


Colors  
      unsigned long keyColors[] = {0xCB500F, 0xB4410C, 0x95230C,
0x853E0B};
 ,   
  
unsigned long currentColor = keyColors[0]; // ƒ 
#
    
. //  
Бессеансовые сети и двоичные протоколы 357


  target  - unsigned long target = keyColors[1]; // ž,  

    
     //   -
 , currentColor —  
- long lastFadeTime = millis(); //    $  
// #
  "   ,  lastFa- long interval = 30; //    - (30 )
deTime —  
    - int threshold = 500; //  $   
 
    . boolean triggered = false; //    $  #

 ,    
 -
 interval   
  -
 % 
 (30 -
   
%
),
threshold — 
 
-
      -
   ,  triggered —
  
   -
:

[  setup()     void setup() {


     - Serial.begin(9600); // \ #  $    '
// $
   $ 
 candle
candle.begin(); // \ #  $   R$  candle
  NeoPixel. 2  //    NeoPixel
"   .clear() candle.clear(); // +'   
      , candle.show(); //    -  
    "  
//   '      Wi-Fi,
.show()       -
while ( WiFi.status() != WL_CONNECTED) {
  . [  .show() - Serial.print("   '      : ");
     ,  Serial.println(ssid); //   R   (SSID)

        WiFi.begin(ssid, password); //   ' 
 . //  
delay(2000);
}
0       setup()
        : // '     ,   R 
     //   
:
 
  ,    IPAddress ip = WiFi.localIP();
Serial.print("IP-: ");
$
 IP-
  
-
Serial.println(ip);
 UDP- : Udp.begin(port); // \ #  $   UDP-$:
}

[  loop()     void loop() {


        int sensorReading = analogRead(A0); // Z  $ 
   

   //    :
if (sensorReading > threshold) { // †  

  , 


  
- //  $ ,
   
    - Serial.print(sensorReading); //    R
. 4       % if (!triggered) { //       

   , 

- //   
currentColor = 0xFFFFFF; //    #
     triggered.
4   
  false (), -
      (0xFFFFFF) 
358 Глава 7


   "   - //     UDP- $ :
 currentColor  
  Udp.beginPacket(destination, port);
UDP- ,     
 - Udp.print("ping");
  
  triggered  - Udp.endPacket();
  true (  ). triggered = true; //     , 
//       
}
  
     -
}
       -
 
     
  


, 
    , 
%
-
" $   :


    loop(), //  #     30   :
% 
  "   if (millis() - lastFadeTime >= interval) {
        . = triggered = false; // M   $  #
//      false
   
 "
  millis()   - if (currentColor != target) {
 
 %  30  - // + -   #  # # :
 . 4   "     currentColor = compare(currentColor, target);
 
 ,      - } else {
 compare(), 
  - // +  $   keyColors  $


// #:

 (  
  - int next = random(4);
     loop()). 4  target = keyColors[next];
 "        - }
 ,  
     
     keyColors:


   loop(), // M  # -  :
   for     for (int pixel = 0; pixel < numPixels; pixel++) {
     ,    candle.setPixelColor(pixel, currentColor);
       ,  - }
candle.show(); //    -
   .show().   $ //     

    
  lastFa- lastFadeTime = millis(); // Z-   -
deTime  " 
, 
- //   
"    millis(),  }

    "   :

2
%    loop() // †    ,   
    " if (Udp.parsePacket() > 0) {
String line = "";
UDP- "  . 
 
// †  UDP-,   :
         while (Udp.available()) {


 
    line = Udp.readStringUntil('\n'); // Z 
.parsePacket(),  " //      

 
 
 
 - }
IPAddress sender = Udp.remoteIP(); //  
,   , "   // IP-  
.available(),  "  . Serial.print(": "); // +  R IP-
&   , 
   //  
Бессеансовые сети и двоичные протоколы 359

     .avail- Serial.print(sender);


able()     " - Serial.print(", Z : "); //    
,    - Serial.println(line);
if (line == "ping") { //    "ping",
   .parsePacket(),
currentColor = 0xFFFFFF; //   

   
  // #   
IP-
 
 
 . }
4  "      }
ping,         } // # % # loop()
    .
//      % # compare()
2
%      com-
pare(), 
  
-
. #
  
  
    loop()  
-
     
 -


:

2


  
 
-
         %
 

    ,  
    
 
,  
 

 
   
 
,   - 
 . *
 . 7.6  
-
  
 node.js, 
" %
-  "       
  
-
 "   "  , 
   
 .
 $ 
 . '    
-
      ,   "  $ +   $       -
 
  "ping". 
 
  -    ,     
 -
     —             . + 
   —
        "  
  -     ,      
-
 , 
     .  
 
. &
 ,   
 
# 
 node.js     " - 
 33  333     

    .   . 3 
  
%   
    ,     
&    
    
  - 
 
      
   
     
  
 -     
   —  -
 ,     


 
-     
 ,     -
       . &     
     . =

            $  "   
  -
      
 -  -  
   candle.show()    -
   
 10 ,     -  setup(),      loop():

 —    


  
 
. =      $- // +'  
#  
   ,      
 //      
     

, $, // '   
 :
     $  , if (WiFi.status() != WL_CONNECTED) {

      
  
 - candle.setPixelColor(0, 0x0000FF);
 
 
 "    $ }
 . 
 $  ,  
360 Глава 7

10 см +    
  %   
   
      -
  
      UDP-
" . +  
 %
 "-
   "        -
" $  ,   
 
,
    %
 "   " -
 
 . >%  
%
-

    IP-
      

 , $ 
  30   -
 , 
 ,    
192.168.0.2  192.168.0.31.    " -
  
      , 
 "  
   
 

   Udp.beginPacket():

int addr = random(30) + 2; //  $


//    2  31
destination = IPAddress(192, 168, 0, addr);
//  IP-
10 см

3

 
  " ,  

     $  $   .
*

,      

 -

   "   IP-
,
       %   % -
         
.



   

  -
"      
   
  
     "  
 -
   , 
 
   
   
 
 


  ,
 " 

 
  -
 
    
. / -
,     
!
#

(TTL5), %
 
    

  .
#   
,    

Рис. 7.6. Версия схемы светильника для платы MKR1000, со- IP  
    TTL,  "
бранная на макетной плате уменьшенного размера. При та-  "   
%

,
кой компоновке вся схема помещается в жестяную коробку 
   % . 
 $ 
из-под леденцов диаметром 10 см. Светодиодная сборка, изо-
лированная от микроконтроллера резиновой прокладкой, %   
%

 
 -
размещена достаточно близко к центру трубки для создания 
     TTL 
  ,  

хорошего светового эффекта, а датчик — достаточно близко  % ,         0  
к ней, чтобы край трубки не вызывал ложных срабатываний.
Батарейка находится под платой. На нижнем рисунке показа-
%

 
  .
на только сама монтажная разводка без микроконтроллерной
платы и светодиодной сборки
5
TTL — Time-To-Live.
Бессеансовые сети и двоичные протоколы 361

UDP в действии: traceroute


#      

       ,        $
 IP-
 
%
-
 
     
     
, 
 

 "  . /
  . =   $  
             

, -
   
 ,  "   tra-       
    
ceroute.   traceroute    
    "  ,      -
UDP   
 
 

 -     

 $   

-
 "  ,      
-  "    . = 
  -
 
%
 
             

 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, 
     - ~   traceroute    
 -
 IP-
 104.25.44.28). 

  -   
 UDP,      -
    , 
     IP-  
 TCP   
 


 UDP-   
  TTL,
  1. / + 
. &
 , 

%


  
"   
  
  
%
-  
  -  
 
-

,  
 
, 
  . 7
%


   
     ,
 
 , 

  
     traceroute,  -

%
. 2  
   UDP-   
-  
 ICMP6, 
    
  TTL,
  2. /   
   
-   ping.
  
%

  " , 
 $ 
-      traceroute 

 
%

 
 
     TTL,    
 UDP- " ,      

   "  
"     
    
    
 
  -

 
%

,      

-  , —    
   
 
  
%
. / 
 
 
           " "  .
  
,  traceroute     -
     . ; 
,  
 6
ICMP, Internet Control Messaging Protocol — 

   traceroute 
    
 
- 
" "  [ ] + 
.
362 Глава 7

& 
     


   *  -   www.yougetsignal.com/tools/visual-
  traceroute      -a, - tracert 
     

 

 
       
 traceroute, 
 
  
%
   
   ( 
AS7). X  
 
   
  
 . ~ $  - -
 ,       
 AS      , 
      
-
https://apps.db.ripe.net/search.    ,  ,   ,
*  
%  
   
%
 "         
 
( .   2 

     traceroute)?      
   + 
 .
7
%

, % "  ,  - > 
  $  
 
      9.
  . X    
  $ -
 , $   
 traceroute  - Traceroute для Windows
 
  : * * *.
& Windows      
 
traceroute —       tracert 
7
AS, Autonomous Systems —      . 
   -a.

XBee: еще один протокол на основе сообщений


Линейка радиоустройств XBee компании Digi представляет собой еще один подход к организа-
ции связи по протоколу на основе сообщений. Эти радиоустройства могут работать в режиме
асинхронной радиосвязи для отдельного устройства или же выполнять независимые операции
чтения и записи на своих собственных контактах ввода/вывода. Они работают подобно модемам
в том смысле, что их настройка осуществляется по асинхронному последовательному подключе-
нию (то есть через УАПП). Радиоустройства XBee используют созданный компанией Digi двоич-
ный протокол связи на основе сообщений, с помощью которого им можно посылать команды по
радио, или считывать их контакты ввода, или управлять их контактами вывода.
X 
     API- - =
 XBee 
    
 XBee,    Digi    
 -  

 —   
   


" 
 
 . 
 $     
,       -
        
-   ,   .
    
 : ZigBee, Wi-Fi  . .
&  "  %  
      
 XBee   
 UDP  

 
     XBee —   ,   
   
 ,
XBee Pro S2C 802.15.4. +  
 
    %
 "  
  " -
     Digi      . 0     
 LoRa,
$  ,   
    
        6, — 

  XBee.  
 
 , 
   
 ,    "


 
   
8 (

  
 
! 

,
       
  

LoRa). #
 XBee   -
ZigBee и XBee
   :   
, 
-
;
 
 ZigBee 
          

   .
ZigBee,  
 
 XBee —   Digi,  
  "  
Inc. / 
  
. =
 
-
  
 XBee. 8
0  . Personal Area Network (PAN) ID.
Бессеансовые сети и двоичные протоколы 363
/ ,          
       
 
/ .        
 . &    , 
 $  -

 / , 
   -  
  " «» 
 
 -
    ($ 
     -  Bluetooth,
     -
 9),        ( -   
      
 
-

), 
 "   
  ,   . /   
 
  
. 3  
    

 XCTN, "  -
XBee  " X3 (UART),   - 
 
 XBee " 
-
              
 , "  -
 . =  
           


 
    Digi 
   
 
. 9 
  
   -

  
  XCNU, 
 -  
     Write   -

    
: www.digi.com/support/ 
    

 , 


product-support. &
  Select Your Product     
    Hayes AT,
for Support   XCTU,     
-     
  
  
  
-
    
.   .

* 
 
 Digi  "    =  
 XBee  
-
   
           
     

     ,     - XBee-to-Serial     


  XBee.
   Hayes AT — 
 ,   Digi 
   $   -

  

         

,     -
 . &      
 "    $ 
  
-
Hayes (,    ,   
   
  
 
-
 
 Digi)       XBee-to-USB. /,  ,   -
ASCII. + " $ 
  
 - 
USB-to-Serial,      ,
 
     
,  " 
 ,
      -
   
  . 
  
-  
  
 
-
     
  " -  XBee. *
 . 7.7,   
  
 
 +++. &     
: XBee-to-USB 
   
" 

.   ,    Adafruit  Parallax ( )  XBee Explorer -

"  
  (
 
 -   SparkFun ( ).

  
   
)  ,
     
 ASCII AT,  
  -
  
 
  
   
, Настройка радиомодулей XBee

 "     ,   
  
 
 XBee -
— 
 
(     ), " 

 XCTU     

   .   


%     Add a Radio (=
) — 
 ASCII  
 
. 7   
      
,   -
        "   OK,  
 . 
  ,  

-

     
, 
     
, 
     
 ,
  . 


  
 . 7.8. X  
 $    
 
, 
  
Hayes AT    -   Write,  
  
-
     
       , . X    
  
    
    
   
 

,  
 
9
0  . sampling.  
 
   3;.
364 Глава 7

Выбор вспомогательного оборудования


для радиомодулей XBee
*
    
 
   - •   >
  XBee 
  -
   
  
 XBee,    —  $    

           " 
  Fio v3   SparkFun,  " 
 :    Arduino 
 


(ATmega32U4)       
-
•   >
  XBee  >-  XBee (
 . 7.7, );
 —    
USB-to-XBee. *
•   >
  XBee  = —  

 . 7.7,  
USB-to-XBee 
-     
  XBee
    Adafruit  Parallax ( ) LilyPad (
 . 7.7, )     

  SparkFun XBee Explorer ( ). & -   XBee  XBee Breakout (
 . 7.7, ).
     
    3
 SparkFun XBee LilyPad  XBee
   
  
 Explorer Regulated ( 
  SparkFun:
XBee. &
 ,       
- WRL-11373)  "  
  -
 
  
 USB-to- 
 
 ,     
Serial,  $ 
    -  XBee  %
    -

  
  3,3 &. & $     .

     TX 
   - 9 XBee   Digi
 
 RX 
  ,  
. *  
  3,3 &, $,     -
  
   
  
   
  
  (   % 
XBee, %      
 XStick 
 ),  
        
802.15.4   Digi; 

   3,3 &.

Рис. 7.7. Вспомогательные платы XBee: а — адаптер XBee-to-USB производства компаний Adafruit и Parallax (слева) и плата
SparkFun XBee Explorer (справа); б — адаптерная плата SparkFun Fio; в — адаптерная плата SparkFun XBee LilyPad; г — адап-
терная плата XBee Breakout

а б

в г
Бессеансовые сети и двоичные протоколы 365
0  

 XCTU    - &
 ,   
  
 

-

   3; 
    
-         
-
       , 
- 
 XCTU. = $     

   "   
   
    

 CoolTerm  

       (
 . 7.9). 
 

      .
> ,   3;   
 
-
Примечание    
   ,    
 
 

,   
-
4  

  
  XCTU   -  
     
. 
  
,   
     

  
 
 
 

 . = $      
 
(  5)
  " . *      Digi        
-
       
-         ,  -
,        ,   
   

 XCTU. & 
 
   5,       
       
 "   
 .
.

Рис. 7.8. Конфигурационная панель при-


ложения XCTU, с помощью которой можно
просматривать и устанавливать параме-
тры радиоустройств. Измененные в этом
окне значения параметров отправляются
на радиоустройство по нажатию кнопки
Write, в результате чего программа XCTU
создает соответствующую команду АТ для
установки на радиоустройстве заданного
значения параметра

Рис. 7.9. Панель терминала последова-


тельной связи программы XCTU. Чтобы
с помощью терминала подключиться к ра-
диоустройству, нажмите кнопку Open/
Close (на рисунке кнопка имеет надпись
Close, поскольку последовательный порт
уже открыт). После этого из панели можно
обмениваться данными напрямую с после-
довательным портом радиоустройства
366 Глава 7

&   
           " ), 
 
-


 XCTU   
       
 (    


       
  +++),       :
    
     : ATDL\r
+++
#
 , 
     0,  -
+   % <Enter>    $ 
        

 %         -   . *      
     $   . 7 XBee 
     ,     
 
  "  : 
,        -
OK  %   . 9  
  16-

 
. 3

=    ,    +++ 

-     %  
  
 ,
 
    
,   -          
     $       0  FFFF.
! #

  (guard time). 4   
   
, 
 10   + 
PAN ID  ( 

       


. $, 
   )   ,   
   $ 
     :
  +++,  10      , 
ATID\r

     , 
   
-
   "  %.     
PAN
-

 3332,         
-
+,    OK 
,  -        
,    -
  
. 
 XBee 
   " 
:
16-

  64-

 
, $- ATID1111\r
 
      : 
%  -
7 XBee    $     ,
  %   ( 
 
 -
   
   :
   %  , 
 "
     ,       ). OK
& %   "  
      - 2 
   
-
 16-

 
.  
,          
 
        WR,
+ " 

    , 
     
 
 -
    : 
. ; 
, $  
 -
ATMY\r   
      
 . *

:
3   $ 
 ,   
ATID1111,WR\r
 :
ATMY1\r 0     
 
 
    
    
 

  
/            
   
  
-

1. 0
    :  \r, - 
 XCTU: 
    +++ 
-

%"  %    ,  , 
   
, 
      % <Enter>.   ,         

 WR    % <Enter>. =
; 
,    
   (      
  

 
,  
 %  
    ATCN\r.
Бессеансовые сети и двоичные протоколы 367

Проект 14
Предупреждение о наличии в мастерской токсичных
испарений
Если у вас есть мастерская, вы оцените этот проект. Подключив датчик летучих испарений
к радиомодулю Digi 802.15.4, вы сможете обнаруживать повышенную концентрацию паров рас-
творителей в атмосфере своей мастерской. При работе с химикатами легко привыкнуть к их
испарениям, что может повлечь нежелательные последствия, вплоть до летальных. Этот проект
демонстрирует, как предотвратить такое развитие событий.
2     
    
-
    
  
 . 0  Рис. 7.10. Проект, выявляющий наличие токсичных газов,
в сборе: датчик газа, шимпанзе Чарли и сервер на одноплат-
        
   ном компьютере. В качестве альтернативы радиомодулю

     
  на сервере можно использовать модуль Digi XStick (показан
Raspberry Pi,
"       справа)
   -

. &
  
  -
   
% — %  '
 
-
 
 
 — 
  
 -  
         -
 ,  
   
 
  -

 
    
    
 
   
   . /
-
           ,
   %  
    

 ,     

,  
  
 . 4  
    -
      ,  $    
  
  
 , 

      
  
.
*
 . 7.10   $   
  

   . 3 
 7.11 
   -
   
 .

Это демонстрационный проект!


* 
  
   , $ 
 

          
-
    . #     
-
    
. 0   %  
    ,  % 
 

 
   

 
   
-
"   
. *     $   -
,   
     
    -
 
 
        .
#  
   ,  -
  
  ,    

 
   .
368 Глава 7

Требуемые компоненты 
9  
  220 0, 1 %.

 
    
 
= $ 
    
 
  -
47 0, 1 %.
  . *
  
 
      ,   

- Компоненты для схемы

 
      исполнительного устройства

: 
>       , 1 %.

3
XBee-to-USB, 1 %. 
9 XBee  XBee Pro S2C  

802.15.4, 1 %.
Компоненты для схемы датчика 
+
% %  '
 
 
-

>       , 1 %. , 1 %.

9 XBee  XBee Pro S2C  

802.15.4, 1 %. Об источнике питания для игрушки

#

  5 &, 1 %. 4   % 
% 
      -

#

  3,3 &, 1 %.   
   3 & ( 

,  

  D), 

   3,3 &

+         9–12 &,   . * 
 $    -
1 %.     
,   
-     
 
   .
   $ 
 . 4  
   
    

3
   XBee, 1 %.
 
    
   ,

=
 %
    , 2 %. 
      «»   $
-

=
  
 , 2 %.      
%. &   

          

  
1 [, 2 %.
    .

  
10 [, 2 %.

#

  3,3 &, 1 %.

=  MQ-6 
   
Hanwei, 1 %. 
3
   XBee, 1 %.

3
    , 1 %. 
=
 %
    , 2 %.

# , 1 %. 
=
  
 , 2 %.

# , 1 %.
Рис. 7.11. Блок-схема системы выявления токсических газов 
9  
  220 0, 1 %.


 =
    NPN-
  
TIP120,
Радиомодуль 1 %.
XBee датчика 
9  
  1 0, 1 %.

  
100 [, 1 %.
Радиомодуль Радиомодуль XBee Компоненты для схемы сервера
XBee сервера исполнительного
устройства 
0  
Raspberry Pi, 1 %. -
    BeagleBone Green   
-
Raspberry Pi    
 Linux.
в качестве
веб-сервера 
9 XBee  XBee Pro S2C  

802.15.4, 1 %.

XBee-to-USB-
, 1 %. 7   -
Локальная
   
,     

-
сеть
 
 
 ,    
 
(  
 802.15.4) 
XStick 
-
Веб-браузер    Digi,    

USB 
.
Бессеансовые сети и двоичные протоколы 369

Настройка радиомодулей
     
   - ? ATID1111 —    PAN ID;

 XBee-to-USB. /      - ? ATD03 —     


   
   

 
 ,   /  0 (D0)    ;
  


  -

 Raspberry Pi  
  - ? ATIR64 —     
   
  100    (0-64h). 4 
 
. & 
     
 
       
,

 
 :   ,    %    ;
       
  (  

 
   - 
 ? ATIT1 —  
 
  -
    
 , 
   -
%      
 )   

 
 . ; 
, 



. 9 
 
,        "    100 -
 
     

, 
-  : 1 
 × 100     
      PAN ID ( 
 
 = 100   ;

    ). & $ 
   -
? ATIAFFFF —   
  
    
     

    
  
 

    / . *

, 
  
 .

     

   
 
  ,   - 9       
  -
      . 
 ,   "   
   , , 
      
   -  -
 
  " -
   
  +7-  .  , 
"      -
[             D0,           
  ,     
 D0
      . +  -

 ($        




). & , 


  
   -
$ 
      "     
     
 


 XCTU    AT. 
 . * 
 
-
       
    -
Z 
 
    
 -    "  :
. 7  
     
 ? ATMY02 —     


   
 
  (D0,
       
 ;
  20)    
   
? ATDL01 —  
 
 
$     %
 "    

 "   



   
    (
01). * $  
 , 
 ( 
    - ,      ,  

 PAN). ~ %      $
   

     
  ,     "  ;
 
,  $ 
  
 -
? ATID1111 —    PAN ID;
 
   
    ,   
       

 ? ATD04 —   




 . * 
 
        D0  
   -
 "  :  ;
? ATIU1 —  
 
 -
? ATMY01 —     

      / 

 ;      
. /  
 -
? ATDLFFFF —   
             —
%
 "  ;          
370 Глава 7

     
 $
- ? ATDL01 —  
 
  -
     
 
 ; 
 "   

 (
01). * $,  ,  
? ATIA01  ATIAFFFF —     
-
   ,   $

 
   
 
  
  "  ;

  ,     

 
 01 (
 ? ATID1111 —    PAN ID;
). 4   $ 
 
  
? ATIU1 —  
 
 -
   FFFF,  
 

      / 

  ,     -
     
. /  -

  $ 
   .
 
       
-
; 
, 
 
  
 .
     
  -
    
 . Сброс настроек радиомодуля
9

   "   
- ' 
   
 
 XBee   -
     
   - 
   
     (  
"  
      
. *-      , 
       -

  $
  
  ,  
   
 ),       
        %  
 , ATRE\r.
      "  :
& . 7.2 
     
-
? ATMY03 —     

-    
   



; 
 .

Таблица 7.2. Сводная конфигурационная информация для всех радиомодулей проекта


Радиомодуль исполнительного
Радиомодуль датчика Радиомодуль сервера
устройства (шимпанзе Чарли)
MY = 01 MY = 02 MY = 03
DL= FFFF DL = 01 DL = 01
ID = 1111 ID = 1111 ID = 1111
D0 = 3 D0 = 4 IU = 1
IR = 64 IU = 1
IT = 1 IA = 01  FFFF
IA = FFFF

0   
   
    1. &    +++.

   ,      


2. 0  , 
  
 
  
    WR\r.
OK. 2     "  
& 

 XCTU $      
(0  D02 — $ 
 ,  %

      
 
 Write.
 ):


     3;    -

 
  ,    - 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.

Монтаж рабочих схем проекта


&    
   
 ,  -  D0. 9 XBee     

     ,               
 
-
 
  

. &   $   -   -
 
    
   
 

 "  - %

      
 
  


 
-  . /    
  

 ,  
 Digi    - 
   9 &   %  
 -
    
   . ;  - ,   
   
 
 
  
  
  , 
     . * 
 

,   
 ,  " 
     ( 
!  ) -

 

 
 
.
 "   
,  -
 
 
 .
Схема датчика газа
Стабилизатор напряжения 3,3 В модели
=   
     
 - LD1117-33V
 5 &, $     


  5 & —  ,


- & $ 
      
-

  3,3 &   LD1117-33V. 9  
  3,3 & — 
,    -
$ 
    
  
  
     9 &  - 
 
  5 &. $ 
-
   . = $       
-          -
 
   9 &,   
   
,      
  -
$ 
  
   9–12 &.      .

*
 . 7.13  
   (  - ~         , 
)     ( 
!)    .     
 ,  
&      MQ-6,  $  -    %  ,  $   
 -
  
    
 -  
   
    . #

   Hanwei.   
-       ,   
 47 0    
 
  
     
 —
  ,    
     
     . /
372 Глава 7

К «плюсу» источника питания


постоянного тока 9–12 В
Стабилизатор
напряжения
7805 на 5 В

Вход Выход
H A

10 мФ 1 мФ
Датчик газа MQ-6
компании Hanwei

H B
Радиомодуль XBee
LD1117-33V
Voltage Reg

Вход Выход
Vcc AD0 / DIO0

TX AD1 / DIO1
47 кОм
10 мФ 1 мФ RX AD2 / DIO2

DO8 AD3 / DIO3

RESET RTS / AD6 / DIO6

PWM0 / RSSI Ass't / AD5 / DIO5

PWM1 Vref + 3,3 В


220 Ом
NC SLP

DTR/DI8 CTS / DIO7

GND AD4 / DIO4

7805 LD1117 7805


805
5 LD11
D 17
D1 7
VReg VReg VReg
g VReg
g
10

15

20

25

30

10

15

20

25

30
1

5
J

J
I

I
G H

G H

G H

G H
F

F
C D E

C D E

C D E

C D E
A B

A B

A B

A B
10

15

20

25

30

10

15

20

25

30
1

Рис. 7.13. Принципиальная (вверху) и монтажная (внизу) схемы подсоединения радиомодуля XBee к датчику газа
Бессеансовые сети и двоичные протоколы 373

   

 
   Схема исполнительного
$   . +
 
    (сигнального) устройства
    «  ». #
 
= 
      
 
            
-
(%  
 
  %  -
     
     -

  )        
 (_0#).  
     
 -
        ,  
     
  _0# ( -

 . 7.14. >
       -

   
 .    
 3  
 ,      
 MQ-6), $       
 
 XBee,    
  
  47 0, "

       

    
     
    .     
 
. 
   
   


      . &  ,  %
_0#    
    
    
     
 -
     1,4–1,7 &. /     

  ,    
   ,

 %   
  %  

 
    
  
 , 
    
 -
3 &. *
 . 7.15     -
 
      
  (  

  
  
%. 3    -

). 
  
  
 -
          
  
 . 7.13   
  -

   % 
.
  
      
  
          (
#      
  

 -
22 0),     


   
-
   
 
  
"   , 
  
, 
 -
 
"    /  -
    (
  
   
. &  +7
 XBee 
 
  
    
  ,
 
  
 TIP120,  
  
,  
    
  
).

, 
   
     

 $ 
     
  -
  :       
  -
    2,3 &.   ,   -

    ,   —   .

 
   , 
  -
  
     
 1,6 &. = 


 $     ,
&%        
- 
 
 ,  
   , $       -     . 
     

    
,          ,   -

  
       .         
 _0#,
&  
   
  -     ,    
 ,          -   
, 

    -
 
 
 (D0). ; . * 
  
    
         
 -   "  
    -

 
 XBee (  14)   -  
. #       
-
  
  3,3 &.     
,       -
  ,      .
Проветрите помещение & $  
    
 

 
 ,     -
2  
 ,    
-
 
  "  . &      
-    .   
 -
   
      -      
   
 ,  
 
"  " .     . 4   
, 
   
    
,
374 Глава 7

          -   


  
 
   
    
   220 0       % 1,5 &    
 
+3 &   
 
  
. /  -  
 .

Рис. 7.14. Принципиальная (вверху) и монтажная (внизу) схемы подсоединения сигнального устройства (обезьянки с ударными
тарелками) к радиомодулю XBee

К «плюсу» источника питания 3 В

Электродвигатель
Радиомодуль XBee
постоянного тока M
1 кОм
Транзистор
Vcc AD0 / DIO0 TIP120
100 мФ TX AD1 / DIO1

RX AD2 / DIO2

DO8 AD3 / DIO3

RESET RTS / AD6 / DIO6

PWM0 / RSSI Ass't / AD5 / DIO5

PWM1 Vref

NC SLP + 3,3 В
220 Ом
DTR/DI8 CTS / DIO7

GND AD4 / DIO4

TIP120
Darlington
10

15

20

25

30
1

5
J

J
I

I
G H

G H
F

F
C D E

C D E
A B

A B
10

15

20

25

30
1

5
Бессеансовые сети и двоичные протоколы 375




Рис. 7.15. Внутреннее устройство игрушки с изменениями подсоединения проводов двигателя. Припаяйте провода питания
для макетной платы к «плюсу» батареи, а общий провод — к ее «минусу» (поз. А). Обрежьте провода, шедшие на двигатель
(поз. Б — «плюс», поз. В — общий), и припаяйте взамен новые, подсоединенные к макетной плате

Схема сервера Библиотека node-serialport


=  


  Rasp- =  
   
 node.js
berry Pi 
     %   "  
%    ,  

  
XBee-to-USB. 
           
.  

Raspberry Pi       
- 
 , 
   -
  
. 7   
    
 node.js     -
 nose.js, 
      -    — node-serialport, 
  -
   
  
   -

.    "   
 npm, 
=    $    
  -   
  :
    node-serialport.
$ npm install serialport
  
   "  
- 
    $     
-
 ,          -   npm 
       
  ,       
   -    
   % -
   "     . *  $-  . &  - 
    -
    
    " :  $  ,    - 
 
    
   ,   - https://github.com/node-serialport/node-serial
   "  
 XBee port#installation-instructions, 
" -
       .               
$      % 
% ,  $  
.
    "  -

.
376 Глава 7

= 
  macOS, Windows  Li- /       
   -
nux           
    : open (
), close
 %
 . *  Raspberry Pi  (
), error (%)  data ( ).

    
 - 2   
  
     
      
 .  $      . ' 
  -
 ,
 
     "   — data — 
   
   -
! «$
        

     -
Raspian». .      
 
-
  ,   $ 
    
>  node-serialport 
 -    
    —  

    ,            
.
    , 
  

     
. &    , - #  "  
  
 -

      
  " -            -
   " 
: " 
:
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);

=    


   
  - & 
     
   
   
   . #    readData()      
  "
       
  ,              
-
          -       . 2    
.
      
  -
  express.js

 HTTP,   $ 
   
 " .
Бессеансовые сети и двоичные протоколы 377

Вк лючение пос ледовательных портов в Raspian


0  
,  Raspberry Pi, 4   
      

    " 
      - (
 )     
 (  
,
 
, 
          TX  RX   /
  ,      
 
 -      
),    -
 
. *    $ 
     (
 )    -
  
   
  .   -  
.        1,   -
  
     
     
         
   
  " 
          -
USB/TTL-Serial — 
  ,  
 
% -
  Raspberry Pi. =   
,  
 
 
  
    -  
 ,  
   
 
.    , 
       
-
 — 
    
 

,
#   , 
     
 ,  %   
 —         -
    Raspberry Pi " 
  
 . *    

USB/TTL-Serial, ,              ,   


        " 
 
.        
  -
>%       $   
  
 "  ssh. ;

        
 
 
         


    
    -    
  
 .
 Raspian. ' 

, 
   
 Raspian % 
,       '  
       
-

 USB        
  ,       
  ssh (   -
        
:
 $  
       
!)
      raspi-config. 2   
-
$ ls /dev/tty*
  Advanced Options (=   -
4       
 
 
 
 ),     Serial. * 
 Would
/dev/ttyUSB0,  

  . & 
- you like a login shell to be accessible over serial?
           + 
 (
          

 
 Raspian  Debian  %   - 
 
       
?)  

  
 USB/TTL-Serial. No. 2     Finish  


Raspberry Pi.   $     

         
. 4
: /dev/ttyAMA0.

Чтение протокола XBee


 $      %    
 API XBee      (-
 
 
 ,  "
 
- 
) 
,  $  
-
      
 ,   %  
  
  

 "  
 .   ,  
 .
&
 ,  
  

  
   



  
,   "  
 . [
 -


 XCTU  
  
    -   "    
  -
   
. &        -  
 XBee 802.15.4   Digi. =
  "    " : 
     $      -
 . 4      ,  $  
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
378 Глава 7

?   1 (7E) —    
   ?   12–13 —       , 
-
(       
   
 - "   (1)   (0) 
 
  

). /     
   .   $ -
   ;       
    -
?   2–3 (00  0ˆ) —

 . -
  . & %     

 
   
  
 
- 00 01   ,    
   
;    D0. 3    , 

,
00 02 (0000 0010    
 -
?   4 (83) —     
 API  )      
  
(, 
 "     );   D1.
?   5–6 (00  01) — 

" 

;           -
?   7 (1F) —  

  
      — 0x7E ( 
    -
  (+X#, RSSI10);  126),

        
?   8 (00) — %
 "           $  -
( 
     %   );  .
?   9 (05) —    
    .
7      $ 
 
 #   $ 
    
"   IT
 ;         node-serialport,
   $   
  npm, 
?   10–11 (00  01) —   / -
,      " 
.      
  . 2  
-
& %  

       
 
   $  
 
   —   D0,   -   serialServer.js.
       ;
10
RSSI, Received Signal Strength Indicator.

Читаем пакет
/  
     - /*
    "     , serialServer.js
    
     : node.js
0-7†,  "   - */
"   . ;  
 -
      
   - var SerialPort = require('serialport'); // '
//    serialport
    ,      var portName = ' /dev/tty.usbserial-xxx'; //   
     . //    
var incoming = []; // &   -  - - -

       -

   node-serialport. //  
:
2    
  var myPort = new SerialPort(portName);
   
 
 USB/
TTL-Serial. + $ 
 -
  " 

     
-
   
   -
   
. 2   

     
 -
 "     
 ,     
 
    
:
Бессеансовые сети и двоичные протоколы 379

=      function portOpen(portName) {



     %  
- console.log('port ' + myPort.path + ' open');
      
,  console.log('baud rate: ' + myPort.options.baudRate);
}
    
  
% 
 
. & $ function portError(error) {
 
     console.log('    
     
 : ' + error);
     
, - myPort.close();
   
   }
 
%      -

:
2       - function readData(data) {

  ,  "  for (c=0; c < data.length; c++) { //    #  



    
. = $- var value = Number(data[c]); //   $  

if (value === 0x7E) { // $  0x7E $
    for, 
- //    
          console.log(incoming); //   R  

,     
 //    
       0-7†,  - incoming = []; //      - 
// - -
"   " ,
} else { //  $  
   0x7E,
    
  "  incoming.push(value); //     
      $
 : // - - 

}
}
}

   
- // +$      :
   : myPort.on('open', portOpen);
// +$      - - - -:
myPort.on('data', readData);
     
   -
// +$      :
     . #
  myPort.on('error', portError);
   
     
   :
$ node serialServer.js

+   $  
 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 ]

 
 $  , -

         126
(0x7Eh  %  
  -
  ), 
     
" 
 XBee.
380 Глава 7

>%  
 
 var message = { //      XBee  
13  ,      - // " JSON:

 
  . & packetLength: -1, // $  
    
 , - apiId: 0, // \ %  API  
  
 
   - address: -1, // ˆ '   XBee
rssi: 0, // M  

   . 
 
channels: 0, //  /, $  
$ 
  —   , - //    
  
 XBee - sampleData: 0, // Š   -  

 ,   
  node. pinStates = [] // & , 
  -
js        // # %-  

 . &
 ,  
- };
     ,  
 "   
-
      .
0    
, -
      
-
 "  , 

  message. / 
-
   JSON   
-
   
 $ -
  " 

XBee:

Разбираем пакет
&   readData()  - if (value === 0x7E) { // $  0x7E $ 
   console.log()   -   
    parseData(). parseData(incoming); //   
  

2   
   $ output = []; //      -  - -
    
   } else { //  $  
   0x7E,
incoming.push(value); //      - -
  readData(). /  - // 

 
    - }
   "    ,

 
     

   . 0     -
 
     

" :

&    


 - function parseData(thisPacket) {
        if (thisPacket.length >= 13) { //     13 

      . // Z  . † R  -
 $ , 
>  
      - // $ _ = 
_
 * 256 + 
_
:
 0-7†    
 message.packetLength = (thisPacket[0] * 256) +
thisPacket[1];
13  . 4  $ ,   
// +  #     $
       - //  #  % , R $
  " $     //    # - $
:
JSON. >     $ - message.apiId = '0x' + (thisPacket[2]).toString(16);
      " //    '  %    -
 :
 " 
 : message.address = (thisPacket[3] * 256) + thisPacket[4];
// Z        :
_$  = 
_ message.rssi = -thisPacket[5];

 * 256 + 
_

Бессеансовые сети и двоичные протоколы 381

   
, //     -
 $  .
    for,   - // †        % ,
// R $     '  :
        message.channels = ((thisPacket[8] * 256) +
 .     thisPacket[9]).toString(2);

      
  // Z  # %-  
:
   ( D0  D8),   - 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 
}
}

Добавляем сервер
; 
,     
- var express = require('express'); // $


   " 
- // express:
var server = express(); // C
Š
 server,
 XBee,   
   //   
 express
 ,   " server.use('/',express.static('public')); // 


      -

. //       
public
0     $  

     
 - // \ #  $   

var SerialPort = require('serialport'); // '
  
  
 //    serialport
 -

  node.js. 2 
     -
  
 %
.
0      -
  express   
 -
. &   
 
    express
   $ 
,   

   
  :

&    
   server.listen(8080); // %



   

   - server.get('/json', respondToClient); // N 

//  GET

 
  GET:

  
     // 


     ,    

parseData()   
 - //  
   
:
function respondToClient(request, response) {
    
   -
// N



:
  
 
  GET, response.end(JSON.stringify(message));

%  $    - }

:
382 Глава 7

2  


  - ?      -  -

  
     . * $ " ? 4  , 
   
-

   
 «
»       XBee ?
$
          " ?  
  
  
  JSON: 
?     


XBee-to-USB  

   
-
{ packetLength: 10,
 XCTU   - 
 
-
apiId: '0x83',        ;
address: 1,
rssi: -33, ?     "       
channels: ‘1’, 
 " 
? 


sampleData: 1, 
    
 " 
-
pinStates: [ 1, 0, 0, 0, 0, 0, 0, 0, 0 ] }      1  10.

4         


 - 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   Z - #   $
public $ 
 . = $ : P5.js
 
      - */
 

 p5.js,   -
var sensorState = 'UNKOWN'; //    
  : var bgColor = 0; // # %  #
$ p5 g -b public
2  
    sketch.js
     

  setup()   -

 :
[  setup()  function setup() {
createCanvas(windowWidth, windowHeight); // 
   


// $  
 
   ,

textSize(24); //  $   %
%
     . 2   fill(255); //  # % 
      GET HTTP  httpGet('/json','json',getResponse); //  
      
 // $   


: }
Бессеансовые сети и двоичные протоколы 383


  

   - // • #   $  % # httpGet():
    
    function getResponse(message) {
// $     0:
getResponse(), 
 -
if (message.pinStates[0] === 1){ //   
          sensorState = 'HIGH'; //     
  ,       
 bgColor = '#FF0000'; //  # % 
  GET HTTP. [    } else { //   $ 


         sensorState = 'low'; //     

,  
      - bgColor = 0; //  # % 

 : }
httpGet('/json','json',getResponse); //  
//  ' $ 
}

[  draw() 
   - function draw() {
  $
 "  : //   %  $   ' # :
background(bgColor);
&     . *
 . 7.16 - // +  R  
text(' $   : ' + sensorState, 30, 30);
 

 
-
}
      

.

; 
,  
    -

 ,    %   - Рис. 7.16. Снимки с экрана веб-страницы радиомодуля сер-
вера датчика газа. Как сам текст, так и цвет фона окна позво-
% 
      ,  - ляют с первого взгляда понять текущее состояние качества
   
   %    воздуха в мастерской: состояние атмосферы в мастерской
  :   %,         нормальное (вверху — фон окна черный) или опасное (вни-
зу — фон окна красный)

,    
    
   -   .

9 Digi 802.15.4  


 API XBee

  
    -
  . ~
    -
  
  
 

 -
   "  
 
 
-
 

  
,   

     ,     

          -
 . & $ 
   
  
-
     
  
 
  
  
.
  
  
 

        
-
 API   
    .
7  
      

   
    -
  —     
  -
 


      -
     . &  $   $

  
  %  .
384 Глава 7


   
  
 API XBee 
      
-

  
    «XBee/    Digi — 

,  
XBee-PRO S2C 802.15.4 RF Module User Wi-Fi     , 

 -
Guide», 
   
  
: 
     10. /    
http://cms.digi.com/resources/documentation/       
    
Digidocs/90001500. 9 
 $
 
   .

Заключение
>           ,    14 — 
 API XBee), 

 
 "  , 
- 
  
 
    


"    
   
   . &   $  
  -
 . = 
 "    
  "   %
 " 
 
      
  , 
  %   —  $  
         - %     
. ; 

      . 0    , %       


    %    - 
 "  — $  % 
       
 ,  
 
  
     
 , 

  
"   
 . +  
     "  .

 
 
    "  ,
       
   
- ; 
,          -
 ,       -         , 
    " .       ,      
  
 
,   " 
#
   
  $  ,   -   
    
   

 ,    
   
        
      
  
 ( - 
: 
         -
 13     
    " - .

Свадебные свечи Тома Иго, Пейки Сю (Peiqi Su), Декинга Суна (Deqing Sun), Бена Лайта (Ben Light)
и Энди Зиглера (Andy Sigler)
/     
 
  Wi-Fi,   "  UDP  
    
"  .
Глава 8

КАК УЗНАТЬ МЕСТОНАХОЖДЕНИЕ


(ПОЧТИ) ЧЕГО УГОДНО?
К этому времени вы уже должны достаточно хорошо понимать,
как можно организовать сетевое общение объектов между
собой. Вы познакомились с пакетами, сокетами, дейтаграммами,
клиентами, серверами и различными протоколами связи. В этой
и следующей главах мы углубим наши знания, рассмотрев два часто
задаваемых вопроса: «Где я?» и «С кем я имею дело?» Технологии
определения местонахождения и идентификации имеют ряд общих
важных свойств. Вследствие этого их часто путают между собой,
полагая, что технологию определения местонахождения можно
использовать для идентификации лица или объекта и наоборот.
В физическом мире — это две разные задачи, и таковыми они также
часто являются и в сетевом окружении. Системы, определяющие
физическое местонахождение объектов, не всегда обладают
хорошими способностями для определения личности тех, кто там
находится, а системы идентификации не всегда хорошо определяют
точное местонахождение найденных объектов. Точно так же знание
того, кто находится на узле, обменивающемся с вами информацией,
не всегда может помочь узнать местонахождение этого узла.
В последующих примерах мы рассмотрим методы определения
местонахождения объектов и их идентификации как в физическом,
так и в сетевом окружении.

«Адрес 2007» от Моуны Андраос (Mouna Andraos) и Сонали Сридхар (Sonali Sridhar)
& $   
  GPS.   
  ,  -
  
           . 0 
  
'.    (J. Nordberg).
388 Глава 8

Компоненты для проектов этой главы


Поскольку предметом рассмотрения этой главы является определение местонахождения раз-
личных объектов, то большинство новых деталей в ней — это датчики.

Коды поставщиков
? 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

1 2

7
8

6
Как узнать местонахождение (почти) чего угодно? 389

ПРОЕКТ 15. Инфракрасный дальномер



"
     , 1 +. = $ 
 &      GP2Y0A21YK, 1 +.

     
    - J: 2150256, D: 425-2063-ND, AF: 164, F: 1243869,
 Arduino . RS: 666-6564
MKR1000 — AF: 3156, RS: 124-0657, A: ABX00004, 
   10  \, 1 +.
GBX00011 (3
  4#), D: 1659-1005-ND D: P11212-ND, J: 29891, F: 1144605, RS: 762-1736
Arduino 101 — D: 1660-1003-ND, J: 2239331, 
H  

, 3 +.
SF: DEV-13787, AF: 3033, F: 2520713, RS: 913-
D: A26509-20-ND, J: 103377, SF: PRT-00116, F:
9999, SS: 114990575, A: ABX00005, GBX00005
1593411
(3
  4#)
Arduino Uno — D: 1050-1024-ND, J: 2151486, 
     > .
SF: DEV-11021, A: A000099, AF: 50, F: 1848687, 
]=
  =

    -
RS: 715-4081, SS: ARD132D2P     
 

  -

.    
 " 
 .

ПРОЕКТ 16. Ультразвуковой дальномер



"
     , 1 +. = $ 
N     HC-SR04, SRF04

     
    -

 
 . / "  
 -
 Arduino . ,      
  

 
 .
MKR1000 — AF: 3156, RS: 124-0657, A: ABX00004,
GBX00011 (3
  4#), D: 1659-1005-ND SF: SEN-13959, D: 1568.1421-ND

H  



   -
Arduino 101 — D: 1660-1003-ND, J: 2239331,
 , 4 +.  
     
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 
.    
 " 
 .

ПРОЕКТ 17. Определение уровня принимаемого сигнала



Arduino-
  MKR1000, 1 +. 
" + 
 Wi-Fi, 1 +.    + -

 
  .
AF: 3156, RS: 124-0657, A: ABX00004, GBX00011
(3
  4#), D: 1659-1005-ND 
     > .
&   
      
]=
  =

    -
  
   ESP8266.     
 

  -
SF: WRL-13231, AF: 2471 
.    
 " 
 .

ПРОЕКТ 18. Геолокационные службы и протокол NMEA



GPS-

1, 1 +. = $ 
   - AF: 746, SF: GPS-1275
       
  
 . 
   GPS Bad Elf GPS Pro+   
9   
     

   -   https://bad-elf.com,
     .  
   GPS Garmin GLO —   -  
1
https://www.garmin.com.
GPS, Global Positioning System —     
 
 .
390 Глава 8


  Bluetooth Serial, 1 +. 
 >   Bluetooth, 1 +. 4 
% 
 "     
AF: 1588, SF: WRL-12580  WRL-12576
Bluetooth,     %  Bluetooth-
.
7      
  - AF: 1327, RS: 807-7742, SS: 113990026

 USB-to-Serial.

C  



, 1 +.  
-
SF: DEV-09716  DEV-14050, AF: 3309  

        
284, SS: 317990026       GPS.

ПРОЕКТ 19. Определение направления с помощью цифрового компаса



C      , 1 +. Arduino Uno — D: 1050-1024-ND, J: 2151486,
SF: DEV-11021, A: A000099, AF: 50, F 1848687,
D: 438-1045-ND, J: 20723  20601, SF: PRT-
RS: 715-4081, SS: ARD132D2P
12615  PRT-12002, F: 4692810, AF: 64, SS:
319030002  319030001 
ˆ
&    
LSM303DLH  -


ST Microelectronics, 1 +.

"
     , 1 +. = $

     
    - AF: 1120, SF: B0B-13303, P: 1250, SS: 101020081
 Arduino . 
H  


, 4 +. #  -
MKR1000 — AF: 3156, RS: 124-0657, A:          .
ABX00004, GBX00011 (3
  4#), D: 1659- D: A26509-20-ND, J: 103377, SF: PRT-00116, F:
1005-ND 1593411
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#)     
 

  -

.    
 " 
 .

ПРОЕКТ 20. Определение положения объекта в пространстве



C      , 1 +. 
   /
  , 1 +. & 

  -
   
  LSM303  L3Gxx -
D: 438-1045-ND, J: 20723  20601, SF: PRT-
 ST Microelectronics.  Arduino101 
12615  PRT-12002, F: 4692810, AF: 64, SS:
 "   
   
 
.
319030002  319030001

"
     , 1 +. = $ AF: 1120, SF: BOB-3303, P: 1250, SS: 101020081

     
    - 
H  


, 6–8 +.
 Arduino .
JD: A26509-20-ND, J: 103377, SF: PRT-00116, F:
MKR1000 — AF: 3156, RS: 124-0657, A: 1593411
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
Как узнать местонахождение (почти) чего угодно? 391

Сетевое местонахождение и физическое


Одной из самых распространенных задач, решения которых люди хотят добиться с помощью
сенсорных систем, является определение местонахождения объектов. Естественная реакция на
осознание диапазона всего того, что могут выявлять датчики, — это восторг от предоставляе-
мой ими свободы. Ведь теперь для взаимодействия с компьютерами больше не требуется быть
прикованным к креслу. Можно свободно танцевать, бегать, прыгать, — а компьютер все равно
сможет различить выполняемые вами действия и отреагировать на них каким-либо образом.
* 
  
    — $ . * $   ,       -

   ,     
  -       
 , —   
      
 ,     %   
       
 .    
 %  - 
  ,  
  
 

-

       Wireless  . /    ,    -


E911 (
 
       %       (  -
     , 
 

      !   

)   -
 

)     ,      ,   
 
             
      Wi-Fi. ;  -
  
    
,      
  
     -
   
  ,     $   
 
     ,
 . 0  
       -  "       
 . 4 
 
              -

 
 $   ,
 - 
 % 
    .    ,  
  
   ,   
    -
2 
          
   ,       , 
       
    -  
 
 ,      
       
 
 -    
 . ; 
, 
   
 . 0" 
        
        -
 
 ,    ,   -        
 ,  
 "  
 
 
 :
        
  .
    IP-
  
  -

Шаг 1: спросите человека


_   
    -          
 
      . %  
  
  
 -
*   
 $    %  —     
 , 
 

  ,  "    
    
 
, —   

%  $ 
  ,   ,  - ,  
      .
"        
   
  
 
   
 
  
     -
       ,         
 
 
-
 
   . 3      
        
. 4  
     % , 
-   ,        -
  
 ,         , — 
    , "  
-
     . 
    . &      
-
  $   , $ 
  "     % 

 :


  
     
   %   %  ,   ,   ,
392 Глава 8

 
    ,  " ,  "- ;,     ,   , 

, 
-
 
  ,    
, —  -         

  

      
 
  
,    

    -
    . *        
  
.
         , - / 
%   ,  
  
     ,    ,  
    . ;  
 ,     ,  

  -        
 "  
 -

     
. &
 ,       
 
 
  
% ,      ,

        %  
  -
   
      , — $          $-
      , 
    
 
 . #   ,  

-
    ,    -            
" 
 
       
 ,          -
 "   . 
    
 
 , -
 ,  " ,    - ,      
 ,
  
         -     $ ,  
-
,   " ,        
    
   . & $


 ,     
    -       
"  
"    
     -   
 
   
  
   
      .   . 2     " -
 %  $   
    % , 
  
   , -
           -        ,  

     
"       . ; 
  

 "    


,               ,   
          . 
      
 .

*

, 
  ,  

   9 
  
 

. # ,  -
 
  
 
 , 


-
        

-
    "    . ;    
  -    
,

    

   
 —  
     
 
  
, 
   - 
  — 
 
     
  -
    
  
   « -             "
-

»,  
  
        . '       ,
 , "   
 
            

. ' 
             ? & ,   -

    
  
  $   
  
      -
 
    —   ,  $  ,  
   ,  
     

  $
 
, —    ,  " - 
  

       "    .  . ; 

    
$       ,  -
*           
-            
 ,  
 
   
 "    ,  
      
-
" . $,         % 
  . &  ,
,     
   ,            ,     
  -
  ,        ,        ,  
-
   % 
 
 ,  
          ,
         
 " .  ",    $    % .
Как узнать местонахождение (почти) чего угодно? 393

Шаг 2: определитесь на местности



        ,   - geocoder.opencagedata.com    -
 ,   
   % 
  .     
   
 ,
_        -  "  
  OpenStreetmaps,
. *

,         
 API 
 Google’s maps 
 -
 
   
,  %
   ,        
    -  
     
   - developers.google.com/maps.
   - .   $  
 
,            - q 
  
  (%
  -
. 4      
 - )        -
    
        ,  "   
   , 
   ,   
  
- 
          
 
  . ;,   %   - 
  . *

,    
,        "    
  
   -


    —  
        ,    
       $ 
 .    
     
& $  ,      
, % -  
  
 . 0  
 

        ,            -
   ,           

, $ 
  -

  
 ,  
  -      
   $
      
. 

     "  -
 . + 
  % 
#           %        
  , 

  
      
- OpenCellID (www.opencellid.org),  -
 ,   %  
- " 

       ,  -

        .    

   
;, 
 
     %
          GPS.
   %  
  #3.
* $   
   -  *            -
  #3,     %     IP-
 
   
  
 ,   
   
,   
  
  
  
  
      . ;   , " -
 "  .    
  -       
   
          - IP-
. 
 
    
        ,      
 ,  
%
-
    . +     
 
 "   , $,

        -          
,  $    
  . 
%

,  
 , 

0
   "     ,    + 
 
 $ 
%

,
 % 
   

.    %    .
*

,  -   www.vterrain.org/Culture/
q 
     IP-
  
geocoding.html 
    

     ,      


  
   #3  


  "      ,   

 ,   

 
 
 
   
  
, 
 -
Virtual Terrain Project2. 
 ,   -  
     + 
  
 .
2

  «&
  %».     ,    IP-

 
394 Глава 8

   IP-
. &  "   
  ,    
 -

 
 


    -   
    ,    
   
            
  
   
   
 .    
 . * % ,  $
       ,    " -
7 ,   ,

     "  
 

,     
       
  -   .

         
 

Шаг 3: уточните происходящее


     ,       ,      
      
 
          - 
  —  %     
,
: 
      -  
         -
  %    $ 
  . ,  
      $

        
-     
     
-
      
  ,      . &    -

        %  -  
       
    
 , "    -   
  , " 
 
  . &  
 
   
- " 
   
 " ,   -
  
 
   
  -
   .

       
 ,
 
 
    
 - [  
    
 -
   -  

. X ,        
,  
-
 
  
    ,   
  
 
   . X 
      , 
 -      
   -
" 

   
-    
  
     -
 

     
 .       
. *

,  
   - 
  ,   
&
 ,    
     -  ,   
   
 $ 
.
   
   . +  0    
     
%  ,     ,   -         ,    -
 . +  
 
   
-     
  
, —  
   ,   - - 
 ,   
  
  -
     %  ,    
,  
      …

      ,  

-
   
. & 

 
-
  
 
 
 
      
   

    
    
.    -
,    
 - -
 
,   %     -
  ,  
     -
  ,     


$  . *

,   
 
    
  
 

. &     -
Как узнать местонахождение (почти) чего угодно? 395

35 способов определить свое местонахождение


*  
 ETech3 2004, 
   - •     

  ?
   O’Reilly,  
 

•  
     
?
    
 ~ (Chris Heathcote)  -
    
  
    - • =       ?
 
%   
     - • *   

 
" ?
   : «35   
  
    »4. 0      •     .

, 
      , 
   • *  .
 
  
  
%  . +,   -
• X /

 .
 , 
 ,  %   
 -
     -   - - • *
 .
       
%  
• *        .
 

 
       -

. 4     —     • 7         
 
-
 
 ,   "  
%     

.



    
      - • ;
   

  

-
. = 
    
-  
 

 —       ,

    $  .  "     Wi-Fi.

• 
  ,    2  . +   • GPS, A-GPS5, WAAS6  
 %  GPS.
 , 
 
  
 $ % • >%  % 
 
/  
-

 
 ,  
   
   -     .
  .
• #    7.
• 0
        
.
• #
   -.
• +    :      
 ? 5
A-GPS ( . Assisted GPS) —   ,  
-
• +        -,  - " « 
» GPS-
  . X 
 
-
     
     
-
 "   
 
  
   
 
   .
 . 6
WAAS (Wide Area Augmentation System) — 
 -
     
 
 
  
-
•    
 .   
. 9
   #3   % 
    
    
   
• +    
     -   GPS   .
 

. 7
#   
  (     ) —  

     ( " 
 )   (  ,
3
Emerging Technology Conference —  
      
, 
 
 
 ,  

"    .  )        
   
-
4
& 
  : «35 Ways to Find Your Location».  
  .
396 Глава 8

Определение расстояния
Электронные системы определения местонахождения — такие как GPS, сонар или локация мо-
бильных телефонов — сначала кажутся каким-то волшебством, поскольку нет никаких видимых
индикаторов принципа их действия. Но если разбить этот процесс на составляющие компонен-
ты, то ничего волшебного в нем не останется, и все станет сравнительно просто для понимания.
Большинство систем определения физического местоположения объекта основаны на одном из
двух принципов: измерении времени, затрачиваемого сигналом для прохождения от известно-
го места до этого объекта, или измерении уровня сигнала в точке приема. В обоих методах для
определения местоположения объекта в двух- или трехмерном пространстве с помощью трила-
терации комбинируются измерения от нескольких источников.

7  
  
       
  ,  
     -

   
  ,      ,    . 9  

  .  
      - 
 $ 
   
   
  
-
   ,   
 -          
 
       $ -  ,     . #   -
. /   , 
   , 
% %   
  
   
 -

        ,      


    
 
 -
  ,
   
    
 
  . ;,    
  

      .    
,           -

               ,       
  , $
      ,  
            -
 
             . ;   GPS 
 
   
,             .
    
 , 
   
 
       $ . & 
      
    
 "        "
*

, 
   GPS 
    
  . 2 
  
  
        
  , -    ,        
   $

 
 
 
         
   . 9  
  ,
     -      
    
  
-
 
    
 . #          . 

  -

          -    
    

 
  
    
,    
  
,    -

             


 
 
    $  .
  ,    
     -
  , 
 
     -  ,     
   
 
-
"     . 
      « »  «  »  -
 
  —   Skyhook (www.     ,     -
skyhookwireless.com) —     - . & 
  
   

 
     (Wi-Fi, GPS  
       
  
  
      )  
   
     
    .
         . 3  
  "    
 % 
,     , 

-
7  
  
    
      . 
 $  -
     . & 
      
     
-
   "        ,  
         , 
Как узнать местонахождение (почти) чего угодно? 397
     
  . ; &   
   
   
    
  
  - 
      ,   
 —
 "    , 
      . &  "  


   
 .       
  
  -
  
  .

Пассивное определение расстояния


X
  
 SRF04   
-   

   
 GP2Y0A21YK —

  
 GP2Y0A21YK   10  80 ,   
 
 

 
    
 - SRF04 —  0  3–4  
. ;  

. = 
SRF04   
-   ,    
 
 -
  ,   
GP2Y0A21YK —         
   
 
 -
    

   . =   , 
 $  %   
 
  
   
     - 
 . 0      
 
        
     
 ""   ,   
  " 
   
   -     
   
  ,
    
  
 . 0 - "     
 
  ,  

   
 
  :    
 " .

Проект 15
Инфракрасный дальномер
Инфракрасные дальномеры серии GP2Yx компании Sharp достаточно точно определяют корот-
кие расстояния, измеряя яркость отраженного от цели инфракрасного луча. На рис. 8.2 показаны
монтажная (вверху) и принципиальная (внизу) схемы подключения инфракрасного дальномера
GP2Y0A21YK к модулю Arduino. Эта связка может определять объекты, находящиеся от нее на
расстоянии от 10 до 80 см.

&   Sharp —  ,  


 
      ,
Требуемые компоненты

    
 
   
 - 
7 Arduino, 1 %.
   
      ,    +       :  -
   
   . &  -   +5 &.
   
GP2Y0A21YK,    
+ 

  
Sharp GP2Y0A21YK,
 
: www.sharp-world.com/products/de- 1 %.
vice/lineup/data/pdf/datasheet/gp2y0a21yk_e.

  
10 [, 1 %.
pdf,  
    . *  -
            - 

    , 3 %.
  

    
 
      
   
10  80 . 
  
 
 $  - + 

  

  -
  
   21,7 &¨ . &
  

  "    
 -
 — 30  ,  $ 
 
     
  
     ,
    
   . 
 . +     "   
398 Глава 8

Напряжение питания
=   

   ,  -
 
 , 
     
Uno ON
  
, 
   
  -
  
  
 

,
 
5 &. *,         -
 13   7, $   

 
 
    3,3 &.

+5 В

Напряжение питания

+5 В
Напряжение
питания Модуль
микроконтроллера

10 мФ Выход
A0

Общий

Общий

Рис. 8.2. Монтажная (вверху) и принципиальная (внизу) схемы подключения инфракрасного дальномера GP2Y0A21YK компании
Sharp к модулю Arduino. Конденсатор, подсоединенный параллельно линиям питания дальномера, сглаживает колебания на-
пряжения и тока, вызываемые его нагрузкой
Как узнать местонахождение (почти) чего угодно? 399
  %  
   
  - # "        


      
    -  
  

  
  -
,    
     
  . 2  $ 
   -
   ,  
  
 .       

  
&    ,  
 
%   " -   
    
   -
   

    
  
,   
       
   
.
    
  .
+  $ 
    
 -
~   
 
  -   ,    
     -

 GP2Y0A21YK
  4,5–5,5 &,    
  ,   
    -

  
   
    ,      
   , — 
 . &    , 
  
 -      %  
  

   , 
 
 
 -
 3,3 &   MKR1000  Arduino 101 
  - 
   .  ,
         

    
    

 

     . 0      


   —     
   -

       $   -      analogRead()  $ -



     
    
   
  
  
-

      
      .
 ,   
   
   

, 
 
      -
 
 
     .

Пишем код
/*
\-     Sharp GP2xx
: Arduino
*/

void setup() {
Serial.begin(9600); // \ #  $  
//  ' $
}

void loop() {
int sensorValue = analogRead(A0); // Z 
// $     
// $   
float voltage = sensorValue * (5.0 / 1024.0);
// +   
float distance = 21.7 / voltage;
Serial.print(voltage);
Serial.print(" V\t");
Serial.print(distance);
Serial.println("  ");
//   39   ,     
// $   .
delay(39);
}
400 Глава 8

Проект 16
Ультразвуковой дальномер
Ультразвуковые дальномеры измеряют расстояние примерно так же, как это делают инфракрас-
ные, но обладают большим радиусом действия. Разумеется, вместо инфракрасного света они
излучают ультразвуковой сигнал и принимают возвращенное эхо. Показания датчика отражают
время возвращения эха, которое соответствует расстоянию до отражателя. На рынке предлага-
ется широкий диапазон модулей ультразвуковых дальномеров, большинство из которых осно-
ваны на керамических преобразователях компании ProWave (www.prowave.com.tw). Самые
первые модули для электронщиков-любителей выпускались компанией Devantech (www.robot-
electronics.co.uk), но, благодаря открытой конструкции этих модулей, сейчас их предлагают
практически все розничные поставщики электронных компонентов.

Требуемые компоненты X


  
  
 
  
   ,    

7 Arduino, 1 %.
     
       -
+       : 
    ,          
   .    
      

X
  
HC-SR04, SRF04  % 
 
 
  . *

,
   , 1 %.  SRF04        -


      
   -    
   70° (  -

 , 4 %.     "     
  $   )
   3–4 . #   ,  -
#"    
    
-   
    %  , -
   
,      -    ,
  

  
  
 Devantech 
 
   " 
% 
.
SRF04,           *
 . 8.4      

 
 (       "

 4×4  
,   
 $ 
   
HC-SR04). &  -   
. 
 $     -
 , 
  
,  
- ,  
  
 -
,          ,         % 
 
-
  (trigger)    
  
  , — $     

  (echo). 
 
     -        
.  
 
    
      
" 
      
10 
  ,   

  - 50   ,     
  -
    
  ,  
  
   
 250   .
       
   
 -
  . 
   
   -   /   


    
             
   3,3 &,

 . =      
   $       /  
  

  
     . Arduino 101  MKR1000,    

-
*

,
      $ 
-        
   5 &, 
  58, 
      
,  
     
  -
  148 —   . *
 . 8.3 
     5 &,    
 
-

   ( )     ( ) 


  USB.
    
 
HC-SR04   Arduino.
Как узнать местонахождение (почти) чего угодно? 401

5В 5В

Напряжение
Модуль питания (Vcc)
микроконтроллера
Вывод активации подачи
выходного сигнала (Trigger)
Цифровой вывод 4
Вывод приема отраженного
сигнала (Echo)
Цифровой вывод 3
Общий

GND.
Echo
Trig.
Общий

Vcc
Uno ON

Рис. 8.3. Принципиальная (слева) и монтажная (справа)


схемы подключения ультразвукового датчика HC-SR04
к модулю Arduino

Рис. 8.4. Измерение расстояния в двух координатах с использованием ультразвуковых дальномеров. Квадрат на каждой
схеме представляет комнату размером 4×4 метра. Для того чтобы обеспечить покрытие всего пространства комнаты, нужно
расположить несколько датчиков по ее сторонам

Измерение расстояния «спереди-сзади» Измерение расстояния «слева-справа»


Датчик 1

Датчик 4 Датчик 5

Датчик 3 Датчик 2
402 Глава 8

Пишем код
# "     - /*
    
, 
- 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  


 

Как узнать местонахождение (почти) чего угодно? 403
   
   
-  Bluetooth  %  ,  
  
   
    ,  
 $ Bluetooth —   . 
     "-
  
 
    
 -  
,  
  , -
    .    . & $  ,     -
 
,   ,      
0    
  
      
      
. *
   
     ,   - 
 ,      $ %   -
  %  ,    $        ,  , 

,
-
 ,

  - 
  
  .  ,  

 MAC-
 
-
*

,      
 , -  (   
 
  
         
 , -   "  ).


, ,    


-

Рис. 8.5. Активное и пассивное определение расстояния

Основное
Base устройство
unit (sensor) sends out
Ответный сигнал, излучаемый (дальномер) излучает сигнал,
Response signal generated by signal,
мобильным устройством затем принимает сигнал,from
reads reflection
mobile unit
(например, (e.g., cell
сотовым phone).
телефоном) отраженный от объекта
mobile object or person

Исходный сигнал,
Initial signal излучаемый
generated by
основным устройством
base unit (e.g., cell tower)
(например, базовой станцией)

Пассивное определение
Активное определение Passive distance ranging
расстояния
Active distance ranging
расстояния
404 Глава 8

Проект 17
Определение уровня принимаемого сигнала
В проектах с устройствами Wi-Fi главы 4, в проектах с устройствами LoRa и Bluetooth главы 6
и в проекте с использованием устройств Digi 802.15.4 главы 7 мы познакомились со свойством
этих радиоустройств, заключающемся в индикации уровня принимаемого сигнала8 (ИУПС). Эта
характеристика предоставляет нам информацию о том, какой силы был последний принятый
устройством сигнал. При отсутствии преград сила принятого сигнала обратно пропорциональна
квадрату расстояния от приемника до передатчика. Таким образом, если мы знаем силу прини-
маемого сигнала, то можем приблизительно установить расстояние до передатчика.
*      «
  », 4      
  
-
    
 
   - , 
    ,  0 > — $ -
" +X#  . &   
    "  ,      -

           -      0 >       ,
 
   ,   
 
     %      
     

  
 . 3 >  . '     
  ,
3            -          
 ,
     
%,    
-       %
   . &  -
   
 
    
    
,         
 
 

   . 
 ,    
 
 
   , -
 ,  
   
  %       
   

    
 ,  
  
   
  
.
    - 
" 
 -
. ;   ,  +X#   &
 
 , 
  
  

   , "   
,   
 , -
  
  
   —   " 
    
  
  
 % —
   
    -  . &   
 Wi-Fi    4
   
.     , 
   
MKR1000  ESP8266,   
 
#
   
        "  

:
  (>). & ,   -
long rssi = WiFi.RSSI();
 
        –65 >.
 $      
   ? 0  3 
 
  LoRa    6  -
    
   -   $   
 

  -
%     "    >.   

:
'        >, 
int rssi = LoRa.packetRssi();
   
  . *

,
1  "   
   
- = ,  
  
 Bluetooth LE
   log 1 >.   log 1 = 0,  1 & = "     "      -
0 >.  "         

   
  "  -
1 &, 
  >      0. *
- "  

 node.js:

, 0,5 & = (log 0,0005) >  –3,01 >.
=
 

: 0,25 & = (log 0,00025) >  console.log('signal strength: ' +
peripheral.rssi);
–6,02 >.
#  
 
  Bluetooth  
8
0  . Received Signal Strength Indicator, RSSI. 
        
-
Как узнать местонахождение (почти) чего угодно? 405
 
    
,    +   

 

 


   
  
   
- node.js, 

       
 
  $      -        
   -
 
 .
        p5.js.  

 

   
 
 -
* ,  
     
-    
  
  POST:
 
  Digi 802.15.4    7    POST /rssi/value
    
    "  Digi
API "  " 
 :  value         .
#


     
 
 -
message.rssi = -thisPacket[5];
   
  ,      
&   $        -   " 
 GET:
      
   
- GET /rssi
  
     
  
 
.

Создаем сервер ИУПС


 
 ,   
  /*
node.js      - Z \M Z

     
  : node.js
*/
    
     -
 server.js. ;  ,    , var express = require('express'); // '   
      
 - express:
   express: var server = express(); // C$ " server,
// $     express
$ npm install express var rssi = -100; //      
//  
2       -

  rssi  
  -
      
   ,
     :

2  
     - function postRssi(request, response) {
 
 
 : rssi = request.params.rssi; //   $ $
// $     
getRssi()  postRssi(). /  response.send("   $  \M Z: " + rssi); // 
      
- //  
     
. 
 — response.end(); //  ' 
}
postRssi() —     

POST,  
    
  function getRssi(request, response) {

      // Z$     
   URL-
 
 . // ˆ     meta
3 
 — getRssi() —   var message = "<meta http-equiv=\"refresh\"
content=\"3\">\n";
        var message = "    $  \M Z: " +

  
    - rssi + " Π<br>";
 
    
   message += "     -  ";
if (rssi <= -60 ) { // Z      
 
:
message += "  ";
}
406 Глава 8

if (rssi > -60 && rssi <=-40 ) {// ^ 


//  
 
message += "   -  ";
}
if (rssi > -40 && rssi <=-20 ) {
message += "   -  ";
}
if (rssi > -20 ) { //  
 
message += "   
  ";
}
message += "   " // Š #  
response.send(message); //     
response.end(); //  ' 
}

*    

 //   

    
 - server.listen(8080);

  GET  POST. &   
//  
     $  :
 
 : server.get('/rssi', getRssi); // GET /rssi
server.post('/rssi/:rssi', postRssi); // POST /rssi/value

= $

  
   
 
Рис. 8.6. Вывод в окне браузера результатов работы скет- 
         ,  
ча, получающего сведения об уровне силы радиосигнала
от только что созданного нами сценария сервера ИУПС.      
 
 
Сервер может выводить значения уровня принятого сигна-  % 
 " 
 . 
 ,
ла не только устройств Wi-Fi. С таким же успехом можно соз-  , 
" 
 GET   
дать клиента, который будет получать от сервера значения
уровня принимаемого сигнала радиоустройств LoRa, или
   "    ,   
Bluetooth, или любого другого радиоустройства, обладаю-     , 

 
щего возможностью измерять величину уровня принимае- $    . 7   
  
-
мого им радиосигнала. Если такой клиент может осущест-


     
     
влять вызовы HTTP POST, он будет работать
          
 
  

  .

# "     


 HTTP POST
     ESP8266  MRH1000,

 "     
 
-
  , 
  
 
 

 

      Wi-Fi.
=
 $   
   
    
 . 

 -
  



 $  

  
 . 8.6.
Как узнать местонахождение (почти) чего угодно? 407

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


;  ,    
 " - /*
   ,    RSSI HTTP Client
Context: Arduino, with WINC1500 module
        */
config.h, 
"   

     - // include required libraries and config files
#include <SPI.h>
   
. 3



#include <WiFi101.h>
(   
 %
) //#include <ESP8266WiFi.h> // Š   -  ESP8266
     
%  // $  R 


. [  setup() - #include <ArduinoHttpClient.h>
#include "config.h"
    
%

 Wi-
Fi    : 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()  


 void loop() {
     
 HTTP HttpClient http(netSocket, server, 8080); // Z$
//   HTTP
POST. &     : 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
 $        
- " 
 
  (
%

 Wi-Fi),
 

        -  
 $      


  


. 2  
  


. =    -
    
 
 
: http://   
 

  


localhost:8080/rssi,  
-    
    
 
 -
 
  GET. = 
 "  
-  
%

 Wi-Fi, 
  
-
 



    
-  
  
 

  .
408 Глава 8

Множественное отражение сигнала


#
 , 
 
 "  
 
- 
 
  , "   
 -

      
%

 Wi-Fi           $ 
 -

 "  
    
,  -    
" 
  (
 . 8.7).
     
  
     *

,    
%


      
  .  
 

    ,
-
*         
 ,  
  
 

   
        
-  , 
   ,  

  
   .    
%

. /  -
     %
   
# 
 
 
     %-   
    -
  
  
      
 -    , 
" 
 
    $    -
  .

Рис. 8.7. Эффект множественного отражения сигнала. Отраженные радиоволны создают эффект наличия фантомных радио-
маяков, которые приемник не может отличить от настоящего радиомаяка. Это вызывает ошибки в вычислениях, основанных на
уровне мощности сигнала
Actual
Настоящий
Beacon
радиомаяк

Фантомный
Phantom Фантомный
Phantom
радиомаяк радиомаяк
Beacon Отраженный
Beacon
Reflected Отраженный
сигнал
Signal Reflected
сигнал
Signal

Основной
Primary
сигнал
Signal

Здание Здание
Building
Building

Приемник
Receiver
Как узнать местонахождение (почти) чего угодно? 409
;    
   
   -
      ,     
"   
   , 
   - %  
     ,  
    ,    
 
%  
      .
     %. $,   - &  
   GPS
 $ -
       ,         
      
% 
 , — 

,  ,    %
  
%         % -     ,       %
     
   , $ 
     
  
  
   
     . 0
  
     , 
    
,  
 
 -
 
     " . &    $-   "      -
 $            
 .

Определение местонахождения методом трилатерации


Определение расстояния предоставляет информацию о том, как далеко в каком-либо одном на-
правлении находится объект от точки, из которой выполняется это определение, но не предо-
ставляет полной информации о местоположении объекта. Расстояние между исходной точкой
и целевым объектом определяется кругом с центром в исходной точке (или сферой — в случае
трех измерений). Наш объект может находиться в любой точке этого круга.
$,  
          
  
. 4  

 -
   -  

 
 
  ,         ,  
 
     % ,   
 -   ,      -
  . '"               (
 . 8.8). = 


    
 
    ,
   ,   
 
   
 
 
,  
  . /   -        
  $

Рис. 8.8. Трилатерация на плоскости: расстояние от точки до объекта определяет круг возможных местонахождений объекта
(слева), расстояние до объекта от двух точек сужает возможное местонахождение объекта до двух точек (в центре), а расстоя-
ние до объекта от трех точек определяет точное его местонахождение в одной точке плоскости (справа)
410 Глава 8


 
. &     
    
   GPS.  
   -
   ,  "   
-        
  ,  -

,      ,                 

   . 7    
   
    
   

    ,    


 ,  
 . >%  
   GPS  -
  $    ,  -       %   ,
  
   
 .   
 % 
  
  . #   
    -
&      
     -        ,  
 (GPS)     

    Wireless E911,    
    -
   2 . 7              
,
     
   
 
 

        -
     "  
 .       
   
     -

    
    , 
  -  
      $   .

Проект 18
Геолокационные службы и протокол NMEA
Хорошей новостью для пользователей системы GPS является то, что им не нужно самостоятель-
но выполнять вычисления трилатерации или триангуляции, поскольку это делает сам приемник
GPS, который выдает пользователю его местоположение в виде географических координат (ши-
роты и долготы). В системе GPS используется несколько протоколов для приемников, но самым
распространенным из них является протокол NMEA 0183, разработанный ассоциацией NMEA9
США. Практически все приемники GPS, имеющиеся на рынке, предоставляют данные по этому
протоколу, а также обычно еще по одному или двум другим протоколам.


,         -
Требуемые компоненты  GPS. *  
%  ,  
-

GPS-
   ( .
     -   
    
   GPS.

     ), 1 %. *    ,  
 
  

Bluetooth- Bluefruit (       ,   , -, -
 
  GPS), 1 %. 
  
 NMEA. $
        $ 
-

>
      Bluetooth
 Bluefruit (      
  GPS), ,    ,   
 -
1 %.  GPS 
  .

&  " 

  
  -
NMEA 0183 — $       
 -     GPS-
  , -

. >%  
    -  %  
    
   ,          %  
 " -

  RS-232  TTL. # 
  
   
  GPS-
  . *  
-
  NMEA 0183    4800   GPS-
       
 
 ,     
    
-         ,
  
 
 . 
 $        -
NMEA 0183                
  GPS
9
NMEA, National Marine Electronics Association — *     
 $ 
 .
Как узнать местонахождение (почти) чего угодно? 411
Рис. 8.9. Модуль Ultimate GPS Breakout компании Adafruit (справа), подключенный
к ее же Bluetooth-модулю Bluefruit (слева). Чтобы получить качественный сигнал GPS,
нужно находиться на открытой местности, для чего более чем удобно использовать
беспроводную передачу данных и батарейный источник питания. Комплект радио-
устройств Bluefruit содержит разъем для подключения батареи, который можно при-
паять к радиоустройству, что позволит питать от аккумулятора LiPo как само радио-
устройство, так и подключенный к нему приемник GPS

FIX
3.3V
EN
3Vout
STS

3Vo
V

VBAT
GND
DSR

>RX
DTR
<TX
Vin

FIX
TX
RX
GND
VIN
PPS


%    . ;  
   - Разбор предложений NMEA
    Garmin, Trimble, Bad Elf
   
. 0     - 
 NMEA 0183 %    
   
  GLO   Garmin 
 ,  
   GPS    -
 GPS Pro  GPS Pro+   Bad Elf. ~      
   -
  
  
  GPS 
. 
   GPS   Adafruit 
 "     
  , SparkFun      
 -
  
  
        Bluetooth "

   Bluetooth  
   Bluefruit (   
 . 8.9)    
-
 
 
      
 ,     " 
 USB/TTL-
     
 . Serial. 3   
   
 
GPS   Garmin  Bad Elf   
-
*
       
        
  

GPS, 
    
 - "   
  Bluetooth.  


. *
 . 8.9   Ultimate 
          

GPS Breakout   Adafruit,  

  
 
    -
      Bluetooth- Blue-    
. 
    $-
fruit, 
        2.  
 (
    
 
 
&   $  
 
    
  9600    ) 
 
-
  ,    
  
  
  
 
      -
GPS GLO   Garmin  GPS- 
       
   ":
  Bad Elf.
412 Глава 8

$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         « »     
 
,   
  -  ,    10–15  

      . * 
   .

   
    -
, 
 —         
  
  
 NMEA -

  , 
 —  
   ,         
  
  
 . .  
         
 
   "     

 ($),  
     $    
  
 -
 
 
 . 2    "   . / 
 

  
-
  
 
 
 ,
    

  "    
 ,
 .     
 
  -  «7
 %  - »   2.
     (*),  
  -
  
  ,     
- * 
   
  

 
-
 
  
 
. 
  
  
  

NMEA, 
    

 -
9 
  

 
  $GPRMC,      
   
  .
   
     

& %        
 -
  (       
 %
-   GPS    
   -
). #
"  RMC10   
    
      , 

    ,  $ 
  -      
  

 -

  
    -  % ,   
 

. &  

         HTML5   
     
. /  
  -     
     , 
-
  
, 
   
        :  
  
  
 . + 
, -  
  GPS- 
 ,   -

"    
 , 
    
      "
 . 8.1.  ,        Wi-Fi
  -      $
3 
  $GPGSV (GPS Satellites in View11)  . 4     
   
      . ;
   $ GPS,  
    

 — -

        - 

, 
 p5.js     
 -
 GPS     . 4    % ,  ,    
  
  NMEA
   
, 
   GPS         ,   $  

  
      . *        
 API
  
 " , $    HTML5.
10
RMC, Recommended Minimum specific —  

      . /  


      
11
#  GPS     .     
 Bluetooth  

Как узнать местонахождение (почти) чего угодно? 413
Таблица 8.1. Информация, содержащаяся в предложении $GPRMC протокола NMEA
Идентификатор сообщения $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
трольной суммой, а между магнитным склонением и режимом,
которые в этом предложении отсутствуют)

 %  GPS-
   "  
 - X 
   
   Android 
-
  
   iOS  Android. 
 -          

    
 GPS-
       %  
   GPS,  
  Garmin  Bad Elf  
  
     "  "
 
   iOS, $ 
    -    
  Bluetooth GPS, -
        ,
     
 https://play.google.com/
   $  %   
  GPS, store/apps/details?id=googoo.android.btgps.
     
  
   GPS.

Выбор оборудования GPS


*
 
   %
  
  
 -   

  
 , -
 GPS (
 . 8.10),    
   
   
: https://www.sparkfun.com/pages/
, "      
  - GPS_Guide. & ,       
. = 
  
  , - 
   GPS  
 

, — $
 

     
  
.          : « »  «-
 » (« »). * 
  
 
 

>% 
 
 
  
   GPS 
   GPS    "     -
  
 

 
     ,   
    
-
       
  TTL  
-           
 .
 NMEA 0183. $      

 

        ,  - &     
   GPS   -
%  ,
   . 9  $ ,  
   GPS GLO   Garmin ( .
   ,  ,   
%     
 . 8.10, ) —    %

-
GPS,  
      
     ,        
 ,
   (  ,   % ,   % ), -  "     Bluetooth. &  
        (  ,     
  $  
       -
% ,   % )   
  $

 -  
 

     GPS,
.   SparkFun 
   %
      
  
  
   GPS,    
 
 %    
 .

12
GMT, Greenwich Mean Time —
 
  q
 .
414 Глава 8

а б в г

Рис. 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, 


   %  
  &   
     -


. =    "   -    GeolocationServer,    — -
       $  
-  public  
      
  getCurrentPosition(),     -  
  p5.js: index.html, sketch.js,  
        —     p5.js. &
     

watchPosition(). & 
 
   $ p5-manager $     "  -
    
   
 - "  :
   success  failure   options
  . +   $   $ p5 g -b public
       

     - $ cd public
"       p5.js. $ p5 u

&  
,        #
  index.html 
  — $ 
   -
 
  API 
    
- 
  
   p5.js, $  -
 ,   
   
       
   
  , -

  HTML, 
" $  
 . 
  %  
 .   -
7  



%    - ,            sketch.js,
    
  , 
   
         " .
    
 HTTP, 
 
$ 
   
  
 

HTTPS, 

  %
 
  .
Как узнать местонахождение (почти) чего угодно? 415

Определяем местонахождение
*        - /*
  
   
 - š# 
 "   
  Context: p5.js
label,        */
JSON     options 

  
 
 
- var label = "    $ # ...";
  . var options = {
enableHighAccuracy: true,
&   setup()    , timeout: 10000,
    

%
 maximumAge: 0
 
        
. };
>%

%
  -
    ,     - function setup() {
//      -   '
       
- //   
   %    - createCanvas(windowWidth, windowHeight);

. * , 
    fill('#A3B5CF'); // Z- 

  watchPosition() - textSize(36); // $   %
   
  . textAlign(CENTER); // +    #
& 
 
   
- //     #
     
  navigator.geolocation.watchPosition(success, failure,
 :      %  - options);

, 
    %- }
 , 
 
  
 ,   , 
   JSON    :
[  draw()   % function draw () {
           background('#0D1133');

      : text(label, width/2, 100);
}
[  
    function success(position) {
success()     var coordinates = position.coords;
   , 

  var now = new Date(position.timestamp);
   "   
  label = '+  :'
label. &   JSON options + '\n˜  : ' + coordinates.latitude.toFixed(5)
       + '\nŠ: ' + coordinates.longitude.toFixed(5)
(HighAccuracy)    - + '\n+ - ' + coordinates.accuracy + ' .
Š: '
 ,   $     - + '\n' + new Date(position.timestamp);
 %
   
 - }
  
   
.toFixed()   " function failure(error) {


. 
      label = '   ' + error.code + ': \n' + error.message;
 %   % - }
   "

.
[  
    fail-
ure()    "  
%  
  label:
&     . #
    

     

.
416 Глава 8

Предоставление файлов по протоколу HTTPS


  %  

 ,      keys       -
  , 
"   : domain.crt  domain.key. 
   — $
 
 API, 
     
  
,  
 —
 
HTTPS,  
   % 
   % 

, " 





,
" $ 
.   %
     . 3 
-
2         % 
- "  
   


     .         %
-
  
 .
0
 
 HTTPS,   
-
, 


 %
  -


 , 
    


  
     

 

. Для систем под Windows


    %  


 


   ,   
 HTTP,   

 Cygwin   bash  Win-
   ,    
 
 - dows 10 
   openSSL. *
%
  .    
 -  
    
  - 
    ,      
 
   Linux 
   
     macOS,    
   -

,         . *, 
 Windows. +    $

   - 
    %
- OpenSSL  
  macOS 
 
,
  - %  -  , 
   Linux.
  
   

 7        
(     
  $ 
- 
 Raspberry Pi.
 
   — . ! «4 
HTTPS
 

 »).

# "   

    - # ,   
  


 
  GeolocationServer   

. 
   ,    , "


 node  
      npm      express.js:
https-server.js. #     -
 keys  
 
. ' $ npm install express

     -
 , 
     
   2  
    https-server.js   

       "  :    "  .

$ openssl req -newkey rsa:2048 -nodes


-keyout keys/domain.key -x509 -days 365
-out keys/domain.crt

& 
  
 



  
   
  % 

     .  



 
      %  -
  ,  $ 
  
    . &
   
Как узнать местонахождение (почти) чего угодно? 417

Создаем сервер HTTPS


*%

 
 - /*
      
- Z HTTP/HTTPS

 
 HTTP  
- : node.js
*/
 
  HTTPS. 
 
      // '    "   :
express,     - var express = require('express'); // '   
   
 node. // express:
js: http, https  fs.     - var https = require('https'); // ƒ     HTTPS
var http = require('http'); // ƒ     http
  — fs —    
var fs = require('fs'); // ƒ     filesystem

    - var server = express(); // Z$ " server,
    : // $     express

= 

 HTTPS var options = { //     HTTPS

   
 
,  -
key: fs.readFileSync('./keys/domain.key'), // '
" ,   
-
cert: fs.readFileSync('./keys/domain.crt') //  % 
  
 , - };

    " server.use('/', httpRedirect); //  % # '
  fs.readFileSync(). //    $ http
server.use('/',express.static('public')); //   ,
//  '    %

=
      
  express.static(), 

 $   
 HTTP


  

HTTPS,       
httpRedirect:

2  
     function httpRedirect(request,response, next) {


  redirect. / if (!request.secure) {
  

 ,    console.log("  $ http  $ 
 $ https");
 " 
 
  response.redirect('https://' + request.hostname + request.url);
HTTPS,     ,   - } else {


    

- next(); //  $ % # express.static()
  
 HTTPS. 3 " }

  HTTPS 
- }
  
  

  express.static():

* ,   

. //   :

 $      http.createServer(server).listen(8080); //   $


HTTP,  

// HTTP
HTTPS. #

HTTPS    https.createServer(options, server).listen(443); //  
// $ HTTPS

  
 443:
418 Глава 8

=   $



  %      % 

  ,  
macOS  Linux         




. X  
sudo  " 
: ,

% 
 
 
 
( 

Chrome   "  
 
$ sudo node https-server.js
  
  Advanced). &
 -
2 

, 
   - 
- 
  %  
  index.html.

     
 
: http://
localhost:8080. #

 

 2
 
 , 


 ,  
$ 
  

   
 HTTPS, 

%        -
. =    "

%  ,
  
  
   
  
-
  %     . *
 . 8.11
Рис. 8.11. Пример страницы геолокации в браузере на
 

  .
устройстве под Android. Обратите внимание на перечер-
кнутый префикс https в адресной строке браузера — таким
образом браузер информирует вас о том, что сервер исполь- 
     %  
   GPS
зует недостоверный сертификат (в данном случае — подпи- 
      
 
санный нами самими)
$         .
9  
   GPS 
  
 

,  
     


      
 "   
 . $
   
    -
   ,       ,  
-
  
 .

7  
 
  "

   GPS , 
  , 
  -
   ,       -
 :   % 
     -

        
? #  
 ,   
     

       GPS, 
         .
$,       
       , , 

, 
      -
     %       -
 $  
,  
 
 
  
  .
Как узнать местонахождение (почти) чего угодно? 419

Протокол HTTPS и сертификаты


    ,    
 
 

    
  $ 
  ,


   HTTP
     TCP.     ,  


   ,
  
 

   
 HTTP,   $
 
 



        
%

 
   

. 
     
%

 

  - 


  
,     -
"      %
   . _ -   " 

" "  , 
-
   
        , 

    
 
 
 -

     
. /   % 
   $ 
  . ' 



  
 
    
. ;  
  

, $  

  ,    
  
  




    
   
      ,     - 
     . 4  


 

  
   ,  $  -  

,  
 
 


  
  
  %
 -    
, 



   HTTP,      HTTPS.  "     
   
 
-
>      HTTPS      
    . &    -

   TLS13.   
 
 

  

-
 ,      
, — 
 , " "    , 
   
   

, 
    
- 
    %    
-


,  
   

 !   ( .
 . 8.11).

 HTTPS.
~ "       

-
> 
  #     ,
 !- , %     
-
#  HTTPS,         %   $  
,

    

 ,   #
  -    ,  Symantec, Comodo,

. >
    
  
- GoDaddy  GlobalSign. +     

     

 

. Z 

-    
 
      -
 
    ,     
 

  
   

    

     -  $   .
 
. &    ,   

,  -
        
     
 ,   Internet Security Research
IP-
, 
 

       Group14  
   

-
     . #
 -  Let’s Encrypt, 

 

 
-

   

, 
     . 0
  Electronic Frontier
     %
   " - Foundation 
         -
 , 
  

. 

    
  (certbot.eff.org)     -



,      
- 
   
Let’s Encrypt. 4  
 

  %
   
-    
  HTTPS, $
  . #" , %
 
    
     , 



,   
 %
   ,    .
" 
  

, 

 

.
13 14
TLS, Transport Layer Security — 
 " q
          + 
 .

 
  
 .
420 Глава 8

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


Определив свое местонахождение, интересно также определить свое положение относительно
окружающего мира. Люди обладают врожденной способностью ориентироваться в окружаю-
щем пространстве, но объекты такой способности лишены. Поэтому для уточнения ориентации
объектов обычно применяются соответствующие датчики: магнитометры, акселерометры и ги-
роскопы. С их помощью можно определить, в какую сторону света вы смотрите, а также где верх
и где низ.
Q
 
,  
  , — $         
     -

  
       
   
 (yaw). 
,   
 
 ,   
  
   - 
  
"     

   2 . 4   -  -      
 
    X, Y  Z
    ,    , -    . /      -
   
  
 
 -  — #

. 3     -
,   
  . *   $     

    
     - #
 (surge),   #
 (sway)
      $  ,     
  #
 (heave). & $
  . & 
      %         
-
        
      -     (
 . 8.12)    -
   — 
. 9   -   %   
 .  

   :   (roll) — 
          -
  
  
   ,    ,     
 
  
   
-
 
    (pitch) —      .
         (
 -
 ) 
   . * 
  
 
   -
 ,       

   — $    %  - 
   
       -
  
      -      2 . G  
    
 
   
  
    
  $ 
 . ;,           
   

Рис. 8.12. Вращения и смещения объекта в трех измерениях

Крен (roll)
Продольное
смещение
(surge)

Рыскание (yaw)
Тангаж (pitch)

Вертикальное смещение
(heave) Боковое смещение
(sway)
Как узнать местонахождение (почти) чего угодно? 421
  
   2 ,   
 
     " , 
 
 ,       
 - 
  —
  ,    
. / 

,          . \
    "      
-

 
  
"     
   
 . &    , 

    
"     - 
 
   %   " -
  
         
 
    
. 3 
 
 
  . +  ,   
Arduino 101    
 
 

-
     
   
 ,    
  
  
-
 
 
  
   ,  
 
 .

Терминология датчиков ориентации


&     ,     
 
 SPI, 
  
 -

 
 
 " 
   
        

  , $      - 
 I2C. & $ ,  
, -

 .    


 
  
 -      
 
 : X, Y
       
 

!-  Z. 0  
  Z    
 -
 
 (IMU)15,      Arduino 
    
  , $ 
 
-
101,   "
 $ , —   
      
CurieIMU. &
      "      .
   . *% 
 
 ,
 
,  
    *
       
 -
Analog Devices, Freescale, ST Microelectronics     . _   
 
  
and Bosch. =   IMU   
,     !  (/ 2)   -
  

   
  (AHRS)16,   
     g (1 g =
        
!- 9,8 / 2). X 
  
     -
 ,    


 (MARG)17    (
/ ).
  
 6-
    (6-DOF)18.
#"     9-   &    
 
 , 
"    
 . *

,    
-
   
 $ ,   -  
    
 LSM303  
  
  
 "  
   ST Microelectronics    
  
-
    .   Adafruit         +/–2 g  +/–16 g,  
 -
  10-DOF, "  
-       —    +/–1,8
 
     
    -  +/–8,1  . 3 
  L3GD20  
  
  
. 
  
     250
 2000 
    . ;
   -
= 
   " 
 
-           
 -
  
 . * 
  
- . = 
      -
   
   -    

      
 

"    
  , 
    2 g,   
  

   $      -       
    
 -
   
    
15
0  . Inertial Measurement Unit, IMU. 
   % .   
,
16
0  . Attitude and Heading Reference System, AHRS —
   
    
 .
 
 
  
" 
  -
17
0  . Magnetism, Angular Rate and Gravity, MARG.        

 
  
-
18
0  . 6-Degree Of Freedom sensor, 6-DOF.    250 
    ,   
422 Глава 8


  
   
  %         
-
  
   


  
 -   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     
         , -
 . 4  

  
          -

   ,           
 
, — 

, 


  Z     
 ,       
     
     
 . 
 
- :     .
"   
   Y (  ) 

Рис. 8.13. Оси трехмерного датчика. Показания его акселерометра будут такими, как здесь показано

Значение координаты Z наибольшее, Значение координаты X наибольшее, Значение координаты Y наибольшее,


координаты X и Y — в состоянии координаты Z и Y — в состоянии координаты Z и X — в состоянии
покоя покоя покоя
Как узнать местонахождение (почти) чего угодно? 423

Проект 19
Определение направления с помощью цифрового компаса
Магнитометры, которые также называются цифровыми компасами, измеряют изменения в маг-
нитном поле Земли, точно так же, как это делают обычные компасы. При этом, как и обычные
компасы, цифровые компасы подвержены помехам от внешних магнитных полей, включая поля,
генерируемые мощной электрической индукцией. Поэтому направление с помощью цифрового
компаса можно определить, если вы находитесь в пространстве, в котором нет слишком силь-
ных магнитных помех.
& $ 
    
 
  ST Microelectronics   LSM303. Требуемые компоненты
7      - 
>       , 1 %.
 Adafruit, SparkFun  Polulu. *
 . 8.13 
7 Arduino, 1 %.
    9-DOF   Adafruit,
    
    - +       : %  I2C.
  
  . 7  - 
Z
    LSM303DLH -
  
     
-   ST Microelectronics, 1 %.
  
         

    , 4 %.
 
  I2C. = LSM303 $ 

  "        
            –32,768 

 ,    "  
 - 32,767,         -
 

    
 
.     +/– 1,3  .

= LSM303   16-



%  *
 . 8.14     ( ) 
  
    
- 
   ( )    

Рис. 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 Напряжение питания (Vcc)


SCL SDA

20 20
SDA SCL
Модуль Модуль компаса
X Y Z

LRDY
LIN2
LIN1 микроконтроллера GND LSM303DLH
GRDY
25 GINT 25 3Vo
SDA
SCL
+Vcc Vin
9 DOF

GND
3Vo Общий
30 VIN 30
A B C D E F G H I J
424 Глава 8

 9-DOF   Adafruit - ? SDA —      . # -


 LSM303  
 

   $     SDA 
-
MKR1000. &
 ,   $  -  

.
    
  
Arduino , 
"  
 =
     $ 
   -
I2C.  .


   
  5 &   - =  LSM303    
-
 . *       " :   ,    
  -
    Polulu —    
 .
? Vin — " 
  5 &. # - =      

 $     5 & 
- I2C       Wire. '  -
 

;
 $  ,      -
? GND — " (« »). #   $         D  |  >

    GND 
 
- 

  | N  

 
,  -

; 
%    " A 

  
? SCL —        
-  
   LSM303,  
 

 . #   $       LSM303 by Polulu    
SCL 
 

; N  . X    ,   
-
     .

Пишем код для цифрового компаса



      - /*
     $ 
  $    LSM303
  LSM303  
 - : Arduino
*/
 compass. &   setup()
 
     - #include <Wire.h>
 ,     #include <LSM303.h>
Wire     
-
  I2C,   % $ - LSM303 compass; // Z$ R$    

compass. * ,   -
void setup() {
 enableDefault()   
Serial.begin(9600); //    ' $
  compass  
   Wire.begin(); //   $  %
 I2C
 . 
   
 - compass.init(); // \ #  $    

    compass.enableDefault(); //     

  +/–1,3  ,   //   '
   
  - }
   2 :

[  loop()  


- void loop() {
         compass.read(); // Z  $   
 compass,    float myHeading = compass.heading(); // + 
 
$   read(),    Serial.println(myHeading); // + $   R
"   heading() delay(100); // +   $  100 
    
  : }
Как узнать местонахождение (почти) чего угодно? 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 = -680;
 ,  % ,  
  - compass.m_min.y = -623;
 
. compass.m_min.z = -616;
compass.m_max.x = 422;

 
    LSM303  - compass.m_max.y = 451;
      
   , compass.m_max.z = 424;
     
     , -

  " 
   - Локальные пределы
, "       . &
  X 
      

            . #
 ,  %    

" 
  , 
    .
  
  
 " github.
X   $      

 
 
    -            -
" . 7   
"   
   %     %   .
  
 
 ,     =        
  API

       . =     LSM303      
 "
     $
   -      
 https://github.
"     loop(): com/pololu/lsm303-arduino.

Введение в интерфейс I2C


 LSM303    
   
  #   
  I2C  SPI    , 
    
  I2C19. ]
 - I2C      
" (  
-
   
  ! 
 TWI20
  
" )        
  
   
      -  
   " 
 
 
   
 -  
 .   
  I2C    
 SPI,     ! 

   2.    
  
   : 

 -
   
# 
  (SCL)21,
19 2
I C, Inter-Integrated Circuit —      
  
 
 

   
  
   .
20 21
TWI, Two-Wire Interface — 
   
- SCL, Serial Clock —     
"
 .  .
426 Глава 8


  (  
 ),  

   • <

  

 (SCL) —  ,  -
(SDA)22,  
 
   . * 
  "  
   

-
 
  
    
     
 ;
   . 
 
 
    • <

  = (SDA) —  ,  
 
-

      (          
 .
 
  ,  
   -
)    
    
 

 &  
 ,  "  
 I2C, -
 
  I2C. 3 
 
 
     "      % ,  " 

      (     $    .
! 
  ,  
    )
   
     
  I2C 
 - >  Wire 
   

  -


. &    
  SPI,  
 - 
  % I2C     Arduino
 I2C 
      
   .   
 . >%      -
 
       
,     
 , 
   
 I2C, 
 
      ,   
 
 -           Wire.
, 
      . &  I2C 
     
 ,
   Arduino   %   -
; 
,  
 I2C
       Arduino        SCL
%    (% )    
 -  SDA.

 (  "  
 )  

 
(   )  
 :
22
SDA, Serial Data —      .

Проект 20
Определение положения в пространстве
Курс по компасу — это прекрасный способ определить направление, если вы находитесь на зем-
ной поверхности. Но направление представляет собой лишь одно из условий нахождения пра-
вильного положения объекта в пространстве. Кроме направления, надо также знать, где верх,
а где низ, — чтобы определить тангаж и крен. И здесь нам помогут акселерометры — устрой-
ства, измеряющие линейное ускорение, и гироскопы, измеряющие угловую скорость вращения.
Таким образом, в этом проекте мы научимся определять положение объекта в пространстве,
используя акселерометры и гироскопы.
3 
 

    -
Требуемые компоненты   
. & 
  
 
 -

>         %  
-  
%  
, 
  -
, 1 %.  
 "     
 
 .

7 Arduino, 1 %.  
  
 
     -
       
  ,  

 
   
 
/-
$ 
      
 

 , 1 %.      .
& $ 
      
 
2     ,   
 
 -
LSM303  L3Gxx   ST Microelectronics    
 . # 
 ,  -
  Arduino 101,  "   
    ,      ,  
 
  
 .  
 
. +  
  -
 
  
 
  $    


    , 6–8 %. ("

 ,  
   
 -
 % ).
 
. 0 ,     
Как узнать местонахождение (почти) чего угодно? 427
  
,   
   , & $ 
        -

      
 
,      
   -
  
 . 3 
 
  
 - 
 
/
   

  $
   
  
   -      "    -
   ,   
    -  . 7 

 ,    
 
  , . .    
 ,
  ,    
" -

   
 .      
,

  # -
   7 (Sebastian Madgwick),
3 
 
    
%          

 , $
    Processing  
  
  
-
 
  
   - 
    $
 .
 . = 
       
 
 
        - &  "  

 
 

  2 g —        
  
   
 
  -
    $  . >% 
 . &   
  $    -

   
 ,  "    -
   
 
/ LSM303

 
, — 
    
- (
    
 "  
-
,    
 
   )    
  L3G   ST
 3–6 g. *         Microelectronics. 7 LSM303   

     %  — -  $    Arduino,    -


,    (
    
 )     
 . 8.14. 3  
 
  
 
              
    Arduino 101
      100 g!  
     
 
/
-
 Bosch BM160 ( $    
  
  ).

Снимаем показания (вариант с платой Arduino 101)


/*
Внимание! Z  -  # - $ 

   CurieIMU
/   
    : Arduino

    
- Z    $   # -
 
/
 
,  
   $ 
Arduino 101.
 Arduino 101 */

#include "CurieIMU.h"
#       -
  
 
  
 , void setup() {
 
    Arduino 101. Serial.begin(9600); //    ' $
>  CurieIMU 
 CurieIMU.begin(); // \ #  $    # -
 , 
 
"  // $ 

     
- //   $ $ 
  +/-2 g
CurieIMU.setAccelerometerRange(2);
 
, 

  -
//   $ $ 
   +/- 250 /
 g,    
 , CurieIMU.setGyroRange(250);


  
  - }
  (/ ). =
  
      - void loop() {

 (    | float x, y, z; //     -
// $
$
 
428 Глава 8

 | " A ) - float gx, gy, gz; //     -
// $
$
 
  Intel Curie Boards by Intel, // Z     $ 
     
CurieIMU.readAccelerometerScaled(x, y, z);
  (D  |  >
 CurieIMU.readGyroScaled(gx, gy, gz);


  | N  

- Serial.print("x: "); // +  R $ 
 
)   CurieIMU. //     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);
}

Снимаем показания (вариант с использованием интерфейса I2C)


=
 $      
Внимание!   ,    
 "  
 

  ,   "  -
/   
   
  - 
        L3G

 
 LSM203  
  L3Gxx.   Polulu.

#        :  - =      Adafruit  -



 
 LSM303   ST Microelectronics       ,     19 —
(
    
 "  
-     
  
 I2C.
  )   
  L3Gxx. / # "       
 
    
  -    SDA     -
 9-DOF   Adafruit,   
  SDA 
 

,    SCL -
   Polulu.   SparkFun -   —    SCL 
 
 -
        : 
 
 ( % I2C    
  
L3G4200D   
 
 LSM303.   
 ).

&      /*


Z  $
  LSM303   L3G
  Wire   
 : Arduino
 
 I2C     Z  $  $
  LSM303
 , 
-   L3G
*/
 

     

  
 . 2  #include <Wire.h>
#include <LSM303.h>
  $ 
  #include <L3G.h>
  
  accel- LSM303 accelerometer;
erometer  gyro: L3G gyro;
Как узнать местонахождение (почти) чего угодно? 429

&   setup()  - void setup() {



        Serial.begin(9600); //    ' $
  
  
 I2C,  Wire.begin(); // \ #  $   %
 I2C
accelerometer.init(); // \ #  $    
 . X    accelerometer.enableDefault(); //    
  
 
 - //  $ $ 
  ' (+/- 2g)
 : gyro.init(); // \ #  $     
gyro.enableDefault(); //      $
// $ 
  ' (+/- 250 /)
}

&   loop()  void loop() {


     , accelerometer.read(); // Z  $   
   "   gyro.read(); // Z  $    
// $ $       # g
readAcceleration()  readGy-
float x = readAcceleration(accelerometer.a.x);
ro() 

     - float y = readAcceleration(accelerometer.a.y);
  "    - float z = readAcceleration(accelerometer.a.z);
 . 0
   $ 
        : // $ $       # /
float gx = readGyro(gyro.g.x);
float gy = readGyro(gyro.g.y);
float gz = readGyro(gyro.g.z);
}

[  readAcceleration() float readAcceleration(int rawValue) {




     - // $    LSM303  16  
//    $ +/- 2g
   
 
   -
float result = (rawValue * 2.0) / 32768.0;
 g,   $      return result;
CurieIMU,    readGy- }
ro()        -
  
 . 9
%   float readGyro(int rawValue) {
16  ( –32 768  +32 767) // $    L3G  16  
//    $ +/- 250 /
 
 
 LSM303  -
float result = (rawValue * 250.0) / 32768.0;
     –2g  +2g. return result;
3

%  
    }
 +/– 250 / :

Определение направления вверх с помощью акселерометра


#
   ,      
 , -   2
   
  
 
   .   Y    $ ,
      ,
  9,8 / 2,     y > 0
  
     . 0 $  - -   3

 ,   
 ,   
 else
 
 
 ( .
 . 8.13) 
  
: -   4
  Z    $ ,
      $ ,  z > 0
 x > 0 -   5
-   1 else
else -   6
430 Глава 8

Ориентация объекта (базовый подход)


/ 
    - /*
    
 -    #  
: Arduino

  
   
 ,
   '  ,   "

  
. = $  -
    
- */
 %
     // Z'   ' $   - 

loop()   
 " // '    , "  -  -
//   % # setup().
  :
void loop() {
// Z'  -
 % #
int orientation = readOrientation(x, y, z);
Serial.println(orientation);
}

; 
 
    int result = -1; // $


  

 
   
  - 

int absX = abs(x); // Œ
 
   
. /   
 
int absY = abs(y);
   x, y  z    - int absZ = abs(z);

 
    g, 

     
 " // N


      

 
 ,  
      int bigger = max(absX, absY);

      int biggest = max(bigger, absZ);
  . =
 

if (biggest == absX) { // *    ’
  ,   -  

    
   g. if (x > 0) { // 
 
 !
    
result = 1;
2         } else { // 
 
 
    

"  , 
  result = 2;
}

  
  
 
-
}
: 
,  ,  , 
,

  . &  ,  if (biggest == absY) { // *    Y  

  
   - if (y > 0) { // 
 
 !
    y
  
    
 - result = 3;
. } else {
result = 4; // 
 
 
 
//   y
/       
- }
 
   
   - }
     
-
 
,   %    if (biggest == absZ) { // *    Z  

      
 - if (z > 0) {
result = 5; // 
 
 !
    z
. 0      
 -
} else {
 
"    
 result = 6; // 
 
 
    z

   : }
}
int readOrientation(float x, return result;
float y, float z) { }
Как узнать местонахождение (почти) чего угодно? 431

Определение рыскания, тангажа и крена


;

   
 


   
     
 -
 , —   , 
  ,  

   "   . *    -

 
,   
  . ;   , Z
   
   
  , 
X
     
  . 0  
     
   
  
-
  
  
.     $ Y
Сила тяжести
    
   
    -
    
 
   Freescale Θ

Semiconductor, 
   
  
-
 PDF  
: http://cache.freescale.com/
Рис. 8.15. Вычисление составляющих силы тяжести на основе
files/sensors/doc/app_note/AN3461.pdf. &
 угла
 ,          
 

    " .

#           


- ' 
   
    ,
 
 
   2 . $,   

      -
          © 
 
    g,   $  
-
( ),   $        X . 3   
    ,  
 ,    —     Y (
 . 8.15). 
  
    
  
 -
X 
   X  Y      
 ,      .
"  
 , 
    -
 "  
 
  
 :
Метод Мадгвика
x 2 + y 2 = z 2.
& 2010  #   7 (Sebastian
2  $,        " Madgwick) 
  
      
 
 " 
  
  
   
     -
         . # "    , 
 
    $
 
    X (Xaxis)
    ,  . 0

  $  

    sin ©,     Y (Yaxis) —  


  
  
 ,  
 ,     cos © (  ,   
     ,     -
 
  %  
    
  
 . / -
  
  
    - 

    
: http://x-io.
 ,     —  %     co.uk/open-source-imu-and-ahrs-algorithms/.

 "   ). 0 : 7     
 %
%
    $   ,  
§ Xaxis ·   
     PDF  
:
>  arctg ¨ ¸ http://x-io.co.uk/res/doc/madgwick_internal_
© Yaxis  Zaxis ¹
2 2
report.pdf.

§ Yaxis · ~   >  (Helena Bisby) 




-
7   arctg ¨ ¸
 7 
   -
© Xaxis  Zaxis ¹
2 2
  Arduino,  
%     -
432 Глава 8

   #


  (Paul Stoffregen)          D  |  >


  
  Arduino. &
- 

  | N  

 
,  -
 
        
- 
%    " A 

  

   
 
   
 -  
   Madgwick,  
 
-
   
  .    Madgwick by Arduino  -
   N  . X    ,
= 
      -    "    
 "
  Madgwick. = $      -  .

Ориентация объекта (продвинутый подход)


'     /*
   #    & 
Madgwick,   
: Arduino
$ 
 
  filter. Z  $  '      
/ $ 
   -  / 
 

  
 — */
 %    40  ,
       25 q. // Z'   ' $   - 

// '     "  -  -
=       
         #include <MadgwickAHRS.h>
   4. 2    - long lastReading = 0; // 
 

 

   
     - long readingInterval = 40; // 40  = 
  25 

 %
: Madgwick filter; // •
 
 Madgwick

&   setup()  - void setup() {



     
 // Z'  
-
 % #
  25 q: filter.begin(25); // N 
    25 
}
[  loop()    void loop() {
      // Z'  -
 % # loop()


       if (millis() - lastReading >= readingInterval) {
  ,     

 , // N 

  Madgwick

%  40      - filter.updateIMU(gx, gy, gz, x, y, z);
      . 4  // $

 
,  !  

//      #

%,     .
float roll = filter.getRoll();
[  readOrientation()  float pitch = filter.getPitch();
      
- float heading = filter.getYaw();
  $
  
 - Serial.print(heading);
Serial.print(",");
"       .
Serial.print(pitch);

  
  Serial.print(",");
  ,     Serial.println(roll);
  getRoll(), getPitch() lastReading = millis(); // N 


// 


 getYaw(),  
  }
   . &  $ }
  $
 ,
  -
  
  

    . * ,  -
    
 . &   
 :
Как узнать местонахождение (почти) чего угодно? 433

Соберем все вместе


/  Processing    /*
   
 

 Š 
& 
        - : Processing
     $    $ 
 
 
   - -        ,
     
 
       .
  

 . 0  
- */
     
 -
"        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(),   , void draw () {


    
 //  #:
 . 0       tilt(), background(#20542E);
fill(#79BF3D);
       - //     :
 : tilt();
}

#   3D  Processing - void tilt() {


// Z        #:

   
"   0  2ª
translate(position, position, position);

 . 7  tilt()  - // X —  $


    
 
 (
- rotateX(radians(roll+90));
 ,    
)  $ // Y —  
434 Глава 8

 . 0    rotateY(radians(pitch));


  Processing translate() // Z -  
rotateZ(radians(heading));
 rotate()   "   
- //  # $  :
"        - fill(#79BF3D);
       
- //     :
 
: ellipse(0, 0, width/3, width/3);
//  # :
fill(#20542E);
// + ,       ''
//  ' :
text(heading + "," + pitch + "," + roll, 0,0,1);
}
7  serialEvent()  - void serialEvent(Serial myPort) {
     ,  "  // Z   $   %:
     
 
- String myString = myPort.readStringUntil('\n');

  , 
  - // †   -  
 ,    :
if (myString != null) {
     ASCII, —  
myString = trim(myString);
  ,   $    - // $    $ :
 «* 

- » String items[] = split(myString, ',');
  2: 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 
 $
  
 
 .


"  
  
 

     ,  $ 
%  -
  
    
,    
   
     %
Как узнать местонахождение (почти) чего угодно? 435
     
 

 

 $    

 -
 Processing. &  $ 

 Processing        
   2 ,
        
 
, 
-
 %

      .
 "     
 
 .
7   ,      7-
; 
  "    .       "     Z.
7  
      % ,  &   ,      
   -
   
 
   , —       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 .
438 Глава 9

Компоненты для проектов этой главы


Основные новые компоненты в проектах этой главы — веб-камеры и считыватели меток 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

1
2
4

7
Идентификация 439

ПРОЕКТ 21. Распознавание цветов с помощью веб-камеры



     >   >  
)   = .
-  .

ПРОЕКТ 22. Распознавание лиц с помощью веб-камеры



     >   >  
J-
 
.
-  .

ПРОЕКТ 23. Распознавание двумерных штрихкодов с помощью веб-камеры



     >   >  

 .
-  .

ПРОЕКТ 24. Чтение меток RFID



D
 RFID, 1 +. 7   - AF: 359  360, SF: SEN-10128  SEN-11319,
      NFC-  SCL3711 USB SS: 113990013
Smart Card Reader   Identiv. 
     > Raspberry Pi, 1 +.
ID: SCL3711 SF: DEV-13825, AF: 3055  3400, SS: 102010048

"
RFID Classic  

Mifare. & -  114990584, RS: 896-8660, F: 2525225


     "   
  

  ,       -

  , 
 
  %  .

ПРОЕКТ 25. Чтение и запись сообщений NDEF



D
 RFID, 1 +. 7   - AF: 359  360, SF: SEN-10128  SEN- 11319,
      NFC-  SCL3711 USB SS: 113990013
Smart Card Reader   Identiv. 
     > Raspberry Pi, 1 +.
ID: SCL3711 SF: DEV-13825, AF: 3055  3400, SS: 102010048

"
RFID Classic  

Mifare. & -  114990584, RS: 896-8660, F: 2525225


     "   
  

  ,       -

  , 
 
  %  .

ПРОЕКТ 26. NFC и бытовая автоматизация



C      , 1 +. 
H
      37    -
    "3   =, 4 +. =  -
D: 438-1045-ND, J: 20723  20601, SF: PRT-
   
 .
12615  PRT-12002, F: 4692810, AF: 64, SS:
319030002  319030001 D: 36-2206-ND

      
 - 
H
      12    -
, 1 +.   ,    
   -     "3   =, 2 +. =  -
  
     
 .    
 .
A: 1609 D: 36-2203-ND
440 Глава 9


'
 "3     
 6 ,  $ 
 
 
  -
12 +. =      
 .   NFC-      DFRobot,
 "    
 X3
D: 36-9300-ND
   %   
 -

    
   , 1 +. 7 

   AVR.
        
-
    8  9   5. AF: 364, D: 1528-1781-ND, SS: 113030001

"
RFID Classic  

Mifare, 2 +.

 Arduino MKR1000, 1 +.
AF: 359  360, SF: SEN-10128  SEN-11319,
AF: 3156, RS: 124-0657, A ABX00004, GBX00011
SS: 113990013
(3
  4#), D: 1659-1005-ND.

(  WeMo  

Belkin, 2 +.
&   
    
  
   ESP8266. B: P-F7C027
SF: WRL-13231, AF: 2471 
     > .

" NFC-
 PN532, 1 +. X 
 - 
]=
  =

    -
 
    
 %     
 

  -
SPI, I2C  UART (X3). *    - 
.    
 " 
 .

ПРОЕКТ 27. Двухфакторная идентификация с использованием NFC



D
 RFID, 1 +. 7   - 

     A

      NFC-  SCL3711 USB 12 ', 1 +.
Smart Card Reader   Identiv.
J: 170245, F: 1176248
ID: SCL3711 
  )

    
 
-

"
RFID Classic  

Mifare. & -   5,5 


 +
 — 2,1 , 1 +.
     "   
   D: CP3-1000-ND , J: 28760, SF: PRT-10287, A:

  ,       - 369, F: 1737256

  , 
 
  %  .

]+    , 1 +.
AF: 359  360, SF: SEN-10128  SEN-11319,
SF: PRT-12044, AF: 65, D: 923273-ND
SS: 113990013

      
 -

     > Raspberry Pi, 1 +.
, 1 +.   ,    
   -
SF: DEV-13825, AF: 3055  3400, SS: 102010048   
     
 .A: 1609
 114990584, RS: 896-8660, F: 2525225

H
      14    -

%  
 TIP120, 1 +.     "3   =, 4 +.
D: TIP120-ND, J: 32993, F: 9804005 RS: 808-
D: 36-2204-ND
0502

'
 "3     
 6 ,

(
 
 1 , 1 +.
8 +. =      
 .
D: 1.0KQBK-ND, J: 690865, F: 9339051, RS: 707-
D: 36-9300-ND
7666

    
   , 1 +. 7 

D 
   , 1 +.
        
-
AF: 1512     8  9   5.

ПРОЕКТ 28. Геолокация по IP-адресу



     >   >

  .
Идентификация 441

Физическая идентификация
Процесс идентификации физических объектов является столь существенной частью нашего жиз-
ненного опыта, что мы редко отдаем себе отчет в том, как мы это делаем. Конечно же, мы полага-
емся в этом на наши органы чувств: смотрим на объекты, ощупываем, поднимаем и встряхиваем
их, прислушиваемся к ним, нюхаем и пробуем их на вкус и так до тех пор, пока мы не сориентиру-
емся в том, что они собой представляют, после чего навешиваем на них соответствующие ярлы-
ки. Весь этот процесс опирается на очень сложные функциональные способности наших мозга
и тела, и любой, кто когда-либо пробовал заниматься компьютерным зрением или искусствен-
ным интеллектом вообще, может сказать вам, что научить компьютер распознавать физические
объекты — задача далеко не из легких. Так же, как сужение человеком поля поиска какого-либо
предмета облегчает задачу определения его местоположения, задача распознавания объектов
посредством компьютеров облегчается, если мы можем ограничить область активного поиска,
а также тем или иным способом пометить важные объекты.

7  
    ,    -  ,    
 $ 
 

, 
    %     . &  ,  
-
 , —   $     -     
     

. 0    
        ,    
       
, -    ,     $ 


    . = -    ,    
   
    
     -            . # 
-
    
  ! 
  
 ,      

 
  


 
 (RFID1).   
%  
    
#"         -      "   ,
  : 
       
     
    
      
 
 
    . +  , "  
%
. 9      -  
    ,  "  

  
    
. RFID          —
       .
#    
   
     
    
    
 
 ,  -
          ,     
     
   


 . 0      
 %
        .
%        *

,    ,     ;,  
     
 
  
 -     . 2    
. & $  %     
 -     ,  $    
-
    RFID. *               %
-
  RFID        
    . ;,  #3   
 ,           -      ; + (Tom Igoe),
  ,       . &       *-
 ,  
 
, 


        
     . $,  
 -
  
   
,        
,    

          ,  
    — 

, 

      "   
 - 
   
 ,   -
                — 

,    :
; +, [
$ . '    
,
1
RFID, Radio Frequency Identification.      % 
    
442 Глава 9

  .    
,  %  
    
 
         
 
 , 
 
  
   
      - $
  
  . 3    CMYK4

,      , 
         
  
-
  
  . . 
,   
 
      , 
 

   
 

   
  ,    
    
     
- 
 ,    
  
 . 9 
 

       . *
 . 9.2  
-
RFID :     
   
      
        
  - 
% —    

  .
 
       , - #  " 
 
     -
        
 
         
-
 "   % . 3  
  ,  %  $  , 
 .
 $        

   "  

 ,  # 
  
 "    $  
   
       
-    
 
   -
,   
   RFID  $ -  
 ,      
 
 
-
. +      
 ,   ,       -

           .
 
. &  " 
 
   
-
#    ,       
  
  

        
   
 ,  " 
 . 
 $

 : «+ ,  !»,       -  
,       
  ,

    %  ?    
       

       RFID  - 


 
,      
  -
 , 
          
   
  USB. 

   
,   - ,    — $ %    
,            HTML5,   
 
  -
 
         

,   

 JavaScript.

,     
 . ;  4     - 
 
 
          — -   JavaScript,     
 -
         ,  $  , 
   
 , 
          .      + 
  , -

 
     .
Видеоидентификация &  " 
 
    -
&        " -  , 
  
 
-
             -  , —  
     
-
: 
   
   -      
 

 
     
   -    "    . & 
 —  -
.    
     
  — 
       -
   
    , 
   ,  
 — ,   ,
  
 "         
  — 
%
 QR5.
  . ;, 

,   RGB2  HSV3
2 4
RGB, Red-Green-Blue — 
 ,   ,   . CMYK, Cyan-Magenta-Yellow-blacK —  , 

-
3
HSV, Hue-Saturation-Value —  ,  "  , ,   , 
.
5
   . QR, Quick Response —  
.
Идентификация 443
# 
  
   
  = $ 
      
    ,   
       —      , -
p5.js.    $ 
     
     
     -
 -
,   
  

HTTPS.    . 2    $   -
&   

    
 
-  ,  
  

  "  
     

 https- "    
  .
server.js   18 ( . !. «&! 
  HTTPS»   8). *  ,   9      
     
$

 
   
 (
 ) $        
 
. $ 
 
      

  
 
  . 

     
   -  ,       
  
     
   
             -
 .
,          
    

      " ,
          
-
Распознавание цветов    . *    
9          —
 -     "       -
   
  
 ,  
    , $     "  
         

  

,     

  

 . # " $   
-   "  
  .

        .

Рис. 9.2. Пример распознавания цветов. Простое отслеживание цветов дает наилучшие результаты, когда распознаются
цвета, резко отличающиеся от фона, на котором они представлены
444 Глава 9

Проект 21
Распознавание цветов с помощью веб-камеры
Скетч p5.js из этого проекта захватывает изображение с подключенной к компьютеру видеока-
меры, ищет в нем пикселы определенного цвета и помечает их на копии изображения, которую
выводит на экран.
0          
 -   HTML 
    
 
   $  
 
  -     
 
 

 
    
% 
   
     
   .
    $ 
 . = 
- =
    ,   

    p5.js, 
" -      -
. #   -
 
      
 , ,
Требуемые компоненты     %

 $
  
 
 ,       
  
 
  
  "       
 
 -
 -
 .   . &  
   -
 0 
   . %      — % $-
   .
Пишем код
*%  
     CameraProjects.  
  p5.js: index.html, sketch.js,  
=    
   libraries, 
"   p5.js.
public, 
    18. 2  - & $ 
      


    public  
  p5.js -    sketch.js,    " 
   colorTracking. &  colorTracking 
  
      public
      ,   .
0
    sketch.js  - /*
    
  -    #   '  % #  HTML5
 setup()  - : p5.js
 
 . 
  ^    Š R ˜ % .
*/
video     

$ 
  
  API  var video; // "  $-  
 , trackColor —  
- var trackColor = [255,0,0]; // ƒ  
#
        var differenceThreshold = 10; //  $ 
 , differenceThreshold — // $ #
   
    var dSlider; // $    $ 

   
   
 ,  dSlider —   -
 
   :
&   setup()   - function setup() {
  ,    - video = createCapture(VIDEO); // M   

     video  //  

video.size(400, 300); //  $  $-


      
- // $ 

   $
 . 2  video.position(0, 0); //    $   

   video  - var canvas = createCanvas(400, 300); // ^ -
     canvas 
- // - $ 

   : canvas.position(0,0); //    -


Идентификация 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    ,  -
     
  ,   
   ",  
    , 
 -

     :

=    
  //   % # ' dist()     $ #
  $  . 9 - //  #

    
  ,    var difference = dist(r1, g1, b1, r2, g2, b2);
   "  // † $  #    - 
 ,    

 // $  $ #  #

 
  ,
    if (difference < differenceThreshold) {
stroke(0); //  
#    
    
 ,  -
point(x, y); // Z   $ #    
 
     .
}
&  
 ,
   }
        
 - }
 differenceThreshold. 4 
   % ,     
    
   -
. #   
 ,
  ,     
  
    :
446 Глава 9

2    $
    // + % #     $ R
         - fill(255);
text("  
#: " + trackColor, 10, height-60);
  
   
 
text("  $  $ #: " + differenceThreshold,
   . / 
% - 10, height-40);
   draw(): } // # % # draw()

'        // Z- #       


     
 " - //     ' trackColor:
function mousePressed() {
  %  
    ,
if (mouseY < dSlider.y) { //    $ ,

     mouse- trackColor = video.get(mouseX,mouseY); // Œ
Pressed(). 
 "    - // $  ' -   #
 $        }
 "   $ - }
  
  trackColor:
* ,  
   - // † $    , $  
   
    //   ' differenceThreshold:

  differenceThreshold. function setDifference() {


differenceThreshold = dSlider.value();
+    $  
}
     . &  
setup()    

$  , 
    -
,    

-
"      %  .
+     
 -
      
 

    differ-
enceThreshold:

Исполнение скетчей работы с изображениями


=    $      - Освещение для распознавания
   


https-server.js,  
$    
 "  :
цвета
$ sudo node https-server.js     
    $
 ,   
  -

  

 
         .  %  
  


. 2 

, 
   -    colorThreshold    , 


     
 
: 
           -
http://localhost:8080/colorTracking.            -
  
 " , 

    
- ,        (
 . 9.3).

       
   -

  

%      >%          -

. *   !,  
  - ,      

 
  
  
 . /  
 
 
       "  . = 
  
-
       
 
-    $  :
    "  
 .
Идентификация 447

Рис. 9.3. Распознавание цвета скетчем на p5.js. Пороговое значение равно (слева направо): 10, 32 и 47. Чем выше пороговое
значение, тем больше он показывает совпадений пикселов нецелевого цвета

?    
           
    ,
DayGlo6, 

    
   -   TAOS TCS34725, 
-
"  
        

     Adafruit.
 ,    
      /  
  
, 

     $     
 
  
,  -
$ ;
   
  
 ,   , -
?    
     , 
     .
 

  , —    


 
   
, -
 
  
   "  . Распознавание форм и образов
*

, 
%
    
2
          -

   
  35--
 
   (     "       

 -
 ), 

       
 , 
  
 , 
  

 . / 
       . '
  
   
,
   
  
  

     
  ,   
   
  -

 
 
 
. ; 
 
      
 .

%       
 

   ,     

  
   « »
      
;
 
 
. & ,   «»  -
?       
% -    , — $  
$.
         
 , 
   

   ,     

  . `
    
-     
 
 
 

   
   ,      -   
.
 
    
 
. 
  « »  -
   —    
  
 , 
       -   
      -
   
 —  $ 
% -    
 
 . 0
    .   Texas Advanced   
" 
   ,
 -
Optoelectronic Solutions (www.taosinc.com)  ,         
6
        ,  
#
.   . Day + Glow — 
   (
   ,
  ,   
 ),    "  
  
         "  
     " .   
,  $      .
448 Глава 9

Проблемы с идентификацией физических маркеров



     ,  %   
 
 
,   

=

 >% (Durrell Bishop)  1992 . (vimeo.   


  

,   
 !  -
com/19930744),          
-     
 . >  -
 
   , 
"   -  Apple
      '  
   

. 
   - >%,  ! 
    
 
  "    
   %- *  ,
 !#   
. 4!,

     
  .     '  ,   % !  


 %  " ,  " %
   Interval Research, 
 ! 



 
-
 
  .  %
 
 "  -  
  
!   

Dallas

   "  
,   "  Semiconductor.
"  
 ,      
 '  Z
 ,   
  . 
   
  
  

  "  ,  & %     ,    , -
     
  
     
     ,   
  .

   ,  "     


      . 0  
>% 

   
   ,      
  
  . '
     
    -
 %
, >%   
 
 -

   

,  
" -       ,  $   
" :  
,  
 
,  
  .

  ,     
 
&    !    
  
  %
       . 4   , 

,

 ( 
  
!  
 -        
  -
   )
        -  ,  
 
 "     

,         !     ,     
 -
    !


. 4
-  "       . 
 ,


  #
  
 
  -       
      ,
#
     ,   
 
 - 
    
   .
  . ]     ,

Обнаружение лиц
4      
 
 ,
-      
  
  
, -

   -          


     
   
 -
 , 
 , $ 
  "   -   
  
  
,    .
  
      . &  - Q 
 
     ! 

 ,      
  
 —   
  
    -
  , 
      
-      
     -
          
 .
 ,          , 
0 
   — 
% 


  -  
  , 
  
 
    
. *% 
  - -     " .
        
  
- # " 
    

 
%  -
 ,   " 
 
  -   
  .
 % , "  "    .
&    , % $   
  
 %     %
 ,    
       
   
-
Идентификация 449

Проект 22
Обнаружение лиц с помощью веб-камеры
Теперь, когда мы располагаем основными сведениями в области оптического обнаружения объ-
ектов, настало время попробовать определение простых образов. В этом проекте мы воспользу-
емся методами обнаружения лиц для нахождения лица в захваченном камерой изображении.

=  
    JavaScript "  
  ,    
 $ Требуемые компоненты

%   "
  
- 

  
 
. *            -
 .

, 
" 

 , - 
_.
" 
  
. &    ,
         
-
,      

, 
    
  
  build
     
   . 0


   libraries 
  faceRecogntion. /
 
,       " 
      tracking.
  
 

  ,   - js  tracking-min.js,    data, 
-
    ,     
- "      
 , 
 
. >  tracking.js 
 
.

   "        -
  : 2  
    index.html 
  face-
Recognition       <script> 
? 
      ;

    " :
? ;
?
. <script src="libraries/tracking-min.
js"></script>
# "          
  <script src="libraries/data/face-min.

   . 
  ,     js"></script>
  .
=      
  
=      public 
       eye-min.js  mouth-
CameraProjects    
   min.js. #
  $  , 
  ,  -
  faceRecognition. #
   $ -   
    sketch.js     
    ,   
  p5.js.  " .
2  
  -   https://trackingjs.
com 
   tracking.js,
  -

Пишем код
   , 
   setup() 
- $ 
ObjectTracker   tracking
      
 .  "   setInitialScale(),
2      
   - setStepSize()  setEdgesDensity()  
 canvas  
  tracker  $ -  
 
. &

  $ 
 


   
 
 -          . 7  -
.      setup()   
 $ 
 
 , -
  
 "  
 . =      
  $ .
450 Глава 9


   
 
 - /*

  
   $       #   '    tracking.js

 ,  
  - : P5.js

  
   - */
      
   -
var canvas; //    -
.
var tracker; //    R$     tracking

* ,   setup() -


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); //    ,    
}

[  draw()   function draw() {


  ,    
  - // ^   
      
  } // # % # draw()
  showTracks().  
-
 
      
- function showTracks(event) {
  ,       clear();
var faces = event.data;

   
 
for (f in faces) {
 event.data. 2    for
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      
-   


       
-
   , 
   
   %
 ,        .
 
 
      -   . # 
        "
452 Глава 9


 ,  %
 
 - 
 ,    
 . 9.5,
      
 . 
      
,      -

  
  
 %
       
  .
    ,    

 %
  
"  , 
- #"    
%
 ,
"    . #  -   
,     -
    , 

            
, 
   -
     
      , 
 
 .      

  
   
     -   ,

  
 
   " 
  , 
   
     . *
 . 9.6

         .   
%
 —
 QR. /   

  ` 
*    
  
   
   
     

-
%
 UPC7             ,     
   
       %
 
    




  
. &
 , 
  
 
. &    ,     
, "       
      
     -

 
  %
      -    
     — , 
-
  , 
  %
 
- 
,        
 
  . *

,   #3 WeChat. &  "  
   

        POSTNET p5.js         QR -
  
  . #   "   JavaScript.
EAN8  JAN9 
  
 %


    UPC  
    
- Рис. 9.5. Одномерный штрихкод (здесь приведен штрихкод
"    
  
 .  ISBN10 этой книги11)
           -
 %
 , 
 
        , -
$ 
 %
 %
    , 9 789781 680458
 , POSTNET "  



   EAN. /   ,     


  
 
 %
 - Рис. 9.6. Двумерная метка штрихкода (QR-кода, если быть
  , 
  
 - более точным) с ограничивающими пометками по углам. Эти
пометки игнорируются обработчиками изображения, но по-
     ,     - могают пользователям центрировать метку для более каче-

 ,           , ственного ее захвата


       "  
-

        

.
= 

  %



   

  ,  -
    %
 %
 
   
     .

7
UPS, Universal Product Code —  
 
-
.
8
EAN, European Article Numbering — 
  
-
10
. ISBN, International Standard Book Number —  -
9
JAN, Japanese Article Numbering —   

    .
11
. +     
     .
Идентификация 453

Проект «Backslash»12 от Педро Оливейра (Pedro Oliveira) и Суеди Чен (Xuedi Chen)
9  
  «Backslash»        
        -
   
    
  
  
     . *
 ,   -
 ,       QR-, 
" "   
 , —   
 
    
 . =     
       www.backslah.cc.
0 
   + +
 (Roy Rochlin)

Проект 23
Распознавание двумерных штрихкодов с помощью
веб-камеры
В этом проекте мы с помощью онлайнового генератора QR-кодов сгенерируем несколько дву-
мерных штрихкодов, а затем расшифруем их, используя камеру и браузер. Когда наш скетч за-
работает должным образом, в качестве домашнего задания вы можете расшифровать рисунки
этой книги, содержащие коды QR.


        QR-
Требуемые компоненты " 
,     -


  
 
     
 . # "
 -
 .   
       -

 QR.
  "   
% " 
 -

, $    
 
  

12
Backslash —     
   «
   ».
454 Глава 9

        . * 


- =      public 
 -
   
  
 ,   
-  CameraProjects    
 
   QR-     $    qrCodeReader. #
   $
  .   ,  + 
         ,   
 
  
  

 QR- p5.js. 2  
  -   https://github.
. 
    $ 
  
 com/IagoLast/qrcodejs 
  
  %       - qrCodeJS,
     
   

 ,      .  ,    qrcode.js   dist   libraries 
-
https://webqr.com/create.html   
-  qrCodeReader.
 

,    QR-
  URL, 
      
 - 2  
    index.html 
  qrCo-
   . +    
 $  ,  deReader       <script> 
  %  
     , 
    " :
  % 

       .
<script src="libraries/qrcode.js"></script>
#

    
   
   %    . #
  $  , 
  ,    -

    sketch.js       -
" .

Пишем код
q 
  $- /*
   
 $ 
’   QR  $   $ 
HTML5
: p5.js
  qrReader   -
*/

   JSON 
  . *   
 - var video; // "  $-  
   
    var message; // Z    QR
   %     %  - var qrReader; // ‰$        QR

  QR,    var config = { // %  # 
"     QR
    
  : sucessCallback: getMessage, // +$  
//   QR
errorCallback: onError, // +$     
//  QR
videoSelector: ‘video’, // \  -
stopOnRead: false //    
//    
}

[  setup()  $ function setup() {


    $    video = createCapture(VIDEO); // M   
  
 "   . //  

video.size(400, 300); //  $  $-


&    ,   
 ,  // $ 
        video.position(0, 0); //    $ 

    
  //  
  $
 . ;  
- var canvas = createCanvas(400, 300); // ^ -
     
, // - $ 
    qrReader  canvas.position(0,0); //    -

"   . 2  - canvas.elt.id = "video"; //     R  -
qrReader = new QrReader(config); // Z$ 
R$ 
  $ 
   //   qrReader
qrReader,    
- }
   
:
Идентификация 455

[  draw()    function draw() {


$
   
 - image(video,0,0); // + $   R

   "   - video.loadPixels(); //     $ 
. 4   %

 
- //   
fill(255);
   QR,     -
text("read: " + message, 10, height - 20);
"    :
} // # % # draw()

function getMessage(result) { // †     


//  QR,
message = result; //       ' message
}

function onError(err) { // +        ,


console.error(err); //     R
}


    $   
  -       
  . ;  -
  ,      
    %    
    
   .
    
 
,    -
/      ,      -  
%
  
 "

 

 ,     -   .

 ,    %. / %
          0 
       "
           
         

   

     , -
 — %
     . & -

  "      " 
 %     
  -
. &
 , $ %     %
,     
%  , 
 
   ,   
 -     
 . * $ 
  -
  
      "-   $    . 4   -
 
     

%  
  
  
  
,   
     
   QR.   %
   
 ,     ,
*  
%   

% -  $ 
         .
,   
     

  X%      %
   -
    ,     
   , 
       -
  
 

    
- 
       , 
. *     
    - 
  
 $,   
-
%, 
    

 "      . & $  %  -
 , 
     . 2      RFID  NFC   
-
       
  
 -      
 
   — 
 "  
 - QR  
   %
.
         ( .
 . 9.6).

   $    
 -
   
   ,    -
      
 
  
 
456 Глава 9

Радиочастотная идентификация (RFID)


и ближняя бесконтактная связь (NFC)
Подобно системам распознавания штрихкодов, система RFID предусматривает наличие на объ-
ектах меток, обеспечивающих их идентификацию. Но, в отличие от меток штрихкодов, метки
RFID, чтобы их можно было считывать, не обязательно должны быть на виду. Считыватель RFID
излучает радиосигнал ближнего действия, который принимается меткой RFID, передающей в
ответ короткую строку данных. В зависимости от размера и чувствительности антенны считы-
вателя и мощности сигнала, метка может находиться на расстоянии до метра от считывателя,
помещена внутри книги, ящика, коробки, предмета одежды и, тем не менее, быть доступной для
считывания.
;  ,       
    ,     

  -

  , "       RFID:   . #   , %   -
     . 4 
   RFID    
  RFID     

 
    

 - 
       
 

  $
         
 (
 . 9.7).
%  . >
   > 
  % 

   
 ,    , 
-  
      
,
           .          
  -
/ $
          -       %   

 
      —  - $ 
 .

Рис. 9.7. Фотография электромагнитного поля считывателя RFID, снятая Тимо Арналом (Timo Arnall), демонстрирует радиус
действия и форму электромагнитного поля типичного пассивного считывателя RFID. Как можно видеть, это всего лишь не-
сколько сантиметров
Идентификация 457
& 
    RFID    -        
  
          
  ,  $ . 0     -


 
, 
 
- ,      RFID
 -
           -  
    
  

  
 . 3       -  , 
     . 3   $
 %
  ,     ,  
      RFID 
   
 %. *   
  
        -
    
 . 4  

    . & ,    

   
   
       , — $ ,    -
  
 $ 
   
     
  
   .
    
 ,  , 
 , -
     RFID. X         
 . 9.8,   RFID -
    E-ZPass13        
 
: -
  RFID,         ,   , 
, 
 
,
 
     
. 
 
 ,       
 .  ,       
7     
  ,  -          %-
    RFID    
,     
     ,
13
 
  
   -
E-ZPass —    $ 
  
   
 
   
 ,     %   
      .    
-

,       
-     #3, 
  ,     RFID  
   % # 
 
      % 
  

 
,  
 -
+  .   
$
 
" 
, —

Рис. 9.8. Все эти предметы различных цветов и форм оснащены метками RFID. Фотография Тимо Арнала. Дополнительную инфор-
мацию по исследованиям Тимо Арнала и его коллег в области дизайна RFID можно найти на веб-сайте www.elasticspace.com
458 Глава 9

  
  , 
" -  
      . >
       . / , 
     ,  
  ,    RFID          
     
   , 
  ,  "         . '  -
  %           
 
     ,

    
  
.     
    -
 
,       . *
 
    
 
  
Имплантация капсул RFID 
    
 
 
.
>%    RFID 
  *
 . 9.9 
      

 
       
  NFC,  
       
 -
(  )  
   
  -   
.
    
 
. 
 , 
   
      . $   - Пояснение
        
 -
• NDEF (NFC Data Exchange Format) — 
-
  RFID. *    $   -          
    %  ,  .

  $   
 
. 3  
          RFID,    • SNEP (Simple NDEF Exchange Protocol) —
 
 
  
  RFID- . 
  
     NDEF.

&    RFID      


  #     RFID 

    %

    .     - 
 . 

       
 

   
,               -

 
,  

 
 
   - 
.   
     -
   —     : 125     %  —   
 134,2 q,      : 13,56 7q.   , 
     
'   %  ,   % 
    
       
,    

   . 

 
     
. &
 ,  
    ,    RFID
-        
 
        
     

  $30  
RFID. 
 
  RFID  -  %  . #      
  , 
 
  
   -
  
    
    -
 , 7  
  
    
-   . *
 
   
 ISO14. #"      
 ISO, 
  
        -


"
         . *

,   ID Innovations
RFID. 0   $  
 
 
- 
     


 , 
 — 

      125 q        
   . . /  

 
-  ,   
   -
     
   EM Microelectronics  
 EM4001.

 — 

: I-Code, Mifare  Mifare # $     
 -
UL    Philips, Tag-IT HF  Picotag       Parallax. #   
  Texas Instruments, SR176    ID Innovations     "
ST Microelectronics  
. #   , -
    

   -
 ,   -    
  SparkFun. ~ $   
14
ISO, International Standards Organization.      ,      
Идентификация 459
 "   
        -     
   

  (     
  
   . ;
  
% 
  

 
 "    ) —   -       %   ,
   
    ,        
  

 
     
  NFC. 134,2 q,  
  
  
   .
$, 
   

 
 
  , 
  ,  
  -

    ,   $
   Ближняя бесконтактная связь (NFC)
    ,       . #   
 ISO 14443 
  
>    
  
 ? +   
 ,  "       
     ? 2 
 
        
-
  "
   
      
 
   
   
, -
      
  %
  
        
 . * 
   
   -  

  
. 
  
,
   ? 4  
    %, 

,       $  


 
    
   -          "  -
      . 0     -  
 
. 
 ISO 14443 
 
    
   
   ,    
 ,    -
   
 
  " - 
  , 
   
"  ,  

 , - 
       NFC,

Рис. 9.9. Стек протоколов NFC. Эта схема должна дать вам представление о множестве разных протоколов, лежащих в основе
типичного приложения RFID или NFC. Стеки протоколов позволяют достичь определенного уровня взаимодействия продук-
тов разных производителей, а разработчикам приложений нужно беспокоиться только о работе своих приложений с верх-
ними уровнями стека. Схема выполнена на основе материала из книги «Beginning NFC» («NFC для начинающих») Тома Иго,
Дона Коулмана (Don Coleman) и Брайана Джепсона (Brian Jepson), издательство O’Reilly, 2014 г.

Пользовательское приложение Пользовательский


интерфейс
Программное
Сообщение NDEF Формат сообщений обеспечение

Записи NDEF Формат записей


ISO-14443A
ISO-18092

Протокол SNEP Командные Связь между


FeLiCa DesFire Mifare Mifare устройствами
Ultralight Classic протоколы
Logical Link Control и метками
Protocol (LLCP) или между
Спецификация устройствами
ISO-14443-3 пакетирования данных

ISO-14443-2 Спецификация радиосвязи


(13,56 МГц)

Считыватели NFC (IPN532, SCL3711 и т. п.) Радиоконтроллеры Аппаратное


Связь между обеспечение
УАПП Интерфейс SPI I2C USB устройствами
ПК. Встроенная система.
ЦП (Arduino, Raspberry Pi, мобильное устройство и т. п.)
Микроконтроллер
460 Глава 9

 %
"     RFID. / 
-    NFC   -

,   

 
     
   - 
   $ 
.
      RFID,      -
   
      
  &    " 
    
   
            ,   NFC. *
  ,        RFID.
 
     $ 
  
  —  

     
"  , Identiv, Adafruit  Seeed Studio. 0   %
  NFC  
     
    %   , 
 
. 
    NFC 
        NFC. > 
-
NDEF 
     ,   
     NFC -
     ,  
-
       «Beginning NFC» («NFC 
(URL)  
  . *

,   -  "») ; +, =    (Don
 NFC   
  
URL,  - Coleman)  >
   =    (Brian Jepson),
 ,    
 ,  "   -    O’Reilly, 2014 .

Проект 24
Чтение меток RFID
В этом проекте мы установим программные средства для управления считывателями NFC и про-
читаем несколько меток RFID, чтобы получить представление о работе считывателей. Кроме того,
мы считаем с метки уникальный идентификационный номер и посмотрим, с какого расстояния
он может быть считан. Это хорошая отправная точка для любого проекта, оснащаемого возмож-
ностями RFID и NFC.
~   
  NFC,   -
 ,  $           Требуемые компоненты
RFID. $       

- 
#   
-
 SCL3711 USB Smart

  
      NFC, Card Reader   Identiv.
     %     - 
7  RFID Classic   Mifare.
      

0  
Raspberry Pi.
 . +  ,     -
 RFID,  "    NFC.
   NFC,      -
RFID-
 Mifare Classic  Mifare 
 
 
 USB. 0 

  -
Ultralight   Philips, %
   -      
,  " -
     "   
 
, -  
 USB, —     
 -
    
 ISO 14443.    
     

  Philips       
, Raspberry Pi. '     



    NFC,  - Raspberry Pi,    "  -

 Mifare      
  - 
     
     
    , 

  -  

   
 . $
 NFC. %   $ 
   "   -
  Raspberry Pi  
  

#   
-
 SCL3711   RFID  NFC. &
 ,      $
Identiv  
    RFID  -  
  ,       

 Mifare Classic,   
  ,    " 
 .
Идентификация 461

Установка программных средств



    $ 
 ,  
- /       
 "
 ,   %  Raspberry Pi   -   (

)  Raspbian   -
  
  
  
  -    . 0
    

     Linux ( . !. «Q  -  ,     


  $
    -
  Raspberry Pi»   1). 9 
      
  "  .  -
  

       
 
%         $

  
      POSIX,    "  :
 OS X  Apple  Linux Ubuntu,   Reading package lists... Done
  Beagle Bone  
   Debian, (      ... š)
, 
 ,  
    .
; 
   
       
;   ,  % 
     -
 . #        -
      

 -
  libnfc —      :
 
,         
 %   
         $ sudo apt-get install libnfc-dev
libnfc-bin libnfc-examples
     Raspberry Pi.
   $    $
   
+,      Raspberry Pi      "  ,  

     " 
    -   
  apt-get 
 
 
   
   ssh,     , 
  ,   ,   
$      1. 4        
       

   Raspberry Pi,    -    %   
 .
  , 
"     
 -
   
 
. &     , -  
%        

       . libnfc          

&    ,  
   " -            -
 :   libfreefare:
$ sudo apt-get install libfreefare-
? libnfc-dev —    
 
dev libfreefare-bin
   NFC;
? libfreefare —       
- 2
%       , 

-

    RFID  
 Mifare.  
       -
 . >  ,       
>      "  
-   % ,   
    
 
 -
  Raspbian  
   

-  
 NFC.
     apt-get. 7     -

   npm         
    NFC
node.js. #
  apt-get
     (
 . 9.10)      :

,  
   %
 
 $ nfc-list


   ,   node.js.
* $
  
   "

        
 ,   :
 apt-get   "    ,  nfc-list uses libnfc 1.7.1
    
   . = $- NFC device: SCM Micro / SCL3711-
   Raspberry Pi  + 
  NFC&RW opened
    "  : ; 
        ,   
 -
$ sudo apt-get update        NFC.
462 Глава 9

GPIO

USB 2x
USB 2x
SCL3711 NFC reader
DSI (DISPLAY)

http://www.raspberrypi.org

CSI (CAMERA)
Audio
HDMI

ETHERNET
Power Рис. 9.10. Подключение считывателя NFC SCL3711
компании Identiv к Raspberry Pi


      libnfc  libfreefare - ? 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-mfclassic -h
? nfc-mfsetuid;
? nfc-mfultralight;
Чтение меток
? nfc-poll;
+ 
     
,    -
? nfc-read-forum-tag3;   libnfc  libfreefare, 
-
? nfc-relay; 
          RFID
? nfc-relay-picc;  NFC  
 Mifare. =  
 

  ,    $  
-
? nfc-scan-device;   nfc-poll:
? mifare-classic-format; $ nfc-poll
? mifare-classic-read-ndef; #    
     -
? mifare-classic-write-ndef; " :
Идентификация 463
nfc-poll uses libnfc libnfc-1.7.1-150- Формат NDEF
gbf31594
NFC reader: SCM Micro / SCL3711-NFC&RW *       
 RFID,
opened            
NFC device will poll during 30000 ms  $ 
  —     
(20 pollings of 300 ms for 5 modulations)
  
. *     NFC
   
  
  %
2             
,   
     -

  . 
  
    -  
UID. /   -
       " "  : 
 " %     NFC — 

NDEF. # 
 NDEF RFID  NFC -
ISO/IEC 14443A (106 kbps) target:
 
   " 
:
ATQA (SENS_RES): 00 44
UID (NFCID1): 04 8e 41 62 b7 20 80 ? RFID —      
 
SAK (SEL_RES): 08 UID;
nfc_initiator_target_is_present:
Target Released ? NFC —    
  
 -
(#_  # _nfc__  :  %    ;
$   #'  ) ? NDEF — 
   " 

Waiting for card removing...done.      NFC
  .
      ....
[
 NDEF     - 

 
*
UID — $ 
     " 
       ,
  
(Unique ID)   
 SD  
  
  
   
RFID  %  
  
 . = 
- %  . ~
 
 
  
  RFID — $    
, 

   
  
-

    
  
  .   ,        
&   
  RFID  UID -     %   
 

       ,  


 
. >
 $   



  ,     -       
   
    
 
      
 SD   %,     -
  .     
 
   .
   
  
    -
4   $ $ %  
  - %  ,   NFC  
  
 
, 

  "
  
  . =    
       —   
        
 

   ,  
    - 
,  
 NDEF 
 
 "
   . *   %
  

,
   
 . 0
  —  % , $   
  -    "     ,
 
. ; 
      ,      
  
       
   - 
   .
 %      , —    

 "            _   
 NDEF 
 #-
RFID  NFC. ~    RFID 
 %- 
  $ 
 ,   "   
  
    
         !
 NDEF  
  ,   %     
  . *
 
 

  $   .     ,   URI, 
"
 
-
,    MIME  ,

 

 

464 Глава 9

 . #"      - ? 7


4 —       
    , 
 
 - DESFire (ISO-14443A)   NXP.

 . & % 
    
- 


 $ : DESFire 
           SmartMX-JCOP   NXP.
URI. & % 
        
Mifare Classic. /    
#  NFC   
  NFC,          
  
 NFC: 
 NDEF, 
     
? 7
1 —      ISO-   ,   $ . >
14443. 


 $ : Topaz     NFC  

   $-
  Innovision  BCM20203    ,     
 -
Broadcom;
  
   Android,  " 
? 7
2 —             NFC.
Mifare Ultralight (ISO-14443A)  
NXP  Philips. 


 $ :
Mifare Ultralight   NXP;
? 7
3 —       
FeliCa (ISO-1892  JIS-X-6319-4)  
Sony. 


 $ : FeliCa
  Sony.

Проект 25
Чтение и запись сообщений NDEF
Здесь мы познакомимся с ближней бесконтактной связью (NFC) и форматом NDEF обмена дан-
ными для нее и станем с помощью сценариев на node.js записывать и считывать данные с меток.
Для этого нам понадобятся сценарии для записи и считывания меток, которые будут работать
с интерфейсом командной строки.

#    
  
     -
Требуемые компоненты  Raspberry Pi   
   
  

#   
-
 SCL3711 USB Smart   ndefReadWrite. #   $ -
Card Reader   Identiv.       writeNdef.js. * ,

7  RFID Classic   Mifare. 
    
   npm   -
   ndef  mifare-classic:

0  
Raspberry Pi.
$ npm install ndef mifare-classic
    , 
 node.
js 
   
 
- &  "   
  %    
 NDEF    Mifare Classis, 
"  NDEF,  "     -

         -    


-
 (URI).
    libnfc  libfreefare.
/  
 
  
JavaScript    libnfc  libfreefare, -
      
 

node.js.
Идентификация 465

Записываем метку
&   
 

  /*
  ndef  mifare-classic   
NDEF
: node.js
      
 
*/
"  NDEF. /  
   
   var ndef = require('ndef'); // \       ndef
" : var mifare = require('mifare-classic'); // \   
//    mifare-classic
var ndefMsg = new Array(); // &   - 
//   NDEF
=      var textRecord = ndef.textRecord("+ R ");
     URI   "  var uriRecord = ndef.uriRecord("http://www.example.com");
     "  . 2  ndefMsg.push(textRecord); // Š  ' $ 
  
  - ndefMsg.push(uriRecord); // Š $  URI
      , 

- var bytes = ndef.encodeMessage(ndefMsg);
// $      


        
 "   ndef.
encodeMessage():

#    
  function writeResponse(error){ // • #  
  Response()    //  - # $  
mifare.write(), 
   if (error) { //      $  ,
console.log(" : " + error); // $  
 " . /   
-
} else { // +       -
   
   

-
// #
    %     %  console.log("Z   $    ");
  "    . }
}
* , "  
mifare.write()    - //      
"    : mifare.write(bytes, writeResponse);

&     
 NDEF   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     
 " .
466 Глава 9

Считываем метку
/  
   ,   /*

 " , 

  ’  
NDEF
   : : node.js
*/

var ndef = require('ndef'); // \       ndef


var mifare = require('mifare-classic'); // \   
//    mifare-classic
    mifare. // • #   $      
write(),   "  function listTag(error, buffer) {
  mifare.read() 
- if (error) { // +      ,
console.log("   : " + error); // $
    
   - //  
, 
   listTag(). } else { //     
[      
"- var bytes = buffer.toJSON(); // $
 
, 
    //    " JSON


    JSON, if (bytes.hasOwnProperty('data')) { // †  

// " JSON   


 data,
         bytes = bytes.data; // $ 
data, 
       }

  . var message = ndef.decodeMessage(bytes);// Š  
//  
for (record in message) { // -  # 
    
,  - //  R   ,

  "  ,  console.log(message[record].value); //  
   . &  for 
- // $  
$ 
  $    ,  - }
}
  $
   : }
* ,       mifare.read(listTag); // Z  
mifare.read()    
 .X  %  
  
      listTag():

#
      
 ,     -    
  
   
      ,    : (   232–1  ). +   "  
-
         " -
$ node readNdef.js
          

    
    -    $    IP-
.
        " "  : &     
    -
  ,
       
Here's a string
  . *

,   
(+ R )  
-
    
 
-
http://www.example.com
     
  Android, 
 -
      Mifare Classic,  
 
Использование записей NDEF    
 
  

 - 
 ,
     "    - 

 
    . 7  -

  
  ,             -

         -        # ,  
 
 
    . &   NDEF - %
   
    .
Идентификация 467
; 
,   
      "  
  
 
,   -

 node.js          $   
 

, -
    "  NDEF,  %    Arduino.

Проект 26
NFC и бытовая автоматизация
В нашем с напарником офисе находятся десятки потребляющих электроэнергию устройств: не-
сколько компьютеров, два монитора, четыре или пять ламп освещения, несколько жестких дис-
ков, паяльник, хабы сети Ethernet, динамики и т. п. Даже в наше отсутствие эти устройства по-
требляют много электроэнергии. Какие устройства включены в определенный момент времени,
зависит от того, кто из нас находится в офисе, и что мы делаем. Этот проект представляет собой
систему, направленную на уменьшение энергопотребления нашего офиса, особенно когда нас
в нем нет. Когда мы заходим в офис, нам достаточно дотронуться брелком с NFC-меткой на коль-
це для ключей до панели возле двери, и система включит устройства, которые мы обычно ис-
пользуем. Каждый из нас имеет соответствующий брелок, а под панелью смонтирован модуль со
считывателем NFC, который считывает поднесенные к нему метки.
#   NFC    
-
 

, 
    Wi- Требуемые компоненты
Fi  
  $ 
 
 - 
>       , 1 %.
.   
     
 Arduino MKR1000  WINC1500, 1 %.
   WeMo (
  )   &   
    
Belkin,    
 $ 
 
 -   
   ESP8266.
   
  . &     +       :  
 -

   , 
 

  , - SPI  I2C, Wi-Fi.
  $     . 
7 NFC-    PN532, 1 %.
q
  -        

7  RFID Mifare Classic, 2 %.

 . 9.11. /     


  
     WeMo, 
7
  WeMo   Belkin, 2 %.


    
,  

    .

Рис. 9.11. Управляемая посредством NFC


Считыватель система автоматического включения/вы-
Интерфейс Беспроводной
RFID ключения электроприборов на основе
SPI канал Wi-Fi передачи
сообщений HTTP модулей WeMo

Микроконтроллер
Модуль WeMo
Беспроводной
канал Wi-Fi передачи
сообщений HTTP

Модуль WeMo
468 Глава 9

Схема системы ~   Belkin 


    -
"     
 API  

   $ 
  
 

WeMo,   
     
-
    WeMo  Wi-Fi,      "  -
 
      Wi-Fi. If This Then That (https://ifttt.com), 
-
+        
 

-       
    -
 Arduino-     MKR1000  
  
 HTTP. ~
%
 WINC1500,      
-   ,   
  WeMo   
  ESP8266. 
 HTTP,   #     
-
 ,  $  .   Belkin  -
& 
         NFC  -       
  

   PN532   NXP Semiconductors.      
 ,  
-

 ,  
       $ 
 "-  .
    $ 
   . 0 
 
   

 PN 532 9   WeMo     -
NFC/RFID   Adafruit,  % NFC   
    
 
 % NFC  Arduino   Seeed Studio     ,   
   
  
 
 
  $    % . ;      
-

 . &
 ,  Grove NFC -   WeMo   
  Android
 Seeed Studio  
 .  iOS. X   
  ,    IP-
#   
, $   
- 
  WeMo. = $    -
    
   PN532, -         15 ] 
|
 &  | D
       -

"  
 SPI  I2C.


|   WeMo,     -


%  IP-
  .
7
   PN532  "   
 
I2C, SPI    
   X3,  -

  WeMo 
    -
%    $ 
      uPnP16,   SOAP17 — 
   -

 , " 
    -  XML  
   
 ,
-

 
   
 . &    ,  " " 
 HTTP  SMTP.

 . 9.12 
      Adafruit * 
  ,       ,
     
  
  SPI. ;  
 
 "   
-
 
 

    -  SOAP, 
   %     .
:       ,  
 *   
  
 

      . HTTP,  
 "  SOAP -
     
    ,  -
Протоколы связи    ArduinoHttpClient.   $
  
       
*         " -     4.
 NDEF, 
" 
  :
15
&      
   
 ,  
?   ;         
,  "
? 
 WeMo,   $        .
16
  ; uPnP, Universal Plug & Play — 
     -
 PnP, 
   
   -
? IP-
 WeMo.  $ 
   $ 
    

 
 
 

   $ " -  
 ,        (    
 ,  ,    ,  "
  ,     
 HTTP   -  
), 
     
 .
       "   17
SOAP, Simple Object Access Protocol — 
  
-
WeMo.      .
Идентификация 469

Vcc

Модуль MISO* MISO*


микроконтроллера Перемычка SEL0:
MOSI** MOSI** снята
Модуль
D4 SCK*** SCK*** NFC PN532 Перемычка SEL1:
установлена
D5 D11 SSEL

Общий («земля») К +U 5V
Общий («земля»)
220 Ом 220 Ом

*MISO (вход ведущего, выход ведомого)


**MOSI (выход ведущего, вход ведомого)
***SCK (тактирование)

Примечание
& $ 
          NFC
     
 SPI. 7
 

 
     
 SPI     -
   Wi-Fi.  % SPI    
  -
   
 ,      
-
        
   .  MKR1000 -
     7   
    Wi-Fi, $ A B C D E F G H I J
1 1
  
    NFC     11. 0

    ,  $  
      10 —
 
     
    Arduino Uno. 
  - 5 5

 ,  
    
    -
   
  I2C. + 
  $ 
 
 

    . 
 $       - 10 10

 
    " 
.

15 15

POWER
GND

P35

P34

P33

P32

P31

P30

AUX2

AUX1
SIGIN

SIGOUT
RSTPD_N

20 20

PN532 Breakout Board


3.3V

SCK
MISO

MOSI/SDA/TX
25 25
SSEL/SCL/RX

RSTOUT_N

SEL0 SEL1 IRQ

UART OFF OFF GND

SPI OFF ON R1 30
5.0V 30
I2C ON OFF C15 OFF OFF A B C D E F G H I J
GND

5.0V

RXD
TXD
NC

NC

SEL0 SEL1
ON ON
FTDICABLE

Рис. 9.12. Принципиальная (вверху) и монтажная (внизу) схемы подключения микроконтроллера к модулю считывателя NFC.
Здесь показана микроконтроллерная плата MKR1000. Для других микроконтроллерных плат, возможно, потребуется исполь-
зовать другие выводы. При этом необходимо, чтобы подключения интерфейса SPI совпадали. Также следует обеспечить под-
ключение шины «земли» на левой стороне макетной платы к общему выводу питания под модулем считывателя NFC
470 Глава 9

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, "    NDEF  
    -
  XML       ,    PN532      -
$   XML  
    . *    
 $
(Envelope)    (Body) " . &   -        
"     BinaryState     -  7 
  Arduino, $ -
 1  0,          
  
     
 
   .  " 
. 2
 
  -
  ,
   ,  

#"  
   
  POST,  -

 Arduino,       -
 HTTP       
:       D  |  >
 
-

  | !
 .ZIP 

   -
Content-type: text/xml; charset=utf-8  
     .
SOAPACTION: "urn:Belkin:service:basic =   NDEF    
event:1#SetBinaryState" 
,   
   
.
Connection: keep-alive 3    PN532     -
Content-Length: 230
      
 : PN532_I2C,
PN532_SPI  PN532_HSU (     -
= 

   HTTP 
 -
     SPI).  
  
       -
  %          \ |
  ArduinoHttpClient.

   
  


. &
 ,  $ 
    -
=    
  WeMo     
  % 

NDEF.
   URL-
: /upnp/control/basiceventl.
7     $ 
 %  
= 
     Arduino 
  HTTP. X 
  WeMo  
  "  NDEF    RFID,  -

 49153.
        .

Установка библиотек
= $ 
   
   -
 :   NDEF  Arduino
-

 =    (Don Coleman)  -


  PN532

  #  (Yihui
Xiong). +   
  
 https://
github.com/don/NDEF  https://github.com/
Seeed-Studio/PN532    . > 
NDEF      

  -
Идентификация 471

Записываем сообщение на метку


2         - /*
 "  NDEF. /     
NDEF  Arduino
  "  
  : Arduino
*/
node.js  
 "  
 ,
  
  $  - #include <SPI.h> // '    SPI
 
    Arduino. #include <PN532_SPI.h> // '    SPI  PN532
&      - #include <PN532.h> // '    PN532
    
  SPI #include <NfcAdapter.h> // '    NFC
    NFC: PN532_SPI pn532spi(SPI, 11); // \ #  $   
NfcAdapter nfc = NfcAdapter(pn532spi);
&   setup()  - void setup() {

         Serial.begin(9600); // \ #  $    '


// $
     : nfc.begin(); // \ #  $   $ NFC
}

&   loop()   - void loop() {


    
  - Serial.println("$   %   ' 
Mifare Classic   .");
   . 
  -
if (nfc.tagPresent()) {
     "  NdefMessage message = NdefMessage();
NDEF,      , 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("  $    .");
}
}
        - Serial.println(); // +   '   #  
  3   ,  
 delay(3000); // Š $'  ,   
     , 
 }
        
 :
&        " -
 NDEF    RFID.

Считываем метку
#        - /*
  ,     , - ’  
NDEF  Arduino
     : Arduino
*/

  "  NDEF. ;
 ,      ,  - #include <SPI.h> // '    SPI
      
472 Глава 9

#include <PN532_SPI.h> // '    SPI  PN532



   . =-
#include <PN532.h> // '    PN532
        - #include <NfcAdapter.h> // '    NFC
 tagLed  
   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()   - void loop() {


 "        if (nfc.tagPresent()) { // Z   NFC
  ,     digitalWrite(tagLed, HIGH);// M$     
NfcTag tag = nfc.read(); //     
       . if (tag.hasNdefMessage()) {// †   
4    
 " - //  ,
 NDEF,     NdefMessage message = tag.getNdefMessage(); //  
  : //  
int recordCount = message.getRecordCount(); //  
//   $ 

&  for 


  - 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
  WeMo:
payloadString += (char)payload[c]; //    -
//    ' payloadString
}
Serial.println(payloadString); // +  
// payloadString  R
} // # #  for     $ 
} // #   if tag.hasMessage()
} // #   if tag.Present()

*       digitalWrite(tagLed, LOW); // M$ ,  


//   
    ,  -
delay(3000); // Š $'    
   
  : }
Идентификация 473
' ,  
    NFC  
   
    
      . 0   -    
  ,   -
,    
   
 
  .
   
     

 Arduino   "  ,      ; 
,    
    -
 
   ,      $  -  ,         

 " Arduino. HTTP     WeMo.

      - 



   
 ,    
    

   -
  
    . 3    

Усовершенствуем код считывателя


&   
 %
- /*
       7
 HTTP NFC  
 WeMo
7 
:Arduino  
WIN1500
       Wi-Fi
*/
    
 -
 WeMo 
 HTTP #include <SPI.h> // '    SPI
    NDEF. 7- #include <WiFi101.h> // $

 WiFi101
    - //#include <ESP8266WiFi.h> // €   

   WiFi101,  // ESP8266  


# 
#include <ArduinoHttpClient.h>
    
 " 
 
#include "config.h"
Wi-Fi.   
   #include <PN532_SPI.h> // '    SPI
     config.h //  PN532
 
     (SSID) #include <PN532.h> // '    PN532
 
    : #include <NfcAdapter.h> // '    NFC

* 
   - PN532_SPI pn532spi(SPI, 11); // \ #  $   
        
- NfcAdapter nfc = NfcAdapter(pn532spi);
 :  
  ,  const int tagLed = 5; // +   
//    #    

   ,
const int wifiLed = 4; //    

 
"   // 
   
 Wi-Fi
Wi-Fi,  $ 
   WiFiClient netSocket; // C

 
  
Wi-Fi, 
 
,  
- const int port = 49153; // ‡
 
,    
   - String route = "/upnp/control/basicevent1"; // $ API
   WeMo,   boolean wemoStates[] = {0, 0}; // 9 

 WeMo
 ,   IP-
  String username = ""; // ‰   


  "   WeMo. String wemoAddress = ""; // Œ
 

  WeMo

 ,     int wemoNumber = -1; // ‡
 

  WeMo

 SOAP     // 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>";
474 Глава 9

&   setup()   void setup() {


    
   Serial.begin(9600); // \ #  $    ' $
nfc.begin(); // \ #   $ NFC

     - pinMode(tagLed, OUTPUT); //  -
 
    Wi-Fi 
 //       #    
 ,        pinMode(wifiLed, OUTPUT); // %
   
! 
//   
 
   
  Wi-Fi

 
   
// $
 
  
 Wi-Fi,
Wi-Fi, 
    while ( WiFi.status() != WL_CONNECTED) {
 
 
  Wi-Fi: Serial.print("$ 
    
  

: ");
Serial.println(ssid); //    #   
 (SSID)
WiFi.begin(ssid, password); //  
    

delay(2000);
}
%    Wi-Fi, // $  
,    # 



//  
:
  "   
- IPAddress ip = WiFi.localIP();
   : Serial.print("IP-
: ");
Serial.println(ip);
}

= 
  %   void loop() {
      loop() // ... %
 
      setup()
  
 ,  % Serial.println(payloadString); // +
//   payloadString  R

  . &  % -
copyRecords(r, payloadString);
       - } // # #  for     $ 
 copyRecords() (
  - } // #   if tag.hasMessage()
 
     ) } // #   if tag.Present()
 
     digitalWrite(tagLed, LOW); // M$ ,  
"   
 //   
  "   - if (WiFi.status() == WL_CONNECTED) { // ` 

 . 4"   
- //  

 Wi-Fi
digitalWrite(wifiLed, HIGH);

      


} else {
     Wi-Fi  digitalWrite(wifiLed, HIGH);
     "  - }
    
   - delay(3000); // Š $'    
      }
  Wi-Fi:
= 
     void copyRecords(int recordNum, String recordString) {
copyRecords(),      switch (recordNum) { // N 
!  

// -  
  setup(). [  
- case 0: // %  

 
; 




     
 
 - break;

   
    - case 1: // %  
  WeMo; $
 


   "   //  


 
      " wemoNumber = recordString.toInt();
break;
 
 . 
 - case 2: // %  IP-
 ; N


 
  , 
 wemoAddress = recordString; // *
 IP-
,
   IP-
,      wemoRequest(wemoNumber, wemoAddress); //   

  wemoRequest()(
 - // 
  
   ),  break;
   
 POST: } // 7
 
 case
}
Идентификация 475

0
     wemoRe- void wemoRequest( int thisWemo, String wemo) {
quest(), 
      if (wemoStates[thisWemo] == 0) { // *  WeMo  
,
soap.replace(">0<", ">1<"); // 


case 2. [  

  -
} else { //    

  
   soap.replace(">1<", ">0<"); //  


WeMo,    
  }

 
  SOAP  - wemoStates[thisWemo] = !wemoStates[thisWemo]; // 


" 
,   //  




 wemoState  ! 

 $   String.


replace(). ;  

 
   " -
,  
    -
    :

=   


 POST HTTP, HttpClient http(netSocket, wemo.c_str(), port); // 9

      // 
 HTTP
http.connectionKeepAlive(); // `
!



ArduinoHttpClient,   $ //     


     4  5.   http.beginRequest(); // ‡ 
 
      - http.post(route); // %

,     - // €
:

   ,    - http.sendHeader("Content-type", "text/xml; charset=utf-8");
String soapAction = "\"urn:Belkin:service:basicevent:
 beginRequest() —  - 1#SetBinaryState\"";
 
   endRequest() — http.sendHeader("SOAPACTION", soapAction);
 
%  . ;  http.sendHeader("Connection: keep-alive");

  POST 
   - http.sendHeader("Content-Length", soap.length());
 endRequest() " http.endRequest(); // 7
 
  http.println(). 
 http.println(soap); // €

 
Serial.println("% 
");
      -
  $,  

  POST   

"   
Stream:

/      $


 while (http.connected()) { // $ 
 

,
    WeMo: if (http.available()) { // 
 

  


String result = http.readString(); //  


Serial.println(result); //     #
}
}
}

      


 "   $  
  
,   -
 ,    NFC      
         
 , 
        -       ,     
. 
 ,     
 , 
   
 "      
         - 
 .  , $  ,   -
, "        
-     
   " 
 . /   
   . 0   - 
    . 
 $  
,               

      ,
476 Глава 9

  
, —    
- &     ,   WeMo
 
     . 
     ,    

 HTTP. /      ,   
# 
 
%  $ 
  — -  WeMo     
 

  
 
     
, 
  
   ,  —     
       
  - 
  —    " ,
   ,   
          
   . +    -
(
 . 9.13). /
%    %
-    loop() 
  

" 
 
     
   
 . %     . & 
 -


   , 
"   
 
 ,   
    


   ,          -
Рис. 9.13. При установке считывателя на двери пользова-
тель вынужден убрать метку после того, как он проведет ее    
      -
по считывателю. Таким образом решается проблема невоз- 
,   
 
.
можности считывания больше чем одной метки за раз

Конструкция

  $ 
    
 
  
     -    -
 5. > ,         %-
, % %  

.

 ,     
 — 
 ,       
         $  -
 
 . 9

  
Adafruit,    
 "  
-
 

  ,   ,     -
      , $   
 
  
       , 
  -
 
 . 9.12. *
 . 9.14  9.15 
   
 
 ,  
 . 9.13 
    
 
 .
Рис. 9.14. Корпус проекта считывателя NFC в процессе
сборки. Требуется, чтобы антенна считывателя находилась
в верхней части корпуса, что вызывает необходимость двух- Рис. 9.15. Корпус проекта считывателя NFC в развернутом
уровневой конструкции с размещением микроконтроллера виде. Модуль считывателя и светодиоды подключены к ми-
на нижнем уровне. Этого можно достичь, используя стойки кроконтроллерной плате с помощью монтажных проводов
разной высоты и прямоугольных штыревых разъемов
Идентификация 477

Безопасность устройств сетевой связи


Физические идентификационные данные во все возрастающей мере связаны с сетевыми дан-
ными, а сетевые данные во все возрастающей мере становятся уязвимыми к атакам. Поэтому
все должны быть осведомлены об основных методах защиты идентификационных данных, как
своих персональных, так и своих устройств.
        
        
-
  
 %     
, ,        -
   
 + 
  % 
-     . +  $  
  
      , ,   
     . &    ,
  %   
      
      -

 "  $ 


  
 ,       
   
 -
    
  %        "      Hue -
   . = 
   -   Philips:      
               ,          
%     
 .        -
  
 . 3      

         %   -
Не выходите за пределы
   , 
   
локальной сети    "  . ; 
-
0 "       %-         
  
       Google. & $  
   
   
    . X 
 ,  
    % 
,  %   -
 " %   IP-
   —       . 4"
,   + 
,   
    — 

,  iOS  
     . 
 $ -  
      .
       


  =  
  
     -
 
 . *    
   -       
  
-
"       ,  
      
  
   
  
 %        " - NFC       .
   ? &
 
  
  . ; 
 $     , Используйте HTTPS и криптографию


  -  
 ,   

   , 

  -
с открытым ключом
  
    %    &   8     



% . 4   
  

 HTTPS 
, 
 "
  
    
 ,   

     -
   $    ,   % 
   
  ( 
 )  
? 4        ,    %
  "   
    % 
 ,    
-

   . ;  


  
   .     
 
    -
  

 
 
.
Применяйте двухфакторную
9  $     " 
.
аутентификацию #     : 
 
=
     ,  
 . =

 HTTPS $ $  -
       
        ,     
 
478 Глава 9


 (

 
 
 
,     
). 4
       
 %
 "  "
%
  "  ,    — - 
  
 ,  
 
  
 %
. 4     
-  
,  "     
  
  " ,     ,    — "   
-
 
 ,  %
  " -  ,  
   ,  
-
       . _ %
-      
 . #

  "   
 %
 -  -  ,  "  
 HTTPS, -
" 
   
 , - 
 
 ,     
      %
   
    
 ,   
 ,
. * 
    , 
   
 %
 "
     %
  -  ,     
 $
" 
  ,  "     -  .
 
 . # 
   
-
    ,    , 3  
  

    
 " $      

,  
  
  -
 % %
 " ,       , " 
  -
  
 %   %
 . %
 , 
 %
  " .
7     
  %
 -
' 
      
    !. «:
  
 »   3, 
,  
       -   
 %
  aes-256-cbc
 
  ,  
    -  
   
 —  %
  

  . 0
  " 
 %
   
. # 
  %-
 %
   " 
-
     
     
  
 
 ,     
- 
  " ,    ,  
  . / 
 %          %
 .

Проект 27
Двухфакторная идентификация с использованием NFC
В этом проекте мы создадим систему двухфакторной аутентификации на основе Raspberry Pi
и метки NFC. Эту систему можно использовать в любом случае, когда требуется двухфакторная
аутентификация, но в здесь мы применим ее для открытия замка.
9    
 —    -  
)   
  
 , -
    — 
 $ 
      

   (%  
NFC, 
 
     
-    ),

  %  
% 
 — 
  
. 9      - 
    
  .
" 
. ' 
 ,  -

   - 
 , 
 
  -     , 
  
  -


  node.js,       NFC      %
   ,   
-
   , 
  $

.        —   "
#

   
     - 
 %
. =
 %
 
   %
  
  
. 
  
     
.
&      
  
  0   %
    
  
  "   

,    - 
  
,   
 ,
   
  
 (%        %
  
   .
Идентификация 479
3 
  
 

    
   
  
 ,
 %
  Требуемые компоненты

  
    " 
- 
#   
-
 SCL3711 USB Smart
   
    . / 
- Card Reader   Identiv.
        
    - 
7  RFID Classic   Mifare.
 ,    
 %





  
      , 
0  
Raspberry Pi.
      . /    
;
  
TIP120.

   ,  -    -

9  
  1 0.
   
  
 .

#  .
          ,  
+       
  
   

 HTTPS, 
  - 12 &.
   18 ( . !. «&!   - 
9     
  

 HTTPS»   8)   
   -
 5,5    %  — 2,1 .
$  ,      
 -

* %    .
. 3   "   
 

 %
   
  
 .

Особенности кода
  $ 
     

- +, 
    
   $ -
  
  NFC  NDEF,   - 
  
 https-server.js  
   -
     26,       
      https-server-
 Raspberry Pi. #   
 - writer.js,  
 — https-server-reader.js. ;
        , 
     ,   
        
 -   
 SSL. =   
  "    
 node. 
      NDEF,   -
js. + 
 JavaScript      —     NDEF,   
 -
express  ndef  
        —  GPIO. 
 ,     
        ,       
 
  .   - 
  , 
  
p5.js. 
 ,  
 ,   

           public  
    
   -
  ndefSignature. 9   % 
  -      
  p5.js  : reader
   
  ,    
 
-  writer. 2  "  
  

       ,  
 — - npm     "  :
   . / 
     ,
              $ npm install express body-parser
 

  
. *  
 ndef mifare-classic onoff

     
     ,
$ 
    
   . #   " 
  : writeNdefSigna-
   
       ture.js, readNdefSignature.js  gpioControl.js.

   

    
 , ,  ,    
-     ,  
   -
        .    
  
 %
-
480 Глава 9

  
  
 . 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
A
B
C
D
E
TIP120

F
G
H
I
J
1 5 10 15 20

GPIO
USB 2x
USB 2x

SCL3711 NFC reader


DSI (DISPLAY)

http://www.raspberrypi.org
CSI (CAMERA)

Audio
HDMI
ETHERNET

Power
Идентификация 481

Управление контактами ввода/вывода (GPIO) на Raspberry Pi


#  $ 
  (
 . 9.16)  % Raspberry Pi 
   ,   
    ,      25     
  
  
, -
 26, —       
 -
,   
, 
    

   ,      .
   /  Rapsberry Pi. 

$     «  » ( 
« »)       "  ( -
 « ») Raspberry Pi. Рис. 9.17. «Распиновка» контактов ввода/вывода общего
назначения (GPIO) плат Raspberry Pi моделей 2, 3 и Zero


   
  

  -
  ,      
 gpio-
Control.js  
     
Raspberry Pi. /  
     - 3.3V Power Питание 5 В
    /  "     GPIO 2 (SDA) Питание 5 В
(GPIO),    $   onoff GPIO 3 (SCL) «Земля»
 node.js. GPIO 4 (GPCLK0) GPIO 14 (TX)
Ground GPIO 15 (RX)
  GPIO Raspberry Pi (
 . 9.17)  GPIO 17 GPIO 18 (PWM0)
   "   
 
- GPIO 27 «Земля»

   Arduino —   
 
- GPIO 22 GPIO 23
   , 
     : 3.3V Power GPIO 24
  
        (
- GPIO 10 (MOSI) «Земля»
 X3),  
 SPI  I2C,   GPIO 9 (MISO) GPIO 25
  +7.   , Raspberry Pi GPIO 11 (SCLK) GPIO 8 (CE0)
 "      . Ground GPIO 7 (CE1)
9 
        - GPIO 0 (ID_SD) GPIO 1 (ID_SC)
  3,3 &,       5-  GPIO 5 «Земля»
 . >  onoff, 
   GPIO 6 GPIO 12 (PWM0)
    
 " 
  (   - GPIO 13 (PWM1) «Земля»
  
  
: https://github.com/
GPIO 19 (MISO) GPIO 16
fivdi/onoff), 
       -
GPIO 26 GPIO 20 (MOSI)


 $   
 

Ground GPIO 21 (SCLK)
   ,      
$  ,       
 
     (

 

).

    


 

 -
  Arduino,   GPIO Raspberry Pi
       
   -
% "  ,   
  -
  
  
,       -
  $  
. ;,  
   -
  
   % , 

482 Глава 9

Код для управления соленоидом


    
  
- /*
,  
 
  GPIO M  GPIO
gpioControl.js     - : node.js
*/
       
 . 2    GPIO var Gpio = require('onoff').Gpio; // '   
18  

   
  // onoff

  ,  
  var lock = new Gpio(18, 'out'); // %     
 

 
  - //          
  
  lock. + 
   $ 
  , 
  
      -
     :
&    ,    function close() {
      
 , lock.writeSync(0); //     $ 

  lock 
    //      
}
   1,     
-
 —    0. /   - function open() {
     open()  lock.writeSync(1); //     
close()    . &  - //      
 open()       setTimeout(close, 2000); // +   $  2  
  close()    //    $ $ 
 2   ,   - }
 
  :
0

  if 
 - // †       ,  -

   
  -o  
- if (process.argv[2] === '-o') {
     
  
 open();
}
  
       -
 open(). /    -
   
 
 %
 
     
:
       
 — // ‰    % # R # 
    . 2   //  $    # 
$ 

  
 - module.exports = {
 $  
  
 close: close,
 
. +   $ open: open
      , };


HTTPS:

Проверяем работу сценария управления GPIO





  
 gpioControl.js -    
 ,     
  
     
  " 
: 
   . 4  
 $   -
 18       , 
  -
$ node gpioControl.js -o
 
 . 9.16, 
     -
&
    $   Rasp- . *
  
   
 

berry Pi         18 -     . = $    18  
Идентификация 483
    ,  
           NFC 

    «  ». 
     -

  "  
 .  

    
   2  -    $  
   
  
 ,     .   ,     
 

.

X %  
      
 ; 
,    
  
 gpio-

    18,    - Control.js,   
  

  -
  $  ,    %
- 
         NDEF.

Модули Node.js

 node.js 
     - '     
  
, 

     
  . 7     $  
 "
      
  node.js 

 require(),   $  , -
 $   ,      node.js   .   $    -

    . 9  
 -       ,   
 -
  
  ,       $ , 
  
    



  ,    


 requrie(). *

,    -

    
    -   
  GPIO  
  -
 
 
 
      .
  ,    $  
  "
7        
  -  :
  .
var lockControl = require('./gpioControl.js');




   
%,   -          ,  
  
         node-modules, 
    -
$ ,    

%  -          . [ 
 
  
, 


 $            -
 
    module.exports,   
  ,  
 
   -
 $     
 
  GPIO. &    
   . *

:

"     module.exports $  -
lockControl.open();
   "    
 .
&    
  
,  - &   "  
       
-
      module.exports,             -
    $            .
 
   .

Разработка сценариев записи и чтения меток NDEF


Сценарий записи метки
; 
,     
- /*
  $ %- 
NDEF
 ,   
 
 %   '  ' $ , $
 

      -      NDEF $     .
. 0
    writeNdef-Sig- : node.js
nature.js       - */
"  . &   
,
  ,   
  var ndef = require('ndef'); // '    ndef
 : ndef-js, mifare-classic var mifare = require('mifare-classic'); // '
//    mifare-classic

 NDEF,   fs  var crypto = require('crypto'); // '   

       // crypto


crypto  %
  
 %- var fs = require('fs'); // '    %


 "  NDEF: //    fs


484 Глава 9

=  
  var privKey = fs.readFileSync('keys/private.key'); // Z 
// 
'

    
 
var privateKey = privKey.toString(); // $

 ,  " %
- //  
: var secret = null; //   
%$,
// 
 % '
=     

      
 - // • #     $   

%$
 
  
 . ~ $ function setSecret(data) {

    
  - secret = data;

,        }



, $ 
  , 
    $  
 
 
 

:

0     $ // • #           NDEF,


 
 setMessage() 
- // $ %  $ %
function setMessage(record, signed) {

   
  
  var ndefRecord; // Z    $  NDEF
%
     var ndefMsg = new Array(); // &     NDEF
  NDEF      - if (signed === true) { // † $    $ %,
 NFC. /     // $ % 
       NDEF var signer = crypto.createSign('RSA-SHA256'); // Z$
//  %
  25    signer.update(record); // Š $ 
   %
 . var signature = signer.sign(privateKey, 'hex');
[  
"     - //  %
, 
     ndefRecord = ndef.textRecord(signature); // Z$
  "   mi- // $  NDEF
else { // † $      %
fare.write():
ndefRecord = ndef.textRecord(record); // Z$
// $ % ' $  NDEF
}

ndefMsg.push(ndefRecord); // Š $ 


//   
var bytes = ndef.encodeMessage(ndefMsg); // $
//      

return bytes; // +$   

}

0      $  - // • #   $  % #


write() format()

        function showResponse(error){
setMessage(),  
  - if (error) {
console.log('  ' + error);
    mifare.write(),
} else {

   
 
  console.log('M-');
    
. =   }
mifare.write()  
- }
    
   -
, 
   
  -
  . [     
showResponse()    %
   $
 "  
  %     %   -
  
  :
Идентификация 485

# "    
 // †       ,  -
   
 
, " if (process.argv[2] != null) {
    writeNdefSig- if (process.argv[2] === '-f') { // †  
//  % -f,
nature.js,  "  -
mifare.format(showResponse); // %    
  
    - } else { // +    
 . &      setSecret(process.argv[2]); // Π$  


 
   "  //  ' %$
   process.argv[]. 4  var response = setMessage(secret, true); // +
      - // $ % '  ' %$    NDEF

 
-f,  
    mifare.write(response, showResponse); //  
// $     


   . 3  }
 
  
,  - }

 %
  ,    -
  "  , 
" -
%
  
  
,
 %    :
       
 $ - // ‰    % # R # 
//  $    # 


  "   
module.exports = {
    
  - format: mifare.format,

. / 


%   
 setMessage: setMessage,
writeNdefSignature.js: 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  ,
" % , %    
  
,     
     


       "   
.
486 Глава 9

Сценарий чтения метки


; 
 
    readNdef- /*
Signature.js       - ’  $ %- 
NDEF
"  . /  
 Z      NDEF, $  %
   '  '.
   
 %
   - : node.js
"  ,       */
NFC 
 "  
 .
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 
0 $  
  
 - // 
'
      
 , var publicKey = pubKey.toString(); // $ '
   
   //  

. 
 ,  $  - var secret = null; //     ' 
%$

  
   -

  
 %

"  ,   
  -

  
   
-
 :

[  setSecret()   , // • #     $   



%$
    
  : function setSecret(data) {
secret = data;
}

'     "  - // • #   $   


function getMessage(error, buffer) {
 "   mifare.
if (error) { // +      ,
read()   . *  console.log('  ' + error); //     
     
- } else { // +    
       . console.log(parseMessage(buffer)); // +
/     " - //    
  % 
   }
}
     
  :
parseMessage(), 
  -
  
  "  NDEF,
   :

[  parseMessage() - function parseMessage(buffer) {


   
     var result = null; // +$ 
$ 
  25. 0  

  var bytes = buffer.toJSON(); // $ 
//   " JSON
"  NDEF   if (bytes.hasOwnProperty('data')) { // †  

   
    // " JSON   
 data,

       - bytes = bytes.data; // $ 


  NDEF. 2    var message = ndef.decodeMessage(bytes);// Š  
//      


   -$  
Идентификация 487

    for  


- for (r in message) { // -  #   R 
//  ,
   verifyRecord() var record = message[r].value; //  


      - // $  
$ 
  
  
 : result = verifyRecord(record, secret);// 
//     
%$

}
} else {
result = false; // Z
 data   ,
// $ $  false
}
return result;
}

[  verifyRecord() function verifyRecord(signature, secret) {


"   

- var verifier = crypto.createVerify('RSA-SHA256');// Z$
     crypto //  %
verifier.update(secret); //   %
    

,    // $ % '  ' %$
     
  //    -
$ %
 
,   " - var result = verifier.verify(publicKey, signature,

 ,    'hex');
 
 . +,   , return result;
     %
  , }
   "  

. [  
  


 %
 -
 ,  
  

 
       ,
  
  ,    
 
 %
 :

=       - // †       ,  -


 
     
- if (process.argv[2] != null) {
.   
 "   - setSecret(process.argv[2]); // Π$  

//  ' %$

,     
 mifare.read(getMessage); //      
    
  
 //  
  "      - }
" 
 . 2  -
"   mifare.read(),

  
   
      
 -
   parseMesage()
 verifyRecord(),   -
    "  NDEF:

*       ,   - // ‰    % # R # 


//  $    # 
, $ 

  "  
module.exports = {
     
  - setSecret: setSecret,

. / 
%    - read: mifare.read,

 readNdefSignature.js: parseMessage: parseMessage


}
488 Глава 9

' 


  
,       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
(  )

    ,  


 
   =  


 HTTP   -
 
,      
    
:   —     ,

   
  
    ,  
 —    . / 
 
%
  
  ,  -             
" 
 ,        

  
. *
 
 .  
 
     
 
   ,    
   .

    "   
-    
      
 
  
,         

      -
   
 

 $ , ,  ,    
-
 
. =     

        .
HTTPS,       
-
    
 . 2  
 $


,        
GPIO, 
"    .

Создаем сервер для записи меток


0
    https-server-writer.js /*
      " . Z HTTP/HTTPS  -%
  % #
2      +   %    $  
   
 %
. : node.js
*/
#      - // '    "   :
  :   var express = require('express'); // '   
body-parser (
    - // express
    3)    var bodyParser = require('body-parser'); // $

   
    
- // 
 body-parser
 POST. ;   - var https = require('https'); // '    HTTPS

  

 require() var http = require('http'); // '    http
var fs = require('fs'); // '    %


    - //    fs


. 0
    ,  
 // $

 

   , 
var tagWriter = require('./writeNdefSignature.js');
     ,  
node_modules,   
     
 -
 :
Идентификация 489

    $ 


 var server = express(); // Z$ R$  


,  
  
 
 var options = { //     HTTPS
key: fs.readFileSync('./keys/domain.key'), // '
  
 SSL, -
cert: fs.readFileSync('./keys/domain.crt') //  % 
    " };
  server.use()  
- server.use('*', httpRedirect); // • #  

  
  HTTP  //   $ http
     ,   
 - server.use('/',express.static('public')); // 
// , 
   %

"  
. 4  
server.use(bodyParser.urlencoded({extended: true}));
       - // N  
  
 
    body-parser, function httpRedirect(request,response, next) {

      if (!request.secure) {

  
  POST HTTP: 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>');
   
  request. } else {
path. #     - response.write(command + ' 
   
.<br>');
  " "   : }
.format()  .write(), 
 response.end();

    writeNdef- }
Signature.js. =    

     
   -
,  "  %-
    %    

. 7 
  $
  — finishResponse() —
 
   

  
 
 
processTag(),      
        

   
% :
490 Глава 9

2
%    pro- //        ,   


:
cessTag()    : if (command === 'formatTag') {
.format()  .write() —  - tagWriter.format(finishResponse); // $ 

//  

     
 . 
}
  , 
    
if (command === 'writeTag') {

    — finish-
var message = tagWriter.setMessage(data, true);
Response() — 
   ,
tagWriter.write(message, finishResponse);

    . // $ 
 

}
2
      
 }
     " 
NDEF, $    -
   .setMessage() 
  "  NDEF:

* ,  

//   
HTTP  HTTPS,   $  - http.createServer(server).listen(8080); //   $ HTTP
  
 " 
 ,  https.createServer(options, server).listen(443); //  
// $ HTTPS
  
  . server.post('/writeTag', processTag); // N 
0 
: writeTag  // 
 writeTag
formatTag —   - server.post('/formatTag', processTag); // N 
      — //   
 formatTag
processTag(), 
  -
  
 :
&     
 .

Добавляем веб-страницу для сервера записи


; 
,    
- /*

,       +- #  $  /%    
 - 
 . & 
  - : p5.js
 writer   public 
  */
  sketch.js     
var userField, challengeField; //   $


 " : //   $ 


%$
var responseDiv; // ƒ
$   
2    % 
 - //  

 : userField,
challengeFiled  responseDiv,

    -
  :
[  setup()    -
 
      -
"  ,    -

   
 
 

. =  -
     writeButton
Идентификация 491

function setup() {
   

 
noCanvas(); // ^      , R -   
formatButton,  $   // Z$ 
$     

     
- responseDiv = createDiv('+    $
  . &      ' %$  $    .');

        - responseDiv.position(10, 130);
   submit(), - var userLabel = createSpan('\  $'); // Z$
//      $

  
   " . userLabel.position(10, 10);
userField = createInput('','text'); // Z$  
&   
 
    - //   $
     - userField.position(100, 10);
var challengeLabel = createSpan('  %$'); // Z$
  , $     - //     
%$
 draw(): 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()   function submit(event) {


 
  " var route = '/' + event.target.id; //  
//  %  

         -
var data = { // Z$  $ POST
   
  POST HTTP.
'user' : userField.value(),
2    
    JSON
'challenge' : challengeField.value()
 
    - };
    
  
 // &    $,
       //  $      '
  
  POST,     - responseDiv.html('      '<br>')

  $ 
 : httpPost(route, data, 'text', getResponse); //  
// $ POST
}

[  getResponse()  function getResponse(data) { // • #   $ $


  
     // $ POST

  POST. 0    % responseDiv.html(data); // +   
// $ - #
   

  
- }
      
  re-
sponseDiv:

&     

  
 . #
  ,  
 -
   
 

.
492 Глава 9

Тестирование сервера записи метки


*% 
       %    ,   "  


   . 
   
    
   
    , 
-
,       . = 
    $   
 ,  
 

 -
$      
 %
:
ndefSignature  
public   HTML
writer p5.js 
  

index.html
libraries
sketch.js
reader p5.js    
index.html
libraries
sketch.js
node_modules    ,    ' npm
https-server-reader.js   
https-server-writer.js 

 
keys  %  '
domain.key  
(
) ' SSL
domain.crt  %  SSL
private.key  
'  #  $  NDEF
public.key 
'  # 
  NDEF
writeNdefSignature.js    
 NDEF
readNdefSignature.js      
NDEF
gpioControl.js  
 GPIO

=  
 

      2   
   
 -

  Raspberry Pi  
   

   
 
   :

      


   - https://..raspberry.pi/writer.
  : 
 $   
  ..
$ sudo https-server-writer.js raspberry.pi  
 IP-
-
%  Raspberry Pi. 0
    ,  
-
 https://      . & 
Рис. 9.18. Веб-страница для приложения записи меток NDEF.
Сообщения сервера выводятся в текстовом разделе внизу


   
  
 , -
страницы   
 . 9.18.

         


  Format tag ([

  ).
&   
   
   -
"  :

     '


   ...
formatTag  .
Идентификация 493
0

  ,    - 4    

 , 

  -
   
  
 (
    , "   :
  
  
 
  ?           ?
 )     Write to tag
?
     
 %  -
(2    ). #    
-   NFC? 

 
 -
  "  : "         -
     '  
  writeNdefSignature.js
   ...  readNdefSignature.js;
writeTag  . ?    
    
 
    ?
4   
 ,   ,   -

    
  
 -  
    
,   
-
 

        .    

     .

Создаем сервер для чтения меток


# 
     https- /*
server-reader.js     Z HTTP/HTTPS  -%
  % #
 
 https-server-writer.js +     
    . #
  : node.js
*/

  
   
   
    -
// '    "   :

  ,     //  ''      ,   # 
(     - // $  https-server-write.js

 %
,     - // $

 

    
 , var tagReader = require('./readNdefSignature.js');
      
  var lockControl = require('./gpioControl.js');
  "  ). /*
... $     
,    $ 
'       https-server-write.js,  $  R$  ,
   —    '    -      $
HTTP  $   $ HTTPS

  ,     -
*/
  writeNdefSignature.
js    readNdef-
Signature.js  gpioControl.js:

=        function processTag(request, response) {


  processTag(). &   var command = request.path; //    


       - command = command.slice(1); //    '  ' 
,       - var data = JSON.stringify(request.body); // $
//  $  
 .write()  .format() 
//   
  $      
response.writeHead(200, {"Content-Type": "text/html"});
  .setSecret()  .read() response.write('   ...<br>');
  readNdefSignature.js. // • #   $  
[  finishResponse() - function finishResponse(error, buffer) {
   
 .   - if (error) {
 ,        - response.write(' : ' + error + '<br>');
 .parseMessage()   } else {
readNdefSignature.js  

- response.write(command + '  .<br>');
  
   : var verified = tagReader.parseMessage(buffer);
494 Глава 9

if (verified) {
response.write('

     .<br>');
lockControl.open();
} else {
response.write('‡ 




   
 #

.<br>');
}
}
response.end();
}
//        ,   


:
tagReader.setSecret(data);
tagReader.read(finishResponse); // $ 
 

}

4      - //   

          - http.createServer(server).listen(8080); //   $ HTTP


  
 
- https.createServer(options, server).listen(443); //  
// $ HTTPS
 POST   /readTag  
server.post('/readTag', processTag); // N
 /writeTag  /formatTag: //  

 readTag

&     
 .

Добавляем веб-страницу для сервера чтения


;  ,   

   /*
 ,     - 
  +- #    



   . : p5.js
*/
= 
    -
var userField, challengeField; //   $


  
  . //   $ 
%$
var responseDiv; // ƒ
$   
  ,    - //  



,  
  
 - 
  

  
       

   - 
   
 . 9 $  

  
      -

 %
. q

     :

[  setup() 
  function setup() {
  ,     - 
  noCanvas(); // ^      , R -
//   
 ,  %
  , 
// Z$ 
$     
  
  responseDiv 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      
  - /*
   
  - 
  Z'   % #
submit() getResponse() $
 - #   $  


      
*/
    submit()
 getResponse():
&     
 .

Тестирование приложения чтения метки


; 
   
 
  
 
   . * 
   
   $- Рис. 9.19. Веб-страница для приложения чтения меток NDEF.
  , 


      - Сообщения сервера выводятся в текстовом разделе внизу
страницы
,     gpioControl.js. X % 

      ,   
    
      "

:
$ sudo https-server-reader.js
2   
   
 -
 

   
 
   :
https://..raspberry.pi/reader.
&  
  ..raspberry.pi
 
 IP-
%  Raspberry Pi.
0
    ,  
 https:// - #

 
  "  :
    . &  

   -

  
 ,   
 . 9.19.      '.
   ...
        
 readTag  .
 ,        
- ^    '
   R

 
    "   
  Verify tag (#
  ). #

- #
 ,    
   
 
  "  :

,  

 , 

 -
     '


   
  POST. &  -
   ...  JSON,      
-
readTag  .  
, 

     %
 -
+    %$.  
, 
         -
       NDEF. # 
  

 $ 
       
  

 ,  
  
(
 . 9.20). 
      
-       ,


     
  
. 
     .
496 Глава 9

7       


    
 . 
 $  
   
    
  
   -     
  
 ,
    NDEF  %
  -  ,    
   
-
       . /          
  ,  
 

      ,  

  
        
       . *        .
"      %  
   . 4   %    - >    %  
    -
     ,   
 %
-    ,   
  
, ,        ,             RFID   
 
     
  
. 

,     
    -
*  
            
  
 . /   
 
       
-  ,      
  
,      
 
  ,  
   
   
    
  
.   ,    
  

    . * , 
    -
~          
 -      
     , $
         
 , 
- 
        
" 
    
 ,      
  
  

 ,    ,      -   


     -   
  -
      ,     -   .

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


Идентификация 497

Сетевая идентификация
До сих пор мы идентифицировали сетевые устройства по их адресам. Для устройств Интернета
в качестве идентификаторов используются как IP-, так и MAC-адреса. Беспроводным устрой-
ствам, работающим по протоколам Bluetooth и 802.15.4, также присваиваются стандартные адре-
са. Но адрес устройства не предоставляет нам никакой информации о самом устройстве или его
функциях.
&   
    
   -    . /  
   -
     4. ; 
 


   ,  
  -
  
 HTTP, 


"  "         -
 .  

  
  . &  
  ,  
API  
 

, 
 

,   ,   
 
 

.
      
 

  - 3

   
   -
  
  , 
  $ -    


   
  
  
      ,    , 
   

. 
 $,    
"     $   . = 
  


   
  
    -     
   HTTP
    - 
 . * ,   ,  
  
 
 -
 
  
  

 

  .
    
     
    
 ,  "  
 ? 

 

 — 

,  -

 node.js,   
 HTTP,    -
>%  
   + 
       %     
-

    
      ,     $  
        
    .

Пишем код сервера


'   
   /*
$  
,   - Z  $ $  
   
  node.js : node.js
*/
  clientHeaders. # 
 $     
 var express = require('express'); // '
  server.js. # " //    express
 
   npm  - var server = new express(); // Z$ R$ 
//    express
   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
498 Глава 9

&
    $  
      

. & ,   


  
        
   %  
 " :  
  
 
  "  -
  -  ,       -
{ host: '114.226.112.201:8080', 
   "   ,    
connection: 'keep-alive',   %  
.
'cache-control': 'max-age=0',
'upgrade-insecure-requests': '1',
4     $  
 

, -
'user-agent': 'Mozilla/5.0 (Macintosh;
Intel Mac OS X 10_12_3) "    
  %   ,
AppleWebKit/537.36 (KHTML, like Gecko)  
    

   
  
Chrome/56.0.2924.87   , IP-
$ 
  -
Safari/537.36',  , 
 , IP-
 %   
 -
accept: 'text/html,application/ . /      ,    %
xhtml+xml,application/  
    "    IP-

xml;q=0.9,image/webp,*/*;q=0.8', ( .   3),

    

%
-
'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,
-  . ~       
 
%    
! ;        
 ,       -
     



  -      
 ,  -

 , 
 -
   
-
    . /   ,  
  .  %    + 
  
%  
 
  ,    -
*

, 
 
user-agent 
 -   
 .
  

  
     -
%    . *   $  -

    
   
 
Анонимность в Интернете
 :     ,   - 2   


     

 - 
 —  
          
  
  " 
         

 ( Chrome $ 

. =
 
 
: accept-language — "
,  Firefox  Safari —


    
    ,  
 ,   Microsoft Edge — 
 InPrivate).
          
 . &  
 , 

 %  -
3   IP-
 , " 
       IP-
,   

 
   IP-
,
 
      
. &  
-
 ,    
  
  
… 3          
      .    …

*    $  
  
 - *  % 
 
   -
   
     
  , 
- . ~  "       + 

Идентификация 499
 , 
     - 
 clientHeaders.js    

,
   IP-
%   
    

Tor. &
  

 , 
     + 
. %      "   + 
 
+ 
   $   4  Tor *-
    Tor  q , 

(www.torproject.org) —     
- 
  
  Tor  [
 ,  
 

     , " 
  "    Tor  *
 .
    + 
 
   +  $   Tor  *
    

    . #  Tor    
 -       

. 3    -
     + 
  
-     nslookup ( .   4),
   

, 

    IP-
,  
 
-

  
-
,
%  %  
 ,        
 
  . 
    

 Tor -  .

  - 
   
   
-
     
    0   "   - 
  
 


  Tor,     
   " 

 Tor     . &   -

  

  Tor, - , 
  
    ,  -
   $  .    

 -            % 

 (     !)    
       
   
      
 - Tor, 
   
  

 
% -
  - 
  ,   
   - 
  . ;   ,  
-
 
             
 
  Tor,  -


. ; 
,


%   % 
 
   
  
%-
  - 
    (  IP-
   
    -  -

%   
 ),          (   ) " 
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_
& 
 
%     CSV, JSON
name":"Ukraine","region_
 XML. = 
 
 ip-   - code":"","region_name":"","city":"","zip_
  IP-
 "   code":"","time_zone":"","latitude":50.
. &        
  45,"longitude":30.5233,"met
 
  IP-
, 
   ro_code":0}
500 Глава 9

# "   
   
      
  Mozilla
 ,       IP-
 , Foundation. / 
  
  
    . 4       Netscape —    
  -
    -

,    
   & 
  . 4  " 
-

 , 
 

        Mozilla — 


   -
Google Maps,         , 
"    
   
 . 
 
  

 NCSA Mosaic.
>

Firefox    Mozilla,    -

   

  
 "          
 

  %  



,     - «
»   -

,   Mozilla

 
 user-agent   
  $   Foundation 
   
  
 ,
Mozilla/5.0. *

,  " 
 -

 "  
  & 


  
  
 
 user-agent    + 
   . #   ,


 Chrome  
 macOS:  
"    
 -
  
  

: 
, CSS
Mozilla/5.0 (Macintosh; U; Intel Mac
 JavaScript —      

OS X 10_5_8; en-US)
AppleWebKit/532.5 (KHTML, like Gecko) Mozilla/5.0  
 
user-agent. + 
Chrome/4.0.249.0      $ 

  
Safari/532.5  
.

=   ,  %  


   - '    

-


 
    «    ,   $  
    
Mozilla»,  $   ,   ,   -    
,      -
, 
   , 
 -   .

Пишем код
#     
- /*
  
     geoIP. Z, '
$ # '     IP-
X     express, : node.js
*/
     
 " 
-
. &  
  - var http = require('http'); // '    http
    server.js     var express = require('express'); // '   
  "  . // express
var server = new express(); // Z$ R$    
&   
,    , // express   
server
    express // ˆ  Google Maps
  
   node.js  - var mapsAddress = 'https://www.google.com/maps/place/';
 http, 
      //    freegeoip
     
   var geoOptions = {
  www.freegeoip.net. = host: 'freegeoip.net',
  $ 
  path: '/json/'
};
express  
  server,
     

    
 
    www.freegeoip.
net ,  , 


  

 
Google Maps:
Идентификация 501

  ,  $   // • #   $     GET
    
 "   
, function respond(request, response) {
   $  
  - console.log("IP-  : " + request.ip);
 
 
  GET,

"   
 
  respond(). & $  -
     IP-
-
    
  HTTP
   www.freegeoip.net, 

     :
&     respond() function getIPAddress(geoResponse) {
     http.request() var result = ''; // Z    - 
  HTTP  
 - // 
//        
  freegeoip

 , 
"   -
geoResponse.on('data', collectData); //  

    getIPAddress(). // - 


/   
 %   geoResponse.on('end', finishResponse); //  
   

 // $  
freegeoip    
- function collectData(data) { // Š   
 
 "   . //     .
result += data; // Z  -  
2
    
  // -   .
      }
 
   

  respond(),  

%  
 
 
         -
   :
 
%    
- //  $   
%          function finishResponse() {
var location = JSON.parse(result);
  finishResponse(). & - var latLong = location.latitude + "," + location.
    
  longitude;
user-agent   
- 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(); //  $
}
502 Глава 9

   ,     
 server.listen(8080); //        
     

  //  8080
server.get('/', respond); //   $ GET

 
    -
 :


 
"   $  
  
-   
 
 example.com IP-
 

      

   
 :
   Google Maps,    IP-

$ curl example.com:8080
     
 . * 
 
"  

   — 

,    curl, #

 
     -
      
 ( .   3), " :
  
"  
 JSON. 
  - {"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 поместил меня в за-
падный Техас
Идентификация 503
     
 . 9.21,   - // Z$   HTTP

   IP-
     . q  HttpClient http(netSocket, server, 8080);
IP-
      
    http.beginRequest(); // ^  $
   
      - http.get(route); //   $ GET
   "    IP-
. * // Š $ user-agent
http.sendHeader("user-agent","arduino");
  $  , 
 ,   
-
http.endRequest(); //  $
 
 "   %  
%
- 

 %   "   + 
, 
%  
   . > , 2
   
  
 us-

   
   
,  - er-agent    
   
  
 -

,
  - curl 
     
. = 
-
 
   
        


  
  -
% . $   "
 
 
 -   Mozilla    user-agent:

 ,  
     

 : «7      IP-
. 0  $ curl -L -A 'Mozilla/5.0' example.
com:8080


     
  -
»,  
 

   $   - [ -L    curl     -
   : «* ,   ! ; %

 ,   -ˆ   ,   -
    " + 
». "   
    
 
 user-
agent.
=
 "        $
 
        user-agent. +   
  user-agent 
'   ,     
       
  %
 
  
 user-agent  - , 

,   $ -

  HTTP,     

 -     
  

  -
  
 

,          "  
  ,


   

,   -        


 
   ,         
   

,
-
user-agent. *

,  


        .
 ,  %       -
 Arduino 
 

, 
  
   

  " 
:
504 Глава 9

Заключение
В этой главе мы рассмотрели несколько примеров
сопоставления физической и сетевой идентифика-
ции. Граница между физической и сетевой иденти-
фикацией всегда порождает возможность путаницы
и недоразумений. Никакая система для перемеще-
ния информации через эту границу не обеспечивает
стопроцентной надежности. Определение идентич-
ности, возможностей и действий — это сложные за-
дачи, результаты решения которых предрасположе-
ны к ошибочной интерпретации. Так что, чем боль-
ше информации от людей вы включите в ситуацию
и чем больше прозрачности и помощи предостави-
те вовлеченным людям, тем лучшие результаты вы
получите.

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/).
508 Глава 10

Компоненты для проектов этой главы


Многие основные аппаратные компоненты, используемые в проектах этой главы, вам уже знако-
мы. Однако здесь нам придется также работать с переменным напряжением номиналом 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. Нитки для вышивания

5
4

15
11 12
13
16 6

14
8
7
1

10 9
Сети мобильной телефонной связи и физический мир 509

ПРОЕКТ 29. Возвращение сетевого кота



C      , 1 +. 
      
, 1 +.
D: 438-1045-ND, J: 20723  20601, SF: PRT-   SparkFun 
   
 , -
12615  PRT-12002, F: 4692810, AF: 64,
  
 "  . &  
SS: 319030002,  319030001,  %  
       -

 AF: 2077, A: TSX00083, SF: DEV-  
  Power Switch Tail.
07914 %     SF: PRT- SF: KIT-13815
12044, AF: 65, D: 923273-ND

  > PowerSwitch Tail, 1 +. /

 Arduino MKR1000, 1 +. 
  
    
AF: 3156, RS: 124-0657, A: ABX00004, GBX00011  
     . &

(3
  4#), D: 1659-1005-ND  240 &   

   -   www.
&   
     powerswitchtail.com.
  
   ESP8266. SF: C0M-10747, AF: 2935
SF: WRL-13231, AF: 2471 
(
 
 1 , 1 +.

   A > IP-
, 1 +. (  D: 1.0KQBK-ND, J: 690865, F: 9339051, RS: 77-
 
    Raspberry Pi). 7666
DL: DCS-930L, DCS-5222L,  DCS-960L 
(
 
 100 , 1 +.
& $ 
    
DCS-930L,
D: 100QBK-ND, J: 690620, F: 9337660, RS: 755-
DCS-5222L  DCS-960L   D-Link, 
0707
 
   
  Raspberry Pi 
Pi Cam (           ), 
 
 4N35, 1 +.
   "   : J: 41056, F: 1244500, D: 160-1304-5-ND, RS: 597-
• Raspberry Pi SF: DEV-13825, AF: 3055, SS: 302
114990584, RS: 896-8660, F: 2525225 &   
    
• Pi Cam SF: 14028, AF: 3099, SS: 113990214 
    SparkFun.
SF: BOB-09118
• Pi Zero W Camera Kit A: 3414

.

!
   
A 
DTH11,
1 +. 
 

  .
AF: 386, J: 2245415, SS: 101020011 
#    (
    ).

ПРОЕКТ 30. Звоним термостату



# +   29, 1 +.

N  
 Twilio, 1 +.

%& , 1 +.

ПРОЕКТ 31. Мобильный регистратор личных биометрических данных



N   D Android

iOS, 1 +. &   
     -
  Arduino 101,  - %

 RedBear BLE Nano
USB-  MK20.


         % .
+    .
D: 1660-1003-ND, J: 2239331, SF: DEV-13787, A:
MS: MKRBL5, SF: WRL-14071 3033, F: 2520713, RS: 913-9999, SS: 114990575,
A: ABX00005, GBX00005 (3
  4#)
510 Глава 10


H  ) + 
  - 
%    >+ , 1 +.

 2,5  A +  
.

]

 +

. =    
AF: 400, SF: PRT-12693. 
 
 .
&   
     
D 

-  
- 
(IC-hook with pigtail). • Adafruit Fona 800.
SF: CAB-09741  CAB-00501 AF: 3147 (#3), AF: 2691 (4
)

! A  
  . • Adafruit Fona Feather
SF: DEV-10730  DEV-13883 
 PRT- AF: 3027
00338, AF: 1870  1871    654. 4 
 
  
 %  , • Seeed Studio Xadow GSM+BLE
 — SF: DEV-11893  PRT-13851. SS: 102040005

(
 
 270 , 1 +. • XBee Cellular
J: 691446, D: CF14JT270KCT-ND, RS: 845-7577 D: 602-1976-ND,

%   $
 .
• Particle Electron Kit
AF: 603, SF: DEV-11791, L: 304
SF: WRL-14211 (#.  Š. 3
/3 
),

%  $   . SF: WRL-14212 (3
/3/4
)
AF: 1168, L: 1220


+
 A 

 
5 .
AF: 1126, SF: DEV-11347

Одна большая сеть


Телефонная сеть возникла задолго до сети Интернет. Все соединения в ней осуществлялись ана-
логовыми электрическими схемами, и все телефонные звонки были коммутируемыми, то есть
между абонентами устанавливалась временная выделенная цепь. Затем появились модемы, ко-
торые позволили компьютерам обмениваться данными по тем же самым телефонным аналого-
вым цепям. Постепенно телефонные коммутаторы были заменены маршрутизаторами, а новые
телефонные сети стали делать цифровыми. Теперь абоненты соединяются виртуальными цепя-
ми, и сценарии телефонных звонков почти не отличаются от сценариев электронной почты или
чата: между абонентами устанавливается сеанс, происходит обмен битами и осуществляется об-
мен сообщениями. Различия между телефонным звонком и электронной почтой сейчас заклю-
чены в протоколах, обеспечивающих каждый вид связи, а не в структуре электрических цепей.

 
   
-    — -   , 
   «  »
 

    
   -      . 0    
   Asterisk (www.asterisk.org),               -
    , 
    -    
      
%
-
  Twilio (www.twilio.com), Google Voice 
,  
 
      
(www.voice.google.com), Skype (www.skype.         ,  
 
 
com)  
., 
 
  
   -   
 , 
  
            
 ,
"  -

 + 
. /   
 
  IP-   .
Сети мобильной телефонной связи и физический мир 511
X         + 
 
- " ,  

    
-
   %  
%

,
-  
  . .,      ,
" 

        - 
 
 
   
-
 

  
. *

,   

. $ 
  
 
 


    
 

     $
SMS-%, "           


 "  $ 
   , -  %    
    

     
   "       
 
 .
SMS,  
 "  SMS, 

     "  $ 
  - 9  
  
  
 -
 . # Google Voice    
 

      —
        
            

-
           , . +  
  $     -
 "        
-    ,  
 
, % 
  , 
  
          
  —



   
  

-  :
       "   , 
 -
  . 0    

- ? 


  ;
 
 ,  "     , ? 
$
  
;
    ,    

-
?      ;
   
    
 
 
 . ?   Bluetooth;
?
  USB;
Компьютер у вас в кармане ? 
   ;
#
     — 
- ?  
  
 
;
 — 
      ?  
 
   GPS.

   
 ,   
     -

 . ; 
 —  *   $       
 -
 iPhone      0# Android — $ , 
   
  
,
 " 
,
"  
- 
     
  -
      
     .      :  Wi-Fi   
&         
   —       
    
      - Bluetooth —   . &   
      
 " -   
  IP- ,    -
  
 ,   
   -  
 

 
-
 — $   %   
 
  + 
: HTTP, $ 
   , SSH,

    , 
  - FTP  . .
      
, -
   %  . >%  
  *
 . 10.2       
  "
    ,  
      


     :  -  , 
 
 
 

 ,  
 
,    "    + 
.         
 
   GPS. +,     ,    -  + 
 
     
     . *     ,  %.
$         -
 

  
  — -
512 Глава 10

Сеть мобильной связи

Базовая Базовая Базовая


приемопередающая приемопередающая приемопередающая
станция (БПС) станция (БПС) станция (БПС) Смартфон

Контроллер Контроллер
базовой станции (КБС) базовой станции (КБС)

Шлюзовый Узел поддержки GPRS


коммутационный центр
мобильной связи
Коммутационный центр
мобильной связи (КЦМС)

Интернет Поставщик услуг


Интернет

Телефонная
коммутируемая сеть
общего пользования
(ТКСОП)

Проводной Поставщик услуг


телефон Интернет

Домашний
маршрутизатор
Поставщик услуг
Персональный компьютер
веб-хостинга

Рис. 10.2. Взаимодействие сети мобильной телефонной связи с сетью Интернет


Сети мобильной телефонной связи и физический мир 513

Определитесь, как это должно происходить


 $ 
       
-  
   
    
 .
 "  

  
 - >%  
 , 

 
-
:   
   ,    ,    $   , 
    
     ,     ,  - 
  
  

.


  ,      
$   %  . &

  - Интерфейс на основе своего
   ,  
   
 
приложения


  
    
 
 
? +    , " - 4   - 
   -

  ,      , 
  -        
 
  
  — 

, %   -      

,  


 - 
?   ,  
  
   
 ,  


  
     . "   
 
-
*     

  
  Bluetooth, , USB  
 -

 ,   
    5,    - "  SMS. 7
 
 


          
    $  . 
" 
     ? X 
  

    
  — 
   
  — 
            

 
 -
  
        - " . *     —   -
        Bluetooth  
 


 ,  
 USB? 4  $     ,        $ 


    ,  
   
  
   
     .
   ? 7     
 
 ,   

    
   ?       "  
,  
  

  
SMS  $ 
   ,  ""        
   
 -
     ? 
 
  ,  $  
     -
  
  
        
 .
 
       , 
 
   
 "    
- Интерфейс на основе сообщений
  
  
 . X   ,   SMS или электронной почты
  ,    
    &         
 -
   . 4        Wi-Fi?    
   
   
-
   ?      Ethernet? 
  
 . 4     
&      %  
  - 
  
       
-

     " Bluetooth       
 
 Wi-Fi?
   
 , 
  -
         , — 

,
Интерфейсы на основе браузера         %-
4    
        " , —       -
 
   
 ,     -  "  SMS  $ 
   . ;
  $       
  

  $ 
 


    + 
  
   
  , 
   "  SMS

  

. ;  
      GPRS,     

,


   
      
 - 


   "  
 -
 
  —  ,    , $       "  "  $ 
 -
         HTTP  -      
" " 
514 Глава 10

   + 
 
 

. Телефон как шлюз

"  $     ,  *  
      
-
   
    
 -  
 
     
 .
 " 
  , 
  - +  
  
    
-
  
 , — 
 "      
     
SMS  $ 
   .        . & 
        -
Голосовые интерфейсы   
 

  
  — 
"
*     
         Bluetooth  USB,    

    —      
  -    

. =
   
  . q   
- $ , 
 ,  
   
      
     
-   
  ,    %  -
    ,     

-           
      
     
     
   .
  
  %     —
  Asterisk  Twilio.

Проект 29
Возвращение сетевого кота
Если в состав программного обеспечения вашего смартфона входит браузер, вам нет надобно-
сти знать, как его программировать, чтобы создать мобильное приложение. В этом проекте мы
создадим вариант проекта сетевого кота из главы 3. Но на этот раз мы воспользуемся новым про-
токолом — MQTT — и IP-камерой, для подключения которой к Интернету компьютер не нужен.

X   ,   _,  , -


Требуемые компоненты 
     q  

. X _

>       , 1 %.   
   %   .

 Arduino MKR1000,  WINC1500,  0       ,  

  
   ESP8266, 1 %. 
,    . 0    
 -
  

,    ,  
+       : GPIO, Wi-Fi.
       
 . ; 


    IP- , 1 %.
  
    %

=  

, 1 %.   ( 
   
 ), _

    
 
 , 1 %.         
 


 
  
-

9  
  1 0, 1 %.
 . ' 
,    -

9  
  100 0, 1 %.    
 

. 7 

 

0
, 1 %.  " 
: _    


   
     

# , 1 %.
 - 
 
"  , 


.   
        -

 
.  . 2      "  
-

   
  

,     -

2
   (      ).

,   

   -
.
Сети мобильной телефонной связи и физический мир 515
4   

% 
,      #      
 
   
       
  
 
      
 

,   % 
  — -   —  $     
   . 

  
             . 9
 
  
      _  Wi-Fi   MKR1000    -
     

. 
 

 
   
  SPI.
=  


   


   
%
  - , 

 
   220 & 
   ,        - 
   
 — 
  -
      
   
- . >  IP-
  $ 
   " -
,  
  %  
, 
  Wi-FI, $  ,   
  ,    
 . *  , — $  
   

 . 10.3   -       , 


%

.  

 

 
 . 10.4 — 
         -

 %  
 ,
. 
  %  .

Рис. 10.3. Блок-схема системы связи


для наблюдения за котом и управления
Мобильный Компьютерный
кондиционером
клиент клиент

Мобильная сеть Сеть Ethernet


или Wi-Fi

Интернет

Подключение DSL
или кабельное

Wi-Fi Домашний
Камера
маршрутизатор

Wi-Fi

Цифровой Интерфейс
Датчик ввод SPI Радиомодуль
температуры Wi-Fi

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

Цифровой
вывод
Реле
516 Глава 10

GET
index.html
Веб-клиент image.jpg

OK Поставщик услуг
index.html, веб-хостинга
image.jpg
Сервер HTTP

Публикация MQTT:
setPoint,
Подписка MQTT: все mode, update

Брокер MQTT

Передача файла по FTP

Публикация MQTT:
все
Микроконтроллер

Датчик Считываем Камера


Подписка MQTT:
температуры показания датчика setPoint, on,
mode, update
Включаем или
Реле
выключаем реле

Рис. 10.4. Блок-схема взаимодействия системы наблюдения за котом и управления кондиционером и собственно контрол-
лера управления кондиционером

=  -
     - 
- Протокол MQTT
  
 p5.js —      -
7  
       -
-
   %  
  
 

 
 

,   

-
FTP 
  
    "-
 
 (        -
    -  . = 
   -
 3),  

  
"  -

     



IP-
. 0      

 

,       "
 
    . &  $ 
 MKR1000    
  
  
   - 
   
 -
ESP8266. *  
   


  "      -  ,  -


 
 node.js, 

  
  $  
 — MQTT2.
%   -   , —     

  - 
 ,   
    - 2
MQTT, Message Queue Telemetry Transport — 
 

 
 

.  
 "     
.
Сети мобильной телефонной связи и физический мир 517
X
" 
   "  *

,       ,
MQTT (http://mqtt.org) 
    
- 
" ,      
        - ,  

  $  -
,  
         .  $ 
   
 . #



 MQTT 
-  "    :
     
. = 
 - ? airConditioner/connected — 

   3,    
 #
4. 
 

    

X 
  
  
            ;
 

 "  ,  
  
? airConditioner/update — 
  -
" . 0    
    -   "   
 
-
  " . /    ,  -  

     
 
 MQTT      
      .

 




5.
Схема системы
*

,  $    %  

(airConditioner)     
 ,  ; 
,        " 
 -
  
   
 airCondi- 
    ,   
  
tioner/   "  :
. 
        -
  
   
 
  
? airConditioner/on —    :  
 . 10.5,     — 
 . 10.6. & , 
   ;      
 

, —
? airConditioner/mode —

 : $   

, 

 .
 ,   ,   ;
? airConditioner/temperature —  " 9  
 % $ 

, -
 

    ;   
     . 
 %    
  ,   -
? airConditioner/setPoint — 

 

,  
  
- 
       , 
 
 
        

  -      
  
,  
 
 .  . 
  
 
   

      

    

   
- (
 . 10.7). 0"      
-
 

   "     
   
 . 10.8.
/temperature,   -     
"     /setPoint,    0
 $  
  -

  

 
 ,   -  
  
,    
 .
   "     /mode, - 0       
  
.
      
  
 

   ,
  
 
     "  
  
,  $   

   
 .       
  $
, 
-
          
 ,
  

          . 0   
 -
   , 
 

  
 
  $ 
   . ;
 -   "  
  
  ""    
 

  -
 

  
 . *
- 
    
      
 
 MQTT      . $ 
 . X
       
3
0  . topics.   " % ,   

4
0  . messages.            -
5
0  . Publish & Subscribe,  PubSub. 
   5 &.
518 Глава 10

«Плюс»
питающего тока

Модуль
«Плюс» микроконтроллера
питающего тока 10 КОм
Выходной
сигнал D4
Датчик
температуры N.C. D5
DHT11 Общий
Общий

100 Ом
Управляющий В электросеть
сигнал Э Реле
Общий (Эмиттер)

К
(Коллектор)

Оптоизолятор

Розетка
для кондиционера
Рис. 10.5. Принципиальная схема системы удаленного управления кондиционером

Рис. 10.6. Монтажная схема системы удаленного управления


кондиционером, собранная на микроконтроллере MKR1000

A B C D E F G H I J
1 1

5 5
LOAD
Gnd Cntl. 5V

10 10

15 15

20 20

25 25

30 30
A B C D E F G H I J
Сети мобильной телефонной связи и физический мир 519
9 
   $ 
 
     , $ — 
  
   
  $ 
  —
  ,        
-
 . 4       
 ,
     
   


  ,      
  PowerSwitch Tail  
  -

   240 & (www.powerswitchtail.com),

  

    Adafruit
 SparkFun.  , $ 
    

   
   WeMo, -

      9.

*     
    
  
 ,       -
 
    SparkFun    -
     %  
 -
 PowerSwitch Tail. & 
    
,       ,

-
            
- Рис. 10.7. Контакты платы реле подключены к разрыву в

    LOAD (*


) 
 . одной из жил кабеля питания
*
 . 10.7 
       
    
  
. &  Рис. 10.8. Блок розеток, включающий реле, провода управ-
« »,   +5 &  
 
 - ления которым подсоединены к модулю Arduino, — так
обеспечивается безопасная работа с питанием от электро-
     
 

. =  
сети. Можно было бы также воспользоваться модулем
    
 
  $ 
- PowerSwitch Tail
   
 ,   -
 
 . 10.8, 
      

  *  #  (Nathan Seidle) 



 www.sparkfun.com/tutorials/119.

'    

      -
   $ 
 ,    -
 
 
 
   

       %
    -
    "      

    . 0  
 %
- 
(

    )    
  
   . 3 
 

(

   ,     
 )
    
    

    
 . ;  

      ,      
 -
      +5 &, $ 
  -
   
 . 3 
   -
   
 
  « » 
-
   $ 
   
.
520 Глава 10



  
  
, 

- 
 . _%       -
 
 
 

. = $   
   
   $ 
 -
      
 
     . 
 $ 
    

D1 
 

     
 - 
  
   
 , 


  «7» (Blink)    1 — 

       -

        .       . 2



   , 

      -
0    
     
 - ,    ,    ,  
 
  
% 
 
 $ -  "  . X  $ 
   -

 . 4          ,     ,        
$     
    ,  
- 
    $ 
 , 
 ,  
    $ 
  —  "     % .

Пишем код для этого проекта


Назовем скетч для этого проекта AirConditionerArduino. Так как скетч весьма сложный, мы будем
создавать его по частям.

Проверяем работу датчика температуры


& 
     /*
 

DHT11. /    MQTT     # 
      : Arduino
    , 
  */
  ,    , -
       . &  #include <DHT.h> // '    DHT
const int sensorPin = 4; // ^      
     
 
- //     
 OneWire   Dallas DHT dht(sensorPin, DHT11); // Z$ R$ 
Semiconductors. =
    
 7 
 

- // DHT

 Arduino      void setup() {


  DHT Sensor Library  Serial.begin(9600); //    ' $
Adafruit Unified Sensor   dht.begin(); // ˆ        
Adafruit. }

&     -


  DHT,      

  , "   
  

,      -
 loop()      -
     
  :
&   loop()     void loop() {
     - float temperature = dht.readTemperature(); // Z 
      $
 . [  // $    
float humidity = dht.readHumidity(); // Z 
readTemperature()  -
// $  
   
  Z  , Serial.print(temperature); // +  
  
   [
  $ // $   R
       
 
 Serial.print("°C ,");
true — readTemperature(true). Serial.print(humidity);
& %  
    
Serial.println("% rH");

  Z  :
}
Сети мобильной телефонной связи и физический мир 521

Управляем реле
X % ,    - /*
   
    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)
setup()  

   
boolean deviceConnected = false; //  




 
  : // 

const int sensorPin = 4; // ^      
//     
const int relayPin = 5; // ‡
    
 


DHT dht(sensorPin, DHT11); // Z$ R$     DHT

&   setup() 


 - void setup() {
     Serial.begin(9600); //    ' $
 

    
 - dht.begin(); // ˆ        

 
 
 temperature = dht.readTemperature(); // –



//  
 : pinMode(relayPin, OUTPUT); // 7 
 
//  
  
 

 
//  
!
 
&   loop() 

 , }
     

, void loop() {

   "   temperature = dht.readTemperature(); // Z 

 ". 4    , // $    
   $
  "  - if (abs(temperature - lastTemperature) > 0) { // $

,
// 
     
 
  


,    
    -
Serial.print("C

 
 . C
 

: ");
"        Serial.println(temperature);
 "  
. }
lastTemperature = temperature; // 9 


 
   " // 

  

 



 :  ,  - if (mode == 3) { // Π
 
! 
 ,   . & - checkThermostat();
 

 }
digitalWrite(relayPin, deviceIsOn); // 

         //  



      

. delay(2000);
*   

 , }
 
 
   -
 
  deviceIsOn.

9      " ,
 
  
  ,    
    loop() -
   2000   :
522 Глава 10

&       - void checkThermostat() {


if (temperature > setPoint) {
  : checkThermostat(). if (!deviceIsOn) {
0 

   

  deviceIsOn = true; // 




       }
}

      
 - if (setPoint > temperature) {
. 4   

 % , if (deviceIsOn) {
  
    
- deviceIsOn = false; //  



,    


 ,  }
}
  % —    : }


      $    -  —      . X 
% ,

 ,      ,   
    
,  -
 

 
     -       
  
 
 
 
  .          MQTT.


       $ $  - =        -
 ( 
 )       -     MQTT  Arduino. 7 

         


   Arduino 
  
   setPoint. 
     -  ,        

     % ,    "   - MQTT



 =$ q 
 (MQTT
     

, 
 by Joel Gaehwiler). X   $  
    
 ,    
 .  


 Arduino "
; 
  
   
- 7 
  . 4    
   -
 
 ,    

  —   $  ,     -

 , 

,       
  
: https://github.com/256dpi/
,
     - arduino-mqtt.

Добавляем учетные данные


    
 /*
    ,    MQTT     # 
       : Arduino
     . */
=  $ 
  Arduino
  config.h, 
  - char ssid[] = " _
"; // \  (SSID) 


    
 char password[] = " "; //   -  
//  ' 

 

   
char mqttUser[] = "airConditioner"; // \  $ 

  $  ,    //   MQTT
          char mqttPass[] = "_mqtt"; // $  
 MQTT
D  | !
 &.

      (SSID)
 
,  $     -
     
  MQTT. &  
      
      

   MQTT. 2  , 
" % , % $ 
,
    
   -
 , 
  
  

 MQTT:
Сети мобильной телефонной связи и физический мир 523

Подключаемся к сети

  ,    - /*
     MQTT   MQTT     # 
 Arduino. 7 
- : Arduino
*/
  Arduino 
 -
   ,    -
#include <DHT.h> // '    DHT
     MQTT #include <SPI.h> // $

 SPI


 =$ q 
 #include <WiFi101.h> // $

 WiFi101
(MQTT by Joel Gaehwiler). X - //#include <ESP8266WiFi.h> // €   

ESP8266
 $     //  
# 



 Arduino - #include <MQTTClient.h> // $

 MQTT
" 7 
  . Client
4    
    #include "config.h" // $
  
   
 $  ,   - WiFiClient netSocket; // •
 

 

MQTTClient client; // •
 
 MQTT
 
  
: https://
char serverAddress[] = "192.168.0.15"; // Œ
 

 MQTT.
github.com/256dpi/arduino-mqtt. // `!

 # IP-
 
   
,
//    
  

+,    - boolean deviceIsOn = false;
 
 
 // ...   '    $ $ 
  (     -
    

%
):

&   setup()   void setup() {



 
     // connect to WiFi
Wi-Fi, 
    Serial.begin(9600); // \ #  $    '
// $
 
 " 
 . ; // $
 
  
 Wi-Fi,
        - while ( WiFi.status() != WL_CONNECTED) {
 config.h: 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() - pinMode(relayPin, OUTPUT); // %     


     MQTT 
- //       
//    .
   client.begin(),
// %

 MQTT   
  
         mqtt- client.begin(serverAddress, netSocket);
Connect(), 
  
 - mqttConnect();
   : }
524 Глава 10

&    loop() void loop() {


  
 
, 
 client.loop(); // $


  

if (!client.connected()) { // * 
 


 ,     //  

,


,   ,     Serial.println("7
   

");
     : deviceConnected = false;
mqttConnect(); // $ 
 

 
}

   - temperature = dht.readTemperature(); // Z  $ 
//   
   
  $   if (abs(temperature - lastTemperature) > 0) { //  ,
  
- //        $ 

. = $  

 - Serial.print("ƒ   $  . ƒ 
  : ");
,   " 

 
Serial.println(temperature);
   

, - client.publish("airConditioner/temperature",
  
    String(temperature));
     

. }
0      loop() lastTemperature = temperature; // Z-   '
//      '  
    
 : if (mode == 3) { // ˆ  
 
checkThermostat();
}
digitalWrite(relayPin, deviceIsOn); // +' 
// ' 
}
&   checkThermo- void checkThermostat() {
stat()   

if (temperature > setPoint) {
client.publish()    if (!deviceIsOn) {
deviceIsOn = true; // +' 
       -
client.publish("airConditioner/on",

. String(deviceIsOn));
}
     MQTT }
  
     if (setPoint > temperature) {
  ,    "  , if (deviceIsOn) {
$       - deviceIsOn = false; // +' 
" 

     client.publish("airConditioner/on",
  .publish(): String(deviceIsOn));
}
}
}

; 
 
    // $ 
    


   mqttConnect(), void mqttConnect() {



       - if (!client.connect("airConditioner", mqttUser, mqttPass)) {
return; // ‡
  
    
    

.
}
&     
"  Serial.println("$  

");

   %  - deviceConnected = true;
. 3 
   %   - // $

  
  
  ,
         // 
   



  , 
   client.subscribe("airConditioner/on");
    , client.subscribe("airConditioner/setPoint");
          client.subscribe("airConditioner/mode");
publishAll(), 
  
- client.subscribe("airConditioner/update");
publishAll();
   " :
}
Сети мобильной телефонной связи и физический мир 525

[  publishAll()  - // $




    
   - void publishAll() {
client.publish("airConditioner/on", String(deviceIsOn));
 
 

  
client.publish("airConditioner/temperature",
   "     / String(temperature));
update,   
 . client.publish("airConditioner/setPoint",
0        - String(setPoint));

: client.publish("airConditioner/mode", String(mode));
client.publish("airConditioner/connected",
* ,       String(deviceConnected));
  " "  }
MQTT. #  
 
 , $     void messageReceived(String topic, String payload, char
   messageReceived() bytes[], unsigned int length) {
      Serial.println(topic);
Serial.println(payload);
  
 
,    
// parse the topic
   
 

int divider = topic.indexOf('/');
topic ( )  message ( " -
String deviceName = topic.substring(0, divider);
 ). *    String property = topic.substring(divider + 1);
     . *    // *
  
  , 


$ 
    - if (property == "update" && payload == "all") {
 /  "   ,    publishAll();

     $  }


  
: deviceName ( if (property == "on") {
 
 )  property (  - deviceIsOn = payload.toInt();
). }
// *
 
 

setPoint,  


4      
  if (property == "setPoint") {
update,  "  all,   - setPoint = payload.toInt();
    publishAll(). }
// *    mode, 
  



4      
  // 

—  ,   , 

   

on  setPoint,  
- // 
!

   "    - if (property == "mode") {


      (int)  - mode = payload.toInt();

       " switch (mode) { // $

 

mode

  .   $  - case 1: //  
 checkThermostat()   digitalWrite(relayPin, LOW); //  



       // ( 


)
    
 . deviceIsOn = false;
client.publish("airConditioner/on", String(deviceIsOn));
3      
  break;
mode,  

    case 2: // 
        (int) digitalWrite(relayPin, HIGH); // 



// ( 
)
        -
deviceIsOn = true;
    
    -
client.publish("airConditioner/on", String(deviceIsOn));
" 
. [  loop() break;
       mode case 3: // Π
 
! 
   
  ,   - checkThermostat(); // $

  
 
    checkThermo- break;
stat(). }
}
/ 
%     mes- } // 7
   messageReceived()
sageReceived()     :
526 Глава 10

+   $    


 

X   Mosquitto  %  Linux,
     
  -    -    Raspian,  

 "  - , 
 -    "  
   apt,
   ,    ,  -    $      9:
        
.
$ sudo apt-get install mosquitto
Брокер MQTT Mosquitto X   

 

 Mosquitto, -
&  , 

   -  
    
   -
   

 MQTT,        %    . X   IP-

 

     Mosquitto.  
 ,  
      

, 
/ 

 
     , -           
 -

        macOS, Windows  serverAddress  
 "    
 Linux. # 
   
    
 

.
      

 http://mos-
quitto.org. 2  $ 

    >

Mosquitto         
   "      -  .    
  " 
:
&
 

  Windows   
- $ mosquitto
   

 http://mosquitto.org. *

       

, - &    $
  
   -
        "  :
( .   readme 

 ). +  $  ,
    
"   %    - 1489964660: mosquitto version 1.4.11
    Raspberry Pi. (build date 2017-03-14
19:27:44+0000) starting
X   

  %  macOS
     " Homebrew —  - 1489964660: Using default config.

    $ 
    - 1489964660: Opening ipv6 listen
 . =     
  Homebrew socket on port 1883.

     -   https://brew.sh,
1489964660: Opening ipv4 listen
          "   :
socket on port 1883.
$ /usr/bin/ruby -e "$(curl -fsSL
https://raw.githubusercontent.com/ 9 

 

"    
Homebrew/install/master/install)"   % <Ctrl>+<C>.
X   Homebrew,       4  
     

 Mosquitto
Mosquitto   :    "   % , $  ,
$ brew install mosquitto  

           .
&   
%      
7  
      - ( .  ! «|  
  

 
 $PATH. = $   
 
  »)  
   
 : 

     .
$sudo nano /etc/paths
4      , "   
-
       
%      

,  
 
-

: /usr/local/sbin/  
   , 
,  
      

, -
    
  

 
 .     
 
   
Сети мобильной телефонной связи и физический мир 527
  

 Mosquitto,       - port 1883
  "  
  "  : listener 8888
protocol websockets
New client connected from 192.168.0.14 password_file mq-pwds
as airConditioner (c1, k60, usomeone)
log_type all
( '  
   192.168.0.14
 airConditioner (c1, k60, usomeone) allow_anonymous false

/   ,  



Mosquitto
  #
  $  ,       

  
,  %     -  Mosquitto mq-pwds   -
   . +       : airConditioner —  
 
 -
  IP-
   
  
 -
  webClient —   - , 

"  .   . [  
    
 -
  
      
-
7      Mosquitto  
-  
 -       :
 

,    -  ( .
 . 10.4). $ mosquitto_passwd -c mq-pwds _$
& -        -  ,
, 

% $,  
    =   "   , 
-
 

    
  
-    . 
  
 . X      Mosquitto -      
     -
          , 
 
  . &   
 mq-
 
         ,  pwds      
   -
    
  - ,   
 %
  .
 .
#   ,   
   -
+,    
,  
  -     -

   - . = $-
    

Mosquitto,   $    
     

    catCamDeux,    —   
  p5.js   public,     
  mq-local.conf       -  
   

  
  -
" 
 :    httpServer.js.

Завершение работы демонов и других процессов


* 
  Linux

 

     
 
 _$  
Mosquitto          ,           Linux. & -
     
 , 
           
    -
       

  
 " :
  
. 4  
    
PID TTY TIME CMD


Mosquitto     
   
744 ? 00:00:00 sshd
"   % Error: Address already
746 pts/0 00:00:01 bash
in use, $   ,  

    -
1461 pts/0 00:00:01 mosquitto
     ,   
%     . 1902 pts/0 00:00:00 ps
= $       —  -

, 

      - 
 
       "   -
 "    
     
 . 

    "  

 
     "   
 - ps -e. +   , $     
   
   "   :  .
$ ps -u _$
528 Глава 10

2
%  
   "      :  ,     . *      - 
 —
     Mosquitto 
 %  

$ kill  _#
1883,       
 
 ,  -
 
 
 _#    
    netstat:

 ,    
   
%.
$ sudo netstat -atnp
& 
 "      "  
 
  
  Mosquitto   
2       " :    -
1461.          " 
  
(-a),       TCP (-t),  IP-
 (-n)
0       
 
    
 
  (-p). &      
-
  ,         -    " :

2        


   ( - ; 
, "   ps  kill  
  Proto),  
 
 (   Local   
   
 ,    ,
Address),  
(   Foreign  
%     . 4      -
Address) 
     ,  
 ,  "    ,
     (   State),   
 
   ,      ps 

    

 ,  

"  
    grep:
(   PID/Program name). *   
 
$ sudo ps -e | grep 'mosquitto'
 " $        :
0   : ps  kill —    
tcp 0 0 *:1883 ... LISTEN 844/mosquitto
  
   . 
   

+   ,    Mosquitto 
 -      ,      man ps 
%  
 1883    

  844. man kill    . *   

#   ,    
%    - 
%      
 ,   
 $ 
     " : 
    ,   $    -
  
     
$ sudo kill 844
  .
*     sudo      , 

   "    ,    ,
   
%    


 .

Создаем веб-сервер
*%  -

  
   /*
 

   Z   - %

 . X   ,   - : node.js
*/
, " npm  -
 express,   
    var express = require('express'); // '
httpServer.js      //    express
 " : var server = express(); // Z$ " server,
// $     express
Сети мобильной телефонной связи и физический мир 529

#

       - server.listen(8080); //   $ HTTP
       "  - server.use('/',express.static('public')); //   ,
//  '    %

   -  ,   
-

MQTT.
Выполняем разметку
=  - 
     - <script src="libraries/p5.js"></script>
    — mqqt.js, - <script src="libraries/p5.dom.js"></script>

 
    
: <script src="libraries/p5.sound.js"></script>
<script src="libraries/mqtt.min.js"></script>
https://unpkg.com/mqtt@2.5.0/
<script src="sketch.js"></script>
dist/mqtt.min.js. #
  
-
      
libraries   p5.js,    -

    index.html, -
 
  <head>    -
 
 %
 
-
. 0   
  
        :
Создаем веб-клиент
&     -  /*
+- %
  mqtt    # 

   
 
-
: p5.js
    
 ,  */

      Arduino.

  clientOptions - var clientOptions = { //     MQTT

 
 
  port: 8888,
host: self.location.hostname, // IP- - 
  MQTT. +    //  '
   
, 
username: 'webClient', // \  $    MQTT
 
 
 : password: '_mqtt', //     MQTT
};


  device 
 var device = { // Z
 

      
 - on: false,
temperature: 24,
, 
   - setPoint: 18,

 

: mode: 1,
connected: false,
name: 'airConditioner'
;   
 
};
 $ 
    
-
       - var client; //   mqtt
     . var webConnected = false; // Z  '   
2     
- var img; // \$  $ - 
   $   
  var timeStamp; // $   
 timeStamp
var deviceStatus; //   R    #
HTML: img —  
  var connectButton, modeControl; // + "
, timeStamp — 
  //   #

 , deviceStatus — 

      
 ,
connectButton —   
 , 
  


    
   
   :
530 Глава 10

&   setup()  - function setup() {



  
 "   $ - frameRate(0.033); //  $  30  
noCanvas(); //   $ 
  
  . = $  
deviceStatus = createSpan(device.name); // &  % # 

   
 - //  

 
    deviceStatus.position(10, 10);
  
%     connectButton = createButton('Connect'); //  ' 
touchEnded(),  - connectButton.position(10, 100);
      - connectButton.touchEnded(connectMe);
setPointSlider = createSlider(10, 40, 21, 1); // $ 
    
   - //   $  setPoint
 . 3   


 setPointSlider.position(180, 100);

 
  
 setPointSlider.touchEnded(changeSetpoint);
changed(),  
 - 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()   - function draw() {


     $   - var now = new Date(); //     '   

 . +     img.elt.src = './image.jpg?' + now; // 
//   $ 

     
 
, timeStamp.html(now); //  $   
  ,   $   }
 
        3,
    

 -

 :

& 
    //   
 $   
     
 // $ 
function changeSetpoint() {
    
 
-
update('setPoint', setPointSlider.value()); //   

       //  $ 
update(), 
   
 }
      ,  -
  

MQTT - //   
 '
  
function changeMode() {
     :
update('mode', modeControl.value()); //    
// $ 
}
Сети мобильной телефонной связи и физический мир 531

& 
    // connect button event handler:
    connectMe() function connectMe() {


      - if (!webConnected) { // †    '
  -   

 MQTT. client = mqtt.connect(clientOptions); // ' 
client.on('connect', announce); //   
4     (  //   ' 
if),      , client.on('message', readMessages); //   
   $   //   -  
mqtt.connect()  
 
} else {
 ,     - client.end(quit); // '   

. [  mqtt.connect() }
    
   - }
 announce(), 
  
-
   . 
    
    
-
     
   "   
-

. 
   
(  else)    -

  client.end():
&   
    //  ' "  

announce()    mqtt. function announce() {
connect()       connectButton.html(‘Disconnect’); //  
// ' 
   
   - webConnected = client.connected; //   
   
  - 
  - // ' 

    updateInter- // -  #    
 

face(), 
  
  for (property in device) {
  . ;      - client.subscribe(device.name + '/' + property); //
 update()     //      -
/update, 
   - }
updateInterface(); //  %
 $

 

   -
update('update', 'all');
      : }

[  quit()    //  '    ' 


  
     function quit() {
  client.end(). 0  - connectButton.html('Connect'); //   
//   ' 
      -
webConnected = client.connected;
  
  ,   }
   
  webCon-
nected:

[  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);
}
}
532 Глава 10

 


  - // Z  -    MQTT
" ,      - function readMessages(topic, message) {
topic = topic.toString(); // $   
" , 
 
  -
var strings = topic.split('/'); // $ 
 "   readMes- //  

sages(). /  
   var origin = strings[0]; // \  
  
       
 , // 


    


     var property = strings[1]; //  
 — .
if (property === 'temperature' || // ‰ 
  
 . 2  
 " - // $
 

    
- property ==='mode' || //   
   "  : property === 'setPoint') {
temperature, mode  setPoint — device[property] = Number(message);
   ,   
 — } else { // +   
 —    
   . &     // & 
      $ :
device[property] = (String(message) == '1');
readMessages()    $ -
}
  
  
  updateInterface(); //  %
 $
  updateInterface(): }

+,  , 
    - // • #    R  $ %

 updateInterface()  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); // 
// '   
}

; 
       - 
 
   mq-local.conf,    
 :  
  
 

,


  
  
  
.
HTTP   - . ' 
 
  *  %,  
 
"
,   

Mosquitto      
,       
 

:

HTTP:

$ mosquitto -c mq-local.conf & $ node httpServer.js

# 
        - * $
     "  
-
,  

         - 
 
 % "   
 -

 . 

   ,  
 Mosquitto. 2
%   


Сети мобильной телефонной связи и физический мир 533
 ,    ,    - 1490449948: airConditioner/on (QoS 0)
% <Ctrl>+<C>. 3  
%     1490449948: airConditioner 0 airConditioner/on
Mosquitto    kill, 
 

  
 
  ! «|  - /   ,       -

  
 
  ».    " . +   
-

  
 
  
2     

, -  -  ,     -   -
 
 

 ,    
   $   
      -
 -

     
 
- 
    
 
.
: http://.:8080 —  
 -

  
   ,   

 . 10.9,     


 .

   

 Mosquitto  " -
Рис. 10.9. Фрагмент снимка с экрана результатов исполне-
       Connect (  - ния скетча удаленного управления кондиционером, сделан-
 ,    
 . 10.9  - ный на смартфоне с ОС Android
 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
534 Глава 10

Сетевые камеры
; 
        -  "  ,       -

,   ,    
- 
 
   "  
. /   
%      -  . &       
 :    IP-
  SFTP,     ,   $ 
-
   
 .  
   %
   
 $       .

      + -

   
      - *     
 
  

  ,           
    public -

   . 2  
 %  
 , 
 
 
-
$60   

 % 
   HTML   
 JavaScript 

 
    Wi-Fi, 
  - p5.js. &
 
    
  
  

. 
 $ 
    
    
 $ 
  — D-Link DCS-930L — - 
  .
%      
  $70. 0 
  
 ,   $ 
 - IP-
    , 
     
 
  
 Pi Cam  Raspberry Pi.  Raspberry
D-Link  
 
  . 

 Pi Zero W   Pi Cam    
 
  


  

    ,    
 ,  
%   
      
,  
 $ 

     FTP6  SFTP7.   %
 
   .
&    , $    
- + 
     
  
 
DCS-5222L  DCS-960L   
 
    
: www.rasp-
D-Link. berrypi.org/products.   Adafruit 
-
  $  
      Pi Zero
* 
   

   
  - Camera Pack (www.adafruit.com/product/3414)
    
"   .     Raspberry Pi Zero W, 

, 
  ,      Pi Cam  
     . 
 
Ethernet 
 
      
  
   
  
 Raspberry Pi

    

   

. *  
Pi Cam  


$ 
   
  
 
 Wi-Fi,  
 
 
    .
 
 
    
, 
-
  
    
,    
-

 . IP-камера на Raspberry Pi
#  IP-
 Raspberry Pi   
  
  
,  
 -  $:  
 $  

-

  ,    
  
  
  %

HTTP  
  
 -
    FTP  SFTP. # "     —   ,  $   
   $   
   
  
        3. 3  

 
    " - $    
   Raspberry
 

. ~  
   - Pi,  

 
 -

 
   

 ,  - 
 
  .
 

 
, 
 
6
FTP, File Transfer Protocol — 
 
  . 7
   
 httpServer.js,  -
7
SFTP, Secure FTP —   FTP. "   %    -  , 
Сети мобильной телефонной связи и физический мир 535
   "  . /   - & 
  Interface Options | Camera
   
  ,  $      .   $ 


   3. Raspberry Pi     piCam.sh  

 . # 
 
,  $ ,
2   
 Pi Cam   Rasp-     
      -
berry Pi  
  ,     :     
  

.
$ sudo raspi-config

Код для загрузки изображения


'   

http- /*
Server.js    
 - Z   - %
  node.js,   '

$   %

 
    ,  
- Z    -    public.
      : node.js
multer, 
    - */
    3:
var express = require('express'); // '   
$ npm install multer // express
var server = express(); // Z$ " server,
; 
   
  
- // $     express
   
 . 
    var multer = require('multer'); // $
! 
$N 
    multer, //    


        // %

  
 !
  

 
 
 catServer.js    3. var imgStore = multer.diskStorage({
destination: __dirname + '/public/', // $ 
2      // 
 
   
 %
. filename: saveUpload // Q   


 
//  
 
=   
 
 });

  
   
"   diskStor-
age()   multer. &  -
 ,    public 

    

:

=  
  $ - // ‰ 

 
 ,   




  multer  
-
// 
 

    
   var upload = multer({storage: imgStore});
   image (
 - // %
 :      image
 ).       - // (7
 !
!   !
):

 POST  
   var type = upload.single('image');

 ,  
 
im-
age      :

&    
   // Q         
//    

 
  POST  -
function getUpload(request, response) {

  ,    
  //    #     
 
    
   - var fileInfo = JSON.stringify(request.file);
 getUpload(): console.log(fileInfo);
response.end( fileInfo + '\n');
}
536 Глава 10

; 
    // Q         

    saveUpload(), function saveUpload(request, file, save) {
//     
 multer,   
 

      
 
save(null,file.originalname);

     
- }
:

* ,      server.listen(8080); //   $ HTTP


 
 
 
  server.use('/',express.static('public')); //  ,
// 
   %

POST: server.post('/upload', type, getUpload); // %!

//  



Автоматизируем захват и загрузку изображений


/  
   - while [ : ] # 
# 
  

 raspistill,  do
# - $ ,  100 ,
 "   
 
# $  400-300,  80%, $  

, 
     raspistill -t 100 -w 400 -h 300 -q 80 -o image.jpg -n
  image.jpg,    
- # Z  ' curl $  $- $  
      -   
"   curl: curl -F "image=@image.jpg" 'http://example.com:8080/
upload'
# \$   $ example.com  IP- 
--
# +   $ $
echo "\$  $ "
#  $ 30  
sleep 30
done

#
      
,    - +   

     
 
"   chmod   

-    
       ,
%          
:          

      
. 7  -
$ chmod u+x piCam.sh 
 
 

 -
      

 -
7   
   "  -
           
  (
    Raspberry Pi) 

 
    "

 -
     . [        -
    
   HTML5.  
   " 
:
      
  
$ ./piCam.sh 
  
      
  
 , $   

+  "   
    - . +   

  
 -
 30      
 
      
    


. 
 " 


    
, 

-
  

  -           

, ,    , -
   -
 
  ,     
 HTTP. 7
 
 $
   


 . 10.9.   %   "  
  .
Сети мобильной телефонной связи и физический мир 537

Проект 30
Звоним термостату
Мы вложили в только что созданный проект много труда. К счастью, он не пропадет даром, и мы
воспользуемся его результатами в этом проекте. Оборудование для него будет то же самое, что и
для предыдущего, но мы внесем в программное обеспечение некоторые изменения, чтобы соз-
дать интерфейс, позволяющий нам позвонить термостату по телефону, прослушать голосовое
сообщение о температуре в квартире и статусе кондиционера, а также задать пороговое значе-
ние термостата с кнопочной панели телефона.
7   _  

 —  
 -

 ,          - Требуемые компоненты
 , — ,        
  
2
%  29.

  
  
  - 
 . 
X     Twilio.
«* $     ! —     . — *
   
    -,  
;   .
  %    

     -
  
 ?» & $ 
  - 
  21-  . 



 —        ,   
    
   ,
      
  "    -   $ 
    -
  .      
 SIP,      


 "      
&           IP-  -  
       

 
     %, :       
 

   " 
 
       -     .
     - 
   
 .
#


  —   Google 4           
-
Voice  Asterisk —  
 
           
,
 
 
:     -   
  ,      " 
    
   " 

 SIP. 0     
   
-
  (;#0) + 
. /
-     ,   

 

  
 SIP8          

 
    ,
         
 -            -
 
 , 
$    ,   

      , 
-

   . ;,   SIP 
"    
.   
 
   ,    -   —          -
 " , 
%

 " -  —



    
 HTTP
 
    . . + 

SIP GET  POST, 
 
    -
          ,          
    
   ,    -  . 
    -
  
 
 
. 3  
 ,

"   ,   

 


  
 

     
. 4 

SIP
   , 

  
    ,   
 ( , 
    
,    
. 
 : «= %! = %! `  


 
, $ 
      
   !» —  $     ),  
-
8
SIP, Session Initiation Protocol — 
   
  %    
, 
 
 .     
   
.
538 Глава 10

& $ 
       
 - & 
 
   -

  SIP   Twilio   ,   "  
  
, 
   
  
  
 -   :     , "  SMS
  
 "  
 .   Twilio          
 —

  
   VoIP9 —  
    . * 


   ,  


-       
   "   -

 . 0
         $      
  
 ,        -  
  API   
 . *

,

,  
 
   $
 , -  
  
  Twilio (

-
        
.      $ 
  )   
   
      

 
   

-
   
 
     —   Tropo, Google Voice  -
 . *  $   
   -    
 ,  

" 
      
, 
    - $
 .
  ,     
 
    ,   $ 
. #  
 
 
  

-
*    $ 
 -   
        -
 Twilio 
      
 "  

 :
       SMS    -
 
 . X ,        - ? 
     
   -
  ?
% 
 ,    
: https://support.
twilio.com/hc/en-us/articles/223183068-Twilio- ?       
 ?
international-phone-number-availability-and- ?      ?
their-capabilities.   , 
  
    
      , ?    
  
 , -

    ?

 
 ;#0 "   -
  + 
, —    ,  
-
     
 . /  `  

 Twilio  $ 
 
         - - 
    
  TwiML,

     $ 
      ,    

  Twilio
,           - 

   ,     


. 4        -
   


  , — -
     
  VoIP  SIP, 
  

, node.js:      "  
  «Asterisk: The Future of Telephony»10 - GET  POST. #  Twilio 
   -
   O’Reilly, 
: = & 7   

 node.js,     
(Jim Van Meggelen), =
 # (Jared Smith) 
%    ,  
-
 _ 7 (Leif Madsen).  $
 . 
   Twilio -
    
%    

. +  
     

Каким стандартом пользоваться?    , 
  
, — 
-
  , 
  SIP  VoIP  - 
, 
 
   
    
-
  
" ,    . 
 
    , ,   , 
-
0    $     " "   
  
 %  

       "  
.   "    .
9
VoIP, Voice over IP — 
    IP-
,
, 
 ,  
-   .
= $ 
       -
10
«Asterisk. >"    », https://www.ozon.ru/      -   www.twilio.com.
context/detail/id/4878006/. 
   
    , 
Сети мобильной телефонной связи и физический мир 539
         Twilio. - /    
 
         , 
 - % 
   % Twilio,  -
   , 
 
    , 
   

HTTP 
     IP-
 "    . 
 , - 
. ;   
 

 
-

     
     "    
. ¥   

  . $   Phone Numbers,    — 
Verified Caller ID    
   ,
*     
(URL)
- 
       Twilio.

 Arduino  
 "  
 .
*

,  IP-
% 

 =  CONFIGURE WITH    
-
63.118.45.189, 
 $ 
         — Webhooks/TwiML.
http://63.118.45.189:8080/voice.xml. ; 
, 
   " 
  Twilio     
 POST 


+,          Twilio        


   

    
  (
 . 10.10). TwiML  
   . 0    
  A CALL COMES IN 
 
 -
'     
, "  
. #
%  $  ,    
-
  All Products and Services (& 
-        XML 


   ),    —  Phone Numbers.  
   ,    

 

      ,    
.
      (Buy a Number).

Рис. 10.10. Панель управления Twilio. Введите адрес (URL) вашего сервера Arduino в поле A CALL COMES IN
540 Глава 10

Краткое введение в XML #  


 $    
 -
     SMS- "  . #  $ -
}! !
#  ! 
 XML11  -     
 :
      -
   
 . 0     
   ? q  $   :
   %   
 . >  • <Dial>

   $       ­ <Client>

, 
     ­ <Conference>
<  >. ;    %, 
- ­ <Number>
       , 
 - ­ <Queue>
  

. /      ­ <Sip>
$   . *

, $   <body>  
  $   <paragraph>: • <Enqueue>
• <Gather>
<body>
• <Hangup>
<p>‰   %</p>
• <Leave>
</body>
• <Pause>
& ,      
"  - • <Play>

"  ,     
 $ - • <Record>
 . /,  
,  
, 

• <Redirect>
  , %     
-
• <Reject>
 .
• <Say>
• <Sms>
 $      
"
 
"  ,        - ? SMS-$   :

  : • <Sms>
• <Redirect>
<  $  ="10" />
#
  
  ,      - 2     $ $   
  -
,     
 
. & 
 "       
     -  
  
 
     
   Twilio (www.twilio.com/docs/api/twiml),   ,
 $,      $ 
  10 - 
 ,          -
 . # " 
 $      %   .
     
 .
= $ 
      $  
4    ,   $    <Response>. & 
 $ $    -
HTML,     
 . `  XML   $   <Gather> —   -
 HTML  
    ,        . /  
  XML   
    " <Gather>    TwiML-
 


. HTML, $    
 action
 method, 
  
    
$  ,    
  
Схема разметки TwiML  . 7      $  
# 
  Twilio — TwiML — 
 - <Say>,        -
      
    Twilio ,   

     
.
     XML. 
  
,  
  ,      " Twilio. /   XML
   %  
11
XML, eXtensible Markup Language —
 %
   -  , $      -
 
 . 
   


HTTP
Сети мобильной телефонной связи и физический мир 541
 node.js, 
   
 -  , 
     -
"  
 . &   
     
 . X   ,    ,
$ 
    
  . "   
   npm:
&   ,  
     - $ npm install mqtt
   node.js — mqtt. /   

Выполняем разметку
= $ 
   
- <?xml version="1.0" encoding="UTF-8"?>
       <Response>
TwiML. 
   
- <Gather numDigits="2" timeout="5" action="set-temp.xml"
    ,  method="POST">
  
  
. <Say>
The current temperature is
    
#temperature
 ,      -
degrees Celsius.
   ,   
[C
 

:
 
 . #
    #temperature
   voice.xml  public  —
 .]
 
 "  
  (
 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>
#temperature, #setPoint  #on.
</Gather>
#

     ,   <Say>
$       HTML. You didn't give a new setting,
~ %  (#)     so the thermostat will remain at #setPoint degrees. Goodbye!

     [

   
, #   


   "  - 


  
 #setPoint . €  !]
. 7 ,  $    , </Say>
  . </Response>

&
   TwiML — <?xml version="1.0" encoding="UTF-8"?>
set-temp.xml —    - <Response>

    public ( <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/>
  <Gather>  
   . </Response>
+  , $  
    ,   
    
  , -
   
:
542 Глава 10

3

 
   - 
 
    -
" :      
-  . +   
  
 , -
 Twilio,               
%   . & %


 POST   voice.xml. #


 - 
  
    
 
     
   

  
,
 
 
  Twilio. #        $
      
   TwiML,     ,

%  
 
       
,  
 
 .
  
%  
  . 4     -
     
,  

- = 
   , 
 
"                   

    -
<Gather>.       Twilio. &    ,
      :  
&     

-  
 POST   XML,  $


    
 
  POST,  $    
 , 
  

   set-temp.xml. #


    
  ,     
     

MQTT,    

 MQTT   "    -
 
   Twilio 
   XML, .

Модифицируем сервер
0
     
 http- /*
Server.js  
 "  
 - Z   - %
   TwiML   MQTT
       , : node.js
*/
     

var express = require('express'); // '   
%
. &  
   // express
     var server = express(); // Z$ " server,
fs (
     - // $     express
 )  mqtt. 2    - var multer = require('multer'); //    
//  $ $ %
  
  
 clientOpi-
var fs = require(‘fs’); // $

  
tons  device,     //     

  
  - . * 
- var mqtt = require('mqtt'); // $


      ,  // MQTT Client

  -    var clientOptions = { // $
 
 MQTT
port: 1883,
 localhost. /   - host: 'localhost',
  , 

node.js  username: 'xmlClient',

 
   MQTT   - password: 'something',
       
, keepalive: 10000
 

Mosquitto: };

var device = { // 9 


on: false,
temperature: 24,
setPoint: 18,
mode: 1,
connected: false,
name: 'airConditioner'
};
Сети мобильной телефонной связи и физический мир 543

&    
   function postFile(request, response) {

 
  POST  - var fileName = __dirname + '/public/' + request.path;
 XML.     save- var data = fs.readFileSync(fileName);
Upload()  
 
 output = String(data);

  POST     for (property in device) {
var searchTerm = new RegExp('#'+ property, 'g');

     
 
var value = String(device[property]);
  postFile()    -
output = output.replace(searchTerm, value);
 
 $ 
 . / }
  
     
- response.writeHead(200, {'Content-Type': 'text/xml'});
    
  
  response.end(output);
output. 2  "  - }
     JavaScript
       
 %  (#)     
    
 
device. 0
   -

 
   
  
      
 -
 Twilio:
    ,   
- function announce() {
    

for (property in device) {
client.subscribe(device.name + '/' + property);
MQTT      - // $ 
  
"   . = $   }
    - }

   "
function readMessages(topic, message) {
  announce()  readMes- topic = topic.toString(); // $
 

  
sages()   - : 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');
}
}

&    
   server.listen(8080); //   $ HTTP

 
  POST   server.use('/',express.static('public')); //   ,
  XML,  "
- //  '    %

    - server.post('/upload', type, getUpload); //   %

//  

    postFile()  server.post('/*.xml', postFile);


   
. ; - client = mqtt.connect(clientOptions); // $

      client.on('connect', announce); // N   
mqtt.connect()  
 // 

      - client.on('message', readMessages); // N
" "  : //    
 


/ 
%   
 

  
.
544 Глава 10

&   
   , - 
 ,    
 
 -

   

  
, -       !     ,
              $ 
    %
-
  
 Twilio. #    
, ,      . & ,  
-
   
% . 4      
-    
, — $   
 ,    
    %  - TwiML 
  

   

-
 ,           
HTTP         
-
 
          . POST  
  

 MQTT,  -
2  , 
%  . 2
. 
 , "     %
    
  
 
-  
 API  node.js, 

 

MQTT    - ,     - TwiML,   
    " -

 

.   %    ,    -
       .

Интерфейсы на основе текстовых сообщений


Обмен текстовыми сообщениями быстро стал одним из наиболее распространенных приме-
нений мобильных телефонов. Многие считают текстовые сообщения не столь раздражающими
вторжениями в их личное пространство, как телефонные звонки. Текстовые сообщения позво-
ляют быстро передать информацию, не тратя времени на разного рода предварительные раз-
говоры. Кроме того, сообщения электронной почты легко посылать как SMS и наоборот — эта
возможность не зависит от какой-либо конкретной платформы. Все, что для этого нужно, — это
мобильный телефон и учетная запись электронной почты. А для ситуаций, когда требуется не-
медленное и малозаметное извещение, или для предоставления простой инструкции, SMS-ка —
самое то.
#
 SMS       
      ". = 


    
     - $    
  
   -
      . +     ,  "  ,      
,
         "     
$ 
   . &  -
            -    %  

   ,
,   
   . / 
 "    
  
  MMS12
"         -   
   "  SMS. 


  ,  "     "   " —     
     
  
  -   % "  . 3  % -
"  . *    SMS         
     
    
    ,    - SMS-  
 
 $ 
  -
   
%     
  -  — $      

  . #"  SMS    
  $ 
      

160 ,   
   
-    ,  @  
 $ 
 
       $ 160 -  

. = 
    -
 %    
. 
 
 
 
 


 
 "  SMS  $ 
 
   

 
   

  #3,
 
      % SMS-    4
 :
email,  $   ,     - 12
MMS, Multimedia Messaging Service —  

 "  SMS        "  .
Сети мобильной телефонной связи и физический мир 545
? AT&T: phonenumber@txt.att.net; *   %
     -
   -   www.emailtextmessages.com
? T-Mobile: phonenumber@tmomail.net;
(
 

,  

  

? Virgin Mobile: phonenumber@vmobl.com; $  ). &
 , 
    ,
"     
 (
 

? Sprint: phonenumber@messaging.sprintpcs.com;
phonenumber),   
 .  
? Verizon: phonenumber@vtext.com;       
,  
  

 $ 
 
 

? Bell Canada: phonenumber@txt.bellmobility.ca;
 
   
     -
? Telenor Norway: phonenumber@mobilpost.no; 
 . [
      -



     
   

? Telia Denmark: phonenumber@gsm1800.telia.dk;
E.164     +nnnnnnnnnnnnnnn. >
? Swisscom: phonenumber@bluewin.ch; n   
, 
     
12  15, 
   ,   
 
 
? T-Mobile Austria: phonenumber@sms.t-mobile.at;  — $  
 . ;   , 

? T-Mobile Germany: phonenumber@t-d1-sms.de;    
,     -


#3  
 
 
 
-
? T-Mobile UK: phonenumber@t-mobile.uk.net.         $ 
 .
$      
   -
%   
    
  
  

.

Отправка SMS через Twilio


# "  
 node.js module.exports = {
    HTTPS, - apiKey: 'Axxxxx', // ' %
 API Twilio
auth: '1xxx', // ˆ  % #   Twilio

      
number: '+15555555555' // ^  % Twilio
  Twilio  
  - }
"  SMS. /  

      
 
 % SMS  -
    
 . #   Защитите этот сценарий

     
TwilioSms,    —   : &   " $  
 %-

    "  

 -
smsClient.js  twilioCreds.js. [ 
 
% 
 . 4     
twilioCreds.js 
   -  - -
     
 , 
"  
,        -
 
  API Twilio,     .
   
  -
. &  $  
  
      
 -
 Twilio. #
  
   " 

(     
-
 %
   ):
546 Глава 10

Сценарий для отправки SMS


' 
 SMS 
 /*
Twilio,   
 
   HTTPS  %
 API   SMS Twilio
HTTPS POST   
 API : node.js
Twilio. &   
 - */
   
  node.js
var https = require('https'); // '    https
  https  querystring. var querystring = require('querystring'); // '
    

    //    querystring
JSON   
 
   - var creds = require('./twilioCreds.js'); // ' %

 HTTP,     //    Twilio
       twilioCreds. var recipient = process.argv[2]; // ^  % $
js. *
      - //   $  

      
:

[
 "  SMS 
  var message = { //     SMS
 
  — "  - To: recipient,
  
   : To (), From: creds.number,
From (0)  Body (; ,   Body:'  !'
}
   "  ). ; 
"    
 % // $     $    HTTP
1600 . *
    var postData = querystring.stringify(message);
    
  
-
 E.164. 
  postData


   "  

 
 :


 
 
  HTTPS //   $ HTTPS
 
 
  
  var options = {
HTTP, 
  
 . host: 'api.twilio.com',
# Twilio     auth: creds.apiKey + ':' + creds.auth,
port: 443,
 
   -
path: '/2010-04-01/Accounts/' + creds.apiKey + '/
  
    API Messages',
       - method: 'POST',
      
 headers: {
   . ;  "  'Content-Type': 'application/x-www-form-urlencoded',
    
    ‘Content-Length’: postData.length

 ,        - }
    querystring: };

   , 
 HTTPS  - // • #   $  $
function confirm(response) {
"        

var result = ''; // Z    -  
      
- function gather (data) { // response 'data' callback
   confirm()   - // function
 
  . / result += data;
      % - }
     : data  function printResult () { // • #   $
end. 0    
   //  end
 , $   gath- console.log(result);
er() 
  $      }
Сети мобильной телефонной связи и физический мир 547

  ,    printRe- response.on('data', gather); // Z   


sult()    
- //   #   $ 
response.on('end',printResult); // +  

  $
 : // $   R
}

* ,     
 //   $ HTTPS
HTTPS. ;  
     - var request = https.request(options, confirm); // ^ 
// $
  ,    end() - request.write(postData); //  

%  
 : request.end(); //  $  

# 
         Получение SMS через Twilio
 "   :
&   
 "  SMS, -
$ node smsClient.js +15555555555    ,    . &  -
2   $   
   ,  -            -
  
 %
, 
, "    Twilio. ' , %   -
 
   
 "  
 
       
SMS. &      Twilio "  . #      smsServer.js
    XML,    
 
     
   

      
     "  SMS. =
  
    -
«
 !». ;    ,        express  body-parser. 0 $  
 , 
                 :
Twilio       % 
 - $ npm install express body-parser
 
    , "  SMS 
 2  
     
  Twilio,
        Twilio   - "      All Products and Services

     
- (
 
 
    
  
.   % 
  ),  
%  
   
 Programmable SMS    -
=  XML   
   "    
     Create
 
  " : 
   - New Messaging Service (#  
 , 
 
,    ( - "  ). 
      
   
, 
   . .)  
. 
   Create. & 
%     
-
 
  TwiML,  Twilio 
-      PROCESS INBOUND
   
 API REST, 
- MESSAGES (
  " " -
  
%
    " - ),      REQUEST URL 
   , 
       
(URL)    - ,  
 -
 %     .  

,  
 : http://.-

..
:8080/sms. *  -
~     %  
 
  Save. 2  
   Numbers

        ,  $   
  
   , 
 

-

  
 
     -    Twilio.
 

  node.js,      -

 %
      
  . ; 
         
; 
          -

    SMS- "  

 

    -  ,    -  Twilio. / 
 

 -
        
   express 
 node.js 
   -
    
 
- 
 POST   /sms  
   
 "  SMS.     TwiML.
548 Глава 10

Сценарий для получения SMS


   , 
 
- /*
 POST      Z   TwiML
: node.js
 
,    
 
*/
    
 
  getText(). /   var express = require('express'); // '   
   $   From // express
 Body " ,  
- var server = express(); // Z$ " server, $ 
//    express
   

var bodyParser = require('body-parser'); // '
     
  //    body-parser
request.body —   
  , 
   function getText(request, response) {
Twilio  
   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);
&    
   - }

 
  HTTP, -
server.listen(8080); //   $ HTTP

   

  - server.use(bodyParser.urlencoded({extended: true}));
"       
 //  $    $
POST "  SMS: server.post('/sms', getText); //   $    /sms

2  $  


   -
  ,    
 
   "    -

Twilio.

Микроконтроллеры в мобильных телефонных сетях


Напрямую подключать микроконтроллеры к мобильным телефонным сетям позволяют сотовые
модемы. С их помощью микроконтроллеры могут подключаться к Интернету так же, как это де-
лает любой смартфон. Обладающий собственным телефонным номером модем может посылать
и принимать сообщения SMS, осуществлять запросы HTTP, — в общем, делать в Интернете все,
что можете делать вы сами. Модемы имеют определенные ограничения, но без них не обойтись,
когда нужно организовать связь при отсутствии сетей других типов. Поэтому весьма полезно
иметь хотя бы базовое представление об их работе.

&   


          
 . & -
            
- "  
  
  -
         
-   
 
 
     $-

. &  2000-      %   . ;    
 
 + 
 "     
  
        , 
Сети мобильной телефонной связи и физический мир 549
      
  , %   . = %  
% -
     ,  -        4G   -
  
           
 LTE17  
    -
    % ,    
   
   100 7/  "
 . 
  50 7/   ".

0
   
   
     ,
     
          -           -
    "   "  
  ,     
 
                 . ; 


, 
 $ 
    
  ,      $ 
 "-
 $ 
  
  
 .       " 

 


      
  
 2G    GPRS 
-
  
       
  
  HTTP    " 
      
 . & - $ 
   . /     
  -
  
   (2G)     
  ,   

 

    "  SMS. 
 

" 
  
 2G
0   
    2G  
-  
  . *
   -
 GSM13. ~  GSM   
 ,     
 3G    
 LTE, 
 
         
    
 % .
 . *     $ 
  -   ,   
 


-
  
    
  
%     
     -

     GPRS14, 
   
 "  SMS,  
-
                
 2G.
   (
      -
     
 
    *      ,     -
  3). &     
  -     
  ,   $

 -
  (3G)    
    UMTS15, ,           
       GSM. 
 $ - . 
 $, 
 
   -

  
  
  ,   -  , , 
 ,  
  
 -
      ,   %    

      
   
    . /  . &
 , %  

 
-
   
     
    
  

 EDGE16. &       «  
  » 
 
   (4G) 
  
    
,     -
         
            -
 ,  IP-   ,      -
   
    % . 

       
 . &

,     
 ,    -
        % -
" 
 

, 
 " 
  + 
,    
 
    
 2G,    
13
GSM, Global System for Mobile Communications — - 
  , $ 
 
 
       .  

  $ 
  
14
GPRS, General Packet Radio Service — "
         SMS,   
  

.
15
UMTS, Universal Mobile Telecommunications System —    
 
    
-
 
       .    .
16
EDGE, Enhanced Data Rates for GSM Evolution — -
17
% GSM  
  . LTE, Long-Term Evolution — 
 
 .
550 Глава 10

Рис. 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 
    ,
- *
 . 10.11  %   .
"   4G LTE.
7 SparkFun 
   GSM/
& 
    GSM     GPRS SM5100B   Spreadtrum Techno-
   SIM-
18. / 
  logies. 7 
  
  AT,
        
  -   
  
  SMS- " 
   
IMSI19.        . 0
;         -  "   /  "  -
 
       
IMEI20.   ,        
*
 IMSI  IMEI    

-  , 
   
   -
        
,  
   %   -
 , 
         
     . 7
   
   . % 
  
  
18
SIM, Subscriber Identity Module —   - $ ,       -
  .   SIM-
  "     
 .
19
IMSI, International Mobile Subscriber Identity —   -

   
   .
20
7 Adafruit 
    
-
IMEI, International Mobile Equipment Identifier —  -

   
  
-  Fona,      SIM80x  -
 . 
 2G   SIMTech,    
Сети мобильной телефонной связи и физический мир 551
 SIM5320  
 3G. &    Electron 
     
 " 
   SIM-
 
- « »
       
    ,   Feather Fona - 
 MQTT, 
    
   "  
 
 M0.    
 
  $  .
Seeed Studion 
    
GSM RePhone,      - +        
  %
 SIM80x   SIMTech. 7  Core  %        -
2G-AtmelSAMD21   RePhone,         Fona  RePhone. &  -
 Feather Fona,   
 
 - "   

    
-

M0,      
 
-
.   AT   SIM800,  

 
0      %   
  Xadow      $ .
GSM + BLE          -

   AT,    SIMTech. * +     $  -
$  
 
,       
  : 
   "-
  "        .      $ . *

,
  Libelium (www.libelium.com) 
-  SIM800   
  

        Cooking     
.    -
Hacks (www.cooking-hacks.com), 
 $ 
   $    ,    
  
 $     -    ,  
  ,  -
     SIMTech. 7 Cooking     . =  
Hacks      
  $  %     -
 
 
 . 
 
 —    ,    
  "
     
 
  Digi 
 XBee 
  -  -
 (LiPo) 
.
     
-
  -

   AT,    


 , 
 =
   $  
 -
     7. /  
 -    " 
  
-
, 
 
 
  $  ,  SIM-
   

. + 
    
     .      

 

   
 ,  
   - -  %  
   ,  -

 4G LTE,      
  
    
  GPRS  
    + 
 
.      
 . 3

*
Digi XBee Cellular   SIM-
    
  ,  
 
 
         
       
  -
 . + 
 
  
  . *   $ 
    
 , 
     ,   -   , $        
, %  
   .   %     
   -
    
 .
  Particle (www.particle.io)  
-
        -
  Electron.       
    IDE   
 API, 

     Arduino,  
 $ -
  . '
 -
 Electron,      
 , —
 
  

 $  . #     
552 Глава 10

Отправка SMS с сотового модема


& $ 


 
,  -         -
   SIM800  
 

  -
 —   
  
,  -

 "  SMS. /    
 
 



 ,    %        -  "    
   
   -
     . 0
       . =  
"   
      ,    TX      RX 
 USB/
 "        
- Serial,    RX —    TX. ;  -
      
 
         « »    
-
 $  . = $ 

    

,         
      
 -        .  -
    SIM80x.    
,   

   -
      
 
, -
*
 . 10.12  
      
    
  9600 
(  )     ( 
!)   -     :
      Fona800
AT
 
 

  Arduino 101.
2       

 - 2        ,  -
  
 
 

  % <Enter>. &   
 
 
Feather Fona —  
    $ 
     :
    . 7    
-
OK
     ,  
    -
 —       
 
   7          

   
   
. AT  OK  ERROR. =   
-
&  Fona   Adafruit  -  "   %     :
 RePhone   Seeed Studio  "

     LiPo-


. AT+CMEE-2
=
   (
  Fona Feather), =         -

     $ 

,   ,   

 
  

         
:
 . '      

 , 
        - AT+CBC
 1200 3, 
  
 —   - 0      +CBC: 0,100,4214.

   . +      /   ,  
 
   100%
          ,  4,214 &.
  "  
   « »
        - 2  

 
IMEI  :
  
   «  » 
 
-

 —   
 
   AT+CIMI
  
  
   .
&   
 
     -
 15-  
, 
   -
&      SIM-
 (%

 IMEI %   .
   

     , 
   ,   
)   -


  
IMSI:
"  ,      
 . AT+GSN
Сети мобильной телефонной связи и физический мир 553
&    
  
 15- - 
           -

.   - :
+COPS: 0,0, "T-Mobile USA"
; 
 

   : ( 

  ,   , 
),
AT+COPS?  
     :
+COPS: 0

Рис. 10.12. Принципиальная (вверху) и монтажная (внизу) схемы подключения модуля сотового модема Fona800 к микро-
контроллерной плате Arduino 101

+3,3 В

Общий («земля»)
Reset

9 TX Модуль
8 RX SIM800

15 кОм Модуль
Светочувствительный микроконтроллера +3,3 В «Плюс» питающего тока
резистор
5
A4 4
Кнопка

10 кОм
Общий («земля»)

A B C D E F G H I J
1 1

5 5
Bat
GND

10 10
Key

+
5V

SPKR
-

ADC

PWR
Ant
Rst

PS

15 15
Key

+ -
Mic

2000mAh

RI Net

TX Buzzer

RX
PWM

NS

20 Vio
2.8V
20

25 25

30 30
A B C D E F G H I J
554 Глава 10

 
   , 

 - 4    
      -
          - ,   
   
 " 

   %     . SMS. ' 
 "  SMS,  -
         :
7  

  
  
   -
AT+CMGF-1 OK
:
AT+CMGS-"+15555556666" (   R
AT+CSQ        %)
>     .
0      

 :
*
    " ,   
+CSQ: 18, 99
% <Ctrl>+<Z> (ASCII 0x1A). 4   -

     
      
  "       -


         ,  ,   
   


 
  "     

 - 
 

  
 "  .
"      .

Сценарий отправки SMS микроконтроллером


+   $   
  - /*
  
 
 -  
SMS   GSM SIM80


  Feather Fona, : Arduino
   
  */
  Arduino,   -
" 
   - #include <SoftwareSerial.h> // '   
// SoftwareSerial

   TX, RX  
 
const int sim800Tx = 8; //      TX
(Reset). // RX   SIM80
const int sim800Rx = 9;
2        const int sim800Reset = 4; //     

    (+15555556666) //  (reset)   SIM80
   
. 4  - const int pushButton = 5; //     
//  '  
   % 
  -
int lastButtonState = HIGH; //     
  Twilio,    
String phoneNum = "+15555556666"; // ^  %,
     
 //  
'  
"  SMS 

, - // Z$  

  - TX RX:

   
 "  SoftwareSerial sim800 = SoftwareSerial(sim800Tx, sim800Rx);

  .

=    


      $-
      

SoftwareSerial —  
-
    
  
      
"    

:
Сети мобильной телефонной связи и физический мир 555

&   setup()    void setup() {


       - Serial.begin(9600); //    '
//  ' $

   

    -
sim800.begin(9600); //     '
   
. =  - //  ' $


 

  - pinMode(sim800Reset, OUTPUT); // %     
 / . 0
 // /
   ,    - pinMode (pushButton, INPUT_PULLUP);
       
-
 " 
 

Arduino,  
  
       

 :

&    
  , - digitalWrite(sim800Reset, LOW); // +   
    
    delay(200);
digitalWrite(sim800Reset, HIGH);
  
 ,  
delay(5000); // Š     $ 
  . 2  
  - while (!sim800.find("OK")) { //   '   ˆƒ
"  OK      OK, sim800.println("AT");
    .find()   }
Stream. 4       - Serial.println("& GSM   .");
 
     }
" 
, "

  ,   
" 
   false ():

&   loop()    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$
   6). 4     - //  %  JSON
  , 
     sensorReading.replace("X", String(reading)); //
"  "   // Š $   
sendSMS(), 
  
 - Serial.println("sending..."); // 
//   SMS
  " .
int result = sendSMS(phoneNum, sensorReading);
Serial.println(result); // 1 = -
2        }
.replace()   String  }
 
 

   - lastButtonState = buttonState; // Z-  
      //      '  
}

 JSON. ; 
,

 
 $ "  


TwiML  
 " 

      


   :
556 Глава 10

=    
 - //    SMS  
"  SMS 
    - int sendSMS(String phoneNumber, String message) {
sim800.println("AT+CMGF=1"); //  %   
 sendSMS(). & $  
if (!sim800.find("OK")) { // †       OK,

      , return -2; // $  

 
 

- }
. #  
   - sim800.print("AT+CMGS=\""); // ^  
 AT+CGMF=1     - //  
   OK. 2  
  sim800.print(phoneNumber); // Š   %
sim800.println("\",145"); // Š %   
  AT+CGMS= 
 - // ( $  #   )
         - if (!sim800.find(">")) { // †       >,
 
%     return -1; // $  
>.  ,   
- }
   ,  - sim800.print(message); // Š   
"        sim800.write(0x1A); //  <Ctrl>+<Z>
// $ %      

  <Ctrl>+<Z>, - return 1; // +$  $ -

     0x1A  ASCII. }


/       
    
 -
"  :
&    

.

Советы по программированию модемов



   $    
 

,   .find() $     
-
 
   
  phoneNum 
   " 
  
   -
     . 4  %   
 -  true (  ) 
  
   -
 (     
     
, " 
   


), 
    
    
 
.   
   
  
   " "  :     .findUntil():
{sensor: 234} .findUntil("#_", '\n');

    ,        /        ,    


           " - .find(),            
,
 .     
 , 

 
 
 
( 

$ 
#   
      -  
 \n). /      
 -
  $  ,        -   

   
-
      
    
  ,  "  
 
 
.
     ,  "  

   AT.  Stream      .timeout(),



        
 .
         OK   2    -   
  1 -
 %   ,  Stream  -   . ; 
,       

  API Arduino 
        .find()      
   
    . &   - 
  
  ,   
   
Сети мобильной телефонной связи и физический мир 557
0 (false — ). 2    -   [  sendSMS()  %    
" 
   " 
:    
    : -2, -1  1. &
" 
  
        
sim800.timeout(5000); //   
// 
-  5   %   
 
 
  
 .
& %    -2    %  -
       4,  Stream  -     CGMF,  -1 — %  -
          
      CGMS,   1 —   % 
     ,         . ~  $   
Serial, SoftwareSerial, Wi-Fi  
 .    
"      ,
        
 

-
   .

Отладочная программа

   " /*

 

   
        
  
     - 
: 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); //    '
//  ' $
Arduino      sim800.begin(9600); //     '
USB/TTL-Serial»    2. ; //  ' $
     

- }
 Arduino   



       void loop() {
if (Serial.available()) { // Z  
,   
  - //    
       sim800.write(Serial.read()); //  -
 . = 
 
- //   


 $     - }
%     
  if (sim800.available()) { // Z  
//     
 
    Feather Fona Serial.write(sim800.read()); //  -
  SIM800. ~ 
- //  


   
   , }
        }
    setup() 
-
 "       
  
    


 :
558 Глава 10

Приложения для операционных систем мобильных


телефонов
Хотя интерфейсы на основе веб-браузеров и SMS-сообщений предоставляют много возможно-
стей, для некоторых проектов мобильное приложение может оказаться более подходящим, чем
интерфейс на основе веб-браузера. Но если вы задались целью создать приложение для всех
типов смартфонов, вам придется изучить все их операционные системы, а также используемые
с ними программные средства. Однако существуют и более простые подходы к решению этой
задачи.

&    
   
   
  . & ,   $ , —
 
 ,   
     $ 

 

    ,  

 , 
  %  -  .
. *
   
 
 -
   Android   Google  iOS
  Apple,   %    - Платформа PhoneGap
  
. +     Gartner 4    
       -
Group (www. gartner.com/newsroom/id/3609817)    
 ,      
  ,       
 

 JavaScript,      -
2016  Android    
  -     PhoneGap (www.phonegap.

      
 ,   com). 
 PhoneGap 
   -
81,6 
  

,  
   
     
  -
   iOS    %    -  
 ,    $
 
%  . 9    Android    HTML5  JavaScript. 9
 

 $ 
  35 
 , 
     
   
 


   2010 . ; 
,   (

    
 HTML5), -
     

 
              -
   
 ,  
  -       

(,
      
    
    
 )     

 Android  iOS.     
 

,    -

       %

-
=

 
    
     
  
  . 9

iOS   ,   ,  - 
  
  
  
 

Apple ID      

-  
 

    


 
    https://developer.apple.com.   
 : Java —  Android, Swift —
>          
  iOS. /      -

     
  
 USB ($ ,       
 -
       sideloading21),  . 2 

     

 
 
   
  App Store. HTML, CSS  JavaScript, 
  -
=

 
 
 
  
 -  
  
      .
  Android 

  
 
      $ 
    
 -
21
  
 .
>  « 
». = 
  
iOS   
   
     
   
  
 USB, Bluetooth, Wi-Fi  &  " 
 
 PhoneGap 
-

    
 ,     -     Adobe,  Adobe 

   
 . = 
   0# Android $
           
   
      
  Apache
APK   
  Android. Foundation    Open Source 
 
Сети мобильной телефонной связи и физический мир 559
Cordova (http://cordova.apache.org). *     

 Apple, ,  ,
 $    
 
-  

   

-
    . 
 PhoneGap  -   
    
    iOS,
  Cordova            Android. &  " 
  
 
 ,   
   
 
       



 %
 .

 PhoneGap   
  
-
      PhoneGap  p5.js. 3 -

 , 
 PhoneGap 
       
 .

  
 , 


-
 
  
%

-
. &    ,   -   PhoneGap Build
Проект будет сложным!
(https://build.phonegap.com) 
   
      —  
- / 
          ,
        HTML,    -
 
    . /    

    
  , 
     ,   
    

    
 . ; 
,         
-
PhoneGap Build  

 
- 
 
 :  
   
 $    

 

- 
 PhoneGap, 
SDK22  iOS 
     
 . 3 
- Android, p5.js,   —     
,
      
 PhoneGap Bluetooth LE  
 

 -
Desktop     
      $ 
   
 .
       
   - /
           -


 HTTP. &


 - , 

   


  
 
  
   
    ,      

 -
  -

—  ,   $   .
 

  node.js  p5.js. 2
 X    
!
 
  

 PhoneGap Desktop
 "    "   
-
  PhoneGap Developer. &  
%,
,    Build,

  Установка набора средств

    
  
- разработки PhoneGap
 
   "

 Adobe,  
-
*

 

 PhoneGap   
  ,

  " PhoneGap
 
     
 PhoneGap, -
Desktop  PhoneGap Developer,   

 SDK  Android  iOS,   
-
     . '  
-

     
 .
          ,
 

 " 

PhoneGap      "   -

 

    " -

   npm  "   :

 . X    

 
-

    
 
  . $ npm install -g phonegap


       
 X   PhoneGap,    
SDK
p5.js 
 PhoneGap  
-      
 (Android
     

  
 -  iOS),       
  
-
   
   Android  iOS.  
 
  .
  , 

  
  22
SDK, Software Development Kit — 

  
  
   iOS      -

 0.
560 Глава 10

Набор средств разработки для iOS     Android Studio, 
 

    
   iOS  
- 
  
: https://developer.android.

     


   macOS com/studio/. =    
  -
      XCode, 
-   Android Studio      "
 
    
  App Store  
. ; 
 
 

  Apple.      $
- r25.2.3  
     
 
 -


           . 2
 $ 
  
 -

  XCode 
     
-     " 
    -
 . /    ,     "     " 
:
 :
http://dl-ssl.google.com/android/repository/
$ xcode-select --install
tools_r25.2.3-windows.zip
   
    , 
-

 
    
   iOS http://dl-ssl.google.com/android/repository /

       

 Apple, tools_r25.2.3-linux.zip
 
     -   https://
developer.apple.com. #    
 http://dl-ssl.google.com/android/repository/
 Apple       
  tools_r25.2.3-macosx.zip
      

 

XCode.
X     Android Studio,    
;       "  :  "     Configure   

 SDK Manager. & 
%    SDK
$ npm install -g ios-deploy Manager 
    System Settings  " -
    Android SDK. 0
   
     
 ADK. & 

Примечание
 
 " 
 Android   
-
4       

   5.1 Lollipop,     
-
node  nvm  n,       -     
 . X  
 Android

      "  :    
   ,      -
         ] 
|
$sudo npm install -g ios- D   | D
   ( 
 )
deploy --unsafe-perm-true --allow-root  ] 
|   + (  % ).
*
 . 10.13  $
     0 
 % .
=     
   
 

 Cordova/PhoneGap  iOS  
X   
Android SDK,  
    -   cordova.apache.org/docs/en/
             -
latest/guide/platforms/ios.
 
 
 PATH,   
-
 
 ,  PhoneGap,  ,
Набор средств разработки    . 0
   $   
-
для Android    

  
     

    
   Android   .bash_profile — $ % 
   


    
  
      
    

   macOS, Windows  Linux,   - (
       bash):
  
  " 


 SDK  Android. *
SDK    $ nano .bash_profile
Сети мобильной телефонной связи и физический мир 561
=  $    " 
 :

?      macOS:


export PATH=$PATH:~/Library/Android/
sdk/tools:~/Library/Android/sdk/plat-
form-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       
- Рис. 10.13. Пример экрана About tablet (О планшете) с ин-
  tools,  . +   формацией о версии Android

 
  
    

      ,    
  
PhoneGap  Cordova. ; 
   
  Android       $ $
 , 


 
  PhoneGap.         
  D

 . =
 

 $
 
,    
     -
Подготовка устройства Android   
 Android 5.1    .
'   
  Android     -



    $  
  '

%


, 

  ,   (A
 -  Build number (*

) 
,

,                    "  ,  
-
USB. = $    
  Android 
" ,     

.

    ] 
. 

 - ; 
 
 
   ] 
 
  
       
    
    

 
.
D   ( 
  :  & , * $      "  $
  -
  +  . .). 0
%    (
-     USB (USB Debugging).


  
 . 10.13) 
- ; 
  
      
  
  %   
  . &
  

 
  .
562 Глава 10

Создаем проект PhoneGap    


 . *      
  p5.js,     
 
'

   ,  PhoneGap
-  
$   . 0
   ,
     
 SDK        $   <platform name="ios">
 
   
 p5.js,  
-  <platform name="android">,   
 
  ,  "  $ -    <icon>  <splash>,  PhoneGap
  . = $  
  PhoneGap,    
 
  
 .
    "     
 ;      
 ,  -
   
: 
   
    

 -
$ phonegap create buttonApp com.   
  , — 

Windows 
example.buttonapp ButtonApp Windows 8.
'   $ 
 
 
? 
 
 platforms     
 " -
    PhoneGap   -
   
    
 .
 buttonApp. 0
    -
+      ,  
  

     
   -
     " 
:
         
 -
 . #   , 
 
 
: com. $ phonegap platform add android
example.buttonapp — 
    , 
   
      - $ phonegap platform add ios
%  
 . 2    
 
com.example     . * , 
    $   PhoneGap   -

 
 
: ButtonApp — $  
       
SDK, 
 -
 XCode  Android Studio.     platforms  
 
   
 . X   
-
= 
   buttonApp    -  "   :
   
"     : phonegap platform rm
$ls
Вниманию разработчиков iOS!
= 
   "  :

   
 
   iOS,
    
 XCode 
  -
CONTRIBUTING.md
   
. 
  
config.xml
platofms/ios/  
   XCode   ButtonApp.
platforms
xcodeoroj — 
  


 . ¥ -
www     
      , 
-
README.md    
       
 . X
hooks   

 (developer team) 
plugins   

 (individual developer),

    . #
   
[  config.xml 
    
 . 0  
   .

    package.json  
  node.js
    ,  
  
 
 , #
 PhoneGap       -
  ,    
    
 
 %
  Bluetooth, 
 
   ,      . .   plugins. 7 ,  $  -

 . & %   
-  ,     $ 
    $
-

  
  
  ,     . 3   hooks 
     -
$    "    
   -  
  
 
 . & 
 -
 
 
 PhoneGap 
  
 $
   hooks   .
Сети мобильной телефонной связи и физический мир 563
#
  
  
   HTML, CSS ; 
   
      .
 JavaScript  "      www. 
      
   index.
=    $  PhoneGap   html  
  p5.js     ,
 % ,            
 
   . /  
p5.js. *  $  
     -      
       

   HTML. X  www 
  p5.js  ,  
 
 

      
  p5.js    
     
 ,  -
www. #
    
      
 
     
,

  

 p5.js. +   
  
 
 

%  
.
   
 p5-manager,  
www   
  p5.js      

  " 
:
$ rm -rf www
$ p5 g -b www
$ cd www
$ p5 update

Создаем свой файл index.html


# "   index.html  - <!DOCTYPE html>
      
  <html>
<head>
  index.html  
 
<meta charset="UTF-8">
p5.js. ;  meta 
  head <meta name="format-detection" content="telephone=no" />
    
 
 <meta name="msapplication-tap-highlight" content="no" />
   PhoneGap  - <meta name="viewport" content="user-scalable=no,
  
  . 0   - 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';

  JavaScript  
 media-src *" />
<title>ButtonApp</title>

    
</head>
  
   . <body>
<script type="text/javascript" src="cordova.js"></
;      script>
  cordova.js, 
 <script src="libraries/p5.js"></script>
PhoneGap   
  <script src="libraries/p5.dom.js"></script>

  . 2   <script src="sketch.js"></script>
      </body>
</html>
p5.js     JavaScript.
0
     ,  $
   
  body
 ,  
  head.
#
 PhoneGap
  
$  ,   
 -

    
 
-
 :
564 Глава 10

Создаем и исполняем приложение


=  
    - /*
"  ,       M' 
  
   
 
- : p5.js
   ,   
'
 . */

=   sketch.js   - var myButton, responseDiv; // ‰  DOM
       "
     1. #  " function setup() {
 
 
    
- createCanvas(windowWidth, windowHeight); // Z$ -
myButton = createButton('click me'); // Z$ 
   $   -
myButton.touchEnded(changeButton); //  % # '
    
 :   //    
 $   ( ),
- myButton.position(10, 10); //    

      responseDiv = createDiv('catch me'); // C$
 — touchEnded (

" - // 
$ div
responseDiv.position(10, 40); //    
   )      }
$   (
  responseDiv).
= 
    - // \   '       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   $   Run 




   platofms/ios/  
   XCode, —       " -



 XCode   ButtonApp.xcodeo-   %  XCode.
roj. ¥           -
      
  ButtonApp,  Устройство под Android
   
        
-    
   
 —
  
  . 
      
 

-
%  USB $ 
. *
&
  Signing  
     -   Yes.
 

 iOS,    
 
   
   
  
- &    
     "
    ,    
 :  :
ButtonApp > Generic iOS Device. ¥   
$ phonegap run android --device
   
  
  "
 , 
" %  
 . & 
 =    
   
   iOS
  ,    
 

    -   android  ios. 4     
 Signing.


     
 ,
  
      phone-
&  
     
   gap build. 4        

 
   iOS         - 
 

   
,
Сети мобильной телефонной связи и физический мир 565
PhoneGap    
 
   
-
     

 

-
    " 
 . & 
-
   $
    

 "  
,    

      %  
% 
.   
%  
PhoneGap 

        -
  
   %   
  .

4      
 ,
  -
 
    
   Android
         

 . 10.14.

Рис. 10.14. Результаты исполнения приложения на устройстве под Android

Где исполняются приложения? Подытожим…


9
 
       7   , 

 
 
   "  
 ,    $-     
      


 . /
  ,    %,   

 
 
 
 
  "  
 . 
 
     
  . = 
 


 XCode  iOS,  
 Android      %

  
Studio 
 $
 
 ,
- 
  , 
  
  
"    " 
 -  " 
 :
   . '   $

 iOS,       1. # "  


     

 
   
 XCode  
 , PhoneGap   
 .

   $
. 3    2. 0

    
  

    
   
  And- config.xml.
roid Virtual Device Creator,     
android avd. * 
 $     - 3. =  
.

  Android Studio SDK Manager    - 4. = iOS      .
    
      
5. X  www     

 
 SDK.   , $


  p5.js   www.
       ,     
-
        
   - 6. 0

    
  
      "  
 . ~ index.html.

 % $   
  
  , 7. *%  
 .
  " 
 

 


 iOS  Android      - 8. &   
 
 .
  
      
 - 9. 2  
      .
. 
   
    
-
   

   
  / 
     %   
  "   
  . 


 %      
 .
566 Глава 10

Проект 31
Мобильный регистратор личных биометрических данных
Одной из причин популярности разработки собственных приложений для смартфонов является
возможность использования беспроводного канала Bluetooth для организации связи смартфона
с другими устройствами. Это позволяет использовать смартфон в качестве шлюза для отправки
данных на какой-либо веб-сайт в Интернете. В этом проекте мы будем с помощью микроконтрол-
лера замерять гальваническую реакцию кожи, отправлять полученные данные по Bluetooth на
смартфон, а затем сохранять их в файле в Интернете.

& 
 "   $   
-
Требуемые компоненты    
  
 

X 
   0# Android  iOS, 1 %.  :       

7 RedBear BLE Nano, 1 %.        
-
  
      


+       : , 
% 
     . 2 
  / ,  Bluetooth LE.
     
 
   
  

USB- MK20   RedBear BLE   Quantified Self23 (http://quantifiedself.
Nano, 1 %.
com),  
       



  % 
 -   ,  $  ,  
  -
  2,5    %
.    
   FitBit (www.fitbit.com)

=
  
  
. 
    Apple Watch,  "   
-
.     
     .    
 . * 
" -

9  
270 0, 1 %.
  
     
 
      
   
-


%      .   
       .

;
"   %. /      
 ,  
   ,       

0
 
"   Shieldit Super,
13  .   

 .


2   «».

;  % , 1 %.

*   % .

Рис. 10.15. Мустафа Багдатли с устройством Poker


Face24 — регистратором биометрических данных, связан-
ным со смартфоном. Фотография предоставлена самим
Мустафой Багдатли (Mustafa Bagdatli)

23
*
       
  : «[ -
  ] 
 ». &    
 -
   : «    `».
24
Poker Face (* 
   ) —   
  -

,  
 
     , -
 
%     
 .
Сети мобильной телефонной связи и физический мир 567
*% 
    

    -
 

  
   
7  > (
 . 10.15). 7 
-
%      -  

 (q9)   


   , 

 ,  
     -
      , —      
-
   
    q9. 4 
 
Poker Face (
 . 10.16)    $  -
 
  

  " -
 Arduino LiliPad  
  Bluetooth 

 , 

    + 
 .
> 
   
  Poker Face   Рис. 10.16. Напульсник из проекта Poker Face с пришитыми
    -   7   
: http:// контактами датчика крупным планом. Напульсник показан
вывернутым наизнанку, чтобы контакты были лучше видны.
mustafabagdatli.com. Фотография предоставлена Мустафой Багдатли

7       ,   


 
7  ,   —  
"  —     ,  $    
 

     
  . & -    6. 
   
 -
        q9     

   
    -
    

 -       . 
    
, 

%   . 
  
        
  .
    Upload (& 
) 
-
*
 . 10.17   -   
 . 7-   
  
 HTTP GET 

 

 

,   
"    node.js,
      -  ,


   
  Bluetooth LE, - 

   "    .
          '   % $  ,
% 

     , 
 , - .

Рис. 10.17. Блок-схема системы проекта


мобильного регистратора биометрических
данных Файл
для данных
Связь HTTP Смартфон
по GSM или LTE
Интернет

Сервер
на node.js

Веб-сервер
Канал Bluetooth LE

Аналоговый Микро-
сигнал 0–3 В контроллер
Датчик КГР
568 Глава 10

Схема системы
7     $ 
  
   

 . 10.18,    " 


 -
   — 
 . 10.19.     ,
  $ 
   
  .

- -

GND

D3/RTS

D0/RX

D1/TX

D2/CTS

Vdd
LFT

SWCLK
SWDIO
GND
Vin

A4

A3
+ +

Рис. 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 
-
   
  .    $ 
 .

 ,  
       &         
  -

 ,  %  
 
 
 -     
,     
-
 
 ,          LilyPad Coin Cell Battery Holder -

    270 0     SparkFun. 4          
  ( .
 . 10.18  10.19). 9  ,    %  ,   
    
   
  
     LilyPad Simple Power
 , 
%     % $   ,  " 
  
. * 
 $       ,    
 LiPo  
   
 -
     % 10 0    
  USB.

 .

=      


 
Подготовка схемы к тестированию
 
 

     - & %     
   -
  
"    
-    
 , %    , 
 
" . 9 
"    
  . ~ $    -
  
      $ 
-        
    
   , $    $ 
-  
     LilyPad  Flora,
 
   ,     ,   

   
 -
  ,      %  .
   
 , 
   % 
&       
 - 
    . $,     
  7     

 -
     
     
%
  
"  , 
%      , 


   
   ( .
 . 10.16). `    


,    - 
-
  
  
  
"     Bluetooth LE —  LightBlue 
Shieldit Super    . iOS  macOS  nRF Connect  Android.
570 Глава 10

#   

   
  Bluetooth & 
     BLE Nano 
%-
LE  $ 
  
    -    
  
 
"

 
, 
     - , $   
    

        q9,         % 
-

%   



 -  . = $   
%    -
         %  
- (
 . 10.21), -
 
   
    . "  
    
,  $     «
».
= 


   BLE Nano  *,       , 
-
   
  %

  ,  %  
   -
         "  - 

  
   
 
 .
 
  USB/Serial MK20 USB. *
 %
 
      
 -
 
    ,      Начинаем разработку кода

   
   . # 
 - & $
   
     ,

 , 
  
,   
  
     
  % 
     $ 
     
 . 2


    , -
 
 MK20 USB. / 
     
  ,    -

%   
     %
         " 
-

   
     
-  ,  


    .

 
  (
 . 10.20). & 
 -

         4   $     BLE


 BLE Nano  
 MK20 USB  - Nano,    



 
- . Arduino "  
 . = $

Рис. 10.20. Подключение платы Bluetooth BLE Nano к адап- Рис. 10.21. Сборка проекта для тестирования с помощью
теру MK20 USB без припаивания штыревых разъемов может крючков-клипс
быть сопряжено с трудностями. Эти трудности можно пре-
одолеть, используя длинные штыревые разъемы и устанав-
ливая плату на адаптер с некоторым перекосом, обеспечи-
вающим надежный контакт
Сети мобильной телефонной связи и физический мир 571

Носимые микроконтроллеры
4    
        $ -    


,    

   
 ,          - BLE Nano,           
"        
 . _  / ,          -
LilyPad,   _ > (Leah Buechley)   -      . & %    $
     SparkFun,  
  -  
 
   
    -
  ,          ,           
 

    $ 
  .   Adafruit  Flora. ; , 
  
    -
   Flora  
   
  -   
"      BLE
  . X 
    LilyPad   - Nano,  %  
     %  -
      
 

 ,         %
-
 
  "    /  
 , 
      %
  "    ,    
  -  
    . 
 , $   
 Flora    $ % 
  $

  ,      -
  I2C    
          

WS2812  
 


      LilyPad  Flora.
 . 0    
    -

 
 

,  =       
" -
        ,
             _ > «Sew Electric»

.   Seeed Studio    - (   HLT Press), #  (Syuzi
     $ 
   
  % Pakhchyan) «Fashioning Technology: A DIY Intro to
 
     , 
,     , - Smart Crafting» (   O’Reilly)    -



 Pebble.      

~ 

-X 
(Hannah Perner-Wilson)  
 http://www.plusea.
0      
 $   at. 
 ,   -   >  
(Becky
        Bluetooth LE Stern)  
 https://beckystern.com  
   Flora Bluefruit LE, 
  -      
     -
 Adafruit.  ,  $        
    .

       \ | ] 


    12   6. X  
     ! 
  - $    




 " A   
%     Arduino "  
  .
] 
 http://redbearlab.github.io/ =         
arduino/package_redbearlab_index.json. &   -   https://github.com/sandeepmistry/
      BLEPeripheral arduino-BLEPeripheral.


 #  7 
, 
  

Пишем скетч для чтения показаний датчика КГР


   ,     - /*
  
    Z  - 
#
       - : Arduino,  nRF51822  nRF8001

     */
      
 
#include <SPI.h>

. ;   #include <BLEPeripheral.h>


  
 
   :
572 Глава 10

//      ($  $  


//  /)
#define BLE_REQ 10
#define BLE_RDY 2
#define BLE_RST 9

int lastInput = 0; //   $  $   


int threshold = 10; //  $  $ # $

//  

2
% 
     - BLEPeripheral blePeripheral = BLEPeripheral(BLE_REQ, BLE_

     - RDY, BLE_RST);


   BLEPeripheral,  - // Z$  
 
   

 : BLEService sensorService("0927AA6A-3588-11E7-A919-92EBCB67-
FE33");

=   

  // Z$ -    $    
// $ :
  
    
BLEIntCharacteristic sensorCharacteristic( \
   ,   
 - "0927ADA8-3588-11E7-A919-92EBCB67FE33", BLERead | BLENotify);

  
   , BLEIntCharacteristic thresholdCharacteristic( \
       - "0927AF9C-3588-11E7-A919-92EBCB67FE33", BLERead | BLEWrite);
     
    -
  



-
 .

= $ 
    -
    -

UUID25 (     -
    ),  
Android 7  
   -

 UUID:

&   setup()   - 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");
}

25
UUID, Universally Unique Identifier —
 
    -

.
Сети мобильной телефонной связи и физический мир 573

&   loop()   void loop() {


    
  BLECentral central = blePeripheral.central(); //  
// ' 
 
 . 
   - //   ' 
       
: if (central) {
    
 Serial.print("Connected to central: "); // +
    
   
 - //  # 

Serial.println(central.address());
,       - //  # 
 '
        while (central.connected()) {


 . 4   " 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 = input;
        - }

  lastInput —   -
     
 -
"  
  " 
 :
* ,   
  // ž 
 ' 
 
    ,  - Serial.print("Disconnected from central: ");
       - // '    # 
:
Serial.println(central.address());
  " "  : }
}

Тестируем код скетча Монтаж компонентов проекта


2
       
 
 
в толстовку

,    - 
  = $ 
        
  Bluetooth LE ( 

, LightBlue   , 
"  
 -
 nRF Connect)  %   
 -  ,    
"  

   
 . %   
 -  
    , 
  


  . 
    " 
    " . 2  
   
 ,        
  
 ,       $  -
   . 4       , %-   ,  

  -
 " 
   LightBlue    
 . &
 ,     -
nRF Connect      
   
    "    -


 ,    

 ,      

"    
   . ; 
  -     .
     
    -
 —     
   %- 7   
 
% 
-
    
    . *   

   
    ,
  $     "
     

    
%   ,
   
  
   .            

574 Глава 10

 .     


%,   4  % 
"      

  
 30AWG (   ,     (, 

,   LessEMF),  -
      3). 
 
-        
 
 
   , 
  "   ,  " . 9   
  



     , — $   
   
   %
 

  
    
    -    ,          -
      .  ,  
  
 . *
 . 10.23
 
      
 .
;
"         
      
  -

"     

     % . >   -

     
    ,  
% 
      
   % 
 (    
  
  
 
   ,

  ).  
     -     
    .
 
  
,  "  
-
 

  
  
 (
   $           
      
 
  
   . ' "
   
 
  
), —    
  -  $,     "
       , 
%   

 LightBlue  nRF Connect, 
-
 

  . 9   
     
  
     
          
 

 .

 . 10.22 (
,  ,   

  X % ,  
    
-
  ,  
 . 10.18). ,   
       -
   
 .

Рис. 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-plugin-


ble-central Рис. 10.24. Внешний вид готового приложения для Android

+    www  


  p5.js:
$ cd BleDatalogger 9
  
   iOS, 
 -
$ rm -rf www    /platforms/ios/   BleDatalogger.
$ p5 g -b www xcodeproj         -
$ cd www

.
$ p5 update
; 
   
  

 
-
    ,     ,    
Примечание    index.html  sketch.js. *
 . 10.24
=     
   BLE  ,      $   -
Central .      -   github.     
   
  
com/don/cordova-plugin-ble-central. Android.
576 Глава 10

Создаем страницу index.html


= 
  
 <!DOCTYPE html>
  index.html  
 - <html>
<head>
  . 0  
 
<meta charset="UTF-8">
  $      <meta name="format-detection" content="telephone=no" />
 
 "  
  <meta name="msapplication-tap-highlight" content="no" />
PhoneGap     - <meta name="viewport" content="user-scalable=no, initial-
 
 connect-sic    scale=1, maximumscale=1, minimum-scale=1, width=device-width" />
<meta http-equiv="Content-Security-Policy" content="default-src
Content-Security-Policy, -
'self' data: gap: 'unsafe-inline' https://ssl.gstatic.com;

  
  - connect-src
    

: http://192.168.0.10:8080; style-src 'self' 'unsafe-inline';
media-src *" />
Вставьте IP-адрес своего <title>ButtonApp</title>
веб-хоста </head>
<body>
Замените выделенный полужир- <script type="text/javascript" src="cordova.js"></script>
ным шрифтом IP-адрес на IP-адрес <script src="libraries/p5.js"></script>
своего веб-хоста. Наше приложение <script src="libraries/p5.dom.js"></script>
будет подключаться к нему, чтобы <script src="sketch.js"></script>
сохранить полученные от датчика </body>
данные.
</html>

Пишем код скетча p5.js


#  p5.js    
 - /*
 $    
  - Bluetooth Central  PhoneGap
 . * 
     :p5.js  PhoneGap
  
    \$    Š    (Don Coleman)cordova-
  

   
 , plugin-ble-central  PhoneGap/cordova
      - */
 ,      

// ‰  %
 $

   
    
var deviceList, responseDiv, dataDiv, autoUpload;
 
   
 . 
 var scanButton, connectButton, disconnectButton, uploadButton;
,       -

   
  var autoUploadTimer; // ƒ
    
$ $
    
 —  var connectState = false; // Z  ' 
     

 - //  %
 

  
  

  - //       
. 4"    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-A919-
 
       - 92EBCB67FE33',

    


 id:''
  

, 
  };
       -


   
 , 

 
 (URL)

  -
 JSON     
 -

   
 :
Сети мобильной телефонной связи и физический мир 577

&   setup()  - 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');
[  draw()  $   disconnectButton.touchEnded(disconnectFromDevice);
   ,    
- disconnectButton.position(190, 60);
       - disconnectButton.size(80,40);
 
     $ - 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);
setup() 

 ,    autoUpload.changed(setAutoUpload);
 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);
}

[  
     // \ #          
 BLE
  Scan for Devices  
- function scanForDevices() {
      
 . responseDiv.html('scanning for devices.');
#  

   $ - // †   
  $,  ,
//     :
   
   deviceList if (deviceList) deviceList.remove();
 
   
 deviceList = createSelect(); // Z$ 
R  
  ,      deviceList.position(10, 110);
   . 2    deviceList.size(150, 30)
     $  - deviceList.option('Pick a device', ''); // 
  
,   

//  
   '

 "  ,   - deviceList.changed(selectDevice);
   
    // +   5          serviceUUID
     :
578 Глава 10

2  $     ble.scan([myDevice.serviceUUID], 5, discoverDevice, bleError);


 
  deviceList,  - //  $  
-   "  $ 
//   :
  
  BLE,  
setTimeout(ble.stopScan, 5000, scanFinished, bleError);
 ble.scan(). >  }
Cordova   -
   ble, 
  
% $ 
  BLE.
    ,  scan()
     
   -

    
 , -

 
  

 : myDevice.serviceUUID.
=  "   
    
   
-
        
 -:

   ble.scan() // \     



 
    
 , function discoverDevice(device) {
var result = device.name + ' ' + // Z$ 
        discov- //   

erDevice(), 
   'RSSI: ' + device.rssi;
$  
      - deviceList.option(result, device.id); // Š
  $      
  // 
  R  
deviceList. +    
 - }
     
  
 -
     
, 
      $  
     MAC-

(,   ,  -

)  
 :

[  
    function scanFinished() {
scanFinished()       responseDiv.html('scan complete. Pick a device.');
     -  
- // Z   $. +  
.
}
     

-
    responseDiv:

[  
    // • #   $     $
selectDevice()       // 
 $   

   
    function selectDevice() {
myDevice.id = deviceList.value();
 
     $  
responseDiv.html('Selected: ' + deviceList.value());
deviceList. 0      }
 
 "   
 -
,    
 -
   MAC-
 
 -
:
Сети мобильной телефонной связи и физический мир 579

[  
    // • #   $   '  connect
connectToDevice()    - function connectToDevice() {

     - if (!connectState) {


  connect. 4   
 - responseDiv.html('connecting to ' + myDevice.id);
// '  
  ,  
ble.connect(myDevice.id, onConnect, bleError);
     . 

connectState = true;
  %      -
}
     onConnect(), }
 
   —  
bleError():
[  
    function onConnect() {
onConnect()      
 //     -  
  %  
%    ble.startNotification(myDevice.id, myDevice.serviceUUID,
 . &  - myDevice.sensorCharacteristic, onData, bleError);
    ble.startNotifica- responseDiv.html('Waiting for data from ' + myDevice.id);
tion()         //     ...
}


  ,  
    
   -

    responseDiv:

[  onData()    - function onData (data) {


,   

   
 - var input = new Uint16Array(data); //   $ 
     

  // $ " ArrayBuffer
. = 
   var reading = { // Z$ " JSON
  ArrayBuffer, 
timestamp: new Date(), // Z$   
  

    value: input[0] // Š $  $ 
}
16-        
readings.push(reading); // Š $    
  (Uint16Array),     // readings

   
 $ - dataDiv.html('latest: ' + JSON.stringify(reading));
  $  . #  - }
 JSON,    "
  
 ,     " 
      readings,
  
      -

     dataDiv:

[  
    function sendToServer() {
sendToServer()    - responseDiv.html('uploading data...');

   

Send to // +    ...
Server 
   while while(readings.length > 0) { //   
 $       // $ ,
var reading = readings.pop(); // $ 
readings, 
   // $   readings
  
 GET HTTP  - // •       $ GET

   

. [
 var path = '/data/' + reading.timestamp + '/' + reading.
"  GET: http://exam- value;
ple.com:8080/data/timestamp/ //  
sensorValue.  
- httpGet(dataServer + path, serverReply);
        }
 , 
     }

%      
  :
580 Глава 10

[  
    function setAutoUpload() {
setAutoUpload()    if (!autoUpload.checked()) {
responseDiv.html('Auto-upload off');
      -
// ˆ$ $ '
  
    //   



  ,     clearInterval(autoUploadTimer);
    sendToServer() } else {
    ,   - responseDiv.html('Auto-upload on');
     $ : // ˆ$ $ '
// set timer to upload every 2 minutes
// M  
  $ $  2  
autoUploadTimer = setInterval(sendToServer, 2*60000);
}
}

[  serverReply() 
 function serverReply(data) {
 
 HTTP GET 
- dataDiv.html('');

 
   

  responseDiv.html('Server said: ' + data);
//  :
  
    data-
}
Div:

[  disconnectFromDe- function disconnectFromDevice() {


vice()      
  if (connectState) {
      - ble.disconnect(myDevice.id, onDisconnect, bleError);
connectState = false;
 disconnect. [    -
}
   
    - }
         
onDicsonnect(), 
  - function onDisconnect() {
  
   
- responseDiv.html('disconnected from ' + myDevice.id);
    responseDiv: // '   
}

* , "    function bleError(error) {


  % bleError() responseDiv.html(' there was a BLE error' + JSON.
stringify(error));
       %
//  $   BLE
  
    }
  "   %
   
    re-
sponseDiv:

&     . #


  ,
     PhoneGap 
   
,  -

     
 
 :

$ phonegap run --device


Сети мобильной телефонной связи и физический мир 581
4        
 ,  ,  
      % 
 -
 
      
   -  .   
     
   
    
   -  
       .
  
  Bluetooth LE, 
  - 4   $ $  
    -

 ,     . *
 . 10.25
,   
    


 ,  

      $  
       .

 . 3 
 . 10.26 
  $
  
 -

Сохраняем показания на сервере


#   

 server.js,     #

 $ 
     -
, 

   ,  
    

 , $ 
 
    -           
      -
 IP-a
,    
   . #


       
dataServer  
 "    .    , 
 GET   
 :
     


 
     " npm  - /data/timestamp/sensorReading
 express.js,       -
   data.csv.

Рис. 10.25. Толстовка регистратора личных биометрических Рис. 10.26. Приложение регистратора личных биометриче-
данных в действии. Сколько радости и какой уровень воз- ских данных в действии
буждения приносит его создателю такая возможность? Это
можно узнать по его данным КГР в файле data.csv
582 Глава 10

0    
 
 /*

 , 

       -
: node.js

         $ GET HTTP    %  /data/
         timestamp/reading
data.csv (
     */
   
    ).
2 

    , 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());
//  $ $ ...
}

[  
    con- function confirmSave(error) {
firmSave()      var now = new Date(); // Z$  
if (error) { // +     $  ,
     fs.appendFile()
console.log(now + ': ' + error); //   
    

 - //      
"  
 
  } else { //     - ,
    : //   '  
console.log(now + ': ' + 'Saved to file');
// Z-  %

}
}

server.listen(8080); //   $ HTTP


server.get('/data/:timestamp/:reading', log); //  
// $ GET

Диагностика
0
      
-

  data.csv      -

   "   
 ,    " :
  Send to Server,    —
    ,     Upload Sat Apr 15 2017 14:59:47 GMT-0400 (EDT),20
every two minutes. *  
  - 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
Сети мобильной телефонной связи и физический мир 583
4    

 , 

  - Удаленная отладка
"   :
4       ,    -
? D 

 

A
 A-
  
 ,     ,  
   -
  ? 4  , 
   
    
  PhoneGap  
- %   
      ,    -

 ,         .     JavaScript 

 Chrome 
Windows  Safari  macOS,  
 -
?  A> 

A

-

  †   
   "    
  . =

 &? 4  , 

    ,  $  .
sketch.js     %. 

-
 
  $    -   
   
 USB 
-
  
      , 
    
,    


   index.html  

. 
 $ 

Chrome      
 
-
     Bluetooth
 : chrome://inspect. 0
       -
 ,   $          
 , 


 
 
   
 . 
 . 10.27.
? C 
  A  
  

 


? 4  ,   , &    
   
  
 ,  -
            
      % 
  . 0
  
  
   
 .   ,  
      
7   
    -
 
    HTML  JavaScript.
 scanForDevices()  
  myDe-
vice.serviceUUID      
- 0    
 
     -
    
    
   " , 

 $   
  ,
Bluetooth.  " ,    ,        
?  
    
 ? JavaScript 
      - 
 .
4  , 

 
   

URL  Content Security Policy   in-   
   



dex.html   
  dataServer    
   Safari   iOS. =  
sketch.js.  
     
 - 
 

Рис. 10.27. Окно браузера Chrome


для исследования устройств
584 Глава 10

Web Inspector — 


     
  " 
 , 
  
  —
Settings                      .
  Safari | Advanced | Web Inspector. 3 

 Mac   

Safari,  - 0
   
    
            + 
     
 
 -
Preferences | Advanced       Menu %
  %   , 
  
-
Bar  
  Show Develop Menu.       
 

2
  
  PhoneGap  iOS,    . *   -
                $ , 
   
  
  Develop | Phone | Apps | index.html. 
   %  ,   

 

   
 ,     
-
X        "  .

 , 
   
% -
%  
 , 
   - &  " 
     
 
      


   
     ,  $ 


  PhoneGap. %
,    
 
   .
;       
    ,
    
  
   -
Подытожим…      
,    .
*%    
        *%  

 
 
    , 

 
  $          
  : 


  
 

,      
     ,

 HTTP,

     -        . #
    


 JavaScript,       - 


"    —  SMS
Bluetooth LE. 4  

     $  HTTP,      
   
 
   -      
 .

Заключение
По определению, сетевые устройства не болтаются в безвоздушном пространстве сами по себе.
Поэтому, если устройство уже подключено к Интернету, следует воспользоваться предоставляе-
мой им мощностью. Чем больше протоколов и инструментов вы знаете, тем легче и приятнее
будет ваша работа. Обратите внимание на преимущества, предоставляемые серверами с обще-
доступными адресами и излишком вычислительных мощностей. Предусмотрите совместное ис-
пользование проводных и беспроводных протоколов, чтобы оснастить разрабатываемые вами
проекты максимальными возможностями реагирования на окружающую их физическую среду.

        "  -   -



,      
   ,      -       . * $ 
   -

            ,    
   -
 . 0       , -         
-
    
       
.

 

       -
     $   ,    &      
   -
$

 . 0         "  

,
" 
 ,           - 
  24/7 (24     7    ).
Сети мобильной телефонной связи и физический мир 585
0   
  "    - '

    
  
 ,       # ,  , 
-  "    
   $ "  
  ,    
 
   -
 . 0    
  
 
         
   ,  
  
    . +     
 -
 
  
   , — 

,   %         :
  
      -
. *       
   ? %  % ,   
 ;

  , 
 
 ?  
  ;


. 2     -
 
   . ?    
    
 ;
? 
 
 .
2        
  
   
 . =   - + 
  "       
% ,

  ,   
 ? ' $  -  $  " %   %  
  
       %  -    %    
 
.
 
  $  ?

Проект 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 ? PS — PowerSwitch Tail, www.powerswitch-
? D — Digi-Key, www.digikey.com tail.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    >
    %  
 . D: 1660-1003-ND, J:
 Wi-Fi. +     %  
- 2239331, SF: DEV-13787, AF: 3033, F: 2520713,
. RS: 913-9999, SS: 114990575, A: ABX00005,
GBX00005 (3
  4#)

    . +     -
 
 . 
" Arduino MKR1000. +   
 %  
 . AF: 3156, RS: 124-

    $
 1,5 . + - 0657, A: ABX00004, GBX00011 (3
  4#),
    
  8, 9, 26  27   - D: 1659-1005-ND

 
  
 .

" Arduino Uno. +     -

 > ,  $   Blue- %  
 . D: 1050-1024-ND, J:
tooth. +     
  3, 12, 18  2151486, SF: DEV-11021, A: A000099, AF: 50,
31. 4  % 
 " - F: 1848687, RS: 715-4081, SS: ARD132D2P
  Bluetooth,     %  -

"
    ATtiny84. +   

Bluetooth. AF: 1327, RS: 8077742, SS:  
  4. D: ATTINY84A-PU-ND, SF:
113990026 COM-11232, F: 1455160, RS: 738-0684

N   D Android

iOS. + - 
  
= ESP8266.   
    
  31.  Adafruit ESP8266 Huzzah!  
Adafruit  ESP8266 Thing Dev  
SparkFun. SF: WRL-13231, AF: 2471
Где брать компоненты и прочее? 589

     > Raspberry Pi. 
D
 RFID. +     
 -
+      
 . ;  24, 25  27.
   BeagleBone Green   

• D
  -   SCL3711. ID:
  
 Linux. SF: DEV-
SCL3711
13825, AF: 3055  3400, SS: 102010048 
114990584, RS: 896-8660, F: 2525225 
" NFC-
 PN532. AF: 364,
D: 1528-1781-ND, SS: 113030001

C      . +   
 %  
 . D: 438-1045-ND, 
"
RFID Classic  

Mifare.
J: 20723  20601, SF: PRT-12615  PRT- +    
  24–27. AF: 359
12002, F: 4692810, AF: 64, SS: 319030002  360, SF: SEN-10128  SEN-11319, SS:
 319030001 113990013

H
  
  Arduino. ; 
   A > IP-
 -
       
-

D-Link (   
   -
                 

 ,  
 $ 
    - Raspberry Pi  
Pi Cam). +   
   %    .  
  29  30. DL: DCS-930L, DCS-
AF: 2077, A: TSX00083, SF: DEV-07914 5222L  DCS-960L.
• "     +
. SF: PRT- 
&         ,   IP-
12044, AF: 65, D: 923273-ND 
  Raspberry Pi  
Pi Cam:

 &
    . + - •   Pi Cam. SF: DEV-14028, AF: 3099,
    
  8, 9  27. AF: 1609, D: V2018- SS: 113990214, RS: 913-2664
ND, J: 616673, F: 4903213, RS: 159-5420 • ]     Raspberry Pi Zero
W. A: 3414
Модули связи 
D 

  USB/TTL-Serial. +    - • Adafruit Fona 800. #3 — AF: 3147,
 
 . SF: DEV-09716  DEV- 4
 — AF: 2691
14050, AF: 3309  284, SS: 317990026
• Adafruit Fona Feather. AF: 3027

" Bluetooth Serial. +     
-
 3  18. AF: 1588, SF: WRL-12580  • SeeedStudio Xadow GSM+BLE. SS:
WRL-12576 102040005


(
 XBee

XBee Pro S2C • XBee Cellular. D: 602-1976-ND
802.15.4. +     
  14. AF: 128, • Particle Electron Kit. #.  Š. 3
/
D: 602-1892-ND, SF: WRL-08665, J: 2253722, 3 
 — SF: WRL-14211, 3
/
PX 32416 3/4
 — SF: WRL-14212

(
 SX1276  

HopeRF


RFM95W  

Semtech. + - Адаптерные платы и разъемы


    
  11. AF: 3072, SS: 113060006

     
 .

USB/XBee-  . +     
  14. +     
  14. SF: B0B-08891,
J: 32400, SF: WRL-11812, AF: 247, PX: 32400 P: 1479  1639

(
 Bluetooth LE. 7   - 
% =   A  JST- ). + -
   
  12    Arduino     
  13  15. SF: SEN-
101  BLE Nano. AF: 1697 08733

 BLE Nano  

RedBear
USB- 
()   
«  » 9 '.
 MK20. +    . +   +     
  3  13. D: 1568-
 
  31 (
    1237-ND, J: 2207056, SF: PRT-09518, A: 80,

  12). MS: MKRBL5, SF: WRL-14071 F: 1650675
590 Приложение


  )

 2,1     - 
D
. +    
  7–9,
 
 , 5,5   + . + - 11, 14  26. D: 160-1144-ND  160-1665-ND,
    
  3  27. D: CP3-1000-ND , J: 34761  94511, F: 1855510, RS: 228-5972
J: 28760, SF: PRT-10287, A: 369, F: 1737256  826-830, SF: COM-09592  COM-09590

    A   . + - 
% =  
  $
 .
    
  5  31. D: K386-ND, J: +     
  1  4. D: 754-1492-
22577, F: 09WX4670 ND, J: 2125181, SF: COM-00105, F: 2290374,

      A   . + - RS: 861-4290
    
  5. D: K445-ND 
WSU-30M, J: 2150361, F: 441089 
 &    
. +   
 
  10  12. J: 106526, A: 387, SF:

H  


 + 2,5 . C0M-09469, F: 1716710, RS: 577-538, SS:
+    %  
 . D: MTR102A2B
A26509-20-ND, J: 103377, SF: PRT-00116, F:
1593411 
D

  A
 5 '. + -

  )  + 2,5 . D:    
  14. J: 51262, D: LM7805CT-
ED7102-ND, F: 1122344, SF: PRT-00115 ND, F: 9756078, RS: 918-1971

     
 XBee. 
D

  A
 3,3 '. + -
+     
  14. SS: 113100001,     
  14. D: 497-1491-5-ND, J:
SF: BOB-08276 242115, F: 1703357, RS: 438-4885

H  ) + 
  +- 
   , 1  \. +     
 -
 2,5 . +     
-  14. D: 1189-1324-ND, J: 94161, F: 8126933,
. AF: 400, SF: PRT-12693 RS: 475-9009

  )  + 2 . + - 
   10  \. +     
-
   
  14. SF: PRT-08272, D:  14  15. D: P11212-ND, J: 29891, F:
3M9406-ND 1144605, RS: 762-1736
Общие компоненты 
   100  \. +     
-
 14. D: P10269-ND, J: 158394, F: 1144642,

D 

 100 . +     
- RS: 762-1746
 8, 9, 29  30. D: 100QBK-ND, J: 690620,
F: 9337660, RS: 755-0707 
  ! 
  NPN TIP120. + -

D 

 220 . +     -     
  14  27. D: TIP120-ND, J:
 
 . D: 220QBK-ND, J: 690700, 32993, F: 9804005, RS: 808-0502
F: 9339299, RS: 707-7612 
C   
 «  », 9 '. +  -

D 

 1 . +     -   
  3.
 
 . D: 1.0KQBK-ND, J: 



    
690865, F: 9339051, RS: 707-7666 9–12 '. +     
  14. SF: T0L-

D 

 10 . +     00298, AF: 798, J: 170245, F: 1176248

  2, 6  10. D: 10KQBK-ND, J: 691104,
F: 9339060, RS: 707-7745 
C  



 3,5-5 '.
+     
  13. AF: 771, D:

    
 47 . + - BC4AAW-ND, SS: 320180002
    
  14. D: A105657-ND, J:
254028, RS: 186205 
<

- 
    . + -

 
 10 . +     -     
  3  13. SF: PRT-13813 
 
 . J: 29082, SF: C0M-09939, PRT-08483; AF: 258  2011
F: 350072, RS: 249-9294 
! A    
(CR2032)

D 

 270 . +    
   . +     
  13.

  31. J: 691446, D: CF14JT270KCT- SF: DEV-10730  DEV-13883 

ND, RS: 845-7577 PRT-00338, AF: 1870  1871 654.
Где брать компоненты и прочее? 591

Специальные компоненты 
'-    ) USB. +   
 
  5, 21, 22  23.

' . +     
  13. SF:
T0L-10285, F: 1015878, RS: 244-890 
\

(
  -


). +    
  6. D:


 &. +     
  13. PDV-P9200-ND, J: 202403, SF: SEN-09088,
SS: 109990013, SF: T0L-11702, AF: 468 F: 7482280

-&  
 . +     
 -

!
  

Hanwei. + -
 10  12. D: 365-1068-ND, RS: 654-8542
    
  14. SF: SEN-09405, P: 1481,

  
 
 WS2812 PX: 60500009
(NeoPixels). +    
  13. AF:

 &      GP2Y0A21YK
2226, 2858  2859, D: 1528-1610-ND, J:
2247947, SF: BOB-13282, SS: 104990139  

Sharp. +     
 
12  14. J: 2150256, D: 425-2063-ND, AF:

"
WeMo  

Belkin. + - 164, F: 1243869, RS: 666-6564


   
  26. B: P-F7C027

N     HC-SR04,

]  
 >$ . SRF04

† 
  . +    
+     
  29  30. SF: KIT- 
  16. SF: SEN-13959, D: 1568-1421-ND
13815

GPS-

. +     
  18.

D 
   . +     
 - AF: 746, SF: GPS-1275
 27. AF: 1512, AMZ: «uxcell DC 12V Open
Frame Type Solenoid for Electric Door Lock» • 
   GPS Garmin GLO   
-

   -   https://www.garmin.com.

  > PowerSwitch Tail.
3
   ,     
- • 
   GPS Bad Elf GPS Pro+  
 29  30. SF: COM-10747, AF: 2935, PS: 

   -   https://bad-elf.com.
240vac Kits (
  240 & 
. .)

ˆ
&     

LSM303DLH

 
 , 4N35. +     
-  

ST Microelectronics. +  -
 29  30. J: 41056, F: 1244500, D: 160-   
  19  20. AF: 1120, SF: BOB-
1304-5-ND, RS: 597-302. 3
  13303, P: 1250, SS: 101020081
    
  -
  SparkFun S: B0B-09118 
D      
. + -
    
  8  9. SF: COM-10443 
BOB-10467
Датчики

!
   
A 
DTH11.

!



. +    
  +     
  29  30. AF: 386,
2  3. D: 905-1000-ND, J: 150551, SF: SEN- J: 2245415, SS: 101020011
10264, AF: 182, RS: 708-1277

  >



 &
- Разное


A
. +    
 

(
  
. D: 3M156065-ND,
2, 8, 9  10. D: GH1344-ND  SW400-ND,
RS: 120-6041, J: 2119718, A: 550 , SF: C0M-
J: 2231822  119011, SF: C0M-09337, F:
10594, F: 1165068
1634684, RS: 718-2213

H
      18 

!
   (†  )   -
      "3   =. + -
. +     
  8  9. AF: 377,
    
  8, 26  27. = % -
SF: C0M-10982 BOB-11722, SS: 311130001
  
  
     

(

  


 

400  
    ,    ,
 

Interlink. +    
 -
  
   ,  
 5. D: 1027-1001-ND, J: 2128260, SF: SEN- 
     . D: 36-
09375, A: 166 2204-ND, RS: 123-6835, F: 2301244
592 Приложение


'
 "3    . D: 36-9300- 
K    
-   & 
-
ND, RS: 274-5086, F: 2500400   10 . +     
  13.

"
   
. + - 
 +  +
   J 
  

    
  1.   
. +     
  14.

]+  
 +  

" - 
 >
- 
  



-
+
. +     
  2  3. 
 
(IC-hook with pigtail). + -
   
  31. SF: CAB-09741  CAB-

 +
. +     
  5, 00501
29  30.


+
 
 A 
-


   . +     
-   5 . +    
  31. AF:
 5. 1126, SF: DEV-11347


&  

   
- 
%  $   . +    

 
   

  
  31. AF: 116, L: 1220
 . +    
  5.

%   $
 . + -

D&
 . +    
  6.     
  31. AF: 603, SF: DEV-11791,

-  
 
   
 - L: 304
 . +     
  10  12. 
% . +     
  31.

" 
    
  
]

 +

. +  
10 . +     
  13.  
  31.

Поставщики аппаратных компонентов


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

Abacom Technologies Adafruit Industries


  Abacom 
   
 
-   Adafruit 
      

, 
    
 
- $ 
  
  «   » -
,   
  Ethernet/ 
     ,  



TTL-Serial. 
 

 AVR, MP3-
  

www.abacom-tech.com 
 .

abacom@abacom-tech.com  www.adafruit.com
 sales@adafruit.com
Acroname Robotics Arduino Store
  Acroname 
  %
  
7 Arduino 
  
 


  
  
  
-   % Arduino,    
    $ 
  . 2       -  
      Arduino.
       —    store.arduino.cc
 
   , 
,
     
 - Atmel

   
. *    
 -
  Atmel     
 


"    
%
    -
AVR,  
    Arduino, Wiring,
    . BX-24    
 . &  " 
 -

www.acroname.com   Atmel 
     Microchip.

info@acroname.com  www.atmel.com
Где брать компоненты и прочее? 593

Charley Chimp ELFA


~
%, 
%, $  $ 
 ,   ELFA —     
  -
  "   

 "  
- " $ 
     # 
-
   ?  +
 .

charleychimp.com

www.elfa.se

customercare@charleychimp.com

CoreRFID Farnell/Element14
  CoreRFID 
  %
  -   Farnell    $ 
 -

      RFID  
 
-     4
 . *
   
 RFID.    ,   
   -
   Newark  #3, $,


www.rfidshop.com   
 3 ,   -

info@corerfid.com  Farnell        
   .
D-Link 
uk.farnell.com
  D-Link 
  
  USB, 
sales@farnell.co.uk
Ethernet  Wi-Fi,  
 Wi-Fi,  -
     10. Figaro USA, Inc.

www.dlink.com   Figaro 
 
   -

sales@dlink.com ,     
  
   , 
 ,  
   
Devantech/Robot Electronics 
 .
  Devantech   
- 
www.figarosensor.com
  
, $ 
  , -

figarousa@figarosensor.com

     , 
 
 -
 ,
  

 
  
     
 

- Future Technology Devices
 
 . International, Ltd. (FTDI)

www.robot-electronics.co.uk
  FTDI  
 


sales@robot-electronics.co.uk 
   USB/TTL-Serial,  
-
  FT232RL, 
  "  
Digi   
  $  .
  Digi 

 XBee,

     Ethernet. 
www.ftdichip.com


www.digi.com 
sales1@ftdichip.com

Digi-Key Electronics Glolab


  Digi-Key —      
    Glolab    
 $ 
 

   
  
 $ 
  - 
   ,    -
. X      %
  
- 
-   

  
, 
-
       :
 
,    
 
.
  
,
 , 
 , -
   , 
, 
    
. 
www.glolab.com

www.digikey.com 
lab@glolab.com
594 Приложение

Gridconnect 
international@jameco.com

custservice@jameco.com
  Gridconnect   


   
,  
 -
 Lantronix  Digi.
Lantronix

www.gridconnect.com   Lantronix 
  Ethernet/
TTL-Serial:  XPort, WiPort, WiMicro,

sales@gridconnect.com
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   Linx    

  ,  -

imagesco@verizon.net
  
 
.

www.linxtechnologies.com
Interlink Electronics 
info@linxtechnologies.com
  Intelkink    
  -
  , 
   
 Low Power Radio Solutions
 
  .
  LPRS  


 -

www.interlinkelectronics.com , 
  
 
.

specialty@interlink electronics.com 
www.lprs.co.uk

info@lprs.co.uk
IOGear
  IOGear     
Maker SHED

. &    ,   
  
  Maker SHED 
    

%    
USB/TTL-Serial, 
        

 
 Powerline Ethernet.
MAKE 
%   . &  " 
 -

www.iogear.com  
  
 
  

sales@iogear.com            -
  
 ,  -
 
Jameco Electronics    .

  Jameco      


 - 
www.makershed.com
 $ 
   ,  ,   
help@makershed.com
 ,  
   
   -
  $    
    - Maxim Integrated Products
  $ 
 .
  Maxim 
 , 
-

www.jameco.com   , 
   
  $
-

domestic@jameco.com 
      
 . 4 
Где брать компоненты и прочее? 595

     Dallas Semiconductor.   Farnell  Newark      -
#    $   
        .
    
     
  

www.newark.com
        , 
 

, 
  
  - 
order@newark.com
     . .

www.maximintegrated.com
New Micros

info2@maxim-ic.com   New Micros 
 


 

. 0   
-
Microchip  
  USB/XBee, "  
    


  Microchip     
 
-
XBee   Digi. / 
  

  PIC. 4 
 


-
 "      
  "  
   -
    


     -

  . 4  
   -

 XBee 
    -
 Atmel.

.

www.microchip.com

www.newmicros.com
Mouser 
nmisales@newmicros.com

  Mouser    


 
   Parallax

 $ 
     #3.
&  
     %   -   Parallax     
 
 -
  ,      
 
  Basic Stamp  
 


$  , —   


 ,  - Propeller. 0   
  %
  

 
,   
. X , 
   ",
 
   

   -
  
     
    ,  -
USB/TTL-Serial  FTDI. 
"  
 ,   $ -

   
 

.

www.mouser.com

help@mouser.com 
www.parallax.com

sales@parallax.com
NetMedia
Phidgets
  NetMedia 
  
 -


 BX-24   Ethernet   Phidgets    
SitePlayer.          -

      
.

www.basicx.com

siteplayer.com 
www.phidgets.com

sales@phidgets.com

sales@netmedia.com
Pololu
Newark/Element14
  Pololu    
 
 $ -
  Newark    $ 
 -

    
 
   #3. *
   

    
 
 .
  ,   
    -
  Farnell/Element14  4
 , $,
- 
www.pololu.com
   
 3 ,   
www@pololu.com
596 Приложение

RS Online SparkFun Electronics


  RS Online —     
    SparkFun       -

 
   
  $ 
 -  
   $ 
  -
  , 
"  
  . 0    
-
  
.   ,
 



www.rsonline.com "  ,   
  %
  
-

general@rs-components.com   
 

 
.

www.sparkfun.com
Samtec 
customerservice@sparkfun.com
  Samtec  
  
$ 
    . &  
  - Symmetry Electronics
 %
  

 ,      Symmetry
 


     $     ,  , ZigBee  Bluetooth, 
Ethernet/TTL-

 ,  . Serial,  Wi-Fi,     


www.samtec.com $ 
  
  .

info@samtec.com

www.semiconductorstore.com
Seeed Studio TI-RFID
  Seeed Studio    
 -
  TI-RFID 
     
   
  $ 
  -
RFID   Texas Instruments. 0  -
 
  
      . 0 
        RFID 
 
 
     
  $ -

      .

   ,       

. 
www.tiris.com

www.seeedstudio.com

order@seeed.cc Trossen Robotics
  Trossen Robotics 
  %

SkyeTek
 
      RFID 
 -
  SkyeTek     , ,   
% , 
-
 
       RFID. 0  
-       Interlink,
    Jadaktech, 
  -  
 , 
Phidgets,  -
 
 
  OEM-    RFID,      %  -
   
 .     RFID.

www.skyetek.com 
www.trossenrobotics.com

www.jadaktech.com 
trsupport@trossenrobotics.com

Smarthome
  Smarthome 
   
 
  % , 

  

%     
-

 —   
 ~10,   INSTEON.

www.smarthome.com

custsvc@smarthome.com
Где брать компоненты и прочее? 597

Программное обеспечение
Большинство используемого в проектах этой книги программного обеспечения распространя-
ется с открытым исходным кодом. Многие из включенных в список программных платформ в
этих проектах не задействованы, но, в целом, весьма полезны.
Arduino CoolTerm
Arduino — $
 


   >   (  
     )

 

 AVR,    
 

 
       



  Processing. 7   -  Windows  macOS. 3
9
7

   Windows, Linux  macOS. (Roger Meier).



www.arduino.cc 
freeware.the-meiers.org

Asterisk Cygwin


 PBX1  

   . + 
    
  POSIX 
+      Linux  UNIX. Windows.      Windows
 
     
  Linux.

www.asterisk.org

www.cygwin.com
AVRlib and avr-gcc
Dave's Telnet
>      C    

 
       
 - 
  telnet  Windows.

 AVR. 7       Windows, 
dtelnet.sourceforge.net
Linux  macOS     

avr-gcc. Eclipse

www.nongnu.org/avr-libc #
 IDE2 

 

 
      
   . 9 -
GNU avr-gcc — $ 
C    -
%
  
   
 
,

  
 

 AVR. 0    - 
   
 -
    Windows, Linux  macOS.  %       


 .
Windows  
"       - +      Windows, Linux  macOS.
  
 

 AVR Studio (www.

www.eclipse.org
atmel.com/tools/atmelstudio.aspx).*

 


  Linux   
  
:
www.atmel.com/tools/atmelavrtoolchainforlinux.
Express.js
aspx,    CrossPack  AVR  macOS — >   JavaScript  
 node.js
 
: www.obdev.at/products/crosspack. 

  -

.
*

 

 avr-gcc  
 
- 
expressjs.com


 Arduino, $,   $

,  
   avr-gcc. GitHub
~   git —
  
  
-
ble-central      

     .
+ 
  git  github    
7  
   
  Bluetooth LE 
    "    .
 
 PhoneGap  Cordova. 
git-scm.com

github.com/don/cordova-plugin-ble-central/ 
github.com
1 2
PBX, Private branch exchange —     - IDE, Integrated Development Environment —   

-
      .  


.
598 Приложение

Java noble
`  


 . 7      + 
 API  
   
  Blue-
 Windows, Linux  macOS,     - tooth  node.js. =     
  API
  
    . 
  
- 

   
  Bluetooth LE.

    Sun Microsystems,   - 


github.com/sandeepmistry/noble
 

    Oracle.

http://www.oracle.com/technetwork/java Node.js

  JavaScript 

, -
JavaScript     
    .
> 
  "       - 
nodejs.org

 . JavaScript — 
 HTML  CSS —
   
       ,  " Nodemailer
  
 + 
. JavaScript, -
>    $ 
   



    
 node.js, node.js.
          
-
     
  


  
nodemailer.com
 
   
 .
node-serialport

developer.mozilla.org/en-US/docs/Web/Java
Script >    
      

  node.js.
libnfc 
github.com/EmergingTechnologyAdvisors/
node-serialport
+ 
 API  NFC. 7      
Windows, macOS      POSIX. npmjs.org

nfc-tools.org ~
 "   
   Node Package
Manager. #
 %
  
 
Max/MSP      node.js  
 -

.

 
    

 -

npmjs.org

 
 -     -
.    

    -
  ,    
     
onoff
      .  Max   >   node.js  
   -
  MSP  
     /  "       
-


  
     Jitter    
 
.
 
     

- 
www.npmjs.com/package/onoff
 
 . 7       Windows
 macOS. p5.js

www.cycling74.com 
  JavaScript    Processing.

   

 
  
  -
Mosquitto         
 
-


    
 . ~
%
7 
 

(

)  MQTT.
  

 
   
-

   Windows, macOS  Linux.    

.

mosquitto.org 
www.p5js.org
Где брать компоненты и прочее? 599

PEAR    
      -
      . 9
   
9 

 %
  
   


  Max — 7

PHP. #
  
 %
    (Miller Puckette). 7     
 
  PHP.  Windows, Linux  macOS.

http://pear.php.net

http://puredata.info
PHP
PuTTY SSH
`   
 ,    
  
  -

. # 
       telnet, SSH       

    HTML.7        Windows.
Windows, Linux  macOS. 
www.puttyssh.org

www.php.net
QRCode.js
PicBasic Pro >   node.js     QR.

  
BASIC  
-

https://github.com/IagoLast/qrcodejs
 

 PIC. +      Windows.

melabs.com Dan Shiffman's Libraries
PhoneGap/Cordova =  (Dan Shiffman)

 -
       Processing 

 PhoneGap 
    
- p5.js. 0  
   
-

 
      
      " 

 .
    HTML, CSS  JavaScript.

 Cordova    $ 
- 
https://github.com/shiffman
 
   
 PhoneGap. 
www.shiffman.net

     Adobe.

https://phonegap.com
Tor

https://cordova.apache.org >

 , "     -
"   -  ,    
 -
Processing

.

`  
 


 , 
   - 
www.torproject.org
   , " -
%          ,  Tracking.js
 "  

  
- >   node.js      .
 
  ,      .
0   Java,        
www.trackingjs.com
Windows, Linux  macOS.

www.processing.org
Twilio

   "   IP-   .
Puredata (PD) 
    
 API, -
"         -
q
 
    

  
 .
 
 -     . -
   

      , 
www.twilio.com
600 Приложение

Visual Studio ws
0  


 IDE   >  WebSocket  node.js.
Microsoft    

  Windows.

https://github.com/websockets/ws
&
  "     Comm-
unity Edition 
       —
    ,         XCode
  
 
  


- 0  


 IDE  
,  
   
  
  Microsoft    

  macOS



 .  iOS. 
      ,   -

www.visualstudio.com   ,          

 
  


 , 
Wiring 
   
  
  

-

 .
#
 


   
 
-

 AVR,    
 

- 
https://developer.apple.com/xcode/

  Processing. 7      


Windows, Linux  macOS.

www.wiring.org.co
ПРЕДМЕТНЫЙ УКАЗАТЕЛЬ

 >  WiFi101 206


ArduinoHttpClient 221, 468  , Client 206
3
 BLEPeripheral 571  , Server 206
   OAuth2 163   323 WiFi101 205
3
Bluetooth 319 >
MK20 USB 570 body-parser 159   355
USB/TTL-Serial 96, 99 Button 263    355
3
CurieBLE
IP 144 >  354
  323 >
   144
CurieIMU 421  
  381

%

 145
dgram 342 > 
  

"   146
Encoder 263 421
  145
ESP8266WiFi 205 >
"   267

   144
L3G 428 >




 145
libfreefare 461 NCSA Mosaic 500

 144
   461
localhost 148 Tor 499
libnfc
MAC 144 >


 MQTT 517
   461
   144 >

MQTT
libnfc-dev 461

 144 Mosquitto 526
LSM303

 144
   424
  148
   148
mqqt.js 529 '
%
 "  148 MQTT 522, 523 & 
3
 MulitCameraIR 295


51, 152
 

 416 multer 185, 535
dateServer.js 154
3  NDEF  Arduino 470
& -

RFID 457 net 191
DCS-960L 534
3   38 noble 329
DCS-5222L 534
 36 node.js
multer 180 & -

   36 If This Then That 468
3   
 
- nodemailer 162
onoff 481 &

 
 

 73  
 311
3
  p5.js 55, 274
PN532 470 &



  267
Processing  -

43
3

net 188 &  " 293

144
video 188 &
"  420
3  
  

 477
3  
    93 querystring 546 &
   "  360
SoftwareSerial 127, 132, 134, 170 & 
   69
Stream 208 & 
 363
C   208 &  
 

 64
>   391 TextFinder 208 
 64
>      38 tracking.js 451 +7 64, 101
602 Предметный указатель

 2 
  


258
   305   
148
q 421  
q 
  393 arp 147
q
 
421  arp -a 147
q 
 54 + 
ifconfig 79
q 
  38 SSID 207 iwconfig 79
q
   
334 Bluetooth LE 323 iwlist 79
 

 323 LoRa.crc() 318
! +  ping 147

   441 Processing
=
+
   35 image() 189
=
+ 

   258 ssh 44
  36, 38
+  
  
   sudo 79
 36
  404 traceroute 361
   36
+  300     49
 
+ 
 " 366

  169    
 42, 43
+ 

TAOS TCS34725 447 
143
API
  
   151
 -   220
LSM303 423  
API REST 547
 

Groundlabs 507
I2C 64
DHT11 520 navigator 414 Twilio 538
= 
 112 SPI 64, 129  
 423
=
%
 452 

 28  
= 
 341   28 Pi Zero Camera 534
=   
  73 $ 
  28 

=  122 +   

 
 

30
=  527   
  53   30, 35, 75, 76
= 
  301 Raspberry Pi 76
= 38
=  
  node 52
 Raspberry Pi B3 76
Raspberry Pi Zero W 76
 

  30
# Ethernet 36
 %  30
USB 35
2 
 31
USB/TTL-Serial 98
Connection 273 
 SIM 550  

30
HTTP 153 

  
37
Upgrade 273 
258   

. &. 
    114, 150  
    157
$ 
   163 Stream 556, 557 
420
2
  82   .find() 556 


2  
  426   .findUntil() 556   
  477
2    .timeout() 556 
   477
NDEF 463      478
 463 [
  301 
   420, 426
2
   152 

 421
HTTP  
  156   51

 
155   36, 38
<
 157   
     36 _   
 421
HTTPS 416   
      _ 
2"  
 366  36 
 369
Предметный указатель 603
_ 7
 

  * 
 82
 

  258 Arduino 61 *   
 419

   258 % 66 * 
 
 317
_  
  84 Arduino 101 63, 65 *     270
Arduino MKR1000 63, 65 * "   293
" BLE Micro 63 *

BLE Nano 63 IMSI 550


7  
420, 423 ESP8266 63, 65 

7    ESP8266 Thing 66  -

 152

   421 7
 

30 $.  152
7   8-

 60 *

   36, 38 32-

 61 

7   195 ARM 61, 63   152
7
%
 % 253   30   152
7
%

143 7

 

IP-
145  
 30
 " 150 7

 
75

7    145 7
   0  
7 
  ESP8266 99, 205   
 93
 381 FT232RL 98 
 32
 355 7   
   
 93
7  ArrayList 255   408 0
7 
7  OSI bash 560
  206 
  93    49
  Ethernet 150 0 
Homebrew 526 IP 150 module.exports 483
7    150 0 
POST 158 
 
 150   31–33
request.query 156 7  143 0  
30,
sendPacket() 345  75, 76
Serial1.print( 124 SM5100B 550 0 
Serial1.println( 124 7 Processing
Serial1.read( 124 BLE Central 575 Contribution Manager 188
Serial1.write() 124 BLE Nano 569       
  583
Bluetooth 122 0 
serialEvent() 111, 116, 121
WiFi IP-
 145
Serial.print() 109
ESP8266 204 0


Serial.write() 109
WINC1500 204    355
server.get() 157
WINC1500 205  
 355
server.post() 157
7 122 0
   
7 432
%
 -  217
  
  82

 121 0     441
7  " 249
7  0

7 
35

  
   396 
 
 517
7  
  302
 396 0
 

  302
  396 Electronic Frontier Foundation 419

      302
7
   301 0
  420
7
 

0 
 35, 84
ATmega 328T 127 ] DSO Nano 84
Atmel 16U2 99 *% 
%
 253 0  420
ATtiny84 127 *
         "  420
BASIC Stamp 98 421 
   "  420
604 Предметный указатель


"  420     Cygwin 44

420    304 forever 195

   "  420   
 426 GNU screen 58

  420  "
 
72 less 47, 48
  420 
   48
0 %  
$.  152 nano 47
 /% 318 
    48
0
    258   152 netcat 346
0
  
 426   152 OpenSSH 44
0   355     57, 59, 71 Photo Booth 188
0 " 35 
, Mac Os 71 Processing 39

, Windows 71 PuTTY 44, 45, 58
 

 134 wpa_cli 79

  152 

     

 
      
   159, 274

 HTTP 155   
  64 

    
    
  64 
 134
RFID 456       



 292 
" 230     42

   369     OpenSSH 44

  
  426 
120 PuTTY 44, 45

  
 57, 59, 71    
 42, 43
request 155 
, Mac Os 71 

response 155 
, Windows 71 ANT 307

 

 134 ASCII 105
Processing   
36, 38, 74 Bluetooth 122, 307
 41 
  DHCP 150
 54 
 NMEA 412 DNS 150

 

  
  267 EDGE 549

  426 
   292 GSM 549
  426 
 
 Hayes AT 363

   
 ,   
 HTTP 153
USB/TTL-Serial 35 64 I2C 421
"  115 
 
 29, 292 IMAP 162
 
  LoRa 307, 310
BLE Nano 570 apt 81 LoRaWAN 310

 

 Bluetooth GPS 413 MQTT 514, 516
ESP8266 Thing Dev 205 PhoneGage Desktop 559 

517
Feather ESP8266 Huzzah! 205 PhoneGap Developer 559 
  517
MKR1000 204 
     NFC 459

   
  404 NMEA
node.js 50 
  REST 234 
  412
      36, 
    84 NMEA 0183 410
38 
   38 OneWire 520
  
  355   37 POP 162
 %"   37 RFID

 
72 
    35 Mifare Classic 460
   

 Mifare Ultralight 460


 
  - Camera 188 RS-232 97
 478 Cheese 188 
  97
  CoolTerm 57, 59 SIP 537
  145 curl 80 SMTP 162
Предметный указатель 605
SOAP 468 9 
 
  
  #  89
TCP 150, 252, 341 81 
TLS 419 9 

  35, 37  
  142
UDP 150, 253, 341 9  
  317   142
webSocket 272 9          304
webSockets 253 169    305
WiFi 307 9  
# 
XBee 362  %" 72     
  408
ZigBee 307  " 72

  129
 112 9  
36, 37
#
    32 9
. &. 
%


   270
    USB 9   420

  95, 96 
  110
    ;;_ #  

  95
D OAuth2 163
 29 #  UMTS 549
    29 
  157 Wireless E91 391
  29 #  

   112  
 69 OAuth2 163

 
  101 
      " -
Bluetooth  101  , Hue 477
GAP 319 # Arduino
GATT 319      341 & -  AirNow 223
SPP 319 # Bluetooth Central  PhoneGap
  174  354 576
 
  HTTP 157 C  253 Camera 189

   341 Processing
C 
    93 & 

268
( C  
 TCP/IP 253 q  415
9   #    151 2  "  NDEF
  441 #


  Arduino 471
9  DNS 150 +- 
399
  node.js
  HTTP NFC  
TwiML 540  
 , 

 54
WeMo 473
9
%    152
  MQTT 520, 523
  46 dateServer.js 154
0   
 
  47 
     252
 

    -
9    30
   
 557
DB-9 97   51
D-sub-9 97 #
 0
   
   -
ICSP 129 SMS 544 
 
 430

 «
 » 35, 38 #
       
     35    419 
 110, 111
9    416 


 
  38 #
  108
%
 36, 38 
  
416  
9   #   & -  AirNow 221
Arduino Uno rev3 66

30 #

HTTP/HTTPS 417
9     204 #

   
  
   396 #      TwML
 396   31, 32    MQTT 542
  396
 32, 33 # 
"  208
606 Предметный указатель

#          


 #     395

  
 E.164 545 #  
   CurieIMU #   391 NFC
427 #    204 SCL3711 460
#    -  - #      37  
   PN532 468

 571 #    420
#       - # 
 %

 
 LSM303  
 - ageCheck.js. 156
; ARP 147

 L3G 428 ageCheck.js,   REST 237
;  420
X "   564 AQI client 232
;   
 112
X
  
402 aqiClient.js 233
;   
X
  
    - dateServer.js 154
% 514
 103, 104 getParameters.js 155
;
 
'   QR,    - js
 
   HTML5 454 #   
 
 155
cd 46
'  "  NDEF mailer.js. 162
cd,   
 

  Arduino 471 node.js 54, 180
46, 47
#  40 #

UDP 343
exit 49
#
  p5.js
logout 49
    71  

 56
ls 45
 421 restAgeCheck.js 237
mkdir 46
#  
    wsExpressServer.js 274
pwd 45
53 & - 
    /
-
rm 46
# 
    490
  45
 
  310 & - 
      
;  
  35
# "  494
;  
 420 2  "  NDEF 465,
GPRS 549

  420 483
PhoneGap 558

  420   HTTPS   
 
uPnP 468
#   API  
 SMS
; 
    307 Twilio 546
 
   
 -
# 
 416 9  

  582
 142
#  252 #

Bluetooth LE  noble 330
  142
#"  #

HTTP/HTTPS 
-
    304
NDEF 463    488
   305

   360 #

webSocket   
;
  
38
#"  Express 274
IRF520 36
%
 "  146 #

  
TIP120 36
#


   497
;
  410
Arduino IDE 1.8.2 62, 67 #

 

   TwiML
;

84
Processing 39 548
;

 409
#
  #

+X# 405
7 
 69 #

, 
 "  -
7 

 71     
N

      IP-
 500 X3 64, 134
   174 #

    528 $ 134
# 
 #

     X 
  421
IEEE 143 node.js, 
 " - X   431
IEEE 802.3 143 
    535 X   

 42
IEEE 802.11 144 X
  GPIO 482 OpenSSH 44
IEEE 802.15.1 144 '  %
  PuTTY 44, 45
LTE 549 "  NDEF 466, 486    
 42, 43
Предметный указатель 607
X     connectToServer() 225, 267, 282 WiFi.macAddress() 209

  Tor 499 .c_str() 222 WiFi.scanNetworks() 209
X 
   
 digitalPinToInterrupt() 267 WiFi.status() 226

 
 64 find() 208 
" 267
X
      "   findUntil() 208, 226 
 

  267
   Hue 477 fs.readFileSync() 417

 152 .get() 158 
X
"    - getCurrentPosition(), 414
  230 httpGet() 333 ~ 143
X
  
     http.request() 233 Z 

  404 http.stop() 226


 419
X
  IRPulse() 299
  OSI 93 JSON.parse() 232 ˆ
Ethernet 150 JSON.stringify() 232
IP 150 keyReleased() 256 Z
  150 map() 117 for-next 41, 42

 
 150 movieEvent() 269 Z

X 
   421 newClient() 277  
 

 72
X   onReceive() 316  423
  parseFloat() 208 ' 
   
-
libfreefare 461 parseInt() 208, 226 

311
libnfc 461 parseMessage() 281 '  "  115
 355 parsePacket() 358
.post() 158 H
printWiFiStatus() 243
\ Processing   
  
  -
[  Capture.list() 188  113, 114
package.json 195 loadStrings() 183  66

 59 readButtons() 266, 282 
 "  " 
[  readBytesUntil() 208 146


%  46 readEncoder() 266 
 " 
  47 readMessage() 255, 278, 280 
148
[ 356 readMessages() 256 
 -  
[
 readString() 208 (+7) 217
IP-
 144 readStringUntil() 208 
MAC-
 144 request.end() 233 SMS 511
NDEF 463 response.on(‘end’) 233     514
  scanNetwork() 208 
 451
CSV 229 scrub() 269 
452
TSV 229 sendIntro() 279  QR 452
[
  sendJsonMessage() 283 

  36, 38
  426 serverEvent() 256

  426 setLeds() 226
[       setMeter() 226
{
307 shutterClick() 298 / 
  
[  stop() 207
 " PHP 162
.addAttribute() 325 String() 222  163
available() 358 tcpSocket.connected() 265 /  
broadcast() 278 toCharArray() 222  
  TwiML 540
compare() 354 watchPosition() 414 /
.connect() 267 WiFi.begin() 211 X3 134
connect() 207 WiFiClient.Connected() 226 /      
 -
connected() 207 WiFi.encryptionType() 209    408
608 Предметный указатель

Ž H P
` 
  HTML5 54 PhoneGap 558
TwiML 538 HTTP PHP
`  


   153
 $ 
   162
   53 
 Processing 39, 40, 41
`  


    156   42
CSS 54  157  
JavaScript 50, 54 
 153 draw() 41
   53 setup() 41
`      305 I 
 41
`"   249  41
IP-
143, 144    41
   144   


A 
%

 145 if-then 41
ASCII 110   145 

   144 for-next 41

 144
B IP-    510
Bluetooth 89, 121 R
Smart J Raspbian 77

 LE. &. Bluetooth       78

 LE 123 JitterBox 136
  raspi-config 78
  
BlueMan 123 
    78

 L RFID 441
Serial Port 123 localhost 148   457
Bluetooth LE
   456
 
323
 

 323
M 

Mifare Classic 460
MAC-
144
Mifare Ultralight 460
   144
C 
 144
RS-232 97, 98
Chip Select. # SS MISO 129
CS. &. SS MOSI 129 S
MQTT
SCK 
 . &.  
D 


Sideloading 558
Mosquitto 526
DHCP Slave Select. &. SS

 150 SMS
DNS
N
 544

 150 NDEF % 511


150   463 SS 129
 463
E "  463 T
NFC   
Ethernet SCL3711 460 TCP
  36  
   PN532 468 
 150

G O U
UDP
GPS 395 OpenSSH 44

 150
Unicode 110

Вам также может понравиться