220 5 43MB
Russian Pages 544 [546] Year 2020
EXPLORING ® ARDUINO Tools and Techniques for Engineering Wizardry Second Edition Jeremy Blum
WILEY
УДК ОО4 ББК 32.973.26 Б71 Б71
&пум Дж.
Изучаем Arduino: инструменты и методы технического волшебства. 2-е изд.: пер. с англ. - СПб.: БХВ-Петербург, 2020. - 544 с.: ил. ISBN 978-5-9775-6735-О
Книга посвящена проектированию электронных устройств на основе микроконтрол лерной платформы Arduino. Приведены основные сведения об аппаратном и программ ном обеспечении Arduino. Изложены принципы программирования в интегрированной среде Arduino IDE. Показано, как анализировать электрические схемы, читать технические описания, выбирать подходящие детали для собственных проектов. Приведены приме ры использования и описание различных датчиков, электродвигателей, сервоприводов, индикаторов, проводных и беспроводных интерфейсов передачи данных. В каждой главе перечислены используемые комплектующие, даны монтажные схемы, подробно описа ны листинги программ. Материал ориентирован на применение несложных и недорогих комплектующих для экспериментов в домашних условиях. Во втором издании обновлены проекты из предыдущего издания, добавлены проекты с шаговыми двигателями и беспро водной связью Bluetooth и Wi-Fi, а также более глубоко рассмотрены темы электротехники и разработки устройств.
Для радиолюбителей
УДКОО4 ББК 32.973.26
Гpynnill nодrотовкм мзданмн:
Руководитель проекта
Игорь Шишигин
Зав. редакцией
Екатерина Сависте
Компьютерная верстка
Людмилы Гауль
Оформление обложки
Карины Соловьевой
Authorized Russian translation of the English edition of Explorlng Ardulno •: Tools ond Technlques for Englnнrlng Wlzordry, Second Editlon, ISBN 978-1-119-40S37-S © 2020 Ьу John Wiley & Sons, lnc., lndianapolis, lndiana. AII Rights Reserved. Тhis translation is puЬlished under license Ьу BHV, © 2020. Авторизованный перевод с английского на русский язык произведения Explorlng Ardulno•: Tools ond Techniques for Enginнrlng Wlzordry, emopoe издание, ISBN 978-1-119-40S37-S © 2020 Ьу John Wiley & Sons, lnc., lndianapolis, lndiana. Все права защищены. Этот перевод пубпикуется по лицензии издательством «БХВ», © 2020. Подписано в печать 03.08.20. Формат 70х100'1,•. Печать офсетная. Усл. печ. л. 43,86. Тираж 2S00 экз. Заказ № 11832. «БХВ-Петербург», 191036, Санкт-Петербург, Гончарная ул., 20. Отпечатано с готового оригинал-макета ООО «Принт-М», 142300, М. О., г. Чехов, ул. Полиграфистов, д. 1 ISBN 978-1-119-40537-5 (англ.) ISBN 978-5-9775-6735-0 (рус.)
© 2020 Ьу John Wiley & Sons, lnc. © Перевод на русский язык, оформление.
ООО «БХВ», 2020
ООО «БХВ-Петербург»,
Посвящается Лиа за ее помощь мне и совет рассматривать каждую трудность как благоприятную возможность.
06 авторе
в
настоящее время Джереми Блум занимает должность технического ди ректора в компании Shaper (https://www.shapertools.com), где он изобре тает новый способ использования ручных электроинструментов, применяя для этого машинное зрение. Ранее Джереми работал ведущим конструкто ром компании Google[x] и разрабатывал различные конфиденциальные про дукты, включая Google Glass. Джереми присвоена степень магистра по электронике и вычислительной технике в Корнеллском университете, в котором он ранее также получил сте пень бакалавра по тому же профилю. В Корнеллском университете он осно вал и возглавлял организацию по экологически щадящему проектированию Cornell University SustainaЫe Design; создал первое в своем роде офисное про странство для совместной работы студентов; а также проводил исследования в области робототехники и машинного самообучения. Джереми занимался разработкой медицинских протезов, систем освеще ния с использованием волоконной оптики и светодиодов, бытовой автомати ки, 3D-принтеров и сканеров, самособирающихся и самообучающихся робо тов, переносных вычислительных платформ, а также устройств дополненной реальности. Его работы представлялись на международных конференциях и публиковались в рецензируемых научных журналах и в таких популярных изданиях средств массовой информации, как телеканал Discovery Channel, газета Wall Street Journal и журнал Popular Science. Журнал Forbes включил его в свой ежегодный список "30 младших, чем 30" в знак признания его дея тельности, которая способствует техническому прогрессу в Америке. Он яв ляется соавтором нескольких патентов в области конструирования перенос ных вычислительных платформ и устройств дополненной реальности. В свободное от разработки и реализации новых проектов время Джереми занимается обучением. Его статьи и видеоуроки помогают миллионам людей изучать проектирование в области электротехники и встроенного программ ного обеспечения. Его книга "Exploring Arduino" была переведена на многие языки и используется в качестве технического учебника во всем мире, включая его альма-матер, Корнеллский университет. Джереми увлекается применени ем технологии для улучшения жизни людей, и разработкой инструментов для этого. Узнать больше о Джереми можно на его веб-сайте: https://www.jeremy Ыum.com.
8
О техническом редакторе
О техническом редакторе
д
октор Дерек Моллой (Derek Molloy) занимает должность доцента ка федры электронной техники инженерно-вычислительного факультета Городского университета Дублина в Ирландии. Он читает лекции для студен тов бакалавриата и аспирантуры по объектно-ориентированному програм мированию для встроенных систем, цифровой и аналоговой электронике и сетевым встроенным системам. Он занимается исследованиями в основном в области компьютерного и машинного зрения, встроенных систем, трехмер ной графики и визуализации, а также в области дистанционного обучения. Дерек ведет популярную серию видеоуроков на канале YouTube, благодаря которым миллионы людей смогли познакомиться с предметом встроенной операционной системы Linux и другими областями цифровой электроники. В 2013 г. он создал персональный веб-сайт/блог, в котором размещены его видеоуроки с вспомогательными материалами, исходный код программ и от зывы пользователей. Этот сайт ежедневно посещают тысячи людей. В мини серии издательства Wiley он опубликовал свои книги "Exploring BeagleBone" (в 2015 r.) и "Exploring Raspberry Pi" (в 2016 г.). Ранее в этом году вышло второе издание его книги "Exploring BeagleBone". Узнать больше о Дереке, его работе и других его публикациях можно на его веб-сайте: http://derekmolloy.ie.
Благодарности
н
а протяжении нескольких лет после выхода первого и�дания этой кни ги я получ ил огромное количество писем от читателеи, в которых они сообщали обо всем, чему смогли научиться. Было высказано и немало кон структивной критики, в основном по поводу незначительных аспектов, кор ректировка которых может повысить качество книги. Я серьезно относился к этим замечаниям и старательно отслеживал их в течение последних лет. Я намереваюсь сделать второе издание этой книги еще более полезным, чем первое, в то же самое время сохраняя легкость изложения, за которую многие читатели выражали свою признательность. Поэтому БОЛЬШУЩЕЕ СПАСИБО всем тем, кто предоставил мне свои отклики о первом издании книги «Изучаем Arduino». Следующим делом я снова хочу выразить свою благодарность издатель ству Wiley. В течение нашей совместной работы сотрудники издательства
Благодарности
проявили себя великолепными партнерами, и я рад, что получил согласие выпустить второе издание книги. В частности, я хочу поблагодарить Джима Минатела (Jim Minatel), Адаоби Оби Тултона (Adaobl ОЫ Tulton), Доктора Дерека Моллойа (Dr. Derek Molloy), Мерилуизу Виак (Marylouise Wiack) и Атийаппан Палит Кумара (Athiyappan Lalith Kumar). Также говорю спасибо всем замечательным людям компании Adafruit, ра ботавшим совместно со мной над обеспечением доступности наборов ком понентов для проектов из этой книги. Компания Adafruit оказывает большую поддержку сообществам открытого аппаратного и программного обеспече ния, и я не стал бы тем инженером, каким являюсь в настоящее время, без их отличных компонентов и руководств. Когда я работал над первым изданием книги «Изучаем Arduino>>, я одно временно обуч ался по программе магистратуры. Я получил степень магистра несколько лет тому назад, и теперь мне нужно концентрироваться на рабо те в компании Shaper. Я также должен высказать благодарность всем моим коллегам как в компании Shaper, так и в компании Google (мой предыдущий работодатель) за их постоянную поддержку и помощь в создании замеча тельных устройств. Отдельную благодарность я хочу выразить моим преподавателям в Кор неллском университете, особенно профессору Франгоису Гимбретиере (Fran gois Guimbretiere), который вел занятия, где я познакомился с Arduino. После выхода первого издания этой книги он использовал ее в качестве учебника для своего курса. Мне доставляет большую радость осознавать, что я смог отблагодарить Корнеллский университет таким образом. Наконец, я хочу поблагодарить моих родителей, моего брата, мою жену и моих друзей за их терпение и за постоянную поддержку и ободрение. Считаю, мне очень повезло, что в моей жизни есть такие замечательные люди.
9
Оглавление Об авторе ....................................................................................................................... ? О техническом редакторе ...................................................................................... 8 Благодарности ............................................................................................................. 8 Об авторских правах.............................................................................................. 19 Введение ..................................................................................................................... 21 Почему Arduino? ........................................................................................................... 22 Для кого эта книга........................................................................................................ 22 Чему вас научит эта книга ........................................................................................ 23 Стиль типографского оформления...................................................................... 24 Приобретение компонентов .................................................................................. 24 Что вам потребуется ................................................................................................... 25 Исходный код и прочие электронные ресурсы ............................................ 26 Список опечаток........................................................................................................... 27 Дополнительный материал и поддержка......................................................... 27 Что такое Arduino? ....................................................................................................... 28 О движении Open Source ......................................................................................... 29 Несколько советов читателю ................................................................................. 29
Часть 1. Технические основы платформы Arduino .............. 31 Глава 1. Начало работы и основные сведения о платформе Arduino .................................................................... 33 Что вы узнаете из этой главы .................................................................................. 33 Исследуем среду Arduino ......................................................................................... 34 Функциональные возможности Arduino .................................................. 35 Платы Arduino ....................................................................................................... 41 Создаем и исполняем первую программу ....................................................... 45 Загрузка и установка среды Arduino IDE .................................................. 47 Запускаем среду IDE и подключаемся к плате Arduino ..................... 47 Структура нашей первой программы ....................................................... 49 Резюме .............................................................................................................................. 52
Глава 2. Цифровые входы и Вt>1ходы и широтно-импульсная модуляция ......................................... 53 Что вы узнаете из этой главы.................................................................................. 53 Ввод цифровых сигналов ......................................................................................... 54 Подключение светодиода и работа с беспаечными макетными платами ........................................................................................... 54
12
Оглавление
Программирование цифровых выводов ................................................. 60 Цикл for....................................................................................... '............................ 61 Генерирование ШИМ-сигнала с помощью функции analogWrite() ...... 63 Считывание входных цифровых сигналов ....................................................... 67 Использование понижающего резистора для считывания входных цифровых сигналов ...................................... 68 Управляемый ночник на трехцветном светодиоде ..................................... 76 Резюме .............................................................................................................................. 82
Глава 3. Считывание сигналов аналоговых датчиков ........ 83 Что вы узнаете из этой главы .................................................................................. 83 Аналоговые и цифровые сигналы........................................................................ 84 Сравнение аналоговых и цифровых сигналов ...................................... 85 Преобразование аналоговых сигналов в цифровые ......................... 86 Опрос аналоговых датчиков с помощью Arduino......................................... 87 Считывание выходного сигнала потенциометра ................................. 88 Применение аналоговых датчиков............................................................. 92 Переменные резисторы в качестве аналоговых датчиков ...................... 97 Резистивные делители напряжения........................................................... 97 Управление выходным аналоговым сигналом посредством входного аналогового сигнала.......................................100 Резюме ............................................................................................................................ 102
Часть 11. Взаимодействие с окружающей средой .............. 103 Глава 4. Использование транзисторов и управление электродвигателями постоянного тока......................................................................... 105 Что вы узнаете из этой главы................................................................................ 1Об Электродвигатели постоянного тока................................................................ 1Об Работа с сильноточными индуктивными нагрузками ......................107 Управление скоростью вращения электродвигателя посредством шим ............................................................................................113 Управление направлением вращения электродвигателя с помощью Н-моста ..........................................................................................115 Создаем шасси самоходного робота ................................................................125 Выбор компонентов для шасси робота ..................................................125 Собираем схему управления роботом.................................................... 128 Разработка программы управления самоходным шасси ............... 132 Сборка устройства............................................................................................ 136 Резюме ............................................................................................................................137
Оглавление
Глава 5. Управление сервоприводами и шаговыми двигателями ......................................................... 139 Что вы узнаете из этой главы................................................................................140 Управление сервоприводами ..............................................................................140 Разница между сервоприводами кругового вращения и с поворотом в пределах сектора ...........................................................140 Управление сервоприводом........................................................................141 Программа управления сервоприводом ...............................................144 Создание сканирующего дальномера .............................................................146 Шаговые двигатели и управление ими ............................................................150 Принцип работы биполярных шаговых двигателей ......................... 152 Приводим шаговый двигатель в действие ............................................ 154 Создаем одноминутный хронограф.................................................................. 159 Сборка схемы хронографа ............................................................................ 160 Программа хронографа ................................................................................. 162 Резюме ............................................................................................................................ 167
Глава 6. Работаем со звуком .................................................... 169 Что вы узнаете из этой главы................................................................................169 Принцип работы динамика ...................................................................................170 Свойства звука ...................................................................................................170 Как динамик воспроизводит звук .............................................................172 Генерация звуков с помощью функции tone(J.............................................. 173 Подключение файла сопоставления нот частотам............................173 Сборка схемы с динамиком..........................................................................175 Создание звуковых последовательностей ............................................ 177 Ограничения функции tone(J ......................................................................181 Миниатюрное пианино ........................................................................................... 181 Резюме ............................................................................................................................ 184
Глава 7. Последовательный интерфейс USB........................ 185 Что вы узнаете из этой главы................................................................................185 Возможности последовательного обмена данными платформы Arduino .................................................................................................. 186 Использование встроенной или внешней микросхемы преобразователя USB/RS-232 компании FTDI или Silicon Laboratories ...................................................................................187 Платы Arduino с дополнительным микроконтроллером ATmega в качестве преобразователя USB/RS-232 ..............................190 Платы Arduino с основным микроконтроллером, поддерживающим интерфейс USB............................................................191 Платы Arduino с возможностями USB-xocтa ......................................... 192
13
Оглавление Прием данных от Arduino на компьютере......................................................192 Использование команды print() ................................................................. 192 Специальные символы ................................................................................... 194 Изменение представления типов данных ............................................. 196 Передача данных с компьютера на плату Arduino .....................................196 Настройка монитора порта для отправки команд ............................196 Получение данных, отправляемых с компьютера или другого устройства через последовательный интерфейс ..............................197 Взаимодействие с компьютерной программой .......................................... 206 Установка Processing ........................................................................................207 Управление приложением Processing посредством платы Arduino...................................................................................................... 208 Передача скетчем Processing данных на плату Arduino .................211 Резюме ............................................................................................................................214
Глава 8. Эмуляция USВ-устройств........................................... 215 Что вы узнаете из этой главы................................................................................ 215 Эмуляция клавиатуры .............................................................................................217 Ввод данных в компьютер.............................................................................217 Управление компьютером с платы Arduino ..........................................221 Эмуляция мыши .......................................................................................................... 223 Резюме ............................................................................................................................ 227
Глава 9. Сдвиговые регистры .................................................. 229 Что вы узнаете из этой главы................................................................................ 229 Что такое сдвиговый регистр ............................................................................... 230 Параллельная и последовательная передача данных .................... 231 Использование микросхемы сдвигового регистра 74НС595 ....... 232 Загрузка в сдвиговый регистр данных с платы Arduino .................. 235 Преобразования между двоичным и десятичным форматом ..... 238 Световая анимация с помощью сдвигового регистра ............................. 239 Эффект «бегущего» светодиода..................................................................239 Гистограмма для реагирования на изменение ВХОДНЫХ УСЛОВИЙ ............................................................................................... 241
Резюме ............................................................................................................................244
Часть 111. Интерфейсы для обмена данными ...................... 245 Глава 10. Шина 12( •••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••• 247 Что вы узнаете из этой главы................................................................................ 247 История создания протокола I2С ........................................................................ 248 Схема подключения устройств I2С ..................................................................... 249
Оглавление Взаимодействие и идентификация устройств..................................... 250 Аппаратные требования и повышающие резисторы ...................... 252 Как правильно выбрать номинал повышающего резистора ....... 253 Взаимодействие с термодатчиком по шине 1 2 С ........................................... 255 Сборка схемы устройства ............................................................................. 255 Использование информации из справочного листка датчика ТС74 ........................................................................................................ 257 Программа для опроса датчика ТС74 ...................................................... 259 Совместное использование сдвиговых регистров, последовательного интерфейса и шины 1 2С.................................................. 262 Собираем систему мониторинга температуры ................................... 262 Модифицируем скетч Arduino .................................................................... 263 Создаем скетч Processing ............................................................................... 265 Резюме ............................................................................................................................ 269
Глава 11. Шина SPI и библиотеки сторонних разработчиков ........................................................ 271 Что вы узнаете из этой главы................................................................................ 271 Общие сведения о шине SPl .................................................................................. 272 Подключение устройств SPl .................................................................................. 273 Конфигурация интерфейса SPI ................................................................... 274 Протокол передачи данных SPI .................................................................. 275 Сравнительные характеристики протоколов SPI, 1 2С и UART ................ 276 Взаимодействие с SРl-акселерометром .......................................................... 277 Что такое акселерометр? ............................................................................... 278 Получаем информацию из справочного листка................................. 280 Сборка схемы устройства ............................................................................. 283 Разработка программы .................................................................................. 285 Аудиовизуальный музыкальный инструмент на основе трехкоординатного акселерометра.................................................................. 292 Сборка схемы устройства ............................................................................. 292 Модифицируем программу .......................................................................... 294 Резюме ............................................................................................................................297
Глава 12. Взаимодействие с жидкокристаллическими дисплеями...................................................................................... 299 Что вы узнаете из этой главы................................................................................ 300 Подключение ЖКД к плате Arduino ................................................................... 300 Библиотека LiquidCrystal для работы с ЖКД ................................................ 303 Вывод текста на дисплей ............................................................................... 304 Создание специальных символов и анимация ................................... 306
16
Оглавление
Создаем термостат ....................................................................................................311 Сборка схемы устройства .............................................................................311 Отображение данных на ЖКД .....................................................................314 Настройка порогового значения температуры с помощью кнопок............................................................................................317 Код программы для звукового оповещения и управления вентилятором........................................................................319 Собираем все фрагменты кода в завершенную программу .........320 Совершенству нет предела ..........................................................................325 Резюме ............................................................................................................................326
Часть IV. Прерывания, комбинирование функций и карты SD ..................................................................................... 327 Глава 13. Прерывания и другие специальные функции ............................................................... 329 Что вы узнаете из этой главы................................................................................329 Аппаратные прерывания .......................................................................................330 Опрос состояния и прерывания: преимущества и недостатки каждого подхода ...................................................................331 Возможности аппаратных прерываний Arduino ................................333 Схема запуска прерывания кнопкой, оснащенной аппаратной защитой от дребезга...................................334 Прерывания по таймеру .........................................................................................343 Прерывания по таймеру ................................................................................343 Установка библиотеки TimerOne ............................................................... 344 Одновременное исполнение двух задач ...............................................344 Музыкальный инструмент на прерываниях .................................................345 Схема музыкального инструмента ............................................................346 Программа для музыкального инструмента ........................................347 Резюме ............................................................................................................................349
Глава 14. Работа с картами памяти SD .................................. 351 Что вы узнаете из этой главы................................................................................351 Подготовка к регистрации данных ....................................................................352 Файлы данных СSV-формата ........................................................................353 Подготовка 5D-карты для записи данных ..............................................353 Сопряжение платы Arduino с 5D-картой .........................................................360 Шилды для 5D-карт ..........................................................................................360 Интерфейс SPI 5D-карт ...................................................................................363 Запись на карточку 5D ....................................................................................363
Оглавление 17 Считывание данных с SD-карты..................................................................368 Часы реального времени ..............................................................................372 Общие сведения о часах реального времени .....................................372 Работа с часами реального времени .......................................................374 Регистратор проходов через дверь ..................................................................384 Схема регистратора .........................................................................................384 Программа регистратора ..............................................................................386 Анализ данных ....................................................................................................391 Резюме ............................................................................................................................392
Часть V. Беспроводная связь ................................................... 395 Глава 15. Радиосвязь .................................................................. 397 Что вы узнаете из этой главы................................................................................397 Электромагнитный спектр ....................................................................................398 Радиоспектр .......................................................................................................400 Принципы обмена данными по радиоканалу......................................402 Передача нажатий кнопки по радиоканалу ..................................................404 Подключение приемника к плате Arduino ............................................404 Программа для работы с радиоприемником.......................................405 Беспроводной дверной звонок ..........................................................................409 Схема приемной стороны звонка .............................................................41О Программа для приемной стороны звонка ..........................................411 Первые шаги на пути к «умному» дому управление светильником ....................................................................................413 Электричество в доме и офисе ...................................................................415 Принцип работы реле.....................................................................................416 Программа для управления реле ..............................................................418 Подключение реле управления светильником к Arduino ..............420 Резюме ............................................................................................................................422
Глава 16. Беспроводная связь Bluetooth .............................. 423 Что вы узнаете из этой главы................................................................................423 Что такое Bluetooth? .................................................................................................424 Стандарты и версии Bluetooth ................................................................... .424 Профили Bluetooth и служба GАП BTLE .................................................425 Установка связи между платой Arduino и смартфоном .......................... .427 Считывание датчика через канал BTLE ...................................................427 Передача данных со смартфона по каналу BTLE ................................442 Управление светильником посредством Bluetooth...................................453 Процедура сопряжения смартфона с устройствами BTLE .............453 Программа для работы с датчиком присутствия ...............................454
18
Оглавление
Сопряжение со смартфоном ........................................................................ 460 Подключаем вместо светодиода светильник ......................................462 Резюме ............................................................................................................................463
Глава 17. Wi-Fi и облачные хранилища ................................. 465 Что вы узнаете из этой главы................................................................................ 465 Работа Arduino в Сети ..............................................................................................466 Сетевая терминология ....................................................................................466 Клиенты и серверы ..........................................................................................470 Arduino с возможностями Wi-Fi ..................................................................470 Управление платой Arduino через Интернет ................................................471 Подготовка оборудования для управления вводом-выводом ...............................................................................................471 Подготовка среды Arduino IDЕдля работы с платой Feather ........473 Проверяем соответствие библиотеки Wi-Fi прошивке модуля Wi-Fi ...................................................................................475 Программа сервера для платы Arduino ..................................................476 Собираем весь код вместе для создания веб-сервера....................488 Управление платой Arduino из локальной сети и извне ее ...........493 Взаимодействие с интерфейсом Web-APl.......................................................498 Работа с интерфейсом Web-API для получения метеоданных .......................................................................................................499 Вывод полученных данных на дисплей .................................................. 512 Резюме ............................................................................................................................ 523
Приложение. Расшифровка справочных листков и изучение принципиальных схем ........................................ 525 Работа со справочными листками ..................................................................... 525 Составные части справочного листка .....................................................525 Цоколевка компонента .................................................................................. 529 Изучение принципиальной схемы платы Arduino .....................................532
Предметный указатель .............................................................. 535
Об авторских правах
в
се изображения, значки и надписи на рис. 3.7 и рис. 10.3 принадлежат компании Analog Devices, Inc. (ADI) и защищены авторским правом© с 2019 r. Все права сохраняются. Эти изображения, значки и надписи воспро изведены с разрешения компании ADI. Воспроизведение, распространение или использование без письменного согласия компании ADI запрещено. Содержащийся в данной книге материал, охраняемый авторским правом, принадлежащий компании Microchip Technology Incorporated, воспроизве ден с разрешения. Все права сохраняются. Последующее воспроизведение без предварительного письменного разрешения компании Microchip Technology Inc. запрещено. Названия Atmel, AVR, ICSP и In-Circuit Serial Programming являются тор говыми марками или зарегистрированными торговыми марками компании Microchip Technology Inc. Названия Arm и Cortex являются торговыми марками или зарегистриро ванными торговыми марками компании Arm Limited (или ее дочерних ком паний} в Соединенных Штатах и/или в любой другой стране. Сопутствующая технология может быть защищенной частично или полностью патентами, авторскими правами, законами о промышленных образцах и законами о коммерческой тайне.
Введение
п
ервое издание этой книги, вышедшее в 2013 году, я открыл следующими
словами: «Мы живем в прекрасное время. Я люблю говорить, что мы уже живем в будущем».
Я думаю, что с таким введением я загнал себя в угол, поскольку если 2013 год был «будущим», тогда я не совсем уверен, как можно называть насто ящее! Далекое будущее? Очень далекое будущее? Тогда я хотел подчеркнуть этими словами, что в последнее время поступь прогресса была настолько стремительной, что возможности, предоставляемые даже поверхностными знаниями в области встроенных электронных устройств и программного обеспечения, расширяются буквально день ото дня. Со времени выхода первого издания этой книги доступность электронных устройств и программного обеспечения продолжала повышаться с каждым прошедшим днем. В 2013 году я сомневался, стоит ли включать в книгу гла ву о подключении рассматриваемых в ней проектов к Интернету, поскольку в то время процесс для этого был довольно непростой. В 2013 году понятие «Интернет вещей» (IоТ 1 ) было только начинающей входить в обиход модной фразой в среде фанатов в этой области. Сейчас же это одно из основных вы ражений глобального языка. Похоже, что в настоящее время любой товар со держит микроконтроллер. Все вещи стали «умными» и большинство из них также оснащены возможностью телефонной веб-связи. Я готов спорить, что в те времена, когда термин «Bluetooth» ассоциировался только с беспровод ными наушниками для сотовых телефонов, вы вряд ли могли представить себе, что в недалеком будущем можно будет купить зубную щетку, оснащен ную возможностью Bluetooth. Принимая все это во внимание, я чувствовал, что настало время для выпу ска нового издания книги «Изучаем Arduino>>. Здесь получили более обшир ное рассмотрение все темы, содержащиеся в первом издании. Обновлены все проекты добавлением в них новых заданий и подробностей, а также объяснены все проблемные вопросы, которые имелись у читателей первого издания. Но самое главное, в книгу добавлен большой объем нового содер жимого, включая множество подробностей по беспроводной связи, совре менному оборудованию для платформы Arduino, изменениям в экосистеме и программном обеспечении Arduino и многое другое.
1
Англ. Internet of Things.
22 Введение
ПОЧЕМУ ARDUINO? Доступные в настоящее время инструменты, о многих из которых вы узнаете в этой книге, предоставляют нам возможность и средства, чтобы за ставить окружающий мир выполнять наши капризы. Еще совсем недавно нельзя было просто взять микроконтроллер и в течение нескольких минут создать устройство на его основе для управления окружающим нас миром. Микроконтроллер представляет собой программируемую интегральную схему (ИС), которая позволяет управлять работой сложных механических, электрических и программных систем с помощью сравнительно простых команд. Возможности в этом поле безграничны, и платформа микроконтрол лера Arduino станет вашим любимым инструментом для исследования мира электроники, программирования, взаимодействия человека с компьютером, систем управления и многих друrих областей. В этой книге вы будете ис пользовать Arduino для реализации самых разнообразных задач, от опреде ления движения до создания беспроводных систем управления и связи через Интернет. Независимо от вашего уровня опыта в любой технической области, будь то абсолютный новичок или бывалый профессионал, намеревающийся занять ся разработкой встроенных систем, платформа Arduino будет замечательной начальной точкой. Или, возможно, вам требуется общая информация каса тельно разработки с использованием платформы Arduino? Эта книга отлич но подойдет и для этой цели. В ней пошагово рассматриваются несколько от дельных проектов, но вы сможете легко возвратиться к изложенному ранее материалу, чтобы позаимствовать фрагменты программного кода, изучить лучшие способы решения задач, свериться с принципиальными схемами и др. Знания в области электротехники, системного проектирования и про граммирования, которые вы приобретете в процессе изучения этой книги, пригодятся вам во множестве друrих областей за пределами платформы Arduino и подготовят вас к работе с разнообразными техническими проекта ми, независимо от того, используют ли они Arduino или какую-либо друrую микроконтроллерную платформу.
ДЛЯ КОГО ЭТА КНИГА Эта книга будет полезной для энтузиастов Arduino с любым уровнем опы та. Каждая новая глава основана на материале предыдущих, содержит по нятия и компоненты проектов из них для разработки более сложных идей. Но не волнуйтесь. При каждой встрече с новыми и сложными идеями пре доставляются ссылки на первое упоминание соответствующих концепций и конструкционных модулей, чтобы помочь вам освежить свою память.
Введение 23 Предполагается, что читатели этой книги могут не иметь опыта работы в области программирования или электротехники. Учитывая пожелания читателей первого издания этой книги, я уделил особое внимание подроб ному объяснению тем, которые для некоторых могут показаться излишне сложными. Чтобы помочь читателям с разным уровнем опыта, книга содер жит несколько факультативных разделов и врезок, которые более подробно объясняют определенное понятие. Хотя эти дополнительные материалы не обязательны для работы с Arduino, они дают более подробное рассмотрение ряда технических аспектов для более дотошных читателей.
ЧЕМУ ВАС НАУЧИТ ЭТА КНИГА В этой книге нет готовых рецептов. Поэтому она не подойдет для тех, кто хочет просто следовать пошаговым инструкциям, подробно излагающим все аспекты разработки определенного проекта, но не объясняющим при этом, зачем все это делается. Данную книгу можно рассматривать как введение в электротехнику, вычислительную технику, проектирование изделий, а также в мышление на высоком уровне, используя платформу Arduino для получе ния практического опыта во всех этих областях. Собирая устройства на базе Arduino из этой книги, вы научитесь не толь ко выполнять монтаж компонентов, но также сможете разобраться в прин ципиальных схемах, узнаете, почему те или иные компоненты используются для определенных целей, а также научитесь читать справочные листки ком понентов, чтобы выбрать наиболее подходящие детали при создании своих проектов. Для программной части проектов предоставляется полный код программы, но сначала рассматриваются и объясняются несколько фрагмен тов, образующих конечную программу. Такой подход поможет закрепить по нимание конкретных функций программы и способствовать приобретению правильных навыков написания кода и пониманию алгоритмов, лежащих в основе программ. Настоящая книга научит вас основам физики, алгоритмам, принципам цифрового проектирования, а также концептам программирования, специ фичным для платформы Arduino. Я надеюсь, что в процессе реализации изложенных в этой книге проектов вы не только станете грамотным разра ботчиком устройств на платформе Arduino, но также приобретете навыки, необходимые для создания более сложных электронных систем, а также для инженерной деятельности в других областях и на других платформах.
Введение
СТИЛЬ ТИПОГРАФСКОГО ОФОРМЛЕНИЯ Чтобы привлечь внимание к некоторой наиболее важной или полезной информации, в этой книге используется следующее типографское оформле ние и форматирование. Внимание! Обязательно обращайте внимание на оформленные таким образом отступления. Они предупреждают, когда неправильные действия могут повредить электронные компо ненты.
Совет Эти отступления содержат краткие советы, как выполнить текущую задачу легче и эф фективнее. Примечание Эти отступления содержат дополнительную, потенциально важную, информацию, включая ссылки на видео и другие онлайн-материалы, которые могут помочь вам в раз работке определенного проекта.
ПРИМЕР ЗАГОЛОВКА Такие расширенные отступления предоставляют более подробную инфор мацию по текущей теме или по связанным с ней аспектам.
ПРИОБРЕТЕНИЕ КОМПОНЕНТОВ При подготовке описания проектов в этой книге я приложил большие усилия, чтобы использовать в них компоненты, которые можно легко приоб рести во многих магазинах электронных товаров как в Соединенных Штатах, так и в других странах. Я также заключил партнерство с компанией Adafruit (www.adafruit.com), которая является популярным розничным поставщиком электронных компонентов для любителей. Таким образом, все компоненты, необходимые для реализации представленных здесь проектов, можно при обрести у этого поставщика. Для вашего удобства на веб-странице https:// www.exploringarduino.com/kits размещен список компонентов для проектов каждой главы. В начале каждой главы также перечислены все компоненты, необходимые для реализации изложенных в ней проектов. Все эти компоненты можно приобрести у многих разных поставщиков. Издательство Wiley также пре доставляет разнообразные электронные ресурсы для этой книги на своем
Введение
веб-сайте (www.wiley.com/go/exploringarduino2e) и, в частности, ссылки на многочисленные источники, где можно приобрести компоненты для проектов каждой главы.
ЧТО ВАМ ПОТРЕБУЕТСЯ Кроме самих компонентов для сборки проектов Arduino, вам потре буются несколько инструментов и материалов. Самым важным из них бу дет компьютер с операционной системой, совместимой с интегрированной средой разработки Arduino IDE (Windows ХР или более поздняя версия, Мае OS Х 10.7 Lion, или более новая версия, или дистрибутив Linux). Когда необходимо, я буду предоставлять соответствующие инструкции для каждой из этих операционных систем. В настоящее время доступна онлайн-среда разработки, но в этой книге мы будем в основном концентрироваться на среде IDE для персональных ком пьютеров. Но все инструкции для среды IDE для настольных компьютеров обычно также применимы и для онлайн-среды IDE. Круг читателей первого издания этой книги был очень обширным, охватывал множество стран с ши роким диапазоном скорости Интернета и надежности доступа к нему. Чтобы и в дальнейшем обеспечить всем желающим легкий и надежный доступ к платформе Arduino, мои инструкции будут в основном применимы к авто номной среде Arduino IDE, поскольку не все имеют постоянный и надежный доступ к Интернету. Для сборки и отладки аппаратных составляющих проектов в этой книге потребуются дополнительные инструменты. Они не только необходимы для реализации проектов из этой книги, но также пригодятся вам и для других проектов, которые вы, возможно, захотите реализовать, используя ваши зна ния и опыт электротехники, приобретенные с помощью этой книги. Я могу порекомендовать следующие основные инструменты и расходные материалы:
■ паяльник и припой; Примечание Некоторые шилды1 и микроконтроллерные платы, упоминаемые в последних главах данной книги, могут продаваться в виде набора, требующего сборки с помощью пайки, в основном впаивания штыревых контактов в отверстия в печатной плате.
■ мультиметр (этот прибор будет полезным для отработки методов отлад ки, рассматриваемых в книге, но не является абсолютно необходимым); ■ набор небольших отверток; ■ пинцет;
1 Это просто калька с английского shield, означает модуль или плату расширения. - Прим. пер.
25
6
Введение
■ проволочные кусачки и инструмент для снятия изоляции с проводов;
■ клеевой пистолет с нагревом; ■ увеличительное стекло (размеры электронных компонентов продол
жают уменьшаться, и иногда необходимо прочитать маркировку, на несенную чрезвычайно мелким шрифтом на интегральных схемах или других компонентах, чтобы можно было посмотреть их характеристи ки в справочном листке или в Интернете).
ИСХОДНЫЙ КОД И ПРОЧИЕ ЭЛЕКТРОННЫЕ РЕСУРСЫ Поддерживаемый автором сайт http://www.exploringarduino.com специ ально предназначен для сопровождения этой книги. С него можно загрузить исходный код примеров и проектов для каждой главы, а также видеоуроки, ссылки и другие полезные материалы. Обратите внимание на то, что по это му адресу доступны электронные ресурсы как для первого издания книги, так и для второго. Поэтому убедитесь, что вы переходите по ссылке для пра вильного издания книги, т. е. второго - 2nd Edition Content. Электронные ресурсы для первого издания книги находятся по адресу https://www.explor ingarduino.com/contentl/, для второго - по адресу https://www.exploringar duino.com/content2/. В меню веб-сайта даются отдельные ясно различимые ссылки на электронные ресурсы разных изданий книги -lst Edition Content и 2nd Edition Content - поэтому у вас не должно возникнуть никаких труд ностей с выбором правильного ресурса. Издательство Wiley также предоставляет электронные ресурсы для этой книги на веб-странице https://www.wiley.com/en-us/Exploring+Arduino%3 А+Tools+and+Techniques+for+Engineering+Wizardry%2C+2nd+Edition-p9781119405375 в разделе Downloads. Ссылку на веб-страницу этой книги на веб-сайте издательства (https://www.wiley.com) можно также получить, вы полнив на сайте поиск по ее номеру ISBN - 9781119405375. Файлы архивов ZIP с исходным кодом для каждой главы можно скачать с любого из этих источников. Скачанные файлы нужно будет разархивировать с помощью соответствующей программы, которой оснащены все упомяну тые ранее операционные системы. Наконец, исходный код для проектов из книги также содержится на по пулярном веб-сайте для обмена открытым кодом GitHub.com (https://github. com/sciguy14/Exploring-Arduino-2nd-Edition). Если вам под силу разобрать ся с управлением версиями на GitHub, то файлы с исходным кодом можно также загрузить из этого хранилища. Ссылки на архив с кодом программ для
Введение
каждой главы, расположенный в хранилище GitHub, также предоставляются на веб-сайте https://www.exploringarduino.com на страницах соответствую щих глав. Примечание Поскольку многие книги имеют похожие названия, если у вас возникнет необходимость выполнить поиск данной книги в Интернете, то для этого лучше всего указать не ее на звание, а код ISBN - 9781119405375. Примечание Некоторые адреса URL (особенно те, которые находятся вне моего контроля) могут быть слишком длинными или измениться в будущем. Чтобы было легче вводить длин ные адреса URL, которые могут встречаться в книге, они заменяются короткими адре сами URL с использованием суффикса сокращения для моего личного веб-сайта: Ьlum. fyi. Например, сокращенный адрес URL Ьlum.fyi/jarvis перенаправляет на страницу на моем веб-сайте для проекта JARVIS.
СПИСОК ОПЕЧАТОК Мы прилагаем все усилия, чтобы обеспечить отсутствие ошибок в тек сте и коде программ. Но никто не идеален, и ошибки случаются. Если вы обнаружите ошибку в этой книге, например, опечатку или неправильный код, то мы будем благодарны, если вы сообщите нам об этом. Предоставляя нам сведения об ошибках, обнаруженных вами в книге, вы поможете сэко номить другим ее читателям многие часы бесплодных попыток понять, по чему определенный проект не работает должным образом. В то же самое время это может помочь нам предоставить вам еще более качественную информацию. Просмотреть список уже обнаруженных ошибок в книге можно по ссыл ке Errata на веб-странице https://www.wiley.com/go/exploringarduino2e. На этой странице можно просмотреть все ошибки в этой книги, о которых нам сообщили и которые были размещены здесь редакторами издательства Wiley. Я также просматриваю все доклады об ошибках и размещаю их на веб-сайте https://www.exploringarduino.com на страницах соответствую щих глав.
ДОПОЛНИТЕЛЬНЫЙ МАТЕРИАЛ И ПОДДЕРЖКА В процессе изучения платформы Arduino у вас неизбежно будут воз никать разного рода вопросы или, возможно, вам придется столкнуться с какими-либо проблемами. В этом отношении вы сможете оценить один из
27
28
Введение
самых лучших аспектов платформы Arduino - существование обширно го онлайн-сообщества, к которому можно обратиться за советом или по мощью в проблемных ситуациях. Эта чрезвычайно активная группа пользо вателей Arduino с готовностью поможет вам при различных затруднениях. Я веду список обновленных ресурсов поддержки по вопросам по Arduino, электротехнике и встроенному программному обеспечению на странице Resources веб-сайта Exploring Arduiono (https://www.exploringarduino. com/resources/). В прошлом я старался сам отвечать пользователям на их вопросы по Arduino, но, к сожалению, это больше невозможно из-за громадного количе ства вопросов, которые я получаю на моем веб-сайте, в Twitter, Facebook, на YouTube и других каналах. Я настоятельно рекомендую обращаться за помо щью через форумы, ссылки на которые даются на странице Resources моего веб-сайта. Я могу почти гарантировать, что они ответят вам быстрее, чем я.
ЧТО ТАКОЕ ARDUINO? Arduino - это аппаратная и программная платформа, с помощью кото рой можно создать прототип любого задуманного вами устройства. Это мо жет быть система управления автоматическим поливом, или веб-сервер, или даже автопилот для мультикоптера. Более конкретно, Arduino - это платформа для разработки устройств на базе микроконтроллера с простым и понятным языком программирования в интегрированной среде разработки Arduino IDE. А оснастив плату Arduino датчиками, приводами, световыми индикаторами, динамиками и более продвинутыми модулями расширения (называемыми шилдами), ее можно превратить в программируемый «мозг» для практически любой системы управления. Трудно даже перечислить все, на что способна платформа Arduino, потому что ее возможности ограничены только вашим воображением. Таким обра зом, эта книга послужит руководством, знакомящим вас с функционально стью Arduino посредством реализации большого количества устройств, что позволит вам получить навыки, необходимые для разработки своих соб ственных проектов. Более подробная информация о плате Arduino и ее разновидностях приво дится в главе 1. Если вам интересно знать внутреннее устройство Arduino, то вам повезло - это полностью открытая платформа как в аппаратном, так и в программном аспекте, и все схемы и документация находятся в свободном доступе на сайте Arduino. Некоторые технические характеристики Arduino приведены в Приложении.
Введение 29
О ДВИЖЕНИИ OPEN SOURCE Если вы новичок в области отрытых источников информации (Open Source), то я рекомендую познакомиться с основными принципами это го движения. Здесь мы не будем вдаваться в подробности, а лишь немного коснемся идеологии данного движения, делающей работу с Arduino такой привлекательной. Получить более полное представление о нем можно на веб-сайте Ассоциации открытого аппаратного обеспечения (Open Source Hardware Association): Ьlum.fyi/OSHW-Definition. Поскольку Arduino является платформой с открытым аппаратным обес печением, все проектные файлы, схемы и исходный код для нее доступны для любого желающего. Это означает, что вы можете не только с большей легкостью модифицировать Arduino для решения какой-либо узкой задачи, но также использовать эту платформу и сопутствующее программное обе спечение в своих разработках, производить и продавать клоны платы Arduino и т.п. На рынке предлагаются сотни плат, основанных на Arduino, при этом часто многие эти платы оснащены специализированными функциями. Лицензия открытой платформы Arduino также разрешает коммерческое использование их разработок (при условии отсутствия торговой марки Arduino на таких разработках). Таким образом, если вы создали на основе Arduino оригинальное устройство и хотите превратить его в коммерческий продукт, то вы можете сделать это. При всем этом непременно соблюдайте лицензионные требования для исходного кода и аппаратного обеспечения, приведенного в этой книге. Некоторые лицензии содержат требование указывать первого автора при публикации разработок на основе предыдущих работ. Другие же требуют всегда предоставлять доступ к внесенным вами улучшениям в исходный продукт по эквивалентной лицензии. Такое предоставление общего доступа помогает развитию сообщества Arduino и созданию онлайн-документации и поддержки, к которым вам часто придется обращаться в процессе экспери ментирования с платформой Arduino. На все примеры программ в этой кни ге распространяются условия лицензии МIТ 1 , что позволяет использовать их без ограничений в любых целях.
НЕСКОЛЬКО СОВЕТОВ ЧИТАТЕЛЮ Некоторые из вас, возможно, уже знакомы с моими популярными ви деоуроками по изучению Arduino и основ электроники на канале YouTube Лицензия открытого программного обеспечения, разработанная Массачусетским технологиче ским институ том. 1
30
Введение
(https://www.youtube.com/sciguyl4). Я постоянно ссылаюсь на них в этой книге, чтобы более подробно осветить изложенные темы. Если вам интересно узнать о том, какие замечательные вещи можно создавать, творчески сочетая электронику, микроконтроллеры и информатику, рекомендую просмотреть мое портфолио с самыми интересными проектами (https://www.jeremyЫum. com/portfolio/). Подобно платформе Arduino, большинство моих разработок соответствует открытой лицензии, что позволяет вам с легкостью использо вать мою работу для ваших собственных нужд. Мне будет интересно узнать, как вы примените знания и навыки, получен ные в результате прочтения этой книги. Я призываю вас поделиться своими открытиями со мной и остальным миром (используйте тег #ExploringArduino в социальных сетях). Желаю удачи в ваших экспериментах с Arduino!
Технические основы платформы Arduino Глава 1. Начало работы и основные сведения о платформе Arduino Глава 2. Цифровые входы и выходы и широтно-импульсная модуляция Глава 3. Считывание сигналов аналоговых датчиков
Начало работы и основные сведения о платформе Arduino
1
Список деталей и оборудования для проектов этой главы :> Плата Arduino Uno или Adafruit METRO 328. :> USВ-кабель (тип А на В для Arduino Uno, тип А на Micro-B для METRO 328). Исходный код и прочие электронные ресурсы • Исходный код программ, видеоуроки и прочие электронные ресурсы для этой главы можно загрузить с веб-страницы https://www.explorin garduino.com/content2/chl. • Исходный код для проектов этой главы можно также загрузить на вкладке Downloads веб-страницы издательства Wiley для этой книги: https://www.wiley.com/go/exploringarduino2e.
з
ЧТО ВЫ УЗНАЕТЕ ИЗ ЭТОЙ ГЛАВЫ
анимаетесь ли вы электроникой только по выходным, чтобы узнать для себя что-то новое, являетесь ли начинающим инженером-электронщиком или разработчиком программного обеспечения, который хочет лучше понять аппаратную составляющую, на которой исполняется ваш код, - запуск в ра боту своего первого проекта Arduino непременно будет для вас стимулирую щим событием. Прочитав вступление, вы уже получили определенное пред ставление о платформе Arduino и ее возможностях, а теперь мы приступим к подробному изучению этих возможностей. В этой главе мы рассмотрим до ступное нам аппаратное обеспечение, ознакомимся со средой разработки и языком программирования, а также напишем и заставим работать нашу пер вую программу. Когда вы поймете, какие возможности может предоставить платформа Arduino, создание этой простейшей программы для Arduino, кото рая мигает светодиодом, не будет представлять для вас никакой трудности. Примечание Изучение материала этой главы можно сопровождать просмотром видеоурока, представ ляющего платформу Arduino. Этот видеофайл находится на странице для главы 1 второго издания этой книги по адресу https://www.exploringarduino.com/content2/ch1.
34
Глава 1. Начало работы и основные сведения о платформе Arduino
ИССЛЕДУЕМ СРЕДУ ARDUINO Для экспериментов с платформой Arduino необходимо наличие трех основных составляющих: платы Arduino (оригинальные или клоны); периферийное оборудование (включая как шилды, так и самостоятель но собранные схемы, которые мы будем рассматривать в этой книге); интегрированная среда разработки Arduino IDE. Все эти системные компоненты работают совместно, позволяя реализо вать с помощью платформы Arduino практически любую задачу. Существует большой выбор плат разработки Arduino. Для большинства проектов в этой книге используются оригинальные платы Arduino разра ботанные одноименной компанией. Но в некоторых проектах последних глав применяются платы-клоны Arduino сторонних разработчиков, позво ляющие расширить стандартные возможности Arduino дополнительны ми функциональностями, как, например, связь Bluetooth и Wi-Fi. Многие платы-клоны Arduino полностью совместимы с программами, библиоте ками и аппаратным обеспечением платформы Arduino. Некоторые из этих плат являются точными копиями официальных плат Arduino, тогда как в другие добавлены дополнительные особенности или возможности. Все платы, предназначенные для реализации проектов в этой книге, можно программировать в одной и той же среде IDE. Когда необходимо, мы бу дем указывать специфичные особенности использования конкретных плат для разных проектов. Большинство проектов в этой книге ориентирова ны на плату Arduino Uno, поскольку, по сути, она стала платой по умол чанию для начальных этапов изучения Arduino. При этом в любом про екте, в котором используется плата Arduino Uno, ее можно заменить пла той Adafruit METRO 328, которая функционально идентична ей. Эту плату можно будет увидеть вместо платы Arduino на некоторых фотографиях и видео, сопутствующих этой книге. В большинстве начальных учебных по собий по Arduino, которые можно найти в Интернете, рекомендуется плата Arduino Uno или ее разновидности. Но если вы предпочтете плату Adafruit METRO 328, для нее, возможно, придется установить драйверы, чтобы Windows определяла ее как Arduino Uno. Эти драйверы можно загрузить по адресу Ыum.fyi/adafruit-windows-drivers.
■ ■ ■
Внимание! Остереrайтесь подделок. Платы Arduino и их клоны следует покупать только у постав щиков с хорошей репутацией (таких как поставщики, упоминаемые в этой книге). На рынке присутствует много компаний, которые изготавливают клоны популярных плат Arduino, используя некачественные компоненты.
Исследуем среду Arduino 35 Мы начнем наше знакомство с платформой Arduino, исследуя базовые воз можности, поддерживаемые всеми платами Arduino. Затем мы рассмотрим различия между всеми современными платами, чтобы вы могли принять обо снованное решение при выборе платы для своего последующего проекта.
БОЛЬШОЙ РАСКОЛ И ПРИМИРЕНИЕ В РЯДАХ ARDUINO Прежде чем приступать к изучению доступных опций в платформе Arduino, нам нужно разобраться с одним щекотливым вопросом, о котором все знают, но предпочитают обходить стороной. В частности, в период времени между выходом из печати первого и второго изданий этой книги команды разра ботчиков аппаратного и программного обеспечения Arduino рассорились между собой. Я не буду вдаваться в подробности этой ссоры или вставать на чью-либо сторону, а только изложу сухие факты. В основном компания Arduino разделилась на две команды, представляемые двумя веб-сайтами: Arduino.cc и Arduino.orb. Эти две группы начали выпускать слегка отлича ющиеся платы, разветвили кодовую базу и оспаривали подлинность обо рудования, производимого противной стороной. К счастью, в настоящее время обе стороны этого противостояния нашли общий язык, и мы снова имеем единую платформу Arduino. В настоящей книге я обычно рассматри ваю оборудование, предлагаемое группой Arduino.cc, хотя к тому времени, когда вы сможете приобрести эту книгу, обе группы Arduino снова должны объединиться. Если вас интересуют нюансы этой драмы, их можно узнать на веб-сайте организации Hackaday.com (https://hackaday.com), которая выпустила ряд докладов на эту тему. А дополнительные подробности о раз решении этого конфликта можно узнать на веб-странице Ыum.fyi/arduino vs-arduino.
Функциональные возможности Arduino Все платы Arduino поддерживают несколько ключевых функциональных возможностей. Уделите немного времени и исследуйте плату Arduino Uno, показанную на рис. 1.1; это будет нашей базовой конфигурацией. Общую функциональность платы Arduino можно разбить на следующие функциональные группы: ■ Микроконтроллер - основной компонент любой платы Arduino. Это «мозги» платы; ■ Программирование - интерфейсы программирования позволяют за гружать программы в плату Arduino; ■ Ввод/Вывод - схемы ввода-вывода позволяют плате Arduino взаимо действовать с датчиками, приводами и прочими периферийными устройствами;
36
Глава 1. Начало работы и основные сведения о платформе Arduino Про�ммирование и Ввод/Вывод: Кнопка сброса ----�
Ввод/Вывод: Контакты общего на3начения, ШИМ и коммуникационные шины
Ввод/вывод: Светодиод отладки и светодиоды USВ-интерфейса
Программирование
�§;
...
,с ...... о,.,..,
,.
о с,, с:,. "'
� < .§ :::е
Питание: 7-12 В поп. тока и стабили3атор напряжения
Питание: Контакты 3емли и положительного напряжения питания
Ввод/вывод: Входы аналого-цифрового преобра3ователя (АЦП)
Рис. 1.1. Функциональные группы платы Arduino. Источник: Arduino, arduino.cc; примечания автора
■ Питание - существуют разные способы подачи питания на плату Ar
duino. Большинство плат могут автоматически переключаться между не сколькими источниками питания (например, от порта USB и от батареи).
Микроконтроллер
Самый важный компонент любой платы Arduino - микроконтроллер. Все первоначальные платы Arduino, включая Arduino Uno, использовали 8-разрядный микроконтроллер ATmega компании Atmel• на основе архитек туры AVRФ. Например, в плате Arduino Uno на рис. 1.1 установлен микрокон троллер ATmega 328Р. Для большинства проектов, которые вы скорее всего захотите реализовать, простого 8-разрядного микроконтроллера подобного этому будет более чем достаточно. Его мы и будем применять для большин ства упражнений в этой книге. Примечание
Компания Atmel была недавно поглощена компанией Microchip, производителем ми кросхем, известным своими микроконтроллерами серий PIC. Производство микросхем ATmega продолжается под этой новой торговой маркой. Поэтому производитель ми кроконтроллеров ATmega может равнозначно называться Microchip или Atmel. Но, не зависимо от названия производителя, если микросхемы разных производителей имеют одинаковый номер артикула детали, они функционально идентичны.
Исследуем среду Arduino
МИКРОКОНТРОЛЛЕРЫ С АРХИТЕКТУРОЙ ИНОЙ, ЧЕМ AVR Но что, если вы хотите заняться чем-то более сложным, например, синтези ровать музыку, запустить веб-сервер или управлять большими светодиод ными дисплеями? Хотя все эти задачи можно реализовать на В-разрядном микроконтроллере, применяя хитроумные приемы программирования для эффективной работы, для них лучше подойдут более быстрые и эффектив ные микроконтроллеры. Как будто бы в ответ на эти потребности компания Arduino расширила диа пазон своих плат устройствами на основе микропроцессоров хВб компании lntel, ARC (Argonaut RISC 1 Core) и ARM l6) (Advanced RISC Machine). Например, в плате Arduino Due используется 32-разрядный микропроцессор Cortexi6) M3 архитектуры ARM. Этот микропроцессор быстрее, чем В-разрядный микроконтроллер AVR, и оснащен большим количеством периферийных устройств, в результате чего плата Arduino Due хорошо подходит для вы полнения таких сложных задач, как синтезирование музыки. Другие новые платы Arduino оснащены возможностями связи Wi-Fi и Bluetooth, что также возможно благодаря наличию в них более быстродействующих процессо ров с большим количеством функций. Мы вкратце рассмотрим некоторые из этих плат далее в этой главе, а также реализуем с их помощью некоторые проекты, описанные далее в этой книге. Для того чтобы программировать и использовать платы Arduino, не обя зательно понимать сложное устройство их процессорных архитектур, по скольку этот аспект скрыт от пользователя несколькими уровнями абстрак ций. Тем не менее некоторые пользователи хотят знать более подробно устройство аппаратного оборудования своих проектов. Чтобы немного по содействовать им в удовлетворении этого желания, далее приведены спи сок и краткие объяснения упоминаемых ранее терминов. 8-разрядная архитектура - архитектура микроконтроллера, в которой все адреса, целые числа и другие основные типы данных представляются в виде В-разрядных двоичных чисел.
■
■ 32-разрядная архитектура - архитектура микроконтроллера, в кото рой все адреса, целые числа и другие основные типы данных представля ются в виде 32-разрядных двоичных чисел. ■ Microchip (ранее Atmel) - компания, занимающаяся изготовлением ми кроконтроллеров. Компания Microchip/Atmel изготавливает как микрокон троллеры AVR, так и процессоры ARM. В большинстве плат Arduino исполь зуются процессоры производства компании Microchip/Atmel. ■ AVR - микроконтроллерная архитектура, разработанная компанией Atmel для своих микроконтроллеров ATmega. 1
Англ. Reduced Instruction Set Computing - вычисления с ограниченным набором команд.
37
38
Глава 1. Начало работы и основные сведения о платформе Arduino ■ ARM - семейство 32/64-разрядных процессорных архитектур, разрабо танных одноименной компанией. Компания ARM предоставляет лицен зии на свои архитектуры встроенных процессоров другим компаниям, как, например, компания Microchip. • Серия Cortex-M - несколько микропроцессорных архитектур ARM, на пример, МО, МЗ и т.п.
Микроконтроллер платы Arduino хранит в своей памяти весь скомпили рованный код программы и исполняет составляющие ее команды. Язык про граммирования Arduino позволяет осуществлять доступ к встроенным пе риферийным устройствам микроконтроллера, включая аналого-цифровые преобразователи (АЦП), контакты ввода-вывода общего назначения, ком муникационные шины (12С 1 , SPI2, УАПП3 и др.), а также интерфейсы RS-232/ USB. Входы и выходы всех этих периферийных устройств выводятся на вы воды микроконтроллера и через дорожки на плате соединяются с разъемами платы Arduino, где их можно использовать, подключая к этим разъемам го товые шилды или собранные вами схемы. На плате Arduino Uno также уста новлен кварцевый резонатор с частотой 16 МГц, подключенный к выводам подачи сигнала тактирования микроконтроллера. Генерируемый этим резо натором прямоугольный сигнал синхронизирует исполнение всех команд программы. Выполнение программы можно прервать и начать снова, нажав кнопку сброса. Большинство плат Arduino оснащены светодиодом, подклю ченным к выводу 13, что позволит нам исполнить нашу первую программу (мигающую светодиодом), не подключая к плате никакого дополнительного оборудования.
Интерфейсы программирования Обычно программы для микроконтроллеров создаются на языке С или на языке ассемблера и записываются в микроконтроллер посредством интер фейса ICSP™4, используя для этого специальный программатор (рис. 1.2). Наверное, самая важная особенность плат Arduino - возможность за писывать в них программы прямо с компьютера, подключив плату к нему через обычный USВ-порт. Такую функцию обеспечивает программа за грузчика Arduino, которая записывается в микроконтроллер один раз при его изготовлении на фабрике (посредством программатора ICSP) и остается в нем постоянно (или пока не будет удалена). Затем эта программа исполь зует УСАПП5 для взаимодействия с USВ-портом компьютера, через который 1 2
' • 5
Англ. Inter-Integrated Circuit - интерфейс связи между интегральными схемами. Англ. Serial Peripheral Interface - последовательный интерфейс (периферийных устройств). Универсальный асинхронный приемопередатчик. Англ. In-Circuit Seria/ Programming~ - внутрисхемное последовательное программирование. Универсальный синхронно-ансинхронный приемопередатчик.
Исследуем среду Arduino
прикладные программы записыва ются в микроконтроллер, не требуя специального программатора. Тема программы загрузчика Arduino рас сматривается более подробно в раз деле «Настройка загрузчика и микро программного обеспечения микрокон троллера Arduino)). В платах Arduino Uno и Mega 2560 USВ-порт подключается к УСАПП микроконтроллера платы не напря Рис. 1.2. Программатор AVRISP mkll (Источник: мую, а через вспомогательный ми © Microchip Technology lncorporated. Репродук ция с разрешения) кроконтроллер (ATmega 16U2 или ATmega8U2, в зависимости от версии платы). На плате Adafruit METRO 328 вместо микроконтроллера ATmega 16U2 установлена мостовая микросхема компании Silicon Laboratories, которая функционально эквивалентна ему. Плата Arduino Leonardo содержит в каче стве основного микроконтроллера микросхему ATmega32U4 со встроенной поддержкой USB, поэтому для этой платы при работе через интерфейс USB отдельный микроконтроллер не требуется. Подобным образом, процессор Cortex МО платы Arduino МО содержит встроенную поддержку USB, поэто му эта плата не требует никаких дополнительных микросхем для работы с интерфейсом USB. В более старых платах Arduino интерфейс между после довательным портом УСАПП микроконтроллера ATmega и разъемом USB обеспечивается с помощью микросхемы преобразователя USB/RS-232 про изводства компании FTDI. Это решение популярно также при разработке пользовательских устройств, совместимых с платформой Arduino.
Ввод-вывод: контакты общего назначения, АЦП и коммуникационные шины
Больше всего в наших проектах: нам придется работать с контактами ввода-вывода общего назначения и входами АЦП. Ко всем этим контактам можно обращаться независимо друг от друга с помощью прикладных про грамм. Контакты общего назначения могут использоваться как для ввода, так и для вывода цифровых сигналов. Контакты АЦП предназначены для ввода аналоговых сигналов (обычно снимаемых с датчиков) с амплитудой от О до 5 В. Многие из этих контактов также мультиплексируются для под держки специальных функций, которые рассматриваются далее в этой книге. В число специальных функций входят различные интерфейсы связи, сигна лы последовательного интерфейса, широтно-импульсная модуляция (ШИМ) и внешние прерывания.
39
О
Глава 1. Начало работы и основные сведения о платформе Arduino
Питание Питание (напряжением +5 В) для большинства рассматриваемых в этой книге проектов подается через кабель USB, которым плата Arduino подклю чается к компьютеру. Но при работе платы в автономном режиме доступны другие опции питания. Большинство плат Arduino могут работать с посто янным напряжением питания величиной от 6 до 20 В. При этом рекомен дуемый диапазон напряжений питания составляет от 7 до 12 В. Питание на плату может подаваться или через цилиндрический гнездовой разъем или на контакты разъема платы Vin. Некоторые платы Arduino работают с логиче скими уровнями величиной 5 В, а другие - 3,3 В. Для плат Arduino с логи ческими уровнями величиной 5 В (в число которых входит и плата Arduino Uno) питание конфигурируется следующим образом: ■ все цифровые схемы на плате используют логические уровни величи ной 5 В. Иными словами, величина низкого входного и выходного ло гического уровня на цифровых выводах платы составляет О В, а высо кого - +5 В; ■ на вывод платы 3.3V с внутреннего стабилизатора платы подается на пряжение величиной 3,3 В для использования шилдами и другими внешними схемами, которые требуют такого напряжения питания. Для большинства проектов в этой книге по умолчанию подразумевается питание плат Arduino от источника с напряжением 5 В, если только не ого варивается другое.
Настройка загрузчика и микропрограммного обеспечения микроконтроллера Arduino Загрузчик представляет собой специальную программу, хранящуюся в зарезервированном участке программной памяти основного микрокон троллера платы Arduino. Микроконтроллеры архитектуры AVR обычно программируются посредством программатора ICSP, который взаимодей ствует с микроконтроллером через интерфейс SPP. Это прямолинейный способ программирования микроконтроллера, но для него требуется на личие специального программатора, например, STK500 или AVRISP mkII (см. рис. 1.2). При подаче питания на плату Arduino запускается загрузчик, который ра ботает в течение нескольких секунд. Если в течение этого времени загрузчик получит через УАПП микроконтроллера от среды разработки IDE команду загрузки, то он загрузит передаваемую ему программу в остальное простран ство памяти для хранения программ микроконтроллера. Если же команда 1
Англ. Serial Peripheral lnterface - последовательный интерфейс (периферийных устройств).
Исследуем среду Arduino :iJl
загрузки не поступает, то на исполнение запускается последняя программа (которая, кстати, на жаргоне Arduino называется скетчем), загруженная в свободную область памяти микроконтроллера. При подаче команды загрузки средой Arduino IDE вспомогательный ми кроконтроллер платы Arduino (ATmega 16U2 или 8U2 в случае Arduino Uno), выполняющий функцию преобразователя USB/RS-232, осуществляет сброс основного микроконтроллера, что переводит его в режим загрузки. Затем внешний компьютер начинает отправлять на микроконтроллер код програм мы, который микроконтроллер получает через свой УАПП с преобразовате ля USB/RS-232. Наличие постоянного загрузчика в памяти микроконтроллера значитель но облегчает его программирование через USB, не требуя никакого дополни тельного оборудования. Но это влечет за собой два недостатка: 1. Программа загрузчика занимает место в памяти микроконтроллера (приблизительно 2 кБ), которое могло бы пригодиться в случае необхо димости загрузить какую-либо сложную прикладную программу. 2. Исполнение программы загрузчика при каждом включении или сбросе платы Arduino означает, что запуск прикладной программы будет за держиваться на несколько секунд, в течение которых загрузчик про веряет наличие запроса на программирование. Если у вас есть программатор (или другая плата Arduino, запрограмми рованная для работы в качестве программатора), то программу загрузчика можно удалить из памяти микроконтроллера и программировать его напря мую с помощью программатора. Для этого программатор нужно подключить к гнездам ICSP и в среде разработки Arduino IDE выполнить последователь ность команд меню Скетч > Загрузить через программатор.
Платы Arduino Существует большое разнообразие плат Arduino, и производители посто янно выпускают новые модели с различными возможностями. Рассмотреть все эти платы в данной книге просто невозможно. Поэтому я остановлюсь только на наиболее распространенных платах Arduino, рассмотрев в следую щих разделах основные возможности этих плат. Плата Arduino Uno (рис. 1.3) является флагманом среди плат Arduino на чального уровня и интенсивно используется в этой книге. На этой плате установлен основной микроконтроллер ATmega 328Р. На плате Mega 2560 (рис. 1.4) установлен основной микроконтроллер ATmega 2560, оснащенный 54 контактами ввода-вывода общего назначения, что позволяет подключать к нему намного больше устройств, чем к плате Arduino Uno.
�2
Глава 1. Начало работы и основные сведения о платформе Arduino
Рис. 1.3. Плата Arduino Uno (Источник: Arduino, ardulno.cc)
Рис. 1.4. Плата Arduino Mega 2560 (Источник: Arduino, arduino.cc)
Плату Mega можно рассматривать, как форсированную версию Uno - она быстрее, имеет увеличенный объем памяти, большее количество каналов АЦП, а также четыре аппаратных последовательных интерфейса по сравне нию с одним на Uno. Плата Mega приблизительно на 50 процентов дороже, чем плата Uno.
Платы Arduino Leonardo и Arduino Micro На обоих этих платах (рис. 1.5 и 1.6) установлен основной микрокон троллер ATmega32U4, который оснащен встроенным интерфейсом USB.
Исследуем среду Arduino 43
Рис. 1.5. Плата Arduino Leonardo (Источник: Pololu Robotics & Electronics, pololu.com)
Рис. 1.6. Плата Arduino Micro (Источник: Arduino, arduino.cc)
Благодаря такой особенности устранена необходимость во вспомогательном микроконтроллере для выполнения преобразования USB/RS-232. Это в свою очередь снижает стоимость платы и позволяет реализовать на ее основе не стандартные проекты, например, эмулировать джойстик и клавиатуру, а не использовать Arduino как простое последовательное устройство. Эти воз можности рассматриваются более подробно в главе 8. Плата Micro функционально идентична плате Leonardo, но меньшего раз мера, что позволяет устанавливать ее в бесконтактную или перфорирован ную макетную плату.
44
Глава 1. Начало работы и основные сведения о платформе Arduino Плата Arduino Due
Эта плата (рис. 1. 7) была первой попыткой компании Arduino внедре ния архитектуры АRМ. В этой плате используется 32-разрядный процессор Cortex-MЗ SАМЗХ архитектуры АRМ. Плата Due отличается наличием АЦП повышенной точности, функцией ШИМ с настраиваемой частотой сигнала, цифроаналоговыми преобразователями (ЦАП), разъемом USB, а также так товой частотой величиной 84 МГц. Кроме только что перечисленных на рынке предлагается большой выбор других плат Arduino. Возможно, что по мере освоения материала этой книги вы посчитаете нужным рассмотреть возможность использования этих плат для более сложных проектов собственной разработки, чем те, которые рас сматриваются в этой книге. В частности, некоторые платы-клоны Arduino сторонних производителей могут быть хорошими кандидатами для решения определенных специфических задач, для которых возможностей стандарт ных плат Arduino окажется недостаточно. Такие платы предлагаются рядом поставщиков, например, SparkFun, Adafruit, Pololu и др. Поскольку Arduino является открытой платформой, на рынке доступны буквально сотни плат клонов Arduino и производных от них. Я лично протестировал продукты и товары, которые я явно называю в этой книге, и могу подтвердить, что они работают должным образом. Но в целом следует быть осторожным, покупая в Интернете платы-клоны Arduino. В частности, рекомендуется попробовать найти обзоры таких плат, чтобы узнать, действительно ли они отвечают за явленным характеристикам. Но при наличии сомнений следует покупать
Рис. 1.7. Плата Arduino Due (Источник: Pololu Robotics & Electronics, pololu.com)
Создаем и исполняем первую программу
Рис. 1.8. Плата Feather 32u4 Bluefruit LE компа нии Adafruit (Источник: Adafruit, adafruit.com)
Рис. 1.9. Плата Photon компании Particle (Источ ник: Adafruit, adafruit.com)
официальные продукты Arduino или же продукты надежных компаний, о которых я говорил чуть ранее. Однако официальные предложения Arduino скромны в некоторых об ластях, например, Bluetooth и Wi-Fi. Поэтому при необходимости реализа ции таких возможностей я рекомендую обратить внимание на совместимые с Arduino платы Feather компании Adafruit, для которых накоплен большой объем документации. Мы будем использовать эти платы в последних главах этой книги для проектов по беспроводной связи Bluetooth и Wi-Fi. На рис. 1.8 показан пример платы-клона Arduino с возможностями Bluetooth, предо ставляемой компанией Adafruit. Навыки, которые вы приобретете, изучая материал этой книги, можно будет с легкостью применить для работы с другими платформами, появив шимися на волне популярности платформы Arduino, в которых реализована аппаратная часть своей разработки, но интерфейс программирования похож на интерфейс Arduino IDE. На рис. 1.9 показан хороший пример такой платы. Это плата Photon производства компании Particle, микроконтроллер которой оснащен возможностью связи Bluetooth, а программирование осуществляет ся на языке наподобие языка программирования Arduino. Я использую эту плату для управления с помощью телефона настольными лампами и оконны ми шторами в моей квартире.
СОЗДАЕМ И ИСПОЛНЯЕМ ПЕРВУЮ ПРОГРАММУ Теперь, коrда мы познакомились с аппаратными средствами Arduino, ко торые мы будем использовать для проектов в этой книге, можно установить среду разработки Arduino IDE (или воспользоваться ее онлайн-версией), на писать и исполнить нашу первую программу.
45
46
Глава 1. Начало работы и основные сведения о платформе Arduino Примечание Прикладные программы Arduino, т. е. программы, которые мы разрабатываем для реше ния какой-либо определенной задачи, называются скетчами. Так мы и будем называть их в дальнейшем.
В этой книге мы будем использовать среду Arduino IDE, установленную на локальный компьютер. Поэтому для начала вам нужно загрузить установоч ный пакет среды и установить ее на свой компьютер.
ОБЛАЧНАЯ СРЕДА РАЗРАБОТКИ ARDUINO CLOUD IDE Для реализации проектов этой книги мы не используем облачную среду раз работки Arduino Cloud IDE, но при желании ее можно задействовать вместо среды IDE, установленной на локальном компьютере. Для этого нужно со здать учетную запись на веб-сайте Arduino (https://www.arduino.cc), а затем перейти на страницу редактора (https://create.arduino.cc/editor). Следуйте инструкциям для установки подключаемого модуля и загрузки кода. о.
(:>G) ARDUINO
HOi.41;
SТORE
SOffWARE
EDUCA"flON
ИESOURCES
COMt.fUNIJY
ННР
.1
S(>fТW...,
• • о
.. ,·)
1
о
•
ARDUINO WEB EDIТOR Start coJJ11S Шt1t v.1:t-1 th� Aн'lv,ro Wtt fd1to1. U,.�yct;fU-etE nc!ve.f'l;.i.lltht!:v1":nt);Jt�t,crai,t1 1,Ю "-lf'port (.Jf r� №u:no t;,,nro3
• CПllNG S1AR'JEO
ЕНiИ!ФЕ •
Download the Arduino IDE ARDUINO 1.8.9
ТМ op«n-.wwt:� A.r..1urno Softw.1:,t CiOE) rnak.ts 1t ••sv to wnнcOМanovp1№1ttotNtюar!S tt;rl.!мon Wlf'ld�'\. /\uc 0S \ &na Lll'IUX ihf tn'l!lonmtf'lt 15 Wf'lttfln in Ji"a &nd Ь.� on Prcxl! входного состояния контакта, он и подключается на землю через понижающий резистор. Резистор называется понижающим 1 потому, что он понижает уровень напряжения на контакте до нуля. Теперь рассмотрим, что происходит при ненажатой кнопке при наличии в схеме понижающего резистора. В таком случае наш контакт подключен на землю через этот резистор. Хотя резистор и ограничивает протекающий че рез контакт ток, это неполное ограничение, и через контакт протекает до статочный ток, чтобы установить на нем низкий входной уровень. Обычно номинал понижающего резистора выбирают равным 1 О кОм. Резисторы большего номинала слабее влияют на потенциал контакта, поскольку их лег че обойти, а резисторы меньшего номинала сильнее снижают его, посколь ку через них току легче протекать на землю. При нажатии кнопки входной 1 В русскоязычной литературе также используются такие термины, как «резистор утечки» или «согласующий резистор». - Прим. пер.
Считывание входных цифровых сигналов
,. s, Контакт 2
4
Земля Рис. 2.5. Принципиальная схема подключения кнопки к плате Arduino (рисунок создан в программе
EAGLE)
Рис. 2.6. Монтажная схема подключения кнопки к плате Arduino (рисунок создан в программе Fritzing)
69
70
Глава 2. Цифровые входы и выходы и широтно-импульсная модуляция
контакт платы Arduino подключается через ее замкнутые контакты напря мую на землю. Теперь у тока с контакта есть два пути: ■ он может протекать через цепь с практически нулевым сопротивлени ем на шину питания 5 В; ■ он может протекать через цепь с высоким сопротивлением на шину земли. Вспомним, что в разделе «Закон Ома и уравнение мощности» говорится, что ток в цепи всегда выбирает путь наименьшего сопротивления. В данном случае подавляющая часть тока протекает через кнопку, поскольку она пред ставляет путь наименьшего сопротивления. В результате на входном контак те платы Arduino создается высокий логический уровень. Примечание Если быть немного педантичным, при нажатой кнопке через понижающий резистор на землю все же будет протекать очень небольшой ток, так называемый ток утечки. Но поскольку при замкнутых контактах кнопки сопротивление в ее цепи настолько близко к нулевому, этот ток утечки практически не влияет на напряжение на входном контакте. Но в коммерческих продуктах, особенно в устройствах с питанием от батарей, напри мер, смартфонах, важен каждый наноампер потребления тока, чтобы повысить время работы батареи. По этой причине в таких устройствах используются понижающие или повышающие резисторы самого большого возможного номинала, которые обеспечи вают протекание через входной контакт достаточного тока, чтобы установить на нем уровень состояния по умолчанию. Таким образом обеспечивается наименьший расход мощности в резисторе. Примечание В данном случае у нас понижающий резистор, но вместо него можно было бы исполь зовать повышающий резистор. Для этого резистор нужно подключить не к шине земли, а к шине положительного питания, а другой контакт кнопки соединить с шиной земли. При такой организации при отпущенной кнопке на входном контакте устанавливается высокий логический уровень, и низкий - при нажатой.
Понижающий или повышающий резистор играет важную роль, поскольку благодаря ему при нажатии кнопки шина положительного питания не зако рачивается на землю, а также устраняется «плавающее» состояние входного контакта. Теперь мы можем написать программу для этой схемы. Сначала мы про сто будем включать светодиод при нажатии кнопки, и удерживать его вклю ченным, пока кнопка остается нажатой. При ненажатой кнопке светодиод находится в выключенном состоянии. Соответствующий код приведен в ли стинге 2.4.
Считывание входных цифровых сигналов Листинг 2.4. Простая программа Led_button.ino дnя управления светодиодом
const int LED=9; const int BUTTON=2;
// Светодиод подключаем к контакту 9 // Кнопку подключаем к контакту 2
void setup0 {
pinMode (LED, OUTPUТ); // Задаем для контакта LED режим вывода pinMode (BUTTON, INPUТ); // Задаем для контакта кнопки режим ввода (не обязательно)
} void toop0 {
if (digitaLRead(BUTTON) = LOW) {
digitaLWrite(LED, LOW);
}
etse {
digitaLWrite(LED, HIGH);
} }
Обратите внимание на наличие в коде некоторых новых конструкций, включая команду digitalRead0 и оператор условия if...else. Также добавлено еще одно объявление- const int BUTTON=2 - для обозначения контакта кноп ки. Кроме того, в функции setupQ контакту кнопки задается режим ввода. Но такое явное задание режима ввода не является обязательным, поскольку для всех контактов установлен режим ввода по умолчанию. Мы выполнили эту установку просто для полноты конфигурации. Функция digitalRead0 считы вает входной сигнал на контакте платы. В данном случае она считывает вход ной сигнал на контакте BUTTON, к которому подключена кнопка. Если кнопка нажата, то на этом контакте присутствует высокий уровень и функция воз вращает значение HIGH (высокий) или 1. Если же кнопка не нажата, то на этом контакте присутствует низкий уровень и функция возвращает значение LOW (низкий) или О. Условный оператор if0 использует функцию digitalReadQ для проверки состояния входного контакта и принятия решения, соответ ствует ли это состояние заданному условию. В данном случае мы проверяем, присутствует ли на входном контакте низкий уровень; если да, то функция digitalReadQ возвратит значение LOW. Проверка выполняется с помощью опе ратора сравнения ==, который проверяет, равняется ли его первый операнд
72
Глава 2. Цифровые входы и выходы и широтно-импульсная модуляция
(значение, возвращенное функцией digitaLReadO) второму операнду (значе нию LOW). Если да (кнопка не нажата), тогда исполняется код в фигурных скобках после оператора if и на контакте LED устанавливается низкий уро вень. В противном же случае (т. е. при нажатой кнопке), исполняется код в фигурных скобках после оператора etse и на контакте LED устанавливается высокий уровень. Вот и вся программа! Загрузите ее в свою плату Arduino и убедитесь, что она работает должным образом.
Проблема дребезга контактов переключателей Когда в последний раз вам приходилось держать кнопку нажатой, чтобы горел свет? Скорее всего, никогда. Более логичный способ управления осве щением - щелкнуть выключателем один раз, чтобы включить свет, а затем щелкнуть опять, чтобы выключить его. При таком подходе нам не нужно удерживать кнопку нажатой все время, в течение которого мы хотим, чтобы был включен свет. К сожалению, реализовать этот подход не так просто, как может вначале показаться. У нас не получится просто проверить состояние кнопки, чтобы выявить его изменение с одного уровня на другой. Причина этому - явление, называемое дребезгом контактов. Переключатели являются механическими устройствами, контакты кото рых работают наподобие пружинных амортизаторов. Иными словами, при нажатии кнопки ее контакты не создают мгновенный постоянный электри ческий контакт, а в течение нескольких миллисекунд размыкаются и смы каются с убывающим размахом, пока наконец не установятся в стабильном замкнутом состоянии. То же самое происходит и при отпуске кнопки. В ре зультате уровень сигнала на выходе кнопки не остается постоянным, а пере ключается между двумя уровнями, пока не примет постоянное состояние на одном из уровней. Это явление иллюстрируется на рис. 2.7, где слева пока зана осциллограмма ожидаемого поведения сигнала, а справа осциллограм ма его действительного состояния. (На рисунке отображены не настоящие осциллограммы, а их эмуляция с помощью сценария MATLAB.) Нажатие кнопки происходит в точке временной оси, отмеченной как 25 мс. Не зная всех нюансов, можно ожидать, что на выходе кнопки сразу же установится высокий логический уровень, как показано на левой осцилло грамме. Но на правой осциллограмме видно, что в действительности контак ты кнопки вибрируют, смыкаясь и размыкаясь, пока не остановятся в ста бильном замкнутом состоянии. Если мы знаем, что при нажатии или отпускании кнопки возникает этот эффект, то с ним сравнительно легко бороться, используя специальную программу. Такая программа отслеживает состояние вывода кнопки и при
Считывание входных цифровых сигналов Сигнал с нажатой кнопки без дребезга
б
5 §
.., s
ЭЕ а:
�
Сигнал с нажатой кнопки с дребезгом
б
5
4
§
.., ..,ЭЕ а:
2
"'
:: 562) {
velocity = map(val, 563, 1023, О, 255); forward(velocity);
} //go backward else if (val < 462) {
velocity = map(val, 461, О, О, 255); reverse(velocity);
} //Ьrake else {
brakeO;
} }
В основном цикле считывается текущее значение выходного сигнала по тенциометра и в зависимости от этого вызывается соответствующая функ ция управления электродвигателем. Вспомним, что значения входных ана логовых сигналов преобразуются в соответствующие цифровые значения в диапазоне от О до 1023. Чтобы разобраться с принципом управления, рассмо трим рис. 4.8 и сравним его с кодом главного цикла. При величине сигнала от потенциометра в пределах 100 единиц от сред ней точки (462) вызывается функция торможения ЬгеаkQдля остановки элек тродвигателя. При увеличении этой величины от 562 до 1023 вызывается
Электродвигатели постоянного тока Режим работы электродвигателя Цифровое значение
Повышение скорости вращения в обратном направлении
(
о
Повышение скорости вращения в прямом направлении
Останов
462
512
562
)
1023
Рис. 4.8. Принцип управления электродвигателем
функция запуска двигателя в прямом направлении forwardQc заданной в па раметре функции скоростью. Подобным образом, при уменьшении величи ны сигнала от 462 до О вызывается функция запуска двигателя в обратном направлении reverseQ с заданной в параметре функции скоростью. Функция сопоставления диапазонов значений mapQ должна быть вам знакомой по материалам предыдущей главы. В данном случае при определении скорости вращения в обратном направлении обратите внимание на порядок перемен ных: значение потенциометра 461 сопоставляется со значением скорости О, а значение потенциометра О - со значением скорости 255. Функция mapQ мо жет выполнять инвертирование при сопоставлении, когда переменные пере даются в нисходящем порядке. Объединив цикл LoopQ с функцией начальной установки setupQ и с вспомогательными функциями, получим полный код программы управления скоростью и направлением вращения электродвига теля (листинг 4.5). Проверьте, что ваша программа такая же, как и в листин ге, и загрузите ее в свою плату Arduino. Листинг 4.5. Программа hbridge.ino дnя управления скоростью и направлением вращения электродвигателя
//Управление электродвигателем с помощью Н-моста const int EN=9; // Вход включения электродвигателя EN const int МС1=3; // Вход 1 управления электродвигателем const int МС2=2; // Вход 2 управления электродвигателем const int РОТ=О; // Сигнал с потенциометра подается на аналоговый // контакт АО платы Arduino // Переменная для хранения значения потенциометра int vaL = О; int veLocity = О; // Переменная для хранения желаемой скорости // электродвигателя (от О до 255) void setupQ {
}
pinMode(EN, OUTPUT); pinMode(MC1, OUTPUT); pinMode(MC2, OUTPUT); brakeQ; // Инициализация выполняется с остановленным электродвигателем
123
i24 Глава 4. Использование транзисторов и управление электродвигателями... void Loop0 { val = anaLogRead(POТ); // Вращение вперед if (vaL > 562) { veLocity = map(vaL, 563, 1023, О, 255); forward(veLocity); }
// Вращение в обратную сторону eLse if (vaL < 462) { veLocity = map(vaL, 461, О, О, 255); reverse(veLocity); }
}
//Торможение eLse { brake0; }
//Функция вращения вперед с заданной скоростью (от О до 255) void forward (int гаtе) { digitaLWrite(EN, LOW); digitaLWrite(MC1, HIGH); digitaLWrite(MC2, LOW); anaLogWrite(EN, rate); } // Функция вращения назад с заданной скоростью (от О до 255) void reverse (int rate) {
digitaLWrite(EN, LOW); digitaLWrite(MC1, LOW); digitalWrite(MC2, HIGH); anaLogWrite(EN, гаtе);
} //Функция торможения void brake О
Создаем шасси самоходного робота 125 {
digitaLWrite(EN, LOW); digitaLWrite(MC1, LOW); digitaLWrite(MC2, LOW); digitaLWrite(EN, HIGH);
}
Работает ли программа, как ожидалось? Если нет, проверьте правильность монтажа схемы. В качестве дополнительного упражнения подключите к сво бодному драйверу И-моста микросхемы L293D второй электродвигатель и напишите программу для управления двумя электродвигателями. Вы долж ны с легкостью справиться с этой задачей.
СОЗДАЕМ ШАССИ САМОХОДНОГО РОБОТА Теперь, когда мы знаем, как управлять скоростью и направлением враще ния одного и нескольких электродвигателей с помощью И-моста, применим эти знания для создания простого самоходного робота.
Выбор компонентов для шасси робота Создание схемы управления самоходным шасси робота поначалу может показаться трудной задачей, но вскоре вы увидите, что у вас уже есть все необходимые знания для ее решения. В самом простом виде для робота тре буются следующие два компонента: датчики или входные сигналы, указы вающие ему, что делать, и приводы, которые преобразуют эти инструкции в соответствующие физические действия.
Выбор электродвигателя и редуктора
Несомненно, при экспериментах со схемой Н-моста вы заметили, что электродвигатели вращаются с очень высокой скоростью. В действительно сти их скорость вращения слишком высока для привода колес небольшого робота. Но эту проблему легко решить с помощью редуктора. В автомоби лях используются сложные редукторы в виде коробки передач для регули ровки соотношения между скоростью вращения и вращающим моментом. При переключении скорости на велосипеде или автомобиле мы выбираем передаточное отношение, при котором обеспечивается требуемая скорость и вращающий момент. Самая простая коробка передач состоит всего лишь из двух шестерен - одна, меньшего диаметра, на валу электродвигателя, а другая, большего диаметра, на оси колеса (или любой другой детали, кото рую нужно вращать). Вследствие разницы диаметров ведущей и ведомой шестерен ведомая ше стерня вращается медленнее, чем ведущая. Рассмотрим пример, где число
126 Глава 4. Использование транзисторов и управление электродвигателями ...
зубьев одной шестерни вдвое больше, чем другой. Если меньшая шестерня установлена на валу электродвигателя, тогда большая шестерня выполнит только пол-оборота при каждом полном обороте меньшей шестерни. Таким способом мы понизили скорость вращения колеса до половины скорости вращения электродвигателя, повысив при этом вращающий момент на оси колеса. Анимированную демонстрацию этого принципа можно посмотреть на веб-странице Ьlurn.fyi/gear-ratio. Соединив вместе несколько таких пар шестерен с понижающим передаточ ным отношением зубьев (диаметров), мы получим редуктор, который может вращать колеса работа с приемлемой скоростью. Быстрый поиск в Интернете выдаст нам сотни поставщиков, предлагающих электродвигатели постоянного тока, уже оснащенные редукторами с разными передаточными отношениями. Чем выше передаточное отношение редуктора, тем меньше скорость враще ния его выходного вала, но больше крутящий момент. Для следующего проек та я рекомендую электродвигатели с редуктором компании Adafruit, которые включены в набор для сборки шасси робота, указанный в списке компонентов для этой главы. Но вместо этого набора для сборки шасси вы можете проявить творческий подход и собрать свое шасси из палочек от мороженого и других бытовых предметов. Независимо от того, из чего вы соберете свою конструк цию, вам потребуются какие-либо электродвигатели с редукторами.
Источник питания для электродвигателей шасси робота В отличие от электродвигателей с питанием напряжением 9 В, которые мы использовали ранее в этой главе, для питания рекомендуемых для этого экс перимента электродвигателей с редукторами необходимо напряжение 5 В. Но это не означает, что питание на них можно подавать в вывода 5V платы Arduino. Наиболее важная характеристика электродвигателей - их ток при заторможенном роторе, т. е. максимальный ток, потребляемый электродви гателем при принудительной остановке вращения его ротора. В зависимости от рабочего напряжения питания, ток при заторможенном роторе для ре комендуемых электродвигателей составляет от 550 до 650 мА. Но даже если брать в расчет более низкое значение 550 мА, это означает, что при одновре менном торможении эти электродвигатели будут потреблять ток свыше 1 А при напряжении 5 В. Стабилизатор напряжения платы Arduino не способен выдать такой ток, поэтому для электродвигателей нам нужен отдельный ис точник питания. Как один из вариантов питание на плату Arduino можно было бы подавать от батареи 9 В, подключив ее к цилиндрическому гнез довому разъему питания платы, а электродвигатели запитать от отдельной батареи с напряжением 5 В. Но два блока батарей может оказаться слишком много для шасси робота. К счастью, есть лучший способ обеспечения пита ния как для платы Arduino, так и для электродвигателей.
Создаем шасси самоходного робота 127
Мы можем подключить к 9-вольтовой батарее отдельный стабилизатор напряжения на 5 В для питания только электродвигателей, а питание для платы Arduino будет обеспечиваться от встроенного стабилизатора, питае мого от той же самой батареи 9 В. Стабилизатор напряжения представляет собой очень простое устройство, которое обычно имеет три вывода: вход, выход и земля. Вывод земли общий как для входного, так и для выходного напряжения. Входное напряжение стабилизатора всегда должно быть выше выходного, а величина выходного напряжения фиксируется на определен ном уровне, в зависимости от типа стабилизатора. Разница между выходным и входным напряжением рассеивается в виде тепла, и стабилизатор должен обеспечивать выходное напряжение постоян ной величины даже при понижении входного напряжения (как в случае с разряжающейся батареей). Для наших экспериментов мы возьмем микросхе му L7805CV стабилизатора напряжения, которая может обеспечить ток ве личиной до 1,5 А при напряжении 5 В. На рис. 4.9 показана принципиальная схема включения этого стабилизатора напряжения. Обратите внимание на конденсаторы на входе и выходе стабилизатора. Это развязывающие конденсаторы, предназначенные для сглаживания пуль саций как входного, так и выходного напряжений. Пульсации напряжения представляют собой небольшие отклонения от номинального напряже ния, вызываемые повышением и понижением величины нагрузки в схеме. Большинство справочных листков для стабилизаторов напряжения содер жат рекомендуемую схему включения, в которой указываются идеальные значения для этих конденсаторов для конкретных применений стабилиза тора. Также следует иметь в виду, что шина положительного питания 5 В этого стабилизатора должна быть отделена от шины питания 5 В для пла ты Arduino. При этом шины земли этих двух источников питания нужно соединить вместе. SV
9V Входное напряжение
Стабилизатор напряжения
sv
Выходное напряжение
Земля (1
sov
10мкФ
N
+
Ul
l7805CV
N
+
(2
sov
10мкФ
Рис. 4.9. Принципиальная схема включения стабилизатора напряжения L7805CV (рисунок создан в программе Fritzing)
128 Глава 4. Использование транзисторов и управление электродвигателями ...
СТАБИЛИЗАТОРЫ НАПРЯЖЕНИЯ И ОГРАНИЧЕНИЕ ИСТОЧНИКА ПИТАНИЯ ПЛАТЫ ARDUINO Почему необходим внешний источник питания в тех случаях, когда неко торые устройства потребляют большой ток? Этому есть несколько причин. Контакты ввода-вывода платы Arduino не могут выдавать ток, превышаю щий 40 мА. Но электродвигатели могут потреблять гораздо больший ток (до сотен миллиампер). Даже если бы контакты платы и могли обеспечить тре буемый ток, их нельзя применять для этой цели, поскольку всплески напря жения, вызываемые индуктивностью обмотки двигателя, могли бы вывести из строя плату. Использование отдельного источника питания для электродвигателя с ра бочим напряжением 9 В выглядит логичным, но зачем нам отдельный ис точник питания для электродвигателя с рабочим напряжением 5 В, таким же самым, как и для платы Arduino? Напряжение 5 В для питания платы Arduino поставляется или с компьютера через разъем USB, или со встроенного ста билизатора напряжения, на который подается внешнее питание через ци линдрический гнездовой разъем. Когда питание на плату Arduino подается через разъем USB, максимальный ток, который может быть предоставлен таким образом для самой платы и всех подключенных к ней периферий ных устройств, составляет 500 мА. Это величина тока, которая обусловлена спецификацией USB. А при подаче питания через гнездовой разъем с внеш него источника питания достаточной мощности встроенный стабилизатор напряжения платы Arduino может выдать только до 1 А тока для всех ком понентов, подключаемых к шине 5 В платы. Часть этого тока потребляется микроконтроллером платы, а остальная часть доступна для периферийных устройств. Но этого тока все равно может оказаться недостаточно для таких устройств с высоким энергопотреблением, как электродвигатели. Кроме того, электродвигатели создают токовые всплески на своих прово дах питания - кратковременные периоды очень высокого потребления тока, когда они набирают обороты. Эти токовые всплески могут создавать пульсации на шине питания 5 В, и могут влиять на другие компоненты, на пример, светодиоды. Наличие отдельного источника питания для электро двигателей позволяет избежать всех этих проблем. Наконец, при недостаточном токе электродвигатель (постоянного тока или переменного) может работать неустойчиво.
Собираем схему управления роботом На рис. 4.1 О изображена принципиальная схема управления самоходным роботом. Большинство ее элементов должны уже быть вам знакомы. Руковод ствуясь данной принципиальной схемой, соберите ее на макетной плате.
111
т
1
Батарея�
_l
9V
L291D
1
1� �1
sv
1)
U1 L7805CV
�
5V
г
Земля
Выходное напряжение
(та6ИJ1и�тор напряжения
Входное напряжение
50V 10мкФ
1 т 11
,s: ;s
)ii с::gJ
1 ),
LEFТ_UGHT RIGНТ_UGHT
-- --
-�UGHT1
� R1 �R2
1 1
�
.J_C2
sv
-------1 "''
------'••
., АО
iorrf
..,,
1
1
�
Земля
,,.
O�PWM
O),WM
Ol
1 Arduino 1
z
>
ArduinoUno (RevЗ)
1
::;
Рис. 4.1 О. Принципиальная схема управления самоходным роботом (рисунок создан в программе Fritzing)
(1 50V 10мкФ
9V
9V
-т
1V 1О
�
-
О1
о
"О
::t
а
о
!
11,/
з::
n
R:s:
11,/
Е
з::
11,/ 11)
о
("'\
:t
130 Глава 4. Использование транзисторов и управление электродвигателями ...
Выводы компонентов с одинаковыми обозначениями соединяются вместе. Такой подход позволяет показать соединения компонентов друг с другом, не загромождая схему пересекающимися соединительными линиями. Таким же образом обозначены подключения компонентов к шине земли и шине 5 В для питания электродвигателей от внешнего стабилизатора. В настоящей схеме используется такая же схема И-моста, как и в наших предыдущих экс периментах по управлению скоростью и направлением вращения электро двигателей. Но в данном случае входное питание И-моста напряжением 5 В подается с выхода отдельного стабилизатора напряжения, поскольку теперь электродвигатели имеют рабочее напряжение 5 В, а не 9 В. В процессе монтажа схемы следует иметь в виду несколько важных мо ментов. Прежде всего убедитесь в правильной ориентации входного и вы ходного выводов стабилизатора напряжения. Если расположить микросхе му стабилизатора так, чтобы сторона с металлической подложкой оказалась сзади, то на левый вывод микросхемы подключается входное напряжение (батарея 9 В), средний вывод соединяется с шиной земли, а с правого выво да берется выходное напряжение 5 В для питания электродвигателей. Далее удостоверьтесь в правильном подключении электролитических конденсато ров, т. е. соблюдена ли правильная полярность. Отрицательный вывод элек тролитических конденсаторов обозначается вертикальной полоской вдоль корпуса конденсатора. Этот вывод нужно подключить к общей земле. Также следите за тем, чтобы выводы конденсатора не касались друга, так как это вызовет короткое замыкание. Для управления самоходным шасси мы будем использовать два фоторе зистора. При освещении фонариком правого фоторезистора шасси повора чивает направо, а левого - налево. При одновременном освещении обоих фоторезисторов шасси движется прямо вперед. Выходные сигналы этих дат чиков подаются на два аналоговых входа платы Arduino. Один из выводов делителей напряжения, образуемых этими датчиками, подключается к кон такту SV выходного напряжения платы Arduino. Обратите внимание на то, что это подключение не должно иметь контакта с выходным напряжением 5 В внешнего стабилизатора, от которого питаются электродвигатели. Проверьте правильность соединений компонентов по монтажной схеме, показанной на рис. 4.11. На рис. 4.12 представлена фотография собранной схемы управления: пла та Arduino с подключенной батареей 9 В, макетная плата со схемой управ ления и подсоединенные к ней электродвигатели. Обратите внимание, что фоторезисторы установлены под углом друг к другу, чтобы обеспечить чет кое определение местонахождения источника света - справа или слева. Убедившись, что все компоненты подключены должным образом, можно переходить к следующему этапу - написанию программы для работы с этой
Создаем шасси самоходного робота
Рис. 4.11. Монтажная схема управления роботом (рисунок создан в программе Fritzing)
Рис. 4.12. Собранная схема управления самоходным роботом
1 -32 Глава 4. Использование транзисторов и управление электродвигателями...
схемой. Но прежде чем устанавливать схему управления на самоходное шас си, написав код для работы с ней, лучше еще раз провери-гь правильность монтажа, вызвав пробное исполнение программы.
Разработка программы управления самоходным шасси
Для работы со схемой управления самоходным шасси мы модифицируем ранее созданную программу. Полный код готовой программы приведен в ли стинге 4.6. Листинг 4.6. Программа car.ino для управления самоходным шасси . . . . . . . . . . . . . . . ...... . . . . · · · · · · · · · · · · ·············· · · · · · · · · · · · · · · · · • . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ..... // Самоходное шасси, управляемое светом // Контакты для управления Н-мостом const int RIGHT_EN =9; // Включение полумоста для правого электродвигателя const int RIGHT_MC1 =2; //Управление выключателем 1 правого моста const int RIGHT_MC2 =3; //Управление выключателем 2 правого моста const int LEFT_EN =10; // Включение полумоста для левого электродвигателя const int LEFT_MCl =4; //Управление выключателем 1 левого моста const int LEFT_MC2 =5; //Управление выключателем 2 левого моста // Контакты платы Arduino для подключения фоторезисторов const int LEFT_LIGHT_SENSOR =О; // Сигнал с фоторезистора подается // на аналоговый контакт АО const int RIGHT_LIGHT_SENSOR =1; // Сигнал с фоторезистора подается // на аналоговый контакт Al // Пороговые значения для движения и значения скорости const int LIGHT_THRESHOLD_MIN = 810; // Минимальный уровень освещения // для начала движения const int LIGHT_THRESHOLD_MAX = 1100; // Максимальный уровень освещения // для начала движения const int SPEED_MIN = 150; // Минимальная скорость // вращения электродвигателя const int SPEED_MAX = 255; // Максимальная скорость // вращения электродвигателя void setup0 {
// Режим вывода для контактов Arduino для управления Н-мостом pinMode(RIGHT_EN, OUTPUТ); pinMode(RIGHT_МС1, OUTPUТ); pinMode(RIGHT_МС2, OUTPUT); pinMode(LEFТ_EN, OUTPUT); pinMode(LEFT_МС1, OUTPUT);
Создаем шасси самоходного робота pinMode(LEFТ_МС2, OUTPUТ); // Инициализация выполняется с остановленными электродвигателями brake("Left"); brake("right"); // Запускаем последовательный интерфейс для калибровки уровней освещения Serialbegiп(9600); } void Loop0 { // Считываем светочувствительные датчики int Left_Light = anaLogRead(LEFТ_LIGHT_SENSOR); int right_Light = anaLogRead(RIGHT_LIGHT_SENSOR); // Небольшая пауза в 50 мс, чтобы обеспечить // считывание последовательного вывода deLay(S0); // Для каждого фоторезистора задаем пропорционально // скорость вращения противоположного электродвигателя. // Не включаем противоположный электродвигатель // ниже минимального значения освещения. // Примечание: Левый датчик управляет скоростью // правого электродвигателя и наоборот. // Чтобы повернуть влево, нужно ускорить вращение // правого электродвигателя. Serialprint("Right: "); Serialprint(right_Light); Serialprint(" "); if (right_Light >= LIGHT_тHRESHOLD_MIN) { // Сопоставляем уровень освещенности со значением скорости // и устанавливаем предел на скорость. int Left_speed = map(right_Light , LIGHT_THRESHOLD_MIN, LIGHT_THRESHOLD_MAX, SPEED_MIN, SPEED_MAX); Left_speed = constrain(Left_speed, SPEED_MIN, SPEED_МАХ); SeriaL.print(Left_speed); // Отображаем на экране скорость вращения forward("Left", Left_speed); // Вращаем противоположный // электродвигатель с вычисленной скоростью
}
eLse { SeriaL.print("0"); brake("Left"); // Если освещенность ниже минимальной, // тормозим противоположный электродвигатель }
rзз
Глава 4. Использование транзисторов и управление электродвигателями .. . Serial.print("\tl..eft: "); Serial.print(left_light); Serial.print(" "); if (left_light >= LIGHT_THRESHOLD_MIN) { // Сопоставляем уровень освещенности со значением скорости // и устанавливаем предел на скорость. int right_speed = map(left_light, LIGHT_THRESHOL.D_МIN, LIGHT_THRESHOLD_МАХ, SPEED_MIN, SPEED_МАХ); right_speed = constrain(right_speed, SPEED_MIN, SPEED_МАХ); Serial.println(right_speed); // Отображаем на экране скорость вращения forward("right", right_speed); // Вращаем противоположный электродвигатель // с вычисленной скоростью else { Seria l.println("O"); brake("right"); // Если освещенность ниже минимальной, // тормозим противоположный электродвигатель } } // Функция вращения вперед с заданной скоростью (от О до 255) // Электродвигатель может быть "left" (левый) или "right" (правый) void forward (String motor, int rate) { if(motor == "left") { digitalWrite(LEFT_EN, LOW); digitalWrite(LEFT_МС1, HIGH); digitalWrite(LEFT_МС2, LOW); analogWrite(LEFT_EN, rate); } else if(motor == "right") { digitalWrite(RIGHT_EN, LOW); digitalWrite(RIGHT_MCl, HIGH); digitalWrite(RIGHT_МС2, LOW); analogWrite(RIGHT_EN, rate); } } // Функция торможения электродвигателя // Электродвигатель может быть "left" (левый) или "right" (правый)
Создаем шасси самоходного робота 13S void brake (String motor) { if(motor == " Left") { digitaLWrite(LEFT_EN, LOW); digitaLWrite(LEFТ_МС1, LOW); digitaLWrite(LEFТ_МС2, LOW); digitaLWrite(LEFT_EN, HIGH); } eLse if(motor == "right") { digitaLWrite(RIGHT_EN, LOW); digitaLWrite(RIGHT_МС1, LOW); digitaLWrite(RIGHT_МС2, LOW); digitaLWrite(RIGHT_EN, Н IGH); } }
Большая часть этого кода такая же, как и код предыдущих примеров из этой и предыдущих глав. Мы использовали уже существующие функции управления скоростью вращения электродвигателя, слегка модифицировав их, добавив один параметр, определяющий, каким электродвигателем управ лять, - правым или левым. Данная программа вращает электродвигатели только для движения вперед, но ее можно легко модифицировать, чтобы, на пример, шасси двигалось назад при низкой освещенности. Константы в начале программы определяют заданные уровни освещенно сти и скорости вращения электродвигателей. Значения этих констант нужно откалибровать в соответствии с уровнями освещенности в вашей конкрет ной ситуации. Для выполнения калибровки программа содержит команды SeriaL.print0, которые выводят в окне монитора порта текущие уровни осве щенности, определяемые каждым фоторезистором. Загрузите скетч в свою плату Arduino и откройте программу монитора порта. Осветите фонариком каждый фотодатчик, чтобы определить их минимальные и максимальные уровни. Затем используйте эти значения в качестве минимального и макси мального пороговых значений освещенности. Этот подход показан в видео фильме для этого проекта на веб-сайте книги. Логика собственно управления самоходным шасси находится в главном цикле toopQ. Считанные с фотодатчиков значения освещенности сопоставля ются посредством функций map0 и constrain0 значениям скорости вращения противоположного электродвигателя. При более высоком уровне освещен ности левого датчика правый электродвигатель начинает вращаться быстрее, в результате чего мобильное шасси поворачивает налево, и наоборот.
136 Глава 4. Использование транзисторов и управление электродвигателями...
Сборка устройства Этот проект можно легко реализовать с помощью компонентов схемы и набора для сборки самоходного шасси, предоставляемых компанией Adafruit. В этом разделе мы рассмотрим, как собрать такое шасси и установить на него компоненты схемы управления. Но если вы желаете сконструировать свою собственную платформу, то это будет даже лучше. Ее можно отпечатать на 30-принтере или сделать из подручных средств. Но независимо от подхода для создания платформы самоходного шасси, все равно настоятельно реко мендуется использовать электродвигатели с редукторами и колесами, предо ставляемые компанией Adafruit. Сборку начинаем с крепления электродвигателей с редукторами к платфор ме. Для этого в комплекте с покупным набором шасси предусмотрены винты и гайки, для шасси вашей собственной конструкции подойдут и другие сред ства, например, клей. Затем надеваем колеса на валы редукторов. Установите на платформу шасси макетную плату со схемой управления и подключите электродвигатели к ней. Если потом обнаружится, что один или оба электро двигателя вращаются не в том направлении, просто поменяйте полярность их подключения к питанию. На рис. 4.13 показано, как может выглядеть собран ное самоходное шасси (тарелочные «глаза» устанавливаются по желанию). В процессе сборки самоходного шасси следует иметь в виду несколько аспектов. Если используется платформа компании Adafruit (или любая другая
Плата Arduino Стабилизатор на S В (скрыт лод пластиной)
Разъем левоrо электродвиrателя
Электродвиrатели с редукторами и колесами
Разъем правоrо злектродвиrателя
переднюю часть шасси
Рис. 4.13. Полностью собранное самоходное шасси
Резюме 137
металлическая платформа), обязательно изолируйте нижнюю сторону платы Arduino от платформы. Из рис. 4.13 видно, что я решил эту задачу, установив плату Arduino на винтовые стойки с пластмассовыми прокладками, чтобы она не прикасалась к металлической пластине. Даже если ваша платформа анодированная, плату Arduino необходимо изолировать от нее с помощью прокладок или простой изоляционной ленты. Острые концы выводов на нижней стороне платы Arduino могут повредить покрытие, в результате чего на плате возникнет короткое замыкание. Также следует быть осторожным с конденсаторами, стабилизатором напряжения и другими компонентами с длинными выводами, установленными на макетную плату. Если требуется согнуть выводы таких компонентов, чтобы установить их в гнезда макетной платы, следите за тем, чтобы случайно не закоротить их. Завершив сборку шасси, подключите к схеме батарею 9 В и с помощью фонарика запустите устройство в движение. В идеале шасси должно следо вать за направлением луча фонарика. Если скорость шасси окажется слиш ком низкой, или схема будет слишком чувствительной к свету или, наоборот, недостаточно чувствительной, или вообще шасси поведет себя странным образом, подключите схему к компьютеру через порт USB, запустите про грамму монитора порта и проанализируйте выводимые в ее окне значения освещенности и скорости электродвигателей. Может потребоваться допол нительно откорректировать пороговые значения этих параметров, как опи сывалось ранее, или же отрегулировать положение фоторезисторов. Если уровень освещенности комнаты слишком высокий, то может потребоваться выключить свет и/или закрыть шторами окна, чтобы схеме было легче рас познавать свет фонарика. Наконец, если какой-то из двигателей вращается не в том направлении, просто поменяйте полярность его питания.
РЕЗЮМЕ В этой главе мы узнали следующее. :) Электродвигатели постоянного тока используют электромагнитную индукцию для преобразования изменений тока, протекающего в обмотке, во вращательное механическое движение. :) Электродвигатели представляют собой индуктивную нагрузку, и для безопасного сопряжения их с платой Arduino необходимо предусмотреть соответствующие схемы защиты и питания. :) Скоростью и направлением вращения электродвигателя постоянного тока можно управлять посредством сигнала ШИМ и И-моста. :) Подключив к плате Arduino аналоговые датчики и приводы, напри мер, электродвигатели, можно создавать интерактивные проекты, в том числе управляемые роботы.
Управление сервоприводами и шаговыми двигателями Список деталей и оборудования для проектов этой главы :> Плата Arduino Uno или Adafruit METRO 328. :> USВ-кабель (тип А на В для Arduino Uno, тип А на Micro-B для METRO 328). :> Беспаечная макетная плата половинного или полного размера. :> Набор проволочных перемычек. :> Кнопки (2 шт.). :> Резистор номиналом 1 кОм (4 шт.). :> Подстроечный потенциометр номиналом 10 кОм (1 шт.). :> Светодиод синего цвета диаметром 5 мм (4 шт.). :> Батарея 9 В (1 шт.}. :> Разъем для батареи напряжением 9 В (1 шт.). :> Микросхема L7805CV стабилизатора напряжения 5 В (1 шт.). :> Электролитический конденсатор, 10 мкФ, 50 В (2 шт.). :> Микросхема сдвоенного И-моста драйвера электродвигателя Т1 L293D. :> Сетевой адаптер, 12 В (рабочий ток >500 мА). :> ИК-дальномер GP2Y0A21YK0FIR компании Sharp в комплекте с JSТ-кабелем. :> Стандартный серводвигатель с рабочим напряжением 5 В. :> Биполярный шаговый двигатель NEMA-17. :> Термоклей или клейкая лента. :> Круглый «циферблат» (можно использовать компакт-диск или вырезать из плотной бумаги). Зажим для бумаг. :> :> Палочка от мороженого.
140 Глава S. Управление сервоприводами и шаговыми двигателями
Исходный код и прочие электронные ресурсы • Исходный код, видеоуроки и прочие электронные ресурсы для этой главы можно загрузить с веб-страницы https://www.exploringarduino. com/content2/ch5. • Исходный код для проектов этой главы можно также загрузить на вкладке Downloads веб-страницы издательства Wiley для этой книги: https://www.wiley.com/go/exploringarduino2e.
в
ЧТО ВЫ УЗНАЕТЕ ИЗ ЭТОЙ ГЛАВЫ главе 4 мы научились управлять электродвигателями постоянного тока. Такие электродвигатели хорошо подходят в качестве тяговых. Но для точного позиционирования они не годятся, поскольку у них отсутствует встроенный механизм обратной связи и регулируется скорость вращения вала, а не его позиция. Чтобы точно знать абсолютное положение ротора электродвигателя, требуется какое-либо внешнее кодирующее устройство или система позиционирования. И наоборот, сервоприводам можно дать команду повернуть вал на определенный угол, в котором он будет находить ся до поступления следующей команды. Такая возможность ценна тем, что она позволяет переместить определенную систему в известное положение. Сервоприводы используются для решения таких задач, как, например, пере мещение защелки замка, вращение якоря на определенное число оборотов или установка точного размера диафрагмы объектива. Шаговые двигатели также позволяют точно управлять углом поворота своего ротора. Это дела ет их идеальными для применения в таких устройствах, как 3D-принтеры, прецизионные инструменты и измерительные приборы. В этой главе мы рас смотрим принципы работы как сервоприводов, так и шаговых двигателей. Управлять этими устройствами будем с помощью платы Arduino.
УПРАВЛЕНИЕ СЕРВОПРИВОДАМИ Сервоприводы широко применяются как в любительской, так и профес сиональной робототехнике. Их можно встретить в разнообразных устрой ствах - от радиоуправляемых моделей самолетов до дверных замков, управ ляемых через Интернет. Они доступны в широком диапазоне размеров и возможностей. Существует два основных типа сервоприводов: кругового вращения и с поворотом ротора в пределах установленного сектора.
Разница между сервоприводами кругового вращения и с поворотом в пределах сектора Стандартные сервоприводы имеют ограниченный угол вращения вала (обычно от О до 180 градусов), поскольку их вал соединен с потенциометром,
Управление сервоприводами 141
который выдает информацию о текущем положении вала. Управление сер воприводом осуществляется подачей на него импульса определенной дли тельности. Длительность управляющего импульса определяет угол поворота вала сервопривода. Но если из сборки сервопривода удалить потенциометр, то вал сможет вращаться вкруговую, и в таком случае длительность импуль са задает скорость вращения вала сервопривода. В проектах, описанных в этой книге, мы будем использовать стандартные сервоприводы, вал которых проворачивается только на заданный угол в пре делах определенного сектора. Если у вас есть желание поэкспериментировать с сервоприводом кругового вращения, можно переделать стандартный сер вопривод, вскрыв его корпус и удалив из него потенциометр. Или же можно купить сервопривод, который уже модифицирован таким образом.
Управление сервоприводом
В отличие от электродвигателей постоянного тока, у сервоприводов три вывода: для подачи положительного питания (обычно красного цвета), зем ли (обычно черного или коричневого цвета) и сигнала управления (обычно белого или оранжевого цвета). На рис. 5.1 показан пример сервоприводов и их выводов. Но у двигателей некоторых производителей другая маркировка проводов, поэтому всегда сверяйтесь со справочным листком, чтобы пра вильно подключить сервопривод. Разные производители сервоприводов могут применять слегка отличаю щиеся цветовые схемы выводов, но наиболее распространена маркиров ка, описанная выше. (Но если вы не уверены насчет своего сервопривода,
управление Рис. 5.1. Примеры серводвигателей и их выводов с цветовой маркировкой
Глава S. Управление сервоприводами и шаговыми двигателями
сверьтесь с его справочным листком.) Подобно электродвигателям серво приводы могут потреблять достаточно большой ток, обычно превышающий возможности платы Arduino. Хотя иногда питания 5 В платы Arduino может быть достаточно для одного или двух небольших сервоприводов, мы соберем отдельный 5-вольтовый источник питания специально для сервоприводов, чтобы при необходимости без труда добавить дополнительные сервоприво ды. Но это не должно быть чем-то новым для вас, поскольку ранее мы при менили такой же подход для питания электродвигателей постоянного тока. В отличие от обычных электродвигателей сервоприводы имеют дополни тельный третий вывод, на который подается сигнал управления. Подавать питание на сервопривод всегда необходимо от стабилизированного источ ника. Управление сервоприводом осуществляется подачей на вывод управле ния сигнала с импульсом регулируемой длительности. Для типичных серво приводов подача сигнала напряжением 5 В и импульсом длительностью 1 мс проворачивает вал в положение О градусов, длительностью 2 мс - в положе ние 180 градусов; импульсы длительностью в интервале между этими двумя предельными значениями проворачивают вал в соответствующие положе ния между двумя крайними положениями. Например, импульс длительно стью 1,5 мс проворачивает вал сервопривода на 90 градусов. Получив им пульс, вал сервопривода поворачивается на соответствующий угол и оста ется в этом положении до прихода следующего управляющего импульса. Но если мы хотим, чтобы сервопривод сохранял установленное положение, т. е. не допускал смещения вала под воздействием внешнего усилия, то нуж но просто посылать на сервопривод этот же импульс каждые 20 мс. Набор команд Arduino содержит команды для работы с сервоприводами, которые автоматически посылают такой сигнал. Чтобы получить лучшее представ ление об управлении сервоприводами, рассмотрим временные диаграммы, изображенные на рис. 5.2. Обратите внимание, что на временных диаграммах на рис. 5.2 импульс на сервопривод посылается каждые 20 мс. При повышении длительности им пульса от 1 до 2 мс угол поворота вала сервопривода (график которого по казан справа от графика импульсов) повышается от О до 180 градусов. Как упоминалось ранее, сервоприводы могут потреблять больший ток, чем плата Arduino в состоянии предоставить. Большинство сервоприводов имеют рабочее напряжение 5 В. Как и в случае с электродвигателями с ра бочим напряжением 5 В из проекта самоходного шасси в предыдущей главе, питание сервоприводов в текущем проекте следует организовать от отдель ного источника, который сможет обеспечить достаточный для них ток. Для этого мы используем ту же самую схему 5-вольтового стабилизатора напря жения на микросхеме L7805CV совместно с батареей 9 В, как и в главе 4.
Управление сервоприводами 143
Н.... � .... ����,�.(·[:. . . .
�.�
....... GЪ.
н ( IJ. . Пп ...·�.��=,··.� П�'.... .......�. О 1 2 3 4 5 6 7 8 9 1011 12 13 14 15 16171819 202122 23 24 25 26272829 303132 33 34 35 36373839 40
Имnу11ьсw ДIIIIТeJlltHomtlO 1,25МС(4S rрадусов )
ВреМ!l(МС)
45rрадусов 90
1so(
J 1 1 �1 1 1 J 1 1 1 1 1 1 1 1 1 1 1 l 1 1 �1 r 1 1 1 1 1 1 1 1 1 1 1 1
/.· \о
О 1 2 3 4 5 6 7 8 9 1011 12 13 14 15 16171819 202122 23 24 25 26272829 303132 33 34 35 36373839 40
ВреМ!I (мс)
О 1 2 3 4 5 6 7 8 9 1011 12 13 14 15 16171819 202122 23 24 25 26272829 303132 33 34 35 36373839 40
Ммn дЬСW д,1111'1!111tИ у ОСТЫО2Мс(1
i:l
Время (мс)
80 -) п
з!
О
, 1 , 1
, 1 1 , , , , , r , , , , 1 , , ,
1 , , , r , , 1 , , , , 1
О 1 2 3 4 5 6 7 8 9 1011 12 13 1415 16171819 202122 23 24 25 26272829 303132 33 34 35 36373839 40
,.r::\.
Время (мс)
Рис. 5.2. Временные диаграммы для сервоприводов (рисунок создан в программе MATLAB)
Примечание Также следует иметь в виду, что шина положительного питания напряжением 5 В, созда ваемого этим стабилизатором напряжения, должна быть отделена от шины питания 5 В платы Arduino. При этом шины земли этих двух источников питания нужно соединить вместе, чтобы обеспечить общую опорную точку между уровнями напряжений в двух частях схемы.
Теперь у нас достаточно информации, чтобы приступить к сборке схемы для управления сервоприводом. На рис. 5.3 изображена монтажная схема для подключения сервопривода, внешнего стабилизатора напряжения на 5 В и потенциометра, которой можно руководствоваться в процессе сборки. Подключите средний вывод потенциометра к аналоговому контакту АО пла ты Arduino, вывод управления сервопривода - к контакту 9 платы, а также проверьте, что на сервопривод подается питание от батареи 9 В через стаби лизатор напряжения. В процессе монтажа схемы следует иметь в виду несколько важных момен тов. Прежде всего, вспомним из предыдущей главы, как подключать стаби лизатор напряжения: разместив микросхему стабилизатора таким образом,
144 Глава 5. Управление сервоприводами и шаговыми двигателями
Стабилизатор на S В
Батарея 9 В
Серводвигатель
Блокирующие конденсаторы
Потенциометр
Рис. 5.3. Монтажная схема подключения сервопривода (рисунок создан в программе Fritzing)
чтобы сторона с металлической подложкой оказалась сзади, на левый вы вод микросхемы подключается входное напряжение (от батареи 9 В), сред ний вывод соединяется с шиной земли, а с правого вывода берется выходное напряжение 5 В для питания сервопривода. После этого удостоверьтесь в правильном подключении блокирующих электролитических конденсаторов, т. е. в их правильной полярности. Отрицательный вывод электролитических конденсаторов обозначается вертикальной полоской вдоль корпуса конден сатора. Этот вывод нужно подключить к общей земле. Также следите за тем, чтобы выводы конденсатора не касались друга, так как это вызовет короткое замыкание. Убедившись, что все компоненты подключены должным обра зом, можно переходить к следующему этапу - написанию программы для работы с этой схемой.
Программа управления сервоприводом Среда разработки Arduino IDE содержит встроенную библиотеку Servo.h для работы с сервоприводами, что значительно облегчает задачу написа ния соответствующих программ управления. Программная библиотека
Управление сервоприводами 145
представляет собой набор готовых функций и других модулей кода, которые можно вставлять в разрабатываемые пользователем программы. Среда раз работки Arduino IDE содержит несколько библиотек для решения распро страненных задач. Библиотека Servo.h реализует процедуры тактирования для подачи импульсов на контакт управления сервопривода, избавляя вас от этой необходимости. Вам нужно будет лишь подключить сервопривод к тре буемому контакту платы Arduino и задать для него необходимый угол враще ния. Библиотека выполнит всю остальную работу, даже задавая для контакта выходной режим работы. Самый простой способ проверить функциональ ность сервопривода - напрямую управлять позицией его вала с помощью потенциометра. В частности, минимальное значение сигнала потенциоме тра (О) устанавливает вал сервопривода на угол О градусов, а максимальное (1023) - на угол 180 градусов. Чтобы увидеть эту функциональность в дей ствии, создайте новый скетч, вставьте в него код из листинга 5.1 и загрузите его в свою плату Arduino. Листинг 5.1. Программа servo.ino дпя управления сервоприводом с помощью потенциометра
// Программа для управления сервоприводом с помощью потенциометра #include const int SERVO = 9; // Подключаем сервопривод к контакту 9 const int РОТ= О; // Сигнал с потенциометра подается // на аналоговый контакт АО Servo myServo; // Переменная для хранения значения потенциометра int val = О; void setup0 {
// Подключаем объект сервопривода myServo.attach(SERVO);
} void Loop0 {
}
// Считываем значение сигнала потенциометра val = map(val, О, 1023, О, 179); // Сопоставляем его с соответствующим значением // в диапазоне значений положений сервопривода myServo.write(val); // Задаем положение сервопривода // Пауза, чтобы дать сервоприводу delay(15); // время отреагировать на команду
val = analogRead(POТ);
146 Глава 5. Управление сервоприводами и шаговыми двигателями
Оператор incLude в начале программы подключает к нашему скетчу функ циональность библиотеки Servo.h. Команда myServo.attach(SERVO) создает объект сервопривода с названием myServo и сопоставляет его с нашим сервоприводом. Теперь все обращения к сервоприводу к коде выполняют ся через это название. При подключении объекта сервопривода в функ ции setup0 выполняются все необходимые инициализации для управления им. Для управления несколькими сервоприводами нужно каждый из них подключить к отдельному контакту Arduino и создать для каждого из них объект Servo с собственным названием. В цикле LoopQ выполняется считы вание сигнала потенциометра, сопоставление его с соответствующим зна чением управляющего сигнала сервопривода, а затем подача этого значе ния на сервопривод формированием импульса на контакте платы Arduino, к которому он подключен. Пауза длительностью 15 мс позволяет серво приводу занять указанную позицию перед подачей следующей команды управления.
СОЗДАНИЕ СКАНИРУЮЩЕГО ДАЛЬНОМЕРА В следующем проекте мы используем наши новые знания по управлению сервоприводами совместно со сведениями из предыдущих глав для созда ния сканирующего дальномера со световой индикацией. Система состоит из инфракрасного (ИК) датчика расстояния, установленного на качалку серво привода, и четырех индикаторных светодиодов. Сервопривод циклически устанавливается в четырех положениях, соответствующих четырем секто рам комнаты, и в каждом из них определяется приблизительное расстояние до находящихся в них объектов, позволяя определить, насколько они далеко или близко. Яркость каждого из четырех светодиодов меняется в зависимо сти от расстояния до объекта. Инфракрасный свет является частью электромагнитного спектра, неви димой для человеческого глаза, что позволяет приспособить эту систему для создания своеобразного «ночного видения». Принцип работы ИК-датчика расстояния следующий. Объект освещается светом ИК-диода, отраженный от объекта свет принимается фотоприемником, расположенным рядом с излучателем, а затем определяется угол между излученным и отраженным лучами света. По величине выходного напряжения ИК-датчика вычисляет ся расстояние до объекта, которое затем преобразуется в выходной анало говый сигнал, пригодный для подачи на вход микроконтроллера. Даже если в комнате темно и вы не можете понять, как далеко находится объект, такой датчик сможет «увидеть» его, поскольку он работает в видимом для него ИК диапазоне злектромагнитных излучений.
Создание сканирующего дальномера 147
Разные модели ИК-дальномеров могут иметь различные интерфейсы. Если ваш дальномер оснащен иным интерфейсом, чем тот, который исполь зуется в этом примере, посмотрите в его справочном листке, выдает ли он выходной аналоговый сигнал. Примечание Демонстрацию работы сканирующего датчика расстояния можно посмотреть в видео клипе на странице https://www.exploringarduino.com/content2/chS. Этот видеоклип также доступен на веб-сайте книги издательства Wiley, указанном в начале этой главы.
Первым делом прикрепите ИК-датчик расстояния на качалку сервоприво да, как показано на рис. 5.4. Я предпочитаю применять для этого термоклей, поскольку он обеспечивает прочное соединение, но при необходимости до статочно легко удаляется. Но вы можете выполнить крепление любым до ступным или предпочитаемым способом, используя суперклей, пластилин, липкую ленту и т.п. Далее подключите сервопривод к плате Arduino через отдельный стабили затор напряжения на 5 В, как в предыдущем эксперименте. Вместо потенцио метра подключите к аналоговому входу АО ИК-датчик расстояния. Четыре светодиода подключаются к контактам 3, 5, 6 и 11 через последовательные то кооrраничивающие резисторы номиналом 1 кОм. Плата Arduino Uno имеет всего шесть. контактов ШИМ, но ШИМ-сиrнал не может подаваться на кон такты 9 и 10 (функцией anaLogWriteO), когда используется библиотека Servo.h. Это объясняется тем, что библиотека Servo.h задействует тот же самый ап паратный таймер, который при'меняется для управления сигналом ШИМ на этих контактах. Поэтому мы выберем четыре других контакта ШИМ.
Рис. 5.4. ИК-датчик расстояния, установленный на качалку сервопривода
148 Глава 5. Управление сервоприводами и шаговыми двигателями Примечание Чтобы осуществить этот проект с количеством светодиодов большим,'чем четыре, мож но или использовать плату Arduino Mega, или же реализовать программное решение ШИМ. Но последний вариант не рассматривается в этой книге.
На рис. 5.5 показана монтажная схема проекта; проверьте по ней правиль ность своего монтажа. В своем устройстве я выбрал светодиоды синего цвета, но можно взять светодиоды любого цвета. Если провода вашего ИК-датчика расстояния не оснащены разъемом, удалите немного изоляции с концов проводов, скрути те жилы вместе, а затем вставьте провода в гнезда на макетной плате и пла те Arduino. Завершив сборку схемы, рекомендуется закрепить сервопривод клейкой лентой, как показано на рис. 5.4. Теперь осталось создать программу для нашего дальномера. Логика про граммы следующая: устанавливаем вал сервопривода в заданное положение, измеряем расстояние, преобразуем его в значение, которое можно исполь зовать для управления светодиодом, изменяем яркость светодиода, пере мещаем вал сервопривода в следующее положение, и т.д. Соответствующий код программы приведен в листинге 5.2. Скопируйте его в новый скетч и загрузите в плату Arduino.
ИК-датчик
Блокирующие конденсаторы Рис. S.S. Монтажная схема проекта сканирующего ИК-дальномера (рисунок создан в программе Fritzing)
Создание сканирующего дальномера 149
Листинг 5.2. Программа сканирующего ИК-дальномера sweep.ino // Программа сканирующего дальномера #incLude const int SERVO =9; // Подключаем сервопривод к контакту 9 const int IR =О; // Сигнал с ИК-датчика подается на аналоговый контакт АО const int LED1 =3; // Контакт для управления светодиодом 1 const int LED2 =5; // Контакт для управления светодиодом 2 const int LED3 =6; // Контакт для управления светодиодом 3 const int LED4 =11; // Контакт для управления светодиодом 4 Servo myServo; // Объект сервопривода int dist1 = О; // Переменная для хранения расстояния первого сектора int dist2 = О; // Переменная для хранения расстояния второго сектора int dist3 = О; // Переменная для хранения расстояния третьего сектора int dist4 = О; // Переменная для хранения расстояния четвертого сектора void setup0 {
myServo.attach(SERVO); pinMode(LED1, OUTPUТ);
// Подключаем объект сервопривода // Задаем режим вывода для контакта // первого светодиода pinMode(LED2, OUTPUТ); // Задаем режим вывода для контакта // второго светодиода pinMode(LED3, OUTPUТ); // Задаем режим вывода для контакта // третьего светодиода pinMode(LED4, OUTPUТ); // Задаем режим вывода для контакта // четвертого светодиода
} void loop0 { // Сканируем сервоприводом 4 сектора и обновляем состояние светодиодов // Измеряем расстояние в положении 15 градусов dist1 = readDistance(15); // Обновляем яркость светодиода analogWrite(LED1, dist1); // Пауза перед следующим замером delay(300); dist2 = readDistance(65); // Измеряем расстояние в положении 65 градусов // Обновляем яркость светодиода anaLogWrite(LED2, dist2); delay(300); // Пауза перед следующим замером dist3 = readDistance(115); // Измеряем расстояние в положении 115 градусов // Обновляем яркость светодиода analogWrite(LED3, dist3); delay(300); // Пауза перед следующим замером dist4 = readDistance(165); // Измеряем расстояние в положении 165 градусов // Обновляем яркость светодиода analogWrite(LED4, dist4); // Пауза перед следующим замером delay(300); }
150 Глава 5. Управление сервоприводами и шаговыми двигателями int readDistance(int pos) { myServo.write(pos); deLay(б0O); int dist = anaLogRead(IR); dist = map(dist, 50, 500, О, 255); dist = constrain(dist, О, 255); retur n dist;
// Перемещаемся в следующее положение // Даем сервоприводу время на перемещение // Считываем ИК-датчик // Сопоставляем его соответствующему // значению яркости светодиода // Накладываем ограничения // Возвращаем сопоставленное значение
}
В программе применяется пользовательская функция readDistance0, кото рая вращает качалку сервопривода на заданный угол, измеряет расстояние, сопоставляет значение расстояния со значением яркости светодиода, после чего возвращает управление в основной цикл LoopQ. Выбор диапазона значений для сопоставления яркости светодиода с рас стоянием до объекта зависит от настроек вашей системы. В моем случае я обнаружил, что для ближайшего объекта датчик выдавал значение 50, а для самого дальнего - 500, поэтому функция map0 была настроена с учетом этих значений. Главный цикл Loop0 исполняет эту функцию для каждого из четы рех светодиодов, а затем все повторяется. Готовая система должна работать примерно так, как показано в демонстрационном видеоклипе, ссылка на ко торый приводится в начале этого раздела.
ШАГОВЫЕ ДВИГАТЕЛИ И УПРАВЛЕНИЕ ИМИ Задача выбора требуемого шагового двигателя, разработки схем с их ис пользованием, управления ими и внедрения их в оборудование настолько сложна, что для ее освещения можно было бы написать отдельную книгу. Из-за обширности этой области здесь мы рассмотрим только управление би полярными четырехвыводными шаговыми двигателями. Шаговые двигатели представляют собой в высшей мере универсальные электродвигатели, прин цип действия которых заключается в попеременной подаче питания на фазо вые обмотки неподвижного статора, расположенные вокруг вращающегося магнитного ротора. В результате последовательного включения и выключе ния этих обмоток создается перемещающееся по кругу магнитное поле, кото рое «тянет» за собой намагниченный ротор. Ротор шагового двигателя вращается по одному шагу за раз (что и отобра жено в его названии), точность перемещения очень высокая, она определяет ся электромагнитными характеристиками электродвигателя - количеством обмоток/фаз, конструкцией магнитного ротора и т.п. Как результат этого шаговые двигатели замечательно подходят для задач, требующих высокой
Шаговые двигатели и управление ими 151
точности позиционирования. Шаговые двигатели также обладают большим преимуществом по сравнению со щеточными электродвигателями - высо ким крутящим моментом при низких скоростях вращения. Областью при менения шаговых двигателей является робототехника, промышленные авто матизированные системы, ЗD- и 2D-принтеры, ЧПУ (числовое программное управление) оборудование и панели управления. Компания Shaper Tools (https://www.shapertools.com), в которой я зани маю должность технического директора, использует шаговые двигатели в своем ручном электрофрезере Origin для обеспечения быстродействующего ЧПУ-позиционирования в режиме реального времени. На рис. 5.6 показан биполярный шаговый двигатель форм-фактора NEMA-17, который вскоре понадобится в наших проектах.
Рис. 5.6. Биполярный шаговый двигатель NEMA-17: внешний вид (вверху); внутреннее устройство (внизу). Источник: компания Adafruit (https://www.adafruit.com)
152 Глава 5. Управление сервоприводами и шаговыми двигателями
В униполярных шаговых двигателях ток протекает по одной половине об мотки в одном направлении, а по второй половине - в другом. В результа те этого для них требуются более простые драйверы, но это также означает, что они могут выдавать только половину своего потенциального крутящего момента. С другой стороны, в биполярных шаговых двигателях ток может протекать по всей обмотке в обоих направлениях, создавая вдвое больший крутящий момент, чем униполярный двигатель со сравнимой обмоткой. Поэтому для управления биполярными шаговыми двигателями требуется Н-мост, с работой которого мы познакомились в предыдущей главе. Примечание
Обозначение NEMA-17 определяет только размер установочной (торцевой) стороны шагового двигателя, а не его тяговые характеристики. Шаговые двигатели типа NEMA17 доступны в широчайшем диапазоне мощности и крутящего момента.
Принцип работы биполярных шаговых двигателей Биполярные шаговые электродвигатели позволяют получить максималь ный крутящий момент при приемлемых габаритах. Они имеют по одной об мотке из медного провода для каждой фазы, каждая из которых состоит из не скольких частей, соединенных последовательно и намотанных на сердечниках из мягкого металла. Когда по обмоткам протекает ток, сердечники становятся электромагнитами, создающими вокруг себя магнитное поле. Обмотки разме щены вокруг вращающегося намагниченного ротора. (На рис. 5.6 можно ви деть восемь обмоток.) Части обмоток разных фаз чередуются друг с другом по периметру статора. Последовательное включение этих обмоток создает пере мещающееся магнитное поле, которое заставляет ротор вращаться. Принцип работы биполярного шагового электродвигателя упрощенно иллюстрируется на рис. 5.7. Обмотки lA и lB соединены последовательно, т. е. электрически являются одной обмоткой. Обмотки 2А и 2В соединены таким же образом. Концы этих катушек выводятся наружу в виде четырех изолированных проводов. 1. На первом шаге ток по обмоткам не протекает. Вследствие этого маг нитное поле, которое могло бы воздействовать на ротор из постоянного магнита, отсутствует. При этом ротор можно свободно проворачивать, приложив внешнее усилие к валу электродвигателя. 2. Питание подается на обмотки первой фазы, в результате чего через них начинает протекать ток, втекая в обмотку lA и вытекая из обмотки lB. Вследствие протекания тока через обмотки на сердечниках из мягкого металла индуцируется магнитное поле, под воздействием которого на магниченный ротор фиксируется в текущем положении.
Шаговые двигатели и управление ими 153
х
Обмотка 2 А
Питание не подается
Ток через обмотки не протекает. Ротор можно свободно вращать рукой.
Питание подается
1-·" ,1,
Ток протекает через обмотку 1, индуцируя магнитное поле. Ротор фиксируется в текущем положении.
Питание подается, ротор вращается
Ток протекает через обмотку 2, индуцируя новое магнитное поле, сдвинутое по отношению к предыдущему. Ротор в виде постоянного магнита вращается вслед за этим полем.
х
Обмотка lд
Обмотка 1 А
.r
100-,В
х
Питание подается, ротор вращается
Ток протекает через обмотку 1, но в противоположном направлении по сравнению с шагом 2. Созданное магнитное поле также имеет обратную полярность. Ротор вращается вслед за этим полем.
х
х
Питание подается, ротор вращается
Ток протекает через обмотку 2, но в противоположном направлении по сравнению с шагом 3. Созданное магнитное поле также имеет обратную полярность, чем магнитное поле на шаге 3. Ротор вращается вслед за этим полем.
J,
Питание подается, ротор вращается
Повторяется шаг 2. Ротор снова вращается, возвращаясь в исходное положение.
Рис. 5.7. Последовательность операций шагового электродвигателя
3. Питание с фазы 1 (обмотки lA и IВ) снимается и подается на фазу 2, в результате чего ток втекает в обмотку 2В и вытекает из обмотки 2А. В результате создается магнитное поле, сдвинутое на 90 градусов по часовой стрелке относительно магнитного поля, которое индуцирова лось обмотками 1. Поскольку противоположные магнитные полюсы притягиваются друг к другу, ротор притягивается к этому магнитному полю, в результате чего он вращается по часовой стрелке. 4. Питание с фазы 2 снимается и снова подается на фазу 1, но на этот раз в об ратной полярности, чем в предыдущий раз (используя для этого И-мост). В результате ток также протекает через эти обмотки в противополож ном направлении, чем в первый раз. Это противоположное направление протекания тока означает, что теперь направленность магнитного поля
154 Глава S. Управление сервоприводами и шаговыми двигателями
противоположна его направленности на шаге 2. Ротор электродвигателя вращается по направлению к новому магнитному полю. 5. Питание с фазы 1 снимается и снова подается на фазу 2, но опять с об ратной полярностью, чем на шаге 3. Ротор электродвигателя вращается по направлению к новому магнитному полю. 6. Процесс повторяется подачей питания на обмотки фазы 1 с первона чальной полярностью. Примечание
Подробное рассмотрение темы электромагнетизма вне рамок этой книги. Но если вы желаете узнать, почему ток, протекающий через обмотку с металлическим сердечником, индуцирует магнитное поле, то данную информацию можно найти в Интернете, выполнив поиск по ключевым словам «уравнения Максвелла» и «Ампер».
ОТЛИЧИЯ НАСТОЯЩИХ ШАГОВЫХ ДВИГАТЕЛЕЙ ОТ ПРИВЕДЕННОГО УПРОЩЕННОГО ПРИМЕРА На рис. 5.7 показан упрощенный пример биполярного шагового электро двигателя. В только что рассмотренном примере для каждой фазы исполь зуется только две обмотки, а не четыре, как в реальном шаговом электро двигателе, показанном на рис. 5.6. Кроме того, в примере ротор состоит из одного магнита с одной парой полюсов: один северный и один южный. В ре зультате электродвигатель из примера за один оборот может делать только четыре шага. Но шаговый двигатель, который мы будем использовать в на ших проектах, способен совершать 200 шагов на оборот. Такое число ша гов возможно благодаря большему количеству обмоток, а также большему количеству чередующихся полюсов магнитного ротора. Эти полюса видны на рис. 5.6 в виде выступов по окружности ротора. В результате при каждом переключении напряжения на обмотках ротор такого шагового электро двигателя проворачивается только на небольшой угол. А ротор шагового электродвигателя из примера на рис. 5.7 при каждом переключении напря жения на обмотках будет проворачиваться на угол 90 градусов.
Приводим шаговый двигатель в действие Теперь, когда мы рассмотрели принцип работы шагового электродви гателя, можно приступать к сборке схемы для управления его вращением. Возможно, вы заметили в предыдущем примере, что управление биполяр ным шаговым электродвигателем осуществляется подобно переключению направления вращения двух щеточных электродвигателей постоянного тока. Единственная разница состоит в том, что фазовые обмотки находятся не в двух разных электродвигателях, а в одном. Но питание на обмотки каждой
Шаговые двигатели и управление ими 155
фазы должно подаваться с чередующейся сменой полярности, как описывается в примере на рис. 5.7. Для решения этой задачи подойдет тот же самый интегрированный драйвер И-моста, который мы использовали для управления двумя щеточными электродвигателями в предыдущей главе. Но есть два важных отличия схемы для управления шаговым двигате лем с Н-мостом от схемы управления двумя щеточными электродвигателя ми. Прежде всего, напряжение питания вашего шагового электродвигателя, скорее всего, выше, чем 5 В. (Точно узнать величину напряжения можно по справочному листку для вашего шагового электродвигателя.) Если вы при обрели рекомендуемый шаговый электродвигатель форм-фактора NEMA-17 у компании Adafruit, то его напряжение питания должно быть 12 В. В таком случае для его питания я рекомендую применить сетевой адаптер с выходным напряжением 12 В постоянного тока. (Шаговые электродвигатели потребля ют большой ток и очень быстро израсходуют заряд батареи.) Подключите выходной разъем адаптера к цилиндрическому гнездовому разъему пита ния платы Arduino. Встроенный стабилизатор напряжения платы понизит напряжение адаптера до 5 В для питания микроконтроллера и логической схемы И-моста. В то же самое время питание 12 В от адаптера будет доступно на гнезде Vin платы Arduino, с которого его можно будет брать для подачи на контакт микросхемы И-моста для питания шагового электродвигателя. Второе отличие состоит в том, что на контакты включения Н-моста мож но напрямую подавать высокий логический уровень (5 В), в результате чего драйвер будет постоянно включенным. Функции библиотеки Arduino для ра боты с шаговыми двигателями, которые понадобятся в наших программах, обеспечат отсутствие комбинаций включенных переключателей Н-моста, которые могут вызвать его повреждение. Руководствуясь принципиальной схемой на рис. 5.8, подключите микросхему И-моста к своей плате Arduino. Если вы не можете определить выводы обмоток каждой фазы своего шаго вого электродвигателя, посмотрите эту информацию в справочном листке на него или на веб-сайте, на котором вы его купили. А проще всего определить их будет с помощью омметра. Процедура для этого следующая. Установите на своем мультиметре режим измерения сопротивления и измерьте сопро тивление между любыми двумя выводами. Если омметр показывает низкое сопротивление (меньше, чем 10 Ом), значит, эти два вывода принадлежат об моткам одной и той же фазы. Если же прибор показывает бесконечно боль шое сопротивление, то эти два вывода принадлежат обмоткам разных фаз. Повторяйте процесс до тех пор, пока не определите выводы обмоток каждой фазы. Оба вывода каждой фазы должны быть подключены к контактам одно го и того же моста, но какой именно вывод подключать к какому контакту не имеет значения. Подключение их в обратном порядке просто изменит на правление вращения шагового электродвигателя.
11
sv
12V
о
8
7
6
5
4
2
L293D
12 11 10 9
5
6
7
8
з L293D 14 4 13
15
16
9
10
11
12
13
14
15
16
01
1С1
•-
"'1 " 1" sv
Ml
SV
COILl_MCl
COILl_B
11
(RevЗ)
COILl_MC2
05PWM 06PWM
АО А1
N/C
AS/SCL
д4/50А
АЗ
о
COILl_MC1
04
013/SCK
012/MISO
011 PWM/MOSI
OlOPWM/SS
09PWM
08
07
COIL1_MC2
ОЗРWМ
ioref
А2
COIL1_MC1
02
01/lX
AREF
�RESШ
>
Arduinol
D0/RX
Arduino Uno
r:;
z
RESEТ
� �
12V
Рис. 5.8. Принципиальная схема подключения Н-моста к плате Arduino (рисунок создан в программе Fritzing)
1
�
COIL1_8)
COIL1_A)
>
sv
...
� :о з: :s:
QI
:s: .,
]:, а1
з: :s:
!!
а1
QI
Е
з: :s: :s:
о
:s: а1
::::1 "U
"U а1
lt)
:s: lt) n
::i::
111 :::J lt)
�
1111 QI
;, QI
U1 Q\
Шаговые двигатели и управление ими 1 S7
Сетевой адаптер, 12 В > SООмд
Рис. 5.9. Монтажная схема подключения Н-моста и шагового электродвигателя (рисунок создан в программе Fritzing)
Завершив монтаж схемы драйвера и шагового электродвигателя, проверь те правильность сборки по монтажной схеме на рис. 5.9. Убедившись в правильности собранной вами схемы, можно приступать к написанию программы для нее. Для начала мы создадим простую програм му, иллюстрирующую работу библиотеки Stepper.h для шаговых двигателей, которая циклически вращает вал шагового электродвигателя вперед и на зад. Подобно библиотеке Servo.h для работы с сервоприводами, библиотека Stepper.h импортируется в разрабатываемый скетч. Создайте новый скетч и вставьте в него код из листинга 5.3, но пока не загружайте его код в свою пла ту Arduino. Сначала проверьте, что сетевой адаптер подключен к розетке, а его выходной разъем вставлен в цилиндрический гнездовой разъем питания платы Arduino. В противном случае шаговый двигатель не запустится долж ным образом, когда скетч начнет исполняться. Листинг 5.3. Простая проrрамма для управления wаrовь1м электродвигателем stepper.ino // Простая программа управления шаговым электродвигателем // с использованием Н-моста #incLude // Константы д ля электродвигателя
158 Глава 5. Управление сервоприводами и шаговыми двигателями // Большинство шаговых электродвигателей NEMA-17 совершают 200 шагов // на один полный оборот вала const int STEPS_PER_REV = 200; // 200 шагов на оборот // Контакты для управления Н-мостом // Контакт Arduino для управления const int COIL1_MC1 = 2; // переключателем 1 фазы 1 // Контакт Arduino для управления const int COIL1_MC2 = 3; // переключателем 2 фазы 1 // Контакт Arduino для управления const int COIL2_MC1 = 4; // переключателем 1 фазы 2 // Контакт Arduino для управления const int COIL2_MC2 = 5; // переключателем 2 фазы 2 // Инициализируем библиотеку Servo.h - передаем ей контакты Arduino // для управления переключателями Н-моста Stepper myStepper(STEPS_PER_REV, COIL1_MC1, COIL1_MC2, COIL2_MC1,� COIL2_MC2); void setup0 { // Устанавливаем скорость шагового электродвигателя myStepper.setSpeed(б0); // 60 об/мин } void loop0 { // Один пошаговый оборот вала в одном направлении myStepper.step(STEPS_PER_REV); delay(S00); // Один пошаговый оборот вала в другом направлении myStepper.step(-STEPS_PER_REV); delay(SO0); }
Уделим немного времени, чтобы разобраться с работой этого кода. Оператор #include подключает к нашему скетчу библиотеку Arduino для работы с шаговыми электродвигателями Stepper.h. Затем объ является и инициируется константа, представляющая количество шагов в одном полном обороте вала шагового электродвигателя. В результате об легчается обращение к этому параметру в скетче. Подобным образом объ являются и инициируются константы для контактов для управления пере ключателями Н-моста. Далее конструктор Stepper myStepperO создает объект
Создаем одноминутный хронограф 159
шагового двигателя с названием myStepper. Название объекта не обязательно должно быть myStepper; это может быть любой идентификатор, по которому к объекту можно обращаться в коде скетча. Этот конструктор объекта при нимает пять аргументов: идентификатор количества шагов в полном оборо те вала и четыре идентификатора контактов платы Arduino для управления выключателями И-моста. В функции setupQ для объекта myStepper задается стандартная скорость вращения в оборотах за минуту. При последующем вызове в программе функции myStepper.stepO библиотека позаботится о том, чтобы провернуть вал шагового электродвигателя с этой скоростью на задан ное количество шагов. Вызываемый в главном цикле LoopQ метод myStepper. stepQ принимает только один аргумент, который предоставляет библиоте ке Stepper.h количество шагов, на которое нужно провернуть вал шагового электродвигателя. Функция stepO означает, что следующая за ней команда не исполняется до тех пор, пока шаговый двигатель не закончит выполне ние указанного перемещения вала. В этой программе вал шагового двигате ля пошагово проворачивается в бесконечном цикле на один полный оборот в одном направлении, а затем в обратном. Примечание
Может случиться, что вал шагового электродвигателя не проворачивается, а только дергается или вибрирует. В таком случае проверьте наличие питания 12 В для шагово го двигателя: вставлен ли адаптер в розетку, а его выходной разъем в разъем питания на плате Arduino, а также правильно ли подключен контакт питания электродвигателя Н-моста. Если отсутствует питание 12 В, и плата Arduino питается только через кабель USB, данного напряжения будет недостаточно для шагового двигателя, и он не будет вращаться должным образом. Если же в этом отношении все в порядке, тогда проверь те подключение выводов фаз шагового электродвигателя к контактам Н-моста: выводы одной фазы должны подключаться к контактам на одной стороне микросхемы Н-моста.
СОЗДАЕМ ОДНОМИНУТНЫЙ ХРОНОГРАФ Как мы узнали из предыдущих разделов этой главы, шаговые электро двигатели могут применяться в разнообразных индустриальных и бытовых устройствах. Например, они часто встречаются в аналоговых индикаторах автомобильных или авиационных приборных панелей. Мы можем исполь зовать наши новоприобретенные знания шаговых электродвигателей, чтобы соорудить что-то подобное: хронограф, который может инкрементировать таймер в течение точного интервала времени. Шаговые двигатели хорошо подходят для такого проекта, поскольку на каждом шаге их вал перемеща ется на строго заданный угол. Зная количество шагов двигателя на каждом обороте его вала, можно установить такую скорость вращения вала, что он будет выполнять один оборот в течение точно заданного периода времени.
160 Глава 5. Управление сервоприводами и шаговыми двигателями
Решить эту задачу посредством щеточного электродвигателя постоянного тока было бы невозможно, не задействовав обратную связь какого-либо типа для предоставления информации о текущей позиции вала.
Сборка схемы хронографа Для нашего хронографа потребуются кнопки для его запуска и остановки, поэтому добавьте эти кнопки в существую щий проект управления шаговым электродвигателем, как показано на рис. 5.10. Не кажется ли вам, что в этой схеме чего-то не хватает? В частности, где повышающие резисторы для кнопок? Не переживайте, схема содержит все, что для нее требуется. Просто в этом проекте мы рассмотрим одну возмож ность платы Arduino (и большинства микроконтроллеров), о которой ча сто забывают. Микроконтроллер АTmega, на котором основана платформа Arduino, позволяет настраивать режим работы контактов ввода-вывода. Мы уже знаем это, поскольку выполняли такую настройку с помощью функции pinModeQ. Но для этих контактов можно также задавать еще одну настройку: режим INPUT_PULLUP. При этом для контакта устанавливается режим вво да, и дополнительно еще подключается повышающий резистор, встроенный в сам микроконтроллер. В зависимости от типа платы этот резистор имеет сопротивление от 20 до 150 кОм. Точное значение можно узнать по справоч ному листку для конкретной платы. Задание такого режима для контакта
Сетевой адаптер, 12 В > SООмА
Рис. 5.10. Монтажная схема хронографа (рисунок создан в программе Fritzing)
Создаем одноминутный хронограф fб1
избавляет нас от необходимости подключать к нему внешний повышающий резистор. Все что нам нужно сделать - это подключить кнопку к данному выводу таким образом, чтобы при ее нажатии контакт замыкался на землю. Код, который мы вскоре напишем, задает встроенные повышающие резисто ры для кнопок в функции setupQ. Примечание Хотя встроенная возможность повышения по напряжению отлично подходит для таких компонентов, как кнопки, это не всегда самое лучшее решение. В частности, программа активирует повышающий резистор только после исполнения загрузчика. Поэтому, если данный контакт подключен к какой-либо микросхеме, которая не допускает «плаваю щего» состояния на этом контакте (хотя бы на несколько секунд), следует использовать внешний повышающий резистор.
Теперь, когда мы собрали электронную схему, можно приступить к постро ению механической части хронографа: циферблата и стрелки. На рис. 5.11 приводится простой пример реализации этой конструкции. В моем устройстве я приклеил циферблат на переднюю сторону корпуса шагового электродвигателя с помощью термоклея. Затем я вставил палочку от мороженого в ушки зажима для бумаг, который прикрепил на вал шаго вого электродвигателя. В завершение я обозначил секунды на = MS_PER_STEP) {
chronograph.step(1); // Вращаем вал на одни шаг steps_taken++; // Инкрементируем переменную счетчика // шагов steps_taken = tast_time curr_time; // Обновляем переменную last_time //текущим временем
} } // Если мы в этой точке, значит, была нажата кнопка Stop // или истекла одна минута // Если не выполнен полный оборот, возвращаем стрелку // в исходную точку. if (steps_taken < STEPS_PER_REV) chronograph.step(-steps_taken); // Сброс счетчика шагов steps_taken = О; }
Вот теперь у нас есть полностью функционирующий хронограф. Нажмите кнопку Start, чтобы запустить его. Стрелка должна выполнить один полный оборот точно за одну минуту. Если нажать кнопку Stop, то стрелка хроногра фа возвратится в исходное положение. Попробуйте поэкспериментировать с разной длительностью интервала отсчета. Можете ли вы сделать двухминут ный хронограф? Можете ли вы сделать, чтобы он вел обратный отсчет? А как насчет простого секундомера?
Резюме 167 Примечание Демонстрацию проекта одноминутного хронографа можно посмотреть в видеоклипе на странице https://www.exploringarduino.com/content2/ch5. Этот видеоклип также доступен на веб-сайте книги издательства Wiley, указанном в начале этой главы.
РЕЗЮМЕ В этой главе мы узнали следующее. :, Сервоприводы позволяют выполнять прецизионное позиционирова ние. Для управления ими с помощью Arduino предусмотрена библио тека Servo.h. :, Инфракрасные датчики расстояния выдают аналоговый сигнал, ам плитуда которого представляет расстояние до объектов, определяемое посредством отражения от них инфракрасного луча. :, Комментарии в коде облегчают отладку и использование кода друrи ми разработчиками. :, Микроконтроллер платы Arduino оснащен встроенными повышаю щими резисторами, которые можно подключать к его контактам, работающим в режиме ввода. :, Вал шаговых электродвигателей можно вращать с прецизионной точ ностью. :, Функция miШsO в скетчах Arduino позволяет отслеживать истекшее время.
Работаем со звуком
6
Список деталей и оборудования для проектов этой главы � Плата Arduino Uno или Adafruit METRO 328. � USВ-кабель (тип А на В для Arduino Uno, тип А на Micro-B для METRO 328). � Беспаечная макетная плата половинного или полного размера. � Набор проволочных перемычек. � Кнопки (5 шт.). � Резистор номиналом 220 Ом (1 шт.). � Резистор номиналом 10 кОм (5 шт.). � Потенциометр номиналом 10 кОм (1 шт.). :, Динамик с сопротивлением катушки 8 Ом (1 шт.). Исходный код и прочие электронные ресурсы • Исходный код, видеоуроки и прочие электронные ресурсы для этой главы можно загрузить с веб-страницы https://www.exploringarduino. com/content2/ch6. • Исходный код для проектов этой главы можно также загрузить на вкладке Downloads веб-страницы издательства Wiley для этой книги: https://www.wiley.com/go/exploringarduino2e.
к
ЧТО ВЫ УЗНАЕТЕ ИЗ ЭТОЙ ГЛАВЫ ак известно, люди обладают пятью органами чувств. Из этих пяти мы не будем пытаться создать интерфейс с электронными устройствами для чувства вкуса - вряд ли у кого-то возникнет мысль облизывать плату Arduino. Мы не будем ничего изобретать и для чувства запаха. Единственное, что можно порекомендовать при появлении какого-либо запаха от ваших электронных устройств, - это немедленно прекратить текущий экспери мент и проверить, не горит ли какой-либо компонент. Остаются чувство ося зания, зрение и слух. Мы уже создавали интерфейс для чувства осязания с помощью потенциометров и кнопок и для зрения с помощью светодиодов. А какой интерфейс можно создать для нашего чувства слуха? В этой главе
Глава 6. Работаем со звуком
мы рассмотрим, как с помощью Arduino воспроизводить звуки, чтобы сде лать более легким решение задачи обратной связи для наших проектов. Существует несколько способов создавать звуки с помощью платформы Arduino. Наиболее простой - использовать функцию toneO, которой в этой главе уделяется самое большое внимание. Но существуют также различные шилды, которые, благодаря их дополнительным вычислительным возможно стям, расширяют музыкальные возможности базовой платформы Arduino. (Шилдами на жаргоне Arduino называются платы расширения, которые вставляются сверху в разъемы платы Arduino, чтобы придать ей ту или иную дополнительную функциональность.) Если у вас плата Arduino Due, то ге нерировать звуки можно будет с помощью встроенного цифроаналогового преобразователя (ЦАП).
ПРИНЦИП РАБОТЫ ДИНАМИКА Прежде чем приступать к созданию звуковых эффектов с помощью Arduino, нам нужно разобраться, что собой представляют звуки и как люди воспринимают их. В этом разделе мы рассмотрим, как возникают звуковые волны, каковы их свойства и как, манипулируя этими свойствами, можно создавать музыку, речь и т.п.
Свойства звука Звук передается через воздух в виде волны повышенного давления. Вибрирующий объект, например, динамик, барабан или колокольчик, пере дает вибрации на соприкасающийся с ним воздух. В свою очередь, эти части цы воздуха передают полученную от объекта энергию другим окружающим их частицам воздуха, в результате чего те также начинают вибрировать. Эти вибрации создают волну повышенного давления, которая в конечном ито ге доходит до нашей ушной барабанной перепонки и воздействует на нее. Посредством такой цепной реакции вибрирующих частиц и происходит рас пространение звука от его источника до приемника. Но зачем нам нужно знать все это, чтобы научиться создавать звуки с помощью платы Arduino? Посредством Arduino мы можем управлять двумя свойствами этой волны вибрирующих частиц: ее частотой и амплитудой. Частота волны вибрирую щих частиц представляет скорость колебаний частиц воздуха туда и обратно, а амплитуда- размах этих колебаний. В физическом аспекте звуки большей амплитуды громче, чем меньшей. Тон высокочастотных звуков выше (напри мер, сопрано), тогда как низкочастотных- ниже (например, бас). На рис. 6.1 изображены синусоидальные звуковые волны с разными амплитудами и ча стотами.
Принцип работы динамика 171 Низкий тон
100
., �
50
о -50 -100
о
2
з
4
5
6
7
8
9
10 Время (мс)
Средний тон 100
.,
., � �
50
о -5 0 -100
о
4
2
� �
6
7
8
9
10 Время (мс)
Высокий тон
100
.,
5
50
о -5 0 -100
о
2
з
4
s
6
7
8
9
10
Время (мс) Рис. 6.1. Звуковые волны с разной частотой и амплитудой (рисунок создан в программе MATLAB)
Графики на рис. 6.1 представляют три фортепианные ноты, в частности ноту «До» малой, первой и второй октав. Для каждой ноты приводится два графика: с малой и большой амплитудой. Чтобы разобраться с вопросом ча стоты и амплитуды, рассмотрим ноту «До» первой октавы, которая имеет частоту 261,63 Гц. Для воспроизведения этой ноты динамик, струна форте пиано или гитарная струна должны колебаться с частотой 261,63 раза в се кунду. Величина, обратная частоте, представляет период волны, или, ины ми словами, длительность одного полного колебания: 1/261,63 секунды или 3,822 миллисекунды. С помощью Arduino мы можем создавать прямоуголь ный сигнал с управляемым периодом, т. е. с регулируемым тоном. Платформа Arduino (за исключением платы Arduino Due, которая осна щена настоящим цифроаналоговым преобразователем) не поддерживает создание синусоидальных сигналов, какими являются большинство нату ральных звуков. Прямоугольный сигнал представляет собой цифровой сиг нал, амплитуда которого, подобно синусоидальному сигналу, также перио дически колеблется между самым низким и самым высоким значениями. Но в отличие от синусоидального сигнала, в котором эти изменения происходят
172 Глава 6. Работаем со звуком
плавно, по синусоидальной зависимости, уровни прямоугольного сигнала переключаются почти мгновенно. Такой сигнал также создает волну давле ния, порождающую звук, но этот звук не такой приятный на слух, как звук, создаваемый синусоидальными волнами. Амплитуду создаваемого таким образом сигнала можно контролировать, изменяя с помощью последовательно подключенного потенциометра вели чину тока, протекающего через.динамик.
Как динамик воспроизводит звук Подобно рассмотренным в предыдущей главе электродвигателям, дина мики используют электромагнитные силы для преобразования электриче ства в движение. Поднесите какой-либо металлический' предмет к задней пластине динамика. Заметили что-то интересное? Скорее всего, ваш предмет прилипнет к этой пластине, поскольку спереди к ней прикреплен постоян ный магнит значительных размеров. Для наглядной иллюстрации на рис. 6.2 показан разрез обычного динамика, объясняющий его устройство. Перед постоянным магнитом находится звуковая катушка. При подаче на катушку синусоидального (или прямоугольного) напряжения протекающий 1
Железный, а не из какого-либо цветного металла.
Рис. 6.2. Устройство динамика (Источник: Википедия. Лицензия свободной документации GNU)
Генерация звуков с помощью функции tone()
по ней переменный ток индуцирует соответствующее переменное магнитное поле. Магнитное поле взаимодействует с постоянным магнитом, вызывая ко лебания катушки, которая в свою очередь передает их на соединенный с ней диффузор. А колебания диффузора передаются окружающему его воздуху, создавая в нем вибрации, соответствующие колебаниям исходного сигнала, подаваемого на катушку. Эти вибрации воздуха распространяются в виде звуковой волны, которая воздействует на наши барабанные перепонки.
ГЕНЕРАЦИЯ ЗВУКОВ С ПОМОЩЬЮ ФУНКЦИИ TONE() Среда разработки Arduino IDE содержит встроенную функцию toneO, которая позволяет с легкостью генерировать звуки любой частоты. Данная функция формирует выходной прямоугольный сигнал заданной частоты на указанном контакте. Функция toneO принимает три аргумента, первые два из которых являются обязательными: ■ в первом аргументе указывается номер контакта, на который нужно подавать выходной сигнал; ■ во втором аргументе указывается частота генерируемого тона; в третьем (необязательном) аргументе указывается длительность тона. Если третий аргумент не указан, сигнал генерируется до тех пор, пока не будет вызвана останавливающая его функция noToneQ. Функция toneO задействует один из аппаратных таймеров микроконтрол лера ATmega, что дает возможность микроконтроллеру выполнять другие за дачи после ее вызова, пока она воспроизводит тон в фоновом режиме. В следующих разделах мы рассмотрим, как генерировать произвольные звуковые последовательности. Научившись делать это, мы сможем исполь зовать функцию toneO для подачи сигнала в ответ на различные события (нажатие кнопок, получение данных с датчиков расстояния, акселерометров и т.п.). В конце главы мы создадим простое пятиклавишное пианино, на ко тором можно будет играть.
■
Подключение файла сопоставления нот частотам Задачу генерирования музыкальных звуков можно значительно облег чить с помощью файла, определяющего частоты для музыкальных нот. Использование такого файла в программе позволит довольно быстро со ставлять простые мелодии. Те из вас, кто знаком с нотами, знают, что ноты обозначаются ,буквами, представляющими их тон. Среда разработки Arduino IDE содержит заголовочный файл pitches.h, в котором каждой ноте со поставлена соответствующая частота. Но вместо того, чтобы искать этот файл в папке установки Arduino, загрузите код для главы 6 с сайта книги
173
Глава 6. Работаем со звуком
(https://www.exploringarduino.com/content2/ch6/) на свой компьютер. Этот код также содержит и требуемый нам заголовочный файл, который нужно будет поместить в папку создаваемого скетча. Запустите среду разработки Arduino IDE и сохраните пустой скетч, кото рый был автоматически создан при запуске среды IDE. Как вы уже, навер ное, заметили, при сохранении скетча создается папка с названием, присво енным скетчу, и уже в этой папке сохраняется файл скетча с расширением .ino. Помещенные в папку скетча заголовочные файлы (такие файлы имеют расширение .h) можно подключить в данный скетч, как будто бы их содер жимое было частью скетча, обеспечивая при этом лучшую организацию кода программы. Скопируйте заголовочный файл pitches.h, который вы загрузили с сайта книги, в папку, созданную средой IDE для скетча генерации музы кальных звуков, и закройте среду Arduino IDE. Затем снова запустите среду Arduino IDE и откройте в ней файл музыкального скетча; обратите внима ние, что теперь под панелью инструментов отображаются две вкладки: одна для файла скетча, а другая для подключаемого файла pitches.h (рис. 6.3). Щелкните по вкладке pitches.h для просмотра содержимого этого файла. Он не содержит ничего сложного или интересного, там просто список опе раторов определения, сопоставляющих понимаемые людьми названия нот их соответствующим частотам. Но просто поместить заголовочный файл в папку со скетчем будет недостаточно, чтобы включить его содержимое в ис полняемый код программы. Чтобы компилятор включил эти определения
Рис. 6.3. Окно редактора Arduino IDE со второй вкладкой для подключаемого заголовочного файла
Генерация звуков с помощью функции tone()
в исполняемый код, ему необходимо дать соответствующее указание. Но это не представляет никаких сложностей - просто добавьте следующую строку кода в начале файла своего скетча: #inctude "pitches.h" // Заголовочный файл с определениями частот нот
Для компилятора эта строка кода равнозначна вставке в файл скетча все го содержимого заголовочного файла. Но, согласитесь, что такой подход по зволяет упорядочить код в файле скетча и сделать его более удобочитаемым. В следующих разделах мы напишем остальной код программы, используя в нем определения нот из подключенного заголовочного файла.
Сборка схемы с динамиком Наша следующая задача - собрать тестовую схему и написать простую программу для воспроизведения несложных последовательностей нот. Необходимая схема довольно проста, требуется только подключить динамик к выходному контакту платы Arduino. Но при этом нужно помнить о необхо димости токоограничивающих резисторов. Как и в случае со светодиодами, последовательно динамику необходимо подключить токоограничивающий резистор, чтобы он не потреблял слиш ком большой ток от контакта платы Arduino, к которому подключен. Как мы помним, каждый выходной контакт платы Arduino может предоставить ток максимальной величины 40 мА; поэтому подберите такой номинал резисто ра, который не позволит превысить этот ток. Сопротивление звуковой ка тушки рекомендуемого динамика составляет 8 Ом (как, впрочем, и катушек большинства предлагаемых на рынке динамиков). Если же ваш динамик име ет другое сопротивление, подставьте это значение в следующих далее вычис лениях. Вспомним, что согласно закону Ома И= IR. В нашем случае напряже ние выходного сигнала составляет 5 В при токе не выше 40 мА. Решив урав нение закона Ома относительно R, видим, что минимальное сопротивление при этих параметрах должно быть: R= 5 В/40 мА= 125 Ом. Из этого общего сопротивления на звуковую катушку динамика приходится 8 Ом, следова тельно, сопротивление подключаемого последовательного резистора должно быть 125 Ом - 8 Ом = 117 Ом. Ближайшими доступными более высокими значениями будут 150 Ом или 220 Ом. Громкость окажется более высокой для резистора номиналом 150 Ом, но, скорее всего, не настолько, чтобы это было ощутимо заметней. Громкость динамика можно регулировать (умень шая ее), повышая сопротивление последовательного резистора. Чтобы об легчить эту задачу, добавьте потенциометр, подключенный последователь но постоянному токоограничивающему резистору, как показано в схеме на рис. 6.4. В этой схеме обозначение Rl соответствует постоянному резистору номиналом 220 Ом, а R2 - потенциометру для регулировки громкости.
175
176 Глава 6. Работаем со звуком Контакт9
SP1
80м
Земля Рис. 6.4. Подключение к плате Arduino динамика и потенциометра для регулировки громкости (рисунок создан в программе EAGLE)
Обратите внимание, что в отличие от предыдущих вариантов включения потенциометров, в данном случае за действуются только два вывода по тенциометра. В частности, средний вывод ( от ползунка) подключается к динамику, а один из концевых выво дов подключается к резистору номина лом 220 Ом. При полном перемещении ползунка потенциометра к неподклю ченному выводу все сопротивление потенциометра добавляется к сопро тивлению постоянного резистора но миналом 220 Ом, в результате чего громкость динамика снижается. А при
Рис. 6.5. Монтажная схема подключения динамика к плате Arduino (рисунок создан в программе Fritzing)
Генерация звуков с помощью функции tone() 1'77
полном перемещении ползунка в обратном направлении, сопротивление по тенциометра удаляется из последовательной цепи сопротивлений, оставляя только сопротивление постоянного резистора номиналом 220 Ом, в резуль тате чего громкость динамика становится максимальной. Руководствуясь схемой на рис. 6.4, подключите динамик к плате Arduino. Проверьте правиль ность сборки, сверяясь с монтажной схемой на рис. 6.5. Если у вашего динамика нет проводов, прикрепленных к выводам звуко вой катушки, то можно припаять их самостоятельно. При отсутствии паяль ника можно просто плотно обмотать одножильные провода вокруг клемм (но все же рекомендуется припаять их). Выводы динамиков не имеют поляр ности, поэтому их можно подключать в любом направлении. Убедившись R правильности монтажа схемы динамика, можно приступать к написанию программы для воспроизведения музыки.
Создание звуковых последовательностей Прежде чем приступать к разработке программы для воспроизведения мелодий, нам нужно разобраться с одним вопросом, необходимым для соз дания такой программы: использованием массивов для хранения большого количества значений с легким доступом к ним. Затем мы напишем простой цикл для перебора элементов массива, содержащих значения нот, воспроиз водя их через динамик.
Использование массивов Массив представляет собой последовательность значений, связанных между собой определенным образом. Сгруппировав такие значения в мас сиве, мы создаем идеальный формат для обработки их посредством цикла. Массив можно рассматривать как пронумерованный список. Каждая пози ция списка обозначается индексом, указывающим ее положение в списке, а по каждому индексу сохраняется значение. В нашем случае мы будем хранить в массиве последовательности нот, которые хотим воспроизвести. Чтобы обеспечить правильное управление памятью Arduino, при объяв лении массива необходимо указывать для него определенное количество эле ментов. Это можно сделать, или явно указывая количество элементов масси ва, или заполнив массив всеми требуемыми значениями. Например, массив для хранения четырех целых чисел можно создать следующей строкой кода: int numbers[4);
Альтернативно элементы массива можно инициализировать значениями при его объявлении. В таком случае указывать размерность массива в скоб ках не обязательно, и количество элементов массива подразумевается рав ным количеству указанных инициализационных значений:
178 Глава 6. Работаем со звуком // Два альтернативных способа объявления массива int numbers[4] = {-7, О, 6,234}; int numbers[] = {-7, О,6,234};
Обратите внимание, что индексация элементов массива всегда начинается с нуля. Иными словами, номер первого элемента массива - О, второго - 1, третьего - 2 и т.д. Обращение к элементам массива осуществляется указа нием индекса требуемого значения в квадратных скобках после переменной массива. Например, задать светодиоду, подключенному к контакту 9, значе ние яркости из третьего элемента массива numbers можно следующей стро кой кода: anaLogWrite(9,numbers[2]);
Обратите внимание на то, что, поскольку нумерация элементов массива начинается с нуля, номер третьего элемента массива будет 2. Присвоить или изменить значение какого-либ о элемента массива можно так: numbers[2] = 10;
Теперь мы можем применить наши знания о массивах, чтобы создать структуру для хранения последовательности нот для вывода на динамик.
Массивы для хранения значений нот и их длительности
Для хранения информация о мелодии, которую мы хотим воспроизвести, мы создадим два массива одинаковой размерности. Первый будет содержать список нот, а второй - список длительностей каждой ноты в миллисекундах. Для воспроизведения мелодии нужно просто пройтись в цикле по всем эле ментам этих массивов. Воспользовавшись своими скромными музыкальными навыками, я составил следующую коротенькую мелодию (листинг 6.1). Листинг 6.1. Пример создания мелодии
// Массив нот int notes[] = { NOTE_A4, NOTE_E3, NOTE_A4, О, NOTE_A4, NOTE_E3, NOTE_A4, О, NOTE_E4, NOTE_D4, NOTE_C4, NОТЕ_В4, NOTE_A4, NOTE_B4, NOTE_C4, NOTE_D4, NOTE_E4, NOTE_E3, NOTE_A4, О }; // Массив длительностей звучания каждой ноты (в мс) int time��] = {
Генерация звуков с помощью функции tone() 179 250,250,250,250, 250,250,250,250, 125, 125, 125, 125, 125, 125, 125, 125, 250,250,250,250 };
Обратите внимание, что оба массива имеют одинаковую размерность: 20 элементов. Также обратите внимание на то, что некоторые элементы мас сива нот содержат значение О. Это музыкальные паузы (такты, которые не вос производятся). Каждая нота из первого массива сочетается с соответствую щим значением ее длительности из второго массива. Те, кто знаком с теорией музыки, могут понять, что длительность четвертных нот составляет 250 мс, а восьмых - 125 мс. Сама же мелодия имеет четырехдольный размер. Сначала попробуйте воспроизвести эту последовательность нот, а затем попытайтесь создать свою собственную. Примечание
Прослушать запись воспроизведения этой мелодии посредством Arduino можно на странице https://www.exploringarduino.com/content2/ch6.
Программа для воспроизведения мелодии Последний шаг - создать собственно программу для воспроизведения нот, сохраненных в массиве. Она может быть в виде простого цикла for, ко торый последовательно проходит по каждому элементу массива нот, воспро изводя каждую ноту в течение периода времени, указанного в соответствую щем элементе массива длительностей. Поскольку, скорее всего, вы вряд ли захотите прослушивать эту мелодию безостановочно, воспроизведение мож но сделать однократным, поместив код в функцию setupQ. При этом возмож ность повторного воспроизведения сохраняется: для этого нужно просто на жать кнопку сброса платы Arduino. Полный код программы для воспроизве дения мелодии приведен в листинге 6.2. Листинг 6.2. Программа music.ino для воспроизведения простой мелодии с по мощью маты Arduino
// Воспроизводит мелодию на динамике #inctude "pitches.h" // Заголовочный файл с определениями частот нот const int SPEAKER=9; // Контакт выходного сигнала, подаваемого на динамик // Массив нот
180 Глава б. Работаем со звуком int notes[) = {
NOTE_A4, NOTE_E3, NOTE_A4, О, NOTE_A4, NOTE_E3, NOTE_A4, О, NOTE_E4, NOTE_D4, NOTE_C4, NOTE_B4, NOTE_A4, NOTE_B4, NOTE_C4, NOTE_D4, NOTE_E4, NOTE_E3, NOTE_A4, О
}; // Массив длительностей звучания каждой ноты (в мс) int times[) = { 250,250,250,250, 250,250,250,250, 125, 125, 125, 125, 125, 125, 125, 125, 250,250,250,250 }; void setupO { // Воспроизводим каждую ноту в течение соответствующего времени for (iпt i = О; i < 20; i++)
{
tone(SPEAKER,notes[i], times[i)); deLay(times[i));
} } void LoopO {
// Повторный запуск скетча проигрывания мелодии происходит // при нажатии кнопки сброса.
}
Если вам захочется создать свою собственную мелодию, имейте в виду, что массив нот и массив соответствующих длительностей звучания этих нот должны иметь одинаковую размерность. Кроме того, если количество нот вашей мелодии будет иным, чем в моей, верхний предел цикла forO нужно бу дет откорректировать соответствующим образом. Поскольку функция toneO может исполняться в фоновом режиме, важно использовать совместно с ней функцию deLayO. Приостанавливая исполнение кода на период времени, рав ный длительности текущей ноты, мы обеспечиваем, что Arduino не начнет воспроизводить следующую ноту, прежде чем закончится воспроизведение текущей в течение указанного для нее времени.
Миниатюрное пианино 181
Ограничения функции tone(J Функция toneO имеет несколько ограничений, о которых следует пом нить. Подобно функциям библиотеки servo.h, эта функция задействует ап паратный таймер, который также нужен для функции ШИМ платы Arduino. Поэтому при использовании функции toneO функциональность ШИМ не бу дет работать должным образом на контактах 3 и 11 (за исключением платы Arduino Mega). Также следует иметь в виду, что контакты ввода-вывода платы Arduino не обеспечивают функцию цифроаналоrового преобразования и, поэтому, они выдают только прямоугольный сигнал заданной частоты, а не синусоидаль ный сигнал. Хотя этой возможности будет достаточно для воспроизведения звуков разной тональности через динамик, она плохо подходит для проигры вания настоящих музыкальных мелодий. Для воспроизведения файлов WAV можно либо подключить специально предназначенный для этой цели шилд (например, шилд Wave от компании Adafruit или шилд МРЗ от компании SparkFun), либо реализовать цифроаналоговый преобразователь, либо ис пользовать встроенный ЦАП платы Arduino Due совместно с аудиобиблио текой, предназначенной исключительно для этой платы. Наконец, функция toneO пригодна для одновременного вывода сигнала только на одном контакте, так что управлять несколькими динамиками с ее помощью не получится. Чтобы одновременно работать с несколькими дина миками, применяя стандартную плату Arduino, придется вручную управлять таймером с помощью прерываний, которые рассматриваются в главе 13. Примечание Дополнительную информацию по работе одновременно с несколькими динамиками можно найти на веб-странице Ыum.fyi/five-speakers.
МИНИАТЮРНОЕ ПИАНИНО
Функциональность воспроизведения сохраненных мелодий хорошо подходит для оснащения обратной связью уже существующих проектов. Например, одновременно с включением зеленого светодиода (или вместо него) можно воспроизводить звуковой сигнал подтверждения. А если мы захотим создавать более сложные мелодии? Давайте рассмотрим, как реа лизовать такую возможность, собрав простое пианино с пятью клавишами. Октава такого музыкального инструмента содержит всего лишь пять нот вместо обычных семи. Но, что интересно, между нотами пентатонной гаммы наблюдается минимальный диссонанс, поэтому любые комбинации этих нот всегда звучат приятно. Для простого пианино это лучшее решение.
182 Глава 6. Работаем со звуком Примечание Перчатка управления SudoGlove может, наряду с другими устройствами, синтезировать музыку, используя пентатонную гамму. Дополнительную информацию об этом устрой стве можно найти на его веб-сайте https://www.sudoglove.com.
Для нашего пианино на основе Arduino мы будем использовать следую щую пентатонную гамму: С, D, Е, G, А. Выбор конкретной октавы предостав ляется на ваше усмотрение. Лично я выбрал из заголовочного файла четвер тую октаву. Первым делом нам нужно подключить к выходным контактам платы Arduino пять кнопок. При подключении кнопок не забываем добавить по нижающие резисторы номиналом 1 О кОм. Если вы забыли, как это делает ся, можете освежить свою память в разделе «Цифровые вводы и выводы и широтно-импульсная модуляцию► главы 2. В данном случае нам не нужно беспокоиться об оснащении кнопок противодребезговой защитой, посколь-
Рис. 6.6. Монтажная схема пианино на Arduino (рисунок создан в программе Fritzing)
Миниатюрное пианино 183
ку ноты будут воспроизводиться только до тех пор, пока кнопка остается на жатой. Подключите кнопки к плате Arduino, как показано на рис. 6.6, оставив подключенным динамик из предыдущего эксперимента. Код программы для пианино очень прост. В каждой итерации главно го цикла LoopQ проверяется состояние каждой кнопки. Пока кнопка оста ется нажатой, воспроизводится соответствующая нота. В данном случае мы используем функцию toneQ без указания длительности звучания нот, поскольку ноты будут воспроизводиться до тех пор, пока нажата соответ ствующая кнопка. Вместо этого в конце цикла LoopQ вызывается функция noToneQ, чтобы прекратить воспроизведение, когда все кнопки были отпу щены. Поскольку нам нужно всего лишь несколько нот, мы можем обой тись без заголовочного файла с определениями нот, скопировав требуемые ноты из него прямо в наш скетч. Создайте новый скетч, вставьте в него код из листинга 6.3, загрузите его в плату Arduino, а затем можете начинать играть на своем пианино. Листинг 6.3. Программа piano.ino nятиклавиwноrо пианино на плате Arduino .. . . . . . .
. . . . . . . . . . . . . .. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
// Пятиклавишное пианино //С D Е GA #define NOTE_C 262 #define NOTE_D 294 #define NOTE_E 330 #define NOTE_G 392 #define NOTE_A440
//Гц //Гц //Гц //Гц //Гц
const const const const const const
// Подключаем динамик к контакту 9 платы // Контакт Arduino для считывания сигнала с кнопки // Контакт Arduino для считывания сигнала с кнопки // Контакт Arduino для считывания сигнала с кнопки // Контакт Arduino для считывания сигнала с кнопки // Контакт Arduino для считывания сигнала с кнопки
int SPEAKER=9; int ВUТТОN_С=7; int BUTTON_D=б; int BUTTON_E=S; int BUTTON_G=4; int BUTTON_A=3;
void setup0 { // Установка не требуется // Настройка выводов осуществляется функцией tone0
} void Loop0
{
whiLe (digitaLRead(BUTTON_С)) tone(SPEAKER, NOTE_C);
184 Глава 6.
Работаем со звуком
while(digitalRead(BUTTON_D)) tone(SPEAKER, NOTE_D); while(digitalRead(BUTTON_E)) tone(SPEAKER, NOTE_E); while(digitalRead(BUTTON_G)) tone(SPEAKER,NOTE_G); while(digitalRead(BUTTON_A)) tone(SPEAKER, NOTE_A); // Если все кнопки отпущены, прекращаем воспроизведение. noTone(SPEAKER); }
В каждом цикле white0 непрерывно вызывается функция tone0 с соот ветствующей частотой, пока данная кнопка остается нажатой. Чтобы избе жать необходимости предварительно сохранять значение состояния кнопки во временную переменную, состояние кнопки можно определять при оцен ке условия цикла white0. Функция digitatRead0 возвращает булево значение Истина, когда на контакте кнопки устанавливается высокий логический уро вень. Это значение можно считывать непосредственно в цикле white0. Чтобы сделать код более аккуратным, для цикла white0 можно не указывать фигур ные скобки, если код цикла содержится в одной строке, как в данном случае. Но если код цикла состоит из нескольких строк, то фигурные скобки обяза тельно необходимы, как это было в предыдущих примерах. Примечание
На веб-странице https://www.exploringarduino.com/content2/ch6 можно просмотреть видеоклип, демонстрирующий миниатюрное пианино в действии.
РЕЗЮМЕ В этой главе мы узнали следующее. :, Динамики создают волну повышенного давления, которая распространяется по воздуху и воспринимается человеческим ухом, как звук. :, Колебания электрического тока индуцируют магнитное поле, которое можно использовать для создания звука динамиком. :, Звуки произвольной частоты и длительности можно создавать с помощью функции Arduino toneQ. :, Язык программирования Arduino позволяет применять массивы для обработки последовательных элементов данных. :, Громкость звучания динамика можно регулировать с помощью потенциометра, подключенного последовательно с динамиком.
Последовательный интерфейс USB
7
Список деталей и оборудования для проектов этой главы :, Плата Arduino Uno или Adafruit METRO 328. :, USВ-кабель (тип А на В для Arduino Uno, тип А на Micro-B для METRO 328). :, Беспаечная макетная плата половинного или полного размера. :, Набор проволочных перемычек. :, Резистор номиналом 220 Ом (3 шт.). :, Подстроечный потенциометр номиналом 10 кОм (1 шт.). :, Светодиод красный диаметром 5 мм (1 шт.). :, Трехцветный светодиод с общим анодом диаметром 5 мм (1 шт.). Исходный код и прочие электронные ресурсы • Исходный код, видеоуроки и прочие электронные ресурсы для этой главы можно загрузить с веб-страницы https://www.exploringarduino. com/content2/ch 7. • Исходный код для проектов этой главы можно также загрузить на вкладке Downloads веб-страницы издательства Wiley для этой книги: https://www.wiley.com/go/exploringarduino2e.
в
ЧТО ВЫ УЗНАЕТЕ ИЗ ЭТОЙ ГЛАВЫ ероятно, самая важная функциональность платформы Arduino - воз можность программирования платы через последовательный порт USB. Платы Arduino можно запрограммировать, не применяя никакого допол нительного специального оборудования, например, программатора AVRISP mkII. Обычно для программирования микроконтроллеров требуется специ альное внешнее устройство (как только что упомянутый программатор), че рез которое программируемый микроконтроллер подключается к компью теру. В случае с платформой Arduino такой программатор, по сути, встроен в саму плату. Кроме того, этот программатор также предоставляет прямой доступ к встроенному в микроконтроллер универсальному синхронному/ асинхронному приемопередатчику (УСАПП). Через этот интерфейс можно
186 Глава 7. Последовательный интерфейс USB
обмениваться данными между компьютером и платой Arduino или между платой Arduino и другими устройствами, оснащенными таким интерфейсом, включая другие платы Arduino. В этой и следующей главах мы рассмотрим практически все, что нужно знать о подключении платы Arduino к компьютеру через порт USB и обмене данными между ними по этому каналу.
ВОЗМОЖНОСТИ ПОСЛЕДОВАТЕЛЬНОГО ОБМЕНА ДАННЫМИ ПЛАТФОРМЫ ARDUINO Разные платы Arduino реализуют последовательный обмен данными раз ными способами. Это касается как аппаратной реализации адаптеров USB/ RS-232, так и программной поддержки различных возможностей. В этом раз деле мы рассмотрим разные аппаратные интерфейсы последовательного об мена данными, предлагаемые на различных платах Arduino. Примечание Дополнительная информация по последовательной связи предлагается в видеоуроке на веб-странице для этой главы по адресу https://www.exploringarduino.com/con tent2/ch7.
Для начала нам нужно понимать разницу между последовательным пор том и портом USB. Тем, кто помоложе, возможно, даже никогда и не приходи лось иметь дело с последовательным портом (или портом RS-232), поскольку этот интерфейс был довольно давно заменен на USB. На рис. 7.1 показано, как выглядит стандартный разъем последовательного порта. Самые первые платы Arduino оснащались разъемом последовательно го порта, который позволял подключать плату к компьютеру с помощью 9-жильноrо кабеля. В настоящее время таким разъемом оснащаются разве что специализированные компьютеры, но на рынке предлагаются адапте ры, позволяющие подключать устройства RS-232 к порту USB компьютера.
Рмс. 7.1. Разъем последовательного порта (Источник: Википедия. Общественный доступ)
Возможности последовательного обмена данными платформы Arduino 187
Микроконтроллер ATmega 328Р, на котором основана плата Arduino Uno, оснащен встроенным аппаратным портом RS-232. На плату Arduino выведе ны его линии передачи (ТХ) и приема (RX), которые подключены к цифро вым контактам О и 1 платы. Как уже упоминалось в разделе «Настройка загруз1-1ика и встроенной про граммы Arduino» главы 1, плата Arduino оснащена загрузчиком, позволяю щим загружать в нее программы через последовательный интерфейс. Эти контакты мультиплексированы, и кроме последовательного интерфейса они применяются для обслуживания других функциональностей. Посредством специальной адаптерной схемы эти контакты также подключены к лини ям передачи и приема разъема USB платы. Но хотя оба интерфейса (USB и RS-232) являются последовательными, они несовместимы напрямую друг с другом. Поэтому для обеспечения возможности взаимодействия платы Arduino с другими устройствами через интерфейс USB используется один из двух вспомогательных способов. Первый способ состоит в преобразовании с помощью дополнительной интегральной схемы протокола RS-232 платы Arduino в протокол USB компьютера, и наоборот. Эта микросхема может встраиваться в плату Arduino или поставляться отдельно с адаптерной пла той или кабелем. Этот подход применяется в плате Arduino Uno, в которой встроенная микросхема выполняет преобразование между протоколами USB и RS-232. Второй способ состоит в использовании микроконтроллера со встроенным контроллером USB. Этот подход применяется, например, в пла те Arduino Leonardo, оснащенной микроконтроллером 32U4.
Использование встроенной или внешней микросхемы преобразователя USB/RS-232 компании FTDI или Silicon Laboratories Как упоминалось в предыдущем разделе, многие платы Arduino (а так же их клоны) оснащены дополнительной микросхемой для преобразования между интерфейсами USB и RS-232. Одна из наиболее популярных таких микросхем - СР210х производства компании FTDI или Silicon Laboratories. При подключении этой микросхемы к компьютеру через разъем USB она отображается в разделе Порты диспетчера устройств как виртуальный по следовательный порт СОМ, к которому можно обращаться, как к обычному последовательному порту RS-232. На рис. 7.2 показана плата Arduino Nano, в которой есть встроенная микросхема преобразователя USB/RS-232 компа нии FTDI (обведена белой линией). В плате METRO 328 от компании Adafruit (которая подойдет вместо платы Arduino Uno для реализации проектов в этой книге) также имеется встроен ная микросхема преобразователя СР2104.
188 Глава 7. Последовательный интерфейс USB Примечание Современные операционные системы содержат встроенные драйверы� для микросхем преобразователя USB/RS-232 от компаний FТDI и Silicon Laboratories. Но если ваша систе ма не содержит таких драйверов, чтобы использовать платы с этими микросхемами, вам потребуется установить драйверы для них. Последние версии драйверов для устройств FТDI для Windows, OS Х и Linux можно найти по адресу Ьlum.fyi/ftdi-drivers. Компания Adafruit также предоставляет установщик для Windows (операционные системы Мае и Linux не требуют отдельных драйверов для микросхем компании Silicon Laboratories), который содержит драйвер для микросхем СР210х компании Silicon Laboratories, уста новленных на плате МЕТRО 328 компании Adafruit. Данный установщик доступен по адресу Ыum.fyi/adafruit-windows-drivers. Ссылки на эти загрузки также приводятся на странице для главы 7 веб-сайта книги.
Для уменьшения размеров некоторые платы не оснащаются самой ми кросхемой преобразователя USB/RS-232, а имеют только стандартный 6-контактный FТDI-разъем для подключения внешнего преобразователя на этой микросхеме. Такой преобразователь может быть реализован в виде ка беля с USВ-разъемом на одном конце и FТDI-разъемом, содержащим микро схему FTDI, на другом. Альтернативно преобразователь на этой микросхе ме может быть выполнен в виде адаптерной платы, оснащенной разъемами USB и FTDI. Эти разновидности преобразователей USB/RS-232 показаны на рис. 7.3 и 7.4 соответственно. Платы Arduino с подключаемым программатором FTDI хороши в тех случаях, когда для работы разрабатываемого устройства его не нужно под-
Рис. 7.2. Плата Arduino Nano с микросхемой преобразователя USB/RS-232 от компании FТDI (выделена прямоугольной рамкой)
Возможности последовательного обмена данными платформы Arduino 189
Рис. 7.3. Преобразователь USB/RS-232 в виде FТDl-кабеля (Источник: компания Adafruit, https://www.adafruit.com)
Рис. 7.4. Плата FТDI Friend преобразователя USB/RS-232 компании Adafruit (Источник: компания Adafruit, https://www.adafruit.com)
ключать к компьютеру через USB-интерфейс. Если планируется изготовле ние партии таких устройств, этот подход позволит сократить общую стои мость, а также уменьшить габариты устройства. Далее приводится список нескольких распространенных оригинальных плат Arduino, оснащенных встроенной FТDI-микросхемой преобразователя USB/RS-232. Обратите внимание на то, что новые платы Arduino больше не используют FТDI-микросхему (этот вопрос рассматривается более подроб но в следующем разделе), так что большинство этих плат в настоящее время сняты с производства. Но на рынке предлагается большое количество клонов этих плат, поэтому они и приведены в этом списке. ■ Arduino Nano. ■ Arduino Extreme (снята с производства). ■ Arduino NG (снята с производства). ■ Arduino Diecimila (снята с производства). ■ Arduino Duemilanove (снята с производства). ■ Original Arduino Mega (снята с производства). А следующий список содержит платы Arduino без встроенной FТDI микросхемы преобразователя USB/RS-232 и ориентированные вместо этого на внешний преобразователь в виде кабеля или адаптерной платы. ■ Arduino Mini. ■ Arduino Ethernet. ■ Original Arduino LilyPad. Arduino Pro (снята с производства). ■ Arduino Pro Mini (снята с производства).
■
190 Глава 7. Последовательный интерфейс USB
Платы Arduino с дополнительным микроконтроллером ATmega в качестве преобразователя USB/RS-232: Плата Arduino Uno была первой, в которой для преобразования USB/RS232 использовалась не FТDI-микросхема, а специально запрограммирован ный дополнительный микроконтроллер АTmega. Функционально процесс преобразования осуществляется точно таким же способом, как и с помощью FТDI-микросхемы, с несколькими незначительными техническими различи ями. На рис. 7.5 показана плата Arduino Unu со встроенным дополнительным микроконтроллером ATmega 16U2, работающим в качестве преобразовате ля USB/RS-232. (На более ранних версиях платы устанавливался микрокон троллер 8U2.)
Рис. 7.5. Плата Arduino Uno со встроенным микроконтроллером 16U2 в качестве преобразователя USB/RS-232 (Источник: Arduino, https://www.arduino.cc; выделение сделано автором)
Далее приводится краткое описание различий между преобразователями USB/RS-232 на FТDI-микросхеме и на выделенном микроконтроллере: Прежде всего, в системах под управлением операционной системы Windows для плат с дополнительным микроконтроллером в качестве преобразователя USB/RS-232 требуется установка специального драй вера. Этот драйвер включен в состав среды разработки Arduino IDE и инсталлируется автоматически при установке этой среды. (Для систем под управлением OS Х и Linux специальные драйверы не требуются.)
■
Возможности последовательного обмена данными платформы Arduino 191
■ Наличие микроконтроллера для обеспечения интерфейса USB/RS232 позволяет идентифицировать плату Arduino при ее подключении к компьютеру, предоставляя индивидуальные идентификаторы произ водителя и продукта. При подключении к компьютеру платы со встро енным преобразователем на FТDI-микросхеме компьютер определяет ее как общее устройство USB/RS-232. А при подключении к компью теру платы Arduino со встроенным преобразователем на основе до полнительного микроконтроллера {ATmega 16U2 для Arduino Uno) она определяется компьютером как плата Arduino. ■ Наконец, поскольку дополнительный микроконтроллер полностью до ступен для программирования (в нем исполняется стек микропрограмм ного обеспечения под названием LUFA, эмулирующий преобразователь USB/RS-232), то его микропрограммное обеспечение можно модифици ровать, чтобы плата Arduino отображалась в диспетчере устройств не как виртуальный последовательный порт, а как какое-либо другое устрой ство, например, джойстик, клавиатура или МIDI-устройство. При такой модификации микропрограммное обеспечение LUFA не загружается, а плату Arduino нужно будет программировать напрямую через внутри схемный программатор с устройством типа AVRISP mkII. Подход с использованием встроенного дополнительного микроконтрол лера вместо встроенной FТDI-микросхемы применяется во всех современ ных оригинальных платах Arduino, основной микроконтроллер которых не поддерживает интерфейс USB. Платы сторонних производителей оснаща ются встроенной микросхемой СР2104 (FТDI-микросхема преобразователя USB/RS-232).
Платы Arduino с основным микроконтроллером, поддерживающим интерфейс USB Плата Arduino Leonardo была первой, в которой основной микрокон троллер также обеспечивал поддержку интерфейса USB. В этой (и подоб ных платах сторонних производителей) используется микроконтроллер ATmega 32U4, оснащенный встроенной поддержкой интерфейса USB. Такой подход позволил реализовать несколько улучшений платформы. Прежде всего вследствие меньшего числа компонентов и меньшего количе ства шагов программирования платы при ее производстве снизилась ее стои мость. Кроме того, такая плата легче поддается эмуляции USВ-устройств, от личающихся от последовательного порта (например, клавиатуры, мыши или джойстика). Наконец, теперь единственный обычный порт УСАПП микро контроллера ATmega не нужно мультиплексировать с USВ-программатором, что позволяет плате одновременно взаимодействовать с компьютером и
192 Глава 7. Последовательный интерфейс USB
каким-либо другим устройством с интерфейсом RS-232, например, устрой ством системы глобального местоопределения GPS. В следующей главе мы рассмотрим использование этих устройств в качестве прямого интерфейса USB с компьютером для реализации таких проектов, как эмуляция клавиа туры или джойстика.
Платы Arduino с возможностями USB-xocтa Некоторые платы Arduino поддерживают возможности USB-xocтa, что позволяет подключать к ним стандартные USВ-устройства (например, кла виатуры, мыши или смартфоны на Android). Конечно же, для подключаемых устройств необходимо установить соответствующие драйверы. Например, нельзя просто подключить веб-камеру к такой плате и ожидать, что сразу же можно будет снимать фотографии без дополнительной работы. В настоящее время платы Arduino Due, Zero и MKR поддерживают класс USB хоста, по зволяющий подключать клавиатуру или мышь к их порту USB On-The-Go для управления платой. В плате Arduino Mega ADR применяется протокол Android Open Accessory (АОА) для обеспечения взаимодействия между пла той и подключенным к ней устройством Android. Эта возможность в основ ном необходима для управления вводом-выводом платы Arduino из прило жения, исполняющегося на устройстве Android.
ПРИЕМ ДАННЫХ ОТ ARDUINO НА КОМПЬЮТЕРЕ Самая базовая функция последовательной связи Arduino позволяет выво дить отправляемые платой данные в окне программы монитора порта. Мы уже применяли эту возможность в проектах из предыдущих глав. В этом раз деле мы рассмотрим эту функциональность более подробно, а еще далее в этой главе мы создадим несколько программ для компьютера, реагирующих на получаемые от Arduino данные более сложным действием, чем просто отображение их в окне программы монитора последовательного порта. Этот процесс одинаков для всех плат Arduino.
Использование команды print() Вывод данных в окно монитора порта осуществляется с помощью следующих функций: SегiаL.Ьеgiп(скорость_в_бодах) Seri аL.priпt("Сообщение ") SeriaL.printLn("Cooбщeниe")
Здесь скорость_в_бодах и Сообщение являются переменными, которые пе редаются функции в аргументе.
Прием данных от Arduino на компьютере 193
Как мы узнали ранее, функция SeriaL.begin0 вызывается один раз в начале программы в функции setupQ, чтобы подготовить последователь ный порт для работы. После этого можно беспрепятственно вызывать функции SeriaL.print0 и SeriaL.printLn0 для отправки данных в последова тельный порт. Единственная разница между этим двумя функциями состо ит в том, что функция SeriaL.printLn0 добавляет в конце символ перевода строки, чтобы следующий текст ото бражался на новой строке. Чтобы .. . . . . . . . . . . . . . . . .. . . поэкспериментировать с этой функ циональностью, соберите простую . . . .. . . . ... . . . ,. .... схему, подключив потенциометр к контакту АО платы Arduino, как по Рис. 7 .6. Монтажная схема подключения казано на рис. 7.6. потенциометра к плате Arduino (рисунок создан в программе Fritzing) Далее создайте новый скетч и ско пируйте в него код из листинга 7.1. Данная программа считывает текущее значение выходного сигнала потенци ометра и отображает его в окне монитора порта в виде исходного значения и значения в процентах.
. ... . ..... .... . ................ .. . ........ .. . ....... . .. . ,.... ..... ....... . .. . .. .. . . .. .... . ..... . . ... .. .. ...... ... • • • • • • • • • • • • • • • • 1 • • ,
,
Листинr 7.1. Проrрамма pot.ino дnя тестирования функций print
................. . . . . . • . .•..•.•....• . . . .•
// Простая программа тестирования функций print const int РОТ=О; // Сигнал с потенциометра подается на аналоговый контакт АО void setup0 {
SeriaL.begin(9600); // Запускаем последовательный порт // со скоростью в бодах = 9600
} void LoopO { // Считываем значение сигнала потенциометра int vaL = anaLogRead(POТ); int рег = map(vaL, О, 1023, О, 100); // Преобразуем в процентное значение Serialprint("AnaLog Reading: "); // Выводим на экран исходное значение SeriaL.print(vaL); SeriaL.print(" Percentage: ");
Глава 7. Последовательный интерфейс USB
SeriaL.print(per); // Выводим на экран аналоговое значение в процентах SeriaL.printLn("%"); // Отображаем символ % и переходим на новую строку // Ждем 1 секунду и повторяем deLay(1000); }
Используя комбинацию функций SeriaL.print0 и SeriaL.printLn0, этот код каждую секунду выводит на экран исходное и процентное значения величи ны сигнала с потенциометра. Следует обратить внимание на то, что функция SeriaL.printLn0 присутствует только в последней строке передаваемого текста, для того, чтобы следующие значения отображались на новой строке. Запустите программу монитора порта из среды Arduino IDE и проверьте, что для величины скорости обмена в бодах задано значение 9600, которое совпадает со значением этого параметра, указанным в скетче. Подключитесь к своей плате Arduino и повращайте ручку потенциометра. В окне монитора порта каждую секунду должно выводиться текущее значение выходного сиг нала потенциометра в двух форматах.
Специальные символы По последовательному каналу можно также передавать разные символы специального назначения, позволяющие форматировать передаваемые дан ные. При передаче спецсимволы обозначаются обратной косой чертой \, за которой следует собственно управляющий символ. Из множества специаль ных символов наибольший интерес для нас представляют символы табуля ции и новой строки. Чтобы вставить в передаваемый текст символ табуляции, потребуется управляющая последовательность \t. А чтобы вставить в пере даваемый текст символ новой строки - управляющая последовательность \n. Последний символ особенно полезен, когда нужно вставить новою строку в начале текста, а не в конце, как это делает функция SeriaL.printLnQ. Если же по какой-либо причине в тексте нужно отобразить комбинацию символов \n или \t не как управляющую последовательность символов, а в виде обычных сим волов, то перед ними просто нужно вставить еще одну обратную косую черту: \\n или \\t. В листинге 7.2 приведен модифицированный код из листинга 7.1, в котором символ табуляции и новой строки служит для отображения пере даваемых значений сигнала потенциометра в табличном формате. Листинг 7.2. Программа pot_tabuLar.ino для отображения данных в табличном формате
// Программа тестирования функций print с выводом данных в табличном формате
const int РОТ=О; void setupO
// Сигнал с потенциометра подается на аналоговый контакт АО
Прием данных от Arduino на компьютере 195 {
SeriaLbegin(9600); // Запускаем последовательный порт со скоростью в бодах = 9600
}
void Loop0 {
Serial.println("\nAnalog Pin\tRaw Value\tPercentage"); Seriа L.println("----- -------------------------------------"); for (int i = О; i < 10; i++) {
// Считываем значение сигнала потенциометра int val = analogRead(POТ); int per = map(va� О, 1023, О, 100); // Преобразуем в процентное значение Serial.print("A0\t\t"); Serial.print(val); Serial.print("\t\t"); Serial.print(per); // Выводим на экран аналоговое значение в процентах Serial.println("%"); // Отображаем символ % и переходим на новую строку delay(1000); // Ждем 1 секунду и повторяем
} }
Теперь значения выходного сигнала потенциометра должны отображать ся, как показано на рис. 7.7.
АО АО АО
87 о о
е, о, о,
An.&109 Pin
P.aw Volue
PercentaQ"e
АО АО АО
2 43 90 141 163 238 311 376 422 '70
о,
An&l09 Pi.a
hv Value:
Percжot;aQ!!:
АО &О
514 572 720 1021 1023
50,
АО
АО АО
АО АО АО АО
4'
г,
13' 15\ 23\
зо,
36, 41' 45\
------------------------------------------
АО
АО АО
ss,
10,
99'
100,
�� Рис. 7.7. Снимок экрана с окном программы монитора порта с принимаемыми данными, отображае мыми в табличном формате
196 Глава 7. Последовательный интерфейс USB
Изменение представления типов данных Функции SeriaL.printO и SeriaL.printLnO способны выводить данные в фор мате по умолчанию, которым является формат ADCII в десятичном коде. Но они также позволяют представлять данные и в других форматах, включая шестнадцатеричный, восьмеричный и двоичный. Требуемый формат вы вода данных указывается в необязательном втором аргументе этих функ ций. В табл. 7.1 приводятся примеры указания разных форматов в функции SeriaL.printLnO и результаты отображения данных в соответствующем форма те в окне монитора порта. Таблица 7.1. Вывод данных в разных форматах Тип данных
Пример кода
Отображение на экране
Десятичный
Serial.println(23);
23
Шестнадцатеричный
Serial.println(23, НЕХ);
Восьмеричный
Serial.println(23, ОСТ) Serial.println(23, BIN)
17
Двоичный
27
00010111
ПЕРЕДАЧА ДАННЫХ С КОМПЬЮТЕРА НА ПЛАТУ ARDUINO Возможность получения данных с платы Arduino, несомненно, очень по лезна. Но, к сожалению, эта полезность ограничена вследствие своей одно сторонней направленности. Но теперь мы знаем достаточно, чтобы разо браться, как реализовать обмен в обратном направлении - от компьютера к плате Arduino.
Настройка монитора порта для отправки команд Кроме поля для отображения получаемых данных, окно монитора порта содержит строку для ввода текста вверху окна, а также поле выпадающего меню внизу окна слева от поля установки скорости связи. Эти два элемен та окна программы монитора порта выделены прямоугольной рамкой на рис. 7.8. Опции этого меню позволяют задать символы окончания строки для тек ста, отправляемого с компьютера на плату Arduino. Откройте это выпадаю щее меню и установите в нем опцию NL (Новая строка). В результате в кон це каждой строки, вводимой в поле вверху окна и отправляемой нажатием клавиши ввода с компьютера на плату Arduino, будет добавляться символ перевода на новую строку - \n. В примерах в последующих разделах предпо лагается, что выбрана данная опция завершения строки.
Передача данных с компьютера на плату Arduino 197
0 Autosc:roll
('-N_ewf_fne--v�) 9600 Ьaud
V
Рис. 7.8. Снимок экрана окна монитора порта с выделенной строкой ввода текста и поля выпадающего меню для выбора опций символов завершения строки
Программа монитора порта среды Arduino IDE отправляет полностью весь текст, введенный в строку ввода, по нажатию клавиши ввода или кнопки Отправить. Некоторые другие программы последовательной связи, напри мер, PuTTY (ссылка на страницу загрузки которой дается на веб-странице цифрового содержимого для этой главы по адресу https://www.exploringar duino.com/content2/ch7), немедленно отправляют каждый символ вводимо го текста.
Получение данных, отправляемых с компьютера или другого устройства через последовательный интерфейс Сначала мы будем отправлять команды плате Arduino, набирая их вруч ную в строке ввода монитора порта среды Arduino IDE. Разобравшись таким образом с основами передачи данных на Arduino, мы рассмотрим, как одно временно передавать несколько команд, а также создадим простой графиче ский интерфейс для отправки команд. Важная особенность последовательного порта платы Arduino - нали чие в нем буфера. Это означает, что плате Arduino можно одновременно от правлять несколько байтов данных, поскольку они будут сначала временно сохраняться в очереди в буфере, а затем плата Arduino будет извлекать их из буфера и обрабатывать в порядке, определяемом содержимым исполня емой программы. Таким образом, нам не нужно беспокоиться, что данные поступают быстрее, чем длится цикл их обработки, но в то же самое время необходимо следить за тем, чтобы не отправлять слишком много данных, ко торые могут не поместиться в буфере и будут утеряны.
198 Глава 7. Последовательный интерфейс USB
Плата Arduino как ретранслятор данных В самом простом примере двусторонней передачи данных плата Arduino будет отправлять обратно получаемые данные. Для этого она должна отсле живать состояние входного буфера последовательного порта и отправлять находящиеся в нем данные обратно отправителю. Для решения этой задачи нам понадобятся две новые функции объекта Seriat: ■ функция Seriat.avaitaьteO - возвращает количество символов (байтов), находящихся в настоящее время во входном буфере последовательного порта платы Arduino. Когда это значение больше нуля, мы будем счи тывать символы из буфера и передавать их обратно на компьютер; ■ функция Seriat.readQ- считывает и возвращает следующий доступный символ в буфере. Следует обратить внимание на то, что функция Seriat.readO возвращает только 1 байт, поэтому ее необходимо продолжать вызывать, пока функ ция Seriat.avaitaьteO выдает значение, большее, чем ноль. Байт, прочитанный функцией Seriat.readQ, удаляется из буфера, делая доступным для чтения сле дующий байт. Обладая этой информацией, мы теперь можем написать про грамму для обратной передачи на компьютер получаемых от него данных. Код этой программы приведен в листинге 7.3. Создайте новый скетч, скопи руйте в него этот код и загрузите его в свою плату Arduino. Листинг 7.3. Программа echo.ino для возвращения матой Arduino получаемых данных // Передаем обратно каждый полученный символ
char data;
// Переменная для хранения получаемого символа
void setupO {
Seriat.begin(9600);
// Запускаем последовательный порт // со скоростью в бодах = 9600
} void toop0 { // Передаем в монитор порта, только если получены данные if (SeriaL.avaitaЬLe0 > О) { data = SeriaL.read0; // Считываем входящий байт данных Seriat.print(data); // Выводим в окно монитора порта // считанный байт данных } }
Передача данных с компьютера на плату Arduino 199
Запустите программу монитора порта, наберите в строке ввода любую последовательность символов и нажмите клавишу ввода на клавиатуре или кнопку Отправить справа от строки ввода. В результате все, что вы ввели, будет отображено в основном поле окна монитора порта. Поскольку в поле выбора символов завершения строки мы указали опцию NL (Новая строка), то каждая отправляемая строка текста будет отображаться на новой стро ке. Этим объясняется использование в скетче, приведенном в листинге 7.3, функции Serial.printQ, а не Serial.printlnO - последовательность символов но вой строки автоматически добавляется в конец каждой передаваемой и воз вращаемой строки текста. Типы данных char и int При передаче буквенно-цифрового символа по каналу последовательной связи в действительности передается не сам символ, например «5» или l".iry 1/I•аие йbje("t 1,s�ri.11\ Port CtЬject
ji'Le(�&,2S6); //Size of HSV I•.-ige i■I = toadl11,11ge( м h�Y-JP&"); //lot'ld in Backg,·mннl tm:11gt1 port"' nt;\JI S.г1al(tl\1f. 1 "СОМ3", ,&ее); //Opfit\ S•r1al. po1t
1>3ckgra11nd(e); i•age-(i•J,e,e);
/ /6l.11ck 8•с�8' rюnd //Ov�f'lity 1■.ige
,.;olf'nd v,йue• to .-rduino
Рис. 7.1 S. Окно программы Processing для выбора цвета
В функции drawO изображение загружается в окно посредством операто ра image(img,0,0). В данном случае аргумент img обозначает изображение, ко торое мы хотим отображать в окне приложения, а аргументы 0,0 обозначают координаты, в которых нужно начинать выводить это изображение. Эти ко ординаты представляют верхний левый угол окна приложения.
214 Глава 7. Последовательный интерфейс USB
При каждом щелчке мышью по изображению палитры в окне приложе ния вызывается функция mousePressedO. Цвет пиксела, по которому пришел ся щелчок, сохраняется в виде объекта типа coLor с названием с. Сам цвет из влекается методом getO, который предоставляет приложению информацию, откуда получить значения цвета (в данном случае координаты Х и У щелчка мыши). Затем вызывается функция mapO, которая сопоставляет значения со ставных цветов с процентными значениями, ожидаемыми скетчем Arduino. Полученные процентные значения далее конкатенируются в строку, которая отправляется по последовательному каналу на плату Arduino. Для справки эти значения также выводятся в консоли главного окна Processing IDE. Подключите свою плату Arduino (с подсоединенным к ней разноцветным светодиодом) к компьютеру и загрузите в нее код из листинга 7.5. Запустите на исполнение скетч Processing (предварительно исправив в нем номер по следовательного порта должным образом) и щелкайте по разным цветам в палитре в открывшемся окне приложения. Выбранный таким образом цвет должен устанавливаться на разноцветном светодиоде, подключенном к плате Arduino.
РЕЗЮМЕ В этой главе мы узнали следующее. :, Платы Arduino подключаются к компьютеру через преобразователь USB/RS-232. :, Для преобразования USB/RS-232 в разных платах Arduino может быть предусмотрена специальная микросхема или реализована встроенная поддержка функциональности USB. :, Плата Arduino может отправлять данные на компьютер через интер фейс USB. :, Для форматирования текста, выводимого в окне монитора порта, можно использовать символы новой строки и табуляции. :, Данные передаются по последовательному каналу в виде символов, которые можно преобразовать в целые числа несколькими способами. :, По последовательному каналу с компьютера в скетч Arduino можно от правлять наборы целых чисел, разделенных запятыми. В скетче Arduino составляющие числа можно извлечь из набора с помощью специальных функций и использовать их в качестве команд для скетча. :, По последовательному каналу можно отправлять данные из скетча Arduino в программу на Processing, исполняющуюся на компьютере. :, Из программы на Processing можно отравлять данные в скетч Arduino для управления подключенными к плате Arduino периферийными устройствами.
Эмуляция USВ-устройств
8
Список деталей и оборудования для проектов этой главы :> Плата Arduino Leonardo или Seeeduino Lite или Pololu A-Star 32U4 PrimeLV. :> USВ-кабель (тип А на Micro-B). :> Беспаечная макетная плата половинного или полного размера. :> Набор проволочных перемычек. :> Кнопки (3 шт.). :> Резистор номиналом 220 Ом (1 шт.). :> Резистор номиналом 10 кОм (3 шт.). :> Фоторезистор (1 шт.). :> Светодиод красный диаметром 5 мм (1 шт.). :> Аналоговый датчик температуры ТМР36 (1 шт.). :> Двухкоординатный джойстик (1 шт.). Исходный код и прочие электронные ресурсы • Исходный код, видеоуроки и прочие электронные ресурсы для этой главы можно загрузить с веб-страницы https://www.exploringarduino. com/content2/ch8. • Исходный код для проектов этой главы можно также загрузить на вкладке Downloads веб-страницы издательства Wiley для этой книги: https://www.wiley.com/go/exploringarduino2e.
в
ЧТО ВЫ УЗНАЕТЕ ИЗ ЭТОЙ ГЛАВЫ главе 7 мы экспериментировали с последовательной передачей данных
USB/RS-232 между компьютером и платой Arduino. Для этого мы под ключали компьютер к плате Arduino через последовательный интерфейс, что позволяло любой программе, способной взаимодействовать с последова тельным портом, «общатьсю> с платой Arduino. Такой метод вполне пригоден для обычного обмена данными, но он весьма далек от использования всех возможностей собственно USВ-интерфейса.
216 Глава 8. Эмуляция USВ-устройств
Интерфейс USB является фактическим международным стандартом для подключения компьютерных периферийных устройств. Возможности этого интерфейса постоянно расширяются в результате добавления новых функ ций. Например, стандарт USB SuperSpeed и разъем USB-C позволяют пере давать данные, видео высокого разрешения, обеспечивают напряжение, до статочное для зарядки аккумуляторной батареи подключенных устройств, и многое другое. Компьютер может определять разнообразные типы под ключенных к нему USВ-устройств. В этой главе мы рассмотрим, как платы Arduino, оснащенные встроенной поддержкой USB, могут действовать как устройства человеко-машинного интерфейса HID. Примечание Для упражнений в этой главе требуется плата Arduino со встроенной в основной микро контроллер поддержкой USВ-интерфейса, например, Arduino Leonardo. Платы Arduino, в которых поддержка USВ-интерфейса обеспечивается дополнительной микросхемой, например, Arduino Uno или Adafruit METRO 328, для этих экспериментов не годятся. Как отмечалось в списке компонентов, клоны платы Arduino Leonardo предлагаются не сколькими сторонними производителями. В частности, кроме платы Arduino Leonardo для упражнений в этой главе подойдет плата Seeeduino Lite (поставщик Adafruit) или A-Star 32U4 Prime LV (поставщик Pololu). Поставщики иногда могут испытывать трудно сти с получением оригинальных плат Arduino и могут предлагать платы-клоны. Но если клоны предлагает поставщик с хорошей репутацией, например, Adafruit или Pololu, то качеству таких плат-клонов можно доверять. Если вы используете плату Seeeduino Lite, установите ее переключатель напряжения на 5 В. Для программирования плат-клонов в меню выбора платы среды Arduino IDE нужно указать плату Arduino Leonardo.
Подобно другим платам Arduino, в которых поддержка USB встроена в главный микроконтроллер, плата Arduino Leonardo может эмулировать та кие устройства, как клавиатура или мышь. В этой главе мы рассмотрим, как использовать плату Arduino Leonardo для эмуляции этих устройств. Совет При реализации примеров этой главы следует соблюдать осторожность, поскольку ино гда могут возникнуть проблемы с перепрограммированием платы. Например, если за груженный в плату скетч эмулирует мышь и безостановочно перемещает курсор мыши по экрану, это может создать трудности с нажатием кнопки Загрузить в среде Arduino IDE. В таких случаях, чтобы перепрограммировать плату, нажмите и отпустите на ней кнопку сброса, одновременно нажав кнопку загрузки скетча в среде Arduino IDE. Таким образом плата будет оставаться в режиме работы загрузчика, что позволит начать ее программирование.
Драйверы для платы Arduino (или эквивалентной платы-клона) должны установиться автоматически при первом подключении платы к компьюте ру. Но на некоторых компьютерах с ОС Windows с этим могут возникнуть проблемы. В таком случае следуйте инструкциям по ручной установке драй веров, предоставляемой на веб-сайте Arduino по адресу Ыum.fyi/installing-
Эмуляция клавиатуры 217
arduino-drivers. (Ссылка на эти инструкции также дается на странице циф ровых материалов для этой книги по адресу http://www.exploringarduino. com/content2/ch8.)
ЭМУЛЯЦИЯ КЛАВИАТУРЫ С помощью уникальной способности платы Leonardo эмулировать USВ устройства можно запросто превратить эту плату в клавиатуру. Спрашиваете, а зачем нам эмулировать клавиатуру, если можно просто подключить на стоящую клавиатуру? Ну, например, это позволит нам передать команды из комбинаций клавиш на компьютер или вводить данные непосредственно в открытый на компьютере файл.
Ввод данных в компьютер Плата Leonardo может эмулировать USВ-клавиатуру, отправляя коды кла виш и их комбинаций. В этом разделе мы рассмотрим, как реализовать эти две возможности. Сначала создадим простую программу, записывающую данные нескольких аналоговых датчиков в формате CSV (значения, разде ленные запятыми) в файл, который потом можно будет открыть в Microsoft Excel или Google Sheets, чтобы создать график этих значений. Для этого запустите какой-либо текстовый редактор, например, Блокнот, и сохраните пустой документ с расширением .csv. Для этого при сохранении файла выберите в поле Сохранить как тип опцию Все файлы, а затем введи те в поле Имя файла название файла вместе с его расширением, например, data.csv. На веб-странице с цифровыми ресурсами для этой главы можно просмотреть демонстрационное видео, как создать файл типа CSV. Затем соберите простое устройство, руководствуясь монтажной схемой на рис. 8.1. Схема будет отслеживать температуру и уровень освещенности, исполь зуя аналоговые датчики, с которыми мы уже работали в главе 3. Кроме со ответствующих датчиков, схема также содержит кнопку для включения и выключения функции записи данных и светодиод для индикации текущего состояния этой функции. Кнопка включения записи данных оснащена защитой от дребезга, рассмо тренной в главе 2. При включенном режиме записи данных плата Arduino опра шивает датчики и, эмулируя клавиатуру, каждую секунду вводит полученные значения в файл на компьютере, разделяя их запятыми. Работа схемы в режи ме записи данных обозначается включенным индикаторным светодиодом. Поскольку нам нужно, чтобы плата Arduino постоянно определяла со стояние кнопки, мы не можем использовать функцию deLayQ, чтобы делать
218 Глава 8. Эмуляция USВ-устройств
Индикаторный светодиод Датчик температуры
•-ft ...... ,. .•••••.• , ... ,. ....... �
....
.. ��······4·
,.,.
.......... � .
............. _.--. ............... i'
+..... • � ..
.........
..... ..
···-� .... �·�-· ..... •. •.... �·· .•.•. ..... .. ......
:о♦♦ i'i'•.iJ•i'-8 е •'i ... 8 •. .,...,. •••t'i, ... #♦ Плата выберите опцию Arduino Leonardo (эту же опцию следует выбрать и для платы-клона Seeeduino Lite). Создайте новый скетч, вставьте в него код из листинга 8.1 и загрузите его в свою плату Arduino Leonardo.
Эмуляция клавиатуры 219
Листинг 8.1. Программа csv_Logger.ino регистратора данных температуры и освещенности // Регистратор данных температуры и освещенности #include const int ТЕМР =О; const int LIGHT =1; const int LED =3; const int ВUТТОN =2;
// Подключаем датчик температуры к контакту АО // Подключаем вывод фоторезистора к контакту Al // Подключаем красный светодиод к контакту 3 // Кнопку подключаем к контакту 2
boolean lastButton = LOW; boolean currentButton = LOW; boolean running = false; int counter = 1;
// Предыдущее состояние кнопки //Текущее состояние кнопки // По умолчанию не исполняется //Указатель записанных элементов данных
void setup0 {
pinMode (LED, OUTPUT); Keyboard.begin0;
// Задаем режим вывода для контакта // красного светодиода // Запускаем эмуляцию клавиатуры
} void loop0 {
currentButton = debounce(lastButton);
// Считываем состояние кнопки // с устраненным дребезгом if (lastButton == LOW && currentButton == HIGH) //Если кнопка была нажата... // Переключаем состояние исполнения на обратное running = !running; lastButton = currentButton; // Сбрасываем значение кнопки if (running) {
// Если режим регистратора включен
digitalWrite(LED, HIGH); // включаем светодиод if (millis0 % 1000 == О) //Если значение прошедшего времени кратно 1000 { int temperature = analogRead(ТEMP); // Считываем показания температуры int brightness = analogRead(LIGHT); // Считываем уровень освещенности // Выводим на экран номер указателя Keyboard.print(counter); Keyboard.print(",'); // Выводим на экран запятую Keyboard.print(temperature); // Выводим на экран значение температуры Keyboard.print(",'); // Выводим на экран запятую
220 Глава 8. Эмуляция USВ-устройств
Keyboard.println(brightness); // Выводим на экран значение // освещенности (и новую линию) // Инкрементируем счетчик counter++; } }
else {
}
digitalWrite(LED, LOW);
// Если регистратор не работает, // выключаем светодиод
}
i
• Функция устранения дребезга контактов • Передаем ей значение предыдущего состояния кнопки • и получаем от нее текущее значение состояния кнопки • с устраненным дребезгом. */ boolean debounce(boolean last) {
boolean current = digitalRead(BUTTON); // Считываем текущее // состояние кнопки. // Если оно иное, чем предыдущее... if (last != current) {
delay(S); current = digitalRead(BUTTON);
} return current;
//Ждем 5 мс // Считываем состояние снова // Возвращаем текущее состояние кнопки
}
Но прежде чем приступать к тестированию нашего регистратора дан ных, рассмотрим более подробно некоторые аспекты новой функциональ ности, используемой в этом скетче. Подобно инициализации последователь ного порта, мы также инициализируем интерфейс клавиатуры оператором Keyboard.beginO в функции setupQ. Но в отличие от библиотеки SeriaL.h, кото рая всегда подключается по умолчанию, нам нужно дать явное указание ком пилятору загрузить библиотеку для работы с клавиатурой, добавив оператор #incLude в начале файла скетча. При каждой итерации основного цикла LoopO выполняется проверка со стояния кнопки, а также исполняется функция устранения дребезга, с ко торой мы уже знакомы. При обнаружении события нажатия кнопки булево значение переменной состояния режима регистратора running меняется на обратное. Это выполняет оператор!, примененный к данной переменной.
Эмуляция клавиатуры 221
Пока скетч работает в режиме регистратора данных, собственно реги страция выполняется только один раз каждые 1000 мс, используя ранее рас смотренную нами логику. Работа клавиатурных функций очень похожа на работу функций последовательного интерфейса. Функция Keyboard.priпtO вводит данную строку в компьютер. После считывания выходных сигналов двух аналоговых датчиков плата Arduino Leonardo отправляет эти значения на компьютер в виде клавишных кодов. Клавиатурная библиотека также содержит функцию Keyboard.priпtLпO, которая эмулирует нажатие клавиши ввода после отправки предоставленного текста. Текущее значение счетчика и оба аналоговых значения разделяются запятыми, а каждый новый набор данных завершается вводом новой строки. Теперь можно проверить наш регистратор данных в действии. Если вы еще не загрузили скетч из листинга 8.1 в плату Arduino Leonardo, загрузите его сейчас. Установите курсор в текстовом документе, а затем нажмите кноп ку начала записи данных. Документ должен начать заполняться данными. Чтобы изменить значения выходного сигнала датчиков, затените фотодат чик ладонью или прикоснитесь пальцем к датчику температуры. В документ должны вводиться соответственно измененные значения. Завершив экспе риментирование, нажмите кнопку, чтобы выйти из режима записи данных. Файл с полученными данными можно сохранить, чтобы потом импортиро вать значения из него в какое-либо приложение электронной таблицы и по строить из них временной график. Все это можно посмотреть в демонстра ционном видеоклипе из электронных ресурсов для этой главы. Примечание Демонстрационный видеоклип регистратора данных датчика температуры и освещен ности в действии можно найти на веб-странице https://www.exploringarduino.com/ content2/ch8.
Управление компьютером с платы Arduino Кроме ввода кодов обычных клавиш, плата Arduino Leonardo позволя ет эмулировать ввод комбинаций клавиш. Например, на компьютерах под Windows нажатие комбинации клавиш + блокирует экран компьютера. На системах под Linux для этого предназначена комбинация клавиш ++. Используя эту возможность с датчиком осве щенности, можно автоматически блокировать компьютер при выключении освещения. В компьютерах под OS Х для блокировки служит комбинация клавиш ++ или ++. Плата Arduino Leonardo не может эмулировать эти комбинации, поскольку она не спо собна эмулировать код для клавиш и . В этом примере мы
222 Глава 8. Эмуляция USВ-устройств
рассмотрим, как заблокировать компьютер под Windows. Для этого мы вос пользуемся схемой, показанной на рис. 8.1, хотя задействуем в ней только датчик освещенности. Снова запустите на исполнение скетч из листинга 8.1 и проверьте реаги рование фотодатчика на несколько разных уровней освещенности. На осно вании полученной информации выберите пороговое значение, при пресече нии которого должна происходить блокировка компьютера. Я обнаружил, что при выключенном освещении в моей комнате значение было 300, а при включенном - около 700. Поэтому для порогового значения я выбрал значе ние 500. При выходном сигнале датчика освещенности ниже этого порогово го значения на компьютер отправляется команда блокировки. Освещенность в вашем случае, скорее всего, будет отличаться от моей, поэтому подберите соответствующее пороговое значение. Создайте новый скетч, вставьте в него код из листинга 8.2 и загрузите его в свою плату Arduino Leonardo. Но обязательно сначала проверьте, что уста новлен разумный порог, протестировав, какие аналоговые значения выдает ваш датчик освещенности для разных уровней освещенности. При установке неправильного значения скетч может заблокировать ваш компьютер сразу же после загрузки. Листинг 8.2. Программа lock_computer.ino для блокировки компьютера при изменении уровня освещения ................ ····················· // Блокирует компьютер при выключении освещения #include const int LIGHT =1; // Подключаем вывод фоторезистора к контакту Al const int THRESHOLD =500; // Уровень освещенности должен быть ниже // этого значения, чтобы заблокировать компьютер void setup0 { Keyboard.begin0; } void loop0 { int brightness = analogRead(LIGHT); // Считываем уровень освещенности if (brightness < THRESHOLD) { КеуЬоаrd. press(KEY_LE FT_GU 1); КеуЬоаrd. press('l');
Эмуляция мыши 223
deLay(lOO); Keyboard.reLeaseALLO; }
}
Загрузив скетч в Arduino Leonardo, выключите освещение. Компьютер должен немедленно заблокироваться. Рассмотрим чуть более подробно работу скетча. Исполнение функции Keyboard.pressO эквивалентно нажатию клавиши, указанной в ее аргументе. Поэтому, чтобы отправить коды нажатия комбинации клавиш и , необходимо вызвать эту функцию для каждой из этих клавиш. Затем выдерживается короткая пауза, после которой исполняется функция Keyboard.releaseAllO, эмулирующая отпускание нажатых клавиш. На страни це Ыum.fyi/arduino-keyboard-modifiers веб-сайта Arduino приведен спи сок кодов для комбинаций клавиш. Ссылка на эту страницу также дается на странице цифровых материалов для этой книги по адресу https://www. exploringarduino.com/content2/ch8. Примечание
Демонстрационный видеоклип схемы блокировки компьютера уровнем освещенно сти в действии можно найти на веб-странице https:/lwww.exploringarduino.com/con tent2/ch8.
ЭМУЛЯЦИЯ МЫШИ Подключив к Arduino Leonardo двухкоординатный джойстик и несколько кнопок, можно превратить эту плату в специализированную мышь. Джойстик будет позиционировать указатель мыши на экране, а кнопки будут функцио нировать как левая, средняя и правая кнопки мыши. Так же, как и в случае с клавиатурой, язык Arduino содержит полезные функции для управления функциональностью мыши. Но прежде чем использовать эти функции в скетче, соберите эмулятор мыши, руководствуясь монтажной схемой на рис. 8.2. Не забывайте о том, что для кнопок необходимы понижающие рези сторы. Выводы джойстика подключаются к контактам АО и Al платы Arduino. Джойстик - это просто два потенциометра, соединенные с ручкой. Перемещение ручки джойстика по оси Х устанавливает значение потенцио метра Х, а по оси У - потенциометра У. На рис. 8.2 показан двухкоординатный джойстик производства ком пании Parallax, предоставляемый как этой компанией, так и компанией Adafruit. Но джойстики с подобным интерфейсом выпускают многие другие
224 Глава 8. Эмуляция USВ-устройств
Левая кнопка мыши Средняя кнопка мыши Правая кнопка мыши
Рис. 8.2. Схема для эмуляции мыши с помощью Arduino Leonardo (рисунок создан в программе Fritzing)
производители. Подробную информацию по подключению данного джой стика можно найти в документации на него на веб-сайте компании Parallax по ссылке Ыum.fyi/parallax-2-axis-joystick. В зависимости от ориентации джойстика может потребоваться откорректировать пределы функции сопо ставления его значений или поменять местами присвоения констант X_AXIS и Y_AXIS аналоговым контактам платы Arduino Leonardo в листинге 8.3. Собрав схему эмулятора мыши, можно загрузить требуемый для нее код в плату Leonardo. Создайте новый скетч Arduino, скопируйте в него код из листинга 8.3 и загрузите его в свою плату Leonardo. Листинr 8.3. Проrрамма mouse.ino эмулятора .мыши на Arduino Leonardo . . . . .. . . . . . . . . . . . . . . . . . . . ...................... ............. . ,
// Эмулируем мышь #include const int LEFT_BUTTON =4;
// Контакт для подключения левой кнопки
Эмуляция мыши 225 const int MIDDLE_BUTTON =3; // Контакт для подключения средней кнопки const int RIGHT_BUTTON =2; // Контакт для подключения правой кнопки const int X_AXIS =О; // Аналоговый контакт для подключения оси Х джойстика const int Y_AXIS =1; // Аналоговый контакт для подключения оси У джойстика void setup0 {
Mouse.beginQ;
} void Loop0 {
int xVaL = readJoystick(X_AXIS); // Получаем значение перемещения по оси Х int yVaL = readJoystick(Y_AXIS); //Получаем значение перемещения по оси У Mouse.move(xVaL, yVaL, О);
// Перемещаем курсор мыши
readButton(LEFT_BUTTON, MOUSE_LEFT); // Управление левой кнопкой мыши readButton(MIDDLE_BUTTON, MOUSE_MIDDLE); //Управление средней // кнопкой мыши readButton(RIGHT_BUTTON, MOUSE_RIGHT); //Управление правой кнопкой мыши deLay(S);
//Управление чувствительностью
} // Считывает значение джойстика, масштабирует его и добавпяет"мерrвую· зону посередине int readJoystick(int axis) {
int vaL = anaLogRead(axis); // Считываем аналоговое значение vaL = map(vaL, О, 1023,-10, 10); // Сопоставляем его значениям перемещения if (vaL = -2)
// Создаем ·мертвую· зону, чтобы остановить // дрейф курсора мыши
return О; eLse return vaL;
// Возвращаем сопоставленное значение
} // Функция считывает состояние кнопки и выдает команду мыши void readButton(int pin, char mouseCommand) {
Глава 8. Эмуляция USВ-устройств // Если кнопка нажата, щелкаем ее, если еще не щелкнули if (digitaLRead(pin) == HIGH) {
if (!Mouse.isPressed(mouseCommaпd)) {
Mouse.press(mouseCommaпd);
} } // Отпускаем кнопку, если уже щелкнули ею else {
if (Mouse.isPressed(mouseCommand)) {
}
Mouse.release(mouseCommand);
}
}
Это определенно один из наиболее сложных скетчей, с которыми мы име ли дело до сих пор, поэтому полезно рассмотреть его подробнее, чтобы разо браться с работой новых функций и ходом исполнения программы. Как и в случае с эмуляцией клавиатуры, в скетч эмулирования мыши не обходимо включить библиотеку функциональностей мыши с помощью опе ратора #include . В начале скетча определяются контакты платы Arduino для подключения выводов кнопок и джойстика, а в функции setupO запускается библиотека Mouse.h. При каждом прохождении главного цикла LoopO считываются значения сигналов джойстика и сопоставляются величи не перемещения курсора мыши. Также проверяется состояние кнопок, и при необходимости передаются сигналы нажатия кнопок. Функция readJoystickO считывает значения сигналов джойстика и сопо ставляет их с перемещением курсора мыши. Диапазон каждой оси джойсти ка на выходе аналого-цифрового преобразователя составляет 1024 значения. Но курсор мыши перемещается по относительным координатам. Иными словами, при передаче функции Mouse.moveO нулевого значения для любой оси джойстика курсор мыши по этой оси перемещаться не будет. Передача положительного значения для оси Х вызовет перемещение курсора вправо, а отрицательного - влево. Чем больше значение, тем больше расстояние, на которое перемещается курсор мыши. Таким образом, в функции readJoystickO диапазон входных значений с джойстика от О до 1023 сопоставляется диапа зону значений от -10 до+ 10. В области нуля добавляется небольшая буфер ная зона, в пределах которой курсор мыши не перемещается. Она необхо дима потому что, поскольку даже когда джойстик находится в нейтральном
Резюме
среднем положении, действительное значение выходного сигнала может ко лебаться вокруг значения 512. Устанавливая величину перемещения равной нулю после сопоставления в определенном диапазоне значений входного сигнала джойстика, мы обеспечиваем, что курсор мыши не будет двигаться самостоятельно, когда мы не перемещаем джойстик. Определившись с тре буемыми значениями, функции Mouse.moveO передаются значения Х и У для перемещения курсора мыши. Третий аргумент функции Mouse.moveO служит для передачи ей информации о перемещении колесика прокрутки и в данном скетче не используется. Функция readButtonO служит для определения щелчков кнопок мыши и предусмотрена для всех трех кнопок. Функция определяет текущее состоя ние кнопок посредством функции Mouse.isPressedO и управляет мышью соот ветствующим образом через функции Mouse.pressQ и Mouse.releaseQ. Примечание Просмотреть демонстрационный видеоклип управления курсором мыши компьютера с помощью эмулятора мыши на плате Arduino Leonardo можно на веб-сайте этой книги по адресу https://www.exploringarduino.com/content2/ch8.
РЕЗЮМЕ В этой главе мы узнали следующее. :> Встроенная поддержка USВ-интерфейса позволяет плате Arduino Leonardo эмулировать такие USВ-устройства, как клавиатура и мышь. :> Благодаря возможности эмулировать нажатие клавиш плата Arduino может запускать специальные функции на компьютере, к которому она подключена (например, блокировать экран). :> Джойстик состоит из комбинации двух соединенных под прямым углом потенциометров.
Сдвиговые регистры
9
Список деталей и оборудования для проектов этой главы :> Плата Arduino Uno или Adafruit METRO 328. :> USВ-кабель (тип А на В для Arduino Uno, тип А на Micro-B для METRO 328). :> Беспаечная макетная плата половинного или полного размера. :> Набор проволочных перемычек. :> Резистор номиналом 220 Ом (8 шт.). :> Светодиод красный диаметром 5 мм (8 шт.). :> Светодиод зеленый диаметром 5 мм (4 шт.). :> Светодиод желтый диаметром 5 мм (3 шт.). :> ИК-дальномер GP2Y0A21YK0FIR компании Sharp в комплекте с JSТкабелем (1 шт.). :> Микросхема сдвигового регистра SN74HC595N (1 шт.). Исходный код и прочие электронные ресурсы • Исходный код, видеоуроки и прочие электронные ресурсы для этой главы можно загрузить с веб-страницы https://www.exploringarduino. сот/content2/ch9. • Исходный код для проектов этой главы можно также загрузить на вкладке Downloads веб-страницы издательства Wiley для этой книги: https://www.wiley.com/go/exploringarduino2e.
н
ЧТО ВЫ УЗНАЕТЕ ИЗ ЭТОЙ ГЛАВЫ есомненно, что в процессе работы над проектами из этой книги вы уже мысленно составили себе список своих собственных будущих проектов. Вполне возможно, что некоторые из них вам пришлось удалить из списка, поскольку плата Arduino просто не обладает достаточным количеством кон тактов для их реализации. Одно из самых распространенных применений платформы Arduino состоит в украшении светодиодными гирляндами всех более-менее подходящих для этого предметов. По гирлянде в каждый угол комнаты! Гирлянду на компьютер! По гирлянде на кота и собаку! Ну, на жи вотных, наверное, не нужно.
Глава 9. Сдвиговые регистры
Однако с реализацией этих проектов может получиться незадача. Как сде лать гирлянду из, скажем, 50 мигающих светодиодов (или управлять большим количеством каких-либо других устройств), если плата, например, Arduino Uno, оснащена только 14 цифровыми контактами? Но эта кажущаяся труд ность в действительности не представляет никакой проблемы, поскольку она с легкостью решается посредством использования сдвиговых регистров. Сдвиговые регистры позволяют расширить возможности ввода-вывода пла ты Arduino без необходимости приобретения более дорогой платы с микро контроллером с большим количеством контактов ввода-вывода. В этой главе мы рассмотрим принципы работы сдвиговых регистров, а также реализуем как программы, так и схемы, необходимые для сопряжения платы Arduino со сдвиговыми регистрами с целью расширения ее возможностей цифрового вывода. После выполнения упражнений этой главы вы сможете самостоя тельно применять сдвиговые регистры, а также будете обладать знаниями, необходимыми для принятия грамотных решений при разработке проектов с большим количеством цифровых выводов.
ВЫБОР ПЛАТЫ ARDUINO ДЛЯ РЕШЕНИЯ ЗАДАЧ Как и в большинстве предыдущих глав, в этой главе в качестве платформы для разработки используется плата Arduino Uno (или эквивалентная плата Adafruit METRO 328). Для реализации упражнений в этой главе подойдет лю бая другая плата Arduino, но будет полезно рассмотреть факторы, вследствие которых предпочтительней выбрать для определенного проекта одну пла ту Arduino, а не другую. Например, вы, наверное, уже задаетесь вопросом, почему бы просто не взять плату Arduino с большим количеством контактов ввода-вывода, например, Mega 2560 или Due. Конечно же, такой подход был бы вполне логичным для реализации проектов, требующих большего коли чества контактов ввода-вывода. Но как инженер при разработке проекта вы всегда должны думать о других аспектах. Например, вычислительных мощ ностей платы Uno может быть вполне достаточно для проекта, но ее контак тов ввода-вывода не хватает. В таком случае значительно дешевле добавить несколько сдвиговых регистров, чем задействовать плату более высоко го уровня. Такая конструкция будет более компактной. Но за это придется расплатиться усложнением программы и, возможно, более длительной ее отладкой.
ЧТО ТАКОЕ СДВИГОВЫЙ РЕГИСТР Сдвиговый регистр представляет собой устройство, которое принима ет поток последовательных битов и одновременно выводит значения этих битов на параллельные выходные контакты. Сдвиговые регистры часто
Что такое сдвиговый регистр
� применяются для управления большим количе u ством светодиодов, например, в семисегментных дисплеях или светодиодных матрицах. Прежде чем приступать к работе со сдвиговыми реги страми в наших проектах с Arduino, взгляни те на рис. 9.1, где представлена организация последовательно-параллельного сдвигового ре Сдвиговый регистр гистра. На протяжении этой главы мы будем ис пользовать разновидности этой диаграммы для иллюстрации того, как разные состояния входов воздействуют на состояние выходов. Восемь кружков внизу представляют свето Рис. 9.1. Организация диоды, подключенные ( через последовательные сдвигового регистра токоограничивающие резисторы) к восьми вы водам сдвигового регистра. А три входа являются линиями последователь ной передачи данных, посредством которых сдвиговый регистр подключает ся к плате Arduino.
1
Параллельная и последовательная передача данных Существует два основных способа передачи множества битов данных. Вспомним, что, как и все микроконтроллеры, плата Arduino является цифро вым устройством, и поэтому может работать только с двумя уровнями сиг нала: высоким и низким, которые в числовом представлении обозначаются, как 1 и О соответственно. Поэтому, чтобы управлять восемью светодиодами цифровым способом, нам нужно найти способ, как передать 8 бит инфор мации. В предыдущих главах мы передавали биты данных параллельно, ис пользуя функции digitaLWriteO и analogWriteO, которые устанавливают состоя ния нескольких выходных контактов. Рассмотрим следующий пример парал лельной передачи информации. Предположим, что нам требуется управлять восемью светодиодами. Для этого нужно просто подключить их к восьми цифровым контактам ввода-вывода платы Arduino, и все биты управления будут одновременно, т. е. параллельно, подаваться на эти контакты. В главе 7 мы рассмотрели последовательную передачу данных, при ко торой биты передаются по одному за раз. Сдвиговые регистры позволяют с легкостью преобразовывать последовательные данные в параллельные и наоборот. В этой главе мы рассмотрим преобразование последовательных данных в параллельные с помощью сдвиговых регистров, которые еще назы ваются регистрами SIPO 1 • В эти устройства по сигналу тактирования вводят ся последовательные биты данных, которые затем выводятся параллельно. 1
Англ. Serial In, Parallel Out - последовательный ввод, параллельный вывод. - Прим. пер.
232 Глава 9. Сдвиговые регистры
Несколько сдвиговых регистров можно подключить последовательно друг за другом, что позволит управлять сотнями цифровых выводов, используя только три выходных цифровых контакта платы Arduino.
Использование микросхемы сдвигового регистра 74НС595 В этом проекте нам потребуется микросхема сдвигового регистра 74НС595. Но прежде чем приступать к работе над проектом, рассмотрим цоколевку микросхемы, показанную на рис. 9.2.
Ов 1 Ос 2 Оо 3 ОЕ 4 0G
5 6
GND
8
OF
Он
7
16 15 14 13
Vcc
Од SER ОЕ
RCLK 11 SRCLK 10 SRCLR 9 Он, 12
Рис. 9.2. Цоколевка микросхемы сдвигового регистра 74НС595 (Источник: предоставлено компанией Texas lпstrumeпts lncorporated)
Назначение выводов сдвигового регистра Далее приводится краткое описание назначения выводов этого сдвигово го регистра. QA по Qн - восемь параллельных выходов сдвигового регистра (подключены к кружкам на рис. 9.1). Vcc - напряжение питания +5 В. GND - общий (земля). Подключается к шине земли платы Arduino. SER- вход последовательных данных; соответствует входу DATA (данные) на рис. 9.1. На этот входной контакт последовательно подают ся восемь двоичных битов, определяющих значения восьми параллель ных выходных контактов. SRCLK - вход сигнала тактирования; обозначен как CLOCK на рис. 9.1. Каждый раз, когда на этот контакт подается сигнал высокого уровня, значения в регистре сдвигаются на один бит. Чтобы принять один байт данных, поступающих на контакты ввода данных, нужно восемь им пульсов высокого уровня.
■ ■ ■ ■ ■
Что такое сдвиговый регистр 233
■
RCLK - вход сигнала фиксации введенного байта данных; обозначен как LATCH на рис. 9.1. Данное сокращение означает register clock, т. е. сигнал тактирования регистра, а сам сигнал фиксирует введенный байт данных на параллельных выходах. В наших примерах выводы SRCLR и ОЕ нам не потребуются. Но, возмож но, вы захотите использовать их в каком-либо своем проекте, поэтому не по мешает разобраться, каково их назначение. Сокращение ОЕ означает output епаЫе, т. е. разрешение выхода. Черта над обозначением контакта обозначает, что подаваемый на него сигнал имеет низкий активный уровень. Иными словами, вывод данных активируется, когда на этот контакт подается сигнал низкого уровня. Когда же на этом контакте присутствует сигнал высокого уровня, вывод данных запрещен. В примерах, рассмотренных в следующих разделах главы, этот контакт будет подключен напрямую на землю, в резуль тате чего вывод параллельных данных будет всегда разрешен. Альтернативно этот контакт можно подключить к выходному контакту платы Arduino, что бы одновременно включать или выключать все светодиоды. Контакт SRCLR предназначен для сброса сдвигового регистра. Когда на этот контакт подает ся сигнал низкого уровня, выполняется обнуление регистра. Для примеров в этой главе данный контакт будет подключен напрямую к шине питания +5 В, чтобы не допускать обнуления содержимого сдвигового регистра.
Принцип работы сдвигового регистра
Сдвиговый регистр является синхронным устройством, т. е. он реагирует только на положительный перепад сигнала тактирования. Всякий раз, ког да уровень сигнала тактирования меняется с низкого на высокий, все зна чения, хранящиеся в восьми выходных регистрах, сдвигаются влево на одну позицию. (При этом последний бит или выбрасывается или передается на контакт Qн в случае каскадного соединения регистров.) Одновременно теку щее значение входа DATA сдвигается в первую позицию параллельного вы хода. После восьми таких операций сдвига текущее значение параллельного выхода вытесняется и заменяется новым В-разрядным значением. В конце этого цикла на контакт LAТСН подается сигнал высокого уровня, чтобы сде лать это новое значение на параллельном выходе доступным. Процесс вво да значения в сдвиговый регистр иллюстрируется блок-схемой на рис. 9.3. Предположим, что мы хотим включить каждый второй из восьми светодио дов, т. е. светодиоды, подключенные к контактам QA, Qc, QE и QG сдвигового регистра. В двоичном формате значение на контактах параллельного выхода регистра будет выглядеть как 1О1О1О1О. Далее следуем ранее описанной процедуре записи значения в сдвиговый регистр. Сначала на контакт LATCH подается сигнал низкого уровня, чтобы не допустить изменения текущего значения на параллельных выходах, пока
L Низкийуровень
tс!:
LАТен DАТд-
Низкиi!уро�ён� CLOeK -
о Низкийуровень LATeH
х. .,:21е .,s
Высокийуровень DATA-
>S
5
_пешек-
tс!:
....а.
.,е:21 .,s
>S
5
1
о о о о о
�
tс!:
Низкиiiу��ён� LATeH Низкийуровень
Низкийуровень LATeH
х.'
Высокийуровень DATA-
>S
DATA
., еs ., 5 :21
_пСLоек-
_пешек-
t2:
о
� Низки�·уро�ён� LATeH Низкийуровень
Низкийуровень
о о
х. :21 .,е
>S
о о о
Высокийуровень DАТд_пСLоек-
�
Низкий уровень
DATA
_пСLоек-
,,.i:21 .,е s .,
5
., о
1
Низкий·ур�·вень LATeH
5
t
еs
о�
s
Низкийуровень LATeH
о о
_пешек-
5
tс!: о
_пСLоек-
5
а. •s :21
1
DАТд-
1
Высокииуровень DATA-
о
Низкийуровень LATeH
.,
.,е s .,
:21
_пСLоек-
t2:
t2: >S
DATA
1
о
Низкийуровень LATeH
.... а.
1
х. о .,:21е о .,s о 5 о >S
_г
tс!: ....
а.
о 1
о
.,е:21 1 .,s о
>S
5
1
о о
LATeH
Низкийуровень DATAНизкийуровень eLOeK -
Рис. 9.3. Операция ввода значения в сдвиговый регистр
tс!: о1
,,.а.:21 1 .,е о ., 5
1
о 1
о о о о о
Что такое сдвиговый регистр 235
в регистр записывается новое значение. Затем по каждому положительному перепаду сигнала тактирования в регистр сдвигаются биты байта состояния светодиодов, подаваемые на контакт DATA. После загрузки всех битов на контакт LATCH подается сигнал высокого уровня, в результате чего введен ное значение становится доступным на параллельных выходах.
Загрузка в сдвиговый регистр данных с платы Arduino Теперь, когда мы понимаем принцип работы сдвигового регистра, можно написать программу для управления им с помощью Arduino. Как и со все ми нашими предыдущими экспериментами, для загрузки последовательных данных в параллельные выходы сдвигового регистра мы можем использо вать встроенную функцию Arduino IDE. В частности, функция shiftOut0 по зволяет выдать 8 бит данных на любой контакт ввода-вывода. Функция при нимает четыре параметра: ■ номер контакта, на который нужно выводить данные; номер контакта, на который подается сигнал тактирования; порядок вывода битов: начиная со старшего или с младшего; выводимое значение. Например, чтобы выполнить вывод значения для управления светодиодами, которое мы рассматривали в предыдущем разделе, функция shiftOut0 используется таким образом:
■ ■ ■
shiftOut(DATA, CLOCK, MSBFIRST, В10101010);
Константам DATA и CLOCK присваиваются значения контактов платы, к которым подключены входы данных и сигнала тактирования. Параметр MSBFIRST означает, что передача начинается со старшего бита (т. е. с само го левого бита отправляемого двоичного числа). Если же указать параметр LSBFIRST, то передача будет начинаться с самого младшего (т. е. с правого) бита двоичного числа. В последнем параметре указывается отправляемое значение. Буква В (английская) в начале числа означает, что число записано в двоичном формате, а не в десятичном. Затем мы создадим физическую версию системы, которую рассматривали в предыдущих разделах. Первым делом подключаем микросхему сдвигового регистра к плате Arduino: контакт DATA микросхемы подключаем к контакту 8 платы Arduino; контакт LATCH (Фиксация) микросхемы подключаем к контакту 9 пла ты Arduino; контакт CLOCK (Сигнал тактирования) микросхемы подключаем к кон такту 1 О платы Arduino. Далее подключаем восемь светодиодов, не забывая при этом о токоогра ничивающих резисторах для них. Монтажная схема изображена на рис. 9.4.
■ ■ ■
:136 Глава 9. Сдвиговые регистры
Рис. 9.4. Монтажная схема подключения к плате Arduino сдвигового регистра и восьми светодиодов (рисунок создан в программе Fritzing)
Теперь, зная, как работает сдвиговый регистр и как использовать функ цию shiftOut0, мы можем написать код для подачи на параллельные выхо ды сдвигового регистра комбинации битов, чтобы включить подключенные к нему светодиоды в чередующейся последовательности (листинг 9.1). Листинг 9.1. Программа aLternate.ino для включения светодиодов через один // Включение светодиодов в чередующемся порядке через сдвиговый регистр // Контакт для подачи последовательных данных // на вход сдвигового регистра const int LATCH =9; // Контакт Arduino для подключения входа // сигнала фиксации сдвигового регистра const int CLK =10; // Контакт Arduino для подключения // тактового входа сдвигового регистра const int SER = 8;
Что такое сдвиговый регистр 237 void setup0 {
// Задаем выходной режим работы для контактов управления pinMode(SER, OUTPUТ); pinMode(LATCH, OUTPUT); pinMode(CLK, OUTPUТ); digitaLWrite(LATCH, LOW); //Latch Low shiftOut(SER, CLK, MSBFIRST, 810101010); // Передаем биты, // начиная с самого старшего digitaLWrite(LATCH, HIGH); // Высокий уровень сигнала фиксации, // чтобы предоставить доступ к параллельным данным
void Loop0 {
// Ничего не делаем
}
Поскольку параллельные значения фиксируются на выходах сдвигового регистра, они отправляются только один раз в функции setupQ. Эти значения сохраняются на параллельных выходах до тех пор, пока не будут записаны новые. Ход исполнения программы следует шагам, показанным графически на рис. 9.3. На контакт фиксации LATCH подается сигнал низкого уровня, посредством функции shiftOutQ в регистр вводятся 8 бит данных, а затем на контакт фиксации LAТСН подается сигнал высокого уровня, в результате чего введенные данные становятся доступными на параллельных выходах микросхемы сдвигового регистра.
КАСКАДИРОВАНИЕ СДВИГОВЫХ РЕГИСТРОВ Управлять восемью устройствами всего лишь через три контакта платы ввода-вывода платы Arduino, это совсем неплохая возможность. Но что, если нам нужно подключить еще больше устройств? Никаких проблем. Мы просто соединяем последовательно требуемое число сдвиговых реги стров. Теоретически таким образом можно получить сотни управляющих цифровых выходов, используя всего лишь три контакта платы Arduino. Но для питания всех этих устройств нам потребуется более мощный источник, чем способна обеспечить шина USB от компьютера, поскольку токовые по требности нескольких десятков светодиодов намного превысят возможно сти интерфейса USB. Вспомним, что в цоколевке на рис. 9.2 есть контакт, обозначенный Qн•· В процессе операции сдвига самый старший бит не вытесняется из реги стра, а сдвигается на этот выход. Это обстоятельство позволяет создать
Глава 9. Сдвиговые регистры
комбинацию сдвиговых регистров с вдвое большей разрядностью: 16 бит. Для этого контакт Qн. одного сдвигового регистра нужно подключить к кон такту входа данных DATA другого, а контакты LATCH и CLOCK обеих микро схем соединить вместе. Таким образом можно каскадировать любое количество сдвиговых реги стров, создавая требуемое количество цифровых выходов. Попробуйте реализовать такой сдвоенный сдвиговый регистр, подключив к схеме на рис. 9.4 еще одну микросхему сдвигового регистра, как только что было описано, и модифицировав код из листинга 9.1 так, чтобы функция shiftOut0 исполнялась два раза подряд. (Функция shiftOut0 может обрабатывать толь ко В-битовые значения.)
Преобразования между двоичным и десятичным форматом В коде в листинге 9.1 информация о состоянии светодиодов представлена в виде строки двоичных цифр (или битов). Это позволяет наглядно пред ставить, какие светодиоды будут включены, а какие выключены. Но состо яние светодиодов можно также выразить десятичным значением, преоб разовав двоичное значение состояния в десятичное. В двоичном представ лении каждый ненулевой бит (начиная с самого правого, или самого млад шего бита) представляет инкрементально нарастающую степень двойки. Преобразование числа из двоичного представления в десятичное выполня ется предельно прямолинейно. Рассмотрим этот процесс на примере двоич ного числа, представляющего изменяющиеся состояния восьми светодиодов. На рис. 9.5 показано это исходное двоичное число и соответствующие шаги его преобразования в десятичный формат. 1 1 о 1 о о 4 5 j 2 2 2 2 22 21 2° 1х128 + Охб4 + 1х32 + Охlб + 1х8 + Ох4 + 1х2 + Qxl = 170 1
7
о
26
Рис. 9.5. Преобразование числа из двоичного формата в десятичный
Десятичное значение каждого ненулевого двоичного бита представляется нарастающей степенью двойки. В данном примере ненулевое значение, т. е. двоичное значение 1, имеют биты в позициях 7, 5, 3 и 1. Таким образом, что бы определить десятичный эквивалент данного двоичного значения, нужно просто сложить десятичные значения 27, 25, 23, и 2 1 или 128 + 32 + 8 + 2 = 170. Правильность наших расчетов можно подтвердить, заменив двоичное значе ние в коде в листинге 9.1 этим десятичным значением. Откорректированный код будет иметь следующий вид: shiftOut(SER, CLK, MSBFIRST, 170);
Световая анимация с помощью сдвигового регистра
Исполнение этого кода должно дать такие же результаты, как и исходного с двоичным значением.
СВЕТОВАЯ АНИМАЦИЯ С ПОМОЩЬЮ СДВИГОВОГО РЕГИСТРА В предыдущем примере мы использовали сдвиговый регистр для задания статического состояния светодиодов. Но, несомненно, вы согласитесь, что возможность динамического управления светодиодами будет представлять намного большую ценность. В следующих двух примерах мы рассмотрим ди намическое управление светодиодами, реализовав простой эффект Как использовать сдвиговый регистр для создания анимационных эффектов.
Интерфейсы
для обмена данными Глава 1 О. Шина 12с Глава 11. Шина SPI и библиотеки сторонних разработчиков
Глава 12. Взаимодействие с жидкокристаллическими дисплеями
Шина 1 2 С
10
Список деталей и оборудования для проектов этой главы � Плата Arduino Uno или Adafruit METRO 328. � USВ-кабель (тип А на В для Arduino Uno, тип А на Micro-B для METRO 328). � Беспаечная макетная плата половинного или полного размера. � Набор проволочных перемычек. � Резистор номиналом 220 Ом (8 шт.). � Резистор номиналом 4,7 кОм (2 шт.). � Светодиод красный диаметром 5 мм (1 шт.). � Светодиод зеленый диаметром 5 мм (4 шт.). � Светодиод желтый диаметром 5 мм (3 шт.). � Микросхема сдвигового регистра SN74HC595N (1 шт.). � Датчик температуры TC74A0-5.0VAT (1 шт.). Исходный код и прочие электронные ресурсы • Исходный код, видеоуроки и прочие электронные ресурсы для этой главы можно загрузить с веб-страницы https://www.exploringarduino. com/content2/chl0. • Исходный код для проектов этой главы можно также загрузить на вкладке Downloads веб-страницы издательства Wiley для этой книги: https://www.wiley.com/go/exploringarduino2e.
м
ЧТО ВЫ УЗНАЕТЕ ИЗ ЭТОЙ ГЛАВЫ ы уже умеем выполнять сопряжение с платой Arduino аналоговых и цифровых входных и выходных сигналов, но как насчет подключения более сложных устройств? Возможности платы Arduino (и, собственно гово ря, любого микроконтроллера) можно расширить, подключая к нему разные внешние компоненты. В частности, упростить связь между микроконтрол лером и разнообразными модулями можно с помощью многих микросхем, реализующих стандартные протоколы цифровой связи. В этой главе мы рас смотрим использование шины РС.
248 Глава 1 О. Шина 1 2С
Шина 12С позволяет реализовать надежную, высокоскоростную, двух стороннюю связь между двумя устройствами при минимальном количестве контактов ввода-вывода, чтобы упростить этот процесс. В зависимости от используемых компонентов и особенностей системы, скорость обмена дан ными по этой шине составляет от 100 килобит до нескольких мегабит в секун ду. К шине I2C подключается одно ведущее устройство (обычно микрокон троллер или микропроцессор), осуществляющее управление шиной, а также одно или больше ведомых устройств, которые получают данные от ведущего устройства. В этой главе мы рассмотрим протокол 12С, а затем реализуем его для взаимодействия с цифровым датчиком температуры, возвращающим по казания в значениях температуры, а не в произвольных аналоговых значени ях. В этом мы будем полагаться на наши знания, полученные в предыдущих главах, добавив сведения из этой главы, чтобы расширить возможности на ших предыдущих проектов. Примечание
На веб-странице электронных ресурсов книги для этой главы (https://www.explorin garduino.com/content2/ch10) можно просмотреть учебный видеофильм о шине 12С.
ИСТОРИЯ СОЗДАНИЯ ПРОТОКОЛА 1 2С Работу коммуникационного протокола намного легче понять, если знать, как он эволюционировал с течением времени. Протокол I2C был разработан компанией Philips Semiconductors в начале 80-х годов прошлого столетия для обеспечения сравнительно низкоскоростной связи между разными микро схемами. К 90-м годам прошлого столетия протокол был стандартизирован, и друтие компании начали использовать его, выпуская совместимые с ним микросхемы. Этот протокол часто называют двухпроводным протоколом, поскольку для обмена данными в нем предусмотрено всего лишь два прово да: для данных и для сигнала тактирования. Хотя не все устройства законно используют для связи двухпроводный протокол (поскольку их производи тели не уплатили за это), обычно их все равно называют РС-устройствами. Можно провести аналогию с копировальными аппаратами, которые назы ваются ксероксами, хотя они не выпускаются компаний Xerox, которая была первой, создавшей копировальный аппарат электрографического типа с по рошковым красящим элементом под этим торговым названием. Поэтому, если для устройства указывается, что оно использует двухпроводный прото кол связи, то можно быть в большой степени уверенным, что этот протокол работает, как описано в этой главе. Вам, возможно, также встретятся устройства, применяющие друтой двух проводный протокол, называющийся SMBus (System Management Bus -
Схема подключения устройств 1 2С 249
системная управляющая шина). Этот протокол разработан компаниями Intel и Duracell на основе протокола 12С и очень похож на него. Но в нем заданы немного другие пределы электрических сигналов, определен алгоритм обна ружения ошибок, а также реализована явная поддержка необязательной сиг нальной линии для прерываний, позволяющая ведомым устройствам уве домлять ведущее об определенных событиях. Обычно устройства SMBus и 12С можно без проблем одновременно подключать к одной шине, если четко соблюдать требования, изложенные в справочных листках.
СХЕМА ПОДКЛЮЧЕНИЯ УСТРОЙСТВ 1 2С На рис. 10.1 показана стандартная схема организации системы связи РС. В отличие от цифровых систем обмена данными, с которыми мы работали ранее в этой книге, интерфейс 1 2С уникален тем, что здесь к линиям связи может быть подключено несколько устройств. В частности, линия сигнала +
sв /\
а:>� ◄>
u u о z
(9
SDA
SCL
>
�,с:> ◄> SOA
SCL
о
С)
'"'�о
о z
о о
u :::>
(!)
t;
----
----
Земля
Земля
о t;
SOA
l...>
,::,;
SCL
о z
о о
(!)
о
..,
---Земля
Рис. 10.1. Стандартная схема организации связи через шину 1 2С (рисунок создан в программе EAGLE)
2S0 Глава 10. Шина 1 2(
тактирования (SCL) и двунаправленная линия обмена данными использу ются ведущим и ведомыми устройствами для обмена информацией между собой. Обратите внимание на то, что для обеих линий шины 12С требуются повышающие резисторы.
Взаимодействие и идентификация устройств Шина РС позволяет нескольким ведомым устройствам взаимодействовать по общим линиям связи с одним ведущим устройством. В этой главе роль ведущего устройства играет плата Arduino. Ведущее устройство является ма стером шины и инициализирует все сеансы связи. Ведомые устройства не могут инициализировать сеансы связи, а могут только отвечать на запросы, отправленные ведущим устройством. Поскольку к линиям связи подключе но несколько ведомых устройств, важно, чтобы начинать сеанс связи могло только ведущее устройство. В противном случае несколько устройств могут пытаться одновременно установить связь, в результате чего произойдет по теря данных. Все команды и запросы, отправляемые ведущим устройством, могут при ниматься всеми ведомыми устройствами шины. Поэтому необходимо каким либо образом обеспечить связь только с тем устройством, которому предна значены посылаемые данные. Эта задача решается присвоением каждому ве домому устройству уникального 7-разрядного адреса или идентификацион ного номера (ID-номер). Когда ведущее устройство инициирует сеанс связи, оно передает ID-номер требуемого ведомого устройства. Ведомые устройства реагируют на данные в шине только тогда, когда эти данные обозначены их ID-номером. Некоторые устройства РС имеют настраиваемый адрес, тогда как другим присваивается постоянный адрес при изготовлении. Таким об разом, чтобы подключить к шине несколько экземпляров устройства одного типа, необходимо, чтобы каждое из них имело уникальный ID-номер. Поэтому, например, датчики температуры выпускаются с разными зара нее запрограммированными адресами шины 1 2С, поскольку обычно к одной шине необходимо подключить несколько таких датчиков. Для эксперимен тов этой главы мы будем применять датчик температуры линейки ТС74. Из справочного листка на этот датчик можно увидеть, что он предлагается с несколькими разными адресами (рис. 10.2). Для описанных далее экспери ментов мы возьмем датчик температуры TC74A0-5.0VAT с адресом 1001000. Данный датчик является версией этой микросхемы с питанием 5 В и корпу сом типа ТО-220. Эта микросхема предлагается с восемью разными ID-номерами; таким образом, к одной шине РС можно подключить восемь таких датчиков и ин дивидуально считывать данные с каждого из них. Когда позже в этой главе
Схема подключения устройств 12С 251
мы будем заниматься разработкой программ для взаимодействия с этим дат чиком температуры, непременно запишите ID-номер своего устройства, что бы посылать ему команды по правильному адресу. Другие микросхемы 12С, например AD7414 and AD7415 (другой 12С циф ровой датчик температуры, выпускаемый компанией Analog Devices), осна щаются контактами выбора адреса (AS - address select), посредством кото рых им можно присвоить определенный 12С-адрес. На рис. 10.3 приведены фрагмент справочного листка для микросхемы датчика AD7414, на котором показана ее цоколевка, а также таблица присвоения ей адреса 12С.
PART NQ Devlce
,
=f
f
f
Addresa Supply Opereting Peckage Options Vol18ge Temperature
Device:
ТС74: S.riel D9\111 Тhermel s.n-
Addl8SI Opticns:
• А1 • А2 • А3 • А4 • А5 • А6 • А7 • АО
1001 1001 1001 1001 1001 1001 1001 1001
АТ
Pecl
)
-- -
8 Add to arthiw_ 8 Addto"Arthiw.Jlf"' • Comp,eя.w:tIO\OII_ Fcwmм:... Eje Ьу Naguiss"• 12С EEPRnм IЬ,а~ e,,..
,4,/
F,_,.,....,_
LOGC5V r�
'-"Ьr1
·11 -,i,,: ••
1/U-
· \•·Д·�
/,
G)O А
1 ..,.....,tac�I
2 O.ttc
10 11 1l ц ') 16 1: ,а 20 21 2Z 2) 2◄ 2S
"
,,,.... Phraи ll/1&,/I018 22;.ЗJMIW:IDThet-1 12/16/IOU 22.3).IS�The•tl 11/16/1011 ZJ:a:tMJ-kloTher•I 1l/t6/IOII ZJ:U:•71klaП..rtl 12/16/Юll U·U:'8 � T'-cl 12J16/Юll u:u:•t 1w1o тм...1 11/16/1011! 12:Н:50� тм"1 12/16/JOll 22:)S:Sl�Tlwr.l U/16/2011 22.:JJ:S2К.lo�nil 12/111/Ю1' H:JJ:SJн.loTt>er-1 12/16/Юll 22:1J:S4t-ktlon..r.l 12/16/1011 22..n:55 Н1':1о Тhertl 11/16/IOU 2l'-.1J:�+lelo'lмttl U/16/IOU 2l:.U:)7Кеlо Тhettl Wlf/2011 21:33.S&Не.. �•1 11/16/Юtl 21:n:ss�n-.1 11/16/1011 U:M:OOtt.lDfм,•I 11/16{101.IU:J.l:Ol�TMrtl IJ/16/20.llU:M.'01:l+elCIТЬ.,.,\ Щ16{10U U::М:031i.-o flwrwl 11/lf/lOU 11:.J.I.Oil М. Therwl Щlt/101l 22:JA.o5Кelcl1Nrwl 11/16/1018 11.;U:Ofit,lelot'мrwl
..,.
wro,pW
-·-
GINr.i
-�;
�-
г- �
_.,;. • •ii��a.c.,.,i •• S•'%t ��= k=�aood -
�
Neulnll
...::�=-�
. f,7" � 1� i;;.-- 1т • �.-!
•
O....f-
�о.-
,
,_
" 1.7
��1
LOO
@
Рис. 14.20. Просмотр в программе электронной таблицы отладочных данных тестирования работы
часов RTC и взаимодействия с SD-картой
384 Глава 14. Работа с картами памяти 50
ПРЕВРАЩАЕМ СЕКУНДОМЕР В ЧАСЫ В главе 5 мы рассмотрели, как с помощью функций тактирования Arduino сде лать из шагового двигателя аккуратный хронограф. Теперь, когда вы знаете, как с помощью часов RTC получить информацию о текущем времени, можете ли вы модифицировать этот секундомер, чтобы он показывал текущее вре мя? То есть превратить его в часы. Разбейте циферблат (компакт-диск) на часы (12 или 24), а стрелка из палочки от мороженного на валу шагового двигате ля пусть указывает текущий час. Или же проявите креативность и превратите его в солнечные часы, отслеживающие время восхода и заката солнца. Для этого вместо часов пометьте циферблат значками восхода и заката, на кото рые будет указывать стрелка. Приблизительное время восхода и заката для вашего меридиана можно вычислить по дате, предоставляемой часами RTC. Скорость перемещения стрелки этих часов нужно будет корректировать в за висимости от времени года, поскольку зимой дни короче, чем летом.
РЕГИСТРАТОР ПРОХОДОВ ЧЕРЕЗ ДВЕРЬ Теперь мы можем воспользоваться нашими базовыми умениями и навы ками, чтобы создать регистратор проходов через дверь. На основе датчика расстояния из наших предыдущих проектов можно создать простой детектор движения, который будет отслеживать прохождение (вход и выход) людей че рез дверной проем. Данные с этого датчика подаются на регистратор, который записывает время этих событий на SD-карту для дальнейшей обработки.
Схема регистратора Все что нужно сделать, чтобы получить схему регистратора прохода, так это лишь добавить к нашей существующей схеме регистратора данных ана логовый датчик расстояния. При использовании шилда регистрации данных от компании Adafruit с установленными гнездовыми и штыревыми разъема ми выводы датчика можно подключить прямо в гнезда шилда. В частности, красный провод вывода датчика подключается в гнездо 5 В шилда, черный или коричневый - в гнездо земли (GND), а белый или желтый - в гнездо АО. При отсутствии на шилде гнездовых разъемов в него нужно будет впаять дополнительные штыревые разъемы, к которым можно будет подключать провода выводов датчика. На рис. 14.21 показан шилд компании Adafruit с впаянными в него дополнительными штыревыми разъемами для подклю чения датчика. Альтернативно выходные провода датчика можно непосред ственно впаять в сквозные монтажные отверстия на печатной плате шилда. Чтобы данная схема работала должным образом, ИК-датчик расстояния необходимо установить таким образом, чтобы его ИК-луч горизонтально
Регистратор проходов через дверь
Рис. 14.21. Шилд регистрации данных компании Adafruit с подключенным к нему датчиком расстояния
Датчик расстояния
USВ-кабель
Рис.14.22. Установка регистратора прохода через дверь
пересекал дверной проем. Таким образом, проходящий через дверь человек обязательно прервет этот луч. Но повремените с установкой датчика до тех пор, пока соответствующее программное обеспечение не будет готово и за гружено в плату Arduino. Датчик и плату Arduino я рекомендую прикрепить малярным скотчем и/или полосками ЗМ Command для крепления картин. Эти крепежные материалы легко удаляются, что позволит снять датчик, не
85
Глава 14. Работа с картами памяти SD
повредив отделку двери или стены. Установленное оборудование может вы глядеть, как показано на рис. 14.22. Но если вы также хотите регистрировать прохождение своих домашних питомцев или детей, то датчик нужно будет установить намного ближе к полу. Подать питание на схему можно несколькими способами. В частности, можно взять сетевой адаптер с кабелем с USВ-разъемом, сетевой адаптер с кабелем с цилиндрическим разъемом или же 9-вольтовую батарейку с вы ходным цилиндрическим разъемом. Конечно же, со временем батарейка ся дет, и ваше устройство будет обесточено. На рис. 14.22 можно видеть, что питание для моего регистратора я подаю через кабель с USВ-разъемом, под ключенный к сетевому адаптеру (который на рисунке не показан).
Программа регистратора Программа для регистратора прохода через дверь создается на основе уже существующей программы регистрации данных. В этом случае возможность чтения конфигурационных переменных из файла не представляет особой полезности, поэтому из программы можно удалить соответствующий код. Добавить же нужно код для чтения состояния выходного сигнала датчика расстояния и проверки, не изменилось ли существенно его значение после последнего опроса. Если изменилось, то можно предполагать, что что-то пе ресекло ИК-луч датчика расстояния на пути в комнату или из комнаты. Также необходимо установить пороговое значение, которое можно счи тать изменением значения сигнала. Для моей схемы я определил, что изме нение аналогового значения на больше, чем 75 единиц было надежным при знаком движения. Для вашей схемы это значение будет, скорее всего, дру гим. Поэтому лучше проверить значения для своей системы после установки аппаратной составляющей. Проверку значения выходного сигнала датчика расстояний следует осуществлять достаточно часто, чтобы не пропустить ни одного прохода через дверной проем. Но с другой стороны не имеет смысла выполнять ее настолько часто, что за один день мониторинга будут записаны миллионы показаний. Я рекомендую записывать на SD-карту каждое определенное перемеще ние, но показания датчика при отсутствии движения записывать только периодически. Этот подход будет «золотой серединой)) между требуемым объемом памяти и точностью. Поскольку для нас наибольшую важность представляет точное время прохода через датчик, данные этих событий за писываются с большим разрешением по времени, чем данные, когда ниче го не происходит. Этот подход реализован в листинге 14.5. Опрос датчика осуществляется каждые 50 мс с записью значения 1 в столбец «active» при каждом выявленном движении. При отсутствии движения в столбец «active>> записывается значение О каждую секунду.
Регистратор проходов через дверь 387
В листинге 14.5 приведен полный код программы регистратора прохода через дверь, содержащий только что описанные модификации. Листинг 14.S. Программа entrance_Logger.ino регистратора прохождений через дверь // Регистрирует вход и выход из комнаты // Раскомментируйте следующую строку, если ваш шилд использует // микросхему D51307, а не PCF8523 //#define RTC_CHIP_IS_D51307 // Раскомментируйте следующую строку кода, если хотите принудительно // задать устанавливаемое время // Эту строку всегда нужно закомментировать, прежде чем исполнять // программу на практике //#define FORCE_UPDAТE #include #include
// Подключаем библиотеку SD // Подключаем библиотеку Wire для связи по 1 2 ( // с часами реального времени #include "RTCLib.h" // Подключаем библиотеку RTCLib для работы // с часами реального времени
// Для связи с SD-картой используются стандартные контакты SPI // Для связи с микросхемой RTC используются стандартные контакты 12С // Для SD-карты всегда необходимо задать контакт CS // для выбора ведомого устройства const int CS_PIN = 10; // Сигнал с ИК-датчика расстояния подается на аналоговый контакт АО const int IR_PIN = О; // Используем флаги компиляторы, чтобы установить правильную микросхему #ifdef RTC_CHIP _IS_D51307 RTC_D51307 RTC; String chip = "D51307"; #else RTC_PCF8523 RTC; String chip = "PCF8532"; #endif
388 Глава 14. Работа с картами памяти SD
// Используем флаги компилятора для решения о принудительном обновлении #ifdef FORCE_UPDATE boot update_ctock = true; #etse boot update_ctock = fatse; #endif // Инициализируем строки даты и времени String time, date; // Инициализируем переменные расстояния int raw = О; int raw_prev = О; bootean active = fatse; int update_time = О; void updateDateTime0 {
// Получаем текущие дату и время и сохраняем в соответствующих // строковых переменных DateTime datetime = RTC.now0; String уеаг = String(datetime.year0, DEC); String month = String(datetime.month0, DEC); String day = String(datetime.day0, DEC); String hour = String(datetime.hour0, DEC); String minute = String(datetime.minute0, DEC); String second = String(datetime.second0, DEC); // Конкатенируем строчные переменные в стандартный // формат даты и времени date = уеаг + ·;· + month + "/" + day; time = hour + ·:· + minute + ·:· + second;
} void setup0 {
Serialbegin(9600); // Для контакта CS необходимо задать режим выхода pinMode(CS_PIN, OUTPUТ); // Инициируем библиотеку RTC RTC.begin0;
Регистратор проходов через дверь 389 // Всегда обновляем время, если часы RTC не работают #ifdef RTC_CHIP_IS_D51307 if (!RTC.isrunningO) update_cLock = true; #eLse if (!RTC.initiaLizedO) update_cLock = true; #endif // Если часы RTC не работают, или мы принудительно устанавливаем их, // устанавливаем время часов RTC по времени компиляции if (update_cLock) {
SeriaL.print(F("Setting ")); SeriaL.print(chip); SeriaL.print(F(" time to compiLe time .. .")); RTC.adjust(DateTime(FLDAТE_J, FLТIME_J)); SeriaL.printLn(F("Done!"));
}
eLse {
SeriaL.print(chip); SeriaL.printLn(F(" time is aLready set!"));
}
// Показываем время updateDateTimeQ; SeriaL.print(F("RTC Date: ")); SeriaL.printLn(date); SeriaL.print(F("RTC time: ")); SeriaL.printLn(time); // Инициализируем SD-карту SeriaL.print(F("lnitiaLizing SD Card.. .")); if (!SD.begin(CS_PIN)) {
SeriaL.println(F("Card Failure!")); while(l);
}
Serial.println(F("Card Ready!")); // Записываем заголовки столбцов File dataFile = SD.open("log.csv", FILE_WRITE);
390 Глава 14. Работа с картами памяти SD if (dataFiLe) {
dataFiLe.printLn(F('\nNew Log Started!")); dataFiLe.printLn(F("Date,Time,Raw,Active·)); dataFiLe.cLoseQ; // Данные записываются только по закрытию // подключения функцией cLoseQ! //Те же данные выводим в окно монитора порта для целей отладки SeriaL.printLn(F('\nNew Log Started!")); SeriaL.printLn(F("Date,Тime,Raw,Active·));
}
eLse {
}
SeriaL.println(F("CouLdn't open Log file")); while(l);
}
void LoopO
{
updateDateTimeQ; // Получаем текущие дату и время // Собираем данные движения raw = anaLogRead(IR_PIN); // Если текущее значение больше предыдущего на 75, // рассматриваем это как движение. if (abs(raw-raw _prev) > 75) active = true; eLse active = false; raw _prev = raw; // Открываем файл и записываем в него данные if (active 11 update_time == 20) {
FiLe dataFile = SD.open("log.csv", FILE_WRITE); if (dataFile)
{
dataFile.print(date); dataFile.print(F(",")); dataFile.print(time);
Регистратор проходов через дверь 391 dataFiLe.print(F(",")); dataFiLe.print(raw); dataFiLe.print(F(",")); dataFiLe.printLn(active); dataFiLe.cLoseO; // Данные записываются только по закрытию // подключения функцией cLoseO! //Те же данные выводим в окно монитора порта для целей отладки SeriaL.print(date); SeriaL.print(F(",")); SeriaL.print(time); SeriaL.print(F(",")); SeriaL.print(raw); SeriaL.print(F(",")); SeriaL.printLn(active); } eLse {
SeriaL.printLn(F("CouLdn't open Log ftLe"));
} update_time = О; } deLay(SO); update_time++; }
Анализ данных Загрузите код в свою плату Arduino, закрепите датчик на двери должным образом и дайте ей поработать некоторое время. Когда наберется достаточ ный объем данных, вставьте SD-карту в считыватель компьютера и загрузи те файл регистрации данных в электронную таблицу. Даже если регистрация велась всего лишь в течение одного дня, собранных данных должно быть до статочно для того, чтобы создать график активности движения во времени. При отсутствии активности значение линии активности графика равно О. Когда же кто-то входит или выходит из комнаты, это значение подскакивает до 1, и можно зафиксировать точное время этого события. Процедура создания графика зависит от конкретного приложения для по строения графиков. Чтобы не затруднять вас этой задачей, я создал онлайн программу электронной таблицы, которая выполняет построение графика. Получить доступ к этой программе можно с помощью вашей учетной записи
392 Глава 14. Работа с картами памяти SD Журнал событий прохода 400
- Активные - Исходные
0.75
� 300
.,
с, :&:
с,: s :&:
� 200 "' :&: "' "' 2i
0.5
:§' � 100
0.25
s
� "':&: "'
j
2018-12-17 20:56 Дата/время Рмс. 14.23. График проходов через дверь в течение нескольких минут
Google Drive. Ссылка на эту программу находится на веб-странице для этой главы (https://www.exploringarduino.com/content2/chl4) в разделе Useful Links под названием Pre-formatted Google Spreadsheet for Graphing Logged Data. При открытии ссылки нажмите кнопку Make а сору, чтобы скопиро вать эту программу в свою учетную запись Google Drive. Откройте таблицу на своем Google Drive и скопируйте свои данные на место образцовых дан ных в левой части таблицы. График в правой части автоматически обновится в соответствии с новыми данными. На рис. 14.23 показан пример, как может выглядеть график данных за несколько минут мониторинга. Цветной рису нок 14.23 можно посмотреть на сайте издательства БХВ (bhv.ru). На графике отображаются как исходные значения датчика, так и активный сигнал, ко торый создается на основе предварительно заданного порогового значения. Если на графике исходных данных наблюдаются всплески, которые отсут ствуют на графике активного сигнала, или наоборот, то нужно откорректи ровать пороговое значение для более качественной работы системы.
РЕЗЮМЕ В этой главе мы узнали следующее. :, Как можно легко хранить данные в виде простого текста в файлах CSV, разделяя элементы данных запятыми. :, Как форматировать карты SD в системах под Windows, Мае OS и Linux. :, На рынке предлагается большой выбор шилдов SD-карт с разными уникальными возможностями. :, Как использовать библиотеку SD для записи и считывания данных с файла на SD-карте.
Резюме 393
:> Как выполнить сопряжение платы Arduino с часами реального време ни и создавать программы для маркировки данных метками времени посредством часов RTC. :> Как использовать директивы и константы препроцессора для ком пилирования разных версий исполняемого кода из одного исходного кода программы. :> Как сэкономить память RAM, сохраняя строковые данные во флэш память. :> Как определять движение по меняющимся значениям выходного ана логового сигнала датчика расстояния. :> Как с помощью программы электронной таблицы создать график дан ных, полученных из регистратора.
Беспроводная связь
Глава 15. Радиосвязь Глава 16. Беспроводная связь Bluetooth Глава 17. Wi-Fi и облачные хранилища
Радиосвязь
15
Список деталей и оборудования для проектов этой главы :> Плата Arduino Uno или Adafruit METRO 328 (1 шт.). :> USВ-кабель (тип А на В для Arduino Uno, тип А на Micro-B для METRO 328) (1 шт.). :> Беспаечная макетная плата половинного или полного размера (1 шт.). :> Набор проволочных перемычек. :> Резистор номиналом 220 Ом (1 шт.). :> Пьезоэлектрический зуммер (1 шт.). :> Сетевой адаптер, 5 В, 1 А, выходной USВ-разъем (1 шт.). :> Радиоприемный модуль с рабочей частотой 315 МГц (или подоб ный радиомодуль с рабочей частотой, разрешенной в вашей стране) (1 шт.). :> Однокнопочный пульт дистанционного управления с радиопередат чиком на частоте 315 МГц (или подобный пульт управления с рабочей частотой, разрешенной в вашей стране) (1 шт.). :> Модуль управляемого силового реле (реле IoT Power Relay компании Digital Loggers, Inc.) (1 шт.). :> Лампочка с сетевым питанием (1 шт.). :> Небольшая отвертка (1 шт.). Исходный код и прочие электронные ресурсы • Исходный код, видеоуроки и прочие электронные ресурсы для этой главы можно загрузить с веб-страницы https://www.exploringarduino. com/content2/chl 5. • Исходный код для проектов этой главы можно также загрузить на вкладке Downloads веб-страницы издательства Wiley для этой книги: https://www.wiley.com/go/exploringarduino2e.
д
ЧТО ВЫ УЗНАЕТЕ ИЗ ЭТОЙ ГЛАВЫ
ля многих микроконтроллерных проектов часто требуется наличие возможности радиосвязи. Оснастить устройство беспроводной свя зью можно многими способами, но проще всего использовать радиомодуль.
�
Глава 15. Радиосвязь
На рынке предлагается большой выбор радиомодулей разных форм и разме ров, но почти все они работают одинаково: когда на передатчике изменяется состояние одного выхода, на выходе приемника тоже появляется соответ ствующий сигнал. По сути, это можно сравнить с однопроводной шиной, по которой за раз передается и принимается один бит информации. В этой главе мы познакомимся с основными принципами беспроводной связи, ограни чившись простыми способами радиосвязи. В последующих двух главах мы расширим рассмотрение этой темы в область радиосвязи Bluetooth и Wi-Fi. Примечание Первое издание этой книги (выпущенное в 2013 г. издательством Wiley) содержало главу по радиосвязи с использованием радиомодулей ХВее, которые работают, как беспро водной последовательный канал. Но радиомодули ХВее трудно настроить для правиль ной работы, они дорого стоят и могут взаимодействовать только друг с другом. В этом издании я решил заменить эту главу двумя новыми главами по Bluetooth и Wi-Fi, по скольку большинство пользователей находят их более полезными и доступными, чем радиомодули ХВее. Также я добавил настоящую главу по простым радиоканалам, по скольку она закладывает хорошую основу для понимания электромагнитного спектра и его значение для радиосвязи. Если же вы хотите научиться работать с радиомодулями ХВее, я настоятельно рекомендую сначала ознакомиться с материалом этой главы, а за тем просмотреть видеоруководство по работе с ними, которое можно найти по адресу
blum.fyl/xbee-tutorial.
ЭЛЕКТРОМАГНИТНЫЙ СПЕКТР Прежде чем приступать к рассмотрению работы радиосвязи, полез но получить базовые знания научных принципов, на которых она основа на. Электромагнитный спектр, наверное, является одним из самых важных аспектов нашей жизни, о котором мы никогда не задумываемся. Данный спектр определяет всю излучаемую во вселенной энергию от гамма-лучей ультравысокой частоты до низкочастотных радиоволн. Посередине спектра находится видимый свет, наиболее знакомый нам тип электромагнитного излучения. Свет от разных источников - солнца, осветительных ламп, све тодиодов наших устройств на Arduino - воздействует на наши глаза в виде электромагнитного излучения. Подобно тому, как глаз воспринимает элек тромагнитную энергию, которую затем наш мозг интерпретирует, как свет и извлекает из нее разную информацию, так и оснащенная «глазамю> в виде радиоприемника плата Arduino может принимать электромагнитные излу чения в виде радиоволн, а затем извлекать из них информацию. На рис. 15.1 приведено наглядное представление (созданное агентством НАСА) всех форм электромагнитных излучений. Все электромагнитные излучения передаются в виде волн определен ной частоты, которые распространяются в вакууме со скоростью света
W�•
. ....,..,,,_""'
� � о• (meters) :
10"(Нeltz)
10'm
1
""'
10"m
"""'
10"2m
�I�---·············
wlcldtOfaЬllleЬal
0"'m \1
10"3m
-·_ _., ....
1
11t'm
-�,�·
,o"rii
ni,,.
10:-m
10"'m
1 ,o"m
....
:
10:1•m Wavelength • wtdltlol1w•�
(11Vf11t
1o•m
Рис. 15.1. Наглядное представление электромагнитного спектра (Источник: NASA, https://science.nasa.gov)
·
;!Фq!15%Щ*
10-11m
10" Нz
lklfJfatomk:nudei
12m
�n\lФ,\FliD ::, 1 o;WmJongl!t• ....
:g
w
,::,
�
11)
:::1
s,
"
о:
-4 :::[
s
:::[
Qj
� ...,
о
,::,
11)
� �
400 Глава 1 S. Радиосвязь
(приблизительно 300 тысяч километров в секунду). Частота волны электро магнитного излучения представляет количество колебаний волны в секунду и измеряется в герцах (Гц). Самая высокая частота у гамма-лучей: 10 квин тильонов герц. На противоположном конце спектра находятся радиоволны, нижний предел диапазона которых составляет приблизительно 30 Гц. С частотой радиоволн (и других волн электромагнитного излучения) тес но связана другая ее характеристика: длина волны. Длина волны - это рас стояние между пиками двух сопредельных колебаний распространяющейся в пространстве волны. Длина волны электромагнитного излучения - просто другой параметр волны, она всегда связана с частотой через скорость рас пространения волны. Скорость распространения электромагнитных волн в вакууме равна скорости света, поэтому длина волны всегда будет равна ско рости света, разделенной на частоту данной волны. Термин длина часто употребляется применительно к волнам видимого спектра, а термин частота - применительно к радиоволнам. Например, в справочном листке для красного светодиода, который был в нескольких на ших проектах, указана длина его первичной волны. Источник красного све та генерирует электромагнитную энергию с длиной волны приблизительно 630 нанометров (нм). Человеческий глаз может воспринимать в виде света электромагнитные излучения с длиной волны в диапазоне от 380 до 750 нм. Радиопередатчик и приемник, используемые в проектах в этой главе, рабо тают в диапазоне частотой 315 МГц. Это означает, что излучаемые передат чиком радиоволны имеют длину волны приблизительно 0,95 м (или около половины роста среднего человека).
Радиоспектр Но зачем нам нужно понимать такие нюансы, как длина и частота волны, если все, что мы хотим, - это только передавать по радиоканалу простой сигнал включено/выключено? Выбор правильной частоты для передачи сиг нала может сильно влиять на скорость передачи данных, способность сигна ла проходить через определенные препятствия (например, стены), а также на возможность легально осуществлять передачу в вашей стране. Большая часть радиоспектра (т. е. диапазона электромагнитных излучений с частотой радиоволн) зарезервирована для специальных применений: военная радио связь, телевизионные передачи, АМ/ЧМ радиопередачи, радиосвязь право охранительных органов и служб чрезвычайных ситуаций, спутниковая связь, мобильная связь и т.п. Возможно, что вам приходилось читать в средствах массовой информа ции статьи о распределении диапазонов радиочастот для сотовой мобиль ной связи. Часто идут дебаты о том, как распределить радиочастоты раз личным технологиям, например, передачи данных по сотовой связи, связи
Электромагнитный спектр 401
Wi-Fi и т.п. Если всяк кому не лень мог бы передавать на любой понравив шейся ему частоте сигнал произвольной мощности, то очень быстро радио спектр был бы заполнен «винегретом» перекрывающих друг друга сигналов, выделить из которого требуемый не смог бы никакой приемник. Чтобы не допустить такого развития событий, различные государственные руководя щие органы во всем мире определяют специфичные правила работы пере дающих устройств. В частности, распределением спектра радиочастот и разработкой соответствующих стандартов в США занимается Федеральная комиссия по связи (FCC - Federal Communications Commission), в Канаде Министерство промышленности (IC - Industry Canada), а в Европейском союзе- Международный специальный комитет по радиопомехам (CISPR Comite International Special des Perturbations Radioelectriques). По большому счету, международные стандарты совместимы друг с другом; иными слова ми, если какая-либо часть спектра радиочастот выделена для определенных целей в одной стране, то часто эта же часть спектра также выделена для это го же и в других странах. Но в общих правилах иногда случаются разногла сия по применению определенных частотных диапазонов в разных странах. Поэтому разработчик приложения с использованием радиопередатчика дол жен знать и выполнять местное законодательство, регулирующее использо вание радиочастотного спектра. В примерах в этой главе передатчик работает на частоте 315 МГц, которая в США регулируется правилами работы в частотном диапазоне 260-470 МГц. Передача в радиочастотном диапазоне не требует разрешения при усло вии соблюдения различных требований к типу и мощности радиосигнала. Например, запрещается передавать звук или видео, но разрешается передача коротких пачек сигнальных импульсов. Этот частотный диапазон часто ис пользуется для пультов дистанционного управления гаражными дверями и автомобильными радиобрелками, поскольку он обеспечивает сравнительно большую дальность передачи, не создавая помех от постоянных потоков дан ных. Обратите внимание на тот факт, что в Европе передача без разрешения в диапазоне 315 МГц запрещена, но согласно правилам CISPR разрешается в диапазоне 433 МГц. Общая частота 433 МГц была выбрана потому, что пере дача на ней без лицензии разрешена во всем мире, что облегчает создание продукта, который можно реализовать на рынках всех стран. Для передачи в диапазоне ISM 1 также не требуется разрешение. Этот диа пазон частот для промышленных, научных и медицинских организаций пред ставляет собой набор поддиапазонов, выделенных во всем мире для общего использования (с некоторыми несущественными различиями в зависимости от региона). В э�ом диапазоне работают беспроводные телефоны, устройства 1 Англ. Industrial, Scientific and Medica/ band - диапазон [частот] для промышленных, научных и медицинских организаций. - Прим. пер.
402 Глава 15. Радиосвязь
RFID, Bluetooth и микроволновые печи. Но, опять же, лишь тот факт, что для передачи в этом диапазоне не требуется разрешение, не означает, что в нем можно передавать что угодно как угодно. Передача в нем регулируется ре гиональными правилами касательно мощности передаваемого сигнала. Эти правила обеспечивают, например, что работа микроволновой печи вашего соседа не нарушала работу вашего оборудования Wi-Fi. (Оба типа устройств работают в одном из поддиапазонов ISМ-диапазона: 2,4-2,5 ГГц.) Но не следует слишком задумываться о правилах касательно передачи в диапазоне, в котором мы будем работать. Респектабельные магазины про дадут вам только такие радиоустройства для Arduino, которые разрешены для использования в вашей стране. Кроме того, проекты Bluetooth и Wi-Fi, с которыми мы познакомимся в следующих двух главах, будут работать без опасно в диапазонах ISM. А для проектов в этой главе, убедитесь в том, что выбранный радиомодуль соответствует требованиям правил вашей страны.
Принципы обмена данными по радиоканалу Итак, мы знаем, что наш радиопередатчик будет посылать короткие па кеты данных на определенной разрешенной частоте. Но как на самом деле осуществляется такая передача? Каким образом приемное устройство может отличить посылаемый передатчиком на определенной частоте (в нашем слу чае 315 МГц или 433 МГц) высокий логический уровень от низкого? Ответ на этот вопрос зависит от типа модуляции в передатчике и прием нике. При одинаковой модуляции на передающем и приемном конце нам не нужно сильно беспокоиться о подробностях работы линии связи. А в общем случае модуляция представляет собой процесс кодирования данных на не сущей волне (электромагнитной волне на частоте передачи). Скорее всего, вы в той или иной степени знакомы с двумя типами модуляции аналогового сигнала: амплитудной и частотной по двум типам радиопередач: АМ (ампли тудная модуляция) и ЧМ (частотная модуляция) 1 • При этих двух типах мо дуляции аналоговый сигнал (например, мелодия) кодируется, изменяя (или модулируя) амплитуду или частоту несущей волны (рис. 15.2). На приемном конце исходный звуковой сигнал можно извлечь из модулированного носи теля по изменениям в амплитуде или частоте. Модуляция цифровых сигналов похожа на эти методы модуляции ана логовых сигналов. Но вместо кодирования в несущую волну информации аналогового сигнала (например, аудио) в нее кодируются нули и единицы. Подобно многим передатчикам, действующим в качестве ключа (например, пультам дистанционного управления гаражными дверями, автомобильным 1 Речь идет о США, где у большинства стандартных радиоприемников только два диапазона: АМ иFМ.
Электромагнитный спектр 403
_____,. Сигнаn
_____,. АМ
_____,. ЧМ Рмс. 15.2. Амплитудная (АМ) и частотная (ЧМ) модуляция аналогового сигнала (Источник: Science АВС, https://www.scienceabc.com)
брелкам и т.п.), рассматриваемые в этой главе радиомодули применяют раз новидность амплитудной модуляции - амплитудную манипуляцию (АМн). Амплитудная манипуляция состоит в изменении амплитуды, или мощности, сигнала несущей при неизменной частоте. Этот подход графически иллю стрируется на рис. 15.3. В простейшем случае прием сигнала ожидаемой ча стоты в течение определенного периода времени соответствует логическому сигналу 1. Отсутствие же такого сигнала в течение определенного периода времени соответствует логическому сигналу О. Но, чтобы обеспечить получение неискаженных данных, кроме основ ной информации, необходимо также передавать и принимать дополнитель ную служебную информацию, такую как биты адресов и контроля ошибок. Посnедов.1теnьно�одных двоичных цифровых сигнаnов
54.5 .... 4
§ Э.5 .... .., s
э ....
2.5,... 2 ....
1.5 1>-0.5 .... 0.2
§: 1 . � o.s .... l 0.6>-� 0.4 .... g-0.2 >--
0.4
0.6
0.8 Время, с
1.2
1.4
1.6
х10·7
Выходной амплитудно-манипуnированный сигнаn
� о--� -0.2....
-0.4 -0.6 .... -0.8 ....
-1 �--- � 2��..._- 4� -� 1.4��-...,-,1.6 o.�6�_._-�o.c'c s--'-L...L�L...L....._��1'=-.2--��..... 0. 0 0_ х10·7 Время, с
Рмс. 15.3. Амплитудная манипуляция цифрового сигнала (рисунок создан в программе MATLAB)
404 Глава 15. Радиосвязь
Но пользователю не нужно заботиться об этом самому, поскольку радиомо дуль автоматически выполняет такие операции. Нам остается только при нять декодированные логические сигналы.
ПЕРЕДАЧА НАЖАТИЙ КНОПКИ ПО РАДИОКАНАЛУ Теперь, когда у нас есть базовые понятия о принципах радиопередачи, можно приступать к экспериментам с беспроводным каналом связи.
Подключение приемника к плате Arduino Используемый в проектах этой главы приемник (предоставляемый ком панией Adafruit, 1D-код продукта 1096) может принимать сигналы нажатия четырех кнопок. Рекомендуемый для этого проекта передатчик оснащен только одной кнопкой, нажатие которой вызывает создание высокого уров ня на контакте D2 модуля радиоприемника. Уровень на контакте D2 остает ся высоким (5 В) до тех пор, пока нажата кнопка на модуле передатчика, и переходит на низкий, когда кнопка отпущена. Сигнал с контакта D2 прием ника можно подать на один из цифровых входов платы Arduino (способных работать с уровнями 0-5 В) и обработать его с помощью программы, выполняющей тре буемое действие в зависимости от состояния этого сигнала. Но сначала рекомендуется размотать ( очень осторожно) антенну приемника, как показано на рис. 15.4, чтобы увеличить даль ность его действия. Примечание Если измерить длину провода антенны, то обнару жится, что она составляет приблизительно 24 см. Такая величина не случайна, а объясняется тем, что это антенна несимметричного (штыревого) четвертьволнового типа. Ее длина равна одной четверти длины волны, для приема которой она предназначена. Длина радиоволны частотой 315 МГц составляет приблизительно 0,96 м (или в четыре раза больше длины нашей антенны).
Рмс.15.4. Выпрямление антенны радиоприемного модуля
Выпрямив антенну, модуль радиоприем ника можно подключить непосредственно к плате Arduino. В частности, модуль мож но напрямую подключить к платам Arduino Uno, Leonardo или совместимым платам,
Передача нажатий кнопки по радиоканалу 40S
Рис. 1 S.S. Установка модуля радиоприемника напрямую в плату Arduino
например, к плате METRO, которая идентична плате Arduino Uno. Именно последняя плата используется в проектах этой главы и показана на соответ ствующих рисунках. Расположите модуль радиоприемника таким образом, чтобы его контакт DO находился между корпусом разъема шин питания и корпусом аналоговых контактов платы Arduino, а затем вставьте штыревые контакты модуля радиоприемника в соответствующие гнезда разъема платы Arduino (рис. 15.5). Таким образом, входной контакт подачи напряжения питания 5 В модуля радиоприемника будет совмещен с выходным контактом Vin платы Arduino (на котором при питании платы через кабель USB присутствует напряже ние 5 В), а контакт земли радиомодуля - с контактом земли платы Arduino. Контакт D2 радиомодуля окажется подключенным к контакту Al платы. Вспомним, что на входные аналоговые контакты также можно подавать циф ровые сигналы.
Программа для работы с радиоприемником После подключения радиомодуля к плате Arduino оборудование готово для приема радиосигналов. Но обратите внимание на следующее обстоятель ство: если модуль радиопередатчика содержит пластиковую прокладку под батарейкой, удалите ее, потянув за язычок. Эта прокладка предназначена для предотвращения разряда батарейки, пока радиопередатчик находится в про цессе доставки до пользователя.
406 Гnава 1 S. Радиосвязь
Как уже упоминалось ранее, наш модуль радиоприемника работает в ре жиме кратковременного приема. Иными словами, высокий уровень на его контакте D2 присутствует только тогда, когда на модуле радиопередатчика нажата кнопка. Если кнопка отпущена, то на этом выходе присутствует низ кий уровень. Чтобы проверить работоспособность схемы, напишем програм му для Arduino, которая отслеживает состояние выходного сигнала на кон такте Al платы Arduino (к которому подключен контакт D2 модуля радио приемника), включает встроенный в плату светодиод, когда на этом контакте присутствует высокий уровень, и выключает его, когда низкий. Такая про грамма предельно проста и состоит всего лишь из одной строки кода раздела setupO, который задает выходной режим контакта управления светодиодом, и одной строки кода раздела LoopO, который устанавливает состояние выход ного сигнала контакта управления светодиода равным состоянию сигнала на контакте А 1: void setup0{digitalWrite(13, OUTPUT);} void loop0{digitalWrite(13, digitalRead(A1));} Вот и вся программа. Обратите внимание на использование функций в качестве аргументов для других функций. Для простых программ нет на добности в присваивании выходных значений этих функций переменным. В данном примере можно было бы сначала исполнить функцию digitaLReadO, присвоить полученное значение булевой переменной, а затем передать эту переменную функции digitaLWriteQ. Но этот процесс можно сократить, вы полнив чтение цифрового входа внутри другой функции. Результат исполне ния вложенной функции (высокий уровень или низкий) служит аргументом для оберточной функции. Примечание Если обнаружится, что при нажатии кнопки на радиопередатчике на контакте D2 радио приемника не создается сигнал высокого уровня, причиной этому может быть то, что передатчик настроен на модуляцию сигнала на одном из других каналов. Прежде все го проверьте, мигает ли красный светодиод на модуле радиопередатчика при нажатии кнопки. Если не мигает, возможно, что разрядилась его батарейка. Если с этим все в по рядке, попробуйте проверить состояние контакта VТ модуля радиоприемника, который вставлен в гнездо АЗ платы Arduino. Выходной сигнал на этом контакте появляется при активировании любого из каналов передачи. Если состояние выходного сигнала на кон такте VТ соответствует нажатиям кнопки радиопередатчика, методом произвольного тестирования контактов других каналов установите, на котором из них ведется пере дача.
Убедившись в работоспособности канала радиосвязи, на его основе мож но создать какой-то более интересный проект. Например, кроме управления светодиодом, можно с помощью функции miШsO измерить длительность пе риода нажатия кнопки и выводить это значение в окно монитора порта для
Передача нажатий кнопки по радиоканалу 407
каждого нажатия кнопки. Чтобы реализовать эту задачу, нам потребуется пара переменных для отслеживания состояния кнопки. Полный код для это го приведен в листинге 15.1. Листинг 15.1. Программа rf_test.ino для выполнения простой задачи с испопьэо ванием радиоканала // Выполнение простой задачи с использованием радиоканала // Предполагается наличие радиоприемника с кратковременным режимом приема // Радиоприемник М4 этого типа функционирует подобно кнопке. // Когда на модуле радиопередатчика нажата кнопка, на контакте D2 //радиоприемника присутствует высокий уровень. // При отпущенной кнопке радиопередатчика на этом выходе //присутствует низкий уровень. // Контакт ввода-вывода платы Arduino, подключенный к контакту D2 //модуля радиоприемника const int TRIGGER_PIN = Al; // Встроенный в плату светодиод включается только //при нажатой кнопке радиопередатчика const int LED_PIN = 13; //Объявляем и инициализируем переменную для хранения //времени начала нажатия кнопки unsigned Long start_time; // Переменная для отслеживания состояния нового нажатия boolean announced; void setup0
{
Serial.begin(9600); //Тестирование радиоканала Serialprintln("RF Test"); //Для контакта управления светодиодом //необходимо задать режим выхода pinMode(LED_PIN, OUTPUT);
} void Loop0 {
digitaLWrite(LED_PIN, LOW);
// Выключаем светодиод при отпущенной кнопке
408 Глава 15. Радиосвязь announced = faLse;
// Таким образом, нажатие кнопки // объявляется только один раз
// Исполняем следующий цикл, пока кнопка остается нажатой whiLe (digitaLRead(ГRIGGER_PIN)) {
// Выполняем следующее один раз для каждого нажатия кнопки: if (!announced) {
start_time = miШsO; SeriaL.print("PRESSED..."); // НАЖАТА... // Выводим сообщение только один раз announced = true; // для каждого нажатия кнопки
}
digitaLWrite(LED _PIN, HIGH); } // После отпускания кнопки вычисляем длительность ее нажатия if (announced) {
// ОТПУЩЕНА после SeriaL.print("RELEASED after"); unsigned Long duration = miШsO - start_time; Serial.print(round(duration/1000.0)); // Выводим длительность // нажатия в секундах //секунд Serial.printLn("second(s).");
} }
Обратите внимание на переменные состояния для отслеживания выво димых в окно монитора порта извещений и длительности нажатия кнопки. Значение переменной announced сбрасывается на faLse (ложь) между нажати ями кнопки (вне цикла whiLeO, но внутри главного цикла LoopQ). Цикл whiLeO внутри главного цикла LoopO исполняется все время, пока нажата кнопка на радиопередатчике. В его первой итерации переменной announced присваи вается значение true (истина). После этого условие !announced возвращает значение faLse (ложь) (вспомним, что восклицательный знак в начале пере менной инвертирует ее значение), поэтому сообщение PRESSED больше не выводится в окно монитора порта, так же, как и таймер miШsO не запускается повторно. После выхода из цикла whileO (из-за отпускания кнопки или по тери сигнала) код в главном цикле LoopO возвращается к ожиданию нажа тия кнопки. Поскольку переменной announced присваивается значение true только в цикле whiLeO, блок if(announced) исполняется только один раз (сразу
Беспроводной дверной звонок 409
L___
RF Te,st PRESSED... RELEASED PRESSED... RELEASED PRESSED... RELEASED PRESSED... RELEASED PRESSED... RELEASED
Send
,,.. after after after after after
з 5 4 l 2
зесоnd(з). зесоnd(з). ,second(з). зесоnd(з). зесоnd(з).
V
Е2] Autosaoll
v 9600 Ьaud
v
dear output
Рис. 15.6. Снимок экрана окна монитора порта с выводимыми в него сообщениями программы тестирования радиоканала
после отпускания кнопки), поскольку на следующей итерации цикла LoopQ переменной announced снова присваивается значение faLse. В результате исполнения этого кода нажатие кнопки на радиопередатчике продолжает, как и прежде, включать встроенный светодиод платы Arduino. Но кроме этого в начале каждого нажатия кнопки сохраняется системное время (благодаря функции miШsO), а после отпускания кнопки в окно мони тора порта выводится длительность ее нажатия. На рис. 15.6 показан снимок экрана монитора порта с выводимыми в него сообщениями о длительности нажатия кнопки. Если у вас возникают перебои в приеме сигнала, попробуйте сократить расстояние между передатчиком и антенной, или измените положение ан тенны на такое, при котором наблюдается наилучший прием. Дальность дей ствия этих передатчиков не особенно большая, но на расстоянии нескольких метров должен быть уверенный прием. Не волнуйтесь, если вследствие падения мощности сигнала одно длитель ное нажатие кнопки передатчика интерпретируется приемником, как не сколько кратковременных нажатий. В остальных проектах в этой главе мы будем кратковременно нажимать (отпускать) кнопку, что должно сделать проблему с перебоями в длительном нажатии менее серьезной.
БЕСПРОВОДНОЙ ДВЕРНОЙ ЗВОНОК Включение светодиода на расстоянии - не особо интересный проект даже с сопровождающими сообщениями о длительности его включения.
41 О Глава 15. Радиосвязь
Наш следующий проект с радиоканалом будет более полезным: беспровод ной дверной звонок. Имея такое устройство, вы сможете оснастить звонком входную дверь в свою спальню, комнату в общежитии или офис без необ ходимости пробивать отверстия в стенах, чтобы установить проводку для обычного дверного звонка. При желании можно проявить креативность с «кнопкой» звонка, т. е. радиопередатчиком, например, извлечь его печатную плату из стандартного корпуса и поместить ее в корпус, изготовленный по вашим требованиям.
Схема приемной стороны звонка Прежде всего нам нужно подключить к приемной стороне динамик или пьезозуммер. Поскольку устройство легче всего смонтировать на макет ной плате, сюда же целесообразно переместить и модуль радиоприемника. Подключите на его вход питания с платы Arduino, а контакт D2 соедините с желаемым контактом на плате Arduino. Если подключить его к контакту 13, то при поступлении сигнала будет включаться встроенный светодиод платы, не требуя от вас создания специального кода для реализации этой индика торной функции. Динамик или пьезозуммер нужно подключать к выходно му контакту платы Arduino через последовательный резистор номиналом
...... ..� ' .... . .... � .. .. .' .... .. .�.... . .� . .... . . . . . . . ., ., ♦ •
• • 8; ••
8} •
•
• ♦ •••
ф
• , •
"., • "t " .
J' н
:
• •
!
Рис. 15.7. Схема приемника беспроводного дверного звонка (рисунок создан в программе Fritzing)
Беспроводной дверной звонок 411
220 Ом, как мы это делали во всех предыдущих проектах с этими устрой ствами. Можно уменьшить номинал этого резистора до 150 Ом, чтобы полу чить более громкое звучание динамика. Готовая схема приемного устройства звонка должна выглядеть, как показано на рис. 15.7. Не забудьте подключить шину питания 5 В и шину земли платы Arduino к соответствующим шинам питания на макетной плате.
Программа для приемной стороны звонка Звучание звонка на приемной стороне создает плата Arduino. Она ожи дает, пока на приемник поступит сигнал нажатия кнопки с передатчика, и проигрывает какую-либо мелодию при получении такого сигнала. Чтобы обеспечить надежную работу нашего звонка, необходимо, чтобы, прежде всего он проигрывал мелодию только один раз при одном нажатии кнопки передатчика. Затем нужно, чтобы повторные нажатия кнопки не прерывали текущее проигрывание мелодии. Наконец, длительное удерживание кнопки не должно вызывать повторное или бесконечное воспроизведение мелодии. Скопируйте файл pitches.h из кода, который использовался в главе 6, в пап ку скетча дверного звонка. Для проигрывания подойдет та же самая мело дия, как и в проектах в главе 6. Данный файл также входит в состав кода для этой главы, который можно загрузить на веб-странице https://www. exploringarduino.com/content2/ch 15. В листинге 15.2 приведен полный код дверного звонка. Программа ожидает сигнала нажатия кнопки, проигрывает мелодию при получении такого сигна ла, а затем снова переходит в режим ожидания сигнала нажатия кнопки. Листинг 15.2. Программа doorbeШno дверного звонка с использованием простого радиоканала .......... .......... ...... ........ // Дверной звонок с использованием простого радиоканала // Предполагается использование радиоприемного модуля // с кратковременным режимом приема // Радиоприемник М4 этого типа функционирует подобно кнопке. // Когда на модуле радиопередатчика нажата кнопка, на контакте D2 // радиоприемника присутствует высокий уровень. // При отпущенной кнопке радиопередатчика на контакте D2 // присутствует низкий уровень. #incLude "pitches.h" // Заголовочный файл с определениями частот нот // Контакт ввода-вывода платы Arduino, подключенный к контакту D2 // модуля радиоприемника
412 Глава 15. Радиосвязь
const int TRIGGER_PIN = 13; const int SPEAKER = 9; // Контакт выходного сигнала,подаваемого 1,,1а динамик // Массив нот int notes[] = { NOTE_A4,NOTE_E3,NOTE_A4,О, NOTE_A4,NOTE_E3,NOTE_A4,О, NOTE_E4,NOTE_D4,NOTE_C4,NOTE_B4, NOTE_A4,NOTE_B4,NOTE_C4, NOTE_D4, NOTE_E4,NOTE_E3, NOTE_A4,О };
// Массив длительноаей звучания каждой ноты (в мс) int times[] = { 250,250,250,250, 250,250,250,250, 125,125,125,125, 125,125,125,125, 250,250,250,250 };
void setupQ { // Установка параметров не требуется } void loopQ { // При нажатии кнопки,проигрываем мелодию один раз if (digitalRead(ТRIGGER_PIN)) { for (int i = О; i < 20; i++) { tone(SPEAKER, notes[i],times[i]); delay(times[i]); } // Если по завершению проигрывания мелодии кнопка остается нажатой, // ждем,пока она не будет отпущена, // прежде чем проигрывать мелодию снова while(digitalRead(ТRIGGER_PIN)); } }
Первые шаги на пути к «умному» дому - управление светильником 413
Внутри главного цикла LoopQ состояние контакта TRIGGER_PIN проверяет ся условным оператором ifQ. Когда на этом контакте устанавливается высо кий уровень, цикл forO проигрывает по порядку ноты, содержащиеся в мас сиве notes[]. Перед выходом из оператора ifO в однострочном цикле whiLeO выполняется проверка состояния кнопки передатчика. Если кнопка все еще нажата, дальнейшее исполнение программы блокируется исполнением дан ного цикла. Таким образом предотвращается бесконечное проигрывание ме лодии, если по какой-либо причине кнопка остается в нажатом состоянии. Исполнение кода в главном цикле LoopQ не возобновляется до тех пор, пока кнопка не будет отпущена, после чего программа начинает ожидать новое нажатие кнопки. Примечание На веб-странице https://www.exploringarduino.com/content2/ch15 можно просмо треть видеоклип, демонстрирующий дверной звонок с использованием радиоканала в действии.
ПЕРВЫЕ ШАГИ НА ПУТИ К «УМНОМУ» ДОМУ УПРАВЛЕНИЕ СВЕТИЛЬНИКОМ Наверное, одной из самых захватывающих возможностей, предостав ляемых беспроводной технологией, является возможность объединять фи зические объекты при условии минимальной модификации инфраструкту ры. В следующих двух главах мы рассмотрим, как использовать радиосвязь Bluetooth и Wi-Fi для взаимодействия с платой Arduino. Но задолго до по явления этих технологий для реализации «умных» устройств применялись радиоканалы. Усовершенствуя наш проект беспроводного дверного звонка, добавим в его схему управляемое реле, которое может включать и выключать устрой ства с питанием от электросети. Таким образом можно легко создать, напри мер, ночной светильник, который можно включить или выключить не вста вая с кровати, или же облегчить использование настольной лампы с трудно доступным выключателем на проводе питания. Реле можно рассматривать как электрический включатель, которым можно управлять низковольтным логическим сигналом. Подача на реле сигнала напряжением 5 В вызывает замыкание его рабочих контактов, обеспечивая протекание тока через под ключенное устройство. Внимание! В этом разделе рассматривается, как управлять электрическим прибором, работающим от вашей домашней электрической сети напряжением 120 или 230 В. Если не соблюдать
414 Глава 15. Радиосвязь должную осторожность при работе с такими напряжениями, это может иметь очень опасные последствия, вплоть до смертельных. Применяйте только сертифицирован ные устройства, предназначенные для безопасной работы с нагрузками такого типа. Для проектов этой главы и последующих глав выбрано реле закрытого типа, специ ально предназначенное для этой цели, но рассчитанное только на напряжение 120 В электрической сети в Северной Америке. Не используйте это реле в странах, в которых напряжение электрической сети равно 230 В. Для этих стран на рынке имеются соот ветствующие устройства. В продаже есть шилды для Arduino, которые могут работать с такими напряжениями, но они не заключены в корпус. Если вы решите использовать один из таких шилдов, вы делаете это на собственный страх и риск. При работе с устрой ствами, подобными этим, всегда предпринимайте адекватные меры, чтобы не допустить оголения проводов, находящихся под высоким напряжением.
ПЕРЕДАЧА ЭЛЕКТРОЭНЕРГИИ В домашней электрической сети используется напряжение переменного тока. В отличие от напряжения постоянного тока, это напряжение меняет направление 50-60 раз в секунду (точная частота зависит от конкретной страны). Величина напряжения электрической сети также зависит от кон кретной страны. В странах Северной и Центральной Америки сетевое на пряжение находится в диапазоне от 11 О до 127 В (приблизительно 120 В), в Японии - 100 В, а в большинстве других стран мира - от 220 до 240 В (приблизительно 230 В). Некоторые устройства могут работать со всеми на пряжениями и частотами, например, зарядные устройства для мобильных телефонов или ноутбуков. Другие же устройства необходимо разрабаты вать под конкретное напряжение и/или частоту электросети. Например, щеточные электродвигатели переменного тока нужно проектировать под конкретное напряжение, поскольку скорость вращения непосредственно зависит от частоты и амплитуды напряжения питания. Переменное напряжение используется для питания бытовых устройств и при передаче электричества на большие расстояния, поскольку так более эффективно по сравнению с постоянным напряжением, а также потому, что его легко повысить и понизить с помощью трансформатора. Подробное рассмотрение физических принципов работы трансформатора выходит за рамки этой книги, но в общих чертах постоянная смена направления про текания переменного напряжения обеспечивает передачу электромагнит ной энергии с коэффициентом по напряжению, который можно определить по числу витков обмотки трансформатора. Вырабатываемое электростан циями электричество повышается трансформаторами до очень высокого напряжения (свыше 115 тысяч вольт) и передается по высоковольтным ли ниям. В месте назначения локальные подстанции и трансформаторы пони жают его обратно до напряжения 120 или 230 В, которое затем разводится по домам.
Первые шаги на пути к «умному» дому - управление светильником 415 Генерация, передача и расnредеnеиие зnектрознерrии Электростанция генерирует электричество
r,,;",:
По линиям лередачи электроэнергия лередается в район конечных потребителей По распределительным линиям электричество подается в дома
Трансформатор повышает напряжение для передачи
Трансформатор на подстанции понижает напряжение
Оконечный трансформатор понижает напряжение для подачи в дома
Рис. 15.8. Процесс передачи электроэнергии от электростанции конечным потребителям
Вспомним, что потребляемая мощность определяется, как произведение на пряжения на ток. Больший ток означает более высокую потребляемую мощ ность, рассеиваемую в виде тепла вследствие сопротивления линии электро передачи. Передача электричества с высоким напряжением и малым током позволяет уменьшить диаметр проводов линий электропередачи и снизить тепловые потери при передаче. В месте расположения конечных потреби телей высокое напряжение линий электропередачи понижается с помощью трансформатора, увеличивая ток и восстанавливая исходную мощность (за вычетом потерь в линии). На рис. 15.8 наглядно показан процесс передачи электроэнергии от электростанции конечным потребителям.
Электричество в доме и офисе С распределительных линий электричество подается конечным потреби телям по трем проводам: фазному, нейтрали (или нулевому) и заземления. Подобно постоянному току, для протекания переменного тока требуется замкнутая цепь. Фазный провод можно сравнить с шиной положительного напряжения постоянного тока, а нулевой - с шиной возврата (которая-так же называется цифровой землей). А провод заземления служит для защиты от поражения электрическим током и подключен к физической земле (зако панному в землю штырю или к водопроводным трубам) в распределительной коробке. Провод заземления устройства подключается к его металлическому корпусу. В случае неисправности прибора и замыкания сетевого напряжения пи тания на его корпус это напряжение отводится через провод заземления на физическую землю, поскольку этот провод предоставляет путь наименьше го сопротивления к самому низкому электрическому потенциалу, которым
416 Глава 15. Радиосвязь
является физическая земля. При отсутствии такого пути на землю через провод заземления электричество может найти такой путь t:Jepeз тело при коснувшегося к корпусу пользователя, в результате чего последний получит болезненный удар током, который в крайних случаях может быть даже смер тельным. Устройства, не оснащенные заземлением, должны иметь двойную изоляцию. Это значит, что высоковольтные компоненты должны быть изо лированы двумя слоями изоляции от любого компонента, к которому может прикоснуться пользователь. Например, двойная изоляция применяется в за рядных устройствах для мобильных телефонов. С другой стороны, шнур пи тания настольного компьютера снабжен шиной заземления, к которой под ключается металлический корпус компьютера. В разных странах употребляются разные цветовые маркировки проводов электропитания. Поскольку мы настоятельно рекомендуем реле закрытого типа, вам не нужно будет подключать никаких проводов электропитания. В США провод фазы обозначается черным цветом, нуля - белым, а зазем ления - зеленым. Однополюсные реле всегда должны переключать фазный провод, а не нулевой.
Принцип работы реле В этом проекте механическое реле управляет обычной лампочкой накали вания. Реле представляет собой электромагнитное устройство, позволяющее управлять нагрузками с высоким напряжением и/или током (например, лам почкой накаливания), по сигналу от низковольтного устройства (например, от платы Arduino ). На рынке предоставляется большой выбор реле разных размеров, рабочих характеристик и конфигураций. Одни реле фиксируются во включенном или выключенном положении. Другие могут одновременно переключать несколько сигналов или нагрузок. Третьи работают по прин ципу «размыкание после замыкания», когда новая нагрузка подключается к общему входу, прежде чем отключается предыдущая. Такие реле часто ис пользуются в телекоммуникационных системах. Для этого проекта нам по требуется реле IoT Power Relay компании Digital Loggers, Inc. Это реле уже за ключено в защитный корпус, содержащий все необходимые подключения и изолирующие и защитные электронные схемы. Данное однополюсное двух позиционное реле работает следующим образом: подача на его вход управления высокого логического уровня (5 В) под ключает общий (входной) контакт к клеммам, обозначенным «normally OFF» (нормально разомкнуто); подача низкого логического уровня (О В) на этот контакт отключает общий входной контакт от клемм «normally OFF» и подключает его к клеммам, обозначенным «normally ON» (нормально замкнуто).
■
■
Первые шаги на пути к «умному» дому - управление светильником 417
Рис. 15.9. Упрощенная коммутационная схема реле (Источник: компания Adafruit, https://www.ada fruit.com). Наложенное обозначение проводки добавлено автором)
Общий входной контакт реле подключается к линии фазы напряжения, которым управляет реле. На рис. 15.9 показана упрощенная коммутационная схема внутри этого реле. Все три провода линии электропитания (которые мы рассмотрели чуть ранее) подключаются к реле через силовой разъем; фаза обозначена черным цветом, нуль - белым, а заземление - серым. Провода нуля и заземления подключаются ко всем соответствующим контактам всех розеток, а провод фазы - к общему входному контакту однополюсного двухпозиционного реле. На рис. 15.9 на вход управления реле подается сигнал 5 В (высокого уровня). Это входное напряжение вызывает протекание тока через катуш ку реле. На самом деле входной сигнал управления включает транзистор ный оптрон, который в свою очередь обеспечивает протекание тока от на пряжения питания, создаваемого из питания электросети, через обмотку катушки реле. Протекание тока через обмотку катушки реле создает вокруг нее магнит ное поле, которое притягивает якорь с подвижным контактом, замыкая его на неподвижный контакт. Пока на входе управления сохраняется сигнал высокого уровня, рабочие контакты реле остаются замкнутыми, подавая
418 Глава 1 S. Радиосвязь
входное напряжение электросети на розетки, обозначенные «normally OFF» (нормально не разомкнуты). Когда с входа управления сигнал высокого уров ня снимается (или, иными словами, подается сигнал низкого уровня), про текание тока через обмотку катушки реле прекращается. В результате этого магнитное поле вокруг нее пропадает и якорь с подвижным контактом под воздействием пружины отходит от сердечника, размыкая его от неподвиж ного контакта, соединенного с розетками «normally OFF», и замыкая на кон такт, соединенный с розеткой «normally ON)). Розетки называются «normally ON/OFF>> (нормально замкнуто/разомкнуто) по их состоянию в нормальном состоянии (т. е. состоянии по умолчанию) входа управления, каковым явля ется отсутствие сигнала управления на нем (т. е. присутствие низкого уров ня). При работе реле можно даже слышать щелчки, создаваемые подвижным якорем при подаче и снятии сигнала управления.
Программа для управления реле Здесь не придется изобретать ничего нового, а нужно просто добавить в предыдущий скетч строку кода, которая переключает состояние выходного контакта. А при желании можно отслеживать состояние этого выходного контакта и проигрывать разные мелодии при включении и выключении светильника. Для этого необходимо добавить булеву переменную, значение которой меняется на обратное при каждом нажатии кнопки передатчика. Каждый раз при нажатии кнопки проигрывайте новую мелодию и пере ключайте на противоположный выходной сигнал на контакте управления светильником. Полный код для реализации всех этих модификаций при веден в листинге 15.3. Чтобы особо не усложнять себе задачу, он просто проигрывает ноты из массива нот в прямом порядке при включении све тильника, и в обратном - при его выключении. Это можно легко реали зовать с помощью цикла forO с инвертированной логикой счета. Оператор for (int i = О; i < 3; i++) запускает счетчик с нулевого начального значения и инкрементирует его с шагом 1 до 3, оператор for (int i = 2; i >= О; i-) запускает счетчик с начального значения 2 и декрементирует его с шагом 1 до нуля. Таким образом мы можем проигрывать ноты в массиве notes[] в обратном порядке. Листинг 15.3. Программа :Lamp_remote.ino для дистанционного управления светильником через радиоканал // Дистанционное управление светильником // Предполагается использование радиоприемного модуля // с кратковременным режимом приема
Первые шаги на пути к «умному» дому - управление светильником 419 // Радиоприемник М4 этого типа функционирует подобно кнопке. // Когда на модуле радиопереда�ика нажата кнопка, на контакте D2 // радиоприемника присутствует высокий уровень. // При отпущенной кнопке на радиопереда�ике на контакте D2 // присутствует низкий уровень. #iпcLude "pitches.h"
// Заголовочный файл с определениями частот нот
// Контакт ввода-вывода платы Arduiпo,подключенный к контакту D2 // модуля радиоприемника // Контакт, на который подается входной сигнал const int TRIGGER_PIN = 13; // с модуля радиоприемника // Контакт выходного сигнала, const int SPEAKER = 9; // подаваемого на динамик // Контакт для управления реле светильника const int LAMP = 2; // Массив нот int notes[] = {NOTE_E3, NOTE_A4, NOTE_C5}; // Массив длительностей звучания каждой ноты (в мс) int times[] = {250,250,250}; // Состояние лампы по умолчанию выключенное booL Lamp_on = faLse; void setup0
{
pinMode(LAMP, OUTPUТ); digitaLWrite(LAMP, Lamp_on);
// Контакт управления реле светильника // в режим выхода // Выключаем светильник // (исходное значение этой переменной - faLse)
} void Loop0 { // При нажатии кнопки меняем состояние светильника на обратное if (digitaLRead(ТRIGGER_PIN))
{
// Инвертируем состояние переменной // управления светильником digitaLWrite(LAMP, Lamp_on); //Устанавливаем новое // состояние светильника Lamp_on = !Lamp_on;
420 Глава 15. Радиосвязь // Проигрываем разные мелодии в зависимости от того, // включается светильник или выключается if (Lamp_on) {
// Проигрываем мелодию для включения светильника for (int i = О; i < 3; i++) {
tone(SPEAKER, notes[i], times[i]); detay(times[i]);
} } etse {
// Проигрываем мелодию для выключения светильника // (те же ноты, только в обратном порядке) for (int i = 2; i >= О; i--) {
tone(SPEAKER, notes[i], times[i]); detay(times[i]);
} } // Если по завершению проигрывания мелодии кнопка остается нажатой, // ждем здесь. Это, по сути, удаляет дребезг кнопки передатчика. white(digitaLRead(ТRIGGER_PIN)); } }
Загрузите этот код в свою плату Arduino, а затем перейдите к следующе му разделу, в котором мы подключим реле управления светильником в нашу предыдущую схему.
Подключение реле управления светильником к Arduino Теперь нам осталось только подключить реле к нашей плате Arduino и к электросети. Убедившись, что кабель питания реле отключен от электро сети, извлеките из корпуса реле контактный разъем зеленого цвета. Ослабьте винты на контактах разъема, вставьте в них проволочные перемычки и снова затяните винты. Вставьте разъем обратно в корпус реле. Подключите пере мычку от положительного контакта разъема к контакту 2 платы Arduino, а отрицательного - к шине земли платы. Для питания платы Arduino отключите ее от компьютера после загрузки программы и подключите к сетевому адаптеру, который вставьте в розетку
Первые шаги на пути к «умному» дому -управление светильником 421
реле, обозначенную «always ON» (всегда замкнуто). Затем вставьте вилку шнура питания реле в сетевую розетку и включите реле. Наконец, вставьте вилку шнура питания управляемого светильника в одну из розеток на реле, обозначенных «normally OFF>> (нормально разомкнуто). Если у светильника есть выключатель, включите его. Собранная схема должна выглядеть, как по казано на рис. 15.10.
Рис. 15.10. Подключение светильника к плате Arduino через реле
Теперь все готово для дистанционного управления светильником. Нажа тие кнопки на передатчике должно включить светильник и запустить про игрывание мелодии платой Arduino. А повторное нажатие кнопки должно выключить светильник и запустить проигрывание другой мелодии. Примечание На веб-странице https://www.exploringarduino.com/content2/ch15 можно просмо треть демонстрационный видеоклип дистанционного управления светильником через радиоканал с помощью реле.
422 Глава 15. Радиосвязь
РЕЗЮМЕ В этой главе мы узнали следующее. :) Как данные можно передавать и принимать по радио, модулируя ими несущую волну. :) Что для разных типов радиопередач выделены только определенные частоты, точное значение которых зависит от конкретной страны. :) Как управлять простыми функциями платы Arduino, передавая по радио данные о нажатии кнопки. :) Как создать дверной звонок, принимая нажатия кнопки на передатчи ке и активируя проигрывание мелодии платой Arduino. :) Что бытовые устройства питаются электричеством переменного тока. :) Как с помощью реле включать высоковольтные устройства по сигналу от низковольтного устройства типа микроконтроллера. :) Как с помощью передатчика с кнопкой, модуля радиоприемника, пла ты Arduino и реле дистанционно управлять бытовым светильником.
Беспроводная связь Bluetooth
16
Список деталей и оборудования для проектов этой главы :> Плата Feather 32u4 Bluefruit LE (с впаянными разъемами) (1 шт.). :> USВ-кабель (тип А на Micro-B) (1 шт.). :> Беспаечная макетная плата половинного или полного размера (1 шт.). :> Набор проволочных перемычек. :> Резистор номиналом 220 Ом (1 шт.). :> Подстроечный потенциометр номиналом 10 кОм (или другой аналоговый датчик по вашему выбору) (1 шт.). :> Светодиод красный диаметром 5 мм (1 шт.). :> Сетевой адаптер, 5 В, 1 А, выходной USВ-разъем (1 шт.). :> Модуль управляемого силового реле (реле IoT Power Relay от компании Digital Loggers, Inc.) (1 шт.). :> Лампочка с сетевым питанием (1 шт.). :> Небольшая отвертка (1 шт.). :> Смартфон с возможностями BTLE (iPhone или Android) (1 шт.). Исходный код и прочие электронные ресурсы • Исходный код, видеоуроки и прочие электронные ресурсы для этой главы можно загрузить с веб-страницы https://www.exploringarduino. com/content2/chl 6. • Исходный код для проектов этой главы можно также загрузить на вкладке Downloads веб-страницы издательства Wiley для этой книги: https://www.wiley.com/go/exploringarduino2e.
с
ЧТО ВЫ УЗНАЕТЕ ИЗ ЭТОЙ ГЛАВЫ
корее всего, вам очень быстро надоело передавать через простой радио канал своей плате Arduino по одному биту информации за раз. Как мы знаем из опыта работы с ноутбуком, смартфоном или устройствами IoT, при наличии радиосвязи другого типа возможности могут быть намного большими. В этой главе мы рассмотрим радиосвязь Bluetooth, которая яв ляется наиболее распространенным стандартом беспроводной связи в мире. Разные варианты Bluetooth используются в гарнитурах, клавиатурах, мышах, компьютерах, смартфонах, радиомаяках и т.п.
424 Глава 16. Беспроводная связь Bluetooth
ЧТО ТАКОЕ BLUETOOTH? В последнее время термин Bluetooth начали широко применять ( часто не правильно) для описания любой беспроводной связи малого радиуса дей ствия между двумя узлами. В действительности разная реализация Вluetooth для различных типов устройств предусматривалась с самого начала. Это обстоятельство часто создает путаницу, когда говорят, что какое-либо устройство поддерживает Bluetooth. Поэтому, прежде чем рассматривать разработку программного обеспечения для Bluetooth, полезно ознакомить ся с разными версиями и профилями Bluetooth, а также с соответствующей терминологией.
Стандарты и версии Bluetooth Исходный стандарт Bluetooth (IEEE 802.15.1) был создан институтом IEEE (Institute of Electrical and Electronics Engineers - Институт инженеров по электротехнике и радиоэлектронике США); в настоящее время эта техноло гия находится в ведении специальной группы SIG Bluetooth. Примечание
Стандарт Bluetooth - только один из стандартов, разработанных и поддерживаемых институтом IEEE. В ведении этого института находятся также другие технологии, с ко торыми вам, возможно, приходилось встречаться: Wi-Fi (IEEE 802.11); РоЕ (Power over Ethernet - питание через Ethernet, IEEE 802.3); стандарт POSIX, являющийся основой для обеспечения совместимости между разными версиями операционной системы UNIX (IEEE 1003); FireWire (IEEE 1394) и многие другие.
Спецификация Bluetooth прошла через несколько этапов развития, когда шаг за шагом добавлялись новые возможности и улучшения. Первая версия, выпущенная в 1998 г., была в основном направлена на обеспечение беспро водной альтернативы проводным каналам последовательной связи (таким же каналам последовательной связи, как и те, которые мы использовали в предыдущих главах для передачи сообщений с платы Arduino на компью тер.) В вышедшей в 2004 г. версии Bluetooth 2.0 была добавлена возможность более высокой скорости передачи данных, что проложило дорогу Bluetooth в качестве цифрового канала для передачи аудио (возможно, наиболее зна комое вам применение Bluetooth). Если вам когда-либо приходилось испы тывать трудности, пытаясь выполнить сопряжение гарнитуры Bluetooth со своим смартфоном, то, возможно, вам будет легче, если узнаете, что трудно сти испытывали не только вы. Исходная спецификация не содержала явной поддержки потокового аудио, поэтому интегрирование этой возможности в спецификации Bluetooth, а также в радиоустройства и процессоры, со храняя при этом обратную совместимость, было для группы Bluetooth SIG
Что такое Bluetooth? 425
задачей не из легких. С выходом версии Bluetooth 2.0 в 2004 r. и версии 3.0 в 2009 r. стали популярными гарнитуры, избавляющие пользователя от не обходимости держать телефон в руках при разговоре, поскольку все больше сотовых телефонов оснащались встроенными радиоканалами Bluetooth. Но, наверное, самая главная модификация в Bluetooth была внесена в 2013 r. В версии Bluetooth 4.0 была добавлена функциональность BTLE (Bluetooth Low Energy - Bluetooth с низким энергопотреблением), которую иногда называют по ее маркетинговому названию - Bluetooth Smart. Это нововведение было особенно важным, поскольку оно, по сути, разделило спецификацию Bluetooth на две отдельные реализации: Bluetooth Classic и Bluetooth Low Energy. Реализация Bluetooth Classic обратно совместима со всеми предыдущими версиями, поддерживает более высокую скорость передачи данных, предо ставляет поддержку различным широкополосным профилям (для потоково го аудио), но при всем этом имеет более высокое энергопотребление. А реа лизация Bluetooth Low Energy отличается значительно более низким энер гопотреблением и прямо предназначена для поддержки простых устройств с питанием от батарей, для которых требуется минимальная полоса про пускания для передачи данных. В качестве примера устройств BTLE можно назвать кардиотахометры, датчики состояния окружающей среды, пульты дистанционного управления «умным» домом и многие другие. Эти устрой ства передают не потоковые данные мультимедиа, а короткие пачки простых данных, находясь в режиме сна все остальное время. Как классический Bluetooth, так и BTLE работают в радиочастотном диа пазоне 2,4-2,5 ГГц, выделенном для радиосвязи ISM. Микросхемы Bluetooth могут реализовать поддержку как обоих разновидностей Bluetooth (Classic и BTLE), так и только BTLE. Смартфоны поддерживают обе эти реализа ции Bluetooth, что позволяет им взаимодействовать как с беспроводными гарнитурами, использующими классические аудиопрофили Bluetooth, так и с более простыми устройствами с возможностями только BTLE, как, на пример, кардиотахометры. Микросхема Bluetooth, которую мы будем ис пользовать в наших проектах с Arduino в этой главе, реализует поддержку только BTLE.
Профили Bluetooth и служба GATT BTLE Чтобы разобраться для чего нужны профили Bluetooth, прибегнем к ана логии с использованием Интернета. Физическое подключение компьютера к Интернету осуществляется через поставщика услуг сети Интернет. Между сетью поставщика и вашим компьютером находится модем, маршрутизатор (в большинстве случаев), далее проводной Ethernet-кaнaл или беспровод ной Wi-Fi-кaнaл между компьютером и маршрутизатором. Этот комплекс
426 Глава 16. Беспроводная связь Bluetooth
оборудования определяет физическое подключение к Интернету, но способ передачи данных по этому каналу зависит от выполняемой задачи. Для выполнения разных задач, компьютеру потребуются службы, систе мы и протоколы, расположенные поверх этой сети. Например, служба DNS позволяет компьютеру сопоставлять IР-адреса с удобочитаемыми адреса ми URL; протокол HTTPS - безопасно загружать веб-страницы в браузер; протокол FTP - обмениваться файлами с удаленным сервером; а протокол SMTP - отправлять сообщения электронной почты. Профили Вluetooth по добны этим службам и протоколам Интернета - они представляют собой разные средства для обмена разной информацией по одному и тому же физи ческому каналу. До тех пор, пока обе стороны «понимают» общий профиль, они могут общаться друг с другом. Поддерживаемые профили зависят от конкретного устройства. Например, наушники Bluetooth будут, скорее всего, поддерживать профиль A2DP (Advanced A udio Distribution Profile - расширенный профиль распростране ния аудио) для приема потокового аудио, но, наверное, не будут поддержи вать профиль FTP (File Transfer Protocol - протокол передачи файлов). При установлении подключения между двумя устройствами Bluetooth они сооб щают друг другу, какие профили поддерживают. Этим объясняется, почему ваш телефон «знает», что он может проигрывать музыку через наушники в то же самое время «понимает», что он не может делать это через дверной звонок с возможностями Bluetooth. Реализации BTLE главным образом предназна чены для поддержки общих атрибутов GATT (Generic A ttributes - общие атрибуты) у специфичного профиля. Профиль GATT используется для опре деления структуры данных для обмена информацией между двумя устрой ствами с возможностями BTLE. Тогда как профиль типа A2DP обеспечивает передачу потокового аудио в одном направлении, службы GATT предусма тривают передачу пакетов данных, отформатированных особым образом. Они оптимизированы для передачи небольшого объема информации в тече ние короткого интервала времени. Существует предопределенный список служб GATT, созданный группой Bluetooth SIG, но пользователи также могут создавать свою собственную службу GATT. В число предопределенных служб GATT входят, например, служба мониторинга кровяного давления, служба отслеживания заряда ба тареи и служба мониторинга окружающей среды. Компания Nordic Semiconductor, чей радиомодуль BTLE понадобится нам в этой главе, реализовала простую службу эмуляции УАПП, исполняющую ся поверх BTLE. Мы будем использовать эту предопределенную службу GATT для обмена данными между платой A rduino и смартфоном. Этот проект бу дет похож на проекты последовательной связи, с которыми мы уже работали в этой книге.
Установка связи между платой Arduino и смартфоном 427
УСТАНОВКА СВЯЗИ МЕЖДУ ПЛАТОЙ ARDUINO И СМАРТФОНОМ Разобравшись с основными принципами работы Вluetooth, можно при ступать к установке подключения между нашей платой Arduino с возможно стями BTLE и смартфоном. В проектах этой главы используется плата Feather 32U4 Вluefruit LE, выпускаемая компанией Adafruit. На рынке предлагается большое количество устройств BTLE, совместимых с Arduino, но компа ния Adafruit предоставляет одни из лучших библиотек и учебные пособия. Обозначение 32U4 должно быть вам знакомо по нашей предыдущей работе с платой Arduino Leonardo. Это такой же микроконтроллер производства компании Atmel/Microchip, который установлен на плате Leonardo, в большой мере совместимой с Feather, используемой в этой главе. Но между этими платами есть одно важ ное различие: плата Feather работает с логическими уровнями напряжением 3,3 В. Иными словами, для этой платы высоким логическим уровнем явля ется напряжение 3,3 В, а не 5 В, как для платы Leonardo. Чтобы подключить к этой плате датчики или периферийные устройства с высоким логическим уровнем 5 В, нужно осуществить пре образование уровней, или же просто •• выбрать устройства с рабочим напря •• жением 3,3 В. Плата Feather - это, по сути, просто плата Arduino на микро контроллере 32U4, объединенная с мо дулем BTLE в конструкции. В действи тельности такая компоновка ничем не отличается от платы Arduino с подклю ченным шилдом BTLE, но обеспечивает более компактное решение благодаря размещению обоих элементов на одной печатной плате.
Считывание датчика через канал BTLE Для начала возьмем самый простой датчик - потенциометр. Подключите его к плате Feather, как показано на монтажной схеме на рис. 16.1. В частно сти, внешние контакты потенциометра подключаются к шинам 3,3 В и земли
Рис. 16. 1. Плата Feather BTLE с подключенным к ней потенциометром (рисунок создан в программе Fritzing)
428 Глава 16. Беспроводная связь Bluetooth
макетной платы, а средний контакт - к контакту АО платы Feather. Мы запрограммируем нашу плату Arduino для передачи значения вьIХодного сиг нала этого потенциометра по каналу BTLE.
Подключение в среде Arduino IDE поддержки плат сторонних производителей Мы уже рассмотрели, как подключать новые библиотеки к стандартным средствам среды Arduino IDE. Но теперь мы впервые используем оборудова ние, которое не было непосредственно разработано организацией Arduino и не является совместимым клоном оригинальной платы Arduino. Платы Feather компании Adafruit совместимы с платформой Arduino в том смысле, что их можно программировать с помощью среды Arduino IDE, использовать с ними библиотеки Arduino, и к ним можно подключать любое оборудование, которое будет работать с оригинальными платами Arduino. Но чтобы среда Arduino IDE могла компилировать код для этой платы, в нее нужно добавить соответствующую поддержку. В прошлом организовать такую поддержку было намного труднее, но но вые версии среды Arduino IDE значительно облегчили этот процесс, реали зовав возможность автоматического добавления всех необходимых файлов для поддержки оборудования сторонних разработчиков. В среде Arduino IDE выполните последовательность команд меню File > Preferences (Файл> Настройки). Внизу открывшегося окна Preferences (Настройки) найди те поле, обозначенное Additional Boards Manager URLs (Дополнительные ссылки для Менеджера плат). Введите в это поле следующий адрес URL: https://adafruit.github.io/arduino-board-index/package_adafruit_index.json (рис. 16.2). Обратите внимание, что на рисунке начало этого адреса URL об резано, поскольку он не вмещается полностью в поле. Но вам нужно вста вить полностью весь адрес URL. Нажмите кнопку ОК. Это даст указание среде Arduino IDE отправить за прос по данному адресу URL, а затем добавить список плат, полученных в от вет на запрос, к перечню плат, для которых можно устанавливать поддержку. Теперь выполните последовательность команд меню Tools > Board: «ХХХХ>> > Boards Manager (Инструменты > Плата: «ХХХХ» > Менеджер плат), где «ХХХХ» означает текущую выбранную плату. В открывшемся окне Boards Manager (Менеджер плат) измените значение в выпадающем списке поля Туре с All (Все) на Contributed (Внесены) и введите AVR в поле поиска (рис. 16.3). В результатах поиска будет только один элемент - Adafruit AVR Boards. Нажмите кнопку Install, чтобы установить поддержку для этих плат. Потом закройте окно менеджера плат, а затем и саму среду Arduino IDE. Наконец, для систем под Windows может потребоваться установить драйверы для платы Feather. Этот шаг можно пропустить для других
Установка связи между платой Arduino и смартфоном 429 .\ \. Set!Jngs Nelwork
.
' ,
,
.
.
.
.
.,
v
(requlres restart of Arduino)
SketchЬook locallon:
i Вrowse, ,
_D:\()ocuments\Ardulno Editor language: Editor font slze:
14
Interface scale:
121 Autornatlc
Theme:
��
Show verЬoSI! output dur1ng: Compiler wamlngs:
100 : '\1,
(requlres restart of Arduino)
(requlres restart of Ardulno)
О compllat!on О upload Oefault v
121 Display line numЬers
О EnaЬle Code Folding
121 Ver1fy code after upload
О Use external edltor
121 Aggresslvely cache compiled core 121 O\edc for updates on startup 121 Update sketch flles to new extenslon on save (,pda -> .lno) 121 Save when ver1fying or uploadlng
--------------------�
Additlonal Вoards Manager URLs: r//adafruit.glthub.io/arduino-lюard-lndex/padcag; �fruiLindex.Jso�
t:I,
More p,efer,nces can Ье edited diredJy in the file C:\Users\]eremy Вlum\AppOata\Local\Arduino 1 S\p1eferer,ces.Ьrt (edit only when Arduino ls not runnlng) гок
Cancel
Рис. 16.2. Окно Preferences среды Arduino IDE с добавленным адресом URL для поддержки плат Feather
Туре f!1tr1Ьuted Aclafruit AVR lloards Ьу Adafruit 8o•rds induded in this packoge: Adafn.,it Floni, Adafruit Gemma 8MHz, Adaf,1,11t Вfuefruit Мic.ro, Ad.afruit Feather 32u4, Adafruit Мetro, Adafruit Меио Мint, Ad,1fruit Itsy6itsy 32u4, Adafru;t Pro Trinket 5V/1бMHz (USB), Adafru;t Pro Trinket ЗV/lZMHz (USB), Adafмt Pro Tnnket 5V/16MHz (FТOf), Ad•fмt Pro Trinket ЗV/12МНz (FТDI), Adafruit Tmket 8МНz, Adofru� Tnnket lбМНz. 1.◄.13
V
Jnst,11
... 1
1 1 1
(
а�]
Рис. 16.3. Добавление поддержки плат Adafruit в окне Boards Manager (Менеджер плат) среды Arduino IDE
430 Глава 1 б. Беспроводная связь Bluetooth
операционных систем. Компания Adafruit предоставляет удобный уста новщик драйверов, который можно загрузить по адресу Ьlum.fyi/adafruit windows-drivers. Следуйте инструкциям, чтобы выполнить установку (мож но установить все опции). После инсталляции драйверов снова запустите среду Arduino IDE, выполните последовательность команд меню Tools > Board (Инструменты> Плата) и выберите из предоставленного списка плат опцию Adafruit Feather 32U4.
Установка библиотеки для модуля BTLE Теперь все готово для программирования нашей платы Feather. Подключите ее к компьютеру через USВ-кабель, убедитесь, что она отобра жается в списке портов Tools> Port и выберите ее. Плата Feather содержит два микроконтроллера, установленных на общей печатной плате. Модуль Nordic BTLE (в частности, микросхема nRFS, которую компания Adafruit называет Bluefruit) отвечает за обеспечение интерфейса BTLE. Он содер жит свое собственное микропрограммное обеспечение, исполняющее раз личные службы BTLE (включая службу GATT эмуляции последовательного канала, которую мы вскоре будем использовать). Данный модуль BTLE под ключен к микроконтроллеру 32U4 (являющемуся, по сути, частью Arduino платы) через интерфейс SPI. Обмен команд между модулями 32U4 и BTLE осуществляется с помощью библиотеки Adafruit nRFS, предоставляемой компанией Adafruit. Установим эту библиотеку так же, как мы делали в главе 11. В частности, выполните последовательность команд меню Arduino IDE Sketch> Include Library> Manage Libraries (Скетч > Подключить библиотеку> Управлять библиотеками). В открывшемся окне управления библиотеками выполните поиск библиотеки Adafruit BLuefruitLE nRFS и установите ее. После этого ее функции будут доступны для взаимодействия с модулем nRFS l BTLE, встро енным в плату Feather.
Программирование платы Feather В процессе разработки программ для платы Feather полезно рассматри вать ее как два отдельных компонента: модуль Arduino и модуль BTLE. Нам нужно беспокоиться только о создании программ для компонента Arduino. Модуль BTLE уже исполняет микропрограммное обеспечение, которое ожидает поступления команд через шину SPI, посредством которой модуль BTLE соединен с модулем Arduino. Цели нашей первой программы для платы Feather следующие: 1. Подключиться к модулю BTLE. 2. Удостовериться в правильном приеме модулем BTLE наших команд.
Установка связи между платой Arduino и смартфоном 431
3. Выполнить сброс модуля BTLE в его состояние по умолчанию и при своить ему пользовательский широковещательный идентификатор (который будет отображаться на смартфоне при установлении подклю чения к плате). 4. Подключиться к смартфону. 5. После подключения смартфона начать передавать значение выходного сигнала потенциометра с максимально возможной скоростью. Чтобы подключиться к модулю, в программу необходимо импортиро вать библиотеку Adafruit BTLE SPI и создать объект btLe. Модуль BTLE пла ты Feather с микроконтроллером 32U4 подключен к контактам SPI модуля Arduino, и его контакты выбора ведомого, прерывания и сброса подключены к контактам 8, 7 и 4 микроконтроллера 32U4. При инициализации модуля BTLE ему в арrументах необходимо передать эти номера контактов. Номера этих контактов не запрограммированы жестко в библиотеке, поскольку она может использоваться и с отдельным модулем BTLE, также предоставляемым компанией Adafruit. Поскольку номера этих контактов можно менять, в слу чае подключения внешнего модуля BTLE к отдельной плате Arduino можно работать с той же самой библиотекой без необходимости модифицировать ее. Код для импортирования библиотеки и создания экземпляра объекта приведен в листинге 16.1. Листинг 16.1. Имnортирование библиотеки Adafruit
. . . . . . . . . . ... . , . , . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ................. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ... . . . . . . ............................. . ......... .
// Подключаем библиотеку Adafruit nRFS #incLude "Adafruit_BLuefruitLE_SPl.h" // Микросхема nRFS1 на плате 32U4 Feather подключена // к микроконтроллеру 32U4 через контакты SPI. // При создании экземпляра объекта BTLE указываются контакты, // используемые для выбора ведомого CS (8), // прерывания IRQ (7) и сброса RST (4): Adafruit_BLuefruitLE_SPI btLe(8, 7, 4);
Наша следующая цель - подключение к модулю BTLE и проверка его реа гирования на команды. Библиотека BTLE содержит встроенную функцию beginO, которая конфиrурирует модуль для получения команд по интерфейсу SPI. Создав объект btLe библиотеки Adafruit_BLuefruitLE_SPI, функция beginO вызывается для этого объекта в секции setupQ: btLe.beginQ; Функция beginO возвращает булево значение, указывающее, смог ли мо
дуль Arduino выполнить успешную инициализацию модуля BTLE. Этим об стоятельством можно воспользоваться, обернув эту функцию в оператор
432 Глава 16. Беспроводная связь Bluetooth
условия ifO, который будет останавливать исполнение программы в случае неуспешной инициализации. Причиной неуспешной инициализации могут быть, например, неправильно указанные номера контактов при создании объекта. Поскольку язык Arduino не содержит явной функции для прекраще ния дальнейшего исполнения кода, эта задача решается косвенно путем пере вода исполнения в бесконечный цикл white(1) как показано в листинге 16.2. Листинr 16.2. Инициализация модуля BTLE . . . . . . . . . . . . . . . · · · · · · · · · · · · · · · •"' " ' ' " " ' ' '' " ' ' ' " ....... ··············••····•····
· · · · · · · • · · · · · · · · · · • • · · · • • · · · · · ·· · · · · ·· ·· · · · · · · · · · · · · · · •
// Подключаемся к модулю BTLE Serial.print(F("lnitializing BTLE Module...")); // Инициализируем модуль BTLE... if (!btle.beginO) {
SeriaL.printLn(" "); SeriaL.printLn(F("CouLdn't connect to nRFS1 ModuLe.")); // Не удалось подключиться к модулю nRFS1. whiLe(1);
} SeriaL.printLn(F("Ready!"));
Для этого фрагмента кода предполагается предварительная инициали зация последовательного интерфейса для вывода отладочных сообщений в окно программы монитора порта, исполняющейся на подключенном ком пьютере. Если функция beginO возвращает значение fatse (ложь), то в окно монитора порта выводится соответствующее сообщение об ошибке и даль нейшее исполнение программы прекращается. Третья цель нашей программы - выполнение сброса модуля BTLE в его состояние по умолчанию и присвоение ему пользовательского имени. В дей ствительности, это не нужно делать при каждом запуске программы, посколь ку после присвоения модулю нового имени и его перезапуска это имя сохра няется в ·энергонезависимой памяти (иными словами, оно сохраняется даже при выключении питания). Но не будет никакого вреда, если устанавливать его при каждом запуске программы. То же самое касается сброса до фабрич ных настроек. Эта операция необходима только в том случае, если есть подо зрение, что какое-либо из последних изменений конфигурационных настро ек вызывает неправильную работу модуля. Тем не менее выполнение сброса до настроек по умолчанию при каждом запуске программы гарантирует, что система всегда будет запускаться в одном и том же состоянии. Это полезно и для отладочных целей, если в будущем в программу будут добавлены более сложные возможности. Сброс модуля к заводским настройкам выполняется с помощью соответствующей встроенной функции: btLe.factoryResetO
Установка связи между платой Arduino и смартфоном Процесс присвоения имени устройству несколько иной, требующий ис пользования команды АТ. Сокращение АТ означает Attention (Внимание) и обозначает специальные команды, подаваемые устройству модема (в данном случае модему Bluetooth), которые устройство должно интерпретировать по иному, чем обычные входящие данные. Все получаемые устройством модема данные передаются ему по одному интерфейсу связи (которым в случае пла ты Feather является интерфейс SPI). Добавляя к данным, предназначенным для изменения внутренних настроек модема Bluetooth, префикс АТ, мы ука зываем модему, что следующие за этим префиксом данные нужно интерпре тировать как команду ему самому (а не данные, которые он должен передать удаленному устройству). Широковещательное имя модема Bluetooth изменя ется с помощью строки команды АТ + GAPDEVNAME. Далее приведен соответ ствующий код: btLe.print("AT+GAPDEVNAME="); btLe.printLn("Jeremy's Sensor"); В первой строке задается команда АТ, а второй - параметр для этой команды. В данном случае устройству присвоено имя «Jeremy's Sensor». Подобно процессу инициализации модема, процедуры его сброса и переиме нования можно обернуть в оператор условия if0, чтобы обеспечить их правиль ный прием и интерпретацию модулем Bluetooth, как показано в листинге 16.3. Листинг 16.3. Сброс модема BLuetooth
// Сброс модема к заводским настройкам Serialprint(F("Resetting to DefauLts...")); // Сбрасываем модем // к заводским настройкам if (!btLe.factoryReset0) {
SeriaL.printLn( " "); SeriaL.printLn(F("CouLdn't reset moduLe.")); // Не удалось выполнить // сброс модуля whiLe(l); }
SeriaL.printLn(F("Done!")); // Готово!
// Задаем широковещательное имя, используя команду АТ SeriaL.print(F("Setting Device name...")); // Задаем имя модема... btLe.print("AT+GAPDEVNAME="); btLe.printLn("Jeremy's Sensor"); if (!btLe.waitForOKO) {
SeriaL.printLn(F("CouLd not set name."));
// Не удалось задать имя.
33
434 Глава 16. Беспроводная связь Bluetooth while(l); } btle.resetQ; // Перезапускаем модуль, чтобы изменения ваупили в силу Serial.println(F("Done!"));
Вспомним, что неменяющиеся (статические) строки можно обволакивать в модификатор F0, чтобы сохранять их во флэш-памяти, а не в памяти RAM микроконтроллера. Функция waitForOK0 возвращает значение true (истина) только в том случае, если модуль Bluetooth подтверждает получение действи тельной команды. Например, если допустить ошибку и вместо GAPDEVNAME ввести GAPDIVNAME, модуль не распознает эту команду и функция waitForOK0 возвратит значение false (ложь). После задания устройству широковеща тельного имени подается команда reset0, которая выполняет сброс модуля Bluetooth, сохраняя новое имя в энергонезависимой памяти. Завершив конфигурирование модуля BTLE, можно приступать к разра ботке кода главного цикла loopQ. В каждой итерации этого цикла программа должна подтверждать, что смартфон все еще подключен к модулю, считать значение выходящего сигнала аналогового датчика, а затем передать это зна чение подключенному смартфону. Если смартфон не подключен к модулю, то программа должна приостановить считывание выходного сигнала датчи ка и ожидать подключения смартфона, прежде чем возобновлять итерации цикла. Проверка подключения смартфона к модулю Bluetooth осуществляет ся с помощью функции isConnected0. Если эта функция возвращает значение false (ложь), то начинает исполняться цикл ожидания. В противном случае может продолжаться исполнение кода главного цикла (листинг 16.4). Листинr 16.4. Главный цикл проrраммы .......... . . . . . . . . . . . . .............. . . . . . . . . . . . . . . . . . . . . .... . . . ........
································•·
.. · · · · ···················•·····•·· ,
// Ожидаем подключения смартфона, если еще не подключен if (!btle.isConnectedQ) { Serial.print("Waiting to connect to а smartphone .. ."); // Ожидаем подключения смартфона... while (!btle.isConnectedQ) { delay(l000); } Serial.println("Connected!"); // Подключились }
В последней части программы выполняется передача данных. Считываем выходной �.ннал аналогового датчика таким же образом, как мы это дела-
Установка связи между платой Arduino и смартфоном 435
ли много раз до этого. Затем отправляем полученное значение на модуль Bluetooth, используя функцию println0 с объектом btle вместо объекта serial. После каждой строки, отправляемой на модуль Bluetooth, можно вызвать функцию waitForOK0, чтобы подтвердить успешное получение модулем дан ных и их дальнейшую передачу по радиоканалу: // Считываем значение выходного сигнала потенциометра int val = analogRead(POT); // Отправляем данные модулю BTLE для дальнейшей передачи по радиоканалу btle.println(vat); // Ждем подтверждения получения данных от модуля BTLE btte.waitForOKQ;
Теперь нам нужно только сложить все эти фрагменты кода вместе, чтобы получить функциональную программу, которая выполняет конфигурирова ния модуля Bluetooth и начинает считывать и передавать значение выходно го сигнала аналогового датчика. Полный текст такой программы с добавлен ным кодом для вывода отладочных сообщений и мигания светодиода при веден в листинге 16.5. Листинг 16.5. Программа ВТLE_sensor.ino для передачи данных аналогового датчика по каналу BTLE // Передает полученные с аналогового датчика данные по каналу BTLE // Подключаем библиотеку nRFS1 SPI #inctude "Adafruit_BluefruitLE_SPl.h" // Микросхема nRFS1 на плате 32U4 Feather подключена // к микроконтроллеру 32U4 через контакты SPI. // При создании экземпляра объекта BTLE указываются контакты, используемые // для выбора ведомого CS (8), прерывания IRQ (7) и сброса RST (4): Adafruit_BluefruitLE_SPI btte(8, 7, 4); // Задаем данной булевой переменной значение true (истина) // для одноразовой конфигурации. // Данная процедура выполняет сброс до заводских настроек, // а затем изменяет широковещательное имя модуля BTLE. // Не будет никакого вреда, если выполнять эту процедуру // при каждом запуске программы (оставьте значение переменной true). // Альтернативно можно ограничиться одноразовым // исполнением процедуры настройки. В таком случае задайте // булевой переменной значение fatse после первой настройки. const bool PERFORM_CONFIGURATION = true;
436 Глава 16. Беспроводная связь Bluetooth // Имя, под которым устройство BTLE будет представлять себя смартфону const String BTLE_NAME = "Jeremy's Sensoг·; // Выходной контакт потенциометра подключаем к контакту АО платьI const int РОТ= АО: // Встроенный светодиод подключен к контакту 13 const int STATUS_LED = 13; void setup(void) {
// Задаем режим вывода для контакта красного светодиода pinMode(STATUS_LED, OUTPUТ); // Будем выводить информацию для отладки в окно монитора порта. Serial.begin(9600):
// Плата Arduino Feather 32U4 оснащена аппаратным USВ-интерфейсом, // поэтому следующую строку кода следует оставить раскомментированной, // если хотите, чтобы инициализация не начиналась до тех пор, // пока не будет запущена программа монитора порта. // Но закомментируйте ее, если хотите, чтобы скетч продолжал // исполнение, не дожидаясь запуска программы монитора порта // (или если плата работает от батареи). while(!Serial); // Подключаемся к модулю BTLE Serial.print(F("lnitializing BTLE Module...")): // Инициализируем модуль BTLE... if (!btle.beginO) {
Serial.println(""): Serial.println(F("Couldn't connect to nRF51 Module.")); // Не удалось подключиться к модулю nRF51. while(l);
} Serial.println(F("Ready!")); // Выполняем сброс модуля BTLE к заводским настройкам. // Эту процедуру можно активировать для восстановления модуля // от возможных ошибок при программировании, в результате которых
Установка связи между платой Arduino и смартфоном // модуль перестал отвечать. // После сброса модулю задается широковещательное имя if (PERFORM_CONFIGURATION)
{
// Сброс модема к заводским настройкам Serial.print(F("Resetting to Defaults...1); // Сбрасываем модем к заводским настройкам if (!btle.factoryResetO)
{
Serialprintin(""); Serialprintln(F("Couldn't reset module.1); // Не удалось выполнить сброс модуля while(1);
} Serialprintln(F('Done!1); // Задаем широковещательное имя, используя команду АТ Serial.print(F("Setting Device name...")); // Задаем имя модема... btle.print(F("AT+GAPDEVNAME=")); btie.println(BTLE_NAME); if (!btle.waitForOK0)
{
Serial.println(F("Could not set name.")); // Не удалось задать имя. while(1);
} btle.reset0; // Перезапускаем модуль, // чтобы изменения вступили в силу Serialprintln(F("Done!")); // Готово!
} // Переключаемся в режим данных (из командного режима) btle.setMode(BLUEFRUIT_MODE_DATA);
} void Loop(void)
{
// Ожидаем подключения смартфона, если еще не подключен if (!btle.isConnected0) {
438 Глава 16. Беспроводная связь Bluetooth Serial.print("Waiting to connect to а smartphone..."); // Ожидается подключение к смартфону... while (!btle.isConnectedQ) { delay(l000); } Serial.println("Connected!");// Подключились! }
// Считываем значение выходного сигнала потенциометра int val = analogRead(POT); // Выводим полученное значение в окно монитора порта Serial.print(F(':Analog Value: "));//Аналоговое значение: Serial.print(val); Serial.print(F('\tSending...")); // Отправляем данные модулю BTLE для дальнейшей передачи // по радиоканалу // Мигаем светодиодом в процессе передачи digitalWrite(STATUS_LED, HIGH); btle.printlп(val); // Ждем подтверждения получения данных модулем BTLE btle.waitForOKQ; Serial.println(F("OK!")); digitalWrite(STATUS_LED, LOW); }
Эта программа реализует все рассмотренные ранее шаги. Кроме того, в ней также реализован вывод сообщений в монитор порта для целей отлад ки, а также создается конфигурационная переменная, позволяющая выбрать, выполнять или нет сброс модуля BTLE к заводским настройкам при запуске программы. Загрузите данный скетч в свою плату Feather 32U4 Bluefruit LE. Поскольку микроконтроллер 32U4 оснащен встроенным USВ-интерфейсом, в код нуж но вставить строку кода цикла while(!Seriat);, чтобы не задержать запуск ис полнения скетча до тех пор, пока не будет открыта программа монитора пор та для отображения выходных данных программы. Как именно плата Feather будет работать с этой строкой кода, зависит от вашего компьютера. В следую щей врезке приведена более подробная информация на эту тему.
Установка связи между платой Arduino и смартфоном 439
USВ-ИНТЕРФЕЙС МИКРОКОНТРОЛЛЕРА 32U4 Как мы узнали в главе 8, микроконтроллер ATmega 32U4 оснащен встро енным USВ-интерфейсом вместо отдельного микроконтроллера для реа лизации преобразования USB/RS-232, как в случае с микроконтроллером ATmega 328Р на плате Arduino Uno. В результате исходящие данные обра батываются немного по-другому. В случае с платой Arduino Uno, если про грамма содержит операторы Serial.printlnO, но монитор порта не запущен, то программа исполняется без проблем, отправляя данные, указанные в этих операторах, в виртуальную пустоту. Но в случае с микроконтролле ром 32U4, если запустить программу при подключенном последователь ном интерфейсе, а затем отключить его, эти сообщения могут сохраняться в буфере передачи. К сожалению, точное поведение может быть разным для различных операционных систем. Если у вас возникают проблемы, когда кажется, будто бы исполнение скетча зависает, их можно решить, запустив программу монитора порта, прежде чем запускать скетч (и держать ее от крытой), или же подключив плату Feather к другому компьютеру или опера ционной системе или выполнив то и другое. Если вывод данных в монитор порта не требуется, тогда из скетча можно удалить команды while{!Serial), Serial.beginO, Serial.printO и Serial.printlnQ. Такой ход может быть полезным при питании платы Feather от батареи. Загрузив скетч в плату Arduino, откройте программу монитора порта. В его окне должны выводиться отправляемые скетчем сообщения, как по казано на рис. 16.4. (Вследствие наличия в нем строки while(!Serial); скетч не начнет исполняться, пока не будет запущена программа монитора порта.)
Send
л
Initializing BTLE Module... Ready! Reзetting to Defaultз ...Done! Setting Device name ... Done! Waiting to connect to а зmartphone...
Б2] Au!Dsaoll
О Show tlmestimp
Newllne
v %00 baud
v
Oear output
Рис. 16.4. Выводимые в окно монитора порта сообщения об инициализации модуля BTLE
440 Глава 1 б. Беспроводная связь Bluetooth
Подключение смартфона к передатчику BTLE Компания Adafruit разработала приложение для смартфонов Android и iPhone, которое позволяет с легкостью выполнять основные операции с мо дулем BTLE. Разработка полноценного мобильного приложения выходит за рамки этой книги, но мы можем поэкспериментировать с этим приложением. Оно имеет открытый исходный код, который можно загрузить со страницы Adafruit на GitHub по адресу Ыum.fyi/Ыuefruit-app-code. Найдите приложение Adafruit Bluefruit LE Connect на Арр Store (для iPhone) или Android Play Store и установите его на своем смартфоне. При первом за пуске приложения оно попросит ввести свое месторасположение и предо ставить ему разрешение на работу с Bluetooth. После согласия на требуемые разрешения откроется главное окно приложения, как показано на рис. 16.5. Если загруженная в плату Feather программа работает должным образом и выводит в окно монитора порта сообщение « Waiting to connect to а smart phone... » (Ожидается подключение к смартфону...), то модуль BTLE должен отображаться в списке устройств BTLE под присвоенным ему именем. На рис. 16.5 можно видеть, что как iPhone, так и Android смартфон должным образом определили наш модуль BTLE. Нажмите кнопку Connect справа от имени устройства. Приложение проверит актуальность микропрограммного обеспечения модуля и может выдать запрос на его обновление к более новой версии, как показано на рис. 16.6. . = ' .о а -; ,. • 1 •• -
Central Mode
Cl'Пt1,1I t.1ocJr,
• No filter selected
) Nofitt•�"
□
) Multlf)i. UARТ mocs. .,11 (ТV) UШ0JU6500
СОНNЕСТ 1
.,11 Connoct·14058
СОНNЕСТ
Jeremy's Sensor .,II UN1.c,cabll,
СОНNЕСТ
.,11 LE-Moon Вoots
CONNECТ
.,11 Тile
CONNECТ
�11 Тile
СОНNЕСТ
.,11 06:46:Э6:ВО:4В:9Е
СОНNЕСТ
RSSI>� ------
-100dВМ
Show unnamed devices Must have UART Se находится в позиции О). Если искомая подстрока отсутствует в строке, в которой вы полняется поиск, функция возвращает значение -1. Таким образом, узнать, содержит ли строка искомую подстроку можно, проверив, не возвратила ли функция indexOf0 значение -1. Попробуйте проследить обработку програм мой одной из строк примеров. После того как программа устанавливает состояние светодиода и присва ивает значение переменной reply, осталось просто передать ответ на смарт фон: // Подтверждаем получение команды btle.println(reply); Serial.print(F("Replied With: "));//Ответ был: Serial.println(reply); btle.waitForOKQ; digitalWrite(STATUS_LED, LOW);
Установка связи между платой Arduino и смартфоном 447
Управление устройством BTLE командами на естественном языке Для такой программы у нас уже есть функциональность анализа команд ных строк, а инициализацию и функциональность установки связи такая же, как и в листинге 16.5. Нужно только добавить соответствующие переменные состояния в начале программы для отслеживания состояния светодиода и ответов модуля BTLE. Также может оказаться полезным изменить широкове щательное имя устройства, чтобы оно лучше обозначало его новую функцию. Окончательно программа должна выглядеть как показано в листинге 16.8. Совет
Размер буфера пользовательских данных службы передачи УАПП микросхемы Nordic BTLE составляет всего лишь 20 байт. Это означает, что любая строка, превышающая 20 символов, будет усекаться. Если в окне монитора порта выводятся усеченные строки, проверьте, что длина ваших команд составляет 20 символов или меньше. Все примеры команд в табл. 16.1 отвечают этому требованию. Листинr 16.8. Проrрамма BTLE_Led.ino для управления светодиодом по каналу BTLE //Управление светодиодом по радиоканалу BTLE // Подключаем библиотеку nRF51 SPI #incLude "Adafruit_BLuefruitLE_SPl.h" // Микросхема nRF51 на плате 32U4 Feather подключена // к микроконтроллеру 32U4 через контакты SPI. // При создании экземпляра объекта BTLE указываются контакты, // используемые для выбора ведомого CS (8), // прерывания IRQ (7) и сброса RST (4): Adafruit_BluefruitLE_SPI btle(8, 7, 4); // Задаем данной булевой переменной значение true (истина) // для одноразовой конфигурации. //Данная процедура выполняет сброс до заводских настроек, // а затем изменяет широковещательное имя модуля BTLE. // Не будет никакого вреда, если выполнять эту процедуру // при каждом запуске программы (оставьте значение переменной true). // Альтернативно можно ограничиться одноразовым исполнением // процедуры настройки. В таком случае задайте булевой переменной // значение false после первой настройки. const booL PERFORM_ CONFIGURATION = true;
Глава 1 б. Беспроводная связь Bluetooth // Имя, под которым устройство BTLE будет представлять себя смартфону const String BTLE_NAME = "Jeremy's LED "; // Встроенный светодиод подключен к контакту 13 const int STATUS_LED = 13; // Управляемый светодиод подключен к контакту 5 const int CТRL_LED = 5; // Переменные для отслеживания состояния светодиода boot Led_state = LOW; String cmd = ··; String repty = ··; void setup(void)
{
// Задаем выходной режим контактам светодиодов и выключаем светодиоды. pinMode(STATUS_LED, OUTPUТ); digitaLWrite(STATUS_LED, LOW); pinMode(CТRL_LED, OUTPUТ); digitaLWrite(CТRL_LED, ted_state); // Будем выводить информацию для отладки в окно монитора порта. SeriaL.begin(9600);
// Плата Arduino Feather 32U4 оснащена аппаратным USВ-интерфейсом, // поэтому следующую строку кода следует оставить раскомментированной, // если хотите, чтобы инициализация не начиналась до тех пор, // пока не будет запущена программа монитора порта. // Но закомментируйте ее, если хотите, чтобы скетч продолжал исполнение, // не дожидаясь запуска программы монитора порта // (или если плата работает от батареи). white(!Seriat); // Подключаемся к модулю BTLE Seriat.print(F("lnitializing BTLE Module...")); // Инициализируем модуль BTLE... if (!btLe.begin0) {
Serialprinttn(""); Seriat.printtn(F("Coutdn't connect to nRF51 Modute.")); // Не удалось подключиться к модулю nRF51.
Установка связи между платой Arduino и смартфоном 449 whiLe(1); } SeriaL.printLn(F("Ready!")); // Готово! // Выполняем сброс модуля BTLE к заводским настройкам. // Эту процедуру можно активировать для восстановления модуля // от возможных ошибок при программировании, // в результате которых модуль перестал отвечать. // После сброса модулю задается широковещательное имя if (PERFORM_CONFIGURATION) {
// Сброс модема к заводским настройкам SeriaL.print(F("Resetting to DefauLts.. .")); // Сбрасываем модем к заводским настройкам if (!btLe.factoryReset0)
{
SeriaL.printLnГ); SeriaL.printLn(F("CouLdn't reset moduLe.")); // Не удалось выполнить сброс модуля whiLe(1); } SeriaL.printLn(F("Done!")); // Готово! // Задаем широковещательное имя, используя команду АТ SeriaL.print(F("Setting Device name...")); // Задаем имя модема... btLe.print(F("AT+GAPDEVNAME=")); btLe.printLn(BTLE _NAMЕ); if (!btle.waitForOK0) {
SeriaL.printLn(F("CouLd.not set пате.")); // Не удалось задать имя. whiLe(1);
} btle.reset0;
// Перезапускаем модуль, // чтобы изменения вступили в силу SeriaL.println(F("Done!")); // Готово! } // Переключаемся в режим данных (из командного режима) btle.setMode(BLUEFRUIT_MODE_DAТА); }
450 Глава 16. Беспроводная связь Bluetooth void loop(void) { // Ожидаем подключения смартфона, если еще не подключен if (!btle.isConnectedQ) { Serial.print("Waiting to connect to а smartphone .. ."); // Ожидаем подключения смартфона... while (!btle.isConnectedQ) { delay(l000); } Serial.println("Connected!");//Подключились! } // Если есть входящие данные, считываем их и выполняем анализ. while (btle.availaЫe0 > О) { // Мигаем светодиодом состояния при получении запроса digitalWrite(STATUS_LED, HIGH); // Считываем символы во входящем буфере, // пока не обнаружим символ новой строки. cmd = btle.readStringUntil(\n'); Serial.print(F("Received Command: "));//Получена команда: Serial.println(cmd); //Преобразуем все буквы строки в строчные, // чтобы упростить распознавание команды cmd.toLowerCaseQ; // Ищем в строке ключевое слово red или led // и продолжаем анализ строк, содержащих их if (cmd.indexOf(F("red")) != -1 11 cmd.indexOf(F("led")) != -1) { // Строка содержит ключевое слово оп if (cmd.indexOf(F("on")) != -1) { led_state = HIGH; reply = F("OK! The LED has been turned оп."); // Светодиод включен. // Строка содержит ключевое слово off
Установка связи между платой Arduino и смартфоном 451 eLse if (cmd.indexOf(F("off")) != -1) {
Led_state = LOW; repLy = F("OK! The LED has been turned off."); // Светодиод выключен.
// Строка содержит ключевое слово toggLe eLse if (cmd.indexOf(F("toggLe")) != -1) {
Led_state = !Led_state; if (Led_state) repLy = F("OK! The LED has been toggLed оп."); // Светодиод переключен. eLse repLy = F("OK! The LED has been toggLed off.");
} // Строка содержит ключевое слово red или Led, // но никаких других ключевых слов eLse {
if (Led_state) repLy = F("The LED is currentLy оп."); // Светодиод сейчас включен eLse repLy = F("The LED is currentLy off."); // Светодиод сейчас выключен
} // Устанавливаем состояние светодиода digitaLWrite(CТRL_LED, Led_state); } eLse {
repLy = F("Command not understood.");// Неизвестная команда
} // Подтверждаем получение команды btLe.printLn(repLy); SeriaL.print(F("RepLied With: "));//Ответ был: SeriaL.printLn(repLy); btLe.waitForOK0; digitaLWrite(STATUS_LED, LOW); } }
452 Глава 1 б. Беспроводная связь Bluetooth
Загрузите скетч из листинга 16.8 в свою плату Feather, а затем откройте среду Arduino IDE и запустите монитор порта. В окне монитора порта долж на выводиться такая же информация, как показано на рис. 16.4. Запустите на своем смартфоне приложение Adafruit Bluefruit LE Connect и подключитесь к модулю BTLE (учитывая возможное новое имя модуля). Проверьте, что сообщения в окне монитора порта подтверждают подключение смартфона. Выберите опцию UART (рис. 16.10), откроется интерфейс, похожий на ин терфейс чата, в котором можно отправлять и принимать сообщения от мо дуля BTLE. Вводите в него команды наподобие команд из табл. 16.1. В глав ном поле окна должны отображаться как вводимые команды, так и ответы на них модуля BTLE. При подаче команды включения встроенного отладочного красного светодиода на плате Feather он должен включиться; также при по лучении модулем каждой команды должен мигать красный светодиод рядом с разъемом USB. На рис. 16.10 показан пример отображения в окне интер фейса UART передаваемых команд и получаемых ответов. Большинство смартфонов поддерживают голосовой набор на клавиатуре. Таким образом, вам не нужно ни разрабатывать, ни устанавливать никаких 9 44
�
е
Q
о •. • ,9
mm .
"f'
UART
G)
:
ed llght on
К! The LED has Ьееп turned оп.
oggle the LED
К! The LED has Ьееп toggled off.
umonthe LED К! The LED has Ьееп turned оп hat's the LED state he LED is currently оп.
�
UART
,N
Plotter
''' '"
-:•
)
hat's Up? ommand поt understood. urnthe light off ommand not understood.
SENO
Pin 1/0 Controller
1
Q
Neopixels
q w е
13
Тherma1 Camera
ш
Updates
2 3 4
а ◊
5 6 7
r
t
у
f
g
h
z
c
v
b
Рис. 16.1 О. Передача команд со смартфона по каналу BTLE
О
о
р
u
s d x
8 9
k n m (IO
Управление светильником посредством Bluetooth 453
программ для распознавания речи, чтобы управлять светодиодом голосо выми командами. Просто запустите службу UART в приложении Adafruit Bluefruit LE Connect и диктуйте в него свои команды. Примечание Видеофильм, демонстрирующий управление светодиодом через радиосвязь посред ством службы UART приложения Adafruit Bluefruit LE Connect, можно просмотреть на веб-странице этой главы по адресу https://www.exploringarduino.arduino.com/con tent2/ch16.
УПРАВЛЕНИЕ СВЕТИЛЬНИКОМ ПОСРЕДСТВОМ BLUETOOTH В предыдущей главе мы использовали закрытое реле с рабочим сетевым напряжением для управления светильником с помощью Arduino через ра диоканал. Теперь мы можем повторить это упражнение, но заменив простой радиоканал связью через Вluetooth. Но вместо службы UART приложения Adafruit Bluefruit LE Connect мы зададим хитроумную комбинацию команд АТ и команд управления излучаемой мощностью, чтобы собрать контроллер светильника, который будет включать его при вашем приближении к нему и выключать при удалении.
Процедура сопряжения смартфона с устройствами BTLE Хотя отправка сообщений со смартфона плате Arduino и может быть ори гинальной возможностью, это не совсем удобный способ управления объ ектами через Bluethooth. Удобнее использовать смартфон в качестве датчи ка близости, который автоматически включает сопряженные с ним через Bluetooth устройства при обнаружении человека в своей зоне действия. Таким образом вы сможете включать освещение на своем рабочем месте и выключать его при уходе на кухню перекусить, где при вашем появлении свет включится автоматически. Таким же образом можно выключать телеви зор, уходя из комнаты. Для последнего проекта этой главы мы используем то же самое закрытое реле, с которым мы экспериментировали в предыдущей главе, чтобы создать умный светильник, который включается только в ва шем присутствии. Вспомним из предыдущего материала этой главы, что современный ин терфейс Bluetooth имеет два рабочих режима: Low Energy или LE (с низким энергопотреблением) и Classic. Описанный в этой главе модуль поддер живает только работу в режиме LE. Смартфоны работают с устройства ми этого типа несколько иначе, чем устройства типа Classic. Классические
454 Глава 16. Беспроводная связь Bluetooth
устройства Bluetooth поддерживают сопряжение. Сопряжение - это про цесс, посредством которого ваш смартфон запоминает определенное устройство Bluetooth, например, наушники. После выполнения сопряжения, когда данное устройство включено и находится в зоне действия смартфона, он автоматически подключается к нему. Но устройства BTLE по умолчанию работают несколько иначе. Когда устройство BTLE подключается к смарт фону, оно предоставляет список служб, которое оно поддерживает. Если оба устройства - смартфон и устройство BTLE - поддерживают какую либо службу, то устройство BTLE предоставляет интерфейс к этой службе, чтобы смартфон мог взаимодействовать с ней. Если же устройство BTLE не предоставляет службу GATT, требующую сопряжения, то сопряжение смартфона с устройством выполняется на уровне операционной системы. В частности, для смартфонов iPhone требуется специальное приложение, предоставляемое изготовителем устройства BTLE, для выполнения процес са сопряжения в случаях, когда устройство BTLE не имеет определенных служб. Чтобы максимально упростить процесс сопряжения и не быть вынужден ным создавать специально приложение для смартфона только для того, чтобы наша плата Arduino могла обнаруживать его присутствие, это ограничение можно обойти. Оба типа смартфонов - iPhone и Android - поддерживают возможность сопряжения с устройствами BTLE, если эти устройства предо ставляют профиль HID (Human Interface Device - человеко-машинный ин терфейс). Например, беспроводная клавиатура имеет профиль HID. Таким образом, если на устройстве BTLE включить службу HID Keyboard, тогда оно будет представлять себя как беспроводная клавиатура. Это устройство будет отображаться в настройках Вluetooth смартфона, который сможет выпол нять сопряжение с ним, как с обычным классическим устройством Bluetooth. Всякий раз, когда смартфон находится в зоне действия сопряженного устрой ства, он будет автоматически подключаться к нему, не требуя никаких дей ствий с вашей стороны. Мы создадим программу для Arduino, которая будет ожидать такое подключение и включать соединенный с платой светильник при подключении смартфона и выключать его при отключении.
Программа для работы с датчиком присутствия Прежде чем пытаться сразу управлять светильником, я рекомендую до биться работоспособности базовой функциональности системы, используя уже имеющуюся у нас схему для управления светодиодом, изображенную на рис. 16.9. Когда это устройство работает должным образом, подключить кон такт управления реле к тому же самому контакту (при этом оставив также подключенным и светодиод) не будет представлять никаких проблем.
Управление светильником посредством Bluetooth 455
За основу программы возьмем уже имеющийся код из листинга 16.8 и внесем в него несколько модификаций. Прежде всего изменим имя устрой ства в переменной BTLE_NAME на более подходящее для новой задачи, напри мер, "Smart L amp". Далее при желании можно удалить константу PERFORM_ CONFIGURATION и связанные с ней операторы условия ifO. Схема будет редко выключаться, поэтому не столь важно, будет ли выполняться ее конфигури рование каждый раз. Затем добавим новую константу POWER_LEVEL: //Устанавливаем уровень излучаемой мощности, // определяющий зону активирования // Разрешенные значения: -40, -20, -16, -12, -8, -4, О, 4 // Чем больше значение, тем больше дальность подключения const int POWER_LEVEL = -20;
Эта константа используется совместно с АТ-командой АТ+BLEPOWERLEVEL для управления мощностью излучаемого модулем сигнала. Меньшее значе ние этой константы означает меньшее расстояние для активирования под ключения, а большее значение - большее расстояние. Скорее всего, будет полезным поэкспериментировать с несколькими разными значениями, что бы определить, какое окажется лучше всего в ваших условиях. Целью здесь является подобрать число, задающее приблизительное расстояние включе ния контроллера светильника. Например, у меня значение -20 вызывает под ключение, когда мой смартфон проходит через входную дверь моей кварти ры. Если бы я хотел, чтобы светильник включался, когда я еще поднимался по лестнице к моей квартире, то я бы установил более высокую мощность сигнала, например, -12 или -16. Уровень мощности излучаемого сигнала устанавливается фрагментом кода, приведенным в листинге 16.9. Листинг 16.9. Установка уровня мощности //Устанавливаем уровень мощности SeriaL.print(F("Setting Power LeveL...")); // Устанавливаем уровень мощности... btLe.print(F("AT+BLEPOWERLEVEL=")); btLe.printLn(String(POWER_ LEVEL)); if (!btLe.waitForOK0) {
SerialprintLn(F("Set Power LeveL.")); whiLe (1);
// Установить уровень мощности
} SeriaL.printLn(F("Done!l); // Готово
После установки уровня мощности излучаемого сигнала запускаем служ бу HID Keyboard, используя для этого АТ-команду BLEKEYBOARDEN (ли стинг 16.10).
456 Глава 16. Беспроводная связь Bluetooth Листинг 16.10. Запуск службы HID Keyboard . . . ................ ...................
.......
.................
// Включаем профиль НЮ Keyboard // (Чтобы устройства iOs могли распознавать модуль, // не используя приложения) SeriaL.priпt(F("EnaЫing НЮ Keyboard.. .")); // Включаем профиль НЮ Keyboard. btLe.printLn(F("AT+BLEKEYBOARDEN=1 ")); if (!btLe.waitForOK0) {
SeriaL.println(F("CouLd not enaьte НЮ Keyboard Profile.")); // Не удалось включить профиль HID Keyboard whiLe (1);
}
SeriaL.println(F("Done!")); // Готово // Перезапускаем модуль, btLe.resetQ; // чтобы новые настройки вошли в силу
Установка уровня мощности сигнала и включение профиля HID Keyboard осуществляются в функции setupO. В функции главного цикла Loop0 нужно только установить высокий уровень на контакте управления при подключе нии устройства BTLE, и низкий - при его отключении (листинг 16.11). Листинг 16.11. Главный цикл программы управления светильником
if (btle.isConnectedQ) {
// Включить светильник при подключении устройства BTLE digitaLWrite(LAMP _PIN, HIGH);
} if (!btLe.isConnectedQ) {
// Выключить светильник при отключении устройства BTLE digitaLWrite(LAMP _PI N, LOW);
}
Когда ваш сопряженный смартфон входит в зону подключения (т. е. зону, определяемую радиусом дальности передачи) модуля BTLE, он автоматиче ски подключается к нему, вызывая включение светодиода, подключенного к плате Arduino Feather. А когда смартфон покидает зону подключения, Arduino обнаруживает это событие и выключает светодиод. Сложив все только что рассмотренные фрагменты кода вместе, получим полнофункциональную программу, код которой приведен в листинге 16.12.
Управление светильником посредством Bluetooth 457 Внимание!
Не оставляйте без присмотра экспериментальное оборудование, не оснащенное сред
ствами безопасности! Данное программное обеспечение предназначено для управле
ния бытовым прибором с питанием от электросети и может потребовать отладки, если оно не будет работать должным образом. Кроме того, данное программное обеспече ние не оснащено средствами безопасности для предотвращения несанкционирован ного подключения к устройству Bluetooth и управления им. Никогда не оставляйте без присмотра устройства, на которых исполняется экспериментальное программное обес печение. Отключите это устройство, когда оно не используется. Листинr 16.12. Проrрамма ВТLE_Led.ino для управления светильником по каналу ВТLЕ // Включает/выключает светильник при подключении/отключении смартфона // Подключаем библиотеку nRFS1 SPI #include "Adafruit-BluefruitLE-SPl.h" // Микросхема nRFS1 на плате 32U4 Feather подключена // к микроконтроллеру 32U4 через контакты SPI. // При создании экземпляра объекта BTLE указываются контакты, // используемые для выбора ведомого CS (8), // прерывания IRQ (7) и сброса RST (4): Adafruit_BluefruitLE_SPI btle(8, 7, 4); // Имя, под которым устройство BTLE будет представлять себя смартфону const String BTLE_NAME = "Smart Lamp"; // Устанавливаем уровень излучаемой мощности, // определяющий зону активирования // Разрешенные значения:-40,-20,-16,-12,-8,-4, О, 4 // Чем больше значение, тем больше дальность определения const int POWER_LEVEL = -40; // Контакт для управления реле светильника const int LAMP_PIN = S; void setup(void) { // Задаем выходной режим для контакта управления реле и выключаем реле pinMode(LAMP_PIN, OUTPUТ); digitaLWrite(LAMP_PIN, LOW); // Будем выводить информацию для отладки в окно монитора порта. Serial.begin(9600);
458 Глава 16. Беспроводная связь Bluetooth
// Плата Arduino Feather 32U4 оснащена аппаратным USВ-интерфейсом, // поэтому следующую строку кода следует оставить раскомментированной, // если хотите, чтобы инициализация не начиналась до тех пор, // пока не будет запущена программа монитора порта. // Но закомментируйте ее, если хотите, чтобы скетч продолжал исполнение, // не дожидаясь запуска программы монитора порта // (или если плата работает от батареи). //whiLe (!SeriaL); // Подключаемся к модулю BTLE Serial.print(F("lnitializing BTLE ModuLe...")); // Инициализируем модуль BTLE... if (!btLe.beginQ) { SeriaL.printLn(""); SeriaL.printLn(F("CouLdn't connect to nR FS1 ModuLe.")); // Не удалось подключиться к модулю nR FS1. whiLe (1); } SeriaL.printLn(F("Ready !")); // Готово! // Сброс модема к заводским настройкам SeriaL.print(F("Resetting to DefauLts...")); // Сбрасываем модем к заводским настройкам if (!btle.factoryResetQ) { SeriаL.printLn(" "); SeriaL.printLn(F("CouLdn't reset moduLe.")); // Не удалось выполнить сброс модуля whiLe (1); } SeriaL.printLn(F('Done !")); // Готово
/! Задаем широковещательное имя, используя команду АТ SeriaL.print(F(" Setting Device name...")); // Задаем имя модема... btLe.print(F("АТ+GAPDEVNAMЕ=")); btLe.printLn(BTLE_NAME); if (!btLe.wait ForOKQ) { Serial.printLn(F("CouLd not set name.")); // Не удалось задать имя.
Управление светильником посредством Bluetooth 459 whiLe (1); } SeriaL.printLn(F("Done!")); // Готово! //Устанавливаем уровень мощности SeriaL.print(F("Setting Power LeveL ..1); //Устанавливаем уровень мощности... btLe.print(F("AТ+BLEPOWERLEVEL=")); btLe.printLn(String(POWER_LEVEL)); if (!btLe.waitForOK0) { SeriaL.printLn(F("Set Power LeveL.")); //Установить уровень мощности whiLe (1); } SeriaL.printLn(F("Done!")); // Готово // Включаем профиль НЮ Keyboard // (Чтобы устройства Юs могли распознавать модуль, // не используя приложение) SeriaL.print(F("Enabling НЮ Keyboard .. .")); // Включаем профиль НЮ Keyboard. btLe.printLn(F("AT+BLEKEYBOARDEN=1 ")); if (!btLe.waitForOK0) { SeriaL.printLn(F("CouLd not enable НЮ Keyboard ProfiLe.")); // Не удалось включить профиль НЮ Keyboard whiLe (1); } SeriaL.printLn(F("Done!")); // Готово! btLe.reset0;
// Перезапускаем модуль, // чтобы новые настройки вошли в силу
void Loop(void) { if (btLe.isConnected0) { // Включить светильник при подключении устройства BTLE digitaLWrite(LAMP_PIN, HIGH); }
460 Глава 16. Беспроводная связь Bluetooth
if (!btLe.isConnectedO) { // Выключить светильник при отключении устройства BTLE digitaLWrite(LAMP_PIN, LOW); }
}
Обратите внимание на то, что в этом скетче я закомментировал строку кода while (!SeriaL);, поскольку он будет исполняться на плате Arduino, не под ключенной к компьютеру (кода мы подключим реле к схеме). Если оставить эту строку незакомментированной, то без запуска программы монитора пор та скетч навечно «зависнет» на этой строке.
Сопряжениесосмартфоном
Процесс сопряжения устройства BTLE со смартфоном для iPhone и Android во многом схож для обеих систем. Но поскольку обе эти операцион ные системы подвергаются частым модификациям, то процесс сопряжения в будущем может отличаться от описанного здесь. В таком случае, если вам не удастся выполнить сопряжение, следуя приведенным инструкциям, просто поищите в Интернете текущие инструкции для сопряжения своего смартфо на и устройства Bluetooth. Начнем с загрузки кода из листинга 16.12 в плату Arduino Feather. Может оказаться полезным запустить программу монитора порта, чтобы подтвердить, что все работает должным образом. В таком слу чае следует раскомментировать строку while(!Seriat); или же загрузить код с уже запущенной программой монитора порта. Сопряжение со смартфоном Android
Запустите приложение Settings (Настройки) смартфона. Это можно сде лать или выбрав его в панели приложений, или нажав значок шестерен ки в выпадающем меню извещений. Откройте панель Connected devices (Подключенные устройства) и нажмите Pair New Device (Выполнить со пряжение с новым устройством). В результате будет включена возможность радиосвязи Bluetooth, если она еще не была активирована. Ваш модуль BTLE должен отображаться в списке доступных устройств под именем, которое вы ему присвоили. Последовательность этих шагов показана на рис. 16.11 (устройство BTLE называется Smart Lатр). Нажмите элемент списка с име нем устройства. Сопряжение должно выполниться немедленно, на что бу дет указывать загоревшийся красный светодиод на плате Feather. Теперь наше устройство должно отображаться в списке подключенных устройств Currently connected. Если вручную включать и выключать радиосвязь Blue tooth на смартфоне, то светодиод также должен включаться и выключаться
Управление светильником посредством Bluetooth 461 ,.ы • $ t--
Q
(
o•.J•""'
Corin.ckIOd;tvkec
Q.
r--·-_' ·---------'I Gli
10•J•*
U.l)
f-
с.!)
Paer мw dtrvk::e
Q.
Ф
f-
Cormec.ted devlcм
О..
Фj
➔
���
1
""
•
8/0Wlt.-..p
+
р..--�
,�· -_,....____...., ➔ 0
:с
№7C'I'
0
Рис. 16.11. Сопряжение со смартфоном Android
(смартфон должен автоматически подключаться к плате Arduino, когда на ходится в пределах зоны действия устройства BTLE). Но при этом будет на блюдаться задержка в несколько секунд.
СопряжениесосмартфономiРhоnе
Процесс сопряжения устройства BTLE со смартфоном iPhone во многом похож на этот процесс для смартфона Android. Откройте панель Settings (Настройки) и нажмите элемент Bluetooth. Запустится поиск находящихся вблизи устройств Bluetooth. Наше обнаруженное устройство должно отобра зиться в списке Other Devices (Другие устройства). Нажмите элемент спи ска с именем устройства. Дайте разрешение на открывшийся запрос выпол нить сопряжение. После завершения процесса сопряжения наше устройство должно отображаться в списке Connected. Шаги этого процесса показаны на рис. 16.12. Если в процессе сопряжения происходит отключение смартфона, про сто повторите попытку. Иногда для успешного сопряжения требуется пред принять две-три попытки. Это в равной мере относится как к смартфонам iPhone, так и Android. Модуль BTLE не может одновременно подключиться больше чем к одному смартфону, но он может выполнить сопряжение и за помнить больше чем один смартфон. Внимание!
Код в листинге 16.12 не содержит никаких средств для выполнения аутентификации или иных мер безопасности при выполнении сопряжения. Поэтому любое другое устрой ство в пределах зоны действия нашего устройства BTLE может подключиться к нему (и управлять пЬдключенным к этому модулю светильником). Данный проект предназна чен только для целей экспериментирования, а настоящие системы управления бытовы ми или офисными устройствами всегда следует оснащать какими-либо программными
462
Глава 16. Беспроводная связь Bluetooth средствами безопасности. Если вы планируете оставлять это устройство работающим без присмотра, вы делаете это на свой собственный страх и риск. Один из способов повысить безопасность этого проекта - реализация приложения на смартфоне, ко торое прежде чем получить доступ для управления устройством BTLE, обрабатывает привязку к нему и передает ему пароль, подтверждающий разрешение на управление им. Разработка мобильных приложений выходит за рамки этой книги, но если вы хо тите написать приложение с открытом исходным кодом, реализующее подобные меры безопасности, дайте мне знать, когда оно будет готово, и я размещу на веб-сайте книги ссылку на него.
.-.тат•
••1'
•:11JPl,I
1:ООРМ
Settings
е ...... а
Вluetooth
О
11
Вluetooth
№wd�.Ы. MYOfVICfS
,1..
Ol'Hl:A OEVICES
Air�neMode
Вluetooth
Smart Lamp
Тile
_,т_._ ..-
.,_,с....
11 Wi-Fi
а
\..ФIIO
Bluetooth
Bluetooth
( SctOngs
'\
_,I, �
Тile
Coпnecttod
_Smart_L_.,,.., _______
0T1'181DEVICES /...
l'Op,tfl'•riltpp!tW,tct\Wl1hyoti,»"rчine,go,tot"
TOPf,lr('\� Examples > WiFil0I > CheckWifil0IFirmwareVersion. В этом скетче нужно будет добавить одну строку кода в функции setupO перед строкой seril.beginO, чтобы задать пра вильные номера контактов для модуля Wi-Fi платы Feather. Требуемая строка кода выглядит таким образом: WiFi.setpins(S,7,4,2);
Данный код сообщает библиотеке, что выводы Chip Select, Interrupt, Reset и ЕnаЫе модуля Wi-Fi подключаются к цифровым контактам 8, 7, 4 и 2 микроконтроллера Cortex-МО+. Загрузите модифицированную таким об разом программу в плату Feather и запустите программу монитора порта. Если в окне монитора порта отобразится сообщение, что версия прошив ки соответствует версии, требуемой библиотекой, тогда у нас все в порядке. Но если появится сообщение, содержащее текст Check result: NOT PASSED
476 Глава 17. Wi-Fi и облачные хранилища
•
.
J •
,.
5
'[11 �i
Л'\rt!I ](
�
.:,L j
·t ◄ -�
i i-1
Данная НТМL-страница содержит четыре элемента формы (разметка HTML между каждой парой тегов и ). Тег обозначает начало формы, а тег - ее конец. Каждая форма содержит тег , который обозначает, что при отправке формы на сервер будут передаваться данные. В случае кнопок переключения состояния светодиодов на сервер с помощью метода GET будет передаваться переменная L со значением, соот ветствующим номеру контакта управления светодиодом, состояние которо го нужно переключить. Когда мы вставим этот код HTML в нашу программу Arduino, то заменим абсолютные значения номеров контактов соответствую щими константами. Элементу action в теге присвоено значение" (пу стая строка), это означает, что при передаче переменной серверу страницу нужно перезагрузить. А скрытый тип ввода (input type='hidden') означает, что данное значение будет отправлено только при нажатии кнопки Submit. Ползунок для управления частотой воспроизводимого сигнала создается с помощью элемента ввода HTML5, называющегося range, который созда ет ползунок для задания значения в пределах данного диапазона значений. Перемещая ползунок (с шагом перемещения, равным 100), можно выбрать частоту воспроизводимого сигнала, которая будет передана на веб-сервер в виде значения переменной S. В старых браузерах, которые не поддержива ют элемент range, ползунок может отображаться в виде поля ввода. Чтобы просмотреть созданную веб-страницу, откройте ее в каком-либо браузере (я рекомендую Google Chrome). Для этого просто дважды щелкните файл страницы или используйте любой другой способ для запуска программ (от крытия файлов). В браузере страница должна отображаться, как показано на рис. 17.8. х
� ➔
С
O
(D File
I
+
C:/test.html?l;11
*.
о
о
1 Toggle Red ] � Toggle Green 1
l Toggle Bluв 1
l Set Frequency j Рис. 17.8. Отображение веб-страницы в браузере
х
488 Глава 17. Wi-Fi и облачные хранилища
Если нажать одну из кнопок, то к адресу страницы в поле адреса браузе ра должна добавиться соответствующая переменная со своим значением. На рис. 17.8 в конце адреса URL добавлено L=11, поскольку была нажата кнопка Toggle Blue для управления синим светодиодом.
Собираем весь код вместе для создания веб-сервера Теперь нам нужно взять только что созданный код НТМLдля веб-страницы и вставить его в основной скетч сервера, который будет заниматься такими задачами, как подключаться к сети Wi-Fi, получать IР-адреса, отвечать на за просы клиента предоставлением ему нашей веб-страницы, а также испол нять действия по управлению оборудованием на основании информации, полученной в запросах GET из формы веб-страницы. Осветив в предыдущих разделах все требования к программе веб-сервера для исполнения на плате Arduino, мы можем приступить к созданию такого сервера. В листинге 17.4 приведен код сервера, который выполняет все необ ходимые задачи по управлению RGВ-светодиодом и динамиком. При жела нии в этот код можно добавить функциональность, используя для этого до полнительные переменные запроса GET. Такая модификация будет довольно прямолинейной задачей. Места в коде, где можно внести такую дополнитель ную функциональность, указаны в комментариях. Листинr 17.4. Проrрамма web_controL_server.ino веб-сервера на Arduino ........................... . . . . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . // Веб-сервер на Arduino для управления светодиодами и динамиком // Некоторые части кода адаптированы из книги //Arduino Ехатр/е Code , автор Том Айго (Тоm lgoe) #include #include //Wi-Fi lnfo const char WIFI_SSID[] = "ВВЕДИТЕ СЮДА ИМЯ SSID СВОЕЙ СЕТИ"; //Имя SSID сети Wi-Fi const сhаг WIFI_PASSWORD[] = "ВВЕДИТЕ СЮДА ПАРОЛЬ ДЛЯ СВОЕЙ СЕТИ"; // Пароль сети Wi-Fi // Обозначаем состояние подключение через встроенный светодиод const int ONBOARD_LED = 13; // Контакты, которыми будет управлять форма HTML const int RED = 5; const int GREEN = 10;
Управление платой Arduino через Интернет 489 const int ВШЕ = 11; const int SPEAKER = AS; // Сервер ожидает подключения на порту 80 (стандартный порт НТТР) WiFiServer server(80); // Переменная для отслеживания, связана ли плата с точкой доступа Wi-Fi int wifi_status = WL_IDLE_STATUS; void setup0 { // Задаем номера контактов для использования с модулем Wi-Fi WiFi.setpins(8,7,4,2); // Задаем режим работы и состояние контактов pinMode(ONBOARD_LED, OUTPUT); digitalWrite(ONBOARD_LED, LOW); pinMode(RED, OUTPUТ); digitalWrite(RED, HIGH); // Высокий уровень (HIGH) // выключает RGВ-светодиод, поскольку это светодиод с общим анодом pinMode(GREEN, OUTPUТ); digitalWrite(GREEN, HIGH); // Высокий уровень (HIGH) // выключает RGВ-светодиод, поскольку это светодиод с общим анодом pinMode(BLUE, OUTPUT); digitalWrite(BLUE, HIGH); // Высокий уровень (HIGH) // выключает RGВ-светодиод, поскольку это светодиод с общим анодом // Запускаем последовательный интерфейс Serialbegi п(9600); // Плата Arduino Feather МО оснащена аппаратным USВ-интерфейсом, // поэтому следующую строку кода следует оставить раскомментированной, // если хотите, чтобы инициализация не начиналась до тех пор, // пока не будет запущена программа монитора порта. // Но закомментируйте ее, если хотите, чтобы скетч продолжал исполнение, // не дожидаясь запуска программы монитора порта // (или если плата работает от батареи). while(!serial); Serial.print("Connecting to: "); // Подключаемся к: Serial.println(WI FI_SSID); WiFi.setTimeout(S000); // Даем вплоть до 5 секунд для установления // подключения к сети WiFi while (wifi_status != WL_CONNECТED)
490 Глава 17. Wi-Fi и облачные хранилища {
wifi_status = WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
} SeriaL.printLn("Connected!\n"); digitaLWrite(ONBOARD_LED, HIGH); // Запускаем сервер server.beginQ; SeriaL.printLn("Server Started!");
// Подключились! // При установке подключения, // включаем встроенный светодиод
// Сервер запущен!
// Выводим в окно монитора порта IР-адрес, // полученный через протокол DHCP IPAddress ip = WiFi.LocaLIPQ; SeriaL.print("Control this Arduino at: http://"); // Адрес для управления этой платой // Arduino: http// SeriaL.println(ip); Serial.println(""); } void loop0 { // Запускаем сервер, ожидающий входящие подключения клиентов WiFiClient client = server.avaiLaЫeQ; // Подключился ли клиент (браузер)? if(cLient) { // Пока клиент подключен, считываем в цикле входящие строки запроса String command = ""; whiLe (cLient.connectedQ) { // Считываем по одной строке входящих данных за раз String incoming_Line = ""; // Используем цикл do-whiLe, чтобы не начинать проверять // форматирование строки, пока строка // не получит свой первый символ do { while(!cLient.availaЬleQ); // Ожидаем поступления // следующего байта = // При поступлении char с client.readQ; // считываем его // и добавляем в конец incoming_Line += с;
Управление платой Arduino через Интернет 491 //текущей строки } whiLe (!incoming_Line.endsWith("\r\n")); SeriaL.print(incoming_Line); // Выводим в монитор порта //только что полученную строку // Выполняем действие, указанное в запросе GET //Анализируем и извлекаем данные из строк, //выглядящих как: "GET ЛL= l0 НТТР/1.1" if (incoming_Line.startsWith("GET П")) {
//Команда выглядит, как L= l0 command = incoming_Line.substring(б,incoming_Line.indexOf(" НТТР/1.1"));
// Если строка пустая (содержит только символы возврата каретки //и новой строки), //значит, мы полностью получили весь входящий запрос if (incoming_Line == "\r\n")
{
// Отвечаем на все полученные полные запросы, //выдавая нашу страницу с формой //Код ответа 200: Запрос страницы был получен и понят cLient.printLn("HТТP/1.1 200 ОК"); cLient. printLn("Conteпt-type :text/htmL"); cLient.printLn0;
//Кнопка переключения состояния красного светодиода cLient.print(""); cLient.print(""); //Кнопка переключения состояния зеленого светодиода cLient.print("");
492 Глава 17. Wi-Fi и облачные хранилища cLient.print(""); cLient.print(" (PCllmlWXQ(ln))PD4 GND
vcc vcc
GND
,
(Рf2ПМ(W.1/'ТО8С1)Р88
7
-
24 23
PCl(№C:1�) РСО_..
"
№СО
ЮС1 GNO
Рис. П4. Цоколевка для микроконтроллера ATmega328P в разных корпусах (Источник:© Microchip Technology lncorporated. Репродукция с разрешения)
установлен микроконтроллер в DIР-корпусе, то вы сможете увидеть на нем этот вырез. Но главное здесь не сам вырез, а то, что слева от него находится первый контакт микросхемы (не путать с номерами контактов самой платы Arduino). А в случае микроконтроллера в SМD-корпусе его первый контакт обозначен точкой в одном из углов корпуса. Обозначения цоколевки содержат некоторые сокращения, которые могут быть вам незнакомы. Далее приведена их расшифровка: ■ VCC - контакт для подачи положительного напряжения питания на ми кросхему 1. Для платы Arduino Uno напряжение питания VCC равно 5 В; 1
В русскоя;:1ычной литературе обычно используется обозначение U+ или +и••. - Прим. пер.
Работа со справочными листками 531
■ AVCC- контакт для подачи отдельного положительного напряжения пи тания на АЦП. Для платы Arduino Uno это напряжение также равно 5 В; ■ AREF - контакт для подачи опорного напряжения для АЦП, который выводится на контакт платы Arduino. Это позволяет при желании по дать на АЦП любое опорное напряжение ниже 5 В; ■ GND - контакт подключения земли (общая шина). Все остальные контакты микроконтроллера являются контактами ввода вывода общего назначения. Все они сопоставлены с помощью программного обеспечения Arduino соответствующему контакту платы Arduino, что избав ляет пользователя от необходимости самому определять номер порта и но мер контакта микросхемы микроконтроллера. В скобках указаны альтернативные функции для каждого контакта. Например, контакты с основными функциями PDO и PD 1 также имеют альтернативные функции линий приема (RX) и передачи (ТХ) для универ сального синхронного/асинхронного приемопередатчика (УСАПП) соот ветственно. А альтернативная функция контактов с основными функциями
ATmega168/328P-Arduino Pin Mapping Note that this chart is for the DIP-package chip. The Arduino Mini is based upon а smaller physical IC package that includes two extra ADC pins, which are not availaЫe in the DIP-package Arduino implementations. Atmega168 Pin Mapping Arduino funrtion
Arduino funrtion
reset digital pin О (RX) digital pin 1 (ТХ) digital pin 2 digital pin 3 (PWM) digital pin 4
(PCINТ14/RESEТ) РС6 (PCINТ16/RXD) РОО (PCINT17/ТXD) PD1 (PCINТ18/INTO) PD2 (PCINТ19/0QB/INТ1) РОЗ (РСINТ20/ХСК/ТО) PD4
GND crystal crystal digital pin 5 (PWM) digital pin 6 (PWM) digital pin 7 digital pin В
GND (PCINТ6/XTAL1/ТОSС1) РВ6 (PCINТ7/ХТАL2/ТОЮ) РВ7 (РСINТ21/ОСОВ/Т1) PDS (PCINШ/OCOA/AINO) PD6 (PCINШ/AIN1) PD7 (PCINTO/CLKO/ICP1) РВО
vcc
1
4 5
vcc
11
PCS (ADCS/SCUPCINПЗ) РС4 (ADC4/SDA/PCINТ12) РО (ADO/PCINТ11) PQ (ADQ/PCINТ1 О) РС1 (ADC1/PCINT9) РСО (ADCO/PCINТ8) GND AREF AVCC PBS (SCК/PCINТS) РВ4 (MISO/PCINТ4) РВЗ (MOSI/OC2A/PCINТ3) РВ2 (SS/OC1B/PCINТ2) PBl (0(1A/PCINТ1)
analog input S analog input 4 analog input 3 analog input 2 analog input 1 analog input О GND analog reference
vcc
digital pin 1 J digital pin 12 digital pin 11 (PWM) digital рiп 10 (PvVMI digital pin 9 (PWMJ
Digital Pins 11, 12 & 13 ме used Ьу the ICSP header for MOSI, MISO, SCK connections (Atmega168 pins 17, 18 & 19). Avoid lo,vimpedance loads оп these pin1 when using the ICSP header. Рис. ПS. Соответствие выводов микроконтроллера ATmega контактам платы Arduino Uno (Источник: Arduino, arduino.cc)
532 ПРИЛОЖЕНИЕ. Расшифровка справочных листков и изучение принципиальных схем
РВ6 и РВ7 - подключение кварцевого генератора (XTAL). В случае платы Arduino Uno к этим контактам подключен внешний пьезокерамический ре зонатор или кварцевый генератор с частотой 16 МГц, поэтому их нельзя ис пользовать для целей ввода-вывода. Если вы не можете сразу понять назначение контактов по их обозначени ям на цоколевке, то эту информацию обычно можно извлечь из контекста, в котором они используются дальше в справочном листке. На веб-сайте ком пании Arduino по адресу Ьlum.fyi/arduino-uno-pin-map приведен рисунок, на котором указывается, как выводы микроконтроллера ATmega подключе ны к контактам платы Arduino. Этот же рисунок продублирован на рис. ПS.
ИЗУЧЕНИЕ ПРИНЦИПИАЛЬНОЙ СХЕМЫ ПЛАТЫ ARDUINO Наверное, один из самых лучших способов изучать разработку электронных схем - анализировать схемы уже готовых устройств, в нашем случае пла ты Arduino Uno. Принципиальная схема этой платы приведена на рис. П6. Попробуйте найти на этой схеме компоненты, которые видите на своей плате Arduino Uno? Начните с главного микроконтроллера ATmega328P (на схеме он обозначен как ZU4) и контактов платы. Таким образом, вы сможе те установить, какие порты или контакты микроконтроллера ATmega соот ветствуют контактам платы Arduino Uno, доступным вам в среде разработки Arduino IDE. Ранее мы установили, что контакты PDO и PDl микроконтроллера под ключены к контактам ТХ (передача) и RX (прием) УСАПП. Глядя на принци пиальную схему платы Arduino Uno, мы можем подтвердить, что эти контак ты в действительности подключены к соответствующим контактам микро контроллера 16U2 (который на плате Arduino Uno используется в качестве преобразователя USB/RS-232). Мы также знаем, что к контакту 13 платы Arduino Uno подключен светодиод (через токоограничивающий резистор). На принципиальной схеме можно видеть, что контакт 13 платы Arduino Uno подключен к контакту функции PBS микроконтроллера ATmega. Но где же сам светодиод? Если на схеме показывать линии всех возможных соедине ний, то она очень быстро может стать запутанной. Поэтому электрические соединения между двумя точками можно обозначать с помощью имен логи ческих цепей, не прорисовывая на схеме сами соединительные линии. В слу чае контакта PBS можно видеть, что из него выходит линия, обозначенная SСК. А посередине вверху рисунка есть подсхема, в которую входит линия с таким же самым обозначением. Эта линия подключена к входу буфера, вы ход которого соединен дальше с резистором, а затем уже подключен знако мый нам отладочный светодиод.
.,v
�
i
i�
'
'"" оно
•Dl.:tPCO)
АЕЗЕТ[РС11ОW/
!№
�-g
Re"vЗ
f'IТt(Б""16UL·rt)(R°,,
��
. g-_ с1+ �""" VGНD •
On
I rf':r,snr0!5c-:;
Arduinosiqn uith this intormation.
xz
�в"е_тн
О№
С1
Ofln
��·•,
!
.,
'
V1 w w
:5· о
а.с
3:: о: :::::1 ::i QI -t о: )>
�
11) ::i::: s 11) :::::1 't:J s ::i::: .s:: s :::::1 s QI ::i rr ::i::: о s, n
:s:: � ..t:.
534 ПРИЛОЖЕНИЕ. Расшифровка справочных листков и изучение принципиальных схем
Большая часть принципиальных схем, с которыми вам придется работать, оформлены подобным образом, с обозначенными логическими цепями, но без непосредственно соединяющих их линий. Более сложные схемы состоят из нескольких страниц с логическими цепями на каждой странице, соеди няющимися друг с другом посредством иерархической структуры. Исследуйте принципиальную схему платы Arduino Uno, пока не выясните, куда идут все сигналы. Попробуйте сопоставить как можно больше компо нентов на ней с компонентами на самой плате. Если у вас плата Adafruit METRO 328, то принципиальную схему для нее можно найти по адресу Ыum.fyi/metro-328-schematic.
ПРЕДМЕТНЫЙ УКАЗАТЕЛЬ А Адрес IP глобальный 468 локальный 468 шлюза 495 МАС 468 Акселерометр микросхема LIS3DH 277 трехосевой ADXL335 93 Амплитуда волны 170 Амплитудная манипуляция 403 Аналого-цифровой преобразователь, АЦП 86 Антенна несимметричная четвертьволновая 404 Архитектура микроконтроллера В-разрядная 37 32-разрядная 37 АRМ 38 AVR 37 Б Библиотека Adafruit BTLE SPI 431 Adafruit GFX 516 Adafruit LED Backpack 516 Adafruit LIS3DH Library 286 Adafruit nRF5 430 Adafruit Unified Sensor Library 286 Adafruit Universal Sensor 289 JSON 502 LiquidCrystal 300,303, 305, 306 Mouse.h 226
RTClib 374,381 SD 360,366 Servo.h 144,146 Stepper.h 157, 158 TimerOne 343, 344 WiFil0l Ьу Arduino 473 Wire 256,257,259 Бит 84 Булевы переменные 75
в Веб-сервер 471 Версия Bluetooth 2.0 424,425 3.0 425 4.0 425 Волатильная переменная 342
д Дальномер инфракрасный Sharp 92 Данные регистратор 352 тип данных 61 unsigned long 163 Датчик температуры AD7414 251 TC74A0-5.0VAT 250 ТМР36 93 Делитель напряжения резистивный 97 Диапазон радиочастот ISM 401 Диод заграждающий 109 Директива RoHS 99 препроцессора 375
536 ПРЕДМЕТНЫЙ УКАЗАТЕЛЬ
Дисплей семисеrментный 513, 514 Длина волны электромагнитного излучения 400 Дребезг контактов 72, 335
3 Заголовок ответа 481 Загрузчик 40, 41 Закон Ома 57, 58 Запись в файл на SD-карте 364 Запрос GET 485
и Излучение электромагнитное длина волны 400 частота 400 Индикатор хода выполнения 308 Институт IEEE 424, 469 Интернет-подключение 425 Интерфейс Web-API 498 Facebook 499 Git Hub 498 Google Maps 498 NASA 499 Phillips Hue 499 назначение 501
к Карты MicroSD 353 SD 353 Клиент 470 Ключевое слово (byte) 308, 311 LED_BUILТIN 51 Код ответа 404 481 НТТР 481 Кодер поворотный 332 Команда analogWrite() 64 АТ 433 df 358
digitalRead() 71 digitalWrite() 52 GET 469 ipconfig 496 mkdosfs 359 ping 479 pinMode() 50, 51 POST 469 sudo 359 unmount 358 Wire.beginTransmission() 261 Wire.endTransmission() 261 Wire.requestFrom() 261 Wire.write() 261 Комментарии мноrострочные 50 однострочные 50 Компания Atmel 36, 37 Digital Loggers, Inc. 416 JeeLabs 374 Maxim Integrated 372 Microchip 36, 37 Nordic Semiconductor 426 NXP Semiconductors 372 PJRC 344 Конденсатор развязывающий 127 Короткое замыкание 116 Корпус, тип DIP 529 SMD 529 Коэффициент заполнения сигнала 65
л Линия MISO 273 MOSI 273 SCLK 273 ss 275 Логический оператор ИЛИ 76
м Макетная плата беспаечная 55 Маршрутизатор администрирование 495
ПРЕДМЕТНЫЙ УКАЗАТЕЛЬ 537
Микроконтроллер ATmega 16U2 190 32U4 439 328Р 525 Cortex МО 471 архитектура В-разрядная 37 32-разрядная 37 AVR 37, 38 Микросхема И-моста L293D 117 nRFS 430 WiFi WINC1500 473,475 акселерометра LIS3DH 277 гироскопа L3GD20H 297 датчика температуры AD7414 251 TC74 A0-5.0VAT 250 преобразователя USB/RS-232 СР2104 187 сдвигового регистра 74НС595 232 стабилизатора напряжения L7805CV 127 триггера Шмитта 74АНСТ14 340 часов реального времени DS1307 372 PCF8523 372 Миллиампер 58 Многозадачность 332 Модификатор F() 375, 432 Модуляция цифровых сигналов 402 широтно-импульсная 54, 64 Мощность номинальная 59 уравнение 59
н Напряжение опорное 86 электросети 414
о Облако 467 Объект DateТime 382 Serial 198 Объявление переменной 61 Оператор != 75