Текст
                    

Том Иго УМНЫЕ ВЕЩИ Arduino, датчики и сети для связи устройств 3-е издание Санкт-Петербург «БХВ-Петербург» 2019
УДК 004.4 ББК 32.973.26 И26 И26 Иго Т. Умные вещи: Arduino, датчики и сети для связи устройств: Пер. с англ. — 3-е изд. — СПб.: БХВ-Петербург, 2019. — 608 с.: ил. — (Электроника) ISBN 978-5-9775-3970-8 Рассмотрен 31 проект на основе микроконтроллерной платы Arduino, в которых показано, как сделать, чтобы электронные устройства могли обмениваться между собой данными и реагировать на команды. Показано, как изменить настройки домашнего кондиционера, «позвонив ему» со своего смартфона; как создавать собственные игровые и видеоконтроллеры, взаимодействующие по сети; как использовать устройства Wi-Fi, Bluetooth, LoRa и инфракрасное излучение для получения информации от датчиков и организации взаимодействия объектов. Рассмотрена работа с четырьмя программными платформами и библиотеками с открытым исходным кодом: Arduino IDE 1.8, Processing, node.js и p5.js. В третьем издании добавлены новые проекты, описано использование в проектах не только Arduino Uno, но и Arduino 101, Arduino MKR1000, ESP32, ESP8266 и Raspberry Pi, а также уделено внимание вопросам безопасности. Для интересующихся современной электроникой УДК 004.4 ББК 32.973.26 Группа подготовки издания: Руководитель проекта Зав. редакцией Компьютерная верстка Оформление обложки Игорь Шишигин Екатерина Сависте Людмилы Гауль Карины Соловьевой © 2019 BHV Authorized russian translation of the English edition of Making Things Talk, 3rd Edition, ISBN 978-1-68045-215-0 © 2017 Maker Media, Inc. This translation is published and sold by permission of O'Reilly Media, Inc., which owns or controls all rights to publish and sell the same. Авторизованный русский перевод английской редакции книги Making Things Talk, 3rd Edition, ISBN 978-1-68045-215-0 © 2017 Maker Media, Inc. Перевод опубликован и продается с разрешения O'Reilly Media, Inc., собственника всех прав на публикацию и продажу издания. «БХВ-Петербург», 191036, Санкт-Петербург, Гончарная ул., 20. ISBN 978-1-68045-215-0 (англ.) ISBN 978-5-9775-3970-8 (рус.) © 2017 Maker Media, Inc. © Перевод на русский язык, оформление, ООО «БХВ-Петербург», ООО «БХВ», 2019
Посвящается Френку Иго, который раскрыл для меня потенциал компьютеров, и Реду Бернсу (Red Burns), который показал мне, как заставить этот потенциал приносить пользу людям
ОГЛАВЛЕНИЕ Предисловие ............................................................................................................. 11 Для кого предназначена эта книга? ..................................................................................................................................12 Что вам нужно знать? ...............................................................................................................................................................13 Содержание книги ....................................................................................................................................................................14 Приобретение деталей и компонентов...........................................................................................................................15 Использование примеров кода ..........................................................................................................................................16 Использование примеров схем ..........................................................................................................................................16 Примечания ко второму изданию .....................................................................................................................................17 Примечания к третьему изданию ......................................................................................................................................18 Благодарности ............................................................................................................................................................................20 Глава 1. Средства ......................................................................................................27 Все начинается с прикосновения.......................................................................................................................................28 Несколько слов об импульсах .............................................................................................................................................29 Компьютеры всех видов и размеров ................................................................................................................................30 Обзаведитесь хорошими привычками ............................................................................................................................31 Инструментарий.........................................................................................................................................................................33 Создаем первые программы для микроконтроллера..............................................................................................67 Одноплатные компьютеры ..........................................................................................................................................75 Как выбрать правильную плату? ........................................................................................................................................81 Работа с осциллографом ........................................................................................................................................................84 Прикосновением все и завершается ................................................................................................................................86 Глава 2. Простейшая сеть .......................................................................................89 Компоненты для проектов этой главы.............................................................................................................................90 Уровни согласования ...............................................................................................................................................................93 Устанавливаем соединение: нижние уровни ...............................................................................................................95 Отправка сообщений: уровень приложений ........................................................................................................... 101 Проект 1. Управление яркостью трехцветного светодиода с клавиатуры ........................................ 101 Усложняем задачу................................................................................................................................................................... 105 Проект 2. Мартышкин пинг-понг (Monski Pong) ............................................................................................. 105 Управление потоком данных ............................................................................................................................................ 120 Проект 3. Беспроводной мартышкин пинг-понг ............................................................................................ 121 Проект 4. Arduino-совместимая плата своими руками ............................................................................... 127 Заключение ............................................................................................................................................................................... 136 Глава 3. Более сложная сеть ................................................................................139 Компоненты для проекта этой главы ............................................................................................................................ 140 Сетевые топологии и сетевые адреса ........................................................................................................................... 141 Клиенты, серверы и протоколы управления связью ............................................................................................. 151 Проект 5. Сетевой кот ................................................................................................................................................. 167 Заключение ............................................................................................................................................................................... 198
8 Оглавление Глава 4. «Глянь, мама, здесь нет компьютера!» Микроконтроллеры в Интернете.........................................................201 Компоненты для проектов этой главы.......................................................................................................................... 202 Введение в сетевые модули ............................................................................................................................................... 203 Проект 6. Привет, Интернет!..................................................................................................................................... 206 Приложение встроенного сетевого клиента ............................................................................................................. 216 Проект 7. Сетевой измеритель качества воздуха .......................................................................................... 216 Форматы данных ..................................................................................................................................................................... 229 Принцип REST и интерфейсы API для Сети ................................................................................................................. 233 Инструменты для программирования и диагностирования встроенных модулей ................................ 239 Заключение ............................................................................................................................................................................... 247 Глава 5. Связь в режиме реального (почти) времени.....................................249 Компоненты для проектов этой главы.......................................................................................................................... 250 Интерактивные системы и цепи обратной связи .................................................................................................... 251 Протокол TCP: сокеты и сеансы ........................................................................................................................................ 252 Проект 8. Управление воспроизведением видео на основе сокетов TCP .......................................... 254 Клиент пульта управления ................................................................................................................................................. 257 Проект 9. Управление воспроизведением видео на основе протокола WebSocket ..................... 272 Сервер и клиент браузера.................................................................................................................................................. 274 Клиент пульта управления WebSocket .......................................................................................................................... 281 Заключение ............................................................................................................................................................................... 284 Глава 6. Беспроводная связь ...............................................................................287 Компоненты для проектов этой главы.......................................................................................................................... 288 Почему не вся связь беспроводная? ............................................................................................................................. 290 Два типа беспроводной связи: инфракрасная и радио ...............................................................................................292 Проект 10. Инфракрасное управление цифровой фотокамерой........................................................... 295 Принцип работы радио ....................................................................................................................................................... 300 Радиосети ................................................................................................................................................................................... 304 Выбор и приобретение радиоустройств ..................................................................................................................... 306 Проект 11. Дуплексная радиосвязь ...................................................................................................................... 310 Проект 12. Управление фотокамерой с помощью Bluetooth LE .............................................................. 319 Заключение ............................................................................................................................................................................... 334 Глава 7. Бессеансовые сети и двоичные протоколы .......................................337 Компоненты для проектов этой главы.......................................................................................................................... 338 Сеансы или сообщения? ...................................................................................................................................................... 341 Широковещательные сообщения или направленные? ........................................................................................ 342 Проект 13. Сетевые светильники ........................................................................................................................... 347 XBee: еще один протокол на основе сообщений ..................................................................................................... 362 Проект 14. Предупреждение о наличии в мастерской токсичных испарений ................................ 367 Заключение ............................................................................................................................................................................... 384
Оглавление Глава 8. Как узнать местонахождение (почти) чего угодно?.........................387 Компоненты для проектов этой главы.......................................................................................................................... 388 Сетевое местонахождение и физическое .................................................................................................................. 391 Определение расстояния ................................................................................................................................................... 396 Проект 15. Инфракрасный дальномер................................................................................................................ 397 Проект 16. Ультразвуковой дальномер .............................................................................................................. 400 Проект 17. Определение уровня принимаемого сигнала ......................................................................... 404 Определение местонахождения методом трилатерации ....................................................................................................409 Проект 18. Геолокационные службы и протокол NMEA.............................................................................. 410 Определение направления и положения в пространстве .....................................................................................................420 Проект 19. Определение направления с помощью цифрового компаса ........................................... 423 Проект 20. Определение положения в пространстве ................................................................................. 426 Заключение ............................................................................................................................................................................... 435 Глава 9. Идентификация .......................................................................................437 Компоненты для проектов этой главы.......................................................................................................................... 438 Физическая идентификация .............................................................................................................................................. 441 Проект 21. Распознавание цветов с помощью веб-камеры ...................................................................... 444 Проект 22. Обнаружение лиц с помощью веб-камеры ............................................................................... 449 Проект 23. Распознавание двумерных штрихкодов с помощью веб-камеры .................................. 453 Радиочастотная идентификация (RFID) и ближняя бесконтактная связь (NFC) ......................................... 456 Проект 24. Чтение меток RFID ................................................................................................................................. 460 Проект 25. Чтение и запись сообщений NDEF ................................................................................................. 464 Проект 26. NFC и бытовая автоматизация ......................................................................................................... 467 Безопасность устройств сетевой связи........................................................................................................................ 477 Проект 27. Двухфакторная идентификация с использованием NFC ..................................................... 478 Сетевая идентификация ...................................................................................................................................................... 497 Проект 28. Геолокация по IP-адресу ..................................................................................................................... 499 Заключение ............................................................................................................................................................................... 504 Глава 10. Сети мобильной телефонной связи и физический мир................507 Компоненты для проектов этой главы.......................................................................................................................... 508 Одна большая сеть ................................................................................................................................................................. 510 Проект 29. Возвращение сетевого кота .............................................................................................................. 514 Проект 30. Звоним термостату................................................................................................................................ 537 Интерфейсы на основе текстовых сообщений ......................................................................................................... 544 Микроконтроллеры в мобильных телефонных сетях ........................................................................................... 548 Приложения для операционных систем мобильных телефонов ..................................................................... 558 Проект 31. Мобильный регистратор личных биометрических данных .............................................. 566 Заключение ............................................................................................................................................................................... 584 Приложение. Где брать компоненты и прочее? ..............................................587 Компоненты............................................................................................................................................................................... 588 Поставщики аппаратных компонентов ........................................................................................................................ 592 Программное обеспечение ............................................................................................................................................... 597 Предметный указатель .........................................................................................601 9

ПРЕДИСЛОВИЕ Несколько лет тому назад Нил Гершенфельд (Neil Gershenfeld) написал толковую книгу, названную им «Когда вещи начинают думать». В ней он рассматривает мир, в котором обыденные вещи и устройства наделены вычислительными способностями, то есть мир сегодняшний. В частности, там обсуждаются последствия обмена между такими устройствами информацией о наших с вами личностях, возможностях и действиях. Книга хорошая, но ее название, на мой взгляд, — неудачное. Я бы назвал ту книгу «Когда вещи начинают общаться», поскольку — давайте признаем это — даже самые захватывающие идеи чего-либо стоят лишь тогда, когда их обсуждаешь с кем-то другим. И моя книга, подзаголовком которой мог бы стать девиз «Пусть вещи общаются!», — рассказывает, как создавать вещи, способные общаться друг с другом, и как предоставить людям возможность использовать эти вещи для общения между собой.
Предисловие 12                                         ,                  .      ,          ,          —  ,        .              — ,  "  .                     .           ,       —      ,            "      (  ,      "      ). # ,        ,     ,    , —    ,              .       $ ,        "       %          . &          $     :  ,   ,   ,  ,    (    )  %  . . '      $       ,                 ,              "     ,         "  % . *     . +         $             .    ,              ,         . /        -       1. 0                  ,           , —           ,     ,    $      %        . &          ,    ,       " . /             ,       ,   "   " . 1 &    : «object-oriented hardware». Для кого предназначена эта книга? Эта книга писалась для тех, кто хочет наделить вещи способностью взаимодействовать друг с другом. Например, для преподавателя естественных наук, который намерен показать своим ученикам, как отслеживать погодные условия одновременно в нескольких местах школьного округа. Или для скульптора, желающего заполнить помещение скоординированно движущимися механическими скульптурами. Или для дизайнера, которому необходимо быстро создавать макеты новых продуктов, моделируя как их форму, так и функции. Или же для хозяина кота, который любит наблюдать за своим питомцем, даже когда находится вне дома. В общем, книга предназначена стать начальным пособием для людей, обладающих ограниченным техническим опытом, но имеющих большой заряд энтузиазма и желающих успешно воплощать в жизнь интересующие их проекты. 0      ,       "       ,       ,      ,  -       —  %   ,        "          . 2                       %         "       ,          . #    ,             ,    
Предисловие  "  "    %. +  $                       (            )           %        ,                   . 3  ,  "        ,    %      $             "     ,   "          ,           . 4     -,   ,   BASIC Stamp2  LEGO Mindstorms3,   ,  % 2 7    %            BASIC (PBASIC),      ROM. 3    (         $    )          ( . http://ru.wikipedia.org/wili/LEGO_Mindstorm). 13                  ,         $      , $       . 0                      - ,    "                  . &  ,     ,                ,  $    ,  ,    ,  "  . &          Bluetooth    TCP/IP,                Ethernet. 9                      ,     . 0     "      -        ,       %          . ;       ,           —    "    "     —         . Что вам нужно знать? Чтобы извлечь для себя как можно больше пользы из этой книги, вам необходимы базовые знания аппаратной и программной части микроконтроллеров, определенное представление об Интернете и доступ к тому и другому. 7     ,          ,           ,    $                                   . ;                 $              ,      . 4         -        — $     .                     ,    ,      %     ,          . &           ,       ,               . 4             ,    ,          ,       $        . +          "   «Physical Computing: Sensing
Предисловие 14 and Controlling the Physical World»4 (  Thomson),       =  0’#  (Dan O’Sullivan). &          $   ,               . +   -     $        "       ,      "      -    . &               7  >  (Massimo Banzi) «Getting Started With Arduino»    Make.   $,             . 4      4  $,             ,          ,                 - ,         .    $  ,               Processing,               : www.processing.org. ;           "        . #       Processing      ,          ,    % $   ,           " ,    "       .                . /       , ,     ,        , "                 ,       . Содержание книги В книге представлены основные принципы создания объектов сетевой структуры, а также приводятся примеры, их иллюстрирующие. Каждая глава содержит инструкции по созданию работающих проектов, основанных на изложенных в ней концепциях. ?  1. 2             ,      ,         «Hello World!» («2   ,  !»)   .     ?  2.              ,              "     . 2         ,         ,    ,      $               . &       ,         ,                                            Bluetooth. #         ,            . •  3.              — +  . 2       ,      ,         $    . 9    " ,  "                 ,           +   ,            "  . 0                +            . ?  4. 2             ,  # .          #  "       ,                       .        , -
Предисловие ? ? ? 15  5. # " %       #  —         ,         . 2   %      ,            ,  "     # .    $     "            ,        , —  ,                       . ?  8. 2                            ( ),                          . ?  6.              . 0           ,         . 2      %   , "   $  «Hello World!» («2   ,  !»)     .  9. 2                     . +                             . *                       . ?  7. 2          , "   "       ,         5. /         "    —     UDP ( +  )  802.15.4 (      ). &      -  ,   "   "  ,  -  10. 2               ,       "       (   )       . &                        ,      ,           +       .   $                      —    "   . Приобретение деталей и компонентов Для реализации проектов, описанных в книге, потребуется много деталей и компонентов, вследствие чего вам придется познакомиться с их поставщиками. Поскольку в моем городе нет больших розничных центров продажи деталей электроники, я покупаю все мне нужное через Интернет. Если вам повезло, и у вас есть возможность покупать необходимые детали в обычном магазине, тем лучше для вас. В противном случае познакомьтесь со следующими интернетпоставщиками: Jameco (http://jameco.com), Digi-Key (www. digikey.com)  Farnell (www.farnell.com) — $    "   $  ,  "            . 3   ",  SparkFun (www.sparkfun.com), Adafruit (www. adafruit.com)  Seeed Studio (www.seeedstudio. com),       ,                 .    "      . 4     -  ,     %   ,    $      .
Предисловие 16 X ,       +            ,         "              -  . ;            $     . 0    ,        -             ,         -                 %   . #  ,             %      "      ,     . Использование примеров кода Эта книга предназначена для того, чтобы помочь вам реализовать свои проекты. Соответственно, код из нее можно использовать в своих программах и документации без необходимости запрашивать какое-либо разрешение, если только речь не идет о коммерческом воспроизведении значительного объема кода. *  ,          $         %    ,             CD-ROM          OYReilly  %     . Z      $  ,  ,  %    ,                         % . 7                      $  . [      -    ,   ,    ISBN  . *  : «Making Things Talk: Practical Methods for Connecting Physical Objects, by Tom Igoe. Copyright 2011 Maker Media, 978-144939243-7»5. 4      ,                               %  ,      $   $        permissions@oreilly.com. 5 &    "    $                   . Использование примеров схем Для сборки проектов из этой книги вам придется разбирать или даже ломать те или иные устройства и нарушать условия их гарантии. Если вам это не по душе, закройте книгу и займитесь чемлибо другим. Эта книга не для тех, кто дрожит от мысли, что если они разберут вещь, то не смогут собрать ее обратно. &  ,               ,                               .                 —                      . 0       ,                            . *      ,         $               . ;    ,     "  ,     , $            ,    , 
Предисловие $               ,  $      . 4         17     - " ,    ,         $       . Примечания ко второму изданию Две новые тенденции побудили меня переписать эту книгу: развитие движения за открытое (open source) оборудование и рост культуры прямого участия, в том числе и в деле создания интерактивных устройств. Это хорошо видно на примере быстрого увеличения круга пользователей Arduino в частности и числа участников движения за открытое оборудование в целом. Последствия этих тенденций все еще в процессе оценки, но одно ясно — объектно-ориентированное оборудование и использование компьютерной техники для взаимодействия с реальной физической средой становятся повседневной реальностью. В настоящее время электроникой занимается намного больше людей, чем я мог бы вообразить в 2005 году.                "   ,           "    . _                    -       ,  $            . = 2005         ,   ,            ,         «     ». &  "      ,   ,     Wii  Kinect — $    ,   %         ,        . #         $       , %       # .    %    $       %    ,   "   " ,  $    %                  . _           Kinect   ,          , "          . 0           Wii,                . _     ,              $       ,    $.         Arduino,    ,  Arduino     -           ,     $          ,                  ,         . ` ,   %      $            ,           Arduino                 . /     "              , %,             ,               . '   ,         $      ,       ,     $   ,   $          .       %     Arduino     ,                                      , —         "     %   . 0                         , $         
Предисловие 18     ,  "    $            . &   ,  "         %  ,    ,       "   . # %       %      ,     «    "». ;     ,           -                ,    $     ,    ,           ,     . > ,    $  %     ,                 %    . `   ,  $                     . Примечания к третьему изданию Переписать эту книгу в предыдущий раз меня побудили две обнадеживающие тогда тенденции: развитие движения за открытое (open source) оборудование и рост культуры прямого участия, в том числе и в деле создания интерактивных устройств. Тенденции, которые толкнули меня переписать книгу в третий раз, не столь оптимистичные: распространение бытовых устройств, которые собирают данные обо всех физических аспектах нашей жизни, а также постепенное сокрытие информации о том, куда в конечном итоге эти данные попадают и для чего используются. Такие устройства предлагаются на рынке под ширмой продуктов и услуг, обеспечивающих нам простоту и удобство их использования. Указанные тенденции и их последствия требуют внимательного рассмотрения. Понимание технологий, лежащих в основе этих тенденций, поможет нам принимать обоснованные решения о том, какую роль им следует играть в нашей жизни. &  ,         $   ,     (     %     ),    +    " . + ,  "    $  ,      ,                $  . q ,     «+    " »       1999     3%  (Kevin Ashton),       Auto-ID 7         . &     «That “Internet of Thins” Thing»6 (www.rfidjournal.com/articles/view?4986)  "      ,  %          +           . =    ,         "  ,             $  . 0   ,    $  «                ,      ,          !   . 6 '        “+    " ”».  : «'  % $ " !   RFID    !    ##       ,       !       #   !   , #   ,   ». 0      ,   ,           %       ,  %  % ,   ,          ,         ,         . +   ,  3%           % ,   ,        ,  $       .   +               %     ,    ,  % —  " ,  ,          %    , —            %  %           .
Предисловие 19 /    ,       ,     ,     ,     ,         %  %      $  .   ,          "         ,   $   %   %  . 7    Nest   ,        ,       ,          "   Hue        "  ,    "   ,           "  Alexa     ,       %. 7  ,      $ ,    «      ». * «» — $       ,     . ' ,  $  %   ,    " ,            % . ` ,            $  % ,    %  ,   $      ,             . ` ,    ,    $         %     ,      $    ,    $    .  $          %      « »           . +   (&    ,     # )                  ,     IP7  HTTP8. &        $   ,       « »  , "  . 2  ,  % %          $  , +           ,     7 Internet Protocol —      +  . Hypertext Transfer [Transport] Protocol —        . 8 -      . #  2016  —      Mirai               —   ,  +   %    ,          . *         ,              %     ,            . &  "    ,     +  ,                    ,  "        . ~      #       $  ,          "     . '    +         ",  $              ,                  ,    ,  . =          %   %       ,  %              . ~            ,   ,         $   ,         "        . 3%  : «$     #   !  ,   ». /   %    ,    %      %   ,   # . О программном обеспечении #                      "     . *   ,             ,       . =  —   Arduino  Processing —     ,    "          ". &  ,     
Предисловие 20       -      ,      -        / %   . +             " gitHub    https://github.com/ tigoe/MakingThingsTalk2        . + "           www.makingthingstalk.com. Об используемом оборудовании '                   ,           -    $       Arduino 101  MKR1000. >%                 Arduino Uno,               . =        %      ,   Arduino,                  ARM Cortex-M0  ESP8266.                       Linux. = $          Raspberry Pi,  %               BeagleBone. Благодарности Эта книга является продуктом обсуждения и сотрудничества со многими людьми. Ее создание было бы невозможным без поддержки и ободрения со стороны круга моих соратников, который продолжает увеличиваться. `  %                      9      Tisch10 *-       —   ,             %   "        . +            «#     »,           . `   ,          $                   . 0     9  >€  (Red Burns)            $  . 0        ,      , %    "          . 0          ,       ,            ,  9 10 &    : «Interactive Telecommunications Program». &    : «Tisch School of the Arts».  ,  "        . 7   = 0Y# ,       ,          ,     %   %        $                     . 0          ,             . >%   $           = . +              ,     % . *      $        %   "  -          ,      . &    , 7     (Marianne Petit), $   (Clay Shirky), =$ $ 9
Предисловие (Daniel Rozin), =  (Dan Shiffman),  &$ /  (Shawn Van Every), >      (Benedetta Piantella), 7  (Mimi Yin), /  $ % (Allison Parrish), q   > - (Gabriel Barcia-Colombo), _ = (Luke Dubois),   = (Katherine Dillon), *$  ~$  (Nancy Hechinger), 7   2  (Marina Zurkow), † -7  q (Jean-Marc Gauthier), =  3 (George Agudow), /  q  (Edward Gordon), 7  `  (Midori Yasuda), /  9  (Eric Rosenthal), 7  =   (Megan Demarest), *$  _ (Nancy Lewis), 9  9 (Robert Ryan), = =$ (John Duane), > _  (Ben Light), 7  / (Marlon Evans), ;  Z  (Tony Tseng), >    (Brian Kim), q  #  (Gloria Sed), 7$ >  (Matthew Berger),  -3 ' (Yen-An Chen), 3 3 % (Ahmad Arshad), =  = = (Dante DelGiacco)  3  q (Anna Gallagher)                                  ,          ,     . 7        -     ,               $   . #         % : =  3 (Jamie Allen), 7  > (Mustafa Bagdatli), 7$ >   (Matthew Belanger), + >  (Ithai Benjamin), =$  >  (David Boyhan), $  >  (Caroline Brown),     #  (Christian Cerrito), =    (Dennis Crowley), =  (Jody Culkin), = = (John Dimatos),   = (Patrick Dwyer), 2 +  (Zach Eveland), 9  [ (Robert Faludi), =  [ (Doria Fan), = [  (John Farrell),  [  (Xiaoyang Feng), =  [  (Jeff Feddersen),#[  (Scott Fitzgerald), ; q   (Thomas Gerhardt), q   q (Gabriela Gutierrez), 7  ~$  (Meredith Hasson),   ~   (Patrick 21 Hebron), _ % ~  (Liesje Hodgson), ; q  (Todd Holoubek), =   =  (Jeremiah Johnson),    (Craig Kapp),    (Peter Kerlin), $    (Kacie Kinzer), 9    (Raffi Krikorian), =  _ (Jihyun Lee), 9 7 (Rune Madsen), 3 7  (Adi Marom), 2  7 % (Zannah Marsh), #  7 (Surya Mattu),   7 (Carlyn Maw),   7 % (Corey Menscher), 3 $ *   (Ariel Nevarez), =$  * (David Nolen), 9  * (Rory Nugent), 7  0  (Michael Olson), 7$   (Matt Parker), =  9  (Dustyn Roberts), 7$ 9   (Matt Richardson),  9 (Paul Rothman), 7   # (Maria Paula Saba), =   (John Schimmel), 7     (Michael Schneider), q $  (Greg Shakar),     (Yining Shi), /  2 (Andy Sigler), $  # (Peiqi Su), =   # (Deqing Sun), =  ; (James Tu), ;  ; (Tymm Twillman),   &  (Karl Ward), 3   &   (Antonius Wiriadjaja), 9  (Rosalie Yu)  Z  ' (Jingwen Zhu). =      $                  ,          . $  9 (Casey Reas)  > [  (Ben Fry)            ,    Processing  "  Processing (processingfoundation. org).      p5.js,    _ 7  (Lauren McCarthy),         $   ,            "      . *                Arduino 7  >  (Massimo Banzi), =  7   (Gianluca Martino), =    (David Cuartielles)  = 7  (David Mellis),   /   >  (Hernando Barragan) —   Wiring  * 2  (Nicholas Zambetti),  %  $   . 7    $ ,              
Предисловие 22      , %       Arduino      . `         ",            . *   ,     ,        , — $ * 2  (Nathan Seidle)  Spark Fun, _ [  (Limor Fried)  [ ;  (Philip Torrone)  Adafruit, X   0 $ (Windell Oskay)  _  / (Lenore Edman)  Evil Mad Science Labs  /   (Eric Pan)  Seeeed Studio. >%            : =   (Don Coleman), #  7   (Sandeep Mistry)  3  3 (Alasdair Allan).                 $      "   ,                      %    . ;        %        Fritzing. /          $           -   www.fritzing.org — 9  &  (Reto Wettach), 3     (Andre Knorig)  =  $ (Jonathan Cohen)               . #  =  0  (Giorgio Olivero)  =  (Jody Culkin)    ,   $   . 7             ,         «+    »           11,     «Z  #7+    »          _ -3   12,     «+    »          0 ,  +        + 13   +          14. #  7  ~  (Mark Hansen)  7   % (Michael Krisch)  Z   >      #7+         15                $   . +       $             . `         $   ,           : ; 3  ;. * (Tuan Anh T. Nguyen), =    (Joo Youn Paek), =  [$ (Doria Fan), 7   7  (Mauricio Melo)  =   (Jason Kaufman). ;    (Tarikh Korula)  =% 9-_ (Josh Rooke-Ley) — «*      ». = - 7 (Jin-Yo Mok), 3  >  (Alex Beim), /      (Andrew Schneider), q _ (Gilad Lotan), 3    (Angela Pablo), 7  3   (Mouna Andraos), #  #  (Sonali Sridhar). ; = (Tim Dye)  Sonoma Technologies. q  > - (Gabriel Barcia-Colombo), $  ~  (Kate Hartman),  _  (Kati London)  # #     (Sai Sriskandarajah). [   _  (Frank Lantz)    # (Kevin Slavin) —     «;  /». #    (Sarah Johansson), >      (Benedetta Piantella)  =  = (Justin Downs)  Groundlab; 7  ~$  (Meredith Hasson), 3 $ *  (Ariel Nevarez)  *     (Nahana Schelling), ; 3  (Timo Arnall), /  #  7   (Elnar Sneve Martinussen), =   (Jrn Knutsen), 7  > (Mustafa Bagdatli), [  q  (Frances Gilbert)  and =  (Jake),    0  (Pedro Oliveira)  # ' (Xuedi Chen). 3  ' ,     ,    ;   (Tali Padan)     . 13 &    : «Interaction Design Institute Ivrea». &    : «Copenhagen Institute of Interaction Design». 15 &    : «Brown Center for Media Innovation at Columbia University». 14 11 12 &    : «Royal College of Arts». &    : «University of California in Los Angeles».
Предисловие #  = q  (Giana Gonzalez), Š   (Younghui Kim), =  7  (Jennifer Magnolfi), = - 7 (Jin-Yo Mok), 7$    (Matt Parker), /       (Andrew Schneider), q _  (Gilad Lotan), 3    (Angela Pablo), =   >  (James Barnett), 7   *$ (Morgan Noel),  _% 16   7  %         . #      ,  %           : 7    (Michael Shiloh), 7 ~  (Mikal Hart), 7  7   (Michael Margolis),  #   (Paul Stoffregen), 3   7Š  (Adrian McEwen), 3     >  (Alexander Brevig), 9  7  (Ryan Mulligan),    (Keith Casey), >    (Bonifaz Kaufmann), 3    q    (Andreas Goransson), ~  >  (Helena Bisby), 7  3  (Michael Adams),  =$ q   (Joel Gahwiler). 9  [ (Robert Faludi)          ,     «Digi International»      XBee and Digi. `           Lantronix: q  7   (Garry Morris), q$  7  (Gary Marrs)  =  /  $ (Jenny Eisenhauer). =  # (Geoff Smith),   ~  (Chris Heathcote), =  >% (Durrell Bishop), 7     (Mike Kuniavsky), ;   (Tod Kurt), >  ~  (Bjoern Hartmann), /   (Eric Paulos), &  † (Wendy Ju), _ /  ~  (Lars Erik Holmquist)        «Sketching in Hardware»    ,        ,      % " ,             . 16 &    : «Noodles».    ,    %           «0   3  »,    9   *    $  . 23 0     MAKE, =$  =  (Dale Dougherty),      ,           %         ,       -  . 9   >    =    (Brian Jepson)   = ~  (Patrick Di Justo)     $          . # [  (Scott Fitzgerald)          ,    "    "              . 3 *$    (Nancy Kotary),   X  (Katie Wilson)  ; _ (Lillis)           . >    ~ (Sherry Huss)    Maker Faire $         %      . & " ,        MAKE. ;       «# >». #     ,            ,   ,        ,   $  ,      ". =  ~$  (Denise Hand), > _  (Ben Light),   ;  (Clive Thompson), = ~  (Joe Hobaica), 7 X  (Max Whitney)  =  7  (Jennifer Magnolfi)   $     . #      ,       %                  . `       . * ,     , = ,         $         . `   ,         "    .
Предисловие 24 Мы хотим знать ваше мнение 4      -        $   ,          "   : Maker Media, Inc. 1700 Montgomery Street, Suite 240 San Francisco, CA 94111 #   ,                  -     : http://shop.oreilly.com/ product/0636920031369.do. 0                  $       : bookquestions@oreilly. com. «Maker Media» —       «OYReilly Media»,     "   % "   "       ,   ,   -    ,  $    . 0   "    «   »                . =        «Maker Media»     : http://makermedia.com.


Глава 1 СРЕДСТВА Эта книга представляет собой что-то вроде сборника кулинарных рецептов, и в ее первой главе я познакомлю вас с основными используемыми при готовке ингредиентами. Описанные здесь понятия и инструменты найдут применение во всех остальных главах книги. Для каждого инструмента дается достаточно информации, чтобы вы могли сказать «Здравствуй, мир!» с его помощью. Скорее всего, некоторые из рассматриваемых в этой главе инструментов или подобные им вам уже приходилось держать в руках. В таком случае вы можете спокойно пропускать знакомый вам материал и переходить к инструментам, с которыми вам еще не приходилось сталкиваться. Использование этих инструментов в проектах, представленных в следующих главах, демонстрирует для большинства из них лишь малую толику того, на что они способны, поэтому рекомендуется самостоятельно разобраться с менее знакомыми вам инструментами, чтобы получить более полное представление о том, что с их помощью можно сделать. Для этого в книге приводятся ссылки на материалы для дальнейшего самостоятельного изучения инструментов, которые вам не столь хорошо знакомы. Happy Feedback Machine1, созданная Туаном Анхом Т. Нгуеном (Tuan Anh T. Nguyen) 0     ,      $    ,   "       "   . 0   ,      $  , —   ,  %   ,    ",    "" ,      . 1 /             ».   : «7%      
Глава 1 28 Все начинается с прикосновения Все рассматриваемые в этой книге объекты — как осязаемые, так и неосязаемые — демонстрируют определенное поведение. Программные объекты отправляют и получают сообщения, хранят данные или делают и то, и другое. Физические объекты двигаются, светятся или издают звуки. Первый вопрос, который нужно задать об объекте, — что он делает? А следующий вопрос — как принудить объект делать то, что он должен делать? Или, иными словами, какой у этого объекта интерфейс? +           .     —  !    . / ,         : ,    ,    ,    %  .   ,       ,           . [                  . +                            .      % ,       ,  %  $  ,      ,         ,              . &            ,   $       ,     ,   %   ,         " . #   , -                 . # "       —    :   ,     ,     . &                  ,    —    " " . *%              ,            ,         .   ,            ,      , $      $     ,         ,     %      .             -                ,     . *           "   ,             . 7                 >... ;    —                        ,         ,          . /     %     . +  -              , %           $  ,     ,      "          . * ,     — %    ,   "   $    $ ,               "        . 4                 ,           $    . *       "   ,   ,       %    $       ,               .
Средства 29 Несколько слов об импульсах Для взаимодействия друг с другом объекты используют протоколы связи. Протокол — это набор взаимно согласованных правил для взаимодействия между двумя или несколькими объектами.       —   USB, MIDI       HID (Human Interface Device,         ) —             ,      ,  ,  %           . #     —   Ethernet      TCP/IP —                  (    ),   ( %  )   .              " ,      "         .             $                    .         -          ,                           —                . *    ,           , — $              ,           . ;       ,     % ,   "          ,    ,             ,   "    —          $   :             ,   $     (   )   "     . ;, " $     "     -   "         %  %  USB-     . =                 $     . =                                       ,                . 3           ,      "                "      .   $     ,     " $     ,      ,        , —                           -   ,     . X ,    "             (   -   ,  "       $  ),        %   %      .
Глава 1 30 Компьютеры всех видов и размеров В этой книге мы встретимся с несколькими разными типами компьютеров, сгруппированными по их физическим интерфейсам. Самый знакомый из них — это персональный компьютер. Будь это настольный компьютер или ноутбук, персональный компьютер имеет клавиатуру, экран и мышь, и вы, скорее всего, пользуетесь им каждый божий день. Эти три элемента — клавиатура, экран и мышь — составляют физический интерфейс персонального компьютера.              ,             , —     %   . ~   ,  "  %    %        ,       ,    "     %  :   "          %        ,             . +  $       "  ,  "                              ,     %  ,   "  %        . ;    ,      $   , —     , "      ,              . /   % $            ,            $      . &        "    "  %    : 1.          ,   "           :   ,     $         —  $    $ . 2.           ,         ,   " $    $       . 3. #           ,   ",           . 7               ,                . +  ,                      . &    ,               Arduino Uno,        Arduino      ,             $   . 2                 ,                  , —   , Raspberry Pi. ~   %     $          ,    ,      " ,                  .                   ,         ,       $   , —      . /,     ,       ,         ,     %. 9     ,         ,         ,          "        . _            . = $  %               .
Средства 31 >%               ,        ,               .   $       ,            %                . # "       *      — $  :      , ,       . .            ,    "         ,       ,  %            . ~                ,           . ; ,     $           ,        ,      ,     —           —       . Обзаведитесь хорошими привычками Взаимодействие сетевых объектов в чем-то схоже с личными отношениями: вы не знаете, о чем думает ваш партнер, — вы только слышите, что он говорит. Основная проблема и тех, и других заключается в том, что, посылая сигнал, мы никогда полностью не можем быть уверены, понимает ли получатель, что мы хотим этим сигналом сказать. Поскольку нам неизвестен внутренний процесс мышления получателей сигнала, мы никогда точно не знаем, как они истолковывают наше сообщение. Все что мы знаем — это как они реагируют на него. Кроме того, существует бесчисленное множество вариантов потери сигнала или искажения его значения при передаче. ;    ,      ,  "     %  ,      ,        ,    "  $ "          %   ,     . $,               (      %      ),        "      : ? %  % ,     ; ?    ,         %   ,   ; ?                 ; ?       " . Слушайте больше, чем говорите # %       %  — $    % %  . #% —     ,    . q       ,   ,       ,  %    % - ,       %.           %  $   ,         ,  %         " ,      "  % ,  $ . 0  "           ,    ,   ,  $               . 0     "      ,            . Никогда не предполагайте #%     % , ,     ,     . +     $          % ,      $      
Глава 1 32   . 4     ,  % "                 ,       $   ,      . *                   %,      " ,                  . #          ,     $  % .   ,             ,          % %. >%  %                     . &          ,      "   «2   ,  !»,               . =         $ "    —   ,              . *       "  —    %  ,     %. = %     $          ,     $         . +            %,  %          ,       ,             . `          ,    %      " ,      ,   "               " . *    ,           $      ,    %     .    ,          $   ,        ,    ,               . &         " ,                       . 3        ,             . Установите правила обмена информацией &  %    %      "  ,    "      . 7          ,  %              ,            " ,     ,        .                    "     ,       . +                  ,           " "   .     " "     ,           ,           " . 4                   ,                          ,    . *  ,  %    ,            -  ,             . *     ,                      ,              ,          . Попросите разъяснений    "                  . *  ,   % -    , ,    ,       %  ,    $  ,       ,  %             . $,   
Средства     %, %         . ;                  ,        " ,        %    . 0  "  ,         ,          ,   % ,   $  %. =   ,            ,    - . 7       %             ,      , ,   33       . ;             . *  ,                "    ,  ,      ,   ,   . $,        " ,   "   . *    $ %   ,     "             .        "      % ,      $                  . Инструментарий Учитывая, что в дальнейшем вы будете иметь дело с физическими, программными и электрическими интерфейсами объектов, вам потребуются «физические» инструменты, программное обеспечение и компьютерное оборудование. «Физические» инструменты О поставщиках деталей 4        $        ,   ,   ,          . *  . 1.1           ,              $  . ; —    —              " ( -     . 1.1). & $        "   . `        " —      ,                    . X  . 1.1  "          ,               ". *   $          . 0            " —                        . 4           ,        $  .      ,                $        . 0       . 1.1           "  ". 7   ,     "            , $                  ". &           ,           $  . ;,    ,              ".          "     $         .
Глава 1 34 8 10 7 9 6 18 11 16 1 34 3 15 5 4 13 19 33 31 25 32 2 27 29 30 12 24 28 14 17 20 26 21 22 23 Рис. 1.1. Инструменты и детали, используемые в проектах этой книги. Их краткое описание дается далее (обратите внимание: после указания поставщика приводится номер детали по его каталогу) 1. 2. 2  . = %           ,             Hakko FX-888D, Weller WLC-100    SP        $      %  . *              .            ,             $           .  ": Digi-key (www.digikey.com): 16911083-ND; Adafruit (www.adafruit.com): 1204; Farnell (www.farnell.com): 2320747. 3.     . +   ,        . Jameco: 2214889; Adafruit: 148; Farnell: 1792724. 4.          , ,  . *       «    »,            . /          ,   %     $     ,    $ . ?          : Jameco: 159291; Farnell: 609195; SparkFun (www. sparkfun.com): TOL-12630;  . _%       21.23 AWG2. 4     ,          ,       . Jameco (www.jameco.com): 2210116; Farnell: 419266. AWG, American Wire Gauge System —          (        ).    .  : http://ru.wikipedia.org/wiki/   _   _ . ?  : Jameco: 161411; Farnell: 3125397; SparkFun: TOL-10447; ? ! : Jameco: 217891; 3127199; SparkFun: TOL-08793. 5. Farnell: " -  .          —        . 0         . Jameco: 127271; Farnell: 4431212.
Средства 6. #$    . 9            ,              . SparkFun: SWG-11046; Farnell: 1696193. 7. «%   ». /                        . Jameco: 681002; Farnell: 1367049; SparkFun TOL-11784. 8. "  . *          . ~  ,         , ,     $     . Jameco: 220759; Farnell: 7430566; SparkFun: TOL-12966. 9.   &.            ,  DSO Nano    %  $100 —         . SparkFun: TOL-11702 (v2); Seeed Studio (www.seeedstudio.com): 109990013; Adafruit: 468. 10.      9–12 '. 0       . *        —         - $       . &             ,            -     . >%                   ,       %        2,1    %  — 5,5  ( .  11), $ %          "      . Jameco: 170245 (12 V, 1000 mA); Farnell: 1176248 (12 V, 1000 mA); SparkFun: TOL-00298. 35 Adafruit: 80; Digi-Key: 1568-1237-ND; Jameco: 2207056; Farnell: 1650675  1737256. 13. <  -    (LiPo)   . =        $            (    )   LiPo —               . 0      %    ,       ,                      3,7 &    800–2000 3. SparkFun: PRT-13813  PRT-08483; Adafruit: 258  2011. 14. USB-  . =    $      USB-    3- -B (    USB- ),    A- - -B (USB- ,         ). SparkFun: CAB-00512, CAB-13244; Farnell: 1838798, 2444222. 15. %   )   «   ». X                   — $        . Jameco: 10444; RS (www.rs-online.com): 161.6511; SparkFun: PRT-12978. 16.               ,   "     « ». Jameco: 135299; SparkFun: CAB-00501. 17.  = USB/TTL-Serial.      USB-      TTL. /                . SparkFun: DEV-14050  DEV-12935; Adafruit: 3309  284; SeeedStudio: 317990026. 18. "      . *  . 1.1       Arduino Uno, Arduino 101  Arduino MKR100. SparkFun: DEV13787; Digi-Key 1660-1003-ND  1659-1005-ND; RS: 913-9999  124-0657. ; . https://store. arduino.cc. 11. () (+  )          2,1    %  — 5,5 . /                           . 9           ,         ,       $   .     %              "    . SparkFun PRT-10288; Jameco: 159611; Digi-Key: CP-024A-ND; Farnell: 3648102. 19.      > . *  . 1.1       Raspberry Pi Zero W, Pi 3  BeagleBone Green. SparkFun DEV-13825; Adafruit: 3055  3400; Seeed Studio: 102010048  114990584 RS: 896-8660; Farnell: 2525225. ; . www.raspberrypi.org. 12. ()      «  ». /     ,            . SparkFun: PRT-09518; 20. (  A . 9                    , 
Глава 1 36              ,   "       . *              $  : 5 &  3,3 &. >            . 0           ,         . ? 3,3 &. Digi-Key: 497-1491.5-ND; Jameco: 242115; Farnell: 1703357; RS: 438-4885 ? 5 &. Digi-Key: LM7805CT-ND; Jameco: 51262; Farnell: 9756078; RS: 918-1971. 21. %    TIP120. ;            ,           "    %      . #"            ,      $          TIP120. 0     ,   % $           ,        ( . . 20). +  $                 , $,         ,             . Digi-Key: TIP120-ND; Jameco: 32993; Farnell: 9804005. 22. "-    IRF520. /           ,             TIP120      ,  $       . Jameco: 209226 Digi-Key: IRF520IRND; Farnell: 9103031. 23. C      . +        % . _         %     ,        « »       . Jameco: 20723 (2 %    ); Farnell: 4692810; Digi-Key: 438-1045-ND; SparkFun: PRT-12615  PRT-12002. 24. D        . =               ,                . 0                       . $             . Jameco: 333973; Farnell: 1208851; Digi-Key: 160-1144-ND. 25. (  . =     $           . *        . 1.1. 26. H  ). /        , $             ,     "     . *  %           % . Jameco: 103377; DigiKey: A26509-20-ND; Farnell: 1593411. 27.    (    ). #"                    . X                ,             . =             /   . ? !  . Jameco: 150551; Adafruit: 182 SparkFun: SEN-08606; ? !    . SparkFun: SEN09375; Adafruit: 166; Digi-Key: 1027-1001-ND. 28.   . =    $    %      :   —              (        Arduino  %       Wiring),                ,    —            ,      $             . *,     ,           . ? !      Digi-Key: SW400-ND; SparkFun: COM-00097;  = =. Jameco: 119011; ? !       =. Digi-Key: GH1344-ND; SparkFun COM-09181. 29.    .    (    )             . Jameco: 29082; SparkFun: COM09939; RS: 91A1A-B28-B15L; Farnell: 350072, RS 249-9294. 30.  Ethernet. ~   "       %             Wi-Fi,                 . DigiKey: N002-004-BK-ND; Farnell: 1526202.
Средства 37 31.    ,  ,   A . =            %           22 AWG. 2  ,     ,                ,   —  " . *                      . ? J  — Jameco: 36792. ? D  — Jameco: 36768. ? #  — Jameco: 36822. ?    — Jameco: 36856. ? K — Jameco: 36920. ? (   — Jameco: 2153705, SparkFun PRT-11375. 32. " A   A   . 3         ,            . +       , $          . Jameco: 20723, SparkFun: PRT-12796; RS: 791.6463; Adafruit: 759. 33.    . =     $            . *        . 1.1. 34. N     . &             %    $     , $                  . SparkFun: TOL-09316. Таблица 1.1. Перечень наиболее часто используемых в проектах книги электронных деталей и компонентов Код, полное имя и веб-сайт поставщика: D — Digi-Key, http://digikey.com F — Farnell, www.farnell.com J — Jameco, http://jameco.com SF — SparkFun, www.sparkfun.com RS — RS, www.rs-online.com Деталь (компонент), номинал Код поставщика и номер детали по его каталогу Резисторы 100  220  470  1K 10 K 22 K 100 K 1M D — 100QBK-ND, J — 690620, F — 9337660, RS — 755-0707 D — 220QBK-ND, J — 690700, F — 9339299, RS — 707-7612 D — 470QBK-ND, J — 690785, F — 9339531, RS — 707-8659 D — 1.0KQBK-ND, J — 690865, F — 9339051, RS — 707-8669 D — 10KQBK-ND, J — 691104, F — 9339060, RS — 707-7745 D — 22KQBK-ND, J — 691180, F — 9337814, RS — 739-7140 D — 100KQBK-ND, J — 691340, F — 9337695, RS — 707-8940 D — 1.0MQBK-ND, J — 691585, F — 9337709, RS — 131-700 Конденсаторы 0,1’F    1 ’F $    10 ’F $    100 ’F $    D — 399-4151.ND, J — 15270, F — 3322166, RS — 716-7135 D — P10312-ND, J — 94161, F — 8126933, RS — 475-9009 D — P11212-ND, J — 29891, F — 1144605, RS — 762-1736 D — P10269-ND, J — 158394, F — 1144642, RS — 762-1746 Регуляторы напряжения 3,3 & 5& D — 497-1491-5-ND, J — 242115, F — 1703357, RS — 438-4885 D — LM7805CT-ND, J — 51262, F — 9756078, RS — 918-1971
Глава 1 38 Таблица 1.1 (окончание) Деталь (компонент), номинал Код поставщика и номер детали по его каталогу Аналоговые датчики + =  D — 905-1000-ND, J — 150551, RS — 708-1277 D — 1027-1000-ND, J — 2128260 Светодиоды 5 ,   5 ,   ,    ,    D — 160-1144-ND, J — 34761, F — 1855510, RS — 228-5944 D — 160-1665-ND, J — 94511, F — 1855570, RS — 848-6480 Транзисторы 2N2222A TIP120 IRF520 D — P2N2222AGOS-ND, J — 38236, F — 1611371, RS — 295-028 D — TIP120-ND, J — 32993, F — 9804005, RS — 774-3653 D — IRF520IR-ND, J — 209226, F — 9103031, RS — 541.1180 Диоды 1N4004-R 3,3 &   (1N5226) D — 1N4004-E3/54GICT-ND, J — 35991, F — 9556109, RS — 628-9029 D — 1N5226B-TPCT-ND, J — 743488, F — 1700785, RS — 805-0110 Кнопки =   =     D — SW400-ND, J — 119011, F — 1555981 D — GH1344-ND, J — 2231822, F — 1634684, RS — 718-2213 Беспаечные макетные платы 9 D — 438-1045-ND, J — 20723, 20601, F — 4692810 Монтажный провод        D — C2117R-100-ND, J — 36856, F — 1662031 D — C2117B-100-ND, J — 36792, F — 1662027 J — 36768, F — 1662034 J — 36920, F — 1662032 Набор монтажных перемычек 9 J — 20723, SF — PRT-12796, F — 2396146, RS — 791-6463, AF — 759 Потенциометр 10 K D — 987-1649-ND, J — 29081, F — 1760793 Разъемы   %  D — A26509-20-ND, J — 103377, F — 1056427, SF — PRT-00116        D — S1121E-36-ND, F — 1056429, SF — PRT-00553 q    D — ED7102-ND, F — 1122344, SF — PRT-00115 Разъем для батареи «Крона» 9& D — 1568-1237-ND, J — 2207056, F — 1650675, SF — PRT-09518
Средства 39 Программные средства =                ,     $    ,                        . Среда Processing 0        ,             $   ,            ,    Processing. /             ,        -   www.processing.org. #  Processing       Java           ,                      . ;   , Processing —                 -    ,     "        :      ,     %             ,      —         %    Processing.  ,     ,  Processing     Java,     Processing          Java. #        macOS, Windows  Linux. #"      Processing  Android. 4    -         Processing,          $                           ,         . 2       Processing     ,       . 0     ,      . 1.2. ``Панель инструментов. Содержит элементы управления для запуска и остановки скетчей ``Окно редактирования. Сюда вводится код скетчей ``Панель консоли. Здесь выводятся предупреждения и сообщения об ошибках Пишем код ;      %       Processing. &        "   ,       Run (+  ) —             Processing. println(" , !"); Рис. 1.2. Окно редактора кода среды Processing
Глава 1 40 *     ,  $                 . +   $        : # ,  !            .  ,    .    Processing      (sketch),                      Processing   . &  ,                . 9  Processing          «  »,  "    .                          ,   " "   ,       $          Java.   ,     $            . Пишем код 9          ,                   Processing. Контекст использования кода &     $        ,  " ,         : Processing, Arduino, node.js  . . /*         : Processing                      */  .  . // "  : float redValue = 0; //     # float greenValue = 0; //    $ # float blueValue = 0; //      # //  setup()    $    : void setup() { size(320, 240); //   $      background(0); //    %     fill(0); // $ #  $  %   (0 =  ) smooth(); //    %       } // & draw()  ,    //   .   ,    ' // $      : void draw() { // +   $ $   , $ // ' - #: redValue = random(255); greenValue = random(255); blueValue = random(255);   // $ #   : stroke(redValue, greenValue, blueValue); //          // (       ): if (mousePressed == false) { //       triangle(mouseX, mouseY, width/2, height/2, pmouseX, pmouseY); }
Средства 41 //        else { background(0); fill(0); } } _    Processing           (   ): setup()  draw(). 7  setup()             ,       , —       ,         . . 3   draw() —        ,   "    ,       . =    Processing       . &            redValue, greenValue  blueValue — "   (float), . .        "  . =            ,        , $: ? int —    ? char —      ;     ASCII; ? boolean —   false (); ? string —   ; ? byte —  .  true (  )  `       Java,     ,        Processing 3    for-next          "     :            $ . =           New    File  Processing.     :                   . +  , $   ,        ,                .   $                  . *  ,      byte        ,  int —      . .   ,             $   ,       ,             , $                        .     Java  JavaScript,         Processing           #.     ,            (         void — . .    "         ). &          ,        . X    (if-then),    (for-next),            #. 2      for-next,  $                     . for (int myCounter = 0; myCounter <=10; myCounter++) { println(myCounter);
Глава 1 42 Пользователям BASIC и Python 4       for-next   #, $         -  % . &     ,       . & ,          , $            myCounter,                   ,  $         %    10. +   myCounter++              myCounter       . /    BASIC    "  : for myCounter = 0 to 10 Print myCounter next 3    Python $        : for myCounter in range (0, 10): print myCounter Processing —     $     ,               . 0                    Java   ". 4      Java,       Java         Processing. &   Processing     %  "       ,       +   .     $   $  9  >  [  ,         «Getting Started with Processing» (  O’Reilly). ;            " «Learning Processing» (   Morgan Kaufmann),    = $    (Daniel Shiffman).    Processing                        ,          $         —            . /       ,    $                ,      $          . 0    $      ,             $  ,          , "           . 4     %             , $          ,         . 7                   ,          -         . =            Processing        ,        -   www.processing.org. X  %        Processing       «Processing: A Programming Handbook for Visual Designers and Artists» (   MIT Press), - Интерфейсы командной строки и удаленные серверы *    $          "  " ,        "            
Средства  . 7                          ,   $     $       ,       $   ,  %    . +            %         ,         , $           "               . *                                UNIX,        ,  BSD, Linux, macOS    . 0     ,                 ,             POSIX3. &   "   $                            $  . Доступ к интерфейсу командной строки =                      $   . В macOS и Linux & macOS $        Terminal      Utilities  Applications. & Linux $           xterm, rxvt, Terminal  Konsole. В Windows +        Windows    DOS             ,              POSIX. *           Windows  ,   cmd 3  POSIX, Portable Operating System Interface —            . 43 Виртуальные частные серверы 7       $           -  ,          - . #   -            . +        - ,        "    -  ,   "           (&'#). X          -  ,           . &   -              -        ,    -                   -  ,                -       -        . #"     "    -  ,   "               "    —          -   %  . *  ,   "    -  ,  Digital Ocean (www.digitalocean.com), Amazon Web Services (aws.amazon.com), BlueHost (www. bluehost.com)  DreamHost (www.dreamhost.com),      &'#        . *   "                /  ,        $   . 4   %      "  -        -  ,                 . /      ,         "    -             -     " . *       -                            ,       ,    ,            -  ,      %   .   $       ,                          "    -   —     ,   . ; ,    $  ,        ".
Глава 1 44        .    $  ,   Microsoft              POSIX  Windows 10 (        : bash  Windows 10) —   "         ,       "" .         (   "            )   POSIX  Windows  ,       Cygwin (www.cygwin.com).     ,   $             Windows        Cygwin        . &      Cygwin                Net (    $   Packages   "),                ,  "  POSIX. Подключение к удаленному веб-хосту ~      ,  $                               :  Рис. 1.3. Главное окно программы PuTTY   - ,           . >%   "  -     Linux, BSD, Solaris    UNIX-       . =   Windows "          ,          PuTTY,          www.puttyssh.org.          —  -          " Windows          . *    macOS  Linux             OpenSSH,         $      . 2            Terminal "   ssh. В macOS и Linux 0        . 0                         " : Last login: Wed Feb 22 07:20:34 on ttyp1 ComputerName:~ username$ &    POSIX  $            .   $     "   , $   ,          . &   ,     $   ,            ,      $ . '                  : ssh _$@  , _-.com 9  ,       _$  _-.com       ( _$)    -   ( _-.com)    . &   ,         -  ,       .
Средства 45 В Windows 2     PuTTY (  . 1.3). &      -   ( _-.com)   Host Name,       Connection type    SSH     Open. 2        ,      "   %          .                  ssh. /     ,   %       %     "    . $          $ . Работа с командной строкой    –l     ls    list —        . &     $           : X      ,          -  "  : Last login: Wed Feb 22 08:50:04 2016 from 216.157.45.215 [userid@myhost ~]$ /   ,              ,           $    . =    ,     . = $     "  : long total 44 drwxr-xr-x 13 igoe users 4096 Apr 14 11:42 public_html drwxr-xr-x 3 igoe users 4096 Nov 25 2005 share /          ,  "    "   ,       : ? $ pwd          print working directory,      «     ». 0             "  . (7    POSIX     —       . #     ,        .) &            "   —     : /   /home/igoe /   (  )          . =              ls (list): $ ls -l. Точки в конце команды ;         « " »,    — «      "  ».    $     (   :     %     $  :   ,       ;    $   (13)         $           ;     $   (igoe)         ,      (users) —     ;   $   (4096)       ,   %  (Apr 14 11:42) —          ;  ,      $   (public_ html)       . drwxr-xr-x) ? ? ? ? &  POSIX    ,        ,  "     . /             — ,   ,            . '       ,       ,   ls        : -la: $ ls -la
Глава 1 46 =       : mkdir (make directory): $ mkdir directoryname /         "   .   ls –l,         ,   $            "  .           (      ) "   ls -la       : drwxr-xr-x 2 tqi6023 users 4096 Feb 17 10:19 . drwxr-xr-x 4 tqi6023 users 4096 Feb 17 10:19 ..     —       — $    ,    —      —      . ;         ,    . '  ,    rm (remove directory)    ,  "   : $ rmdir directoryname X      , $              —    ,    .   rmdir        ,           , $            . *                ,    . & %   -     -          % ,      html  pub   HTML lic_html, —   "    "   . 4   %   -    ,    "   mkdir: $ mkdir html =   "            cd (change directory) —   . *  ,         html  ,     "  : $ cd html '           %     ,       : $ cd .. =    %  (  )     cd       ~ (): $ cd ~ &    %    ,        cd      . =      $                  / ( $%). *  ,      html  %   ,        cd~/html. '          (     root —   ),              — /.                . Управление доступом к файлам &     ls –l,         "  ,      !     . *  ,    : drwx ------   ,        (d — directory),  %    (      )         (r — read),     (w — write),       (x — execute). 9       % : -rw-rw-rw
Средства 47 =      ,         ( ),       ,      (           $   ),      ,        ,               .   $     rw-    %   ,   —   ,    —     . &           %  "   chmod: $ chmod go-w _%     $       ,       ,      % . &          %     (-w)    (g — group)           (o — others),      . 3   "                        : $ chmod go+wx _%    ,        chmod  u      (user), g —   (group),  o —   (others). 7    ,   r     %     (read), w —   (write),  x —   (execute). 2  + ( )         %  ,    – (  ) — %  . >    ,    %  %    ( ).   ,                    ,    $   , —     "    -                —     . Создание, просмотр и удаление файлов =        "         : nano  less.    nano — $     ,        , $      %          " -  ,   ,  ,            . *  %          nano  . '  " nano   ,     "  :   $ nano _% .txt 0        (  . 1.4). Рис. 1.4. Окно текстового редактора nano. В нижней части окна имеется список доступных команд, которые исполняются по нажатию клавиши <Ctrl> совместно с клавишей буквы английского алфавита, указанной слева от соответствующей команды. Например, нажатие комбинации клавиш <Ctrl>+<K> выполняет операцию вырезания (kut) выделенного фрагмента текста
Глава 1 48 &      nano       % <Ctrl>. *  ,             % <Ctrl>+<X>. *               . X       rm (remove): "  - $ rm filename     rmdir,   rm             , $            . *   nano            %      ,          %   less. /             $    . =           less         $  ,        : $ less _% .txt &         $  ,  %       (:)    $  . * %       " $    . '  %     ,  % <q>. 0   ,          less  ,        —         —      «   ». =               cat, head  tail.   cat     $                : $ cat _% .txt 3   head  tail               , -    .                   ,  "     : $ head -5 _% .txt & $            _% .txt.      : $ tail -10 filename.txt    $            _% .txt.   cat, head  tail     ,             . /          "    . Объединение нескольких программ в одну 0      UNIX        «          ». +  ,              (           ,                  )         ,      %.   ,                       .                    ,                   . *  ,         ls   %    ,           $     "  . *      ls        less,           ,  ""   $  . =    $  "  : $ ls -la . | less
Средства &                 (|)            ,                       %  . &     $                     —   ,   . ;,             ,     "  : 49            -    . 7          $      .     , "            5. #         ,          help,            —     : man _  $ ls -la . >  _% .txt /        _% . txt            ls. 4        "  ,            ls. &     " "   ,          : $ ls -la . >>  _% .txt 0     ,          ,     ,  POSIX-              ,             . *  ,    $                — standard out,     stdout. 3               — standard in,  stdin. [        ,     "              "         (stdin)      (stdout). '          %          ,      logout. &      Linux  $     loguot       exit. * %          POSIX —   %   macOS, Linux     —                   %   ,             ssh. >%  $       Cygwin  %   Windows. +            ,      $  . =                        UNIX  Linux     ,   ,    3   * (Aaron Newcomb) «Linux for Makers» (   Maker Media).             ,          ,      . ;  ,   "               . ;    /     FIFO4:     —      . /          4 FIFO, First In, First Out —    % ,     % . 5 0  . command shell —   ,                 .
Глава 1 50 Платформа node.js >%       -    $          (  ) node.js, "               JavaScript.       JavaScript           -  ,             -   ,        HTML6. &                    -  . & 2009  9  = (Ryan Dahl)         Joyent %     JavaScript         ,           node.js. &    $      %               ,   %        . &      ,         node.js                  ,    $      7. /                     ,           .   node.js      -          %         +  . '          $  ,  %              . &   node.js "           Processing,              . 9 "     . 6 HTML, HyperText Markup Language —           . 7 2   $               ,               ,                 — PHP,      -   —   , Apache. 2       " node.js   https://nodejs.org/en/        . 2            ,        "    ,      : $ node –v &    $          "    " : v6.9.5 / "          node.js,       .      $         node.js 6.9.5, $       %           $       node.js. Установка набора средств разработки =       node.js                ,        "    . ;      ,                    8 (             ). =    Windows %  $                   Microsoft Visual Studio,   macOS —           XCode.   Visual Studio  ,   "        Community Edition. 2      ,    ,     : www.visualstudio.com/ downloads/.   XCode           Mac App Store.      $             XCode         . /   ,     "  : $ xcode-select --install                   node.js. 8 0  . toolchain. 
Средства 51 Пишем код +,   node.js     . 2      ,      " :         hello.js     . console.log("Hello world!");  2              ,          . 2         ,     : $ node hello.js &     $    $        "   : Hello world!       " ,  %      Processing9,  ? Веб-сервер на node.js   node.js               -  ,    " %         . &  — $   ,              ,       .    -   -        HTTP10. &    $          HTML,    ,     $    -  . *  , %    ,   "   ,            %   -   . #                      (. .   )   ,   " $  -   .   HTTP,                3,               node.js. 9   ,          node.js   , $    «2   ,  !»    . Пишем код #     %        simpleServer. 2        ,                    server. js   simpleServer. 9      ,    ,    "       node.js: 10  HTTP, Hypertext Transfer [Transport] Protocol —       .
Глава 1 52 1.    : // '    "   : var express = require('express'); // '    // express 2. 0       : var server = express(); // $ " server, // $     express 3. 0          : //  % # ',  $ //    $   : function respondToClient(request, response) { console.log("got a request"); //    //      //      : response.writeHead(200, {"Content-Type": "text/html"}); response.write("Hello, client!"); response.end(); } 4. +      //   : server.listen (8080); //  ,      $  : server.get('/*', respondToClient); console.log("Server is listening on port 8080");   : X        +  ,             simpleServer      : $ npm install express /       npm —       node (node package manager)      express.js,       . &                ,         ,    %       "       . ;       "  :    %          , $          . 0    -          : http://localhost:8080 &         ,      . 1.5.   $              "    " : Got a request! (   !)   %    8080) +       -               . +             -          ,          favicon — %                 -  .   $              ,  ,          hello.js,    - '  %       ,      % <Ctrl>+<C>. $ node server.js &     $         "   :  $  Server is listening on port 8080 (# 
Средства 53 Рис. 1.5. Результат исполнения программы сервера node.js в браузере Структура программ node.js #      node.js (            )  ,      Processing. 9    $  .    , JavaScript (,    , node.js)              . /   ,                —      "    var. 3 JavaScript                      . &  , JavaScript             . ;            ,    . &       ,     $       .         -      "   . &            (      %! )   node.js express,            express. [  $              http. &        express()   $     express,           server. = ,       ,    -    listen()   server,     %    8080          . ;  ,    JavaScript       . /   ,                    " ,    %    .                 ! ,       ,        -  .                         server.js —   server. get()          respondToClient(),                   . >             JavaScript,              ,      %     ,        . &   JavaScript            #  Java. &    ,   (  )      ,        . #       #             if-then      for.
Глава 1 54 #        :  node.js      1. # "   require()      . 2. 0    ,               (   ). 3. 0        ,           . 4. +        . HTML5 и веб-приложения #                  — HTML5 —                     . 0   %                            ,     "   $   . *  ,     HTML5        ,    ,          JavaScript          CSS3.     HTML5, JavaScript  CSS3  "? X ",   ,  HTML       "   , CSS —      ,  JavaScript —  ,             . `  HTML            $    :   , $   ,       . 0  "       ,      -    :   ,  ,    . ., —    HTML       "   DOM11.    CSS            $  :  , %  ,      $    . . 3   11 DOM, Document Object Model —       . &    $    server.js.       =            node.js        ,       -   www.nodejs.org. >             node.js         $ (Shelley Powers) «Learning Node: Moving to the ServerSide» (   O’Reilly). 3   /  >   (Ethan Brown) «Learning JavaScript» (   O’Reilly)         JavaScript.     JavaScript       $       ,             . 7        ,         ,  $           %            ,       ,                       ,     ,          —             .     ,   "      ,                   ,        . 9             %      +             ,  ,               . &   -  !     ,   ,            +  , $    %      %. ~              ,   "                            . &     ,  %  "        +   —     -             "    Google Docs 
Средства Dropbox. >         "        ,   %      # . 9               "     —      % ,             . #   HTML5  JavaScript,  "                     ,   $ . &   "             ,    GPS12,          . *  $          —        "          . $            ,   ,    ,          . & " ,  ,                %          ,                         . Библиотека p5.js     -     "   node.js,              -   ,   "       . =    $          -     HTML   " JavaScript. #"           JavaScript     .     ,               . ; ,      Processing,         p5.js,     "             Processing. #   ,           $       . 12 Global Positioning System —   (  )          . 55 >  p5.js           .        $   ,               https://p5js.org. =              _ 7  (Lauren McCarthy) «Getting Started with p5.js» (  Maker Media). =        p5.js          ,        $   . '     ,       (  Complete Library)    https://p5js.org/download. &            empty-example,         p5.js       . #   $     ,     ,     ,               ,        " : HTML   index.html   %    ,    libraries    p5.js   %  (addons): p5.dom.js (      DOM  HTML-    )  p5.sound.js (     ). &         sketch.js —  ,            . '        p5.js (       JavaScript)     HTML-    ,         <script>,           . /        URL-       % ,         ,   "     . =                <script>. 0    index.html   example-project,    ,                p5.js,                sketch.js:
Глава 1 56 <!DOCTYPE html> <html> <head> <meta name="viewport" width=devicewidth, initial-scale=1.0, maximumscale=1.0, user-scalable=0> <style> body {padding: 0; margin: 0;} </style> <script src="../p5.min.js"></script> <script src="../addons/p5.dom.min.js"> </script> <script src="../addons/p5.sound.min.js"> </script> <script src="sketch.js"></script> </head> <body> </body> </html> /        %                 . =    ,         ,          , —       $         " .    p5.js          . = $ "       node        p5manager: $ sudo npm install -g p5-manager   $             p5.js,       : $ p5 generate --bundle myProject : $ p5 g -b myProject ~   p5.js     Processing          ,       .       Processing,    p5.js     setup()  draw(),           Processing,   p5.js     JavaScript. &    ,      p5.js          JavaScript,    Java,       "    var,   — " myFunction()  . . 7     p5.js      Processing: function setup() { //   $ $  # } function draw() { //  , //    # }    %         -           ,   draw()         ,               -     ,       . $      p5.js     draw(). Пишем код #      p5.js,      sketch.js            " : /* M'  context: p5.js    ,    ' */ var myButton, responseDiv; // R  DOM function setup() { createCanvas(windowWidth, windowHeight); // Z$ - myButton = createButton('click me'); // Z$  :
Средства #    ,         index.html       . 57 myButton.touchEnded(changeButton); //  % # ' //     myButton.position(10, 10); //     responseDiv = createDiv('catch me'); // C$ //  $ div responseDiv.position(10, 40); //     } // \   '    : function changeButton() { var x = random(windowWidth) - myButton.width; // ^ //   var y = random(windowHeight) - myButton.height; // ^ //   y myButton.position(x, y); //    responseDiv.html(x + ',' + y); //  $ // responseDiv } >  p5.js  %          -   ,   $.   "        % (     ,    )     "        $  ,                    . &  ,   ,       ,   $         draw(),                 % (     $          ). Инструменты для работы через последовательный порт      $      " ,         "      $      . &  "          %    $                     USB           . '           "             ,          . 9    ( . !. «'        »)    %               +  ,      $     .                      . #        %      +    "      - %      ,           "  ,            . 3                       (bulletin boards, BBS)  "              p5.js              : https://p5js.org/reference. 7 "       p5.js   "   . &    $                             . #"   %          —   ,     . 0                 CoolTerm,   
Глава 1 58 9  7  (Roger Meier),        -   http://freeware. the-meiers.org.           macOS,    Windows, —  $       . 4   %   ,             ,            . =   Windows  %           -   PuTTY (  . 1.6),  ,      ssh,              . &            —          Screen (   GNU),   "      . /               OS,       %     ,      CoolTerm. Рис. 1.6. Установка типа подключения и последовательного порта в PuTTY Рис. 1.7. Окно программы терминала CoolTerm
Средства 59 Кто получит порт? ;                   . +  ,               ,              ,        %   $  .                ,    %         .   $              ,  "       ,              $     . 2 %        ,       . +        , "       ,                   . &                       ,      . &  ,    ,            ,        ,  $     . &    $                        ,  "  ,    . 4         ,            . Программа CoolTerm 2     CoolTerm (  . 1.7)  "    %    Options. &  %     Connection Options       "     Port      ,         Arduino. +     macOS       : /dev/ tty.usbmodem1441 & Windows      COM1, COM2, COM3  . . '    ,        %     Arduino,                 ,    —     .  , %       -        ,      . '             ,    Connect               . '          ,    Disconnect. Программа GNU Screen   Linux  macOS                CoolTerm ( .  . 1.7)         GNU Screen. * Ubuntu   15    GNU Screen     ,     : $ sudo apt-get install screen '   GNU Screen  macOS  Linux,               "  : $ ls /dev/tty —* # macOS $ ls /dev/tty* # Linux &     $                   ,        . [          macOS  Linux   ,     COM1, COM2  . .,     Windows,       $ 0#      . &               : $ screen  _ _  *  ,           macOS          Arduino     9600    ,       : screen /dev/tty.usbmodem1441 9600 #  "   :    Linux   screen /dev/ttyUSB0 9600
Глава 1 60 &             "  ,                      ,       ,             .   $      $     ,    ,               ,      $     ASCII. '        ,    % <Ctrl>+<A>,    — <Ctrl>+<\>. &  "       ,                "   "    . Оборудование &    ,          "   ,      "   : ?            —      . 1.1; ? $     ,         ,   "               ; ?                 —      ,       ; ?          . Микроконтроллеры      "     . 4   -      $              ,  ,   ,  "      . &% $      " ,   ,   ,          — %                 . 7           ,     "      , $    ,    ,      $  ,             . &       "  . 0     %  ,                                  . /   ( 13)        /   #  !  . &                 GPIO (  . General-Purpose Input and Output)     I/O. 7                        ( ) GPIO,           ,        $      "    ,  "   -      . &            "              . 7        ,             :    ,  (RAM14  ROM15),          —     ,           . =                 8-       ,       ,               8  (  ). 0                  ,    %     "  , —   ,             $   . 13 0  . pin —  . Random Access Memory —     , 02X. 15 Read-Only Memory —       , 2X. 14
Средства *         32-         (     32   )   ,        8-      . & %       ,   ,     64-      ,        — 32-   . *             . &               PIC   Microchip     (www.microchip.com), AVR   Atmel (www.atmel.com)  MSP430   Texas Instruments (www.ti.com),  %        %         . #       32-          "       %          ARM (www.arm.com). /              ,        .     ,    ,  Intel (www.intel.     com),         ,            $   ,          ARM, Atmel AVR   . ~            ( $1  $10  %),                             ,            ,          ,     ,    % ,         ,       $   . /      %  %             ,            $   .   Basic Stamp 2 (BS-2)   Parallax, PICAXE, Wiring, Arduino   ,            $  ,  "           ,               . 61 Arduino, Wiring и подобные микроконтроллерные модули =    $                Arduino. 7 Arduino (www.arduino.cc),            — Wiring (www.wiring.com),      +             +  (Ivrea)  2005 . 0                 ATmega   Atmel (www.atmel.com),                « »   C/C++. / « »      Processing,   ,           IDE (  . Integrated Development Environments), "   $   "    "  . &    ,   IDE  Arduino  Wiring     $     Processing —     setup()  loop()16,   map()    .        $  , "       Wiring,        Arduino     . &  "   "        Arduino,  "            . ; "        Wiring,            Wiring S.   ,               Arduino. *  . 1.8       %,       $ . ~ "           Arduino   , %      Arduino         %    . &    ,  $    . =          API17,   " Arduino  Wiring, $  "      ,   Arduino  Wiring, 16 7  draw()   Processing       loop(). 17 API, Application Programming Interface —           .
Глава 1 62 2 3 1 4 15 16 14 11 12 13 10 5 9 8 7 6 Рис. 1.8. Несколько как уже устаревших, так и актуальных сейчас моделей плат Arduino и ее клонов, Wiring и прочих: 1. Arduino Uno. 2. ATtiny85. 3. LilyPad Arduino. 4. Wiring. 5. Arduino Due. 6. Arduino Pro. 7. Arduino c.2005. 8. Arduino c.2006. 9. Arduino Fio. 10. Arduino Micro. 11. Arduino MKR1000. 12. Adafruit Feather Huzzah! 8266. 13. SparkFun 8266 Thing. 14. Arduino Leonardo. 15. Red Bear BLE Nano. 16. Arduino 101      ,      $     . ;   ,           Arduino,   -  ,       ,     %    . &          $    %    ,  " 32-                          .    Arduino Uno,             "   ,       Wiring S  " 8-        ,          $     . *,  " ,    $               . =      $                    ,       .                 Arduino IDE 1.8.2      ,          www.arduino.cc. 3             Arduino, Wiring            ,         -
Средства    " . #                 ",         ,        . 3  ,             ,                   . 0    "  - %      ,  %         ,                 . '    $   ,          2        Arduino-              .  0     %    Arduino  Wiring — $ ,            Windows, macOS  Linux, —                 . =       $         %     . ;    ,       Processing        Java,     ,    IDE  Wiring  Arduino,      C/C++,          C — AVR-C. =        $           $  . 3     Arduino                 «Getting Started with Arduino» (   O’Reilly),    7  >  (Massimo Banzi). Другие микроконтроллеры &                  $         .   $     "   $        :                           %     ,         . 63 ;  ,       ,     ,   %   $  ,                   "                ( #)  "      . *      %                               —   Python  JavaScript,         "       .   32-        (       ARM)      ,  % $   . 7      ARM         ,   MicroPython, BBC Micro Bit, Espruino  NodeMCU. +     Python  JavaScript,         $   . 0                  "     . ;                   ,        %        "         .   MKR1000,    Arduino 101  "         —     Ethernet (Wi-Fi) . #    Bluetooth LE18        "         —   ,  ESP8266   Espressif      Wi-Fi,   BLE Micro  BLE Nano   RedBear Labs — Bluetooth LE. 4        ,                       . Функциональные возможности микроконтроллеров 7    — $   % %  . +     ,    "      , 18 LE, Low Energy —  $    .
Глава 1 64 а б Arduino 101 MKR1000 Кнопка Разъем Разъем питания полного USB (пост. тока) сброса Разъем USB Кнопка сброса I ~Выводы ШИМ (3, 5, 6, 9) Выводы питания Аналоговые вводы Цифровой ввод/вывод (0 – 13) Аналоговые вводы (A0 – A5) Bluetooth LE Радио, акселерометр (на микросхеме процессора) Разъем для подключения LiPo-батареи 2C Разъем SPI Выводы ШИМ Цифровой ввод/вывод (0 – 14) УАПП Aref A0 A1 A2 A3 A4 A5 A6 0 1 ~2 ~3 ~4 ~5 Кнопка сброса WiFi Radio (in processor) 5В (ввод питания) +5 В (вывод) +3,7 В (вывод) Общий («земля») Сброс 14 –> TX 13 <–RX 12 SCL 11 SDA 10 MISO 9 SCK 8 MOSI 7 6 Выводы питания УАПП I2C SPI Рис. 1.9. Функциональные части плат Arduino 101 (а) и MKR1000 (б). Обратите внимание, что номера функциональных выводов — т. е. аналоговый А1, цифровой 2 и т. п. — не соответствуют номерам физических выводов платы. В технической документации обычно имеются в виду номера функциональных выводов, а не физических                 . *  . 1.9      "       Arduino 101  MKR1000. 0 $          ,     /  "     (GPIO),                 . =                      :    (            ) —              (X3)19      :    SPI20     I2C21. 0 $                2. *                  % USB. =  —   , Arduino Uno, 19 0  . UART, Universal Asynchronous Receiver-Transmitter. 20 SPI, Serial-Peripheral Interface —               . 21 2 I C, Inter-Integrated Circuit communications —          .   %  USB              USB/ TTL-Serial. >%               , . .                       . *  ,        ,      (~),                ,               ,              . /        -     (+7)22      ,   ,                  "  $   . *            ,      -    "      : 22 0  . PWM, Pulse Width Modulation.
Средства ? ? ? ? 65 /  "    ;   ;   +7 (PWM);      : • X3 (UART) —     • SPI —    ; • I2C —    . ; &         ,          %      ,   —  .&            ,    ,           . Какую микроконтроллерную плату выбрать? =    $    %     %        Arduino                . * $   ,      $  ,                 . *     $     ,  —    —   %       ,         . О напряжении питания плат =       "         Arduino       5 &,              %          5 &. *   ,        $  ,      3,3 &. *   ,    Arduino 101,      5 &,          $   %                 3,3 &.    $  — Arduino 101 —       Intel Curie. /             32-       :    86     ARC23, "   . 9  24 $    ,     Arduino Uno.   ,          ,     ,          Bluetooth LE. &   — MKR1000 —        SAMD21 Cortex-M0+   Atmel. /   %      "       LiPo-      ,          %            .                  Wi-Fi. ;           ESP8266   Espressif. *        ,       32-        "      Wi-Fi.     /  $    % ,      "  . * $   %      ,         /   ,         Wi-Fi        .     $         , ,       ,           . *    $   "         ESP8266       Arduino,              $       . +    ESP8266,      ,        Huzzah! ESP8266   Adafruit  ESP8266   SparkFun.   ,       "      $   . 23 ARC, advanced RISC Computing —         %   RISC- . 24 =             ,     «   »      ,       «        /  ». 7 ,   ,           -    « »,    %        % $ $                %   .
Глава 1 66 *  ,   Adafruit     Feather Huzzah! ESP8266     %     Huzzah! ESP8266 breakout board. 3   SparkFun     ESP8266 Thing  ESP8266 Thing Dev Board        . #  Feather Huzzah! ESP8266  ESP8266 Thing Dev Board   " ,                USB. 3   -      Huzzah! ESP8266 breakout board  ESP8266 Thing          USB/TTL-Serial. 4    ,     ,   Feather Huzzah! 8266  8266 Thing Dev Board. &               ,  $      . Шилды Arduino 0        Arduino,         ,     % ,       (shield),         Arduino        . &  Arduino  %           ,        %. *    $   ,     Arduino Uno rev3                 . = %  , %         Arduino    , "  % ,            . +  "      %                 Arduino.                    ,  " "     $    . +            %      -   www.arduino.cc. #          $                  - . &  $             %,          . *  . 1.10        %   . & %     $      % ,          ,              $       —  Arduino 101,   MKR1000. 0      ! *  %     . 0                            ,          5 &  3,3 &. $,        %      ,              %  ,    ,      . Рис. 1.10. Шилды и внешние модули для широкого диапазона приложений
Средства 67 Создаем первые программы для микроконтроллера Загрузите последнюю версию программного обеспечения для Arduino с сайта www.arduino.cc и установите его на свой компьютер, следуя приведенным далее инструкциям. Установка на macOS Начало работы 9      ,        "   %.              Arduino. ;      Arduino.        USB    "      Arduino IDE   " ,       . 0         (  . 1.11).  "      Arduino. X      Arduino,           . Установка на Windows 10 2    " Windows,            . &               %             USB. 9 %    $  .   %           Arduino IDE      . Установка на Linux &       Arduino  Linux          Linux. = Ubuntu 14             www.arduino.cc,    ,              "   : $ $ $ $ sudo mv arduino-1.8.2 /opt cd /opt/arduino-1.8.2/ chmod +x install.sh ./install.sh   %        "         Arduino      .   $,           dialout,              : $ sudo usermod -a -G dialout $USER #    Arduino        Processing:                 D (New),   (Open)  D=   (Save). ;             —    (Verify)    #   (Upload). *                ,       %    ,    #   —                .   ,                 "    (Serial Monitor),                         . Внимание!          Arduino      . & $          Arduino IDE 1.8.2. *     ,       , 0     , $       Arduino (www.arduino.cc)           .
Глава 1 68 ``Панель инструментов. Самая правая дальняя кнопка — Монитор порта (Serial Monitor) ``Окно редактирования. Рекомендуется установить флажок Показать номера строк (Numbering) в меню Настройки (Preferences) ``Панель консоли. Здесь выводятся предупреждения и сообщения об ошибках ``Индикатор версии платы и номера порта Рис. 1.11. Среда разработки Arduino Пишем код      Processing,    Arduino         . =     %     : /* &  : Arduino  '     */    . void setup() { pinMode(LED_BUILTIN, OUTPUT); // %     //       } void loop() { digitalWrite(LED_BUILTIN, HIGH); // ' //   delay(500); //    digitalWrite(LED_BUILTIN, LOW); // ' //   delay(500); //    — } &  $    . 2            (Tools)   (Board)         . 4  %     ,  "   " A  ( $  ,     ! «*  »  ). 2                   (Serial Port)    -        . *    macOS  Linux            : /dev/tty.usbmodem1421 (Arduino 101) *    Windows              COMx,  x — -  . *  , COM5.
Средства 69 Порты Windows *    Windows     COM1  COM4                    —    ,              . Менеджер плат 7   ,           $           %   Arduino IDE. '   ,            . =    $ "   " A  Arduino IDE,       ( Arduino 1.6.6      )                 |  | " A .          "  #      ,      "       " "    : Z $  928   (2%)    . +   32256  . 2                           .          % ,       (  25  L )          . &        $     «2   ,  !». Программа не работает &  %             . 4       ,       : N  . &          "               N  . =                     %,    —   (URL)   "          Arduino IDE. *  ,          ESP8266,              \ | ]         !      " A  . =  ESP8266     : http:// arduino.esp8266.com/stable/package_esp8266com_ index.json. 2     OK      .   $                . ;                        . &            ,      ,        .     %   %        "             "      + . ;      #  ,            . 2       .   %        "  4    -           ,           ". 7               Learning  -   Arduino (www.arduino.cc/en/Tutorial).   ,    Arduino (www.arduino.cc/forum)    ,        ". ~             /     ,  $     ,      ,     LED_BUILTIN,            ,          . *  ,   Arduino 101        Uno          13,    MKR1000      6. 0         LED_BUILTIN            ,          "           . &               —  ,      , $ ,    "                       . 25 0  . L, LED —  .
Глава 1 70 Связь по последовательному порту 0           ,               $  ,                ,  ,   ,               -                ,         . Пишем код &  "            :                   ,          ,  "       ,                     $   —                 . /*     : Arduino &    ;           #   . ƒ  '      . */ /   Arduino              . 0                   ,         (    ,      "    ),            . void setup() { pinMode(LED_BUILTIN, OUTPUT); //   13, //   Serial.begin(9600); // $    //   //  9600  / } int inByte = 0; //    -   // long blinkTimer = 0; //    ,   //  '    int blinkInterval = 1000; //   ' /'  — //    void loop() { // †  -  : if (Serial.available() > 0) { inByte = Serial.read(); // Serial.write(inByte+1); // // // } Z    : M   $     #  : //      . // +'      : if (millis() - blinkTimer >= blinkInterval / 2) { digitalWrite(LED_BUILTIN, HIGH); // '   } // Z    '    //  : if (millis() - blinkTimer >= blinkInterval) { digitalWrite(LED_BUILTIN, LOW); // '   blinkTimer = millis(); //    } }
Средства 71 Инструмент Монитор порта +    "     Arduino IDE          "   Arduino. =                                  . 2     "    (            ) —            (  . 1.12).                    9600    . &               ( % <Enter>   ). 7    "    . &    —     ,       ASCII26               . 26 ASCII, American Standard Code for Information Interchange —    ( ,  ),                       . Куда делся мой последовательный порт?      ,    Arduino,                 ,                               Arduino     USB.                                 .   ,                      . *    Windows $        COM- ,      macOS      -         .                                . /      ,            ,                ,          , —   ,           % ,     . *                       ! —        ,  " $       ( %   —    ). +                 . Рис. 1.12. Окно монитора порта среды Arduino при исполнении предшествующего скетча: пользователь ввел буквы ABCDEF
Глава 1 72 Подсоединение компонентов к плате     / ,  Arduino  Wiring  "    , $               ,  "      "   (   ),            . *  . 1.13              Arduino   $      . Базовые схемы ввода/вывода &    $                    . 4                     , $         . 7        $  ,         ,    . =             , $              —     ,           ,  " . Цифровой ввод Z        — $   %    (   ,  ),                    ,      "          («  »)         (10 0     ). /         #  !  . 7     «  »   ,    ,            , —           . & $          # .  %"   "                             .        ,      . 1.14,                (      )    . 3       :        " ,              —                     . Рис. 1.13. Подключение электронных компонентов к плате Arduino с помощью беспаечной макетной платы. Питание (+5 В и общий) подаются от модуля на крайние ряды гнезд макетной платы, называемые шинами питания. В результате все датчики и приводы имеют общее питание с модулем. Сигнальные и управляющие контакты каждого датчика и привода подключаются к соответствующим контактам ввода/вывода платы. В этом примере две кнопки подключены к контактам 2 и 3 цифрового ввода физических
Средства 73 A B К плюсу К общему C D E F G H J I 1 1 5 5 Входное напряжение К цифровому вводу микроконтроллера 10 10 Кнопка К цифровому вводу микроконтроллера 15 15 Понижающий резистор 20 20 25 25 30 30 A B A B К плюсу К общему К аналоговому вводу микроконтроллера К аналоговому вводу микроконтроллера C D E C D E F G H F J I G H I J 1 1 5 5 10 10 15 15 20 20 Рис. 1.14. Цифровой ввод на микроконтроллер: общий вид макетной платы (слева); принципиальная схема соединений (справа) Входное напряжение Переменное сопротивление (светочувствительный резистор) Постоянное сопротивление К аналоговому вводу микроконтроллера Входное напряжение Потенциометр 25 25 30 К аналоговому вводу микроконтроллера 30 A B C D E F G H I J Рис. 1.15. Ввод в микроконтроллер аналогового сигнала: общий вид макетной платы (слева); справа показаны принципиальные схемы двух способов получения входного аналогового сигнала: с использованием в делителе напряжения светочувствительного резистора (вверху) и с использованием потенциометра (внизу). Эти сигналы можно подавать на два разных контакта аналоговых вводов микроконтроллера Аналоговый ввод # ,       . 1.15,        . & $              ,         ,    —  -   . *                   %     $    . *  ,             
Глава 1 74                     . 3            ,   ,     1  2 0 (           ),     $      2/3   . 4            -          ,  "    "      ,                      . +        :    ,    ,   ,    . . &     . 1.15 (  !)        ,        .             ,   "          .     "                          . &    ,    — $            . 4          ,    —  " ,      "             . &   "           ,  $      ,        . Документируйте свою работу /          ,   -     ,        . .     $         , $          ,       ,   ,         ,         $.    $                    ,                : • Adobe Illustrator (www.adobe.com/products/illustrator.html). /        ,            ,     %   . = $       "           $     ,       # . • Affinity Designer (https://affinity.serif.com/en-us/ designer/) —          ,       $      Windows   "   - . /         %      ,        SVG27 % ,   Adobe Illustrator. ;     .     . /  %               ,        ,       ,              . =        %        $     ,                   ,          "                      $     . /   28    "   $     ,    "      ,  =  (Jody Culkin)  =  0  (Giorgio Olivero),        3     (Andre Knorig)  =   $  (Jonathan Cohen),        Fritzing. • Fritzing (www.fritzing.org) —           Fritzing        ,        $ - *     ,      ,         ,        %  . _             :     Wordpress (www.wordpress.org)  "    -   www.makingthingstalk.com, http://tigoe.net/blog  http://tigoe.net/pcomp/code,   "  github (https://github.com/tigoe)      Maker’s Notebooks (www.makershed. com,   › 9781449358976). 27 28  SVG, Scalable Vector Graphics —  %      . +                       .
Средства Специальные схемы и модули &              . 7             . & $           ,       . 1.13–1.15,          ,    . *  ,           ,              ,       . & $                      "       ,               $           .                 ,    $          .              Arduino    ,                   ,            . Рис. 1.16. Одноплатные компьютеры (слева направо): Raspberry Pi 3; Raspberry Pi Zero W; BeagleBone Green; Arduino Yuún 75 Ознакомьтесь с техническими характеристиками компонентов &     $              . $                      ,   %         ,      . Одноплатные компьютеры &       ,                              —  ,   /        — $         %     . *              ,    ,  "          ,        . &    ,              $     ,  " "        ,              
Глава 1 76      %         $ ,           $   . 0     ,        . 0               ,         ,           ,             . &          %        -    Linux,      Windows 10,         . >%  $      "      /  "    ,  %         / .   ,   /                3,3 &     , $,            ,           . &    $           Raspberri Pi,    "             . *               ,   BeagleBone   Texas Instruments               ,    Raspberry Pi. #       %        $        BeagleBone.  Raspberry Pi 3   &  "       ARM Cortex A7   Broadcom    1,2 qq,       1 q   RAM.   ,          ,     Wi-Fi  Bluetooth.  HDMI,   &               Linux,  "  Raspbian,      "             "                "    .                   ,    ,            / ,                     —   Wi-Fi,  ,   . . +  $              ,                   . & $   Raspberry Pi       %   . Плата Raspberry Pi 0   Raspberry Pi  %         2012 .        35  ,       "    $   ,      $                       . #     %  %      ,     Raspberry Pi 3        ,         "  ,    %   .                   $     Pi Zero W   10  .     $       "          Wi-Fi. &  ,    Raspberry Pi  35       . '           ,                :   ,       ,       "     . *        Raspberry Pi       . &    ,                                  . /    ,   ,                          -  . $         -
Средства  Raspberry Pi  %          . #        ,             ,    "   $    .                   ,            . 77         Raspberry Pi,   ,                 ,      %  . Основы работы с Raspberry Pi ?     A  5 '  )  -USB. # ,    $   ,      2  . = $                "   USB; ?    MicroSD     8 q ,  " % — 16 q . +  ,  ;   ,     ,     Raspberry Pi, — $             Linux  Raspberry Pi (      Raspbian)   www.raspberrypi.org/downloads/raspbian/. 2       Raspbian Jessie 4.4    . =    $         Lite,  ,    ,         . 9          ,  "   $    ,                MicroSD,               ,          USB/ TTL-Serial (  . 1.17),              USB  . ? -  = USB/TTL-Serial. /                      ,   "   . *     "   ,   -   USB/ TTL-Serial  Raspberry Pi (ID: 954)     FTDI Friend (ID: 284)   Adafruit; Внимание! '  %          ,    Raspbian,  " ,   1   2017 ,         . = $    ,         MicroSD      ,         "     config.txt        " : ?    Wi-Fi,    USB-   (       Raspberry Pi 3  Zero W). &  ,     %          ,              "  ,      Wi-Fi     . = Raspberry Pi                 Wi-Fi (AF: 2638),        ,   ,   Miniature WiFi (802.11b/g/n)  Adafruit (AF: 814),         Wi-Fi   Realtek.                , '       Raspberry Pi     $  ,      "    : [code style] enable uart=1 X       USB/TTL-Serial     ,                     CoolTerm                . X         115 200         %   . * $        %       : Raspbian GNU/Linux 8 raspberrypi ttyAMA0 raspberrypi login:
Глава 1 78 TX ,    Ethernet  "  .                ,              Wi-Fi. RX USB 2x BLACK GND CTS VCC TX RX RTS GREEN Power CSI (CAMERA) HDMI Audio ETHERNET USB 2x DSI (DISPLAY) GPIO Подключение через сетевой кабель                   ,    —       %  . 4  %  %              DHCP (  %      %   $       ),        Raspberry Pi    .    $ ,     : $ ifconfig eth0 Рис. 1.17. Плата Raspberry Pi 2/3 B с подсоединенным переходником USB/TTL-Serial. Контакты последовательного ввода/вывода одинаковы на всех моделях плат Raspberry Pi =       Raspbian    (login)    pi,    — raspberry. &        $     . &          ,       ,         Linux,      Linux,     !. «+      »  . 0    "   raspi        . = $     :          " : eth0 Link encap:Ethernet HWaddr b8:27:eb:63:37:4a inet addr:192.168.0.17 Bcast:192.168.0.255 Mask:255.255.255.0 inet6 addr: fe80::ffc5:e696:3b93:5b47/64 Scope :Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:110 errors:0 dropped:0 overruns:0 frame:0 TX packets:103 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:38147 (37.2 KiB) TX bytes:12819 (12.5 KiB) config  $ sudo raspi-config 0     ,         "  " %-  ,       ,  % <Enter>. #        1. Expand Filesystem,    %     —  2. Change Password               . * $ $    %              /   ,       Ethernet        Ethernet (        "  eth0)   192.168.0.17. 4        ,     . >                    3. Подключение через адаптер Wi-Fi 4                Wi-Fi,          Raspbian   . '          Jessie $,
Средства 79     USB-        "  : $ iwconfig wlan0 4        " :  - wlan0 IEEE 802.11bgn Nickname:"<WIFI@REALTEK>" $   ,   Wi-Fi     . '          Wi-Fi,     "  : Настройка Wi-Fi с помощью wpa_cli         wpa_cli  ,            . #         ,       ,      ,         ,              .           ,          ,     % . '     ,     : $ sudo wpa_cli $ sudo iwlist wlan0 scan * $          "     Wi-Fi   "     . &      "     $  , "            scan    less,        : $ sudo iwlist wlan0 scan | less =      "     %   ,    %      — % <q>. О команде sudo &     POSIX   sudo          %        ,               (      ! ). *        ,      sudo,          . & %   ,     wpa_cli          ,          %    . *  Raspberry Pi %         sudo. X     — ifconfig  iwconfig —                     . *  ,   ifconfig             (      : InterFace CONFIGuration). 3    $      : eth0  wlan0 —         :       Ethernet          29. /                  ,       ,          Wi-Fi. = $   %  "     Raspbian         ,  "  wpa_cli. 29 WLAN — Wireless Local Area Network. * $              wpa_cli,         "   : Selected interface 'wlan0' //  // %  'wlan0' Interactive mode // \  //  > # >   %      . &   "  : add_network &             : 0 >   ,  -
Глава 1 80 /    ,           . =   : > set_network 0 ssid "_SSID" > set_network 0 psk " " &  _SSID       Wi-Fi       . 4           ,   " : > set_network 0 key_mgmt NONE 2    : > enable_network 0 // ˆ   //  > save_config // Z-  // %  #    ;  ,   %  Raspberry Pi                     $      . '  %     wpa_cli,      quit.   ,              ,   "   ifconfig wlan0  iwconfig wlan0,       . * $    ifconfig        Pi,    iwconfig —  . Подключение к одноплатному компьютеру по ssh      ,             ssh. = $        ,             "   ifconfig. 0     _            ssh $@xx.xx.xx.xx. 2     _$       . =  Raspberry Pi $   pi,        — root. 3    xx.xx. xx.xx           . *  ,   Pi      192.168.0.23 $        : ssh pi@192.168.0.23.       %  ,           ,         . Проверка сетевого подключения с помощью curl _            —      Wi-Fi —          .               -  , %                 curl. /    -   -           . 2    ,     "  : $ curl http://www.example.com &    $         HTML,           "  : <body> <div> <h1>Example Domain</h1> (ƒ  ) nts. You may use this domain in examples without prior coordination or asking for permission.</p> (‰    $   - $        $ .) <p><a href="http://www.iana.org/ domains/example">More information...</a></p> ((Š  % # ...) </div> </body> </html> ;    ,              ,   ,  %  Raspberry Pi   +  .   curl  "      -   ,       ,    -  ,      — . .    HTML-. '           ,   URL-        .
Средства 81 X     Упорядочивание системы        Raspberry Pi            +                    "     node.js. =          ,          Raspberry Pi. # "    apt (               Raspbian)               :     node.js: $ sudo apt-get remove --purge node* npm* # "    curl            node (nvm): $ sudo curl -o- https://raw.githubusercontent. com/creationix/nvm/v0.33.1/install.sh | bash &          ,      : $ nvm install v6.9.5 #         node        node (npm)      : $ sudo ln -s /home/pi/.nvm/versions/ node/v6.9.5/bin/node/usr/bin/node $ sudo ln -s /home/pi/.nvm/versions/ node/v6.9.5/bin/npm/usr/bin/npm * ,     Processing: $ curl https://processing.org/download/ install-arm.sh | sudo sh $ sudo apt-get update X    node.js 6.9.5:  $ sudo logout raspberrypi login: pi    . ;  ,    Pi,               ,         . *  $ $      : $ sudo poweroff              "  ,     ,               . Как выбрать правильную плату? Выбирая микроконтроллер или одноплатный компьютер для какого-либо проекта, нужно принять во внимание несколько факторов.    ,         — ,          ,   ?                     ,       ,        . 3                         $    . #            10  30   ,             . &                               ,         . 7           ,            ,            . &           ,                .
Глава 1 82 Операционные системы и «реальное время» &        ,               . /   ,   100%            $    . /,    ,   ,  $          :                       —            %   $  .        %      "    ,               . 0      — $   ,              . ;             #  !  ,              ,              %      —      SD-  ,    !     /   (>#&&)30,                     ,      $  . 2             !  ! ,       %   ,   "                "          .                             , %                       / . ;      «        ».   ,         . &        , $        ,   ,     -    ,    ,       $        . '           ,           ,  ,     ,         ,                   (0#9&)31. ;                  / ,  %                . 0 ,   ,      / ,          % . &        0#9&                   .    :          Arduino 101                      . 0#9&    ,               ,       ,                          . >%  0#9& %      "    . 0#9&  Arduino 101             % ,             ,   Bluetooth      ,                .          $       ,                       / . Сетевое время 4                    ,   $                ,       , - 7     0#9&  %           ,    ,      - 30 31 0  . BIOS, Basic Input-Output System. 0  . RTOS, Real-Time Operating System.
Средства              ,   "      . *            ,  "      :         ,      ,             ,    %           . =            %   ,           ,           0#9&. = %                        . 2               ,              " "       ? &                      ,    -        -    ,    ,                 . = %                              . /               . &%     %,   ,        ,   "            "   USB-            ,           . /   —                —           "     $   . Безопасность 2        ,   "   %   ?                     ,  "         , - 83         . .? >%       %        ,        %    .    "   ,     +  , %      . &       "    . 2 % ,        %            ,      %   ,             ,      ,                  . & +               "       ,              , "               . X             . 0    "                  %          ,      %          . *        %          ,  $          "        . 0          "          %         .   ,     "         -      ,              ,   "        . *  ,     $         Wi-Fi,                 . 3                ,         . 2 $         %               . *       
Глава 1 84                    Wi-Fi, "         ,    ,                   . /         ,                  ,             0#9&,          . 4     ,   %                      . Работа с осциллографом Большинство проектов этой книги содержат схемы, которые отслеживают меняющееся во времени напряжение. Независимо от выполняемой микроконтроллером операции: будь то отслеживание состояния цифрового или аналогового входа, управление скоростью электродвигателя или отправление данных на персональный компьютер — он или считывает или генерирует изменяющееся во времени напряжение. Частота событий, с которыми работает микроконтроллер, настолько высокая, что она находится вне диапазона человеческого восприятия. Например, при последовательном обмене, который мы недавно рассматривали, импульсы электрического тока подаются со скоростью 10 тыс. раз в секунду. Эти колебания тока невозможно определить с помощью мультиметра. Для этого требуется осциллограф. 0   — $          $         . =                ,             (           % )           (  ,                  % ). ;                —           ,          ,     ,                       (  ). 4"                %    ,   "               . +             DSO Nano,     Seed Studio (  . 1.18).      $100 $       %        $   $   . ~                ,                    ,                 $  . 0           1 7q,           %           . *  . 1.18         Nano   «2   ,  »      Arduino.                 .             ,       —  . &         %      %   200         % ,     — 1      % . 0 "       "  («  »)    Arduino,    —      1, "           .     ,               Logic   Saleae (www.saleae.com)             . *  ,             "    " -
Средства 85 Рис. 1.18. Отслеживание последовательного потока данных на осциллографе DSO Nano         . *,      ,                           . #       Logic — Logic 4 —        ,      DSO Nano,            %           .          , "         —   - ,    .                   ,           ,      . * $     "       %       ,           .   $            . *             ,  #      %             .
Глава 1 86 Прикосновением все и завершается Хотя большая часть материала этой книги посвящена решению задач общения устройств друг с другом, важно помнить, что наши проекты создаются, скорее всего, для того, чтобы они могли доставлять удовольствие людям, которым не интересны внутренние технические детали. *           ,             -   . *  ,    ,  " %   ,  ,    ,    ,      ,  %         . &            ,           . $                    ,      "  . +           ,          ,    %    ,        . *    ,       ,      . *  ,                        . =,    ,   " $  ,                 "         . +      ,      %     ,         " ,    -          ,     . /     ",   ,                    .             — $ % %  ,          -                . *           " —          /           .            ,           ,     ,   . #   ,    $                     .            ,         ,                  $   . &    ,    %    ,    ,    $           . +  ,    ,      % "        $     ,       ,         «%  ». *   %        . &          ,     %       . X                ,    %     ,     %    %      ,             . &      ,      ,      "   "    "     , — $  %   "      .


Глава 2 ПРОСТЕЙШАЯ СЕТЬ Самая простая сеть — это соединение двух объектов один к одному. В этой главе подробно рассматривается двусторонняя связь, и начнем мы с характеристик, которые нужно оговорить прежде всего. Мы познакомимся с некоторыми логистическими элементами сетевой связи: протоколами данных, управлением потоками и адресацией. Эти теоретические понятия мы применим на практике, создав два устройства, реализующих примеры использования последовательной связи между микроконтроллером и персональным компьютером. Мы также рассмотрим модемную связь и узнаем, как заменить кабель, соединяющий микроконтроллер и компьютер, на приемопередатчики беспроводной связи Bluetooth. Наконец, мы научимся программировать микроконтроллеры низкого уровня с тем, чтобы распределять вычислительные потребности наших проектов между разными процессорами. «Молниеносный» оркестр Джу Йон Паэка (2006) /                 "       -  . 2             " ,                       ,   "             . 0   ' 1 4 % (Joo Youn Paek).
Глава 2 90 Компоненты для проектов этой главы Коды поставщиков ? A — Arduino Store, http://store.arduino.cc ? AF — Adafruit, http://adafruit.com ? D — Digi-Key, www.digikey.com ? F — Farnell, www.farnell.com ? J — Jameco, http://jameco.com ? RS — RS, www.rs-online.com ? SF — SparkFun, www.sparkfun.com ? SS — Seeed Studio, www.seeedstudio.com Рис. 2.1. Новые компоненты для проектов этой главы: 1. Компоновочный корпус. 2. Литиево-полимерная батарейка. 3. Батарейка типа «Крона», 9 В. 4. Контактный разъем для батарейки «Крона» 9 В с разъемом питания. 5. Небольшая мягкая игрушка по имени Мартышкин. 6. Мячик для настольного тенниса. 7. Трехцветный светодиод. 8. Датчики изгиба. 9. Шилды для прототипов. 10. Кнопки. 11. Микроконтроллер ATtiny85. 12. Адаптерная плата микросхемы CH340G. 13. Адаптерная плата FTDI Friend. 14. Адаптерная плата микросхемы CP2104 Friend. 15. Штыревые разъемы. 16. Модуль Bluetooth Mate. 17. Модуль Bluefruit EZ-Link 1 3 4 2 5 17 9 14 8 16 7 13 10 11 12 15 6
Простейшая сеть ПРОЕКТ 1. Управление яркостью трехцветного светодиода с клавиатуры  "      , 1 +. = $             Arduino . &            MKR1000  Arduino 101,   Arduino Uno         . MKR1000 — AF: 3156, RS: 124-0657, A: ABX00004, GBX00011 (3   4#), D: 1659-1005-ND Arduino 101 — D: 1660-1003-ND, J: 2239331, SF: DEV-13787, AF: 3033, F: 2520713, RS: 9139999, SS: 114990575, A: ABX00005, GBX00005 (3   4#) Arduino Uno — D: 1050-1024-ND, J: 2151486, SF: DEV-11021, A: A000099, AF: 50, F 1848687, RS: 715-4081, SS: ARD132D2P  % =     $  , 1 +. /,  ,       ! 0        ,       . D: 754-1492.ND, J: 2125181, SF: COM-00105, F: 2290374, RS: 861-4290 (  220 , 1 +.  D: 220QBK-ND, J: 690700, F: 9339299, R: 7077612  C      , 1 +. D: 438-1045-ND, J: 20723  20601, SF: PRT12615  PRT-12002, F: 4692810, AF: 64, SS: 319030002  319030001       > .  ]=   =                . &       $    Arduino — $ %     USB. *          ,     %  .  "     , 1 +. 7           . ПРОЕКТ 2. Мартышкин пинг-понг (Monski Pong)  "      , 1 +. = $            - 91  Arduino . &            MKR1000  Arduino 101,   Arduino Uno         . MKR1000 — AF: 3156, RS: 124-0657, A: ABX00004, GBX00011 (3   4#), D: 1659-1005-ND Arduino 101 — D: 1660-1003-ND, J: 2239331, SF: DEV-13787, AF: 3033, F: 2520713, RS: 9139999, SS: 114990575, A: ABX00005, GBX00005 (3   4#) Arduino Uno — D: 1050-1024-ND, J: 2151486, SF: DEV-11021, A: A000099, AF: 50, F 1848687, RS: 715-4081, SS: ARD132D2P  (      , 2 +. D: 905-1000-ND, J: 150551, SF: SEN-10264, AF: 182, RS: 708-1277     &  , 2 +. +          . &  ,   %     . D: GH1344-ND  SW400-ND, J: 2231822  119011, SF: COM-09337, F: 1634684, RS: 718-2213  (    10 , 4 +. J: 29082, SF: COM-09939, F: 350072, RS: 2499294  C      , 1 +. D: 438-1045-ND, J: 20723  20601, SF: PRT12615  PRT-12002, F: 4692810, AF: 64, SS: 319030002  319030001       > .  ]=   =                . ;  ,      "    .  ]+    +    " + , 1 +. (  —       ). ПРОЕКТ 3. Беспроводной мартышкин пинг-понг  # +  »     «" +   2.  C    9 '   )  -     )  , 1 +. D: 1568-1237-ND, J: 2207056, SF: PRT-09518, A: 80, F: 1650675
Глава 2 92 =  MKR1000      9 &        -      , 1 +. SF: PRT-13813  PRT-08483; A: 258  2011    )   2,1        , 5,5   + . 4         Farnell,   $     . D: CP3-1000-ND, J: 28760, SF: PRT-10287, A: 369, F: 1737256     Bluetooth, 1 +. AF: 1588, SF: WRL-12580  WRL-12576             ,    Bluetooth, 1 +. ПРОЕКТ 4. Arduino-совместимая плата своими руками  "  Arduino, 1 +. _%      Arduino Uno, MKR1000  Arduino 101. MKR1000 — AF: 3156, RS: 124-0657, A: ABX00004, GBX00011 (3   4#), D: 1659-1005-ND Arduino 101 — D: 1660-1003-ND, J: 2239331, SF: DEV-13787, AF: 3033, F: 2520713, RS: 9139999, SS: 114990575, A: ABX00005, GBX00005 (3   4#) Arduino Uno — D: 1050-1024-ND, J: 2151486, SF: DEV-11021, A: A000099, AF: 50, F 1848687, RS: 715-4081, SS: ARD132D2P  "     ATtiny84, 1 +. 4        $     ,           . D: ATtiny84A-PU-ND, SF: COM-11232, F: 1455160, RS: 7380684  % =     $  , 1 +. ;  ,     1. D: 754-1492.ND, J: 2125181, SF: COM-00105, F: 2290374, RS: 861-4290  (   220 , 1 +. D: 220QBK-ND, J: 690700, F: 9339299, R: 7077612  C      , 1 +. D: 438-1045-ND, J: 20723  20601, SF: PRT12615  PRT-12002, F: 4692810, AF: 64, SS: 319030002  319030001       . J: 20723, SF: PRT-12796, F: 2396146, RS: 7916463, AF: 759 Для всех проектов    USB/TTL-Serial. /                         . *           -   USB-A  USB-Mini-B   USB-Micro-B. 0           ,  ,        USB/TTL-Serial,              . D: 36-84-4-ND, J: 216452, SF: DEV-09716  DEV-14050, A: 3309  284, SS: 317990026. Рис. 2.2. Адаптеры USB/TTL-Serial (слева направо): Adafruit FTDI Friend; Adafruit CP2104 Friend; SparkFun Serial Basic Breakout CH340G
Простейшая сеть 93 Уровни согласования Прежде чем мы предоставим устройствам возможность общаться друг с другом, нам нужно определиться с основными вопросами такого общения. Эти вопросы можно разбить на пять уровней, каждый из которых основывается на предыдущем. ? \   .                  ? #                  " ? ? {   .                 ? 5 &? 3,3 &?  -      ? ? <  .       —        ? # ,                   1,   —   0,      ,            :               0,   —   1, —   . ? N    =.   "        ? #       : 8, 9, 10  % ? 0                ? ? N   A .             "  ?      "   ,  -  ? /  "            ,  "    OSI1. &               ,                                .    %                            1 OSI, Open System Interconnect,         (&0#). #           ,    ISO (    ISO-7498)  1984 .             .            ,     $    .         ,      ,     $        — $   % $     . X   ,  " "           ,      $   .  "                 "           ,               . '      0  1    ,            ,              :      . 0                   (  . 2.3). #                                    (   :   )               . 3                       ,           (  )       (   . 2.3                 :    SPI           I2C). #                         (   ,               ). & $                  ,     $              ,    "  $  :  Ethernet-             .
Глава 2 94 Асинхронный обмен данными Передатчик Приемник Направление данных RX (Прием) TX (Передача) Направление данных TX (Передача) RX (Прием) Общий («земля») Общий («земля») Асинхронный обмен данными: каждое устройство использует свой собственный генератор тактовых (синхронизирующих) сигналов, обмен данными осуществляется с заранее согласованной скоростью. Синхронный обмен данными (интерфейс SPI) Master (ведущее устройство) Slave (ведомое устройство) Chip Select (CS) Выбор схемы Chip Select (CS) Выбор схемы Выход ведущего, вход ведомого Направление данных MOSI (выход ведущего, вход ведомого) Направление данных Вход ведущего, выход ведомого Направление сигнала тактирования Clock (CLC) Сигнал тактирования MISO (вход ведущего, выход ведомого) Clock (CLK) Сигнал тактирования 3,3 В Тактовые импульсы 0В Синхронный обмен данными (интерфейс SPI, Serial Peripheral Interface): ведущее устройство подает сигнал тактирования на ведомое устройство и инициирует обмен, подавая сигнал выбора схемы. Обмен данными происходит по смене уровня напряжения сигнала тактирования на обратное. Синхронный обмен данными (интерфейс I2C) Master (ведущее устройство) Slave (ведомое устройство) Обмен данными осуществляется в обоих направлениях Serial Data (SDA) Последовательные данные Serial Clock (SCL) Сигнал последовательного тактирования Направление сигнала тактирования SDA (последовательные данные) SCL (cигнал последовательного тактирования) 3,3 В Тактовые импульсы 0В Синхронный обмен данными (интерфейс I2C): ведущее устройство подает сигнал тактирования на ведомое устройство, выбирая ведомое по его адресу. Обмен данными происходит по смене уровня напряжения сигнала тактирования на обратное. Рис. 2.3. Типы последовательной связи
Простейшая сеть 95 Устанавливаем соединение: нижние уровни Мы уже знакомы с одним примером последовательного обмена данными — между микроконтроллером и персональным компьютером. В частности, в главе 1 мы подключили микроконтроллерный модуль к персональному компьютеру через порт USB. Это подключение является примером асинхронного последовательного обмена данными с использованием двух протоколов последовательной связи: TTL Serial и USB.     — $  ,        ,        778 (TTL2 Serial). /         "     :  Arduino Uno,     USB      ;;_           . *    —   ,  MKR1000  Arduino 101, $                   . ? \   . 0      ,            . &  Arduino        ,   RX ( Receive,   ),      ,    TX ( Transmit,  ). 0         USB   "            "    USB3,                TTL. 0      "      : ? {   . 0              . &               3,3 &,    — 5 &. ? <  . &        (3,3  5 &)          1,   (0 &) —      0. \   .   USB           : Data+  Data–       (+5 &  " ). ? {   . #     Data–          Data+,         $       . /                   % $      —  $          $   . 4       ,           . ? ? N    =. 0       "        9600    . =              ,     8   ,       (      ). ? N   A . * $                 ,         "      . ? <  . _     1          +5 & (    Data+)  –5 & (    Data–),       0 —      0 &. * $ "  . +        . #       TTL/USB-      ,            TTL-        USB-   . *        —   , ? N    =. X         USB   ,     "             ;;_. & USB            480     . 0  2 TTL, Transistor-Transistor Logic —           (;;_). 3 - USB, Universal Serial Bus (protocol) —            % .
Глава 2 96         ,    8   ,        . *      USB                        (              ).      %             ,             $                         %         "       . ? N   A . *          USB/TTL-Serial   Arduino              ,     . 0         $         ,      ,                $    . & $          ,      USB          ,      USB — неисчерпаемый источник последовательных портов 0                 —    ,               . *  ,     %             ,               ,             . 3     $           ,      ,         $      —                . 0    % USB                . 4       "   USB,            USB  ,                  "      . 3     USB      ,       USB-    (). *  ,            Arduino   USB-,                    . * %   Mac OS          : /dev/cu.usbmodem1441 /dev/cu.usbmodem1461 /dev/cu.usbmodem1471 &    POSIX,  macOS,         :    /dev/tty.usb- modemXX  "   /dev/cu.usbmodemXX. /          $      :   TTY4    "  ,  CU5 —   ". =     USB/TTL-Serial,       $   ,         "     . * %   Windows $      ,   , : COM8, COM9, COM10. >%            "           USB/TTL-Serial. =   ,           ,            $15–20. 0                ,              ,  "              TTL,       FTDI (Future Technology Devices International),          www.ftdichip.com. /                        Maker SHED, SparkFun, Adafruit     . =      : 5 &  3,3 & —              $  .  -   USB/ TTL-Serial   FTDI    . 2.4,        TTL —   . 2.5. 4 5 TTY, Teletype Unit —         . CU, #alling Unit —   "    .
Простейшая сеть 97  . 7        USB/ TTL-Serial   Arduino                                 USB           (9600     —        1). Рис. 2.4. Кабель-переходник USB/TTL-Serial компании FTDI Рис. 2.5. Распиновка разъема TTL кабеля USB/TTL-Serial компании FTDI. Кроме линий передачи, приема и питания он также имеет линии для аппаратного управления обменом данных: RTS (Request-to-send, запрос на передачу) и CTS (Clear-to-send, готовность к передаче). Некоторые устройства используют эти линии для управления потоком последовательных данных Распиновка разъема TTL кабеля USB/TTL-Serial компании FTDI Общий («земля») GND Черный Готовность к передаче CTS Коричневый Используется для подачи питания на устройство от USB-порта компьютера Vcc Красный К контакту RX (Прием) микроконтроллера TX Оранжевый К контакту TX (Передача) микроконтроллера RX Желтый RTS Зеленый Запрос на передачу 4   "    —          BASIC Stamp              ,   USB,  ,   ,  " 9-               USB/RS-232 (      USB  RS-232     . 2.6). /       DB-9  D-sub-9                    : RS-232.   RS-232                     USB   "                    . /       "       : ? \   . =    RS-232          2,       3.   5 — « ». ? {   . =     RS232          :  +3 &  +25 &   –3 &  –25 &. ? <  . &        ( +3 &  +25 &)          0,   ( –3 &  –25 &) —      1.     , $             (      ) . ? N    =. ;  ,      TTL, — 8-              .
Глава 2 98 1 2 3 4 2 3 1 4 USB тип A USB тип B 1 2 3 4 5 5 4 3 2 1 USB тип Mini-B USB тип Micro-B 1 — +5 В 2 — Данные – 3 — Данные + 4 — «Земля» 2 3 4 5 2 — Прием на ПК 3 — Передача с ПК 5 — «Земля» ПК 7 8 9 6 RS-232 (штекерный разъем) 1 — +5 В 2 — Данные – 3 — Данные + 4 — ID 5 — «Земля» # %  ,         —   , BASIC Stamp,             RS-232?                 ,           ;;_          RS-232                 .   RS-232    " ,     USB, ,   ,  ,  %  ,     . >%           "         USB/TTL-Serial. & %             %   ,              $    "    . ;   ,                 $     ,            -     . Преобразователи USB/Serial >%     $     ,           , ,   ,  " -                . #                   TTL-   — TTL-Serial. *  , %      GPS6 6 1 GPS, Global Positioning System —         . Рис. 2.6. Распиновка разъемов USB и RS-232 (             8)  "     TTL-Serial. = ,             $       ,     USB/ TTL-Serial             . *             USB/Serial. 0             FT232RL,        FTDI. *   $          -  ,       $        -    .       FTDI ( .  . 2.4)       ,      ( .  . 2.5)          -         $               .    -      FTDI,         ,  Adafruit, SparkFun, Parallax    . 7    FT232RL   "       ,   XBee   Digi   - Arduino RedBoard   SparkFun. /        ,            TTL-        : 5  3,3 &.     SparkFun          ,    FTDI Friend   Adafruit             ,  
Простейшая сеть 99                         .   , $               RS-232. =  RS-232            Parallax,  "       DB-9.  —   ,   Prolific ( PL2303), Silicon Labs ( CP2102), Jiangsu Heng Qin ( CP340)   . =          $         "   : ? www.ftdichip.com/FTDrivers.htm (FTDI); +     USB/TTL-Serial         .     (TX) $               (RX)       . 0" («   »)         "       ,                  VCC             .             ,      ,              ,    . *     %    USB/TTL-Serial    5 &,             3,3 &. &   1   ,  "   USB/TTLSerial   FTDI          Raspberry Pi ( .  . 1.17). *                 . ? www.silabs.com/products/mcu/Pages/ USBtoUARTBridgeVCPDrivers.aspx (Silicon Labs); ? www.prolific.com.tw/US/Show-Product. aspx?pcid=41 (Prolific); ? www.wch.cn/download/CH341SER_ZIP. html (Jiangsu Heng Qin). '         USB/Serial,               $  .      USB/TTL-Serial             . =     %               . $        ,           ,            . & $  %            FTDI —     $              "   Windows, macOS       Linux. *     FTDI,  USB/TTLSerial       - &  Arduino Uno      USB/ TTL-Serial         "     Atmel 16U2,      $ . = $          macOS  Linux,     USB  Windows         " Windows. +     USB/TTL-Serial  Arduino Uno       hardware/arduino/avr/firmwares/ATmegaxxu2   https://github.com/arduino,                 USB       -   www.usb.org/developers/usbfaq.        USB/TTL-Serial            ,   ,          CTS (clear-to-send,       )  RTS (request-to-send,     ). >%      , "    USB/TTL-Serial, —  ,     Huzzah!      ESP8266   Adafruit   ESP8266 Thing   SparkFun,  "    $  ,          $. =             USB/TTLSerial            "          %  .
Глава 2 100 Использование платы Arduino в качестве адаптера USB/TTL-Serial 4            USB/ TTL-Serial,           Arduino  ,        . &    ,  $      MKR1000  Arduino 101. 0         ,  "        USB,        $ ,        ,          . =  "     TX ( )  RX ( )           Serial1. =        $ . &      USB           (RX)  ,       USB —      (TX)  . ; ,                     USB   "     USB/TTL-Serial. void setup() { //  #  $     // ' : Serial.begin(9600); // USB Serial1.begin(9600); // TTL } void loop() { //   RX TTL,   USB: if (Serial1.available()) { char c = Serial1.read(); Serial.write(c); } //   USB,  if (Serial.available()) { char c = Serial.read(); Serial1.write(c); } }  TX TTL: 7        —   , Arduino Uno,           USB. $,             USB,    "           USB/TTL-Serial. &    (TX)             (RX)        . /   ,                  Arduino      USB/TTL-Serial. = $           ,      : void setup() {} void loop() {} 2                   "   (    :        ,           ): •       %      —    RX (0)  Arduino; •      %      —    TX (1)  Arduino. ;   %                USB/TTL-Serial  Arduino,      .              ,                  .
Простейшая сеть 101 Отправка сообщений: уровень приложений Теперь, когда у нас появилось представление о том, как устанавливать соединение между устройствами, настало время создать пару проектов, чтобы научиться организовывать отправляемые данные. Проект 1 Управление яркостью трехцветного светодиода с клавиатуры В этом примере мы будем управлять микроконтроллером нажатием клавиш клавиатуры компьютера. Это очень простой проект — в нем используется минимальное количество деталей, что даст нам возможность сосредоточиться непосредственно на обмене данными. =    ,           ,        . =    ,       ,   ,     ,        ,   «  ». /           Arduino  —    ,     "         ,         analogWrite(). ;      7    :"* ,                     (        ), ,   ,      "     . = $           ,          . `         $           . ;         ,               :   ,     ,   "    .   $              ( ),       (   )   " .       ($            " )       7 +7, %  -  . Требуемые компоненты  ;   , 1 %.  9   (RGB)   " -  220 0, 1 %.  #  Arduino  (   . 2.8,  ,    MKR1000,   ! —  Arduino 101), 1 %. +       : X3 (UART),   +7 (PWM).  >       , 1 %.      .  7       , 1 %.     220 0    « »       ,        —    +7,      . 2.7 (  MKR1000 — $   3, 5  4,    Arduino 101 — 3, 5  6).         ,     %        —  %    ,      ,       ,      . 2.8. 7            "   . 4            %   ,   ,             .
Глава 2 102 Макетная плата с модулем MKR1000 A B C D E F G H I J 1 1 5 5 10 10 15 15 Рис. 2.8. Светодиод с надетым на него теннисным мячиком, играющим роль светорассеивающего абажура +3,3 В 20 20 25 25 30 Модуль микроконтроллера ШИМ ШИМ ШИМ 30 A B C D E F G H I Принципиальная схема Показаны только задействованные выводы J Общий («земля») Макетная плата Arduino 101/Uno Макетная платассмодулем модулем Arduino 101/Uno A B C D E F G H I J 1 1 5 5 10 10 15 15 20 20 25 25 30 30 A B C D E F G H I J Рис. 2.7. Подключение анодов трехцветного светодиода к выводам ШИМ микроконтроллерной платы: для платы MKR1000 (вверху) — это контакты 3, 5 и 4, а для платы Arduino 101 (внизу) — 3, 5 и 6. Общий катод светодиода подключается через последовательный резистор номиналом 220 Ом к контакту «земля» платы 220½ Ом
Простейшая сеть 103 Создаем коммуникационный протокол +,     ,      %,         ,     . = $          ,   %          : ?        ,                 : r, g  b; ?              ,     :  0  9. *  ,   ( %  0  9)             — 5,     — 3     — 7,     " : r5g3b7 &      —       . *  "            ,           ,    % ,    —            . Пишем код    ,    ,           ,        ($              ). ;     :          "             : /* M  -# : Arduino      -#   ,   r ( ), g ($ ) b (  )     3, 5 4 . /* //   -     : //   ' $      MKR1000. // ^     Arduino 101 $ //    -. const int redPin = 3; //  Arduino 101 $   3 const int greenPin = 5; //  Arduino 101 $   6 const int bluePin = 4; //  Arduino 101 $   5 int currentPin = 0; //   int brightness = 0; //   =   setup()                          :   $     void setup() { //  #    '  : Serial.begin(9600); // $  : pinMode(redPin, OUTPUT); pinMode(greenPin, OUTPUT); pinMode(bluePin, OUTPUT); } &              : void loop() { //   %    , //    : if (Serial.available() > 0) { int inByte = Serial.read();
Глава 2 104 4   - "   ,                 .;,             ,       if,            : //      $  'r', 'g', 'b' // '0'  '9'. //    '    $ : if (inByte == 'r') { currentPin = redPin; } if (inByte == 'g') { currentPin = greenPin; } if (inByte == 'b') { currentPin = bluePin; } +,  ,     "        (   )          "   analogWrite(): if (inByte >= '0' && inByte <= '9') { //  $  -   //  $   analogRead(): brightness = map(inByte, '0', '9', 0, 255); //   $ '    // : analogWrite (currentPin, brihtness); }  } } 2  $        ,          , "      "               (  . 2.9). &              "         : r9 ;            . ;       : r2g7 Рис. 2.9. Значок монитора порта в панели инструментов среды разработки Arduino        ,       . =   : g0r0b8 7        . &! 7                . 4          ,    ,  ,   ,        ,           ,        . /      %        ,           . =                     Arduino IDE. _    ,            ,      Arduino       . ; ,    "   ,                   Processing.
Простейшая сеть 105 Несколько слов об ASCII  ,        ,                    ? / ,    $          ASCII.   ASCII             . *  ,    ASCII   'r' — 114,   '0' — 48. 2      ,              ,      ASCII. *  ,  $   : brightness = map(inByte, '0', '9', 0, 255);     $ :    ASCII  ‘0’         48,   ‘9’ —     57.                 ASCII               ,         . &                       ASCII        ,     —    ASCII $ . &               ,         . >        ASCII      ! «;   ASCII?»   $  . brightness = map(inByte, 48, 57, 0, 255); Усложняем задачу В предыдущем проекте мы управляли микроконтроллером с компьютера, используя для этого очень простой протокол. На этот раз уже микроконтроллер будет управлять анимацией на компьютере. Коммуникационный протокол для этого проекта будет более сложным. Проект 2 Мартышкин пинг-понг (Monski Pong) В этом проекте мы, по сути, создадим аналог компьютерной мыши. Ведь если рассматривать мышь в качестве объекта данных, она будет выглядеть, как показано на рис. 2.10: есть сигналы на входе, есть реакция на выходе. Требуемые компоненты  9    , 2 %.      , 2 %.  9     4 0, 4 %.  >       , 1 %.  #  Arduino  (   . 2.11      MKR1000,   ! —  Arduino 101), 1 %. +       :   ,   , X3 (UART).     Рис. 2.10. Представление мыши в виде объекта данных Вывод: 4 значения: Ввод: движение по оси X 1 2 — координата Х, 10 битов — координата Y, 10 битов — кнопка 1, 1 бит — кнопка 2, 1 бит Кнопки ввода  .  * %   %   %, 1 %. Ввод: движение по оси Y
Глава 2 106 1 5 10 15 20 25 30 5 10 15 20 25 30 25 30 Принципиальная схема Показаны только задействованные выводы +3,3 В I G H F C D E A B A B C D E F G H I J J 1 Макетная плата с модулем Arduino 101/Uno +3,3 В +3,3 В Резистивный датчик изгиба сопротивлением 15 кОм 10 кОм Резистивный датчик изгиба сопротивлением 15 кОм 10 кОм сброс Модуль микроконтроллера 4 Analog0 5 подача 10 кОм 10 кОм A1 Общий («земля») 5 10 15 20 5 10 15 20 25 30 A B C D E F G H I J 1 A B C D E F G H I J 1 Макетная плата с модулем MKR1000 Рис. 2.11. Монтажные (вверху и внизу) и принципиальная (в центре) схемы проекта «Мартышкин пинг-понг». Датчики здесь — для удобства вычерчивания — показаны с короткими проводами, но для реального проекта датчики нужно подсоединять проводами значительно большей длины
Простейшая сеть '         %  ,      . & %          %      ,  . 0                        .             ,       %     %     "       . +           .       —   ,         . 2                —                   .    : «#  »  «».        ,      . 2.11.    %     %   %,       . &  ,       %,         107   "          (  . 2.12). 9 "       %         ,            . +             -      ,                   , —      %         . X  ,                   ,               . ~ %            —   %            $   ,        . = $                  . & " ,            ,                $       . 9           $           . Рис. 2.12. Закрепите датчики изгиба на какой-либо плотной основе и прикрепите их к рукам мартышки
Глава 2 108 Пишем код ;          Arduino  " ,       . &        Arduino —                           9600    ,        1 —         "  : 284,284,1,1 285,283,1,1 286,284,1,1 289,283,1,1        ,         ,              . /* Z  $ : Arduino   Z  $    - - - # %- -   - $ .  - ' : ˆ   —     A0  —   # %  4 5 */ const const const const int int int int int int int int leftSensor = A0; rightSensor = A1; resetButton = 4; serveButton = 5; leftReading = 0; rightReading = 0; resetReading = 0; serveReading = 0; A1 // // // //             # %     # %     // // // // $       $             void setup() { //      : Serial.begin(9600); // configure the digital inputs: pinMode(resetButton, INPUT); pinMode(serveButton, INPUT); } void loop() { //   $  -  : leftReading = analogRead(leftSensor); rightReading = analogRead(rightSensor); //   $  # %-  : resetReading = digitalRead(resetButton); serveReading = digitalRead(serveButton); // + $   R: Serial.print(leftReading); Serial.print(','); Serial.print(rightReading); Serial.print(','); Serial.print(resetReading); Serial.print(','); /*   R  $      ' % # printlin(),    $ $    : /* Serial.println(serveReading); }
Простейшая сеть ;           ,     $   ,  " : 9     $             : .,P,, (,F,, (,A,, ),I,, 109 Serial.write(leftReading); Serial.write(44); Serial.write(rightReading); Serial.write(44); Serial.write(resetReading); Serial.write(44); /*   R  $      ' % # printlin(),    $ - $    : /* Serial.write(serveReading); Serial.write(10); Serial.write(13); Возвратите прежний код         "   ,           $          Processing,                 . '      ? &            Serial.print(),     $            ASCII,     "   Serial.write()    $  « »    . 7    (             )   ,           ASCII, $           ASCII      « »     . *  ,    13  10     ASCII «   »  «   »,     44 —   . /                     . +             (leftValue, rightValue, reset  serve). &      ,            ,   , 65,    «A»,   $  ASCII      -   65.       ASCII           www. asciitable.com.             ,           —      (« »)       ASCII? /          , "  ,          ,         .                              . *       ,     $   ,    ASCII.   ,  ASCII    ,                 " $ . =    «7  %  - »         ASCII (  ) ,    ,    ,   $     .
Глава 2 110 Что такое ASCII?  ASCII (American Symbolic Code for Information Interchange,              )     1967 .    American Standards Association8 (         ANSI9)     ,            "     ,           . /              ,           . &             ,        ,  $                 .   ,        ,    ASCII           ,   "         —                (   ), 8 3         . ANSI, American National Standards Institute — 3         . 9 4   " $  ,        «#     »        ,         . =%                  ,             ASCII 10  13    . ;  ,   "                    . /                 32      ASCII (ASCII 0–32). =  128    ASCII       ,            ,    "  . * $                ,   "                             . $   "     ASCII               "        ,      Unicode        ASCII. Unicode      , "       . $     ,                - . /            ,       Arduino. =        %     Processing. Пишем код #     Processing       " : /*     : Processing */ import processing.serial.*; //       // Processing       Serial myPort; //     String resultString; // Z    $  void setup() { size(480, 130); //   $    printArray(Serial.list()); // +  R  //     // Œ    $   .
Простейшая сеть 111 // ^   '    //     , // R  ' Serial.list()[0]. // \$   0     , //   '  : String portName = Serial.list()[0]; //   : myPort = new Serial(this, portName, 9600); //       %,     //   (ASCII 10): myPort.bufferUntil('\n'); }    void draw() { // $ # % $    : background(#044f6f); fill(#ffffff); //    : if (resultString != null) { text(resultString, 10, height/2); } } /* & serialEvent()         $,    % $     $  ,    bufferUntil()  #  setup(): /* void serialEvent(Serial myPort) { // Z   $   %: String inputString = myPort.readStringUntil('\n'); //    $  //   $  : inputString = trim(inputString); //     ' resultString: resultString = ""; // $ - '   $ $ //   %   #  : int sensors[] = int(split(inputString, ',')); // Š $    $ : for (int sensorNum = 0; sensorNum < sensors.length; sensorNum++) { resultString += "Sensor " + sensorNum + ": "; resultString += sensors[sensorNum] + '\t'; } // + $   R: println(resultString); }
Глава 2 112 Текст или двоичный код? 0     "                       .  ASCII        Unicode                   ,    ,  - .                    ,      ,                     $       . Разве не все данные двоичные? *,     , . &    ,        . $              . *      "        ,                 . *  ,     «1-2-3, go». &  "     $     "    "     ASCII       . Символ 1 - 2 - 3 , g o ! Код ASCII 49 45 50 45 51 44 32 103 111 33 Двоичный 00110001 00101101 00110010 00101101 00110011 00101100 01000000 01100111 01101111 01000001 код *,         ,           "  ?                 RGB,            0  255:     %     " . &    ,            36  ,    9    . *                ,       %    . ; ,           ,     ". &      ,          ,                   . _%            (   , $         ),        ASCII  Unicode. &  ,      %    ,   $    ASCCI  Unicode         ,   %                                ,            . #   : 102,198,255,127,127,212,255,155,127, • 7   ,      %       ,  $      ,      ,               . 3                 ? =  . & $   80 . = ,             TTL-      9600    . 4            ( $           TTL  RS-232),     96 ,  ,        $ "       1/100    . & " -,     . 7   ,    "          (    0  255   256    ,  28,  8 ), $           %    . *            ,           ,  -      %       ,       (   )     ; •         ASCII  Unicode; •   %      ,             .
Простейшая сеть 113 Интерпретация двоичного протокола    $                   ,      "          ,  "   . *                  , "      , $                    ,        . $        . =                            . +        $             . >%      SPI  I2C   %   . +                        .   $          %               ,    . 7     $   %     (  16)        .   ,  %          0x,     Arduino,      C,    0b,   : 0b10101010. ;       ,      "      %    ? $2,508 0    —   2,          %   —   ,      103. ;    2        %    . '   $            ,                      .     %   "      ? 0b10010110 #   %           ,                 128,  27. 0  ,          ,         ,       . *  ,         7   API   XBee     2-      ,  "  Channel Indicator,             . & $ 16-     9 %        ,  " 6  — 4    ,    %    . +   $                "   . 4              , Channel Indicator      "      : 0111111000000000     ,   9- % ,   "     ,        " 6- ,   0,   "     ,      1,  " ,  $     . &              $ 2-     —        ,  $      ,      ,     . +               16-     ,       —    64-     .                 /   -         XBee. 9 %          3Z    10 , $              . ; ,              1023. 4          ,             3,   — 255. & %         $         0x3FF. '        ,         256 (3 × 256 = 768)                (FF = 255),       1023 (768 +255 = 1023). +  ,            256.
Глава 2 114 Польза шестнадцатеричного представления                ,  ,   ,      ,      %         ? /     ,     ,         16. *  ,   MIDI         ,       128    ,     ,            ,      16. &   "   .         0x9n         (Note On),  n        0  A  %       . ;,   0x9A          3 (    10       ). 3   0x8A        (note off)    3. ;  ,     ,      MIDI        16,           %       .                       "  :    (r — red),    (g — green)    (b — blue). *  :  = 0xFF0000 $ = 0x00FF00   = 0x0000FF 2  $,                "      %       . *  ,   0x26B0E7            " (0x26,  38    255),        (0xB0,  176)        (0xE7,  231). /                . Пакеты данных, заголовки, полезные нагрузки и «хвосты» ;  ,                (         % )    ( ,   "     Processing),               ,      . 0  , $          "   : Датчик левой руки Датчик правой руки Кнопка сброса (0-1023) (0-1023) (0 или 1) 1–4   1–4   1   '  $                ASCII 44,    . 7    "       . >        "   — $ !    ! ,            — « ». 2  !  . /     ,        —  . 2 — $        ,        "   ,          $  . &     ,       "             ,         ,   ,   ,    . ;  ,            ,    ,       "  . *            —          ,  "   " . & %    , Кнопка подачи (0 или 1) Символ возврата каретки, символ перевода строки 1   2       "     , $       " ,     "    " . &                "  ,   $.        "           ,      ,  , « ». =      "      !  . & %                               . #  Processing                ,   % 16-            . #"    %      %        ,         "      . &            ,     ,               " .
Простейшая сеть 115 0                   "   . 0             (      ,                   ),           . ;      %    Processing. 4       %,                     ,        . 2.13. ;        $  ,      - .    ,          Processing —     setup() —      $                   (       % ): Числа с плавающей запятой &              $        "  (floats),                    . *  ,         : 480  400 —   1,  1,2. ;                : 400  480 —   0,  0,833. #   ,                        . +  $           %    map(). Рис. 2.13. Вывод списка значений датчиков в окне апплета float leftPaddle, rightPaddle; //       //   int resetButton, serveButton; //      int leftPaddleX, rightPaddleX; //    //   int paddleHeight = 50; //        int paddleWidth = 10; //        float leftMinimum = 120; //          //   float rightMinimum = 100; //         //   float leftMaximum = 530; //         //   float rightMaximum = 500; //        //   void setup() { size(640, 480); //         String portName = Serial.list()[0]; //   : myPort = new Serial(this, portName, 9600); //       %,     //     (ASCII 10): myPort.bufferUntil('\n');  //      : leftPaddle = height/2; rightPaddle = height/2; resetButton = 0; serveButton = 0; //     leftPaddleX = 50; rightPaddleX = width - 50; //   noStroke(); }    :   :
Глава 2 116 ;       serialEvent()  "   ,    "         : void serialEvent(Serial myPort) { //          : String inputString = myPort.readStringUntil('\n'); //             //   : inputString = trim(inputString); //     resultString: resultString = ""; //            //       : int sensors[] = int(split(inputString, ',')); //        ,   : if (sensors.length == 4) { //        //  : leftPaddle = map(sensors[0], leftMinimum, leftMaximum, 0, height); rightPaddle = map(sensors[1], rightMinimum, rightMaximum, 0, height); //         //   : resetButton = sensors[2]; serveButton = sensors[3]; //         : resultString += "left: "+ leftPaddle + "\tright: " + rightPaddle; resultString += "\treset: "+ resetButton + "\tserve: " + serveButton; } } * ,      draw(),           (        % ). void draw() { // $ # % background(#044f6f); fill(#ffffff); $    : //     : rect(leftPaddleX, leftPaddle, paddleWidth, paddleHeight); //    : rect(rightPaddleX, rightPaddle, paddleWidth, paddleHeight); }
Простейшая сеть 117 9          ,       , . .     ,     . &    ,             %,          ,          . [  map()               ,       "   . = $  ,                %,                      ,         . 2       %,       ,             . 2%             . 2     $       leftMinimum, leftMaximum, rightMinimum  leftMaximum   setup().  $         ,        %            $  . * ,            . 0     "        .               $                  .            $     "      .                           . =   $                ,         setup(): int ballSize = 10; //    int xDirection = 1; //      !  //  //  : –1, : 1 int yDirection = 1; //      !  //  //  : –1,  : 1 int xPos, yPos; //        // !   3      setup()          : //    xPos = width/2; yPos = height/2; ;           : animateBall()  resetBall(). /          draw(): void animateBall() { //   !   : if (xDirection < 0) { //           if ((xPos <= leftPaddleX)) { //    !        : if((leftPaddle - (paddleHeight/2) <= yPos) && (yPos <= leftPaddle + (paddleHeight /2))) { //        !     : xDirection =-xDirection; } } }      :
Глава 2 118 //   !  : else { //        if ((xPos >= ( rightPaddleX + ballSize/2))) { //    !     //   : if((rightPaddle - (paddleHeight/2) <=yPos) && (yPos <= rightPaddle + (paddleHeight /2))) { //        // !     : xDirection =-xDirection; } } } //         if (xPos < 0) { resetBaVL(); } //         if (xPos > width) { resetBall(); }    :   : //          !       if ((yPos - ballSize/2 <= 0) || (yPos +ballSize/2 >=height)) { //        !   //    : yDirection = -yDirection; } //    !  : xPos = xPos + xDirection; yPos = yPos + yDirection; //  : rect(xPos, yPos, ballSize, ballSize); } void resetBall() { //       xPos = width/2; yPos = height/2; } 7        . *              . =    (         setup()          ) "     ,      ,     . =  "         . boolean ballInMotion = false; // int leftScore = 0; int rightScore = 0;   :  ! ?
Простейшая сеть 119 7       . 0  " $          draw():     if()              ,    if()   "  "  ,  ,     if()  "                       : //    !  if (ballInMotion == true) { animateBaH(); } 7     animateBall(),     ,                (       % ): //    -  $   : if (xPos < 0) { rightScore++; resetBall(); } //    -  $   : if (xPos > width) { leftScore++; resetBall(); } =          setup()      : int fontSize = 36; //  =     : //  !   ,  if (serveButton == 1) { ballInMotion = true; }   ! //  !   ,   //   !  : if (resetButton == 1) { leftScore = 0; rightScore = 0; ballInMotion = true; }        !    setup()         ,   " % : //       ,    PFont myFont = createFont(PFont.list()[2], fontSize); textFont(myFont); * ,       draw()          : //      # : text(leftScore, fontSize, fontSize); text(rightScore, width-fontSize, fontSize); & ! ;         «7  %  - » (  . 2.14). '          ,      %         ,         -    . Рис. 2.14. Игра «Мартышкин пинг-понг» на экране компьютера  : :
Глава 2 120 Управление потоком данных Возможно, вы заметили, что ракетки на экране не всегда плавно повторяют движения мартышкиных рук. Иногда ракетки движутся с отставанием от них, а могут на долю секунды и застывать. Причина этому — асинхронная связь между компьютером и микроконтроллером. ~  $                 , $    ,  "                     . &"                               ,  "      ,           . & %                       ,            .   ,      $  (Processing  %   ),      , —      =  $      "     startup()   Arduino ( .   «&    !      »   !. «4  2. *   - »). +   $ , Arduino    "      ,      Processing: 2        loop()   Arduino      if(),      (       % ): $  ,      "        ,               ,                         . #   ,            ,        ,           . #"                ,     %  % $    . &    ,     Processing    %   ,        ,                      ,                    . while (Serial.available() <= 0) { Serial.println("hello"); //  }     void loop() { //   ,         //        : if (Serial.available() > 0) { //          : //          —     // : int inByte = Serial.read(); //      #   ' // ... } }
Простейшая сеть *  "  %             serialEvent()   Processing, "    «7  %  - »: 121 void serialEvent(Serial myPort) { // '     myPort.write('\r'); //        } ;      $           . *% %     "  :          "hello"     ,    -  ,              . /            ,         ,       ,            . 4      ,        . ;     Processing       ,  "  .         ,  "     ,        serialEvent(),  $      .         ,       ,       ,      , —   $      . 4        (   ,  $   "hello"),    Processing     . +     Processing        serialEvent(). *%                 ,  ,    ,         ,       . ;  ,         Processing                 . 2            "  . /    %      Processing,  ""     ,        . * "    "  "hello",        ,    %   Processing   ,   "        , $ Processing         . ;                     !   . /                           . Проект 3 Беспроводной мартышкин пинг-понг Игра «Мартышкин пинг-понг» могла бы быть еще более занимательной, если бы сам Мартышкин не был привязан к компьютеру кабелем USB. Этот проект ликвидирует проводное соединение между микроконтроллером и персональным компьютером и вводит новые сетевые понятия: «модем» и «адрес». Приобретите адаптер Bluetooth 4  %   "       Bluetooth,        "  %   . 4       %     .
Глава 2 122 Bluetooth: многоуровневый сетевой протокол & $            —  Bluetooth,  "     :           ,               RX ( )  TX ( ),     ,  "        Bluetooth. ;          ,         Bluetooth                 .                   ,           .                 ,         —  . ;          ,      :         ,       "  +             ,        ,  "               . 7       Bluetooth                     .   $        —   —       "     . #        Bluetooth — $             ,      $    , "   Bluetooth Serial Port Profile, SPP10. =      Bluetooth      :        —   HSP11,      %   —   HID12.       Bluetooth        $  ,  "         13, " 10 SPP, Serial Port Profile —         . 11 HSP, Headset Profile —   % . 12 HID, Human Interface Device —    «  % ». 13 Service Discovery Protocol. Требуемые компоненты  2 %  .    2. " + -  #  Arduino  (   . 2.15      Arduino 101/Uno,   ! —  MKR1000), 1 %. +       :   ,   , X3 (UART).  >   9 &             ,  "    %  , 1 %.  q      2,1      , 5,5   % , 1 %.   7 Bluetooth Serial, 1 %.      , 1 %.                     Bluetooth. #   ,    Bluetooth    ,                           ,               . & $    Bluetooth    RS-232  USB,        %     $                             . +,      Bluetooth         «7  %  - »,      . 2.15 (     ! —     ,   —    ). &      Bluefruit EZ-Link  Adafruit,        Bluetooth Mate   SparkFun.          "         :   VCC  —  +5 &  ,  "    (GND) —  "   (–). #     TX  RX  Arduino   RX  TX  Bluetooth    .      ,     .
Простейшая сеть Стойте, разве плата Arduino 101 не имеет встроенного адаптера Bluetooth? 0     . * $         Bluetooth 4.0,        Bluetooth LE  Bluetooth Smart. /                       $    .   ,  Bluetooth 4.0              Serial Port,           . +     Bluetooth 4.0             "   . 3          Serial Port     Bluetooth 2.2,        Bluefruit EZ-Link  Bluetooth Mate,      ,   "                  TTL-Serial,     . & $         . +      Bluetooth              Bluetooth        ,              %   Bluetooth,   "         .   , $           Arduino     ,  "               (X3). Сопряжение компьютера с модулем Bluetooth '                Bluetooth,        $    . = $           Bluetooth, "            Bluetooth. * %  macOS        System Preferences,        Bluetooth. X  ,      Bluetooth        123    ,      Show Bluetooth status in the menu bar (0   Bluetooth     ).    ,                Bluetooth. 3  %  Windows 10            Bluetooth Settings (   Bluetooth) —         ,                          . &       Bluetooth  Ubuntu Linux     , $ %          BlueMan (Bluetooth Manager). = $    Z     Ubuntu,        BlueMan     $   . X   BlueMan,         D . & ,        Bluetooth,              Bluetooth Manager. 0    —                   Bluetooth,   %           . #   $                 00:3A:45:6C:9A: 06 — $   MAC- 14        . &                     . 2             . &    ,     Adafruit-EZ-Link-XXXX,  XXXX —          . 4              Bluetooth, $      Bluetooth —      . 4         ,   1234,       ! —                 . *   macOS              Adafruit-EZ-Link-XXXXSPP,   Windows —       COMX (    $     COM14). 14 MAC, Media Access Control —      . 
Глава 2 124         Ubuntu "      ]   —         ,               . *   '  ,                   %   Bluetooth: /dev/rfcomm0. Модификация программы микроконтроллера ' %     «7  %   »     Bluetooth,        .             Arduino.        Arduino    —   Arduino Uno  Mega,      RedBoard   SparkFun,  "       USB, $                      USB/ TTL-Serial. *     X3            USB/TTL-Serial,      TX ( )  RX (  )  . $     $        . *            Bluetooth    TX  RX  ,    %   . 3           USB —    Arduino 101  MKR1000,     USB     X3,          Serial. &  TX  RX        X3,          ,    "        Serial       Serial1. ; , "  ,  "    RX  ,     "   Serial1.read(),            TX "   Serial1.write(), Serial1.print()  Serial1.println(). $,  %        Bluetooth,      TX  RX  ,               Serial  Serial1. *   $               .                Bluetooth,         . 3                    . Модификация программы «Мартышкин пинг-понг»          Bluetooth      ,         . 2    «7  %  - »                 . /        %   Bluetooth.      $      portName    setup(): String portName = Serial.list()[0]; *  ,            Bluetooth        ,              : portName = Serial.list()[8] &        ,           USB-    . Завершающие штрихи: упорядочиваем и закрываем &           «>     %  - »      . = $              % ,      . 2.16 (          ,     . 2.15). &           %    "    .
Простейшая сеть 125 30 20 20 A B C D E F G H I J 15 15 30 10 10 25 5 5 25 1 A B C D E F G H I J 1 GND DSR Vin <TX X >RX X DTR STS 3Vout 3Vo V Макетная плата с модулем MKR1000 Принципиальная схема Показаны только задействованные выводы +3,3 В +3,3 В +3,3 В Резистивный датчик изгиба сопротивлением 15 кОм сброс Модуль микроконтроллера подача 10 кОм 10 кОм Analog0 4 5 Резистивный датчик изгиба сопротивлением 15 кОм 10 кОм TX A1 RX Общий («земля») 10 кОм Модуль Bluetooth Bluefruit RTS RX TX Vin +3,3 В CTS Общий («земля») 20 25 30 20 25 30 10 A B C D E F G H I J 15 15 5 5 GND DSR Vin X <TX 10 X >RX DTR 1 A B C D E F G H I J 1 STS 3Vo V 3Vout Макетная плата с модулем Arduino 101/Uno Рис. 2.15. Монтажные (вверху и внизу) и принципиальная (в центре) схемы проекта «Беспроводной мартышкин пинг-понг» с подсоединенным модулем Bluetooth
Глава 2 126 #    ,                  ,  "   ,            $    (  . 2.17).     - Рис. 2.16. Сборка проекта «Беспроводной мартышкин пинг-понг» на макетном шилде Рис. 2.17. Проект «Беспроводной мартышкин пинг-понг» в завершенном виде
Простейшая сеть 127 Проект 4 Arduino-совместимая плата своими руками Иногда в проекте требуется задействовать больше одного микроконтроллера, или — наоборот — для работы проекта достаточно только одного или двух выводов общего назначения микроконтроллера, что делает излишним включение в такой проект микроконтроллера с широкими возможностями. Бывают также ситуации, когда вместо использования одного микроконтроллера для выполнения ряда задач проще задействовать несколько микроконтроллеров, возложив на каждый из них ответственность только за одну задачу. Для таких случаев прекрасно подойдут микроконтроллеры Atmel семейства ATtiny. Эти небольшие микроконтроллеры ценой всего лишь несколько долларов можно программировать с помощью платы Arduino или ее клона по синхронному последовательному протоколу SPI.          ,      ,   MKR1000, Arduino 101   Arduino Uno,     %      . >%  $                !               . 7    "     ,                 ,            ,   "       . *      USB/TTL-Serial,    —   MKR1000  Arduino 101 —               . '  %         ,         ,     % —    %  .   ,  %          %            . ;   ,    "   8-   AVR-      Atmel       DIP15,          "       . 0            ATmega328T,        Arduino Uno. *              15 DIP, Dual-in-Line Package —       (  )       (      ). Требуемые компоненты  #  Arduino  (Arduino 101/ Uno  MKR1000), 1 %. +       : X3 (UART), SPI.  7    ATtiny84, 1 %.  >       , 1 %.      ;   , 1 %. (RGB)    9    . " -   220 0, 1 %. ,   ,     ATtiny84  ATtiny85. 0 $           /  "     (GPIO),            ,      +7 (  . 2.18). +                    ,                 ,             +7. ~         X3,                    SoftwareSerial.                 ,         "           "   .
Глава 2 128 & $      ,  "               "        Точка обозначает вывод 1      , —  ,  $        1. Выемка обозначает верхнюю часть корпуса Сброс Вход напряжения питания 3 (аналоговый ввод 3) 2 (аналоговый ввод 1, SCK)* ATtiny85 4 (аналоговый ввод 2) 1 (PWM, MISO) Общий («земля») 0 (PWM, ARef, MOSI) Точка обозначает вывод 1 Выемка обозначает верхнюю часть корпуса Вход напряжения питания Общий («земля») 10 0 (аналоговый ввод 0, ARef)* 9 Сброс 1 (аналоговый ввод 1) ATtiny84 8 (PWM) 2 (аналоговый ввод 2) 3 (аналоговый ввод 3) 7 (аналоговый ввод 7, PWM)* 4 (аналоговый ввод 4, SCK)* 6 (аналоговый ввод 6, PWM, MOSI)* 5 (аналоговый ввод 5, PWM, MISO)* *Здесь: • • • • • SCK — тактирование; PWM — ШИМ; MISO — вход ведомого, выход ведущего; ARef — опорное напряжение; MOSI — выход ведомого, вход ведущего. Рис. 2.18. Распиновка микроконтроллеров ATtiny84 (вверху) и ATtiny85 (внизу) Использование Arduino в качестве устройства ISP     Arduino Un                  %   ,       !  !  (bootloader)   ,         ,         . 4    $            X3 (UART). 4  $           ,              -        . >  $            Arduino     USB. *             . &              ICSP16  16      $           ICSP  ISP, In-Circuit Serial Programmer —            .
Простейшая сеть 129 Введение в интерфейс SPI =            $                            ,  "   SPI17. +   SPI               I2C18 (            TWI19)                   ,    -        . /                     —   ,   Wi-Fi   MKR1000  SD-  ,      .                       "    ,               (       )   "         .  "                ,       %                  . +   SPI              "     ( "    ,    )      (  )    : •        (SCK) —  ,   "            (    ); • = $, =  (MOSI, Master Out, Slave In):  $    "                    ; • = $, =  (MISO, Master In, Slave Out):  $                    "     . 4                " ,   MISO    ; •   (SS, Slave Select)   = (CS, Chip Select) —    %              , 17 SPI, Serial Peripheral Interface —               . 18 2 I C, Inter-Integrated Circuit — %            . 19 TWI, Two-Wire Interface —       .        CS       "    . '             ,  "              $   . 4   $          ,        % . Master Slave 1 Chip Select 1 CS MOSI MOSI MI SO MI SO Clock CLK Chip Select 2 Slave 2 CS MOSI MI SO CLK      SPI                   AVR, %    $    ,  Arduino Uno      ,  "  ICSP,        SPI. /      "  : Белая точка обозначает вывод 1 1: MISO 2: Вход напряжения питания 3: SCK 4: MOSI 5: Сброс 6: Общий («земля») 4  %      ICSP,       ,         ,       . *   SPI                 . &  "             SPI     Arduino Uno, 101  MKR1000: Функция MOSI MISO CLK Uno 101 MKR1000 11  ICSP4 12  ICSP1 13  ICSP3 ICSP4 ICSP1 ICSP3 CS 10 10 8 10 9      
Глава 2 130   SPI.                ,              "              .           ,           ,               .                    " -   "       — ,            AVR        AVRISP mkII   Atmel  USBTinyISP   Adafruit. #       Arduino           ,    — ArduinoISP —   "    Рис. 2.19. Монтажные (вверху) и принципиальная (внизу) схемы программирования микроконтроллера ATtiny84 с помощью платы Arduino (вверху слева) и MKR1000 (вверху справа). Полукруглый неглубокий вырез на одном конце микросхемы ATtiny обозначает ее верх, а круглое очень мелкое углубление с одной стороны этого выреза — физический вывод 1 микросхемы (это стандартная маркировка микросхем в корпусе DIP) Макетная плата с модулем Arduino 101/Uno Макетная плата с модулем MKR1000 A B C D E F G H I J 1 1 5 5 10 10 15 15 20 20 25 25 30 30 A B A B Принципиальная схема Показаны только задействованные выводы C D E F G H +3,3 В К выводу MOSI программатора Сброс F G H I J 1 5 5 10 10 15 15 20 20 25 25 J 30 Vin К выводу CS программатора I C D E 1 30 A B C D E F G H I J ATtiny84 6 Общий («земля») 4 К выводу SCK программатора 5 К выводу MISO программатора
Простейшая сеть 131  Arduino  ICSP-   . 0   $       ,           \ |    | ArduinoISP,        ,            . 2       ATtiny84   Arduino,      . 2.19. *      ATtiny84        ,              Arduino. ;  ,     $    1 ( . ! «*  »),        \ | ]          !      " A    "  : http://www.leonardomiliani.com/repository/package_leonardomiliani.com_index.json. 2     OK       . &             |       ATtiny. =        AVR        . *  ,       ATmega328P           Arduino Uno,   ATmega2560 —       Arduino Mega. =           ATtiny          . /                           20.    $               ,       ,     . . &           ATtiny84       : ? : ATtiny; ? Processor: ATtiny84; ?  : 8 7q (  ?  :  ,     ,           . 20  ). 0  . fuse —      . = $         ATtiny24/44/84,                   Micro. &   $     $   ATtiny84@8 MHz (internal oscillator; BOD disabled),           ,          .                           Arduino as ISP —               %  Arduino             ATtiny. 2          #    (Burn Bootloader),       .   %                 "  #      +  (Done Burning Bootloader). ;               ATtiny84. 4     ,              ATtiny84    ATtiny84@8 MHz (internal oscillator; BOD disabled). /   ,                  %       ,              .                ATtiny  ,       , — $        ( +3 &  +5 &),            %"       . &   $  ,                Blink («7»). *                    13-  6              D  | #       . &        Arduino    %  Arduino                        ATtiny. 4        6      ATtiny   ,    ,           .
Глава 2 132 Библиотека SoftwareSerial и управление яркостью светодиода с помощью ATtiny 7    ATtiny                     $  —              :          . = $              /  6, 7  8 ATtiny84. /             +7 —     +7  Arduino 101  MKR1000,     $  . 2      Arduino   «X        »           ,  $     . Пишем код =         —        SoftwareSerial    $   $                      "  /  (GPIO). 7      0  1: #include <SoftwareSerial.h> // SoftwareSerail: ;             : //   -        : const int redPin = 8; const int greenPin = 7; const int bluePin = 6; =         '    SoftwareSerial swSerial(0, 1); // RX, TX   Serial  swSerial. >  SoftwareSerial       print(), println(), read(), write()  available(),        Serial. 2           ATtiny84,    Arduino       ,    ,       «7». 2                       USB/TTL-Serial (  . 2.20). &  TX         0 ( ,     )     ,    RX —    1.             -   ,       « »  «" »      "       . 2     CoolTerm           ,                       ,   $         . *  : r5g3b7 `               ,         . 0     ,   $      ,          %      .
Простейшая сеть 133 Макетная плата с установленным на ней микроконтроллером ATtiny84 и подключенным адаптером USB/TTL-Serial A B C D E F G H I 1 J BLACK 1 GND CTS VCC TX 5 5 RX RTS GREEN TX 10 10 15 15 20 20 25 25 30 RX 30 A B C D E F G H I J Принципиальная схема Показаны только задействованные выводы Общий («земля») CTS Vcc* TX 10 кОм Адаптер USB/TTL-Serial RX RTS Напряжение питания микроконтроллера ATtiny84 Сброс 0 1 ATtiny84 8 7 220 Ом 6 Общий («земля») *Напряжение питания с адаптера USB/TTL-Serial Рис. 2.20. Монтажная (вверху) и принципиальная (внизу) схемы реализации проекта управления яркостью светодиода с клавиатуры на микроконтроллере ATtiny84. Питание на микроконтроллер и сопутствующую схему подается через адаптер USB/ TTL-Serial из порта USB компьютера. Поскольку микроконтроллер ATtiny84 и светодиоды могут работать на напряжении величиной как 3,3 В, так и 5 В, величина подаваемого адаптером напряжения не имеет значения. Подключенный к выводу сброса микроконтроллера повышающий резистор номиналом 10 кОм не допускает произвольного сброса микроконтроллера, удерживая на этом выводе высокий уровень напряжения. Сброс микроконтроллера осуществляется кратковременным замыканием вывода сброса на землю
Глава 2 134 Эмуляция последовательных портов: библиотека SoftwareSerial X           (X3)      (    0  1,   RX  TX)     "          ,    ,      $     "    . /   ,                 X3                  . *   ,         Arduino %                 ? /      %   "             X3. *  ,  Arduino Mega2560      X3. *         $       X3     ,       %        . &          "    SoftwareSerial. 0        $                          $  X3. >     "   $  ,        "   .         SoftwareSerial X3       ,                ,     X3,     %        4800 /  57,6 / . /                      —   ,   ATtiny. &  , $                        X3 —   , Arduino Uno,  ,                        $     X3     . ~                 ,                         . *  ,     ESP8266,       $    ,              Wi-Fi,      %    ,              1 . $    ,           —   ,  «7  %    », $          . *                       ATtiny84  ATtiny85.  . &      $          ,            ,         . &  ,   ,                     ,               . *  ,                                      # "    Arduino                     AVR,                  . +        ,          Arduino         "     : ?  ATmega328P — " Arduino Uno; ?  ATmega168 — "  Arduino Diecimila  Duemilnove; ?  ATmega8 — "  Arduino NG     ; ?  ATmega2560 — "  Arduino Mega2560; ?  ATmega32U4 — "  Arduino Micro.
Простейшая сеть 135    ,        Arduino Uno,          Arduino-  ,   +   . 3         $   ,         "     : ? ? ? ? ATtiny84; ATtiny44; ATtiny 85; ATtiny45. *  . 2.21                      Arduino Uno         . 2            ,             ATtiny:     SPI           ,      Arduino Uno,       . +               ,   ,        ATtiny      ATmega328P.     %      %  ,     " 30 25 20 10 J Принципиальная схема Показаны только задействованные выводы F G H I RX TX RTS GREEN VCC CTS BLACK 5 GND F G H I J 1 78xxl 15 TX RX Макетная плата с установленным на ней микроконтроллером ATmega328P и подключенным адаптером USB/TTL-Serial Общий («земля») C D E A B 30 25 20 15 10 5 C D E Vcc 1 CTS A B ATMEGA328 TX Адаптер USB/TTL-Serial RX RTS Стабилизатор напряжения 7805 +9-12V In* +5 В Out** 10 кОм Сброс *Входное напряжение **Выходное напряжение Напряжение питания 0 (RX) 22 пФ 1 (TX) ATmega328P Кварц Кварц 22 пФ Общий («земля») Рис. 2.21. Монтажная (вверху) и принципиальная (внизу) схемы для сборки на макетной плате совместимого с Arduino Uno микроконтроллерного устройства на основе микроконтроллера ATmega328P и адаптера USB/TTL-Serial
Глава 2 136 2        ,        ,    USB/TTL-Serial, —       $              .       . 2.21         -   5 &     ,        %           9–12 &. 9        ATmega328P       : www. arduino.cc/en/Hacking/PinMapping168. Заключение Проекты, рассмотренные в этой главе, поясняют несколько понятий, являющихся базовыми для всех типов сетевого обмена данными. Прежде всего запомните, что обмен данными основан на последовательности уровней соглашений: первым идет физический уровень, затем электрический, логический, уровень данных и, наконец, уровень приложений. Имейте эти уровни в виду при разработке и диагностировании своих проектов, так как это облегчит вам задачу локализации проблем. ? ' :   ,               ASCII,           (« »)    .   $      ,        ,             . *  ,                , ,   ,        %           ASCII. ? % :          " ,     ,       ,     %         . /    %    .               : ,     « »,           . ? J :         "            %             .      « - »            . ? :     ,  "         %   ,            USB/TTL-Serial          Bluefruit. &                  ,                       ",     % . ? ]  ,                         ,         . #       ,               ,       ATtiny,                             . /                      "    . *   ,                       . & $    " "            . JitterBox. Автор Габриель Барсия-Коломбо (Gabriel Barcia-Colombo) JitterBox21 — $           ,        40-   %  ,          . 4     —        ,        . ; "           ,        ,  "  ,       ,         Arduino,                           40-   %  . /     ,      "      . & JitterBox    " 9 7 (Ryan Myers). 21 JitterBox —     jitterbug (      )  jukebox (         ).
Простейшая сеть 137

Глава 3 БОЛЕЕ СЛОЖНАЯ СЕТЬ Теперь, когда мы обладаем основными знаниями о сетевом обмене данными, можно перейти к более сложным вопросам. И лучше всего начать с самой знакомой нам сети передачи данных — Интернета. По сути, это не одна сеть, а система сетей разных поставщиков сетевых услуг, которые связаны между собой с помощью определенных общих протоколов. В этой главе мы рассмотрим структуру Интернета, а также устройства и протоколы, которые соединяют эту сеть в единое целое. Вы на практике познакомитесь с закулисными сторонами работы веб-браузера и клиента электронной почты и научитесь использовать сообщения этих сетевых средств для подключения своих объектов к Сети. Сетевые цветы Дории Фэн (Doria Fan), Маурисио Мело (Mauricio Melo) и Джейсона Кауфмана (Jason Kaufman) # "        «#    »             "  . X              -  ,             "   .
Глава 3 140 Компоненты для проекта этой главы Коды поставщиков ? A — Arduino Store, http://store.arduino.cc ? J — Jameco, http://jameco.com ? AF — Adafruit, http://adafruit.com ? RS — RS, www.rs-online.com ? D — Digi-Key, www.digikey.com ? SF — SparkFun, www.sparkfun.com ? F — Farnell, www.farnell.com ? SS — Seeed Studio, www.seeedstudio.com Рис. 3.1. Новые компоненты для проекта этой главы: 1. Резистивные датчики давления серии 402 компании Interlink. 2. Провод для монтажа накруткой диаметром 30 AWG. 3. Инструмент для монтажа накруткой (в ручку инструмента вставлено приспособление для снятия изоляции с провода). 4. Веб-камера. 5. Резиновые подкладки. 6. Листы толстого картона или фанеры для основания под датчики давления 3 5 6 4 1 2 ПРОЕКТ 5. Сетевой кот  "      , 1 +. = $             Arduino . &            Arduino 101,   Arduino Uno,  MKR1000        . Arduino Uno — D: 1050-1024-ND, J: 2151486, SF: DEV-11021, A: A000099, AF: 50, F 1848687, RS: 715-4081, SS: ARD132D2P  "     ATtiny84. '        ,      $     . MKR1000 — AF: 3156, RS: 124-0657, A: ABX00004, GBX00011 (3   4#), D: 1659-1005-ND D: ATTINY84A-PU-ND, SF: COM-11232, F: 1455160, RS: 738-0684  (        400  Interlink,  2  4 +. &          402,     400        . Arduino 101 — D: 1660-1003-ND, J: 2239331, SF: DEV-13787, AF: 3033, F: 2520713, RS: 9139999, SS: 114990575, A: ABX00005, GBX00005 (3   4#)
Более сложная сеть 141 D: 1027-1001-ND, J: 2128260, SF: SEN-09375, A: 166  (    1 , 1 +. _ . D: 1.0KQBK-ND, J: 690865, F: 9339051, R: 7077666  C      , 1 +. D: 438-1045-ND, J: 20723  20601, SF: PRT12615  PRT-12002, F: 4692810, AF: 64, SS: 319030002  319030001       > .  ]=   =                .      "   . '-  , 1 +.    . 4      &       , 2 +.            .      A   . D: K386-ND, J: 22577, F: 09WX4670  (    . D: 3M156065-ND, RS: 120-6041, J: 2119718, A: 550, SF: C0M-10594, F: 1165068        A   . D: K445-ND  WSU-30M, J: 2150361, F: 441089  H  ). D: A26509-20-ND, J: 103377, SF: PRT- 00116, F: 1593411    USB/TTL-Serial.    ,             ATtiny.  ,      . SF: DEV-09716  DEV-14050, A: 3309  284, SS: 317990026      , 1 +. Сетевые топологии и сетевые адреса Задача отслеживания маршрутов сообщений из предыдущей главы была простой, так как созданная нами сеть состояла только из двух узлов: отправителя и получателя. Но в любой сети, состоящей из более чем двух узлов: от трех до трех миллиардов — нужна карта сети для отслеживания объектов, с которыми установлено соединение. А чтобы сообщения доставлялись по месту назначения, требуется схема адресации. Сетевые топологии: как соединяются объекты? 0               %  "   .  "     —            . ; - "                .           ,                             (  . 3.2,  ). #"       —         (    ) Рис. 3.2. Три типа сетевой топологии: полносвязная (слева), звездообразная (в центре) и кольцевая (справа) Прямое соединение узлов сети Топология «Звезда» Топология «Кольцо»
142   "   "           . ;      ! ! ! (  . 3.2,  )       ,      ,            .   ,   %            ,    %    ,           " . ;    —         (  . 3.2,  ).                 ,   "               ,  "                %   ,         . ) %   *   ( +             (  . 3.3). &               (        )          (    %   ). 3                        %     Рис. 3.3. Сложная многоуровневая звездообразная сеть Глава 3 (        ).   $         %                $    ,     "                     . ;          ,               ,     "            "             ,           -       "         . #                  . 4           ,   "            . *   %       ,               ,                       .     ,           ,        %    , $          ,    ,         ,   %                               . ; ,            +  ,              $ . *         ,           ,       ,   %      %   . =                        ,     . 3.2, $      . *            ,    ,      $           ,  " +  .
Более сложная сеть 143 Модемы, хабы, коммутаторы и маршрутизаторы =              ( .  . 3.3),      +  ,         . *           ,  (    ),    %  (  ). &        % ,          $    . 9            ,          . * —    ,                            . &            DSL- ,  " +    %   . /          %  %       ,        ,                 ,              ,     %   "   +  .  $           Bluetooth,          2,         $            . =  (    )        ,       (    )               "            . =      ,      " , —             . &         Адреса аппаратные и сетевые *       :       ,           —                  -         .                      . *     $         " "               $   . ;,     Bluetooth    2   "    " ,        $ "   "   ,       . ~         ,                 . >      ,      %        "      . &    ,     " ,  "           ,       ,       . 0    ,    ,   ,           (     %    DSL-  ,     ),      !                  . 0                     . 7 %                ,  "               ,            ,    $      %  . 7 %        IP-     ,  "  ,            %  . *     %     +   —     , DSL-      , — %       $           %  .             Bluetooth. 3         +       1  IEEE , ,     ,      IEEE 802.x. *  , %  %          ,   ,        Ethernet,                   IEEE 802.3. 3         Ethernet — Wi-Fi — 1 IEEE, Institute of Electrical and Electronics Engineers — +      $      $   (#3).
Глава 3 144                IEEE 802.11: 802.11a, b, g  n. #   %     $  . ;           Bluetooth         IEEE 802.15.1. &        802.              MAC-   2. MAC- ,    ,        6-    ,                  $              Ethernet    . =     MAC-              IEEE     MAC- . MAC-                       . =       Ethernet  Wi-Fi +           IP3. IP-        #  !    ,     , . . MAC-  ,     ,  !         . 4      ,  !# IP-    ,  #     !   %     *G&-  ,   !       IP-  . '         !             IP-    MAC-   . 4   "    ,    IP-  MAC-    , $      "  : ? 2  %  macOS         ,              System Preferences | Network. /                ,           +  . #  , %      "     MAC- (  . Media Access Control) —        . 3 IP, Internet Protocol —   - . Ethernet-     Wi-Fi. 0 $         IP- ,     ,              . *   Advanced    ,     Hardware,          MAC-  ,   TCP/IP,          IP-  ,     ; ?  %   Window 10         (   ,       |     ),         "     D   . 0        Wi-Fi,  ,      %    .         "     !      . 0        —    D,  "      IP-    ; ?  %  Ubuntu Linux      D ,             ]  | D  > . 0     ,  "         . &            ,        ,          . *  . 3.4              %  macOS ( )  Windows (). *             , MAC-  IP-    "   : ?       %    %       —   : 00:11:24:9b:f3:70; ? IP-               ,    , —   : 192.168.1.20.       IP-  ,      " ,   %  ,      ,      MAC- ,      IP- . $,  
Более сложная сеть а 145 б Рис. 3.4. Диалоговые окна параметров сетевого подключения для машин под macOS (а) и Windows (б)        ,              ,       . Улица, город, область, страна: структура IP-адресов             %   ,    "  (   )       (      ).      , IP-        . *      IP  —    ,            .  % "   IP-      ,     . 7 %         ,       ,   IP-   ,          . q  IP-       ,          . & ,   ,  IP-  217.123.152.20. 7 %  ,     $  ,  ,   ,    217.123.152.1. 2            0–255,      %            . *  ,  %        XXX.XXX.XXX.1.   $  % -   %            217.123.152.XXX. +   %       %          ,           %  . ;       217.123.1.1.     %                     .    ,    %     ,          . ;        : 255.255.255.0.                . 9      $   ,           . '    ( )   32 .  ,      ,             $  .  ,            ,                    255.255.255.255. *  ,       255.255.255.255         —   %  . 4            0 ( . . 3.1), $       —   
Глава 3 146  %   —   255  ( .255      %  "   "  ).     255.255.255.192     62    %  (255 – 192 – 1 = 62)    . *               -         ,                   %. & . 3.1    "               "           . Таблица 3.1. Соотношение между значением маски подсети и максимальным количеством поддерживаемых узлов этой подсети Маска подсети Максимальное количество машин в подсети, включая маршрутизатор (учитываются зарезервированные адреса) 255.255.255.255 1 (   %  ) 255.255.255.192 62 255.255.255.0 254 255.255.252.0 1022 255.255.0.0 65,534           IP-                   "  . 0    $                         :  -  ,   $     *                IP-          ,        %     . .       . Частные и общедоступные IP-адреса *       +             . +          %     ,  %           ,     " "      ,    $   "    %  . &   IP-                  . /,   ,       192.168.XXX.XXX, 10.XXX.XXX.XXX  172.16.XXX.XXX  172.31.XXX.XXX. ;           %   %   . &     % %  ,   ,         $  . * " ,    %       %  ,    ,          "    IP-   %  . ;                NAT-  !  4. +  ,   %  ,        . 4 NAT, Network Address Translation —         . *   ,        192.168.1.45,  %   -        -  . /         %    % . =  %   %           192.168.1.1,       +          "     66.187.145.75. 7 %               "     ,       ,        $  "    .      -  ,  %              ( )   192.168.1.45. ;  ,               ,         "     "    IP- ,         "    ,      +  .
Более сложная сеть 147 Протокол ARP         ARP,  "            73#-    " IP- . ;  , "   arp     IP-         % %   ,             . 3               "   ARP5. &   ,   POSIX arp      5 ARP, Address Resolution Protocol —    %   . Просматриваем таблицу ARP 0          (    macOS  Linux,          bash  %  Windows)        "   ( ,   $      %      ,     ): 0      " : $ arp -a ? ? ? ? ? ? ? (192.168.0.1) at ac:b3:13:a1:d7:77 on en0 ifscope [ethernet] (192.168.0.2) at 0:17:88:a:17:45 on en0 ifscope [ethernet] (192.168.0.15) at 0:e0:4c:9:3b:3f on en0 ifscope [ethernet] (192.168.0.176) at (incomplete) on en0 ifscope [ethernet] (192.168.0.255) at (incomplete) on en0 ifscope [ethernet] (224.0.0.251) at 1:0:5e:0:0:fb on en0 ifscope permanent [ethernet] (255.255.255.255) at (incomplete) on en0 ifscope [ethernet]                  ARP %    —      %   . &          IP-    ,     (  at) —  MAC- . &     arp -a,       $          IP-  .   ,     73#  %       IP- . # (incomplete)   ,        —   ,      $        ,   - ,  $    ,            . Команда ping: вы там?   arp     ,          ,       ,                     $  . # "           — ping —               IP- . /            "   «& ?»,       . Ограничения p i n g и a r p 0       —   , % ,      ,            ping. *        ,       $  ,              —     arp —                        . 4          ,        $  ,       %         . &               — $      %        .
Глава 3 148 0                 "   (  %   Windows      -  –n. +,   ,  $    — $    %     ): /        127.0.0.1 "      .  ,     ,    "  ,     . 0        " :   - $ ping -c 3 127.0.0.1 PING 127.0.0.1 (127.0.0.1): 56 data 64 bytes from 127.0.0.1: icmp_seq=0 64 bytes from 127.0.0.1: icmp_seq=1 64 bytes from 127.0.0.1: icmp_seq=2 &      ping              —               -c ( macOS/Linux)  -n ( Windows).       %           ,                    "   .                          " : --- 127.0.0.1 ping statistics --3 packets transmitted, 3 packets received, 0.0% packet loss round-trip min/avg/max/stddev = 0.056/0.061/0.072/0.008 ms &             %             %       ,      $. &    ,                       ,        —    ,             ,           $   . &      ping       ,         % . bytes ttl=64 time=0.056 ms ttl=64 time=0.056 ms ttl=64 time=0.072 ms 0                                                . Специальные адреса локальной сети 3 127.0.0.1 — $    ,  "      (loopback address)      ! (localhost address). #" ,     $  ,        . &           localhost. # "     localhost                             . =  $         $  ,                    ,    —     . &     arp      "     : X.X.X.255 ( X.X.X.            ). /           # . #"  
Более сложная сеть 149           .   "       ,   , ,              ,     %                  . +  %  "       ping,            ,      "    . Пробуем ping с широковещательным адресом 0                 "   (  —     Windows —   -  -n): 0      " : $ ping -c 3 192.168.0.255 64 bytes from 192.168.0.12: icmp_seq=0 ttl=64 time=0.102 ms 64 bytes from 192.168.0.4: icmp_seq=0 ttl=64 time=1.457 ms 64 bytes from 192.168.0.1: icmp_seq=0 ttl=64 time=12.232 ms 64 bytes from 192.168.0.12: icmp_seq=1 ttl=64 time=0.061 ms 64 bytes from 192.168.0.4: icmp_seq=1 ttl=64 time=1.672 ms 64 bytes from 192.168.0.1: icmp_seq=1 ttl=64 time=10.419 ms 64 bytes from 192.168.0.12: icmp_seq=2 ttl=64 time=0.062 ms --- 192.168.0.255 ping statistics -3 packets transmitted, 3 packets received, +4 duplicates, 0.0% packet loss round-trip min/avg/max/stddev = 0.061/3.715/12.232/4.877 ms Еще об ограничениях p i n g +     ping %  "          "          . &       Request timed out (  %       ). >        $        %        . 0      ,   $          192.168.0.255,         73#- . 7 %     "    192.168.0.255           6. $    %    $    —       ,   ,          ping. ;  ,            %  "     ping,    $  ,     IP-    6 3      $   . =                  .    .     %   , $            %    ,   ,       , " ,     ,    %            Ethernet      Wi-Fi. *            $    %  "     . /            ping,    %  . 4     %  "     ping       ,  ,      ,     % ,            5-  7-     ,    . Примечание *          "   %  "     ,         $       % %            .
Глава 3 150   ,   IP-       ,       ping     $ . /,  , %   -    ,       %            . Преобразование числовых адресов в имена & ,   ,   ,   $        ,    +          -    www.makezine. com  www.archive.net. /      ,                IP- ,    ,  ,     . 2 $         DNS 7,        -       IP- . /           —   DNS 8,    ,           . 0           ,   ,        DNS. *           $     %   "     DHCP 9,   IP- ,      $     . Коммутация пакетов: как сообщения путешествуют по Интернету? ;     "               ? /           ,  ,    . =           % % ",                 "  %  . '-           "   ,     Ethernet (           ) " -            ,      ,           !  ,  "   .                           "    ". ;         ,      IP         "  ,  "   "    "  . 0  "      ,           ,          .         "         . /                       . =         +           : TCP10  UDP11. 7    $        $    . 0           ,    TCP      ,    "   , ,     $,      ,     UDP,          ,         .   %      "          % . 4   %      "  %  12,         ,    . ;  ,      "         "  %  ,  10 7 DNS, Domain Name System —        . 8 DNS, Domain Name Server —     . 9 DHCP, Dynamic Host Control Protocol —           . TCP, Transmission Control Protocol —        . 11 UDP, User Datagram Protocol —         . 12 & "  %  —  %  ,   %  %      " " .
Более сложная сеть 151     $       "  %  . &                % ,  "       ( %  ) .             "  %                "  . 0      "   ( )      %         .   $       $         . =                              —                    . #   $      ,      ,         . +    %         %            . Клиенты, серверы и протоколы управления связью Теперь, когда у нас появилось представление об организации Интернета, давайте разберемся, как все это там делается. Например, каким образом сообщение электронной почты доставляется своему адресату? Или как ввод адреса в адресную строку браузера или щелчок на ссылке доставляет соответствующую веб-страницу на компьютер? В основе всего этого лежит обмен сообщениями между сетевыми объектами, использующими только что описанную систему их транспортировки. Рассмотрим это более подробно, используя в качестве примера просмотр веб-страницы. Как веб-страница попадает на компьютер? *  . 3.5   -            :              -  ,   -      %      .    %      "             ,    ,    ,    %  "  . Рис. 3.5. Путь веб-страницы от веб-сервера к браузеру пользователя. Географическое расположение физических компьютеров не имеет значения, если известны адреса веб-сайтов Сервер веб-сайта Поставщик сетевых услуг веб-сайта Интернет Поставщик сетевых услуг веб-сайта Сервер веб-сайта     - Ваш поставщик сетевых услуг Ваш кабельный или DSL-модем Ваш маршрутизатор Ваш компьютер
Глава 3 152 # -  — $   ,   "    ,     -  +   ,    "         # .  ,             ,        ,      ,        #        ,        .          & -  HTML,   ,      $     "     -           +  . >  — $     ,     ,       . *  , %   ,      ,         ,      -   . #                      (    )   ,   "  -    ,  %  . #       IP-      "        ,            . *  ,     -           80,      $        $    -  . 3              25,      $       . _                 ,               . & $  %                . 7  %                 — ,     $     ,     (FTP), telnet   -  . # %       ,               (         ). >                -       "  :      1. &      (URL)  -  : http://www. example.com/index.html. 2.               www.example.com    80. 3. #            . 4.        %      -  : index.html.  - 5. #        %            ,                  $   . 6. >       ,               -       (   , -    ,    . .)             $  ,              .      ,                 . &        ,             (            ),       . X  $            ,         . 0        ,   $    ,       ping. * %   Windows       PuTTY. Версия telnet для Windows &  telnet, "    Windows,        . *  ,       localecho,          $  ,        "    Trying... Connected. $          PuTTY.
Более сложная сеть 153 Обращаемся к серверу &         "    % <Enter>. $ telnet www.example.com 80 #      "  : Trying 64.233.161.147... Connected to www.example.com. Escape character is '^]'. =    "  (       ,   ,    .          % <Enter>  ): * $       : GET /index.html HTTP/1.1 Host: www.example.com Connection: Close   - HTTP/1.1 200 OK Cache-Control: max-age=604800 Content-Type: text/html Date: Hon, 11 Apr 2016 15:51:58 GMT Etag: "359670651+gzip+ident" Expires: Hon, 18 Apr 2016 15:51:58 GMT Last-Modified: Fri, 09 Aug 2013 23:54:35 GMT Server: ECS (lga/1384) Vary: Accept-Encoding X-Cache: HIT x-ec-custom-error: 1 Content-Length: 1270 Connection: close   $        HTML — $ HTML-         -   www.example.com. +       -        — "      HTTP13.   http://     -           $          . # ,  % 13 HTTP, HyperText Transfer Protocol —       .  Выход из telnet 4     telnet        ,    % <Ctrl>+<]>,        %  telnet       quit. "  HTML,     !   HTTP. 2 HTTP     , ""   ,       ,   $        .      $        ,                      .
Глава 3 154 Создаем веб-сервер      -  ,    " node.js    1? ~         ,    , $    "  -  , "   HTTP. $      ,                 -       . #    "    %   —               "  . & $           ,             ,                . Пишем код &        "        server.js         dateServer.js. 2    ,     1,       $     :        - $ node dateServer.js ;      "       ,    telnet  localhost (  127.0.0.1)    8080     $        . &    $           " ,  "  HTTP   "        : /* Z  : node.js */ var express = require('express'); // ' //    express: var server = express(); // $ " server, // $     express //  % # ',  $ //    $   : function respondToClient(request, response) { //      : response.writeHead(200, {"Content-Type": "text/html"}); response.write("< " + new Date() + ">"); response.end(); } //   : server.listen (8080); //        server.get('/*', respondToClient); $  : Примечание HTTP/1.1 200 OK &       dateServer.js   X-Powered-By: Express  ,     server.js,    ,   Content-Type: text/html     express.js   : Date: Tue, 11 Apr 2017 16:43:39 GMT Connection: keep-alive npm install express Transfer-Encoding: chunked < Tue Apr 11 2017 12:43:39 GMT-0400 (EDT)> ~  -   ,     ,    ,    "   ,          ,  %      Processing          . = $              <  >.         ,   HTTP            —             ,                . =                     %          .  
Более сложная сеть 155          HTTP    "   : 2             : name  age,      tom  14    .                ,    "     (&).       HTTP     «-!  ».           . &             request,  req,       "   :   %"     ,     ,             %"     ,    ,     ,      . 7       "    $   ,        response (         res),  "  "    . >  HTTP   node.js         , "     $         =         HTTP GET,  ""        ,            . http://localhost:8080/?name=tom&age=14 Пишем код # "    node.js                  $  : /* Z    : node.js */ var express = require('express'); // '    // express: var server = express(); // $ " server, // $     express //  % # ',  $ //    $   : function respondToClient(request, response) { // Z  '  JSON.stringify $ //     : var request = "request: " + JSON.stringify(request.query); //      : response.writeHead(200, {"Content-Type": "text/html"}); response.write(request); response.end(); } //   : server.listen(8080); //       server.get('/', respondToClient); $  : #     $        getParameters.js,        ,                  : http://localhost:8080/?name=tom&age=14 &            "   : request: {"name":"tom","age":"14"}
Глава 3 156 HTTP/1.1 200 OK X-Powered-By: Express Content-Type: text/html Date: Mon, 11 Apr 2016 17:16:48 GMT Connection: keep-alive Transfer-Encoding: chunked /          -  "  telnet     PutTTY,   $   ,—           GET      : request: {"name":"tom","age":"14"} ?name=tom&age=14 ;     .:    GET /get-parameters.php?name=tom&age=14 &    $    -       (  HTTP),    " : Методы HTTP GET и POST #            ,       HTTP,          . *  ,       ,  ,             ,       ,      "  $     ,         " . = $               (URL)   ,       " node.js,      $          "         "  $     . HTTP                 : GET, POST, PUT  DELETE. *           PUT  DELETE,           GET  POST. & node.js       GET          $   "   request.query.    "                 JSON,    "            ,           . Пишем код          %  ,            ,         $       . &   "    -              ageCheck.js. /*   $ : node.js Z#    $ HTTP   : name ( ) age (#  ) +$  $   ,    $    $ ($    age). */ var express = require('express'); // '    // express: var server = express(); // $ " server, // $     express
Более сложная сеть 157 2  $         :  node ageCheck.js                 ,      "    ,  : //  % #  $   $: function respondToClient(request, response) { // Z  '  JSON.stringify $ //     : var request = "request: " + JSON.stringify(request.query); //      : response.writeHead(200, {"Content-Type": "text/html"}); response.write(request); response.end(); } ?name=tom&age=14 ;       "    :   - /check/?name=tom&age=14 * ,         age    % ,   21. /                         . #         ,         , . .: http://localhost:8080/,            , . .: http://localhost:8080/check. &      $       !  . ,         (/),             . function checkAge(request, response) { var name = request.query.name; var age = request.query.age; var responseString = ""; if (age < 21) { responseString = "<p>" + name + ", +    ,    .</p>\n"; } else { responseString = "<p>  , " + name + ". +  $ ,     '  , "; responseString += "    R $ .</p>\n"; } //      : response.writeHead(200, {"Content-Type": "text/html"}); response.write(responseString); response.end(); } //   : server.listen (8080); //        server.get('/', respondToClient); // // server.get('/'check', checkAge); // // >  express.js  "        ,      GET  POST            .   $      GET     "   server.get(),   POST — c "   server.post(). >     $           4,  "             (REST)14. 14 REST, REpresentational State Transfer (  :         ) —                  . $  :     /?      /check/?  +               : http://localhost:8080/  http://localhost:8080/check —                . /      ,            . 9          ,              . #            . *     ,                $         
Глава 3 158      . =                  POST. &             (URL),  $      GET,   POST            HTTP.           ,    POST            —       .   ,      POST        %    ,  $           -        —       URL,     URL           . &        GET       ,     POST    "  : http://www.example.com/check 3                ,   POST. =     "   ,          : GET  POST. Пишем код '      POST,             (       % ). #            : var express = require('express');// '    // express: var server = express(); // $ " server, // $     express var bodyParser = require('body-parser'); //  //        //           URL: server.use(bodyParser.urlencoded({ extended: true })); // ...    - =      checkAge —            ,      % :   % # checkAge function checkAge(request, response) { var name, age; if (request.method === "GET") { name = request.query.name; age = request.query.age; } else if (request.method === "POST") { name = request.body.name; age = request.body.age; } var responseString = ""; //     * ,             ,   "   POST   /check. /               ,     GET. [  .get()  .post() "         ,           GET  "    POST. $     # # . server.get('/check', checkAge); //     // /check/?  server.post('/check', checkAge); //  !     // POST
Более сложная сеть 159 *     $      ,  "       npm       body-parser. = $        ,        ,                 "  : $ npm install body-parser ;  ,          express,            ,    " "  ,            %      . ;     body-parser       node_modules,           . Тестируем код       -   "  telnet    127.0.0.1    8080              "  . *  $     $ "   POST: POST /check HTTP/1.0 Host: example.com Connection: Close Content-Type: application/x-www-form-urlencoded Content-length: 16 name=tom&age=14 Примечание &     ,          GET,                 —      . 9   (    $   Content                . $,      ,      ,     %   % ,     ,          "  . length:)  Доставка файлов & ,         -   ,  ,         HTML,           -    ,                   . 9    $       "        ,           .   $      ,     node.js,               (      ),        .       ,                   . *   "  $    ,   %              -     . = $      HTML   ,               ,    $           /check   "    POST. *          checkAge,        ,  "     $ HTML-   . &   "           body-parser         %     POST. &  $    "   "   server.use(). /             (middleware),                    . & %   "          "         — express.static,       ,    %  node.js  
Глава 3 160       . /       ,  "        ,                  . =               . *   "                ,                  : http://localhost:8080/ _&.html. Пишем код #    ,            ,      public. #      ,               $     index.html. +,  <html> <body> <form action="/check" method="post" enctype="application/x-www-form-urlencoded"> Name: <input type="text" name="name" /><br> Age: <input type="text" name="age" /> <input type="submit" value="Submit" /> </form> </body> </html>      index. html   public. : form action="/check" method="post"   ,            ageCheck,          POST. ;  ,      Submit   %    POST   /check,   %         . =     checkAge.js  " ,      % : Рис. 3.6. Форма для проверки возраста // use the parser for data that's URL-encoded: server.use(bodyParser.urlencoded({ extended: true })); // serve static pages from public/ directory: server.use('/',express.static('public')); ;          respondToClient()    "   server.get(). /   %  ,               . #                . &           : http://localhost:8080/index.html —           ,     . 3.6. #                        GET,                POST.
Более сложная сеть &   %       $      . 7       -      ,             -  ,           , "    public. 161 4        ,      , —   ,   /     $  ,    check, ,            , "      . Отправка запросов с помощью curl +     $                 HTTP,           "    telnet. &   ,             . *            .   , $      %,         POSIX-  curl,         Linux  macOS (         Raspberry Pi    1). +        Windows 10      curl,         Cygwin (   ,       $  ,        1,        Net). 2  POST  %    "   curl       "  : < X-Powered-By: Express < Content-Type: text/html < Date: Tue, 12 Apr 2016 17:58:46 GMT < Connection: keep-alive < Transfer-Encoding: chunked < * Connection #0 to host localhost left intact <p>tom, +    ,    .</p><a href="/index.html">    '. </a>   curl     %  ,            $  ,     : man curl. =            . +    $           . ? $ curl -v -d "name=tom&age=14" localhost:8080/check   ):   (    - curl -v http://www.example.com 3           : * Trying ::1... * Connected to localhost (::1) port 8080 (#0) > POST /check HTTP/1.1 > Host: localhost:8080 > User-Agent: curl/7.46.0 ? 2  POST  : curl -d "key=value&key2=value2" http://www.example.com ? 2  GET       : curl -G -d "key=value&key2=value2" http://www.example.com > Accept: */* > Content-Length: 15 > Content-Type: application/x-www-form-urlencoded > * upload completely sent off: 15 out of 15 bytes < HTTP/1.1 200 OK ? 0       curl -L http://www.example.com :
Глава 3 162 Принцип работы электронной почты 0 "  $       "    "     . & $            :    $          ,    $          .              "  ,  "   ,  ",  $ "  $     ,         "     " . 2           $       ,     "    $      .         ,             $           " . 0   $               ,    "        . =   "  $           SMTP 15. Q            # :  POP 16 IMAP 17. 4  HTTP, %  . 15 SMTP, Simple Mail Transfer Protocol —        ($    )  . 16 POP, Post Office Protocol —     . 17 IMAP, Internet Message Access Protocol —     ($    )   +   . Пишем код отправителя почты =          node.js    "  $     . #     $        mailer.js. X      nodemailer: npm install nodemailer &  "                    %                      %         .   465               SSL- 18. /      %     " ,                   . 18 SSL, Secure Socket Layer — (  )        . *               ,  $     .            ,   $    ,       "    . /*    : node.js */ // '    nodemailer: var nodemailer = require('nodemailer'); //   ' $    : var account = { host: 'smtp.gmail.com', Измените на действительный SMTP-сервер, если вы port: 465, не используете Gmail secure: true, auth: { user: '_ _@gmail.com' pass: '_ ' } }; Измените на свой действительный адрес электронной почты
Более сложная сеть 163 &  "                    " . =          $     . 0  : to (), from (), subject ( )   text (  ). &           " : //   : var message = { from: account.auth.user, to: '  @gmail.com', subject: '  ', text: ' , ', }; *    "      ,  "   % . $              $   : // $ % # '  $    //  $ '  : function confirm(error, info){ if(error){ console.log(error); } else { console.log('Message sent: ' + info.response); } } 0     % " $   , "   createTransport   ,       "  . [  sendMail              "               %    " : // $   $      //  : var client = nodemailer.createTransport(account); client. sendMail(message, confirm); ~     $         $     nodemailer, "      %   node.js    "  $     .   node.js                    — ,      $    Processing,           ,          . Измените на действительный адрес электронной почты адресата Авторизация в Gmail   Gmail            %           . =                       OAuth2. '  %       %    ,    %      Gmail,           My Account (3  Google), "      Sign-in and Security (>     )  Apps with account access (  ,        )   $          Allow less secure apps (9 %     )    ON (& ).   %            $             OFF. > ,      %          Gmail         . =           ""    $            OAuth2        http://nodemailer.com/ smtp/oauth2/ (  $          ).
Глава 3 164 Шифрование паролей &   "                        ,                ". =                  ,   % ,          $  . =       ,   ,            %  " -      . #"                    ,         ,         .   node.js     crypt, "     %          .  % - ' %    ,       %  ,   %    % ,        %  . &  "           "  %     "  %  ,         ,  %   "           . /                 "      —   ,           . Пишем код шифрования #     $           encrypt.js. &                    node.js, $             . /* #    "        process. argv[]          (      )      node. js      . & %           "    %  ,          . // Œ  $    : var key = process.argv[3]; // ’ R   //    var message = process.argv[2]; // ƒ R   //    2          ,         %   "  . & %             ,      %  : //    %   -  $ % : var fileName = 'info.txt'; Z#  %  : node.js */ // '    crypto var crypto = require('crypto'); var fs = require('fs'); fs:
Более сложная сеть = "   % ,    ,      $  % %  : 165     "  .    // Z$  %: var cipher = crypto.createCipher('aes-256-cbc', key); // Š   %   $ #: var encryptedMsg = cipher.update(message, 'utf8', 'hex');       writeFile()          , $        19: // • #   $  % # writeFile(): function success(data) { console.log('I wrote to the file: ' + fileName); } * , //   $ %    % : fs.writeFile(fileName, encryptedMsg, success);       writeFile(),    %       : 19  ,  node.js        . 4    "    ,      ,  "         .   $         %    "   . 9 %   "        . #          "   :   - $ node encrypt.js   ' #    '   ,   , "      %    % . #"               .           "          info.txt,           %     . #  $               (   ).   %   "    "  "    . Пишем код расшифровки #     $           decrypt.js. #    %     ,     %  : /* Z#  % : node.js */      ,       %  : var crypto = require('crypto'); // '    crypto var fs = require('fs'); // '    %  //    fs &   process.argv[]           %  ,     : // Œ  $    : var key = process.argv[3]; // ’ R   //    : var fileName = process.argv[2]; // $   %  //  $ %  
Глава 3 166 # "   %  :   // Z$  %: var decipher = crypto.createDecipher('aes-256-cbc', key);       readFile()           , $        . & $       %   "    %  : // • #   $  % # readFile(): function success(error, data) { if (data){ data = data.toString(); var decryptedMsg = decipher.update(data, 'hex', 'utf8'); decryptedMsg += decipher.final('utf8'); console.log('I read this from the file: ' + decryptedMsg); } else if (error) { console.log(error); } } * , fs.readFile(fileName, success);       readFile(),       %    : X  ,    info.txt,     %  ,       ,         % ,             "  : $ node decrypt.js _%  ' * $         : _%     ,     % ,     %     .   ' —  9     ":        I read this from the file:   (   $ % :)            ,      %      "    . 2%    $     ,                %         "  $     ,     %      . /                ,  "  %            . ;  ,              HTTP    $    "  ,      % ,             "     .
Более сложная сеть 167 Проект 5 Сетевой кот Людям очень просто выполнять такие задачи, как просмотр веб-страниц или работа с электронной почтой, потому что для нас созданы компьютерные интерфейсы, очень хорошо взаимодействующие с нашими руками: клавиатура отлично подходит для работы с ней пальцами, а мышь удобно помещается в ладонь. Но, например, для кота отправить сообщение электронной почты — задача не из легких. В этом проекте мы попытаемся исправить такую дискриминацию котов, одновременно демонстрируя создание нашего первого физического интерфейса для Интернета. 4     ,     ,       , ,  %  ,          .       ,      "   ,        ,          . 3           ,     $     (      $    ), — $     " %    . +       ,   %   "   $     ,       ! *%       $  . #      "  :       "               — %     ,  "      $       . 7           ,        - .       ,        . /        ,        Processing      ,  ,    ,     HTTP GET   -  .  $   ,  -      "  $     ,      ,  %         "         .        ,   Processing          -         -  "   HTTP POST. Требуемые компоненты  9        Interlink, 2–4 %.  9    400 -   1 0, 1 %.  >       , 1 %.  7 Arduino, 1 %. +       :   , X3 (UART).      .  & - , 1 %.     , 1 %.  0 .          , 2 %.            .         .      .  9   . /        : ?     Arduino       "                            Processing; ?     Processing                  HTTP GET; ?     node.js      HTML-        $            HTTP GET;
Глава 3 168 ?    -      - ;   "  ?  %                       ; ?  %        Processing      -   ,    $   HTTP POST.   $      ,     " , - ,               ,          ,  "               . +   . 3.7          #     . Рис. 3.7. Наглядная схема подключения кота к Сети Клиент получает сообщение электронной почты и открывает веб-страницу, чтобы увидеть снимок кота. Вау! Симпатяга!! Почтовый сервер получает сообщение электронной почты и сохраняет его для последующей отправки клиенту > SMTP > 250 OK > HTTP/1.1 > 200 OK Сервер отправляет сообщение электронной почты и доставляет веб-страницу со снимком кота Пока кот остается на подстилке, программа Processing каждые две минуты отправляет запросы на загрузку снимка Микроконтроллер отправляет показания датчиков программе Processing по последовательному каналу Когда кот ложится на подстилку, программа Processing посылает запрос HTTP GET на отправку сообщения электронной почты
Более сложная сеть 169 *  . 3.8     -       #              (   ),   "       (   )    "     (      ). ;        — "  ,            , —               . Установка датчиков в подстилку для кота    ,              ,        . = $  "           ,        "      . &             (9==)  400   Interlink (  . 3.9). ; ,        ,       . Рис. 3.8. Блок-схема подключения кота к Сети Почтовый сервер Программа почтового сервера Персональный компьютер Почтовый клиент Протокол SMTP Протокол SMTP Веб-клиент HTTP GET /index.html Веб-сервер Серверная программа на node.js HTTP POST / загрузка снимков HTTP GET / почта Персональный компьютер Sensor Программа загрузчика Входное аналоговое напряжение Камера Программа считывания показаний датчиков Микроконтроллер Данные TTL-Serial по USB Видео по USB
170 Глава 3 Рис. 3.9. Поскольку резистивные датчики при пайке легко пережечь, вместо пайки я применил монтаж накруткой проводом диаметром 30 AWG. Инструменты для монтажа накруткой стоят недорого, не требуют особого умения для пользования ими, но создают надежное соединение. Подсоединив провода к датчикам давления, я изолировал места соединений с помощью термоусадочного кембрика (кембриковая изоляция на рисунках не показана) =             Arduino     . *      %                 , $            ATtiny ( .   2)    SoftwareSerial. *  . 3.10                  ,            MKR1110, Arduino 101/Uno  ATtiny84. '             ,              :   ,  ,         "    (  . 3.11). *     $       —  %  ,          :                  ,             ,  -      . &  $    "            ,     .                    %   ,      .            ,        %   ,      Номиналы резисторов &         %                        . 3.10              (        1 0). 4  $      %   ,        4,7  10 0.      . 2             ( .  . 3.11,     !  ). '               ,           ( .  . 3.11,  !  ),      "    (                 ). ;                   ,   %  . 2                    "       ,        ,     ,            "    . 4       %  ,
Более сложная сеть 171 Принципиальная схема Показаны только задействованные выводы 3,3 В Резистивные датчики давления, 4 шт. Модуль микроконтроллера Аналоговый ввод 0 1 кОм Общий («земля») Макетная плата с микроконтроллером ATtiny84 Макетная плата с модулем MKR1000 A B C D E F G H I Вывод сброса микроконтроллера нужно подключить к плюсу питания через повышающий резистор номиналом 10 кОм. Для подключения к порту USB компьютера понадобится отдельный адаптер USB/TTL-Serial (слева вверху). Этот адаптер здесь также используется для подачи питания на микроконтроллер J 1 5 5 10 10 15 15 20 20 25 25 30 30 TX RX 1 A B C D E F G H I RX TX VCC C D E F G H I J 1 5 5 10 10 15 15 20 20 25 25 RTS GREEN CTS BLACK GND A B 1 J 30 Макетная плата с модулем Arduino 101/Uno A B C D E 30 A B F G H I C D E F G H I J J 1 1 5 5 10 10 15 15 20 20 25 25 30 30 A B C D E F G H I J Рис. 3.10. Принципиальная (вверху) и монтажные (внизу) схемы подключения датчиков давления к микроконтроллерам. Поскольку все резистивные датчики давления соединены между собой параллельно, от них отходят всего два контакта
172 Глава 3 Рис. 3.11. Сборка панели датчиков: размещение датчиков по углам нижней пластины (вверху); резиновая накладка, передающая давление верхней пластины на датчик (внизу слева); датчик давления, смонтированный на нижней пластине (внизу справа). Все четыре датчика давления подключаются параллельно. Обратите внимание на резиновые накладки, которые передают на датчики давление верхней пластины. Обязательно изолируйте все соединения перед тем, как скреплять панели. Выводы датчиков соединяются с проводом, ведущим к микроконтроллеру, обычными разъемами типа «мама»
Более сложная сеть 173            ,   %  ,               ,       . 7     ,              % ",     ,       ,   $ —      . = $                    ,         ,           ,       . 3.10,  , — $             . 7              "     . $,          ATtiny84                 USB/TTL-Serial,      $             ( .  . 3.10,  !).  Arduino Uno/101  MKR1000           USB  ,   $     . #               ,      Arduino  " ,      . Тестируем панель датчиков 4          ATtiny84               X3,          SoftwareSerial,   $      2. '      ,           9600    . 2                    $         . X             ,          .          -  %    % ,           -  . X % ,          ,              ,      ,        "  $   . /* Z  $ : Arduino -   Z   $      Analog 0    R $       $   %  ASCII. */ void setup() { //      // 9600    . Serial.begin(9600); } void loop() { // Z   : int sensorValue = analogRead(A0); // +    $   R: Serial.println(sensorValue); }
Глава 3 174 Датчики и события *%       "  $     ,             . = $                      . ' $  ,                ,               %       %. +             . +         " ,     ,    ,          ,    ,     ,  . . 3  "         ,         ,   ,           . &       "         >    Arduino IDE. 2  $  ,      "          ,     %                    .        ,          ,      . 3.12. +,          ,         ,    —  "        . 7  $             %    ,       . ; ,                  % ,         .     ,                    ,             :      ,              . '            $  ,                    .                         ,   %     . 3                  , $    ,      ,     %     . *           ,                     . 7  ,          , $             $   . ;        ,                        . Рис. 3.12. Вывод программы графического отображения значений датчиков давления
Более сложная сеть 175 Пишем псевдокод *%    Processing                  "  .   ,               - . ;           $     : /* 7   ,         setup(),        . 3   draw()        $  . void setup() { // \ #  $   // M  } #        "      ,    $   serialEvent(). 0              : void serialEvent(Serial myPort) { //     - // †  -    : // - $       // -    R.  } = ,        ,        . =      ,      ,    ,     : void sendMail() { // †       // $ R. : // -  $ HTTP GET     // R.  // -     }  $     : Processing */ // \        ' $     void draw() { // + $      R // †    ,   R // †   -    , // $    } void uploadPicture() { // †       // $ $ : // -    // -   $ HTTP POST  $ $  // -     } ' ,       "     ,           . 
Глава 3 176 Пишем код =    %    "              . /         ,           «7  %  - »    2: &     $                   —     ,                    «7  %   ». *      ,           . /*  $     : Processing */ // \       import processing.serial.*; Serial myPort; //     void setup() { // \ #  $    ' $ // \$   0     , //   '  : String portName = Serial. list()[0]; myPort = new Serial(this, portName, 9600); // Z$ serialEvent()      //   : myPort.bufferUntil('\n'); }  void draw() { } void serialEvent(Serial myPort) { //     - String inString = myPort.readStringUntil('\n'); int sensorValue = 0; if (inString != null) { // M    : inString = trim(inString); // $  $    int: sensorValue = int(inString); println(sensorValue); } } X % ,  $  ,        %,       «      ».     ,      ,       ,              . *            ,    "       ,                       . +                 $          ,   %         . 3                  ,     ,      .   $           ,                   ,    ,          ,          . $,     "  ,       ,    %      %   . *        ,                ,                . +                     ,         .
Более сложная сеть 177 '   ,       ,       "    ". =   $         ,                ,      : lastSensorReading, threshold  catOnMat (           % ): Serial myPort; //     int threshold = 400; // $    int lastSensorValue = 0; // $       //  boolean catOnMat - false; //    ? 2        SerialEvent  " . &       "        "       "         "    lastSensorReading   "   . 0  println(sensorValue) %  , $    . void serialEvent(Serial myPort) { //     - String inString = myPort.readStringUntil('\n'); int sensorValue = 0; if (inString != null) { // M    : inString = trim(inString); // $  int   R: sensorValue = int(inString); // println(sensorValue); %  !  . } // *    "   " if (sensorValue > threshold ) { //      >     if (lastSensorValue <= threshold) { //       <     catOnMat - true; // #   ,     //      println("7       "); // %!   ,     // #.  : uploadPicture(); sendMail(); } } else { //     "    " if (lastSensorValue > threshold) { catOnMat - false; println("7       "); } } // 9          : lastSensorValue = sensorValue; Избавляемся от проводов с помощью Bluetooth *                   ,                 Bluetooth —      «7  %  - »    2. 9         ,           . }
Глава 3 178 * ,        "  $        . *       "   $                  . 3   $          "  "  $     . ;  %        "   : void sendMail() { // ‰ % #    $ $ HTTP GET //     R.  println("     R. "); } void uploadPicture() { // ‰ % #    $ $ HTTP POST //  $ $  : println("  $   ."); }                   "   ,   %        ,   ,         "  $     . 4                 %    %  , %        . =        %       , "     %" ,    ,       . *   $       %      ,        .       , %        ,          ,   ,                 ,       . /          %           ,     ,      "  $     . '    ,       ,        "   %         ,         . /   ,     sendMail()  ,    ,          "  . 2          uploadPicture(). =  ,  $    . Дорабатываем код 0  "  $     ,            . =          $   ,   "              : int int =    draw()                currentTime (      % ): void draw() { // C         currentTime = hour() * 3600 + minute() * 60 + second(); } int int int currentTime = 0; lastMailTime = 0; // // // mailInterval = 60; // // lastUploadTime = 0; // uploadInterval = 120; // //                       !                     !      
Более сложная сеть 179 ;         uploadImage()  "   (       % ): sendMail()     , $      "     " —              serialEvent().   mailInterval  uploadInterval      "  $          - . 2            %      : %  % ,     . & %                " ,         . void sendMail() { //   ,       //      #.  : int timeDifference = currentTime - lastMailTime; if ( timeDifference > mailInterval) { println("     R. "); // 9     #.      // : lastMailTime = currentTime; } } void uploadPicture() { //   ,       //           int timeDifference = currentTime - lastUploadTime; if (timeDifference > uploadInterval) { println("    $   ."); // 9          lastUploadTime = currentTime; } } : 2              ,             . +   ,       "  $         . Отправка сообщений от кота      %    Processing,             node.js,      ,    $  ,          express.js    1. /         "  $           GET. ? crypto —  %    %   $     ; *% ? filesystem —       ; ? nodemailer —    "  $     ; ? express —       . ? ? ?        :   "  $         HTTP GET;    ,    Processing ( $     ); =     ,          ,              $ . &   ,             :             HTML      .    -  - -
Глава 3 180   $,                  — multer. #        catServer,   catServer.js.     —      *      $             $     ,            . = $ %     "       %  ,     %        info.txt          catServer. Планируем сценарий сервера * ,   $    ,     %   .     ,         ,       1. &      : cat server : node.js // '    : // crypto, filesystem, express, multer, nodemailer =            %,        : // // // // // // // // // // 2               "     : //  % #  $    // -   GET    // -   POST  $ $   * ,          ,       ,      "   : //  %     %  //    //   -  $          % : -   % - $   %   $ %        : - $     - %    - -  -   $ - %  -   % , $-  $ $        : -  $  -     Задаем конфигурационные параметры #            node.js.                 : // '    : var crypto = require('crypto'); //    % / % var fs = require('fs'); //   %     var express = require('express'); // - var nodemailer = require('nodemailer'); //    :
Более сложная сеть 181 2                    %       —   ,  $         encrypt.js  decrypt.js: //   $    '   % %  //   : var key = process.argv[3]; // Z %  -    # : var fileName =__dirname + "/info.txt"; // Z$  %: var decipher = crypto.createDecipher('aes-256-cbc', key); = ,          express      ,            HTML, —   ,  $              checkAge.js: // Z$    '    express //   -    - % : var server = express(); serve r.use('/',express.static( 'public')); 2    ,     ,          nodemailer. +            —  $      : //   ' $  R : var account = { Замените на адрес своего host: 'smtp.gmail.com', почтового сервера port: 465, secure: true, $ //  SSL  // Š   $  //  $ -  auth: { user: process.argv[2], // // pass: '' //  % }    $ $       $ }; //      R. : var message = { Замените на свой from: account.auth.user, адрес эл. почты to: 'cat.owner@example.com', subject: '    ', text: '   ! http://www.example.com/catcam.html' }; 0        ,           .           "   GET   / mail,   "  $     . #       %  node.js. #                ,  // • #   $     $ //   R. : function sendMail(request, response) { // • #   $    //    %    : function confirmMail(error, info) { if(error){ console.log(error); response.end("’-   .     $    ."); } else { response.send("Z   : " + message.to); } }
Глава 3 182            "  . [              confirmMail()         sendMail(). &     Processing (       Java)  Arduino (          #),  JavaScript             : // Z$      : var mailClient = nodemailer.createTransport(account); var responseString = mailClient.sendMail(message, confirmMail); } =              %     . /,  ,    ,          decrypt.js. 9 %   ,            account.auth.pass   nodemailer: // • #   $   %  $ % : function decryptFile(error, data) { // † $ %       , //   % : if (data){ var content = data.toString(); var decryptedPassword = decipher.update(content, 'hex', 'utf8'); decryptedPassword += decipher.final('utf8'); account.auth.pass = decryptedPassword; // †  $  ,   R : } else if (error) { console.log(error); } } // Z   $ %  : fs. readFile(fileName, decryptFile); console.log("M   " + account.auth.user + "  ."); * ,           ,     %      ,       : #           .  ,  //   : server.listen(8080); server.get('/mail', sendMail); console.log(" ' - .");    ,         ,     2         "  : X    ,         :    - $ node catServer.js __  @_  _.com   2     $ npm install crypto express nodemailer _ _$@ _ _ .com  '    =     node        ,         . +          ,      ,     $     npm. $      ,    %       .          " "  :
Более сложная сеть 183 M   __  @_  _.com  .  ' - . ;           :   . &          "  ,  "  $         .      ". &       " "  : http://localhost:8080    From: _ _$@_  _ .com To: _ _$@_  _ .com Subject:      Date: Wed, 27 Apr 2016 23:30:42 +0000    ! http://www.example. com/catcam.html X % ,  "  $               %       ,    Processing,    POST. &   Processing       ,       loadStrings()       HTTP GET. /             Processing      -   . +      POST        . 7   ,  $    ,  . 3     "      sendMail()    Processing,          . Модифицируем скетч =  "       Processing       "         (       % ). /*  $     : Processing */ // ...  '     '   ... int uploadlnterval = 120; // &   .    // $ $ String serverAddress = "localhost"; int port = 8080; String mailRoute = "/mail"; // ... % # setup(), draw() serialEvent()',   ... 2     println()  void sendMail() {   sendMail() ,  // ‰ % #    $ $ HTTP GET //     R.       "    // +  ,         % . / //   $ R. :      URL int timeDifference = currentTime - lastMailTime;     serverAddress, if ( timeDifference > maillnterval) { port  mailRoute,    String mailUrl = "http://" + serverAddress + ":" + "   loadStrings() port + mailRoute; String[] response = loadStrings(mailUrl);      HTTP GET  println("K      :"); $  .       printArray(response);      $  // Z-    R.    '    . [  load// -: Strings()  "    lastMailTime = currentTime;   —      }      : }
Глава 3 184 #        -   (  catServer.js),        Processing           ,   " ,   . ;     Processing %     ,          "  Processing     " " : * %  "       "   .   ! &               %   ".   %        . ;            -          - .    $    $   : Z   : _ _ $@_ _ .com Создание веб-страницы для размещения снимков с веб-камеры *      -      "    ,       . *%                  ,   "    public  . _ HTML-     , "   $  ,         ,          "  : http://localhost:8080/ Рис. 3.13. Страница сетевого кота в браузере _%  #    ,  "       -   catServer.js,  public. #    ,        catcam.jpg     $     public. 2                       : http://localhost:8080/catcam.jpg #           (  . 3.13). ;     -   ,         $ .
Более сложная сеть 185 Создаем веб-страницу #      index.html   public  " :  JavaScript            update(),       $    -    :    (img)       (div). 2         setInterval(),        update()    . ;  ,                   . &                ,    $    JavaScript  $      img     div ,    . <!DOCTYPE html> <html> <head> <script type="text/javascript"> // • #   $      //    #: function update() { //     '   : var now = new Date(); //   R   #: $  //  $: var timeLabel = document.getElementById('timeLabel'); var catPic = document.getElementById('catPic'); // $ $  URL, $  //     ,  $ //    #: catPic.src= "/catcam.jpg?" + now; //     $: timeLabel.innerHTML = now; } // $   $ % # //  '   : setInterval(update, 60000); </script>   <title>CatCam!</title> </head> <body align=center> <h1>CatCam!</h1> <img src="/catcam.jpg" id="catPic"> <div id="timeLabel"></div> </body> </html> Загрузка файлов на веб-сервер с помощью node.js *  "  %              . 2        "         HTML      HTML POST.    %                (middleware)    ,    "        ( %   : application/x-www-form-urlencoded)   "   % $       request.body.       ,             0,      ,    ,     "           request.file.     %       $            . >             ,         ,     multer. X   $    "  : $ npm install multer ;                  .   
Глава 3 186 Пишем код для загрузки снимков =   " "    require    catServer.js  "    (             % ): /* cat server context: node.js */ // ... '      ' ... var nodemailer = require('nodemailer'); //    var multer = require('multer'); //  !  $N //        2                       "           0 multer.    imgStore               ,          ,           . var server = express(); server.use('/' ,express.static('public'));    upload    $     multer,   ,     server    $     express.           .           ,        Processing:      : //       ! var imgStore = multer.diskStorage({ destination: dirname + '/public/', //   //    filename: saveUpload //         //     }); //      !  multer, //         : var upload = multer({storage: imgStore}); //   :    "image" // (  ! !   ! ): var type = upload.single('image'); ;              saveUpload(),         imgStore. 9      $                      sendMail(). ;  ,             ,     — destination —             imgStore,     ,       . // % #   $  $ $ $ % : function saveUpload(request, file, save) { // $ % #    multer,  - % : save(null, file.originalname); } 4"       ,           . = $        server. post()         server.get()        : server.get(7mail', sendMail); //    // R.  server.post('/upload', type, getUpload); // !  //     console.log(" ' $ - .");
Более сложная сеть 187 * ,             $ . 9      $           sendMail(): // Q          //    : function getUpload(request, response) { //    #       : var fileInfo = JSON.stringify(request.file); console.log(fileInfo); response.end( fileInfo + '\n'); } ;   %            . *   "           . *  ,         curl,         $  . 2      " curl  "    "  : $ curl -F image=@path/to/catcam.jpg 'http://localhost:8080/upload' & $       path/to/catcam.jpg           ,     URL-  . 2        JPEG-    ,               index.html,      . *                . Анатомия составного запроса POST [  HTML,  POST                  :     HTTP     ,             : multipart/form-data,    ,    . & $             ,       -    . 9        HTTP   ,     Здесь определяется boundary (разделитель). Им может быть любая строка, лишь бы она была уникальной. Такой разделитель предшествует каждой части POST /upload HTTP/1.1 Host: www.example.com:8080 Content-Type: multipart/form-data; boundary=----H4rkNrF Content-Length: 40679 ------H4rkNrF Content-Disposition: form-data; name="submit" Значение для этой части. При загрузке посредUpload ством формы это будет вывод кнопки Submit формы ------H4rkNrF Content-Disposition: form-data; name="image"; filename-"catcam.jpg" Content-Type: image/jpeg Content-Disposition — заголовок, определяющий эту часть. Для файлов также содержит локальный путь к файлу [$  '   $   % ] Финальный разделитель с двумя дополнительными дефисами ------H4rkNrF--
Глава 3 188 Захват и загрузка изображений с помощью Processing ;  ,                ,            ,       $       . 9           -  "     ,   —        —            . +      ,    $ "  Processing,     %   : video ( )  net (  ). >    ,    Processing 3.0,   $                       . Захват изображения =         . 4  %   "       ,         %   - ,    USB. 0    ,        %       -       . * %   macOS              Photo Booth,  Windows 10 —    Camera,   Ubuntu      Linux  %     Cheese. 4   %                  ,         ,  Processing          . '      video  Processing,      Contribution Manager,     $           Sketch | Import Library | Add Library. &    Filter  video,               Video   The Processing Foundation (        : Author)     Install. X         ,          +  .   %         Contribution Manager,   —         . ;         %                   - . Пишем код для проверки вывода видео с камеры 9   video        Serial. ;  ,    Serial,       video        $  : #            "   Capture.list(). =            $    Capture —   ,   $  ,    Serial: /* -   : Processing */ import processing.video.*; // \    Capture myCam; //         void setup() { size(400, 30020); //  $   //     '-   ' String[] devices = Capture.list(); video   printArray(Capture.list()); // \$   '      myCam = new Capture(this, width, height, devices[0]); myCam.start(); } 20 /  %       %   ,  Processing       " "   % . &       %  800×600  640×480.
Более сложная сеть 189 =                image().        — myCam —          . 3                "            : void draw() { // +  image(myCam, 0, 0); }        ,      $    captureEvent(). +        "   myCam.read(): // R    - ,      //    : void captureEvent(Capture MyCam) { myCam.read(); } $-   R #   $      Camera        . &             . Пишем код захвата кадров ;  ,     ,     video,     %       . #           video (            % ). 3   —      : =     setup()  "        21: 21 X       %  (400×300)      %   ,  Processing       " "   % . &      %  800×600  640×480. /*  $     : Processing */ // \       import processing.serial.*; import processing.video.*; // ...    ' $ $  . Capture myCam; // $      String fileName = "catcam.jpg"; //      //       void setup() { size(400, 300); // %     // `      //        Processing      //    ,        String[] devices = Capture.list(); printArray(devices); // %  0  devices[0]        : myCam = new Capture(this, width, height, devices[0]); myCam.start(); setup()   ... // ...   % # }
Глава 3 190 &   draw()               : void draw() { // ƒ         : currentTime = hour() * 3600 + minute() * 60 + second(); //   !        image(myCam, 0, 0); } =    captureEvent()        : // #   ,    //     : void captureEvent(Capture MyCam) { myCam.read(); } &   uploadPicture()     println(" void uploadPicture() { // +  ,       //  $  $ $   int timeDifference = currentTime - lastUploadTime; if (timeDifference > uploadInterval) { PImage img = get(); img.save(fileName); // Z-   $ $   '  : lastUploadTime = currentTime; } }    $    " :  ");   #                  .       ,  " % %   ,   uploadPicture()          catCam.jpg   . 0           $  . 0       uploadPicture()       "              uploadInterval. &      $         120   (   ). 4    ,           uploadInterval. *     %     —            . Ставим метку времени на снимки >             ,   ,       . /    ,   "  (     % )      draw()       image():                       ,      . 3.14. image(myCam, 0, 0); // Q   : ~~::99 €€--: String timeStamp = nf(hour(), 2) + ":" + nf(minute(), 2) + ":" + nf(second(), 2) + " " + nf(day(), 2) + "-" + nf(month(), 2) + "-" + nf(year(), 4); //         , //     1     : fill(15); text(timeStamp, 11, height - 19); //          : fill(255); text(timeStamp, 10, height - 20); }
Более сложная сеть 191 Рис. 3.14. Вывод изображения кота с меткой времени *  "  %      ,         HTTP POST. +  $        Processing —           ,   $       loadStrings(). #     net                      ,  %      ,        POST,       . #   $           ,      ! «G     !  POST», —            ,                     -   . *  %   $           —   ,     "  : POST /upload HTTP/1.1 Host: localhost:8080 Content-Length: 19006 Content-Type: multipart/form-data; boundary=H4rkNrF --H4rkNrF Content-Disposition: form-data; name="image"; filename-"catcam.jpg" Content-Type: image/jpeg ['   ----H4rkNrF--     % ]
Глава 3 192 Пишем запрос POST =              ,  "      .    ,           ,              . ;  ,           ,             ". // \       import processing.serial.*; import processing.video.*; import processing.net.*; // ... Client String String      ' $ $  ... thisClient; //      uploadRoute = "/upload"; //       boundary = "H4rkNrF"; // 9     //   POST &           net      ,           : ;                      POST. = $               ,          new Client   : void postFile() { // %!   !    : byte[] thisFile =loadBytes(fileName); // N        : thisClient = new Client(this, serverAddress, port); 3            . #        : String request = ""; // N   POST HTTP: request += "POST " + uploadRoute + " HTTP/1.1\r\n"; request += "Host: " + serverAddress + ":" + port + "\r\n"; 2           . /      ,                      : ContentType: // Q     : String boundaryHeader = "--" + boundary + "\r\n"; boundaryHeader +="Content-Disposition: form-data; name=\"image\"; "; boundaryHeader += "filename=\"" + fileName + "\"\r\n"; boundaryHeader +="Content-Type: image/jpeg\r\n\r\n";   $           : // Q    : String boundaryTail ="\r\n--" + boundary + "--\r\n"; ;      $       ,          . =  $    ,             ,   %    : // $     ,   // ,     boundaryTail: int contentLength = boundaryHeader.length() + thisFile.length + boundaryTail.length(); request += "Content-Length: " + contentLength + "\r\n"; // 9   ,   POST   //     ,       // -   #  : request += "Content-Type: multipart/form-data; boundary="; request += boundary + "\r\n\r\n";
Более сложная сеть 193 // N ,  boundaryHeader,  //     boundaryTail: thisClient.write(request); thisClient.write(boundaryHeader); thisClient.write(thisFile); thisClient.write(boundaryTail); * ,      , ,         "   thisClient.write(): } 2      $       uploadPicture() (     % ): void uploadPicture() { // ‰ % #    $ $ HTTP POST //  $ $  : // +  ,       //  $  $ $   int timeDifference = currentTime - lastUploadTime; if (timeDifference > uploadlnterval) { PImage img = get(); img.save(fileName); postFile(); // Z-   $ $   '  : lastUploadTime = currentTime; } } '      ,    "    draw()         ,      . 4   thisClient     -   , $         $      : text(timeStamp, 10, height - 20); * ,          ,        . *    ,           ,        uploadPicture(), "      ,              . = $         draw(): // *  !    !    if (catOnMat == true) { //     uploadPicture(); } } //           POST,   //  # : if (thisClient != null) { String result = ""; while (thisClient.available() > 0) { result += char(thisClient.read()); } if (result != "") println(result); }   , 
Глава 3 194 Тестируем всю систему '       ,    -  ,                       .                   -        ,      "  $     .      "      " .       -              .   (    )      ,              -      .            ,      ,  -        "    . &     Processing     "  ,   %   .    ,         -    ,      . +     ,          ,   ,   ( )      . 7               ,            . 0     ,                   . 7               ,      ,      —         "     . *  %"  %  IP- .   $        "    Размещаем сервер на ресурсе с общедоступным IP-адресом *%      Processing   -     node.js  "          ,           ,       localhost. +             ,       ,         ,          .     . 3.7,  -          +  . ;     "   IP- ,         "      +    . 7   "    -         %       - ,       %        node. js          .         1,  % %       -   — $              ,            ,     . *  ,     Amazon Web Services EC2       Elastic Beanstalk,          node.js, Python, Ruby on Rails            . 3     Digital Ocean        22  droplet  %   ,                .            "   ,             $     node.js. Установка сценариев на сервер      node.js,      node.js   ,    22     =   —  .                       .
Более сложная сеть *  ,           catServer.js,         $   ,             $ . 2    ,   $       ,         : $ npm install crypto express nodemailer   ,           ,             ,       . 195 Подключение к общедоступному серверу  %          "    ,      ,     ,     IP- $  . *          —      —            serverAddress    Processing      ,  %        .     ,           -  ,            : http://server.address:8080  server.address      -  . %  Управление библиотеками node.js с помощью файла package.json      node.js         ,         ,          ,  "            . ;         . #      "            npm.              ,    $  :              package.     (   )        ,     : json. 2   $ npm install =       $                 - package.json  $ npm init &           ,          npm            package.json,         . [          ,   ,              (      node_modules). ;  ,              , . =   $   ,           node.js,     "     package.json,        "   : www.github.com/tigoe/MakingThingsTalk2/tree/ master/3rd_edition. Использование программы forever X      -    node.js,         "          forever, "                 node.js. X               npm   ,    , —      "   ( Windows       sudo): $ sudo npm install -g forever
Глава 3 196 #   " forever         "  : $ forever start catServer.js &     $           : warn: --minUptime not set. Defaulting to: 1000ms (+  minUptime  $.   '    1000 ) warn: --spinSleepTime not set. Your script will exit if it does not stay up for at least 1000ms (+  spinSleepTime the $. \  #   ,           1000 ) info: Forever processing file: catServer.js (Forever  % : catServer.js)                    %    ,            . '          forever    ,     : $forever list 0      " : info: Forever processes running (\'  # Forever) data: uid command script forever pid id logfile uptime data: [0] kEH1 /usr/local/bin/node catServer.js 1803 1808 /home/username/.forever/kEH1.log 0:0:2:7.956 =    "                    ,      ,       :   . '  - $ forever stop n  n          ,      .     forever        ,        $        .      "  "      "   : - $ forever logs &            : info: Logs for running Forever processes data: script logfile data: [0] catServer.js /home/username/.forever/9QCs.log [          "   less, tail, head          ,         1. *  ,  "  : $ tail -10 home/username/.forever/9QCs.log                "    . >       %      -      %         ,     -         (     )     . /     %     —               " .
Более сложная сеть 197 Завершающие штрихи >    ,       -        %     node. js,      Processing            "     -        . &      %  -      . &   %          ,        +   . ;          +      (  . 3.15). Рис. 3.15. Завершенный проект «ложа» для кота: кот на своей подстилке (вверху слева); часть панели датчиков, которая находится под подстилкой, и бамбуковый ящичек для ювелирных украшений, оформленный под стиль остальной мебели, с размещенными в нем электронными компонентами (справа внизу). Кабель USB подсоединен к компьютеру (компьютеры проекта здесь не показаны). В обязательном порядке основательно обезопасьте все провода, чтобы кот, ласкаясь об электронику, случайно их не погрыз (внизу слева)
Глава 3 198 4     %    ,      "  ,     node.js,   "   %   -  . /                +      . &   ,    ,       %         ($,  ,   ),     "                   "      .&  "           :         "    +   ,       ? &    , +      "       ,   ,             +  ,      ,   $  . Заключение Полагаю, что прочитав эту главу, вы лучше поняли организационную структуру Интернета и принципы работы сетевых приложений. +  ,  , — $   ,  "      . =          " ,     ,     %   +       .                   "    ,        ,   $ "            . =             .  $     ,          "              telnet,  -     "   . 7                    ,  " $   ,          «#   ». ;  ,      ,         " ,                       , —   "         +     "        Ethernet      .


Глава 4 «ГЛЯНЬ, МАМА, ЗДЕСЬ НЕТ КОМПЬЮТЕРА!» МИКРОКОНТРОЛЛЕРЫ В ИНТЕРНЕТЕ Первая мысль, которая приходит многим людям в голову после создания проекта наподобие подключенного к Сети места отдыха для кота из главы 3, — Замечательно! А как бы вообще обойтись без компьютера? Подключать к настольному компьютеру или даже к ноутбуку микроконтроллер лишь для того, чтобы он мог получить доступ в Интернет… В конце концов, как мы видели в той же главе 3, протоколы управления связью в Интернете — это всего лишь текстовые строки, а микроконтроллеры могут обмениваться короткими текстовыми сообщениями без каких бы то ни было проблем. Использование микроконтроллеров совместно с периферийными модулями, которые могут подключаться к Сети, придаст и им эту полезную способность. В этой главе мы узнаем, как подключить микроконтроллер к Интернету с помощью периферийного устройства беспроводной связи Wi-Fi. Необычные проекты X    YBox (http://uncommonprojects.com/site/play/ybox-2)    RSS-    %    ,    $ Ethernet-        XPort      Propeller. 0        !   Uncommon Projects.
Глава 4 202 Компоненты для проектов этой главы Коды поставщиков ? A — Arduino Store, http://store.arduino.cc ? J — Jameco, http://jameco.com ? AF — Adafruit, http://adafruit.com ? RS — RS, www.rs-online.com ? D — Digi-Key, www.digikey.com ? SF — SparkFun, www.sparkfun.com ? F — Farnell, www.farnell.com ? SS — Seeed Studio, www.seeedstudio.com Рис. 4.1. Новые компоненты для проектов этой главы: 1. Микроконтроллер с возможностями Wi-Fi. Слева направо показаны платы Arduino MKR1000, SparkFun ESP8266 Thing и Adafruit Feather Huzzah! ESP8266. 2. Фотодатчики. 3. Красный, зеленый и синий светофильтры. 4. Вольтметр. В принципе подойдет любой, но для лучшего эффекта желательно найти вольтметр как можно более «антикварного» вида 2 1 3 4 ПРОЕКТ 6. Привет, Интернет! Веб-сервер цвета дня  Arduino-   MKR1000, 1 +. AF: 3156, RS: 124-0657, A: ABX00004, GBX00011 (3   4#), D: 1659-1005-ND &                ESP8266. SF: WRL-13231, AF: 2471  N   >      Wi-Fi, 1 +. 4       +     Wi-Fi,   $       . 0       .  Wi-Fi        (     10 , 3 +. J: 29082, SF: C0M-09939, F: 350072, RS: 249-9294
«Глянь, мама, здесь нет компьютера!» Микроконтроллеры в Интернете  \ ), 3 +. (    - D: PDV-P9200-ND, J: 202403, SF: SEN-09088, F: 7482280  C      , 1 +. D: 438-1045-ND, J: 20723  20601, SF: PRT12615  PRT-12002, F: 4692810, AF: 64, SS: 319030002  319030001 203  D&  , 3 +.:   ,    . +                    .       > .  ]=   =                .      "   . ПРОЕКТ 7. Сетевой измеритель качества воздуха  Arduino-   MKR1000, 1 +. AF: 3156, RS: 124-0657, A: ABX00004, GBX00011 (3   4#), D: 1659-1005-ND &                ESP8266. SF: WRL-13231, AF: 2471  N   >      Wi-Fi, 1 +. 4       +     Wi-Fi,   $       . 0        Wi-Fi       .  C      , 1 +. D: 438-1045-ND, J: 20723  20601, SF: PRT12615  PRT-12002, F: 4692810, AF: 64, SS: 319030002  319030001  ' , 1 +.             %   %      . &   ,             0–5 &   $. SF: TOL-10285, F: 1015878, RS: 244.890  D , 1 +. D: 160-1144-ND  160-1665-ND, J: 34761  94511, F: 1855510, RS: 228-5972  826-830, SF: COM- 09592  COM-09590  (    220 , 1 +. D: 220QBK-ND, J: 690700, F: 9339299, R: 7077612      > .  ]=   =                 .      "   . Введение в сетевые модули В течение последних нескольких лет на рынке появилась линейка коммерческих устройств, способных выходить в Интернет без участия персонального компьютера. Такую способность им придают встроенные микроконтроллеры — подобные рассмотренным в этой книге ранее — обладающие возможностью устанавливать связь по сети Ethernet или по беспроводному каналу Wi-Fi. Простейшие из них могут обрабатывать одну транзакцию за раз, запрашивая информацию у сервера, а затем ожидая ответа, или отправляя простое сообщение в ответ на какое-либо событие. Эти устройства обычно играют роль клиента удаленного сервера, но некоторые из них также могут функционировать и в качестве сервера локальной сети.   D-Link, Sony, Axis         ,  "       , —  Ethernet,   Wi-Fi.   Nest         ,  "       +  .   Philips    ,        % . 3   Belkin          ,                    ,       +  . & $                   ,      $   .
Глава 4 204 =            ,         $    :                           ,   SMTP  HTTP. /       ,         ,             ,        . 0                        . *                        .  %  , $        ,                     ,            —         —     %      . [ , $             ,   "                     Wi-Fi  Ethernet. ;           Bluetooth,          2,              . &   "   $   %          Ethernet,             Ethernet — ,      Wi-Fi, —         ,      Wi-Fi   ,        Wi-Fi          . Сравниваем два модуля Wi-Fi 7   Wi-Fi            ,    Arduino. & $    "        :  Wi-Fi WINC1500   Atmel   ESP8266   Espressif,         1. 7 WINC1500      MKR1000,    % Arduino WiFi101    Feather M0 WiFi WIN1500   Adafruit. 3  ESP8266         Huzzah! ESP8266   Adafruit,   Thing   SparkFun    .  Thing Dev   SparkFun, MKR1000  Feather Huzzah! ESP8266   Adafruit    . 4.2. Рис. 4.2. Оснащенные модулями Wi-Fi микроконтроллерные платы: Thing Dev компании SparkFun (слева), MKR1000 (в центре) и Feather Huzzah! ESP8266 компании Adafruit (справа). Для проектов этой книги, использующих беспроводной канал Wi-Fi, можно взять любую из них, так же как и плату Feather Huzzah! WINC1500. Плата MKR1000 имеет большее количество контактов ввода/вывода общего назначения и аналогового ввода. Платы MKR1000 и Feather оснащены встроенными зарядными устройствами Off D0 RESET On RX TX D5 Pwr 3.3V NC GND GND GND 3.3V Vin A0 D2 D5 D14 D0 RESET D4 TX D13 RX D12 5V D16 NC A0 GND D15 Antenna VBat NC En NC VUSB NC D14 NC D12 NC D13 SCK D15 MOSI D0 MISO D16 RX D2 TX SCL CHPD D2 SDA
«Глянь, мама, здесь нет компьютера!» Микроконтроллеры в Интернете + $   : ESP8266  WINC1500 —    WINC1500,            %  ,           ,  "       .    WINC1500         TCP/IP,                 . 0  : MKR1000  Feather M0 c WINC1500 —  "     Cortex M0   Atmel,       Wi-Fi       SPI. 3     ESP8266            Wi-Fi  «   ». 0                    (0#9&),       ,         ,  Arduino. * $          %     /  "    ,    MKR1000  Feather M0 c WINC1500. 7    ESP8266       USB-Serial,       TTL-   . 0   ESP8266 Thing Dev   SparkFun  "      USB/Serial    FTDI,   Feather ESP8266 Huzzah!   Adafruit —     USB/Serial   Silicon Labs, $   $           "    ,  $     !. «4  !  USB/ Serial»   2.  ,            ESP8266 Thing  ESP8266 Thing Dev  % ,      Feather ESP8266 Huzzah!, $ $        %    .   SparkFun      %       ESP8266 —        : https://learn.sparkfun.com/tutorials/ esp8266-thing-hookup-guide/installing-theesp8266-arduino-addon. 205    $      MKR1000,  "    WINC1500,                     . = $                 Arduino IDE   ,  "    "  . >  WiFi101       WINC1500    ESP8266WiFi  Arduino  %        . /   ,     MKR100   ESP8266          . & ,           $     , — $              . # ,    ESP8266      ,          . ;   ,  ,            ,       /  "          ESP8266            MRK1000. 0      ,               802.11n (  5 qq)     API-            .
Глава 4 206 Проект 6 Привет, Интернет! Из предыдущей главы мы узнали, что сетевые устройства могут работать как клиент или как сервер. В этом проекте мы на основе Arduino-совместимого микроконтроллера создадим очень простой веб-сервер, предоставляющий веб-страницу, чей фон меняется в соответствии с цветом, освещающим подключенные к микроконтроллеру датчики. Требуемые компоненты  #  Arduino     ,  "      Wi-Fi, 1 %., —  MKR1000           ESP8266. +       : Wi-Fi,   , X3 (UART).  X       +  Wi-Fi, 1 %.  9        10 0, 3 %.  [ (     ), 3 %.  -  >       , 1 %.  #     . , 3 %.:   ,   Установка соединения     $   ,          ,      Arduino IDE          .    ,        MKR1000        | ,   ,     "    1. 2     ,        D  |  >        WiFi101. 4  ,      "     2     D  |  >      | N      . =        ESP8266     \ | ]       ]       1  MKR1000           Arduino SAMD Boards. 2 '       $  ,          "    %       Arduino,     % —    Wi-Fi 101. !      " A   $    http://arduino.esp8266. com/stable/package_esp8266com_index.json. 2       " A          esp8266 by ESP Community. /            SparkFun,     Adafruit. =       "             ,         :   ,      . /                            . *         —            "   . & $         .        MKR1000     . 4.3. Как работает библиотека WiFi101?                ,                WiFi101  Arduino          (     $               ESP8266 WiFi). >  WiFi101       WINC1500    ,    ,                 . 7       $  : Server  Client.     ,            , "   -  +   ,         Wi-Fi. 3               ,     -
«Глянь, мама, здесь нет компьютера!» Микроконтроллеры в Интернете            $  .   ,                  ,     : read(), write(), print()  println()    Stream,         Serial,    Client  Server.  Client,   ,     connect()      ,   connected()                 stop()     . 7       $    —         . 0         % ,             . >  ESP8266 WiFi,        $     Stream,   $     . 0           ,   %  Wi-Fi      +  . &    ,          %   Wi-Fi (    , %   %  ) —         (SSID)3,            %  .   ,    MAC- %   Wi-Fi,      $                    %  . 4  %  %         MAC- ,     MAC- %       %  MAC-             %  . = $                 %  ,        . X  MAC-      "  ,        ,  !. «&     ». 4           Wi-Fi / MAC-      ,              "            3 SSID, Service Set Identifier —     [    ]      [    ] . A B C D E 207 F G H I J 1 1 5 5 10 10 15 15 20 20 25 25 30 Красный светофильтр Зеленый светофильтр Синий светофильтр 30 A B C D E F G H I J Фотосопротивление 200 кОм 10 кОм Фотосопротивление 200 кОм 3,3 В Модуль микроконтроллера Analog 0 Analog 1 Analog 2 10 кОм Фотосопротивление 200 кОм Общий 10 кОм Рис. 4.3. Монтажная (вверху) и принципиальная (внизу) схемы подключения RGB-сервера к модулю MKR1000. Обратите внимание на три цветных светофильтра, установленные на фотодатчиках
Глава 4 208   . =  $    scanNetwork()        WiFi101. /  %        ,          MAC   !. «&     » —     $   MAC- %   Wi-Fi,         .                    ,             $. #   ,                  %  (SSID)       ,       .     %   Wi-Fi       ,                   . &   $     - Библиотека Stream для Arduino       Arduino,      ,    Serial, SPI, I2C   Wi-Fi Client  Server,           ,                . /   Stream,              ,          (stream)  . &   1           ,     , % %            ,         . 2     (   ,      Serial.write())             ,       (   ,      Serial.read())            . >  Stream     read(), write(), available(), print()  println(),         . &             ,      Stream. >  Stream           TextFinder 7  7   (Michael Margolis),             . &    ,   readString()           string. 3   readBytesUntil()       ,         , —   : readByteUntil('\n’). [  readStringUntil()      ,   "    string. >  Stream            . [  find()  findUntil()                ,    parseInt()  parseFloat()     "                "     . /                    ,      HTTP. [    Stream     $     . =          Stream         www.arduino.cc/en/Reference/ HomePage. Сканируем адреса =    %   Wi-Fi           SPI  WiFi101. 2           ,              $  . =       ESP8266      WiFi101.h  ESP8266WiFi.h: /* Z  : Arduino    WINC1500 */ #include <SPI.h> #include <WiFi101.h> void setup() { Serial.begin(9600); // \ #  $    ' $ }
«Глянь, мама, здесь нет компьютера!» Микроконтроллеры в Интернете 209 &   loop()       :       $  73#-  %  ,    —            . *           %  ,   $                     $  : void loop() { printMacAddress(); // +  R &ˆZ-    Wi-Fi listNetworks(); // Z       Wi-Fi delay(10000); //  '  $ 10   '  MAC-  Wi-Fi,       WiFi.macAddress(),    "        6  .     MAC-     $    printMacAddress()  (  ESP8266WiFi  "    MAC-       , $         0  5        5  0): void printMacAddress() { Serial.print("MAC-: "); byte mac[6]; // &   -  MAC- WiFi.macAddress(mac); //   MAC- for (int i = 5; i > 0; i--) { // #   5  1 if (mac[i] < 0x10) { //    , //  1 #  # %, Serial.print("0"); //     } Serial.print(mac[i], HEX); // +  R //  '   MAC- Serial.print(":"); //   R   $ } Serial.println(mac[0], HEX); //   R //    MAC- } [  WiFi.scanNetworks()  "            ,     ,        %  : void listNetworks() { Serial.print("+     -  :"); int numSsid = WiFi.scanNetworks(); if (numSsid == -1) { Serial.println("^  '    Wi-Fi"); return; // +$    #  } [  WiFi.encryptionType()  "   ,  "  %  : // +    - -  : Serial.println(numSsid); // +        : for (int thisNet = 0; thisNet < numSsid; thisNet++) { String message = WiFi.SSID(thisNet); message += "\tM  : "; message += WiFi.RSSI(thisNet); message += " dBm \t˜ % :"; message += WiFi.encryptionType(thisNet); Serial.println(message); } Serial.println(); } 1. 2. 3. 4. 5. WEP WPA WPA2 *  3     >  ESP8266WiFi  "           : 1 — %         0 — %      :
Глава 4 210 Планируем сценарий веб-сервера #     -  ,   ,          " : /* +- : Arduino   ? ? ?    ;      ;     HTTP.  %       $   ,                      . =          -  :        "  , HTTP-           . $                  . 0       ,  ,   HTTP,          : */ // '      WINC1500 " %  #    void setup() { // \ #  $    ' $ //   '      Wi-Fi, //   '  //    ' , $   //   R      } void loop() { // ™ '   //    ', //   -   , //   -       $ $ //   '   R. // †    ((\n  \r\n) //   HTTP // Š   ,      // †     ', // ' . } HTTP/1.1 200 OK *%          . *,         "  ,     $                  . # % %  $    —   $   ,           #include. = $ "       ,                      (  . 4.4,  ),      New Tab (* ). 2          (  . 4.4,  !) —   , config.h. &  $             $  . # "   $   Рис. 4.4. Создание новой вкладки в среде разработки Arduino (вверху) и присвоение ей имени (внизу)
«Глянь, мама, здесь нет компьютера!» Микроконтроллеры в Интернете           ,    #include "config.h"    . #  ,    " ,           SSID    % :  ssid char ssid[] = "ssid"; // \  (SSID) //   Wi-Fi char password[] = " "; //  //  -   211 ;              "     ,    %       % . *        $        config.h. &  %      "        —    config.h —              Arduino. Пишем код веб-сервера +,          %       -  . &           %   config.h. ;                 $    . #        80,       -  : &   setup()          Wi-Fi ,    ,           ,   . >  WiFi101      %  : WEP4  WPA/WPA25,         . ; %                  WiFi.begin(). = WPA  WPA2 $         "  : WiFi. begin(ssid, ); (    ). 4  %    "   ,          . ; %   WEP            : 4 WEP, Wired Equivalent Privacy —    ,    "    . 5 WPA, WiFi Protected Access — ""    Wi-Fi. /* +- : Arduino    WINC1500 */ #include <SPI.h> #include <WiFi101.h> #include "config.h" //     ssid[] WiFiServer server(80); // Z$ password[] R$    void setup() { Serial.begin(9600);// \ #  $    ' $ //   '      Wi-Fi, while ( WiFi.status() != WL_CONNECTED) { Serial.print("   '      : "); Serial.println(ssid); WiFi.begin(ssid,  ); //   '  delay(2000); //    $  2   //   '  }
Глава 4 212 &       ,        $  IP- ,   ,        : server.begin(); //    ' , $   //   R  IP- Serial.print("Š -  - %  R       : http://"); IPAddress ip = WiFi.localIP(); Serial.println(ip); } &                .          HTTP-   : void loop() { // ™ '   WiFiClient client = server.available(); while (client.connected()) { //    ', if (client.available()) { //   -   , //   -      $ $ String request = client.readStringUntil('\n'); Serial.println(request); //   ' //   R.                    ,      : // †    ((\n  \r\n) if (request.length() <= 2) { client.println("HTTP 200 OK\n"); //  //  HTTP delay(10); // Š    ,  //     if (client.connected()) { // †    //  ', client.stop(); // ' . } } } } } 0                   . 2                   IP- ,         . &           $   HTTP,          ,    %      . /    ,      ,       HTTP    3. ;           ($          "   curl): GET / HTTP/1.1 Host: 192.168.43.184 User-Agent: curl/7.46.0 Accept: */* >%          HTTP         ,              :    ,     ,   %   ,       ,         ,   %   . 2        ,     %            ,            GET/. & %    "     ,        ,      $         —         —   . '             -   ,  ,    "     -  HTML. =  ,  $  .
«Глянь, мама, здесь нет компьютера!» Микроконтроллеры в Интернете 213 Недостаток аналоговых вводов в платах ESP8266 & $            ,   WSP8266         .      Дорабатываем скетч веб-сервера &            makeResponse(), "       . &        HTTP,     —     (  \n\n        ). 2        HTML: String makeResponse() { String result = "HTTP/1.1 200 OK\n"; //  HTTP result += "Content-Type: text/html\n\n"; //   //   # $ result += "<!doctype html>\n"; // ƒ    HTML result += "<html><head><title>"; // ƒ HTML, head title result += "    Arduino</title></head>"; // # // $ HTML result += "\n<body>\n"; // ^    HTML &     HTML     $          MKR1000. =       %                  analogChannel: // + $     : for (int analogChannel = 0; analogChannel < 6; analogChannel++) { result += "    "; result += analogChannel; result += " "; result += analogRead(analogChannel); result += "<br />\n"; } * ,   "   </body>     ,    HTML   : result += "</body></html>\n\n"; // #    //    return result; }  - </html>   %   &      loop()     client. println("HTTP 200 OK\n")   "     (     % ): &        ,        ,        Wi-Fi        . if (request.length() <= 2) { //client.println("HTTP 200 OK\n"); //   HTTP String response = makeResponse(); client.println(response); delay(10); // Š    ,     
Глава 4 214 ;         .   $        ,             "     ,   -              Arduino      «  "»   . &   makeResponse()     HTML     —          ,   "      ,       ,                            .           ,         . *   ,       $       ? = $     makeResponse()    ,       "   </head>,  "    (      % ),         : *%  Arduino              ,         —            +  . *      ,    %   ,       . *, %                 makeResponse(),     %             -      Arduino    Wi-Fi. =       ,  ",          $  . result += "    Arduino</title></head>"; // # // $ HTML result += "<meta http-equiv=\"refresh\" content=\"3\">"; ;                   . &              . &    $  ,    %   ,           . = $      makeResponse()   for     $         "  (     % ). *   "    ,                     %   : 2 %   %       " ,     ,   "       . result += "\n<body>\n"; // ^    // %         : result += "<body bgcolor=#"; // 9         : int red = analogRead(A0) / 4; int green = analogRead(A1) / 4; int blue = analogRead(A2) / 4; // N!      //         : result += String(red, HEX); result += String(green, HEX); result += String(blue, HEX); // %   : result += ">"; // %  HTML-  : result += "‡ Arduino     #"; result += String(red, HEX); result += String(green, HEX); result += String( blue, HEX); result += "</body></html>\n\n"; // #    //    return result; }
«Глянь, мама, здесь нет компьютера!» Микроконтроллеры в Интернете 215 Предоставление доступа из Интернета к устройству с частным IP-адресом =    %   -    %                 . 3         ,         ,  %          +               .  "      "       ,        %  %   %        IP- ,             % % . '    $    ,      ,       %    %   " "      . = $           %   %        $          Port forwarding (     )  Port mapping (0   ). +    %               ,     $             . =                    80, $      %  ,     80 %   Wi-Fi     8080  %   (        %   %  "  ).      $      "         IP-   %       8080          IP-   WiFi     80. Рис. 4.5. Настройки перенаправления портов маршрутизатора Apple AirPort Express 0     ,   %                . *  ,       80,    %     $            . $          —   , 8080. ;       $       %    node.js     8080.     -         80,           ,          : http://www.myserver.com:8080/ ;     "          %      Wi-Fi %    . *  ,   IP- %   %   203.48.192.56,                -       http://203.48.192.56:8080. &                     %   Apple AirPort Express     . 4.5,       %   Linksys —   . 4.6. Будьте осторожны! &          ,      %               %    ! /   %         +   . &     ,      %     (,   "   . .), $      . Рис. 4.6. Настройки перенаправления портов беспроводного маршрутизатора Linksys
Глава 4 216 Приложение встроенного сетевого клиента Теперь, когда наш сервер готов, пора создавать клиента. Это будет встроенный веб-клиент, запрашивающий данные у веб-сайта, отслеживающего качество воздуха, и выводящий эти данные на физическое устройство — стрелочный индикатор, в роли которого выступит аналоговый вольтметр. Проект 7 Сетевой измеритель качества воздуха Кроме вывода на веб-страницы, всевозможные данные могут отображаться многими иными способами. В наших домах, например, имеются часы, барометры и термометры, служащие в качестве как информационных, так и декоративных устройств. Но чтобы физическое устройство могло показывать нам полученные из Интернета данные, оно должно уметь подключаться к серверу, запрашивать эти данные и преобразовывать их в цифровой ряд, управляющий устройством их отображения. & $          . = $             - %     :       . `            ,            %     $          %  . 7 ,      ,    ,  ,         ,      ,          % . 7          -  ,    #  "  Wi-Fi. 2               ,            ,    "   analogWrite()                ,   %     (+7) $  . 7              -   ,             HTML             (     - !    6), ,   ,  "   %    "   -    "     , 6 0  . web-scraping. Требуемые компоненты  #  Arduino     ,  "      Wi-Fi, 1 %.: • MKR1000; •  Arduino Uno-    % WiFi101; •          ESP8266. +       : Wi-Fi, +7 (PWM), X3 (UART),  /  "     (GPIO).  X       +     Wi-Fi, 1 %.  >       , 1 %.  &  , 1 %.  # , 1 %.  9     220 0, 1 %. "  %      ,              HTML  CSS. ;          API7.       AirNow — 3       -     " 7 API, Application Programming Interface —           .
«Глянь, мама, здесь нет компьютера!» Микроконтроллеры в Интернете  #3 (www.airnow.gov). * $                   #3. C "   %                     (   ,     #3)      ,      $  -    . 217 Для жителей других стран =  ,     #3,  -     AirNow — Sonoma Technologies —  %                 . 4       AirNow-I      $        , ;         7  . =              www.sonomatech.com/project.cfm?uprojectid=1102           . Управление вольтметром с помощью микроконтроллера    ,           "          "     . 7              ,                  ,             . '   % %                  ,    %     . /       -     (+7)8. '   +7           ,      , "  ,          ,     . *  ,     +7   ,    ,      , 8 0  . Pulse-Width Modulation (PWM).            , "    "  " ,   30    . 3          "         , $  %          +7.                   ,    —  " ,  ,            +7   %            . *  . 4.7             $   .     ,       :  —     MKR1000,    —  %  ,     4. /             . Скетч для проверки работоспособности вольтметра # "         ,            : /*    \$    analogWrite()      . : Arduino    WINC1500 */ const int meterPin = 5; // Š    -  // ESP8266   $   # %  void setup() { Serial.begin(9600); } void loop() { //           //    -  :
Глава 4 218 for (int pwmValue = 0; pwmValue < 255; pwmValue ++) { analogWrite(meterPin, pwmValue); Serial.println(pwmValue); delay(10); } delay(1000); // Z $      '   $ : analogWrite(meterPin, 0); delay(1000); } A B C D E F G H I J 1 1 5 5 10 10 15 15 20 20 25 25 30 30 A B 3,3 В D6 Встроенный светодиод Модуль микроконтроллера Цифровой вывод 4 Цифровой вывод 5 (ШИМ) Общий Светодиод V Вольтметр C D E F G H I J Рис. 4.7. Монтажная (вверху) и принципиальная (внизу) схемы подключения вольтметра к микроконтроллерной плате MKR1000. Встроенный светодиод подключен к цифровому выводу платы 6 (D6)
«Глянь, мама, здесь нет компьютера!» Микроконтроллеры в Интернете =       pwmValue              %    . &  ,         $   ,       . =     ,         ,    0–5 &,   $     "                ,             MKR1000   3,3 &. *  «  » 219        0–3 &, $                pwmValue     230,              3 &,              . 0                pwmValue       $      . /                 % %    . Запрос данных веб-страницы через ее API *  . 4.8       -   AirNow    *-  (www.airnow. gov/?action=airnow.local_city&zipcode=10003 &submit=Go). /                 -      "     (AQI9)          . *  9 AQI, Air Quality Index —       (+&).    -    AirNow     ,         . 7             ASCII          . 0             -          ,  $        . *,           ,  -   AirNow                — "   -    Рис. 4.8. Веб-страница AirNow отображает текущее качество воздуха для географического местоположения, определяемого почтовым индексом США. Однако в интерфейсе API веб-страницы географическое положение определяется широтой и долготой точки замера
Глава 4 220 API,       docs.airnowapi.org. =    API-                  ,         500     API   . ;  -   API (    API  -   AirNow     )          -  ,   "      ,   HTML. 2       API    "   HTTP             ,      ,   $          «  "   »    3. 4    ,  API-          , %                    . 7  API-             API,  "         %    .  API-               -    ,           %     . #       API-     -   AirNow,     -   AirNow    ,     Current Observations by Reporting Area    By Lattitude/Longitude  "       Query Tool (https://docs.airnowapi.org/Current ObservationsByLatLon/query). 0     ,     "            API-                   %    . #          , "    ,    %    , ,          ,       "         %    . &    ,  $     (      API,          ): http://www.airnowapi.org/aq/observation/latLong/historical/?format=application/ json&latitude=40.7496&longitude=-73.9836&date=2016-05-10T00-0000&distance=10&API_ KEY=0000AAAA-0A0A-1111-A123-11223344AA55 0             : [{"DateObserved":"2016-05-10 ","HourObserved":0,"LocalTimeZone ":"EST","ReportingArea":"Newark","StateCode":"NJ","Latitude":40 .7496,"Longitude":-73.9836,"ParameterName":"OZONE","AQI":28,"Cat egory":{"Number":1,"Name":"Good"}},{"DateObserved":"2016-05-10 ","HourObserved":0,"LocalTimeZone":"EST","ReportingArea": "Newark","StateCode":"NJ","Latitude":40.7496,"Longitude":73.9836,"ParameterName":"PM2.5","AQI":33,"Category":{"Number":1," Name":"Good"}}] &  $  ,         $        ,        HTML. &             PM2.5 —                 . >  , $           , ,           10     %      . =   ,  - "     ,          $    . &      PM2.5  $            :        ,    PM2.5,          "       (AQI). /        %   "     Arduino.
«Глянь, мама, здесь нет компьютера!» Микроконтроллеры в Интернете 221 Планируем чтение параметра PM2.5 ;  ,       Wi-Fi  # ,      AirNow           ,        "    : 1. 0       -  . 2. 0     HTTP GET. 3. †   . 4. 0     . 5. *                . 6. &     "       .           HTTP. = $           6 (    )     4 (  ). &            — ArduinoHttpClient. >  $    3   7Š  (Adrian McEwen),  %  #  7   (Sandeep Mistry)        HTTP   GET, POST, PUT  DELETE,       . # " $              HTTP,     HTTP,           . Версии библиотек HttpClient   %      "  $ ,           ,          #"       HttpClient. *   ,         ArduinoHttpClient. >       "        ,               Arduino. 0     D ,      >      | N      ,   %    " A          (         %)    ArduinoHttpClient,             N . /*          : void loop() { //  HTTP-$     // M      HTTP-$ }   +-  AirNow : Arduino    WINC1500 */ // '       %  #  %  //    / "  //   void setup() { // \ #  $    ' $ // \ #  $     //   '      Wi-Fi, //   '  // &     # '    // '     ,   R  //     } void connectToServer() { //  $ HTTP,  // †     , //   $  $  //    '      "PM2.5",   PM2.5 
Глава 4 222 >-   $             . 4.9. 0  %  if   )  (   ,    "   —   . 9         -          ,           . /    ,       ,              true (  ). // †   $    $ - (\+), //  $    , $ $, // -   R $ HTTP } void setMeter() { // Z  $  PM2.5   $ //   ,  $     } void setLeds() { //  '   , '    # // '    //  '  TCP, '   // '   -  } void blink() { // &    }          API        . 4           ,               "       . &           ,              .          ,   ,  $      -   ,            —   . Сочетание в строке данных разных типов         -                     . 7    $    %   "      ,      HTTP,              $    . &                     $   ,   API,   , %   ,          . 9  $           Arduino String. # "               ,      . 3               "      ,         String(),               . >                  %         ,    $  BIN  HEX. *              (    char),  (    string). &                "   "   toCharArray(). =          : String myString = "/some/server/route"; char stringArray[myString.length() + 1]; myString.toCharArray(stringArray, myString. length() + 1);   $    ,                      0, $   $                      % ,      $  . #               "  "   .c_str()   String.
«Глянь, мама, здесь нет компьютера!» Микроконтроллеры в Интернете 223 Пытаемся подключиться к серверу Подключились к серверу? Да Нет Отправляем запрос HTTP Нет Да Ответ содержит ИКВ? Прошло достаточное время после последней попытки подключения? Да Извлекаем значение ИКВ из ответа Сопоставляем результат диапазону показаний вольтметра Выводим результат на вольтметр Рис. 4.9. Блок-схема программы Arduino для отправки запроса HTTP GET и обработки полученного ответа Пишем код веб-клиента AirNow ;  ,            -            (+&),         . +    ,    ,                  .  /* +-  AirNow : Arduino    WINC1500 */ // '       #include <SPI.h> #include <WiFi101.h> #include <ArduinoHttpClient.h> #include "config.h" %  #  % 
224 Глава 4     SPI, WiFi101  ArduinoHttpClient.   ,         config.h         (SSID)      —   ,  $          .             APIKey      API: 2            (       ESP8266       ),                 (            )        : //    / "  //  : const int networkLED = LED_BUILTIN; //    // '  const int connectedLED = 4; //   '    const int meterPin = 5; //    const int meterMin = 0; //      const int meterMax = 255; //      const int AQIMax = 200; //     // $ - const long requestInterval = 120000; // $  //     *      : WiFiClient   ,        ,         API                   : WiFiClient netSocket; //     const char serverAddress[] = "www.airnowapi.org"; //  //  String route = "/aq/observation/latLong/current/"; //   API long lastRequestTime = 0; //    $   &   setup()          ,                   ,   ,   $         . 2 ,  ,     :                    blink()         . 0    $            : void setup() { Serial.begin(9600); //  #  $    ' $ pinMode(networkLED, OUTPUT); // %      //  '     # //       pinMode(connectedLED, OUTPUT); // %      //  '    # '  //         pinMode(meterPin, OUTPUT); // %      //           //   '      Wi-Fi, while ( WiFi.status() != WL_CONNECTED) { Serial.print("   '      : "); Serial.println(ssid); //   R   (SSID) WiFi.begin(ssid, password); //   '  blink(networkLED, 5); //     # // '    } // '     ,   R    //  
«Глянь, мама, здесь нет компьютера!» Микроконтроллеры в Интернете 225 IPAddress ip = WiFi.localIP(); Serial.print("IP Address: "); Serial.println(ip); &     setup()            ,    URL- ,    "        API-       AirNow. #             ,   $      ,                          . *  ,     %      %     ,           : //       ' API: route += "?format=application/json&latitude=40.7296"; route += "&longitude=-73.9936&date=2016-05-10T000000&distance=10"; route += "&API_KEY="; route += APIKey; } &   loop()       .   — $                  (      lastRequestTime)   "    (  millis()),    ,  %            "    . 4  ,       connectTo Server(). 3    — $     setLeds()          . 4           : void loop() { //  HTTP-$    : if (millis() - lastRequestTime > requestInterval) { connectToServer(); } // M     : setLeds(); } [  connectToServer()              . &         HTTP (   HttpClient),         HTTP GET,       : void connectToServer() { int AQI = -1; //   $ \+ HttpClient http(netSocket, serverAddress); // $ //   HTTP http.get(route); //  $ HTTP http.skipResponseHeaders(); //    $ // HTTP-
Глава 4 226      ,          ,      setLeds(),      ,    .           findUntil()      $     "PM2.5",    "   parseInt()     "                    .            +& (AQI)       setMeter()        : //  '   : while (http.connected()) { setLeds(); //      : if (http.available()) { http.findUntil("PM2.5", "\n"); //    //  "PM2.5" AQI = http.parseInt(); //   $  // $    PM2.5 http.flush(); //     } } if (AQI > -1) { // †   $   //  $ - AQI (\+), Serial.print("PM2.5: "); Serial.println(AQI); setMeter(AQI); //  $     } 2         ,     http. stop(),       "       lastRequestTime: http.stop(); // $ $ lastRequestTime = millis(); // -   R // $ HTTP } &   setMeter()       map(),       +&  "               . 2        "   analogWrite(): void setMeter(int level) { //  $  $ '  -  //  $   : int meterSetting = map(level, 0, AQIMax, meterMin, meterMax); //  $    : analogWrite(meterPin, meterSetting); &   setLeds()        ,     % # WiFi.status()   ,   Wi-Fi   ,          .        WiFiClient. Connected()               "           : void setLeds() { //  '   , '   //  # '    : if (WiFi.status() == WL_CONNECTED) { digitalWrite(networkLED, HIGH); } else { digitalWrite(networkLED, LOW); } //  '  TCP, '   // '   -  : int connectedToServer = netSocket.connected(); digitalWrite(connectedLED, connectedToServer); }
«Глянь, мама, здесь нет компьютера!» Микроконтроллеры в Интернете * ,   blink()     "      200   . *  ,      ,                 ,            : 227 void blink(int thisPin, int howManyTimes) { // &    : for (int blinks = 0; blinks < howManyTimes; blinks++) { digitalWrite(thisPin, HIGH); delay(200); digitalWrite(thisPin, LOW); delay(200); } } &       - . #      AQIWebClient     MKR1000.                             "   ,                            (  . 4.10). Рис. 4.10. Завершенный проект сетевого измерителя качества воздуха
Глава 4 228 Определение IP-адреса сетевого узла & $            ,   IP- . X  IP-      "   ping,          3. *  ,              : ping -c 1 www.makezine.com (    Windows       -n   -),   "    IP- :   "  , PING makezine.com (104.25.44.28): 56 data bytes 64 bytes from 104.25.44.28: icmp_seq=0 ttl=52 time=38.870 ms 4    ping     (   "   +     ,             "   ),          nslookup. *  ,      nslookup makezine.com  "   "  : Server: 8.8.8.8 Address: 8.8.8.8#53 Non-authoritative answer: Name: makezine.com Address: 104.25.45.28   IP-   .    Команда nslookup также возвращает адрес сервера DNS, который она использовала             , $    Послесловие к завершенному проекту &     $      %        ,           ,         . &      $       "    . ?  :                  , $  ,       . =   ,  ,                                      .     ,                 , —       "       . &     $      %       ,            , %        . ? ' :    $     ,   %     ,          ,        "               , -          ,                  . +        "     ,       ,      $                . +     "   ,   ,                ,          ,            -     ,            . ? % :              ,             , $ %        . &    
«Глянь, мама, здесь нет компьютера!» Микроконтроллеры в Интернете            ,    ,       ,       API-   ,      %     ,                   ,       "       ,          %     . &   "                 ,   ,         ,  $       %  ,          . +    "                          %    "          . /               —   ,      229      "   Hue lighting hub   Philips. 0   Wi-Fi  WINC1500  ESP8266                                   .    ,       ,            ,   ,                            ,           "  %          . &         $      ,                         . $ %      %                   . Форматы данных Разбираясь с проектами этой книги, мы уже познакомились с рядом существующих протоколов, основанных на передаче текстовых данных, и даже создали несколько своих. По сути, протокол — это средство для структурирования данных при организации связи. Некоторые протоколы просто передают информацию, а другие отдают команды — явно или неявно — посредством запросов. Далее нам придется часто работать с разными протоколами, поэтому сейчас было бы полезно подытожить наши знания о рассмотренных к этому моменту форматах данных. Простые форматы данных &    «7  %  - »       ,   10 11  . [  CSV  TSV        —     CSV                   ,      . ~ %       CSV        NMEA-0183,           GPS.   $    10 CSV, Comma-separated values —   ,    . 11 TSV, Tab-separated values —   ,    . -  . 7                «-   ».  %  ,       ,         (    ),         . &    ,    «-   »      HTTP,   ,         HTTP. [         ,                  ,    —  . *  ,   "               ,   —  :
Глава 4 230 "DateObserved":"2016-05-10 ","HourObserved":0,"LocalTimeZone":" EST","ReportingArea":"Newark","StateCode":"NJ","Latitude":40.7267 ,"Longitude":-74.1442 3   "             (&).       (=),   — - ?name=tom&age=14 3         — "       «»,      . 2         ,     : &             :        ,   ,      ,   . 3               :     . '                              $ $           ,         $  . Host: localhost Content-Length: 19006 Content-Type: multipart/form-data 7             +   —   HTTP12  SMTP13. 0     "  :        GET  POST,               ,              . 2           "       ,   "               . _  "            «-   »,            ,  $                (&). & ,    ,  "   HTTP POST    2: POST /check HTTP/1.0 Host: example.com Connection: Close Content-Type: application/x-www-formurlencoded Content-length: 16 name=tom&age=14 12 HTTP, HyperText Transfer Protocol —        . 13 SMTP, Simple Mail Transfer Protocol —        [$    ]  . Примечание &        Java, JavaScript  C     ,     ,       ,         #    "  : • • •    — \n     — \r  — \t *        ,   " %  "           .  $        . &      "
«Глянь, мама, здесь нет компьютера!» Микроконтроллеры в Интернете 231 Форматы структурированных данных =       ,         «-   »,     -   . 9  ,   ,   ,         %   (. 4.1). Таблица 4.1. Массив датчиков, расположенных в разных местах дома Адрес Размещение 1 2 3 4 5   q   &  #    Последнее чтение Значение 12:30:00 05:40:00 01:15:00 09:25:00 06:20:00 60 54 23 18 3 & $            $         «   ». &     ,    «-   »        ( ,   , :3, $ :23). &                 . =        $                JSON14. 14 JSON, JavaScript Object Notation —    JavaScript. Формат JSON [  JSON         ,    «-   ».             ,     . =  ,      . 4.1,          "  : [{"ˆ":1,"$  ":" -","   ":"12:30:00"," ":60}, {"ˆ":2,"$  ":" ","   ":"05:40:00"," ":54}, {"ˆ":3,"$  ":"","   ":"01:15:00"," ":23}, {"ˆ":4,"$  ":"","   ":"09:25:00"," ":18}, {"ˆ":5,"$  ":" ","   ":"06:20:00"," ":3}] /               . /         ,               ,       $         " .   $     ,       ,   % . #   ,            JSON, $                 "  : "$  ":" ", "   ":"05:40:00", " ":54 }, { "ˆ":3, "$  ":"", "   ":"01:15:00", " ":23 }, { "ˆ":4, "$  ":"", "   ":"09:25:00", " ":18 [ }, { { "ˆ":1, "$  ":" -", "   ":"12:30:00", " ":60 "ˆ":5, "$  ":" ", "   ":"06:20:00", " ":3 }, { } "ˆ":2, ]
Глава 4 232  "        ,  JSON,        —     ,         ,     ,              . ;  ,              %    ,       ,   $      $            . =    JSON            HTTP,          (  )               . JSON и JavaScript         ,   JSON      JavaScript, $     JSON      ,       " $  . > ,    JavaScript   " JSON. *           . &    ,                   ,            JSON. 7   -        JSON   API-   ,       "           ,         $ JavaScript. & -    AirNow,           7,   "       JSON. =          node.js     $  . Парсинг ответа сервера с помощью сценария на node.js # "                       $  . [                  JSON       JSON.parse()      >  http       node.js, $                .    http,             . 0     ,       $       (   options)     JSON. & $            «-   »,    . 2     API         (     % )     :     JSON,           .      — JSON.stringify() —         JSON   . /* AQI client : node.js */ var http = require('http'); // '    http: // $   $    R  " JSON: var options = { host: 'www.airnowapi.org', port: 80, path: '/aq/observation/latLong/current/?format=application/ json&latitude=40.7296&longitude=-73.9936&date=2016-05-10T000000&distance=10&API_KEY=0000AAAA-0A0A-1111-A123-11223344AA55' };
«Глянь, мама, здесь нет компьютера!» Микроконтроллеры в Интернете 233 [            ,          handleRespons(),      ,           .  "            result. 3   response.on('end')         JSON ,      ,     $  : function handleResponse(response) { var result = ''; // Z    -   * ,          http.request()   %       request.end(): var request = http.request(options, handleResponse); // ^  // $ request.end(); //  $ response.on('data', function (data) { //     , result += data; //     $  }); response.on('end', function () { // // var response = JSON.parse(result); // // console.log(response); // });  $ '    ,    $     R } #   $         aqiClient.js         : $ node aqiClient.js              ,      JSON     $      . 0          , $        $  $   response [0],    — $   response[0].AQI  response[0].Longitude. &              ,   . /              ,                $       API-          ,   "       JSON. #  "           HTTPS,            require('https');   %    443. Принцип REST и интерфейсы API для Сети Протокол HTTP основан на принципе передачи состояния представления REST15. REST — это не протокол, а, скорее, архитектурный стиль для обмена информацией. Он часто используется в Сети в интерфейсах прикладного программирования (API). И хотя принцип REST берет свое начало в веб-приложениях, он нашел применение и в иных областях. Некоторое представление о REST не только поможет вам понимать другие системы, но также и разрабатывать свои собственные коммуникационные протоколы. Усвоив этот принцип, вы уже не сможете в своей жизни без него обойтись. 15 0  . REpresentational State Transfer —         .
Глава 4 234 0     REST      " :  -  #      -   (     ). & , $   , ,    , $     ,  " %      . 7       "    ,    $    .    REST      (  )    $    #     $        . 7    REST — $    ,        HTTP.                 ,       GET,     POST         . X       %              (   ,    HTML      . 4.8     -   AirNow.gov,  "          ),     $    (   ,              " ).     REST     URL  —  "   ,     ,    —   ,     "   . & URL-              $% (   ). *  ,          REST          ,           2. X           ,   ,   Arduino  "   : GET /color/r/ #          0  255,   "            . 3          ,  ,   ,  "  : & $                            255. & %    Arduino          ,   "           ,       . 0      :       1.     (       )        $%. 2. 2      —                     ,     . 2  HTTP     : GET, POST, PUT  DELETE. 2  GET        , PUT —     , POST —    " "  ,  DELETE —  " "  . +   $   , GET  POST      . 3. /            . #          ,    -  ,  "    HTML    XML,    node.js,  "     $  ,          PHP  Ruby,    C/C++,  "   Arduino,        . ;          :            ,      $    —    . &              ,     REST                . ;,    REST                 OSC16,        MIDI.    REST                    POST /color/g/255 16 OSC, Open Sound Control.
«Глянь, мама, здесь нет компьютера!» Микроконтроллеры в Интернете       Ethernet,                  .   ,    REST,                           ,           " ,        ,                 . 4"    "  REST    ,           ,   "   ,  URL-       .      %     html, $    ,                 , ,    ,  $    . ; ,                  -  ,     $  . #           . '     -       REST,         (   ,  -        )       ,             $        .   $        REST: ? /"/   —     - 235 Традиционная веб-служба = ,      "       ,                  . = $                        :   ( ,    ),         . URL-    $       31    2012       "  : ?        31    2012 : PUT /myrun.example.com/runnerName/31/1/2012 ?        : GET /myrun.example.com/ runnerName/31/1/2012/distance/ ?         12,56   : POST /myrun.example.com/runnerName/31/1/2012/ distance/12.56 0   ,          ,    ,         ,   "       ,    GET (  )     PUT  POST        ,    (  )                .    ; ?  /"/  /  —        .         —        —              PUT  POST. >                   HTTP. =              . 0   —     - ,    —        . Физическое веб-устройство = ,                %   . &    12  ,        . &             1  10.                . URL-                  "  : ?       : GET /mywindows.example.com/windows
Глава 4 236 ?           (    —   2): GET /mywindows.example.com/window/2/ ?             : - POST /mywindows.example.com/window/2/height/5 ?    : POST /mywindows.example.com/windows/height/S #                %    . 7            ,        ,       $         . 3    REST     ,    -,       . 3    REST            . & ,           , — $   "         " $%,   ,          ,       "     "    . /         . URL- ,             ,     ,      : http://myrun.example.com/?runnerName=George &day=31&month=1&year=2012&distance=12.56   REST — $ ,   ,       $     ,     ,   ,      . *   -                  REST. *  ,  -   AirNow.gov,      "   %           ,          REST,       . 7            REST   "    $  . &    ,                     HTTP   REST,      node.js    Arduino. Работа по REST в node.js   node.js  express.js          REST, $    $  "   ,      REST,        . ;,     " express.js    ,         ,     . *  : server.post('/check/age/:age', checkAge); = $         "   POST: http://www.example.com/check/age/21        "             request.params. age,     21. _    ,  - "         /age/,          . 7    "          : server.post('/check/name/:name/age/:age', checkAge); *    ,                      REST,  $ % ,     . 4         ,  express.js          .
«Глянь, мама, здесь нет компьютера!» Микроконтроллеры в Интернете 237 Модифицируем код сценария «Проверщик возраста» в стиле REST =         «  "   » ( .   ageCheck.js    3),         REST. *       % . #   $              restAgeCheck.js,      express.js: $ npm install express & $            : request. params.name  request.params. age —      . ;                   —   ,       $    : 2          ,              $        : /* RESTful age checker   $    REST : node.js */ var express = require('express'); // '    // express: var server = express(); // C$ " server, // $     express function checkAge(request, response) { var name = request.params.name; var age = request.params.age; var responseString = ""; if (typeof age === 'undefined') { responseString = "<p>9! ,     ?.</p>\n" } else { if (age < 21) { responseString = "<p>" + name + ", +    ,    ..</p>\n"; } else { responseString = "<p> Hi " + name + ". +  $ ,     '  , , "; responseString += "    R $ ..</p>\n"; } } //      : response.writeHead(200, {"Content-Type": "text/html"}); response.write(responseString); response.end(); } // start the server: server.listen(8080); //        $  : server.get('/check/name/:name', checkAge); server.get('/check/age/:age', checkAge); server.get('/check/name/:name/age/:age', checkAge); & ,     ,                GET. 9  REST   ,          POST  PUT? #      GET   $ ,         ,                   . X % ,         ,              server.get()  server.post(). #              "  : $ node RestAgeCheck.js    - 2        ,              " : http://www.myserver.com:8080/check/ name/tom/age/42 3  ,             "   curl: $ curl http://www.myserver.com:8080/ check/name/tom/age/42 &     www.myserver.com         localhost,    "     .
Глава 4 238 Работа по REST в Arduino '       REST   Arduino      ,    node.js. = $      ,         6. #         ,     ,        . 2            Stream,     $   (  -  ,      Serial,  Client  Server   WiFi101   $     Stream). [  setup()      REST       6           ,    loop()     . Пишем код Arduino в стиле REST *             HTTP,         "  : GET /check/age/21 HTTP/1.1 #        ,       : GET  POST: =           ,        $% (/). 4    "              ,   "         : while   &    while      "           "   :     $        ,      node.js.                         . void loop() { // ™ '   WiFiClient client = server.available(); while (client.connected()) { //    ', if (client.available()) { //   -   , //    '    -  , //       $: String request = client.readStringUntil(' '); // check if the request is GET or POST: if (request == "GET" || request == "POST") { //          /   : String lastToken = ""; //     while (!lastToken.endsWith("HTTP")) { String currentToken = client.readStringUntil('/'); if (lastToken == "age") { int age = currentToken.toInt(); // ƒ     Serial.print("age: "); Serial.println(age); } //      lastToken = currentToken;   } ,     ,              : client.println("HTTP 200 OK\n\n"); //   HTTP if (client.connected()) { // †     ', client.stop(); // ' . } } } } }
«Глянь, мама, здесь нет компьютера!» Микроконтроллеры в Интернете 239 Инструменты для программирования и диагностирования встроенных модулей При попытках подключиться к сети в проектах этой главы вам, возможно, пришлось столкнуться с некоторыми проблемами. Не исключено, что самым трудным моментом их диагностирования было то, что модуль Wi-Fi очень скудно информировал вас о проблеме, если предоставлял какую-либо информацию вообще. Такая ситуация является нормой взаимоотношений со встроенными модулями в собственных разработках. Чтобы помочь вам в решении таких проблем, мы рассмотрим несколько моментов, которые нужно учесть в подобных случаях, а также несколько инструментов диагностирования. Эти методы применимы как при работе с модулями Wi-Fi, так и с другими сетевыми или коммуникационными модулями. Мы будем постоянно использовать эти методы в последующем материале книги. Они вам также пригодятся и в других ситуациях, не связанных с нашими проектами. Три самые распространенные ошибки Проверьте линии питания Проверьте соединения &                 :       (" ). /       %                MKR1000  ESP8266. *         % WiFi  -       ,        (  )   %     $. 4     ,        "     ,  "        . *    ,        ,               (")  ,                 .                                       . X  ,           ,      ,   ,    "     ,     ,        ,   . &              ,       "  (    " )  . Проверьте конфигурацию 4              ,           ,      ,       . &    ,           IP-     ,    (SSID),      . ;         Wi-Fi,     . Средства и методы диагностирования X % ,         ,            "  ,     %    . &          , $              , $                ,     ,        . &                 ,       .   ,  
Глава 4 240       /                           ,      $  .       ",       . 4  -  ,    " $ "  .   ,     Физические методы диагностирования #             . *  $    ,       ,         . '       ,            , "      . ;     ,  %       . &        $    ,             ,       %         ,  $      "   . &   — $           ,           . /   " ,       " . $        ,    ,    ,     %      . +        . Использование для диагностирования последовательного обмена         - ,  Wi-Fi,        $  ,       ,  "  . *  ,     ,                       ,   ,                    "  ,       ,   "     $       "    . =        $                  " ,           .   $    ,            .                . 7               ,               . ~ $        ,                 . $                  ,    %     . Используйте отладочные команды 0     —       ,           ,      "   . 4        %       if (DEBUG),       ,      DEBUG    false: const boolean DEBUG = true; void setup() { Serial.begin(9600); } void loop() { if (DEBUG) Serial.println("‰   "); }
«Глянь, мама, здесь нет компьютера!» Микроконтроллеры в Интернете 241 Объявляйте вызовы функций                    . 0  ,         $   ,  , $               "      . = $            Serial.print()       "  " ,      "   : void connectToServer() { if (DEBUG) Serial.print("\ % #  connectToServer()..."); // Z'    % # } void setMeter() { if (DEBUG) Serial.print("\ % #  setMeter()..."); // Z'    % # } void setLeds(int thisLevel) { if (DEBUG) Serial.print("\ % #  setLeds()..."); // Z'    % # } Проверьте условные операторы &      ,       %     ,            ,       . &       % %,            . $      ,             ,     "  " ,      "   : while (http.connected()) { if (DEBUG) Serial.print("http.connected..."); setLeds(); // †     : if (http.available()) { if (DEBUG) Serial.print("http.available..."); http.findUntil("PM2.5", "\n"); //     // "PM2.5" AQI = http.parseInt(); //   $  $  //   PM2.5 http.flush(); //     } } Проверьте вложенные операторы #                 . X          %      . 4   , "   . *  ,                          ,       . $   $   ,      "   : int AQI = -1; //     $  \+ HttpClient http(netSocket, serverAddress); // $   // HTTP http.get(route); //  $ HTTP while (http.connected()) { //  '   , if (http.available()) { //      //   $  $  \+ // ...  $     $   ... } } if (AQI > -1) { // †      $  \+, setMeter(AQI); //      $ }
Глава 4 242 Разделите код на части      $  , $      "         . *               . *  ,  "                  client.connect(),                     : if (client.connect()) { // † '  ,    // $ : Serial.println(" '  "); } else { // †   '    : Serial.println(" '   "); } X   $          ,                    %   $  .  ,                       %  . * %           . =    $  $  ,   : client.connect(); // connect delay(1); // wait a millisecond if (client.connected()) { // † '  ,    Serial.println(" '  "); } else { // †   '    : Serial.println(" '   "); } $ : Просто наблюдайте +        %                    ,      . 0    ,                 ,          $   ,      . /               . 0"" ,        %   ,         ,     . $       ,         , —    ,     ,    . // † ', -  -      : if (client.connected()) { if (client.available()) { char inChar = client.read(); Serial.write(inChar); } }
«Глянь, мама, здесь нет компьютера!» Микроконтроллеры в Интернете 243 Создайте программу проверки состояния сети Wi-Fi                ,             . = $      MAC- %   Wi-Fi,           ,              . # "      $   -    Wi-Fi,          ,  %  —    $  IP-  MAC-   Wi-Fi,     . /           ,            . Скетч для проверки параметров сети Wi-Fi   $     ,  $             config.h,  " SSID       . /* WiFi Status check    Wi-Fi Context: Arduino, with WINC1500 module */ #include <SPI.h> #include <WiFi101.h> #include "config.h" void setup() { Serial.begin(9600); Serial.println("^   "); //   '      Wi-Fi, while ( WiFi.status() != WL_CONNECTED) { Serial.print("   '      : "); Serial.println(ssid); //   R   (SSID) WiFi.begin(ssid, password); //   '  delay(2000); //    $  2   //   '  } } void loop() { printWiFiStatus(); delay(10000); } [  printWiFiStatus()     $           : void printWiFiStatus() { // +  R SSID   ,   ': Serial.print("SSID: "); Serial.println(WiFi.SSID()); // +  R IP- '$   ,   // ': IPAddress ip = WiFi.gatewayIP(); Serial.print("IP- '$: "); Serial.println(ip); // +  R    //   ': IPAddress subnet = WiFi.subnetMask(); Serial.print("&  : ");  ,
Глава 4 244 Serial.println(subnet); // +  R MAC-   ,   // ': byte apMac[6]; WiFi.BSSID(apMac); Serial.print("BSSID (MAC-   ): "); for (int i = 0; i < 5; i++) { // #   0  4 if (apMac[i] < 0x10) { //    ,  16 // (0-0ˆ  #  % ) Serial.print("0"); // +  R 0: } Serial.print(apMac[i], HEX);// +  R   // MAC- Serial.print(":"); //    } Serial.println(apMac[5], HEX); //   R //    MAC-           $            Wi-Fi (  ESP8266WiFi  "    MAC-        , $         0  5        5  0): Внимание! Разные библиотеки // +  R MAC-   Wi-Fi: byte mac[6]; WiFi.macAddress(mac); Serial.print("MAC-  : "); for (int i = 5; i > 0; i--) { // #   5  1 if (mac[i] < 0x10) { //    ,  16 // (0-0ˆ  #  % ) Serial.print("0"); // +  R 0: } Serial.print(mac[i], HEX); // +  R   // MAC- Serial.print(":"); //    } Serial.println(mac[0], HEX); //   R  //   MAC-      #        ESP8266WiFi           . =      macAddress()  BSSID()     $        "   ,       # . // +  R IP-   Wi-Fi: IPAddress gateway = WiFi.localIP(); Serial.print("IP- "); Serial.println(gateway);           Wi-Fi: // + long rssi = WiFi.RSSI(); Serial.print("M  : (RSSI):"); Serial.print(rssi); Serial.println(" Œ "); Serial.println(); } Создайте тестовую программу клиента _              ,     %             . 7                  . #  Arduino        ,            . #               $   ,      :    . /  %   ,      ,   ,    . " HTTP       , 
«Глянь, мама, здесь нет компьютера!» Микроконтроллеры в Интернете 245 Пишем код вывода ответа сервера /     %   ,        "    ,              . 4        ,   ,  ,      ,    %       .   $     ,  $            config.h,   " SSID       . /* Test HTTP Client ƒ     HTTP : Arduino    WIN1500 */ // '       %  #  %  #include <SPI.h> #include <WiFi101.h> #include <ArduinoHttpClient.h> #include "config.h" WiFiClient netSocket; //     const char server[] = "myserver.com"; //   String route = "/foo"; //   API void setup() { Serial.begin(9600); //  #  $    ' $ while ( WiFi.status() != WL_CONNECTED) { //   ', Serial.print("   '      : "); Serial.println(ssid); //   R   (SSID) WiFi.begin(ssid, password); //   '  delay(2000); } // '     ,   R     : IPAddress ip = WiFi.localIP(); Serial.print("IP-: "); Serial.println(ip); } void loop() { HttpClient http(netSocket, server, 8080); // $   HTTP http.get(route); //  $ HTTP while (http.connected()) { //  '   , if (http.available()) { //      : String result = http.readString(); //    Serial.print(result); //   R } } //  #  http.stop(); // $ $ delay(10000); //  10   }
Глава 4 246 Создайте тестовую программу сервера   "                           " . *   $      , $        ,      % " . 4   =           node.js,               .        "       $  " ,         . ;          HTTP.       ,      node.js,     $           . 9 %  ,        ,     ,     .     %       $          ,           :        ,         ,     "      . '    $    ,          ,        . /* test web server ƒ - : node.js */ // '    " var express = require('express'); // // var server = express(); // // //   : '    express: C$ " server, $     express //  % # '  $,  $ //    $   : function respondToClient(request, response) { console.log(request.connection.remoteAddress); console.log(request.headers); console.log(request.query); // write back to the client: response.write("  ,  !\n"); response.end(); } //   : server.listen(8080); //        server.get('/', respondToClient); $  :
«Глянь, мама, здесь нет компьютера!» Микроконтроллеры в Интернете 247 Заключение В этой главе вам был продемонстрирован подход, позволяющий создавать очень гибкие и полезные сетевые объекты. По сути, сетевой объект представляет собой браузер, запрашивающий содержимое из Сети и извлекающий требуемую информацию, или сервер, который доставляет информацию клиенту. Такой подход можно использовать во многих разных проектах.  "  $     ,            ,    " "  -        . # % —            node.js,  "   "    " "   -  . ;                ,    %     -   ,  -   ,   . /             ,            ,       . 0      $         ,    "   ,      "   . *                ,           ,     $  . #                             %  . ;         ,    ,         " $ ,     ,     .

Глава 5 СВЯЗЬ В РЕЖИМЕ РЕАЛЬНОГО (ПОЧТИ) ВРЕМЕНИ До сих пор большинство рассмотренных нами коммуникационных проектов использовали для работы веб-браузер. Наше устройство посылало запрос удаленному серверу, сервер исполнял программу, а затем отправлял устройству ответ на запрос. В процессе этой транзакции клиент устанавливал подключение к веб-серверу, происходил обмен информацией, а затем подключение разрывалось. В этой главе мы узнаем, как удерживать такое подключение открытым. Для этого мы создадим две разные серверные программы, которые позволят удерживать подключение открытым с тем, чтобы обеспечить более быстрый и надежный обмен данными между сервером и клиентом. Музыкальный ящик Джин-Йо Мока (2004) 7  "      -    +   "  TTL-Serial/Ethernet.            "  ,     . #             -      "   %          . 0     ' -1 * (Jin-Yo Mok).
Глава 5 250 Компоненты для проектов этой главы Коды поставщиков ? A — Arduino Store, http://store.arduino.cc ? J — Jameco, http://jameco.com ? AF — Adafruit, http://adafruit.com ? RS — RS, www.rs-online.com ? D — Digi-Key, www.digikey.com ? SF — SparkFun, www.sparkfun.com ? F — Farnell, www.farnell.com ? SS — Seeed Studio, www.seeedstudio.com Рис. 5.1. Новые компоненты для проектов этой главы: 1. Матовый картон для корпуса. 2. Датчик угла поворота (энкодер). 3. Гнездовые разъемы. 4. Светодиоды. 5. Плата MKR1000. 6. Кнопка со встроенным светодиодом. 7. Перфорированная печатная плата 3 4 1 2 5 7 6 ПРОЕКТЫ 8 и 9. Управление воспроизведением видео  Arduino-   MKR1000, 1 +. AF: 3156, RS: 124-0657, A: ABX00004, GBX00011 (3   4#), D: 1659-1005-ND &            Arduino Uno     % WiFi101      WINC1500. AF: 3033   2891  N   >      Wi-Fi, 1 +. 4       +     Wi-Fi,   $       . 0        Wi-Fi       .  C      , 1 +. D: 438-1045-ND, J: 20723  20601, SF: PRT12615  PRT-12002, F: 4692810, AF: 64, SS: 319030002  319030001
Связь в режиме реального (почти) времени  (     220 , 5 +. D: 220QBK-ND, J: 690700, F: 9339299, R: 707-7612   &        , 1 +. AF: 1609, D: V2018-ND, J: 616673, F: 4903213, RS: 159-5420  H       18        "3   =, 4 +. = %                   ,            . D: 36-2204-ND, RS: 123-6835, F: 2301244  '  "3       6 , 8 +. D: 36-9300-ND, RS: 274-5086, F: 2500400  D , 3–5 +. D: 160-1144-ND  160-1665.ND, J: 34761  94511, F: 1855510, RS: 228-5972  826-830, SF: COM-09592  COM-09590 251  !    († 1 +. AF: 377, SF: COM-10982 311130001  )   , BOB-11722, SS:    , 1 +. D: GH1344-ND  SW400-ND, J: 2231822  119011, SF: COM-09337, F: 1634684, RS: 7182213  H  ). D: A26509-20-ND, J: 103377, SF: PRT-00116, F: 1593411   ).  D: ED7102-ND, F: 1122344, SF: PRT- 00115         ).  , 1 +. (  .  Интерактивные системы и цепи обратной связи В любой интерактивной системе имеются цепи обратной связи: пользователь предпринимает действие, система реагирует на это действие, пользователь видит результат реакции (или извещение о нем) и предпринимает другое действие, возможно, зависящее от результатов предыдущего. В некоторых системах реагирования цепь обратной связи может быть весьма «неповоротливой» — со значительными задержками между действием и реакцией на него, в то время как для других приложений реагирование должно быть быстрым. *  ,      «   »    3         " ,       ,                   . *    ,       ,    , — $        ,     . 3           %  -  ( .       2),                   , —                   7  % ,           . ;  ,                  %   ,        . _   ,  "            ,             . & ,   ,        .      ,       . & $                 ,             (    ), —  ,            "  . &                          $   . =                  . 4  %          ,            
Глава 5 252     "   ,        . =          ,              (  ,  $      HTTP),       $  .               ,              . *   , $       .    ,                       . 2     $ ,                   ? +  $   ,         ? 3,  ,         «  -- »,                  ?   $   -                 . &                  ,      ,  "  $  ,     . &           ,     "                  . 3                   ,        %     . & %   ,             ,         "      . #                     "               Skype  Google Hangout. #     ,    "              "           ,               ,   -   (  . chat servers). & $   %      ,  "         -  . #               "      "    .          "   +       ,  "      . *                ,     ,             ,        . Протокол TCP: сокеты и сеансы Работа каждого открытого подключения клиента к веб-серверу обеспечивается протоколом TCP1. Протокол TCP определяет, каким образом объекты в Интернете открывают, удерживают и закрывают подключение, связанное со множественными обменами сообщениями. Подключение, установленное между двумя объектами с помощью протокола TCP, называется сокетом (socket). Сокет можно представить как канал, соединяющий два объекта. Сокет позволяет передачу данных в обоих направлениях в течение всего времени удержания подключения. Для нормальной работы подключения обе стороны должны поддерживать его открытым. 9  ,   ,       -             " .      ,         ,            ,    1    %  . 4             —         ,                      . TCP, Transmission Control Protocol —        .
Связь в режиме реального (почти) времени 2               . 0   ,  "     TCP,                . & $         ,          %   %             . О «наилучшем» маршруте 0               —           %             -  ,        ,             ,                      % .                %            (session). &        ,  "  ,          (      )    ,             ,                                    ,          ,             ,  %     . & $                 TCP/IP,     Net  Processing             Wi-Fi,          4. #     TCP            . *  ,    — "  $      $       .    ,        " ,           . *            %   TCP     - 253 ,   ,    "    ,               . 0   #                     — $  UDP 2. &       TCP      "     ,   UDP     %   . >      UDP         7. Сокеты TCP и веб-сокеты     3  "    telnet     -  ,             TCP,     HTTP        . *               -  ,  ,   ,  %     webSockets,          HTML5.   webSockets ( -   )        HTTP             —   ,            ,                    . &      ,      $  ,       -  ,    —      TCP.                      . 2 UDP, User Datagram Protocol —       .   -
Глава 5 254 Проект 8 Управление воспроизведением видео на основе сокетов TCP Разработка приложений для управления мультимедиа предоставляет хорошую возможность изучить подключения, осуществляемые в режиме реального времени. Следующий проект представляет собой сетевое видеоприложение, которым можно управлять с помощью физического устройства (пульта). Сервером будет программа Processing, а клиентом — пульт, оснащенный микроконтроллером, подключенным к Сети по Wi-Fi. Экраны клиента и сервера должны быть расположены вблизи друг от друга, чтобы пользователь мог их видеть. Здесь мы используем сетевую связь потому, что она предоставляет гибкость в работе с множественными подключениями, а не ради ее возможности подключаться к удаленным устройствам. _       "      $     :       / ,            ,   ,  ,         .   %         " :            / ,        ,             . 3   1. &       " :     . 2.         TCP.   3.               . 4.        :       -  " - •         ; •    N-        ; •  . 5. 2        ,         "  . 0     ,                  .           ,       TCP-                   " "     ASCII.                 ,      ,       "             %      ( $     ). 4           ,       "        , %      " . *                 $ " ,        .           «-   »,    $ ,           . /                    . #"       "  : ? ?       — connect: n 2  n          ;          — playing: n ? ? ? 2  n  1,  0 (    );        — position: n 2  n                .          ,    — ;     — exit: n 2   n=1        ;  "         (\n).
Связь в режиме реального (почти) времени 255 Тестовый чат-сервер    ,      . #              ,    %     ,              " . =           Processing,  "  $         . 0         ,       " ,       ,              . Пишем код чат-сервера #         ,          . &    ,     net,                 . 0    : $    Server,              ArrayList       . * $  Server  ArrayList      ,       ,      setup(): /* ƒ    : Processing Z$ ,    '       R -  . ƒ     ,       . */ &   setup()     : void setup() { size(640, 360); //  } 7  draw()    "            readMessage()    : void draw() { //   $   : Client currentClient = myServer.available(); // †      ,   : if (currentClient != null ) { readMessage(currentClient); } } // '    Net: import processing.net.*; int port = 8080; // ,      // '  Server myServer = new Server(this, port); // "  ArrayList clients = new ArrayList(); // Z    $   Массивы типа ArrayList & $           ,    ,  , "    : ArrayList. /      ,      .   $      ArrayList    ,        $           . ;       ,         $  ,       . & $       ,       , $             ArrayList,      %    . `  Processing     $       Java.             ArrayList       -   Processing    www.processing.org. `  JavaScript           ArrayList,  ,   ,     Arduino  #.
Глава 5 256 [  readMessages()     " " . 0        "  (   ,  ,  "     )     $     " ,   IP-   . 4        "  ,  "    "exit",            : void readMessage(Client thisClient) { // Z    '   '       //    R: String message = thisClient.readStringUntil('\n'); // †    ,     % # : if (message == null) return; // +  R   IP-   : println(thisClient.ip() + ": " + message); if (message.contains("exit")) { // †    // ' , myServer.disconnect(thisClient); // '   clients.remove(thisClient); //   $ //    . } } [  serverEvent()   "  ,          . [   "             . 0         "     ,           ArrayList: //    '   , //  -     ServerEvent. void serverEvent(Server myServer, Client thisClient) { println("^  : " + thisClient.ip()); // + //  R IP-   clients.add(thisClient); //       //   thisClient.write(" :" + clients.size() + "\n"); //      } * ,   keyRe       %      . /             : void keyReleased() { myServer.write(key); } leased() 2                   telnet (  %   Windows 10 telnet             $  ). 4  IP- %   ,    , 192.168.1.45,  (         8080)           : telnet 192.168.1.45 8080          ,         ,  "      : telnet localhost 8080  telnet 127.0.0.1 8080.         ,      telnet,           ,   ,          ,           .        " : playing, position  exit.   exit:1          . ;  ,        ,                    .
Связь в режиме реального (почти) времени 257 Клиент пульта управления Клиент пульта управления видео отслеживает как локальный, так и удаленный ввод. Локальный ввод поступает от пользователя, а удаленный — от сервера. Клиент постоянно ожидает ввод от пользователя, а от сервера — только тогда, когда тот подключен к нему. =            " : ?          . ;         ,        ; ?       ?                     .    ; =                       " : ?        ,      ;  ?        ,       ; ?                  .  †       "       ,    "    . = $           . =      -  ,             ,          ,       ,   ,    /        "   . $      ,   "   ,   , ""     %   . &         $       ,                      . #  $         ,         , $        . &             ,  "                  :              . 4             ,      %         . Схема клиента пульта управления Требуемые компоненты  Arduino-       ,  "      Wi-Fi, 1 %.: •  MKR1000; •  ,   Arduino Uno,    % WiFi101; •      WINC1500. +       : Wi-Fi,  / , X3 (UART).  X       +  Wi-Fi, 1 %.     >       , 1 %.  9     220 0, 5 %.             , 1 %.  #  , 3–5 %. (  .      ).   , 1 %.  =    ($  )   , 1 %.       , 1 %. (     ).  . 
258 #              MKR1000. *    /   "            ,           .         ESP8266      $        / , $,          ,              ,               . ;                   /  . &                   ,        %       % . =     "        ,   "   360°.    "              . /        ,   ,         ,        "  .             $            (gray code).         $              . 9 $               . ;, $  ,         $    ,   24       . /   ,            24               / .   $               —   $  ,     $   . ;               /                       . /    SparkFun,   ,  " "           ,       - Глава 5             . 0             $    Adafruit,         "     . =                          . /                       $         . &           ,                   %   .         ,        .    ,    «" »   ,  « ». &                         (LOW)      . ;           (     )         ,       ,            "    . &            ,      ,        pinMode(pinNumber, INPUT_PULLUP). >%             /  "     (GPIO)    " (pullup)   ,                 .        ,       « »  .           ,      «" »    ,          . = $     —               ,          , ""        . #     $           .
Связь в режиме реального (почти) времени 259 45 50 55 60 45 50 55 60 I G H F C D E 35 10 A B A B C D E F G H I J J 40 C30 30          %      %       40 25 25 35 20 20 A B1 B2 15 +                            . 0                 ,         , $      15 5 5 10 1 1 *  . 5.2                     ,    . 5.3 —       $ . 7       ,              ,     . 5.4 (      )    . 5.5 (      ). Рис. 5.2. Монтаж компонентов пульта управления видео на беспаечной макетной плате. Хотя здесь использована полноразмерная макетная плата, схема поместится на макетную плату вдвое меньшего размера Рис. 5.3. Принципиальная схема пульта управления видео 220 Ом 220 Ом 3,3 В Энкодер Digital 0 220 Ом Digital 1 Digital 2 Модуль микроконтроллера Digital 3 Кнопка подключения к серверу Digital 4 Digital 5 220 Ом Светодиод индикации состояния воспроизведения 220 Ом Светодиод индикации подключения к серверу Общий
Глава 5 260         . *                                 ( .  . 5.4  5.5),            ( .  . 5.3),             ,     . =                    . 7             ,        . *  ,      % ,          ,  %     $  .       %    $        ,       ,    ! 3          ,           - C A B1 B2 Рис. 5.4. Монтаж схемы пульта управления видео на перфорированной печатной плате (вид сверху). За исключением резисторов, все компоненты схемы подключены вставкой их штыревых контактов в гнездовые разъемы платы, чтобы их можно было легко извлечь    . *  . 5.6  5.7    ,            ,    . 5.8 — %      . 4           —  ,   , ,     ,             "     . #        %   %    ,       . 0    "                73,      %    .      %                 ,          .                                  . Рис. 5.5. Монтаж схемы пульта управления видео на перфорированной печатной плате (вид снизу). Здесь хорошо видны соединения пайкой монтажных проводов, резисторов и гнездовых разъемов на обратной стороне плат
Связь в режиме реального (почти) времени 261 Рис. 5.6. Пульт управления видео, смонтированный в корпусе из твердого картона. Высота расположения деталей схемы рассчитана таким образом, чтобы светодиоды и ручка энкодера слегка выступали над верхней панелью корпуса. Прежде чем приступать к изготовлению корпуса для пульта, соберите и смонтируйте его схему, чтобы знать, какого размера корпус делать Рис. 5.7. Cхема пульта управления видео, собранная на перфорированной печатной плате и подготовленная для упаковки в корпус. Монтаж на эту плату светодиодов, энкодера и светодиодов осуществляется с помощью гнездовых разъемов. Использование дополнительных удлиняющих разъемов намного облегчает задачу подгонки высоты компонентов под корпус. Откусывайте выводы светодиодов понемногу, пока не будет достигнута требуемая высота, а затем вставьте их в разъемы. Шестигранные стойки позволяют приподнять плату над днищем корпуса, создавая пространство для LiPo-батареи, которая удобно подключается к специальному разъему в плате MKR1000. Для проекта необходимо использовать батарею емкостью минимум 1000 мА
Глава 5 262 83,8 мм Ø 5,2 мм 34,9 мм Ø 3,2 мм 73 мм Ø 3 мм 24,3 мм 8,9 мм 101,6 мм Ø 8,3 мм Ø 5 мм Ø 7 мм 33,5 мм 76,2 мм 5 мм 7,6 мм Диаметр всех нижних отверстий 3,2 мм 12,6 мм 5,8 мм 52 мм 8,9 мм 73 мм 8,9 мм 52 мм 55,6 мм 61,2 мм 68 мм 74,9 мм 5,2 мм 52 мм 34,2 мм Ø 3,2 мм Вырежьте по сплошным линиям Сделайте насечки и согните по пунктирным линиям Линии с засечками служат только для указания размеров Рис. 5.8. Шаблон для выкройки корпуса пульта управления видео. Заготовку можно вырезать из плотного картона, а затем согнуть по линиям разметки и склеить. Размеры шаблона будут зависеть от вашей сборки схемы пульта, поэтому подгоните их по месту, как потребуется. Несмотря на то, что на рисунке все размеры выглядят рассчитанными точно, в действительности они взяты с готового корпуса
Связь в режиме реального (почти) времени 263 Код клиента для управления воспроизведением видео &     ,  "         ,       : Encoder,      #  (Paul Stoffregen)  Button,    7  3  (Michael Adams). /           ,   $    %    . >  Encoder        $  . &   ,            -  $      "  / ,      ,   "    %      "   . 3   Button         "  /   . 0                    "        :   , "            . Разрабатываем псевдокод сценария клиента   ,  "         ,        (  $     )       .                   . &  "                      : /*     : Arduino */ // +'   -     : // \ #  $     : void setup() { // '     // \ #  $   # %  : // \ #  $    ' $ } void draw() { // Z        // Z     // † '   , //   -     // † $         , $     //  // † $      ' , // '   '  // † $       $ , // '    $  //        } Пишем код сценария клиента             config.h         (SSID)           ,   ,  $       Arduino    4: // config.h char ssid[] = "ssid"; // \  (SSID)   Wi-Fi char password[] = "s3c3r3+!"; //   -  
Глава 5 264 &         : // '       #include <SPI.h> #include <WiFi101.h> #include <Encoder.h> #include <Button.h> #include "config.h" %  #  %  0           IP-  (IP-  ,            )     ,     $    WiFiClient. / $           TCP         : const char serverAddress[] = "192.168.0.12"; // IP-  2    $    Encoder  Button   $     . 0           ,       ,        . * ,                                          $  : Encoder myEncoder(0, 1); // ‰$     Encoder Button playButton(2); // ‰$     Button Button connectButton(3); const int playLED = 4; // ^    '  //   const int connectLED = 5; boolean playing = false; //      //  $    long lastPosition = 0; //    $ #  // R &   setup()        /       $   . 0    ,      ,     $  ,   INPUT_PULLUP. ;                $      "   . void setup() { Serial.begin(9600);                     ,   $        4: int port = 8080; WiFiClient tcpSocket; //    //   Замените указанное здесь значение на IP-адрес своего сервера //  #  $   //  ' $ pinMode(0, INPUT_PULLUP); // \ #  $    // '  R pinMode(1, INPUT_PULLUP); pinMode(connectLED, OUTPUT); // \ #  $    // '    pinMode(playLED, OUTPUT); connectButton.begin(); // \ #  $    playButton.begin(); //   '      Wi-Fi, while ( WiFi.status() != WL_CONNECTED) { Serial.print("   '      : "); Serial.println(ssid); //   R   (SSID) WiFi.begin(ssid, password); //   '  delay(2000); }
Связь в режиме реального (почти) времени 265 О прерываниях =          Encoder             . 3                  "    "                 . 4      %        MKR1000     Wi-Fi,    ,    : #define ENCODER_DO_NOT_USE_ INTERRUPTS         . // '     ,  //    : IPAddress ip = WiFi.localIP(); Serial.print("IP-: "); Serial.println(ip);  R  } [  loop()            : readEncoder()  readButtons(),      .          $  ,    —  . 2            ,    ,            .                  . * ,        . #                  , $              ,  "   tcpSocket.connected(),       1 (  )  0 (). 3                   ,      playing,          1 (  )  0 (): void loop() { // Z    : readEncoder(); readButtons(); //     - - -  : if (tcpSocket.connected()) { // † '   , if (tcpSocket.available()) { //     //  , String result = tcpSocket.readString(); //    Serial.print(result); //   R // (   #-    ) } } //     : digitalWrite(connectLED, tcpSocket.connected()); digitalWrite(playLED, playing); }
Глава 5 266 [  readEncoder()         myEncoder.read(),    "        $  .         "   $        ,     —  . #    "        , ,           ,        . 2       "   $     "   : void readEncoder() { long position = myEncoder.read(); // Z  R long difference = position - lastPosition; //   //   $ #  if (difference != 0) { //  $ #  $   if (tcpSocket.connected()) { //   ', tcpSocket.print("position:"); //  ' tcpSocket.println(difference); //  $  } lastPosition = position; //  $    //  $ # } } &    readBut         Connect ,      ,    ,   ,    . 4  ,       ,      . 4   ,      exit:1,    . void readButtons() { if (connectButton.toggled()) { // †    // '  $  , if (connectButton.read() == LOW) { //  , if (!tcpSocket.connected()) { //   ' //   , connectToServer(); // '    } else { //   '   , tcpSocket.println("exit:1"); // '  } } } // # % # connectButton.toggled tons() &     ,           (   connectButton.toggled()   true),    "       $    (connectButton. read() == LOW),        ,          . 4    ,      ,              ,    : &       readButtons()              Play. ;  ,       ,  $           ,     . 4       ,                  playing     , ,     ,    "    "     $    : if (playButton.toggled()) { // †    //  $  $  , if (playButton.read() == LOW) { //  , playing = !playing; // $  $    // playing    if (tcpSocket.connected()) { //  ' //   , tcpSocket.print("playing:"); //  ' tcpSocket.println(playing); //  $  } } } // # % # playButton.toggled } // # % #    readButtons()
Связь в режиме реального (почти) времени * ,       connectToServer(),               readButtons(). /             .connect()   WiFiClient,            . /  "   —                   ,          . #  ,                         : 267 void connectToServer() { Serial.println("   ' ..."); //   '     $ if (tcpSocket.connect(serverAddress, port)) { Serial.println(" '  "); } else { Serial.println("^  ' "); } } 2   $        ,             Processing -  ,      . 0         ,        " .                    ,                . *             $  ,       Processing      " . 4         Processing    -     :   % <Enter>, $               Arduino. 4     ,    ,            . 0     "  ,     $      ,           ,         . X % ,       $  ,                     . Аппаратные прерывания G                   "    "                 . &          Encoder         $      . >                    Arduino    www. arduino.cc/en/Reference/AttachInterrupt. &                      . ;,    ATmega328,        Arduino Uno,          (0  1),           2  3    . *  Arduino 101              . 3   MKR1000        0, 1, 4, 5, 6, 7, 8, 9, A1  A2. [  digitalPinToInterrupt( )               . *  ,   Arduino Uno   digitalPinToInterrupt(3)  "     1. * $       Arduino 101,    $       .
Глава 5 268 Доработка видеосервера 0             -      ,            "                         .              "      ,   -  , $,      ,         "   Processing       " .   $         "      : ?          ;  —    ?   setup() —               ; ?   draw() —                 ; ?   serverEvent() —    ?   readMessage() —   «-   »      "        "   . +   "   : ?   movieEvent()—     ,         ; ?   scrub() —             . - >  video           ,          3. 0       %     ,    Processing          H.264. 9                 %   —  640×480  . 4              ,           ,       . &                    data.  ; Добавляем в скетч код для работы с видео &        video                    "    (           % ): /* +  : Processing */ // ' -     : import processing.net.*; import processing.video.*; //    : int port = 8080; // ,      '  Server myServer; // "  ArrayList clients = new ArrayList(); // Z    Movie myVideo; // $     boolean playing = false; //     : //    /   String lastMessage = ""; //       
Связь в режиме реального (почти) времени 269 &   setup()       size(),                 . &         size()    %      (  )  ,       $   movie         . 0      scrub(),    "             ,      : void setup() { size(640, 360); myVideo = new Movie(this, "movie.mov"); // ‰  // #  Š  Movie: myServer = new Server(this, port); //    scrub(0.0); // $       } &   draw()                  . 2 ,   $      «   »    3,            ,  "      "    ,   $  : void draw() { //   $   : Client currentClient = myServer.available(); // †      ,   : if (currentClient != null ) { readMessage(currentClient); } // N!      : image(myVideo, 0, 0, width, height); // N!  ,       : fill(15); // C -    text(lastMessage, 11, height-19); //     fill(255); //    text(lastMessage, 10, height-20); //      } =     : movieEvent()  scrub(). [  movieEvent()               . &       — $       .read()   video      . void movieEvent(Movie myVideo) { myVideo.read(); } void scrub(float newPosition) { myVideo.loop(); //    myVideo.jump(newPosition); // $       //  if (!playing) myVideo.pause(); // * !    //    ,    } [  scrub()             . *         .loop()          %   "       "   .jump(). 4              ,     .pause():
Глава 5 270 * ,      readMessage(),     " "   ,   ,      % . *                 -  ,      : if (message.contains("exit")):    , "   trim()         «  »: %   ,        . /              . *                (   ,   Arduino printlin()         \r\n —            ),      %             . void readMessage(Client thisClient) { // Z    '   '    //       R: String message = thisClient.readStringUntil('\n'); // †    ,     % # : if (message == null) return; // +  R   IP-   : println(thisClient.ip() + "\t" + message); message = message.trim(); // `     String[] decodedMsg = split(message, ":"); // K  //      String property = decodedMsg[0]; // $   —  int value = int(decodedMsg[1]); //   —    2  "                :      — $    " ,   —     : split() +                  ,          ( if),       "   . #  playing (     )               : #"                   "   position      . // *      !    , //           if (property.equals("playing")) { playing = boolean(value); // $      //    if (playing) { // *  , myVideo.loop(); //        } else { //     myVideo.pause(); //      } } // *       (position), //      : if (property.equals("position")) { float frames = value * 0.033;
Связь в режиме реального (почти) времени =              0,033   : 3   exit ( )        : &         "          ,         draw()     $  : 271 float videoTime = myVideo.time() + frames; scrub(videoTime); // $        // () } // *        (exit), //   : if (property.equals("exit") && value == 1) { myServer.disconnect(thisClient); // N   clients.remove(thisClient); //      //  . } // 9          //      # : lastMessage = thisClient.ip() + ": " + message; } #      $           ,   -  . 2        ,         "           telnet,       $. *        "                . *  . 5.9       —       ,   "    .            ,        "      . *     $ , "    %                          . /      %,           %  "        ,       .   $                      " .    ,          . Использование Raspberry Pi для управления видео &            $           . =          Raspberry Pi        .       HDMI-              Processing. &  Raspberry Pi 2  3    $    .     HDMI   Raspberry Pi       ,     USB —     %. 2                . '        Processing,              ,              Processing   -     1. #      Processing Raspberry Pi               ,        . 2              Raspberry Pi "    Programming,         processing       . &  Processing  Raspberry Pi        ,          ,      video,     $     .        Processing  Raspberry Pi       : https://github.com/processing/processing/wiki/Raspberry-Pi.
Глава 5 272 Рис. 5.9. Снимок экрана воспроизведения видео сервером Processing. В нижнем левом углу изображения можно видеть IP-адрес клиента и его последнее сообщение Проект 9 Управление воспроизведением видео на основе протокола WebSocket При работе скетча видеосервера из предыдущего проекта вы, наверное, заметили некоторую задержку между моментом воздействия на элементы управления пульта и моментом, когда в Processing начиналось воспроизведение видео. Объясняется это тем, что для воспроизведения видео требуются значительные вычислительные ресурсы. Так что было бы предпочтительней отделить серверную часть скетча, которая обрабатывает сетевые транзакции, от части, которая работает с видео, чтобы серверу не приходилось выполнять объемные вычисления. Здесь мы это и сделаем, создав веб-сервер в node.js — вместо сервера Processing, и веб-страницу — вместо клиента дисплея на Processing. Клиент пульта будет управлять видео на клиенте дисплея, а сервер станет управлять сетевым обменом. Постоянное подключение между клиентами и сервером будет поддерживаться с помощью веб-сокетов (webSockets). &       :     HTTP-  ,  $       4? &             ,  ? &        ,    ,  ,            "              HTTP       . *    ,    HTTP           ,    $                   —  %     ,                       .      HTTP                    %        webSocket. /  %   -  HTTP       %      ,            ,       "        . &         TCP                 . $   webSocket          ,  "                     . *  . 5.10     -        . #         —       ,       . 4        ,             "          .
Связь в режиме реального (почти) времени 273 0    -     ,      TCP-  . #         HTTP,        " : Upgrade: websocket Connection: Upgrade\r\n Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ== Sec-WebSocket-Version: 13 2 Upgrade  Connection       ,          ,      Sec-WebSocket-Key           ,    Sec-WebSocket-Version           webSocket,     . 0           " :                    . *   ,      %  " ,    ,       webSocket. = %    "    webSocket,            . &  "    -       HTML5       JavaScript,              HTML. ; "            webSocket  node.js. &    ,  $             —   ws. >   Arduino,       ,      webSocket   ArduinoHttpClient,         "     . HTTP/1.1 101 Switching Protocols Upgrade: websocket Connection: Upgrade Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+x0o= О взаимодействии библиотек webSocket    Sec-WebSocket-Accept         , %           webSocket,              . Рис. 5.10. Блок-схема видеосервера на веб-сокетах. Сервер предоставляет видеостраницу HTML и видеоресурс для браузера посредством HTTP, затем посредством заголовка HTTP Upgrade подключает веб-сокеты клиентов пульта управления и дисплея. Этот сервер может одновременно поддерживать несколько клиентов обоих типов 7    webSocket              ,                           . *    $     ws  node.js    %      Arduino  HTML5. 4      %        ,        ,               . Устройство видеоклиента Программа клиента webSocket Веб-клиент Устройство видеоклиента Веб-клиент Микроконтроллер Серверная программа на node.js Программа клиента webSocket 1 Микроконтроллер 2 HTTP GET/ Upgrade: websocket position: n playing: n exit: n Веб-клиент 1 HTTP GET index.html 2 HTTP GET /movie.mov 3 HTTP GET/ Upgrade: websocket Веб-сервер Устройство видеоклиента
Глава 5 274 Сервер и клиент браузера Серверы webSocket создаются поверх серверов HTTP, поэтому нашим начальным сервером для этого проекта станет HTTP-сервер на основе библиотеки express node.js (вспомните сервер, с которым мы работали в главе 4). А клиент браузера будет страницей HTML, отображающей и управляющей видео с помощью библиотеки p5.js языка JavaScript. Пишем код сервера на node.js *      ,    $   express.js. #                wsExpressServer.js, a        express,   $    : $ npm install express #    ,      $  ,      public    ,          4,     $  . /* Z webSocket   express : node.js */ // '    : var express = require('express'); //    var http = require("http"); //    express http var server = express(); // c express var httpServer = http.createServer(server); //  http //    %   $ -   /public: server.use('/',express.static('public')); //   : httpServer.listen(8080); //   '  http >  webSocket      $     http node.js, $      $ $     express,            : ~     ,      ,    ,       . *    -   ,        . '  $  -   ,       p5.js. Промежуточное программное обеспечение [  express.static()              ,  "   . /          HTTP,               —   http.get()  http.post(). &   "                     . [  .use()        ,           ,       0,         .
Связь в режиме реального (почти) времени 275 Добавление интерактивных элементов с помощью p5.js &   1         JavaScript p5.js, "         -      ,  "  Processing. ;     %     ,   $  . #       ,   public                  p5.js. =          ,        : public/ index.html sketch.js libraries/ p5js p5.dom.js p5.sound.js 4             p5.manager,      p5.js             "  : $ p5 g -b public 2      public      p5.js        : $ p5 update &   "               :    node.js, "   ,  public,  "    p5.js. #      node.js  p5.js           . Пишем код             index.html   %     p5.js,          "  : <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <script type="text/javascript" src="p5.js"></script> <script type="text/javascript" src="libraries/p5.dom.js"> <script type="text/javascript" src="sketch.js"> <title></title> </head> &   JavaScript,   ,          sketch.js. 0   $          " : /*     : p5.js */ var myVideo; //     function setup() { myVideo = createVideo("movie.mov"); // \ #  $   // R$  " Movie.     R %  //      %   ,     // $  , -     ( '  //         % ) myVideo.size(640, 360); //  $   //  $  myVideo.position(10, 30); //     myVideo.loop(); // + $   }
Глава 5 276 #          public,       . ;      %           . 2        : 2                 "  : - http://localhost:8080 &               . $ node wsExpressServer.js Добавление функциональности webSocket ;  ,      HTTP-   HTTP- ,                webSocket. =                -     . 5.10     "    " ,    -       1  2, —   %          index.html     .  %        3. # %   %  $  —             webSocket,             .      $     ,         "    . + "        "  : ?       — connect: n 2  n      ;     ?          — playing: n ? 2  n  1,  0 (    );        — position: n ? 2  n                .          ,    — ;     — exit: n ? 2   n=1        ;  "         (\n). * $ ,     ,           JavaScript, "        JSON,     JavaScript         . /   ,  "       ,    —   ,   «-   »    . 2       $                   JSON.parse()  JSON.stringify(). Пишем код для webSocket &            ws   $  (           *               ,  $       .     , server,    $   % ). >  ws               : $ npm install ws /* Z webSocket   express : node.js */ var express = require('express'); // ' // express   
Связь в режиме реального (почти) времени 277 express.js,              . &    , httpServer,       ,       HTTP. +     , wss,     ,       webSocket: var http = require("http"); // '    http var WebSocketServer = require('ws').Server; //  Server //   ws var server = express(); //  express var httpServer = http.createServer(server); //  http var wss = new WebSocketServer({ server: httpServer }); //    // websocket &                      HTTP. ;       webSocket   %       "   webSocket: //   : httpServer.listen(8080); //   '  http wss.on('connection', connectClient); // N!  // webSocket: =       express            public,        newClient()    "   webSocket. /           %    ,     .         %          $  . &     connectClient()            :     "          . +      .size, .length      ,     wss.clients      set. & JavaScript $   set     ,   $        . &   ws        $   set,  "  wss. clients:    webSocket     "  :   "  ,         %.   $             ,     %             connectClient(). ;             : readMessage(), readError()  disconnect(). // serve static files from /public: server.use('/',express.static('public')); function connectClient(newClient) { // 7          webSocket: function readMessage(data) { //     #     } // if there's a webSocket error: function readError(error){ console.log(error); } // $       webSocket: function disconnect() { console.log('Client ' + newClient.clientName + ' '); } // 9      newClient.on('message', readMessage); newClient.on('error', readError); newClient.on('close', disconnect); // 7          , //     : var greeting = {" ": wss.clients.size}; newClient.send(JSON.stringify(greeting)); }
Глава 5 278 +            readMessage()   ,       " "  ,     %,    . 2  «%»     $  ,      , $ .  " "      playing  position,           ,            . [  broadcast()  $         . 4  " "      exit,        1,       webSocket  $  : [  broadcast()  connectCli     ent(). 0            webSocket —     $ "  . 4  ,      %  "   "  . =     sendToAll()    $         wss.clients       .forEach(): // 7          webSocket: function readMessage(data) { var result = JSON.parse(data); //      //   JSON if (result.hasOwnProperty('clientName')) { //   // clientName, newClient.clientName = result.clientName; //  //    } if (result.hasOwnProperty('playing') || //   //  playing, result.hasOwnProperty('position')) { //   broadcast(newClient, result); //     //      } if (result.exit === 1) { //    exit, console.log("  " + result.clientName + "  "); newClient.close(); //   webSocket } console.log(result); //    #     } // $          //   webSocket: function broadcast(thisClient, data) { function sendToAll(client) { if (client !== thisClient) { console.log('‹      :' + client.clientName); client.send(JSON.stringify(data)); } } //      sendToAll()  ! #  //  wss.clients: wss.clients.forEach(sendToAll); } #  webSocket     %         Processing    % . &-  ,  webSocket           clients,      Processing,             ,  ,  ArrayList. &- , $      " "     —                          .   -    -  " "       readMessage()   Processing,                       . *   %            ,      Processing       ,   . +,      ,        webSockets.    ,        ws,
Связь в режиме реального (почти) времени 279          $        . *           -    ,      sketch.js  $    "              -  . =        $          . Модифицируем сценарий sketch.js &                         ,       " ,    -     "  " . &    message     client    browser,    ,         . ~  $            ,             : /* &   setup()        HTML       div,    $   createDiv(). & $       "    . 2       webSocket      . ;           %    :   —      %     ,    —    "  : function setup() { myVideo = createVideo("movie.mov"); // \ #  $   // R$  " Movie: myVideo.size(640, 360); //  $   //  $  myVideo.position(10, 30); //     myVideo.loop(); // + $    #  lastMessage = createDiv(''); // 9   div  //     lastMessage.position(10, 10); // %  !  socket = new WebSocket('ws://' + host); // $  //     socket.onopen = sendIntro; // $    //   socket.onmessage = readMessage; // $  //     }      ,        draw(),     $           ,    webSocket. [  sendIntro()       "              : function sendIntro() { // $   Š      //   : socket.send(JSON.stringify(message)); } Video client context: p5.js */ var var var var var myVideo; //     socket; //  -  lastMessage; // $          host = document.location.host; // Œ     message = {"client": "browser"}; // 9 !  , //     
Глава 5 280 [  readMessage()           . 0    " " ,          JSON,    "        : playing  position.    $                    ,   ,  $     readMessage()    Processing. &     readMessage()   "            "       : #          sketch.js,    ,    "  ,          . &                 "         (  . 5.11). 3                    "  { client: 'browser' }. ;                . function readMessage(event) { // ~      : var msg = event.data; // 9      // onmessage var videoTime = myVideo.time(); // $    //    var message = JSON.parse(msg); // $   //     Š  JSON // *      !    , //           if (message.playing) { myVideo.loop(); } else { myVideo.pause(); } // *       position, //      : var value = parseFloat(message.position); if (!isNaN(value)) { // * #     , var frames = value * 0.033; // 1   .    //    30      videoTime += frames; //        //   myVideo.time(videoTime); // `     } // 9        //      # : lastMessage.html(JSON.stringify(message));   } Рис. 5.11. Кадр видео в окне браузера 
Связь в режиме реального (почти) времени 281 Клиент пульта управления WebSocket Клиент пульта управления для этого проекта физически такой же, как и клиент пульта управления предыдущего проекта. Для него можно использовать ту же схему, изменив при этом только программу микроконтроллера. Единственное различие между этим клиентом микроконтроллера и предыдущим состоит в том, что вместо подключений сокетов TCP этот клиент должен открывать подключения webSocket. Для этого мы воспользуемся библиотекой ArduinoHttpClient, опыт работы с которой у нас уже имеется. Эта библиотека содержит класс webSocket, благодаря которому задача открытия подключения не представляет никаких сложностей. Пишем код клиента пульта управления *         Arduino    "    . &          %             ArduinoHttpClient. ;                   $   webSocket (           % ). >%               . [  setup() "       : [  loop()        "    . 7       TCP-    webSocket,              . [  parseMessage()   webSocket        "  "    "       . X %     , "    "        Stream  read()  readString(). ;                      connectLED,          webSocket,  TCP-  : /*   webSocket       : Arduino    WINC1500 */ #include #include #include #include #include #include <SPI.h> <WiFi101.h> <ArduinoHttpClient.h> <Encoder.h> Замените указанное здесь значение <Button.h> на IP-адрес своего сервера "config.h" const char serverAddress[] = "192.168.0.12"; // IP- //  int port = 8080; //    WiFiClient tcpSocket; //   //  #  webSockt WebSocketClient webSocket = WebSocketClient(tcpSocket, serverAddress, port); void loop() { readEncoder(); readButtons(); // $   - , !   : if (webSocket.connected()) { int msgLength = webSocket.parseMessage(); // $ //     if (msgLength > 0) { // if it's > 0, String message = webSocket.readString(); //  //   Serial.println(message); //     # } } //     : digitalWrite(connectLED, webSocket.connected()); digitalWrite(playLED, playing); }
282 Глава 5 &   readEncoder()      :            TCP,         .             sendJsonMessage()         "   webSocket. #   sendJsonMessage()       : void readEncoder() { long position = myEncoder.read(); // Z  R long difference = position - lastPosition; //   //   $ #  if (difference != 0) { //  $ #  $  , if (webSocket.connected()) { //    -  sendJsonMessage("position", difference); //    JSON } lastPosition = position; //  $  //    $ # } } +     readButtons()       readEncoder().   void readButtons() { if (connectButton.toggled()) { // †   //  '  $  , if (connectButton.read() == LOW) { //  , if (!webSocket.connected()) { //  //      connectToServer(); // '    } else { //   '   sendJsonMessage("exit", 1); //   } } } // # % # connectButton.toggled         connectButton           TCP-                -  ,               connectToServer(). 3           "  exit,     .                         -  ,          "          : [  connectToServer()              ,     "  . *        webSocket.begin()  "     1, $     ,       "  . /              "        . = $       sendJsonMessage(),           : if (playButton.toggled()) { // †    //  $  $  , if (playButton.read() == LOW) { //  , playing = !playing; // $  $  //   playing    if (webSocket.connected()) { //   //    , sendJsonMessage("playing", playing); //    } } } // # % # playButton.toggled() } // # % #    readButtons() void connectToServer() { Serial.println("   ' ..."); boolean error = webSocket.begin(); // $   //   if (error) { Serial.println("‡   "); } else { Serial.println("$ "); sendJsonMessage("", 0); // N     //      } }
Связь в режиме реального (почти) времени 4       $      — sendJsonMessage(). 0      "  JSON     .     "   webSocket     " ,    $   webSocket.beginMessage() .    $        "  —        webSocket (       : text, binary, ping   .). 2            "    print()  println(). * ,   webSocket. endMessage()          " : // 9    "-   "    JSON //  : void sendJsonMessage(String key, int val) { webSocket.beginMessage(TYPE_TEXT); //   : text webSocket.print("{\"clientName\":\"MKR1000\""); if (key != "") { //   ,      webSocket.print(",\""); //     //   webSocket.print(key); //  webSocket.print("\":"); //     //    webSocket.print(val); //    } webSocket.print("}"); webSocket.endMessage(); } 2                      . 2              . &           "  : { clientName: 'MKR1000' } #          ,              "      : {"client":1} 4        ,      $              —            . Рис. 5.12. Один клиент пульта управления может одновременно управлять несколькими клиентами браузера 283 /                                       (  . 5.12). 0    $                         . *   ,     "          ,           $   .
Глава 5 284 Заключение Базовую структуру клиентов и сервера из проектов этой главы можно использовать всегда, когда вы хотите создать систему, которая управляет одновременными подключениями нескольких сетевых объектов. Основные задачи сервера состоят в ожидании подключения новых клиентов, отслеживании уже подключенных клиентов, а также в обеспечении передачи сообщений без ошибок соответствующим клиентам. Из них первостепенной задачей сервера должно быть ожидание попыток подключения клиентов.                "    ,    "                        .                            .  ,               % ,                  ,      ,          " . 0       ,  $ ,   —   , "  client  exit,          $    . #"          ,      ,  . 9           ,   " %       ,   ,      $      JSON. 2                -               . &                 "   TCP,        $  -   (webSockets).             ,   —   ,   —        TCP-  . #     ,       -    %     " "    HTTP,     -      .  $                                (    HTTP    4)       (     $  ).    $     ,                   . &  "       +             .
Связь в режиме реального (почти) времени Исходный эскиз музыкального ящика Джин-Йо Мока Композиторский интерфейс музыкального ящика 285

Глава 6 БЕСПРОВОДНАЯ СВЯЗЬ Полагаю, что вас, как и многих людей, интересует эта область, и вы приобрели мою книгу, потому что мечтаете создать устройства, взаимодействующие друг с другом по беспроводной связи. Возможно, вам так не терпелось разобраться с этим вопросом, что вы «перепрыгнули» через весь предыдущий материал прямо сюда. Если вы действительно это сделали, возвратитесь к началу и прочитайте все, что пропустили! В предыдущих главах мы познакомились с такими распространенными видами беспроводной связи, как Wi-Fi и Bluetooth, но, что более важно, в них мы также рассмотрели некоторые принципы цифрового взаимодействия, на которых основана беспроводная связь. В частности, если вы не знакомы с последовательным обменом данными между компьютерами и микроконтроллерами, вам надо обязательно изучить материал главы 2. А в этой главе беспроводная связь рассматривается более подробно — в ней мы встретимся еще с двумя типами беспроводной связи, а также создадим несколько работающих проектов. «Зиготы» Алекса Байма (www.tangibleinteraction.com) «2 » — $   % % ,   "      ZigBee.           ,                      . 0    % ,     ,          ,      ,         % $   . 0     G Z  (Alex Beim).
Глава 6 288 Компоненты для проектов этой главы Коды поставщиков ? A — Arduino Store, http://store.arduino.cc ? MS — Maker SHED, www.makershed.com ? AF — Adafruit, http://adafruit.com ? RS — RS, www.rs-online.com ? D — Digi-Key, www.digikey.com ? SF — SparkFun, www.sparkfun.com ? F — Farnell, www.farnell.com ? SS — Seeed Studio, www.seeedstudio.com ? J — Jameco, http://jameco.com Рис. 6.1. Новые компоненты для проектов этой главы: 1. Инфракрасный пульт дистанционного управления. 2. Логический пробник компании Saleae (по желанию). 3. Плата Arduino 101. 4. Радиомодули RFM95W, поддерживающие технологию LoRa1. 5. Осциллограф DSO Nano. 6. Инфракрасный светодиод. 7. Инфракрасный фототранзистор 1 LoRa (  . Long Range) —     ,   " %      /    $   .    2 1 7 6 5 3 4
Беспроводная связь 289 ПРОЕКТ 10. Инфракрасное управление цифровой фотокамерой  "      , 1 +. = $             Arduino . &            MKR1000  Arduino 101,   Arduino Uno         . MKR1000 — AF: 3156, RS: 124-0657, A: ABX00004, GBX00011 (3   4#), D: 1659-1005-ND • Arduino 101 — D: 1660-1003-ND, J: 2239331, SF: DEV-13787, AF: 3033, F: 2520713, RS: 913-9999, SS: 114990575, A: ABX00005, GBX00005 (3   4#) • Arduino Uno — D: 1050-1024-ND, J: 2151486, SF: DEV-11021, A: A000099, AF: 50, F 1848687, RS: 715-4081, SS: ARD132D2P   &     , 1 +. •  (    220 , 1 +. D: 220QBK-ND, J: 690700, F: 9339299, R: 7077612  (    10 , 1 +. D: 10KQBK-ND, J: 691104, F: 9339060, R: 7077745    &. SS: 109990013, SF: TOL-11702, AF: 468  -           (  .      ). -  -&    , 1 +. D: 365-1068-ND, RS: 654-8542  C      , 1 +. J: 106526, A: 387, SF: COM-09469, F: 1716710, RS: 577-538, SS: MTR102A2B    , 1 +. D: 438-1045-ND, J: 20723  20601, SF: PRT12615  PRT-12002, F: 4692810, AF: 64, SS: 319030002  319030001       > . D: GH1344-ND  SW400-ND, J: 2231822  119011, SF: COM-09337, F: 1634684, RS: 7182213  ]=   =                .      "   . ПРОЕКТ 11. Дуплексная радиосвязь C      , 2–3 +. D: 438-1045-ND, J: 20723  20601, SF: PRT12615  PRT-12002, F: 4692810, AF: 64, SS: 319030002  319030001  "      , 1 +. = $             Arduino . • • • MKR1000 — AF: 3156, RS: 124-0657, A: ABX00004, GBX00011 (3   4#), D: 1659-1005-ND Arduino 101 — D: 1660-1003-ND, J: 2239331, SF: DEV-13787, AF: 3033, F: 2520713, RS: 913-9999, SS: 114990575, A: ABX00005, GBX00005 (3   4#) Arduino Uno — D: 1050-1024-ND, J: 2151486, SF: DEV-11021, A: A000099, AF: 50, F 1848687, RS: 715-4081, SS: ARD132D2P  (  HopeRF RFM95W SX1276, 2–3 +.  Semtech AF: 3072, SS: 113060006   , 2–3 +. D: GH1344-ND  SW400-ND, J: 2231822  119011, SF: COM-09337, F: 1634684, RS: 7182213 (    220 , 2–3 +.  D: 220QBK-ND, J: 690700, F: 9337792, RS: 7077612  D , 2–3 +. D: 160-1144-ND  160-1665-ND, J: 34761  94511, F: 1855510, RS: 228-5972  826-830, SF: COM-09592  COM-09590       > . ]=   =                 .      "   .
Глава 6 290 ПРОЕКТ 12. Управление фотокамерой с помощью Bluetooth LE   Arduino 101     Arduino      Bluetooth LE  nRF8001  nRF51822  Nordic Semiconductor, 1 %. MKR1000 — AF: 3156, RS: 124-0657, A: ABX00004, GBX00011 (3   4#), D: 1659-1005-ND • Arduino 101 — D: 1660-1003-ND, J: 2239331, SF: DEV-13787, AF: 3033, F: 2520713, RS: 913-9999, SS: 114990575, A: ABX00005, GBX00005 (3   4#) • Arduino Uno — D: 1050-1024-ND, J: 2151486, SF: DEV-11021, A: A000099, AF: 50, F 1848687, RS: 715-4081, SS: ARD132D2P  N  Bluetooth LE (Bluetooth 4.0), 1 +. • AF: 1697 &           RedBear BLE Nano "    USB- MK20. MS: MKRBL5, SF: WRL-14071  C      , 1 +. D: 438-1045-ND, J: 20723  20601, SF: PRT12615  PRT-12002, F: 4692810, AF: 64, SS: 319030002  319030001   &     , 1 +. J: 106526, A: 387, SF: COM-09469, F: 1716710, RS: 577-538, SS: MTR102A2B  (    220 , 1 +. D: 220QBK-ND, J: 690700, F: 9337792, RS: 7077612  +   > ,  &   ,  $    Bluetooth LE, 1 +. 7     ,            ,  "  Bluetooth LE. 4      ,  "   %       ,   $   "   .  ]=   =                .      "   . Почему не вся связь беспроводная? Преимущество беспроводной связи кажется очевидным — нет проводов. Это значительно упрощает конструкцию любого проекта, в котором взаимодействующие устройства должны перемещаться. Носимые сенсорные системы, цифровые музыкальные инструменты, дистанционно управляемые транспортные средства — вот всего лишь несколько примеров устройств, работу с которыми можно упростить, используя беспроводную связь. Но этот тип связи имеет определенные ограничения, которые необходимо принять во внимание, прежде чем переводить на нее все, что движется. ? C        A ,   . +        ,                 . [        $   ,                     , —               , $     ,       %     ,           (   " ) "       . ? C    ,   , =        =   =  . # ,    -          ,           ,  "   "       . +  $   ,     "                     . *  ,     Bluetooth, %      Wi-Fi (    802.11b, g  n)  ZigBee (    802.15.4) —             2,4 qq
Беспроводная связь 291 (     802.11n     5 qq). +        ,          %   ,   %       ZigBee          ,  ,   ,      Wi-Fi, -          . ? ? C      >   $ $ . #           ,     .   "   "         ,                 %                ,    $  . #                   $ ,   $              %  , ,    ,      ,                   % ,     . C           . X            $     ,     . 3        «  »,         . >        ,          . 0                   %,        %    -   .       $     %  ». # «    ,                  $  $          ,  $     %          . 4                 $    ,             %,             . 0          ,  "    ,          ,  ,    ,            $    . $,            ,                ,           $   ,                     . ? N       > †      . *   ,             $     $ ,              . /   $ ,     % "         %    +  . +          ,       $     $              ,      %           ,   $   ? ?  >   >. D   9     $                ,           " ,   $            . $,      "            ,                            .
Глава 6 292 Два типа беспроводной связи: инфракрасная и радио Большинству людей в своей жизни и работе приходится сталкиваться с двумя видами беспроводной связи: посредством инфракрасного излучения и посредством радиоволн. С точки зрения пользователя или разработчика, основная разница между ними состоит в их направленности и радиусе действия.                        . &    ,                     ,                       $  . +          ,              , Рис. 6.2. Сигнал от инфракрасного светодиода распространяется в виде направленного луча (слева), а сигнал радиоантенны — во всех направлениях (справа)        .      ,                   , $      « »      . X               ,                       . =                    . & %              . +  ,         .   $,      "              ,           %   ,       . #   ,                  %                  ,    —        . 9                       . 6.2. Передатчики, приемники и приемопередатчики      ,          "     :     ,    ,      ,   ,     ,    ,       ,      ,    . 7      ,                ,   $       ?           ,                 . &     ,   ,    ,             ,   $             ,     . =       %               %,      "   ,       . ; ,   ,            . /            . ;   ,            "          ,         
Беспроводная связь               . *  ,      Bluetooth  Wi-Fi      . 0                ,  ,       ,    -     %  ,     "    .                     ,     $          -     293    . 2   —    %         ,            ? =        ,       . #         ,         "  ? 7   % $   ,   "      ,       ?         $    ,  ,              -     $     . Принцип работы инфракрасной связи X          ,                                 $          . /         ,    "              $   .   "                     (   ,       ,        . .),                         . = $,               "  ,                 . #  $     ,    # ,               .                ,       ,         "  . 2          "   ,       . ;                      %                  . *                ,     %  ,   -  ,      % $ . &  ,   ,          %  ,  $ $      ,     "        . ;   ,              $   $ $                    , "            .                     %        $          . '  %  ,     "  ,      "  . >%                     "   38  40 q. '  "              , $                    —   ,  500  2000    . =   %     $    ,                      . &          ,       $    ,            8-    . &    ,   ,   Control-S   Sony  
Глава 6 294     : 12-, 15-  20- . 3 %                RC5   Philips    14-  .  . 3    EPanorama orama.net/links/irremote.html)                   4                  ,  +       %  ,  "              . +                 -  $     ,  SparkFun, Adafruit, Seeed Studio   .   SparkFun  Adafruit        - 4       ,     ,   %      —    %    ,                "      ,     ,    "          . *          "         . (www.epan        . Как увидеть инфракрасный свет? '              ,  $             . '   ,  % "        , —        - . 4     ,  -  $  . *  . 6.3               ,         - ,         : —     ,  —  . # "                       ,       $          . *    "            , $,                 -  ,       -              ,    $               , —   ,        . Рис. 6.3. Вид инфракрасного светодиода через веб-камеру: слева — светодиод выключен, справа — включен
Беспроводная связь 295 Проект 10 Инфракрасное управление цифровой фотокамерой В этом проекте мы будем управлять цифровой фотокамерой с помощью инфракрасного светодиода и микроконтроллера. Этот простой проект позволит вам получить общее представление о работе инфракрасных устройств дистанционного управления. >%             (SLR2)          "      .              ,                :    . & +         %  ,   "                     . &  $          ,        . =               Adafruit    https://learn.adafruit.com/ir-sensor     MulitCameraIR,    #    2   (Sebastian Setz). ~ $               Arduino,                   . & %                            Canon RC-3  Nikon ML-L3. ; ,        Nikon  Canon,         %       ,   $  %      . *       ,   "                %         "         . 2 SLR, Single Lens Reflex —         . Чтение ИК-сигнала =                              . +    $   %          DSO Nano. ;            Logic 4   Saleae (www.saleae.com),         ,      Nano. 0   DSO Nano,            ,                       $  (  . 6.4). 3       Logic 4    ,           ,        $   . =                     "  $      ,     «  » Рис. 6.4. Отображение начальной части ИК-сигнала пульта дистанционного управления камеры Nikon на экране осциллографа DSO Nano
Глава 6 296 (" )               .           ,     %          ,       %  ( $  , %         %    ). >%               ,                  . X             ,      ,     ,              . &                                . ;      "    "      .       Canon      32,7 q,    Nikon —    38 q. '             . & . 6.1                    Canon  Nikon. /            $         ,        .       %         ,            "     . /       ,            . Таблица 6.1. Сигналы инфракрасных пультов управления для спуска затвора двух разных цифровых камер Nikon (38 кГц) Canon (32,7 кГц) 2  —  16   —  27  —   7,33  —   0,4  —  16   —  1,5  —   100  —      0,5  —  3,44  —   0,5  —  65  —        Схема инфракрасного пульта управления Требуемые компоненты  Arduino-   +   / .  +        , 1 %.     :       , 1 %.  +           , 1 %.  0  , 1 %.    -  +     , 1 %.   , 1 %.  9     220 0, 1 %.  9     10 0, 1 %.  >         %   , 1 %.
Беспроводная связь 297 A B C D E F G H I J 1 1 5 5 10 10 15 15 3,3 В Модуль микроконтроллера Кнопка Цифровой вывод 7 20 20 25 25 30 30 Цифровой вывод 4 220 Ом Общий A B C D E F G H I 10 кОм J Рис. 6.5. Монтажная (слева) и принципиальная (справа) схемы простейшего инфракрасного пульта управления 0        $             . /       %  ,       $   . #       . 6.5. 2      Arduino 101,          %         MO, AVR  Curie.                   ,            ,                          - . #             (  $     ),   "    (  . 6.6). Пишем код для инфракрасного пульта управления    ,                       "     "      : /* \     : Arduino ‰   # %     ' \-$ . */ const int pushButtonPin = 4; //  , //   '  const int IRPin = 7; //  , //   ' \-  const int CAM_NIKON = 1; //   # %-   const int CAM_CANON = 2; int buttonState = 0; //      int lastButtonState = 0; //      &   setup()               +-              : void setup() { pinMode(pushButtonPin, INPUT); //   //      pinMode(IRPin, OUTPUT); //  \-  //      }
Глава 6 298 &   loop()                ". 4      ,        ,    $   shutterClick(),         . =  Canon      $      CAM_CANON. 2       "        "   : void loop() { // Z      ' buttonState = digitalRead(pushButtonPin); [  shutterClick()          . +-            ,        $  : void shutterClick(int cameraType) { if (cameraType == CAM_NIKON) { //    Nikon unsigned long irFrequency = 38000; //  //   \-  = 38 š# for (int i = 0; i < 2; i++) { //    //  IRPulse(2000, irFrequency); // '   //  2  delay(27); // '    27  IRPulse(400, irFrequency); // '   //  0,4  delayMicroseconds(1500); // '   //  1,5  IRPulse(500, irFrequency); // '   //  0,5  delayMicroseconds(3500); // '   //  3,44  IRPulse(500, irFrequency); // '   //  0,5  delay(65); //  $ 65    } }  : if (buttonState != lastButtonState) { // †   //  $  , if (buttonState == HIGH) { //   shutterClick(CAM_NIKON); //  \-  //   $ } } // Z-        '  : lastButtonState = buttonState; } if (cameraType == CAM_CANON) { // †   Canon unsigned long irFrequency = 32700; //  //   \-  = 32,7 š# for (int i = 0; i < 2; i++) { //    //  IRPulse(489, irFrequency); // 16   //     delayMicroseconds(7330); //  $ 7,33  IRPulse(489, irFrequency); // 16   //     delay(100); //  $ 100    } } }
Беспроводная связь '               ,  shutterClick()       IRPulse(). /   "      Arduino tone()             +-     "   ,       %                  ,        .   tone()              delayMicroseconds(), $ $             : 299 //  \-  $          : void IRPulse(unsigned long interval, unsigned long frequency) { unsigned long now = micros(); //       //   tone(IRPin, frequency); //    IRPin //   $  while (micros() - now < interval);//     //    $   noTone(IRPin); // '   } Рис. 6.6. Это устройство создано с использованием только что описанного подхода. Микроконтроллер Arduino в корпусе, стоящем рядом с камерой, улавливает изменение показаний пассивного инфракрасного датчика А и посылает камере инфракрасный сигнал с командой сделать снимок А
Глава 6 300 Принцип работы радио Радио работает на основе электромагнитного эффекта, называемого индукцией. Суть его заключается в следующем. При изменении протекающего в проводнике электрического тока генерируется соответствующее магнитное поле, излучаемое проводником в окружающее пространство. Если в это изменяющееся магнитное поле попадает другой проводник, оно индуцирует (наводит) в нем соответствующий электрический ток. Частота изменения магнитного поля равна частоте изменения электрического тока в первом проводнике. Таким образом, если мы хотим передать электрический сигнал, не используя для этого проводов, мы можем генерировать переменный электрический ток определенной частоты в одном проводнике, а к другому проводнику подсоединить схему для выявления изменений тока на этой частоте. Таков вкратце принцип работы радиосвязи. 9   ,          ,    "    ,         ,    ,           . '              ,   %                . 0        "  "              . 3          ,        % ,     . *          ,             .                   , $    $           . *                    : €    = 5,616 '  /   &š# = 14,26606  /   &š# /       «American Radio Relay League Handbook»3 1929              . &    $               . /     ,                       5%  ,     ,          . =        ,      ,                3,0×108 / . ;  ,          ,   , 915 7q,    : 1/915 × 106 × 3,0×108 × 0,95/2 = 0,1557382  +     15,6 .     ,       ,             . >        $                             . =                        %   . Аналоговая и цифровая радиопередача               ,              . &              $      (   ,   )       "  4. /       "  ,         . &      "          , $              "                $ . +  ,       4 3 #         . *         .   "    -
Беспроводная связь 301      ,     — .  $     [  . 9 "          %   . /       ,          . &      . ~   ,           $  ,      ,        , "    ,      . ;, %         , "    ,     "        . /                   ,              $  . 4      ,    ,              . /     $     . Z  $        "                          . /         %     . 7    ,            ,        . > " $        $   "        ,        . &                     " ,       $         . ; $      " $      0  —     7  [  ,               . & $             $     $     . _   "               ,   $   , " $              . &      %     ,              , —                   ,             .  ,  ,     ,    "              Радиопомехи +             $  . 4                ,    ,            -       % "     . *                ,        9 Wi-Fi           ,              !,      $                 . 7           "     $      "  ,                " , ,    ,       . 0   ,   ,     $             ,                     . 0            $         .     $          . = $     (  )  "    ,    —   %.       $       %          ,              ,  ,        ,  " . 3  ,    "  -           
302 $      %   $    . ;  , $                 ,            " . ; $                 . #"                        %            . $                    . 2                "                      . Мультиплексирование и протоколы              ,      "    . #           , $,             ,         . & $    %    :        ,    ,    . &    $,               ,       $                  . #      . /             ,       . 4      ,     ,         ,      "                         . +  ,              . Глава 6 +   ,            , $ ,     . ;       "     %              . +  ,                 . 9                        —          (       ).   $                  . 9     $   ,     ,           . 3                   "        %,              %   ,      (               1:  %    ,   %  % ,     ). +  ,                     ,          ,  %   () "             . / "             "      (          )             . *     %  . 4       "         ,       "       . &      $              !    (   ). /   ,                       . +        "    ,                 ,          $  . &                   
Беспроводная связь     . *  %     $      ,   %             . 7         $     ,              ,             . /         . ;    ,         ,             .                 . *  , Bluetooth, ZigBee  Wi-Fi — $              ,      . & $                      (        Wi-Fi — $       Ethernet). 0  $              ,              ,       . 0                     ,                    . 3         —          %         . 0         "   . Радио: передатчики, приемники и приемопередатчики         , %,    ,    -           ?  "    ,       ,        ,        ,         . & %        . > ,   ,       (,    ,    )         ,               . 303 *                 . #                             . &      ,         ,        ,     ,      ,          . ;       ,                  . 4           ,  "      . 3                 "       , "       .   ,                      ,               . *         . &  "   %             ,          . *  ,   Bluetooth        2              Bluetooth,   ,         %. 9   ,        "   ,           . =           %          ,           %  %   . # %                         ,                . /   ,   %,  "     -            ,     "             .
Глава 6 304 Радиосети Расстояние, на которое сообщение может передаваться по радио, в основном зависит от мощности передатчика и чувствительности приемника. Повышение мощности передатчика означает повышение расхода электроэнергии. Но дальность передачи сообщения можно повысить, используя радиосеть. В таком случае сообщения можно передавать по цепочке от одного радиоустройства к другому или сохранять, пока требуемый приемник не окажется в радиусе действия передатчика. Технические характеристики радиосети определяются методом ее управления балансировкой энергопотребления, радиуса действия и доставки сообщений. Топологии радиосетей 9       3           . =                ! ! !     . &             "       $  (  . 6.7,  ),     —  %  "                 (  . 6.7,  ). &  ,         ,              %  "      (  . 6.7,  ). #            % "  . X $        ,     "          .              ,                   . ;               . &  , "   ,   %  "  . X      ( .  . 6.7,  )   "    . 0       %  "               ,   ,                % .               Bluetooth. Рис. 6.7. Три типа топологии радиосетей: полносвязная (слева), звездообразная (в центре) и ячеистая (справа). В первом типе все узлы соединены друг с другом напрямую, во втором — обмен между периферийными узлами реализуется через один центральный узел, а в третьем — сообщения могут передаваться от одного узла другому через цепочки промежуточных узлов Прямое соединение узлов сети Топология «Звезда» Ячеистая топология
Беспроводная связь 305 &         ( .  . 6.7,  )                              %  "    ,        . /                Wi-Fi,              %  (  ). &      ( .  . 6.7,  )         %  "      —      "  ,       ,      % . *    "       ,             , $              %  "       ,    "   %  .            ,   " $            . 7 %  "          "     ,               ,           %    -   .   $  %   $     "    " ,             ,             "  . `                 ,             . 4     ,   %         %          ,   %            . Сеансы и сообщения #               $               ( ) —     "  .        -             .       $                ,           " . 3  ,               (  "  ),   "        .   $              "                     . 3            ,      ,           % ,                            . # Bluetooth,          2,       ,                            . X         Wi-Fi         ,    $    UDP,        ,    $    TCP. =                  . 9          (  ,   TCP    ,    UDP),            $   . 3       ( "  )     $ $  ,    $   . *      "          "               %     .              "          "  ,  "         ,      " ,     ,     "          " .
Глава 6 306 Стеки протоколов беспроводной связи ;                           . /                  (     ,       4),            —             "     ,                         .       "         , $    ,       "               ,         . /      ,                             ,           8. #          .*    ,  "         , $ "                    ,              $  . #         %       . *  ,         : Wi-Fi, Bluetooth  ZigBee —                 . & $         IEEE 802,        Ethernet. #  Ethernet         802.3, Wi-Fi —    802.15.1,  ZigBee —    802.15.4. 0      "                 . *      Wi-Fi  Bluetooth           ,     $        "   $   " . Физические радиоинтерфейсы Z                                      ,        :          X3, SPI  I2C     ,            ,  USB  -    ,                 . 9             ,       ,            ,    ,         "      . Выбор и приобретение радиоустройств В настоящее время доступно много разнообразных протоколов цифровой радиосвязи для разных промышленных, бытовых и прочих приложений, и каждый год появляются все новые протоколы. Все эти протоколы предназначены для выполнения разных задач и имеют различные ограничения. Поэтому, прежде чем приступать к работе над каким-либо проектом с использованием радиосвязи, следует внимательно рассмотреть доступные варианты. Далее отмечаются несколько моментов, которые следует принять во внимание при выборе радиоустройства для своих проектов.
Беспроводная связь 307             %     . +   $     ,                . *                      Wi-Fi  Bluetooth. /          %                          ( ,  %  ,   ),         (   ,  %,  ,    . .)  +  . &               —     "    —           ZigBee. 3   ANT  "              —   ,                      . =  %      "                LoRa. =       $     . *  ,     ZigBee  XBee   802.15.4   Digi          ZigBee     ,                 Digi         . /      ,                   Digi. 0      ,        Wi-Fi  Bluetooth  %     ,         .        $     %              , $     Bluetooth   Nordic  Texas Instruments            Bluetooth %     %    ,       . =  " ,    ,           ,      %       . ~              %  ,        ,    $      ,               . 4  ,           % . 3  %  "   "        ,             %          . 0   % %            — $              .                   —  %     . &              ,            ,  $      . ;               ,   ,              ,   %       « »,      %      %  ,       $                . 4          ,    ,               . 3            ,     ,    ,   %         . ? \     &                     .         "  ,         %      :          , SPI  I2C. ;   ,                       . ? \      . >                  ?
Глава 6 308 ? ? (    †                  . *          " ?  $       ,          ? #   %               $         ? X  ,  ,    "         ,              ,      %     ,      .    ,     ,           ,   $          . *  ,   %                ,           Wi-Fi        %   . =      %          ,  ,        -   , "  %  "    . 3      %                          %             . ?                 . =          "                ( "  ),  ,           ,  "         . ? D     ,       , ,   ,       ,            . &                . 0                            — $                     - ,            . 7  ,   $     ,          ,  $ . =                       ,               . ? ˆ ,     ,           ,  % % . +          ,  "      %     ,     $   .                      ,         . & . 6.2                  ,              . &                      $             .   %     $  ,     XBee   Digi   %             ,   -          . *              ,             +  ,            Wi-Fi  Bluetooth. 0      Bluetooth        ,   Wi-Fi,    ,  Bluetooth SIG5                     ,     Wi-Fi Alliance6  .   HopeRF          ,       5 Bluetooth Special Interest Group —       Bluetooth. 6 Wi-Fi Alliance —       ,  "       Wi-Fi-   "        Wi-Fi.
Беспроводная связь 309 Таблица 6.2. Технические характеристики нескольких наиболее популярных радиоустройств, используемых в микроконтроллерных проектах. Из них мы уже знакомы с устройствами Wi-Fi Радиоустройство Протокол Частота Топология ESP8266 Wi-Fi 2,4 qq «2 »   _ (TCP  UDP)   WINC1500 Wi-Fi 2,4 qq «2 » SPI Digi Xbee 802.15.4 802.15.4, [  2,4 qq    , X3    *   "  (        X3) HopeRF RFM69 [  433, 868, 915 7q     SPI *   "  HopeRF RFM95W LoRa 433, 868, 915 7q     SPI *   "  Nordic 51822 Bluetooth LE 2,4 qq     SPI *   "  Cambridge Silicon CSR8510 Bluetooth LE 2,4 qq     USB *   "  RF Link TTL Serial   "X3    *     (   X3) 434 7q     %  ,  $     %    . +    ,      LoRa,           LoRa Alliance7,   "   ,  $             ,               .   SparkFun  Seeed Studio         -                  X3. * $                                ,            ,            . =    %    "       . 7 LoRa Alliance (3  LoRa) —       ,  "   LoRa-            . Проводной интерфейс Протокол на основе сообщений (пакетов)/сеансов _ (TCP  UDP)         "           .                Curie   Intel        Bluetooth   Nordic Semiconductor,  "     Arduino 101. 3     ESP8266,       ,      Wi-Fi. X   $,                    ,  $       ,        " %     . &  "                     ,          LoRa,          ,             ,          Bluetooth LE.
Глава 6 310 Проект 11 Дуплексная радиосвязь В этом проекте мы подключим радиоприемопередатчик и кнопку к микроконтроллеру. Для создания канала связи потребуются два таких устройства. Каждый микроконтроллер при нажатии его кнопки будет посылать сигнал другому. Когда один из микроконтроллеров получает сообщение, он реагирует на это событие, зажигая светодиод, а также отправляет сообщение по каналу последовательной связи.   Bluetooth  Wi-Fi      ,       " "         ,      ,            -      ,     "      %     . /    %                .              $    ,       HopeRF  Semtech. & $       " %     . 9     RFM9x   HopeRF   SX127x   Semtech     LoRa. /      ,            %    "      $    . 0       %      !   ,                    ,    $         .          ( "  ), $              ,            .   LoRa         ,      . /                      . 0            LoRa      LoRaWAN. 0   %              ,               "   #   . #" ,               %  "   ,      . /               .        LoRa       ,     LoRa          !  (sync word),         " ,     $ . &      ,       " ,        . [         ,   "               ,    %    . *  ,                125 q,        — 915 7q. [         ,   %  "              125 q       915 7q. [       $          6  12,        7. >                        , $                 .
Беспроводная связь 311 Схема организации дуплексной радиосвязи Требуемые компоненты  Arduino-       , 2–3 %. +      :   / ,    SPI.  >       , 2–3 %.  9 HopeRF RFM95W  Semtech SX1276, 2–3 %.   , 2–3 %.  #  , 2–3 %.  9     220 0, 2–3 %. *   ,   ,         . 3 ,         ,   $         ,          "   . & $              RFM95W LoRa Radio Transceiver Breakout   Adafruit. *  $       % Dragino LoRa  Arduino,   Wireless SX1276   Modtronix    Seeed Studio. /            : 868–915 7q  433 7q.           915 7q,           . X                 SPI, $              "        (  . 6.8–6.11).       MOSI, MISO,    (SCK)       (CS),          (RST)              (IRQ  G0),                      . 0     ,        (G0)       D1  MKR1000 ( .  . 6.10  6.11),     D2,    Arduino Uno  Arduino 101 ( .  . 6.8  6.9),    $            . '   %     ,         .  "   $  %,                      (ANT). [                  !. «4    » $  . &    ,       915 7q         7,8 . /        , $                   (        ,               —     ). 7    $           .     —         —  %       $            . &  $        " ,           ,        30–50                 . Полосы радиочастот ISM & ,   ,  %               . /           ISM,          % ,          8. =      $      % . =   ISM     8 ISM — Industrial, Science, Medical. 7      $               . =    LoRa     "  :  4 : 863–870 7q  433 7q  #3: 902–928 7q  3  : 915–928 7q   : 779–787 7q  470–510 7q
Глава 6 312 A B C D E F G H I J 1 1 5 5 10 10 Антенна 15 VIN G1 GND G2 EN G3 G0 G4 SCK G5 15 MISO MOSI CS 20 20 RST RFM95 Radio 25 25 30 30 A B C D E F G H I J Рис. 6.8. Монтажная схема подключения адаптерной платы с радиомодулем RFM95W к плате Arduino 101 или Arduino Uno (для обеих этих плат задействуются одни и те же выводы). Обратите внимание на подключение антенны, длина которой должна быть около 7,8 см для частотного диапазона 915 МГц и 16,5 см для 433 МГц. Обе антенны четвертьволновые Рис. 6.9. Принципиальная схема подключения адаптерной платы с радиомодулем RFM95W к плате Arduino 101 или Arduino Uno +3,3 В +3,3 В G0 Напряжение питания D13 SCK D12 MISO D11 MOSI Модуль RFM95W 7,8 см CS Микроконтроллерный модуль Arduino 101 или Arduino Uno RST D7 ANT Общий D6 D5 D4 D3 D2 220 Ом Общий Напряжение питания
Беспроводная связь 313 45 50 55 45 50 55 60 40 RFM95 Radio 40 J 60 35 A B C D E F G H I CS RST G5 MOSI G4 MISO G3 SCK 35 30 30 G2 25 25 G0 20 20 EN 15 15 G1 10 10 GND 5 5 VIN 1 A B C D E F G H I J 1 Антенна Рис. 6.10. Монтажная схема подключения адаптерной платы c радиомодулем RFM95W к плате MKR1000. Обратите внимание на подключение антенны, длина которой должна быть около 7,8 см для частотного диапазона 915 МГц и 16,5 см для 433 МГц. Обе антенны четвертьволновые Рис. 6.11. Принципиальная схема подключения адаптерной платы c радиомодулем RFM95W к плате MKR1000 +3,3 В +3,3 В G0 Напряжение питания SCK MISO Микроконтроллерный модуль MKR1000 D10 MOSI D9 CS D8 RST D7 Модуль RFM95W D4 D3 D2 D1 220 Ом 7,8 см ANT Общий D6 D5 Общий Напряжение питания
Глава 6 314 Код для проекта дуплексной радиосвязи =  %             Arduino. *            Stream —   ,  "         ,         , — $   LoRa. =    $            ,        LoRa,            LoRa by Sandeep Mistry       . =         $      ,           https://github.com/sandeepmistry/ arduino-LoRa. Пишем код    ,                           . 2           (   irqPin)   ,     %      . *                5 ( .  ! «G     »). &    ,  Arduino Uno  101 $   2,         Cortex-M0   ARM ( MKR1000) —   1. =                       . +              : &   setup()          ,                      915 7q. 0   91543            $           #. 2  $    915×103. 2                    . * ,             ,          : /* Š  $ LoRa : Arduino */ #include <SPI.h> // #include <LoRa.h> const const const const const int int int int int ''    : buttonPin = 4; receiveLED = 5; csPin = 7; // + -    LoRa resetPin = 6; // Z   LoRa irqPin = 1; //    int lastButtonState = HIGH; // \-    byte msgCount = 0; //  - -  byte localAddress = 0xBB; // ˆ    byte destination = 0xFF; // ˆ   byte syncWord = 0xB4; // Z - $  '  (   ) byte spreadingFactor = 8; // %   (6-12); void setup() { Serial.begin(9600); // \ #  $    ' $ LoRa.setPins(csPin, resetPin, irqPin); // %     //  CS,  IRQ if (!LoRa.begin(915E6)) { // \ #  $   //         $ 915 &š# Serial.println("^     #  $# ' LoRa.    ."); while (true); // †  #  $#    } LoRa.setSyncWord(syncWord); LoRa.setSpreadingFactor(spreadingFactor); LoRa.setTimeout(10); //  $  10   //  -  Stream Serial.println("\ #  $#  LoRa ."); //     : pinMode(buttonPin, INPUT_PULLUP); pinMode(receiveLED, OUTPUT); }
Беспроводная связь [  loop()             . 4             "   ,        , $  ,        . 0     ,   $          "   . 2                                             . 4      ,   "  ,    $   sendMessage(),            . 2               lastButtonState      "   . &            onReceive(),             . /     " "       $  . *           "   LoRa.parsePacket(),         Stream,          4. /               "  . 7          7    "  UDP: [  sendMessage()        ,        " . &    ,    ,  "       (destination — 1  ),      (localAddress — 1  ),      "  (msgCount — 1  ),  "  (outgoing.length — 1  ),   315 void loop() { int buttonState = digitalRead(buttonPin);// Z  //    if (buttonState != lastButtonState) { // † $  , delay(3); //  ,   - $  if (buttonState == LOW) { //   $ //   , String message = "HeLoRa!"; //    sendMessage(message); Serial.println(message); // +  R   //   } lastButtonState = buttonState; // Z-   //  } // +    $ onReceive(LoRa.parsePacket()); } % # ' onReceive:
Глава 6 316     "  . 2           "  . ~ $    «   »  ,     $  ,                . &   onReceive(),         ,  ,   "   " : void sendMessage(String outgoing) { LoRa.beginPacket(); // ^   LoRa.write(destination); // Š    LoRa.write(localAddress); // Š    LoRa.write(msgCount); //     //   LoRa.write(outgoing.length()); //  $  //     LoRa.print(outgoing); //      LoRa.endPacket(); // $   //   msgCount++; // M   $     } * ,       onReceive().        ,   " "  " ,      . 4  $    %   0,   "          "        loop(). 4   "  ,     $,   . 2         :  ,   ,   "  "  (   " ),   "  ,  ,  "  : void onReceive(int packetSize) { if (packetSize == 0) return; // †  , // $    #  2           "    . 4    ,   "          "   % .         ,          $       $ %  "   . 4          ,   ,   "       :   "     if (msgLength != incoming.length()) { //  //       Serial.println(" :      . "); return; //     % # } // †   R      , if (recipient != localAddress && recipient != 0xFF) { Serial.println("‰     ."); return; //     % # } =    $   $   " .   $  ,       ,   LoRa           $  :             %   /%. // †    R    , //   : Serial.print(" : "); Serial.println(sender, HEX); Serial.print("  : "); Serial.println(recipient, HEX); Serial.print("ID  : "); digitalWrite(receiveLED, HIGH); // +'   //        // Z    $ : int recipient = LoRa.read(); //    byte sender = LoRa.read(); //    byte incomingMsgId = LoRa.read(); //  %  // -   byte msgLength = LoRa.read(); //   - //   String incoming = LoRa.readString();//     
Беспроводная связь 317 *      ,   $   %    : Serial.println(incomingMsgId); Serial.print("Š   : "); Serial.println(msgLength); Serial.print("Z : "); Serial.println(incoming); Serial.print("RSSI: "); Serial.println(LoRa.packetRssi()); Serial.print("Snr: "); Serial.println(LoRa.packetSnr()); Serial.println(); digitalWrite(receiveLED, LOW); // +'   //        } 2  $        (    "       )          . =               . *                         . 2     CoolTerm,                     ( CoolTerm                    )     -     -   . &              . Широковещательные сообщения   . /    ,          onReceive(),                  " . &             ,     %     " ,  ,        !   9. /          ,              . 4       ,         ,    $     $      -   (   localAddress),             0xFF.         onRecieve()   "    "  ,       $    . *                     ,      %  "    ,     ,   . 0        "         ,        %  "    ,       "    "          . &          $ " ,        +    $           , %            ,    ,      , $       $    . 0             ,                   $         . Слова синхронизации и фактор распределения &               "     ,     "             . /           ,        9 0  . promiscuous mode.
Глава 6 318 LoRa      . =   ,               .                       ,  $     $ . &       "            . 9               "      .                        ,   , —           %    . ~        %    $  ,                . 0              :               —          . /                       HopeRF  Semtech,       PDF       : www.hoperf. com/upload/rf/RFM95_96_97_98W.pdf (  RFM95W   HopeRF)  www. semtech.com/images/datasheet/sx1276.pdf (  SX1276   Semtech). 0 $           . Уровень принимаемого сигнала 0      ,             ,                 (+X#)10,     "           . >    $           8.       $     $ , "          %               . $      ,      $,   "                . Отношение сигнал/шум =      ,     ,        /11. /      ,                    ,   —     ,   %. '   %    $ % ,      . 0         %   /%            ,          %       "  " . *  %                   ,              . Циклический контроль избыточности &                           LoRa    ! 12,    . 7        !                   #  !#  !              . 4   !      #            !   . &  #  !   !  ,          ,          . 4      # ,      ,              ! .   !      !      %   ,  !   LoRa.crc(). /        ,           . * * * 9    LoRa                     . +  $      %   ,    %    ,             "  . 11 10 0  . RSSI, Received Signal Strength Indicator. 12 0  . SNR, Signal-to-Noise Ratio. 0  . CRC, Cyclic Redundancy Check.
Беспроводная связь 319 Проект 12 Управление фотокамерой с помощью Bluetooth LE В главе 2 мы научились подключать микроконтроллер к персональному компьютеру с помощью радиомодуля Bluetooth (см. проект 3). Там мы использовали профиль последовательного порта (Serial Port Profile) Bluetooth из спецификации Bluetooth 2.0. Здесь же мы возьмем устройство спецификации Bluetooth 4.0 (называемой также Bluetooth LE) и задействуем его для управления инфракрасным пультом фотокамеры из проекта 10 этой главы. /      %       ,         % ,          . &  ,   ,      ,       $              —   ,       %    . /              Bluetooth. #  Bluetooth 4.0 (Bluetooth LE)               .  Arduino 101   "    Bluetooth LE,             $   . *               . >  Bluetooth,         ,        Bluetooth     nRF8001  nRF58122   Nordic Semiconductor. /              %        ,           , —  ,   ,  BLE Nano   RedBear Lab. 4            ,               Bluetooth LE,        . &   4.0   Bluetooth    %   . Z  $     —        —      $ $  ,                Bluetooth. ;       SPP (Serial Port Profile,         )        Bluetooth       GAP (General Access Profile,   "   ),                           GATT (Generic Attribute Profile,   "  ). &   «Make: Bluetooth» (  «Maker Media»),    3    3  (Alasdair Allan), =    (Don Coleman)  #  7   (Sandeep Mistry),             "     Bluetooth LE. Bluetooth LE: центральные и периферийные устройства X    Bluetooth LE      "   :      .                      ,     GAP (General Access Profile,   "   ). Z         %       ,             .             ,         !  . =              GATT (Generic Attribute Profile,   "  ). ;,  " Bluetooth LE           —    , Z,  "     : ›  . *            "     ,     $   . 3             ,           —   , +.  $          \ ,         ,      
Глава 6 320     ›,  ,          .  *    GATT       SPP    ?        SPP                Bluetooth  ,            . 2              , -             .  -       ,   $ ,   SPP   . &                      «  %  —    % »,                    . &     $,   GATT    Рис. 6.12. Устройство Bluetooth 2.0 (схема вверху) — в нашем случае светильник — предоставляет профиль SPP. При подключении к устройству весь обмен данными происходит через поток данных последовательного порта. Центральное устройство (планшет, смартфон, ноутбук) считывает все три элемента данных и выбирает требуемые. Светильник на Bluetooth 4.0 (Bluetooth LE), показанный на схеме внизу, предоставляет сервис Z, имеющий три характеристики. В зависимости от свойств этих характеристик центральное устройство может выполнять операции чтения, записи или подписки с любой из них Bluetooth 2.0: профиль последовательного порта (SPP) Сопряжение Поток данных Яркость, Оттенок, Вкл \n Планшет, смартфон, ПК Светильник Bluetooth 4.0: профиль общих атрибутов (GAP) Сопряжение Свет Вкл Яркость Оттенок Планшет, смартфон, ПК (центральное устройство) Светильник (периферийное устройство)
Беспроводная связь     .          (           ),                ,             . /        ,          .                         ,       . &  ,           ,               "          . X    Bluetooth 2.0          . *  ,     Bluefruit,       2,      SPP, %  Bluetooth —   (Audio Profile),      %   —   HID (Human Interface Device,      -- 321 % ). &     $,     Bluetooth 4.0 (LE)       .  , %            Bluetooth LE  ,   ,                     ,  ,             ,                . 0        Bluetooth         . 6.12. ~                 ,           ,        "             ,          ,       . 7 ,   "             "    $   . Схема управления фотокамерой с помощью Bluetooth LE =  Arduino 101          ,     10 ( .  . 6.5),   $   "          Bluetooth LE. 3   Arduino Uno      nRF8001   Nordic Semiconductor    . 6.13 ( )  6.14 (   ). 7                       SPI,    $      .      $             Arduino         ATmega328  Cortex-MO —          SPI   ,   "     . ~   $        Arduino Uno, Arduino 101  MKR1000,    Arduino  - Требуемые компоненты   Arduino 101     Arduino      Bluetooth LE  nRF8001  nRF51822   Nordic Semiconductor, 1 %. +       :   / ,  Bluetooth LE.  +     9    , 1 %.   220 0, 1 %.  >         %   , 1 %.   %   "  ,    ,   Bluetooth LE, 1 %.           Bluetooth nRF8001  nRF51822   Nordic Semiconductor      ,     $    .
Глава 6 322 A B C D E F G H I J 1 1 5 5 10 10 SCK MISO 15 15 MOSI nRF8001 Bluetooth LE REQ RDY UNO ACT RST 20 3Vo 20 GND VIN 25 25 ON 30 30 A B C D E F G H I J Рис. 6.13. Монтажная схема проекта управления фотокамерой посредством Bluetooth LE на основе платы Arduino Uno и радиомодуля nRF8001 компании Nordic Semiconductor. Для платы Arduino 101 можно использовать схему из проекта 10, поскольку эта плата содержит встроенный радиомодуль Bluetooth Рис. 6.14. Принципиальная схема проекта управления фотокамерой посредством Bluetooth LE на основе платы Arduino Uno и радиомодуля nRF8001 компании Nordic Semiconductor +3,3 В Модуль микроконтроллера +3,3 В D13 SCK D12 MISO D11 MOSI D10 Req D9 RDY Напряжение питания Модуль nRF8001 Act Reset D7 Общий D2 Общий 220 Ом Инфракрасный светодиод
Беспроводная связь 323 +                            ,   "     , —      . *  $  cameraService. #           —     ,       shutter      ,         "       .     $       1,                  .   %               shutter    0. X    Bluetooth LE,             128-      UUID13 —   : 2f45c1ee-5048-11e6-beb8-9e71128cae77 ( %       ). *         —   ,         —        , 16-   UUID,    Bluetooth SIG (      UUID             : https:// www.bluetooth.com/specifications/gatt/services). #            0-180F,    ,       13 UUID, Universally Unique Identifiers —        .     ,            UUID,             ,   $   . =               128-   UUID,     " "  . 0    $          16-   . Код для управления камерой по Bluetooth LE & $          BLEPeripheral,   #  7   (Sandeep Mistry). =   ,   Arduino 101,      "     . &      Arduino 101     CurieBLE                   . =     CurieBLE      : www. arduino.cc/en/Reference/CurieBLE,     BLEPeripheral —   : https:// github.com/sandeepmistry/arduino-BLEPeripheral. 0        ,            (         ,   Arduino 101,      % ). Пишем код    ,     - /* M      ' Bluetooth LE     : Arduino 101 . !  Arduino 101 /* >     CurieBLE: #include <CurieBLE.h> Внимание! ' $    Arduino 101,    2.0.1 (   )      Arduino 101.                       "    .
Глава 6 324 !   =   †     >    SPI BLEPeripheral. 2                 "       Request (2  ), Ready (q  )  Reset (#  ). =   $         ,   $    : /*       UUID         . 9            : BLEIntCharacteristic (  $  ) —            , BLEFLoatCharacteristic —      "  , BLECharCharacteristic —    ASCII  . .        $             . //     %  UUID    : BLEService cameraService("F01A"); //     %  UUID -   $ BLEIntCharacteristic shutter("F01B", BLERead | BLEWrite); const int IRPin = 7; //  ,   // ' \-  const int CAM_NIKON = 1; //   # %-   const int CAM_CANON = 2; int buttonState = 0; //      int lastButtonState = 0; //      Bluetooth LE IR Camera Control context: Arduino Other /* #include <SPI.h> // €       // SPI  BLEPeripheral #include <BLEPeripheral.h> // N        ,   //   Bluetooth Request, Ready  Reset // (     ,  Arduino 101) const int BLE_REQ = 10; const int BLE_RDY = 2; const int BLE_RST = 9; // 9 #      : BLEPeripheral blePeripheral = BLEPeripheral(BLE_REQ, BLE_ RDY, BLE_RST);   $               10: !  Arduino 101    setup()               ,        ,                .          . 2                 shutter,    $   .setValue(),              ,     .begin(): void setup() { Serial.begin(9600); BLE.begin(); //      %    //   "      : BLE.setLocalName("irRemote"); BLE.setAdvertisedServiceUuid(cameraService.uuid()); // Š   -      //     %   : BLE.addService(cameraService); cameraService.addCharacteristic(shutter); BLE.advertise(); //   "    //     shutter.setValue(0); //    $  //  -   $ Serial.println("^   "); }
Беспроводная связь 325 !   = ,  >$ =     BLEPeripheral,        $   blePeripheral,                      .addAttribute(). & $     blePeripheral.begin()              : void setup() { Serial.begin(9600); //      %    //   "      : blePeripheral.setLocalName("irRemote"); blePeripheral.setAdvertisedServiceUuid(cameraService.uuid()); // Š   -      //     %   : blePeripheral.addAttribute(cameraService); blePeripheral.addAttribute(shutter); blePeripheral.begin(); //   Š //        shutter.setValue(0); //    $  //  -   $ Serial.println("^   "); }     loop()   %  $            ,    $     .poll() (  ,                  ). /        .written()    ,                             ,   %            shutter.                        shutterClick(),                 "   . void loop() { //    %        //   : BLE.poll(); // Š  Arduino 101 $  R  // blePeripheral.poll(); // ‰  #   //   BLEPeripheral // † #    % #  // -   $: if (shutter.written()) { // $  -    1: if (shutter.value() == 1) { shutterClick(CAM_NIKON); //  \-    // $ Serial.println("œ"); shutter.setValue(0); // Z $   0 } } } &              shutterClick()  IRPulse()                  :
Глава 6 326 Приложения диагностики для Bluetooth LE ;           —            %                    Bluetooth LE.         $     ,             ,          . #"           ,   "       Bluetooth LE       ,               . 7      "      $ : LightBlue      macOS  LightBlue Explorer       iOs —      Punch Through Designs. 3       Android        nRF Connect     Nordic Semiconductor. & $              macOS, iOS  Android. X            ,      % . &  "       ,    $              %               . Приложение LightBlue для macOS    LightBlue              Bluetooth LE.                ,  "      (  . 6.15)           . 0              .   "   $   -              . ¥                ,  "                 . *%               $     irRemote,             . ;  ,           Arduino 101-XXXX,             MAC      Bluetooth. ;         ,                  ,         . ¥      ,    ,       UUID,       cameraService. = "        (     shutter). = $  UUID,                   ,    Read                   ,    . 2        %            ASCII. &              0-01   % <Enter>.    LightBlue    Рис. 6.15. Рабочее окно приложения LightBlue для сканирования устройств Bluetooth LE. В окне выводятся обнаруженные устройства Bluetooth LE, и там же можно просматривать их параметры
Беспроводная связь 327 $               ,      %              .   $   "                 $        0,             $    . Программа LightBlue Explorer для iOS ~ $        ,       ,            :  $              ,  "            . 0  , "            (  . 6.16). ;  ,            ,    $           . *              %                0-. '     ,     Hex        $          ,      ,              . Рис. 6.16. Приложение LightBlue Explorer для iOS — здесь показан экран просмотра характеристик Приложение nRF Connect для Android    nRF Connect   Nordic Semiconductor          " "     Android,           Bluetooth LE.           ,      "            Bluetooth LE. *   $  (  . 6.17, )             ,    (  . 6.17, ) —            ,      (  . 6.17, ) —  -     ,            ,  $  % . 2           ,             . =                  UINT 8 ( .  . 6.17, ),         1 (  . 6.17, ). * Send,                        .
Глава 6 328 а б в г Рис. 6.17. Приложение nRF Connect для Android * * * *    ,     Bluetooth LE        $             ,         %                   "   . &  %  Bluetooth LE                        . Центральное приложение Bluetooth LE на node.js =                Bluetooth LE       ,       . ~        Bluetooth LE " ,   ,  Windows,               $   . #"    Bluetooth LE   macOS, ,   ,         "    . 0      node.js,        macOS, Linux  Windows. >      noble         #  7  . &  %"   $        node.js,      %                          -   .    $       p5.js,        "  . Установка библиотек noble и express >  noble             node.js.   ,         express,             . #      ,  ,   , NobleCameraControl,           ,     : $ mkdir NobleCameraControl $ cd NobleCameraControl $ npm install noble express
Беспроводная связь 329 &                              . ;,  %  macOS      ,   %    2012 ,      Bluetooth   Bluetooth LE. =    Windows  Linux,  "     ,    Bluetooth LE,      CSR8510  Cambridge Silicon,      $  ( . . 6.2). =    $             Windows. =            Linux,  Raspberry Pi,      "   : $ sudo apt-get install bluetooth bluez libbluetooth-dev libudev-dev =    Windows            USB  Bluetooth,    noble        ,   $         . #   $          Zadig,       http://zadig.akeo.ie,           noble           "    https://github. com/noble/noble. ;              $      Linux. #           noble,         . Код сервера node.js /          HTTP,                "  -         Bluetooth LE.                     "    :     $                 ,                ,               ,     ,         . /                node.js            , $        ,    . Создаем псевдокод =      ,        %  node.js:                    .    ,              ,         : // // ''    : '    // // // // // // †     ',        %    †    %   ,      , '            -   // // // // // // † '      -    %   :  -      -     -   $ shutter -      // // // // // // †   HTTP  $ GET  #   $:         -   shutter:   $     HTTP $ 
Глава 6 330 Пишем код &      express.          — noble 2    $   express: /* Z Bluetooth LE  noble : node.js */ var noble = require('noble'); var express = require('express'); var server = express(); // C$ " server, // $     express =             UUID       %         ,        . 4"                 . 2     public        ,           " express. use(). #     : &           %    .         noble,         (.on('stateChange')),    —                 (.on('discover')).             ,        .   $     express    %     GET      /click:                ,                     stateChange.     ,                        Bluetooth stateChange. var cameraUuid = 'f01a'; var var var var // \ %  UUIS   //   shutterUuid = 'f01b'; // \ %  UUID // -   $ shutter = null; // -   $ clickCount = 0; //     $   device; //  %    //    %   $ -   /public: server.use('/',express.static('public')); // Z    %      //  %  UUID     noble.on('stateChange', scanForPeripherals); noble.on('discover', readPeripheral); server.listen(8080); //    express server.get('/click', click); //      $ GET
Беспроводная связь 331 &  ,                    ,              ,               . ;        .startScanning(),        UUID    : // • #   $    stateChange: function scanForPeripherals(state){ if (state === 'poweredOn') { // †     // Bluetooth ', noble.startScanning([cameraUuid], false); //    //  %      //  %  UUID     console.log("+   ..."); } else { // †     Bluetooth ', noble.stopScanning(); //     console.log("M  Bluetooth  .   ."); process.exit(0); //   . } }              ,       ,             readPeripheral(). /     "                           %              readServices()             .                    device,              % : // • #   $    discover: function readPeripheral (peripheral) { console.log('  ' + peripheral.advertisement. localName); console.log('M  : ' + peripheral.rssi); function readServices() { device = peripheral; // Z-  %  //       console.log('   : ' + peripheral.advertisement.localName); //       - -   . //    - $ % # ' explore: peripheral.discoverAllServicesAndCharacteristics(explore); } noble.stopScanning(); //     peripheral.connect(); //   '  //   %    peripheral.on('connect', readServices); //  // '       } #           ,     ,           explore()    // • #  explore       -  . //       -  ,     %. //  , R   ,    //    '  % # readPeripheral(). function explore(error, services, characteristics) { // Z    -   -   console.log('Z : ' + services); console.log('   : ' + characteristics); //   %  UUID  -   //     UUID -   shutter for (c in characteristics) { if (characteristics[c].uuid === shutterUuid) { // ‰ -  ,     shutter = characteristics[c]; } } } .discoverAllServicesAndCharacteristics(). /  -  "                    UUID          shutter. *   ,            $    ,   $          -  . $                ,            :
Глава 6 332 * ,                GET HTTP. & $      ,    "          ,              shutter,                . &          HTTP     % % : // • #     HTTP  $ GET  //   $: function click(request, response) { var result = "^  %   "; // Z , //     // † '     ' -   : if (device.state === 'connected' && shutter != null ) { //   $  -   : var output = new Buffer([0x01]); shutter.write(output, true); clickCount++; // M   $    //   $ result = "Click count: " + clickCount; // \$   } response.end(result); //    HTTP } &     . #       server.js   NobleCameraControl        ,     : node server.js                      Bluetooth LE. 4  %                 ,  $       "   : +   ...   irRemote   : irRemote Z : {"uuid" :"f01a","name" :null,"type":null,"includedServic eUuids":null}    : {"uuid":"f01b","name":null,"type":null,"Z :":["read", "write"]}      ,                     ,           . +            ,                  $ ,         . =   ArduinoBLE           Arduino,     CurieBLE — ARDUINO 101XXX,   XXX         %     MAC     . Веб-интерфейс      %         %   ,     "    "  -   . =          ,            ,   $                5. = $     NobleCameraControl    public,   —     p5.js. #          p5.js        p5.js,   $      5. +       p5-manager,    p5.js           "  : $ p5 generate --bundle public 2      public      p5.js        : $ p5 update *%    HTML       $  :         div       "    . 0 $ $     "  JavaScript,  %  " p5.js.              GET,                 .  HTML %      index.html    p5.js          . 7   $             %    JavaScript,        sketch.js.
Беспроводная связь 333 Пишем код веб-страницы &     sketch.js             : /* Z # \-  : p5.js */    p5.js var shutterButton; //    $ var messageDiv; // ƒ $     //  &   setup()          . / $              . =   touchEnded               getShutter(). 7    $      : function setup() { // Z$    $, $     # // $   % # '  $ getShutter() shutterButton = createButton('shutter'); shutterButton.position(windowWidth/2, 20); shutterButton.touchEnded(getShutter); // Z$  $ $     #: messageDiv = createDiv("    ..."); messageDiv.position(20, 50); } [       // • #   $  % #    $ function getShutter() { httpGet('/click', 'text', clickDone); } getShutter()      GET HTTP,    $   p5.js httpGet(). &            ,                      . =         — clickDone() —                : // • #   $  $ httpGet() function clickDone(data) { messageDiv.html(" : " + data); } &       . #   ,    ,  %          ,             server.js,               : http://localhost:8080,                . &            "               ,              ,     . 6.18. #       "     ...,       —        :     - $.                      - Рис. 6.18. Страница веб-интерфейса для сервера центрального устройства Bluetooth                 ,     -        .
Глава 6 334 *%      %               ,      $  :       ,         - ,         " . #                  Bluetooth LE              . *   node.js           ,          %     ,              ,         IP-  %   . /           "   . Заключение Беспроводная связь в некотором роде значительно отличается от проводной. Вследствие осложнений, связанных с природой беспроводной связи, нельзя рассчитывать на бесспорное прохождение сообщений, как в случае с проводной связью, поэтому нужно определиться со способами решения подобных проблем.         ,  4           %  % ,     %   -  " "   %,   "   ,   Bluetooth        ,  -     "    -   ,     Wi-Fi,    "      ,   ,   $,   ,             .  $   ,       &  %   ,    -    %.        ,         %     ;  ,       ,          . &  -    —     —     2,  "            -   $         —                     .    -       %- 7          "      $    .   ,          *            -  %  ,          ,        ,   "       $      . &  ,                            "  ( ),           ,          ,                   TCP      $      :   . &  "            $             "  .       . =     Городской сонар. Авторы Кэйт Хартман (Kate Hartman), Кэти Лондон (Kati London) и Саи Срискандараджа (Sai Sriskandarajah) &   %           . 7           Bluetooth       (    %  ). &           ,      ,          ,  "          $       ,  "           ,                  +   .
Беспроводная связь 335

Глава 7 БЕССЕАНСОВЫЕ СЕТИ И ДВОИЧНЫЕ ПРОТОКОЛЫ Сетевые подключения, с которыми мы до сих пор имели дело, были в основном выделенными соединениями между двумя объектами. Для последовательной связи требуется управление последовательным портом, а для подключений почты, браузера и telnet — сетевой порт. Во всех этих случаях присутствует устройство, которое предоставляет порт (обычно это сервер), и устройство, запрашивающее доступ к порту (так называемый клиент). Классическими примерами этого подхода были проекты главы 5. В этой главе мы рассмотрим, как организовать прямое взаимодействие любого сетевого устройства с другим сетевым устройством или одновременно с несколькими другими сетевыми устройствами. Все рассмотренные нами ранее протоколы были текстовыми. Но некоторые протоколы требуют умения интерпретировать цифровые данные в виде чисел или битов. Эти вопросы мы также рассмотрим более подробно в этой главе. Туфли-дирижеры Эндрю Шнайдера (Andrew Schneider) ;             Digi.          «»                   .
Глава 7 338 Компоненты для проектов этой главы Коды поставщиков ? A — Arduino Store, http://store.arduino.cc ? P — Pololu, www.pololu.com ? AF — Adafruit, http://adafruit.com ? PX — Parallax, www.parallax.com ? D — Digi-Key, www.digikey.com ? RS — RS, www.rs-online.com ? F — Farnell, www.farnell.com ? SF — SparkFun, www.sparkfun.com ? J — Jameco, http://jameco.com ? SS — Seeed Studio, www.seeedstudio.com Рис. 7.1. Новые компоненты для проектов этой главы: 1. Датчик газа Hanwei на адаптерной плате. 2. Держатель для трех батареек типа ААА. 3. Подстроечные потенциометры номиналом 47 кОм. 4. Модуль XBee S2C компании Digi. 5. Адаптерная плата XBee-toSerial. 6. Одноплатный мини-компьютер Raspberry Pi. 7. Конденсаторы. 8. Стабилизаторы напряжения на 3,3 и 5 В. 9. Транзистор TIP120. 10. Инфракрасный дальномер Sharp GP2Y0A21YK. 11. Гнездовые разъемы. 12. Программируемые светодиоды WS2812. 13. Матовая пластиковая трубка диаметром 10 см. 14. Жестянка из-под леденцов. 15. Игрушка шимпанзе Чарли 15 14 5 4 13 3 11 1 12 6 2 7 10 9 8
Бессеансовые сети и двоичные протоколы 339 ПРОЕКТ 13. Сетевые светильники Набор компонентов приведен для каждого отдельного светильника. Проект выглядел бы более эффектно с большим количеством светильников (от 6 до 30), но разобраться в его работе можно и всего с двумя.  Arduino-   MKR1000, 1 +. AF: 3156, RS: 124-0657, A: ABX00004, GBX00011 (3   4#), D: 1659-1005-ND &                ESP8266. SF: WRL-13231, AF: 2471   &      Sharp GP2Y0A21YK, 1 +.  C      , 1 +. JJ: 2150256, D: 425-2063-ND, AF: 164, F: 1243869, RS: 666-6564        WS2812 (NeoPixel), 3–7 +.  K     -   &    10    -   "       . D: 438-1045-ND, J: 20723  20601, SF: PRT12615  PRT-12002, F: 4692810, AF: 64, SS: 319030002  319030001  C   3,3 '  5 ', 1 +. AF: 771, D: BC4AAW-ND, SS: 320180002  "         10 , 1 +. AF: 2226, 2858  2859, D: 1528-1610-ND, J: 2247947, SF: BOB-13282, SS: 104990139 ПРОЕКТ 14. Предупреждение о наличии в мастерской токсичных испарений Для этого проекта нужно собрать три отдельные схемы. Наборы компонентов приведены для каждой из них отдельно, хотя для программирования радиомодуля используется один адаптер.  XBee-to-USB   , 1 +. J: 32400, SF: WRL-11812, AF: 247, PX: 32400. 4              XBee,          XStick 802.15.4   Digi. D: 602-1200-ND Компоненты для схемы датчика  C      , 1 +. D: 438-1045-ND, J: 20723  20601, SF: PRT12615  PRT-12002, F: 4692810, AF: 64, SS: 319030002  319030001  (  XBee  XBee Pro S2C 802.15.4. AF: 128, D: 602-1892-ND, SF: WRL-08665, J: 2253722, PX: 32416  D    A  5 ', 1 +. J: 51262, D: LM7805CT-ND, F: 9756078, RS: 9181971  D    A  3,3 ', 1 +. D: 497.1491-5-ND, J: 242115, F 1:703357, RS: 438-4885         9–12 ', 1 +.      ,       $   . SF: TOL-00298, AF: 798, J: 170245, F: 1176248       XBee, 1 +. SS: 113100001, SF: BOB- 08276  !=   +   , 2 +. D: A26509-20-ND, J: 103377, SF: PRT-00116, F: 1593411  !=     ), 2 +. SF: PRT-08272, D: 3M9406-ND     1  \, 2 +. D: 1189-1324-ND, J: 94161, F: 8126933, RS: 4759009     10  \, 2 +. D: P11212-ND, J: 29891, F: 1144605, RS: 7621736 !     Hanwei, 1 +. SF: SEN-09405, P: 1481, PX: 605-00009
Глава 7 340         , 1 +. 9    Hanwei «  »         ,  $      « ». SF: BOB-08891, P: 1479  1639  D , 1 +. Компоненты для схемы исполнительного устройства (шимпанзе Чарли с ударными тарелками)  C      , 1 +. D: 160-1144-ND  160-1665-ND, J: 34761  94511, F: 1855510, RS: 228-5972  826-830, SF: COM-09592  COM-09590  (    220 , 1 +. D: 438-1045-ND, J: 20723  20601, SF: PRT12615  PRT-12002, F: 4692810, AF: 64, SS: 319030002  319030001  (  XBee  XBee Pro S2C 802.15.4. D: 220QBK-ND, J: 690700, F: 9339299, R: 707-7612          47 , 1 +. AF: 128, D: 602-1892-ND, SF: WRL-08665, J: 2253722, PX: 32416   +  +    J       , 1 +. D: A105657-ND, J: 254028, RS: 186-205 Компоненты для схемы сервера  D         > Raspberry Pi, 1 +.     BeagleBone Green         Linux. D: 497.1491-5-ND, J: 242115, F: 1703357, RS: 4384885       XBee, 1 +. SF: DEV-13825, AF: 3055  3400, SS: 102010048  114990584, RS: 896-8660, F: 2525225  (  XBee  XBee Pro S2C 802.15.4. SS: 113100001, SF: BOB- 08276 !=   +    AF: 128, D: 602-1892-ND, SF: WRL-08665, J: 2253722, PX: 32416  XBee-to-USB-  , 1 +. 0                   XBee. J: 32400, SF: WRL-11812, AF: 247, PX: 32400. Об источнике питания для игрушки 4   %  %              3 & (   ,     D),      3,3 &   . *   $              . 4                      ,        «»   $       %. &                   .  A  3,3 ', 1 +. , 2 +. D: A26509-20-ND, J: 103377, SF: PRT-00116, F: 1593411  !=     ), 2 +. SF: PRT-08272, D: 3M9406-ND  D , 1 +. D: 160-1144-ND  160-1665-ND, J: 34761  94511, F: 1855510, RS: 228-5972  826-830, SF: COM-09592  COM-09590  (    220 , 1 +. D: 220QBK-ND, J: 690700, F: 9339299, R: 707-7612    !     NPN-     TIP120, 1 +. D: TIP120-ND, J: 32993, F: 9804005, RS: 808-0502  (    1 , 1 +. D: 1.0KQBK-ND, J: 690865, F: 9339051, R: 7077666     100  \, 1 +. D: P10269-ND, J: 158394, F: 1144642, RS: 7621746
Бессеансовые сети и двоичные протоколы 341 Сеансы или сообщения? До сих пор большинство проектов связи из этой книги работали, открывая выделенное соединение между двумя узлами на весь период обмена данными. Такой тип связи называется связью на основе сеансов (session-based). Но иногда требуется организовать между объектами более свободный вариант обмена данными — когда они могут менять партнеров по общению «на лету» или даже отправлять сообщения целой группе узлов, если ситуация того требует. Для этого нужен протокол, основанный на сообщениях (message-based).             ,      " . Так сеансы или сообщения? &   5       TCP,        %        +   . =   "   TCP                . &                   ,        . 2         ,   %         . &  $      «  —   —  —   »       (  ). 4             ,             . #                 TCP. *          . & +       "    — UDP1.     UDP,    "  ,       ,          . &           TCP,   UDP    "  (message-based). #"    UDP        . =            ,                   ,            . =                     $     . 0      ,      ,      1 UDP, User Datagram Protocol —       .   - ;    ,    UDP       « -- »             ,     %  "  "           . ;,        192.168.1.45   "  UDP    192.168.1.255, $ "            $  . '        ,        %  "   : =.=.=.255,   =            . /             ,         "  ,     "            . ;                 ,       "     .  "    UDP              "  ,                    .   ,                . 3       ,           ,           .   UDP             ,  " %   "    , —      .      -            %        , "  "        .
Глава 7 342 #    TCP    UDP              (SPP) Bluetooth,         2,      LoRa,         6. 9 LoRa        "   ,     .     TCP,   Bluetooth    ,         ,            ,       ,        ,     LoRa. & $            "  ,  "          802.15.4,      Digi. Широковещательные UDP-сообщения в офисных сетях &  "        % "   UDP- " . 4       %   %  ,       $    . *                %  "     UDP"  . $,          ,         $      %  "   UDP- " ,                       . &  ,   UDP, %      +           ,  %        -      ,  % "   "  . Широковещательные сообщения или направленные? Первое преимущество бессеансовых протоколов, таких как UDP, состоит в том, что они позволяют передавать сообщения одновременно всем узлам сети. Впрочем, все время делать это нежелательно, поскольку это наводнит сеть сообщениями, которые нужны далеко не каждому устройству, но такую возможность полезно иметь под рукой, когда надо узнать, какие еще устройства имеются в сети. Для этого нужно просто отправить широковещательное сообщение с вопросом «Кто там?» и ожидать ответов. Кто здесь, кроме нас? — выявление других устройств с помощью UDP   node.js     dgram         . =          UDP-       $  . #        "     ,     +      UDP-  . >  WiFi101  Arduino                  UDP. /        ,    %  "  "       . ;          ,           %         . 0   %  "      "     node.js.            MKR1000          ESP8266      . 0  %  "  UDP- " ,         "        netcat      POSIX,           $  .    netcat           Raspberry Pi  BeagleBone,         .
Бессеансовые сети и двоичные протоколы 343 Пишем код сервера UDP-сообщений # "    node.js   %  "  UDP"     "   UDP      8888. /           ,                      . #      %  "  "    =.=.=.255,           "  . ' %  "  "        %  ,         $      "       . *  ,  IP- %   %   192.168.0.1, %  "  "          192.168.0.255. &     "         ,      ,  $          ,           , "  UDP          " : udp.send(),   ,      " ,          : /* Z UDP : node.js */ var dgram = require('dgram'); // '    //    dgram: var UDP_PORT = 8888; // ^  $    var udpServer = dgram.createSocket('udp4'); // Z$ // UDP- var broadcastAddress = '192.168.0.255'; // ˜  // . //         //        function udpBegin() { udpServer.setBroadcast(true); console.log('Z UDP $ '); } function readMessage(message, sender) { console.log(sender.address + ':' + sender.port +' sent: ' + message); } udpServer.bind(UDP_PORT); //     UDP udpServer.on('listening', udpBegin); //    UDP udpServer.on('message', readMessage); // \ //    '  UDP //     : var data = "  "; udpServer.send(data, 0, data.length, UDP_PORT, broadcastAddress); Пишем код скетча, ожидающего сообщения UDP и отвечающего на него # "   Arduino   "  UDP      8888      . 2     MKR1000          ESP8266 (         WiFi101    ESP8266). =              . /*    $ UDP : Arduino */ #include <SPI.h> #include <WiFi101.h> // #include <ESP8266WiFi.h> // Š   -  ESP8266 // $  R  #include <WiFiUdp.h> #include "config.h"
Глава 7 344 9             ,     setup(),       , —              Wi-Fi. *          Wi-Fi     ,        " . 0      ,                             config.h (    $    -    "  ). 0    $         "    ,      UDP,  "   "    UDP,      WiFiUdp: WiFiUDP Udp; // Z$ R$     WiFiUDP const int port = 8888; // ,      //   Z loop()   "   UDP     ,     node.js    %  "  " . void loop() { // †    ,    if (Udp.parsePacket() > 0) { // +   // - : String message = ""; Serial.print(": "); // +  R  //   Serial.print(Udp.remoteIP()); Serial.print("   : "); //   Serial.println(Udp.remotePort()); while (Udp.available() > 0) { // +   //    message = Udp.readString(); } Serial.print("Z : " + message); // + //    R sendPacket(message); //   } }       UDP          TCP.    UDP        ,            .       $         . /         parsePacket()    WiFiUdp,           . #  " $       $       " . 2  "   Stream (  $   readStream())     "  ,        TCP        : void setup() { Serial.begin(9600); //   '      Wi-Fi, while ( WiFi.status() != WL_CONNECTED) { Serial.print("   '      : "); Serial.println(ssid); //   R   (SSID) WiFi.begin(ssid, password); //   '  delay(2000); } // '     ,   R  //    : IPAddress ip = WiFi.localIP(); Serial.print("IP-: "); Serial.println(ip); Udp.begin(port); }
Бессеансовые сети и двоичные протоколы 7  sendPacket()       . & %            IP-   ,        "  . 0     %  "  ,     "  ,          " : 345 void sendPacket(String message) { // ^   : Udp.beginPacket(Udp.remoteIP(), Udp.remotePort()); Udp.print("   : " + message); // -     Udp.endPacket(); //      }     ,  "     UDP       "       TCP.    "      %.        beginPacket()      Wi-Fi       "        ,          endPacket()   %   , $          . &     . 2    Arduino               "     .   Arduino  IP- ,              " "  :   '     myNetwork Connected to wifi SSID: myNetwork IP-: 192.168.0.3 signal strength (RSSI):-36 dBm  : ;              "   node.js. &       Arduino       " "  : : 192.168.0.8   : 8888 Z :   3  "    IP-  %   . 3          "  . &       ,      "     ,       " : Z UDP $  192.168.0.4:8888 sent:   192.168.0.3:8888 sent: Received:   2            —    ,         %  "   "  . &    —      . 4                 $  ,        . ;   $           %  ,        . * "        % "  ,    —    ,       "  . /    ,                "   "        ,             "   node.js.                  ,    . &           $  UDP       % ,    sendPacket ()         ,      %     ,      %  "    .
Глава 7 346 Программа netcat =       UDP- "                    POSIX             netcat. /         TCP-,   UDP-  ,         ,      . /                       . '    $       "  ,    %   "   node.js,     "           (            ,   ,             ,   $        8888): $ nc -u -l 8888 * Raspberry Pi $  ,          sudo:  , - $ sudo nc -u -l 8888   ,  $           ,             ,          ,   %   8888     " "  . 0 -u   ,        UDP,   -l —      %   " "  ,    " . &   $        (Raspberry Pi, BeagleBone  . .),                .       %  "   "                    "   :   4             ,                ,             . 9      "       % <Ctrl>+<C>. *    netcat     % ,        %   "  . &    , "       " ,    "  : $ nc -u 192.168.0.4 8888   $        "    % <Enter>.        ,          " ,       . 0     ,      "     Arduino " netcat,        "          ,  8888. /      ,   netcat    "     8888  ,           ,      . *            netcat    -  . *  ,  Linux %  "  "           -b,   macOS      %  "   "     .         $      ,     : $ man nc    netcat      Windows,  "           Windows,     ,      .   Net  Cygwin   bash  Windows 10,       $        - ,       netcat.
Бессеансовые сети и двоичные протоколы 347 Перенаправление вывода в сообщении UDP      netcat,      POSIX "            UDP        .   $              "  : $ echo "&  " > /dev/ udp/192.168.0.4/8888 & $       echo   $             /dev/ udp/<IP->/<>,            ,    . /    ,                 "  UDP. *  ,     date: ;      macOS  Linux,          POSIX.              Net  Cygwin    -   bash  Windows 10, ,   ,       Windows.     node.js        POSIX, ,     ,              UDP. *                UDP     ,           . $ date > /dev/udp/192.168.0.4/8888 Проект 13 Сетевые светильники Протокол UDP удобно использовать для реализации сетевых проектов, в которых большое количество устройств выполняют обмен данными между собой или с сервером, причем такой обмен осуществляется нерегулярно и в течение короткого времени. В этом проекте мы создадим набор мерцающих сетевых светильников, которые обмениваются сигналами друг с другом, когда над каким-либо из них проводят рукой. *    Wi-Fi         —                %         . &             $    ,    $      ,        . 2        $   . #        "    ,             ,         (  . 7.2). 4         ,               ,               . &   ,            ,          . #       "       "  UDP:    %       %  "   "  UDP,              . #"              . >    UDP,             ,         ". +     UDP          $ :           %  "   "  . &  ,    UDP          . /   ,     , 
Глава 7 348      "  . &                  %  ,      +  .   $         ,           , ,   ,     $       ,             $. 3      "         ,  %           TCP,               . Требуемые компоненты =     (          6,  % — 30)   :   Arduino MKR1000,  WINC1500,        ESP8266. +       : Wi-Fi,   / ,   /  .  +      Sharp GP2Y0A21YK, 1 %.       (NeoPixels), 3–7 %. Рис. 7.2. Сетевые светильники   WS2812  >         %   , 1 %.  >      3,3–5 &, 1 %.  7        10 , 1 %.  †     -       10 , 1 %. #       ,      ,         . `    .       % %      $ ... Схема устройства светильника              "         WiFi            WS2812   Worldsemi.   Adafruit         NeoPixels. #         SparkFun  Seeed Studio. =      (RGB)       (RGBW)   $  . =              ,      "                   ,       %           (« »
Бессеансовые сети и двоичные протоколы 349  " )         . >      2  $         : https://learn. adafruit.com/adafruit-neopixel-uberguide.  %  1 &. /   ,     ,       $   ,     % 1 &,             .          ,            . &     MKR1000 (  . 7.3) "     , $    Wi-Fi        ESP8266 (  . 7.4  7.5). &             . *        $          .         ESP8266        (  ADC      SparkFun,     Adafruit),        - +      ,    . 7.3–7.5,         10  80 ,      "        $            "         0  5 &.        ESP8266       ,   %" 1 &,            ,   %    $         .     . 7.4,  ,                        ,   % 2   ,        . Рис. 7.3. Монтажная схема проекта сетевых светильников (версия для платы MKR1000). Слева здесь показана LiPo-батарея, обеспечивающая электропитание всех устройств проекта. Емкость батареи должна быть не менее 800 мА, а еще лучше — 1200–2000 мА. Это необходимо для питания как электронной части проекта, так и самих светодиодов, потребляющих значительный ток A B C D E F G H I J 2000mAh 1 1 5 5 10 10 15 15 20 20 25 25 30 30 A B C D E F G H I J
Глава 7 350   $ 1 &. *      $       ,              "   ,     ,            . =     ,      NeoPixels,           5 &,     ,       %        4,5 &,         33,    3,7 &,     $      LiPo.       3,3 &    ,      " ,            ,                       .             5 &   Adafruit                  NeoPixels                   470 0. 0        ,       $   ,                       ,   ,   ,      ,        %  . =                 ,            . =                NeoPixel Jewel   Adafruit,       . &             ,     ,     "    "       . 0   ,     NeoPixel      60  , $   ,  %                  ,         . Рис. 7.4. Принципиальная схема проекта сетевых светильников. Максимальное рабочее напряжение аналогового ввода плат на микросхеме ESP8266 (обозначен ADC на платах компаний SparkFun и Adafruit) составляет 1 В, поэтому используйте делитель напряжения (см. его схему справа), чтобы уменьшить напряжение, подаваемое на него с выхода инфракрасного датчика расстояния, до допустимого уровня +3,3 В Напряжение питания (Vin) Вывод +3,3 В Напряжение питания (Vin) A0 Для плат на микросхеме ESP8266 используйте делитель напряжения, чтобы уменьшить максимальное выходное напряжение инфракрасного дальномера до величины, не превышающей 1 В +3,3 В Программируемые Напряжение питания (Vin) светодиоды (NewPixels) Входные данные Выходные данные Модуль микроконтроллера 10 кОм ADC Вывод 220 Ом Общий D5 Общий Общий Напряжение питания (Vin) +3,3 В Общий
Бессеансовые сети и двоичные протоколы 351 OFF A B 1 C D E + F GND 3V3 VIN 3 x AAA J 1 0 5 4 DTR 10 I 5 SCL OFF-ON G H GND SDA 5 ON - TX 13 RX 12 5V XPD NC ADC GND 10 EN 15 15 20 20 25 25 30 30 A B C D E F G H I J Рис. 7.5. Монтажная схема проекта сетевых светильников (версия для платы ESP8266). В качестве источника питания для этого проекта можно использовать три батарейки типа ААА. Но питание от батареек подключайте не через схему питания платы, а непосредственно к выводу Vin. Плата Feather Huzzah! ESP8266 компании Adafruit имеет иную распиновку, но вывод от датчика расстояния так же можно подавать на вывод ADC платы, а светодиоды подключать к ее выводу 5 Код для управления светодиодами =           NeoPixel   Adafruit. >            —       Arduino.              "   ,   ,    . Работа с библиотекой NeoPixel   ,         NeoPixel, — $    %   : Adafruit_NeoPixel candle = Adafruit_ NeoPixel( numPixels, neoPixelPin, NEO_ GRB + NEO_KHZ800);    numPixels  neoPixelPin                 (  ,        ")       ,          .              . &      (NEO_GRB)      ,     NeoPixel     . =    ,  ,       RGB (  ,    ),    —  GRB (  ,   ),    ,   ,  ,   ,   ),   RGBW (          ,   ,  . &                GRB  GRBW. +              
Глава 7 352  ,        . &              (NEO_KHZ800)           ,             . & %           800 q. ? candle.setPixelColor(( , #)); &                       . *  ,    0xFFFF0000                . 4                ",    ,            . X              : ?          ,      :   : candle.setPixelColor( ,  , $ ,   ); =              : $                         %       —  ,      HTML: &  "                 %      . candle.setPixelColor( ,  , $ ,   ,  ); Познакомимся с библиотекой NeoPixel поближе =    ,        NeoPixel —               . X % ,        ,          ,   ,    -     .       HTML,             "  :                    ,    ,      . &     .show()             ,  $                   .   .clear()     0x000000     : ? ? ?   : 0xFF0000   : 0x00FF00   : 0x0000FF 2        "   ( )        0  255 (0x00–0xFF  %       ). *  ,    0x2375FF      -   . /*     -   : Arduino */ #include <Adafruit_NeoPixel.h> const int neoPixelPin = 5; // +     const int numPixels = 7; //   $  -   Adafruit_NeoPixel candle = Adafruit_NeoPixel( numPixels, numPixels, NEO_GRB + NEO_KHZ800); void setup() { Serial.begin(9600); // \ #  $   // $  '
Бессеансовые сети и двоичные протоколы 353 candle.begin(); // \ #  $     '  candle.clear(); candle.show(); //  ' -   //  -   } void loop() { for (int pixel = 0; pixel < numPixels; pixel++) { candle.setPixelColor(pixel, 0xFF0000); } candle.show(); //    -   delay(1000); candle.clear(); // +'    candle.show(); //      delay(1000); } Создание эффекта мерцания светильника 9            :   "    ,   "   UDP    $       . #                  . *                         "              . 9    " " $    .         "   ,                ,          %       %    "      ,     $    . +   $ $ ,        (             ) %    $                       .   $            —              . 2                    .                   "          . 4      ,              %       .                       . ~         (  ,   ,     ,      )   4-      $  ,     ,          .             ,         0xCB500F,       ,         0x853E0B,         ,        " (. 7.1). +                   ,        "         ,       "         "       %       . Таблица 7.1. Составляющие текущего и целевого цветов Красный Зеленый Синий Текущий 0xCB 0x50 0x0F Целевой 0x85 0x3E 0x0B
Глава 7 354 9         ,        "  "    "  ,        . /                 ,            ,     %   . /            "    . '                 4-           . ;        byte (      ). 2                   ,        "        %  .            "      .               ,         %          ,        . Пишем код для сравнения составляющих цветов # "          "          "      ,    "            %. /              $               . 7    $              : unsigned long compare(unsigned long thisColor, unsigned long thatColor) { // +  #: byte r = thisColor >> 16; // Z         byte g = thisColor >> 8; // Z          byte b = thisColor; // Œ      // +  #: byte targetR = thatColor >> 16; // // byte targetG = thatColor >> 8; // // byte targetB = thatColor; // Œ Z         Z               // + -  #   : if (r > targetR) r--; // † $    # // ,      if (g > targetG) g--; if (b > targetB) b--; '  %              NeoPixels,   %          —      ,          . if (r < targetR) r++; // † $    # // ,      if (g < targetG) g++; if (b < targetB) b++; // Z  $ ,      #: unsigned long result = candle.Color(r, g, b); return result; }
Бессеансовые сети и двоичные протоколы 355 Битовый сдвиг и побитовое маскирование '                           . 7 Arduino                 : // Š   $   : myBit = bitRead(someByte, bitNumber); // Š $  $   : bitWrite(someByte, bitNumber, bitValue); &              1          3,     0 —   4. $ "      : //      $  1: bitSet(someByte, bitNumber); //      $  0: bitClear(someByte, bitNumber); • AND (&): 4      ,   1. &     $ 0: 1 0 1 0 & & & & 1 0 0 1 = = = =  - 1 0 0 0 • OR (|): 4        1,  1. &     $ 0: 1 0 1 0 | | | | 1 0 0 1 = = = =  1 0 1 1 • XOR (^): 4        ,    1. &     $ 0: 1 0 1 0 ^ ^ ^ ^ 1 0 0 1 = = = = - 0 0 1 1 +              . ;           . /     "        ,       C, Java  JavaScript. 0      (<<)            ,     (>>) —      . # "  ,    ,                        ,    "    : 0b00001111 << 2; // $  0b00111100 0b10000000 >> 7; // $  0b0000001 *  ,        ,                    "           NeoPixels    "  : /       : 0x00FF00 >> 8; // $  0x0000FF 0x0000CD << 16; // $  0xCD0000 0        ,                     ,  $      $    . _    + (AND), +_+ (OR)   " +_+ (XOR)           . ;            : 3 4 0  . Setting the bit. 0  . Clearing the bit. 0b00001111 & 2; // 0b00000010,  2 0b00001111 | 0b10000000; // 0b10001111,  143 // $  // $  //  $    $ #: unsigned long myColor = 0x1A3CFF; //  // #  -$ unsigned long green = 0; //  $  $  : green = myColor & 0x00FF00; // $  // 0x003C00 &   $                           .
Глава 7 356 Активация вспышки светильника &      $    —          —        :       ,         ,   %           ,          $        %  "   UDP- "  .   $         triggered    true (  ),      ,         %   . +             !       . & %   "  triggered    "    %  "   "    ,               %       . /              ,        "  . X                   ,      triggered         false (). &  "    $    ,                        . #     $ ,       ,   ,  $      %   . Собираем все части скетча воедино #          %  .    ,            config.h,  "    (SSID)    ($    ,      "    ): /* =             UDP, %  "           "  .               NeoPixels:                  ,    $  candle   NeoPixel: WiFiUDP Udp; // Z$ R$     UDP IPAddress destination(192,168,0,255); // IP- $  const int port = 8888; // UDP- 2      keyColors          ,            . // ž     #  RGB- : unsigned long keyColors[] = {0xCB500F, 0xB4410C, 0x95230C, 0x853E0B}; unsigned long currentColor = keyColors[0]; // ƒ  # //   Z    : Arduino */ #include <SPI.h> #include <WiFi101.h> // #include <ESP8266WiFi.h> // Š   -  ESP8266 // $  R    #include <WiFiUdp.h> #include <Adafruit_NeoPixel.h> #include "config.h" const int neoPixelPin = 5; // +  //      const int numPixels = 7; //   $  //   // Z$ R$     NeoPixel: Adafruit_NeoPixel candle = Adafruit_NeoPixel( numPixels, neoPixelPin, NEO_GRB + NEO_KHZ800);
Бессеансовые сети и двоичные протоколы 357    target             , currentColor —     "   ,  lastFadeTime —             .   ,       interval       %   (30     % ), threshold —             ,  triggered —       : unsigned long target = keyColors[1]; // ž,   //   - long lastFadeTime = millis(); //    $   // # long interval = 30; //    - (30 ) int threshold = 500; //  $    boolean triggered = false; //    $  # [  setup()             $   candle   NeoPixel. 2  "   .clear()       ,     "   .show()         . [  .show()      ,            . void setup() { Serial.begin(9600); // \ #  $    ' // $ candle.begin(); // \ #  $   R$  candle //    NeoPixel candle.clear(); // +'    candle.show(); //    -   //   '      Wi-Fi, while ( WiFi.status() != WL_CONNECTED) { Serial.print("   '      : "); Serial.println(ssid); //   R   (SSID) WiFi.begin(ssid, password); //   '  //   delay(2000); } 0       setup()         :          ,    $  IP-     UDP- : // '     ,   R  //    : IPAddress ip = WiFi.localIP(); Serial.print("IP-: "); Serial.println(ip); Udp.begin(port); // \ #  $   UDP-$: } [  loop()                       ,             . 4       %     ,        triggered. 4      false (),       (0xFFFFFF)  void loop() { int sensorReading = analogRead(A0); // Z  $  //    : if (sensorReading > threshold) { // †   //  $ , Serial.print(sensorReading); //    R if (!triggered) { //        //    currentColor = 0xFFFFFF; //    #
Глава 7 358     "    currentColor     UDP- ,            triggered    true (  ).                            ,      ,  % " $   : //     UDP- $ : Udp.beginPacket(destination, port); Udp.print("ping"); Udp.endPacket(); triggered = true; //     ,  //        } }      loop(), %    "           . =      "   millis()      %  30   . 4   "        ,       compare(),      (          loop()). 4   "         ,              keyColors: //  #     30   : if (millis() - lastFadeTime >= interval) { triggered = false; // M   $  # //      false     loop(),    for          ,           ,     .show().   $         lastFadeTime  "  ,  "    millis(),      "   : // M  # -  : for (int pixel = 0; pixel < numPixels; pixel++) { candle.setPixelColor(pixel, currentColor); } candle.show(); //    //      lastFadeTime = millis(); // Z-   - //    } 2 %    loop()     " UDP- "  .                    .parsePacket(),  "        ,   , "   .available(),  "  . &   ,     // †    ,    if (Udp.parsePacket() > 0) { String line = ""; // †  UDP-,   : while (Udp.available()) { line = Udp.readStringUntil('\n'); // Z  //        } IPAddress sender = Udp.remoteIP(); //   // IP-   Serial.print(": "); // +  R IP- //   if (currentColor != target) { // + -   #  # # : currentColor = compare(currentColor, target); } else { // +  $   keyColors  $  // #: int next = random(4); target = keyColors[next]; }
Бессеансовые сети и двоичные протоколы      .avail " ,       .parsePacket(),       IP-      . 4  "      ping,             . able()    359 Serial.print(sender); Serial.print(", Z : "); //     Serial.println(line); if (line == "ping") { //    "ping", currentColor = 0xFFFFFF; //    // #    } } } // # % # loop() //      % # compare() 2 %      compare(),     . #           loop()            : 2               ,            ,       node.js,  " %  "   "  ,     $   . '           ,   "  $     "ping".           —               "      ,       . #   node.js     "     . &                       ,                . &                       -       10 ,      —          . =      $   ,               , $,      $  ,                  "    $  .   $  ,            %        ,       . *  . 7.6    "              . +   $          ,             . +     —     ,           . &  ,        33  333         . 3     %        ,                            —        ,             . =  $  "           candle.show()     setup(),      loop(): // +'   #   //       // '     : if (WiFi.status() != WL_CONNECTED) { candle.setPixelColor(0, 0x0000FF); }
Глава 7 360 10 см +       %                       UDP" . +    %  "   "        " $  ,      ,     %  "   "    . >%   %      IP-          , $    30    ,   ,     192.168.0.2  192.168.0.31.    "          ,   "             Udp.beginPacket(): int addr = random(30) + 2; //  $ //    2  31 10 см destination = IPAddress(192, 168, 0, addr); //  IP- 3      " ,         $  $   . *  ,             "   IP- ,        %   %           . Рис. 7.6. Версия схемы светильника для платы MKR1000, собранная на макетной плате уменьшенного размера. При такой компоновке вся схема помещается в жестяную коробку из-под леденцов диаметром 10 см. Светодиодная сборка, изолированная от микроконтроллера резиновой прокладкой, размещена достаточно близко к центру трубки для создания хорошего светового эффекта, а датчик — достаточно близко к ней, чтобы край трубки не вызывал ложных срабатываний. Батарейка находится под платой. На нижнем рисунке показана только сама монтажная разводка без микроконтроллерной платы и светодиодной сборки          "                   "       ,                    ,  "              . / ,      ! #  (TTL5), %           . #    ,      IP       TTL,  "  "    %  ,     % .   $  %    %           TTL    ,     % ,         0   %      . 5 TTL — Time-To-Live.
Бессеансовые сети и двоичные протоколы 361 UDP в действии: traceroute #               ,                . =   $           ,  "   traceroute.   traceroute      UDP           "  ,         %               . &        -        $  IP-   %  ,      "  . /             ,                "  ,             $      "    . =            traceroute: $ traceroute -a makezine.com traceroute: Warning: makezine.com has multiple addresses; using 104.25.44.28 traceroute to makezine.com (104.25.44.28), 64 hops max, 52 byte packets 1 [AS0] 192.168.0.1 (192.168.0.1) 5.359 ms 7.537 ms 10.090 ms 2 * * * 3 [AS12271] tge-0-10-0-10.nymanyfo01h.nyc.rr.com (68.173.209.1) 30.503 ms 32.057 ms 34.002 ms 4 [AS12271] agg115.nyclnyrg01r.nyc.rr.com (68.173.198.64) 30.132 ms 38.111 ms 39.582 ms 5 [AS19548] bu-ether19.nwrknjmd67w-bcr00.tbone.rr.com (66.109.6.78) 41.176 ms 34.952 ms 24.525 ms 6 [AS19548] bu-ether12.nycmny837aw-bcr00.tbone.rr.com (66.109.6.27) 34.226 ms 40.067 ms 34.095 ms 7 [AS7843] 0.ae2.pr0.nyc20.tbone.rr.com (107.14.19.147) 35.052 ms [AS19548] 0.ae0.pr0.nyc20. tbone.rr.com (66.109.6.157) 29.482 ms [AS19548] 0.ae1.pr0.nyc20.tbone.rr.com (66.109.6.163) 27.959 ms 8 [AS1299] nyk-b5-link.telia.net (62.115.34.145) 20.895 ms 43.579 ms 47.807 ms 9 [AS1299] nyk-bb2-link.telia.net (80.91.254.15) 40.781 ms 29.687 ms 29.712 ms 10 [AS1299] nyk-b2-link.telia.net (62.115.134.108) 31.577 ms 29.079 ms 30.539 ms 11 [AS1299] cloudflare-ic-301663-nyk-b2.c.telia.net (213.248.77.162) 30.656 ms 35.082 ms 25.414 ms 12 [AS13335] 104.25.44.28 (104.25.44.28) 29.912 ms 30.884 ms 27.869 ms =    ,   $   .       traceroute      ,        UDP-  ( %   $ makezine.com,        IP-  104.25.44.28).         ,       IP  UDP-      TTL,   1. /    "          %  ,     ,        ,    ,      % . 2      UDP-      TTL,   2. /           %    " ,   $    %           TTL,     "   "        %  ,           % . /             ,  traceroute          . ;  ,       traceroute         -       %           .  ~   traceroute          UDP,         TCP       +  . &  ,   %      -      . 7 %             traceroute,          ICMP6,    ping.       traceroute       UDP- " ,                       , —                  " "  . 6 ICMP, Internet Control Messaging Protocol —    " "  [ ] +  .
Глава 7 362 &               traceroute      -a,                (  AS7). X        ,         AS    https://apps.db.ripe.net/search. *   %       %  ( .   2        traceroute)? 7 %  , % "  ,    . X       $  , $     traceroute      : * * *. 7 *  -   www.yougetsignal.com/tools/visualtracert           traceroute,       %           . ~ $  -   ,            ,  ,   , "                     +   . >    $           9. Traceroute для Windows & Windows             tracert      -a. traceroute —   AS, Autonomous Systems —      . XBee: еще один протокол на основе сообщений Линейка радиоустройств XBee компании Digi представляет собой еще один подход к организации связи по протоколу на основе сообщений. Эти радиоустройства могут работать в режиме асинхронной радиосвязи для отдельного устройства или же выполнять независимые операции чтения и записи на своих собственных контактах ввода/вывода. Они работают подобно модемам в том смысле, что их настройка осуществляется по асинхронному последовательному подключению (то есть через УАПП). Радиоустройства XBee используют созданный компанией Digi двоичный протокол связи на основе сообщений, с помощью которого им можно посылать команды по радио, или считывать их контакты ввода, или управлять их контактами вывода. X       API-  XBee,    Digi       "     .   $                : ZigBee, Wi-Fi  . . &  "  %                XBee —  XBee Pro S2C 802.15.4. +            Digi     $  ,           XBee. ZigBee и XBee ;    ZigBee       ZigBee,      XBee —   Digi, Inc. /     . =       XBee. =  XBee           —              ,         ,   .   XBee     UDP    ,         ,   %  "     "  . 0       LoRa,          6, —       ,       ,    "         8 (       !  ,             LoRa). #  XBee      :    ,            .     "   8 0  . Personal Area Network (PAN) ID.
Бессеансовые сети и двоичные протоколы 363 / ,         / .         / ,         ($        9),        (  ),   "      ,     . 3    XBee  " X3 (UART),               . =              Digi           XCNU,         : www.digi.com/support/ product-support. &   Select Your Product for Support   XCTU,           .                . &    ,   $      " «»      Bluetooth,                   . /            XCTN, "      XBee "       , "             . 9               Write           ,             Hayes AT,                 . *     Digi  "                      ,        Hayes AT —   ,              . &        Hayes (,    ,        Digi)      ASCII. + " $              ,       .             "       +++. &     "   .   ,     "     (           )  ,        ASCII AT,                 ,   "     ,   —    (     ),    .    %    ASCII     . 7          "   OK,         ,       . =    XBee            XBee-to-Serial        XBee.   Digi     $       ,     "    $              XBee-to-USB. /,  ,    USB-to-Serial,      ,  "   ,               XBee. *  . 7.7,     : XBee-to-USB      Adafruit  Parallax ( )  XBee Explorer   SparkFun ( ).    Hayes AT                 ,             9 0  . sampling. Настройка радиомодулей XBee        XBee "    XCTU        Add a Radio (= ) —           ,     .    ,       ,         ,        . 7.8. X    $       ,    Write,      . X            ,            3;.
Глава 7 364 Выбор вспомогательного оборудования для радиомодулей XBee *                   XBee,             "    : •   >   XBee  > —     USB-to-XBee. *  . 7.7,   USB-to-XBee      Adafruit  Parallax ( )   SparkFun XBee Explorer ( ). &                   XBee. &  ,              USB-toSerial,  $            3,3 &. & $        TX      RX    ,   . *              XBee, %        XStick 802.15.4   Digi; •   >   XBee      —  $       Fio v3   SparkFun,  "     Arduino      (ATmega32U4)         XBee (  . 7.7, ); •   >   XBee  = —          XBee LilyPad (  . 7.7, )         XBee  XBee Breakout (  . 7.7, ). 3  SparkFun XBee LilyPad  XBee Explorer Regulated (    SparkFun: WRL-11373)  "         ,       XBee  %        . 9 XBee   Digi      3,3 &, $,            (   %    ),                 3,3 &. Рис. 7.7. Вспомогательные платы XBee: а — адаптер XBee-to-USB производства компаний Adafruit и Parallax (слева) и плата SparkFun XBee Explorer (справа); б — адаптерная плата SparkFun Fio; в — адаптерная плата SparkFun XBee LilyPad; г — адаптерная плата XBee Breakout а б в г
Бессеансовые сети и двоичные протоколы 0     XCTU        3;              ,      "                 (  . 7.9). Примечание 4         XCTU      ,            . = $         (  5)   " . *            ,        ,       5,         "     . Рис. 7.8. Конфигурационная панель приложения XCTU, с помощью которой можно просматривать и устанавливать параметры радиоустройств. Измененные в этом окне значения параметров отправляются на радиоустройство по нажатию кнопки Write, в результате чего программа XCTU создает соответствующую команду АТ для установки на радиоустройстве заданного значения параметра Рис. 7.9. Панель терминала последовательной связи программы XCTU. Чтобы с помощью терминала подключиться к радиоустройству, нажмите кнопку Open/ Close (на рисунке кнопка имеет надпись Close, поскольку последовательный порт уже открыт). После этого из панели можно обмениваться данными напрямую с последовательным портом радиоустройства 365 &  ,                     XCTU. = $            CoolTerm             . > ,   3;             ,          ,            .              Digi                 ,        XCTU. &            .
Глава 7 366 &               XCTU                              : +++ +   % <Enter>     %              $   . 7 XBee     "  : OK =    ,    +++          ,        $       ! #    (guard time). 4        ,   10           . $,    $        +++,  10      ,        ,         "  %. +,    OK  ,     .   XBee     16-    64-    , $        :  %    %   (        %  ,   "      ,       ). & %   "          16-    . + "      ,     : ATMY\r 3   $   :  ,    ATMY1\r /          1. 0     :  \r,  %"  %    ,  ,       % <Enter>. ;  ,        (   ,    %          " ),         (     +++),       : ATDL\r #  ,       0,   $             . *             ,       ,         %   . 9     16-    . 3      %       ,           0  FFFF. +  PAN ID  (      )   ,     : ATID\r      PAN   3332,                  ,    "  : ATID1111\r 7 XBee    $     ,        : OK 2        ,                     WR,            . ;  , $               . *  : ATID1111,WR\r 0                                       XCTU:      +++       ,    ,            WR    % <Enter>. =           ATCN\r.
Бессеансовые сети и двоичные протоколы 367 Проект 14 Предупреждение о наличии в мастерской токсичных испарений Если у вас есть мастерская, вы оцените этот проект. Подключив датчик летучих испарений к радиомодулю Digi 802.15.4, вы сможете обнаруживать повышенную концентрацию паров растворителей в атмосфере своей мастерской. При работе с химикатами легко привыкнуть к их испарениям, что может повлечь нежелательные последствия, вплоть до летальных. Этот проект демонстрирует, как предотвратить такое развитие событий. 2                    . 0                       Raspberry Pi, "          -  . &          % — %  '        —      -             ,                                 . /            ,    %          ,       ,       . 4             ,  $            ,             . *  . 7.10   $           . 3   7.11          . Это демонстрационный проект! *        , $                    . #           . 0   %       ,  %                  "    . *     $   ,                          . #      ,       ,           . Рис. 7.10. Проект, выявляющий наличие токсичных газов, в сборе: датчик газа, шимпанзе Чарли и сервер на одноплатном компьютере. В качестве альтернативы радиомодулю на сервере можно использовать модуль Digi XStick (показан справа)
Глава 7 368 Требуемые компоненты = $             . *            ,               :  3 XBee-to-USB, 1 %. Компоненты для схемы датчика  >       , 1 %.  9 XBee  XBee Pro S2C    802.15.4, 1 %.  #    5 &, 1 %.  #    3,3 &, 1 %.  +         9–12 &, 1 %.      ,       $   .  3    XBee, 1 %.  =  %     , 2 %.  =     , 2 %.    1 [, 2 %.      10 [, 2 %.  =  MQ-6      Hanwei, 1 %.  3     , 1 %.  # , 1 %. Рис. 7.11. Блок-схема системы выявления токсических газов Радиомодуль XBee датчика Радиомодуль XBee сервера Raspberry Pi в качестве веб-сервера Локальная сеть Веб-браузер Радиомодуль XBee исполнительного устройства  9     220 0, 1 %.         47 0, 1 %.   Компоненты для схемы исполнительного устройства  >       , 1 %.  9 XBee  XBee Pro S2C    802.15.4, 1 %.  + % %  '     , 1 %. Об источнике питания для игрушки 4   %  %              3 & (   ,      D),      3,3 &   . *   $              . 4                      ,        «»   $       %. &                   .  #    3,3 &, 1 %.  3    XBee, 1 %.  =  %     , 2 %.  =     , 2 %.  # , 1 %. 9     220 0, 1 %.     =     NPN-    TIP120, 1 %.  9     1 0, 1 %.     100 [, 1 %. Компоненты для схемы сервера  0   Raspberry Pi, 1 %.     BeagleBone Green         Linux.  9 XBee  XBee Pro S2C    802.15.4, 1 %.  XBee-to-USB- , 1 %. 7       ,            ,       (    802.15.4)  XStick     Digi,      USB  .
Бессеансовые сети и двоичные протоколы 369 Настройка радиомодулей           XBee-to-USB. /              ,            Raspberry Pi       . &            :   ,            (         -   %        )     . 9    ,              ,        PAN ID (       ). & $                     / . *  ,                 ,         .   ,                 +7-  . [              ,        ($          ). & $        "    XCTU    AT. Z          . 7                   (D0,   20)         $     %  "               (        PAN). ~ %              ,      ,  $                ,               . *           "  : ? ATMY01 —    ; ? ATDLFFFF —    %  "  ;        ? ATID1111 —    PAN ID; ? ATD03 —          /  0 (D0)    ; ? ATIR64 —            100    (0-64h). 4           ,   %    ; ? ATIT1 —             ,         . ;  ,      "    100  : 1   × 100         = 100   ; ? —                      . ATIAFFFF 9            "       , ,   -     "  ,  "       D0,            D0       . +  ,                       . *                   "  : ? ATMY02 —               ; ? ATDL01 — ? ATID1111 —    PAN ID; ? ATD04 —         D0       ; ? ATIU1 —         "     01). * $    ,   ( ,      ,   $       "  ;             /        . /             —          
Глава 7 370        $          ; ? - ATDL01 —         "     01). * $,  ,    (    ,   $       "  ; ? ATID1111 —    PAN ID; ? ATIU1 — ATIA01  ATIAFFFF —      -           ,         01 (  ). 4   $            FFFF,     ,        $     . ;  ,                  . 9     "             "          . *   $      ,          %    ,       "  : ? ? ATMY03 —       -  ;             /        . /                . Сброс настроек радиомодуля '         XBee             (        ,               ),        ATRE\r. & . 7.2                   . Таблица 7.2. Сводная конфигурационная информация для всех радиомодулей проекта Радиомодуль датчика Радиомодуль исполнительного устройства (шимпанзе Чарли) Радиомодуль сервера MY = 01 MY = 02 MY = 03 DL= FFFF ID = 1111 D0 = 3 IR = 64 IT = 1 IA = FFFF DL = 01 ID = 1111 D0 = 4 IU = 1 IA = 01  FFFF DL = 01 ID = 1111 IU = 1 0               ,                WR\r. &    XCTU $                  Write.        3;         ,                     . *  ,         ,     "    : 1. &    +++. 2. 0  ,   OK. 2     " (0  D02 — $   ,   ):     % ATMY1, DLFFFF\r ATID1111, D03, IR64\r ATIT1, IAFFFF, WR\r *                    "  :
Бессеансовые сети и двоичные протоколы 371 ATMY2, DL1\r ATID1111, D04\r ATIU1, IAFFFF, WR\r 3 $            : ATMY3, DL1\r ATID1111, IU1, WR\r Совет >       XBee,           ,         ,           "         . ~  ,      . 7.12. Рис. 7.12. Рекомендуемая разметка радиомодулей, позволяющая их не перепутать Монтаж рабочих схем проекта &          ,        ,            . &   $           "            ,    Digi            . ;            ,  ,     ,  "         . Схема датчика газа  D0. 9 XBee                    -        %          . /             9 &   %    ,                . *          (  !  )  "    ,       . Стабилизатор напряжения 3,3 В модели LD1117-33V =            5 &, $         5 & —  ,     3,3 & —  ,            9 &     . = $             9 &,       $        9–12 &. & $            3,3 &   LD1117-33V. 9   $               5 &. $            ,              . *  . 7.13      (  )     (  !)    . &      MQ-6,  $              Hanwei.     47 0           ,      ~         ,        ,      %  ,  $               . #        ,            —           . /
Глава 7 372 К «плюсу» источника питания постоянного тока 9–12 В Стабилизатор напряжения 7805 на 5 В Вход Выход 10 мФ 1 мФ A H B Датчик газа MQ-6 компании Hanwei Радиомодуль XBee LD1117-33V Voltage Reg Вход H Выход Vcc AD0 / DIO0 TX AD1 / DIO1 RX AD2 / DIO2 DO8 AD3 / DIO3 47 кОм 10 мФ 1 мФ RTS / AD6 / DIO6 RESET PWM0 / RSSI Ass't / AD5 / DIO5 PWM1 Vref NC SLP + 3,3 В 220 Ом 15 20 25 30 20 25 30 30 30 15 25 25 10 20 20 10 15 15 LD11 D 17 D1 7 VReg g 5 10 10 7805 805 5 VReg g J I G H A B C D E F G H C D E A B F G H F C D E A B A B C D E F G H I I I J J 5 5 J 1 LD1117 VReg 5 AD4 / DIO4 1 GND 1 CTS / DIO7 1 7805 VReg DTR/DI8 Рис. 7.13. Принципиальная (вверху) и монтажная (внизу) схемы подсоединения радиомодуля XBee к датчику газа
Бессеансовые сети и двоичные протоколы            $   . +           «  ». #                            (_0#).                  _0# (      .      MQ-6), $             47 0, "             .           _0#               1,4–1,7 &. /        %      %        ,                   (    ).             . 7.13                             ( 22 0),           "   ,     ,       (                  ,         ).   $              2,3 &.   ,         ,              1,6 &. &%            , $             ,              . &          ,               (D0). ;                XBee (  14)        3,3 &. Проветрите помещение 2    ,         "  . &                   "  " . 373 Схема исполнительного (сигнального) устройства =           (%       %    )                 ,     . 7.14. >         3    ,          XBee,                  .               . &  ,  %                ,        ,        3 &. *  . 7.15            %. 3                   %  . #                       "    /  . &  +7  XBee          TIP120,      ,    ,              :              ,   —   . =     $     ,     ,       .               ,             _0#,     ,        ,       . *            "         . #             ,         ,      . & $              ,        .                ,       . 4    ,           ,
Глава 7 374                   220 0   +3 &         . /  -                 % 1,5 &          . Рис. 7.14. Принципиальная (вверху) и монтажная (внизу) схемы подсоединения сигнального устройства (обезьянки с ударными тарелками) к радиомодулю XBee К «плюсу» источника питания 3 В Электродвигатель постоянного тока Радиомодуль XBee 1 кОм AD0 / DIO0 TX AD1 / DIO1 RX AD2 / DIO2 DO8 AD3 / DIO3 RESET PWM0 / RSSI Транзистор TIP120 RTS / AD6 / DIO6 Ass't / AD5 / DIO5 PWM1 Vref NC SLP + 3,3 В 220 Ом DTR/DI8 CTS / DIO7 GND AD4 / DIO4 10 15 20 25 30 10 15 20 25 30 C D E F G H I J 5 5 A B A B C D E F G H I J 1 TIP120 Darlington 1 100 мФ Vcc M
Бессеансовые сети и двоичные протоколы 375     Рис. 7.15. Внутреннее устройство игрушки с изменениями подсоединения проводов двигателя. Припаяйте провода питания для макетной платы к «плюсу» батареи, а общий провод — к ее «минусу» (поз. А). Обрежьте провода, шедшие на двигатель (поз. Б — «плюс», поз. В — общий), и припаяйте взамен новые, подсоединенные к макетной плате Схема сервера Библиотека node-serialport =       Raspberry Pi       %   "     XBee-to-USB.        Raspberry Pi           . 7      nose.js,                  -  . =    $           node-serialport. =        node.js  %    ,          .      ,          node.js        — node-serialport,       "     npm,       :       "    ,            ,              "     . *  $         " :         ,      "    XBee        .  $      %  % ,  $      "  -  .      $        npm                 %  . &  -       $  ,    -    https://github.com/node-serialport/node-serial port#installation-instructions,  "                . $ npm install serialport
Глава 7 376 =    macOS, Windows  Linux            %  . *  Raspberry Pi                 .  $  ,        "  ! «$      Raspian». >  node-serialport        ,           ,            . &    ,           "    "  : /                : open ( ), close ( ), error (%)  data ( ). 2                  . '     — data —                   .           ,   $               —         . #  "                  "  : var myPort = new SerialPort(portName); // '    serialport: var SerialPort = require('serialport'); var portName = '/dev/ttyUSB0' // \$         var myPort = new SerialPort(portName); // • #   $    - - -: function readData(data) { // Š        : console.log(data); } // • #    : // +$      : myPort.on('open', portOpen); // +$      - - - -: myPort.on('data', readData); // +$   $   : myPort.on('close', portClose); // +$     myPort.on('error', portError);  : =                  . #              ,            . &              "                    . 2                express.js   HTTP,   $       " . readData()      
Бессеансовые сети и двоичные протоколы 377 Вк лючение пос ледовательных портов в Raspian 0   ,  Raspberry Pi,     "          ,          ,            . *    $            .                   "   USB/TTL-Serial —    ,     %              . #   ,         ,     Raspberry Pi "   USB/TTL-Serial, ,               "    . >%       $                             Raspian. '   ,       Raspian %  ,         USB                    : $ ls /dev/tty* 4                . &             +       Raspian  Debian  %        USB/TTL-Serial. /dev/ttyUSB0,   4            (  )       (   ,     TX  RX   /       ),        (  )      .        1,                             Raspberry Pi. =    ,      ,          ,           —          ,  %     —            . *            ,                 "  ssh. ;                     . '           ,          ssh (    $           !)       raspi-config. 2      Advanced Options (=     ),     Serial. *   Would you like a login shell to be accessible over serial? (                       ?)   No. 2     Finish     Raspberry Pi.   $                 . 4 : /dev/ttyAMA0. Чтение протокола XBee  $      %         ,  "           ,   "    . &  ,       ,      XCTU              . &          "    " : 7E 00 0A 83 00 01 1F 00 01 00 05 00 01 59 7E 00 0A 83 00 01 1F 00 01 00 05 00 01 59 7E 00 0A 83 00 01 1F 00 01 00 05 00 01 59   API XBee      ( )  ,  $     %           ,    .             "    . [    "          XBee 802.15.4   Digi. =       $       . 4      ,  $         :
Глава 7 378 ?   1 (7E) —        (                 ). /        ; ?   2–3 (00  0ˆ) —   .            ; ?   4 (83) —       API (,   "     ); ?   5–6 (00  01) —  ;   12–13 —       ,  "   (1)   (0)        .   $              . & %      00 01   ,            D0. 3    ,   , 00 02 (0000 0010       )            D1.  "  ?   7 (1F) —           (+X#, RSSI10); ?   8 (00) — %  "  (       %   ); ?   9 (05) —         . 7      $     "   IT  ; ?   10–11 (00  01) —   / ,      "  . & %             —   D0,         ; 10 ?                — 0x7E (       126),                   $   . #   $               node-serialport,    $      npm,          . 2             $     serialServer.js. RSSI, Received Signal Strength Indicator. Читаем пакет /            "     ,           0-7†,  "   "   . ;                  ,           .             node-serialport. 2              USB/ TTL-Serial. + $     "                    . 2             "       ,             : /* serialServer.js : node.js */ var SerialPort = require('serialport'); // ' //    serialport var portName = ' /dev/tty.usbserial-xxx'; //    //     var incoming = []; // &   -  - - //   : var myPort = new SerialPort(portName);
Бессеансовые сети и двоичные протоколы 379 =            %          ,          %    . & $                     ,          %       : function portOpen(portName) { console.log('port ' + myPort.path + ' open'); console.log('baud rate: ' + myPort.options.baudRate); } 2         ,  "       . = $    for,             ,              0-7†,  "   " ,        "        $  : function readData(data) { for (c=0; c < data.length; c++) { //    #    var value = Number(data[c]); //   $    if (value === 0x7E) { // $  0x7E $ //     console.log(incoming); //   R   //     incoming = []; //      -  // - } else { //  $      0x7E, incoming.push(value); //      // - -   } } }        : // +$      : myPort.on('open', portOpen); // +$      - - - -: myPort.on('data', readData); // +$      : myPort.on('error', portError);               . #                : function portError(error) { console.log('    : ' + error); myPort.close(); }  $ node serialServer.js +   $          $  "    " :    $  ,           126 (0x7Eh  %       ),        "   XBee. port /dev/tty.usbserial-00001414 open baud rate: 9600 [] [[ 0, 10, 131, 0, 1, 35, 0, 1, 0, 1, 0, 1, 85 ] [ 0, 10, 131, 0, 1, 35, 0, 1, 0, 1, 0, 1, 85 ] [ 0, 10, 131, 0, 1, 42, 0, 1, 0, 1, 0, 1, 78 ] [ 0, 10, 131, 0, 1, 41, 0, 1, 0, 1, 0, 1, 79 ] [ 0, 10, 131, 0, 1, 34, 0, 1, 0, 1, 0, 1, 86 ] [ 0, 10, 131, 0, 1, 36, 0, 1, 0, 1, 0, 1, 84 ]
Глава 7 380 >%      13  ,           . &       ,             .    $    —   ,     XBee  ,      node. js         . &  ,        ,    "          . var message = { // // packetLength: -1, // apiId: 0, // address: -1, // rssi: 0, // channels: 0, // // sampleData: 0, // pinStates = [] // //      XBee   " JSON: $   \ %  API   ˆ '   XBee M    /, $       Š   -   & ,    # %-   }; 0     ,         "  ,     message. /     JSON         $   "   XBee: Разбираем пакет &   readData()     console.log()       parseData(). 2       $           readData(). /           "    ,             . 0              " : if (value === 0x7E) { // $  0x7E $     parseData(incoming); //        output = []; //      -  - } else { //  $      0x7E, incoming.push(value); //      - //   } &                    . >            0-7†    13  . 4  $ ,             " $     JSON. >     $       "  "   : function parseData(thisPacket) { if (thisPacket.length >= 13) { //     13   // Z  . † R  -  $ ,  // $ _ =  _  * 256 +  _ : message.packetLength = (thisPacket[0] * 256) + thisPacket[1]; // +  #     $ //  #  % , R $ //    # - $ : message.apiId = '0x' + (thisPacket[2]).toString(16); //    '  %    -  : message.address = (thisPacket[3] * 256) + thisPacket[4]; // Z        : message.rssi = -thisPacket[5]; _$  =  _   * 256 +  _ 
Бессеансовые сети и двоичные протоколы     ,     for,            .                  ( D0  D8),          ,         ,         $  : 381 //     -  $  . // †        % , // R $     '  : message.channels = ((thisPacket[8] * 256) + thisPacket[9]).toString(2); // Z  # %-   : message.sampleData = (thisPacket[10] * 256) + thisPacket[11]; // $      //  # %-   : for (var pin = 0; pin < 9; pin++) { // +    -  : var thisPinState = message.sampleData & (1 << pin); // Z-    # %     : message.pinStates.push(thisPinState); } console.log(message); // +  R  R  } } Добавляем сервер ;  ,         "   XBee,        ,   "       -  . 0     $                   -    node.js. 2           % . 0        express     . &          express    $  ,           : var express = require('express'); // $   // express: var server = express(); // C Š  server, //     express server.use('/',express.static('public')); //   //        public &                    GET: server.listen(8080); // %    server.get('/json', respondToClient); // N  //  GET         parseData()                    GET,  %  $     : //         ,      //       : function respondToClient(request, response) { // N    : response.end(JSON.stringify(message)); } // \ #  $     var SerialPort = require('serialport'); // ' //    serialport
Глава 7 382 2             . * $      « »      $           "   JSON: { packetLength: 10, apiId: '0x83', address: 1, rssi: -33, channels: ‘1’, sampleData: 1, pinStates: [ 1, 0, 0, 0, 0, 0, 0, 0, 0 ] } 4                ,     "        ,      $       ,           . &               ,          -  , — $  %    ,  % . #       "          : ?      -  " ? 4  ,       XBee ? - ?          ?        XBee-to-USB         XCTU   -           ; ?     "          "  ?           "       1  10. X % ,           ,    -            : http:// localhost:8080/json. &              ,  "   ,   " : {"packetLength":10,"apiId":"0x83", "address":l,"rssi":-37,"channels " :"1", "sampleData" :1, "pinStates": [1,0,0,0,0,0,0,0,0]} =      -             . Создаем веб-страницу    ,       p5.js   public $   . = $             p5.js,     : /* Z - #   $ : P5.js */ var sensorState = 'UNKOWN'; //     var bgColor = 0; // # %  # $ p5 g -b public 2       sketch.js          setup()    : [  setup()             ,  %      . 2         GET HTTP           : function setup() { createCanvas(windowWidth, windowHeight); // // textSize(24); //  $   % fill(255); //  # %  httpGet('/json','json',getResponse); //  // $ }  $      
Бессеансовые сети и двоичные протоколы 383                  getResponse(),               ,           GET HTTP. [               ,           : // • #   $  % # httpGet(): function getResponse(message) { // $     0: if (message.pinStates[0] === 1){ //    sensorState = 'HIGH'; //      bgColor = '#FF0000'; //  # %  } else { //   $  sensorState = 'low'; //      bgColor = 0; //  # %  } httpGet('/json','json',getResponse); //   //  ' $  } [  draw()       $  "  : function draw() { //   %  $   ' # : background(bgColor); // +  R   text(' $   : ' + sensorState, 30, 30); } &     . *  . 7.16              . ;  ,         ,    %   %        ,         %      :   %,          ,             -   . 9 Digi 802.15.4    API XBee           . ~                  "             ,          ,                  . & $                          .                    API        . 7                     —                       . &  $   $      %  . Рис. 7.16. Снимки с экрана веб-страницы радиомодуля сервера датчика газа. Как сам текст, так и цвет фона окна позволяют с первого взгляда понять текущее состояние качества воздуха в мастерской: состояние атмосферы в мастерской нормальное (вверху — фон окна черный) или опасное (внизу — фон окна красный)
Глава 7 384          API XBee         «XBee/ XBee-PRO S2C 802.15.4 RF Module User Guide»,         : http://cms.digi.com/resources/documentation/ Digidocs/90001500. 9   $            Digi —   ,   Wi-Fi     ,         10. /                      . Заключение >              "  ,  "             . =   "               ,                 . 0        %             ,       "     . +           "  ,              ,           " . #       $  ,    ,                     (  13          " -  ,    14 —   API XBee),               . &   $        "   %  "     %   —  $   %      . ;   , %           "  — $  %             ,         "  . ;  ,                  ,        ,            ,   "                        :           . Свадебные свечи Тома Иго, Пейки Сю (Peiqi Su), Декинга Суна (Deqing Sun), Бена Лайта (Ben Light) и Энди Зиглера (Andy Sigler) /    "  .       Wi-Fi,   "  UDP       


Глава 8 КАК УЗНАТЬ МЕСТОНАХОЖДЕНИЕ (ПОЧТИ) ЧЕГО УГОДНО? К этому времени вы уже должны достаточно хорошо понимать, как можно организовать сетевое общение объектов между собой. Вы познакомились с пакетами, сокетами, дейтаграммами, клиентами, серверами и различными протоколами связи. В этой и следующей главах мы углубим наши знания, рассмотрев два часто задаваемых вопроса: «Где я?» и «С кем я имею дело?» Технологии определения местонахождения и идентификации имеют ряд общих важных свойств. Вследствие этого их часто путают между собой, полагая, что технологию определения местонахождения можно использовать для идентификации лица или объекта и наоборот. В физическом мире — это две разные задачи, и таковыми они также часто являются и в сетевом окружении. Системы, определяющие физическое местонахождение объектов, не всегда обладают хорошими способностями для определения личности тех, кто там находится, а системы идентификации не всегда хорошо определяют точное местонахождение найденных объектов. Точно так же знание того, кто находится на узле, обменивающемся с вами информацией, не всегда может помочь узнать местонахождение этого узла. В последующих примерах мы рассмотрим методы определения местонахождения объектов и их идентификации как в физическом, так и в сетевом окружении. «Адрес 2007» от Моуны Андраос (Mouna Andraos) и Сонали Сридхар (Sonali Sridhar) & $      GPS.      ,                . 0     '.    (J. Nordberg).
Глава 8 388 Компоненты для проектов этой главы Поскольку предметом рассмотрения этой главы является определение местонахождения различных объектов, то большинство новых деталей в ней — это датчики. Коды поставщиков ? A — Arduino Store, http://store.arduino.cc ? P — Pololu, www.pololu.com ? AF — Adafruit, http://adafruit.com ? PX — Parallax, www.parallax.com ? D — Digi-Key, www.digikey.com ? RS — RS, www.rs-online.com ? F — Farnell, www.farnell.com ? SF — SparkFun, www.sparkfun.com ? J — Jameco, http://jameco.com ? SS — Seeed Studio, www.seeedstudio.com Рис. 8.1. Новые компоненты для проектов этой главы: 1. Приемник Bad Elf GPS Pro+. 2. Приемник GPS Garmin GLO. 3. Модуль GPS на адаптерной плате компании Adafruit Ultimate GPS Breakout. 4. Ультразвуковой дальномер HC-SR04. 5. Адаптерная плата 9DOF IMU компании Adafruit. 6. Цифровой компас LMS303DLH. 7. Инфракрасный дальномер GP20Y0A21 компании Sharp. 8. Плата Arduino 101 2 1 3 4 7 8 5 6
Как узнать местонахождение (почти) чего угодно? 389 ПРОЕКТ 15. Инфракрасный дальномер  "      , 1 +. = $             Arduino . MKR1000 — AF: 3156, RS: 124-0657, A: ABX00004, GBX00011 (3   4#), D: 1659-1005-ND Arduino 101 — D: 1660-1003-ND, J: 2239331, SF: DEV-13787, AF: 3033, F: 2520713, RS: 9139999, SS: 114990575, A: ABX00005, GBX00005 (3   4#) Arduino Uno — D: 1050-1024-ND, J: 2151486, SF: DEV-11021, A: A000099, AF: 50, F: 1848687, RS: 715-4081, SS: ARD132D2P   &      GP2Y0A21YK, 1 +. J: 2150256, D: 425-2063-ND, AF: 164, F: 1243869, RS: 666-6564    10  \, 1 +.  D: P11212-ND, J: 29891, F: 1144605, RS: 762-1736  H   , 3 +. D: A26509-20-ND, J: 103377, SF: PRT-00116, F: 1593411       > .  ]=   =                .      "   . ПРОЕКТ 16. Ультразвуковой дальномер  "      , 1 +. = $             Arduino . MKR1000 — AF: 3156, RS: 124-0657, A: ABX00004, GBX00011 (3   4#), D: 1659-1005-ND Arduino 101 — D: 1660-1003-ND, J: 2239331, SF: DEV-13787, AF: 3033, F: 2520713, RS: 9139999, SS: 114990575, A: ABX00005, GBX00005 (3   4#) Arduino Uno — D: 1050-1024-ND, J: 2151486, SF: DEV-11021, A: A000099, AF: 50, F 1848687, RS: 715-4081, SS: ARD132D2P  N     HC-SR04, SRF04     . / "    ,              . SF: SEN-13959, D: 1568.1421-ND  H         , 4 +.                    .       > .  ]=   =                .      "   . ПРОЕКТ 17. Определение уровня принимаемого сигнала  Arduino-   MKR1000, 1 +. AF: 3156, RS: 124-0657, A: ABX00004, GBX00011 (3   4#), D: 1659-1005-ND &                ESP8266. SF: WRL-13231, AF: 2471  " +   Wi-Fi, 1 +.    +      .       > .  ]=   =                .      "   . ПРОЕКТ 18. Геолокационные службы и протокол NMEA 1  GPS , 1 +. = $                 . 9              . 1 GPS, Global Positioning System —         . AF: 746, SF: GPS-1275     GPS Bad Elf GPS Pro+         -   https://bad-elf.com,      GPS Garmin GLO —   -   https://www.garmin.com.
Глава 8 390    Bluetooth Serial, 1 +. AF: 1588, SF: WRL-12580  WRL-12576 7          USB-to-Serial.  - SF: DEV-09716  DEV-14050, AF: 3309  284, SS: 317990026   >   Bluetooth, 1 +. 4  %   "      Bluetooth,     %  Bluetooth- . AF: 1327, RS: 807-7742, SS: 113990026  C     , 1 +.                    GPS. ПРОЕКТ 19. Определение направления с помощью цифрового компаса  C      , 1 +. D: 438-1045-ND, J: 20723  20601, SF: PRT12615  PRT-12002, F: 4692810, AF: 64, SS: 319030002  319030001  "      , 1 +. = $             Arduino . MKR1000 — AF: 3156, RS: 124-0657, A: ABX00004, GBX00011 (3   4#), D: 16591005-ND Arduino 101 — D: 1660-1003-ND, J: 2239331, SF: DEV-13787, AF: 3033, F: 2520713, RS: 9139999, SS: 114990575, A: ABX00005, GBX00005 (3   4#) Arduino Uno — D: 1050-1024-ND, J: 2151486, SF: DEV-11021, A: A000099, AF: 50, F 1848687, RS: 715-4081, SS: ARD132D2P  ˆ &     LSM303DLH   ST Microelectronics, 1 +. AF: 1120, SF: B0B-13303, P: 1250, SS: 101020081  H    , 4 +. #           . D: A26509-20-ND, J: 103377, SF: PRT-00116, F: 1593411       > .  ]=   =                .      "   . ПРОЕКТ 20. Определение положения объекта в пространстве  C      , 1 +. D: 438-1045-ND, J: 20723  20601, SF: PRT12615  PRT-12002, F: 4692810, AF: 64, SS: 319030002  319030001  "      , 1 +. = $             Arduino . MKR1000 — AF: 3156, RS: 124-0657, A: ABX00004, GBX00011 (3   4#), D: 16591005-ND Arduino 101 — D: 1660-1003-ND, J: 2239331, SF: DEV-13787, AF: 3033, F: 2520713, RS: 9139999, SS: 114990575, A: ABX00005, GBX00005 (3   4#) Arduino Uno — D: 1050-1024-ND, J: 2151486, SF: DEV-11021, A: A000099, AF: 50, F 1848687, RS: 715-4081, SS: ARD132D2P     /   , 1 +. &           LSM303  L3Gxx  ST Microelectronics.  Arduino101   "          . AF: 1120, SF: BOB-3303, P: 1250, SS: 101020081  H    , 6–8 +. JD: A26509-20-ND, J: 103377, SF: PRT-00116, F: 1593411       > .  ]=   =                .      "   .
Как узнать местонахождение (почти) чего угодно? 391 Сетевое местонахождение и физическое Одной из самых распространенных задач, решения которых люди хотят добиться с помощью сенсорных систем, является определение местонахождения объектов. Естественная реакция на осознание диапазона всего того, что могут выявлять датчики, — это восторг от предоставляемой ими свободы. Ведь теперь для взаимодействия с компьютерами больше не требуется быть прикованным к креслу. Можно свободно танцевать, бегать, прыгать, — а компьютер все равно сможет различить выполняемые вами действия и отреагировать на них каким-либо образом. *         — $     ,                ,      .      %         Wireless E911 (               ,           )     ,                        ,            ,     $  . 0                      -   %      . 2                                   . 0"             ,    ,    "        :     IP-      - . * $   ,               , —    %               ,          . /    ,    %       (     !    )      ,             Wi-Fi. ;                     ,  "         . 4       -     $   ,    ,         ,             ,       ,       ,            . ;  ,                        ,              . Шаг 1: спросите человека _                . *     $    %    ,  "    %  $    ,   ,  "                            ,         . 3             % ,      ,             .       $   , $                          %           —       ,            , —    ,         .                              . 4     ,         , —      , "    . &        "     %    : %   %  ,   ,   ,
392 Глава 8       ,  " ,  "    ,     , —                -     . *            ,      ,    ,   ,     ,            . &  ,  % ,      ,              , — $       ,         ,    "            "   .      ,  " ,                ,   " ,          ,          "                    .  %  $                         "     "     ,               . ;,     ,   ,   ,                  ,               . /  %   ,           . ;            "                       %              $     . #   ,                  ,               , ,        ,     $ ,             . & $        "                 . 2     " % ,        ,        ,       . ;               ,             . *  ,    ,               ,        "    . ;                ,                « -  »,           , "          . '                   $       —   ,  $          $   , —         "    . 9        . # ,                  -     ,   —            —                        "     . '       ,                  ? & ,                ,      ,      ,  " -      . ;        $       ,                ,           %    . &  ,        ,              ,            ,  ",    $    % . *             ,          "  " . $,        ,         ,       ,        ,     %     ,               " .
Как узнать местонахождение (почти) чего угодно? 393 Шаг 2: определитесь на местности          ,    ,       %    . _        . *  ,             ,  %    ,              - .   $     ,             . 4                      ,         . ;,   %   ,        "       —             $   . & $  ,       , %            ,    ,              ,            . #                      ,   %            . ;,         %     %     #3. * $       -    #3,     %        ,                   "  .                         ,       . +              ,  $       . 0    "     ,  %       . *  ,  -   www.vterrain.org/Culture/ geocoding.html              #3      ,         2 Virtual Terrain Project .   ,   -   2    «&   %». geocoder.opencagedata.com              ,  "     OpenStreetmaps,    API   Google’s maps              -   developers.google.com/maps. q       (%   )         ,  "       ,                   . *  ,                    ,                     . 0                  , $             $        "   . +    %   %           ,  OpenCellID (www.opencellid.org),  "          ,                    GPS. *             IP-        ,           . ;   , "             IP- .             ,   %     "   , $,            %  ,    ,      +     $  %  ,    %    . q       IP-          ,          "      ,             ,       +      .     ,    IP-   
394    IP- . &  "                                . 7 ,   ,                              Глава 8     ,             ,                    . * % ,  $        ,    " "      ,        . Шаг 3: уточните происходящее      ,       ,             :          %    $    .                    ,            %        , "      . &                            ,              -    . X ,          ,         ,   "                 . &  ,                 . +  %  ,     ,    . +            ,   - -   ,      %  ,           ,        . &                                    .    ,      -   ,   %       ,          ,        $  . *  ,                 . &     -                 —  %      ,            ,         $               . &                   , "    "       " ,     -    . [                 ,            . X                              . *  ,      -    ,     ,         $  . 0                   ,            , —            ,         …
Как узнать местонахождение (почти) чего угодно? 395 35 способов определить свое местонахождение *    ETech3 2004,        O’Reilly,           ~ (Chris Heathcote)                %            : «35           »4. 0       ,        ,             %  . +,    ,   ,  %          -   -         %                . 4     —        ,   "   %                . =           $  . •    ,    2  . +    ,        $ %     ,            . •       •       • =  ?   ?      ? • *    •       " ?    . • *  . • X /   . • *  . • *        . • 7               .   - • ;                —       ,   "     Wi-Fi. • GPS, A-GPS5, WAAS6    %  GPS. • >%  %        . /   - • #    7. • 0          . • #    -. • +    :        ? • +        -,   "            . •      . • +            . 3  - Emerging Technology Conference —     "    . 4 &    : «35 Ways to Find Your Location». 5 A-GPS ( . Assisted GPS) —   ,   " «  » GPS-   . X                       . 6 WAAS (Wide Area Augmentation System) —                   . 9    #3   %                  GPS   . 7 #      (     ) —         ( "   )   (  ,      ,       ,    )                 .
Глава 8 396 Определение расстояния Электронные системы определения местонахождения — такие как GPS, сонар или локация мобильных телефонов — сначала кажутся каким-то волшебством, поскольку нет никаких видимых индикаторов принципа их действия. Но если разбить этот процесс на составляющие компоненты, то ничего волшебного в нем не останется, и все станет сравнительно просто для понимания. Большинство систем определения физического местоположения объекта основаны на одном из двух принципов: измерении времени, затрачиваемого сигналом для прохождения от известного места до этого объекта, или измерении уровня сигнала в точке приема. В обоих методах для определения местоположения объекта в двух- или трехмерном пространстве с помощью трилатерации комбинируются измерения от нескольких источников. 7                  ,     .            ,            $ . /   ,     ,  % %         ,     ,                  .     ,               , $       ,                 ,              ,               $ . *  ,     GPS                 ,              ,              . #                      ,                   ,            ,         "     .           —   Skyhook (www. skyhookwireless.com) —            (Wi-Fi, GPS          )           . 7                 . &         "        ,      ,           ,    . 9     $                          ,     . #                             . ;,                      ,                           . ;   GPS       . &               "        "    . 2           ,            $          . 9                        .                     ,             $  .  ,             « »  «  »      ,     . &                                      . 3     "      %  ,     ,        .   $                      , 
Как узнать местонахождение (почти) чего угодно?         . ;            "    ,          . 397 &                   ,     —    . &  "                      . Пассивное определение расстояния X     SRF04         GP2Y0A21YK              . =  SRF04      ,    GP2Y0A21YK —           . =                                "                  . 0         :          GP2Y0A21YK —  10  80 ,      SRF04 —  0  3–4   . ;     ,                        ,   $  %      . 0           ""   ,               , "          ,         " . Проект 15 Инфракрасный дальномер Инфракрасные дальномеры серии GP2Yx компании Sharp достаточно точно определяют короткие расстояния, измеряя яркость отраженного от цели инфракрасного луча. На рис. 8.2 показаны монтажная (вверху) и принципиальная (внизу) схемы подключения инфракрасного дальномера GP2Y0A21YK к модулю Arduino. Эта связка может определять объекты, находящиеся от нее на расстоянии от 10 до 80 см. &   Sharp —  ,           ,                        ,           . &      GP2Y0A21YK,      : www.sharp-world.com/products/device/lineup/data/pdf/datasheet/gp2y0a21yk_e. pdf,       . *                                    10  80 .        $        21,7 &¨ . &    — 30  ,  $               . Требуемые компоненты  7 Arduino, 1 %. +       :    +5 &.  +      Sharp GP2Y0A21YK, 1 %.       10 [, 1 %.     , 3 %. +             "                 ,   . +     "   
Глава 8 398 Напряжение питания Uno =        ,     ,           ,                 ,   5 &. *,          13   7, $             3,3 &. ON +5 В Напряжение питания +5 В Напряжение питания 10 мФ Выход Модуль микроконтроллера A0 Общий Общий Рис. 8.2. Монтажная (вверху) и принципиальная (внизу) схемы подключения инфракрасного дальномера GP2Y0A21YK компании Sharp к модулю Arduino. Конденсатор, подсоединенный параллельно линиям питания дальномера, сглаживает колебания напряжения и тока, вызываемые его нагрузкой
Как узнать местонахождение (почти) чего угодно?   %                      ,             ,       . &    ,     %   " ,                   . ~          GP2Y0A21YK   4,5–5,5 &,              . &    ,       3,3 &   MKR1000  Arduino 101                     . 0             $                          ,             ,                   . 399 # "          . 2                  .              $                            +  $          ,              ,          ,          , —       %          ,         -     .  ,                —              analogRead()  $                . Пишем код /* \-     : Arduino Sharp GP2xx */ void setup() { Serial.begin(9600); // \ #  $   //  ' $ } void loop() { int sensorValue = analogRead(A0); // $   // $    float voltage = sensorValue * (5.0 // +    float distance = 21.7 / voltage; Serial.print(voltage); Serial.print(" V\t"); Serial.print(distance); Serial.println("  "); //   39   ,  // $   . delay(39); } // Z     / 1024.0);    
Глава 8 400 Проект 16 Ультразвуковой дальномер Ультразвуковые дальномеры измеряют расстояние примерно так же, как это делают инфракрасные, но обладают большим радиусом действия. Разумеется, вместо инфракрасного света они излучают ультразвуковой сигнал и принимают возвращенное эхо. Показания датчика отражают время возвращения эха, которое соответствует расстоянию до отражателя. На рынке предлагается широкий диапазон модулей ультразвуковых дальномеров, большинство из которых основаны на керамических преобразователях компании ProWave (www.prowave.com.tw). Самые первые модули для электронщиков-любителей выпускались компанией Devantech (www.robotelectronics.co.uk), но, благодаря открытой конструкции этих модулей, сейчас их предлагают практически все розничные поставщики электронных компонентов. Требуемые компоненты  7 Arduino, 1 %. +       :      .  X    HC-SR04, SRF04    , 1 %.              , 4 %. #"              ,              Devantech SRF04,              (        $      HC-SR04). &   ,     ,   ,            (trigger)            (echo).                      10    ,              ,                   .                         . =          $             . *  ,       $    58,         ,   148 —   . *  . 8.3        ( )     ( )        HC-SR04   Arduino. X               ,                     ,                       %        . *  ,  SRF04               70° (      "        $   )    3–4 . #   ,         %  ,    ,          "  %  . *  . 8.4        "   4×4   ,       .   $     ,       ,         %    , — $               .    "         50   ,               250   .   /              3,3 &,       /   Arduino 101  MKR1000,                 5 &,               5 &,            USB.
Как узнать местонахождение (почти) чего угодно? 5В 401 5В Модуль микроконтроллера Цифровой вывод 4 Цифровой вывод 3 Напряжение питания (Vcc) Вывод активации подачи выходного сигнала (Trigger) Вывод приема отраженного сигнала (Echo) Uno GND. Echo Vcc Общий Trig. Общий ON Рис. 8.3. Принципиальная (слева) и монтажная (справа) схемы подключения ультразвукового датчика HC-SR04 к модулю Arduino Рис. 8.4. Измерение расстояния в двух координатах с использованием ультразвуковых дальномеров. Квадрат на каждой схеме представляет комнату размером 4×4 метра. Для того чтобы обеспечить покрытие всего пространства комнаты, нужно расположить несколько датчиков по ее сторонам Измерение расстояния «спереди-сзади» Измерение расстояния «слева-справа» Датчик 1 Датчик 4 Датчик 3 Датчик 2 Датчик 5
Глава 8 402 Пишем код # "          ,               ,                     . ;  ,            ,                  . /* M$    : Arduino */ const int triggerPin = 4; const int echoPin = 3; void setup() { //     //  ' $ pinMode(triggerPin, OUTPUT); pinMode(echoPin, INPUT); Serial.begin(9600); }  #  $   void loop() { digitalWrite(triggerPin, HIGH); //   //      #    (trigger) delayMicroseconds(10); //    10  , digitalWrite(triggerPin, LOW); //     //   // $         //        (echo): long pulsewidth = pulseIn(echoPin, HIGH); float distance = pulsewidth / 58.0; // cm = microseconds/58 Serial.println(distance); } Активное определение расстояния X         ,      "  ,                . #          GPS          (  . 8.5). /       (         GPS)      (        GPS).                         . ;         %      %        . *                               . =              -  "            ,           $    . *                  ,           . =     $       ,      $    ,         . 0         GPS                 GPS                ,    "               .   Wi-Fi, Bluetooth, 802.15.4     
Как узнать местонахождение (почти) чего угодно?                 ,    $                . 0                    ,     %  ,    $       -       . *  ,        ,            ,   , ,       - 403  Bluetooth  %  ,      Bluetooth —   .       "  ,     ,    . & $  ,       ,   ,                  . *   ,      $ %       ,  ,   , -  ,  ,     MAC-    (           "  ). Рис. 8.5. Активное и пассивное определение расстояния Ответный сигнал, излучаемый Response signal generated by мобильным устройством mobile unit (e.g., cell phone). (например, сотовым телефоном) Основное устройство Base unit (sensor) sends out (дальномер) излучает сигнал, signal, reads reflection затем принимает сигнал,from отраженный от объекта mobile object or person Исходный сигнал, излучаемый Initial signal generated by основным устройством base unit (e.g., cell tower) (например, базовой станцией) Пассивное определение Активное определение Active distance ranging расстояния Passive distance ranging расстояния
Глава 8 404 Проект 17 Определение уровня принимаемого сигнала В проектах с устройствами Wi-Fi главы 4, в проектах с устройствами LoRa и Bluetooth главы 6 и в проекте с использованием устройств Digi 802.15.4 главы 7 мы познакомились со свойством этих радиоустройств, заключающемся в индикации уровня принимаемого сигнала8 (ИУПС). Эта характеристика предоставляет нам информацию о том, какой силы был последний принятый устройством сигнал. При отсутствии преград сила принятого сигнала обратно пропорциональна квадрату расстояния от приемника до передатчика. Таким образом, если мы знаем силу принимаемого сигнала, то можем приблизительно установить расстояние до передатчика. *      «   »,           " +X#  . &                       ,                . 3                  %,                         .   ,    ,                ,         -  "   . ;   ,  +X#          , "          —    % —             . #              (>). & ,             –65 >.  $          ? 0          %     "    >. '        >,        . *  , 1  "           log 1 >.   log 1 = 0,  1 & = 0 >.  "          1 &,    >      0. *  , 0,5 & = (log 0,0005) >  –3,01 >. =    : 0,25 & = (log 0,00025) >  –6,02 >. 8 0  . Received Signal Strength Indicator, RSSI. 4          ,      ,  0 > — $   "  ,           0 >       ,       %       3 >  . '        ,            ,       %    . &    ,                     , %                    . &    ,        ,     , "              . &     Wi-Fi    4     ,      MKR1000  ESP8266,       "    : long rssi = WiFi.RSSI(); 3      LoRa    6    $             : int rssi = LoRa.packetRssi(); = ,       Bluetooth LE "     "             "  "     node.js: console.log('signal strength: ' + peripheral.rssi); #       Bluetooth             -
Как узнать местонахождение (почти) чего угодно?        ,                    $         . * ,             Digi 802.15.4    7             "  Digi API "  "   : message.rssi = -thisPacket[5]; &   $                                 . 405 +           node.js,                              p5.js.                       POST: POST /rssi/value  value         . #                  ,         "   GET: GET /rssi Создаем сервер ИУПС    ,      node.js                          server.js. ;  ,    ,            express: $ npm install express /* Z \M Z : node.js */ var express = require('express'); // '    express: var server = express(); // C$ " server, // $     express var rssi = -100; //       //   2         rssi               ,      : 2             : getRssi()  postRssi(). /               .   — postRssi() —       POST,                    URL-    . 3   — getRssi() —                               : function postRssi(request, response) { rssi = request.params.rssi; //   $ $ // $      response.send("   $  \M Z: " + rssi); //  //   response.end(); //  '  } function getRssi(request, response) { // Z$      // ˆ     meta var message = "<meta http-equiv=\"refresh\" content=\"3\">\n"; var message = "    $  \M Z: " + rssi + " Œ <br>"; message += "     -  "; if (rssi <= -60 ) { // Z       message += "  "; }
Глава 8 406 if (rssi > -60 && rssi <=-40 ) {// ^  //     message += "   -  "; } if (rssi > -40 && rssi <=-20 ) { message += "   -  "; } if (rssi > -20 ) { //     message += "      "; } message += "   " // Š #   response.send(message); //      response.end(); //  '  } *                 GET  POST. &       : //    server.listen(8080); //        $  : server.get('/rssi', getRssi); // GET /rssi server.post('/rssi/:rssi', postRssi); // POST /rssi/value Рис. 8.6. Вывод в окне браузера результатов работы скетча, получающего сведения об уровне силы радиосигнала от только что созданного нами сценария сервера ИУПС. Сервер может выводить значения уровня принятого сигнала не только устройств Wi-Fi. С таким же успехом можно создать клиента, который будет получать от сервера значения уровня принимаемого сигнала радиоустройств LoRa, или Bluetooth, или любого другого радиоустройства, обладающего возможностью измерять величину уровня принимаемого им радиосигнала. Если такой клиент может осуществлять вызовы HTTP POST, он будет работать = $                     ,              %   "   .   ,  ,  "   GET       "    ,        ,     $    . 7                                       . # "       HTTP POST      ESP8266  MRH1000,   "          ,                   Wi-Fi. =  $              .          $        . 8.6.
Как узнать местонахождение (почти) чего угодно? 407 Пишем код скетча для вывода сведений об уровне силы радиосигнала ;  ,      "    ,            config.h,  "              . 3   (     % )       %   . [  setup()      %   WiFi    : /* RSSI HTTP Client Context: Arduino, with WINC1500 module */ // include required libraries and config files #include <SPI.h> #include <WiFi101.h> //#include <ESP8266WiFi.h> // Š   -  ESP8266 // $  R  #include <ArduinoHttpClient.h> #include "config.h" WiFiClient netSocket; //     const char server[] = "192.168.0.8"; // IP- . //    R $      String route = "/rssi/"; //   API void setup() { Serial.begin(9600); // \ #  $    ' $ //   '      Wi-Fi, while ( WiFi.status() != WL_CONNECTED) { Serial.print("   '      : "); Serial.println(ssid); //   R   (SSID) WiFi.begin(ssid, password); //   '    delay(2000); } Serial.print(" '   : "); // +  ' , Serial.println(ssid); //   R   } &   loop()           HTTP POST. &     : void loop() { HttpClient http(netSocket, server, 8080); // Z$ //   HTTP int rssi = WiFi.RSSI(); //   $  \M Z: http.post(route + rssi); //   $ POST: while (http.connected()) { //  '   , if (http.available()) { //   , String result = http.readString(); //    Serial.println(result); //   R } } //  #  http.stop(); // $ $ delay(3000); //  3   } 2  $                         . 2                : http:// localhost:8080/rssi,       GET. =   "             - "      ( %   Wi-Fi),    $        . =                             %   Wi-Fi,               .
Глава 8 408 Множественное отражение сигнала #  ,     "             %   Wi-Fi    "        ,                         . *           ,                . #           %                  $    -      , "              $       "    (  . 8.7). *  ,     %            ,              ,     ,        %  . /       %               ,  "      . Рис. 8.7. Эффект множественного отражения сигнала. Отраженные радиоволны создают эффект наличия фантомных радиомаяков, которые приемник не может отличить от настоящего радиомаяка. Это вызывает ошибки в вычислениях, основанных на уровне мощности сигнала Actual Настоящий Beacon радиомаяк Фантомный Phantom радиомаяк Beacon Фантомный Phantom радиомаяк Beacon Отраженный Reflected сигнал Signal Отраженный Reflected сигнал Signal Основной Primary сигнал Signal Здание Здание Building Building Приемник Receiver
Как узнать местонахождение (почти) чего угодно? ;            "       ,         ,            %. $,          ,    %   , —   ,  , %         %          ,              ,           " . &    $ $            409       ,      %        ,   %         . &      GPS  $                 %        ,       % $               . 0       ,        "        . Определение местонахождения методом трилатерации Определение расстояния предоставляет информацию о том, как далеко в каком-либо одном направлении находится объект от точки, из которой выполняется это определение, но не предоставляет полной информации о местоположении объекта. Расстояние между исходной точкой и целевым объектом определяется кругом с центром в исходной точке (или сферой — в случае трех измерений). Наш объект может находиться в любой точке этого круга. $,            -          ,        % ,       . '"                     ,     ,     . /   -         . 4             ,     ,            (  . 8.8). =      ,                    $ Рис. 8.8. Трилатерация на плоскости: расстояние от точки до объекта определяет круг возможных местонахождений объекта (слева), расстояние до объекта от двух точек сужает возможное местонахождение объекта до двух точек (в центре), а расстояние до объекта от трех точек определяет точное его местонахождение в одной точке плоскости (справа)
Глава 8 410    . &            ,  "     ,      ,         . 7         ,      ,   $    ,          . &             (GPS)              2 . 7                      "    .              ,    -      GPS.                ,                               . >%      GPS        %   ,     %       . #               ,   Wireless E911,                    ,                                $   . Проект 18 Геолокационные службы и протокол NMEA Хорошей новостью для пользователей системы GPS является то, что им не нужно самостоятельно выполнять вычисления трилатерации или триангуляции, поскольку это делает сам приемник GPS, который выдает пользователю его местоположение в виде географических координат (широты и долготы). В системе GPS используется несколько протоколов для приемников, но самым распространенным из них является протокол NMEA 0183, разработанный ассоциацией NMEA9 США. Практически все приемники GPS, имеющиеся на рынке, предоставляют данные по этому протоколу, а также обычно еще по одному или двум другим протоколам.  >       Bluetooth  Bluefruit (         GPS), 1 %.  ,          GPS. *   %  ,              GPS. *    ,          ,   , -,      NMEA. $         $  ,    ,      GPS    . NMEA 0183 — $          . >%          ,          RS-232  TTL. #         NMEA 0183    4800    ,                 .   NMEA 0183          &  "            GPS-   ,  %           %    "     GPS-   . *   GPS-                   , $                 GPS Требуемые компоненты  GPS-    ( .       ), 1 %.      -  Bluetooth- Bluefruit (         GPS), 1 %. 9 NMEA, National Marine Electronics Association — *       $   .
Как узнать местонахождение (почти) чего угодно? 411 Рис. 8.9. Модуль Ultimate GPS Breakout компании Adafruit (справа), подключенный к ее же Bluetooth-модулю Bluefruit (слева). Чтобы получить качественный сигнал GPS, нужно находиться на открытой местности, для чего более чем удобно использовать беспроводную передачу данных и батарейный источник питания. Комплект радиоустройств Bluefruit содержит разъем для подключения батареи, который можно припаять к радиоустройству, что позволит питать от аккумулятора LiPo как само радиоустройство, так и подключенный к нему приемник GPS FIX DTR >RX <TX Vin DSR GND STS 3Vout 3Vo V 3.3V EN VBAT FIX TX RX GND VIN PPS  %    . ;          Garmin, Trimble, Bad Elf     . 0           GLO   Garmin  GPS Pro  GPS Pro+   Bad Elf. ~         GPS  "        ,               Bluetooth                  ,        . *            GPS,          . *  . 8.9   Ultimate GPS Breakout   Adafruit,        Bluetooth- Bluefruit,          2. &   $          ,          GPS GLO   Garmin  GPS-      Bad Elf. Разбор предложений NMEA   NMEA 0183 %       ,      GPS              .     GPS   Adafruit  SparkFun           Bluetooth "  Bluefruit (     . 8.9)         "   USB/TTLSerial. 3          GPS   Garmin  Bad Elf              "      Bluetooth.                               .      $   (              9600    )                         ":
Глава 8 412 $GPGGA,180226.000,4040.6559,N,07358.1789,W,1,04,6.6,75.4,M,-34.3,M,,0000*5B $GPGSA,A,3,12,25,09,18,,,,,,,,,6.7,6.6,1.0*36 $GPGSV,3,1,10,22,72,171,,14,67,338,,25,39,126,39,18,39,146,35*70 $GPGSV,3,2,10,31,35,228,20,12,35,073,37,09,15,047,29,11,09,302,20*7D $GPGSV,3,3,10,32,04,314,17,27,02,049,15*73 $GPRMC,180226.000,A,4040.6559,N,07358.1789,W,0.29,290.90,220411,,*12 $GPGGA,180227.000,4040.6559,N,07358.1789,W,1,04,6.6,75.4,M,-34.3,M,,0000*5A $GPGSA,A,3,12,25,09,18,,,,,,,,,6.7,6.6,1.0*36 $GPRMC,180227.000,A,4040.6559,N,07358.1789,W,0.30,289.06,220411,,*1C &   NMEA        ,            . *             ,   —            ,   —      ,  . .              ($),             . 2            ,     .               (*),          ,             . 9          $GPRMC,              (         % ). # "  RMC10          ,  $                     . /        ,            . +  ,  "      ,      . 8.1. 3    $GPGSV (GPS Satellites in View11)       . ;    $           GPS     . 4    % ,    ,     GPS                 . *     " , $    10 11 RMC, Recommended Minimum specific —         . #  GPS     .    « »       ,    10–15     .         NMEA                      "      $         "   . /             "      ,  «7  %  - »   2. *                       NMEA,                     . & %            GPS                  ,              % ,       . &    HTML5                    ,        :          GPS-   ,           "  ,        Wi-Fi   -      $  . 4          GPS,          —   ,   p5.js        ,          NMEA   ,   $            API HTML5. /                Bluetooth   
Как узнать местонахождение (почти) чего угодно? 413 Таблица 8.1. Информация, содержащаяся в предложении $GPRMC протокола NMEA Идентификатор сообщения Время Состояние данных (действительные или нет) Широта Индикатор юга/севера Долгота Индикатор востока/запада Скорость относительно поверхности (земли) Направление движения относительно поверхности Дата Магнитное склонение Режим Контрольная сумма (Перед контрольной суммой нет запятой. Последняя запятая в таком предложении ставится не перед контрольной суммой, а между магнитным склонением и режимом, которые в этом предложении отсутствуют)  %  GPS-    "          iOS  Android.          GPS-      Garmin  Bad Elf          iOS, $              ,    $  %      GPS,             GPS. $GPRMC 180226,000  18:02:26 GMT12 A—   (V —    ) 4040.6559  40°40.6559' N — #  (North), S — Š (South) 07358,1789  73°58,1789' W — 2 (West), E — &  (East) 0,29  290.90  290,90° #   220411  22  , 2011   *12 X         Android                %      GPS,         "  "       Bluetooth GPS,        https://play.google.com/ store/apps/details?id=googoo.android.btgps. Выбор оборудования GPS *      %    GPS (  . 8.10),    , "     . =                            ,    . >%            GPS                     TTL    NMEA 0183. $                   ,  %  ,    . 9  $ ,    ,  ,    %      GPS,                 (  ,   % ,   % ),         (  ,     % ,   % )      $   .   SparkFun     %        GPS,        12 GMT, Greenwich Mean Time —     q  .         ,     : https://www.sparkfun.com/pages/ GPS_Guide. & ,            GPS      , — $            : « »  « » (« »). *              GPS    "        ,                     . &         GPS        GPS GLO   Garmin ( .  . 8.10, ) —    %   ,          ,  "     Bluetooth. &      $                    GPS,          %      .
Глава 8 414 а б в г Рис. 8.10. Приемники GPS разных производителей: а — GPS-приемник EM-506 компании SparkFun. 48 каналов, хороший прием, и не такой дорогой, как другие варианты; б — модуль Ultimate GPS Breakout компании Adafruit. 22 канала (66 для поиска), оснащен также памятью для хранения данных; в — приемник GPS GLO компании Garmin. Оснащен интерфейсом Bluetooth и смонтирован в компактном корпусе; г — приемник GPS Pro+ компании Bad Elf. Компактный, имеет экран пользовательского интерфейса, оснащен интерфейсом Bluetooth Геолокация в браузере & HTML5      API navigator,            %       . =    "          $     getCurrentPosition(),             —   watchPosition(). &       $              success  failure   options   . +   $                 "       p5.js.  $  ,      . &   ,            API        ,               HTML,  " $    . 7     %           ,           HTTP,    $            HTTPS,     %     . #   index.html    — $            p5.js, $            ,    %    .   ,            sketch.js,           " . &            GeolocationServer,    —  public              p5.js: index.html, sketch.js,     p5.js. &        p5-manager $     "  "  : $ p5 g -b public $ cd public $ p5 u
Как узнать местонахождение (почти) чего угодно? 415 Определяем местонахождение *                 "      label,        JSON     options            . &   setup()    ,       %             . >%  %       ,                %    . * ,        watchPosition()       . &                 :      %  ,      % ,        ,   ,     JSON    : /* š#  Context: p5.js */ var label = "   var options = { enableHighAccuracy: true, timeout: 10000, maximumAge: 0 };  $ # ..."; function setup() { //      -   ' //    createCanvas(windowWidth, windowHeight); fill('#A3B5CF'); // Z-   textSize(36); // $   % textAlign(CENTER); // +    # //     # navigator.geolocation.watchPosition(success, failure, options); } [  draw()   %                   : function draw () { background('#0D1133'); text(label, width/2, 100); } [           ,        "      label. &   JSON options        (HighAccuracy)     ,   $      %             .toFixed()   "  .         %   %    "  . function success(position) { var coordinates = position.coords; var now = new Date(position.timestamp); label = '+  :' + '\n˜  : ' + coordinates.latitude.toFixed(5) + '\nŠ: ' + coordinates.longitude.toFixed(5) + '\n+ - ' + coordinates.accuracy + ' . Š: ' + '\n' + new Date(position.timestamp); } success()    [       fail  "   %     label: ure()  &     . #              . function failure(error) { label = '   ' + error.code + ': \n' + error.message; }
Глава 8 416 Предоставление файлов по протоколу HTTPS   %     ,    ,  "      API,         HTTPS,      %      , " $  . 2         %       . 0    HTTPS,    ,     %      ,                     .     %            ,     HTTP,      ,        %   .        -      ,              ,         . *,     -      %   ,           (        $       — . ! «4  HTTPS     »). # "               GeolocationServer     node         https-server.js. #      . '  keys           ,                   "  : $ openssl req -newkey rsa:2048 -nodes -keyout keys/domain.key -x509 -days 365 -out keys/domain.crt &                   %       .           %    ,  $         . &         keys       : domain.crt  domain.key.     — $   ,    —    %   , "      %      . 3  "                 %     . Для систем под Windows    Cygwin   bash  Windows 10     openSSL. *               Linux  macOS,          Windows. +    $ OpenSSL     macOS  %  -  ,     Linux. 7           Raspberry Pi. # ,          .     ,    , " npm      express.js: $ npm install express 2       https-server.js      "  . 
Как узнать местонахождение (почти) чего угодно? 417 Создаем сервер HTTPS *%                HTTP       HTTPS.          express,          node. js: http, https  fs.       — fs —              : =    HTTPS        ,  " ,        ,      "   fs.readFileSync(). =          express.static(),    $     HTTP       HTTPS,        /* Z HTTP/HTTPS : node.js */ // '    "   : var express = require('express'); // '    // express: var https = require('https'); // ƒ     HTTPS var http = require('http'); // ƒ     http var fs = require('fs'); // ƒ     filesystem var server = express(); // Z$ " server, // $     express var options = { //     HTTPS key: fs.readFileSync('./keys/domain.key'), // ' cert: fs.readFileSync('./keys/domain.crt') //  %  }; server.use('/', httpRedirect); //  % # ' //    $ http server.use('/',express.static('public')); //   , //  '    %  httpRedirect: 2            redirect. /      ,     "      HTTPS,     ,              HTTPS. 3 "    HTTPS           express.static(): * ,      $       HTTP,   HTTPS. #  HTTPS      443:  .     function httpRedirect(request,response, next) { if (!request.secure) { console.log("  $ http  $   $ https"); response.redirect('https://' + request.hostname + request.url); } else { next(); //  $ % # express.static() } } //   : http.createServer(server).listen(8080); //   $ // HTTP https.createServer(options, server).listen(443); //   // $ HTTPS
418 =   $    %  macOS  Linux       sudo  "  : $ sudo node https-server.js 2   ,     -           : http:// localhost:8080. #      $           HTTPS, Рис. 8.11. Пример страницы геолокации в браузере на устройстве под Android. Обратите внимание на перечеркнутый префикс https в адресной строке браузера — таким образом браузер информирует вас о том, что сервер использует недостоверный сертификат (в данном случае — подписанный нами самими) Глава 8     %     ,          . X   ,  %        (   Chrome   "          Advanced). &     %     index.html. 2    ,     ,     %        . =    "  %  ,                %     . *  . 8.11      .       %      GPS           $         . 9      GPS        ,                   "     . $            ,       ,       . 7       "     GPS ,    ,       ,        :   %                 ? #    ,                  GPS,           . $,               , ,   ,             %        $   ,            .
Как узнать местонахождение (почти) чего угодно? 419 Протокол HTTPS и сертификаты     ,               HTTP      TCP.             HTTP,           %        %       "      %    . _             ,        . /             . ;    ,                    ,            ,  $          %     HTTP,      HTTPS. >      HTTPS          TLS13.      ,       , —   ,     ,         ,        !    HTTPS. >    #     ,  !#  HTTPS,             ,   #    . >                   . Z        ,                    . &    ,     ,                IP- ,                 . #        ,         %    "  ,      .         ,            %       . #" , %       ,     %   "      ,      . 13 TLS, Transport Layer Security —   "        .       $    ,     ,        ,   $             .        ,       "   " "  ,              %     $    . '        , $                    . 4          ,             ,      "                 . &            " "    ,           %      ( .  . 8.11). ~ "         , %          %   $   ,    ,  Symantec, Comodo, GoDaddy  GlobalSign. +                             $   .   ,   Internet Security Research Group14        Let’s Encrypt,          . 0   Electronic Frontier Foundation              (certbot.eff.org)          Let’s Encrypt. 4         HTTPS, $         ,   ,    . 14 q           +   .
Глава 8 420 Определение направления и положения в пространстве Определив свое местонахождение, интересно также определить свое положение относительно окружающего мира. Люди обладают врожденной способностью ориентироваться в окружающем пространстве, но объекты такой способности лишены. Поэтому для уточнения ориентации объектов обычно применяются соответствующие датчики: магнитометры, акселерометры и гироскопы. С их помощью можно определить, в какую сторону света вы смотрите, а также где верх и где низ. Q   ,     , — $                 ,              2 . 4   -      ,    ,           ,      . *            ,         $    . &                          —  . 9       :   (roll) —            ,    ,       (pitch) —             (   )     .                 (yaw).  ,          "                 X, Y  Z    . /        — #  . 3      $      #  (surge),   #  (sway)      #  (heave). & $ %              (  . 8.12)      %     .                            . *           ,                         2 . G           $                — $    %                         . ;,      Рис. 8.12. Вращения и смещения объекта в трех измерениях Крен (roll) Продольное смещение (surge) Рыскание (yaw) Вертикальное смещение (heave) Тангаж (pitch) Боковое смещение (sway)
Как узнать местонахождение (почти) чего угодно?       2 ,      ,         ,          . \         "           "                      . +  ,               ,           , 421         " ,     —   ,     . /     "             . &    ,        %   "          . 3  Arduino 101                         . Терминология датчиков ориентации &     ,          "       , $       .                      !   (IMU)15,      Arduino 101,   "  $ , — CurieIMU. &          . *%     ,   ,       Analog Devices, Freescale, ST Microelectronics and Bosch. =   IMU    ,           (AHRS)16,          ! ,       (MARG)17     6-     (6-DOF)18. #"     9-    ,  "         $ ,          "          .   Adafruit       10-DOF, "                     . =     "        . *            "       ,      $      15 0  . Inertial Measurement Unit, IMU. 0  . Attitude and Heading Reference System, AHRS —           . 17 0  . Magnetism, Angular Rate and Gravity, MARG. 18 0  . 6-Degree Of Freedom sensor, 6-DOF. 16     SPI,                   I2C. & $ ,   ,          : X, Y  Z. 0     Z              , $              "      . *              . _             !  (/ 2)           g (1 g = 9,8 / 2). X             ( / ). &         . *  ,             LSM303   ST Microelectronics            +/–2 g  +/–16 g,          —    +/–1,8  +/–8,1  . 3    L3GD20            250  2000      . ;                . =                         2 g,                                  % .    ,        "                     250      ,   
Глава 8 422                                  . *         ,                 .     "        $       % ,     —   .                                   "     —                 ,      $     ,     . ;,              ,   ,     , — $                 . ;           %                 (  . 8.13).           ( ),  %            Z,       X  Y         . 4            ,            Z       ,          .    "       Y (  )  %            X,                     . 3    "        X ( )  %            Y. [   ,   "   ,             . = $            %     . *  ,                    2 g   %    16     216,            –32 768  32 767. 2 ,         –2 g  +2 g,          "  : $ _ /32,768 =  /2.0 :   = $ _  * 2.0 / 32,768 2               . *   $              ,               , —   ,              :     . Рис. 8.13. Оси трехмерного датчика. Показания его акселерометра будут такими, как здесь показано Значение координаты Z наибольшее, координаты X и Y — в состоянии покоя Значение координаты X наибольшее, координаты Z и Y — в состоянии покоя Значение координаты Y наибольшее, координаты Z и X — в состоянии покоя
Как узнать местонахождение (почти) чего угодно? 423 Проект 19 Определение направления с помощью цифрового компаса Магнитометры, которые также называются цифровыми компасами, измеряют изменения в магнитном поле Земли, точно так же, как это делают обычные компасы. При этом, как и обычные компасы, цифровые компасы подвержены помехам от внешних магнитных полей, включая поля, генерируемые мощной электрической индукцией. Поэтому направление с помощью цифрового компаса можно определить, если вы находитесь в пространстве, в котором нет слишком сильных магнитных помех. & $           ST Microelectronics   LSM303. 7       Adafruit, SparkFun  Polulu. *  . 8.13     9-DOF   Adafruit,               . 7                           I2C. = LSM303 $     "            ,    "              .            –32,768  32,767,             +/– 1,3  . = LSM303   16-  %          - *  . 8.14      ( Требуемые компоненты  >       , 1 %.  7 Arduino, 1 %. +       : %  I2C.  Z     LSM303DLH   ST Microelectronics, 1 %.       , 4 %.    ( )  )     Рис. 8.14. Монтажная (слева) и принципиальная (справа) схемы подключения модуля 9-DOF компании Adafruit с компасом LSM303 к микроконтроллерной плате MKR1000 (здесь показаны только задействованные выводы). Такой вариант подключения можно использовать с любой совместимой с Arduino микроконтроллерной платой, поддерживающей интерфейс I2C A B C D E F G H I J 1 1 5 5 10 10 15 15 20 X Y Z 20 9 DOF 25 30 A B C D E LRDY LIN2 LIN1 GRDY GINT SDA SCL GND 3Vo VIN F G H Напряжение питания (Vcc) SCL SDA SDA SCL Модуль микроконтроллера GND 3Vo 25 Общий 30 I J +Vcc Vin Модуль компаса LSM303DLH
Глава 8 424  9-DOF   Adafruit  LSM303        MKR1000. &  ,   $          Arduino ,  "    I2C.        5 &    . *       " : ? Vin — "    5 &. #  $     5 &     ; ? GND — " (« »). #   $     GND     ; ? SCL —          . #   $     SCL     ; ? SDA —      . #  $     SDA     . =     .   $     - =  LSM303       ,           Polulu —      . =        I2C       Wire. '   $  ,              D  |  >      | N      ,   %    " A           LSM303,        LSM303 by Polulu     N  . X    ,         . Пишем код для цифрового компаса             $    LSM303     compass. &   setup()         ,     Wire        I2C,   % $  compass. * ,    enableDefault()      compass       .              +/–1,3  ,            2 : /* [  loop()             compass,    $   read(),    "   heading()        : void loop() { compass.read(); // Z  $    float myHeading = compass.heading(); // +    Serial.println(myHeading); // + $   R delay(100); // +   $  100  }   $    LSM303 : Arduino */ #include <Wire.h> #include <LSM303.h> LSM303 compass; // Z$ R$     void setup() { Serial.begin(9600); //    ' $ Wire.begin(); //   $  %  I2C compass.init(); // \ #  $     compass.enableDefault(); //       //   ' }
Как узнать местонахождение (почти) чего угодно? 425 Калибровка цифрового компаса                 ,        ,        : $   ,   , $    , " ,  $     . $                             $    .                        , $   ,          %    . = $            ,  % ,       . Serial.print(compass.m.x); Serial.print("\t"); Serial.print(compass.m.y); Serial.print("\t"); Serial.println(compass.m.z);    %      16 ,            –32,768 ( )  32,767 ( ). 2                  ,          setup()  "  : compass.m_min.x compass.m_min.y compass.m_min.z compass.m_max.x compass.m_max.y compass.m_max.z        LSM303            ,            ,    "     , "       . &              "    ,         " github.          " . 7    "           ,             . =        $    "     loop(): = = = = = = -680; -623; -616; 422; 451; 424; Локальные пределы X          . #  ,  %     .       X   $                    %     %   . =           API   LSM303        "        https://github. com/pololu/lsm303-arduino. Введение в интерфейс I2C  LSM303                  I2C19. ]          !   TWI20                   SPI,     !      2. 19 2 I C, Inter-Integrated Circuit —              . 20 TWI, Two-Wire Interface —       . #      I2C  SPI    ,  I2C       " (    " )                 "       .      I2C               :        #    (SCL)21,            21 SCL, Serial Clock —      .  "
Глава 8 426    (    ),       . *  (SDA)22,                         .                 (         ,      )                  I2C. 3                 (     !    ,       )             I2C     . &       SPI,     I2C            .            ,            ,       ,        . ;  ,    I2C      %    (% )       (  "    )      (   )    : 22 SDA, Serial Data —      • <      (SCL) —  ,    "           ; • <      = (SDA) —  ,         . - &    ,  "    I2C,  "      % ,  "  $    . >  Wire            % I2C     Arduino    . >%         ,       I2C,            Wire. &  I2C         ,    Arduino   %     Arduino        SCL  SDA. . Проект 20 Определение положения в пространстве Курс по компасу — это прекрасный способ определить направление, если вы находитесь на земной поверхности. Но направление представляет собой лишь одно из условий нахождения правильного положения объекта в пространстве. Кроме направления, надо также знать, где верх, а где низ, — чтобы определить тангаж и крен. И здесь нам помогут акселерометры — устройства, измеряющие линейное ускорение, и гироскопы, измеряющие угловую скорость вращения. Таким образом, в этом проекте мы научимся определять положение объекта в пространстве, используя акселерометры и гироскопы. Требуемые компоненты  >         %   , 1 %.  7 Arduino, 1 %.          / , 1 %.      . & $           LSM303  L3Gxx   ST Microelectronics   Arduino 101,  "            .       , 6–8 %. ("  % ). 3            . &          %   ,       "         .                       ,   $           2     ,            . #   ,    ,      ,       . +              $       ,          . 0 ,     
Как узнать местонахождение (почти) чего угодно?    ,       ,           ,      . 3                     ,            , . .      ,       . 3         %    , $              . =                        2 g —           $  . >%        ,  "      , —       ,          3–6 g. *               %  —   ,    (       )                  100 g! 427 & $                     /        $      "     . 7    ,       ,     " #       ,      7 (Sebastian Madgwick),          Processing              $  . &  "                       . &      $          / LSM303 (       "    )       L3G   ST Microelectronics. 7 LSM303     $    Arduino,          . 8.14. 3                  Arduino 101           /  Bosch BM160 ( $          ). Снимаем показания (вариант с платой Arduino 101) /* Внимание! /               /   ,      Arduino 101 #                ,       Arduino 101. >  CurieIMU    ,    "          ,      g,      ,          (/ ). =            (    | Z  -  # - $      CurieIMU : Arduino Z    $   # $  Arduino 101. */ #include "CurieIMU.h" void setup() { Serial.begin(9600); //    ' $ CurieIMU.begin(); // \ #  $    # // $  //   $ $    +/-2 g CurieIMU.setAccelerometerRange(2); //   $ $     +/- 250 / CurieIMU.setGyroRange(250); } void loop() { float x, y, z; //     // $ $  
Глава 8 428 float gx, gy, gz; //     // $ $   // Z     $  CurieIMU.readAccelerometerScaled(x, y, z); CurieIMU.readGyroScaled(gx, gy, gz); Serial.print("x: "); // +  R $  //     X Serial.print(x); Serial.print(",\ty: "); // +  R $ ', //  # ' $      Y Serial.print(y); Serial.print(",\tz: "); // +  R $ ', //  # ' $      Z Serial.print(z); Serial.print("\tgx: "); // +  R $ ', //  # ' $      X Serial.print(gx); Serial.print(",\tgy: "); // +  R $ ', //  # ' $      Y Serial.print(gy); Serial.print(",\tgz: "); // +  R $ ', //  # ' $      Z Serial.println(gz);  | " A )   Intel Curie Boards by Intel,         (D  |  >      | N      )   CurieIMU.  ,     ,     /            ,         %      : } Снимаем показания (вариант с использованием интерфейса I2C) /              LSM203     L3Gxx. =  $         ,      "        ,   "           L3G   Polulu. #        :      LSM303   ST Microelectronics (       "     )      L3Gxx. /           9-DOF   Adafruit,        Polulu.   SparkFun         :    L3G4200D       LSM303. =      Adafruit        ,     19 —          I2C. # "           SDA      SDA     ,    SCL   —    SCL      ( % I2C            ). Внимание! &        Wire        I2C      ,                . 2    $         accelerometer  gyro: /* Z  $   LSM303   L3G : Arduino Z  $  $   LSM303   L3G */ #include <Wire.h> #include <LSM303.h> #include <L3G.h> LSM303 accelerometer; L3G gyro;
Как узнать местонахождение (почти) чего угодно? 429 &   setup()                  I2C,   . X           : void setup() { Serial.begin(9600); //    ' $ Wire.begin(); // \ #  $   %  I2C accelerometer.init(); // \ #  $     accelerometer.enableDefault(); //     //  $ $    ' (+/- 2g) gyro.init(); // \ #  $      gyro.enableDefault(); //      $ // $    ' (+/- 250 /) } &   loop()       ,    "   readAcceleration()  readGyro()          "     . 0    $          : void loop() { accelerometer.read(); // Z  $    gyro.read(); // Z  $     // $ $       # g float x = readAcceleration(accelerometer.a.x); float y = readAcceleration(accelerometer.a.y); float z = readAcceleration(accelerometer.a.z); // $ $       # / float gx = readGyro(gyro.g.x); float gy = readGyro(gyro.g.y); float gz = readGyro(gyro.g.z); } [  readAcceleration()                  g,   $      CurieIMU,    readGyro()            . 9 %   16  ( –32 768  +32 767)      LSM303       –2g  +2g. 3  %        +/– 250 / : float readAcceleration(int rawValue) { // $    LSM303  16   //    $ +/- 2g float result = (rawValue * 2.0) / 32768.0; return result; } float readGyro(int rawValue) { // $    L3G  16   //    $ +/- 250 / float result = (rawValue * 250.0) / 32768.0; return result; } Определение направления вверх с помощью акселерометра #    ,        ,             .       ,   9,8 / 2,            . 0 $    ,     ,          ( .  . 8.13)     :       $ ,  x > 0 -   1 else   Y  y > else   Z  z > else -   2    $ , 0   3   4    $ , 0   5   6
Глава 8 430 Ориентация объекта (базовый подход) /                    ,     . = $       %      loop()     "   : /*    #   : Arduino    '  ,   "  */ // Z'   ' $   -   // '    , "  -  //   % # setup(). void loop() { // Z'  -  % # int orientation = readOrientation(x, y, z); Serial.println(orientation); } ;                . /         x, y  z           g,         "  ,                  . =      ,           g. 2          "  ,             :  ,  ,  ,  ,    . &  ,                 . int result = -1; // $        int absX = abs(x); // Œ       int absY = abs(y); int absZ = abs(z); // N        int bigger = max(absX, absY); int biggest = max(bigger, absZ);    if (biggest == absX) { // *    ’   if (x > 0) { //     !      result = 1; } else { //           result = 2; } } if (biggest == absY) { // *    Y   if (y > 0) { //     !     y result = 3; } else { result = 4; //        //   y } } /                         ,   %            . 0          "          : int readOrientation(float x, float y, float z) {   if (biggest == absZ) { // *    Z   if (z > 0) { result = 5; //     !     z } else { result = 6; //          z } } return result; }
Как узнать местонахождение (почти) чего угодно? 431 Определение рыскания, тангажа и крена ;                      , —   ,    ,       "   . *      ,      . ;   ,           ,          . 0                      .     $                        Freescale Semiconductor,          PDF   : http://cache.freescale.com/ files/sensors/doc/app_note/AN3461.pdf. &   ,                  " . #                   2 . $,           © ( ),   $        X  ,    —     Y (  . 8.15). X     X  Y     "    ,       "         : x 2 + y 2 = z 2. 2  $,        "    "                . # "       X (Xaxis)     ,     sin ©,     Y (Yaxis) —   ,     cos © (  ,      %                ,     —  %       "   ). 0 : § · Xaxis >  arctg ¨ ¸ 2 2 © Yaxis  Zaxis ¹ 7   § · Yaxis arctg ¨ ¸ 2 2 © Xaxis  Zaxis ¹ Z X Y Сила тяжести Θ Рис. 8.15. Вычисление составляющих силы тяжести на основе угла '          ,                  g,   $   . 3        ,                   ,      . Метод Мадгвика & 2010  #   7 (Sebastian Madgwick)                         ,        $  . 0    $           ,          ,            . /        : http://x-io. co.uk/open-source-imu-and-ahrs-algorithms/. 7       % %     $   ,           PDF   : http://x-io.co.uk/res/doc/madgwick_internal_ report.pdf. ~   >  (Helena Bisby)     7       Arduino,   %     -
Глава 8 432    #   (Paul Stoffregen)        Arduino. &                              . =          Madgwick. = $      -         D  |  >      | N      ,   %    " A           Madgwick,        Madgwick by Arduino     N  . X    ,    "      "  . Ориентация объекта (продвинутый подход) '     Madgwick,    $      filter. / $            —  %    40  ,        25 q. =                    4. 2           % : /* &   setup()            25 q: void setup() { // Z'   filter.begin(25); // N  } [  loop()                     ,        ,  %  40            . 4   %,     . void loop() { // Z'  -  % # loop() if (millis() - lastReading >= readingInterval) { // N     Madgwick filter.updateIMU(gx, gy, gz, x, y, z); // $    ,  !    //      # float roll = filter.getRoll(); float pitch = filter.getPitch(); float heading = filter.getYaw(); Serial.print(heading); Serial.print(","); Serial.print(pitch); Serial.print(","); Serial.println(roll); lastReading = millis(); // N    //   } } [  readOrientation()           $     "       .         ,       getRoll(), getPitch()  getYaw(),        . &  $   $  ,              . * ,        . &     :    #    &  : Arduino Z  $  '        /  */ // Z'   ' $   -   // '     "  -  #include <MadgwickAHRS.h> long lastReading = 0; //           long readingInterval = 40; // 40  =    25  Madgwick filter; // •    Madgwick -  % #     25 
Как узнать местонахождение (почти) чего угодно? 433 Соберем все вместе /  Processing                                          . 0          "            ,                 . *         ,   ,                 ,         . /* Š  &  : Processing      $    $  -        ,      . */ import processing.serial.*; // \       serial float heading, pitch, roll; // ƒ  float position; // & ,       Serial myPort; //     7  setup()              ,          : void setup() { // draw the window: size(400, 400, P3D); // calculate translate position for disc: position = width/2; // +  R      printArray(Serial.list()); //  , $    myPort = new Serial(this, Serial.list()[0], 9600); // † // - , $   R        // $   Serial.list(),       // '   // š     serial  , //        : myPort.bufferUntil('\n'); //  %     textSize(12); textAlign(CENTER, CENTER); } 7  draw(),   ,        . 0       tilt(),         : void draw () { //  #: background(#20542E); fill(#79BF3D); //     : tilt(); } #   3D  Processing     "   0  2ª  . 7  tilt()          (  ,     )  $ void tilt() { // Z        #: translate(position, position, position); // X —  $ rotateX(radians(roll+90)); // Y —  
Глава 8 434  . 0      Processing translate()  rotate()   "    "                  : rotateY(radians(pitch)); // Z -   rotateZ(radians(heading)); //  # $  : fill(#79BF3D); //     : ellipse(0, 0, width/3, width/3); //  # : fill(#20542E); // + ,       '' //  ' : text(heading + "," + pitch + "," + roll, 0,0,1); } 7  serialEvent()       ,  "             ,         ASCII, —     ,   $     «*   - »   2:              ,            ,     ,    $       . void serialEvent(Serial myPort) { // Z   $   %: String myString = myPort.readStringUntil('\n'); // †   -    ,    : if (myString != null) { myString = trim(myString); // $    $ : String items[] = split(myString, ','); if (items.length > 2) { heading = float(items[0]); pitch = float(items[1]); roll = float(items[2]); println(heading, pitch, roll); } } } Рис. 8.16. Вывод скетча Processing для отображения положения акселерометра методом Мадгвика      "         ,  $   "       $    "     (  . 8.16). ~                     "  ,     . 8.16,     %   ,                . +,           "                ,        $          " .     "   Madgwick   $       .  "              ,  $  %          ,              %
Как узнать местонахождение (почти) чего угодно?            Processing. &  $    Processing            ,   "         . ;    "    . 7         % ,           , —            ,    %   . *     435    $                  2 ,  %        . 7   ,      7      "     Z. &   ,              LSM303,  "   ,                   $  . Заключение Начиная разрабатывать проекты, которые используют системы определения местоположения, мы обычно обнаруживаем, что меньше означает больше. Довольно часто бывает так, что мы начинаем разработку проекта, полагая, будто нам нужно знать местоположение, расстояние и направление, а потом — по мере углубления в проект — выясняется, что физические ограничения создаваемых объектов и пространства, в которых они создаются, решают за нас многие проблемы и дают возможность проект упростить. / $                                     % .       %     "   $   ,        ,             ,      ,        $    . ;             $    ,    . &    $          . *           ,            «Адрес 2007» от Моуны Андраос (Mouna Andraos) и Сонали Сридхар (Sonali Sridhar)     ,                    . 0     '.    (J. Nordberg).     .    $       ,            ,                . &  "        ,  "             .

Глава 9 ИДЕНТИФИКАЦИЯ В предыдущих главах мы предположили, что идентичность равнозначна адресу. Зная адрес устройства в сети, мы уже могли с ним взаимодействовать. Но представьте себе, какими непредсказуемыми были бы последствия, если бы мы использовали этот подход в повседневной жизни, — например, сняли трубку телефона, набрали номер и просто начали говорить. А что, если мы набрали неправильный номер? А если ответит кто-либо другой, а не тот, кого мы ожидаем услышать? Адреса устройств в сети обозначают их сетевое расположение, но не имеют никакого отношения к содержанию сообщений, которые между ними пересылаются. Это мы сетевые устройства используем для передачи тех или иных сообщений другим людям. При этом сетевой идентификатор устройства и физическая идентичность лица — это две абсолютно разные вещи. Физическая идентичность обычно оценивается присутствием (это возле меня?) или адресом (где это?), а сетевая идентификация также принимает во внимание сетевые возможности устройства и его состояние, когда с ним устанавливается контакт. В этой главе мы рассмотрим некоторые методы наделения физических объектов сетевыми идентификаторами, а также способы, посредством которых устройства в сети могут определить возможности друг друга с помощью пересылки сообщений и используемых протоколов. Вы также узнаете, как устройства в сети могут определять возможности друг друга через отправляемые ими сообщения и используемые протоколы. «Нюхач» — игрушка для детей с проблемами зрения от Сары Йогансон (Sara Johansson) &           RFID.           RFID,         ,      . 9  #   ,     «0"   »         0 ,       ; 3  (Timo Arnal)  7 #  (Mosse Sjaastad). 0     &  1 .
Глава 9 438 Компоненты для проектов этой главы Основные новые компоненты в проектах этой главы — веб-камеры и считыватели меток RFID, которыми мы воспользуемся для идентификации цветов, лиц, меток RFID и прочих внешних признаков. Коды поставщиков ? A — Arduino Store, http://store.arduino.cc ? J — Jameco, http://jameco.com ? AF — Adafruit, http://adafruit.com ? P — Pololu, www.pololu.com ? AMZ — Amazon, www.amazon.com ? PX — Parallax, www.parallax.com ? B — Belkin, www.belkin.com ? RS — RS, www.rs-online.com ? D — Digi-Key, www.digikey.com ? SF — SparkFun, www.sparkfun.com ? F — Farnell, www.farnell.com ? SS — Seeed Studio, www.seeedstudio.com ? ID — Identiv, www.identiveusa.com Рис. 9.1. Новые компоненты для проектов этой главы: 1. Шилд NFC PN532 компании Seeed Studio. 2. Адаптерная плата PN532 компании Adafruit. 3. Считыватель NFC-меток SCL3711 USB компании Identiv. 4. USB-камера (если ваш компьютер не оснащен встроенной веб-камерой). 5. Розетка WeMo компании Belkin. 6. Объекты разных цветов. 7. Соленоидный замок. 8. Набор QR-кодов. 9. Метки RFID Classic компании Mifare 5 3 1 2 4 6 8 9 7
Идентификация 439 ПРОЕКТ 21. Распознавание цветов с помощью веб-камеры      -  .  >   >   )   = . ПРОЕКТ 22. Распознавание лиц с помощью веб-камеры      -  .  >   >   J-   . ПРОЕКТ 23. Распознавание двумерных штрихкодов с помощью веб-камеры      -  .  >   >     . ПРОЕКТ 24. Чтение меток RFID  D  RFID, 1 +. 7         NFC-  SCL3711 USB Smart Card Reader   Identiv. AF: 359  360, SF: SEN-10128  SEN-11319, SS: 113990013       > Raspberry Pi, 1 +. ID: SCL3711  " RFID Classic   Mifare. &      "          ,          ,      %  . SF: DEV-13825, AF: 3055  3400, SS: 102010048  114990584, RS: 896-8660, F: 2525225 ПРОЕКТ 25. Чтение и запись сообщений NDEF  D  RFID, 1 +. 7         NFC-  SCL3711 USB Smart Card Reader   Identiv. AF: 359  360, SF: SEN-10128  SEN- 11319, SS: 113990013       > Raspberry Pi, 1 +. ID: SCL3711  " RFID Classic   Mifare. &      "          ,          ,      %  . SF: DEV-13825, AF: 3055  3400, SS: 102010048  114990584, RS: 896-8660, F: 2525225 ПРОЕКТ 26. NFC и бытовая автоматизация  C      , 1 +. D: 438-1045-ND, J: 20723  20601, SF: PRT12615  PRT-12002, F: 4692810, AF: 64, SS: 319030002  319030001          , 1 +.   ,                  . A: 1609  H       37        "3   =, 4 +. =       . D: 36-2206-ND  H       12        "3   =, 2 +. =       . D: 36-2203-ND
Глава 9 440  '  "3       6 , 12 +. =        . D: 36-9300-ND          , 1 +. 7               8  9   5.   Arduino MKR1000, 1 +. AF: 3156, RS: 124-0657, A ABX00004, GBX00011 (3   4#), D: 1659-1005-ND. &               ESP8266. SF: WRL-13231, AF: 2471  " NFC-  PN532, 1 +. X           % SPI, I2C  UART (X3). *    -  $          NFC-      DFRobot,  "      X3    %         AVR. AF: 364, D: 1528-1781-ND, SS: 113030001  " RFID Classic   Mifare, 2 +. AF: 359  360, SF: SEN-10128  SEN-11319, SS: 113990013  (  WeMo   Belkin, 2 +. B: P-F7C027       > . ]=   =                 .      "   . ПРОЕКТ 27. Двухфакторная идентификация с использованием NFC  D  RFID, 1 +. 7         NFC-  SCL3711 USB Smart Card Reader   Identiv. ID: SCL3711  " RFID Classic   Mifare. &      "          ,          ,      %  . AF: 359  360, SF: SEN-10128  SEN-11319, SS: 113990013       > Raspberry Pi, 1 +. SF: DEV-13825, AF: 3055  3400, SS: 102010048  114990584, RS: 896-8660, F: 2525225  %    TIP120, 1 +. D: TIP120-ND, J: 32993, F: 9804005 RS: 8080502  (    1 , 1 +. D: 1.0KQBK-ND, J: 690865, F: 9339051, RS: 7077666  D     , 1 +. AF: 1512 ПРОЕКТ 28. Геолокация по IP-адресу       >   >   .    12 ', 1 +.      A  J: 170245, F: 1176248    )           5,5   +  — 2,1 , 1 +. D: CP3-1000-ND , J: 28760, SF: PRT-10287, A: 369, F: 1737256 ]+    , 1 +.  SF: PRT-12044, AF: 65, D: 923273-ND          , 1 +.   ,                  .A: 1609  H       14        "3   =, 4 +. D: 36-2204-ND  '  "3       6 , 8 +. =        . D: 36-9300-ND          , 1 +. 7               8  9   5.
Идентификация 441 Физическая идентификация Процесс идентификации физических объектов является столь существенной частью нашего жизненного опыта, что мы редко отдаем себе отчет в том, как мы это делаем. Конечно же, мы полагаемся в этом на наши органы чувств: смотрим на объекты, ощупываем, поднимаем и встряхиваем их, прислушиваемся к ним, нюхаем и пробуем их на вкус и так до тех пор, пока мы не сориентируемся в том, что они собой представляют, после чего навешиваем на них соответствующие ярлыки. Весь этот процесс опирается на очень сложные функциональные способности наших мозга и тела, и любой, кто когда-либо пробовал заниматься компьютерным зрением или искусственным интеллектом вообще, может сказать вам, что научить компьютер распознавать физические объекты — задача далеко не из легких. Так же, как сужение человеком поля поиска какого-либо предмета облегчает задачу определения его местоположения, задача распознавания объектов посредством компьютеров облегчается, если мы можем ограничить область активного поиска, а также тем или иным способом пометить важные объекты. 7       ,     ,      %  , —   $     . 0                ,      . =                  !             (RFID1). #"           :                         % . 9               . #                                ,       . 0       %                    . & $  %           RFID. *        RFID            ,             ,       . &                       ,             ,       "                 1 RFID, Radio Frequency Identification.  ,      $        . &  ,                   ,        ,     $     ,                    . #     ,          %             "   ,            . +  , "         ,  "   RFID          —        .       ,              %         . *  ,    ,     ;,       . 2         ,  $              %   . ;,  #3         ; + (Tom Igoe),    *-  ,     ,     . $,          ,            —   ,         ,       —   ,    : ; +, [ $ . '     ,      %      
Глава 9 442   .     ,                     ,      ,          .                       . 9       RFID :                             ,            "   % . 3     $             "     ,              ,       RFID  $ . +                    . #    ,                   : «+ ,  !»,            %  ?          RFID   ,             ,   ,                       ,       . ;            —          ,           . Видеоидентификация &        "              :                    .                 ,      "         . ;,   ,   RGB2  HSV3 2 RGB, Red-Green-Blue —   ,  HSV, Hue-Saturation-Value —  ,    . 3 ,   .  "  , %               ,       $      . 3    CMYK4           .  ,            ,        ,       ,             . *  . 9.2            % —        . #  "                     ,  %  $  ,   . #      "    $               ,           ,   ,         . &  "                   ,  "   .   $   ,          ,              ,                   USB.   ,    — $ %     HTML5,           ,      JavaScript. 4     -        JavaScript,        $  ,       ,       +    ,        . &  "         ,        , —                    "    . &   —      —            ,    — ,   ,      —  %  QR5. 4 5 CMYK, Cyan-Magenta-Yellow-blacK —  ,   ,   ,  . QR, Quick Response —   .
Идентификация #               ,     p5.js.    $         - ,        HTTPS. &                    httpsserver.js   18 ( . !. «&!    HTTPS»   8). *  ,   $         (  )   . $                              . Распознавание цветов 9          —          ,                   . # " $             . 443 = $               —      ,               . 2    $    ,         "   "       . 9             $                      .    ,                    ,                       " ,               . *         "       , $     "        ,            "     . Рис. 9.2. Пример распознавания цветов. Простое отслеживание цветов дает наилучшие результаты, когда распознаются цвета, резко отличающиеся от фона, на котором они представлены
Глава 9 444 Проект 21 Распознавание цветов с помощью веб-камеры Скетч p5.js из этого проекта захватывает изображение с подключенной к компьютеру видеокамеры, ищет в нем пикселы определенного цвета и помечает их на копии изображения, которую выводит на экран. 0            -   HTML            $       -                  %               .     $   . =  - =     ,         p5.js,  " -      - . #             , ,     %   $    Требуемые компоненты    ,                  "            -  .   . &      %      — % $ 0     .    . Пишем код *%        CameraProjects. =       public,      18. 2      public     p5.js    colorTracking. &  colorTracking       ,      p5.js: index.html, sketch.js,    libraries,  "   p5.js. & $              sketch.js,    "            public  . 0     sketch.js          setup()     .    video       $       API   , trackColor —            , differenceThreshold —                  ,  dSlider —        : /* &   setup()     ,          video             $  . 2      video       canvas     : function setup() { video = createCapture(VIDEO); // M    //   video.size(400, 300); //  $  $- // $  video.position(0, 0); //    $    var canvas = createCanvas(400, 300); // ^ - // - $  canvas.position(0,0); //    -    #   '  % #  : p5.js ^    Š R ˜ % . HTML5 */ var video; // "  $-   var trackColor = [255,0,0]; // ƒ   # var differenceThreshold = 10; //  $  // $ # var dSlider; // $    $ 
Идентификация 445 dSlider = createSlider(0, 100, 10, 1); // \ #  $   // $  dSlider.position(10, height-30); //     dSlider.touchEnded(setDifference); // +$ % # ' //  $  $   $  } 7  draw()          ,     ,           . =        ,          , — $                 . =             $  :   ,       "     «» —     . =               "   (             ): function draw() { image(video,0,0); // + $   R video.loadPixels(); // Œ   $  $   // -  #      for (var x = 0; x < video.width; x++ ) { // Z for (var y = 0; y < video.height; y++ ) { // Z# // +  $ # '      //        var loc = (x + y * video.width) * 4; //   $  ' -      var r1 = video.pixels[loc]; //  // '   var g1 = video.pixels[loc + 1]; //  // '   var b1 = video.pixels[loc + 2]; // Z  // '   //   $  ' //     # var r2 = trackColor[0]; //  ' var g2 = trackColor[1]; //  ' var b2 = trackColor[2]; // Z  ' arrayLocation = x + (y * width) * 4; 2    ,          ,       ",       ,         : =         $  . 9        ,       "   ,            ,           ,         . &    ,               differenceThreshold. 4     % ,              . #     ,   ,             : //   % # ' dist()     $ # //  # var difference = dist(r1, g1, b1, r2, g2, b2); // † $  #    -  // $  $ #  # if (difference < differenceThreshold) { stroke(0); //   #     point(x, y); // Z   $ #     } } }
Глава 9 446 2    $                          . /  %    draw(): // + % #     $ R fill(255); text("   #: " + trackColor, 10, height-60); text("  $  $ #: " + differenceThreshold, 10, height-40); } // # % # draw() '               "   %       ,       mousePressed().   "     $         "   $      trackColor: // Z- #        //     ' trackColor: function mousePressed() { if (mouseY < dSlider.y) { //    $ , trackColor = video.get(mouseX,mouseY); // Œ // $  ' -   # } } * ,                differenceThreshold. +    $        . &   setup()      $  ,      ,      "      %  . +                     differenceThreshold: // † $    , $   //   ' differenceThreshold: function setDifference() { differenceThreshold = dSlider.value(); } Исполнение скетчей работы с изображениями =    $            https-server.js,   $      "  : $ sudo node https-server.js               . 2   ,     -           : http://localhost:8080/colorTracking.      " ,                         %       . *   !,         . /                         "    . Освещение для распознавания цвета          $  ,         .  %          colorThreshold    ,                        ,        (  . 9.3). >%          ,                "  . =        $  :
Идентификация 447 Рис. 9.3. Распознавание цвета скетчем на p5.js. Пороговое значение равно (слева направо): 10, 32 и 47. Чем выше пороговое значение, тем больше он показывает совпадений пикселов нецелевого цвета ?                     DayGlo6,  "           ,                $    $ ; ?          ,       , —             ,         "  . *  ,  %             35-     (     "  ),        ,       . /         ,               . ;   %              ,             ; ?        %             ,         . `             ,            .  ,              —  $  %     .   Texas Advanced Optoelectronic Solutions (www.taosinc.com) 6 # .   . Day + Glow —     (    ,   ,     ),    "         " .          ,   TAOS TCS34725,          Adafruit. /      ,          ,          ,  ,      . Распознавание форм и образов 2                         ,            . '            ,                    .        « »     . & ,   «»     , — $   $.   ,                     -    .    « »     —                        . 0    "     ,   ,                  ,              "      ,  $      .
Глава 9 448 Проблемы с идентификацией физических маркеров       ,  =  >% (Durrell Bishop)  1992 . (vimeo. com/19930744),                ,  "        .       "        %        .     %  " ,  " %        .  %    "     "   ,   "  "    ,          .               "  ,               . >%          ,                ,   " " : &    !           (     !       )          ,         !       !   . 4    #        #      ,         . ]     , %        ,            ,     !        . >   Apple       '   >%,  !         *  ,  !#    . 4!,   '  ,   % !   Interval Research,   !           !    Dallas Semiconductor. '  Z  ,    & %     ,    ,          ,        ,  "              . 0              . '  % , >%             ,  $      ,     ,     .    ,        %        . 4   ,   ,            ,      "        ,        "       .   ,              ,          . Обнаружение лиц 4          ,    -            ,   , $    "            . &   ,           ,                     . 0     —  %          . *%                 ,   "       % , "  "    . &    , % $        %     %  ,                 -             ,                     ,    . Q         !     —                       ,          ,      ,       -     " . # "          %       .
Идентификация 449 Проект 22 Обнаружение лиц с помощью веб-камеры Теперь, когда мы располагаем основными сведениями в области оптического обнаружения объектов, настало время попробовать определение простых образов. В этом проекте мы воспользуемся методами обнаружения лиц для нахождения лица в захваченном камерой изображении. =       JavaScript "     ,      $  %   "    . *            ,  "    , "     . &    ,           ,        ,            . 0      ,       "         ,       ,        . >  tracking.js       "          : ?        ; ? ; ? . # "                 .    ,       . =      public    CameraProjects          faceRecognition. #    $     ,      p5.js. 2     -   https://trackingjs. com     tracking.js,   - Требуемые компоненты      -  .     _.          build   libraries    faceRecogntion. /        tracking. js  tracking-min.js,    data,  "        ,   . 2       index.html    faceRecognition       <script>       " : <script src="libraries/tracking-min. js"></script> <script src="libraries/data/face-min. js"></script> =               eye-min.js  mouthmin.js. #   $  ,    ,         sketch.js       " . Пишем код    ,     setup()          . 2           canvas     tracker  $         .      setup()       "    . =   $  ObjectTracker   tracking  "   setInitialScale(), setStepSize()  setEdgesDensity()       . &    $              . 7    $     ,       $ .
Глава 9 450       .             $    ,                   - * ,   setup()        ,            : [  draw()     ,                  showTracks().              ,               event.data. 2    for    $              : /*     #   '    : P5.js */ tracking.js var canvas; //    - var tracker; //    R$     tracking function setup() { //   $- $    var video = createCapture(VIDEO); // M  //     video.size(400, 300); //  $  $- // $  video.position(0, 0); //    $    canvas = createCanvas(400, 300); // ^ - // - $  canvas.position(0,0); //    - // ^  #     tracker = new tracking.ObjectTracker('face'); tracker.setInitialScale(4); //       tracker.setStepSize(2); tracker.setEdgesDensity(0.1); tracking.track(video.elt, tracker); // \  $  tracker.on('track', showTracks); // +$ % # ' //  $  -    ellipseMode(CORNER); //    ,     } function draw() { // ^    } // # % # draw() function showTracks(event) { clear(); var faces = event.data; for (f in faces) { fill(0xFF, 0x00, 0x84, 0x3F); //    $ # noStroke(); //    $  # ellipse(faces[f].x, faces[f].y, faces[f].width, faces[f].height); } } 2               —  %             .       $             (  . 9.4).     ,             (  . 9.4, ),     (  . 9.4, ). #    %            (  . 9.4, ). 0       
Идентификация 451 а б в г Рис. 9.4. Результаты исполнения скетча для обнаружения лиц                . 3  %  —  " ,   _%     , —    " (  . 9.4, ),   ,     ,    . >  tracking.js          ,                 -   . Распознавание штрихкодов :  — $                ,          -    .     % ,                    %  ,        . #          "
Глава 9 452   ,  %            .           %      ,       %    "  ,  "    . #      ,                      ,                "    ,               . *          %  UPC7                       . &  ,   , "             %         ,    %     . *  ,   #3         POSTNET      . #   EAN8  JAN9      %      UPC        "         .              %  ,            , $   %  %     ,  , POSTNET "         EAN. /   ,              %    ,           ,      ,           ,        "              . =     %           ,      %  %            .   ,      . 9.5,      ,               . #"     %  ,    ,           ,         .          ,             . *  . 9.6    %  —  QR. /       `                    ,       %              . &    ,                          — ,   ,           WeChat. &  "        p5.js         QR "   JavaScript. Рис. 9.5. Одномерный штрихкод (здесь приведен штрихкод ISBN10 этой книги11) 9 789781 680458 Рис. 9.6. Двумерная метка штрихкода (QR-кода, если быть более точным) с ограничивающими пометками по углам. Эти пометки игнорируются обработчиками изображения, но помогают пользователям центрировать метку для более качественного ее захвата 7 UPS, Universal Product Code —     . 8 EAN, European Article Numbering —     . 9 JAN, Japanese Article Numbering —    . 10 11 ISBN, International Standard Book Number —       . +           .
Идентификация 453 Проект «Backslash»12 от Педро Оливейра (Pedro Oliveira) и Суеди Чен (Xuedi Chen) 9     «Backslash»                       ,       QR-,  "         . =      0                  . *  ,   "     , —           www.backslah.cc.   + +  (Roy Rochlin) Проект 23 Распознавание двумерных штрихкодов с помощью веб-камеры В этом проекте мы с помощью онлайнового генератора QR-кодов сгенерируем несколько двумерных штрихкодов, а затем расшифруем их, используя камеру и браузер. Когда наш скетч заработает должным образом, в качестве домашнего задания вы можете расшифровать рисунки этой книги, содержащие коды QR. Требуемые компоненты      -  .      QR. 12 Backslash —         «    ».          QR- "  ,            . # "             "    % "   , $         
Глава 9 454         . *          ,       QR-     $   .   ,  +               QR.      $        %         ,      .  ,    https://webqr.com/create.html       ,    QR  URL,             . +      $  ,    %        ,   %          . #              %    . =      public    CameraProjects          qrCodeReader. #    $     ,      p5.js. 2     -   https://github. com/IagoLast/qrcodejs     qrCodeJS,           qrcode.js   dist   libraries   qrCodeReader. 2       index.html    qrCodeReader       <script>       " : <script src="libraries/qrcode.js"></script> #   $  ,    ,         sketch.js       " . Пишем код q    $     $    qrReader       JSON    . *                %     %    QR,           : [  setup()  $     $        "   . &    ,     ,                    $  . ;         ,     qrReader   "   . 2    $     qrReader,         : /* ’   QR  : p5.js $   $  HTML5 */ var video; // "  $-   var message; // Z    QR var qrReader; // ‰$        QR var config = { // %  #  "     QR sucessCallback: getMessage, // +$   //   QR errorCallback: onError, // +$      //  QR videoSelector: ‘video’, // \  - stopOnRead: false //     //     } function setup() { video = createCapture(VIDEO); // M    //   video.size(400, 300); //  $  $- // $  video.position(0, 0); //    $  //   var canvas = createCanvas(400, 300); // ^ - // - $  canvas.position(0,0); //    - canvas.elt.id = "video"; //     R  - qrReader = new QrReader(config); // Z$  R$  //   qrReader }
Идентификация [  draw()    $          "   . 4   %       QR,     "    : 455 function draw() { image(video,0,0); // + $   R video.loadPixels(); //     $  //    fill(255); text("read: " + message, 10, height - 20); } // # % # draw() function getMessage(result) { // †      //  QR, message = result; //       ' message } function onError(err) { // +        console.error(err); //     R }      $        ,                 . /      ,           ,       ,    %. / %                               ,    "        - . &  , $ %          ,              "         %           QR. *   %     % ,                 ,                   . *          %,          ,       . 2                 —   "             ( .  . 9.6).     $             ,                  ,          . ;    %            ,      %     "   . 0         "               — %      . & "   %      % ,      %  ,        . * $      $    . 4   -           ,      %      ,     ,  $           . X%      %     ,                 ,       $,    "      . & $  %      RFID  NFC            QR      % .
Глава 9 456 Радиочастотная идентификация (RFID) и ближняя бесконтактная связь (NFC) Подобно системам распознавания штрихкодов, система RFID предусматривает наличие на объектах меток, обеспечивающих их идентификацию. Но, в отличие от меток штрихкодов, метки RFID, чтобы их можно было считывать, не обязательно должны быть на виду. Считыватель RFID излучает радиосигнал ближнего действия, который принимается меткой RFID, передающей в ответ короткую строку данных. В зависимости от размера и чувствительности антенны считывателя и мощности сигнала, метка может находиться на расстоянии до метра от считывателя, помещена внутри книги, ящика, коробки, предмета одежды и, тем не менее, быть доступной для считывания. ;  ,             , "       RFID:      . 4     RFID              $     %  . >     ,    ,             . / $                  —  -  ,           . #   , %         RFID                        (  . 9.7). >    %                ,                   %    $   . Рис. 9.7. Фотография электромагнитного поля считывателя RFID, снятая Тимо Арналом (Timo Arnall), демонстрирует радиус действия и форму электромагнитного поля типичного пассивного считывателя RFID. Как можно видеть, это всего лишь несколько сантиметров
Идентификация &      RFID                   ,                   . 3        %   ,     ,      %. *         . 4                      $               ,  ,   ,      RFID. X        E-ZPass13      RFID,                . 7        ,      RFID     , 13 E-ZPass —    $                ,     %     ,        -     #3,    % #          % +  . 457              ,  $ . 0     ,      RFID              ,       . 3   $         RFID                 . & ,        , — $ ,             .        . 9.8,   RFID        :  ,   ,  ,    ,     ,         .  ,                 %          ,               .        ,     RFID          ,       $   "  , — Рис. 9.8. Все эти предметы различных цветов и форм оснащены метками RFID. Фотография Тимо Арнала. Дополнительную информацию по исследованиям Тимо Арнала и его коллег в области дизайна RFID можно найти на веб-сайте www.elasticspace.com
Глава 9 458      ,  "        . /   ,    RFID         ,    ,  "     %                  . Имплантация капсул RFID >%    RFID                (  )                .   ,            . $               RFID. *    $       %  ,     $      . 3             RFID,             RFID- . &    RFID             .            ,     ,            —     : 125  134,2 q,      : 13,56 7q. '   %  ,   %          .           ,    RFID           RFID.      RFID    ,           , 7            ISO14. #"        ISO,  "        RFID. 0   $         ,   —         . . /                —   : I-Code, Mifare  Mifare UL    Philips, Tag-IT HF  Picotag    Texas Instruments, SR176    ST Microelectronics   . #   ,  ,   -     14 ISO, International Standards Organization.         . > ,       ,                    . '            ,            ,       . *                       . *  . 9.9          NFC,               . Пояснение • NDEF (NFC Data Exchange Format) —            . • SNEP (Simple NDEF Exchange Protocol) —          NDEF. #     RFID       %    .                         .             %  —      ,                 ,         . &  ,                     $30    %  . #                     . *                     . *  ,   ID Innovations           125 q          ,        EM Microelectronics    EM4001. # $            Parallax. #    ID Innovations     "            SparkFun. ~ $         ,      
Идентификация 459  "               (              "    ) —           ,             NFC. $,             ,    ,          ,   $        ,       . >         ? +       ? 2                           . *            ? 4       %,                 . 0                 ,         " "  ,     , -           . ;    %            %   ,          134,2 q,            . Ближняя бесконтактная связь (NFC) #     ISO 14443        ,  "                -   "          , %                   .     ,   ,       $             "      .   ISO 14443         ,       ,              NFC, Рис. 9.9. Стек протоколов NFC. Эта схема должна дать вам представление о множестве разных протоколов, лежащих в основе типичного приложения RFID или NFC. Стеки протоколов позволяют достичь определенного уровня взаимодействия продуктов разных производителей, а разработчикам приложений нужно беспокоиться только о работе своих приложений с верхними уровнями стека. Схема выполнена на основе материала из книги «Beginning NFC» («NFC для начинающих») Тома Иго, Дона Коулмана (Don Coleman) и Брайана Джепсона (Brian Jepson), издательство O’Reilly, 2014 г. Пользовательское приложение Пользовательский интерфейс Сообщение NDEF Формат сообщений Записи NDEF Формат записей FeLiCa DesFire Logical Link Control Protocol (LLCP) УАПП Mifare Mifare Ultralight Classic ISO-14443A ISO-18092 Протокол SNEP Командные протоколы ISO-14443-3 Спецификация пакетирования данных ISO-14443-2 Спецификация радиосвязи (13,56 МГц) Считыватели NFC (IPN532, SCL3711 и т. п.) Радиоконтроллеры Интерфейс SPI I2C USB ЦП (Arduino, Raspberry Pi, мобильное устройство и т. п.) Связь между устройствами ПК. Встроенная система. Микроконтроллер Программное обеспечение Связь между устройствами и метками или между устройствами Аппаратное обеспечение
Глава 9 460  % "     RFID. /                   RFID,                                ,        RFID.        "  ,   NFC          .      NFC   NDEF       ,      ,   -  (URL)     . *  ,    NFC       URL,   ,      ,  "   -    NFC   -  ,        $  .  &    "            ,   NFC. *        $       —   Identiv, Adafruit  Seeed Studio. 0   %      %   ,         NFC. >          NFC       «Beginning NFC» («NFC   "») ; +, =    (Don Coleman)  >    =    (Brian Jepson),    O’Reilly, 2014 . Проект 24 Чтение меток RFID В этом проекте мы установим программные средства для управления считывателями NFC и прочитаем несколько меток RFID, чтобы получить представление о работе считывателей. Кроме того, мы считаем с метки уникальный идентификационный номер и посмотрим, с какого расстояния он может быть считан. Это хорошая отправная точка для любого проекта, оснащаемого возможностями RFID и NFC. ~      NFC,    ,  $           RFID. $                  NFC,      %             . +  ,      RFID,  "    NFC. RFID-  Mifare Classic  Mifare Ultralight   Philips, %         "      ,       ISO 14443.     Philips        ,       NFC,    Mifare             ,      NFC. #    -  SCL3711   Identiv       RFID    Mifare Classic,      , Требуемые компоненты  #    -  SCL3711 USB Smart Card Reader   Identiv.  7  RFID Classic   Mifare.  0   Raspberry Pi.    NFC,            USB. 0           ,  "    USB, —                Raspberry Pi. '      Raspberry Pi,    "                       . $ %   $     "     Raspberry Pi       RFID  NFC. &  ,      $     ,           "   .
Идентификация 461 Установка программных средств      $   ,    ,   %  Raspberry Pi                   Linux ( . !. «Q    Raspberry Pi»   1). 9                          POSIX,  OS X  Apple  Linux Ubuntu,     Beagle Bone      Debian, ,   ,       . ;   ,  %                  ,           %                  Raspberry Pi. +,      Raspberry Pi      "             ssh,        $      1. 4       Raspberry Pi,      ,  "             . &     ,         . &    ,      "  : ? libnfc-dev —          NFC; ? libfreefare —             RFID    Mifare. >      "     Raspbian             apt-get. 7         npm       node.js. #   apt-get       ,      %         ,   node.js.            ,   apt-get   "    ,          . = $   Raspberry Pi  +        "  : $ sudo apt-get update /         "   (  )  Raspbian      . 0       ,        $            "  .   %         $     "  : Reading package lists... Done (      ... š) ;               . #          libnfc —      : $ sudo apt-get install libnfc-dev libnfc-bin libnfc-examples    $    $          "  ,         apt-get        ,    ,   ,                %     .   %         libnfc                         libfreefare: $ sudo apt-get install libfreefaredev libfreefare-bin 2 %       ,             . >  ,         % ,               NFC.  -        NFC (  . 9.10)      : $ nfc-list * $   :      " nfc-list uses libnfc 1.7.1 NFC device: SCM Micro / SCL3711NFC&RW opened ;          ,            NFC.
Глава 9 462 DSI (DISPLAY) USB 2x USB 2x GPIO SCL3711 NFC reader http://www.raspberrypi.org Audio ETHERNET Power CSI (CAMERA) HDMI        libnfc  libfreefare                    ,        ,         . =      $       : Рис. 9.10. Подключение считывателя NFC SCL3711 компании Identiv к Raspberry Pi ? mifare-desfire-access; ? mifare-desfire-create-ndef; ? mifare-desfire-ev1-configure-ats; ? mifare-desfire-ev1-configure-default-key; ? mifare-desfire-ev1-configure-random-uid; ? nfc-anticol; ? mifare-desfire-format; ? nfc-dep-initiator; ? mifare-desfire-info; ? nfc-dep-target; ? mifare-desfire-read-ndef; ? nfc-emulate-forum-tag2; ? mifare-desfire-write-ndef; ? nfc-emulate-forum-tag4; ? mifare-ultralight-info. ? nfc-emulate-tag; ? nfc-emulate-uid; ? nfc-list; '        -  $    ,     ,  "          -h. *  : ? nfc-mfclassic; ? nfc-mfsetuid; ? nfc-mfultralight; ? nfc-poll; ? nfc-read-forum-tag3; ? nfc-relay; ? nfc-relay-picc; ? nfc-scan-device; ? mifare-classic-format; ? mifare-classic-read-ndef; ? mifare-classic-write-ndef; $ nfc-mfclassic -h Чтение меток +        ,      libnfc  libfreefare,             RFID  NFC    Mifare. =        ,    $     nfc-poll: $ nfc-poll #    " :       -
Идентификация nfc-poll uses libnfc libnfc-1.7.1-150gbf31594 NFC reader: SCM Micro / SCL3711-NFC&RW opened NFC device will poll during 30000 ms (20 pollings of 300 ms for 5 modulations) 2              .                " "  : ISO/IEC 14443A (106 kbps) target: ATQA (SENS_RES): 00 44 UID (NFCID1): 04 8e 41 62 b7 20 80 SAK (SEL_RES): 08 nfc_initiator_target_is_present: Target Released (#_  # _nfc__  : $   #'  ) Waiting for card removing...done.       .... * UID — $          (Unique ID)   RFID  %       . =       RFID — $     ,            . &      RFID  UID        ,        ,                  . 4   $ $ %       ,     "         —        ,          . *   %     —  % , $        . ;        ,             %      , —       "            RFID  NFC. ~    RFID   %              ,   %       $   . 463 Формат NDEF *         RFID,              $    —         . *     NFC          %   ,           UID. /     " %     NFC —   NDEF. #   NDEF RFID  NFC      "  : ? RFID —      UID;    ? NFC —          %    ; ? NDEF —     "        NFC   . [  NDEF     -    "         ,   SD             %  . ~                ,             %       . >  $                    SD   %,               .            %  ,   NFC          . =                 ,    NDEF     "   ,      . 0    "     ,              . _     NDEF   #   $   ,   "         !  NDEF      . *          ,   URI,  "   - ,    MIME  ,       
Глава 9 464  . #"          ,       . & %                  URI. #  NFC          NFC: ? 7 1 —      ISO14443.     $ : Topaz   Innovision  BCM20203   Broadcom; ? 7 2 —        Mifare Ultralight (ISO-14443A)   NXP  Philips.     $ : Mifare Ultralight   NXP; ? 7 3 —        FeliCa (ISO-1892  JIS-X-6319-4)   Sony.     $ : FeliCa   Sony. ? 7 4 —        DESFire (ISO-14443A)   NXP.     $ : DESFire  SmartMX-JCOP   NXP. & %           Mifare Classic. /     NFC,             NDEF,          ,   $ . >     NFC       $ ,             Android,  "       NFC. Проект 25 Чтение и запись сообщений NDEF Здесь мы познакомимся с ближней бесконтактной связью (NFC) и форматом NDEF обмена данными для нее и станем с помощью сценариев на node.js записывать и считывать данные с меток. Для этого нам понадобятся сценарии для записи и считывания меток, которые будут работать с интерфейсом командной строки. Требуемые компоненты  #    -  SCL3711 USB Smart Card Reader   Identiv.  7  RFID Classic   Mifare.  0   Raspberry Pi. #              Raspberry Pi             ndefReadWrite. #   $       writeNdef.js. * ,          npm      ndef  mifare-classic: $ npm install ndef mifare-classic     ,   node. js         NDEF    Mifare Classis,               libnfc  libfreefare. /        JavaScript    libnfc  libfreefare,           node.js. &  "      %     "  NDEF,  "       -  (URI).
Идентификация 465 Записываем метку &           ndef  mifare-classic          "  NDEF. /          " : /* =           URI   "       "  . 2             ,             "   ndef. encodeMessage(): var textRecord = ndef.textRecord("+ R "); var uriRecord = ndef.uriRecord("http://www.example.com"); ndefMsg.push(textRecord); // Š  ' $  ndefMsg.push(uriRecord); // Š $  URI var bytes = ndef.encodeMessage(ndefMsg); // $         #         Response()    mifare.write(),      " . /                 %     %    "    . function writeResponse(error){ // • #   //  - # $   if (error) { //      $  , console.log(" : " + error); // $   } else { // +       - // # console.log("Z   $    "); } } * , "       : mifare.write()  "  &       NDEF   "    . #   ,                     :    NDEF : node.js */ var ndef = require('ndef'); // \       ndef var mifare = require('mifare-classic'); // \    //    mifare-classic var ndefMsg = new Array(); // &   -  //   NDEF //       mifare.write(bytes, writeResponse); NDEF file is 38 bytes long. (•  NDEF   38  .) Found Mifare Classic 1k with UID 0a64ef28. (   Mifare Classic  UID 0a64ef28. Tag written successfully (Z   $    ) $ node writeNdef.js * $       "  : ;            . = $      ndefRead.js      ndefReadWrite       " .
Глава 9 466 Считываем метку /      ,     " ,        : /* ’   NDEF : node.js */ var ndef = require('ndef'); // \       ndef var mifare = require('mifare-classic'); // \    //    mifare-classic     mifare. write(),   "    mifare.read()          ,     listTag(). [       "  ,            JSON,          data,            .      ,     "  ,     . &  for    $    ,    $    : * ,           .X  %            listTag(): // • #   $       function listTag(error, buffer) { if (error) { // +      , console.log("   : " + error); // $ //   } else { //      var bytes = buffer.toJSON(); // $ //    " JSON if (bytes.hasOwnProperty('data')) { // †   // " JSON     data, bytes = bytes.data; // $  } var message = ndef.decodeMessage(bytes);// Š   //   for (record in message) { // -  #  //  R   , console.log(message[record].value); //   // $   $  } } } mifare.read(listTag); // Z   mifare.read()  #         ,           ,    : $ node readNdef.js                   " "  : Here's a string (+ R ) http://www.example.com Использование записей NDEF      "          ,                 . &   NDEF -            (   232–1  ). +   "            "               $    IP- . &            ,           . *  ,      -                Android,         Mifare Classic,                -   ,         . 7                    # ,     %         .
Идентификация 467 ;  ,           node.js            "  NDEF,  %   "        ,     $       ,   Arduino. Проект 26 NFC и бытовая автоматизация В нашем с напарником офисе находятся десятки потребляющих электроэнергию устройств: несколько компьютеров, два монитора, четыре или пять ламп освещения, несколько жестких дисков, паяльник, хабы сети Ethernet, динамики и т. п. Даже в наше отсутствие эти устройства потребляют много электроэнергии. Какие устройства включены в определенный момент времени, зависит от того, кто из нас находится в офисе, и что мы делаем. Этот проект представляет собой систему, направленную на уменьшение энергопотребления нашего офиса, особенно когда нас в нем нет. Когда мы заходим в офис, нам достаточно дотронуться брелком с NFC-меткой на кольце для ключей до панели возле двери, и система включит устройства, которые мы обычно используем. Каждый из нас имеет соответствующий брелок, а под панелью смонтирован модуль со считывателем NFC, который считывает поднесенные к нему метки. #   NFC        ,      WiFi     $     .            WeMo (   )   Belkin,      $           . &         ,       ,   $     . q   -          . 9.11. /              WeMo,        ,        . Считыватель RFID Интерфейс SPI Требуемые компоненты  >       , 1 %.   Arduino MKR1000  WINC1500, 1 %. &               ESP8266. +       :    SPI  I2C, Wi-Fi.  7 NFC-    PN532, 1 %.  7  RFID Mifare Classic, 2 %.  7   WeMo   Belkin, 2 %. Рис. 9.11. Управляемая посредством NFC система автоматического включения/выключения электроприборов на основе модулей WeMo Беспроводной канал Wi-Fi передачи сообщений HTTP Микроконтроллер Беспроводной канал Wi-Fi передачи сообщений HTTP Модуль WeMo Модуль WeMo
Глава 9 468 Схема системы    $            WeMo  Wi-Fi,       Wi-Fi. +             Arduino-     MKR1000  WINC1500,         ESP8266. &           NFC      PN532   NXP Semiconductors.   ,           $     . 0          PN 532 NFC/RFID   Adafruit,  % NFC  % NFC  Arduino   Seeed Studio          $   . &  ,  Grove NFC  Seeed Studio    . #    , $            PN532,  "    SPI  I2C. 7    PN532  "      I2C, SPI        X3,  %    $         , "              . &    ,   . 9.12        Adafruit            SPI. ;          :       ,          . Протоколы связи *         "  NDEF,  "    : ~   Belkin      "       API    WeMo,               "  -   If This Then That (https://ifttt.com),                   HTTP. ~ %   ,      WeMo      HTTP,   #       ,  $  .   Belkin                   ,      $   "-  . 9   WeMo                   ,           % . ;         WeMo      Android  iOS. X      ,    IP   WeMo. = $    |         15 ]   &  | D         |   WeMo,     %  IP-   .    WeMo       uPnP16,   SOAP17 —      XML        , " "   HTTP  SMTP. *    ,       ,      "     SOAP,     %     . *          HTTP,    "  SOAP           ,     ArduinoHttpClient.   $                4. 15 ? ? ?   ;   WeMo,    ; IP-  WeMo.  $         $ "   ,       HTTP          "   WeMo. &            ,            ,  "        . 16 uPnP, Universal Plug & Play —        PnP,          $     $             ,        (      ,  ,    ,  "   ),         . 17 SOAP, Simple Object Access Protocol —          .
Идентификация 469 Vcc Модуль MISO* микроконтроллера MOSI** D4 SCK*** D5 D11 Общий («земля») MISO* Перемычка SEL0: снята MOSI** Модуль NFC PN532 SCK*** SSEL К +U Перемычка SEL1: установлена 5V Общий («земля») 220 Ом 220 Ом *MISO (вход ведущего, выход ведомого) **MOSI (выход ведущего, вход ведомого) ***SCK (тактирование) Примечание & $            NFC        SPI. 7             SPI        Wi-Fi.  % SPI            ,                   .  MKR1000      7        Wi-Fi, $        NFC     11. 0      ,  $         10 —             Arduino Uno.     ,                  I2C. +    $           .   $             "  . A B C D E F G H I J 1 1 5 5 10 10 15 15 20 20 AUX1 P30 AUX2 P31 P32 P33 P34 P35 SIGOUT GND SIGIN RSTPD_N POWER PN532 Breakout Board 3.3V SCK MISO MOSI/SDA/TX 25 25 SSEL/SCL/RX RSTOUT_N I2C ON OFF IRQ GND R1 C15 RXD ON NC OFF OFF TXD OFF SPI 5.0V UART GND SEL1 NC SEL0 5.0V 30 OFF OFF SEL0 SEL1 ON ON 30 A B C D E F G H I J FTDICABLE Рис. 9.12. Принципиальная (вверху) и монтажная (внизу) схемы подключения микроконтроллера к модулю считывателя NFC. Здесь показана микроконтроллерная плата MKR1000. Для других микроконтроллерных плат, возможно, потребуется использовать другие выводы. При этом необходимо, чтобы подключения интерфейса SPI совпадали. Также следует обеспечить подключение шины «земли» на левой стороне макетной платы к общему выводу питания под модулем считывателя NFC
Глава 9 470 0   "        "  : <?xml version="1.0" encoding="utf-8"?> <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> <s:Body> <u:SetBinaryState xmlns:u="urn:Belkin:service:basicevent:1"> <BinaryState>1</BinaryState></u:SetBinaryState> </s:Body> </s:Envelope>     ,     HTML,   XML       ,  $   XML     (Envelope)    (Body) " . &   "     BinaryState          1  0,        . #"         POST,   HTTP        : Content-type: text/xml; charset=utf-8 SOAPACTION: "urn:Belkin:service:basic event:1#SetBinaryState" Connection: keep-alive Content-Length: 230 =      HTTP               ArduinoHttpClient. =       WeMo         URL- : /upnp/control/basiceventl. 7     $   %     HTTP. X    WeMo     49153. Установка библиотек = $          :   NDEF  Arduino  =    (Don Coleman)    PN532    #  (Yihui Xiong). +        https:// github.com/don/NDEF  https://github.com/ Seeed-Studio/PN532    . >  NDEF          - "    NDEF         PN532        . *      $          7    Arduino, $               "  . 2       ,    ,      Arduino,             D  |  >      | !  .ZIP             . =   NDEF      ,        . 3    PN532             : PN532_I2C, PN532_SPI  PN532_HSU (          SPI).     %          \ |           . &  ,  $        %   NDEF. =       Arduino    "  NDEF    RFID,          .
Идентификация 471 Записываем сообщение на метку 2          "  NDEF. /     "     node.js    "    ,      $        Arduino. &             SPI     NFC: /* &   setup()                : void setup() { Serial.begin(9600); // \ #  $    ' // $ nfc.begin(); // \ #  $   $ NFC } &   loop()             .         "  NDEF,      ,        "             : void loop() { Serial.println("$   %   '  Mifare Classic   ."); if (nfc.tagPresent()) { NdefMessage message = NdefMessage(); message.addTextRecord("Tom Igoe); //      //  $ message.addTextRecord("1"); //       //    WeMo message.addTextRecord("192.168.0.17); //     // IP-    WeMo if (nfc.write(message)) { Serial.println("     ."); } else { Serial.println("  $    ."); } }      3        : Serial.println(); // +   '   #   delay(3000); // Š $'  ,    }        ,      ,            NDEF  : Arduino Arduino */ #include <SPI.h> // '    SPI #include <PN532_SPI.h> // '    SPI  PN532 #include <PN532.h> // '    PN532 #include <NfcAdapter.h> // '    NFC PN532_SPI pn532spi(SPI, 11); // \ #  $    NfcAdapter nfc = NfcAdapter(pn532spi); &        "  NDEF    RFID. Считываем метку #          ,     ,         "  NDEF. ;  ,      ,         /* ’   NDEF  : Arduino Arduino */ #include <SPI.h> // '    SPI
Глава 9 472     . =         tagLed          ,      ,   "          : #include <PN532_SPI.h> // '    SPI  PN532 #include <PN532.h> // '    PN532 #include <NfcAdapter.h> // '    NFC PN532_SPI pn532spi(SPI, 11); // \ #  $    NfcAdapter nfc = NfcAdapter(pn532spi); const int tagLed = 5; // +      //  #     [  setup()   ,      "   ,                      : void setup() { Serial.begin(9600); // \ #  $    ' // $ nfc.begin(); // \ #   $ NFC pinMode(tagLed, OUTPUT); //  -   //      } &   loop()    "          ,            . 4      "  NDEF,       : void loop() { if (nfc.tagPresent()) { digitalWrite(tagLed, HIGH); NfcTag tag = nfc.read(); if (tag.hasNdefMessage()) { &  for     " ,    . +                 "   ,    "      ,               . =                WeMo: for (int r = 0; r < recordCount; r++) { NdefRecord record = message.getRecord(r); //   $  int payloadLength = record.getPayloadLength(); //   $  $  $ byte payload[payloadLength]; // &   //      $  $ record.getPayload(payload); //   $ ' //  $ String payloadString; //     ' // payloadString for (int c = 3; c < payloadLength; c++) { //   //  ,      3 payloadString += (char)payload[c]; //    //    ' payloadString } Serial.println(payloadString); // +   // payloadString  R } // # #  for     $  } // #   if tag.hasMessage() } // #   if tag.Present() *           ,        : digitalWrite(tagLed, LOW); // M$ ,   //    delay(3000); // Š $'     } // Z   NFC // M$      //      // †    //  , NdefMessage message = tag.getNdefMessage(); //   //   int recordCount = message.getRecordCount(); //   //   $ 
Идентификация 473 ' ,       NFC        . 0   ,                      Arduino   "  ,           ,      $   " Arduino.                                  ,      . ;  ,          ,          HTTP     WeMo.   -    ,            . 3     Усовершенствуем код считывателя &     %               Wi-Fi        WeMo   HTTP     NDEF. 7       WiFi101,        "    Wi-Fi.            config.h        (SSID)       : /* *               :     ,      ,   "   Wi-Fi,  $     Wi-Fi,    ,   ,           WeMo,    ,   IP-      "   WeMo.   ,       SOAP      . =         ,                ,       (\)      : PN532_SPI pn532spi(SPI, 11); // \ #  $    NfcAdapter nfc = NfcAdapter(pn532spi); const int tagLed = 5; // +    //    #     const int wifiLed = 4; //      //       Wi-Fi WiFiClient netSocket; // C       const int port = 49153; // ‡   String route = "/upnp/control/basicevent1"; // $ API boolean wemoStates[] = {0, 0}; // 9    WeMo String username = ""; // ‰     String wemoAddress = ""; // Œ      WeMo int wemoNumber = -1; // ‡      WeMo // 9   SOAP String soap = "<?xml version=\"1.0\" encoding=\"utf-8\"?> \ <s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" \ s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"> \ <s:Body> \ <u:SetBinaryState xmlns:u=\"urn:Belkin:service:basicevent:1\"> \ <BinaryState>1</BinaryState></u:SetBinaryState></s:Body> \ </s:Envelope>"; 7  HTTP NFC    WeMo 7  :Arduino   WIN1500 */ #include <SPI.h> // '    SPI #include <WiFi101.h> // $   WiFi101 //#include <ESP8266WiFi.h> // €    // ESP8266   #  #include <ArduinoHttpClient.h> #include "config.h" #include <PN532_SPI.h> // '    SPI //  PN532 #include <PN532.h> // '    PN532 #include <NfcAdapter.h> // '    NFC
Глава 9 474 &   setup()                     Wi-Fi    ,               Wi-Fi,            Wi-Fi: void setup() { Serial.begin(9600); // \ #  $    ' $ nfc.begin(); // \ #   $ NFC pinMode(tagLed, OUTPUT); //  -   //       #     pinMode(wifiLed, OUTPUT); // %     !  //            Wi-Fi // $       Wi-Fi, while ( WiFi.status() != WL_CONNECTED) { Serial.print("$          : "); Serial.println(ssid); //    #     (SSID) WiFi.begin(ssid, password); //         delay(2000); } // $ %    Wi-Fi,   "       :   ,    #    //   : IPAddress ip = WiFi.localIP(); Serial.print("IP- : "); Serial.println(ip); } =    %         loop()     ,  %    . &  %         copyRecords() (          )        "       "    . 4"                   Wi-Fi       "                  Wi-Fi: =       copyRecords(),        setup(). [                         "           "    .       ,      IP- ,        wemoRequest()(        ),       POST: void loop() { // ... %         setup() Serial.println(payloadString); // + //   payloadString  R copyRecords(r, payloadString); } // # #  for     $  } // #   if tag.hasMessage() } // #   if tag.Present() digitalWrite(tagLed, LOW); // M$ ,   //    if (WiFi.status() == WL_CONNECTED) { // `  //     Wi-Fi digitalWrite(wifiLed, HIGH); } else { digitalWrite(wifiLed, HIGH); } delay(3000); // Š $'     } void copyRecords(int recordNum, String recordString) { switch (recordNum) { // N  !    // -   case 0: // %     ;     break; case 1: // %     WeMo; $   //     wemoNumber = recordString.toInt(); break; case 2: // %  IP-  ; N  wemoAddress = recordString; // *  IP- , wemoRequest(wemoNumber, wemoAddress); //    //  break; } // 7    case }
Идентификация 475 0      wemoRequest(),        case 2. [            WeMo,            SOAP  "  ,    $   String. replace(). ;         " ,           : void wemoRequest( int thisWemo, String wemo) { if (wemoStates[thisWemo] == 0) { // *  WeMo   , soap.replace(">0<", ">1<"); //   } else { //     soap.replace(">1<", ">0<"); //    } wemoStates[thisWemo] = !wemoStates[thisWemo]; //   //       wemoState  !  =     POST HTTP,       ArduinoHttpClient,   $      4  5.         ,         ,     beginRequest() —       endRequest() —   %  . ;     POST     "  endRequest()   http.println().           $,      POST     "    HttpClient http(netSocket, wemo.c_str(), port); // 9 //   HTTP http.connectionKeepAlive(); // ` !   //      http.beginRequest(); // ‡    http.post(route); // %  // € : http.sendHeader("Content-type", "text/xml; charset=utf-8"); String soapAction = "\"urn:Belkin:service:basicevent: 1#SetBinaryState\""; http.sendHeader("SOAPACTION", soapAction); http.sendHeader("Connection: keep-alive"); http.sendHeader("Content-Length", soap.length()); http.endRequest(); // 7   http.println(soap); // €    Serial.println("%  "); Stream: /      $      WeMo: while (http.connected()) { // $     , if (http.available()) { //          String result = http.readString(); //    Serial.println(result); //     # } } }         "   $  ,    NFC       ,          .   ,       ,          , "          . /       . 0   ,                ,                    ,            "         .  , $  ,           "       .   $               ,
Глава 9 476    , —            . #    %  $    —            ,              ,          (  . 9.13). / %    %              . Рис. 9.13. При установке считывателя на двери пользователь вынужден убрать метку после того, как он проведет ее по считывателю. Таким образом решается проблема невозможности считывания больше чем одной метки за раз &     ,   WeMo       ,       HTTP. /      ,     WeMo                ,  —         —    " ,         . +       loop()      "  %     . &       ,  "       ,             ,                     ,      . Конструкция    $                 -     5. > ,         %, % %    .   ,       —   ,                 $     . 9     Adafruit,      "        ,   ,           , $                ,       . 9.12. *  . 9.14  9.15         ,    . 9.13          . Рис. 9.14. Корпус проекта считывателя NFC в процессе сборки. Требуется, чтобы антенна считывателя находилась в верхней части корпуса, что вызывает необходимость двухуровневой конструкции с размещением микроконтроллера на нижнем уровне. Этого можно достичь, используя стойки разной высоты Рис. 9.15. Корпус проекта считывателя NFC в развернутом виде. Модуль считывателя и светодиоды подключены к микроконтроллерной плате с помощью монтажных проводов и прямоугольных штыревых разъемов
Идентификация 477 Безопасность устройств сетевой связи Физические идентификационные данные во все возрастающей мере связаны с сетевыми данными, а сетевые данные во все возрастающей мере становятся уязвимыми к атакам. Поэтому все должны быть осведомлены об основных методах защиты идентификационных данных, как своих персональных, так и своих устройств.             %      ,      +    %           , ,   %         "  $      ,          %      . =                  %       . Не выходите за пределы локальной сети 0 "       %                  . X   ,  " %   IP-   ,   +  ,        .   $                . *        "       ,         %        "    ? &        . ;   $     ,     -    ,        ,            %     % . 4                  ,    $    ,   % ? 4        ,      %   ,           . Применяйте двухфакторную аутентификацию =      ,                         ,            . +  $           . &    ,                         "      Hue   Philips:         ,                      . 3                 %      ,         "  . ;           Google. & $             %  ,  %    —       . 4"      —   ,  iOS           . =                                 NFC       . Используйте HTTPS и криптографию с открытым ключом &   8       HTTPS  ,   "                 (   )     %   "        . ;                        . 9  $     "  . #     :      . =   HTTPS $ $     ,       
Глава 9 478   (     ). 4        %   "  ,    —     % . 4           " ,       ,  %   "        . _ %   "     %  "       ,       %       . *      ,      %   "    ,  "       . #          ,    ,  " $       % %  " ,      %   %  . '           ,              ,          . 0   "   %    "        ,        . /   %        ,        %  "  "      ,       ,  "       ,    — "     ,      ,          . #   -  ,  "    HTTPS,     ,          ,     ,       %  "  ,       $  -  . 3              ,             , "    %  ,   %   " . 7        %    !. «:     »   3,      %   aes-256-cbc        —  %     %     . #    %               " ,    ,        %  . Проект 27 Двухфакторная идентификация с использованием NFC В этом проекте мы создадим систему двухфакторной аутентификации на основе Raspberry Pi и метки NFC. Эту систему можно использовать в любом случае, когда требуется двухфакторная аутентификация, но в здесь мы применим ее для открытия замка. 9      —        —   $      NFC,           —     . 9      "  . '   ,      -   ,          node.js,       NFC    ,    $  . #              %       . &              "     ,            (%      )        ,        (%      ),    %   %          .     ,            %    ,           —   "   % . =  %             . 0   %             ,     ,     %       .
Идентификация 3                     ,  %           "          . /                ,      %               ,       . /        ,  -            .           ,        HTTPS,       18 ( . !. «&!    HTTPS»   8)       -  $  ,        . 3   "        %         . 479 Требуемые компоненты  #    -  SCL3711 USB Smart Card Reader   Identiv.  7  RFID Classic   Mifare.  0   Raspberry Pi.  ;    TIP120.  9    #    1 0. .  +     12 &.        9          5,5    %  — 2,1 .  * %    . Особенности кода   $              NFC  NDEF,        26,        Raspberry Pi. #             ,             "      node. js. +   JavaScript     express  ndef       ,               .               ndefSignature. 9   %          ,               ,    —    . /       ,                     . *                , $          .                        , ,  ,             . +,          $      https-server.js             https-serverwriter.js,    — https-server-reader.js. ;       ,        SSL. =           NDEF,    —     NDEF,          —  GPIO.     ,          -    ,     p5.js.   ,    ,    public                   p5.js  : reader  writer. 2  "      npm     "  : $ npm install express body-parser ndef mifare-classic onoff #   "    : writeNdefSignature.js, readNdefSignature.js  gpioControl.js.     ,              % -
Глава 9 480        . 7       $    SSL      ,    %  -       . *         keys "    openssl  "  : $ openssl genrsa -out keys/private.key 2048 $ openssl rsa -pubout -in keys/private.key -out keys/public.key ;        . Рис. 9.16. Монтажная (внизу) и принципиальная (вверху) схемы подключения считывателя NFC SCL3711 компании Identiv к Raspberry Pi через транзистор TIP120. Рабочее напряжение соленоида 12 В при токе 1 А, поэтому ему требуется отдельный источник питания постоянного тока напряжением 12 В и достаточной мощности. «Минус» (контакт «земля») этого источника питания нужно подключить к контакту «земля» платы Raspberry Pi. Но ни в коем случае не подключайте к Raspberry Pi напряжение +12 В, поскольку это безвозвратно повредит компьютер К плюсу источника питания 12 В Контакты ввода/вывода (GPIO) платы Raspberry Pi Соленоидный замок TIP120 1 кОм GPIO 18 1N4004 1 5 10 15 20 15 20 A B C D E TIP120 F G H I J 1 5 10 DSI (DISPLAY) USB 2x USB 2x GPIO http://www.raspberrypi.org Audio ETHERNET Power CSI (CAMERA) HDMI SCL3711 NFC reader
Идентификация 481 Управление контактами ввода/вывода (GPIO) на Raspberry Pi #  $    (  . 9.16)  %     ,      25  26, —             ,         /  Rapsberry Pi.   $     «  » (  « »)       "  (  « ») Raspberry Pi.              ,        gpioControl.js         Raspberry Pi. /            /  "     (GPIO),    $   onoff  node.js.   GPIO Raspberry Pi (  . 9.17)     "          Arduino —         ,       :            (  X3),    SPI  I2C,     +7.   , Raspberry Pi  "      . 9            3,3 &,       5-   . >  onoff,           "    (         : https://github.com/ fivdi/onoff),            $          ,       $  ,               (     ).            Arduino,   GPIO Raspberry Pi            % "  ,            ,         $   . ;,            % ,  Raspberry Pi     ,               , ,    ,       . Рис. 9.17. «Распиновка» контактов ввода/вывода общего назначения (GPIO) плат Raspberry Pi моделей 2, 3 и Zero 3.3V Power Питание 5 В GPIO 2 (SDA) Питание 5 В GPIO 3 (SCL) «Земля» GPIO 4 (GPCLK0) GPIO 14 (TX) Ground GPIO 15 (RX) GPIO 17 GPIO 18 (PWM0) GPIO 27 «Земля» GPIO 22 GPIO 23 3.3V Power GPIO 24 GPIO 10 (MOSI) «Земля» GPIO 9 (MISO) GPIO 25 GPIO 11 (SCLK) GPIO 8 (CE0) Ground GPIO 7 (CE1) GPIO 0 (ID_SD) GPIO 1 (ID_SC) GPIO 5 «Земля» GPIO 6 GPIO 12 (PWM0) GPIO 13 (PWM1) «Земля» GPIO 19 (MISO) GPIO 16 GPIO 26 GPIO 20 (MOSI) Ground GPIO 21 (SCLK)
Глава 9 482 Код для управления соленоидом         ,       GPIO gpioControl.js              . 2    GPIO 18            ,                 lock. +     $    ,                : /* &    ,            ,    lock         1,       —    0. /        open()  close()    . &   open()         close()     2   ,       : function close() { lock.writeSync(0); //     $  //       } M  GPIO : node.js */ var Gpio = require('onoff').Gpio; // '    // onoff var lock = new Gpio(18, 'out'); // %      //           function open() { lock.writeSync(1); //      //       setTimeout(close, 2000); // +   $  2   //    $ $  } 0    if         -o                        open(). /           %         : // †       if (process.argv[2] === '-o') { open(); }          —     . 2   $        $         . +   $       ,   HTTPS: // ‰    % # R #  //  $    #  module.exports = { close: close, open: open }; ,  - Проверяем работу сценария управления GPIO        gpioControl.js         "  : $ node gpioControl.js -o &     $   Raspberry Pi         18 -      ,             . 4    $    18       ,       . 9.16,       . *               . = $    18  
Идентификация 483     ,        «  ».                2   ,     .           NFC      "    .      $            ,         . X %                18,      $  ,    % - ;  ,         gpioControl.js,                    NDEF. Модули Node.js   node.js                . 7          node.js  $   ,      node.js      . 9         ,       $    ,                              . 7             . '         ,      $    "    require(),   $  ,   .   $          ,     ,           requrie(). *  ,         GPIO       ,    $     "  :        %,              $ ,      %       ,     $       module.exports,   $          GPIO. &  "     module.exports $     "      . &        ,        module.exports,        $             .          ,    node-modules,               . [                 ,               . *  : var lockControl = require('./gpioControl.js'); lockControl.open(); &   "                        . Разработка сценариев записи и чтения меток NDEF Сценарий записи метки ;  ,       ,               . 0     writeNdef-Signature.js       "  . &    ,   ,       : ndef-js, mifare-classic   NDEF,   fs         crypto  %     % "  NDEF: /*   $ %-  NDEF  %   '  ' $ , $      NDEF $     . : node.js */ var ndef = require('ndef'); // '    ndef var mifare = require('mifare-classic'); // ' //    mifare-classic var crypto = require('crypto'); // '    // crypto var fs = require('fs'); // '    %  //    fs
Глава 9 484 =               ,  " % : =                     . ~ $         ,         , $    ,      $          : 0     $    setMessage()           %        NDEF       NFC. /            NDEF   25       %  . [   "     ,         "   mifare.write(): var privKey = fs.readFileSync('keys/private.key'); // Z  //  ' var privateKey = privKey.toString(); // $ //   var secret = null; //    %$, //   % ' // • #     $     %$ function setSecret(data) { secret = data; } // • #           NDEF, // $ %  $ % function setMessage(record, signed) { var ndefRecord; // Z    $  NDEF var ndefMsg = new Array(); // &     NDEF if (signed === true) { // † $    $ %, // $ %  var signer = crypto.createSign('RSA-SHA256'); // Z$ //  % signer.update(record); // Š $  var signature = signer.sign(privateKey, 'hex'); //  % ndefRecord = ndef.textRecord(signature); // Z$ // $  NDEF else { // † $      % ndefRecord = ndef.textRecord(record); // Z$ // $ % ' $  NDEF } ndefMsg.push(ndefRecord); // Š $  //    var bytes = ndef.encodeMessage(ndefMsg); // $ //        return bytes; // +$     } 0      $           setMessage(),         mifare.write(),               . =   mifare.write()           ,          . [      showResponse()    %    $  "     %     %        : // • #   $  % # function showResponse(error){ if (error) { console.log('  ' + error); } else { console.log('M-'); } } write() format()
Идентификация 485 # "            , "     writeNdefSignature.js,  "          . &            "     process.argv[]. 4          -f,            . 3       ,    %   ,      "  ,  " %       ,  %    : // †       ,  if (process.argv[2] != null) { if (process.argv[2] === '-f') { // †   //  % -f, mifare.format(showResponse); // %     } else { // +     setSecret(process.argv[2]); // Œ $    //  ' %$ var response = setMessage(secret, true); // + // $ % '  ' %$    NDEF mifare.write(response, showResponse); //   // $      } }          $     "           . /  %     writeNdefSignature.js: // ‰    % # R #  //  $    #  module.exports = { format: mifare.format, setMessage: setMessage, write: mifare.write };              . 9        Mifare Classic          "  : $ node writeNdefSignature.js -f #          " : Found Mifare Classic 1k with UID 1e6f5ba5. (  Mifare Classic 1k  UID 1e6f5ba5.) Formatting 16 sectors [...4...8...12...16] done. (•    16  [...4...8...12...16] .) success M      ,        . ;   %         . = $     "  : $ node writeNdefSignature.js 'this is my secret phrase' #          " : NDEF file is 522 bytes long. (•  NDEF   522  .) Found Mifare Classic 1k with UID 1e6f5ba5. (  Mifare Classic 1k  UID 1e6f5ba5.) success M  #   %     (   )  %    . 2  , " % , %        ,                     "    .
Глава 9 486 Сценарий чтения метки ;        readNdef  "  . /         %    "  ,       NFC   "    . Signature.js            ,        . *  $         (   )        . 0 $               ,         .   ,  $              %  "  ,              : /* ’  $ %-  NDEF Z      NDEF, $    '  '. : node.js */  % var ndef = require('ndef'); // '    ndef var mifare = require('mifare-classic'); // ' //    mifare-classic var crypto = require('crypto'); // '    // crypto var fs = require('fs'); // '    %  //    fs var pubKey = fs.readFileSync('keys/public.key'); // Z  //  ' var publicKey = pubKey.toString(); // $ ' //   var secret = null; //     '  %$ [  setSecret()   ,        : // • #     $    function setSecret(data) { secret = data; } '     "   "   mifare. read()   . *               . /     "   %             : parseMessage(),         "  NDEF,    : // • #   $    function getMessage(error, buffer) { if (error) { // +      , console.log('  ' + error); //      } else { // +     console.log(parseMessage(buffer)); // + //     } } [  parseMessage()            25. 0      "  NDEF                    NDEF. 2        -$   function parseMessage(buffer) { var result = null; // +$  $  var bytes = buffer.toJSON(); // $  //   " JSON if (bytes.hasOwnProperty('data')) { // †   // " JSON     data, bytes = bytes.data; // $  var message = ndef.decodeMessage(bytes);// Š   //         %$
Идентификация 487 for (r in message) { // -  #   R  //  , var record = message[r].value; //   // $   $  result = verifyRecord(record, secret);//  //      %$ } } else { result = false; // Z  data   , // $ $  false } return result;     for      verifyRecord()                : } [  verifyRecord() "          crypto       ,            ,   "   ,       . +,   ,      %   ,    "    . [        %   ,                ,      ,        %  : function verifyRecord(signature, secret) { var verifier = crypto.createVerify('RSA-SHA256');// Z$ //  % verifier.update(secret); //   % // $ % '  ' %$ //    - $ %   var result = verifier.verify(publicKey, signature, 'hex'); return result; } =               .     "    ,                  "      "   . 2  "   mifare.read(),                    parseMesage()  verifyRecord(),       "  NDEF: // †       ,  if (process.argv[2] != null) { setSecret(process.argv[2]); // Œ $    //  ' %$ mifare.read(getMessage); //       //   } *       ,   , $     "            . /  %     readNdefSignature.js: // ‰    % # R #  //  $    #  module.exports = { setSecret: setSecret, read: mifare.read, parseMessage: parseMessage }
Глава 9 488 '       ,       NFC  ,     "   "    ,        "  : $ node readNdefSignature.js 'this is my secret phrase' #          " : Found Mifare Classic 1k with UID 1e6f5ba5. (  Mifare Classic 1k  UID 1e6f5ba5.) NFC Forum application contains a "NDEF Message TLV". (    NFC Forum   "Z  TLV NDEF".) true (  )     ,          ,                     , %      ,  "   ,       .      "         ,             $   . =        HTTPS,              . 2    $  ,         GPIO,  "    . =      HTTP      :   —     ,    —    . /                          . *                ,        .                        , ,  ,            . Создаем сервер для записи меток 0     https-server-writer.js       " . 2           % . /* Z HTTP/HTTPS  -%   % # +   %    $   : node.js */ #        :   body-parser (         3)              POST. ;        require()     . 0     ,       ,       ,   node_modules,            : // '    "   : var express = require('express'); // '    // express var bodyParser = require('body-parser'); // $ //   body-parser var https = require('https'); // '    HTTPS var http = require('http'); // '    http var fs = require('fs'); // '    %  //    fs // $     var tagWriter = require('./writeNdefSignature.js');
Идентификация     $    ,             SSL,     "   server.use()         HTTP       ,     "   . 4              body-parser,              POST HTTP: &       ,   , %            ,            .        ,        ,    :         ,    %      ,    ,          . '     - , $            : &                ,    . ;                  request. path. #       " "   : .format()  .write(),        writeNdefSignature.js. =               ,  "  %    %      . 7    $   — finishResponse() —               processTag(),                     % : 489 var server = express(); // Z$ R$   var options = { //     HTTPS key: fs.readFileSync('./keys/domain.key'), // ' cert: fs.readFileSync('./keys/domain.crt') //  %  }; server.use('*', httpRedirect); // • #   //   $ http server.use('/',express.static('public')); //  // ,     %  server.use(bodyParser.urlencoded({extended: true})); // N        function httpRedirect(request,response, next) { if (!request.secure) { console.log('  $ http  $   $ https'); response.redirect('https://' + request.hostname + request.url); } else { next(); //  $ % # express.static() } } function processTag(request, response) { var command = request.path; // $    command = command.slice(1); // N     //   var data = JSON.stringify(request.body);// $   //      // $    response.writeHead(200, {"Content-Type": "text/html"}); response.write('N    ...<br>'); // Q        function finishResponse(error, buffer) { if (error) { response.write('N: ' + error + '<br>'); } else { response.write(command + '      .<br>'); } response.end(); }
Глава 9 490 2 %    processTag()    : .format()  .write() —         .    ,            — finishResponse() —     ,      . 2              "  NDEF, $       .setMessage()    "  NDEF: * ,    HTTP  HTTPS,   $      "   ,       . 0  : writeTag  formatTag —         — processTag(),        : //        ,      : if (command === 'formatTag') { tagWriter.format(finishResponse); // $   //    } if (command === 'writeTag') { var message = tagWriter.setMessage(data, true); tagWriter.write(message, finishResponse); // $     } } //    http.createServer(server).listen(8080); //   $ HTTP https.createServer(options, server).listen(443); //   // $ HTTPS server.post('/writeTag', processTag); // N  //   writeTag server.post('/formatTag', processTag); // N  //     formatTag &       . Добавляем веб-страницу для сервера записи ;  ,      ,        -   . &     writer   public      sketch.js       " : 2    %     : userField, challengeFiled  responseDiv,        : [  setup()            "  ,              . =       writeButton /* +- #  $  /%    : p5.js  */ var userField, challengeField; //   $ //   $  var responseDiv; // ƒ $    //    %$
Идентификация        formatButton,  $            . &                 submit(),        " . &                 , $      draw(): 491 function setup() { noCanvas(); // ^      , R -    // Z$  $      responseDiv = createDiv('+    $  ' %$  $    .'); responseDiv.position(10, 130); var userLabel = createSpan('\  $'); // Z$ //      $ userLabel.position(10, 10); userField = createInput('','text'); // Z$   //   $ userField.position(100, 10); var challengeLabel = createSpan('  %$'); // Z$ //      %$ challengeLabel.position(10, 40); challengeField = createInput('','password'); // Z$ //     %$ challengeField.position(100, 40); var writeButton = createButton('   '); // Z$ //   $  writeButton.position(10, 70); writeButton.id('writeTag'); writeButton.touchEnded(submit); var formatButton = createButton('•     ') // Z$ //   %     formatButton.position(10, 100); formatButton.id('formatTag'); formatButton.touchEnded(submit); } [  submit()       "                POST HTTP. 2         JSON                            POST,        $   : function submit(event) { var route = '/' + event.target.id; //   //  %    var data = { // Z$  $ POST 'user' : userField.value(), 'challenge' : challengeField.value() }; // &    $, //  $      ' responseDiv.html('      '<br>') httpPost(route, data, 'text', getResponse); //   // $ POST } [  getResponse()             POST. 0    %                  responseDiv: function getResponse(data) { // // responseDiv.html(data); // // } &           . #   ,           . • #  $ + $  $ POST    - # $
Глава 9 492 Тестирование сервера записи метки *%    ,   $        %    ,   "       .                   ,      . =      $     ,             % : ndefSignature public writer     HTML p5.js     p5.js      index.html libraries sketch.js reader index.html libraries sketch.js node_modules https-server-reader.js https-server-writer.js keys domain.key domain.crt private.key public.key writeNdefSignature.js readNdefSignature.js gpioControl.js    ,    ' npm         %  '   ( ) ' SSL  %  SSL   '  #  $  NDEF  '  #    NDEF      NDEF       NDEF    GPIO =               Raspberry Pi                    : $ sudo https-server-writer.js Рис. 9.18. Веб-страница для приложения записи меток NDEF. Сообщения сервера выводятся в текстовом разделе внизу страницы 2                     : https://..raspberry.pi/writer.   $      .. raspberry.pi    IP- %  Raspberry Pi. 0     ,    https://      . &            ,     . 9.18.             Format tag ([    ). &           "  :      '    ... formatTag  .
Идентификация 493 0    ,            (     ,            )     Write to tag (2    ). #       "  :      '    ... writeTag  . 4      "   : ? ? ? 4     ,   ,                        .  ,     -           ?        %    NFC?      "         writeNdefSignature.js      readNdefSignature.js;                ?        ,              . Создаем сервер для чтения меток #       httpsserver-reader.js        https-server-writer.js     . #                      ,     (       % ,           ,            "  ). '          —      ,       writeNdefSignature. js    readNdefSignature.js  gpioControl.js: =          processTag(). &           ,        .write()  .format()    $         .setSecret()  .read()   readNdefSignature.js. [  finishResponse()      .    ,         .parseMessage()   readNdefSignature.js          : /* Z HTTP/HTTPS  -% +      : node.js   % # */ // '    "   : //  ''      ,   #  // $  https-server-write.js // $     var tagReader = require('./readNdefSignature.js'); var lockControl = require('./gpioControl.js'); /* ... $      ,    $  https-server-write.js,  $  R$  , '    -      $ HTTP  $   $ HTTPS */ function processTag(request, response) { var command = request.path; //     command = command.slice(1); //    '  '  var data = JSON.stringify(request.body); // $ //  $   //    response.writeHead(200, {"Content-Type": "text/html"}); response.write('   ...<br>'); // • #   $   function finishResponse(error, buffer) { if (error) { response.write(' : ' + error + '<br>'); } else { response.write(command + '  .<br>'); var verified = tagReader.parseMessage(buffer);
Глава 9 494 if (verified) { response.write('       .<br>'); lockControl.open(); } else { response.write('‡        #  .<br>'); } } response.end(); } //        ,      : tagReader.setSecret(data); tagReader.read(finishResponse); // $     } 4                      POST   /readTag    /writeTag  /formatTag:  //    http.createServer(server).listen(8080); //   $ HTTP https.createServer(options, server).listen(443); //   // $ HTTPS server.post('/readTag', processTag); // N //     readTag &       . Добавляем веб-страницу для сервера чтения ;  ,         ,     -          . =           .   ,      ,       -                     -       . 9 $               % . q       : [  setup()      ,     -     ,  %   ,       responseDiv                                  : /* +- #    : p5.js  */ var userField, challengeField; //   $ //   $  var responseDiv; // ƒ $    //    %$ function setup() { noCanvas(); // ^      , R - //    // Z$  $      responseDiv = createDiv('               ..'); responseDiv.position(10, 130); /* Z'   $  $   $   userfiled    $  challengeField    %$ */
Идентификация 495 var readButton = createButton('~  ');// 9 //      readButton.position(120, 70); readButton.id("readTag"); readButton.touchEnded(submit); } 0               -                 submit()  getResponse(): /* Z'   % # submit()  - #   $  */ getResponse()  $ &       . Тестирование приложения чтения метки ;                . *         $  ,          ,     gpioControl.js. X %         ,               "  : Рис. 9.19. Веб-страница для приложения чтения меток NDEF. Сообщения сервера выводятся в текстовом разделе внизу страницы $ sudo https-server-reader.js 2                     : https://..raspberry.pi/reader. &     ..raspberry.pi    IP- %  Raspberry Pi. 0     ,    https://     . &            ,     . 9.19.            ,               "      Verify tag (#   ). #      "  :      '    ... readTag  . +    %$.   $       (  . 9.20).                  . #      "  :      '.    ... readTag  . ^    '    R  #  ,          ,     ,            POST. &   JSON,         ,        %    ,                  NDEF. #             ,            ,         .
Глава 9 496 7                         NDEF  %          . /             ,            . *  "      %      . 4   %         ,     % , ,        ,              . *                      ,                  . ~                       ,  "        ,      ,    ,            ,     -     .   $                ,  ,                ,                      . >    %          ,               RFID        ,                  . /     ,           ,             ,            . * ,                 , $                           -        . Рис. 9.20. Соленоидный замок устанавливается вместо обычного дверного замка
Идентификация 497 Сетевая идентификация До сих пор мы идентифицировали сетевые устройства по их адресам. Для устройств Интернета в качестве идентификаторов используются как IP-, так и MAC-адреса. Беспроводным устройствам, работающим по протоколам Bluetooth и 802.15.4, также присваиваются стандартные адреса. Но адрес устройства не предоставляет нам никакой информации о самом устройстве или его функциях. &                 4. ;         HTTP,    "   .         API      ,     ,                   ,    $            .   $,     "                 -   . * ,   ,                            ,  "    ? >%      +                          . /          ,     "         . &     ,    ,         . 3                     ,    ,         $   . =              HTTP             .       —   ,    node.js,     HTTP,          %          ,     $    . Пишем код сервера '       $   ,         node.js   clientHeaders. #   $         server.js. # "      npm     express,    "        ,           : /* Z  $ $   : node.js */ var express = require('express'); // ' //    express var server = new express(); // Z$ R$  //    express // • #   $     GET function respond(request, response) { console.log(request.headers); console.log("\  - : " + request.hostname); console.log("IP-  : " + request.ip); response.end("  ,  !"); } server.listen(8080); //         //  8080 server.get('/', respond); //   $ GET
Глава 9 498 &     $                  " : { host: '114.226.112.201:8080', connection: 'keep-alive', 'cache-control': 'max-age=0', 'upgrade-insecure-requests': '1', 'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36', accept: 'text/html,application/ xhtml+xml,application/ xml;q=0.9,image/webp,*/*;q=0.8', 'accept-encoding': 'gzip, deflate, sdch', 'accept-language': 'en-US,en;q=0.8' } \  - : 114.226.112.201 IP-  : ::ffff:206.175.85.178     , $      %     : IP-  -     ,    ,         ,              . & ,     , ,        HTTP, %     ! ;                ,   -       .      . & ,          %            "    -  ,           "   ,       %   . 4     $      , "       %   ,                  , IP- $     ,   , IP-  %     . /      ,    %       "    IP-  ( .   3),        %  ,      %    ,      ,      %           %       .              "   ,   ,               ,     ,     . ~                ,              ,      . /   ,    %    +     %       ,        . *  ,    user-agent               %    . *   $               :     ,     -   —       "      . =     : accept-language —           ,                . 3   IP-  , "         IP- ,     ,                . 2                                ( Chrome $   " ,  Firefox  Safari —  ,   Microsoft Edge —   InPrivate). &    ,    %       IP- ,           . &    … 3              … *    $                   ,  - *  %       . ~  "       +   Анонимность в Интернете
Идентификация  ,          IP- %       ,       +  . +     $   4  Tor (www.torproject.org) —              , "     +           . #  Tor           +          ,        - , %    .         Tor    -                       Tor,         "        Tor,    $  .        (     !)                  -    ,                  . ;  ,   %    -      (  IP %     ),      Tor. *  ,         - 499   clientHeaders.js      ,     Tor. &     %      "   +    *-     Tor  q ,        Tor  [  ,      "    Tor  *  . +  $   Tor  *               . 3        nslookup ( .   4),    IP- ,     %    ,            . 0   "   -          Tor     . &   ,         ,             %            Tor,            %   -    . ;   ,           Tor,   %           %        -      (   ) "     +   . Проект 28 Геолокация по IP-адресу В этом проекте IP-адрес клиента используется для определения географических широты и долготы его местонахождения. Необходимая информация берется с сайта www.freegeoip.net, который представляет собой общественный проект геолокации по IP-адресу. Полученные от этого сайта результаты дадут вам определенное представление о том, насколько точным или неточным является геолокация по IP-адресу. Наш сценарий также использует параметр user-agent запроса HTTP для соответствующего форматирования ответа для разных клиентов. & -   www.freegeoip.net        API, "              IP-   "  :    . `    $  ,        IP      . =     : http://freegeoip.net/ <% >/<ip->. {"ip":"91.200.12.34","country_ code":"UA","country_ name":"Ukraine","region_ code":"","region_name":"","city":"","zip_ code":"","time_zone":"","latitude":50. 45,"longitude":30.5233,"met ro_code":0} &    %     CSV, JSON  XML. =     ip-     IP-  "   . &               IP- ,    
Глава 9 500 Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_8; en-US) AppleWebKit/532.5 (KHTML, like Gecko) Chrome/4.0.249.0 Safari/532.5        Mozilla Foundation. /           Netscape —         &    . 4  "    Mozilla —         ,  "             NCSA Mosaic. >  Firefox    Mozilla,               « »   -  ,   Mozilla Foundation          ,   "     &     +     . #   ,   "             :  , CSS  JavaScript —        Mozilla/5.0     user-agent. +       $        . =   ,  %              «   Mozilla»,  $   ,   ,   ,     ,   - '      ,   $            ,        . # "           ,       IP-  ,     . 4        -  ,        ,           Google Maps,            .           "    %    ,        user-agent      $   Mozilla/5.0. *  ,  "             user-agent     Chrome    macOS: Пишем код #              geoIP. X     express,        "  . &         server.js       "  . &    ,    ,     express      node.js   http,                   www.freegeoip.net. =   $    express     server,                   www.freegeoip. net ,  ,          Google Maps: /* Z, ' : node.js $ # '     IP- */ var http = require('http'); // '    http var express = require('express'); // '    // express var server = new express(); // Z$ R$     // express    server // ˆ  Google Maps var mapsAddress = 'https://www.google.com/maps/place/'; //    freegeoip var geoOptions = { host: 'freegeoip.net', path: '/json/' };
Идентификация 501   ,  $   // • #   $     GET       "    , function respond(request, response) { console.log("IP-  : " + request.ip);    $           GET,  "        respond(). & $       IP-        HTTP    www.freegeoip.net,        : &     respond()      http.request()   HTTP      ,  "       getIPAddress(). /     %         freegeoip        "   . 2                       respond(),    %                   :   %     %            finishResponse(). &        user-agent          : function getIPAddress(geoResponse) { var result = ''; // Z    -  //  //           freegeoip geoResponse.on('data', collectData); //   // -  geoResponse.on('end', finishResponse); //   // $   function collectData(data) { // Š    //     . result += data; // Z  -   // -   . } //  $    function finishResponse() { var location = JSON.parse(result); var latLong = location.latitude + "," + location. longitude; console.log(latLong); /* †   user-agent $   $ (   -  $ '   Mozilla/5.0),   Google Maps. +      $ # '     JSON */ if (request.headers['user-agent']. includes('Mozilla/5.0')) { response.redirect(mapsAddress + latLong); } else { response.end(JSON.stringify(location)); } } } // ^  $ geoIP geoOptions.path = '/json/' + request.ip; // Š // IP-      geoIP var geoRequest = http.request(geoOptions, getIPAddress); // ^  $ geoRequest.end(); //  $ }
Глава 9 502    ,                        : server.listen(8080); //         //  8080 server.get('/', respond); //   $ GET    "   $                   Google Maps,    IP-         . *    "       —   ,    curl,         ( .   3),    "    JSON.              ,         example.com IP-    :   $ curl example.com:8080 #   " :       - {"ip":"208.113.160.6","country_ code":"US","country_name":"United States","region_code":"CA","region_ name":"California","city":"Bre a","zip_code":"92821","time_ zone":"America/Los_Angeles","latitud e":33.9269,"longitude":117.8612,"metro_code":803} *           ,        Google Maps        %  IP-  (  . 9.21).    "                 "   ,            Tor,    "              Tor,    %    .                  ,   ,     %    . Рис. 9.21. Геопозиционирование IP-адреса устройства обычно отображает расположение его поставщика услуг Интернета. Здесь же в качестве моей геопозиции отображена геопозиция моего оператора — город Сайпресс Хилл (Cypress Hill) в штате Нью-Йорк, тогда как я в действительности находился в нижнем Манхэттене. Такой же запрос из того же самого места из браузера Tor поместил меня в западный Техас
Идентификация        . 9.21,      IP-      . q  IP-                         "    IP- . *   $  ,   ,       "   %   %   %   "   +  ,  %      . > ,          ,      -  ,               % . $   "        ,           : «7      IP- . 0            »,         $      : «* ,   ! ; %     " +  ». =  "        $           user-agent. '   ,           user-agent     HTTP,              ,           ,        ,      user-agent. *  ,      ,  %        Arduino     ,            "  : 503 // Z$   HTTP HttpClient http(netSocket, server, 8080); http.beginRequest(); // ^  $ http.get(route); //   $ GET // Š $ user-agent http.sendHeader("user-agent","arduino"); http.endRequest(); //  $  2         user-agent         curl        . =             Mozilla    user-agent: $ curl -L -A 'Mozilla/5.0' example. com:8080 [ -L    curl       ,   -ˆ   ,   "            useragent. +      user-agent             % ,   ,   $                  "     ,                    ,         .
Глава 9 504 Заключение В этой главе мы рассмотрели несколько примеров сопоставления физической и сетевой идентификации. Граница между физической и сетевой идентификацией всегда порождает возможность путаницы и недоразумений. Никакая система для перемещения информации через эту границу не обеспечивает стопроцентной надежности. Определение идентичности, возможностей и действий — это сложные задачи, результаты решения которых предрасположены к ошибочной интерпретации. Так что, чем больше информации от людей вы включите в ситуацию и чем больше прозрачности и помощи предоставите вовлеченным людям, тем лучшие результаты вы получите. 0              "                  ,   $       ,    %  ,     . & +       "     -  "   , $                %  . &     ,       ,                 $  ,         .       ,       .   " ,          %         $   ,     ,                  . *     ,     "          . *   ,         -  -     ,   -  "    — $                  . 9 %  $          ,         % . *        ,        ,        ,   %    % . $                     ,         .
Идентификация 505

Глава 10 СЕТИ МОБИЛЬНОЙ ТЕЛЕФОННОЙ СВЯЗИ И ФИЗИЧЕСКИЙ МИР Технологии Ethernet и Wi-Fi удобны для общения людей и объектов по Интернету, однако намного больший охват имеет мобильная телефонная связь. Тем не менее, в настоящее время телефония и Интернет настолько переплетены, что не имеет смысла рассматривать их отдельно друг от друга. Подключать к сетям мобильной телефонной связи не только мобильные телефоны, но и другие физические устройства становится все легче. В этой главе мы рассмотрим, как совместить Интернет и сети мобильной телефонной связи и как извлечь из такого совмещения максимальную пользу. ohai lion, how r u??? txt me l8r!!!1 (привет, лев, ты там как??? кинь мне потом смс-ку!!!) /        SMS-.   Groundlabs          «†   »  «2"  »   $   " %    GPS/GSM    "  SMS                         . Z  $           —         "  "         , "     ,            ,  "         . 0        Groundlabs. 1 l8r — $         ,    %      «later» (   . — « , »). Z      —     «eight» [¬t]      «later». $   "     ,           $  (      https://thequestion.ru/).
Глава 10 508 Компоненты для проектов этой главы Многие основные аппаратные компоненты, используемые в проектах этой главы, вам уже знакомы. Однако здесь нам придется также работать с переменным напряжением номиналом 120 или 220 В и с проводящими тканями и нитками. Коды поставщиков ? A — Arduino Store, http://store.arduino.cc ? J — Jameco, http://jameco.com ? AF — Adafruit, http://adafruit.com ? L — Less EMF, www.lessemf.com ? D — Digi-Key, www.digikey.com ? RS — RS, www.rs-online.com ? DL — D-Link, www.dlink.com ? SF — SparkFun, www.sparkfun.com ? F — Farnell, www.farnell.com ? SS — Seeed Studio, www.seeedstudio.com Рис. 10.1. Новые компоненты для проектов этой главы: 1. Raspberry Pi Zero с камерой Pi в Pi-корпусе. 2. Блок розеток для бытовой электросети со шнуром достаточной длины. 3. Толстовка с капюшоном. 4. Переключатель PowerSwitch Tail. 5. Проводящая ткань. 6. Сотовые модемы. 7. Пришиваемые к ткани кнопки. 8. Держатель батареек. 9. Оптоизолятор. 10. Датчик температуры и влажности DHT11. 11. Реле переменного тока. 12. Адаптер USB MK20. 13. Плата Bluethooth BLE Nano. 14. Штыревые разъемы. 15. Токопроводящие нитки. 16. Нитки для вышивания 3 5 4 2 15 11 12 13 16 6 14 8 1 10 9 7
Сети мобильной телефонной связи и физический мир 509 ПРОЕКТ 29. Возвращение сетевого кота  C      , 1 +. D: 438-1045-ND, J: 20723  20601, SF: PRT12615  PRT-12002, F: 4692810, AF: 64, SS: 319030002,  319030001,  %    AF: 2077, A: TSX00083, SF: DEV07914 %     SF: PRT12044, AF: 65, D: 923273-ND   Arduino MKR1000, 1 +. AF: 3156, RS: 124-0657, A: ABX00004, GBX00011 (3   4#), D: 1659-1005-ND &               ESP8266. SF: WRL-13231, AF: 2471    A > IP- , 1 +. (         Raspberry Pi). DL: DCS-930L, DCS-5222L,  DCS-960L & $       DCS-930L, DCS-5222L  DCS-960L   D-Link,          Raspberry Pi  Pi Cam (           ),    "   : • Raspberry Pi SF: DEV-13825, AF: 3055, SS: 114990584, RS: 896-8660, F: 2525225 • Pi Cam SF: 14028, AF: 3099, SS: 113990214 • Pi Zero W Camera Kit A: 3414 !      A  1 +. AF: 386, J: 2245415, SS: 101020011 DTH11,         , 1 +.   SparkFun       ,     "  . &               Power Switch Tail. SF: KIT-13815    > PowerSwitch Tail, 1 +. /                 . &   240 &        -   www. powerswitchtail.com. SF: C0M-10747, AF: 2935  (    1 , 1 +. D: 1.0KQBK-ND, J: 690865, F: 9339051, RS: 777666  (    100 , 1 +. D: 100QBK-ND, J: 690620, F: 9337660, RS: 7550707     4N35, 1 +. J: 41056, F: 1244500, D: 160-1304-5-ND, RS: 597302 &              SparkFun. SF: BOB-09118 .        .  #    (     ). ПРОЕКТ 30. Звоним термостату  # +  N     29, 1 +.  Twilio, 1 +.  %& , 1 +. ПРОЕКТ 31. Мобильный регистратор личных биометрических данных  N   D Android  iOS, 1 +.   RedBear BLE Nano +    . USB-  MK20. MS: MKRBL5, SF: WRL-14071 &           Arduino 101,  - %           % . D: 1660-1003-ND, J: 2239331, SF: DEV-13787, A: 3033, F: 2520713, RS: 913-9999, SS: 114990575, A: ABX00005, GBX00005 (3   4#)
Глава 10 510  H  ) +      2,5  A +   . - AF: 400, SF: PRT-12693. &          -   -  (IC-hook with pigtail). SF: CAB-09741  CAB-00501  ! A     . SF: DEV-10730  DEV-13883   PRT00338, AF: 1870  1871    654. 4        %  ,  — SF: DEV-11893  PRT-13851.  (    270 , 1 +. J: 691446, D: CF14JT270KCT-ND, RS: 845-7577  %   $  . AF: 603, SF: DEV-11791, L: 304  %  $   . AF: 1168, L: 1220   +  A 5 .   %    >+ , 1 +.  ]   +  . =      .     D  • Adafruit Fona 800. AF: 3147 (#3), AF: 2691 (4 ) • Adafruit Fona Feather AF: 3027 • Seeed Studio Xadow GSM+BLE SS: 102040005 • XBee Cellular D: 602-1976-ND, • Particle Electron Kit SF: WRL-14211 (#.  Š. 3 /3  ), SF: WRL-14212 (3 /3/4 )    AF: 1126, SF: DEV-11347 Одна большая сеть Телефонная сеть возникла задолго до сети Интернет. Все соединения в ней осуществлялись аналоговыми электрическими схемами, и все телефонные звонки были коммутируемыми, то есть между абонентами устанавливалась временная выделенная цепь. Затем появились модемы, которые позволили компьютерам обмениваться данными по тем же самым телефонным аналоговым цепям. Постепенно телефонные коммутаторы были заменены маршрутизаторами, а новые телефонные сети стали делать цифровыми. Теперь абоненты соединяются виртуальными цепями, и сценарии телефонных звонков почти не отличаются от сценариев электронной почты или чата: между абонентами устанавливается сеанс, происходит обмен битами и осуществляется обмен сообщениями. Различия между телефонным звонком и электронной почтой сейчас заключены в протоколах, обеспечивающих каждый вид связи, а не в структуре электрических цепей.       -    —               Asterisk (www.asterisk.org),       ,        Twilio (www.twilio.com), Google Voice (www.voice.google.com), Skype (www.skype. com)   .,                      +  . /        ,     «  »      . 0                            %  ,                    ,           ,         , "    IP-   .
Сети мобильной телефонной связи и физический мир X         +       %   %  , "                 . *  ,          SMS-%, "        "  $     ,           "  SMS,    "  SMS,        "  $     . # Google Voice                            ,  "           ,                           "   ,     . 0         ,  "     ,     ,                    . 511 " ,             . .,      ,             . $                $         %                   . 9                  —             . +     $        ,     , %           —  : ? ?      ;  $    ; ?      ?   Bluetooth; ? ;   USB; Компьютер у вас в кармане ?     ; #      —   —             ,           . ;   —   iPhone      0# Android — $  "  , "               . &                               "     ,        — $   %            ,           ,    %  . >%       "     ,       :   ,     ,    "        GPS. +,     ,         . *     ,  $                 — - ?        ; ?        GPS. *   $         ,         ,               :  Wi-Fi     —        Bluetooth —   . &         IP- ,           +  : HTTP, $     , SSH, FTP  . . *  . 10.2                   ,         +  .           +          %.
Глава 10 512 Сеть мобильной связи Базовая приемопередающая станция (БПС) Базовая приемопередающая станция (БПС) Контроллер базовой станции (КБС) Базовая приемопередающая станция (БПС) Смартфон Контроллер базовой станции (КБС) Шлюзовый коммутационный центр мобильной связи Узел поддержки GPRS Коммутационный центр мобильной связи (КЦМС) Интернет Поставщик услуг Интернет Телефонная коммутируемая сеть общего пользования (ТКСОП) Проводной телефон Поставщик услуг Интернет Домашний маршрутизатор Персональный компьютер Рис. 10.2. Взаимодействие сети мобильной телефонной связи с сетью Интернет Поставщик услуг веб-хостинга
Сети мобильной телефонной связи и физический мир 513 Определитесь, как это должно происходить  $           "        :       ,    ,      ,     ,      ,       $   %  . &       ,                      ? +    , "   ,      ,         —   , %    -  ?   ,             . *           ,        5,                   ? X           —                           Bluetooth  USB? 4  $     ,      ,           ? 7          ?       "  SMS  $     ,  ""       ?                        ,         "            . X   ,     ,            . 4        Wi-Fi?    ?      Ethernet? &      %          " Bluetooth  Wi-Fi? Интерфейсы на основе браузера 4                 ,       $              +             . ;                       —  ,    , $            HTTP  -             . >%    ,        $   ,               . Интерфейс на основе своего приложения 4   -                      ,            ,   "         Bluetooth, , USB    "  SMS. 7            $  .  "          —             " . *     —          ,         $               .   ,           ,                      ,  $               . Интерфейс на основе сообщений SMS или электронной почты &                            . 4                                ,             , —   ,         %   " , —        "  SMS  $     . ;     $         ,     "  SMS    GPRS,       ,       "        "  "  $         " " 
Глава 10 514    +       .  "  $     ,             "    ,        , —   "  SMS  $     . Голосовые интерфейсы *                —               . q                     ,                        %     —   Asterisk  Twilio. Телефон как шлюз *                     . +                             . &                     —  "    Bluetooth  USB,           . = $ ,   ,            ,    %                       . Проект 29 Возвращение сетевого кота Если в состав программного обеспечения вашего смартфона входит браузер, вам нет надобности знать, как его программировать, чтобы создать мобильное приложение. В этом проекте мы создадим вариант проекта сетевого кота из главы 3. Но на этот раз мы воспользуемся новым протоколом — MQTT — и IP-камерой, для подключения которой к Интернету компьютер не нужен. Требуемые компоненты  >       , 1 %.   Arduino MKR1000,  WINC1500,        ESP8266, 1 %. +       : GPIO, Wi-Fi.       IP- , 1 %.  =          , 1 %.    , 1 %.  9     1 0, 1 %.  9     100 0, 1 %.  0 , 1 %.  # , 1 %.  .    .  2    (      ). X   ,   _,  ,       q    . X _       %   . 0       ,     ,    . 0          ,    ,            . ;         %   (       ), _                    . '  ,           . 7     "  : _                 -    "  ,              . 2      "           ,      ,        - .
Сети мобильной телефонной связи и физический мир 4     %  ,                   ,   %    —    .                      _         .      %      ,                  ,     %   ,   ,      . *  . 10.3   -       ,    . 10.4 —       . Рис. 10.3. Блок-схема системы связи для наблюдения за котом и управления кондиционером 515 #                         —  $              . 9 Wi-Fi   MKR1000                SPI. =          ,        220 &        —    . >  IP-   $     "    Wi-FI, $  ,     , — $        %  .          -   %    ,    %  . Мобильный клиент Компьютерный клиент Мобильная сеть Сеть Ethernet или Wi-Fi Интернет Подключение DSL или кабельное Камера Wi-Fi Домашний маршрутизатор Wi-Fi Датчик температуры Интерфейс SPI Цифровой ввод Микроконтроллер Реле Цифровой вывод Радиомодуль Wi-Fi
Глава 10 516 Веб-клиент GET index.html image.jpg Поставщик услуг веб-хостинга OK index.html, image.jpg Сервер HTTP Подписка MQTT: все Публикация MQTT: setPoint, mode, update Брокер MQTT Передача файла по FTP Публикация MQTT: все Микроконтроллер Датчик температуры Считываем показания датчика Подписка MQTT: setPoint, on, mode, update Камера Включаем или Реле выключаем реле Рис. 10.4. Блок-схема взаимодействия системы наблюдения за котом и управления кондиционером и собственно контроллера управления кондиционером =  -      -      p5.js —         %        FTP         "    -  . =                   ,       "  MKR1000        ESP8266. *           node.js,      %   -   , —        -   ,             . Протокол MQTT 7          -       ,        (         3),       "  IP- . 0             . &  $        -         "      -  ,    $    — MQTT2. 2 MQTT, Message Queue Telemetry Transport —        "      .
Сети мобильной телефонной связи и физический мир X "     "  MQTT (http://mqtt.org)               ,           . #     MQTT        . =   3     ,      # 4. X               "  ,      " . 0           " . /    ,     MQTT             5. *  ,  $    %   (airConditioner)       ,          airConditioner/   "  : ? airConditioner/on —    :     ; ? airConditioner/mode —   :  ,   ,   ; ? airConditioner/temperature —  "        ; ? airConditioner/setPoint —      ,                     .                  "     /temperature,   -      "     /setPoint,            ,      "     /mode,                      .                 ,       -   "              . *    MQTT      . 3 4 5 0  . topics. 0  . messages. 0  . Publish & Subscribe,  PubSub. 517 *  ,       ,  " ,       ,      $    .  $       "    : ? airConditioner/connected —                      ; ? airConditioner/update —    -   "                    . Схема системы ;  ,        "        ,       .                        . 10.5,     —   . 10.6. & ,           , — $     ,    . 9    % $   ,         .   %       ,           ,               ,    .                   (  . 10.7). 0"             . 10.8.     0  $      ,      . 0           .         ,    "      ,  $             $ ,              ,  . 0           $     . ;  ""                       $   . X           " % ,                   5 &.
Глава 10 518 «Плюс» питающего тока «Плюс» питающего тока Выходной сигнал Датчик температуры DHT11 Модуль микроконтроллера 10 КОм D4 N.C. D5 Общий Общий 100 Ом Управляющий сигнал Э Общий (Эмиттер) В электросеть Реле К (Коллектор) Оптоизолятор Розетка для кондиционера Рис. 10.5. Принципиальная схема системы удаленного управления кондиционером Рис. 10.6. Монтажная схема системы удаленного управления кондиционером, собранная на микроконтроллере MKR1000 A B C D E F G H I J 1 5 5 10 10 15 15 20 20 25 25 LOAD 1 30 A B C D E F G H I J Gnd Cntl. 5V 30
Сети мобильной телефонной связи и физический мир 519 9     $         , $ —           $    —   ,          . 4         ,               ,         PowerSwitch Tail         240 & (www.powerswitchtail.com),          Adafruit  SparkFun.  , $               WeMo,        9. *               ,             SparkFun         %     PowerSwitch Tail. &       ,       ,                   LOAD (* )   . *  . 10.7                  . &  « »,   +5 &               . =            $       ,      . 10.8,           *  #  (Nathan Seidle)    www.sparkfun.com/tutorials/119. '               $   ,                      %         "            . 0    % -  (      )           . 3     (     ,       )                  . ;         ,              +5 &, $         . 3             « »     $      . Рис. 10.7. Контакты платы реле подключены к разрыву в одной из жил кабеля питания Рис. 10.8. Блок розеток, включающий реле, провода управления которым подсоединены к модулю Arduino, — так обеспечивается безопасная работа с питанием от электросети. Можно было бы также воспользоваться модулем PowerSwitch Tail
Глава 10 520         ,          . = $              D1                «7» (Blink)    1 —         . 0                 %     $   . 4          , $          ,       $    —  "     . _%                 $    .   $                 ,                 . 2     ,         ,    ,    ,    "  . X  $         ,              $   ,   ,     % . Пишем код для этого проекта Назовем скетч для этого проекта AirConditionerArduino. Так как скетч весьма сложный, мы будем создавать его по частям. Проверяем работу датчика температуры &          DHT11. /            ,      ,    ,        . &           OneWire   Dallas Semiconductors. =    7      Arduino        DHT Sensor Library  Adafruit Unified Sensor   Adafruit. /*   MQTT     #  : Arduino */ #include <DHT.h> // '    DHT const int sensorPin = 4; // ^       //      DHT dht(sensorPin, DHT11); // Z$ R$     // DHT void setup() { Serial.begin(9600); //    ' $ dht.begin(); // ˆ         } &       DHT,          , "        ,       loop()              : &   loop()                $  . [  readTemperature()        Z  ,       [   $            true — readTemperature(true). & %           Z  : void loop() { float temperature = dht.readTemperature(); // Z  // $     float humidity = dht.readHumidity(); // Z  // $   Serial.print(temperature); // +   // $   R Serial.print("°C ,"); Serial.print(humidity); Serial.println("% rH"); }
Сети мобильной телефонной связи и физический мир 521 Управляем реле X % ,             ,         (     ,    ,      % ). &    ,           . ;         ,  "   ,     setup()            : &   setup()                        : &   loop()    ,        ,    "     ". 4    ,    $   "    ,         "         "   .      "   :  ,   ,   . &                      . *      ,           deviceIsOn. 9      " ,        ,         loop()    2000   : /*   MQTT     #  : Arduino */ #include <DHT.h> // '    DHT boolean deviceIsOn = false; // 9   int temperature = 0; // C     int lastTemperature = 0; // $      //    int setPoint = 18; // $        int mode = 3; //  !  —  ,   , //    (1, 2, 3) boolean deviceConnected = false; //      //   const int sensorPin = 4; // ^       //      const int relayPin = 5; // ‡         DHT dht(sensorPin, DHT11); // Z$ R$     DHT void setup() { Serial.begin(9600); //    ' $ dht.begin(); // ˆ         temperature = dht.readTemperature(); // –   //   pinMode(relayPin, OUTPUT); // 7    //           //   !   } void loop() { temperature = dht.readTemperature(); // Z  // $     if (abs(temperature - lastTemperature) > 0) { // $  , //             Serial.print("C     . C    : "); Serial.println(temperature); } lastTemperature = temperature; // 9    //          if (mode == 3) { // Œ    !  checkThermostat(); } digitalWrite(relayPin, deviceIsOn); //   //     delay(2000); }
Глава 10 522 &        : checkThermostat().                          . 4      % ,         ,      ,    % —    :  0 void checkThermostat() { if (temperature > setPoint) { if (!deviceIsOn) { deviceIsOn = true; //    } } if (setPoint > temperature) { if (deviceIsOn) { deviceIsOn = false; //     } } }        $      ,      ,                 .  —      . X  % ,         ,                       MQTT.         $ $   (   )                     setPoint.            % ,    "          ,         ,      . ;            ,        —   ,   ,       ,      - =            MQTT  Arduino. 7    Arduino      ,         MQTT   =$ q   (MQTT by Joel Gaehwiler). X   $        Arduino " 7    . 4         $  ,         : https://github.com/256dpi/ arduino-mqtt. Добавляем учетные данные           ,              . =  $    Arduino     config.h,                   $  ,              D  | !  &.        (SSID)   ,  $             MQTT. &                     MQTT. 2  ,  " % , % $  ,          ,          MQTT: /*   MQTT     #  : Arduino */ char ssid[] = " _ "; // \  (SSID)    char password[] = " "; //   -   //  '  char mqttUser[] = "airConditioner"; // \  $  //   MQTT char mqttPass[] = "_mqtt"; // $    MQTT
Сети мобильной телефонной связи и физический мир 523 Подключаемся к сети    ,         MQTT  Arduino. 7    Arduino      ,         MQTT   =$ q   (MQTT by Joel Gaehwiler). X  $        Arduino " 7    . 4          $  ,        : https:// github.com/256dpi/arduino-mqtt.    +,        (           % ): /*   MQTT     #  : Arduino */ #include <DHT.h> // '    DHT #include <SPI.h> // $   SPI #include <WiFi101.h> // $   WiFi101 //#include <ESP8266WiFi.h> // €    ESP8266 //   #  #include <MQTTClient.h> // $   MQTT Client #include "config.h" // $        WiFiClient netSocket; // •       MQTTClient client; // •    MQTT char serverAddress[] = "192.168.0.15"; // Œ     MQTT. // `!   # IP-       , //         boolean deviceIsOn = false; // ...   '    $ $  &   setup()           Wi-Fi,         "   . ;          config.h: void setup() { // connect to WiFi Serial.begin(9600); // \ #  $    ' // $ // $       Wi-Fi, while ( WiFi.status() != WL_CONNECTED) { Serial.print("$          : "); Serial.println(ssid); //    #     (SSID) WiFi.begin(ssid, password); //      //    delay(2000); } // $   ,    #    //   : IPAddress ip = WiFi.localIP(); Serial.print("IP- : "); Serial.println(ip); // ˆ            // $  dht.begin(); temperature = dht.readTemperature(); &     setup()      MQTT     client.begin(),          mqttConnect(),         : pinMode(relayPin, OUTPUT); // %      //        //    . // %   MQTT       client.begin(serverAddress, netSocket); mqttConnect(); }
Глава 10 524 &    loop()      ,      ,       ,   ,          : void loop() { client.loop(); // $       if (!client.connected()) { // *    //    , Serial.println("7      "); deviceConnected = false; mqttConnect(); // $       }     -       $       . = $     ,   "          ,               . 0      loop()       : temperature = dht.readTemperature(); // Z  $  //    if (abs(temperature - lastTemperature) > 0) { //  , //        $  Serial.print("ƒ   $  . ƒ    : "); Serial.println(temperature); client.publish("airConditioner/temperature", String(temperature)); } lastTemperature = temperature; // Z-   ' //      '   if (mode == 3) { // ˆ     checkThermostat(); } digitalWrite(relayPin, deviceIsOn); // +'  // '  } &   checkThermostat()     client.publish()    void checkThermostat() { if (temperature > setPoint) { if (!deviceIsOn) { deviceIsOn = true; // +'  client.publish("airConditioner/on", String(deviceIsOn)); } } if (setPoint > temperature) { if (deviceIsOn) { deviceIsOn = false; // +'  client.publish("airConditioner/on", String(deviceIsOn)); } } }         .      MQTT           ,    "  , $       "          .publish(): ;           mqttConnect(),               . &      "      %  . 3     %              ,         ,           publishAll(),        " : // $        void mqttConnect() { if (!client.connect("airConditioner", mqttUser, mqttPass)) { return; // ‡         } Serial.println("$    "); deviceConnected = true; // $          , //        client.subscribe("airConditioner/on"); client.subscribe("airConditioner/setPoint"); client.subscribe("airConditioner/mode"); client.subscribe("airConditioner/update"); publishAll(); }
Сети мобильной телефонной связи и физический мир [  publishAll()                     "     /   . update,   0         : * ,         " "  MQTT. #      , $        messageReceived()            ,           topic ( )  message ( "  ). *         . *    $       /  "   ,         $     : deviceName (    )  property (  ). 4         update,  "  all,       publishAll(). 4            "          (int)          "    .   $   checkThermostat()                . on  setPoint,   3                      (int)                  "  . [  loop()        mode       ,       checkThermostat(). mode,   /  %     messageReceived()     : 525 // $   void publishAll() { client.publish("airConditioner/on", String(deviceIsOn)); client.publish("airConditioner/temperature", String(temperature)); client.publish("airConditioner/setPoint", String(setPoint)); client.publish("airConditioner/mode", String(mode)); client.publish("airConditioner/connected", String(deviceConnected)); } void messageReceived(String topic, String payload, char bytes[], unsigned int length) { Serial.println(topic); Serial.println(payload); // parse the topic int divider = topic.indexOf('/'); String deviceName = topic.substring(0, divider); String property = topic.substring(divider + 1); // *      ,   if (property == "update" && payload == "all") { publishAll(); } if (property == "on") { deviceIsOn = payload.toInt(); } // *      setPoint,    if (property == "setPoint") { setPoint = payload.toInt(); } // *    mode,       //   —  ,   ,        //  ! if (property == "mode") { mode = payload.toInt(); switch (mode) { // $     mode case 1: //   digitalWrite(relayPin, LOW); //     // (  ) deviceIsOn = false; client.publish("airConditioner/on", String(deviceIsOn)); break; case 2: //  digitalWrite(relayPin, HIGH); //    // (  ) deviceIsOn = true; client.publish("airConditioner/on", String(deviceIsOn)); break; case 3: // Œ    !  checkThermostat(); // $       break; } } } // 7    messageReceived()
Глава 10 526 +   $                 "  - ,      ,    ,  -           . X   Mosquitto  %  Linux,    -    Raspian,      "      apt,   $      9: $ sudo apt-get install mosquitto Брокер MQTT Mosquitto &  ,            MQTT,               Mosquitto. /          ,          macOS, Windows  Linux. #                   http://mosquitto.org. 2  $          "      -  . &      Windows          http://mosquitto.org. *           ,         ( .   readme    ). +  $  ,      "   %        Raspberry Pi. X       %  macOS      " Homebrew —       $       . =        Homebrew       -   https://brew.sh,           "   : $ /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/ Homebrew/install/master/install)" X   Homebrew,    Mosquitto   :    $ brew install mosquitto 7           $PATH. = $     : $sudo nano /etc/paths         %      : /usr/local/sbin/      ,             . X         Mosquitto,            %    . X   IP-    ,           ,               serverAddress    "         . >  Mosquitto              "  :   $ mosquitto &    $  "  :      - 1489964660: mosquitto version 1.4.11 (build date 2017-03-14 19:27:44+0000) starting 1489964660: Using default config. 1489964660: Opening ipv6 listen socket on port 1883. 1489964660: Opening ipv4 listen socket on port 1883. 9      "     % <Ctrl>+<C>.   4           Mosquitto    "   % , $  ,               . &    %       ( .  ! «|          »)              . 4      , "       ,      ,           ,           
Сети мобильной телефонной связи и физический мир      Mosquitto,         "     "  : New client connected from 192.168.0.14 as airConditioner (c1, k60, usomeone) ( '      192.168.0.14  airConditioner (c1, k60, usomeone) /   ,    Mosquitto      ,  %        . +       IP-         "  . 7      Mosquitto      ,    -  ( .  . 10.4). & -        -  , ,   % $,                 . X      Mosquitto           ,            ,          . +,     ,           Mosquitto,   $      catCamDeux,    —     mq-local.conf       "   : 527 port 1883 listener 8888 protocol websockets password_file mq-pwds log_type all allow_anonymous false #   $  ,          Mosquitto mq-pwds     : airConditioner —        webClient —   - ,     . [                      -       : $ mosquitto_passwd -c mq-pwds _$ =   "   ,    -    .                     . &     mqpwds          ,     %   . #   ,           -     - . = $             p5.js   public,                     httpServer.js. Завершение работы демонов и других процессов *    Linux      Mosquitto          ,        ,                      . 4          Mosquitto          "   % Error: Address already in use, $   ,             ,    %     . = $       —   ,          "            .         "            "   : $ ps -u _$         _$             Linux. &             " : PID TTY 744 ? 746 pts/0 1461 pts/0 1902 pts/0 TIME 00:00:00 00:00:01 00:00:01 00:00:00 CMD sshd bash mosquitto ps           "         "   ps -e. +   , $       .
Глава 10 528 2 %      "      : $ kill  _#      _#       ,         %. &   "      "          Mosquitto    1461. 0               ,         - 2            (   Proto),      (   Local Address),   (   Foreign Address)       ,      (   State),            ,    "   (   PID/Program name). *       " $        : tcp 0 0 *:1883 ... LISTEN 844/mosquitto +   ,    Mosquitto   %    1883        844. #   ,     %     $       " : $ sudo kill 844  ,     . *      -   —      Mosquitto   %    1883,           ,      netstat: $ sudo netstat -atnp 2       " :             "     (-a),       TCP (-t),  IP-  (-n)       (-p). &          " : ;  , "   ps  kill           ,    ,   %     . 4         ,  "    ,      ,      ps      grep: $ sudo ps -e | grep 'mosquitto' 0   : ps  kill —           .            ,      man ps  man kill    . *      %        ,         ,   $               . *     sudo      ,      "    ,    ,     %        . Создаем веб-сервер *%  -               . X   ,   , " npm   express,        httpServer.js       " : /* Z   - %  : node.js */ var express = require('express'); // ' //    express var server = express(); // Z$ " server, // $     express
Сети мобильной телефонной связи и физический мир #                "     -  ,     MQTT. 529 server.listen(8080); //   $ HTTP server.use('/',express.static('public')); //   , //  '    %  Выполняем разметку =  -           — mqqt.js,         : https://unpkg.com/mqtt@2.5.0/ dist/mqtt.min.js. #           libraries   p5.js,         index.html,     <head>       %   . 0               : <script <script <script <script <script src="libraries/p5.js"></script> src="libraries/p5.dom.js"></script> src="libraries/p5.sound.js"></script> src="libraries/mqtt.min.js"></script> src="sketch.js"></script> Создаем веб-клиент &     -               ,         Arduino.    clientOptions          MQTT. +        ,       : /*    device           ,         : var device = { // Z  on: false, temperature: 24, setPoint: 18, mode: 1, connected: false, name: 'airConditioner' }; ;       $                   . 2         $      HTML: img —     , timeStamp —      , deviceStatus —          , connectButton —     ,                  : +- %   mqtt    #  : p5.js */ var clientOptions = { //     MQTT port: 8888, host: self.location.hostname, // IP- -  //  ' username: 'webClient', // \  $    MQTT password: '_mqtt', //     MQTT }; var var var var var var   client; //   mqtt webConnected = false; // Z  '    img; // \$  $ -  timeStamp; // $     timeStamp deviceStatus; //   R    # connectButton, modeControl; // + " //   #
530 Глава 10 &   setup()       "   $      . = $                 %     touchEnded(),                 . 3             changed(),           : function setup() { frameRate(0.033); //  $  30   noCanvas(); //   $  deviceStatus = createSpan(device.name); // &  % #  //    deviceStatus.position(10, 10); connectButton = createButton('Connect'); //  '  connectButton.position(10, 100); connectButton.touchEnded(connectMe); setPointSlider = createSlider(10, 40, 21, 1); // $  //   $  setPoint setPointSlider.position(180, 100); setPointSlider.touchEnded(changeSetpoint); var sliderLabel = createSpan('Setpoint: '); sliderLabel.position(100,100); modeControl = createRadio(); //    // '/' modeControl.option('off', 1); modeControl.option('on', 2); modeControl.option('auto', 3); modeControl.style('width', '65px'); modeControl.value(device.mode); modeControl.position(220, 10); modeControl.changed(changeMode); timeStamp = createSpan(new Date()); // Š // $     timeStamp.position(10, 160); img = createImg('./image.jpg?'); img.position(10, 180); } [  draw()        $     . +              ,   ,   $             3,          : function draw() { var now = new Date(); //     '    img.elt.src = './image.jpg?' + now; //  //   $  timeStamp.html(now); //  $    } &                            update(),             ,      MQTT      : //     $    // $  function changeSetpoint() { update('setPoint', setPointSlider.value()); //    //  $  } //     '    function changeMode() { update('mode', modeControl.value()); //     // $  }
Сети мобильной телефонной связи и физический мир 531 &          connectMe()           -      MQTT. 4     (  if),      ,    $   mqtt.connect()      ,      . [  mqtt.connect()          announce(),        .                     "     .      (  else)      client.end(): // connect button event handler: function connectMe() { if (!webConnected) { // †    ' client = mqtt.connect(clientOptions); // '  client.on('connect', announce); //    //   '  client.on('message', readMessages); //    //   -   } else { client.end(quit); // '    } } &        announce()    mqtt. connect()                    -        updateInterface(),         . ;       update()     /update,                  : //  ' "    function announce() { connectButton.html(‘Disconnect’); //   // '  webConnected = client.connected; //    // '  // -  #        for (property in device) { client.subscribe(device.name + '/' + property); // //      } updateInterface(); //  %  $ update('update', 'all'); } [  quit()              client.end(). 0             ,         webConnected: //  '    '  function quit() { connectButton.html('Connect'); //    //   '  webConnected = client.connected; } [  update()                    " : //     - -    function update(property, value) { device[property] = value; //    var topic = String(property); // $  // $     % # .publish() var message = String(value); if (webConnected) { //    '      client.publish(device.name + '/' + topic, message); } }
Глава 10 532       " ,      " ,       "   readMessages(). /               ,            . 2    "            "  : temperature, mode  setPoint —    ,     —    . &     readMessages()    $           updateInterface(): // Z  -    MQTT function readMessages(topic, message) { topic = topic.toString(); // $    var strings = topic.split('/'); // $  //    var origin = strings[0]; // \      //   var property = strings[1]; //    — . if (property === 'temperature' || // ‰     // $ property ==='mode' || //    property === 'setPoint') { device[property] = Number(message); } else { // +     —     // &        $ : device[property] = (String(message) == '1'); } updateInterface(); //  %  $ } +,  ,       updateInterface()         $      ,            : // • #    R  $ %  function updateInterface() { var onState; // Z  '   #  if (device.on) { //  ' (on === true) onState = 'on'; // $ true  'on' } else { onState = 'off'; // $ false  'off' } //  ,   '  $  //       : deviceStatus.html(device.name + '<br>' + onState + '<br>temperature: ' + device.temperature + '<br> thermostat setpoint: ' + device.setPoint); setPointSlider.value(device.setPoint); //  // $    $  modeControl.value(device.mode); //  // '    } &        . ;         :         ,  HTTP   - . '      " ,     Mosquitto     : $ mosquitto -c mq-local.conf & #          ,               .      ,         mq-local.conf,               . *  %,          ,         HTTP: $ node httpServer.js * $      "       % "      Mosquitto. 2 %     
Сети мобильной телефонной связи и физический мир  ,    ,    % <Ctrl>+<C>. 3   %     Mosquitto    kill,            ! «|          ». 2       ,       ,        -          : http://.:8080 —          ,     . 10.9,       .       Mosquitto  "        Connect (   ,      . 10.9   Disconnect      ). &           "    ": 1490449929: Config loaded from mq-local.conf. 1490449929: Opening websockets listen socket on port 8888. 1490449929: Opening ipv4 listen socket on port 1883. 1490449929: Opening ipv6 listen socket on port 1883. 1490449930: New client connected from 74.72.23.0 as mqttjs_ ce14eb0b (c1, k10000, u'webClient'). 1490449930: Sending CONNACK to mqttjs_ce14eb0b (0, 0) 1490449930: Received SUBSCRIBE from mqttjs_ ce14eb0b 1490449930: airConditioner/on (QoS 0) 1490449930: mqttjs_ce14eb0b 0 airConditioner/on 1490449930: airConditioner/temperature (QoS 0) ... 1490449948: New connection from 74.72.23.0 on port 1883. 1490449948: New client connected from 74.71.6.0 as airConditioner (c1, k60, u'airConditioner'). 1490449948: Sending CONNACK to airConditioner (0, 0) 1490449948: Received SUBSCRIBE from airConditioner 533 1490449948: airConditioner/on (QoS 0) 1490449948: airConditioner 0 airConditioner/on /   ,          " . +              -  ,     -    $                  . Рис. 10.9. Фрагмент снимка с экрана результатов исполнения скетча удаленного управления кондиционером, сделанный на смартфоне с ОС Android
Глава 10 534 Сетевые камеры ;           ,   ,     . /    %      :    IP-        .        +              ,             . 2    $60      %          Wi-Fi,           .    $    — D-Link DCS-930L — %         $70. 0      ,   $             D-Link       .              ,   %           FTP6  SFTP7. &    , $       DCS-5222L  DCS-960L   D-Link. *                  "   .  ,    ,      Ethernet                        . * $            Wi-Fi,          ,          ,       .       ,       ,               FTP  SFTP. # "    $               "    . ~               ,       ,    6 7 FTP, File Transfer Protocol —    SFTP, Secure FTP —   FTP.   .  "  ,             "    -  . &        SFTP,     ,   $       %      $       . *                   public %    ,       HTML     JavaScript   p5.js. &        $               . IP-     ,    Pi Cam  Raspberry Pi.  Raspberry Pi Zero W   Pi Cam           ,           ,    $    %      . +                   : www.raspberrypi.org/products.   Adafruit    $         Pi Zero Camera Pack (www.adafruit.com/product/3414)     Raspberry Pi Zero W,  Pi Cam        .              Raspberry Pi   Pi Cam               . IP-камера на Raspberry Pi #  IP-  Raspberry Pi     $:    $      %  HTTP           —   ,  $              3. 3    $        Raspberry Pi,            . 7      httpServer.js,  "   %    -  , 
Сети мобильной телефонной связи и физический мир    "  . /         ,  $       3. 2     Pi Cam   Raspberry Pi     ,     : 535 &    Interface Options | Camera   .   $    Raspberry Pi     piCam.sh     . #    ,  $ ,                     . $ sudo raspi-config Код для загрузки изображения '     httpServer.js            ,         multer,          3: $ npm install multer ;              .          multer,            catServer.js    3. 2           % . =               "   diskStorage()   multer. &   ,    public         : /* Z   - %   node.js,   ' $   %  Z    -    public. : node.js */ var express = require('express'); // '    // express var server = express(); // Z$ " server, // $     express var multer = require('multer'); // $ !  $N  //       // %      !       var imgStore = multer.diskStorage({ destination: __dirname + '/public/', // $  //    filename: saveUpload // Q        //     }); =     $    multer              image (   ).         POST        ,     image      : // ‰      ,     //     var upload = multer({storage: imgStore}); // %  :      image // (7  ! !   ! ): var type = upload.single('image'); &             POST     ,                getUpload(): // Q          //     function getUpload(request, response) { //    #        var fileInfo = JSON.stringify(request.file); console.log(fileInfo); response.end( fileInfo + '\n'); }
Глава 10 536 ;           saveUpload(),                  : // Q          function saveUpload(request, file, save) { //       multer,      save(null,file.originalname); } * ,              POST: server.listen(8080); //   $ HTTP server.use('/',express.static('public')); //  , //     %  server.post('/upload', type, getUpload); // %!  //     Автоматизируем захват и загрузку изображений /           raspistill,   "       ,         image.jpg,           -   "   curl: while [ : ] #  #  do # - $ ,  100 , # $  400-300,  80%, $   raspistill -t 100 -w 400 -h 300 -q 80 -o image.jpg -n # Z  ' curl $  $- $    curl -F "image=@image.jpg" 'http://example.com:8080/ upload' # \$   $ example.com  IP-  -- # +   $ $ echo "\$  $ " #  $ 30   sleep 30 done #        ,    "   chmod     %           : $ chmod u+x piCam.sh 7       "    (     Raspberry Pi)        . [           "  : $ ./piCam.sh +  "         30             .   "           -          -     ,         . 10.9. +                        ,                   . 7                                    "           HTML5.                            , $     . +                       ,         , ,    ,      HTTP. 7    $   %   "     .
Сети мобильной телефонной связи и физический мир 537 Проект 30 Звоним термостату Мы вложили в только что созданный проект много труда. К счастью, он не пропадет даром, и мы воспользуемся его результатами в этом проекте. Оборудование для него будет то же самое, что и для предыдущего, но мы внесем в программное обеспечение некоторые изменения, чтобы создать интерфейс, позволяющий нам позвонить термостату по телефону, прослушать голосовое сообщение о температуре в квартире и статусе кондиционера, а также задать пороговое значение термостата с кнопочной панели телефона. 7   _     —      ,           , — ,                    -   . «* $     ! —     . — *         -,    %               ?» & $     —        ,            "      . &           IP-         %,    "                -       . #     —   Google Voice  Asterisk —          :             "    (;#0) +  . /      SIP8                   ,  $        . ;,   SIP      ,     " ,  %   "       . . +   SIP           ,         ,           . 3              ,            ,     .    , $          8 SIP, Session Initiation Protocol —      . Требуемые компоненты  2 %  29.  X     Twilio.  ;   .    21-  .             ,   $             SIP,          "                  :               .     4                   ,      ,      "    SIP. 0              ,                    ,            ,           ,   "     .      —           —          HTTP GET  POST,                   .        ,  "   ,            . 4   SIP    ,     ( ,    : «= %! = %! `      !» —  $     ),      %     ,             .
Глава 10 538 & $              SIP   Twilio                  "    .   Twilio        VoIP9 —     ,   -       . 0          $  ,        ,        $  ,          .                      . *  $              ,       ,            ,   $  . *    $    Twilio                 SMS       . X ,        %   ,     : https://support. twilio.com/hc/en-us/articles/223183068-Twiliointernational-phone-number-availability-andtheir-capabilities.   ,                ,     ;#0 "     +  , —    ,          . /                 $      ,             . 4                VoIP  SIP,      «Asterisk: The Future of Telephony»10    O’Reilly,  : = & 7   (Jim Van Meggelen), =  # (Jared Smith)  _ 7 (Leif Madsen). Каким стандартом пользоваться?   ,    SIP  VoIP     " ,    . 0    $     "         "   . 9 VoIP, Voice over IP —      IP- , ,   ,   -   . 10 «Asterisk. >"    », https://www.ozon.ru/ context/detail/id/4878006/. &       ,   "      ,    :     , "  SMS            —      . *         "                API     . *  ,        Twilio (       $    )              —   Tropo, Google Voice       ,    "  $  . #                      "     : ?         ? ?   ?      ? ?         ,      ?          -  ? `     Twilio  $    -         TwiML,   ,        Twilio      ,              , —   , node.js:      "   GET  POST. #  Twilio        node.js,       %    ,    $  .     Twilio      %      . +             ,     , —   ,                    , ,   ,  "        %     "    . = $              -   www.twilio.com.          , 
Сети мобильной телефонной связи и физический мир          Twilio.          ,      ,        ,      "    .   ,                . *      (URL)   Arduino    "    . *  ,  IP- %    63.118.45.189,   $      http://63.118.45.189:8080/voice.xml. +,          Twilio          (  . 10.10). '      , "     All Products and Services (&     ),    —  Phone Numbers.           ,        (Buy a Number). 539 /       %     % Twilio,    HTTP       IP . ;         "     . ¥    $   Phone Numbers,    —  Verified Caller ID        ,         Twilio. =  CONFIGURE WITH          — Webhooks/TwiML. ;  ,     "     Twilio       POST             TwiML      . 0       A CALL COMES IN     . # %  $  ,            XML         ,        . Рис. 10.10. Панель управления Twilio. Введите адрес (URL) вашего сервера Arduino в поле A CALL COMES IN
Глава 10 540 Краткое введение в XML }! ! #  !   XML11        -      . 0            %     . >      $        ,       <  >. ;    %,         ,       . /      $   . *  , $   <body>     $   <paragraph>: <body> <p>‰  </body>  %</p> & ,       "   "  ,       $  . /,   ,   ,    , %       .  $       "   "  ,           : <  $  ="10" /> #      ,      ,        . &   "                 $,      $    10  . # "   $            . 4    ,   $    HTML,       . `  XML  HTML       ,    XML        "  . Схема разметки TwiML #    Twilio — TwiML —              Twilio      XML.     ,     ,      " Twilio. 11 XML, eXtensible Markup Language —    .  %   #    $           SMS- "  . #  $       : ? q  $   : • <Dial> ­ <Client> ­ <Conference> ­ <Number> ­ <Queue> ­ <Sip> • <Enqueue> • <Gather> • <Hangup> • <Leave> • <Pause> • <Play> • <Record> • <Redirect> • <Reject> • <Say> • <Sms> ? SMS-$   : • <Sms> • <Redirect> 2     $ $                 -   Twilio (www.twilio.com/docs/api/twiml),   ,   ,           %   . = $        $   <Response>. &   $ $      $   <Gather> —         . /   <Gather>    TwiML-    HTML, $      action  method,          $  ,         . 7      $   <Say>,        ,           . /   XML    %    -  , $             HTTP
Сети мобильной телефонной связи и физический мир  node.js,       "    . &      $         . &   ,           node.js — mqtt. /    541  ,            . X   ,    , "       npm: $ npm install mqtt Выполняем разметку = $             TwiML.          ,        .       ,         ,       . #        voice.xml  public    "     (                ,      % ,     . / %   ,       % ):     , $         ,      "     : #temperature, #setPoint  #on. #       ,   $       HTML. ~ %  (#)              "  . 7 ,  $    ,   . &    TwiML — set-temp.xml —         public (  ,         ,          ,      % ,           ). & ,   ,  $        ,          <Gather>      . +  , $       ,           ,     : <?xml version="1.0" encoding="UTF-8"?> <Response> <Gather numDigits="2" timeout="5" action="set-temp.xml" method="POST"> <Say> The current temperature is #temperature degrees Celsius. [C    : #temperature  —  .] The thermostat is set to #setPoint degrees Celsius. [C      #setPoint  —  .] The air conditioner is set to #on. [K !     —  .] If you would like to change the thermostat, please enter a new setting. [*          ,       .] If you are satisfied, please hang up. [*     ,     .] </Say> </Gather> <Say> You didn't give a new setting, so the thermostat will remain at #setPoint degrees. Goodbye! [      , #          #setPoint . €  !] </Say> </Response> <?xml version="1.0" encoding="UTF-8"?> <Response> <Say> The thermostat is now set to #setPoint degrees. [C      #setPoint .] The temperature is #temperature degrees. [C  : #temperature .] Thank you. Goodbye. [€  !] </Say> <Pause length="2"/> <Hangup/> </Response>
Глава 10 542 3       " :        Twilio,               POST   voice.xml. #                  Twilio. #           TwiML,         ,      %     . 4           ,    "               <Gather>. &                  POST,  $    set-temp.xml. #              MQTT,          Twilio     XML,         . +        ,    %   . & %                  ,        $     ,  %        . ,    =                     Twilio. &    ,       :      POST   XML,  $      ,        ,        MQTT   "    . Модифицируем сервер 0        http "           ,        % . &           fs (       )  mqtt. 2        clientOpitons  device,          - . *        ,     -     localhost. /     ,   node.js        MQTT           ,    Mosquitto: Server.js   /* Z   - %    TwiML   MQTT : node.js */ var express = require('express'); // '    // express var server = express(); // Z$ " server, // $     express var multer = require('multer'); //     //  $ $ %    var fs = require(‘fs’); // $     //       var mqtt = require('mqtt'); // $   // MQTT Client var clientOptions = { // $    MQTT port: 1883, host: 'localhost', username: 'xmlClient', password: 'something', keepalive: 10000 }; var device = { // 9  on: false, temperature: 24, setPoint: 18, mode: 1, connected: false, name: 'airConditioner' };
Сети мобильной телефонной связи и физический мир 543 &             POST   XML.     saveUpload()         POST                postFile()       $   . /                    output. 2  "       JavaScript          %  (#)             device. 0                      Twilio: function postFile(request, response) { var fileName = __dirname + '/public/' + request.path; var data = fs.readFileSync(fileName); output = String(data); for (property in device) { var searchTerm = new RegExp('#'+ property, 'g'); var value = String(device[property]); output = output.replace(searchTerm, value); } response.writeHead(200, {'Content-Type': 'text/xml'}); response.end(output); }     ,          MQTT      "   . = $           "   announce()  readMessages()   - : function announce() { for (property in device) { client.subscribe(device.name + '/' + property); // $     } } &             POST     XML,  "         postFile()      . ;       mqtt.connect()          " "  : server.listen(8080); //   $ HTTP server.use('/',express.static('public')); //   , //  '    %  server.post('/upload', type, getUpload); //   %  //   server.post('/*.xml', postFile); client = mqtt.connect(clientOptions); // $  client.on('connect', announce); // N    //   client.on('message', readMessages); // N //        function readMessages(topic, message) { topic = topic.toString(); // $       var strings = topic.split('/'); // K   //     var origin = strings[0]; // ‰        //    var property = strings[1]; //   —  . if (property === 'temperature' || // •  !  //   property ==='mode' || //   property === 'setPoint') { device[property] = Number(message); } else { //    —    //           device[property] = (String(message) == 'true'); } } /  %          .
Глава 10 544 &       ,          ,                Twilio. #     ,     % . 4        ,         %   ,                       . 2  ,  %  . 2            MQTT    - ,         .   ,              !     ,    $      % ,      . & ,       , — $    TwiML            HTTP          POST        MQTT,  .   , "     %    API  node.js,     TwiML,        "   %    ,           . Интерфейсы на основе текстовых сообщений Обмен текстовыми сообщениями быстро стал одним из наиболее распространенных применений мобильных телефонов. Многие считают текстовые сообщения не столь раздражающими вторжениями в их личное пространство, как телефонные звонки. Текстовые сообщения позволяют быстро передать информацию, не тратя времени на разного рода предварительные разговоры. Кроме того, сообщения электронной почты легко посылать как SMS и наоборот — эта возможность не зависит от какой-либо конкретной платформы. Все, что для этого нужно, — это мобильный телефон и учетная запись электронной почты. А для ситуаций, когда требуется немедленное и малозаметное извещение, или для предоставления простой инструкции, SMS-ка — самое то. #  SMS                         . +     ,          "              ,       . /   "           ,  "     "            "  . *    SMS              ,        %          . #"  SMS       160 ,               $ 160  %     .               % SMSemail,  $   ,      "  SMS          ". =    $            "  ,       ,     $     . &     %       , "          MMS12       "  SMS.      " —        % "  . 3  %            SMS-      $     — $        $             ,  @    $       . =                    "  SMS  $            #3,    4  : 12 MMS, Multimedia Messaging Service —      "  . 
Сети мобильной телефонной связи и физический мир ? AT&T: phonenumber@txt.att.net; ? T-Mobile: phonenumber@tmomail.net; ? Virgin Mobile: phonenumber@vmobl.com; ? Sprint: phonenumber@messaging.sprintpcs.com; ? Verizon: phonenumber@vtext.com; ? Bell Canada: phonenumber@txt.bellmobility.ca; ? Telenor Norway: phonenumber@mobilpost.no; ? Telia Denmark: phonenumber@gsm1800.telia.dk; ? Swisscom: phonenumber@bluewin.ch; ? T-Mobile Austria: phonenumber@sms.t-mobile.at; ? T-Mobile Germany: phonenumber@t-d1-sms.de; ? T-Mobile UK: phonenumber@t-mobile.uk.net. 545 *   %         -   www.emailtextmessages.com (    ,        $  ). &  ,      , "       (   phonenumber),     .          ,        $                   . [                    E.164     +nnnnnnnnnnnnnnn. > n    ,        12  15,     ,         — $    . ;   ,       ,      #3                 $   . $          %                . Отправка SMS через Twilio # "    node.js     HTTPS,          Twilio     "  SMS. /              % SMS        . #          TwilioSms,    —   : smsClient.js  twilioCreds.js. [  twilioCreds.js      ,  "      API Twilio,         . &  $               Twilio. #       "   (       %    ): module.exports = { apiKey: 'Axxxxx', // ' %  API Twilio auth: '1xxx', // ˆ  % #   Twilio number: '+15555555555' // ^  % Twilio } Защитите этот сценарий &   " $    %    "       %   . 4       - -        ,          .
Глава 10 546 Сценарий для отправки SMS '   SMS   Twilio,       HTTPS POST     API Twilio. &           node.js   https  querystring.           JSON          HTTP,            twilioCreds. js. *              : /* [  "  SMS        — "        : To (), From (0)  Body (; ,      "  ). ;  "      % 1600 . *              E.164.    postData      "       : var message = { //     SMS To: recipient, From: creds.number, Body:'  !' }        HTTPS          HTTP,      . # Twilio                 API                   . ;  "             ,            querystring: //   $ HTTPS var options = { host: 'api.twilio.com', auth: creds.apiKey + ':' + creds.auth, port: 443, path: '/2010-04-01/Accounts/' + creds.apiKey + '/ Messages', method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', ‘Content-Length’: postData.length } };    ,   HTTPS  "                    confirm()       . /       %      : data  end. 0         , $   gather()    $      // • #   $  $ function confirm(response) { var result = ''; // Z    -   function gather (data) { // response 'data' callback // function result += data; }   HTTPS  %  API   : node.js SMS Twilio */ var https = require('https'); // '    https var querystring = require('querystring'); // ' //    querystring var creds = require('./twilioCreds.js'); // ' %  //    Twilio var recipient = process.argv[2]; // ^  % $ //   $    // $     $    HTTP var postData = querystring.stringify(message); function printResult () { // • #   $ //  end console.log(result); }
Сети мобильной телефонной связи и физический мир   ,    printResult()       $  : 547 response.on('data', gather); // Z    //   #   $  response.on('end',printResult); // +   // $   R } * ,       HTTPS. ;          ,    end()  %    : #    "       : //   $ HTTPS var request = https.request(options, confirm); // ^  // $ request.write(postData); //   request.end(); //  $       $ node smsClient.js +15555555555 2   $       ,      % ,  ,        "  SMS. &      Twilio     XML,                 "  «  !». ;    ,       ,          Twilio       %         , "  SMS           Twilio             . =  XML           " :      ,    ,    (     ,     . .)   .       TwiML,  Twilio       API REST,     %     "    ,          %     . ~     %               ,  $                 node.js,        %          . ;                   -  ,                      "  SMS. Получение SMS через Twilio &     "  SMS,    ,    . &             "    Twilio. ' , %              "  . #      smsServer.js              SMS. =          express  body-parser. 0 $            : $ npm install express body-parser 2           Twilio, "      All Products and Services (            %    ),   %        Programmable SMS    "          Create New Messaging Service (#   "  ).           Create. &  %           PROCESS INBOUND MESSAGES (   " " ),      REQUEST URL   (URL)    - ,       ,    : http://. .. :8080/sms. *   Save. 2      Numbers          ,        Twilio. ;                 SMS- "     Twilio. /        express   node.js       POST   /sms           TwiML.
Глава 10 548 Сценарий для получения SMS    ,     POST        ,                getText(). /      $   From  Body " ,                request.body —      ,     Twilio         : &            HTTP,       "         POST "  SMS: /* Z   TwiML : node.js */ var express = require('express'); // '    // express var server = express(); // Z$ " server, $  //    express var bodyParser = require('body-parser'); // ' //    body-parser function getText(request, response) { console.log(request.body.Body); var twiml = '<?xml version="1.0" encoding="UTF-8"?> \ <Response> \ <Message to="+15555555555">Z  $  </Message> \ </Response>'; // +  $   +15555555555    % response.writeHead(200, {'Content-Type': 'text/xml'}); response.end(twiml); } server.listen(8080); //   $ HTTP server.use(bodyParser.urlencoded({extended: true})); //  $    $ server.post('/sms', getText); //   $    /sms 2  $        ,          "     Twilio. Микроконтроллеры в мобильных телефонных сетях Напрямую подключать микроконтроллеры к мобильным телефонным сетям позволяют сотовые модемы. С их помощью микроконтроллеры могут подключаться к Интернету так же, как это делает любой смартфон. Обладающий собственным телефонным номером модем может посылать и принимать сообщения SMS, осуществлять запросы HTTP, — в общем, делать в Интернете все, что можете делать вы сами. Модемы имеют определенные ограничения, но без них не обойтись, когда нужно организовать связь при отсутствии сетей других типов. Поэтому весьма полезно иметь хотя бы базовое представление об их работе. &                                 . &  2000-    +   "               . & "                    $  %   . ;                , 
Сети мобильной телефонной связи и физический мир 549          , %      ,                  % ,        .   . = %   %        4G       LTE17            100 7/  "    50 7/   ". 0                        "   "              ,   $         $         .                               . &       (2G)          "  SMS. 0        2G    GSM13. ~  GSM     ,           . *     $               %        GPRS14,               (                     3). &          (3G)         UMTS15,        GSM.   $         ,         ,           . /            EDGE16. &         (4G)                 ,  IP-   ,               . &          %   +  ,           ,                     ,              . ;   ,      $   "     "        2G    GPRS      HTTP    "  $     . /           ,           "      2G     . *         3G      LTE,            % .   ,                     "  SMS,            2G. 13 GSM, Global System for Mobile Communications —        . 14 GPRS, General Packet Radio Service — "      . 15 UMTS, Universal Mobile Telecommunications System —          . 16 EDGE, Enhanced Data Rates for GSM Evolution — % GSM     . *      ,            ,   $   ,            .   $,        , ,   ,       %              . &  , %                  «     »      ,                         % .   ,       ,    "     ,   "        2G,        , $           $             SMS,                  . 17 LTE, Long-Term Evolution —     .
Глава 10 550 Рис. 10.11. Сотовые модемы (слева направо): Fona 800 и Fona Feather компании Adafruit, Xadow GSM+BLE компании Seeed Studio, Cellular компании XBee, Electron компании Particle. Обратите внимание на антенны на модулях Fona, Xadow и Electron, которые нужны, чтобы обеспечить уверенный прием радиосигнала 7                           . >%           AT,              Digi    7. 7   ,   Digi      , "   4G LTE. &      GSM        SIM- 18. /                   IMSI19. ;                   IMEI20. *  IMSI  IMEI               ,                . 18 SIM, Subscriber Identity Module —     . 19 IMSI, International Mobile Subscriber Identity —          . 20 IMEI, International Mobile Equipment Identifier —           . Сотовые модемы *    %      ,           " $      . *  . 10.11  %   . 7 SparkFun     GSM/ GPRS SM5100B   Spreadtrum Technologies. 7       AT,         SMS- "         . 0  "   /  "    ,          ,          ,      %           . 7 %        $ ,         SIM-   "       . 7 Adafruit        Fona,      SIM80x    2G   SIMTech,    
Сети мобильной телефонной связи и физический мир  SIM5320    3G. &    "     SIM-       ,   Feather Fona    "      M0.   Seeed Studion       GSM RePhone,       SIM80x   SIMTech. 7  Core 2G-AtmelSAMD21   RePhone,    Feather Fona,        M0,         - . 0      %      Xadow GSM + BLE              AT,    SIMTech. * $     ,       "        .   Libelium (www.libelium.com)          Cooking Hacks (www.cooking-hacks.com),   $     $          SIMTech. 7 Cooking     Hacks          .   Digi   XBee          -      AT,      ,        7. /    ,        $  ,           .       ,        4G LTE,             +    . * Digi XBee Cellular   SIM-                . +          ,       ,   , %      .   Particle (www.particle.io)             Electron.            IDE     API,        Arduino,    $   . '   Electron,        , —        $  . #      551  Electron        « »           MQTT,             $  . +           %  %              Fona  RePhone. &  "            AT   SIM800,           $ . +     $       :     "     $ . *  ,  SIM800             .        $    ,        ,     ,      . =   $  %         —    ,       "          -  (LiPo)  . =    $       "      SIM-      . +           -  %      ,          GPRS          . 3        ,              . *   $         , $           %               .
Глава 10 552 Отправка SMS с сотового модема & $      ,     SIM800          "  SMS. /     ,    %             . 0     "          ,   "                       $  . = $                  SIM80x. *  . 10.12      (  )     (  !)         Fona800        Arduino 101. 2                    Feather Fona —       $     . 7         ,       —                   . &  Fona   Adafruit   RePhone   Seeed Studio  "      LiPo- . =    (   Fona Feather),       $   ,           . '         ,           1200 3,      —       . +                ,   "      « »               «  »      —                  . &               ,    "  ,     . SIM-  (%     ,  )               —       ,         —  "               . =     TX      RX   USB/ Serial,    RX —    TX. ;       « »        ,                 .      ,                 ,            9600      : AT 2        ,  % <Enter>. &              : OK 7            AT  OK  ERROR. =     "   %     : AT+CMEE-2 =           ,            : AT+CBC 0      +CBC: 0,100,4214. /   ,        100%  4,214 &. 2      IMEI  : AT+CIMI &            15-   ,       IMEI %   .      AT+GSN IMSI:
Сети мобильной телефонной связи и физический мир &     . 553      15- -               - : +COPS: 0,0, "T-Mobile USA" ;        : (     ,          : AT+COPS? ,  ), +COPS: 0 Рис. 10.12. Принципиальная (вверху) и монтажная (внизу) схемы подключения модуля сотового модема Fona800 к микроконтроллерной плате Arduino 101 +3,3 В Общий («земля») Reset 9 TX 8 RX Модуль микроконтроллера 15 кОм Светочувствительный резистор +3,3 В Модуль SIM800 «Плюс» питающего тока 5 4 A4 Кнопка 10 кОм Общий («земля») A B C D E F G H I J 1 1 5 5 Bat GND 10 10 Key 5V + SPKR - Ant ADC Rst PWR PS 15 Net Buzzer TX RX PWM NS 20 20 Vio 2.8V 25 25 30 30 A B C D E F G H I J 2000mAh RI Mic + - Key 15
Глава 10 554      ,                  %     . 7             : AT+CSQ 0        4           ,         "  SMS. '   "  SMS,           : AT+CMGF-1 OK AT+CMGS-"+15555556666" (   R        %) >     .  : +CSQ: 18, 99                        ,   "        "      . *     " ,    % <Ctrl>+<Z> (ASCII 0x1A). 4       "        ,                    "  . Сценарий отправки SMS микроконтроллером +   $                Feather Fona,         Arduino,   "         TX, RX     (Reset). 2             (+15555556666)     . 4     %      Twilio,            "  SMS   ,      "    . =           $        SoftwareSerial —                  "      : /*   : Arduino SMS   GSM SIM80 */ #include <SoftwareSerial.h> // '    // SoftwareSerial const int sim800Tx = 8; //      TX // RX   SIM80 const int sim800Rx = 9; const int sim800Reset = 4; //      //  (reset)   SIM80 const int pushButton = 5; //      //  '   int lastButtonState = HIGH; //      String phoneNum = "+15555556666"; // ^  %, //   '   // Z$      - TX RX: SoftwareSerial sim800 = SoftwareSerial(sim800Tx, sim800Rx);
Сети мобильной телефонной связи и физический мир 555 &   setup()                         . =          / . 0     ,             "     Arduino,                : void setup() { Serial.begin(9600); //    ' //  ' $ sim800.begin(9600); //     ' //  ' $ pinMode(sim800Reset, OUTPUT); // %     // / pinMode (pushButton, INPUT_PULLUP); &       ,              ,     . 2     "  OK      OK,     .find()   Stream. 4              "  , "    ,    "     false (): digitalWrite(sim800Reset, LOW); // +    delay(200); digitalWrite(sim800Reset, HIGH); delay(5000); // Š     $  while (!sim800.find("OK")) { //   '   ˆƒ sim800.println("AT"); } Serial.println("& GSM   ."); } &   loop()                    "    ,   $      "    (   ,                  6). 4       ,       "  "   sendSMS(),        " . void loop() { // Z     int buttonState = digitalRead(pushButton); if (buttonState != lastButtonState) { // † $  , delay(100); //  ,   - $  if (buttonState == LOW) { //  , int reading = analogRead(A4); // Z  //   String sensorReading = "{\"Sensor\":X}"; // Z$ //  %  JSON sensorReading.replace("X", String(reading)); // // Š $    Serial.println("sending..."); //  //   SMS int result = sendSMS(phoneNum, sensorReading); Serial.println(result); // 1 = } } lastButtonState = buttonState; // Z-   //      '   } 2        .replace()   String                  JSON. ;  ,     $ "    TwiML    "            : 
Глава 10 556 =      "  SMS       sendSMS(). & $          ,       . #       AT+CGMF=1        OK. 2       AT+CGMS=              %     >.  ,       ,  "           <Ctrl>+<Z>,      0x1A  ASCII. /              "  : //    SMS   int sendSMS(String phoneNumber, String message) { sim800.println("AT+CMGF=1"); //  %    if (!sim800.find("OK")) { // †       OK, return -2; // $   } sim800.print("AT+CMGS=\""); // ^   //   sim800.print(phoneNumber); // Š   % sim800.println("\",145"); // Š %    // ( $  #   ) if (!sim800.find(">")) { // †       >, return -1; // $   } sim800.print(message); // Š    sim800.write(0x1A); //  <Ctrl>+<Z> // $ %       return 1; // +$  $ - } &      . Советы по программированию модемов     $                phoneNum       . 4  %      (             ),                 " "  : {sensor: 234}     ,                   "  . #            $  ,                           ,  "      AT.          OK    %   ,  Stream     API Arduino              . &   - ,   .find() $         "         true (  )         , "         .            .findUntil(): .findUntil("#_", '\n'); /        ,     .find(),             ,       ,         (   $     \n). /                ,  "       .  Stream      .timeout(),            . 2    -      1   . ;  ,            .find()             ,       
Сети мобильной телефонной связи и физический мир 0 (false — ). 2    -      "  : sim800.timeout(5000); //    //  -  5          4,  Stream                    ,    Serial, SoftwareSerial, Wi-Fi    . 557 [  sendSMS()  %     "          : -2, -1  1. & "              %            . & %    -2    %      CGMF,  -1 — %      CGMS,   1 —   %       . ~  $        "      ,                . Отладочная программа     "                    ,             ,           ,                                  ,   . /     ,      «" !     Arduino      USB/TTL-Serial»    2. ;         Arduino              ,              . =     $     %              Feather Fona   SIM800. ~         ,             setup()   "                   : /*         : Arduino */ #include <SoftwareSerial.h> const int sim800Tx = 8; //      // TX RX   SIM800 const int sim800Rx = 9; // Z$      // TX RX: SoftwareSerial sim800 = SoftwareSerial(sim800Tx, sim800Rx); void setup() { Serial.begin(9600); // // sim800.begin(9600); // // }    '  ' $     '  ' $ void loop() { if (Serial.available()) { // Z   //     sim800.write(Serial.read()); //  //      } if (sim800.available()) { // Z   //      Serial.write(sim800.read()); //  //     } }
Глава 10 558 Приложения для операционных систем мобильных телефонов Хотя интерфейсы на основе веб-браузеров и SMS-сообщений предоставляют много возможностей, для некоторых проектов мобильное приложение может оказаться более подходящим, чем интерфейс на основе веб-браузера. Но если вы задались целью создать приложение для всех типов смартфонов, вам придется изучить все их операционные системы, а также используемые с ними программные средства. Однако существуют и более простые подходы к решению этой задачи. &               ,           ,    %  . *           Android   Google  iOS   Apple,   %       . +     Gartner Group (www. gartner.com/newsroom/id/3609817)   ,           2016  Android               ,   81,6      ,        iOS    %    %  . 9    Android     $    35   ,       2010 . ;  ,                    ,                    Android  iOS. =            iOS   ,   ,   Apple ID            https://developer.apple.com. >                       USB ($        sideloading21),            App Store. =              Android         21 >  «  ». =     iOS                      USB, Bluetooth, Wi-Fi         ,          . =     0# Android $                  APK      Android.    . & ,   $ , — $         ,    . Платформа PhoneGap 4                 ,        JavaScript,          PhoneGap (www.phonegap. com).   PhoneGap                  ,    $   HTML5  JavaScript. 9                (       HTML5),                    (,     )               ,            %          . 9                                : Java —  Android, Swift —  iOS. /      ,         . 2         HTML, CSS  JavaScript,               .      $            . &  "     PhoneGap      Adobe,  Adobe           Apache Foundation    Open Source   
Сети мобильной телефонной связи и физический мир Cordova (http://cordova.apache.org). *    $           .   PhoneGap    Cordova            ,         %  .   ,   PhoneGap       ,         %  . &    ,   -   PhoneGap Build (https://build.phonegap.com)            —           HTML,            ,             . ;  , PhoneGap Build       $                . 3          PhoneGap Desktop                     HTTP. &                     -  —  ,   $      node.js  p5.js. 2         PhoneGap Desktop  "    "      PhoneGap Developer. &   %, ,    Build,                  "   Adobe,     ,    " PhoneGap Desktop  PhoneGap Developer,         . '             ,     "          "   . X                 .           p5.js   PhoneGap                     Android  iOS.     ,              iOS      - 559      Apple, ,  ,                    iOS,    Android. &  "                   PhoneGap             PhoneGap  p5.js. 3         . Проект будет сложным! /            ,       . /      ,                      :       22   PhoneGap,  SDK  iOS  Android, p5.js,   —      , Bluetooth LE           $       . /            ,           ,           . X     ! Установка набора средств разработки PhoneGap *     PhoneGap             PhoneGap,  SDK  Android  iOS,            . PhoneGap          npm  " "     : $ npm install -g phonegap X   PhoneGap,     SDK        (Android  iOS),               . 22 SDK, Software Development Kit —    0.   
Глава 10 560 Набор средств разработки для iOS          iOS            macOS       XCode,           App Store   Apple.      $              XCode         . /    ,     "  : $ xcode-select --install         ,            iOS            Apple,        -   https:// developer.apple.com. #       Apple                     XCode. ;       "  : $ npm install -g ios-deploy Примечание 4           node  nvm  n,              "  : $sudo npm install -g iosdeploy --unsafe-perm-true --allow-root =              Cordova/PhoneGap  iOS       -   cordova.apache.org/docs/en/ latest/guide/platforms/ios. Набор средств разработки для Android          Android                 macOS, Windows  Linux,        "     SDK  Android. * SDK        Android Studio,        : https://developer.android. com/studio/. =         Android Studio      "   . ;       r25.2.3              . 2  $          "          "  : http://dl-ssl.google.com/android/repository/ tools_r25.2.3-windows.zip http://dl-ssl.google.com/android/repository / tools_r25.2.3-linux.zip http://dl-ssl.google.com/android/repository/ tools_r25.2.3-macosx.zip X     Android Studio,      "     Configure      SDK Manager. &  %    SDK Manager      System Settings  "     Android SDK. 0            ADK. &      "   Android     5.1 Lollipop,            . X    Android        ,               ]  | D   | D    (   )  ]  |   + (  % ). *  . 10.13  $      0   % . X    Android SDK,                     PATH,       ,  PhoneGap,  ,    . 0    $                  .bash_profile — $ %                 (        bash): $ nano .bash_profile
Сети мобильной телефонной связи и физический мир 561 =  $    "   : ?      macOS: export PATH=$PATH:~/Library/Android/ sdk/tools:~/Library/Android/sdk/platform-tools: ? =     Linux: export PATH=$PATH:~/Android/sdk/ tools:~/Android/sdk/platform-tools: ? =     Windows 10      Cygwin: export PATH=$PATH:/cygdrive/c/Users/ username/AppData/Local/Android/Sdk/ tools/ '     ,    % <Ctrl>+<X>,  % <Y> ,  , % <Enter>. '      ,        ,       . * ,    (    )               tools. =     macOS   $ : ~/Library/Android/sdk/,  Linux — ~/Android/sdk/,   Windows — C:\Users\  _   \AppData\Local\ Android\Sdk. 4          tools,  . +                     ,        PhoneGap  Cordova. ;              PhoneGap. Рис. 10.13. Пример экрана About tablet (О планшете) с информацией о версии Android Подготовка устройства Android Android       $ $  ,             D   . =     $   ,              Android 5.1    . '      Android            $        ,   (A   ,          USB. = $       Android      ]  .                 D   (    :  & ,   +  . .). 0 %    (       . 10.13)       %      . &  '  %   ,   Build number (*  )  ,           "  ,    " ,       . ;         ]              . * $      "  $       USB (USB Debugging). ;                   .
Глава 10 562 Создаем проект PhoneGap '     ,  PhoneGap        SDK           p5.js,       ,  "  $   . = $     PhoneGap,     "           : $ phonegap create buttonApp com. example.buttonapp ButtonApp '   $      ?        PhoneGap       buttonApp. 0                       . #   ,      : com. example.buttonapp —      ,           %    . 2       com.example     . * ,      : ButtonApp — $      XCode  Android Studio. =     buttonApp        "     :      . *         p5.js,          $   . 0    ,     $   <platform name="ios">  <platform name="android">,       <icon>  <splash>,  PhoneGap           . ;        ,                   , —   Windows  Windows 8.  platforms       "           . +      ,            "  : $ phonegap platform add android  $ phonegap platform add ios      $   PhoneGap         SDK,          platforms       . X     "   : phonegap platform rm $ls Вниманию разработчиков iOS! =     "  : CONTRIBUTING.md config.xml platforms www README.md hooks plugins [  config.xml        . 0     package.json     node.js     ,         ,   ,              ,       . & %            ,   $    "             PhoneGap               iOS,       XCode        .     platofms/ios/      XCode   ButtonApp. xcodeoroj —        . ¥            ,               . X      (developer team)       (individual developer),      . #          . #  PhoneGap           %   Bluetooth,   . .   plugins. 7 ,  $   ,     $      $   . 3   hooks               . &    $    hooks   .
Сети мобильной телефонной связи и физический мир #          HTML, CSS  JavaScript  "      www. =    $  PhoneGap    % ,          p5.js. *  $            HTML. X  www          p5.js    www. #                 p5.js. +           p5-manager,   www      p5.js          "  : $ $ $ $ rm p5 cd p5 563 ;            .            index. html     p5.js     ,         . /                    p5.js  ,                ,            ,       %   . -rf www g -b www www update Создаем свой файл index.html # "   index.html             index.html     p5.js. ;  meta    head            PhoneGap       . 0        ,              ,            JavaScript                . ;        cordova.js,   PhoneGap         . 2         p5.js     JavaScript. 0      ,  $       body  ,     head. #  PhoneGap    $  ,              : <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta name="format-detection" content="telephone=no" /> <meta name="msapplication-tap-highlight" content="no" /> <meta name="viewport" content="user-scalable=no, initial-scale=1, maximumscale=1, minimum-scale=1, width=device-width" /> <meta http-equiv="Content-Security-Policy" content="default-src 'self' data: gap: 'unsafe-inline' https://ssl.gstatic.com; style-src 'self' 'unsafe-inline'; media-src *" /> <title>ButtonApp</title> </head> <body> <script type="text/javascript" src="cordova.js"></ script> <script src="libraries/p5.js"></script> <script src="libraries/p5.dom.js"></script> <script src="sketch.js"></script> </body> </html>
Глава 10 564 Создаем и исполняем приложение =       "  ,                 . /* =   sketch.js          "      1. #  "             $         :    $   ( ),         — touchEnded (  "    )      $   (   responseDiv). =         : var myButton, responseDiv; // ‰  DOM ;          "  $    .                 . M'  : p5.js    ,    ' */ function setup() { createCanvas(windowWidth, windowHeight); // Z$ - myButton = createButton('click me'); // Z$  myButton.touchEnded(changeButton); //  % # ' //     myButton.position(10, 10); //     responseDiv = createDiv('catch me'); // C$ //  $ div responseDiv.position(10, 40); //     } // \   '       R: function changeButton() { var x = random(windowWidth) - myButton.width; // ^ //   var y = random(windowHeight) - myButton.height; // ^ //   y myButton.position(x, y); //    responseDiv.html(x + ',' + y); //  $ responseDiv } Устройство под iOS     platofms/ios/         XCode   ButtonApp.xcodeoroj. ¥                    ButtonApp,                    . &   Signing            iOS,                      ,      : ButtonApp > Generic iOS Device. ¥             "  ,  " %    . &     ,             Signing. &                 iOS         -   $   Run   XCode, —       "   %  XCode. Устройство под Android          —            %  USB $  . *   Yes. &     :       " $ phonegap run android --device =            iOS   android  ios. 4               ,          phonegap build. 4                  ,
Сети мобильной телефонной связи и физический мир 565 PhoneGap                         "   . &     $       "   ,            %   %  .    %   PhoneGap                 %      . 4        ,             Android            . 10.14. Рис. 10.14. Результаты исполнения приложения на устройстве под Android Где исполняются приложения? 9             "    ,    $   . /   ,        "    .     XCode  iOS,    Android Studio   $    , "    "      . '   $  iOS,              XCode    ,     $ . 3               Android Virtual Device Creator,      android avd. *   $        Android Studio SDK Manager                    SDK.   , $        ,                        "    . ~  % $         ,   "         iOS  Android                .                        "      . Подытожим… 7   ,                   %,                    . =         %        ,         "   : 1. # "        PhoneGap     . 2. 0    config.xml. 3. =           . 4. = iOS      5. X  www       p5.js   www. 6. 0    index.html.  .        7. *%    . 8. &       . 9. 2         . /       %        %        .
Глава 10 566 Проект 31 Мобильный регистратор личных биометрических данных Одной из причин популярности разработки собственных приложений для смартфонов является возможность использования беспроводного канала Bluetooth для организации связи смартфона с другими устройствами. Это позволяет использовать смартфон в качестве шлюза для отправки данных на какой-либо веб-сайт в Интернете. В этом проекте мы будем с помощью микроконтроллера замерять гальваническую реакцию кожи, отправлять полученные данные по Bluetooth на смартфон, а затем сохранять их в файле в Интернете. Требуемые компоненты  X     0# Android  iOS, 1 %.  7 RedBear BLE Nano, 1 %. +       :   / ,  Bluetooth LE.  USB- MK20   RedBear BLE Nano, 1 %.      %    2,5    % .  -  =       .     .           .  9   270 0, 1 %.   %      .  ; "   %.  0   " 13  .   Shieldit Super, &   "   $              :                           ,  %       . 2                   Quantified Self23 (http://quantifiedself. com),             ,  $  ,            FitBit (www.fitbit.com)  Apple Watch,  "         . *  "                                 . /        ,      ,             .  2   «».  ;  % , 1 %.  *   % . Рис. 10.15. Мустафа Багдатли с устройством Poker Face24 — регистратором биометрических данных, связанным со смартфоном. Фотография предоставлена самим Мустафой Багдатли (Mustafa Bagdatli) 23 *           : «[   ]   ». &         : «    `». 24 Poker Face (*     ) —       ,          ,   %       .
Сети мобильной телефонной связи и физический мир *%                      7  > (  . 10.15). 7  %      -    (q9)       ,    ,              , —               q9. 4    Poker Face (  . 10.16)    $          "  Arduino LiliPad     Bluetooth    ,       +   . >        Poker Face       -   7    : http:// mustafabagdatli.com. 7       ,      7  ,   —   "  —           . &         q9         ,   %   . *  . 10.17   -     . 7    ,    "            Bluetooth LE,                 ,   , - Рис. 10.17. Блок-схема системы проекта мобильного регистратора биометрических данных 567 Рис. 10.16. Напульсник из проекта Poker Face с пришитыми контактами датчика крупным планом. Напульсник показан вывернутым наизнанку, чтобы контакты были лучше видны. Фотография предоставлена Мустафой Багдатли   ,  $          6.                          .                      .     Upload (&  )         HTTP GET     node.js,       -  ,      "    . '   % $  , %  . Файл для данных Связь HTTP по GSM или LTE Смартфон Интернет Сервер на node.js Веб-сервер Канал Bluetooth LE Аналоговый сигнал 0–3 В Датчик КГР Микроконтроллер
Глава 10 568 Схема системы 7     $          . 10.18,    "      —   . 10.19.     ,   $        . Vdd A4 - - + + LFT D0/RX Vin GND D2/CTS D3/RTS D1/TX GND SWCLK A3 SWDIO Рис. 10.18. Монтажная схема мобильного регистратора биометрических данных. Контактные площадки датчика выполнены из токопроводящей ткани. Кнопки пришиты к ткани токопроводящими нитками. К кнопкам и к компонентам припаяны провода (красный, синий, черный). Наличие отстегивающихся кнопок позволяет снять электронные компоненты с одежды для ухода за ней — например, для стирки Рис. 10.19. Принципиальная схема мобильного регистратора биометрических данных +3,3 В +3,3 В Держатель для таблеточной батарейки Модуль микроконтроллера с возможностью связи Bluetooth LE Контактные площадки из токопроводящей ткани A4 Общий («земля») 270 КОм Общий («земля»)
Сети мобильной телефонной связи и физический мир 569 & ,          -  , — $        % . '     $,                . &  ,              —        . &    -        ,    ,             . &  ,          .             ,      ,         . & $               %     .    ,   ,  %              %    ,              , ,    ,                    . & $           BLE Nano   RedBear Labs, "        ARM M0,        "  Arduino IDE,   Bluetooth LE 51822   Nordic Labs —    Bluetooth,       Arduino 101. $         Arduino 101,    "          BLEPeripheral   CurieBLE. *        -       Arduino 101   %   %     . ;   ,    $        BLEPeripheral,           Arduino    Bluetooth nRF51822  nRF8001   Nordic Labs —              Bluetooth LE    6. =           BLEPeripheral CurieBLE     $   .  ,            ,  %           ,             270 0      ( .  . 10.18  10.19). 9  ,             ,  %     % . *   $       ,       % 10 0     . &                 ,        LilyPad Coin Cell Battery Holder  SparkFun. 4             %  ,           LilyPad Simple Power $   ,  "         LiPo           USB. =                      "     " . 9  "             $     , $    $       ,    ,      %  . &           7           "  ,  %     ( .  . 10.16). `             "   Shieldit Super    . Подготовка схемы к тестированию & %              , %    ,       . ~ $                        LilyPad  Flora,    ,               ,     %       . $,                  %     ,           ,    -    Bluetooth LE —  LightBlue  iOS  macOS  nRF Connect  Android.
Глава 10 570 #           Bluetooth LE  $           ,                q9,   %                 %           . =       BLE Nano        %    ,           "      USB/Serial MK20 USB. *  %                 ,              . #    ,     ,           $         MK20 USB. /    %         %                  (  . 10.20). &             BLE Nano    MK20 USB    - . Рис. 10.20. Подключение платы Bluetooth BLE Nano к адаптеру MK20 USB без припаивания штыревых разъемов может быть сопряжено с трудностями. Эти трудности можно преодолеть, используя длинные штыревые разъемы и устанавливая плату на адаптер с некоторым перекосом, обеспечивающим надежный контакт &       BLE Nano  %         " , $                %   . = $    %      - (  . 10.21), "        ,  $     « ». *,       ,  - %                  . Начинаем разработку кода & $          ,          %     . 2       ,       ,           "   ,         . 4   $     BLE Nano,        Arduino "    . = $ Рис. 10.21. Сборка проекта для тестирования с помощью крючков-клипс
Сети мобильной телефонной связи и физический мир 571 Носимые микроконтроллеры 4             $       ,          "          . _  LilyPad,   _ > (Leah Buechley)        SparkFun,       ,          ,     $    .   Adafruit     Flora           . X      LilyPad                  "    /   "    ,        Flora    $ %     I2C       WS2812              . 0               ,          ,      .   Seeed Studio         $        %        ,  ,     ,    Pebble. 0        $           Bluetooth LE    Flora Bluefruit LE,     Adafruit.  ,  $             \ | ]       !     " A    %     ]   http://redbearlab.github.io/ arduino/package_redbearlab_index.json. &        BLEPeripheral   #  7  ,           ,     BLE Nano,            / ,               . & %    $                           Flora. ; ,            "      BLE Nano,  %        %  ,         %    ,        %       .   , $     $    ,                LilyPad  Flora. =        "         _ > «Sew Electric» (   HLT Press), #  (Syuzi Pakhchyan) «Fashioning Technology: A DIY Intro to Smart Crafting» (   O’Reilly)           ~  -X  (Hannah Perner-Wilson)    http://www.plusea. at.   ,   -   >   (Becky Stern)    https://beckystern.com                     .     12   6. X   $        Arduino "     . =           -   https://github.com/sandeepmistry/ arduino-BLEPeripheral. Пишем скетч для чтения показаний датчика КГР    ,                                  . ;           : /* Z  -  : Arduino,  nRF51822 */ #include <SPI.h> #include <BLEPeripheral.h> #  nRF8001
Глава 10 572 //      ($  $   //  /) #define BLE_REQ 10 #define BLE_RDY 2 #define BLE_RST 9 int lastInput = 0; //   $  $    int threshold = 10; //  $  $ # $ //   2 %               BLEPeripheral,          : BLEPeripheral blePeripheral = BLEPeripheral(BLE_REQ, BLE_ RDY, BLE_RST); =                  ,           ,                         . // Z$ -    $     // $ : BLEIntCharacteristic sensorCharacteristic( \ "0927ADA8-3588-11E7-A919-92EBCB67FE33", BLERead | BLENotify); BLEIntCharacteristic thresholdCharacteristic( \ "0927AF9C-3588-11E7-A919-92EBCB67FE33", BLERead | BLEWrite); // Z$   BLEService sensorService("0927AA6A-3588-11E7-A919-92EBCB67FE33"); = $          25  UUID (         ),   Android 7       UUID: &   setup()               . =   ,      ,       ,                  : 25 UUID, Universally Unique Identifier —        . void setup() { Serial.begin(9600); // \ #  $    ' $ //  "     %  UUID //   blePeripheral.setLocalName("BleNano"); blePeripheral.setAdvertisedServiceUuid(sensorService.uuid()); // add service and characteristics to device blePeripheral.addAttribute(sensorService); blePeripheral.addAttribute(sensorCharacteristic); blePeripheral.addAttribute(thresholdCharacteristic); // set initial value for threshold, and begin: thresholdCharacteristic.setValue(threshold); blePeripheral.begin(); Serial.println("BLE LED Peripheral active"); }
Сети мобильной телефонной связи и физический мир 573 &   loop()             .             :                 ,                  . 4   "             "      %,        ,              : void loop() { BLECentral central = blePeripheral.central(); //   // '  //   '  if (central) { Serial.print("Connected to central: "); // + //  #   Serial.println(central.address()); //  #   ' while (central.connected()) { if (thresholdCharacteristic.written()) { threshold = thresholdCharacteristic.value(); } int input = analogRead(A4); if (abs(input - lastInput) > threshold) { sensorCharacteristic.setValue(input); Serial.print(threshold); Serial.print(","); Serial.println(input); } *        "           lastInput —          "     "   : lastInput = input; } * ,            ,           " "  : // ž   '  Serial.print("Disconnected from central: "); // '    #  : Serial.println(central.address()); } } Тестируем код скетча 2              ,    -      Bluetooth LE (   , LightBlue  nRF Connect)  %          . %       .      "      ,            . 4       , % "     LightBlue  nRF Connect           ,       ,       . ;               —         %         . *    $     "               . Монтаж компонентов проекта в толстовку = $             ,  "     ,     "         ,           " . 2       ,       $    ,          . &  ,            "        "         . 7      %             ,         %   ,             
Глава 10 574  .      %,        30AWG (   ,        3).       ,    "   ,         , — $                     . ; "          "                      %   (        ).             ,  "             (                    ), —              ,  %        . 9                . 10.22 ( ,  ,         ,    . 10.18). 4  %  "          (,   ,   LessEMF),              " . 9                %       ,           ,       . *  . 10.23           .               % . >   ,   %                    ,          .  $               . ' "      $,     "    LightBlue  nRF Connect,                      . X % ,        ,                . Рис. 10.22. Размещение компонентов на внутренней стороне толстовки: микроконтроллер и держатель батарейки пристегиваются кнопками. Пайка кнопок не представляет никаких сложностей, но ее следует выполнять на защелкнутых кнопках, чтобы припаиваемые части не деформировались от тепла паяльника. Постарайтесь не пришить кнопки питания к контактам датчика на внутренней стороне толстовки, что может создать короткое замыкание Рис. 10.23. Контактные площадки из токопроводящей ткани внутри кармана толстовки
Сети мобильной телефонной связи и физический мир 575 Мобильный клиент на PhoneGap Z      $          PhoneGap,            ,               . 7    %  $     . *        PhoneGap,     : $ phonegap create BleDatalogger com. example.bledatalogger BleDatalogger   $     : $ cd BleDatalogger 2        config.xml,       <icon>  <splash>  $   <platform name="ios">  <platform name="android">,         . #    ,       ,     "   (         iOS   android  ios): $ phonegap platform add android   $   BLE Central  PhoneGap  Cordova: $ phonegap plugin add cordova-pluginble-central Рис. 10.24. Внешний вид готового приложения для Android +    www     p5.js: $ $ $ $ $ cd rm p5 cd p5 BleDatalogger -rf www g -b www www update Примечание =         BLE Central .      -   github. com/don/cordova-plugin-ble-central. 9       iOS,      /platforms/ios/   BleDatalogger. xcodeproj          . ;                ,     ,        index.html  sketch.js. *  . 10.24  ,      $               Android.
Глава 10 576 Создаем страницу index.html =        index.html      . 0       $         "     PhoneGap        connect-sic    Content-Security-Policy,            : Вставьте IP-адрес своего веб-хоста Замените выделенный полужирным шрифтом IP-адрес на IP-адрес своего веб-хоста. Наше приложение будет подключаться к нему, чтобы сохранить полученные от датчика данные. <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta name="format-detection" content="telephone=no" /> <meta name="msapplication-tap-highlight" content="no" /> <meta name="viewport" content="user-scalable=no, initialscale=1, maximumscale=1, minimum-scale=1, width=device-width" /> <meta http-equiv="Content-Security-Policy" content="default-src 'self' data: gap: 'unsafe-inline' https://ssl.gstatic.com; connect-src http://192.168.0.10:8080; style-src 'self' 'unsafe-inline'; media-src *" /> <title>ButtonApp</title> </head> <body> <script type="text/javascript" src="cordova.js"></script> <script src="libraries/p5.js"></script> <script src="libraries/p5.dom.js"></script> <script src="sketch.js"></script> </body> </html> Пишем код скетча p5.js #  p5.js       $        . *                       ,        ,                         .   ,                    —                   . 4"                         $  . * ,                         ,                 ,      (URL)     JSON            : /* Bluetooth Central  PhoneGap :p5.js  PhoneGap \$    Š    (Don Coleman)cordovaplugin-ble-central  PhoneGap/cordova */ // ‰  %  $ var deviceList, responseDiv, dataDiv, autoUpload; var scanButton, connectButton, disconnectButton, uploadButton; var autoUploadTimer; // ƒ      $ $ var connectState = false; // Z  '  //  %    //        var dataServer = 'http://192.168.0.10:8080'; var readings = new Array(); // $    $  //       %    BLE var myDevice = { serviceUUID: '0927AA6A-3588-11E7-A919-92EBCB67FE33', sensorCharacteristic: '0927ADA8-3588-11E7-A91992EBCB67FE33', id:'' };
Сети мобильной телефонной связи и физический мир &   setup()           $                             . ;         ,                 $  . 577 function setup() { // Z$    , ' , '  // $ $ : scanButton = createButton('Scan for devices'); scanButton.touchEnded(scanForDevices); scanButton.position(10, 60); scanButton.size(80,40); connectButton = createButton('connect'); connectButton.touchEnded(connectToDevice); connectButton.position(100, 60); connectButton.size(80,40); disconnectButton = createButton('disconnect'); disconnectButton.touchEnded(disconnectFromDevice); disconnectButton.position(190, 60); disconnectButton.size(80,40); [  draw()  $      ,                   $         ,         $   . uploadButton = createButton('Send to Server'); uploadButton.touchEnded(sendToServer); uploadButton.position(10, 250); uploadButton.size(80,40); // Z$ %    $ $ autoUpload = createCheckbox('Upload every two minutes', false); //       autoUpload.position(100, 250); autoUpload.changed(setAutoUpload);         $         ,      setup()    ,     Bluetooth: // Z$  $    responseDiv = createDiv('tap the scan button to begin'); // ^     ,    responseDiv.position(10, 150); responseDiv.style("font-size", "14px"); dataDiv = createDiv(''); dataDiv.position(10, 200); dataDiv.style("font-size", "14px"); //  , '  $ BLE ble.isEnabled(scanForDevices, bleError); } [          Scan for Devices           . #       $        deviceList          ,         . 2         $     ,       "  ,                : // \ #            BLE function scanForDevices() { responseDiv.html('scanning for devices.'); // †      $,  , //     : if (deviceList) deviceList.remove(); deviceList = createSelect(); // Z$  R   deviceList.position(10, 110); deviceList.size(150, 30) deviceList.option('Pick a device', ''); //  //      ' deviceList.changed(selectDevice); // +   5          serviceUUID
Глава 10 578 2  $         deviceList,       BLE,    ble.scan(). >  Cordova      ble,     % $    BLE.     ,  scan()                 ,        : myDevice.serviceUUID. =  "                       -: ble.scan([myDevice.serviceUUID], 5, discoverDevice, bleError); //  $   -   "  $  //   : setTimeout(ble.stopScan, 5000, scanFinished, bleError); }    ble.scan()         ,         discoverDevice(),     $           $         deviceList. +                      ,        $        MAC- (,   ,   )    : // \       function discoverDevice(device) { var result = device.name + ' ' + // Z$  //     'RSSI: ' + device.rssi; deviceList.option(result, device.id); // Š //    R   } [                  -              responseDiv: function scanFinished() { responseDiv.html('scan complete. Pick a device.'); // Z   $. +   . } [                            $   deviceList. 0         "     ,         MAC-    : // • #   $     $ //   $     function selectDevice() { myDevice.id = deviceList.value(); responseDiv.html('Selected: ' + deviceList.value()); } scanFinished() selectDevice()
Сети мобильной телефонной связи и физический мир 579 [       connectToDevice()           connect. 4       ,        .     %           onConnect(),      —   bleError(): // • #   $   '  connect function connectToDevice() { if (!connectState) { responseDiv.html('connecting to ' + myDevice.id); // '   ble.connect(myDevice.id, onConnect, bleError); connectState = true; } } [                %   %     . &      ble.startNotification()             ,                responseDiv: function onConnect() { //     -   ble.startNotification(myDevice.id, myDevice.serviceUUID, myDevice.sensorCharacteristic, onData, bleError); responseDiv.html('Waiting for data from ' + myDevice.id); //     ... } [  onData()    ,                   . =       ArrayBuffer,          16-           (Uint16Array),          $   $  . #   JSON,    "     ,     "        readings,                dataDiv: function onData (data) { var input = new Uint16Array(data); //   $  // $ " ArrayBuffer var reading = { // Z$ " JSON timestamp: new Date(), // Z$    value: input[0] // Š $  $  } readings.push(reading); // Š $     // readings dataDiv.html('latest: ' + JSON.stringify(reading)); } [       sendToServer()          Send to Server     while  $       readings,         GET HTTP        . [  "  GET: http://exam- function sendToServer() { responseDiv.html('uploading data...'); // +    ... while(readings.length > 0) { //    // $ , var reading = readings.pop(); // $  // $   readings // •       $ GET var path = '/data/' + reading.timestamp + '/' + reading. value; //   httpGet(dataServer + path, serverReply); } } onConnect() ple.com:8080/data/timestamp/ sensorValue.   -          ,        %         :
Глава 10 580 [                          ,         sendToServer()     ,        $ : function setAutoUpload() { if (!autoUpload.checked()) { responseDiv.html('Auto-upload off'); // ˆ$ $ ' //     clearInterval(autoUploadTimer); } else { responseDiv.html('Auto-upload on'); // ˆ$ $ ' // set timer to upload every 2 minutes // M     $ $  2   autoUploadTimer = setInterval(sendToServer, 2*60000); } } [  serverReply()      HTTP GET                  dataDiv: function serverReply(data) { dataDiv.html(''); responseDiv.html('Server said: ' + data); //  : } [  disconnectFromDevice()                disconnect. [                      onDicsonnect(),               responseDiv: function disconnectFromDevice() { if (connectState) { ble.disconnect(myDevice.id, onDisconnect, bleError); connectState = false; } } * , "      % bleError()        %          "   %         responseDiv: function bleError(error) { responseDiv.html(' there was a BLE error' + JSON. stringify(error)); //  $   BLE } setAutoUpload() &     . #   ,      PhoneGap      ,            : $ phonegap run --device function onDisconnect() { responseDiv.html('disconnected from ' + myDevice.id); // '    }
Сети мобильной телефонной связи и физический мир 4          ,                               Bluetooth LE,      ,     . *  . 10.25  ,          $   . 3   . 10.26    $     - 581 ,         %    .                   . 4   $ $       ,                    . Сохраняем показания на сервере #      server.js,     ,      ,          -           IP-a ,       dataServer    "    .    ,                " npm   express.js,          data.csv. #   $           , $             . #             GET     : Рис. 10.25. Толстовка регистратора личных биометрических данных в действии. Сколько радости и какой уровень возбуждения приносит его создателю такая возможность? Это можно узнать по его данным КГР в файле data.csv Рис. 10.26. Приложение регистратора личных биометрических данных в действии /data/timestamp/sensorReading
Глава 10 582 0          ,                         data.csv (              ). 2       ,           : /*   : node.js  $ GET HTTP   timestamp/reading */  %  /data/ var express = require('express'); // '    // express var fs = require('fs'); // '    %  //    fs var server = express(); // Z$ " server, $  //    express function log(request, response) { // %        $// $ $ var newData = request.params.timestamp + ',' + request.params.reading + '\n'; // Š     %   //    fs.appendFile('data.csv', newData, confirmSave); response.end('Last upload at ' + new Date()); //  $ $ ... } [       confirmSave()           fs.appendFile()        "           : function confirmSave(error) { var now = new Date(); // Z$   if (error) { // +     $  , console.log(now + ': ' + error); //    //       } else { //     - , //   '   console.log(now + ': ' + 'Saved to file'); // Z-  %  } } server.listen(8080); //   $ HTTP server.get('/data/:timestamp/:reading', log); //   // $ GET Диагностика 0            "     ,    Send to Server,    —     ,     Upload every two minutes. *              ,       "      . #             data.csv        " : Sat Apr 15 2017 14:59:47 GMT-0400 (EDT),20 Sat Apr 15 2017 16:48:41 GMT-0400 (EDT),20 Sat Apr 15 2017 16:48:41 GMT-0400 (EDT),22 Sat Apr 15 2017 16:48:40 GMT-0400 (EDT),18
Сети мобильной телефонной связи и физический мир 4      "   : ? ? ? ?  ,     - D     A  A  ? 4  ,             PhoneGap     ,         .  A>   A    †     &? 4  ,      sketch.js     %.       $             ,        index.html    .   $      Bluetooth   ,   $             . C    A         ? 4  ,   ,                     . 7         scanForDevices()     myDevice.serviceUUID                   Bluetooth.         ? 4  ,          URL  Content Security Policy   in  dataServer    dex.html    sketch.js. Рис. 10.27. Окно браузера Chrome для исследования устройств 583 Удаленная отладка 4       ,        ,     ,      %          ,        JavaScript    Chrome  Windows  Safari  macOS,       "       . =  ,  $  .         USB     ,       Chrome         : chrome://inspect. 0              ,        . 10.27. &             ,         %    . 0      ,                HTML  JavaScript. 0             " ,    $      ,  " ,    ,         JavaScript        -   .               Safari   iOS. =            -   
Глава 10 584 Web Inspector —          Settings              Safari | Advanced | Web Inspector. 3    Mac     Safari,              Preferences | Advanced       Menu Bar     Show Develop Menu. 2      PhoneGap  iOS,                 Develop | Phone | Apps | index.html. X        "   ,      % %    ,                      PhoneGap. Подытожим… *%                 ,       $   :          ,   HTTP,        JavaScript,       Bluetooth LE. 4         $          - "   ,       —           . 0          +           %   %   ,                  . *     $ ,             %  ,            ,      . &  "              ,  $   % ,          . ;            ,                  ,    . *%                             ,        . #       -  "    —  SMS  HTTP,              . Заключение По определению, сетевые устройства не болтаются в безвоздушном пространстве сами по себе. Поэтому, если устройство уже подключено к Интернету, следует воспользоваться предоставляемой им мощностью. Чем больше протоколов и инструментов вы знаете, тем легче и приятнее будет ваша работа. Обратите внимание на преимущества, предоставляемые серверами с общедоступными адресами и излишком вычислительных мощностей. Предусмотрите совместное использование проводных и беспроводных протоколов, чтобы оснастить разрабатываемые вами проекты максимальными возможностями реагирования на окружающую их физическую среду.         "     ,                 . 0       ,                             $   ,    $   . 0        ,           -   -  ,             . * $        ,                  . &            "    , "     24/7 (24     7    ).
Сети мобильной телефонной связи и физический мир 0      "        ,       # ,    $ "     . 0            ,                , —   ,          . *              ,       . 2          . 2                 . =     ,     ? ' $            %      $  ? 585 '        ,  -  "      ,                       . +         %         : ? %  % ,     ; ?     ; ?           ; ?     . +    "        % ,  $  " %   %      %       . Проект SIMbaLink. Разработчики Мередит Хэссон (Meredith Hasson), Ариэль Неварес (Ariel Nevarez) и Нахана Шеллинг (Nahana Schelling)   SIMbaLink                 %    $   ,  "     ,                -   SIMbaLink     GPRS. 9         $    /,   SIMbaLink  "        %        $      Awassa  /. #           "    10 ,              . /               ,  $       . 0    *   =%.

Приложение ГДЕ БРАТЬ КОМПОНЕНТЫ И ПРОЧЕЕ? В книге упоминается много разных поставщиков аппаратных устройств и источников программного обеспечения. В этом приложении приводится список всех используемых в книге компонентов и краткое описание их поставщиков. Приложение разбито на три раздела: ? компоненты; ? поставщики аппаратных компонентов; ? поставщики программного обеспечения.
Приложение 588 Компоненты В этом разделе приводится список всех компонентов, используемых в книге. Для каждого компонента указываются проекты, в которых он задействован. Со времени предыдущего издания этой книги ситуация с поставщиками претерпела некоторые изменения, поскольку одни компании получили новых собственников, а другие прекратили свою деятельность. Но, к счастью, на рынке все еще достаточно небольших поставщиков электронных компонентов, предлагающих интересные решения. Поскольку возможны обновления этого списка, посетите веб-страницу http://oreilly.com/ catalog/0636920010920, чтобы ознакомиться с ними. Коды поставщиков ? A — Arduino Store, https://store.arduino.cc ? L — LessEMF, www.lessemf.com ? AF — Adafruit, www.adafruit.com ? MS — Maker SHED, www.makershed.com ? AMZ — Amazon, www.amazon.com ? P — Pololu, www.pololu.com ? B — Belkin, www.belkin.com ? ? D — Digi-Key, www.digikey.com PS — PowerSwitch Tail, www.powerswitchtail.com ? DL — D-Link, www.dlink.com ? PX — Parallax, www.parallax.com ? F — Farnell, www.farnell.com ? RS — RS, www.rs-online.com ? ID — Identive, www.identiveusa.com ? SF — SparkFun, www.sparkfun.com ? J — Jameco, https://jameco.com ? SS — Seeed Studio, www.seeedstudio.com Инфраструктура       > . +         .  " Arduino 101. +     - N    >       Wi-Fi. +     %   .      . +        . -      $  1,5 . +        8, 9, 26  27          .  > ,  $    Bluetooth. +        3, 12, 18  31. 4  %   "   Bluetooth,     %   Bluetooth. AF: 1327, RS: 8077742, SS: 113990026  N   D Android        31. Микроконтроллеры, шилды и макетные платы  iOS. + - %    . D: 1660-1003-ND, J: 2239331, SF: DEV-13787, AF: 3033, F: 2520713, RS: 913-9999, SS: 114990575, A: ABX00005, GBX00005 (3   4#) " Arduino MKR1000. +      %    . AF: 3156, RS: 1240657, A: ABX00004, GBX00011 (3   4#), D: 1659-1005-ND " Arduino Uno. +      %    . D: 1050-1024-ND, J: 2151486, SF: DEV-11021, A: A000099, AF: 50, F: 1848687, RS: 715-4081, SS: ARD132D2P "      ATtiny84. +        4. D: ATTINY84A-PU-ND, SF: COM-11232, F: 1455160, RS: 738-0684    = ESP8266.     Adafruit ESP8266 Huzzah!   Adafruit  ESP8266 Thing Dev   SparkFun. SF: WRL-13231, AF: 2471
Где брать компоненты и прочее?       > Raspberry Pi. +        . ;    BeagleBone Green         Linux. SF: DEV13825, AF: 3055  3400, SS: 102010048  114990584, RS: 896-8660, F: 2525225  C      . +     %    . D: 438-1045-ND, J: 20723  20601, SF: PRT-12615  PRT12002, F: 4692810, AF: 64, SS: 319030002  319030001 589  D  RFID. +       -  24, 25  27. • D  SCL3711  -   SCL3711.  " NFC-  PN532. AF: 364, D: 1528-1781-ND, SS: 113030001 "  RFID Classic   Mifare. +       24–27. AF: 359  360, SF: SEN-10128  SEN-11319, SS: 113990013    Arduino. ;                       ,    $         %    . AF: 2077, A: TSX00083, SF: DEV-07914    A > IP-  • "     + . SF: PRT12044, AF: 65, D: 923273-ND &         H    &      . +        8, 9  27. AF: 1609, D: V2018ND, J: 616673, F: 4903213, RS: 159-5420 Модули связи    USB/TTL-Serial. +       . SF: DEV-09716  DEV14050, AF: 3309  284, SS: 317990026 " Bluetooth Serial. +        3  18. AF: 1588, SF: WRL-12580  WRL-12576 (  XBee   XBee Pro S2C 802.15.4. +        14. AF: 128, D: 602-1892-ND, SF: WRL-08665, J: 2253722, PX 32416 (  SX1276    HopeRF  RFM95W   Semtech. +        11. AF: 3072, SS: 113060006  USB/XBee-  . +        14. J: 32400, SF: WRL-11812, AF: 247, PX: 32400  (  Bluetooth LE. 7   -       12    Arduino 101  BLE Nano. AF: 1697   BLE Nano   RedBear USB MK20. +    . +       31 (        12). MS: MKRBL5, SF: WRL-14071 ID:  D-Link (             Raspberry Pi   Pi Cam). +        29  30. DL: DCS-930L, DCS5222L  DCS-960L.   ,   IP   Raspberry Pi   Pi Cam: •   Pi Cam. SF: DEV-14028, AF: 3099, SS: 113990214, RS: 913-2664 • ]     Raspberry Pi Zero W. A: 3414 D   • Adafruit Fona 800. #3 — AF: 3147, 4  — AF: 2691 • Adafruit Fona Feather. AF: 3027 • SeeedStudio 102040005 Xadow GSM+BLE. SS: • XBee Cellular. D: 602-1976-ND • Particle Electron Kit. #.  Š. 3 / 3   — SF: WRL-14211, 3 / 3/4  — SF: WRL-14212 Адаптерные платы и разъемы         . +        14. SF: B0B-08891, P: 1479  1639 % =    A  JST- ). +        13  15. SF: SEN08733 ()     «  » 9 '. +        3  13. D: 15681237-ND, J: 2207056, SF: PRT-09518, A: 80, F: 1650675
Приложение 590    )   2,1        , 5,5   + . +        3  27. D: CP3-1000-ND , J: 28760, SF: PRT-10287, A: 369, F: 1737256      A   . +        5  31. D: K386-ND, J: 22577, F: 09WX4670        A   . +        5. D: K445-ND  WSU-30M, J: 2150361, F: 441089  H     + 2,5 . +    %    . D: A26509-20-ND, J: 103377, SF: PRT-00116, F: 1593411    )  + 2,5 . D: ED7102-ND, F: 1122344, SF: PRT-00115        XBee.  +        14. SS: 113100001, SF: BOB-08276 H  ) +    +  2,5 . +      . AF: 400, SF: PRT-12693   )  + 2 . +        14. SF: PRT-08272, D: 3M9406-ND  D . +       7–9, Общие компоненты     100  \. +      -  D    100 . +       8, 9, 29  30. D: 100QBK-ND, J: 690620, F: 9337660, RS: 755-0707  D    220 . +        . D: 220QBK-ND, J: 690700, F: 9339299, RS: 707-7612  D    1 . +        . D: 1.0KQBK-ND, J: 690865, F: 9339051, RS: 707-7666  D    10 . +        2, 6  10. D: 10KQBK-ND, J: 691104, F: 9339060, RS: 707-7745        47 . +        14. D: A105657-ND, J: 254028, RS: 186205     10 . +        . J: 29082, SF: C0M-09939, F: 350072, RS: 249-9294  D    270 . +        31. J: 691446, D: CF14JT270KCTND, RS: 845-7577 11, 14  26. D: 160-1144-ND  160-1665-ND, J: 34761  94511, F: 1855510, RS: 228-5972  826-830, SF: COM-09592  COM-09590  % =     $  . +        1  4. D: 754-1492ND, J: 2125181, SF: COM-00105, F: 2290374, RS: 861-4290   &     . +        10  12. J: 106526, A: 387, SF: C0M-09469, F: 1716710, RS: 577-538, SS: MTR102A2B  D    A  5 '. +       14. J: 51262, D: LM7805CTND, F: 9756078, RS: 918-1971  D    A  3,3 '. +        14. D: 497-1491-5-ND, J: 242115, F: 1703357, RS: 438-4885     , 1  \. +       -  14. D: 1189-1324-ND, J: 94161, F: 8126933, RS: 475-9009     10  \. +       14  15. D: P11212-ND, J: 29891, F: 1144605, RS: 762-1736  14. D: P10269-ND, J: 158394, F: 1144642, RS: 762-1746    !    NPN TIP120. +        14  27. D: TIP120-ND, J: 32993, F: 9804005, RS: 808-0502  C     «  », 9 '. +  -      3.         9–12 '. +        14. SF: T0L00298, AF: 798, J: 170245, F: 1176248  C      3,5-5 '. +        13. AF: 771, D: BC4AAW-ND, SS: 320180002  <  -      . +        3  13. SF: PRT-13813  PRT-08483; AF: 258  2011  ! A     (CR2032)    . +        13. SF: DEV-10730  DEV-13883   PRT-00338, AF: 1870  1871 654.
Где брать компоненты и прочее? Специальные компоненты  ' . +        13. SF: T0L-10285, F: 1015878, RS: 244-890   &. +        13.  SS: 109990013, SF: T0L-11702, AF: 468 -&    . +         10  12. D: 365-1068-ND, RS: 654-8542        WS2812 (NeoPixels). +       13. AF: 2226, 2858  2859, D: 1528-1610-ND, J: 2247947, SF: BOB-13282, SS: 104990139 "  WeMo   Belkin. +       26. B: P-F7C027 ]     >$ . +        29  30. SF: KIT13815 D     . +         27. AF: 1512, AMZ: «uxcell DC 12V Open Frame Type Solenoid for Electric Door Lock»   >  PowerSwitch Tail. 3    ,       29  30. SF: COM-10747, AF: 2935, PS: 240vac Kits (   240 &  . .)    , 4N35. +        29  30. J: 41056, F: 1244500, D: 1601304-5-ND, RS: 597-302. 3            SparkFun S: B0B-09118 Датчики  !  . +       2  3. D: 905-1000-ND, J: 150551, SF: SEN10264, AF: 182, RS: 708-1277   >     &  A . +       2, 8, 9  10. D: GH1344-ND  SW400-ND, J: 2231822  119011, SF: C0M-09337, F: 1634684, RS: 718-2213 !     (†  )   . +        8  9. AF: 377, SF: C0M-10982 BOB-11722, SS: 311130001 (         400   Interlink. +       5. D: 1027-1001-ND, J: 2128260, SF: SEN09375, A: 166 591  '-    ) USB. +        5, 21, 22  23. \  (     ). +       6. D: PDV-P9200-ND, J: 202403, SF: SEN-09088, F: 7482280 !     Hanwei. +        14. SF: SEN-09405, P: 1481, PX: 60500009  &       GP2Y0A21YK   Sharp. +        12  14. J: 2150256, D: 425-2063-ND, AF: 164, F: 1243869, RS: 666-6564 N      HC-SR04, SRF04  †    . +        16. SF: SEN-13959, D: 1568-1421-ND GPS  . +        18. AF: 746, SF: GPS-1275 •     GPS Garmin GLO       -   https://www.garmin.com. •     GPS Bad Elf GPS Pro+        -   https://bad-elf.com.  ˆ &      LSM303DLH   ST Microelectronics. +       19  20. AF: 1120, SF: BOB13303, P: 1250, SS: 101020081  D       . +        8  9. SF: COM-10443  BOB-10467  !     A  DTH11. +        29  30. AF: 386, J: 2245415, SS: 101020011 Разное  (    . D: 3M156065-ND, RS: 120-6041, J: 2119718, A: 550 , SF: C0M10594, F: 1165068 H        18        "3   =. +        8, 26  27. = %                   ,    ,       ,         . D: 362204-ND, RS: 123-6835, F: 2301244
Приложение 592  '  "3    . D: 36-9300ND, RS: 274-5086, F: 2500400 "             1. . + - ]+    +     + " . +        2  3.  +  . +        5, 29  30.      . +      -  5.   &                   . +       5. D&  . +       6.  -            . +        10  12. "          10 . +        13. K      -   &    10 . +        13.   +  +    J        . +        14.   > -           (IC-hook with pigtail). +       31. SF: CAB-09741  CAB00501   +    A    5 . +       31. AF: 1126, SF: DEV-11347  %  $   . +        31. AF: 116, L: 1220  %   $  . +        31. AF: 603, SF: DEV-11791, L: 304  % . +        31.  ]   +      31. . +   Поставщики аппаратных компонентов Следующий список содержит всех поставщиков аппаратного оборудования для проектов из текущего и прошлых изданий книги, которые продолжают заниматься бизнесом. Abacom Technologies Adafruit Industries   Abacom         ,         ,      Ethernet/ TTL-Serial.   Adafruit         $       «   »       ,          AVR, MP3-      .  www.adafruit.com  sales@adafruit.com www.abacom-tech.com   abacom@abacom-tech.com Acroname Robotics   Acroname    %                 $    . 2              —        ,  ,            . *      "     %         . www.acroname.com   info@acroname.com Arduino Store 7 Arduino          % Arduino,            Arduino. store.arduino.cc   Atmel   Atmel         AVR,       Arduino, Wiring, BX-24      . &  "     Atmel       Microchip.  www.atmel.com
Где брать компоненты и прочее? 593 Charley Chimp ELFA ~ %,  %, $  $   ,   "      "      ?   ELFA —        " $       #   +  . charleychimp.com   customercare@charleychimp.com  www.elfa.se CoreRFID Farnell/Element14   CoreRFID    %          RFID      RFID.   Farnell    $       4  . *        ,          Newark  #3, $,      3 ,    Farnell            . www.rfidshop.com   info@corerfid.com D-Link   D-Link       USB, Ethernet  Wi-Fi,    Wi-Fi,       10. www.dlink.com   sales@dlink.com Devantech/Robot Electronics   Devantech       , $    ,       ,      ,                      .  www.robot-electronics.co.uk  sales@robot-electronics.co.uk  uk.farnell.com  sales@farnell.co.uk Figaro USA, Inc.   Figaro       ,            ,   ,         .  www.figarosensor.com  figarousa@figarosensor.com Future Technology Devices International, Ltd. (FTDI) Digi   FTDI          USB/TTL-Serial,     FT232RL,    "        $  .   Digi    XBee,      Ethernet. www.ftdichip.com  www.digi.com   sales1@ftdichip.com Digi-Key Electronics Glolab   Digi-Key —                 $    . X      %           :   ,    ,  ,   ,    ,  ,       .   Glolab      $        ,     -        ,        .  www.digikey.com  lab@glolab.com  www.glolab.com
Приложение 594 Gridconnect   Gridconnect          ,     Lantronix  Digi.  international@jameco.com  custservice@jameco.com Lantronix  www.gridconnect.com  sales@gridconnect.com   Lantronix    Ethernet/ TTL-Serial:  XPort, WiPort, WiMicro, Micro      . Images SI, Inc. www.lantronix.com   sales@lantronix.com   Images SI           $   . 2      %     RFID,     ,    ,  ,      $       ,          ,       $  ,       . Libelium   Libelium        XBee         . www.libelium.com  Linx Technologies www.imagesco.com   imagesco@verizon.net   Linx        ,       . Interlink Electronics www.linxtechnologies.com   info@linxtechnologies.com   Intelkink         ,           . Low Power Radio Solutions www.interlinkelectronics.com   specialty@interlink electronics.com IOGear   IOGear       . &    ,        %     USB/TTL-Serial,     Powerline Ethernet. www.iogear.com   sales@iogear.com Jameco Electronics   Jameco         $     ,  ,    ,            $           $   . www.jameco.com   domestic@jameco.com   LPRS      ,       . www.lprs.co.uk   info@lprs.co.uk Maker SHED   Maker SHED                 MAKE  %   . &  "                            ,  -      . www.makershed.com   help@makershed.com Maxim Integrated Products   Maxim   ,    ,        $          . 4 
Где брать компоненты и прочее?       Dallas Semiconductor. #    $                            ,     ,            . . www.maximintegrated.com   info2@maxim-ic.com Microchip   Microchip           PIC. 4        "         . 4       Atmel. www.microchip.com  Mouser   Mouser            $       #3. &        %     ,         $  , —     ,    ,    . X         -   USB/TTL-Serial  FTDI. www.mouser.com   help@mouser.com NetMedia   NetMedia        BX-24   Ethernet SitePlayer. www.basicx.com   siteplayer.com  sales@netmedia.com Newark/Element14   Newark    $      #3. *       ,          Farnell/Element14  4  , $,      3 ,   595   Farnell  Newark            .  www.newark.com  order@newark.com New Micros   New Micros         . 0        USB/XBee, "          XBee   Digi. /      "                     XBee       . www.newmicros.com   nmisales@newmicros.com Parallax   Parallax           Basic Stamp      Propeller. 0      %    ,     ",              ,   "    ,   $         . www.parallax.com   sales@parallax.com Phidgets   Phidgets                      . www.phidgets.com   sales@phidgets.com Pololu   Pololu        $                 . www.pololu.com   www@pololu.com
Приложение 596 RS Online SparkFun Electronics   RS Online —                 $     ,  "       .   SparkFun            $     . 0       ,     "  ,      %            .  www.rsonline.com  general@rs-components.com  www.sparkfun.com  customerservice@sparkfun.com Samtec   Samtec    $      . &     %     ,        $      ,  .       ,  ,  www.samtec.com  info@samtec.com Seeed Studio   Seeed Studio            $               . 0            $     ,         .  www.seeedstudio.com  order@seeed.cc Symmetry Electronics   Symmetry    ZigBee  Bluetooth,  Ethernet/TTLSerial,  Wi-Fi,       $       . www.semiconductorstore.com  TI-RFID   TI-RFID        RFID   Texas Instruments. 0          RFID           . www.tiris.com  Trossen Robotics   SkyeTek     ,          RFID. 0       Jadaktech,          OEM-       .   Trossen Robotics    %          RFID   ,    % ,        Interlink,    ,  Phidgets,    RFID,      %      RFID.  www.skyetek.com  www.jadaktech.com www.trossenrobotics.com   trsupport@trossenrobotics.com SkyeTek Smarthome   Smarthome          % ,       %        —     ~10,   INSTEON.  www.smarthome.com  custsvc@smarthome.com
Где брать компоненты и прочее? 597 Программное обеспечение Большинство используемого в проектах этой книги программного обеспечения распространяется с открытым исходным кодом. Многие из включенных в список программных платформ в этих проектах не задействованы, но, в целом, весьма полезны. Arduino CoolTerm Arduino — $             AVR,           Processing. 7      Windows, Linux  macOS. >   (        )              Windows  macOS. 3 9 7 (Roger Meier). www.arduino.cc  freeware.the-meiers.org  Asterisk Cygwin    PBX1    +      Linux  UNIX.    . www.asterisk.org  AVRlib and avr-gcc >      C                  AVR. 7       Windows, Linux  macOS       avr-gcc. www.nongnu.org/avr-libc  GNU avr-gcc — $  C           AVR. 0        Windows, Linux  macOS.  Windows   "              AVR Studio (www. atmel.com/tools/atmelstudio.aspx).*      Linux       : www.atmel.com/tools/atmelavrtoolchainforlinux. aspx,    CrossPack  AVR  macOS —   : www.obdev.at/products/crosspack. *     avr-gcc        Arduino, $,   $ ,      avr-gcc. ble-central 7         Bluetooth LE    PhoneGap  Cordova. +         POSIX  Windows.      Windows           Linux. www.cygwin.com  Dave's Telnet    telnet  Windows. dtelnet.sourceforge.net  Eclipse #  IDE2                  . 9 %          ,       %           . +      Windows, Linux  macOS.  www.eclipse.org Express.js >   JavaScript    node.js     -  . expressjs.com  GitHub ~   git —                   . +    git  github          "    . github.com/don/cordova-plugin-ble-central/  git-scm.com   github.com 1 2  PBX, Private branch exchange —          .  IDE, Integrated Development Environment —        .
Приложение 598 Java noble `      . 7       Windows, Linux  macOS,            .         Sun Microsystems,          Oracle. +   API         Bluetooth  node.js. =        API         Bluetooth LE. http://www.oracle.com/technetwork/java  Node.js JavaScript    JavaScript           . >    "         . JavaScript —   HTML  CSS —            ,  "     +  . JavaScript,          node.js,                                . developer.mozilla.org/en-US/docs/Web/Java  Script libnfc +   API  NFC. 7       Windows, macOS      POSIX. nfc-tools.org  Max/MSP              -     .            ,                 .  Max     MSP                 Jitter             . 7       Windows  macOS. www.cycling74.com  github.com/sandeepmistry/noble   , - nodejs.org  Nodemailer >    $   node.js.    nodemailer.com  node-serialport >         node.js.       github.com/EmergingTechnologyAdvisors/  node-serialport npmjs.org ~  "       Node Package Manager. #  %           node.js     . npmjs.org  onoff >   node.js       /  "              . www.npmjs.com/package/onoff  p5.js 7     (  )  MQTT.     Windows, macOS  Linux.    JavaScript    Processing.                                 . ~ %                . mosquitto.org   www.p5js.org Mosquitto
Где брать компоненты и прочее? 599 PEAR 9    %      PHP. #     %      PHP.   http://pear.php.net  PHP `     ,          -  . #           HTML.7       Windows, Linux  macOS.                 . 9          Max — 7    (Miller Puckette). 7       Windows, Linux  macOS. http://puredata.info  PuTTY SSH   telnet, SSH          Windows. www.puttyssh.org   www.php.net PicBasic Pro QRCode.js >   node.js     QR.     BASIC       PIC. +      Windows.  https://github.com/IagoLast/qrcodejs  melabs.com Dan Shiffman's Libraries PhoneGap/Cordova =  (Dan Shiffman)          Processing  p5.js. 0           "    .   PhoneGap                      HTML, CSS  JavaScript.   Cordova    $         PhoneGap.       Adobe. https://phonegap.com   https://cordova.apache.org Processing `        ,        , " %          ,   "           ,      . 0   Java,        Windows, Linux  macOS. www.processing.org  Puredata (PD) q              -     .            ,  https://github.com/shiffman  www.shiffman.net Tor >   , "     "   -  ,       . www.torproject.org  Tracking.js >   node.js      .  www.trackingjs.com Twilio     "   IP-   .        API, "           .  www.twilio.com
Приложение 600 Visual Studio ws 0      IDE   Microsoft        Windows. &   "     Community Edition         —     ,                   ,                . >  WebSocket  node.js. www.visualstudio.com  Wiring #             AVR,          Processing. 7       Windows, Linux  macOS.  www.wiring.org.co  https://github.com/websockets/ws XCode 0      IDE   Microsoft        macOS  iOS.        ,     ,                    ,                . https://developer.apple.com/xcode/ 
ПРЕДМЕТНЫЙ УКАЗАТЕЛЬ  3     OAuth2 163 3 MK20 USB 570 USB/TTL-Serial 96, 99 3 IP 144    144  %   145 "   146   145     144    145   144 localhost 148 MAC 144    144   144   144   148    148 %  "  148 3     416 3  RFID 457 3   38  36    36 3        73 3      267 3   144 3        477 3       93 C >   391 >      38 >  ArduinoHttpClient 221, 468 BLEPeripheral 571   323 Bluetooth 319 body-parser 159 Button 263 CurieBLE   323 CurieIMU 421 dgram 342 Encoder 263 ESP8266WiFi 205 L3G 428 libfreefare 461    461 libnfc    461 libnfc-dev 461 LSM303    424 mqqt.js 529 MQTT 522, 523 MulitCameraIR 295 multer 185, 535 NDEF  Arduino 470 net 191 noble 329 node.js multer 180 nodemailer 162 onoff 481 p5.js 55, 274 PN532 470 Processing net 188 video 188 querystring 546 SoftwareSerial 127, 132, 134, 170 Stream 208   208 TextFinder 208 tracking.js 451 WiFi101 206  , Client 206  , Server 206 WiFi101 205 >   355    355 >  354 >     381 >      421 > "   267 >  NCSA Mosaic 500 Tor 499 >    MQTT 517 >  MQTT Mosquitto 526 ' &   51, 152 dateServer.js 154 & -  DCS-960L 534 DCS-5222L 534 & -  If This Then That 468 &         311 &   -  43 &  " 293 & "  420 &    "  360 &     69 &   363 &       64   64 +7 64, 101
Предметный указатель 602 2       305  q 421 q    q   421 q  q   q     393   38 334  54 ! = =   36, 38  36    36     169 TAOS TCS34725 447    LSM303 423    DHT11 520 =   112 = %  452 =   341 =      73 =  122 =  527 =    301 = 38 =     node 52 # 2 Connection 273 HTTP 153 Upgrade 273     114, 150 $     163 2   82 2     426 2  NDEF 463  463 2  HTTP   156    155  157 HTTPS 416 2"    366 +  SSID 207 Bluetooth LE 323     323 +     441 +    35 +      258 +           404 +  300 +   " 366 +   API  -   220 API REST 547 I2C 64 navigator 414 SPI 64, 129    28   28 $    28 +           53    Ethernet 36 USB 35 USB/TTL-Serial 98   SIM 550    258  Stream 556, 557   .find() 556   .findUntil() 556   .timeout() 556   [   301   152     51   36, 38         36           36    258    148   arp 147 arp -a 147 ifconfig 79 iwconfig 79 iwlist 79 LoRa.crc() 318 ping 147 Processing image() 189 ssh 44 sudo 79 traceroute 361     49      42, 43  143    151   Groundlabs 507 Twilio 538    423   Pi Zero Camera 534      30   30, 35, 75, 76 Raspberry Pi 76 Raspberry Pi B3 76 Raspberry Pi Zero W 76    30  %  30   31    30    37     . &.       157  420         477     477    478     420, 426    421 < _    _    369  421
Предметный указатель _      258     258 _     84 " 7   420, 423 7        421 7      36, 38 7   195 7 %  % 253 7 %  143 IP- 145  " 150 7    145 7     381  355 7  ArrayList 255 7    206   Homebrew 526 7  POST 158 request.query 156 sendPacket() 345 Serial1.print( 124 Serial1.println( 124 Serial1.read( 124 Serial1.write() 124 serialEvent() 111, 116, 121 Serial.print() 109 Serial.write() 109 server.get() 157 server.post() 157 7 432  121 7         396  396   396 7    301 7    ATmega 328T 127 Atmel 16U2 99 ATtiny84 127 BASIC Stamp 98 603 7      Arduino 61 % 66 Arduino 101 63, 65 Arduino MKR1000 63, 65 BLE Micro 63 BLE Nano 63 ESP8266 63, 65 ESP8266 Thing 66 7    30 8-   60 32-   61 ARM 61, 63   30 7       30 7    75 7    ESP8266 99, 205 FT232RL 98 7        408 7  OSI    93 Ethernet 150 IP 150   150     150 7  143  SM5100B 550 7 BLE Central 575 BLE Nano 569 Bluetooth 122 WiFi ESP8266 204 WINC1500 204 WINC1500 205 7 122 %  -  217 7  " 249 7  35 7     302    302       302 ] *%  %  253 *        421 *   82 *     419 *     317 *     270 * "   293 * IMSI 550    -   152 $.  152 *      152   152  0       93   32    93 0 bash 560    49 0  module.exports 483 0    31–33 0   30, 75, 76 0  Processing Contribution Manager 188          583 0  IP-  145 0     355    355 0          82 0     441 0     517 0   Electronic Frontier Foundation 419 0   420 0   35, 84 DSO Nano 84 0  420   "  420     "  420
Предметный указатель 604  "  420  420     "  420   420   420 0 %   /% 318 0     258 0     426 0   355 0 " 35       HTTP 155    RFID 456   292     369       426    request 155 response 155   Processing  41  54      426   426    USB/TTL-Serial 35 "  115  BLE Nano 570      ESP8266 Thing Dev 205 Feather ESP8266 Huzzah! 205 MKR1000 204   node.js 50       36, 38      355  %"   72           478     145        304     426  "   72    $.  152     152   152     57, 59, 71  , Mac Os 71  , Windows 71    134    152            64     64        " 230      120   57, 59, 71  , Mac Os 71  , Windows 71    134    36, 38, 74      NMEA 412       267     292        ,    64     29, 292    apt 81 Bluetooth GPS 413 PhoneGage Desktop 559 PhoneGap Developer 559            404    REST 234      84     38   37   37      35    Camera 188 Cheese 188 CoolTerm 57, 59 curl 80 Cygwin 44 forever 195 GNU screen 58 less 47, 48   48 nano 47    48 netcat 346 OpenSSH 44 Photo Booth 188 Processing 39 PuTTY 44, 45, 58 wpa_cli 79             159, 274          134        42 OpenSSH 44 PuTTY 44, 45      42, 43   ANT 307 ASCII 105 Bluetooth 122, 307 DHCP 150 DNS 150 EDGE 549 GSM 549 Hayes AT 363 HTTP 153 I2C 421 IMAP 162 LoRa 307, 310 LoRaWAN 310 MQTT 514, 516   517    517 NFC 459 NMEA    412 NMEA 0183 410 OneWire 520 POP 162 RFID Mifare Classic 460 Mifare Ultralight 460 RS-232 97    97 SIP 537 SMTP 162
Предметный указатель SOAP 468 TCP 150, 252, 341 TLS 419 UDP 150, 253, 341 webSocket 272 webSockets 253 WiFi 307 XBee 362 ZigBee 307  112     32     USB    95, 96     ;;_    95  29     29   29    112   Bluetooth GAP 319 GATT 319 SPP 319   174     HTTP 157 ( 9     441 9    TwiML 540 9 %    46   47 9  DB-9 97 D-sub-9 97 ICSP 129   «  » 35, 38      35 9    38 %  36, 38 9   Arduino Uno rev3 66 9         396  396   396 605 9         81 9     35, 37 9     317 9      169 9    %" 72  " 72 9   36, 37 9 . &.  %  9   420 D #     157 #     69    101  101 #      341 #  354 C  253     341 C      93 C    TCP/IP 253 #    151 #  DNS 150 node.js    ,    54   152 dateServer.js 154       252   30   51 #  SMS 544 #     419   416 #      416 #    30   204 #     31, 32  32, 33 #  89      142   142     304    305 #         408    129 #    270    110 #   OAuth2 163 UMTS 549 Wireless E91 391   OAuth2 163        "  , Hue 477 Arduino & -  AirNow 223 Bluetooth Central  PhoneGap 576 Camera 189 Processing &   268 q  415 2  "  NDEF    Arduino 471 +-  399   HTTP NFC   WeMo 473   MQTT 520, 523 0                  557 0            430          110, 111       108   & -  AirNow 221 #  HTTP/HTTPS 417 #         TwML    MQTT 542 #  "  208
Предметный указатель 606 #              CurieIMU 427 #    -    571 #          LSM303      L3G 428 X "   564 X    402 X         103, 104 '   QR,       HTML5 454 '  "  NDEF    Arduino 471 #  40 #       71  421 #       53 #     310 # "   420    420    420 #       307 #   416 #  252 #"  NDEF 463     360 #"  %  "  146 #    Arduino IDE 1.8.2 62, 67 Processing 39 #   7   69 7    71           174 #   IEEE 143 IEEE 802.3 143 IEEE 802.11 144 IEEE 802.15.1 144 LTE 549       E.164 545 #   391 #    204 #      37 #    420 #   ageCheck.js. 156 ageCheck.js,   REST 237 AQI client 232 aqiClient.js 233 dateServer.js 154 getParameters.js 155 js #       155 mailer.js. 162 node.js 54, 180 #  UDP 343 p5.js     56 restAgeCheck.js 237 wsExpressServer.js 274 & -      /      490 & -         494 2  "  NDEF 465, 483   HTTPS      API    SMS Twilio 546 9      582 #  Bluetooth LE  noble 330 #  HTTP/HTTPS     488 #  webSocket    Express 274 #       497 #       TwiML 548 #  +X# 405 #  ,   "       IP-  500 #      528 #       node.js,   "      535 X   GPIO 482 '  %   "  NDEF 466, 486 #     395 #   NFC SCL3711 460      PN532 468 % ; ARP 147 ;  420 ;     112 ;    % 514 ;     cd 46 cd,      46, 47 exit 49 logout 49 ls 45 mkdir 46 pwd 45 rm 46   45 ;     35 ;   GPRS 549 PhoneGap 558 uPnP 468 ;          142   142     304    305 ;    38 IRF520 36 TIP120 36 ;   410 ;  84 ;   409 N X3 64, 134 $ 134 X    421 X   431 X      OpenSSH 44 PuTTY 44, 45      42, 43 42
Предметный указатель X        Tor 499 X           64 X       "      Hue 477   152 X "      230 X           404 X     OSI 93 Ethernet 150 IP 150   150     150 X     421 X     libfreefare 461 libnfc 461  355 \ [  package.json 195   59 [   %  46   47 [ 356 [  IP-  144 MAC-  144 NDEF 463   CSV 229 TSV 229 [     426    426 [       307 [  .addAttribute() 325 available() 358 broadcast() 278 compare() 354 .connect() 267 connect() 207 connected() 207 607 connectToServer() 225, 267, 282 .c_str() 222 digitalPinToInterrupt() 267 find() 208 findUntil() 208, 226 fs.readFileSync() 417 .get() 158 getCurrentPosition(), 414 httpGet() 333 http.request() 233 http.stop() 226 IRPulse() 299 JSON.parse() 232 JSON.stringify() 232 keyReleased() 256 map() 117 movieEvent() 269 newClient() 277 onReceive() 316 parseFloat() 208 parseInt() 208, 226 parseMessage() 281 parsePacket() 358 .post() 158 printWiFiStatus() 243 Processing Capture.list() 188 loadStrings() 183 readButtons() 266, 282 readBytesUntil() 208 readEncoder() 266 readMessage() 255, 278, 280 readMessages() 256 readString() 208 readStringUntil() 208 request.end() 233 response.on(‘end’) 233 scanNetwork() 208 scrub() 269 sendIntro() 279 sendJsonMessage() 283 serverEvent() 256 setLeds() 226 setMeter() 226 shutterClick() 298 stop() 207 String() 222 tcpSocket.connected() 265 toCharArray() 222 watchPosition() 414 WiFi.begin() 211 WiFiClient.Connected() 226 WiFi.encryptionType() 209 WiFi.macAddress() 209 WiFi.scanNetworks() 209 WiFi.status() 226  " 267      267  ~ 143 Z   419 ˆ Z for-next 41, 42 Z        72  423 '        311 '  "  115 H          113, 114  66   "  "  146   "   148   -   (+7) 217  SMS 511     514   451  452  QR 452     36, 38 { /      " PHP 162  163 /       TwiML 540 / X3 134 /           408
Предметный указатель 608 Ž H P `    TwiML 538 `          53 `       CSS 54 JavaScript 50, 54    53 `      305 `"   249 HTML5 54 HTTP  153     156  157   153 PhoneGap 558 PHP  $     162 Processing 39, 40, 41   42   draw() 41 setup() 41   41  41    41     if-then 41  for-next 41 A ASCII 110 B Bluetooth 89, 121 Smart   LE. &. Bluetooth   LE 123    BlueMan 123   Serial Port 123 Bluetooth LE   323     323 C Chip Select. # SS CS. &. SS D DHCP   150 DNS   150  150 I IP- 143, 144    144  %   145   145     144   144 IP-    510 J JitterBox 136 L localhost 148 M MAC- 144    144   144 MISO 129 MOSI 129 MQTT   Mosquitto 526 N Ethernet   36 NDEF   463  463 "  463 NFC    SCL3711 460      PN532 468 G O GPS 395 OpenSSH 44 E R Raspbian 77       78   raspi-config 78      78 RFID 441   457    456   Mifare Classic 460 Mifare Ultralight 460 RS-232 97, 98 S SCK   . &.   Sideloading 558 Slave Select. &. SS SMS  544 % 511 SS 129 T TCP   150 U UDP   150 Unicode 110