Text
                    Валерий Я цен ков
от Arduino до Omega:
платформы для меикеров
Санкт-Петербург
«БХВ-Петербург»
2018


УДК 004 ББК 32.973.26 Я92 Яценков В. С. Я92 От Arduino до Omega: платформы для мейкеров шаг за шагом. — СПб.: БХВ-Петербург, 2018. — 304 с: ил. — (Электроника) ISBN 978-5-9775-3863-3 Рассмотрен ряд современных программно-аппаратных платформ для люби- тельского творчества. Отобраны платформы простые для понимания новичками, с низкой ценой стартового комплекта, но в то же время производительные и рас- ширяемые, популярные в среде мейкеров, от школьников и студентов до руково- дителей кружков и преподавателей. Описаны современные онлайн-сервисы для разработки и макетирования любительских проектов Arduino Create и Autodesk Circuits. Рассказано об обучающей платформе Arduino и среде Arduino IDE, одно- кристальной системе ESP8266, платформе для Интернета вещей NodeMCU и языке Lua, микрокомпьютере Omega2 и облачной среде Onion Cloud. Приведены приме- ры программ и авторских проектов полезных устройств, особое внимание уделено ошибкам и трудностям, с которыми сталкиваются новички. В файловом архиве на сайте издательства предоставлены исходные коды программ, чертежи печатных плат и принципиальных схем. УДК 004 ББК 32.973.26 Для читателей, интересующихся электроникой, робототехникой, авиамоделизмом Группа подготовки издания: Главный редактор Екатерина Кондукова Зам. главного редактора Евгений Рыбаков Зав. редакцией Екатерина Капалыгина Редактор Григорий Добин Компьютерная верстка Ольги Сергиенко Корректор Зинаида Дмитриева Дизайн обложки Марины Дамбиевой Подписано в печать 31.08 17 Формат 70хЮ01/16. Печать офсетная. Усл. печ. л. 24,51 Тираж 1500 экз Заказ №5078. "БХВ-Петербург", 191036, Санкт-Петербург, Гончарная ул., 20. ООО "Печатное дело", 142300, МО, г Чехов, ул Полиграфистов, д 1 ISBN 978-5-9775-3863-3 © ооо "БХВ", 2018 © Оформление ООО "БХВ-Петербург", 2018
Оглавление Предисловие 9 Как работать с этой книгой? 10 Глава 1. Платформы для творчества и обучения 13 1.1. Не бойтесь экспериментировать! 14 1.2. Совместимость на уровне периферии и протоколов 16 1.3. Общие средства разработки и языки программирования 16 1.4. Облачные сервисы обмена данными 17 1.5. Онлайновые лаборатории и средства разработки 18 Глава 2. Советы для начинающих 19 2.1. Универсальные отладочные и макетные платы 19 2.2. Монтажные провода для пайки 23 2.3. Инструменты для подготовки проводов 25 2.4. Источники питания 26 2.4.1. Особенности питания от порта USB 27 2.4.2. Сетевые источники питания 28 Линейные стабилизаторы напряжения 28 Смещение рабочего напряжения стабилизатора 31 Импульсные преобразователи напряжения 31 2.4.3. Химические источники тока 33 Никель-кадмиевые аккумуляторы 34 Литиевые аккумуляторы 35 2.5. Согласование логических уровней 39 2.6. Интерфейсы обмена данными 41 2.6.1. Последовательный интерфейс UART 41 2.6.2. Конвертер интерфейсов USB-UART 43 2.6.3. Последовательная шина 12С 45 2.6.4. Последовательный интерфейс SPI 46 2.6.5. Последовательный протокол 1-Wire 47 2.7. Измерительное оборудование 48 2.7.1. Цифровой мультиметр 49 2.7.2. Цифровой осциллограф 49
Оглавление 2.8. Паяльное оборудование 51 2.9. Полезные программы и утилиты 53 2.9.1. PuTTY 53 2.9.2. WinSCP 54 2.9.3. Hercules 55 2.9.4. Termite 56 2.9.5. Notepad++ 57 Глава З. Онлайн-лаборатория Autodesk Circuits 59 3.1. Регистрация и первый проект 60 3.1.1. Создание макета и симуляция 60 3.1.2. Принципиальная электрическая схема макета 64 3.1.3. Печатная плата по схеме макета 64 3.2. Создание и редактирование компонентов 65 3.2.1. Создание символа компонента 67 3.2.2. Создание монтажного чертежа компонента 69 3.2.3. Работа с чужими компонентами 71 3.2.4. Доступ к своим компонентам 72 3.2.5. Рисование принципиальной схемы 72 3.3. Вывод схемы и чертежа платы на печать 73 3.3.1. Получение рисунка принципиальной схемы 73 3.3.2. Экспорт рисунка печатной платы в формате Eagle 73 3.3.3. Экспорт чертежа платы в формате GERBER 73 Глава 4. Среда разработки и макетирования Fritzing 75 4.1. Установка Fritzing 75 4.2. Создание макета схемы 76 4.3. Создание принципиальной электрической схемы 77 4.4. Разработка чертежа печатной платы 77 4.5. Экспорт чертежа печатной платы 78 4.6. Добавление компонентов в библиотеку 79 4.7. Разработка и загрузка программ 79 Глава 5. Обучающая платформа Arduino 80 5.1. Аппаратная база платформы, популярные модели 81 5.1.1. Arduino Nano 81 5.1.2. Arduino Uno 82 5.1.3. Arduino Pro Mini 82 5.1.4. Arduino Mega 2560 83 5.2. Установка драйверов USB-UART 83 5.3. Система нумерации выводов Arduino 84 5.4. Среда разработки и отладки Arduino IDE 85 5.4.1. Установка Arduino IDE 86 Установка для ОС Windows 86 Установка альтернативных версий IDE 86 Установка для ОС Linux 86 Установка для Mac OS X 87 5.4.2. Подключение платы Arduino и первые программы 88
Оглавление 5.4.3. Установка сторонних библиотек 92 Автоматическая установка библиотеки 93 Установка библиотеки вручную 93 5.4.4. Установка дополнительных описаний плат 94 Автоматическая установка описания 94 Установка описания вручную 95 5.4.5. Сетевой модуль расширения Dragino Yun 96 Почему именно Dragino Yun? 97 Технические характеристики Dragino Yun v2.4 97 Особенности питания шилда Dragino Yun 98 Добавление новых плат в Arduino IDE 99 Подключение к компьютеру для настройки 100 Функции кнопки сброса Dragino Yun 101 Обновление прошивки 102 Базовые настройки 103 Определение типа базовой платы 104 Загрузка скетча через сеть из Arduino IDE 105 Автоматическое обновление скетча 105 Использование консоли Dragino Yun для вывода сообщений 107 Глава б. Облачная среда разработки Arduino Create 110 6.1. Подготовка среды Arduino Create Ill 6.2. Онлайн-редактор Arduino Web Editor 112 Sketchbook 113 Examples 113 Libraries 113 Serial Monitor 114 Help 114 Preferences 114 6.3. Подключение платы Arduino и первая программа 115 6.4. Облачный сервис Arduino Cloud 116 6.5. Библиотека проектов Arduino Project Hub 117 Глава 7. Примеры программ и проектов для Arduino 119 7.1. Использование системного времени Linux 119 7.2. Сохранение данных на карту памяти 122 7.3. Сохранение данных на USB-накопитель 125 7.4. Сохранение данных в таблицу MySQL 125 7.5. Сервис Temboo и передача данных в Google Spreadsheet 128 7.6. Анализатор эфира в диапазоне 2,4 ГГц 137 7.6.1. Модуль радиоприемника 138 7.6.2. Модуль дисплея 139 7.6.3. Модуль Arduino 139 7.6.4. Напряжение питания и согласование логических уровней 139 7.6.5. Схема электрических соединений 140 7.6.6. Алгоритм работы устройства 140 7.7. Миниатюрный монитор силовой литий-полимерной батареи 147 7.7.1. Компоненты монитора 149 7.7.2. Алгоритм работы устройства 149
Оглавление 7.8. Установка библиотеки ATTiny 154 7.8.1. Подключение программатора 154 7.8.2. Установка фюзов микроконтроллера 156 7.8.3. Запись прошивки 157 7.8.4. Калибровка порога срабатывания 157 Глава 8. Однокристальная система ESP8266 159 8.1. Ученик обогнал учителя: феномен успеха ESP8266 159 8.1.1. Технические характеристики 160 8.1.2. Особенности эксплуатации 160 8.1.3. Модули на основе ESP8266 161 8.2. Расширение Arduino IDE для работы с ESP8266 163 8.2.1. Установка расширения 163 8.2.2. Особенности программирования ESP8266 163 Порты и прерывания 164 Функции задержки 164 Работа с EEPROM 165 Поддержка интерфейсов 12С и SPI 165 Специальные функции API ESP8266 165 Специальные функции библиотеки ESP8266WiFi 166 Обращение к функциям SDK ESP8266 из скетча Arduino 166 Глава 9. Примеры программ и проектов для ESP8266 168 9.1. Получение точного времени от сервера NTP 168 9.2. Получение уведомлений от устройств на Android 173 9.2.1. Скетч для принимающего устройства 174 9.2.2. Установка и настройка приложения Android 175 9.2.3. Настройка расширенных уведомлений с приложением Tasker 176 Настройка события Tasker — новое сообщение Viber 177 9.3. Модуль управления экшн-камерой Xiaomi Yui 179 9.3.1. Аппаратная часть модуля 180 9.3.2. Прошивка модуля 181 Алгоритм работы устройства 190 Измерение длительности импульсов 191 Совместимость программы модуля с разными версиями Arduino IDE и камеры 192 9.4. Адаптация взаимодействия с сервисом Temboo 193 Глава 10. Платформа NodeMCU для Интернета вещей 198 10.1. Подготовка к использованию NodeMCU 199 10.1.1. Рекомендованное оборудование 199 10.1.2. Подключение отладочной платы к компьютеру 201 10.1.3. Обновление прошивки NodeMCU 201 Конструктор прошивок 202 Возможная проблема: сбой обновления прошивки 204 10.2. Среда разработки ESPlorer IDE 207 10.3. Пакет разработки Lua for Windows 214 10.4. Язык программирования Lua — освоим за один вечер 215 10.4.1. Типы данных 217 10.4.2. Комментарии 218
Оглавление 10.4.3. Переменные и преобразование типов 218 10.4.4. Работа с таблицами и массивами 221 10.4.5. Условный оператор // 222 10.4.6. Цикл с предусловием while 223 10.4.7. Цикл с постусловием repeat 223 10.4.8 Цикл с оператором for 223 10.4.9. Операторы break и return 224 10.4.10. Функции 225 10.4.11. Функции обратного вызова 226 Глава 11. Примеры программ и проектов для NodeMCU 228 11.1. Использование графического OLED-дисплея 229 11.1.1. Подключение дисплея 229 11.1.2. Настройка модуля U8G 230 11.1.3. Пример программы 230 11.1.4. Монитор курса электронной валюты биткоин 232 Загрузка программы в отладочную плату 235 Алгоритм работы программы 236 11.1.5. Вывод на OLED-дисплей битовых изображений 237 Создание файла битового изображения 237 Пример программы 237 11.2. Использование графического TFT-дисплея 239 11.2.1. Подключение дисплея к плате NodeMCU 240 11.2.2. Пример использования графической библиотеки 240 Глава 12. Микрокомпьютер Omega2 245 12.1. Аппаратный состав платформы 246 12.2. Подготовка к работе 250 12.2.1. Настройка при помощи мастера 250 12.2.2. Настройка при помощи командной строки 253 12.3. Браузерное приложение Onion Console 255 12.4. Облачный сервис Onion Cloud 257 12.5. Python 2.7 и дополнительные модули 259 12.5.1. Управление портами GPIO 260 12.5.2. Модуль Python SPI 263 12.5.3. Модуль Python I2C 264 12.6. Файловый менеджер Midnight Commander 265 12.7. Расширение пространства памяти 266 12.7.1. Использование карты MicroSD и USB-накопителя 266 Размонтирование накопителя 267 Форматирование внешних накопителей 267 Изменение точки монтирования по умолчанию 268 12.7.2. Загрузка с внешней карты памяти 269 12.7.3. Своп-файл на внешнем носителе 271 12.7.4. Автоматическое включение своп-файла после перезагрузки 272 12.8. Особенности использования Omega2 274 12.8.1. Необходимость стабильного питания 274 12.8.2. Необходимость буферизации выводов 274
Оглавление Глава 13. Примеры программ и проектов для Omega2 276 13.1. Подключение OLED-дисплея 276 13.2. Подключение модуля PWM Servo 281 13.3. Подключение модуля расширителя портов 286 13.4. Модуль светодиодной матрицы 8x8 289 13.5. Модуль семисегментных светодиодных индикаторов 292 13.6. Автономный клиент BitTorrent 294 Приложение. Содержание электронного архива 299 Предметный указатель 301
Предисловие Не надо самому выпиливать кубики Лего. Следует знать, какие они бывают, где их купить, и уметь быстро соби- рать из них. Это совершенно иные навыки, чем разработ- ка игрушек с нуля. А. Себраит, директор «Яндекса» по маркетингу Как вы думаете, почему обучающий проект Arduino приобрел феноменальную из- вестность? С технической точки зрения, это всего лишь заурядный микроконтрол- лер Atmel, смонтированный на несложной плате с разъемами в сопровождении простой среды разработки программ Arduino IDE. Каждый производитель микро- схем выпускает отладочные платы и средства разработки приложений, но обычно ими пользуется лишь узкий круг профессионалов. Причина успеха Arduino в том, что из обучающего проекта он превратился в плат- форму для любительского творчества. Сложно провести четкую границу, за кото- рой средство разработки и отладки становится платформой. Сформулируем глав- ные требования к платформе для обучения и любительского творчества: ♦ простота для понимания новичками, старт с нуля; ♦ низкая цена стартового комплекта; ♦ расширяемость и дополняемость; ♦ достаточный запас производительности; ♦ вовлеченность сторонних производителей и энтузиастов; ♦ обширное сообщество единомышленников. Простота освоения и гибкость аппаратно-программного комплекса Arduino позво- ляют начать работу с простыми проектами даже в младшем школьном возрасте. Затем любитель электроники может впасть в растерянность— куда двигаться дальше? Мигающие светодиоды, датчики влажности и выключатели лампочек дав- но освоены. Хочется чего-то нового и необычного. Рано или поздно любитель вста- ет перед выбором из двух следующих альтернатив: ♦ углублять свои навыки в узкой областа, разрабатывая специфические проекты и осваивая особые приемы программирования;
j(0 Предисловие ♦ осваивать новые платформы с более широкими возможностями и на другом оборудовании. На самом деле, можно и нужно сочетать оба подхода. Далее в книге мы покажем, как это сделать. Успех Arduino не дает покоя разработчикам новых творческих проектов. В этой книге мы изучим несколько программно-аппаратных платформ для любительского творчества. Они существенно различаются между собой — как технически, так и концептуально. Тем не менее, они отлично уживаются вместе, потому что связаны общей идеей: легкий старт с нуля и быстрый рост полезных навыков. Восприни- майте эти платформы, как ступени лестницы, ведущей вверх. Отдельного упоминания заслуживают современные виртуальные средства для лю- бительских разработок. Существуют даже онлайн-лаборатории, позволяющие ма- кетировать устройства в окне браузера, подключать к ним измерительные приборы и проводить виртуальные эксперименты. Такие сервисы удачно дополняют аппа- ратную часть платформ и позволяют осваивать азы электроники без лишних затрат времени и денег. В этой книге мы также расскажем о средствах виртуального маке- тирования и разработки для любителей электроники. С хорошей обучающей платформой пользователь выходит далеко за рамки стан- дартных проектов, предложенных разработчиками платформы. Например, на базе Arduino Mega был создан проект полетного контроллера для квадрокоптеров. К не- му добавили акселерометры и гироскопы от игровой приставки Nintendo Wii, и по- лучился проект универсального контроллера MultiWii для летающих моделей. На основе платы Arduino Nano был разработан модуль дисплейной телеметрии для авиамоделей MinimOSD. Оба проекта давно живут самостоятельной жизнью, но для работы с программами по-прежнему используется среда Arduino DDE. Поэтому любой пользователь, немного знакомый с Arduino, без труда может обновить и даже изменить прошивки этих устройств. Соотношение цены и качества электронных компонентов имеет значение для любителей электроники, особенно если это школьники и студенты. Поэтому в опи- саниях прикладных проектов вы найдете рекомендации по выбору оптимального набора элементов. Имейте также в виду, что издательство «БХВ-Петербург» регу- лярно выпускает новые наборы электронных компонентов для технического твор- чества1. Как работать с этой книгой? В книге использован пошаговый переход «от простого к сложному» как в целом, так и внутри тематических глав, посвященных различным платформам. Однако если полностью раскрывать все тонкости настройки и использования их компонен- тов, то каждая глава превратится в самостоятельную книгу. Поэтому глава начина- 1 См. http://www.bhv.ru/books/list_covers.php?get=rubrics&id=233.
Предисловие 1J_ ется с минимального руководства по старту с нуля и сопровождается несколькими проектами разной сложности, иллюстрирующими возможности платформы. По- путно раскрываются некоторые особенности, редко упоминаемые в руководствах для начинающих. Благодаря такой структуре, вы можете начинать чтение книги с любого интере- сующего вас раздела либо изучать их параллельно, работая над комплексным про- ектом. В любом случае, прогресс в мире электроники стремителен, и даже за время подготовки книги к печати могут произойти большие изменения. Рассматривайте эту книгу, как путеводитель по миру технического творчества, и будьте готовы к потрясающим воображение достижениям современной электроники. Я буду бла- годарен за отзывы и пожелания, которые обязательно учту при подготовке сле- дующих изданий. Пишите мне по адресу: valeriy.yatsenkov@gmail.com. * * * Завершая предисловие, хочу отметить, что в русском языке нет полноценного ана- лога английскому слову maker. У этого слова много переводов: творец, создатель, творческая личность, поэт. В техническом контексте оно обозначает людей, кото- рые в удовольствие себе и на радость окружающим разрабатывают и воплощают различные проекты. Иными словами, maker— это креативный любитель-само- делыцик. Возможно, когда-то в русском языке приживется фонетическая калька «мейкер», но в этой книге я использую слово любитель, подразумевая любителя технического творчества, радиолюбителя или новичка в мире электроники.
ГЛАВА 1 Платформы для творчества и обучения В далеком детстве я начинал изучение электроники с конструктором «Электронные кубики». Он состоял из оснащенных контактами пластмассовых кубиков, внутри которых находились транзисторы, резисторы, конденсаторы и прочие электронные компоненты (рис. 1.1). Размещая кубики по схеме, можно было собрать много раз- ных устройств, вплоть до радиоприемника. Такой конструктор можно считать предком модульной обучающей платформы. Альтернативой «электронным куби- кам» были скромные наборы радиодеталей, из которых мы собирали мелодичные Рис. 1.1. Конструктор «Электронные кубики» (http://www.yaplakal.com/forum2/st/550/topic983074.html)
^4 Глава 1 дверные звонки, датчики влажности и прочие несложные устройства. Для разра- ботки и отладки собственных проектов следовало обладать изрядными знаниями и навыками. Все изменилось после прихода на рынок дешевых и мощных микроконтроллеров. Раньше мы собирали готовые схемы из множества различных радиодеталей. Теперь акцент творчества сместился на программирование функций универсального про- цессорного блока, к которому подключаются те или иные внешние устройства. В большинстве случаев пайка не требуется — модули соединяются между собой при помощи стандартных разъемов или монтируются на отладочной плате. Не надо беспокоиться и о функциональной и электрической совместимости модулей, об этом позаботились разработчики и производители оборудования. Модульный подход резко снизил входной порог знаний для новичков. Представи- тели традиционной инженерной школы иногда считают учебные платформы про- фанацией и пренебрежительно относятся к «ардуинщикам» за их поверхностные знания. Вероятно, некоторые профессионалы испытывают досаду от того, что элек- троника и программирование теряют мистический ореол знаний для избранных. Я не вижу проблемы в том, что работа с любительскими проектами дает поверхно- стные знания. Следует правильно определить область интересов. Для многих чита- телей электроника и программирование так и останутся увлекательным развлече- нием по вечерам. Получение системных фундаментальных знаний— это задача специального высшего образования, а не хобби. Разумеется, если речь идет о про- фессиональной деятельности, то применять в ней любительский подход действи- тельно будет дурным тоном. Я имею в виду так называемое «грязное проектирова- ние» без учета индустриальных стандартов, помехоустойчивости и прочих требо- ваний к профессиональному продукту. Но если вы хотите интересно и с пользой провести свободное время или обучить школьников основам будущей профессии, то нет ничего лучше, чем обучающие платформы, в которых сочетаются электрон- ное оборудование и программирование. Именно таким платформам посвящена эта книга. 1.1. Не бойтесь экспериментировать! Выбирая платформу для обучения или хобби, прежде всего, опирайтесь на свои сегодняшние потребности и базовые навыки. Не бойтесь, что слишком простое оборудование быстро исчерпает себя и будет напрасно лежать на полке. Благодаря модульной структуре, даже базовое оборудование можно долго дополнять и изу- чать. Приобретенные ранее навыки и оборудование сполна пригодятся вам при ра- боте с другими платформами. Платформы и модули расширения совместимы между собой намного лучше, чем это может показаться неопытному пользователю. Поэтому купленные для Arduino датчики, индикаторы или исполнительные механизмы вы сможете легко применить для новой платформы, будь то Raspberry Pi или Omega2. В равной мере это отно- сится к полученным ранее знаниям и навыкам.
Платформы для творчества и обучения 15_ По критерию процессорной части платформы можно условно разделить на два больших семейства: 1. Базовые устройства на основе микроконтроллеров малой и средней мощности. Программируются на уровне прошивки микроконтроллера. Взаимодействуют с простыми периферийными модулями (сенсоры, индикаторы) и решают отно- сительно несложные задачи. 2. Базовые устройства на основе более мощных процессоров. Работают под управ- лением традиционных операционных систем (Linux, Android, Windows IoT Core) и представляют собой компактный компьютер. Взаимодействуют как с внешни- ми модулями, так и с другими компьютерами. Позволяют разрабатывать и вы- полнять сложные программы на языках высокого уровня. Часто имеют видео- подсистему, могут подключаться к телевизору или компьютерному дисплею. Характерным примером платформы первого типа является Arduino, работающая на базе микроконтроллеров компании Atmel. Для этой платформы выпускается широ- чайший ассортимент модулей расширения, допускающих сборку и отладку люби- тельских конструкций без пайки. В исходном виде оборудование этой платформы мало подходит для встраиваемых применений наподобие центра управления «ум- ным домом» — слишком ненадежна и неуклюжа конструкция, состоящая только из макетных плат. Отладочные платы Arduino можно успешно использовать для тес- тирования программного обеспечения и конструкции компонентов «умного дома» с последующим переносом прошивок в специально изготовленные устройства. В качестве примера платформы второго типа можно привести Raspberry Pi. Это полноценный микрокомпьютер с операционной и файловой системами, но осна- щенный аппаратными портами ввода/вывода и видеоподсистемой. К нему можно подключать исполнительные устройства и внешние модули. Некоторые платформы занимают промежуточное положение. Например, это бес- проводная платформа для «умного дома» NodeMCU. Она оснащена встроенным интерпретатором языка Lua и файловой системой. В то же время, для устройств этой платформы можно создавать программы в среде Arduino IDE, а многие модули предназначены для макетного монтажа. Платформы также можно условно различать по степени модульности. Модульный подход в большей или меньшей степени присущ практически всем любительским платформам. Благодаря модульной конструкции обеспечивается расширяемость и низкая стоимость начального набора компонентов. Нужные модули можно приоб- ретать по мере необходимости. Эти модули принято также называть шилдами (от англ. shield—навесная монтажная плата). Лидером по количеству расширяющих модулей является платформа Arduino. Для нее выпускаются все мыслимые варианты внешних устройств— от одиночной лампочки или кнопки до цветного графического дисплея и приемника GPS. Можно сделать вывод, что чем проще «ядро» платформы, тем больше функциональности возлагается на подключаемую периферию. Это спорное обобщение, но в целом оно верно отражает положение дел.
J6 Глава 1 1.2. Совместимость на уровне периферии и протоколов В большинстве модулей используются стандартные протоколы и каналы обмена данными (UART, SPI, I2C, 1-Wire, Wi-Fi, Bluetooth). Поэтому одни и те же перифе- рийные устройства могут использоваться в проектах на основе разных платформ. Трудности могут возникнуть из-за отсутствия на некоторых платформах готовых библиотек устройств. В этом случае вам придется потрудиться немного больше, чтобы понять, как устроена и работает библиотека этого устройства на другой платформе, а затем перенести программу на новое оборудование. Это один из при- знаков вашего творческого роста. Устройство на основе Arduino само по себе может стать внешним модулем для бо- лее мощной платформы. Например, на основе платы Arduino можно изготовить многофункциональный выносной модуль метеостанции, который будет измерять температуру, влажность, давление, освещенность и по Bluetooth или Wi-Fi переда- вать данные центральному узлу на основе Raspberry Pi. В этом случае найдется применение не только оборудованию, но и навыкам программирования в сре- де Arduino IDE. 1.3. Общие средства разработки и языки программирования Среда разработки программ Arduino IDE и язык Wiring/Processing, на котором пи- шут программы для Arduino, столь же популярны и просты, как и оборудование, на котором они работают. Поэтому реализацию среды разработки можно найти в са- мых неожиданных местах. Например, поддержка языка Processing в стиле Arduino IDE есть в специальном расширении среды Visual Studio 2015 для Windows. Вы можете написать программу на привычном для вас простом языке Processing и выгрузить ее в микрокомпьютер Raspberry Pi 3 с операционной системой Win- dows lOIoTCore. После этого вам останется один шаг до программирования на языке C++. Совсем недавно считалось, что трудно придумать более непохожие сре- ды программирования и устройства. Но спрос рождает предложение. Можно поступить проще и установить Arduino IDE для ОС Linux на микрокомпью- тер Raspberry Pi, чтобы использовать его, как универсальное средство разработки в домашней лаборатории. Общие языки программирования также облегчают переход между платформами. Кроме уже упомянутого языка Processing, являющегося вариацией C++, вы можете писать программы на скриптовом языке Lua, который применяется даже при разра- ботке приложений для ОС Android. Можно сменить прошивку NodeMCU на MicroPython, чтобы освоить язык Python, а затем программировать на нем для Omega2 и других устройств. Подробнее об этом будет сказано в следующих главах.
Платформы для творчества и обучения 17 1.4. Облачные сервисы обмена данными Кроме прямого физического обмена данными между платформами вы можете ис- пользовать облачные сервисы. Что это такое? Облачный сервис представляет собой сервер в Интернете, на котором работают специальные программы, а также имеется пространство для хранения пользовательских данных. Обычный пользователь не знает, где физически находятся серверы и устройства хранения данных. С его точки зрения, обмен данными происходит с неким виртуальным «информационным обла- ком» Интернета. Ваше устройство может соединяться через Интернет с облачным сервисом, чтобы передать серверу данные для обработки и хранения, либо получить команды и дан- ные с вашего компьютера или планшета (рис. 1.2). Каждое устройство, подключен- ное к облаку, получает уникальное имя или номер и пароль. Образно говоря, об- лачный сервис играет две роли: посредника в обмене данными и нотариуса, кото- рый заверяет подлинность соединений. ОБЛАЧНЫЙ СЕРВИС Рис. 1.2. Взаимодействие устройств с облачным сервисом Устройства, взаимодействующие с облачным сервисом, могут быть разбросаны по всему земному шару. Необходимо иметь лишь доступ в Интернет в нужное время. Иногда, в особых случаях, данные передают при помощи SMS или в сообщениях электронной почты. Функциональность облачного сервиса не зависит от того, ком- понент какой из платформ к нему обращается. Устройства пользователей могут быть самыми разными, но должны передавать и получать данные в заранее огово- ренном формате сервиса (API, Application Programming Interface, формат обмена между приложениями). Сервер обрабатывает и компонует данные для представления в удобном виде. На- пример, зайдя на страницу облачного сервиса со стационарного компьютера или смартфона, вы можете посмотреть статистику потребления электроэнергии «умно-
18^ Глава 1 го дома» или диаграмму скорости бега в колесе вашего любимого хомяка. При этом подсчет пробега хомяка будет выполнять устройство на основе платы Arduino и оптического датчика вращения, а рассматривать отчет сервиса можно на дисплее, подключенном к Raspberry Pi. 1.5. Онлайновые лаборатории и средства разработки Облачные сервисы используются не только для управления Интернетом вещей (IoT, Internet of Things) и сбора данных с датчиков. Набирают популярность онлай- новые лаборатории для разработки и макетирования любительских проектов. Такие сервисы сочетают в себе возможности облачной технологии и компьютерных си- муляторов электронных схем. Если раньше для разработки схемы и печатной платы устройства нужно было устанавливать приложение на стационарный компьютер, то теперь можно вести разработку и виртуальное макетирование, а также запускать симуляцию схемы и даже прошивки контроллера в окне браузера. В некоторых онлайн-лабораториях есть виртуальные измерительные приборы, которые можно «подключать» к схеме. Разумеется, в первую очередь создаются облачные среды разработки для самых популярных платформ, таких как Arduino и Raspberry Pi. Проекты пользователей сохраняются в облаке и доступны из любого места, где есть Интернет. В большинстве случаев обеспечивается независимость от операционной системы компьютера. Можно организовать совместную работу в команде, члены которой разбросаны по всему миру, или опубликовать проект на своей странице в соцсети. * * * В этой главе мы схематически обрисовали некоторые варианты взаимодействия и совместного использования устройств, чтобы показать: чем больше платформ вы освоили и чем сильнее они различаются, тем богаче возможности для творчества. В следующих главах вы изучите приемы работы с популярными платформами и сервисами.
ГЛАВА 2 Советы для начинающих Вы можете начать изучение любительских проектов с готового набора деталей, но рано или поздно столкнетесь с необходимостью приобретать дополнительные модули, макетировать собственные разработки и сопрягать их между собой. В этой главе мы рассмотрим общие вопросы макетирования, электропитания и сопряже- ния различных элементов любительских конструкций. 2.1. Универсальные отладочные и макетные платы Наиболее популярны два типа плат для отладки и макетирования электронных уст- ройств: беспаечные (ламелъные) и печатные. Примеры макетных плат ламельного типа приведены на рис. 2.1, а плат печатного типа — на рис. 2.4. Внутри у беспаечных макетных плат находятся упругие пластинчатые контакты — ламели, изготовленные из фосфористой бронзы, покрытой никелем. Сверху ламели а б Рис. 2.1. Макетная плата ламельного типа (а) и ее внутреннее устройство (б)
20 Глава 2 накрыты трафаретом с отверстиями. Отверстия расположены на стандартном рас- стоянии 2,54 мм по горизонтали и вертикали. В них можно вставлять как гребенча- тые разъемы модулей, так и выводы микросхем в корпусах типа DIP. Как видно на разрезе платы, по две шины питания проходят вдоль длинных сторон платы, а на поле для монтажа деталей короткие шины расположены поперек и соединяют группы по пять отверстий. В англоязычном мире такие платы называют breadboard (доска для резки хлеба). У этого термина занятная история. Дело в том, что для моделирования первых радиолюбительских конструкций действительно применяли деревянные разделоч- ные доски, на которые шурупами прикручивали проводники и радиодетали (рис. 2.2). Рис. 2.2. Так выглядели макетные платы на кухонной разделочной доске (http://electronics.stackexchange.com/questions/48516/why-are-they-called-breadboards) Достоинства беспаечной платы: ♦ простота и наглядность при макетировании несложных схем; ♦ универсальность; ♦ возможность многократного макетирования без потери свойств или разрушения; ♦ отсутствие необходимости в пайке; ♦ возможность быстро изменить схему соединений, добавить или удалить компо- ненты.
Советы для начинающих 21_ Недостатки беспаечной платы: ♦ большое количество ненадежных контактов в схеме, «шумы» в контактах; ♦ сильные взаимные помехи в соединительных проводах; ♦ сложность использования компонентов для поверхностного монтажа и малога- баритных компонентов; ♦ путаница и большая вероятность ошибки в соединениях при макетировании сложных схем. Беспаечные платы идеально подходят для быстрого и наглядного макетирования несложных устройств, но неприменимы для окончательной сборки законченных изделий. Для соединений между модулями и компонентами на ламельной плате вам потре- буется набор специальных соединительных проводов. Это гибкие разноцветные провода с разъемной частью на обоих концах (рис. 2.3). Наверняка вы уже видели такие или подобные соединители. а 6 в Рис. 2.3. Различные варианты соединительных проводов для макетирования Провода с разъемами типа штекер-гнездо (рис. 2.3, а) применяются для подключе- ния выносных модулей или компонентов, расположенных за пределами макетной платы. Штекеры вставляются в гнезда макетной платы, а гнезда надеваются на разъем модуля или выводы радиоэлемента. Провода с разъемами типа гнездо- гнездо (рис. 2.3, б) могут использоваться для соединения модулей между собой на- прямую, вообще без макетной платы. Наиболее часто применяют провода типа штекер-штекер (рис. 2.3, в) — с их помощью выполняют большинство соединений на макетной плате. Таких проводов разной длины и цвета в наборе должно быть больше всего. В крайнем случае можно использовать самодельные провода с за- чищенными на 4-5 мм концами. Хорошо подходят отрезки провода КСВВ 4x0.4, который используется при монтаже пожарно-охранной сигнализации. Но все-таки лучше сразу приобрести большой набор готовых соединительных проводов. Они прослужат вам много лет.
22 Глава 2 Если вы увлеклись техническим хобби, рано или поздно вам придется научиться паять. Но осваивать основы электроники лучше всего с беспаечными макетными платами. Это сэкономит много времени и сил. Даже при наличии большого опыта и хорошей домашней мастерской беспаечные платы остаются удобным средством макетирования. Я радиоинженер, занимаюсь радиолюбительством более тридцати лет и могу изготавливать дома печатные платы высокого качества. Но все равно использую беспаечные платы, когда нужно быстро макетировать устройство, со- стоящее из готовых модулей и небольшого количества навесных компонентов. Это особенно удобно в ситуациях, когда основное внимание следует уделить разработ- ке и тестированию прошивки. Иногда оказывается, что идея не оправдала себя, или устройство лучше выполнить на другой элементной базе. В таком случае пайка ма- кетной платы и, тем более, изготовление пробной печатной платы были бы напрас- ной тратой времени. Рис. 2.4. Печатные макетные платы Макетные печатные платы изготавливают по той же технологии, что и обычные печатные платы, с готовыми отверстиями под выводы элементов и контактными площадками (рис. 2.4, а). Шаг отверстий, как правило, стандартный, 2,54 мм (0,1 дюйма). Такое же межвыводное расстояние применяется в разъемах плат и мо- дулей Arduino и многих других модулей. Некоторые макетные платы оснащены монтажными площадками под микросхемы и дискретные элементы для поверхно- стного монтажа. Для желающих разрабатывать собственные расширения в стиле Arduino выпускают комбинированные макетные платы (рис. 2.4, б). Кроме про- странства для макетирования они имеют установленные гребенчатые разъемы и по габаритам совместимы с разъемами популярных плат Arduino или Raspberry Pi. Для покупки в зарубежных интернет-магазинах ищите печатные макетные платы по ключевым словам Prototype рсв (Printed Circuit Board — печатная плата). Беспаеч- ные платы продаются под названием Solderless Breadboard. Печатные макетные платы тоже имеют достоинства и недостатки. Достоинства печатных плат: ♦ можно выпилить из большой заготовки макетную плату нужного размера и формы;
Советы для начинающих 23^ ♦ печатные макетные платы выпускают в широчайшем ассортименте, часто с го- товыми установочными местами под микросхемы и прочие компоненты; ♦ паяные соединения на них компактны, аккуратны и надежны; ♦ в некоторых случаях можно обойтись без изготовления постоянной платы и по- местить в корпус любительского устройства схему на макетной плате. Недостатки печатных плат имеют значение, прежде всего, для новичка: ♦ для монтажа деталей требуются навыки пайки и паяльное оборудование; ♦ скорость монтажа пайкой у новичков обычно низкая; ♦ припаянные детали сложно использовать повторно, а испорченные детали труд- но заменять. Для соединений на печатной макетной плате используют разные способы. Некото- рые компоненты удается соединить между собой непосредственно при помощи их выводов, пропуская их через отверстия платы и отгибая в стороны. Если соедине- ния не пересекаются, применяются одножильные луженые проводники. В осталь- ных случаях обычно используют гибкие изолированные провода. 2.2. Монтажные провода для пайки У мягких монтажных проводов в виниловой изоляции, которые обычно применяют радиолюбители, есть серьезный недостаток. При попытке залудить и припаять за- чищенный кончик провода изоляция сокращается по длине и плавится от нагрева, оголяя излишний участок провода. Это досадное явление очень мешает работе и грозит замыканиями. Проблему можно решить двумя способами: опытным путем подобрать провода, изоляция которых плохо плавится и не стягивается при нагреве, либо использовать провода в специальной термостойкой изоляции из фторопласта (МГТФ) или силикона. Провода в изоляции из фторопласта редко встречаются в продаже и дорого стоят. Они также редко бывают окрашены в разные цвета. Тонкие провода в силиконовой изоляции идеально подходят для макетирования и монтажа любительских конструкций. Они легко зачищаются и лудятся, их силико- новая изоляция не плавится даже при сильном нагреве. Несколько лет назад тонкие силиконовые провода стоили весьма дорого и редко встречались в продаже. Сейчас такие провода можно найти в китайских и российских интернет-магазинах. При- чем, у российских продавцов цены зачастую ниже (но ассортимент меньше). Что- бы не ошибиться в выборе проводов, следует разбираться в их маркировке. Диаметр провода обозначается аббревиатурой AWG (American Wire Gauge). Иногда числовое значение AWG называют калибром провода. Исторически значение AWG происходит от технологии производства проволоки волочением. Заготовку, которая обозначается как 0AWG, последовательно протягивают через ряд уменьшающихся калиброванных отверстий (волоков, фильер). Соответственно, числовое значение AWG обозначает количество протягиваний. Поэтому, чем больше значение AWG, тем тоньше провод. Например, обозначение 24AWG (или AWG24) соответствует диаметру проводника, который протянули через стандартные дюймовые фильеры 24 раза.
24 Глава 2 Многожильные монтажные провода состоят из большого количества скрученных тонких проводников (рабочих жил), поэтому калибр AWG относится к общему диаметру проводящей жилы. Отдельно в характеристиках провода указывают количество рабочих жил и их диаметр. Чем тоньше рабочие жилы, тем мягче и гибче монтажный провод в целом. Усредненные характеристики многожильных проводов по шкале AWG приведены в табл. 2.1. Данные из этой таблицы можно использовать при выборе мягких мон- тажных проводов, как в силиконовой, так и в виниловой изоляции. В зависимости от производителя, диаметр рабочих жил, их количество и толщина изоляции могут незначительно различаться. В радиолюбительской практике для монтажа и макетирования удобнее всего ис- пользовать провода 30AWG, 28AWG и 26AWG. Более толстые провода используют для питания силовых цепей. Например, в электрических авиамоделях для подклю- чения силовых литий-полимерных батарей обычно применяют провода калибром Таблица 2.1. Размерность электрических проводов по шкале AWG (одиночная рабочая жила 0,0В мм) Калибр noAWG 30AWG 28AWG 26AWG 24AWG 22AWG 20AWG 18AWG 16AWG 14AWG 12AWG 10AWG 8AWG 6AWG Кол-во жил 11 16 30 40 60 100 150 252 400 680 1050 1650 3200 Диаметр проводника, мм 0,30 0,32 0,44 0,58 0,72 0,92 1,20 1,53 1,75 2,50 3,60 4,40 5,20 Внешний диаметр, мм 0,8 1,2 1,5 1,6 1,7 1,8 2,3 3,0 3,5 4,5 5,8 6,3 8,5 Толщина изоляции, мм 0,05 0,08 0,15 0,20 0,30 0,50 0,55 0,80 0,90 1,00 1,20 1,20 1,65 Предельный рабочий ток, А 0,8 1,2 3,5 5,0 8,7 13 22 35 55 88 140 190 230 Если нужно быстро найти подручные монтажные провода для макетирования, а покупать их некогда, попробуйте очистить от внешней изоляции тонкий ненужный USB-кабель, которыми обычно комплектуют различные китайские гаджеты. Как правило, таких кабелей со временем накапливается дома довольно много, и они лежат без дела. Хорошо подходят жилы кабеля от неисправной компьютерной
Советы для начинающих 25_ мыши — они тонкие и мягкие. К сожалению, такие провода часто бывают рассчи- таны на монтаж обжимкой в разъемах и плохо переносят пайку. 2.3. Инструменты для подготовки проводов При макетировании пайкой на печатной плате кончики соединительных проводов приходится зачищать десятки и сотни раз. Именно эта операция занимает больше всего времени. Для быстрой и аккуратной зачистки монтажных проводов применя- ют инструменты различной конструкции под общим названием стриппер (stripper). Пример такого устройства показан на рис. 2.5. Рис. 2.5. Стриппер для зачистки проводов в виниловой и силиконовой изоляции К сожалению, профессиональные стрипперы слишком дорогие, громоздкие, зани- мают много места в рабочем столе и редко подходят для зачистки тонких монтаж- ных проводов калибра 28...30AWG. Я давно и успешно применяю самодельное приспособление (рис. 2.6). Это очень простое и компактное устройство можно сделать за один вечер из подручных материалов. Для его изготовления вам потре- буются: ♦ старый металлический пинцет; ♦ обломки закаленного полотна от ножовки по металлу; ♦ алмазный надфиль или ручная бормашинка с алмазным диском; ♦ винт М2... МЗ для регулировки; ♦ паяльник мощностью 60... 100 ватт, припой, кислотный флюс. Изготовьте рабочие режущие пластины из ножовочного полотна. Постарайтесь сра- зу как можно аккуратнее заточить режущие кромки под углом около 30 градусов. Лучше всего делать это при помощи алмазного надфиля.
26 Глава 2 Укоротите пинцет примерно наполовину. С одной стороны просверлите отверстие под регулировочный винт. Бели нет возможности нарезать в отверстии резьбу, припаяйте гайку нужного размера. Припаяйте режущие пластины к остаткам пин- цета. Обратите внимание на правильную ориентацию пластин — они должны рабо- тать по принципу ножниц, то есть при сближении соприкасаться плоскими сторо- нами выреза (рис. 2.6, а). Чтобы регулировочный винт не проворачивался самопро- извольно, используйте пружину или стопорную гайку (рис. 2.6, б). На этом изготовление самодельного стриппера окончено. Остается отрегулировать смыкание пластин таким образом, чтобы они надрезали изоляцию, но не поврежда- ли центральную жилу провода. а б Рис. 2.6. Самодельный стриппер для зачистки проводов 2.4. Источники питания К организации электропитания своих устройств нельзя относиться легкомысленно. Многие проблемы в работе электронного оборудования возникают именно по при- чине некачественного источника питания: ♦ недостаточной его мощности; ♦ заниженном или завышенном выходном напряжении; ♦ пульсации питающего напряжения; ♦ помех в цепях питания. Попытка сэкономить, используя кустарные или некачественные источники пита- ния, обычно заканчивается испорченным оборудованием, которое стоит значитель- но дороже источника, а на ремонт уходит больше времени, чем на подготовку пра- вильного электропитания. В любительской электронике обычно применяется питающее напряжение 5 В, но ему на смену в новых устройствах приходит напряжение 3,3 В. Это стандартное на- пряжение питания большинства современных микросхем. К сожалению, сейчас для питания любительских проектов часто требуются оба напряжения, потому что в од- ной конструкции объединяются старые и новые компоненты, но не все новые моду-
Советы для начинающих 27_ ли снабжены встроенным источником +3,3 В. Попытка запитать такое устройство напряжением 5 В, равно как и переполюсовка, приводит к мгновенному выходу низ- ковольтных микросхем из строя. Будьте предельно внимательны при подключении линий питания! 2.4.1. Особенности питания от порта USB Вариант питания от компьютерного порта USB наиболее часто встречается в люби- тельской практике, особенно во время разработки и отладки устройства. Он удобен, когда вы подключаете устройство через встроенный или внешний конвертер USB- UART для программирования и настройки. По одному кабелю происходит обмен данными с компьютером и поступает питание на устройство. Но порты USB имеют ограничения по предельному току в нагрузке. За потребляе- мым током следит хост-контроллер. Это специальная микросхема на материнской плате компьютера, которая обеспечивает работу портов. Стандартом USB преду- смотрены предельные токи, потребляемые от порта: USB 2.0 — до 500 мА, USB 3.0 — до 950 мА. Для большинства любительских устройств этого вполне дос- таточно. Если же в устройстве применяется мощный процессор, светодиоды, элек- тромоторы, дисплей, то предельный ток порта может быть превышен. Порты USB снабжены защитой от замыканий в цепи питания. Обычно это самовос- станавливающийся предохранитель, установленный на материнской плате. Он вос- станавливает свои проводящие свойства через некоторое время после срабатыва- ния. Если после замыкания в нагрузке и повторного включения компьютера на разъеме порта не появилось питающее напряжение, не пугайтесь. Отключите ком- пьютер и дайте предохранителю 20-30 минут на восстановление. При экспериментах с самодельными устройствами, имеющими комбинированное питание USB/батареи, велика вероятность случайно подать на порт USB так назы- ваемое встречное напряжение питания. Это может повредить материнскую плату, особенно в ноутбуках! В качественных модулях заводского производства устанав- ливают защитно-развязывающие диоды, подключенные по схеме, приведенной на рис. 2.7. Батарею подключают к клемме +VBAT, а плюсовую линию питания от разъема USB — к клемме +5V USB. В зависимости от того, на какой из клемм присутствует +5V USB D1 С=2ЕЗ И 1 4-VBAT D2 =s И—> > Питание устройство GND GND I >—I Г 1—> I Т Рис. 2.7. Защитно-развязывающие диоды в цепи питания устройства
_28 Глава 2 напряжение питания, ток протекает либо через диод D1, либо через D2. Если под- ключить одновременно два источника, устройство будет питаться от того из них, чье напряжение выше. Относительно полярности батареи диод D1 включен встречно, поэтому не может проводить ток от батареи в порт USB. Аналогично, напряжение порта USB не мо- жет повредить батарею благодаря диоду D2. Кроме того, эти диоды защищают уст- ройство от переполюсовки питания — самой частой причины необратимой полом- ки любительских устройств. Если конструкция исключает подсоединение двух ис- точников одновременно, то устанавливается один диод. Он защищает устройство от переполюсовки, а порт USB — от случайной подачи встречного напряжения. Несмотря на то, что в защитно-развязывающих цепях применяют специальные дио- ды с пониженным падением прямого напряжения (Low-Drop diode), напряжение по- рядка 0,2-0,3 В все же падает на полупроводниковом переходе диода. Кроме того, на USB-портах некоторых компьютеров присутствует слегка сниженное напряжение питания, около 4,7...4,8 В. В таком случае оставшееся напряжение порядка 4,5 В может оказаться слишком низким для питания устройства. Например, производите- ли авиамодельной бортовой электроники для питания полетных контроллеров часто рекомендуют использовать источники напряжением 5,25...5,35 В, чтобы компенси- ровать падение напряжения на диодах. Заниженное напряжение питания приводит к нестабильной работе устройства и выражается в самопроизвольной перезагрузке или «зависании» микроконтроллеров и хаотичных показаниях датчиков. На поиск причины сбоев может уйти много времени. Если устройство без видимых причин ведет себя непредсказуемо, начните с проверки качества питания. 2.4.2. Сетевые источники питания Стандартный сетевой адаптер (Wall Adaptor) от любого гаджета — это второй по популярности источник питания любительских устройств. Он полностью готов к использованию и имеет защиту от перегрузки. Следует лишь удостовериться, что он обеспечивает на выходе именно 5 В и достаточный ток. Желательно использо- вать адаптер с гнездом USB, так как это позволит применять стандартные провода для питания многих популярных отладочных модулей. Не используйте дешевые подделки под сетевые адаптеры Apple— внутри у них находятся примитивные схемы без какой-либо защиты. Обратите внимание, что се- тевые адаптеры большинства планшетов выдают напряжение от 7 до 9 В. В этом случае вам понадобится дополнительный регулятор напряжения. В случаях, когда требуется несколько питающих напряжений, либо выходное на- пряжение источника не соответствует нужному значению, применяются различные преобразователи напряжения. Они могут понижать или повышать исходное на- пряжение. Далее мы рассмотрим различные варианты преобразователей. Линейные стабилизаторы напряжения Линейные стабилизаторы напряжения, по сути, представляют собой регулируемое сопротивление с источником образцового напряжения и цепью обратной связи. Если входное напряжение растет, то ровно в такой же степени (линейно) возрастает
Советы для начинающих 29 внутреннее сопротивление регулятора. Благодаря этому выходное напряжение не меняется. Аналогичным образом регулятор поддерживает напряжение на выходе при колебаниях мощности нагрузки. Регулятор реагирует на изменение напряжения по линейному закону, отсюда происходит название стабилизатора. Современные линейные стабилизаторы представляют собой микросхему, на вход которой подают исходное напряжение, а на выходе получают стабильное заданное напряжение, которое определяется номиналом микросхемы (рис. 2.8). Обычно в любительской практике востребованы напряжения 5 и 3,3 В. Если напряжение 5 В можно получить от порта USB или сетевого источника в готовом виде, то на- пряжение 3,3 В в любом случае придется формировать отдельно. Достоинства линейных стабилизаторов: ♦ очень низкая цена и доступность в продаже; ♦ маленькие габариты; ♦ готовые стандартные напряжения; ♦ простота монтажа и ремонта. Недостатки линейных стабилизаторов: ♦ низкий КПД — стабилизатор включается последовательно с нагрузкой, и изли- шек напряжения падает на стабилизаторе. При этом стабилизатор нагревается, а лишняя энергия напрасно теряется в виде тепла. Чем больше падение напряже- ния (разность напряжения между входом и выходом) и ток в цепи, тем сильнее нагревается стабилизатор. Терять в виде тепла драгоценную энергию батарей — расточительно; ♦ ограниченный диапазон входных напряжений. Например, для обычного стаби- лизатора на 5 В допустимое входное напряжение редко превышает 15 В; ♦ линейные стабилизаторы работают только на понижение входного напряжения. +7...+12V IN Ш 1 I )—I IN OUT GND GND 1 >-4 1 U2 IN OUT GND +5V OUT IN 1 1 ? 1 +3.3V OUT 1—> 1 GND Рис. 2.8. Схема последовательного включения линейных стабилизаторов питания Перечисленные недостатки линейных стабилизаторов во многих случаях с лихвой перекрываются их дешевизной, распространенностью и схемной простотой. Осо- бенно хорошо они подходят для несложных устройств с низким потреблением тока.
30 Глава 2 К этой категории относятся и любительские схемы. Рекомендую приобрести ли- нейный стабилизатор, оформленный в виде модуля, совместимого по установоч- ным размерам со стандартной беспаечной макетной платой. Один из вариантов та- кого модуля изображен на рис. 2.9. Он формирует стандартные напряжения +5 и +3,3 В. При помощи перемычек можно раздельно задать напряжения на обеих ши- нах вдоль макетной платы. Разумеется, для такого стабилизатора нужен внешний источник с выходным напряжением +7...+15 В. Основные элементы модуля (рис. 2.9): ♦ 1,2 — переключатели напряжения +5/+3,3 на шине питания; ♦ 3 — линейный стабилизатор +5 В; ♦ 4 — линейный стабилизатор +3,3 В; ♦ 5 — диод защиты от переполюсовки входного напряжения; ♦ 6 — разъем для подключения внешнего источника питания +7...+15 В; ♦ 7 — разъем USB с выходным напряжением +5 В для подключения внешних по- требителей. Микросхемы стабилизатора серии AMS1117 выдерживают ток нагрузки до 1 А (при условии, что внешний источник способен обеспечить такой ток). Но не забы- вайте, что чем выше входное напряжение, тем сильнее нагрев стабилизатора. Рис. 2.9. Источник питания для беспаечной макетной платы
Советы для начинающих 31 Смещение рабочего напряжения стабилизатора В обычных интегральных стабилизаторах не предусмотрена регулировка выходно- го напряжения. Но если нужно незначительно повысить выходное напряжение, чтобы компенсировать падение на защитном диоде, можно прибегнуть к неболь- шой хитрости. Включите в разрыв «земляного» провода стабилизатора диод, как показано на рис. 2.10. Такой прием называется смещением нулевой точки относи- тельно физической «земли». В нашем случае на /?-«-переходе диода будет падать некоторое прямое напряжение, и ровно на такую же величину возрастет выходное напряжение стабилизатора. Величина падения напряжения зависит от типа диода. На переходе обычного кремниевого диода падает порядка 0,7...0,9 В, на переходе диода Шоттки— порядка 0,2...0,4В. Если в качестве смещающего диода вы ис- пользуете такой же диод, как в защитной схеме (см. рис. 2.7), это будет наилучшим решением, поскольку вы поднимете напряжение питания точно на величину паде- ния прямого напряжения на защитном диоде, и надежность работы устройства уве- личится. +7...+12V IN U1 IN OUT GND +5.3V OUT GND GND н—> i Рис. 2.10. Повышение выходного напряжения линейного стабилизатора Импульсные преобразователи напряжения Современные импульсные преобразователи напряжения состоят всего из несколь- ких недорогих компонентов и занимают мало места на плате, при этом их КПД значительно выше, чем у линейных стабилизаторов. Они почти не греются при токе в несколько ампер и могут не только понижать, но и повышать рабочее напряже- ние. Их выходное напряжение можно легко настраивать при помощи переменного резистора. Благодаря этим свойствам импульсные преобразователи постепенно вы- тесняют линейные стабилизаторы. В импульсных преобразователях постоянное входное напряжение при помощи встроенного генератора и силового ключа преобразуется в импульсы высокой час- тоты с регулируемой длительностью. Отношение периода повторения электриче- ских импульсов к их длительности называется скважностью S, а обратная величи- на 7s называется коэффициентом заполнения. Чем выше коэффициент заполнения,
32 Глава 2 тем больше количество энергии, передаваемой с входа преобразователя на выход, и тем выше напряжение на выходном каскаде. Напряжение регулируется только за счет длительности активных импульсов. Все остальное время ток через силовой ключ не протекает, поэтому потери энергии минимальны. КПД импульсного регулятора достигает 95%. В отличие от линейно- го стабилизатора, работающего только с понижением напряжения, импульсные преобразователи могут быть как понижающими (Step-Down Converter), так и по- вышающими (Step-Up Converter), а по типу схемы бестрансформаторными (Switched ВЕС) и трансформаторными (UBEC). Чаще используются бестрансфор- маторные понижающие преобразователи на ключевом транзисторе. Структурная схема такого преобразователя показана на рис. 2.11. vtffi DZStv C=j= ч \1Z/ I ° Рис. 2.11. Упрощенная схема преобразователя напряжения Управляемый напряжением генератор Vi вырабатывает импульсы переменной скважности, которые управляют ключом S. В качестве ключа обычно используются MOSFET транзисторы с низким проходным сопротивлением канала, что снижает потери энергии на нагрев. Когда ключ замкнут, ток начинает протекать через нако- пительную цепь из дросселя L и конденсатора С, заряжая конденсатор. Напряжение на нагрузке R равно разности напряжения источника питания и ЭДС самоиндукции дросселя, ток через дроссель растет, как и напряжение на конденсаторе и нагруз- ке. При размыкании ключа ток самоиндукции дросселя продолжает протекать через нагрузку в том же направлении через диод D, а также через нагрузку протекает ток разряда конденсатора. Далее цикл повторяется. Чем выше коэффициент заполнения импульсов, тем выше напряжение на конденсаторе и нагрузке. Генераторы им- пульсных преобразователей работают на высоких частотах — от сотен килогерц до единиц мегагерц, что позволяет снизить габариты накопительного дросселя и кон- денсатора. Встроенная цепь обратной связи генератора отслеживает выходное напряжение и при падении напряжения на нагрузке увеличивает длительность импульсов, и наоборот. Преобразователь может быть как регулируемым, так и настроенным на заданное выходное напряжение. Достоинства импульсных преобразователей: ♦ высокий КПД; ♦ широкий диапазон входных и выходных напряжений, возможность повышать выходное напряжение относительно входного; ♦ возможность плавной регулировки напряжения.
Советы для начинающих 33^ Недостатки импульсных преобразователей: ♦ при пробое ключа S в схеме преобразователя напряжение первичного источника оказывается полностью приложенным к нагрузке и, при отсутствии защиты, вы- водит ее из строя. Это, пожалуй, самый неприятный и опасный недостаток; ♦ в них генерируются импульсные помехи, вредные для чувствительного обору- дования. Но, как показала практика, рабочие частоты и их гармоники даже у са- мых дешевых преобразователей не мешают любительским устройствам, вклю- чая модули приемников GPS/ГЛОНАСС. А вот низкочастотные каналы связи диапазона 40.. .70 МГц могут испытывать помехи от преобразователя; ♦ более сложная конструкция, большие габариты по сравнению с интегральным линейным стабилизатором. На рис. 2.12 изображены примеры различных плат преобразователей для любитель- ских конструкций. Вы можете видеть на каждой плате обязательные элементы: ин- тегральную микросхему, дроссель и выходной накопительный конденсатор. Без них преобразователь работать не будет. Дополнительно могут присутствовать эле- менты для индикации напряжения, защиты от переполюсовки и подавления помех. Рис. 2.12. Различные модули преобразователей напряжения 2.4.3. Химические источники тока Если нужно обеспечить питание мобильного устройства — например, робота или электрической модели автомобиля, то без батарей или аккумуляторов не обойтись. Элементы типоразмеров АА или ААА, которые в быту принято называть «пальчи- ковыми батарейками» — самый безопасный, но и самый неэффективный источник
34 Глава 2 тока. Им присуща низкая энергоемкость при большом весе и объеме. Разряженные элементы питания приходится выбрасывать и покупать новые. Из напряжения заряженной пальчиковой батареи 1,5 В невозможно составить стандартные напря- жения 5 или 3,3 В. Придется использовать линейный стабилизатор или преобразо- ватель напряжения, теряя и без того скудный запас энергии. Поэтому пальчиковые батарейки и батарейки типа «Крона» обычно применяют только в конструкциях начального уровня или игрушках. Для регулярного применения в энергоемких устройствах требуются перезаряжае- мые химические источники тока — аккумуляторы. Никель-кадмиевые аккумуляторы Несколько лет назад в быту довольно широко применялись никель-кадмиевые ак- кумуляторы (NiCd) размеров АА и ААА, которые совпадают по габаритам с обыч- ными пальчиковыми элементами, но допускают до 900 циклов заряд-разряд. Эти аккумуляторы достаточно быстро утратили свои позиции на рынке бытовой электроники, но по-прежнему используются в электрических инструментах, про- мышленном и военном оборудовании. Причина такой неоднозначной популярности заключается в особенных свойствах NiCd аккумуляторов. Они имеют существен- ные достоинства: ♦ большой рабочий ток разряда; ♦ могут быстро заряжаться большим током; ♦ сохраняют емкость на морозе; ♦ могут храниться разряженными; Ф не склонны к возгоранию. Но недостатки этих аккумуляторов существенно ограничивают их использование в быту и любительских конструкциях: ♦ эффект памяти; ♦ потеря емкости при заряде-разряде малыми токами; ♦ большой вес и габариты; ♦ низкое напряжение: 1,35 ... 1 В; ♦ экологическая опасность кадмия. В любительской практике один только эффект памяти аннулирует все достоинст- ва NiCd аккумуляторов. Он возникает при попытке зарядить не полностью разря- женный аккумулятор. При этом внутри аккумулятора возникает «лишний» поляр- ный электрический слой, снижающий напряжение аккумулятора на 0,1 В. Контрол- лер заряда воспринимает это как сигнал о разряде аккумулятора и пытается его зарядить. Тем самым, ситуация только усугубляется. На практике это выглядит, как потеря емкости. Аккумулятор быстро заряжается и быстро разряжается. Избежать эффекта памяти помогают дорогие и сложные следящие контроллеры — специаль- ные электронные устройства, которые не только формируют зарядный ток, но и
Советы для начинающих 35^ следят за тем, какой заряд был фактически израсходован. Иными словами, NiCd аккумуляторы не переносят частичную подзарядку, она их попросту выводит из строя. Качественные контроллеры заряда могут сначала полностью разрядить аккумулятор и только после этого начать процесс зарядки. Но это лишняя трата времени. В профессиональной среде оборудование работает посменно, и чаще всего аккуму- ляторы разряжаются полностью. Их обслуживают специалисты. В быту и люби- тельской практике нередко требуется подзаряжать частично разряженные аккуму- ляторы. Кроме того, любительские конструкции обычно потребляют относительно небольшие токи. Вкупе с низким зарядным током это также приводит к быстрой деградации аккумулятора. Еще один фактор — низкое напряжение. Если для полу- чения напряжения 5 В с учетом разряда достаточно четырех обычных элементов АА, то никель-кадмиевых нужно уже минимум пять, а лучше шесть. Это слишком большие вес и объем даже для любительской конструкции. Поэтому в любительской практике аккумуляторы NiCd не получили большого рас- пространения. Литиевые аккумуляторы Аккумуляторы на основе литийсодержащего электролита получили широчайшее применение в современных электронных устройствах. Без них не обходится ни один современный смартфон, планшет, фотокамера или ноутбук. Литиевые акку- муляторы, особенно силовые, весьма капризны и требуют аккуратного обращения. Но, несмотря на дурную репутацию, связанную со случаями самовозгорания и про- чие недостатки, альтернативы им пока нет. Этот тип аккумуляторов обеспечивает наилучший показатель плотности энергии на единицу объема и при этом мало весит. Можно изготавливать плоские аккумуляторы произвольного размера. Мы будем обсуждать только плоские аккумуляторы в пленочной упаковке, как наибо- лее удобные и распространенные. Существует две основных модификации литиевых аккумуляторов: литий-ионные (Li-Ion) и литий-полимерные (LiPo, Li-Pol), отличающиеся типом электролита. В литий-ионном аккумуляторе используется гелевый электролит, а в литий-поли- мерном — специальный полимер, насыщенный литийсодержащим раствором. Ли- тий-полимерные батареи собирают из отдельных аккумуляторных ячеек. Ячейка представляет собой герметичный плоский пакет из очень прочного металлизиро- ванного пластика, внутрь которого помещена слоеная структура из электродов и сепараторов, пропитанных гелевым полимерным электролитом. Благодаря такой конструкции утечка электролита исключена, а сама батарея может иметь произ- вольную форму. Достоинства литиевых аккумуляторов: ♦ нет эффекта памяти; ♦ большая емкость при малом объеме и весе; ♦ могут отдавать большие токи и заряжаться большими токами; ♦ огромный ассортимент аккумуляторов разного размера и емкости.
36^ Глава 2 Недостатки литиевых аккумуляторов: ♦ склонность к самовозгоранию при нарушении режимов эксплуатации; ♦ ограниченный срок службы (естественная деградация); ♦ относительно высокая цена; ♦ быстро теряют заряд на холоде. Чтобы сполна использовать все преимущества литиевых батарей, но избежать не- приятностей и лишних расходов, надо строго соблюдать правила эксплуатации и хранения. Наиболее опасны, капризны и дороги силовые батареи для питания авиамоделей, роботов и прочих мощных потребителей. Слаботочные батареи для питания мобильных устройств менее опасны, но выходят из строя столь же быстро и необратимо. Рабочее напряжение литиевых аккумуляторов Литиевая батарея обычно состоит из нескольких последовательно соединенных ячеек. Максимальное напряжение одной заряженной ячейки — 4,2 В, среднее рабо- чее напряжение— 3,7 В. Категорически запрещается разряжать ячейку ниже напряжения 2,9 В! — это приводит к резкому сокращению срока службы. При раз- ряде до 2,5 В или ниже ячейка необратимо выходит из строя в течение 20 минут. Ячейкам, из которых составлена батарея, всегда присущ разброс параметров. При эксплуатации одна из ячеек может разряжаться чуть быстрее, а заряжаться чуть медленнее. С каждым циклом заряда-разряда эта разница будет нарастать. В итоге одна из ячеек может выйти из строя раньше других. Чтобы этого не случилось, не- обходимо следить за балансом напряжений ячеек. В идеале, у заряженной батареи напряжения на ячейках должны различаться не более чем на 0,01 В. Для выравни- вания напряжений на ячейках, тестирования и подготовки к хранению используют специальное устройство — балансир заряда (рис. 2.13). Нет строгой необходимости использовать балансир при каждой зарядке, особенно если батарея качественная. Но контроль напряжения ячеек необходимо вести по- Рис. 2.13. Балансир/разрядник/тестер для литиевых батарей
Советы для начинающих 37_ стоянно. Категорически запрещается ставить на зарядку батарею, у которой на- пряжение между ячейками различается более чем на 20%! Это чревато перезаря- дом тех ячеек, у которых напряжение выше, их перегревом с разгерметизацией и пожаром. Если вы хотите попытаться реанимировать батарею с большим разбросом напряжений на ячейках, необходимо сначала через балансирный разъем отдельно подзарядить самую разряженную ячейку (ячейки). Зарядка литиевых батарей Для питания устройств с рабочим напряжением 3,3 В часто применяется одна ли- тиевая ячейка и линейный стабилизатор. Для питания пятивольтовых потребителей от одной ячейки можно использовать повышающие преобразователи, о которых мы говорили ранее. Если емкость ячейки не превышает 600 миллиампер-часов, для ее зарядки можно использовать простой модуль, изображенный на рис. 2.14. Он мо- жет получать питание от разъема USB или зарядного устройства с напряжением 5 В. Рис. 2.14. Модуль для зарядки одной литиевой ячейки от порта USB Для зарядки батарей, составленных из нескольких ячеек, применяют специальные зарядные устройства. Постарайтесь приобрести «интеллектуальное» зарядное уст- ройство на основе микроконтроллера (рис. 2.15). Это устройство можно использо- вать для заряда различных типов батарей, вплоть до свинцовых кислотных аккуму- ляторов, проводить их балансировку и проверять фактическую емкость. У литиевых батарей отсутствует уже упомянутый ранее эффект памяти, поэтому их можно подзаряжать после частичной разрядки, и сколь угодно часто. Для них это будет даже полезно, тогда как хранение в разряженном состоянии, напротив, для батареи вредно. Категорически запрещено повторно ставить на зарядку уже заряженную батарею! Это может привести к избыточному заряду с быстрым вы- ходом батареи из строя или даже к пожару. В процессе заряда следует соблюдать тепловой режим. При отрицательных темпе- ратурах аккумуляторы практически не заряжаются, а положительная температура не должна превышать 50 °С. Литиевые батареи можно заряжать только специальными зарядными устройствами, при строгом соблюдении алгоритма заряда. Попытка использовать неподходящее или кустарное устройство может привести к возгоранию батареи или быстрому вы- ходу ее из строя!
38 Глава 2 Рис. 2.15. Универсальное зарядно-балансное устройство Хранение литиевых батарей Литиевым батареям присущ процесс старения, который начинается сразу после из- готовления и ускоряется после первого цикла заряда-разряда. Особенно быстро стареют при хранении полностью заряженные и полностью разряженные батареи. Поэтому батареи хранят частично разряженными до напряжения 3,9 В. Говоря о хранении, мы имеем в виду период времени более двух месяцев. Если ожидаемый перерыв меньше, то специально готовить батареи для хранения не обязательно. Батареи можно хранить при комнатной температуре или в дверке холодильника, но чрезмерное охлаждение до минусовых температур может привести к полной само- разрядке и порче батареи. Начало эксплуатации Литиевые батареи поступают в продажу заряженными примерно до 75% емкости. В состав электролита современных литиевых батарей входит специальный консер- вант, который предотвращает саморазряд и преждевременное старение ячеек до начала эксплуатации. Перед использованием батарею необходимо полностью заря- дить, а первые три цикла заряда-разряда избегать максимальной нагрузки. Если вы вводите в эксплуатацию силовую батарею, то лучше не спешить и дважды разря- дить/зарядить ее при помощи зарядного устройства, и лишь затем подвергать мак- симальной нагрузке. Этот простой совет поможет вам избежать быстрого вздувания батарей и продлит срок службы. Признаки неисправности Основной признак неисправности литиевой ячейки— раздувание пластикового корпуса газами. Это признак необратимого разложения электролита. Попытка про- колоть пакет и выпустить газ ничем не поможет. Вы только усугубите ситуацию, открыв доступ кислороду воздуха, и можете устроить пожар! Раздувание обычно сопровождается резким падением емкости. Аккумулятор быстро разряжается и быстро заряжается, запасая небольшое количество энергии. Вздувшиеся аккумуляторы опасно хранить или эксплуатировать. Но не спешите выбрасывать неисправную батарею. Часто случается так, что в батарее вздулась
Советы для начинающих 39_ только одна ячейка. Если аккуратно, не допуская повреждения корпуса или корот- кого замыкания, разобрать неисправные батареи, то из оставшихся исправных яче- ек можно собрать новую батарею. Если же батарею составить не получается, исправные одиночные ячейки можно использовать для питания низковольт- ных устройств, либо разрядить до напряжения 3,9 В и хранить в дверке холодиль- ника. При эксплуатации литиевых аккумуляторов не допускаются: ♦ короткое замыкание выводов; ♦ избыточный заряд; ♦ превышение допустимого разрядного и зарядного тока; ♦ нагрев аккумулятора выше 60 °С; ♦ механические повреждения ячеек и упаковки; ♦ хранение в автомобиле, особенно на солнце. Нарушение любого из этих правил грозит пожаром! Причем литиевый аккумуля- тор невозможно потушить даже углекислотным огнетушителем — все необходи- мые компоненты для горения находятся внутри аккумулятора. 2.5. Согласование логических уровней Цифровые микросхемы, с которыми вы будете работать, оперируют логическими уровнями «ноль» (низкий уровень) и «единица» (высокий уровень). Мы уже гово- рили о том, что наиболее часто встречаются два напряжения питания: 3,3 и 5 В. К сожалению, часто приходится соединять между собой сигнальные выводы уст- ройств или модулей с разными напряжениями питания. Это — если не принять ме- ры защиты — грозит порчей низковольтных устройств. В зависимости от напряжения питания различаются и напряжения логических уровней ноля и единицы на выходах микросхем. У микросхем с пятивольтовым питанием напряжение логического нуля лежит в пределах 0..Д5 В, а напряжение логической единицы— в пределах 2,4...5 В. У микросхем с трехвольтовым пита- нием напряжение логического нуля так же лежит в пределах 0...0,5 В, но напряже- ние логической единицы лежит в диапазоне 2,4.. .3,3 В. Рассмотрим варианты соединения микросхем с разным напряжением питания и разберемся, что при этом может произойти. 1. Выход трехвольтовой микросхемы соединяется со входом пятивольтовой. В этом случае схема будет нормально работать. Напряжения на выходе низко- вольтной части вполне достаточно, чтобы вход пятивольтовой микросхемы на- дежно определял уровень логической единицы. Рабочий диапазон логического нуля в любом случае совпадает. 2. Выход пятивольтовой микросхемы соединяется со входом трехвольтовой. В этом случае уровень логической единицы на входе трехвольтовой микросхемы
40 Глава 2 может превысить ее напряжение питания. Это с большой вероятностью приве- дет к перегрузке и выходу из строя низковольтной микросхемы! Существуют низковольтные микросхемы со встроенной защитой, устойчивые к превышению входного напряжения. В описании таких микросхем или модулей на их основе встречается текст «TTL tolerant» или «5 V tolerant». Если вы не уверены в этом, то лучше применить согласование логических уровней. Если сигнал передается в одном направлении — от высоковольтного выхода к низ- ковольтному входу, то для защиты от перенапряжения достаточно включить после- довательно в разрыв соединительной линии резистор сопротивлением 470... 1000 Ом. Сложнее обеспечить согласование уровней на двунаправленной линии — например, при обмене данными по шине 12С. В этом случае вам потребуется двунаправленный преобразователь уровней (рис. 2.16), выполненный на транзисторах или на специ- альной микросхеме. Для того чтобы преобразователь работал правильно, на него необходимо подавать оба питающих напряжения. При поиске в зарубежных интернет-магазинах используйте ключевые слова logic level converter или logic level shifter. Рис. 2.16. Двунаправленные преобразователи логических уровней Самодельный двунаправленный преобразователь уровней можно изготовить на основе дешевых и широко распространенных полевых транзисторов BSS138 или BSS123. Схема преобразователя для одной линии сигнала изображена на рис. 2.17. Количество задействованных линий зависит от схемы подключения вашего уст- ройства.
Советы для начинающих 4jf_ +3V3 +5V Логика 3,3В BSS138 Логика 5В Рис. 2.17. Схема двунаправленного преобразователя уровней 2.6. Интерфейсы обмена данными В большинстве случаев электронные устройства не могут обходиться без обмена данными. Как минимум, вы должны записать прошивку в микроконтроллер. А это поток двоичных данных, передаваемых из компьютера определенным способом. Отдельные компоненты устройства тоже могут обмениваться данными. Интерфейс состоит из аппаратной части и протокола, по которому она работает. Следует понимать различие между протоколом обмена и форматом данных. Про- токол— это способ передачи сигнала, согласованный на физическом уровне, а формат данных — это способ организации данных на высоком уровне. Например, приемник GPS использует последовательный интерфейс UART. Используя аппа- ратный протокол в виде чередования логических уровней заданной длительности и амплитуды, он передает непрерывный поток форматированных текстовых данных, содержащих координаты и точное время. Эти данные понятны человеку, их можно прочесть визуально на экране текстового терминала. При загрузке программы в микроконтроллер тоже используется последовательный протокол UART или SPI, но формат прошивки — это набор байтов, который выглядит как случайная меша- нина шестнадцатеричных чисел. Л, Может показаться, что достаточно соединить между собой устройства с одинаковым /?\ интерфейсом и начать работу. Увы, так получается не всегда. Есть нюансы, которые могут поставить неопытного пользователя в тупик и заставить напрасно потерять много времени или испортить устройство. Далее мы очень кратко расскажем о раз- личных интерфейсах, но сделаем акцент на проблемах, которые могут возникнуть при отладке устройств. 2.6.1. Последовательный интерфейс UART UART (Universal Asynchronous Receiver-Transmitter, универсальный асинхронный приемопередатчик)— это самый старый, простой и популярный способ обмена данными в любительской электронике. Он используется при записи прошивок в отладочные платы Arduino, при обмене данными между микроконтроллерами и внешними модулями, при настройке модулей при помощи настольного компьютера и во многих других случаях.
42 Глава 2 Строго говоря, UART — это общее название целого семейства последовательных протоколов, которые различаются по рабочему напряжению логических уровней и физическому носителю сигнала. Примерно десять лет назад в каждом компьютере был последовательный порт COM (Communication port) RS-232 для подключения периферийных устройств. Сейчас компьютеры с таким портом можно найти только в промышленном оборудовании, потому что RS-232 работает с логическими уров- нями +12 и -12 В, что очень неудобно для бытовой электроники. Инфракрасный порт IrDA тоже работает по протоколу семейства UART, но в качестве носителя сигнала используется оптический канал. Наибольшее распространение получила разновидность UART, работающая со стандартными уровнями трехвольтовой или пятивольтовой логики и позволяющая соединять устройства между собой напрямую. Практически все современные мик- роконтроллеры содержат встроенный аппаратный модуль UART или поддержива- ют его программную эмуляцию. Поэтому, если говорят об интерфейсе UART, по умолчанию подразумевается именно вариант со стандартными логическими уров- нями для прямого подключения к микроконтроллерам. Возможная проблема: не забывайте о согласовании логических уровней частей схемы, если одновременно используете устройства с трехвольтовым и пятивольто- вым питанием! Мы обсудили этот вопрос в разд. 2.5. Данные передаются по одному биту в заданный промежуток времени. Передача начинается со стартового бита и заканчивается стоповым битом и битом четности. Скорость передачи измеряется в бодах (битах в секунду), иногда называется словом битрейт (от англ. bitrate — битовая скорость). Существуют общепринятые ско- рости передачи: 300, 600, 1200, 2400, 4800, 9600, 19 200, 38 400, 57 600, 115 200, 230 400, 460 800, 921 600 бод. Наиболее часто используются скорости 9600, 19 200, 57 600 и 115 200 бод. Поскольку вместе с битами данных передаются старт-стоповые биты и бит чет- ности, пропускная способность отличается от скорости обмена. Например, при ско- рости обмена 115 200 битов в секунду фактическая скорость передачи данных составит всего 92 600 бит/сек. Эту особенность следует учитывать при проектиро- вании устройств, критичных к скорости передачи данных. Возможная проблема: некоторые устройства используют нестандартные скорости обмена. Кроме того, скорость работы устройства может быть неизвестна заранее. Иногда устройство сразу после включения стартует и выдает лог загрузки с одной скоростью обмена, а затем работает на другой скорости. Если вы не можете устано- вить связь с устройством или наблюдаете бессмысленный набор символов на экра- не терминала, попробуйте последовательно перебирать все скорости из стандарт- ного ряда. Несовпадение скоростей часто ставит новичков в тупик, когда не удается записать прошивку в отладочную плату или получить данные от приемника GPS или GPRS-модема. Обмен данными происходит по двум линиям: прием Rx (RXD) и передача Тх (TXD). Устройства, которые обмениваются данными, полностью равноправны. Линия передачи одного устройства является линией приема для другого, и наоборот. По-
Советы для начинающих 43 этому выводы UART необходимо соединять перекрестно: Rx—>Tx, Tx—^Rx1 (рис. 2.18). Если предполагается передавать данные только в одном направлении, достаточно соединить выход Тх передающего устройства со входом Rx прини- мающего. Возможная проблема: неопытные радиолюбители часто соединяют одноименные выводы Rx-Rx и Тх-Тх. Разумеется, при таком соединении обмен данными работать не будет. Иногда китайские производители путают подписи выводов на плате. Если при подключении устройства на экране терминала не появляются никакие данные, либо перебор скоростей обмена не помогает, попробуйте поменять подключение выводов Rx и Тх. Не бойтесь, ошибочное подключение не испортит устройство. Устройство 1 Устройство 2 Рис. 2.18. Схема соединений интерфейса UART 2.6.2. Конвертер интерфейсов USB-UART Многие электронные устройства приходится подключать к компьютеру для про- граммирования, настройки или просмотра потока данных. Для этого используется обычный разъем USB. Но далеко не всегда устройство поддерживает работу по протоколу USB. Этот протокол достаточно сложен для программирования, как на стороне компьютерных приложений, так и на стороне прошивки устройства. На- много чаще используется программно-аппаратная эмуляция последовательного порта обмена данными. Некоторые устройства, особенно отладочные платы, со- держат встроенные конвертеры интерфейсов USB-UART в виде специальной мик- росхемы, но часто применяются внешние преобразователи. При подключении конвертера USB-UART к компьютеру, в системе появляется виртуальный последовательный порт. Программы работают с ним, как с обычным аппаратным портом. В свою очередь, микроконтроллер устройства также обмени- вается данными с микросхемой конвертера, как с обычным последовательным пор- том. Таким образом, конвертер «прозрачен» для последовательного потока данных в обе стороны. В продаже доступно большое количество недорогих конвертеров USB-UART, но почти все они построены на базе одного из трех чипов: FTDI (FT232), WCH (CH340G) или Prolific (PL2303). Микросхема конвертера может быть установлена на плате устройства либо оформлена в виде внешнего модуля (рис. 2.19). В любом Это правило относится только к интерфейсам UART или СОМ, в остальных случаях соединяют ли- нии с совпадающими именами.
44 Глава 2 случае, на компьютер необходимо установить драйвер соответствующей микро- схемы. При покупке конвертера следует в последнюю очередь обращать внимание на цену и даже на тип микросхемы. Гораздо важнее, какие выводы микросхемы разведены на разъем-гребенку, и переключается ли напряжение логических уровней. г д е Рис. 2.19. Примеры внешних плат конвертера USB-UART Старайтесь найти плату, на разъем которой выведены линии RTS и DTR от микро- схемы (как минимум, только DTR). Дело в том, что для записи прошивки в микро- контроллеры Atmel непосредственно перед началом записи необходимо подать им- пульс на вывод сброса микроконтроллера. Приложение Arduino IDE формирует этот импульс на линиях DTR и RTS автоматически. Если у вашего конвертера от- сутствует вывод DTR, придется либо дорабатывать его плату, либо каждый раз вручную нажимать кнопку RESET на плате устройства, ловя нужный момент. Все микросхемы конвертеров могут вырабатывать напряжение питания +3,3 В для питания внешних потребителей током до 50 мА. Удобно, если это напряжение вы- ведено на разъем. В таком случае при настройке или отладке маломощных трех- вольтовых устройств можно обойтись без дополнительного источника питания. В некоторых конвертерах предусмотрена возможность переключения напряжения логических уровней выходного каскада при помощи перемычки или переключате- ля. Благодаря этой опции можно подключать конвертер к микросхемам трехволь- товой логики без преобразователя уровней. Из числа конвертеров, изображенных на рис. 2.19, лучше всего подойдут варианты под буквами б, в и г. Вариант е выглядит подходящим, но изготовлен на поддель-
Советы для начинающих 45 ной микросхеме-клоне FT232 и работает очень нестабильно. Вариант а не оснащен выводом сброса, а вариант д рассчитан только на логические уровни трехвольтовых микросхем. На рынке присутствует множество поддельных микросхем FT232 и плат на их осно- ве. Такие микросхемы нестабильно работают на скоростях выше 57 600, с длинными соединительными проводами USB и не всегда надежно распознаются операционной системой компьютера. Пример конвертера на поддельной нестабильной микросхеме показан на рис. 2.19, е. Компания FTDI борется с подделками и распространяет в составе ОС Windows драйвер, который при обнаружении поддельной микросхемы блокирует работу порта. Настоятельно рекомендую не экономить на фирменном конвертере FT323. В качестве недорогой альтернативы можно купить конвертер на основе CH340G или PL2303. 2.6.3. Последовательная шина I2C Последовательная шина I2C (IIC, Inter-Integrated Circuit) разработана в 1980 году компанией Philips для простого 8-битного обмена данными между интегральными микросхемами внутри одного устройства. В любительских устройствах по этой шине могут также подключаться различные датчики, вынесенные на небольшое расстояние от основной платы. К шине 12С обязательно подключено главное устройство (master, ведущий) и одно или несколько ведомых (slave). У каждого ведомого на шине есть свой адрес. Спо- соб задания адреса зависит от ведомой микросхемы. У некоторых микросхем — например, у трехвыводных датчиков температуры, адрес фиксированный и указан в документации. У более сложных микросхем адрес можно задавать комбинацией перемычек на выводах, соединяя их с «землей» или шиной питания. Разработчикам доступно до 112 свободных адресов для подключения ведомых на одну шину (рис. 2.20). Ведущий Ведомый 1 Ведомый 2 Ведомый N SCL SDA Адрес 1 SCL SDA Адрес 2 SCL SDA Адрес N SCL SDA Рис. 2.20. Схема соединений шины I2C Для обмена данными используются две линии: тактирование (SCL) и данные (SDA). Обмен начинается с того, что ведущий дает команду START и передает по линии SDA адрес ведомого. Ведомый, распознав свой адрес, дает в ответ сигнал подтверждения готовности. Далее ведущий передает ведомому устройству коман- ды или данные, и может получать данные в ответ. Например, микроконтроллер передает команду измерить температуру и получает в ответ измеренное значение.
jg Глава 2 В большинстве устройств используется одна из двух стандартных скоростей: 100 Кбит/с или 400 Кбит/с. Логические уровни стандартные, трех- или пятивольто- вые, в зависимости от рабочего напряжения схемы. Преобразование интерфейса 12С в какой-либо другой встречается редко и обычно не требуется в любительской практике. Микроконтроллеры имеют аппаратную ли- бо программную поддержку 12С. Все, что от вас требуется, — правильно соединить выводы микросхем или модулей и не ошибиться с адресом устройства. Учитывайте при этом особенности и ограничения шины 12С: ♦ логические уровни обязательно должны быть согласованы при помощи двуна- правленных преобразователей; ♦ двунаправленными являются обе линии: SCL и SDA; ♦ при неустойчивой работе шины могут понадобиться подтягивающие резисторы сопротивлением около 1 кОм, подключенные к линиям SCL и SDA и шине питания; ♦ шина чувствительна к помехам и емкости соединительных проводов, поэтому плохо работает на линиях длиннее 30 см; ♦ в любительских устройствах старайтесь использовать скорость 100 Кбит/с. 2.6.4. Последовательный интерфейс SPI Четырехпроводной интерфейс SPI (Serial Peripheral Interface) предназначен для несложного, но скоростного, сопряжения микроконтроллеров с периферийными устройствами. При помощи SPI подключают компактные матричные дисплеи, мик- росхемы и карты памяти, бесконтактные считыватели карт и прочие устройства, требующие передачи относительно больших объемов данных за короткое время. Многие современные микроконтроллеры имеют аппаратную поддержку SPI и, кроме обмена данными, допускают загрузку прошивок по этому протоколу. В SPI используется четыре цифровых линии: 1. MOSI (SDI, SI, DI) — выход ведущего, вход ведомого (Master Out Slave In); 2. MISO (SDO, SO, DO) — вход ведущего, выход ведомого (Master In Slave Out); 3. SCLK (SCK, CLK)— выход тактовых импульсов для тактирования ведомых устройств; 4. SS или CS — выбор ведомой микросхемы (Slave Select, Chip Select). SPI— это полноценный дуплексный интерфейс. Данные могут одновременно передаваться в двух направлениях: от ведущего к ведомому по линии MOSI и от ведомого к ведущему по линии MISO. В любом случае ведущий выбирает ведомое устройство при помощи сигнала SS и тактирует передачу данных по шине. Скорость передачи данных определяется частотой тактовых импульсов ведущего, может достигать 50 Мбит/с и технически ограничивается возможностями самого медленного устройства на шине. Например, в библиотеке Arduino SPI по умолча- нию задана частота тактовых импульсов, равная 1А от тактовой частоты контролле-
Советы для начинающих 47 ра: 16/4 = 4 МГц. Следовательно, скорость по умолчанию 4 Мбит/с. Это намного больше, чем скорость других интерфейсов. Как правило, такой скорости достаточ- но для большинства любительских конструкций. Интерфейс SPI может работать в четырех разных режимах. Они различаются ак- тивным уровнем тактового импульса и порядком передачи битов в байте. По умол- чанию активен положительный тактовый импульс (захват данных по переходу из О в 1), первым передается старший бит. Это наиболее распространенный режим SPI Mode 0. При разработке собственных проектов следует уточнить специфика- цию периферийных устройств. Стандартные библиотеки SPI позволяют менять режим перед обращением к конкретному устройству. Поскольку для каждого ведомого нужен отдельный сигнал SS, то приходится выде- лять под каждый из них отдельный вывод микроконтроллера. Это главный недос- таток интерфейса SPI, особенно в случае использования маломощных контролле- ров с небольшим числом выводов. Под интерфейс занято минимум четыре вывода, и каждое следующее устройство занимает еще один вывод. Но для современных микроконтроллеров, у которых бывает более двух десятков портов ввода/вывода, эта проблема менее актуальна. Интерфейс SPI предназначен для коммутации на небольших расстояниях внутри одного устройства. Следует соединять между собой одноименные выводы ведуще- го и ведомого (рис. 2.19). Ведущий MOSI MISO SCLK SS Ведомый MOSI MISO SCLK SS Рис. 2.21. Схема соединений по интерфейсу SPI 2.6.5. Последовательный протокол 1-Wire Для связи между устройствами по протоколу 1-Wire (рис. 2.22) требуется всего два провода: сигнальный и общий («земля»). Питание периферийного устройства осу- ществляется по линии сигнала. Устройство содержит конденсатор емкостью 800 пФ, который заряжается при высоком логическом уровне на линии сигнала. Но такая технология питания работает только на коротких линиях. Для питания ком- понентов, вынесенных на большие расстояния, используют отдельную линию. В электронных системах шина 1-Wire обычно задействуется для подключения не- дорогих внешних датчиков и средств идентификации. Пример — всем известные «таблетки» iButton для домофона. Часто по шине 1-Wire подключается специальная микросхема в батареях ноутбуков и смартфонов. Это нужно для проверки подлин-
48 Глава 2 ности батареи и мониторинга ее температуры. В принтерах по шине 1-Wire распо- знается тип и состояние картриджей с тонером. Преимущество протокола 1-Wire заключается в широких возможностях адресации и гибкости системы. Каждое устройство имеет 64-битный серийный номер, со- стоящий из трех частей: код семейства, уникальный 48-битный номер, контрольная сумма. Уникальность номеров устройств гарантируется обладателем торговой мар- ки— компанией Dallas Semiconductor (с 2001 года Maxim Integrated). Устройства самотактируются. Информация кодируется длительностью импульсов. Все импуль- сы несут в себе либо данные, либо номер адресуемого компонента. На шине при- сутствует одно ведущее устройство, остальные ведомые. Ведущий имеет возмож- ность перед началом работы опросить шину и определить перечень подключенных ведомых. Стандартная скорость передачи данных составляет 15,4 Кбит/с. В режиме Overdrive скорость может достигать 125 Кбит/с на линиях длиной менее 50 см. Vcc Vcc Ведущий _L линия данных Ведомый 1 _L Ведомый 2 4,7 кОм 1 1 Ведомый N 1 Рис. 2.22. Схема организации шины 1-Wire 2.7. Измерительное оборудование От наличия измерительного оборудования в первую очередь зависит возможность диагностики неисправностей и ошибок в схеме, а также проверка напряжений питания. Попытка экономить на измерительном оборудовании и инструментах — распространенная ошибка начинающих радиолюбителей. Действительно, хорошее профессиональное оборудование стоит очень дорого. Но в последние годы в про- даже появилось неплохое оборудование для любителей по низкой цене. Важно лишь правильно его выбрать. Помните, что без измерительных приборов вы будете действовать наобум, совер- шенно не понимая, что происходит с устройством, а совокупная стоимость испор- ченных компонентов и потерянного времени быстро превысит стоимость лаборатор- ного оборудования.
Советы для начинающих 49_ 2.7.1. Цифровой мультиметр В любительской лаборатории основным измерительным устройством является не- дорогой цифровой мультиметр. Рекомендую выбирать прибор, у которого есть функция «пищалки» — звуковая индикация наличия соединения между щупами. Эта функция удобна при проверке соединений в жгутах и на платах и при поиске коротких замыканий, так как благодаря звуку можно не смотреть на индикатор. Та- кие дополнительные функции мультиметра, как измерение характеристик транзи- сторов или встроенный термометр, реже требуются на практике. Еще одной полез- ной функцией является проверка полупроводниковых переходов, которая помогает проверять диоды и транзисторы, не выпаивая их из схемы. Перечисленным требо- ваниям соответствует, например, популярный мультиметр М-831 (рис. 2.23), опти- мальный по соотношению цена/функциональность. Рис. 2.23. Мультиметр М-831 с дополнительными функциями 2.7.2. Цифровой осциллограф Лабораторный осциллограф можно назвать дополнительным органом чувств ра- диолюбителя. Это особая степень свободы в техническом творчестве. Благодаря возможности видеть амплитуду и форму сигналов, многократно ускоряются отлад- ка проектов и поиск неисправностей. Некоторые неисправности можно выявить только при помощи осциллографа. Я твердо уверен в том, что любитель электрони- ки должен иметь хотя бы простейший осциллограф и уметь им пользоваться. Профессиональные цифровые осциллографы стоят очень дорого, но для работы с большинством любительских цифровых проектов начального и среднего уровня вполне можно обойтись прибором с ценой менее 20 долларов (рис. 2.24). Ищите его в зарубежных интернет-магазинах по ключевым словам digital oscilloscope. Такой осциллограф можно приобрести собранным или в виде набора деталей. Хорошим вариантом для любительской лаборатории являются USB-осциллографы. Они содержат в своем корпусе быстродействующие аналого-цифровые преобразо- ватели и процессор, а в качестве устройства отображения используется обычный
50 Глава 2 Рис. 2.24. Простой любительский осциллограф настольный компьютер или ноутбук. Благодаря тому, что значительная часть зада- чи по вторичной обработке и отображению сигналов выполняется внешним ком- пьютером, существуют качественные приборы по доступной цене. Потратив около 70 долларов, можно заказать двухканальный USB-осциллограф Hantek 6022BE (рис. 2.25). Этот осциллограф можно использовать в профессиональной практике при ремонте бытовой техники, электроники автомобилей, производственного обо- рудования предприятий. /, «t! *■''•''■ Рис. 2.25. Двухканальный бюджетный осциллограф Hantek 6022BE
Советы для начинающих 51_ 2.8. Паяльное оборудование Паяльное оборудование представлено на рынке в широчайшем ассортименте, а раз- личным приемам и технологиям пайки можно посвятить отдельную книгу. Но, на- чиная осваивать электронику, можно обойтись простейшими инструментами для пайки. Дальнейшее оснащение лаборатории будет зависеть от ваших потребностей и квалификации. В этом разделе мы рассмотрим минимальный комплект для начи- нающих. Оснащая рабочее место с нуля, имеет смысл приобрести паяльный набор, анало- гичный изображенному на рис. 2.26. Набор может быть менее обширным и состо- ять только из паяльника, пинцета, припоя ПОС-61 в виде тонкой проволоки и канифоли. Важное условие — паяльник обязательно должен быть с регулировкой нагрева. Паяльники обычно рассчитаны на то, чтобы обеспечить рабочую темпера- туру при сниженном сетевом напряжении. При обычном или повышенном напря- жении в сети они перегреваются, жало быстро выгорает, а пайка получается нека- чественная. Желательно, чтобы паяльник имел сменные жала разной формы. \ Рис. 2.26. Набор паяльных принадлежностей для домашней лаборатории
52 Глава 2 Ни в коем случае не используйте для лужения проводников и пайки электронных устройств агрессивные кислотные флюсы! Остатки кислотного флюса, впитавшиеся под изоляцию проводов или в отверстия печатной платы, невозможно удалить пол- ностью. Со временем кислота разъест проводники или будет вызывать «блуждаю- щие» сбои в работе за счет паразитной проводимости. Для удобства монтажа обязательно приобретите монтажный зажим «третья рука» с увеличительным стеклом (рис. 2.27). Обычно он оснащен держателем, в который можно временно опускать паяльник в процессе работы. Рис. 2.27. Монтажный зажим «третья рука» с лупой и подсветкой А Рис. 2.28. Паяльная станция SAIKE 909D со встроенным лабораторным источником питания
Советы для начинающих 53_ Если вы планируете заниматься монтажом и ремонтом печатных плат, приобретите настольную паяльную станцию (SMD rework station). Изображенная на рис. 2.28 паяльная станция содержит паяльник с регулировкой нагрева и сменными жалами, регулируемый фен со сменными насадками для пайки деталей с поверхностным монтажом (SMD) и регулируемый источник питания 0...15 В с амперметром и защитой от перегрузки до 3 ампер. Такая паяльная станция удовлетворит все по- требности любительской лаборатории в плане пайки и электропитания. 2.9. Полезные программы и утилиты Несмотря на то, что практически все платформы предлагают фирменные средства для настройки и отладки, вы не сможете обойтись без универсальных программ для обмена данными между компьютером и устройством. Это простые и полезные ин- струменты, которые значительно облегчают работу. Иногда без них вообще нельзя обойтись. В этом разделе вы познакомитесь с самыми популярными программами, которые проверены годами и миллионами пользователей. Некоторые функции этих программ повторяются, но удобство использования зависит от конкретной за- дачи. Далее мы будем полагать, что вы установили эти программы и ознакомились с ними. 2.9.1. PuTTY Это наиболее универсальная программа терминала— окна текстового обмена командами и данными с другим устройством или компьютером. Поддерживает раз- личные протоколы, из которых нам пригодятся SSL, Serial и Telnet. Скачайте установочный файл для Windows по адресу www.putty.org. Установите программу и запустите ее. Интерфейс состоит из одного окна, в котором доступны все настройки и режимы (рис. 2.29). В большинстве случаев для подключения по Telnet или SSH используются стан- дартные номера портов, поэтому достаточно указать IP-адрес и нажать кнопку Open. Для подключения через последовательный порт Serial необходимо указать номер порта в системе Windows и скорость соединения. В левом столбце вы може- те выбрать различные настройки: изменить шрифт, цвет текста и рабочего окна, номер и скорость последовательного порта по умолчанию. Остальные настройки не следует менять без четкого понимания, что и зачем вы делаете. Чтобы каждый раз не вводить настройки часто используемого соединения, вы можете сохранить их. Задав нужные настройки, введите в поле Saved Sessions имя, под которым вы хотите сохранить текущий профиль, и нажмите кнопку Save. Те- кущие настройки будут сохранены — для открытия соединения достаточно будет выбрать сохраненный вариант настроек и нажать кнопку Open. Программа PuTTY хорошо подходит для работы с «умными» устройствами — на- пример, микрокомпьютерами с ОС Linux, но менее удобна при настройке различ- ных простых периферийных модулей.
54 Глава 2 Рис. 2.29. Окно программы PuTTY 2.9.2. WinSCP Это еще одна простая, но мощная программа, которая, кроме протокола Windows Secure Copy Protocol, поддерживает также FTP, SFTP и SSH. Программа имеет гра- фический интерфейс, что значительно облегчает работу с файловой структурой микрокомпьютеров на основе ОС Linux, не имеющих собственной графической подсистемы, либо доступных только удаленно. Скачайте установочный файл по адресу https://winscp.net/eng/download.php. Сразу после установки программа готова к работе. Для подключения к файловой структу- ре устройства введите его IP-адрес, логин и пароль. В большинстве случаев будем выбирать стандартный протокол FTP, а если потребуется SCP или SFTP, — это будет указано отдельно. После подключения в левой панели окна отображается файловая система вашего настольного компьютера или ноутбука, в правой — файловая система устройства (рис. 2.30). Вы можете создавать и удалять файлы и папки, а также перемещать их перетаскиванием. Двойным щелчком на имени текстового файла его можно открыть во встроенном редакторе. Так можно открывать, редактировать и сохранять файлы конфигурации Linux. Это намного удобнее, чем в консольном редакторе. Программа WinSCP может автоматически запускать терминал PuTTY для работы с консолью Linux-устройств. Для этого исполняемый файл putty.exe должен быть размещен по адресу C:\Program Files\PuTTY\.
Советы для начинающих 55 Рис. 2.30. Окно программы WinSCP 2.9.3. Hercules Эта утилита была разработана для настройки и диагностики сетевого оборудования компании HW Group, но быстро получила популярность, благодаря оптимальному сочетанию простоты и функциональности. Теперь эта утилита распространяется свободно и бесплатно. Скачайте установочный файл по адресу http://www. hw-group.com/products/hercules/indexen.html Программа не требует установки и запускается из любого расположения. Нам по- требуется вкладка Serial (рис. 2.31). Удобство программы состоит не только в воз- можности настраивать любые параметры соединения через последовательный порт, но и в наличии трех полей в секции Send. В каждое из этих полей можно занести заранее подготовленные строки с командами для передачи через последовательный порт и отправлять их в нужный момент нажатием соответствующей кнопки Send. Это позволяет избежать опечаток в ответственных длинных строках команд — на- пример, при аварийном восстановлении прошивки устройства, и экономит время при отправке набора повторяющихся команд. При обычном использовании в любительских разработках достаточно выбрать нужный номер порта в поле Name и скорость в поле Baud, а затем нажать кнопку Open. Имейте в виду — если нужно добавить к передаваемой строке символ воз- врата каретки, то это необходимо делать в явном виде, добавляя в конце строки текстовые символы <cr>. Например: at+password=12345<cr>. Символ $ является для Hercules служебным, поэтому для передачи в строке его нужно повторить: $$.
56 Глава 2 Рис. 2.31. Окно программы Hercules 2.9.4. Termite Это простая и надежная программа терминала. Работает только через последова- тельный порт. Идеально подходит для подключения к простым устройствам, под- держивающим обмен командами через COM/UART: приемники GPS, модемы, мо- дули Bluetooth и т. д. Скачайте самораспаковывающийся архив программы по адре- су http://www.compuphase.com/softwaretermite.htm. При установке выберите опцию GNU Unifont (рис. 2.32). Этот шрифт отображает небуквенные служебные символы, если они встречаются в потоке данных. Такая опция может пригодиться в будущем. При работе с дополнительными модулями потребуется проверить и изменить сле- дующие настройки терминала (рис. 2.33): ♦ номер последовательного порта — это порт, который появляется в системе при подключении адаптера USB-COM. При подключении одного и того же устрой- ства к разным разъемам USB номер порта может меняться; ♦ скорость обмена с устройством — для каждого устройства определена своя ско- рость по умолчанию, указанная в инструкции или в описании; ♦ присоединение символов конца строки и перевода каретки: <lf> и <cr>. Некото- рые устройства требуют наличия этих символов в конце команды, некоторые нет. Несоблюдение условия по наличию или отсутствию символов <lf> и <cr> может привести к невозможности передачи команд или к неправильной реакции устройства; ♦ шрифт — если нужно отображать спецсимволы, выберите опцию unifont.
Советы для начинающих 57 И1-- ■ Termite Рис. 2.32. Установка программы Termite Рис. 2.33. Окно настроек программы Termite 2.9.5. Notepad++ Это простой, но мощный текстовый редактор для редактирования файлов конфигу- рации, скриптов и прочих специальных текстовых файлов. В большинстве случаев стандартный редактор Windows Notepad не подходит для этих целей. Он использу- ет специфическую Win-кодировку символов (СР-1251 в русской локализации) и добавляет в конец каждой строки, кроме символа возврата строки <lf>, символ перевода каретки <cr>. Системы на основе ОС Linux используют UNIX-кодировку UTF-8 и одиночный символ <lf> в конце строки. Поэтому микрокомпьютеры, о ко- торых говорится в этой книге, не поймут текстовый файл, созданный или изменен-
58 Глава 2 ный в редакторе Windows Notepad. Редактор Notepad++ позволяет сохранять тек- стовые файлы в любой кодировке с нужным символом конца строки. Скачайте установочный файл редактора по адресу https://notepad-plus-plus.org/ download/ и установите редактор. Запустите его и настройте рабочую кодировку (рис. 2.34). Символ конца строки можно задать щелчком на строке состояния (пока- зано стрелкой). Вы можете использовать этот редактор для редактирования про- грамм с подсветкой синтаксиса, выбрав нужный язык программирования в меню Синтаксисы. :.V Кодировка а UTF-3 6е 60М ; К | ^Г Ксдирсе^ ■ №<? ^ : *' - * - ксдироека в УС л-Г: 1яд Епййп К с д и с о 0 к; с< г U С S • 2 L i Ш £• Е ?",> с! i а п Рис. 2.34. Текстовый редактор Notepad++
ГЛАВА 3 Онлайн-лаборатория Autodesk Circuits Прогресс подарил нам возможность разрабатывать и отлаживать устройства про- граммно, не собирая схему «в железе». Такие программы называются симулятора- ми и различаются перечнем поддерживаемых устройств и инструментов для отлад- ки. Но мы пойдем дальше и воспользуемся новым бесплатным сервисом от знаме- нитой компании Autodesk. Он доступен по адресу www.circuits.io и начал работать совсем недавно. Это виртуальная лаборатория радиолюбителя, которая не требует установки про- граммы на компьютер пользователя. Весь процесс разработки происходит в окне браузера. Для комфортной работы не требуется сверхбыстрый Интернет или мощ- ный компьютер. Разработчики Autodesk Circuits рекомендуют использовать Google Chrome, но в браузерах Edge и Safari сервис тоже работает без проблем. Что позволяет делать лаборатория? Практически все, что нужно радиолюбителю с начальным и средним уровнем подготовки: ♦ создавать визуальные макеты проектов на беспаечной макетной плате; ♦ рисовать принципиальные электрические схемы; ♦ разводить печатные платы и заказывать их изготовление; ♦ симулировать работу схем из дискретных компонентов; ♦ подключать к схеме функциональные генераторы, вольтметры и осциллографы; ♦ писать программы для Arduino и эмулировать их выполнение; ♦ хранить свои проекты в облаке и работать с ними на любом компьютере из любого места; ♦ работать над проектами в команде и делиться ими с окружающим миром. Возможно, вы уже знаете о популярной среде разработки Fritzing, которая обладает многими из упомянутых функций (о среде Fritzing рассказано в главе 4). Преиму- щество Autodesk Circuits заключается в симуляции программ для Arduino и воз- можности подключать виртуальные измерительные приборы. Кроме того, нет не- обходимости устанавливать и периодически обновлять приложение на своем ком-
60 Глава 3 пьютере. Это позволяет работать над проектом в любом месте, на любом компью- тере или планшете. Разумеется, нужен доступ в Интернет. Сервис активно развивается. Он постоянно пополняется новыми функциями и мо- делями, устраняются мелкие недостатки. Следует особо подчеркнуть полную открытость сервиса Autodesk Circuits. Любой проект, компонент, схема или печатная плата доступны для просмотра каждому за- регистрированному пользователю. Понятия закрытой рабочей области не существу- ет. Вам принадлежит личное рабочее пространство, которое представляет собой хранилище ваших объектов и их список. Представьте огромный зал общественной лаборатории, где стоит ваш рабочий стол, на котором вы работаете с проектами. Разумеется, посторонний пользователь не может произвольно вмешаться в вашу работу, пока вы его не пригласите работать в команде. Но любой желающий может скопировать ваш проект или компонент и создать ветку разработки (fork — развилка, ответвление). Дальше ветки будут существовать независимо и в любой момент мо- гут образовать новые ветки. Помните о полной открытости и будьте тактичны по от- ношению к сообществу пользователей. 3.1. Регистрация и первый проект Заполнив простую регистрационную форму, вы можете немедленно приступить к разработке виртуального проекта. Сервис предлагает на выбор три виртуальных мастерских: ♦ Open Electronics Lab Hub — лаборатория для макетирования электронных схем и разработки программного кода. Позволяет рисовать макеты и принципиальные электрические схемы, писать программы и запускать их симуляцию в виртуаль- ных платах Arduino; ♦ Open Circuit Scribe Hub— эмулятор детской образовательной платформы Circuit Scribe, которая позволяет рисовать на бумаге схему специальными токо- проводящими чернилами и подключать к ней различные модули; ♦ Open PCB Design Hub — средство для разработки печатных плат и передачи заявки на изготовление. 3.1.1. Создание макета и симуляция Нажмите кнопку Electronics Lab на главной странице и перейдите в персональную электронную лабораторию. В левом верхнем углу окна браузера находится кнопка для отображения главного меню сервиса. В нижней части окна расположены не- сколько учебных проектов, которые вы можете открыть и запустить на эмуляцию, чтобы оценить возможности сервиса. Нажмите кнопку New Electronics Lab для создания своего первого проекта. По умолчанию открывается окно с большой макетной платой. Но для нашего первого проекта она слишком велика. Выделите плату щелчком мыши и удалите нажатием клавиши <Delete> на клавиатуре. Нажмите кнопку -^Components и в строке поиска введите слово breadboard. Во вто- рой главе была рассказана история этого термина. Достаточно нескольких первых
Онлайн-лаборатория Autodesk Circuits 61 букв (рис. 3.1). Компоненты можно подбирать по категориям, но если вы знаете англоязычные названия, то при помощи строки поиска комплектация схемы проис- ходит намного быстрее. Например, светодиод мгновенно находится по трем буквам led, а резистор по буквам res. Blink Led М М АН Components list Arduino Basic Kit OF Rob Breadboard Breadboard SmaH Рис. З.1. Поиск и размещение макетной платы Сейчас мы говорим только о компонентах, пригодных для симуляции на макетной плате. О компонентах для рисования обычных электрических схем и разработки пе- чатных плат мы поговорим позже. Их очень много. Кроме того, вы можете создавать свои компоненты. Аналогичным способом найдите плату Arduino. На момент подготовки книги вы- бор стандартных плат, пригодных для симуляции, был невелик: Arduino Uno R3, DFRduino R3 и Arduino Micro. Наверняка вскоре их станет больше. Установите плату Arduino Micro и разъем USB для подачи питания, как показано на рис. 3.2. Обратите внимание, что при наведении курсора на вывод компонента ото- бражается его название. Поместите на плату провода питания. Все плюсовые линии питания сделайте красными, a GND— черными (рис. 3.3). Возьмите за правило назначать проводам интуитивно понятные и общепринятые цвета. Всю разводку одного сигнала выполняйте одинаковым цветом. Это облегчит чтение схемы. Вот и все! За несколько минут вы собрали макет, пригодный для запуска програм- мы, не потратив ни копейки. На фабрике в платы Arduino записывают простейшую
62 Глава 3 Рис. 3.2. Размещение платы Arduino и разъема питания Рис. 3.3. Макет готов к запуску симуляции
Онлайн-лаборатория Autodesk Circuits проверочную программу. Она мигает встроенным светодиодом, подключенным к выводу D13. В модель платы Arduino Micro тоже записана эта программа. На- жмите кнопку Start Simulation. Светодиод на плате начнет мигать один раз в се- кунду. Если это не произошло, проверьте правильность соединений. Остановите симуляцию и нажмите кнопку Code Editor. Попробуйте менять значе- ние длительности задержки в строках 14 и 16. Внеся изменение, нажмите кнопку Upload & Run для загрузки и запуска программы. Пока симулятор работает, редак- тировать программу невозможно. Теперь добавим внешнюю цепь из светодиода и резистора (рис. 3.4). Установив на плату резистор, в панели свойств задайте номинал 220 Ом. После установки свето- диода вы можете выбрать в панели свойств его цвет. Внесите в программу небольшое изменение. Строку int led = 13; замените на int led = 7;, потому что цепь из резистора и светодиода подключена к выводу D7. Теперь после запуска симуляции начнет мигать внешний светодиод. Качество си- муляции не идеально, в некоторых браузерах светодиод включается сразу, а гаснет плавно, хотя плавное гашение программой не предусмотрено. Это издержки брау- зерной симуляции. В качестве тренировки измените программу так, чтобы мигали оба светодиода, но в противофазе: когда зажигается светодиод на плате, внешний должен гаснуть. Рис. 3.4. Окончательный вариант схемы
64 Глава 3 Вы можете открыть этот проект по ссылке https://circuits.io/circuits/3370250-blink- led. Буду признателен, если в комментариях к проекту вы оставите свои вопросы, отзывы и пожелания. 3.1.2. Принципиальная электрическая схема макета В верхней панели окна проекта нажмите кнопку Schematics View со стилизован- ным изображением электрического символа микросхемы О. В открывшемся окне появится принципиальная схема проекта, которая будет выглядеть, как хаотичное нагромождение элементов. Придется немного потрудиться над их компоновкой, перемещая и вращая элементы, чтобы сделать схему наглядной (рис. 3.5). Схема привязана к макету, и вы не можете произвольно добавлять и редактировать компоненты. Рисовать произвольные схемы и разводить по ним печатные платы можно в среде РСВ Design. Работу в ней мы рассмотрим позже. 11111 11111 1111 |о о о о о о о ооо о о о о о о а] 1 > > § g н ? Arduino Hi era о О 5* S 2 О ооооооооооооооооо I 1 I I I I I I I I Г т 1 I Г и3 CD t \ Рис. 3.5. Принципиальная электрическая схема проекта 3.1.3. Печатная плата по схеме макета В верхней панели окна проекта нажмите кнопку РСВ View со стилизованным изо- бражением установочной площадки микросхемы О. Полученный эскиз печатной платы (рис. 3.6)1 не имеет практического смысла, поскольку состоит из уже готовой платы и содержит дополнительное гнездо USB, которое и без того имеется на плате Arduino Mini. Как вы помните, мы использовали разъем USB на макете, чтобы ими- тировать источник питания. Но для тренировки этот эскиз вполне годится. 1 Из-за ограничений типографской технологии снимок экрана пришлось обратить в негативный, иначе темные детали рисунка на черном фоне будут плохо различимы.
Онлайн-лаборатория Autodesk Circuits 65 ,« \4 >i Рис. 3.6. Эскиз печатной платы по схеме макета Вы можете изменять размеры и форму платы. Двойной щелчок по кромке платы добавляет в этом месте точку перегиба. Добавив несколько таких точек и пере- мещая их, можно создать плату произвольной формы. Двойной щелчок по ранее созданной точке превращает ее в опорную точку для построения кривой Безье. 3.2. Создание и редактирование компонентов Прежде чем приступить к рисованию электрических принципиальных схем, надо научиться создавать собственные компоненты. Готовых компонентов достаточно много, но в любой момент может случиться так, что их окажется недостаточно. Компонент— это любая радиодеталь или модуль, задействованные в схеме уст- ройства. Каждый компонент состоит из символа — графического изображения для принципиальной схемы и монтажного чертежа для печатной платы. ♦ Символ содержит контур компонента и его выводы с нумерацией и описанием. Иногда, особенно в любительских проектах, символ делают максимально похо- жим на исходный физический объект, чтобы облегчить понимание схемы (рис. 3.7). Вы можете рисовать свои символы как угодно, но лучше следовать общепринятым правилам и обеспечивать наилучшую читаемость схемы. Один и тот же символ может использоваться для изображения множества разных ком- понентов одного типа. Например, символ и-/?-и-транзистора обозначает любой транзистор типа п-р-п.
66 Глава 3 AUTODESK CIRCUITS f ♦••• | ARDUfMO Рис. З.7. Отображение платы Arduino в качестве компонента схемы ♦ Монтажный чертеж обязательно содержит отображение монтажных площадок (footprint) для печатной платы в соответствии с размещением физических выво- дов компонента. Площадки могут быть как поверхностными (SMD), так и с от- верстиями. На монтажный чертеж обычно добавляют габаритный контур ком- понента и поясняющие надписи и метки, облегчающие правильное размещение на плате. Монтажный чертеж может быть использован для различных компо- нентов с одинаковым типом корпуса. Например, в корпусе SOT-23 может нахо- диться транзистор, диодная сборка или стабилизатор напряжения. Благодаря унификации, вовсе не обязательно для каждого компонента заново рисо- вать символ и монтажный чертеж. С большой вероятностью можно найти готовую работу. После создания символа и монтажного чертежа следует задать соответствие между выводами компонента на графическом отображении и номерами монтажных пло- щадок, чтобы редактор платы смог отобразить электрические связи. Через главное меню сайта перейдите в раздел РСВ Design и нажмите ссылку Components. В центре экрана расположены значки компонентов, над которыми работают другие члены сообщества. Список очень длинный и подгружается по мере прокрутки. Еще раз напомню, что Autodesk Circuits — это абсолютно открытое сообщество. Разработанные вами компоненты будут доступны всем желающим для копирования и использования. В качестве примера создадим компонент для модуля Wi-Fi ESP-09. Это миниатюр- ный модуль, предназначенный для припаивания на базовую печатную плату (рис. 3.8). Нам надо создать символ, чертеж площадок печатной платы и связать площадки с выводами изображения.
Онлайн-лаборатория Autodesk Circuits 67 Рис. 3.8. Миниатюрный модуль Wi-Fi ESP-09 для поверхностного монтажа 3.2.1. Создание символа компонента Нажмите кнопку +New в правом верхнем углу, а затем New PCB Component. Вве- дите имя компонента. Желательно, чтобы оно отражало сущность и особенности компонента. Используйте англоязычные термины и латиницу, чтобы название было понятно всему сообществу (рис. 3.9). I | Oescr®li6n ! (-(.'('.«(Vi,,!,!^»;.;^ -v. Рис. 3.9. Имя и описание нового компонента Теперь создадим символ компонента, который будет отображаться в электрической схеме. Нажмите кнопку Add Symbol — в нижней части экрана откроется список готовых символов, разработанных другими членами сообщества. Координаторы сервиса настоятельно просят проверять наличие готового симво- ла, прежде чем начать рисование. Не следует дублировать имеющиеся символы без нужды и засорять общественную библиотеку. Примените к списку поиск по названию (рис. 3.10). Попробуйте разные варианты названия. В нашем случае ни- кто раньше не создавал компонент для модуля ESP-09. Создадим его с самого на- чала. Нажмем кнопку Create New. Откроется окно графического редактора. При помощи инструментов Реп (Ручка), Rectangle (Прямоугольник) и Circle (Окружность) нарисуем символ. Наличие даже примитивного карандашного эскиза
68 Глава 3 ЕSP8266 Base (forked} ШЛШ ESP8266-G1 Base «forked) ESP8266.ESP-Q7.ESP-12 (forked) Рис. 3.10. Проверка наличия готовых символов компонента на бумаге поможет значительно ускорить работу и обойтись без серьезных исправ- лений. Добавьте выводы при помощи инструмента Place Terminal (Разместить вывод). Номер вывода можно редактировать. Работа с выводами имеет свои особенности. В схеме подключение внешнего проводника к выводу происходит в точке, обозна- ченной квадратиком. Линия вывода означает направление отвода проводника и на схеме не отображается. Если нужно, чтобы символ имел отображаемые выводы, нарисуйте каждый из выводов по отдельности инструментом Реп. Затем на внеш- ний конец каждого отвода прикрепите значок вывода. Добавьте поясняющие надписи и номера выводов. Убедитесь, что номер терминала в его свойствах совпадает с нужным номером вывода. При добавлении и переме- щении вывода редактор пытается автоматически задать ему номер. Иногда это вно- сит путаницу. Готовый символ, который у меня получился, изображен на рис. 3.11. Вы можете найти его по адресу https://circuits.io/components/3405032-esp-09-l. Обратите вни- мание, как оформлены выводы. Это один из возможных вариантов. Чтобы упростить работу по созданию стандартного многовыводного символа, можно нажать кнопку Generate Symbol с изображением микросхемы. В открыв- шейся нижней панели отредактируйте количество выводов на каждой из сторон. Затем измените названия выводов, добавьте поясняющие надписи, задайте имя компонента и сохраните его нажатием на кнопку Save and Add Symbol. Генератор символов существенно ускоряет работу, но недостаточно гибок, если надо создать собственный символ нестандартного вида.
Онлайн-лаборатория Autodesk Circuits 69 Autodesk Circuits / Components / ESP-O'9*1 vcc ANT GUD GHD GHD GHD GHO GND GHD GND CH_PD RESET TX 4. RX GP1O0 GP1O2 GPIO15 GFIO13 GPIO12 GPIO14 ESP-09 Close H N Ц А 4 О Рис. 3.11. Символ компонента готов к сохранению 3.2.2. Создание монтажного чертежа компонента Теперь создадим чертеж контактных площадок нашего компонента. Обычно в ка- честве источника данных используют фирменный чертеж радиодетали или модуля, предоставляемый изготовителем. В зарубежных текстах такой чертеж обычно называется Pad Layout (раскладка площадок) или Footprint (оттиск). В окне редактирования компонента (рис. 3.12) нажмите в панельке, расположенной в левом верхнем углу рабочей области, кнопку Footprint View и затем Add Footprint | Create New. В модуле ESP-09 все контактные площадки предназна- чены для поверхностного монтажа. Используем инструмент SMD Pad Tool. В ка- честве источника информации о размерах и координатах контактных площадок я использовал чертеж из открытой графической библиотеки элементов другой про- граммы. Площадки автоматически нумеруются по мере размещения на плате. Можно пред- варительно расставить площадки в приблизительном порядке, а затем настроить точные координаты и размеры. Внимание: все размеры приводятся в микрометрах (тысячных долях миллиметра). После настройки площадок при помощи графических инструментов нарисуйте кон- тур детали. Рекомендуется изображать характерные признаки, облегчающие пра- вильное позиционирование детали на плате: положение ключа, среза корпуса и т. д. Наконец чертеж готов (см. рис. 3.12). Обратите внимание, что на нем схематично указано расположение микросхем и кварцевого резонатора (сравните с фотографи- ей модуля на рис. 3.8).
70 Глава 3 #ж т >;.;:;jj 4-;й«3 «да Рис. 3.12. Чертеж установочного места модуля ESP-09. (Цвет рисунка инвертирован для лучшей наглядности при печати) После сохранения чертежа необходимо задать соответствие между выводами сим- вола и контактными площадками. В окне редактирования компонента нажмите кнопку Mapping View в панельке слева (см. рис. 3.13). Щелкните на выводе 1 сим- вола, затем на площадке 1 чертежа. Цвет вывода и площадки изменится. Редактор подсказывает малиновым цветом, какую площадку выбрать следующую, но вы мо- жете выбрать свой порядок обхода выводов. Рис. 3.13. Установка соответствия между выводами символа и контактными площадками
Онлайн-лаборатория Autodesk Circuits 71 Несмотря на то, что выводы и площадки могут быть связаны в произвольные пары, желательно, чтобы их обозначения взаимно соответствовали: 1—>1, 2—>2. В против- ном случае будет очень сложно читать чертеж печатной платы и выполнять ручную трассировку дорожек. Если вы завершили редактирование компонента и не предполагаете вносить изме- нения, нажмите под рабочей областью редактора (см. рис. 3.13) кнопку Mark As Done (пометить, как завершенный). Компонент станет доступен для использования в схемах и создания ответвлений. 3.2.3. Работа с чужими компонентами Щелкните на значке любого пользовательского компонента. Он откроется в окне просмотра. Под изображением расположена панель обсуждения компонента. Вы можете вести открытое обсуждение этого компонента и обращаться к разработчи- ку. Точно так же члены сообщества смогут обращаться к вам и обсуждать ваши компоненты. Нажмите кнопку Duplicate Component. Произойдет перенос копии компонента в ваше рабочее пространство. Таким образом, вы создадите ответвление (fork) от чужой разработки. Теперь нажмите кнопку Manage Symbols. В открывшемся списке нажмите кнопку Edit напротив нужного компонента. Откроется окно редак- тирования (рис. 3.14). Component's / HC-SR04 Help it и и Ш л з о Рис. 3.14. Редактирование чужого компонента К названию компонента автоматически добавляется в скобках слово forked, чтобы остальным пользователям было понятно, что это ответвление от ранее созданной работы. Проявите уважение к открытому сообществу и автору компонента. Не уда- ляйте это слово, либо измените название так, чтобы всем было понятно, зачем вы создали ответвление. Одинаковых элементов с пометкой forked может быть
72 Глава 3 несколько. Это означает, что несколько человек создали свои независимые ветки. Автор тоже может создать несколько ветвлений своей работы. 3.2.4. Доступ к своим компонентам Чтобы получить доступ к перечню компонентов, над которыми вы работали, нажмите на аватарку своего профиля в правом верхнем углу страницы. Затем выбе- рите пункт Components. Нажав на значок компонента, вы сможете продолжить ре- дактирование, изменить название и описание компонента или пометить компонент, как завершенный. 3.2.5. Рисование принципиальной схемы В главном меню нажмите кнопку РСВ Design (Печатная плата) и далее кнопку +New РСВ Design. Технология рисования предельно упрощена. Новый компонент добавляется кнопкой +Components. Один и тот же компонент может быть размещен в корпусах разного типа. Напри- мер, микросхемы для поверхностного монтажа (корпус SOP) и монтажа в отверстия (корпус DIP). Если не знаете, какой корпус выбрать, щелкните мышью на названии элемента. Откроется отдельное окно просмотра, в котором будет показан символ элемента и чертеж контактных площадок. Вот почему при создании компонентов желательно упоминать в названии тип корпуса — чтобы не терять потом время на проверку. Набор функций для рисования схемы весьма ограничен. Ваша задача— указать курсором два вывода, и редактор автоматически нарисует соединительный провод- ник. Вы не можете корректировать его форму и положение. Возможно, придется 1 ] • I D О ;. 00 Рис. 3.15. Пример схемы, разработанной пользователем Autodesk Circuits
Онлайн-лаборатория Autodesk Circuits подобрать оптимальное расположение компонентов для лучшей читаемости схемы. Тем не менее, после небольшой тренировки вы сможете быстро рисовать достаточ- но большие и сложные схемы (рис. 3.15). Для редактирования печатной платы переключитесь в режим РСВ View при помо- щи верхней строки меню. Процесс редактирования не отличается от упомянутого ъразд. 3.1.3. 3.3. Вывод схемы и чертежа платы на печать Возможно, вам понадобится распечатать рисунок печатной платы для изготовления самодельного фотошаблона и платы в домашних условиях либо создать файл доку- ментации для заказа платы на предприятии. Рисунок схемы нужен для размещения на своем сайте или для распечатки на бумаге. 3.3.1. Получение рисунка принципиальной схемы На момент подготовки книги функция экспорта принципиальной электрической схемы в какой-либо файл в сервисе Autodesk Circuits отсутствовала. Пользователю предлагается опубликовать схемы на своем сайте или в соцсетях в виде прямой ссылки на проект. Вероятно, такое ограничение введено для привлечения пользова- телей непосредственно на сайт circuits.io. Поэтому единственный способ получить рисунок схемы — сделать снимок экрана при помощи любой утилиты захвата изо- бражения или нажатием клавиш <Alt>+<PrintScreen> на клавиатуре и отредактиро- вать изображение в графическом редакторе. 3.3.2. Экспорт рисунка печатной платы в формате Eagle Для работы с печатной платой предоставляется больше возможностей. Откройте свой проект и нажмите кнопку Show More. Если ваш проект основан на стандарт- ных компонентах симулятора, то вы можете экспортировать рисунок печатной пла- ты в формате Eagle. Это программа для разработки схем и печатных плат от компа- нии Autodesk, которая предоставляет онлайн-сервис circuits.io. Поэтому обеспечи- вается полная совместимость форматов и компонентов. Для экспорта нажмите кнопку Export Eagle Board. Скачанный файл платы можно открыть в редакторе Eagle и редактировать локаль- но. Описание приемов работы с программой Eagle занимает отдельную книгу и здесь не приводится. 3.3.3. Экспорт чертежа платы в формате GERBER Также есть возможность экспортировать чертеж платы в универсальном формате GERBER. Нажмите кнопку Download Gerber и дождитесь скачивания архива, со- держащего пакет Gerber-файлов. Имейте в виду, что архив содержит файлы описа-
74 Глава 3 ния платы, готовой к производству. Любое редактирование можно выполнять только в окне редактора платы. GERBER— унифицированный файловый формат, описывающий печатную плату для изготовления на различном оборудовании. Почти все современные программы генерируют Gerber-файлы, и практически любое современное оборудование пони- мает данные в этом формате. Gerber-файл представляет собой текстовое описание команд прорисовки различных элементов печатной платы (проводники, отверстия, площадки, надписи). Данные разделяются на функциональные слои: слой надписей, слой проводников, слой отверстий и т. д. Для просмотра Gerber-файлов перейдите на сайт http://circuitpeople.com и загрузи- те на него ваш архив с Gerber-файлами. Принцип работы с сайтом чрезвычайно прост. После обработки архива откроется страница со значками рабочих слоев пакета. Сервис автоматически распознает назначение большинства слоев: ♦ Silk Top — надписи на верхней стороне платы; ♦ Mask Top — рисунок паяльной маски на верхней стороне платы; ♦ Copper Top — рисунок проводников на верхней стороне платы; ♦ Silk Bottom — надписи на нижней стороне платы; ♦ Mask Bottom — рисунок паяльной маски на нижней стороне платы; ♦ Copper Bottom — рисунок проводников на нижней стороне платы. Поддержку слоя сверления обещают добавить в ближайшее время. Выберите подходящее разрешение рисунка слоя и скачайте его. Для изготовления фотошаблона выбирайте разрешение 300 или 600 dpi.
ГЛАВА 4 Среда разработки и макетирования Fritzing Бесплатное приложение Fritzing предназначено для любительской разработки элек- тронных схем— от визуального макетирования и рисования схемы до разводки печатной платы и редактирования кода прошивки. Для работы следует скачать и установить это приложение на компьютер. Доступны версии для Windows, Mac и Linux. В книге рассмотрена версия 0.9.3Ь. В чем основные отличия Fritzing от упомянутой в предыдущей главе онлайн- лаборатории Autodesk Circuits? Fritzing не поддерживает визуальную симуляцию работы устройства и подключение виртуальных приборов, но позволяет загружать код прошивки непосредственно в устройство. Иными словами, Autodesk Circuits это, в первую очередь, виртуальная лаборатория, которая позволяет изучить основы электроники даже без покупки компонентов. Fritzing же в большей степени является средой разработки прикладных любитель- ских проектов, особенно с расчетом на последующую публикацию. Наглядные изо- бражения схем и макетов в стиле Fritzing популярны среди начинающих любителей электроники. 4.1. Установка Fritzing Программа не требует специальной установки и запускается из любого каталога. Скачайте файл архива для своей операционной системы с сайта www.fritzing.org и распакуйте в удобную папку. Заодно можно создать и ярлык для запуска програм- мы. Пользовательские файлы хранятся в другом месте, поэтому при обновлении программы не будут утрачены. Новые версии Mac OS по умолчанию не позволяют запускать приложения из не- проверенных источников. Чтобы преодолеть это ограничение, для запуска про- граммы щелкните правой кнопкой мыши на значке приложения и выберите Open. В открывшемся диалоговом окне безопасности снова выберите Open. Первый запуск после установки может длиться долго — приложение будет прове- рять наличие обновлений и загружать обновленные библиотеки элементов. При
_7g Глава 4 этом программы мониторинга безопасности на вашем компьютере могут запросить разрешение на скачивание файлов. Чтобы отключить запрос при каждом запуске, добавьте Fritzing в исключения системы безопасности. 4.2. Создание макета схемы Запустите приложение и перейдите на вкладку Макетная плата. Справа от рабоче- го поля расположена библиотека компонентов: вкладка CORE — библиотека стан- дартных компонентов программы, вкладка МШЕ — библиотека компонентов, соз- данных или загруженных пользователем. Далее идут библиотеки компонентов раз- личных производителей. Нажмите на значок с изображением логотипа Arduino. Перетащите на рабочее поле изображение модуля Arduino Nano. Для вращения компонента можно использовать сочетание клавиш <Ctrl>+<R>, для зеркального отражения по вертикальной оси — <Ctrl>+<F>. Аналогичным образом перенесите на макетную плату красный светодиод и рези- стор из библиотеки CORE. Разместите элементы на макетной плате (рис. 4.1). Об- ратите внимание на правильную полярность подключения светодиода. Рис. 4.1. Макет простейшей учебной схемы Справа под списком библиотек находится окно Инспектора компонентов. Выдели- те компонент на макете, схеме или печатной плате. Если компонент имеет редакти- руемые свойства (сопротивление, цвет, размер и т. д.), их можно изменить в окне Инспектора. Цвет проводников можно выбрать щелчком правой кнопки мыши.
Среда разработки и макетирования Fritzing 77 4.3. Создание принципиальной электрической схемы Продолжим работу над проектом. Переключитесь на вкладку Принципиальная схема. Все выбранные вами компоненты уже размещены в окне редактирования. Теперь надо отредактировать их положение и добавить проводники (рис. 4.2). Схе- му можно нарисовать без предварительного создания макета. LEO1 Red (633nm) ж- R1 220Q Рис. 4.2. Принципиальная электрическая схема макета Вращать подписи компонентов и менять их содержание можно при помощи меню, которое открывается правым щелчком мыши. Аналогично меняется цвет провод- ников, добавляются или удаляются точки перегиба. 4.4. Разработка чертежа печатной платы Переключитесь на вкладку Печатная плата и отредактируйте расположение ком- понентов. По умолчанию все компоненты располагаются на верхней стороне платы (top). Изменить расположение на нижнюю сторону (bottom) можно в окне Инспек- тора. Также в окне Инспектора можно указать расположение и толщину соедини- тельных дорожек. Пустые участки платы в большинстве случаев принято «заливать» проводящим слоем меди. Слой медной фольги улучшает экранирование платы и помогает рав- номерно рассеивать тепло, а также экономит травильный раствор. Заливку обычно соединяют с общим проводом («землей»). Выберите пункт главного меню Routing
78 Глава 4 (Трассировка), далее Ground Fill | Ground Fill Seed Editor и поставьте галочку на- против опции GND. Затем нажмите кнопку OK and fill. Активный рабочий слой будет залит медью, а нужные выводы компонентов соединятся перемычками с об- щим проводом (рис. 4.3). Если соединение с общим проводом не требуется, заливку можно выполнить про- ще. В библиотеке компонентов CORE найдите раздел Печатная плата и перета- щите значок с названием Copper Fill прямо на плату. Рис. 4.3. Готовый рисунок печатной платы учебного проекта с заливкой медью 4.5. Экспорт чертежа печатной платы Готовый чертеж печатной платы можно экспортировать в разнообразные форматы. Пользуясь кнопкой Export to PCB в нижней части окна, вы можете быстро конвер- тировать чертеж в файлы PDF или SVG и распечатать их для изготовления само- дельных фотошаблонов или конвертировать в формат Gerber RS-274 для передачи на производство. Внимание: при экспорте создается большое количество фай- лов — по одному на каждый рабочий слой платы, включая паяльные маски и надпи- си. Поэтому экспортируйте чертеж в заранее созданную пустую папку. Меню Файл | Экспорт предоставляет более широкий выбор опций. С его помощью можно сохранить чертеж платы в виде растрового рисунка, а также экспортировать список компонентов и файл описания электрических соединений схемы.
Среда разработки и макетирования Fritzing 79 4.6. Добавление компонентов в библиотеку Независимые разработчики создали множество компонентов, которые можно доба- вить в библиотеку Fritzing. Разнообразный запас дополнительных компонентов за- ботливо собран на сайте http://robotosha.ru/arduino/fritzing-library.html. Скачайте нужный файл. Щелкните правой кнопкой мыши на разделе MINE в окне списка компонентов и выберите пункт Import. В открывшемся окне найдите скачанный файл и добавьте его. Щелкните правой кнопкой мыши на вкладке МЕЧЕ и выбери- те пункт Save Bin, чтобы сохранить компонент в библиотеке для будущих сеансов работы. Создание новых элементов в приложении Fritzing — весьма нетривиальная задача. Прежде всего, новый компонент в текущей версии программы невозможно создать с нуля. Надо выбрать наиболее похожий из уже имеющихся в базовом наборе и от- редактировать его. Для редактирования кроме встроенного редактора потребуется любой векторный редактор (CorelDRAW, Adobe Illustrator, Inscape) и навыки рабо- ты с ним. Поэтому даже опытные пользователи рекомендуют, прежде всего, поста- раться найти уже готовый компонент, чтобы не тратить время зря. Подробное описание процесса создания нового компонента выходит за рамки ма- териала книги. При необходимости рекомендую ознакомиться с подробной статьей на сайте http://robotosha.ru/arduino/owii-part-fritzing-partl.html. 4.7. Разработка и загрузка программ Несмотря на то, что в среде Fritzing есть встроенный редактор кода программ с подсветкой синтаксиса, функции самостоятельной компиляции кода и выгрузки программного кода в платы Arduino остаются нереализованными с 2014 года. Для компиляции и загрузки кода необходимо использовать средства Arduino IDE. Судя по ответам разработчиков Fritzing, маловероятно, что полноценный и автономный инструмент программирования когда-либо будет реализован. Действительно, разработка и редактирование программ для Arduino в среде Fritzing не имеет практического смысла. Если вы установили среду разработки Arduino IDE, то заниматься программированием надо именно в ней, a Fritzing следует ис- пользовать для разработки схем и печатных плат. В главе 5 мы подробно рассмот- рим работу с Arduino IDE.
ГЛАВА 5 Обучающая платформа Arduino Аппаратно-программная платформа Arduino совершила революцию в мире средств обучения и разработки. Ключевые достоинства Arduino — минимализм конструк- ции, низкая цена и работа из коробки. До появления этого проекта обучающие пла- ты предназначались для студенческих лабораторий и выглядели иначе. Считалось правильным разместить на них максимум внешних компонентов, чтобы получить стендовый набор «все-в-одном»: светодиоды, кнопки, регуляторы. Такие платы до- рого стоили и требовали от студентов немалых усилий, чтобы разобраться с их конструкцией. При этом они почти не поддавались расширению и ограничивали диапазон проектов. Автор идеи Arduino, итальянский преподаватель и предприниматель Массимо Бан- ци, никогда не работал инженером, поэтому легко перевернул концепцию с ног на голову. Получившийся продукт иногда вызывает раздражение профессиональных инженеров-электронщиков, но отлично работает и покорил мир. На базовых платах Arduino присутствует минимум компонентов и максимум кон- тактов для подключения внешних элементов. Именно в модульной структуре заключается аппаратная мощность и гибкость Arduino. К основной плате можно подключить десятки различных датчиков, исполнительных устройств и расши- ряющих модулей. Поэтому диапазон проектов зависит только от вашей фантазии и доступности модулей расширения. Впрочем, никто не мешает вам придумать свои модули. Платформа Arduino не стала бы настолько популярной без удобного средства раз- работки и отладки программ. Массимо Банци взял за основу среду программирова- ния проекта Wiring. В нем применяется интуитивно понятный и простой язык про- граммирования Processing, адаптированный к использованию в микроконтролле- рах. В результате получилась среда разработки и отладки Arduino IDE. Она тоже работает по модульному принципу и допускает подключение программных расши- рений в виде описаний сторонних микроконтроллеров и плат, не входящих в состав семейства Arduino. Все электрические схемы, чертежи печатных плат и исходные коды программ находятся в открытом доступе.
Обучающая платформа Arduino 81_ Практически все современные платформы, например Raspberry Pi, обеспечивают поддержку среды Arduino IDE и языка Processing. Похожий синтаксис и приемы программирования аппаратных ресурсов применяются в других языках программи- рования — Python и Lua. Поэтому ваши навыки программирования не пропадут зря при переходе к другим платформам. 5.1. Аппаратная база платформы, популярные модели Прежде, чем перейти к практическим проектам, кратко ознакомимся с базовыми платами Arduino, которые рекомендуются для использования новичками. Полный перечень плат и модулей намного шире, с ним можно ознакомиться на сайте www.arduino.cc, но начинать лучше с простых популярных плат, которые можно приобрести в отечественных и зарубежных магазинах по низкой цене. Платы гото- вы к немедленному началу работы, все необходимые выводы портов разведены на боковые разъемы. В этой книге мы используем современные варианты плат, но вы можете встретить устаревшие версии на микроконтроллере ATmegal28. Будьте внимательны. 5.1.1. Arduino Nano Контроллер: ATmega328P Рабочее напряжение: 5 В Внешнее питание: 7...12 В Тактовая частота: 16 МГц Цифровые порты: 14 (из них 6 ШИМ) Аналоговые входы: 8 (10 битов АЦП) Предельный ток порта: 40 мА Память программ: 32 Кбайт (бутлоадер 0,5 Кбайт) Память SRAM (ОЗУ): 2 Кбайт Память EEPROM: 1 Кбайт Размеры: 45x18 мм Вес: 5 г Рис. 5.1. Arduino Nano Arduino Nano — это «рабочая лошадка» любителя электроники. Плата полностью реализует возможности микроконтроллера ATmega328. С обратной стороны платы установлены линейный стабилизатор +5 В и конвертер USB-UART. Микросхема конвертера содержит встроенный стабилизатор +3,3 В. Этим напряжением можно питать внешние трехвольтовые модули с током потребления до 50 мА. Преимуще- ствами этой версии являются компактность и возможность установки непосредст- венно в беспаечную макетную плату. В некоторых проектах Arduino Nano устанав- ливается в разъем на основной плате в качестве «мозга» устройства.
82 Глава 5 Внимание! Внешнее нерегулируемое напряжение питания в диапазоне +7...+12 В следует пода- вать только на вход VIN! При этом на выводах 5V и 3.3V появятся соответствующие стабилизированные напряжения, которые можно использовать для питания внешних элементов схемы с суммарным потребляемым током до 50 мА. Стабилизированное внешнее напряжение +5 В можно подавать напрямую на вывод 5V. 5.1.2. Arduino Uno Рис. 5.2. Arduino Uno Контроллер: ATmega328P Рабочее напряжение: 5 В Внешнее питание: 7. .12 В Тактовая частота: 16 МГц Цифровые порты: 14 (из них 6 ШИМ) Аналоговые входы: 6 (10 битов АЦП) Предельный ток порта: 40 мА Память программ: 32 Кбайт (бутлоадер 0,5 Кбайт) Память SRAM (ОЗУ): 2 Кбайт Память EEPROM: 1 Кбайт Размеры: 68,6x53,4 мм Вес: 25 г Основное отличие платы Arduino Uno от Nano заключается в монтажном факторе. Если Nano вставляют в макетную плату, то Uno сама является макетной платой. Для нее выпускают множество расширений (шилдов), которые совпадают по форме и вставляются в разъемы поверх основной платы. Кроме того, на плате Uno есть дополнительный разъем для внешнего источника питания напряжением 7—12 В, электролитические конденсаторы в цепи питания и более сложная схема коммута- ции питания с автоматическим переключением между источниками. 5.1.3. Arduino Pro Mini Контроллер: ATmega328P Рабочее напряжение: 5 В / 3,3 В Внешнее питание: 7... 12 В (RAW) Тактовая частота: 16 МГц / 8 Мгц Цифровые порты: 14 (из них 6 ШИМ) Аналоговые входы: 6(10 битов АЦП) Предельный ток порта: 40 мА Память программ: 32 Кбайт (бутлоадер 0,5 Кбайт) ! Память SRAM (ОЗУ): 2 Кбайт ., „ . . . _ ... . Память EEPROM: 1 Кбайт Рис. 5.3. Arduino Pro Mini Размеры: 33,6x17,8 мм Вес: 3,8 г Arduino Pro Mini — это вариант платы с минимальным количеством внешних ком- понентов. Не содержит конвертер USB-UART, поэтому для соединения с компью- тером и программирования понадобится качественный внешний конвертер
Обучающая платформа Arduino 83^ (см. разд. 2.5.2). Официальная плата выпускается в двух вариантах рабочего на- пряжения и тактовой частоты: 5 В (16 МГц) и 3,3 В (8 МГц). От рабочего напряже- ния зависит микросхема стабилизатора, установленная на плате. Внимание! Внешнее напряжение питания в диапазоне +7...+12 В следует подавать только на вход RAW! Вывод VCC подключен непосредственно к линии питания микроконтрол- лера. Допускается подавать на него только стабилизированное напряжение +5 В или +3,3 В в зависимости от модификации платы. Будьте внимательны при покупке пла- ты и подключении внешнего конвертера USB-UART. Плату Arduino Pro Mini удобно монтировать непосредственно на поверхность печатной платы готового устройства. В сочетании с низкой ценой это делает плату незаменимым компонентом многих любительских и мелкосерийных проектов. 5.1.4. Arduino Mega 2560 Контроллер: ATmega2560 «* Рабочее напряжение: 5 В Внешнее питание: 7 .12 В Тактовая частота: 16 МГц Цифровые порты: 54 (из них 15 ШИМ) Аналоговые входы: 16 Предельный ток порта: 40 мА Память программ: 256 Кбайт (бутлоадер 8 Кбайт) Память SRAM (ОЗУ): 8 Кбайт Память EEPROM: 4 Кбайт Рис. 5.4. Arduino Mega 2560 Размеры: 101,5x53,3 мм Вес: 37 г По сравнению с предыдущими платами Arduino Mega 2560 имеет больше цифро- вых и аналоговых портов, увеличенный объем памяти. На плате установлен само- восстанавливающийся полимерный предохранитель, дополнительно защищающий порт USB компьютера от перегрузки. Благодаря большому количеству портов к базовой плате можно подключать быстродействующие цветные дисплеи с парал- лельной восьмибитной шиной, при этом остается достаточно выводов для работы с другими периферийными устройствами. 5.2. Установка драйверов USB-UART Большинство плат Arduino оснащено отдельной микросхемой конвертера протоко- лов USB-UART (о назначении конвертера рассказано в разд. 2.5.2). На фирменных платах и некоторых их клонах установлена микросхема FT232. Драйвер этой мик- росхемы автоматически устанавливается вместе с Arduino IDE, если вы дали согла- сие на установку драйвера. Кроме того, ОС Windows, начиная с версии Windows 7, автоматически распознает фирменный чип FT232 и может установить драйвер из собственного хранилища.
84 Глава 5 В некоторых платах Arduino в качестве конвертера используется еще один микро- контроллер Atmel, либо плата построена на чипе Intel. Для этих случаев установоч- ный пакет IDE также содержит нужные драйверы. Если вы не установили драйверы сразу, то впоследствии их можно найти в папке /drivers того каталога, в который вы установили или развернули из архива среду Arduino IDE. Недорогие клоны китайского производства обычно содержат микросхемы СН340 (СН341) или СР2102 (СР2103). Для работы с такими платами вам придется уста- новить драйверы самостоятельно. Определите маркировку микросхемы при по- мощи увеличительного стекла и скачайте нужный драйвер, например, с сайта www.fankraft.ru/download. Приведенные здесь рекомендации в равной степени относятся и к внешним моду- лям конвертера USB-UART, если плата Arduino не содержит встроенной микро- схемы. 5.3. Система нумерации выводов Arduino У начинающих разработчиков часто вызывает затруднение и непонимание специ- фическая нумерация выводов плат Arduino, которая используется в коде программ и не совпадает с физическими номерами выводов микроконтроллера. Эта система обозначений унифицирована для платформы Arduino и некоторых производных платформ. В качестве примера рассмотрим обозначения выводов платы Arduino Nano(pnc. 5.5). i.*:r TXD 'P01 ^.v%" RXO PO0 Щ}— \ :\n.t BESET, PC6 Щ— ЖР1 55 ''VM^ 'OCW- ■MISO1 "-mi МОЯ.,*м? 0€2::РЗЗ ■'*—-® -:#;: jgS" --г-/ Рис. 5.5. Обозначения выводов платы Arduino Nano На этом рисунке ближняя к кромке платы колонка — это физические номера выво- дов микроконтроллера ATmega328. Далее следует обозначение вывода в соответст- вии с его назначением в фирменном описании микроконтроллера. Помните, что
Обучающая платформа Arduino 85^ большинство выводов микроконтроллера поддерживают несколько функций, по- этому обозначение вывода может меняться в зависимости от контекста использова- ния. Внешние столбцы содержат номера выводов по системе Arduino. Найдите на рис. 5.5 вывод с физическим номером 1. В системе обозначений Atmel это цифровой порт ввода/вывода PD3, вход прерывания INT1, вход прерывания PCINT19, выход ШИМ ОС2В — в зависимости от контекста использования. В сис- теме обозначений Arduino это цифровой порт номер D3. В данном случае номер по системе Atmel совпадает с номером Arduino. Но в платформе Arduino нумерация выводов сплошная, поэтому дальше начинаются различия. Найдите вывод с физическим номером 13. В документации Atmel он обозначен как РВ1. Но в системе Arduino у него номер D9. Поэтому, если мы говорим, что све- тодиод подключен к выводу D13 Arduino, то имеем в виду обозначение вывода платы. Фактически же вывод Arduino D13 разведен на физический вывод 17 микро- контроллера. Поэтому при написании кода программы для самостоятельно разра- ботанной принципиальной схемы не забывайте переводить номера выводов микро- контроллера в номера портов Arduino. Важный нюанс: несмотря на то, что обозна- чения цифровых выводов содержат букву D, в тексте программы они именуются только цифрами. Ситуация с обозначениями аналоговых выводов запутана еще больше. Аналоговые входы на плате содержат префикс А, но в тексте программы могут обозначаться как с префиксом А, так и без него. Более того, выводы А0-А5 можно обозначить как номерами 0-5 (в контексте чтения аналоговых сигналов), так и номерами 14-19 (рис. 5.5). Но для лучшей читаемости программы желательно использовать обозна- чения аналоговых каналов только с префиксом А. Пример обозначения цифрового вывода в коде программы: pinMode(13, OUTPUT); // установить цифровой порт D13 (17) в режим выхода Примеры обозначения аналогового вывода в коде программы (все три обозначения равнозначны): analogRead(A3) ; // чтение напряжения на выводе A3 (26) при помощи АЦП analogRead(3); analogRead(17); 5.4. Среда разработки и отладки Arduino IDE Бесплатная среда разработки программ Arduino ШЕ позволяет писать, компилиро- вать и загружать собственные программы в память микроконтроллера, установлен- ного на Arduino-совместимой плате. Более того, Arduino DDE позволяет добавлять описания сторонних плат и микроконтроллеров для расширения базовой функцио- нальности. Внимание: возможен конфликт версий Обычно рекомендуют устанавливать самую свежую версию среды программирова- ния, но в случае с Arduino IDE ситуация сложнее. В процессе разработки новых вер- сий IDE изменилась версия движка компилятора AVR-GCC, который используется
jg Глава 5 для компиляции исходного кода. Изменился, например, синтаксис объявления таб- личных констант для хранения в памяти программ и других, не очень часто приме- няемых методов программирования. Вы этого даже не заметите, пока работаете с простыми стандартными проектами. Но если обратиться к более сложным проек- там, разработанным 3-4 года назад, новая версия IDE может выдать неожиданные ошибки компиляции. Притом, что исходный код заведомо правильный и многократно проверен другими пользователями. Причина в частичной несовместимости версий исходного кода программы и компилятора. Ошибки могут также возникать при до- бавлении сторонних описаний плат и микроконтроллеров. Не имея достаточных навыков программирования, ошибки совместимости версий компилятора сложно устранить. В случае возникновения проблем совместимости проще установить предыдущую версию IDE. Последняя стабильная версия на ста- ром движке, у которого не будет проблем совместимости со старыми проектами, имеет номер 1.5.8. Сейчас у вас нет необходимости устанавливать обе версии. Сна- чала установите новую версию. В случае обнаружения проблем совместимости со старыми проектами вы можете в любой момент установить версию IDE 1.5.8, ска- чав соответствующий архивный файл. 5.4.1. Установка Arduino IDE Скачайте самую свежую версию Arduino IDE для своей операционной системы с сайта разработчика http://www.arduino.cc/en/Main/Software. Установка для ОС Windows Пользователям Windows для первой установки на компьютер рекомендуется вы- брать вариант Windows Installer. Кроме автоматической распаковки он создаст нужные записи в реестре, ассоциирует файлы .ino с редактором IDE, а также создаст специальную рабочую папку для хранения файла конфигурации и служебных файлов. Установка альтернативных версий IDE Установщик Windows Installer проверяет наличие других версий Arduino IDE и предлагает их удалить. Поэтому для установки старой версии (или нескольких разных версий) необходимо скачать ZIP-архив, а не установщик, и развернуть его в отдельную папку. Затем можно создать на рабочем столе ярлыки для запуска с указанием номера версии. При совместной работе над сложными проектами или тестировании чужих проек- тов рекомендуется использовать одинаковые версии IDE. Даже при использовании двух идущих подряд версий возможна ситуация, когда скомпилированные прошив- ки будут различаться по размеру, быстродействию или наличию скрытых ошибок. Установка для ОС Linux Раньше способ установки Arduino IDE зависел от версии Linux, а для пользователей Raspberry Pi вообще существовала отдельная инструкция. Новые сборки IDE содержат все необходимые скрипты для автоматической установки независимо от
Обучающая платформа Arduino 87_ версии ОС. Вам нужно лишь правильно определить тип сборки ОС Linux, которую вы используете: 32bit, 64bit или ARM — и скачать подходящую версию установоч- ного пакета по адресу http://www.arduino.cc/en/Main/Software. Версия указана в названии файла. Распакуйте архив в любую удобную вам папку. Программа будет запускаться на выполнение из этой папки. В процессе распаковки будет создана папка с именем ardulno-1.8.x. Найдите в ней файл install.sh и щелкните по нему правой кнопкой мы- ши. В контекстном меню выберите пункт Run in Terminal. После короткого про- цесса установки на рабочем столе появится новый значок. Если в контекстном меню нет опции запуска скрипта, откройте терминал и перей- дите в папку arduino-1.8.x (в нашем примере версия IDE 1.8.1): cd arduino-1.8.1 ./install.sh Теперь среда Arduino IDE готова к запуску. Может случиться так, что при попытке записи прошивки в плату вы получаете сообщение об ошибке: Error opening serial port... Это означает, что нужно задать разрешения для работы с портом. Подключи- те свою плату к компьютеру. Введите в терминале команду: Is -I /dev/tty* В ответ вы получите строку наподобие такой: crw-rw 1 root dialout 188, Feb 16 13:22 ttyUSBl Строк может быть несколько, но нас интересуют только те, в которых содержится слово dialout. Они могут содержать как текст ttyusBx, так и ttyACMx, где х — это номер порта, к которому подключена плата. Дата и время в строке указывают на время, когда вы подключили плату. Запомните наименование и номер порта и ука- жите его в настройках Arduino IDE. Теперь надо включить нового пользователя (себя) в группу dialout: sudo usermod -a -G dialout <ваше имя пользователя> Изменения начнут действовать только после выхода из системы и повторного вхо- да. Далее вы сможете загружать прошивки как обычно. Разумеется, для большинства версий Linux среду Arduino IDE можно установить из репозитория. Но при этом будет установлена далеко не самая последняя версия программы. Кроме того, вы будете лишены возможности выбора версии в случае особых требований к проекту. Установка для Mac OS X Скачайте архив нужной версии Arduino IDE со страницы загрузки. Если вы исполь- зуете браузер Safari, то архив будет развернут автоматически. При использовании иного браузера архив придется развернуть самостоятельно. Скопируйте приложе- ние Arduino в папку Applications (Программы). Значок Arduino появится в панели запуска программ LaunchPad. Вы можете также скопировать приложение в любую другую папку и запускать оттуда.
J38 Глава 5 5.4.2. Подключение платы Arduino и первые программы Сразу после успешной установки и запуска Arduino IDE вы можете скомпилиро- вать и загрузить первую программу. Для первых экспериментов лучше использо- вать одну из самых простых и недорогих плат: Arduino Nano (см. разд. 5.7.7), Arduino Mini или Arduino Pro Mini (см. разд. 5.7.3). В меню Инструменты | Плата выберите нужную плату. Если вы используете ки- тайский клон на основе микроконтроллера ATmega328 и не уверены в типе платы, то выбирайте Arduino Pro or Pro Mini. Этот вариант платы позволяет выбрать раз- ные варианты напряжения питания и тактовой частоты в пункте меню Инструмен- ты | Процессор. В подавляющем большинстве случаев процессор питается напря- жением 5 В и тактируется с частотой 16 МГц. Теперь укажем последовательный порт, к которому подключена плата. Если вы пользователь ОС Windows, то к этому моменту уже должны были установить нуж- ный драйвер конвертера USB-UART (см. разд. 5.2). Желательно заранее посмотреть в Диспетчере устройств номер виртуального СОМ-порта, который появляется в системе при подключении платы или внешнего конвертера, и запомнить его. К моменту настройки порта плата должна быть подключена к компьютеру, ина- че нужный номер порта не появится в списке (рис. 5.6). Рис. 5.6. Настройка типа платы и номера порта в Arduino IDE Теперь все готово к загрузке первой программы. Традиционно это будет мигающий светодиод. Практически все платы Arduino, за редким исключением, оснащены встроенным светодиодом, который подключен к цифровому выходу D13. Некото- рые, самые простые и недорогие платы, не содержат этот светодиод. Кроме того,
Обучающая платформа Arduino 89_ в них отсутствует встроенный конвертер USB-UART. В таком случае вам придется провести небольшую подготовку: подключить светодиод и конвертер. Схема подключения приведена на рис. 5.7. Прежде всего подключим конвертер, тщательно соблюдая назначение выводов. Если использовать модули конвертера, аналогичные изображенным на рис. 2.19, в и е, то подключение сводится к попар- ному соединению выводов, расположенных друг напротив друга. Затем подключите светодиод. Внимательно соблюдайте полярность. Переполюсов- ка светодиода ничего не испортит, он просто не будет светиться. Выполнив соеди- нения, подайте на схему питание от порта USB. Внешний светодиод, подключен- ный к выводу D13, должен коротко мигнуть 2-3 раза, показывая запуск бутлоадера. О Rl 220Q USB-UART Arduino Pro Mini Рис. 5.7. Схема подключения конвертера USB-COM и внешнего светодиода Что такое бутлоадер (bootloader)? Это маленькая служебная программа-загрузчик, записанная в специальную защи- щенную область памяти программ процессора. Она отвечает за запись кода про- шивки, передаваемого по последовательному протоколу, в память программ. Иными словами, процессор получает код прошивки из компьютера через последовательный порт и «программирует сам себя». Благодаря этому удается обойтись любым про- стым конвертером USB-UART вместо внешнего программатора. При старте бутло- адер 1-2 секунды ждет начала передачи кода прошивки. Если это не происходит, то бутлоадер передает управление ранее записанной программе. При обычной работе с Arduino IDE пользователь не имеет прямого доступа к бутлоадеру и не может его стереть или изменить. Каждый производитель устройств записывает свой бутлоадер в микроконтроллер самостоятельно. Можно обойтись вообще без бутлоадера и записывать прошивки при помощи специального программатора. В устройствах Arduino используется фирменный бутлоадер, и его версии могут различаться в зави- симости от года выпуска платы. Если светодиод не мигнул при подаче питания, то вы допустили ошибку при мон- таже, либо в микроконтроллер платы на фабрике не записали бутлоадер (что случа-
90 Глава 5 ется крайне редко). На фабрике, кроме бутлоадера, в платы Arduino обычно запи- сывают проверочную программу, которая мигает светодиодом один раз в секунду. Поэтому в правильно собранной исправной схеме светодиод, подключенный к вы- воду D13, с большой вероятностью будет мигать при подаче питания сразу после покупки. Но мы все равно попробуем загрузить и модифицировать эту программу, наблюдая за результатом. Откройте файл Blink.ino из набора встроенных примеров, как показано на рис. 5.8. Программа примера готова к загрузке в плату. Нажмите стрелку загрузки (стрелка вправо во второй строке меню). Если все предшествующие шаги сделаны правиль- но, то после нескольких секунд компиляции программа загрузится в плату, и свето- диод станет мигать. В противном случае внимательно прочитайте сообщения об ошибках в нижней части окна IDE, проверьте правильность соединений и настрой- ки порта. Рис. 5.8. Пример программы для мигания светодиодом Для понимания того, как работает программа, рассмотрим исходный код примера (листинг 5.1): void setup() { pinMode(LED_BUILTIN, OUTPUT); } void loop() { digitalWrite(LED_BUILTIN, HIGH); delay(1000); digitalWrite(LED_BUILTIN, LOW); delay(1000);
Обучающая платформа Arduino 91_ Здесь ledbuiltin — внутренняя переменная, обозначающая номер вывода, к кото- рому подключен встроенный светодиод. Номер этого вывода назначен в служебном описании подключенной платы, и компилятор подставит его автоматически. В дан- ном случае вы можете даже не знать номер вывода, но для самостоятельной разра- ботки проектов это неприемлемо. Вы должны иметь полный контроль над исполь- зованием выводов. Электронный архив Основные нумерованные листинги, приведенные в книге, вы найдете в сопровож- дающем книгу электронном архиве, размещенном на сайте издательства (см. при- ложение). В начало текста программы добавим две строки: tdefine MY_LED 13 #define MYJDELAY 500 В этих строках мы сообщаем компилятору, что в процессе компиляции везде в про- грамме вместо myled нужно подставить значение 13, а вместо mydelay значе- ние 500. Модифицированный код программы должен выглядеть так (листинг 5.2): tfdefine MY_LED 13 tfdefine MY_DELAY 500 void setup () { pinMode(MY_LED, OUTPUT); } void loopO { digitalWrite(MY_LED, HIGH); delay(MYJDELAY); digitalWrite(MY_LED, LOW); delay(MY_DELAY); Загрузите новую программу в плату. Светодиод будет мигать в два раза чаще, по- тому что мы задали задержку mydelay 500 миллисекунд вместо 1000. Попробуйте менять значение задержки и посмотрите, что получается. Обратите внимание, что, используя директиву компилятора #define, можно менять значение константы по всей программе одновременно. Достаточно один раз изменить значение в момент объявления, и не нужно просматривать всю программу в поисках нужных строк. Аналогично заменяется номер вывода. В качестве самостоятельной работы под- ключите внешний светодиод к выходу D10 и внесите изменение в программу. Теперь добавим в нашу программу функцию передачи строковых данных через по- следовательный порт (листинг 5.3).
92 Глава 5 #define MY_LED 13 #define MY_DELAY 500 void setup() { pinMode(MY_LED, OUTPUT); Serial.begin(9600); // Инициализация порта на скорости 9600 бод } void loop () { digitalWrite(MY_LED, HIGH); Serial.println("LED On"); // Отправка строки "LED On" delay(MY_DELAY); digitalWrite(MY_LED, LOW); Serial.println("LED Off"); // Отправка строки "LED Off" delay (MYJDELAY) ; Откройте окно монитора в меню Инструменты | Монитор порта и установите скорость 9600 бод. Запустите компиляцию и загрузку программы. Во время работы программы синхронно с миганием свето диода в монитор будет отправляться строка состояния (рис. 5.9). Вывод сообщений в последовательный порт часто применяют для отладки программы и вывода диагностических сообщений о работе устройства. |LED Off |LED Co ' t'7-< r.&f LED C-ff It2> Cn Рис. 5.9. Сообщения от программы в мониторе порта 5.4.3. Установка сторонних библиотек Библиотека— это набор стандартных функций для решения определенных при- кладных задач. Как правило, это массово востребованные задачи: работа с датчи- ками, дисплеями, микросхемами внешней памяти, поддержка протоколов обмена.
Обучающая платформа Arduino 93^ Чтобы не тратить зря время и силы на повторное написание уже существующих программ, имеет смысл воспользоваться готовыми решениями. Обычно они много- кратно испытаны и отлажены членами творческого сообщества Arduino. Библиоте- ка может содержать примеры использования. Многие библиотеки написаны специалистами компаний, выпускающих электрон- ные модули и компоненты. Для них это реклама, а для пользователей — готовое профессиональное решение. Наиболее универсальные и востребованные библиоте- ки входят в состав среды Arduino EDE. Но рано или поздно вы столкнетесь с необ- ходимостью добавить библиотеки, которых нет в стандартном наборе. Автоматическая установка библиотеки Библиотека может присутствовать во встроенном списке среды Arduino IDE, но требовать установку. Поэтому прежде всего обратимся к встроенному списку биб- лиотек. Перейдите в пункт меню Скетч | Подключить библиотеку | Управлять библиотеками и внимательно изучите список. Установленные библиотеки помече- ны словом INSTALLED возле заголовка. Найдя нужную библиотеку, выделите ее в списке и нажмите кнопку Установка. Если библиотека отсутствует во встроенном списке, то разработчики обычно рас- пространяют ее в виде ZIP-архива. Скачайте архив библиотеки и не распаковывай- те его. Откройте пункт меню Скетч | Подключить библиотеку | Добавить ZIP-биб- лиотеку. Выберите архив библиотеки в диалоговом окне. Архив будет автоматиче- ски распакован в папку libraries внутри вашей рабочей папки Arduino IDE. Теперь снова откройте меню Скетч | Подключить библиотеку. Название новой библио- теки должно появиться в списке библиотек с пометкой INSTALLED. Библиотеку можно начинать использовать сразу после установки, но чтобы стали доступны примеры из меню Файл | Примеры, приложение Arduino IDE надо перезагрузить. Установка библиотеки вручную При автоматической установке библиотеки разворачиваются в папку My Documents\ Arduino\libraries\ (Windows) или Documents/Arduino/libraries/ (Mac, Linux) и доступны для всех версий Arduino DDE. Но библиотеки, как и обычные программы, иногда стра- дают несовместимостью с отдельными версиями IDE. Если установлено несколько версий Arduino IDE, а библиотеку надо установить только для одной из них, потре- буется ручная установка. Закройте Arduino IDE. Распакуйте архив с библиотекой. Если название папки биб- лиотеки содержит компонент -master, удалите его. Откройте папку, в которую вы раньше установили нужную версию IDE. Найдите папку libraries и откройте ее. Внутри должны находиться некоторые папки стандартных библиотек. Поместите туда же папку с вашей библиотекой. Запустите Arduino IDE и убедитесь, что новая библиотека появилась в списке.
94 Глава 5 5.4.4. Установка дополнительных описаний плат Большое преимущество среды Arduino IDE заключается в универсальности и рас- ширяемости списка поддерживаемых плат. Причем дополнительные платы могут быть вообще не из состава платформы Arduino. Чтобы ядро Arduino IDE могло работать с новой платой, необходимо добавить в среду набор специальных файлов, которые описывают все параметры платы (процессор, тактовая частота, наименование выводов и т. д.), содержат директивы для компилятора и программатора и многое другое. Установить описание платы можно автоматически или вручную. Автоматическая установка описания Это наиболее надежный и простой механизм. Многие производители плат или раз- работчики проектов предоставляют специальные ссылки для автоматического ска- чивания файлов. Эти ссылки могут быть уже включены в стандартный пакет по- ставки, но файлы не установлены. Откройте пункт меню Инструменты | Плата | Менеджер плат. Допустим, нам нужно установить плату Arduino Due. Найдите ее в списке (рис. 5.10), выберите нужную версию (обычно ставят самую свежую) и нажмите кнопку Установка. Напротив названия установленных плат появляется отметка INSTALLED (установлено). Рис. 5.10. Установка описания платы при помощи менеджера плат Иногда ссылка на описание предоставляется сторонним разработчиком в виде обычного пути для скачивания. Его нужно добавить в список плат вручную. От- кройте пункт меню Файл | Настройки и вставьте строку ссылки в поле Дополни- тельные ссылки для Менеджера плат (рис. 5.11). Если ссылок несколько, их надо
Обучающая платформа Arduino 95_ разделить запятой. Теперь перейдите к Менеджеру плат и дождитесь, пока он со- единится с ресурсами по указанным ссылкам и обновит список плат. Затем найдите нужную плату в списке и нажмите кнопку Установка. После этих несложных манипуляций название платы появится в списке Инструменты | Плата. Рис. 5.11. Ввод дополнительных ссылок для Менеджера плат Установка описания вручную Иногда описание не подходит для скачивания автоматическим способом и предос- тавляется в виде набора файлов, которые необходимо установить вручную. Распа- куйте архив со служебными файлами для новой платы. Внутри будет папка hardware, которая содержит подпапку tools и подпапку с именем платы. Также внут- ри папки hardware может присутствовать папка drivers с драйверами для Windows, если они требуются. Найдите папку hardware на компьютере. В случае с Windows и Linux она находится в папке с Arduino ГОЕ. В случае Mac OS щелкните правой кнопкой мыши на значке приложения Arduino ГОЕ и выберите пункт Показать содержимое пакета. Далее перейдите во вложенные папки Contents/Java и найдите там папку hardware.
_9б Глава 5 Теперь надо аккуратно и внимательно перенести файлы из установочной папки в среду Arduino IDE. Подпапку с именем вашей платы скопируйте в папку hardware на компьютере. Далее откройте на компьютере путь hardware/tools/avr/etc и скопи- руйте с заменой файл avrdude.conf из вашей установочной папки. Можно на всякий случай сохранить под другим именем старую версию файла. Если описание платы установлено правильно, ее имя появится в меню Инструменты | Плата. 5.4.5. Сетевой модуль расширения Dragino Yun Обращаясь к описанию модуля Arduino для работы с сетью, мы немного забегаем вперед, потому что в следующей главе мы будем знакомиться с сетевым облачным сервисом Arduino Cloud. Но прежде следует рассказать про аппаратные средства Arduino для работы с сетью. Сейчас вы можете предварительно ознакомиться с описанием и заказать нужные платы, а после получения заказа вернуться к этому разделу для детального изучения и настройки оборудования. В семействе Arduino имеется специальная плата для работы с проводными и бес- проводными сетями— Arduino Yun. Это своеобразная и самодостаточная плата. С точки зрения программирования она полностью аналогична Arduino Leonardo, потому что содержит процессор ATmega32U4. Но на этой плате есть встроенный беспроводной модуль на основе специального процессора Atheros AR9331, рабо- тающий под управлением Linux с поддержкой беспроводного стека OpenWRT. Плата содержит разъем Ethernet, USB-хост и слот для карты памяти формата microSD. Если установлено соединение с сетью, вы можете выгружать скетчи из Arduino IDE в плату через Wi-Fi. При этом также поддерживается обычная загрузка через USB. Для связи между процессорами ATmega32U4 и Atheros AR9331 задей- ствован порт Serial 1 и специальная библиотека Bridge. По сути, Arduino Yun — это микрокомпьютер с ОС Linux, веб-интерфейсом, доступом по SSH и возможностью запускать скрипты на языке Python. Для тех, кто хочет сэкономить, выпускают модуль расширения Arduino Yun Shield, подключаемый к уже имеющейся базовой плате Arduino. Его можно подключить к платам Due, Leonardo, Zero, 101, Uno Rev3, Mega2560 Rev3, а также ко многим другим платам (в том числе с применением соединительных проводов или макет- ной платы). Обратите внимание на идеологию работы сетевого модуля. Несмотря на наличие полноценной операционной системы, он работает только как средство коммуника- ции между сетью и платой Arduino. При помощи этого модуля вы можете загружать скетчи в плату Arduino через Wi-Fi или Ethernet и обмениваться по сети данными. Вы не можете обращаться к выводам шилда средствами его прошивки или про- граммировать работу шилда при помощи Arduino IDE. Разумеется, если у вас есть достаточный опыт работы с Linux, вы можете загружать в модуль собственные скрипты на языке Python или Lua для работы с сетью, но все равно для аппаратной коммуникации можете использовать только порты UART, SPI и выводы управле- ния светодиодами.
Обучающая платформа Arduino 97^ Почему именно Dragino Yun? Плата Arduino Yun весьма дорого стоит ($72 + доставка) и на момент подготовки книги официально в Россию не отгружалась. Модуль расширения стоит дешевле ($48), но в Россию также не отгружается. Поэтому рекомендую использовать клон от китайских разработчиков под торговой маркой Dragino. Он дешевле, доступен для заказа во многих интернет-магазинах и содержит интересные конструктивные доработки, облегчающие использование модуля с разными платами Arduino. Страница с описанием модуля расширения доступна на сайте производителя по адресу: http://www.dragino.com/products/yunshield.html. На момент подготовки книги самой новой была версия платы 2.4. Для поиска платы в интернет-магазинах используйте ключевые слова Yun shield и внимательно читайте описание, чтобы заказать именно новую версию. Вместе с платой Dragino Yun настоятельно рекомендую заказать базовую плату DCCduino Uno R3. Это недорогой клон фирменной платы Arduino Uno R3. Досто- инство этого клона в том, что он полностью и без доработок совместим как с моду- лем Dragino Yun v2, так и с фирменными модулями Arduino. Подсказка: сетевой модуль и базовую плату можно приобрести у одного и того же продавца на Aliexpress. Технические характеристики Dragino Yun v2.4 Внешний вид платы показан на рис. 5.12. ♦ Процессор: 400 МГц (24К MIPS) ♦ Flash: 16 Мбайт ♦ RAM: 64 Мбайт ♦ Питание: 7...23 В (через разъем базовой платы Arduino) ♦ Ethernet: I x 10M/100MRJ45, поддержка питания Passive PoE Ф 150 Мбайт Wi-Fi 802. llb/g/n Ф Внешняя антенна Wi-Fi Рис. 5.12. Модуль расширения Dragino Yun v2.4
98 Глава 5 ♦ 2 х USB 2.0 хост для подключения накопителя и Зв-модема ♦ Аппаратная кнопка сброса ♦ Автоматическая совместимость с 3- и 5-вольтовыми платами Arduino ♦ Слот для карты памяти microSD. Шилд содержит два встроенных импульсных источника питания и схему автомати- ческого выбора логического уровня. Некоторые платы Arduino работают при на- пряжении питания 3,3 В. Шилд автоматически определяет напряжение питания и выставляет нужное напряжение логических уровней на линиях коммуникации с платой. Особенности питания шилда Dragino Yun Шилд Dragino Yun не имеет отдельного разъема питания и получает питание от базовой платы, к которой подключен. По питанию цепи разделены на две линии: питание совмещенного контроллера USB-хоста + слот для карты памяти microSD и питание основной процессорной части платы. Чтобы избежать перегрева встро- енного стабилизатора базовой платы, процессорная часть шилда питается от собст- венного импульсного преобразователя, вход которого соединен непосредственно с разъемом питания базовой платы. Поэтому шилд Dragino Yun невозможно питать напряжением 5 В от USB-nopma компьютера. Следует подавать питание 7... 15 В на разъем питания базовой платы. Контроллер USB-хоста питается стабилизированным напряжением 5 В, которое поступает со стабилизатора базовой платы. Этим напряжением питаются также внешние накопители и/или Зв-модем, подключенные к хосту Dragino Yun. Чтобы уменьшить риск перегрева линейного стабилизатора базовой платы, при подключе- нии потребителей к USB-хосту рекомендуется использовать источник питания с напряжением 7 В. Шилд Dragino Yun вместе с подключенной базовой платой Arduino можно питать через сетевой кабель Ethernet по схеме Passive PoE (Power over Ethernet, питание по сетевому кабелю). Схема подключения питания показана на рис. 5.13. RJ45-MJ1А-В211-RT009 1 ТХ+ I Рис. 5.13. Питание устройства по схеме Passive PoE
Обучающая платформа Arduino 99 Внешнее напряжение питания в диапазоне 9... 15 В подается по витым парам сете- вого провода на контакты сетевого разъема RJ-45. Положительное напряжение по- дается на контакты 4 и 5, «земля» подключена к выводам 7 и 8. Имейте в виду, что данная схема Passive PoE предельно проста и НЕ содержит преобразователь пи- тающего напряжения из стандартных напряжений РоЕ 24 или 48 В. Напряжение с линии питания подается напрямую на стабилизатор платы. Поэтому нельзя ис- пользовать стандартные высоковольтные инжекторы питания от других устройств. Следует просто подать напряжение 9...15 В на нужные жилы на другом конце кабе- ля. Питающие жилы не используются для передачи информации. Добавление новых плат в Arduino IDE Для корректной работы платы шилда Dragino Yun, подключенного к платам Uno, Leonardo и Mega2560, необходимо добавить специальные описания в перечень плат Arduino IDE. Откройте пункт меню Файл | Настройки и вставьте строку ссылки http://wnww.dragino.coni/downloads/downloads/YunShield/package_dragino_yun_te stindex.json в поле Дополнительные ссылки для Менеджера плат (см. рис. 5.11). Если ссылок несколько, их надо разделить запятой. Теперь перейдите к Менеджеру плат и дождитесь, пока он соединится с ресурсом по указанной ссылке и обновит список плат. Затем найдите в списке Менеджера строку с названием Dragino Yun by Dragino Technology (рис. 5.14) и нажмите кнопку Установка. После этих мани- пуляций в списке Инструменты | Плата появится раздел Dragino Yun. Рис. 5.14. Установка набора плат Dragino Yun в среде Arduino IDE Начинающие разработчики могут спросить, почему мы добавляем новые платы, а не воспользуемся готовым пунктом Arduino Yun из стандартного пакета Arduino IDE? Дело в том, что мы используем шилд, который может подключаться к различным
100 Глава 5 платам Arduino, содержащим различные микроконтроллеры. При помощи Arduino IDE мы программируем не шилд, а базовую плату. Шилд используется только в ка- честве средства сетевой коммуникации. Поэтому компилятор Arduino IDE дол- жен «знать», для какого процессора компилировать скетч. Перечень из трех плат: Leonardo, Uno и Mega2560 — фактически перекрывает все необходимые варианты процессоров. Например, если вы захотите подключить шилд Dragino Yun к плате Arduino Nano, вам следует выбрать в списке плат Arduino Uno — Dragino Yun, потому что в платах Nano и Uno R3 используется один и тот же процессор ATmega328. Иными словами, ключевое значение имеет не название платы, а применяемый в ней процессор. Подключение к компьютеру для настройки При первом включении ненастроенный шилд работает в режиме открытой точки доступа Wi-Fi. Подключите шилд к базовой плате Arduino и подайте питание от источника посто- янного тока 7... 15 В. Шилд должен мигнуть всеми светодиодами. Если светодиоды хаотично мерцают или горят вполнакала, у вас проблемы с источником питания. Учтите, что шилд не начинает работать сразу после включения. Загрузка ОС Linux занимает примерно 90 секунд. Когда загорится синий светодиод WLAN, устройство готово к работе. Теперь нужно установить соединение с компьютером. Самый простой способ — подключение по Wi-Fi. Подойдет ноутбук, стационарный компьютер или планшет. Рекомендуется использовать браузеры Chrome или Firefox. Найдите открытую точ- ку доступа с именем Dragino-******* и подключитесь к ней. В браузере введите адрес веб-интерфейса 192.168.240.1. Пароль доступа по умолчанию: dragino. Стационарный компьютер можно подключить напрямую при помощи сетевого ка- беля (патчкорда). Один конец сетевого кабеля подключите к сетевой карте компью- тера, второй — непосредственно в разъем Ethernet шилда. Шилд по умолчанию не предоставляет сервис DHCP для проводного подключения и не может автоматиче- ски присвоить нужный IP-адрес компьютеру. Сделаем это вручную на примере ОС Windows. Перейдите к свойствам сетевого адаптера компьютера и введите IP-адрес 172.31.255.253 и маску подсети 255.255.255.252 (рис. 5.15). По окончании ра- боты с шилдом не забудьте вернуть настройки сетевого адаптера вашего компью- тера в исходное состояние. Веб-интерфейс шилда будет доступен по адресу 172.31.255.254. Опытные пользователи Linux могут подключиться к шилду по SSH. Адрес для под- ключения 192.168.240.1, порт 22, логин пользователя root, пароль dragino (рис. 5.16). Но мы здесь не будем рассматривать настройку по SSH, потому что нет такой задачи, которую обычный пользователь Arduino не смог бы решить при помощи удобного и понятного веб-интерфейса.
Обучающая платформа Arduino 101 f ><г>й?сз«хение £# Eeate»; . «/ С./* й/вден1' да я сетей Microsoft •• : •**! д«"?1>5щя(3 доступ ч Файлам и приктерем &ns се w^ Mi У. V^nnawtpoeiuwK пакетов GoS ^^*^ > Л IP версии 4 ilCPAPvf; ^-**^^ .'. х, ГЬэтокоп ^^пьтиппексора сетевого aasmeca (M* Параметр IP яожяо н подйвр^ивае" эт у вол 17? . ?I , 2S5 . 2Ъ'} ■ Протокол тс? IP О К Qmma СЖ Откена Рис. 5.15. Настройка сетевого адаптера компьютера для поключения к Dragino Yun login as: root root@192.168.240.1's password: BusyBox vl.19.4 {2015-01-06 10:25:28 CST) built-in shell (ash) Enter 'help1 for a list of built-in commands. I _ \| _ \ / \ / t_ _| \ I I/ _ \ \ I I I l_> I /_\i I I I! \l I I I I \ \__\ I _ < / \ l_! If II f\ I l_f I I /!_! W_/ \_\ 1 I_i \_|\ / WiFi, Linux, M С JJ, Embedded Model: Dragino v2 Versxon: Dragxno-v2 conmon-2.0.5 Buxld Tue Aug 18 17:10:10 CST 2015 www.dragino.com root@dragino-a2656d:~# Рис. 5.16. Окно терминала доступа по SSH Функции кнопки сброса Dragino Yun Кнопка сброса расположена возле разъема USB-хоста. Кратковременное (менее 5 секунд) нажатие на эту кнопку приводит к перезагрузке модуля Wi-Fi. Нажатие на кнопку сброса дольше пяти, но менее 30 секунд, приводит к сбросу на- строек Wi-Fi. После этого Dragino Yun вновь запускает открытую беспроводную точку доступа с именем Dragino-*******. После подключения к этой точке веб-
102 Глава 5 интерфейс настройки доступен по адресу 192.168.240.1. Данная функция кнопки сброса удобна в случае, когда шилд оказался в зоне действия новой беспроводной сети и не может к ней подключиться. Если проводное подключение через разъем Ethernet недоступно, то спасти положение может только сброс сетевых настроек. Длительное (более 30 секунд) нажатие на кнопку приводит к сбросу всех настроек дистрибутива Linux до начального состояния (factory reset), в котором он находится сразу после покупки или перепрошивки. При этом удаляются все ранее установ- ленные файлы и сетевые настройки. Применяйте такой сброс только в крайнем случае. Обновление прошивки Начиная работу с новым устройством, необходимо проверить версию прошивки и при необходимости обновить ее. Только после этого можно производить началь- ную настройку. Для этого есть серьезная причина: устройства, поступившие из ма- газина, часто содержат устаревшую на несколько поколений прошивку. В таком случае рекомендуется вместе с файлом прошивки обновить и файл конфигурации, иначе может возникнуть проблема совместимости новой прошивки со старым фор- матом конфигурации. Если вы обновите прошивку с большим разрывом версий, то велика вероятность потерять все настройки, сделанные ранее. Войдя в веб-интерфейс, проверьте версию прошивки на первой странице (рис. 5.17). Рис. 5.17. Первая страница интерфейса, проверка версии прошивки Перейдите по адресу http://www.dragino.com/downloads/index.php?dir= motherboards/msl4/FirmwareAfun/Legacy_Firmware/ и найдите самую новую по дате ссылку с названием common-build—v2. Войдите в каталог и скачайте файл прошивки, который обязательно должен содержать слово sysupgrade в названии и расширение bin. На момент подготовки книги это была версия 2.0.7 от 24.11.2015,
Обучающая платформа Arduino 103_ обновленная 01.05.2016. Все дальнейшие скриншоты и инструкции будут отно- ситься к новой версии. Размер файла около 15 Мбайт. Нажмите кнопку UPGRADE в веб-интерфейсе, выберите путь к скачанному файлу прошивки и убедитесь, что галочка KEEP SETTINGS (сохранить настройки) снята, чтобы файл конфигурации обновился вместе с прошивкой. Процесс обновления занимает около двух минут, после чего все светодиоды мигнут, и устройство перезагрузится. Дождавшись окончания перезагрузки, заново подключитесь к точке доступа и войдите в веб- интерфейс. Теперь можно приступать к настройке. Базовые настройки Убедитесь, что в шилд успешно записана новая прошивка. Нажмите кнопку SYSTEM. Здесь вы можете настроить следующие параметры: ♦ YUN NAME — имя, под которым устройство будет видно в локальной сети; ♦ PASSWORD — общий пароль для доступа ко всем сервисам, требующим авто- ризации. По умолчанию dragino; ♦ TIMEZONE — часовой пояс вашего географического положения; ♦ CONFIGURE A WIRELESS NETWORK — если опция выбрана, то после на- стройки подключения к вашему роутеру Wi-Fi и перезагрузки шилд перейдет в режим клиента и подключится к вашей беспроводной сети; ♦ DETECTED WIRELESS NETWORK— список доступных беспроводных се- тей. Выберите в нем ваш домашний роутер Wi-Fi, к которому будет подключен шилд; ♦ WIRELESS NAME, SECURITY — заполняются автоматически после выбора точки доступа; ♦ PASSWORD — пароль вашего роутера Wi-Fi; ♦ REST API ACCESS — шилд поддерживает так называемый REST API, специ- альный стандарт обмена данными с платой Arduino через адресную строку брау- зера. Например, в строке браузера можно в явном виде указать номер вывода платы Arduino и логический уровень. Шилд расшифрует адресную строку, пре- образует ее в команду для платы Arduino и передаст через последовательный порт. Если вы работаете только внутри домашней сети, то можно установить режим без пароля OPEN. Для открытых сетей и критичных приложений реко- мендуется оставить режим доступа с паролем WITH PASSWORD; Закончив настройки на этой вкладке, нажмите кнопку CONFIGURE & RESTART. Дождитесь перезагрузки шилда и включения синего светодиода WLAN на плате. После настройки подключения Wi-Fi и перезагрузки шилд перестанет работать в режиме беспроводной точки. Надо определить новый IP-адрес устройства в локальной сети. Это можно сделать тремя способами: ♦ войдите в административную панель вашего роутера Wi-Fi и найдите там IP-адрес шилда в списке подключенных устройств;
104 Глава 5 ♦ запустите Arduino IDE и подождите около минуты, пока идет поиск шилда в се- ти. Затем перейдите в меню Инструменты | Порт и найдите сетевой порт в спи- ске (рис. 5.18); ♦ подключите шилд сетевым проводом напрямую к компьютеру, настройте сете- вой адаптер компьютера, как показано на рис. 5.15, войдите в веб-интерфейс по адресу 172.31.255.254 и найдите IP-адрес на первой странице в разделе WI-FI (WLAN0). Если шилд не получает IP-адрес при соединении по Wi-Fi, снова перейдите на страницу SYSTEM и проверьте правильность настройки подклю- чения к роутеру Wi-Fi. Определив новый IP-адрес, подключитесь к веб-интерфейсу шилда для продолже- ния работы. Рис. 5.18. Определение IP-адреса шилда и задание сетевого порта Определение типа базовой платы Нажмите кнопку SENSORS на главной странице веб-интерфейса. Шилд может ав- томатически определять тип процессора, установленного на базовой плате (рис. 5.19), и обычно делает это правильно. Если по каким-либо причинам автома- тическое определение не сработало, тип процессора и платы можно задать вручную из небольшого списка. Если установлена галочка UPLOAD BUTLOADER, то вместе с кодом прошивки в процессор базовой платы Arduino будет записан бутлоадер. Это может быть полезно, если бутлоадер не был записан раньше или поврежден, а также если плата не определяется правильно. В остальных случаях запись бутлоадера не требуется и галочку можно снять. На этом основные настройки шилда завершены. Чтобы вернуться на главную стра- ницу, щелкните на логотипе Dragino.
Обучающая платформа Arduino 105 Рис. 5.19. Определение типа процессора и загрузка бинарных файлов в плату Arduino Загрузка скетча через сеть из Arduino IDE Запустите Arduino IDE, выберите правильный тип базовой платы, подключенной к шилду. В списке портов выберите сетевой порт (см. рис. 5.18). Обычным путем отправьте скетч на загрузку в плату. Перед началом прошивки будет запрошен пароль доступа. По умолчанию: dragino. При помощи веб-интерфейса вы можете загрузить скомпилированный код прошив- ки (файл с расширением hex). Чтобы получить этот файл, выберите в меню Arduino IDE пункт Скетч | Экспорт бинарного файла. После завершения компиляции скетча выберите пункт Скетч | Показать папку скетча. В ней будут находиться два варианта файла с расширением hex — с бутлоадером и без бутлоадера. Для за- грузки в стандартную плату Arduino бутлоадер не нужен. Полученный бинарный файл вы можете загрузить в плату с любого компьютера, имеющего подключение к шилду. Автоматическое обновление скетча Начиная с версии прошивки шилда 2.0.4, поддерживается функция автоматическо- го обновления скетча Arduino. Шилд соединяется с заданным HTTP-сервером и проверяет номер версии скетча. Если обнаружена более новая версия, она скачива- ется и загружается в плату. Таким образом, вы можете автоматически обновлять множество удаленных устройств без необходимости доступа к каждому в отдель- ности. Есть возможность записывать разные скетчи в разные устройства в зависи- мости от их МАС-адреса.
106 Глава 5 Auto Update MCU image Auto Update On Boot Current Image Version Update URL Enable MAC Identify Update Info m 0 htt m ш f) Auto update once device boot Current Image Version used in the MCU Get Update Info from this URL Ц maintain different update info for different device autoupdatetxt © File Includes Update information Рис. 5.20. Настройка автообновления скетча Для настройки автообновления перейдите в расширенные настройки: SYSTEM | Advanced Configuration Panel | Sensor | Microcontroller (рис. 5.20). ♦ Auto Update On Boot — при каждой загрузке шилд будет проверять наличие обновления; ♦ Current Image Version — здесь отображается текущая версия скетча. Это поле обновляется автоматически после успешной загрузки новой версии; ♦ Update URL— адрес каталога, из которого по протоколу HTTP будет скачи- ваться обновление; ♦ Enable MAC Identify — если выбрана эта опция, то шилд будет искать в ката- логе текстовый файл описания с именем, содержащим МАС-адрес этого шилда. Например, если шилд имеет МАС-адрес E8:40:41:75:68:DF, то файл описания, предназначенный именно для этого шилда, должен быть назван E840417568DF.txt; ♦ Update Info — имя текстового файла описания, в котором хранится информация об обновлении (название скетча, контрольная сумма, номер версии). Подготовьте скомпилированный файл скетча с расширением hex. Например, пусть это будет файл blink.hex. Как это сделать, сказано ранее в разд. «Загрузка скетча через сеть из Arduino IDE». Определите контрольную сумму файла скетча. Для вычисления контрольной суммы MD5 пользователи Windows могут использо- вать небольшую утилиту WinMD5, доступную для свободного скачивания по адре- су www.winmd5.com. Аналогичные приложения доступны и пользователям Mac OS и Linux. Создайте текстовый файл описания, состоящий из трех строк, содержащих назва- ние скетча, его контрольную сумму и номер версии: image=[MMH вашего скетча].hex md5sum= [контрольная сумма вашего файла] version=1.2 [номер версии скетча, разделитель - точка]
Обучающая платформа Arduino 107 Важное замечание: текстовый файл должен быть создан только в UNIX-формате (перенос строки <lf>, кодировка UTF-8). Для создания и редактирования таких фай- лов можно использовать популярный бесплатный редактор Notepad++. Обычный редактор Windows Notepad для этой цели не подходит — файл не будет прочитан шилдом! Сохраните файл под любым именем. По умолчанию используется имя autoupdate.txt, но вы можете указать любое другое имя или МАС-адрес шилда. Создайте каталог autoupdate/ на сервере, с которого будут скачиваться обновления. Сервер должен поддерживать протокол HTTP, а каталог открыт для доступа внеш- них пользователей. В каталог загрузите файл скетча и файл описания. Внесите пол- ный путь к каталогу в поле Update URL, а имя файла описания — в поле Update Info и поставьте галочку Auto Update On Boot. Если все сделано правильно, то по- сле перезагрузки шилда новый скетч будет записан в плату Arduino, а в поле Current Image Version появится номер новой версии. Для проверки того, как функционирует готовое и заведомо правильное автообнов- ление, укажите в настройках адрес сервера http://www.fankraft.ru/autoupdate/ и имя файла описания autoupdate.txt. На сервере хранится модифицированный скетч blink.hex, скомпилированный для Arduino Uno (и аналогичных плат на основе ATmega328). В нем задано мигание встроенного светодиода с задержкой 300 мил- лисекунд. После успешной автозагрузки обновления светодиод начнет быстро ми- гать, а в панели настроек будет видна версия скетча 1.1. Использование консоли Dragino Yun для вывода сообщений Среда Arduino IDE имеет встроенный монитор порта. В его окне выводится текст обмена сообщениями через последовательный порт платы Arduino. Внимание! Если к плате подключен сетевой шилд Yun, то последовательный порт занят шил- дом. Большинство плат Arduino имеют только один аппаратный порт, поэтому для обмена данными со скетчем через терминал приходится использовать консоль Linux, работающую на базе шилда Yun. Запустите среду Arduino IDE. Откройте пример Файл | Примеры | Bridge | Console Read. Выберите плату, к которой подключен шилд, и сетевой порт беспроводного соединения. Скомпилируйте скетч и загрузите его в плату. Почему-то у текущей версии Arduino IDE не всегда происходит корректное автоматическое соединение с консолью после загрузки скетча. Закройте и снова откройте Arduino IDE. Запус- тите монитор порта и нажмите клавишу <Enter>. Введите в поле ввода монитора свое имя и снова нажмите клавишу <Enter>. Скетч прочитает через консоль ваше имя и выведет его в строке (рис. 5.21). С консолью можно соединиться при помощи терминальной программы PuTTY. Это немного сложнее, но работает надежнее. Загрузите скетч в плату. Запустите терми- нал и соединитесь по SSH с сетевым адресом вашего шилда. Войдите с логином root и паролем dragino (по умолчанию). В командной строке введите: telnet localhost 6571
108 Глава 5 | dragmo-i5e.324 at 192,168.1,159 (ArduinoYun) Hi, what's your name? Hi Valeriy1 Nice to meet you1 Hi, what'a your name? D Рис. 5.21. Текстовый обмен со скетчем через монитор порта и консоль # T92.168.1.159-PuTTY I _ \| _ \ / \ / |__| \ I I/ _ \ I I I I l_) I /_\i I I и \l I I I 1 I i_i I _ < / \ i_i и и i\ I i_i I I /i_i \_\/_/ \_\ I ij \_i\ / WiFi, Linux, M С U, Embedded Model: Dragino v2 Version: Dragino-v2 common-2.0.7 Build Tue Nov 24 19:39:50 CSX 2015 www.dragino.com D root8dragino-15e324:~# telnet localhost €571 Hi ! Nice to meet you! "ff Hi, what's your name? Valeriy Hi Valeriy! Nice to meet you! , what's your name? Рис. 5.22. Текстовый обмен со скетчем через терминал и дважды нажмите клавишу <Enter>. Введите в командной строке свое имя и снова нажмите клавишу <Enter> (рис. 5.22). Рассмотрим код примера (листинг 5.4) и комментарии в коде. #include <Console.h> String name; void setup() {
Обучающая платформа Arduino 109 II Инициализируем библиотеку Bridge и консоль: Bridge.begin(); // сначала обязательно Bridge Console.begin(); // и только затем Console // Ждем, пока установится соединение с консолью через сетевой порт while (!Console); // Выводим текст в консоль Console.println("Hi, what's your name?"); void loopO { if (Console.available() > 0) { char с = Console.read(); // Читаем очередной полученный символ // проверяем наличие символа перевода строки - это конец строки if (с = '\п') { // Выводим приветствие и полученное имя Console.print("Hi "); Console.print(name); Console.println("! Nice to meet you!"); Console.println(); // Спрашиваем снова и стираем старое имя Console.println("Hi, what's your name?"); name = ""; } else { // Если строка еще не закончилась name += с; // Прибавляем к имени следующий символ } } else { delay(100); В начале программы мы инициализируем консоль и библиотеку Bridge, которая служит мостом (bridge) между физическим последовательным портом платы Arduino и сетевым портом шилда Yun. После инициализации надо обязательно до- ждаться установления связи с консолью, поскольку процедура соединения занима- ет несколько секунд. Нельзя, чтобы в это время скетч пытался обращаться к порту. Все донные, которые скетч попытается вывести до фактической инициализации Linux-консоли, будут утеряны. Далее происходит посимвольное чтение входящей строки из буфера Yun и вывод ответного сообщения. По сути, в данном скетче вместо обычного объекта последо- вательного порта Serial используется объект Console. В остальном заметных разли- чий между работой с консолью Linux и последовательным портом нет. Вы можете написать собственный скетч, который будет обрабатывать консольные команды и управлять состоянием портов микроконтроллера. Например, включать свето- диоды или реле.
ГЛАВА 6 Облачная среда разработки Arduino Create Arduino Create — это реализация нового подхода к программированию: основная функциональность среды разработки переносится с компьютера пользователя на облачные серверы. Проще говоря, это привычная среда Arduino IDE, вынесенная в облачный сервис и дополненная новыми возможностями. На компьютер пользо- вателя устанавливается только небольшое расширение браузера, которое является посредником между облачным сервисом и физической платой устройства, подклю- ченной к компьютеру. На момент подготовки книги расширение работало с опера- ционными системами Windows, Mac OS X и Linux 64bit. Опытные пользователи Linux 32bit и Linux ARM могут попробовать самостоятельно скомпилировать ис- полняемый файл расширения из исходного кода. Детальное рассмотрение этого процесса выходит за рамки книги. Вся работа с проектом происходит в окне обычного браузера, а файлы проекта по умолчанию хранятся в облаке. Сервис обеспечивает полную независимость от мес- та работы. Вы можете начать писать программу в офисе, на компьютере с ОС Windows, а продолжить дома на ноутбуке с Mac OS и не заметите разницы в усло- виях работы. Вам не надо заботиться об обновлении версии IDE или библиотек. Сервис всегда использует самые свежие версии программного обеспечения. Легко и логично организуется публикация проектов в открытом доступе. Чтобы поделиться с миром своей замечательной программой, достаточно разместить в блоге или на странице социальной сети сгенерированную сервисом ссылку. К проекту можно прикрепить дополнительные файлы с изображениями и тексто- выми описаниями. Благодаря этому вместе со скетчем легко публикуются схемы макетных соединений, принципиальные электрические схемы и чертежи печатных плат. Еще одной удобной функцией сервиса Arduino Create является доступ к фирменно- му облаку Интернета вещей (IoT, Internet of Things). Перед началом разработки программы вы создаете «вещь» (Thing), которой в облаке присваивается уникаль- ный серийный номер и пароль. Готовая запрограммированная «вещь» подключена к облаку при помощи Wi-Fi или проводного соединения, а вы можете управлять ею или получать от нее данные через Интернет из любой точки мира.
Облачная среда разработки Arduino Create 111 Такая емкая бочка меда не обошлась без ложки дегтя. На момент написания книги сервис поддерживает только фирменные платы Arduino и устройства Windows 10 loT Core. Возможность добавления сторонних плат и расширений компилятора пока не предусмотрена, хотя давно была обещана разработчиками. В самом деле, возмож- ность произвольного добавления пользовательских расширений сложно реализовать в централизованном сервисе. Если вы планируете использовать платы сторонних разработчиков, например, на базе ESP8266, то придется использовать обычную ло- кальную версию Arduino IDE. Впрочем, даже в этом случае вы можете в любой мо- мент выгрузить файлы и библиотеки в облако для хранения и удаленного редакти- рования. 6.1. Подготовка среды Arduino Create Если у вас еще нет учетной записи на сайте www.arduino.ee, создайте ее сейчас, щелкнув там по ссылке Sign Up. Заполните регистрационную форму и дождитесь получения письма по электронной почте. Пройдите по подтверждающей ссылке в письме и активируйте аккаунт. Вы можете использовать этот аккаунт для входа на официальный форум, для покупок в официальном магазине, для подключения к облачному сервису Temboo и даже для создания обучающих проектов в разделе Arduino Project Hub. Перейдите по адресу http://create.arduino.ee. Вы увидите стартовую панель со значками приложений (рис. 6.1). Теперь надо установить на компьютер расширение браузера. Щелкните на значке Getting Started и в открывшейся панели — на значке Setup the Arduino Editor Plugin. Браузер автоматически определит операционную систему компьютера и начнет скачивание нужного установщика. Для ОС Linux 64bit рекомендуется использовать браузер Chromium. ОС Linux 32bit на момент подготовки книги не поддерживалась. Рис. 6.1. Стартовая панель сервиса Arduino Create
112 Глава 6 Распакуйте скачанный архив и запустите исполняемый файл. В названии этого файла должно содержаться название вашей версии ОС. После установки расшире- ния необходимо перезапустить браузер и вновь войти на сайт. Обратите внимание, что в случае с ОС Windows спустя несколько секунд после окончания установки может появиться окно с запросом на установку универсального драйвера USB. Это окно спрятано позади остальных окон. Нажмите кнопку Разрешить и дождитесь окончания установки драйвера. При включении компьютера расширение запускается автоматически и работает в фоновом режиме. Его значок постоянно находится в панели задач. К сожалению, у расширения нет меню, в котором можно отключить автозапуск. Это делается средствами вашей операционной системы. Детальную инструкцию с иллюстрация- ми можно получить по адресу https://github.com/arduino/arduino-create-agent. 6.2. Онлайн-редактор Arduino Web Editor В главной панели сервиса щелкните на значке Arduino Web Editor. Откроется ок- но редактора (рис. 6.2). На самом деле это не просто текстовый редактор, а средст- во управления проектами и средой программирования. Рис. 6.2. Онлайн-редактор Arduino Web Editor Если расширение браузера не установлено или установлено неправильно, в верх- ней части окна появится сообщение об ошибке (рис. 6.3). Ничего страшного, нажми- те кнопку Help и в новом окне по ссылке перейдите к скачиванию расширения. Затем перезапустите браузер. Если расширение установлено и активно, в нижней или верхней панели задач (в зависимости от ОС) должен появиться значок с логотипом Arduino в виде символа бесконечности.
Облачная среда разработки Arduino Create 113 Рис. 6.3. Сообщение об ошибке при отсутствии расширения браузера Окно состоит из трех вертикальных панелей. В левом верхнем углу панели (1) на- ходится значок перехода к стартовой панели Arduino Create. Ниже следуют основ- ные разделы меню редактора. Панель (2) содержит контекстное меню, содержимое которого зависит от первой панели. В панели (3) всегда открыт текстовый редак- тор. Рассмотрим подробнее пункты основного меню. Sketchbook Здесь обеспечивается работа с исходными текстами программ (скетчами). Вы мо- жете перенести все имеющиеся скетчи с локального компьютера в облако или соз- дать новый скетч. Облачное хранилище поддерживает структуру вложенных папок. Вы можете создавать собственные папки для хранения скетчей. Можно создать новый скетч, импортировать одиночный скетч или полностью им- портировать папку с ранее созданными скетчами со своего компьютера в облако. Для импорта всех скетчей сожмите папку на локальном компьютере в архив с рас- шиением zip и нажмите большой значок со стрелкой вверх в нижней части пане- ли (2). Для создания нового скетча нажмите кнопку New Sketch. Вместе с новым скетчем автоматически создается шаблон файла документации с расширением adoc на слу- чай, если вы захотите обнародовать проект. Для переименования скетча двойным щелчком щелкните на его имени в панели (3) редактора. Полное меню работы со скетчем открывается по щелчку на кнопке с троеточием. Кнопки с галочкой и стрелкой вправо означают то же самое, что и в Arduino IDE — проверить и загру- зить в плату скетч. Если после создания новой папки или переименования скетча изменения в пане- ли (2) никак не проявились, обновите страницу браузера вручную. Examples Этот пункт меню ведет к обучающим примерам. Состоят они из двух блоков: встроенные в среду программирования и поставляемые с библиотеками. Прежде чем решать какую-то задачу программирования, особенно с применением библио- теки, проверьте наличие примера. Это может сэкономить много времени. Помните, что в Arduino Create библиотеки обновляются наиболее оперативно. Libraries При выборе этого пункта меню открывается каталог библиотек. Кнопка Library Manager ведет на постоянно обновляемый перечень библиотек от сторонних раз- работчиков. Найдя нужные библиотеки, нажмите на значок звездочки напротив
114 Глава 6 них, затем на кнопку Done — выбранные библиотеки окажутся во вкладке Favo- rites (Избранное). Наведя указатель мыши на имя нужной библиотеки в этой вклад- ке, вы увидите кнопку Include. Нажатием на эту кнопку в начало активного скетча вставляется строка вызова библиотеки. Если у библиотеки несколько версий, вы можете выбрать нужную версию нажатием на значок треугольника возле кнопки. Такой подход удобнее, чем в традиционном IDE. Он позволяет быстро менять вер- сии без промежуточного удаления библиотеки. Мы уже упоминали, что иногда возникает несовместимость программного кода с текущей версией компилятора. Иногда разработчики убирают отдельные функции из новых версий библиотеки. В таких случаях может помочь обращение к предыдущим версиям. Во вкладке Custom можно хранить собственные библиотеки, которых нет в офици- альном перечне. Упакуйте папку со своими библиотеками в архив с расширением zip и выгрузите в облако, нажав на значок со стрелкой вверх. Предварительно убе- дитесь, что в папке нет лишних файлов, которые не относятся к библиотекам. Serial Monitor Выбор этого пункта меню открывает окно терминала последовательного порта, ко- торый позволяет отправлять символьные значения в порт и отображать полученные символы. Активным автоматически назначается тот порт, который выбран для под- ключенной платы в панели редактора (3). Можно выбрать символ, которым завер- шается передаваемая из терминала в устройство строка: ♦ No Line Ending — строка не завершается никаким символом; ♦ Newline — добавляется символ новой строки NL (0x0А); ♦ Carriage Return — добавляется символ возврата каретки CR (OxOD); ♦ Both NL & CR — добавляются оба символа: новой строки и возврата каретки. Скорость обмена выбирается из перечня стандартных значений. Нестандартные скорости порта не поддерживаются. Текст из окна монитора можно скопировать в буфер обмена нажатием на значок в правом верхнем углу окна. В нижней части окна можно включить/выключить автопрокрутку выводимого текста. Help Здесь содержится перечень ссылок для получения подробного руководства, описа- ния примеров и библиотек, открытых исходных кодов. Preferences Выбрав этот пункт меню, вы получите доступ к настройкам редактора. Кроме раз- мера шрифта и цветового оформления окна можно настроить следующие опции: ♦ Save when verifying.,. — сохранять изменения скетча при каждом нажатии на кнопки проверки и загрузки в плату. Эта опция по умолчанию отключена, пото- му что иногда нужно протестировать одно или несколько изменений, не внося
Облачная среда разработки Arduino Create 115 их в сохраненный скетч. Если вы уверены, что не испортите исходный код слу- чайными изменениями, можете включить опцию; ♦ Enable Autosave— разрешить автоматическое сохранение. Скетч автоматиче- ски сохраняется через некоторый промежуток времени (в меню не указан); ♦ Always show...— включает показ нижней панели редактора, куда выводятся служебные сообщения сервиса при компиляции и загрузке; ♦ Sketchbook: Show all files — включить показ имен файлов с любыми расшире- ниями, а не только ino; ♦ Console: Show verbose output — включить вывод подробных сообщений в ниж- ней панели. Будут показаны все сообщения, включая необязательные. Опция полезна при выявлении сложных ошибок компиляции или загрузки в плату. б.З. Подключение платы Arduino и первая программа Если вы раньше подключали к своему компьютеру платы Arduino и работали со средой Arduino IDE, то на вашем компьютере уже установлены необходимые драй- веры. В противном случае может потребоваться их установка. Дело в том, что ус- тановочный пакет содержит драйверы только для официальных плат, в которых используется микросхема FT232. Китайские клоны часто используют микросхемы СН340 или СР2302 (СР2303). Если при подключении платы в системе не появляет- ся новый виртуальный СОМ-порт, вернитесь к разд. 5.2. При подключении платы список доступных портов обновляется в интерфейсе Arduino Create автоматически. Подключив плату, нажмите на выпадающий список выбора плат в панели редактора. Все ранее выбранные варианты сохраняются в этом списке. Если нужного варианта там нет, нажмите кнопку Select Other Board & Port и выберите нужный порт и плату из общего списка. Для примера мы воспользуемся платой Arduino Nano. Как обычно, первым проек- том будет мигающий светодиод, который встроен на плату и подключен к выводу D13. Подключив плату, убедитесь, что между ней и расширением Arduino Create установлено соединение. Если соединения нет, слева от имени платы отображается линия, перечеркнутая красным крестиком. Выберите на панели слева пункты Examples | Built In | Basics | Blink. В редактор автоматически загрузится скетч примера. Ничего не меняя, нажмите кнопку загруз- ки в плату (стрелка вправо). Вместо кнопки появится надпись Busy, означающая, что порт занят выгрузкой программы, а на плате замигают светодиоды Rx и Тх (если они установлены). После успешной загрузки под текстом скетча должна по- явиться зеленая полоса с текстом Success: Done uploading. Если этого не произош- ло, надо проверить правильность установки драйвера, выбор порта и платы. Не об- ращайте внимания на служебные сообщения в нижней части панели редактора. В случае успешной загрузки светодиод на плате начнет мигать с частотой 1 Гц. Чтобы убедиться, что это работает именно ваша программа, а не загруженная ки-
116 Глава 6 тайцами на фабрике тестовая прошивка, замените в скетче строки delay (книж- на delay (300); и снова выгрузите прошивку. Светодиод начнет мигать в три раза чаще. Теперь загрузите другой пример: Examples | Built In | Basics | Fade. Это плавное гашение и зажигание внешнего светодиода, подключенного к цифровому порту D9. Обратите внимание, что в панели редактора появились вкладки layout.png и schematic.png — схема соединений на макетной плате и принципиальная элек- трическая схема. В схеме проекта не указан номинал резистора в цепи светодиода. Используйте резистор с номиналом 200 или 240 Ом. 6.4. Облачный сервис Arduino Cloud На момент подготовки книги сервис Arduino Cloud находился в стадии тестирова- ния и активной разработки. Следить за этим процессом очень интересно, а исполь- зовать функции сервиса можно уже сейчас. Давайте создадим свою первую «вещь» (Thing). В стартовой панели сервиса Arduino Create (см. рис. 6.1) щелкните на значке Getting Started и в открывшейся панели — на значке Setup Arduino Cloud. Выбе- рите одну из трех официальных плат (рис. 6.4). Выберем модуль расширения YUN Shield, как самый доступный по цене. Этот модуль подключается к популярной базовой плате Arduino Uno. Рис. 6.4. Выбор платы для работы с облачным сервисом Arduino Cloud Теперь надо установить библиотеку ArduinoCIoud на ваш компьютер. Валено: на компьютере должна быть установлена среда разработки Arduino IDE. Запустите приложение Arduino DDE. Перейдите в пункт меню Скетч | Подключить библио- теку | Управлять библиотеками и найдите в списке библиотеку ArduinoCIoud. Нажмите кнопку Установка.
Облачная среда разработки Arduino Create Установив библиотеку, вернитесь к окну настройки облачного сервиса. Нажмите кнопку Next и придумайте имя вашей первой «вещи». Пусть это будет TestThing. После следующего нажатия кнопки Next на экране появится таблица с параметрами «вещи»: ваше имя пользователя, имя «вещи», уникальный номер «вещи» и ее па- роль (рис. 6.5). TWNCJD Т Н <, Ы С .„ £> А 5 S 'Л О Р. 0, Рис. 6.5. Параметры интернет-вещи для подключения к облаку Arduino Cloud При следующем нажатии кнопки Next на экране появится большая кнопка Add Property (Добавить свойство). На этом этапе мы можем добавить свойство, кото- рым будем управлять через Интернет. По умолчанию нам предлагают учебный пример. Не будем пока ничего менять в этом примере и просто еще раз нажмем кнопку Next. Появится окно для скачивания готовой программы, которую можно загрузить в плату. В код программы автоматически подставлены все значения для подключения к облаку. Нажмите кнопку Download и сохраните программу в удоб- ном месте для последующего использования. К сожалению, на момент подготовки книги к сервису Arduino Cloud можно было подключиться только при помощи фирменных устройств Arduino, поскольку для этого требуется наличие сертификата SSL, установленного на устройстве. Такие популярные модули, как Dragino Yun Shield и Iduino Yun Shield, пока не могли под- ключиться к облаку. Возможно, к моменту выхода книги из печати проблема будет исправлена. 6.5. Библиотека проектов Arduino Project Hub Arduino Project Hub представляет собой подборку проектов по тематике Arduino, представленную на сайте www.hackster.io. Каждый проект сопровождается под- робнейшим описанием с иллюстрациями и видео. Пользователи предлагают десят- ки интересных проектов, полезных, обучающих или просто забавных. Вы можете
118 Глава 6 создать и предложить для публикации свой проект. Оригинальные и полезные про- екты включаются в новостную рассылку Arduino и продвигаются в соцсетях. Это хороший способ сделать ваш проект популярным. Войдите на сайт www.create.arduino.cc под своей учетной записью и перейдите на страницу Arduino Project Hub. Для создания нового проекта нажмите кнопку New Project. Перед публикацией проекта внимательно ознакомьтесь с требованиями. В целом они просты и понятны, но для составления описания и инструкции необ- ходимо владеть грамотным английским языком на уровне выше среднего или обра- титься за помощью к переводчику. Все проекты перед публикацией проверяются редакторами сервиса. Если ваш проект не соответствует правилам или сопровожда- ется неграмотным текстом, его вернут на доработку.
ГЛАВА 7 Примеры программ и проектов для Arduino В этой главе мы рассмотрим как учебные примеры использования компонентов платформы Arduino, так и законченные проекты. Наличие в составе платформы сетевых модулей с операционной системой Linux открывает новые возможности для любительского творчества. 7.1. Использование системного времени Linux В устройствах, которые ведут логи измерений или нуждаются в отображении те- кущего времени на индикаторе, обычно используют модуль часов реального вре- мени (RTC, Real Time Clock). Такой модуль снабжен резервным источником пита- ния и продолжает работать после отключения основного источника. Он требует начальной настройки и периодической корректировки времени. Если к плате Arduino подключен сетевой модуль на основе ОС Linux, и имеется выход в Интернет, можно обойтись без аппаратного модуля часов. Linux получает точное время со специального NTP-сервера (Network Time Protocol, протокол сете- вого времени). Во время настройки шилда Dragino Yun мы указали локальный ча- совой пояс (см. разд. 5.4.5). Теперь мы можем в любой момент из скетча отправить запрос текущего времени и даты в шилд. Кроме упрощения конструкции, такой подход имеет еще одно, менее очевидное преимущество. К открытым серверам NTP ежесекундно обращаются миллионы устройств. С развитием Интернета вещей количество таких запросов будет только расти. Поддержание аппаратных ресурсов, способных обслужить эти запросы, требует изрядных финансовых затрат. Но прак- тически все серверы NTP бесплатны и общедоступны. Поэтому хорошим тоном в проектировании считается минимизация количества обращений к NTP-серверам. Рекомендуется отправлять внешний запрос только в случае реальной необходимо- сти. Например, для корректировки часов один раз в сутки. Но к собственному сете- вому модулю вы можете обращаться сколь угодно часто. Имейте в виду, что по стандарту UNIX общемировое время выводится в американском стандарте. Ответ- ственность за правильную настройку часового пояса в устройстве и учет воз- можного перехода на летнее время лежит исключительно на пользователе!
120 Глава 7 Для получения информации о текущем времени и дате в ОС Linux введите в консо- ли PuTTY команду date. В ответ вы получите строку типа: Fri Jan 27 21:55:03 KRAT 2017 Это полный формат даты с указанием часового пояса. Он не всегда удобен. Для форматирования отображения даты в соответствии со своими предпочтениями существуют специальные поля (табл. 7.1). Указатель на формат должен начинаться с символа +. Перед указателем поля ставится символ %, остальные символы, встав- ленные в формат, отображаются без изменения. Все поля имеют фиксированный размер и при необходимости дополняются нулями. Таблица 7.1. Поля форматирования отображения даты Символ п t m d У Y D H M S т j w a h r Значение Вставить символ перевода строки Вставить символ табуляции Месяц года: от 01 до 12 День месяца: от 01 до 31 Две последние цифры года: от 00 до 99 Год полностью (четыре цифры) Дата в виде мм/дд/гг Час: от 00 до 23 Минуты: от 00 до 59 Секунды: от 00 до 59 Время в виде чч:мм:сс День года: от 001 до 366 День недели: воскресенье = 0 Сокращение дня недели: от Sun до Sat Сокращение названия месяца: от Jan до Dec Время по 12-часовой шкале Примеры: ♦ команда: date f+%d-%m-%Yf—результат: 28-01-2017 ♦ команда: date '+%т' —результат: 19:05:47 (часы:минуты:секунды) ♦ команда: date '+DATE: %d/%m/%yf—результат: DATE: 15/03/2017 Теперь создадим скетч Arduino, который будет запрашивать текущее время у шил- да Dragino Yun. Он предельно прост (листинг 7.1).
Примеры программ и проектов для Arduino 121 tinclude <Console.h> tinclude <Process.h> void setup() { Bridge.begin(); Console.begin(); while (!Console); Console.println("Console connected"); void loopO { Process askTime; askTime.begin("date"); askTime.addParameter("+%T"); askTime.run(); while (askTime.available()>0) { char с = askTiine.readO ; Console.print (c); } //Console.flush(); delay(1000); Библиотека console понадобится нам лишь для того, чтобы выводить полученное значение текущего времени в консоль скетча и убедиться, что он работает правиль- но. Библиотека Process позволяет выполнить системные команды или запустить программы в среде ОС Linux и передать в них параметры. Также мы используем встроенную библиотеку Bridge, которая нужна для двустороннего обмена коман- дами и данными между скетчем в плате Arduino и операционной системой в шилде. В блоке настройки мы сначала активируем виртуальный мост Bridge, затем вирту- альную консоль и ждем, пока она не запустится. В блоке основного цикла один раз в секунду мы создаем процесс оболочки Linux с именем askTime, отправляем ему команду date и параметр +%т. Затем запускаем команду на исполнение. Команда блокирующая, т. е. выполнение следующих опе- раторов скетча останавливается до завершения выполнения отправленной в шилд команды. Далее в цикле посимвольно считываем полученную строку ответа в стро- ковую переменную и выводим ее в консоль. В реальном проекте вместо бесполез- ного демонстрационного вывода времени в консоль выполняются нужные дейст- вия — например, вывод времени на дисплей устройства или запись в лог. Строка console, flush о служит для принудительной очистки буфера консоли, если из нее не прочитаны данные, во избежание переполнения. Это может случиться, например, если вы запустили скетч, он пытается выводить в консоль большой объ-
122 Глава 7 ем текста, но к консоли не подключено окно вывода (монитор порта Arduino IDE, PuTTY и т. п.). В таком случае консоль становится похожа на засорившуюся водо- сточную трубу, а команда flush (промыть) ее прочищает. В данном примере эта строка закрыта комментарием, потому что подразумевается, что вы обязательно подключитесь к консоли, чтобы наблюдать за работой скетча. Загрузив скетч, под- ключитесь к шилду по SSH при помощи PuTTY и введите команду: telnet localhost 6571 В консоли должно один раз в секунду обновляться значение текущего времени (рис. 7.1). Если попытка запустить telnet выдает сообщение об ошибке, значит, кон- соль скетча не активна, и в нее ничего не выводится. ©-PuTTY - □ X root@dragino-15e324:~# root@dragino-15e324:~# telnet localhost 6571 22:44:57 22:44:58 22:44:59 22:45:00 22:45:02 22:45:03 22:45:04 22:45:05 22:45:06 22:45:07 22:45:09 22:45:10 22:45:11 22:45:12 22:45:13 22:45:15 22:45:16 22:45:17 22:45:18 22:45:19 22:45:20 22:45:22 Рис. 7.1. Результат работы скетча, запрашивающего системное время 7.2. Сохранение данных на карту памяти Шилд Yun оснащен встроенным слотом для карты памяти microSD. Скетч Arduino может обращаться к этой карте памяти при помощи библиотеки Bridge. В корневом каталоге карты памяти создайте папку с названием Arduino. Только при наличии такой папки карта памяти будет автоматически подмонтирована в систему при загрузке операционной системы шилда. Внутри папки Arduino создайте пустой файл с названием datalog.csv. В этом файле будут храниться данные лога. Установи- те карту памяти в слот шилда, подсоедините его к плате Arduino и включите пита- ние. После окончания загрузки убедиться, что созданный файл доступен, вы може- те ПрИ ПОМОЩИ КОМаНДЫ Is /mnt/sd/arduino В КОНСОЛИ PuTTY.
Примеры программ и проектов для Arduino 123_ Скетч Arduino (листинг 7.2) считывает уровень аналогового сигнала на входах АО, А1 и А2. К этим входам могут быть подключены любые сенсоры с аналоговыми выходами. Напряжение на аналоговом входе не должно превышать напряжение питания микроконтроллера! Если сейчас у вас нет подходящих датчиков, можно оставить все входы свободными. Скетч измерит напряжение помех на этих входах, поэтому значения все равно не будут нулевыми. В нашем примере значения изме- ренных напряжений сохраняются в лог каждые пять секунд. Запустив консоль или монитор порта, вы можете наблюдать, как меняются значения (рис. 7.2). Аналогич- ные значения записываются в файл. Если файл отсутствует, в консоль выводится сообщение об ошибке. tinclude <FileIO.h> //класс FilelO позволяет обращаться к файловой системе Linux linclude <Console.h> //класс Console позволяет выводить сообщения скетча в консоль Linux void setup () { // Initialize the Console Bridge.begin(); Console.begin(); FileSystem.begin(); while (!Console); // Ждем готовность консоли Console.printIn("Filesystem datalogger\n"); void loop () { // Создаем строку данных, начинающуюся со штампа времени String dataString; dataString += getTimeStamp(); dataString += " , "; // Читаем значения трех сенсоров и добавляем к строке лога: for (int analogPin = 0; analogPin < 3; analogPin++) { int sensor = analogRead(analogPin); dataString += String(sensor); if (analogPin < 2) { dataString += ","; // Разделяем значения запятыми // Открываем файл. Только один файл может быть открыт в системе в одно время. // Прежде, чем открыть новый, надо закрыть предыдущий. // Указываем путь к накопителю данных в системе Linux File dataFile = FileSystem.open("/mnt/sd/arduino/datalog.csv", FILE_APPEND);
124 Глава 7 // Если файл доступен, записываем в него данные: if (dataFile) { dataFile.println(dataString); dataFile.close(); // Также выводим строку в консоль: Console.println(dataString); } // Если файл недоступен, сообщаем об ошибке: else { Console.println("Error opening datalog.csv"); } delay(1000); //Повторяем измерение каждые 10 секунд // Функция получения системного времени Linux // Выполняем команду date в шилде Yun String getTiirieStamp () { String result; Process t; t.begin("date"); // Объявляем команду t.addParameter("+%D-%T"); // Добавляем параметры вывода t.run(); // Выполняем команду // Читаем результат выполнения команды в строковую переменную while (t.available() > 0) { char с = t.read(); if (с != f\nf) result += c; } return result; // Выполняем результат # 192.168/IЛ 59 - PuTTY - □ root@dragino-15e324:~# telnet localhost 6571 Filesystem datalogger 01/29/17-12:04:17 , 269,232,226 01/29/17-12:04:22 , 870,865,884 01/29/17-12:04:27 , 890,893,923 01/29/17-12:04:32 , 859,857,876 01/29/17-12:04:38 , 782,788,844 01/29/17-12:04:43 , 800,802,858 01/29/17-12:04:48 , 697,684,738 01/29/17-12:04:53 , 681,666,700 01/29/17-12:04:58 , 793,790,806 01/29/17-12:05:04 , 849,847,870 01/29/17-12:05:09 , 815,814,829 01/29/17-12:05:14 , 678,660,693 01/29/17-12:05:19 , 670,653,688 01/29/17-12:05:24 , 653,635,679 Рис. 7.2. Просмотр сохраняемых данных в консоли (см. листинг 7.2)
Примеры программ и проектов для Arduino 125 В этом скетче нам пригодится функция запроса системного времени, которую мы рассмотрели в предыдущем примере (см. листинг 7.1). Она добавлена в скетч под именем getTimeStamp (). Чтобы извлечь сохраненные данные для анализа и обработки, подключитесь к шилду Yun при помощи файлового менеджера WinSCP (см. разд. 2.9.2) и перене- сите файл datalog.csv из каталога /mnt/sd/arduino/ на свой компьютер. Отметим, что файл лога пригодится не только для сохранения измеренных данных. Если позво- ляет объем свободной памяти программ микроконтроллера, то функцию ведения лога можно добавить в любой другой скетч и сохранять в лог отладочную и слу- жебную информацию о работе устройства. Зачастую это помогает выявить причи- ны сбоев или неисправностей. 7.3. Сохранение данных на USB-накопитель Вместо карты памяти, установленной во встроенный слот, вы можете использовать USB-накопитель, подключенный в разъем USB-хоста. Прежде всего убедимся, что установлены необходимые пакеты для работы с USB-накопителем. Введите в тер- минале PuTTY следующие команды: opkg update op kg install kmod-usb-ohci insmod usb-ohci opkg install kmod-usb2 insmod usbcore insmod ehci-hcd Вставьте накопитель в гнездо USB. Теперь мы должны узнать, под каким именем он подмонтировался в системе. Введите в терминале команду is /mnt/. Вы должны получить в результате строку вида: sd sdbl sdcl Буквами sd обозначен встроенный слот для карты памяти, а ваш внешний накопи- тель скрыт под буквами sdbl или sdcl. Введите команду is /mnt/sdbi для просмот- ра содержимого накопителя. Если ничего не отобразилось, значит, вы неправильно выбрали имя накопителя. В таком случае введите is /mnt/sdci. Вы должны увидеть содержимое файловой системы накопителя. В файловом менеджере WinSCP содержимое этого накопителя будет доступно в каталоге с тем же путем, какой вы указали в команде терминала. Теперь мы можем создать в корневом каталоге накопителя папку arduino и помес- тить в нее пустой файл datalog.csv. He забудьте в скетче исправить адрес файла! 7.4. Сохранение данных в таблицу MySQL Существует множество облачных сервисов, позволяющих сохранять рабочие дан- ные на сервере и обращаться к ним в любое время. Тем не менее, в несложных частных проектах бывает удобнее работать с собственным сервером. Иногда вся
126 Глава 7 инфраструктура проекта расположена в пределах собственной квартиры. Прямой доступ к серверу MySQL применяется также в производственных системах, кото- рые по соображениям безопасности изолированы от глобальной сети Интернет. В такой ситуации можно рассчитывать только на свои ресурсы. В дальнейшем, для построения отчетов и графиков, к сохраненным данным могут обращаться различ- ные приложения и локальные веб-серверы. Приблизительно по такому принципу работают облачные сервисы, но в данном случае у вас будет собственное «облачко». Мы подразумеваем, что у вас установлен и настроен сервер MySQL. Подробное описание развертывания сервера MySQL и работы с базами данных (БД) выходит за рамки книги. Этим вопросам посвящено множество хороших книг и сетевых ре- сурсов. Отметим лишь, что сервер MySQL можно получить бесплатно и развернуть на любой популярной компьютерной платформе. Например, на собственном ноут- буке. Процесс установки и настройки максимально автоматизирован, освоение на- чальных навыков работы займет у вас не более двух-трех вечеров. Перед началом работы с примером вам необходимо знать IP-адрес и номер порта сервера. Эти параметры в дальнейшем не должны меняться, поскольку будут в яв- ном виде прописаны в коде программы. Установим на шилд Yun модуль клиентской части MySQL для языка Lua. Введите в окне терминала команды: opkg update opkg install luasql-mysql Теперь на своем компьютере запустите утилиту для работы с сервером MySQL. Например, для ОС Windows вместе с сервером устанавливается среда MySQL Workbench. Введите в окне SQL Query следующий многострочный SQL-запрос и запустите его на выполнение: create database temperature; use temperature; create table record(time datetime, value float(4,1)); В этом запросе мы создали базу данных temperature, указали серверу, что будем работать с этой БД, в базе данных создали таблицу record, состоящую из двух по- лей: time и value. В первом поле будет храниться штамп времени измерения, во втором — измеренное значение. Теперь проверим функционирование нашей базы данных. Введите и выполните еще две строки SQL-запроса: insert into record(time,value) values("2017-01-25 11:01", 29.0); select * from record; Первая строка создает пробную запись, вторая выводит содержимое таблицы в ок- но просмотра результатов запроса. Если БД работает правильно, в окно результата будет выведена таблица, состоящая из одной пробной записи. Запустите блокнот Notepad++ и создайте скрипт на языке Lua под названием linkmysql.lua (листинг 7.3). Строки вводятся без переноса. Вместо слов 'login1 и
Примеры программ и проектов для Arduino 127_ 'password1 подставьте имя пользователя, имеющего права для записи в БД и его пароль. Вместо звездочек подставьте IP-адрес сервера MySQL. luasql = require "luasql.mysql" local value=arg[l] local current_time=os.date("%Y-%m-%d %H:%M:%S") env = assert (luasql.mysql()) con = assert (env:connect('temperature1, 'login1, 'password1, res = assert (con:execute('INSERT INTO record(time,value) VALUES ("'. .current_time.. "\ '. .value..')')) Проверим работу скрипта. В это время сервер MySQL должен быть доступен. В консоли SSH, подключенной к шилду, введите команду lua linkmysql.lua 24.5 В утилите работы с сервером MySQL вновь введите запрос select * from record; В таблице temperature должна появиться еще одна запись. Теперь мы готовы загру- зить в плату Arduino скетч (листинг 7.4). tinclude <Bridge.h> int sensor; char с; void setup () { // инициализируем классы Bridge и Console Bridge. begin (); Console. begin () ; while (!Console); // Ждем готовность консоли Console.println("Start Sketch\n"); void loop () { //read the sensor sensor = analogRead(O); send_data () ; delay (5000);
128 Глава 7 // Функция вызова скрипта linkmysql.lua void send_data() { Process logdata; logdata.begin("lua"); // Объявляем команду запуска Lua // Добавляем параметр - адрес скрипта logdata.addParameter("/root/linkmysql.lua"); // Добавляем параметр - значение температуры logdata.addParameter(String(sensor)); logdata.run(); // Выполняем команду с параметрами // Читаем выходной текст команды и выводим в консоль // Если команда выполнена успешно, вывод пустой // Если присутствует сообщение об ошибке, оно будет выведено в консоль while (logdata.available() > 0) { с = logdata.read(); } Console.println(с); 7.5. Сервис Temboo и передача данных в Google Spreadsheet Сервис Temboo предоставляет унифицированный и максимально автоматизирован- ный доступ более чем к сотне популярных интернет-сервисов при помощи одного аккаунта. Достаточно зарегистрироваться на Temboo, чтобы организовать взаимо- действие вашего устройства с Twiter, Facebook и даже PayPal. Кроме подробного пошагового руководства с шаблонами настройки и диагностикой ошибок, сервис Temboo предоставляет автоматический генератор программного кода. После успешной настройки подключения вы получаете готовый скетч для Arduino, в ко- торый уже внесены необходимые пароли, идентификаторы и вызовы библиотек. Для автоматической генерации кода, при работе с шаблонами проекта вы должны выбрать платформу Arduino в раскрывающемся списке возле логотипа. Откровенно говоря, настройка проектов в Temboo не очень проста. Не всегда уда- ется выполнить ее с первого раза. Но Temboo не только указывает на ошибки — вы получаете подсказки по их исправлению. Сейчас мы рассмотрим пример передачи данных в электронную таблицу Google Spreadsheet. Этот пример входит в набор типовых примеров Temboo, но мы адаптируем его для шилда Dragino Yun. В поша- говом описании на Temboo имеются некоторые неточности, а некоторые нюансы упущены. Постарайтесь аккуратно и последовательно выполнять все действия, о которых будет рассказано дальше. Если что-то не получится, просто вернитесь назад и повторите нужные действия, стараясь понимать их значение. Перед началом настройки откройте программу для заметок или стандартный блок- нот и в процессе создания приложения копируйте туда все настроечные значения (идентификатор пользователя, секретный код и т. д.). Обязательно сохраните их, чтобы не возвращаться в Temboo. Эти данные понадобятся вам при настройке скетча.
Примеры программ и проектов для Arduino 129 Если у вас еще нет аккаунта Google, создайте его. Теперь нам нужно активировать API для Google Sheets. Перейдите в консоль разработчика по адресу https://console.developers.google.com/. Создайте новый проект под названием TestDataSheet (рис. 7.3). Для этого выберите пункт меню Create Project в раскры- вающемся списке проектов радом с логотипом Google APIs. Mew Project iesc.t? ?m*>, me upd?t<?s ?€O»2rd?»^5 feature #r$nc j' ug,g<ei-'\c"'!,ii feedback c«u<v*vs d^c? соеааи o*'*t?$ a«re*r thai nv» -j^f of any ■"■ ,= •••• .••■■ \ ..•; .»'•.•'..'' '■ '" ' \^ i>jt:>t?>:" "g my .'.с Рис. 7.З. Создаем новый проект в Google API В секции API Manager выберите закладку Library. На открывшейся странице с перечнем всех API найдите ссылку Sheets API (рис. 7.4) и перейдите по ней. Google Maps APIs ШЩЁ Googie Apps API* Рис. 7.4. Расположение ссылки на Sheets API По умолчанию пользовательские API в вашем проекте отключены. Активируйте Google Sheets API нажатием кнопки Enable (рис. 7.5). В секции API Manager выберите закладку Credentials. Создайте новый идентифи- катор клиента Client ID, указав тип приложения Web application (рис. 7.6). Введи- те далее свой адрес электронной почты и название своего веб-приложения (рис. 7.7). Google подразумевает, что вы создаете веб-приложение, которое будете
130 Глава 7 распространять среди других пользователей. Поэтому без ввода имени приложения и почты разработчика не обойтись, даже если вы создаете приложение для собст- венных нужд. <r Gooqle Sheets API About this API Credentials Create client ID Application type • Web app':cationл Android L^m • Uh'orns1 App •„ 6 m РЛ-ABIF Рис. 7.5. Активация Sheets API Рис. 7.6. Первый шаг настройки идентификаторов Credentials Email address ! Product name <hovvn to use Рис. 7.7. Второй шаг настройки идентификаторов
Примеры программ и проектов для Arduino 131 После сохранения данных, введенных в закладке OAuth consent screen, укажите адрес обратного вызова в поле Authorized Redirect URL Сервис Temboo автомати- чески подскажет этот адрес. Убедитесь, что он содержит имя пользователя. В моем случае адрес имеет вид https://fankraft.temboolive.com/callback/google. Это адрес, на который Google будет возвращать пользователя веб-приложения после оконча- ния настроек разрешений. В данном случае это пустая страница-заглушка. Вернитесь на страницу Temboo и перейдите по адресу https://temboo.com/ libraiy/Libraiy/Google/OAut^nitializeOAuth/. В верхней части страницы выбери- те платформу Arduino, плату Arduino Uno и шилд Arduino Yun. В поле Client ID введите идентификатор, который Google присвоил вашему при- ложению, а в поле Scope введите текст: https://spreadsheets.google.com/feeds (рис. 7.8). Нажмите кнопку Generate Code. Если все сделано правильно, в итоге вы получите секретные данные авторизации для вашего конкретного приложения (рис. 7.9). Сохраните их на будущее. : Google . OAuth . tnitializeOAuth ; Рис. 7.8. Ввод данных для подключения к сервису Google Sheets Под секцией данных авторизации на странице Temboo будет выведено два поля, в одном из которых приведена ссылка для подтверждения доступа к Google, а во втором— специальный длинный набор символов, который называется Callback Ш. Не пропустите этот этап и два этих поля! Прежде всего, в новом окне брау- зера перейдите по сгенерированной ссылке Authorization URL, чтобы подтвердить свое согласие на доступ приложения к вашей учетной записи Google. Эта ссылка уникальная для каждого случая, процитировать ее в книге невозможно. В ответ на запрос Google нажмите кнопку Accept. Если разрешение оформлено нормально, откроется пустая страница. Помните, недавно мы говорили про пустую страницу- заглушку? Это окно браузера с пустой страницей можно закрыть.
132 Глава 7 OAuth client Рис. 7.9. Секретные данные для авторизации приложения Скопируйте в буфер обмена набор символов Callback ID и перейдите по ссылке, которая на странице Temboo называется FinalizeOAuth. Введите скопированное значение Callback Ш и нажмите кнопку Run (рис. 7.10). Важное примечание: Callback ID имеет ограниченное время жизни, поэтому желательно не делать пере- рыв на этом этапе настройки. Если значение все же устарело, и после нажатия кнопки Run появляется сообщение об ошибке, вернитесь к этапу, показанному на рис. 7.8, и повторите генерацию кода. Client 10 Call back! О Рис. 7.10. Форма для ввода Callback ID После успешной отработки нажатия кнопки будет сгенерирован AccessToken (рис. 7.11). Сохраните его текст в заметке. Наверняка у вас возникли вопросы: что мы сейчас получили и почему все так сложно? Сложность связана с обеспечением безопасности доступа к сервисам Google. Поэтому применяется многофакторная
Примеры программ и проектов для Arduino 133 поэтапная авторизация. Помните, вы на странице Google в новом окне браузера разрешили доступ к личному аккаунту? Так вот, AccessToken — это ваша личная цифровая подпись, заверяющая право внешнего приложения получить доступ толь- ко к вашему аккаунту, и только к сервису электронных таблиц на этом аккаунте. Предоставляя кому-то этот токен, вы даете ему в руки ключ для входа в хранилище личных данных. В нашем случае веб-приложением будет скетч Arduino, работаю- щий через шилд Dragino Yun. Сначала скетч проходит авторизацию на сервисе- посреднике Temboo. Затем Google проверяет, зарегистрировано ли вообще такое приложение, может ли оно запрашивать доступ к сервисам. И наконец, скетч предъявляет свой токен, чтобы получить доступ к конкретному аккаунту Google, и называет имя таблицы, с которой будет работать. Надеюсь, вы не забыли сохранить все значения полей, с которыми работали, в текстовой заметке. Run Рис. 7.11. Токен для доступа к таблице пользователя Подготовим таблицу для выгрузки данных. Перейдите по адресу https:// docs.google.com/spreadsheets/. Создайте новую таблицу с двумя столбцами, кото- рые называются time и sensor (рис. 7.12). В нашем примере эта таблица называется mysampledata. После того, как сгенерирован токен, вы получаете автоматически сгенерированный код основного скетча и так называемый файл заголовка, который содержит данные mysampleclata Hi File E'lit View Insert Format Data Tools .Add-ons Help '■/■'*■.• : ■ iqi nr^ "•* *p S ":ъ .0 ,1)1} 123 - A rial - 10 • H / I 1. 'time A E ? sensor Рис. 7.12. Таблица для выгрузки данных через Temboo
134 Глава 7 для подключения к аккаунту Temboo. Мы будем использовать модифицированный скетч для Dragino Yun (листинги 7.5 и 7.6), поэтому сохраните автоматически сгенерированные коды в удобном месте для последующего копирования данных доступа. Скетч состоит из файлов dragino_google_sheet.ino (основной файл) и TembooAcount.h (файл заголовка). Эти файлы должны располагаться в одной папке. Вместо значений, заполненных символами звездочек, подставьте одноименные значения из автоматически сгенерированного сервисом Temboo кода программы. Содержимое файла TembooAccount.h универсальное и пригодится для любых других проектов с использованием Temboo. #define TEMBOO_ACCOUNT "******" // Логин вашего аккаунта Temboo #define TEMBOO_APP_KEY_NAME "*******" // Название вашего приложения на Temboo #define TEMBOO_APP_KEY "********" // Ключ приложения на Temboo #include <Bridge.h> #include <Console.h> #include <Temboo.h> #include "TembooAccount.h" // Файл содержит информацию об аккаунте Temboo // Введите здесь ваши данные доступа к аккаунту Google, // скопируйте их из кода, который автоматически сгенерирован сервисом Temboo const String GOOGLE_CLIENT_ID = и*********************"; const String GOOGLE_CLIENT_SECRET = "*********************.». const String GOOGLE_REFRESH_TOKEN = »*******************•*"; // Название существующей таблицы Google Sheets // Обратите внимание, что надо ввести именно название таблицы, а не ее URL, как // сказано в руководстве на Temboo const String SPREADSHEET_TITLE = "mysampledata"; int numRuns =1; // Счетчик количества обращений к таблице int maxRuns = 100; // Максимальное количество обращений, // будет добавлено не более 100 строк за время работы скетча void setup() { Bridge.begin(); Console.begin(); delay(4000); Console.print("Initializing the bridge... "); while (!Console); // Ждем, пока консоль Linux будет запущена Console.println("Done!\n");
Примеры программ и проектов для Arduino 135 void loop() { // Повторяем запись новых значений в таблицу, пока не превышено число обращений if (numRuns <= maxRuns) { Console.println("Running AppendRow - Run #" + String(numRuns++)); // получаем время в миллисекундах с момента запуска скетча unsigned long now = millis(); Console.println("Getting sensor value..."); // получаем от сенсора измеренное значение unsigned long sensorValue = getSensorValue(); Console.println("Appending value to spreadsheet..."); // создаем процесс для отправки запроса на добавление строки через Teinboo TembooChoreo AppendRowChoreo; // запусаем клиента ТетЬоо // учтите, что клиент должен быть вызван и обеспечен данными в виде // соответствующих аргументов при каждом использовании метода run(). AppendRowChoreo.begin(); // определяем персональные данные аккаунта Temboo, из файла TembooAccount.h AppendRowChoreo. setAccountName (TEMBOO_ACCOUNT) ; AppendRowChoreo.setAppKeyName(TEMBOO_APP_KEY_NAME); AppendRowChoreo.setAppKey(TEMBOO_APP_KEY); // определяем библиотеку Temboo Choreo //(Google > Spreadsheets > AppendRow) AppendRowChoreo.setChoreo("/Library/Google/Spreadsheets/AppendRow"); // определяем необходимые входные данные библиотеки // читайте //https://www.temboo.com/library/Library/Google/Spreadsheets/AppendRow/ // для детальной расшифровки требований к входным параметрам // определяем ваш Google Client ID AppendRowChoreo.addlnput("ClientID", GOOGLE_CLIENT_ID); // определяем ваш Google Client Secret AppendRowChoreo.addlnput("ClientSecret", GOOGLE_CLIENT_SECRET); // определяем ваш Google Refresh Token AppendRowChoreo.addlnput("RefreshToken", GOOGLE_REFRESH_TOKEN);
136 Глава 7 // определяем название вашей таблицы AppendRowChoreo.addInput("SpreadsheetTitle", SPREADSHEET_TITLE); // преобразуем время и показания сенсора в строку, // разделенную запятой String rowData(now); rowData += ","; rowData += sensorValue; // add the RowData input item AppendRowChoreo.addlnput("RowData", rowData); // запускаем метод Temboo Choreo и ждем результат // возвращаемый код принимает одно из значений: "успех" или "ошибка" unsigned int returnCode = AppendRowChoreo.run(); // возвращаемый код "ноль" (0) означает успех записи if (returnCode ==0) { Console.println("Success! Appended " + rowData); Console.println(""); } else { // код, отличный от ноля, означает наличие ошибки // читаем и выводим в консоль все сообщения об ошибках while (AppendRowChoreo.available()) { char с = AppendRowChoreo.read(); Console.print(c); AppendRowChoreo.close(); // закрываем текущий процесс Console.printIn("Waiting..."); delay(5000); // ждем 5 секунд перед следующим запуском цикла измерения-записи //в этой функции симулируем чтение значения из сенсора // считывается случайное значение с аналогового входа АО //вы можете заменить код этой функции на код чтения данных с реального датчика unsigned long getSensorValue() { return analogRead(AO); Скомпилируйте и загрузите программу в плату Arduino. Откройте созданную ранее таблицу в браузере. Данные в окне браузера обновляются автоматически, поэтому вы будете видеть, как в таблице появляются новые записи (рис. 7.13). Если через 10-15 секунд после запуска скрипта данные не появились, подключитесь к консоли
Примеры программ и проектов для Arduino 137 при помощи терминала PuTTY (или запустите встроенный терминал Arduino IDE), введите команду telnet locaihost 6571 и посмотрите, какое сообщение об ошибке поступает в ответ на попытку записать строки в таблицу. Сервис Temboo ограничивает бесплатное количество вызовов. По исчерпании лими- та вам будет предложено оплатить услуги. Поэтому не злоупотребляйте длительной работой учебных примеров. mysampiedata File Edit View Insert,, Format Data Tools Add-ons Help L^-.,t ;;,чтд v^io © Г ^K ? * % л ■•$& f23 - Anal - 10 • В / -S- 1 itime 2 3 4 5 ^^1 sensor 10613 22976 35043 47034 146 659 640 662 Рис. 7.13. Результат работы скетча (см. листинг 7.6) 7.6. Анализатор эфира в диапазоне 2,4 ГГц В открытом участке диапазона 2,4 ГГц работает множество маломощных приемо- передающих устройств: точки доступа Wi-Fi, беспроводные клавиатуры, беспро- водные датчики охранно-пожарной сигнализации и домашних метеостанций, бес- проводные видеокамеры и различные устройства Bluetooth. Иногда нестабильная работа устройства или плохая скорость передачи по Wi-Fi объясняется наличием мощной помехи на частоте рабочего канала. За городом, на открытом воздухе, по- мех от бытовых устройств намного меньше. Но в диапазоне 2,4 ГГц работает боль- шинство пультов радиоуправляемых моделей и каналы их бортовой телеметрии. На этой же частоте работают так называемые «удлинители канала Wi-Fi», часто при- меняемые в загородных населенных пунктах, некоторые охранные сигнализации и прочее оборудование. Поэтому чистота эфира важна, в том числе и за городом, особенно для радиоуправляемых авиамоделей. Загруженность стандартных каналов Wi-Fi можно легко проверить при помощи бесплатного приложения для смартфона. Но, в силу программно-аппаратных огра- ничений смартфона, он может отображать только уровень сигнала стандарт- ных точек доступа Wi-Fi. Никакие другие источники помех, тем более вне диапа- зона Wi-Fi, при помощи смартфона вы не увидите. Для того чтобы быстро оценить помеховую обстановку для бытовых нужд, мы мо- жем обойтись несложным устройством, которое сканирует весь открытый для гра- жданского применения диапазон 2,4 ГГц и показывает уровень сигнала на разных частотах. Нам не важно, полезный это сигнал или шум, какой у него способ моду-
138 Глава 7 ляции и т. д. В данном случае имеет значение только один фактор — может ли этот сигнал нам помешать. Кроме того, полезно видеть помеховую обстановку диапазо- на в целом, потому что некоторые передатчики, кроме полезного сигнала, излучают помехи на смежных частотах. Устройство, которое можно изготовить за один-два вечера, состоит из трех основ- ных модулей: управляемый по SPI радиоприемник, плата Arduino и дисплей. Стра- ница проекта с описанием процесса разработки и обсуждением пользователей рас- положена по адресу: http://forum.rcdesign.ru/f8/thread397991.html. Сканер работает в диапазоне 2400,009949-2483,128540 МГц с промежутком 405,456543 кГц — итого получается 206 каналов: с 0 по 205. 7.6.1. Модуль радиоприемника На рынке представлено множество недорогих миниатюрных приемопередающих модулей (трансиверов) диапазона 2,4 ГГц. Увы, большинство из них не подходит для использования в качестве измерителя уровня произвольного сигнала. Алгоритм работы стандартного приемника таков: ♦ внешний микроконтроллер загружает в регистры трансивера рабочую частоту, тип модуляции сигнала и прочие настроечные параметры; ♦ трансивер пытается установить связь с другим устройством и провести с ним служебный обмен данными. Только в случае успешного обмена приемник тран- сивера измеряет уровень входного сигнала, оцифровывает его и помещает в спе- циальный регистр RSSI (Received Signal Strength Indicator, индикатор уровня принимаемого сигнала); ♦ микроконтроллер считывает цифровое значение из регистра RSSI. При таком алгоритме работы приемник не может измерить уровень произвольного сигнала или помехи на заданной частоте. Именно поэтому приложение для смарт- фона отображает уровень сигнала только для точек доступа Wi-Fi, которые отвеча- ют на стандартный служебный запрос. Остальные сигналы и помехи смартфон не замечает. Недорогой и функционально насыщенный трансивер, который идеально подходит для нашей задачи, построен на микросхеме СС2500 производства Texas Instruments. Модуль приемопередатчика на основе этой микросхемы можно без труда приобре- сти в зарубежных интернет-магазинах. Я экспериментировал как с дорогим про- фессиональным модулем, содержащим малошумящий усилитель входного сигнала и внешнюю антенну (рис. 7.14, а), так и с дешевым китайским клоном (рис. 7.14, б). Эти модули полностью совместимы программно. Разумеется, профессиональный модуль продемонстрировал лучшие результаты чувствительности и надежнее фик- сирует шумы и помехи, но для бытовых целей в большинстве случаев достаточно купить дешевый аналог. Будьте внимательны при оформлении покупки! Нам нужен модуль только на микросхеме GC2500 или ее полноценном клоне, и никакой другой.
Примеры программ и проектов для Arduino 139 Рис. 7.14. Модули трансивера на основе микросхемы СС2500 (а) и ее аналога (б) 7.6.2. Модуль дисплея Проект изначально разрабатывался под недорогой дисплей 1.8" 128x160 SPI на микросхеме дисплейного драйвера ST7735 или S6D02A1. Но этот дисплей не мо- жет уместить информацию по всему диапазону частот, который охватывает прием- ник СС2500. В окончательном варианте проекта используется дисплей 2.2м 240x320 SPI на микросхеме ILI9341. Свободное место экрана может быть использовано для отображения меню или любой другой полезной информации. Для всех вариантов дисплея существуют готовые библиотеки Arduino, которые доступны в сопровождающем книгу электронном архиве, размещенном на сайте издательства (см. приложение). 7.6.3. Модуль Arduino Благодаря глубокой унификации, в проекте может быть использована любая плата Arduino. В авторском варианте применяется плата Arduino Nano. 7.6.4. Напряжение питания и согласование логических уровней Микросхема СС2500 питается напряжением 3,3 вольта. Если плата Arduino не со- держит встроенного источника +3,3 вольта (обычно такой источник содержит мик- росхема конвертера USB-UART), то следует позаботиться об отдельном источнике. Подача пятиволыповых логических уровней на выводы СС2500 приведет к выходу
140 Глава 7 микросхемы из строя! Необходимо организовать согласование логических уровней при помощи включенных последовательно резисторов или специального преобра- зователя уровней (см. разд. 2.5). 7.6.5. Схема электрических соединений Схема электрических соединений приведена на рис. 7.15. На этой схеме согласова- ние логических уровней выполнено резисторами. Предполагается, что использова- на пятивольтовая плата Arduino и трехвольтовые платы дисплея и трансивера. По умолчанию вход сброса дисплея соединяется с линией сброса платы Arduino. Если сброс дисплея при включении питания происходит нестабильно, подключите вход линии сброса дисплея к выводу D7 платы Arduino и раскомментируйте в скетче строку //#define tftrst 7. В этом случае сброс дисплея будет происходить при- нудительно, коротким импульсом от платы Arduino. На схеме не показаны линии питания +J вольт и +3,3 вольта, т. к. их подключение зависит от модификации платы Arduino. Вам могут понадобиться внешние источники питания. Будьте ак- куратны и проверяйте полярность перед включением. Arduino MOSI MISO SCLK DJRST (D7) D_CS (D9) T_CS(D10) Дисплей 7R О * CO CO о | d *i °. 5 2 CO Q Q CC2500 MOSI MISO SCLK T_CS Рис. 7.15. Схема электрических соединений анализатора помех 7.6.6. Алгоритм работы устройства Основная функциональная нагрузка возлагается на программную часть. Разбираясь с алгоритмом работы устройства, необходимо постоянно обращаться к исходному тексту программы. После сброса микроконтроллера происходит инициализация библиотеки интерфей- са SPI для взаимодействия с дисплеем и трансивером. Используется встроенный аппаратный модуль SPI процессора ATmega, настроенный на максимальную ско- рость для ускорения обновления изображения на дисплее. Дисплей очищается, на- страивается цвет текста, ориентация изображения. Затем происходит инициализация регистров трансивера СС2500. Значения для записи в регистры подобраны специально— для наиболее точного и быстрого измерения уровня произвольного сигнала. Они хранятся в отдельном файле
Примеры программ и проектов для Arduino 141 cc2500_REG.h. После каждого включения питания приемник трансивера должен пройти процедуру самокалибровки для каждой рабочей частоты, на которой будет происходить прием. Поэтому программа перебирает все значения частот, проводит для каждого значения частоты самокалибровку и сохраняет каждое значение ка- либровочной константы в массиве в памяти микроконтроллера. Во время сканиро- вания диапазона соответствующая калибровочная константа извлекается из масси- ва и записывается в регистр приемника. Это позволяет избежать повторной калиб- ровки и значительно ускоряет сканирование. Во время процесса самокалибровки на экране отображается линейка его протекания. В дальнейшем программа работает циклично. В регистр синтезатора частоты мик- росхемы записывается номер канала. Физическая частота приема определяется но- мером канала, настройками шага между каналами и граничными частотами диапа- зона. Из ранее созданного массива калибровочных констант извлекается значение калибровки для текущего канала и записывается в регистр FSCAL1. Выдерживает- ся пауза 300 микросекунд для стабилизации рабочего режима синтезатора частоты микросхемы. Производится несколько измерений уровня входного сигнала подряд. Из них выби- рается максимальное значение. Это сделано для того, чтобы надежнее фиксировать кратковременные или пульсирующие помехи. По умолчанию измерение произво- дится 20 раз. Увеличение числа измерений замедляет сканирование, уменьшение — снижает надежность фиксации спорадических шумоподобных помех. Далее значе- ние из регистра RSSI пересчитывается в значение в единицах дБ/м по алгоритму, описанному в технической документации микросхемы. В каждом цикле измерений опрашивается положение движка потенциометра, пере- мещающего маркер. По умолчанию средний вывод потенциометра подключен к аналоговому входу А7. Его положение пересчитывается в номер канала, вычисля- ется частота канала и отображается в правом верхнем углу экрана. Маркер частоты отображается в виде вертикальной белой линии. Чтобы определить частоту, на которой присутствует визуальный пик помехи, нужно навести маркер на этот пик. Правильно собранное устройство с исправными компонентами начинает работать сразу и не требует наладки. Вы можете подобрать количество измерений в канале (значение в строке #def ine maxsampling), а также настроить другие выводы платы Arduino, исходя из удобства монтажа. Исходный код программы приведен в лис- тинге 7.7. Файл с объявлением полного перечня регистров микросхемы СС2500 в печатном виде не приводится, поскольку содержит исключительно техническую информацию, не имеющую познавательного смысла. Вы найдете этот файл в со- провождающем книгу электронном архиве, размещенном на сайте издательства (см. приложение). На рис. 7.16 показан пример работы устройства с дисплеем 128x160 точек. Видны сигналы окрестных точек доступа Wi-Fi. На рис. 7.17 показано отображение ин- формации на дисплее 240x320 точек, работает передатчик радиоуправления авиа- моделью и модуль бортовой телеметрии.
142 Глава 7 Рис. 7.16. Отображение помеховой обстановки диапазона на дисплее 128x160 точек Рис. 7.17. Отображение помеховой обстановки на дисплее 240x320 точек
Примеры программ и проектов для Arduino 143 #include <Adafruit_GFX.h> // Ядро графической библиотеки #include <Adafruit_ILI9341.h> // Библиотека для дисплея на чипе ILI9341 //#include <Adafruit_QDTech.h> // Библиотека для дисплея на чипе S6D02A1 tinclude <SPI.h> #include "cc2500_REG.h" // Описание регистров СС2500 #define TFT_CS #define SCAN_CS #define SS //#define TFT_RST Arduino) #define ТБТ DC 9 4 10 8 // Вывод дисплея CS // Вывод трансивера CS // вывод SPI SS по умолчанию // сброс дисплея (0 при использовании сброса // Вывод дисплея DC (Data/Command) #define MAX_CHAN_QTY 205 // Максимальное число каналов при шаге 405.456543MHz #define MAX_DISP_LINE 205 // Ограничение разрешения дисплея по горизонтали (для небольших дисплеев) #define MAX_SAMPLING 20 // Количество измерений на каждом канале (1...100) для поиска наибольшего #define TEXT_SIZE 2 #define ROTATION 1 tdefine FCHAN_X 95 // Позиция текстового значения частоты по X tdefine FCHAN Y 4 // Позиция текстового значения частоты по Y Adafruit_ILI9341 tft аппаратный SPI Adafruit_ILI9341(TFT_CS, TFT_DC); // используем byte cal[MAX_CHAN_QTY], data; byte RSSI_data; int RSSI_dbm, RSSIjnax; int i, res_l, res_2, tmp_l, tmp_2, res_dif; float f_chan; void setup(void) { Serial.begin(9600); pinMode(TFT_CS, OUTPUT); pinMode(SCAN_CS, OUTPUT); pinMode(SS, OUTPUT); digitalWrite(TFT_CS, HIGH); digitalWrite(SCAN_CSf HIGH); SPL. begin(); SPI.setClockDivider(SPI_CLOCK_DIV2); 1/2 F CLOCK // Максимально возможная скорость SPI,
144 Глава 7 tft.begin() ; //tft.initR(INITR_BLACKTAB); tft.setRotation(ROTATION); // Горизонтальное положение дисплея tft.fillScreen(ILI9341_BLACK); // Очистка дисплея tft.setCursor(0, 5); tft.setTextColor(ILI9341_WHITE); // Белый цвет текста tft.setTextSize(TEXT_SIZE); // Задаем размер шрифта tft.print("Calibration procedure..."); init_CC2500(); // Загружаем начальные значения в регистры СС2500 // Процедура калибровки // Собираем и сохраняем калибровочные константы для каждого отображаемого канала for (i = 0; i < MAX_DISP_LINE; i CC2500_Write(CHANNR, i); // Задаем номер канала CC2500_Write(SIDLE, 0x3D); // Режим ожидания команды CC2500_Write(SCAL, 0x3D); // Старт калибровки delayMicroseconds(800); // Ждем окончание калибровки data = CC2500_Read(FSCALl); // Читаем калибровочную константу... cal[i] = data; // ... и сохраняем ее Serial.println(data, DEC); tft.drawFastVLine(i, 50, 20, ILI9341_BLUE); // рисуем шкалу прогресса калибровки tft.fillScreen(ILI9341_BLACK); // Очищаем экран tft.drawRect(0, 0, 207, 151, ILI9341_WHITE); tmp_2 = 1; CC2500_Write(CHANNR, 0x00); // Задаем нулевой канал CC2500_Write(SFSTXON, 0x3D); // Запускаем калибровку и ждем 800 мкс delayMicroseconds(800); CC2500_Write(SRX, 0x3D); // Включаем приемник трансивера void loop() { for (i = 0; i < MAX_DISP_LINE; CC2500_Write(CHANNR, i); // Задаем рабочий канал CC2500_Write(FSCAL1, cal[i]); // Загружаем из массива калибровочную константу этого канала delayMicroseconds(300); // Ждем 300 мкс
Примеры программ и проектов для Arduino 145 RSSI_max = -120; for (int j =0; j <= MAX_SAMPLING; j++) { // Собираем заданное число измерений уровня сигнала digitalWrite(SCAN_CS, LOW); // Выбираем микросхему трансивера по выводу CS while (digitalRead(MISO) = HIGH) {. }; SPI.transfer(REG_RSSI); // читаем регистр RSSI RSSI_data = SPI.transfer(0); digitalWrite(SCAN_CS, HIGH); // Конвертируем значение RSSI из двоичного дополненного в десятичное со знаком if (RSSI_data >= 128) { RSSI_dbm = (RSSI_data - 256) / 2 - 70; } else { RSSI_dbm = RSSI_data / 2 - 70; } if (RSSI_dbm > RSSI_max) RSSI_max = RSSI_dbin; // находим максимум RSSIjnax += RSSI_OFFSET; //if (RSSIjnax > 110) RSSIjnax = 110; if (RSSIjnax < 0) RSSIjnax = 1; if (i+1 != res_2) { // если номер канала НЕ совпадет с позицией маркера tft.drawFastVLine(i + 1, 22, 128 - RSSIjnax, ILI9341_BLACK); // стираем старую линию спектра tft.drawFastVLine(i + 1, 150 - RSSIjnax, RSSIjnax, ILI9341_GREEN); // рисуем новую линию спектра // длина линии пропорциональна значению RSSI DrawMarker(); // иначе рисуем вместо линии спектра белую линию маркера // Функция рисования линии маркера и отображения частоты void DrawMarker() { tft.setCursor(FCHAN_X, FCHAN_Y); res__l = analogRead (A7); res_dif = res_l - tmp_l; if ,(abs(res_dif) > 4) { tmp_l = res_l; res_2 = res_l / 5;
146 Глава 7 if (res_2 != tmp_2) { tft.fillRect(FCHAN_X, FCHAN_Y, 110, 15, ILI9341_BLACK); f_chan = .405456 * res_2 + 2400.009949; tft.print(f_chan, 4); tft.drawFastVLine(tmp_2, 50, 100, ILI9341_BLACK); tft.drawFastVLine(res_2, 50, 100, ILI9341_WHITE); tmp_2 = res_2; // Функция инициализации регистров СС2500 void init_CC2500() { CC2500_Write(0x30, 0x3D); CC2500_Write(FSCTRLl, OxOF); CC2500_Write(PKTCTRL0, 0x12); CC2500_Write(FREQ2, 0x5C); CC2500_Write(FREQ1, 0x4E); CC2500_Write(FREQ0, OxDE); CC2500_Write(MDMCFG4, OxOD); CC2500_Write(MDMCFG3, ОхЗВ); CC2500_Write(MDMCFG2, 0x00); CC2500_Write(MDMCFGl, 0x23); CC2500_Write(MDMCFG0, OxFF); CC2500_Write(MCSMl, OxOF); CC2500_Write(MCSM0, 0x04); CC2500_Write(FOCCFG, 0x15); CC2500_Write(AGCCTRL2, 0x83); CC2500_Write(AGCCTRLl, 0x00); CC2500_Write(AGCCTRL0, 0x91); CC2500_Write(FSCAL3, OxEA) ; CC2500_Write(FSCAL2, OxOA); CC2500_Write(FSCAL1, 0x00); CC2500_Write(FSCAL0, Oxll); // Функция записи в регистр СС2500 void CC2500_Write(char CC2500_addr, char CC2500_value) { digitalWrite(SCAN_CS, LOW); while (digitalRead(MISO) = HIGH) { }; SPI.transfer(CC2500_addr); SPI.transfer(CC2500_value); digitalWrite(SCAN_CS, HIGH); // Функция чтения из регистра СС250 char CC2500_Read(char CC2500_addr) { CC2500 addr = CC2500 addr + 0x80;
Примеры программ и проектов для Arduino 747 digitalWrite(SCAN_CS, LOW); while (digitalRead(MISO) == HIGH) { }; SPI.transfer(CC2500_addr); char CC2500_reg = SPI.transfer(0); digitalWrite(SCAN_CS, HIGH); return CC2500_reg; 7.7. Миниатюрный монитор силовой литий-полимерной батареи Монитор предназначен для непрерывного контроля степени разряда силовых ли- тий-полимерных батарей, применяемых в авиамоделях, моделях роботов и прочих любительских конструкциях. Чрезмерный разряд губителен для батарей этого типа (см. разд. 2.4.3). Поэтому желательно непрерывно следить за напряжением каждой ячейки батареи в отдельности. Для летающих моделей, особенно миниатюрных, важен каждый грамм веса. Наш монитор весит всего 1,2 грамма при габаритах 10x20 мм (рис. 7.18). ВЕЕР IN GND BATS1 BATS2 ВАТ S3 10 мм 20 мм Рис. 7.18. Внешний вид монитора литий-полимерной батареи В электронных устройствах часто используют звукоизлучатели (биперы). Такой звукоизлучатель уже есть в мониторе, и его можно использовать для других нужд— например, для индикации переключения режимов устройства. Поэтому монитор оснащен специальным входом BEEPIN. При подаче на этот вход высоко- го логического уровня независимо от состояния батареи раздается непрерывный звуковой сигнал. Если внешнее управление звуком не используется, вход BEEP_IN следует соединить с выводом GND. Монитор питается непосредственно от батареи, которую контролирует, и подключается к балансирному разъему. Количество ячеек подключенной батареи (2S или 3S) определяется автоматически. Микроконтроллер ATTiny24 питается напряжением 5 вольт, поэтому монитор не может контролиро- вать одноячеечные литий-полимерные аккумуляторы с напряжением 3,7 вольта. Свободных выводов микроконтроллера достаточно для контроля батареи 4S. Для этого следует внести в программу и плату устройства небольшие изменения. Принципиальная электрическая схема устройства изображена на рис. 7.19. Файлы схемы и чертежа печатной платы в формате DipTrace вы найдете в сопровож-
00 U1 L78L05BUTR +5V D1 -Д* «optional low drop Shottki diode U2 PA0(AOC0/AR£r/PaNT0) PAXADCVAWe/PONTi) PA2(ADC2/AN1/PONT2) PA3(ADC3/T0/PONT3) < GND +5V +5V C2 | 10mF Vcc <) PA5(AD5/D0/MIS0/0C«/PaNT5) PA6(PCMTe/0C1A/SDA/M0SI/ADCe) РА7(РСИТ7/ЮР/ОСОВ/А0С7) PB0(PCINT8/XTAL1) PBXPCNT9/XTAL2) PB2(PCINT10/NTe/OCOA/CKOUT) PB3(PCWTH/ftESET/dW GND ATTiny24 Рис. 7.19. Принципиальная электрическая схема монитора батареи LS1 Q1 k BSS138
Примеры программ и проектов для Arduino 1_49_ дающем книгу электронном архиве, размещенном на сайте издательства (см. прило- жение). 7.7.1. Компоненты монитора ♦ Микроконтроллер— ATTiny24 можно заменить на модификации ATTiny44 или ATTiny84, у которых больше объем памяти программ и выше цена (уста- новка библиотеки ATTiny описана далее ъразд. 7.8). ♦ Звукоизлучатель — пассивный электромагнитный, в миниатюрном SMD-кор- пусе. Он содержит катушку, постоянный магнит и металлическую мембрану. Такие звукоизлучатели эффективно работают только на резонансной частоте около 2700 Гц. Импульсы с этой частотой вырабатывает микроконтроллер. Обратите внимание: иногда в аналогичных корпусах выпускают пьезоэлектри- ческие излучатели. Для данной схемы они не подойдут! ♦ Полевой транзистор— BSS138, BSS123 или аналогичный N-канальный со встроенным защитным диодом от выбросов обратного тока на катушке излуча- теля и открывающийся стандартным логическим уровнем TTL. Ф Стабилизатор напряжения — любой с выходным напряжением +5 вольт и ра- бочим током не менее 200 мА. Ф Светодиоды — любые подходящие по габаритам. В конструкции установлен один красный светодиод для индикации наличия питания и три синих для инди- кации состояния ячеек. 7.7.2. Алгоритм работы устройства Исходный код прошивки монитора приведен в листинге 7.8. При подаче питания устройство производит самотестирование. На короткое время включаются все све- тодиоды и раздается звуковой сигнал. По окончании проверки устройство перехо- дит в рабочий режим. Обратите внимание на важный нюанс. Для генерации звука используется внутрен- нее прерывание по состоянию аппаратного таймера TimerO. Это нужно для того, чтобы генерация звуковых импульсов не зависела от работы программы. В против- ном случае звук будет хриплый и прерывистый, а процессор вместо полезной рабо- ты будет занят генерацией импульсов. Благодаря использованию аппаратного тай- мера, генерация звуковых импульсов почти не занимает ресурсы процессора. В на- шем проекте таймер TimerO генерирует прерывания с частотой следования 2700 герц (звук), а таймер Timeri — прерывания с частотой 2 герца (проверка на- пряжения ячеек и мигание светодиодов). Но — это важно! — если встроенные таймеры задействованы для выработки пре- рываний, то мы не можем использовать программную функцию delay о, потому что она тоже основана на работе аппаратного таймера. В начале программы, когда нам нужна небольшая задержка, чтобы зажечь светодиоды и включить звук для проверки, вместо функции delay () мы используем цикл, повторяемый 30 000 раз:
150 Глава 7 for (int i = 0; i < 30000; i++) { byte t = digitalRead(BEEP_IN); } В этом цикле не происходит ничего полезного. Чтение входа beepin осуществля- ется лишь потому, что чтение входов — это одна из самых длительных операций микроконтроллера. Мы загружаем микроконтроллер бесполезной задачей пример- но на секунду, и пока он ее выполняет, светодиоды светятся, а звукоизлучатель пищит. За это время мы можем убедиться, что устройство исправно и подключено к батарее. Как генерируют импульсы при помощи таймера? По сути, встроенный таймер микроконтроллера представляет собой счетчик импуль- сов тактового генератора. В специальный регистр сравнения записывается опорное число. После каждого такта содержимое счетчика сравнивается с содержимым этого регистра. При совпадении счетчика с заданным числом генерируется внутреннее прерывание, таймер обнуляется и начинается новый отсчет. Чем меньше опорное число, тем быстрее таймер досчитает до него, и тем выше будет частота прерыва- ний. Подбирая опорное число, можно с достаточно высокой точностью генерировать прерывания заданной частоты. Далее, в процедуре обработки прерывания, выпол- няется нужное действие. Например, меняется логический уровень на выводе микро- контроллера. В главном цикле происходит проверка логического уровня на входе beepin. Если уровень высокий, принудительно устанавливается флаг разрешения подачи звуко- вых импульсов на излучатель. В противном случае флаг сбрасывается. Проверка напряжения ячеек происходит дважды в секунду по прерыванию таймера Timeri. Организация рабочего цикла при помощи аппаратного прерывания часто встреча- ется в программировании микроконтроллерных устройств. В нашем случае это по- зволяет алгоритмически разделить проверку состояния входа beepin и проверку напряжения ячеек. Вход принудительного включения звука надо проверять как можно чаще, чтобы успевать отработать короткие звуковые импульсы. Напряжение на ячейках можно проверять реже. Цикла с длительностью 0,5 секунды достаточно, чтобы успеть зафиксировать даже кратковременные просадки напряжения под на- грузкой. Кроме того, при использовании аппаратного прерывания легко реализует- ся мигание сигнальных светодиодов. Достаточно лишь по каждому прерыванию менять состояние активного светодиода на противоположное. Иными словами, стандартный метод Arduino, когда главный цикл программы организуется в виде цикла loop () — это не единственный и не всегда оптимальный подход. #include <avr/interrupt.h> #define BEEP_OUT 7 // (pin 10) выход на звукоизлучатель #define BEEP__IN 3 // (pin б) вход управления звукоизлучателем, соединить с GND если не используется
Примеры программ и проектов для Arduino 151 #define LED_1 0 // (pin 5) выход светодиода LED I tdefine LED_2 1 // (pin 3) выход светодиода LED 2 tdefine LED_3 2 // (pin 2) выход светодиода LED 3 tdefine BAT_1 АО // (pin 13) Аналоговый вход Bat 1 tdefine BAT_2 Al // (pin 12) Аналоговый вход Bat 2 tdefine BAT_3 A2 // (pin 11) Аналоговый вход Bat 3 // ВАЖНО: // здесь настраиваются уровни срабатывания для ВАШЕЙ платы (+3.65V //на каждую ячейку LiPo) tdefine BAT_LIM_1 173 tdefine BAT_LIM_2 173 tdefine BAT_LIM_3 173 int VBAT_1, VBAT_2, VBAT_3; boolean FLAG_Tone = true, FLAG_Tone_In = false, FLAG_Blink = true, FLAG_Tone__l = false, FLAG_Tone_2 = false, FLAG_Tone_3 = false; void setup () { pinMode (BAT_1, INPUT) ; pinMode(BAT_2, INPUT); pinMode(BAT_3, INPUT); pinMode(BEEP_IN, INPUT); pinMode(LED_1, OUTPUT); pinMode(LED_2, OUTPUT); pinMode(LED_3, OUTPUT); pinMode(BEEP_OUT, OUTPUT); digitalWrite(BEEP_OUT, LOW); // Аппаратный генератор звука с частотой 2700Hz при помощи прерывания TIMER0 стс TCCR0A = ВООООООЮ; TCCR0B = В00000011; TIMSK0 = ВООООООЮ; OCR0A = 22; // Включаем все светодиоды (активный уровень - низкий) digitalWrite(LED_1, LOW); digitalWrite(LED_2, LOW); digitalWrite(LED_3, LOW); // Пустой цикл для формирования задержки на время самопроверки устройства for (int i = 0; i < 30000; i++) { byte t = digitalRead(BEEP_IN);
152 Глава 7 // Гасим все светодиоды (активный уровень - низкий) digitalWrite(LED_1, HIGH); digitalWrite(LED_2, HIGH); digitalWrite(LED_3, HIGH); // Настраиваем аппаратный генератор главного прерывания с частотой 2 Гц TCCR1A = В00000000; TCCR1B = В00001101; TIMSK1 = В00000010; OCR1AH = 7; OCR1AL = 200; void loop () { if (digitalRead(BEEP_IN)) // Если на входе BEEP_IN высокий уровень { FLAG_Blink = true; // Флаг включения мигания активен FLAG_Tone_In = true; // Флаг включения звука активен } else { FLAG_Tone_In = false; // Подпрограмма обработки аппаратного прерывания по совпадению таймера TimerO ISR(TIM0_COMPA_vect) { digitalWrite(BEEP_OUT, !digitalRead(BEEP_OUT) && FLAG_Blink && (FLAG_Tone || FLAG_Tone_In)); // Подпрограмма обработки главного прерывания с частотой 2 Гц ISR(TIMl_COMPA_vect) { FLAG_Blink = IFLAGJBlink; // Читаем напряжение на аналоговых входах VBAT_1 = analogRead(BAT_l) ; VBAT_2 = analogRead(BAT_2) ; VBAT_3 = analogRead(BAT_3) ; // Вычисляем напряжение на каждой ячейке в отдельности int Bat_l = VBAT_1; int Bat_2 = VBAT_2 - VBAT_1; int Bat 3 = VBAT 3 - VBAT 2;
Примеры программ и проектов для Arduino 153 II Проверяем, не опустилось ли напряжение ниже предельного if (Bat_l <= BAT_LIM_1) { digitalWrite (LED_1, !digitalRead(LED_l) ); // Переключаем светодиод (мигание) FLAG_Tone_l = true; // Разрешаем звуковой сигнал тревоги } else // Если напряжение выше порога { digitalWrite(LED_1, LOW); // Светодиод погашен FLAG Tone 1 = false; // Звук выключен if (Bat_2 <= BAT_LIM_2) { digitalWrite(LED_2, !digitalRead(LED_2)) \ FLAG_Tone_2 = true; } else { digitalWrite (LED_2, LOW) ; FLAG Tone 2 = false; if (VBAT_3 > 10) { // Если ячейка #3 подключена (батарея 3S) if (Bat_3 <= BAT_LIM_3) digitalWrite(LED_3, !digitalRead(LED_3)); FLAG_Tone_3 = true; else digitalWrite(LED_3, LOW); FLAG Tone 3 = false; else { digitalWrite(LED_3, HIGH); // Если ячейка #3 не подключена, гасим светодиод LED3 // Если хотя бы для одной из ячеек активирован звуковой сигнал тревоги, // разрешаем подачу звуковых импульсов на излучатель FLAG_Tone = FLAG_Tone_l | | FLAG_Tone_2 | | FLAG_Tone_3;
154 Глава 7 ISR( vector_default) { // Здесь можно разместить обработку или заглушку для других прерываний, // которые не были объявлены в явном виде. // Обычно здесь обрабатывают все ошибочные прерывания. 7.8. Установка библиотеки ATTiny Компилятор Arduino IDE в стандартной поставке не поддерживает работу с микро- контроллерами ATTiny. Нам потребуется несложная доработка, которая не требует особых навыков. Достаточно лишь выполнить пошаговые инструкции. Скачайте на сайте http://www.arduino.cc архив компилятора версии 1.5.8. Более новые версии для наших целей не подойдут, т. к., начиная с версии 1.6, сменился движок компилятора, и наше расширение не будет работать с версиями 1.6jc. Реко- мендую скачать не установщик для Windows, а именно ZIP-архив, и развернуть его в отдельную папку. Это позволит вам иметь самую новую версию Arduino IDE для обычной работы и отдельную модификацию для ATTiny. Скачайте описание плат ATTiny24/44/84 по адресу: http://www.fankraft.ru/ filestore/hardware.zip или найдите его в сопровождающем книгу электронном ар- хиве, размещенном на сайте издательства (см. приложение). Запустите Arduino IDE 1.5.8, откройте меню Файл | Настройки и проверьте путь к папке скетчей. По умолчанию она находится в папке документов пользователя по адресу CAUsersW/w? пользователя\0осигг\еп\в\Аг6и\по (рис. 7.20). Вы можете задать в настройках другой путь. Сохраните его при необходимости и закройте Arduino IDE. Распакуйте архив с расширением внутри папки DocumentsWduino. У вас должна по- лучиться такая структура папок: Documents\Arduino\hardware, где hardware — это папка из ранее скачанного архива, содержащая расширение для ATTiny. Вновь запустите Arduino IDE 1.5.8 и откройте меню Инструменты | Плата. В спи- ске доступных плат должны появиться микроконтроллеры ATTiny, как показано на рис. 7.21. Если этого не произошло, внимательно проверьте правильность пути, по которому размещена папка hardware. Теперь вы можете компилировать и запи- сывать программы для ATTiny в привычной среде Arduino IDE. 7.8.1. Подключение программатора Прошивка через последовательный порт и конвертер USB-UART для контроллеров ATTiny24/44/84 в нашем случае не поддерживается, поскольку пришлось бы записать специальный бутлоадер, который займет значительную часть и без того скудной памяти контроллера. Поэтому мы будем использовать только программи- рование через порт SPI. Для этого нам потребуется недорогой популярный про- грамматор USBAsp или Arduino ISP. На наш взгляд, удобнее всего приобрести и всегда иметь под рукой USBAsp или прошить одну из стандартных плат Arduino
Примеры программ и проектов для Arduino 155 5gi Настройки Язык редактора:1 Систем по уисгманию Размер шрифта: 12 -(нужен перезапуск Агалпо) Показать подробный выша: [ \ Компиляция ' _ j Бгрузигг 1 | Dtsptav iine numbers 0 Проверить t^.00 "OC!¥i ВГРУЗ^-И ( ~] Использовать внешний релзктор [л/| Проверить 0бнСБЯеН41Й при Sanyoх: Г%/| Конвертировать фдн*.1» эскизов б гюеып фориат Г,обе Г ; Аетоматичесн.и ёссошчрое^ь файш ,?по с Дгс^шо С; 'ilsers\valer'vAppOsta^Reami^CiV^s'^u'fio 15preferences, rvr Рис. 7.20. Проверка пути к папке скетчей Arduino IDE по умолчанию Рис. 7.21. Проверка доступности установленных описаний плат
156 Глава 7 (например, Arduino Nano) специальной прошивкой, которая превратит ее в про- грамматор Arduino as ISP. Для подключения программатора USBAsp к выводам микроконтроллера можно использовать специальную зажимную панель или аккуратно припаять тонкие про- вода непосредственно к выводам микросхемы. Но удобнее всего временно припа- ять провода к дорожкам платы уже собранного устройства, т. к. вам придется запи- сывать прошивку несколько раз подряд, когда вы станете подбирать опытным путем калибровочные константы для каждого из каналов ВАТ1...ВАТЗ. Для программирования задействованы только шесть выводов микроконтроллера: ♦ (1) — УСС+5вольт; ♦ (4) —RESET; ♦ (7) — MOSI; ♦ (8) —MISO; ♦ (9) —SCK; ♦ (14) —GND. Соедините эти выводы с одноименными выводами разъема программатора. Схема специально разработана таким образом, чтобы ее компоненты не мешали процессу внутрисхемного программирования. Будьте особенно внимательны при подключе- нии выводов питания! В отличие от множества других цифровых микросхем, у ATTiny24/44/84 вывод 14 предназначен для подключения общего провода (GND). Выберите соответствующий программатор в меню Инструменты | Программатор. 7.8.2. Установка фюзов микроконтроллера Важные аппаратные настройки микроконтроллера, такие как параметры тактирова- ния: тактовая частота и источник тактовых импульсов — устанавливаются при по- мощи битов специального служебного регистра. Эти биты называют фюзами (от mrn.fuse — перемычка, предохранитель). Биты тактирования очень важны. Будьте предельно внимательны! Если вы выберете вариант платы микроконтроллера с внешним источником тактовых импульсов, то микроконтроллер не будет рабо- тать, пока вы не подключите внешний тактовый генератор или кварцевый резо- натор. Чтобы выставить режим внутреннего тактирования контроллера, выберите в списке плат опцию internal 8MHz clock (рис. 7.21), подключите контроллер к программа- тору и выберите пункт меню Инструменты | Записать бутлоадер. При этом ника- кой бутлоадер записан не будет, но будут выставлены нужные фюзы. При использовании программатора USBAsp со старой версией прошивки компиля- тор может выдавать предупреждения о том, что не может изменить частоту такти- рования на линии SCK, либо о том, что описание плат не является полным. Эти предупреждения никак не влияют на процесс компиляции программы и записи прошивки.
Примеры программ и проектов для Arduino 157_ Еще один нюанс связан с фюзом защиты содержимого EEPROM. По умолчанию, с завода, фюз защиты EEPROM сброшен, и при стирании памяти программ перед записью новой прошивки содержимое EEPROM также затирается байтами FF. Но в нашей версии настроек фюз защиты установлен, и содержимое EEPROM сохра- няется после записи новой прошивки. Это нужно для того, чтобы при разработке ваших собственных версий прошивки в EEPROM могли сохраняться ваши калиб- ровочные константы, коды доступа и прочие уникальные данные, и вам не прихо- дилось бы каждый раз проводить их восстановление при отладке и перезаписи прошивки. 7.8.3. Запись прошивки Перед первой записью прошивки в новый микроконтроллер достаточно один раз выполнить процедуру фиктивной записи бутлоадера для того, чтобы установить нужные фюзы. После этого микроконтроллер ATTiny подготовлен к записи про- шивки. В дальнейшем запись фюзов следует выполнять, только если вы их измени- ли. Компиляция и запись происходят как обычно, по нажатию кнопки со стрелкой в среде Arduino IDE. 7.8.4. Калибровка порога срабатывания Во входных делителях датчика используются резисторы с погрешностью 5... 10%. Соответственно, такой же будет погрешность измерения напряжений на секциях батареи у некалиброванного датчика. Кроме того, в качестве опорного напряжения используется напряжение питания Vcc, которое тоже может слегка различаться между экземплярами. Для калибровки вам потребуется регулируемый источник напряжения и вольтметр. От точности этого вольтметра непосредственно зависит качество калибровки. Установите на выходе регулируемого источника напряжение 3,65 В. Соедините перемычкой вход BEEPIN и вывод GND, чтобы отключить внешний вход управ- ления звуком. Подключите датчик к программатору, запустите Arduino IDE с уста- новленным расширением плат ATTiny и откройте скетч с прошивкой датчика. Обратите внимание на три калибровочные константы в коде прошивки: #define BAT_LIM_1 173 #define BAT_LIM_2 173 #define BAT_LIM_3 173 Эти константы мы будем подбирать в процессе калибровки. Подключите общий провод источника образцового напряжения к выводу GND дат- чика, а образцовое напряжение подайте на вход ВАТ1. Если светодиод LED1 горит постоянно, начинайте постепенно увеличивать значение константы BATLIM1 с шагом 1-2 единицы, каждый раз перезаписывая прошивку в кон- троллер, пока светодиод не начнет изредка мигать. И наоборот, если светодиод LED_1 постоянно мигает, уменьшайте значение константы. Редкое мигание означа-
158 Глава 7 ет, что датчик находится на границе срабатывания при входном напряжении 3,65 вольт, а светодиод слегка мигает из-за погрешностей срабатывания АЦП и незначительных флуктуации напряжения. По окончании калибровки датчик начнет подавать периодический сигнал при напряжении 3,65 вольт и будет гарантированно срабатывать при напряжении 3,60 вольт. Для калибровки порога срабатывания второй ячейки соедините вход ВАТ1 с об- щим проводом (GND), а образцовое напряжение подайте на вход ВАТ_2. Повтори- те процедуру калибровки, как только что описано, наблюдая за светодиодом LED_2. Для калибровки порога срабатывания третьей ячейки соедините входы ВАТ1 и ВАТ2 с общим проводом (GND), а образцовое напряжение подайте на вход ВАТ_3. Повторите описанную ранее процедуру калибровки, наблюдая за светодио- дом LED_3. Обычно с указанными на схеме номиналами резисторов по окончании калибровки значения констант варьируются в диапазоне 170...175. Соблюдайте порядок калибровки! Не забывайте, что ячейки батареи соединены последовательно. Монитор измеряет напряжение ВАТ1 относительно общего провода, напряжение ВАТ2 вычисляется как разница между напряжением ВАТ1 и напряжением, измеренным на втором входе относительно общего провода. Ана- логично, напряжение ВАТЗ вычисляется как разница между напряжениями на втором и третьем входах относительно общего провода. Поэтому необходимо соблюдать порядок калибровки от меньшего входа к большему.
ГЛАВА 8 Однокристальная система ESP8266 Однокристальная система или система на кристалле (SoC, System-on-Chip) — это микросхема, объединяющая на одном кристалле несколько модулей с принципи- ально различными функциями и выполняющая задачи целого устройства. Как пра- вило, такая система содержит микропроцессорное ядро, встроенную память, внут- ренние шины данных и специфические функциональные модули. Это может быть цифровой сигнальный процессор, управляемый функциональный генератор, радио- передающий модуль и т. д. Граница между современными микроконтроллерами и SoC весьма размыта, поскольку большинство микроконтроллеров оснащено встро- енной памятью, АЦП, ЦАП, ШИМ и прочими функциональными компонентами. Микросхема ESP8266, о которой мы расскажем в этой главе, является ярким при- мером SoC, потому что состоит из микропроцессора и функционального модуля Wi-Fi, выполненных на одном кристалле. Таким образом, на одной этой микросхе- ме можно сделать законченное устройство, подключаемое к беспроводной сети Ин- тернет. 8.1. Ученик обогнал учителя: феномен успеха ESP8266 Сегодня можно утверждать, что успех микросхемы ESP8266 превзошел самые сме- лые ожидания компании Espressif. Изначально SoC ESP8266 разрабатывалась как микросхема для модулей Wi-Fi, подключаемых к другим микроконтроллерам. Предполагалось, что ESP8266 будет работать под управлением специальной про- шивки, взаимодействовать с внешним микроконтроллером при помощи последова- тельного порта UART и получать обычные текстовые АТ-команды, как это делают GSM-модемы или модули Bluetooth. Например, ожидалось, что на основе этой микросхемы будут изготавливать шилды Wi-Fi для плат Arduino. На практике же оказалось, что возможности встроенного процессора настолько велики, что в большинстве случаев позволяют обойтись вообще без внешнего мик- роконтроллера. Радужную картину довершают чрезвычайно низкая цена ESP8266
160 Глава 8 и возможность разработки программ в привычной среде Arduino IDE. Кроме этого, можно писать для нее программы на языках Lua, MicroPython и Smart-JS и даже запускать их в среде простой операционной системы! Образовались многочислен- ные сообщества энтузиастов и профессиональных разработчиков, использующих ESP8266, серийно выпускаются сотни разновидностей модулей и устройств. За ру- бежом изданы десятки книг про ESP8266 и Интернет вещей. Поэтому мы рассмат- риваем ESP8266 как основу независимой платформы для технического творчества и обучения. Прежде, чем приступить к изучению платформ и проектов на базе SoC ESP8266, рассмотрим ее основные технические характеристики и особенности эксплуатации. 8.1.1. Технические характеристики ♦ Процессор: одноядерный Tensilica L106 с тактовой частотой до 160 МГц. ♦ Поддерживаемые стандарты Wi-Fi 802.11: b/g/n/d/e/i/k/r. ♦ Поддерживаемые типы шифрования: WEP, WPA, WPA2. ♦ Поддерживаемые режимы работы: Клиент (STA), Точка доступа (АР), Кли- ент+Точка доступа (STA+AP). ♦ Количество одновременных соединений TCP: 5. ♦ Напряжение питания: 1,7...3,6 В. ♦ Потребляемый ток: до 215 мА в зависимости от режима работы. ♦ Количество GPIO: 17 (количество доступных зависит от модификации моду- ля). ♦ Интерфейсы: ADC 10 битов, I2C. UART, SPI, PWM. ♦ Внешняя Flash-память: от 512 Кбайт до 16 Мбайт. ♦ Объем памяти данных (EEPROM): 80 Кбайт. ♦ Объем памяти команд (RAM): 64 Кбайт. 8.1.2. Особенности эксплуатации При разработке устройств на основе ESP8266, особенно при переносе готовых про- ектов с платформы Arduino, необходимо учитывать некоторые специфические осо- бенности микросхемы. ♦ Максимальная нагрузка на порт. Платы Arduino допускают нагрузку на порт до 40 мА, что позволяет, не задумываясь, подключать малогабаритные сверхъ- яркие светодиоды и прочую подобную нагрузку. Однако порты ESP8266 выдерживают ток не более 14 мА, поэтому их можно перегрузить далее обыч- ным светодиодом. Посему следует тщательно рассчитывать нагрузку и при- менять ключевые транзисторы. ♦ Согласование логических уровней. Согласно спецификации производителя, только линии UART (Tx, Rx) допускают работу с напряжениями пятивольтовой
Однокристальная система ESP8266 161 логики. Подача на остальные выводы логических уровней, превышающих на- пряжение питания микросхемы, с большой вероятностью выведет ее из строя. При совместном использовании модулей с разным напряжением питания необ- ходимо применять согласование логических уровней (см. разд. 2.5). Режим программирования. Для перевода микросхемы в режим записи про- шивки необходимо установить низкий уровень на входе GPIO0 и кратковремен- но подать низкий уровень на вход сброса RESET (либо держать вывод GPIO0 соединенным с общим проводом в момент включения питания). Микросхема перейдет в режим программирования и коротко мигнет встроенным светодио- дом, подключенным к выводу GPIO2. После этого можно вернуть высокий уро- вень на вход GPIO0. Для автоматического перехода в режим программирования по сигналам DTR, RTS от конвертера USB-UART применяется несложная схема из двух транзисторов (рис. 8.1). RESETс Q1 2N3904 R1 15 кОм ESP8266 DTR 02 2N3904 R2 GPIO0 USB-UART 15 кОм »RTS Рис. 8.1. Схема автоматического переключения в режим программирования ♦ Температурный режим. В режиме максимальной мощности потребляемый ток иногда достигает 240 мА, и корпус микросхемы в условиях недостаточного от- ведения тепла может нагреваться до 80 °С. Несмотря на то, что микросхема спо- собна работать при температуре до +125 °С, перегрев модуля может привести к росту погрешности синтезатора частоты трансмиттера Wi-Fi, а циклические тепловые перегрузки ускоряют выход модуля из строя из-за нарушения пайки. ♦ Требования к монтажу. Микросхема чувствительна к наводкам сигнала на ли- нии портов от собственной антенны Wi-Fi. Длинные соединительные проводни- ки между платой на основе ESP8266 и внешними устройствами могут привести к нестабильной работе, что будет выражаться в зависании и самопроизвольной перезагрузке микросхемы. 8.1.3. Модули на основе ESP8266 В продаже доступно множество разнообразных модулей Wi-Fi на основе ESP8266 и их клонов, как под маркой ESP-xx (рис. 8.2), так и под иными торговыми марками. В большинстве случаев, особенно в домашних условиях, нет никакого смысла при- обретать отдельную микросхему для изготовления собственного модуля.
162 Глава 8 Любой модуль ESP-xjc обязательно содержит SoC ESP8266, кварцевый резонатор, микросхему внешней памяти и несколько конденсаторов и резисторов. Кроме это- го, на плате может присутствовать антенна Wi-Fi или разъем для ее подключения, индикаторный светодиод и контактные площадки или место для установки разъ- ема. Выбирая модуль для своего проекта, надо внимательно изучить его характери- стики, особенно разводку выводов GPIO. Например, у модуля ESP-05 к разъему не разведен вывод GPIO0, что значительно затрудняет запись собственной прошив- ки, — ведь для перехода в режим программирования необходимо соединять GPIO0 с общим проводом в момент сброса. Другими важными факторами являются нали- чие встроенной антенны и объем внешней памяти. В микросхеме внешней памяти мы будем хранить, например, программы на языке Lua при работе с платформой NodeMCU. ESP-01 ESP-02 ESP-03 ESP-04 ESP-05 ESP-10 ESP-08 ESP-11 ESP-12 ESP-13 - ESP-14 Рис. 8.2. Модули серии ESP-xx Модули серии ESP-jcjc удобны при изготовлении законченной конструкции или прототипа. Но для хобби и образовательных целей желательно приобрести ком- плектную отладочную плату, которая, кроме модуля ESP, содержит встроенный источник питания 3,3 В, конвертер USB-UART со схемой сброса и перехода в ре- жим программирования и максимальное количество линий GPIO, выведенных на внешние контакты. Некоторые наиболее популярные отладочные платы изображе- ны на рис. 8.3. Несмотря на разную конструкцию и торговые марки, все они прак- тически полностью идентичны с функциональной точки зрения. В главе 10 мы под- робно рассмотрим программно-аппаратную платформу NodeMCU, для которой разработана специальная плата. Но с таким же успехом для работы с NodeMCU вы можете применить платы WeMos, Robotdyn и многие другие.
Однокристальная система ESP8266 163 WeMos D1 Mini Рис. 8.3. Примеры плат для отладки и разработки на основе ESP8266 8.2. Расширение Arduino IDE для работы с ESP8266 Благодаря открытой спецификации среды Arduino IDE, к ней можно подключить описания процессоров и плат сторонних производителей. Это обеспечивает нам комфортный переход к работе с новой аппаратной базой. Если говорить о ESP8266, то в простых программах вы почти не заметите разницу между кодом для ориги- нальных плат Arduino и кодом для плат на основе ESP8266. 8.2.1. Установка расширения Откройте в среде Arduino IDE пункт меню Файл | Настройки и вставьте в поле Дополнительные ссылки для Менеджера плат (см. рис. 5.11) строку ссылки: http://arduino.esp8266.com/staging/packageesp8266comindex.json. Если в поле для дополнительных ссылок уже есть запись, отделите ее запятой. Теперь перейдите в меню Инструменты | Плата | Менеджер плат и дождитесь, пока Менеджер плат соединится с ресурсами по указанной ссылке и обновит спи- сок плат. Затем найдите в списке плату esp8266 by ESP8266 Community (обычно в конце списка) и нажмите кнопку Установка. Теперь вы можете работать с платой на основе ESP8266 точно так же, как с любой платой Arduino. Обратите внимание, что в меню Файл | Примеры появился раздел с примерами для ESP8266. Кроме этого, установлена специальная библиотека ESP8266WiFi для поддержки функций беспроводного соединения. 8.2.2. Особенности программирования ESP8266 Простые программы, наподобие управления портами GPIO, будут работать точно так же, как на оборудовании Arduino. Но если вы не будете учитывать аппаратные особенности ESP8266 при разработке более сложных программ, то обязательно на- ткнетесь на «подводные камни», которые могут доставить много проблем. Нельзя забывать, что в SoC ESP8266, кроме процессорной части, имеется модуль Wi-Fi,
164 Глава 8 который живет своей жизнью, занимает ресурсы процессора и требует отдельного внимания. Расширение среды Arduino IDE, которое вы установили, представляет собой обертку (wrapper) для набора официальных функций API SDK, предоставляемых производителем микросхемы. Когда в вашей программе совершается любое дейст- вие — например, запись логического уровня в порт ввода/вывода, на самом деле компилятор не генерирует собственный оригинальный код, а обращается к готовой функции API SDK и передает ей нужные параметры. Одна простая команда скетча может скрывать за собой последовательное обращение к нескольким сложным функциям API SDK. На самом деле, прямая работа с функциями API SDK предос- тавляет больше возможностей для программиста, но трудна и требует наличия опыта и знаний. Заслуга разработчиков расширения для Arduino IDE состоит в том, что они проделали за нас всю самую сложную работу, переведя обращения к API SDK на простой и понятный язык Wiring. Порты и прерывания Формально вы можете обратиться в программе к любому из портов GPIO0- GPIO16, но для свободного пользования доступны не все порты, т. к. часть выводов занята для служебных нужд. Количество линий портов, выведенных на внешние контакты платы, зависит от конструкции модуля, но некоторые порты заняты все- гда, либо их не рекомендуется использовать. В частности, порты GPIO1 и GPIO3 заняты под линии порта UART Тх и Rx. По этим линиям производится запись про- шивки, а также обмен последовательными данными с внешними устройствами. К выводу GPIO2 по умолчанию подключен встроенный светодиод большинства модулей. Однако в модуле ESP-01 светодиод подключен к порту GPIO1, поэтому невозможно одновременно управлять встроенным светодиодом и использовать по- следовательный порт. Порт GPIO0 служит для управления режимом программиро- вания. Порт GPIO15 определяет режим загрузки с карты памяти SD и по умолча- нию в большинстве случаев соединен на плате с общим проводом. Порт GPIO16 (часто обозначаемый как DEEPSLEEP) используется для вывода микросхемы из режима пониженного энергопотребления. В этом случае он должен быть соединен с выводом RESET микросхемы. Во многих модулях это соединение выполнено на печатной плате. Поэтому крайне нежелательно использовать GPIO16 для своих це- лей. Таким образом, не рекомендуется задействовать порты GPIOO, GPIO1, GPIO2, GPIO3, GPIO15 и GPIO16 для каких-либо иных целей, кроме назначенных по умол- чанию. Прерывания поддерживаются функциями attachinterrupt и detachinterrupt и мо- гут быть назначены на любой GPIO, кроме GPIO16. Функции задержки Функции delay о и deiayMicroseconds () работают аналогично Arduino, при этом работа модуля Wi-Fi и стека TCP/IP не прерывается. Поэтому функцию delay о иногда используют для того, чтобы приостановить выполнение скетча и дать воз-
Однокристальная система ESP8266 165_ можность отработать модулю Wi-Fi. Функции Wi-Fi и TCP/IP SDK обрабатывают события только в конце каждого цикла loop о вашего скетча, либо во время за- держки delay (). Если внутри цикла loop () есть фрагменты, которые выполняются дольше 50 миллисекунд, необходимо использовать функцию delay (***), чтобы со- хранить работоспособность стека Wi-Fi. Функция deiayMicroseconds () блокирует выполнение других задач, включая Wi-Fi, поэтому не рекомендуется использовать ее для организации задержек более 20 миллисекунд. Работа с EEPROM В отличие от Arduino, перед каждым обращением к EEPROM необходимо вызвать функцию eeprom.begin (size), где size— это размер данных в байтах в диапазоне от 4 до 4096 байтов. Функция eeprom. write о не записывает данные в память не- медленно! Для завершения записи следом за ней надо использовать функцию eeprom.commit (). Функция eeprom.end () также завершает запись в EEPROM, но при этом очищает оперативную память от данных, запись которых завершена. Поддержка интерфейсов 12С и SPI Для интерфейса 12С (библиотека Wire) реализован только режим ведущего с часто- той до 450 кГц. Для всех модулей, кроме ESP-01, по умолчанию используются вы- воды 4 (SDA) и 5 (SCL). Выводы могут быть переназначены при помощи функции Wire.pins (int sda, int scl). Например: Wire.pins (3, 7). Библиотека SPI поддерживается почти полностью, за исключением полярности тактовых импульсов Clock Polarity (CPOL). Поэтому режимы SPI_MODE2 и SPIMODE3 не работают. Но практически во всех любительских проектах они не требуются. Специальные функции API ESP8266 В объекте esp реализованы специфичные функции глубокого сна и сторожевого таймера. Функция esp.deepsieep(microseconds, mode) переводит микросхему в ре- жим глубокого сна с минимальным энергопотреблением. Параметр mode может принимать значения wakejdefault, wake_rfcal, wake_no_rfcal, wake_rf_disabled. Для вывода из режима сна порт GPIO16 должен быть соединен с выводом RESET. Сторожевым таймером управляют функции ESP.wdtEnabieO — разрешить работу таймера, ESP.wdtDisabieO — запретить работу таймера, ESP.wdtFeedo — сбросить счетчик сторожевого таймера. В виде методов объекта esp также реализованы следующие функции: ♦ esp . reset () — перезагрузка модуля; ♦ esp . getFreeHeap — возвращает размер свободной памяти; ♦ ESP.getchipidO—возвращает уникальный ГО микросхемы ESP8266, int 32bit; ♦ ESP.getFiashChipidO — возвращает уникальный ID микросхемы флеш-памяти, int 32bit;
166 Глава 8 ♦ ESP.getFiashChipSizeO — возвращает размер флеш-памяти в байтах, как его определяет функция SDK (может быть меньше реального); ♦ esp . getnashchipspeed (void) — возвращает частоту флеш-памяти, в герцах (Гц); ♦ ESP.getCycieCounto — возвращает количество циклов CPU с момента старта, unsigned 32-bit, применяется для точного измерения очень коротких интерва- лов между событиями. Специальные функции библиотеки ESP8266WiFi Функции библиотеки ESP8266WiFi очень схожи с функциями стандартной библио- теки Wi-Fi Arduino, за исключением некоторых отличий: ♦ wiFi.mode(m)— задать режим работы, где параметр m принимает значения wifiap (точка доступа), wifista (клиент), или wifiapsta (оба режима одно- временно); ♦ wiFi. sof tAP (ssid) — создать открытую точку доступа с именем ssid; ♦ wiFi. sof tAP (ssid, password) — создает точку доступа с WPA2-PSK шифровани- ем и именем ssid, пароль password должен быть не менее 8 символов; ♦ wiFi.macAddress (mac) — получить МАС-адрес в режиме клиента; ♦ wiFi. softAPmacAddress (mac) — получить МАС-адрес в режиме точки доступа; ♦ wiFi. locaiip () — получить IP-адрес в режиме клиента; ♦ wiFi. sof tAPiP () — получить IP-адрес в режиме точки доступа; ♦ wiFi. rssi () — измерить уровень полезного сигнала на входе приемника Wi-Fi; ♦ WiFi. printDiag (Serial) — ВЫВвСТИ Диагностическую Информацию. Существуют некоторые отличия от библиотеки Wi-Fi Arduino в приеме и пере- даче пакетов multicast в режиме клиента, класс wiFiUDP. Для передачи пакета multicast вместо udp.beginPacket(addr, port) используйте функцию udp.beginPacketMulticast (addr, port, WiFi. locallP () ). Для приема пакетов multicast вместо udp.begin (port) ИСПОЛЬЗуЙте функцию udp.beginMulticast(WiFi.localIP()/ multicastipaddr, port). Чтобы удостовериться, что пакет multicast был адресован именно вам (на ваш адрес IP), используйте функцию udp.destinations (). Функции широкополосного вещания multicast не поддерживаются в режиме точки доступа. Обращение к функциям SDK ESP8266 из скетча Arduino Функций SDK очень много и не все реализованы (обернуты) средствами Arduino IDE. Для прямого обращения к функциям необходимо подключить к скетчу биб- лиотеки SDK на языке С. Для этого в начале скетча, там, где вы подключаете сто- ронние библиотеки и объявляете переменные, добавьте такой фрагмент кода: #ifdef ESP8266 extern "С" { #include "ets_sys.h"
Однокристальная система ESP8266 167 #include "os_type.h" tinclude "osapi.h" #include "inem.h" #include "user_interface.h" #include "cont.h" } #endif В этом коде компилятор проверяет заявленный тип процессора. Если это действи- тельно ESP8266, то к скетчу подключаются библиотеки, содержащие множество функций. Теперь вы можете обратиться к нужной функции напрямую. В качестве примера покажем, как регулировать выходную мощность передатчика Wi-Fi мик- росхемы: #ifdef ESP8266 system_phy_set_max_tpw (85); #endif В этом фрагменте кода мы обратились к системной функции system_phy_set__ maxtpwo. Она принимает числовые значения в диапазоне от 0 до 85, что соответ- ствует диапазону мощности от 0 до 0,25 дБм. Перечень функций SDK и их пара- метров очень обширен и далеко выходит за рамки этой книги. Основные функции SDK реализованы в расширении для Arduino IDE. Если вам потребовались специ- фические функции, значит, вы доросли до уровня, когда необходимо обратиться к фирменной документации на SDK и микросхему по адресу: http://espressif.com/ en/support/download/documents.
ГЛАВА 9 Примеры программ и проектов для ESP8266 В этой главе мы рассмотрим несколько примеров, которые наглядно демонстриру- ют простоту и удобство использования среды Arduino IDE для программирования SoC ESP8266 в несложных проектах. 9.1. Получение точного времени от сервера NTP NTP (Network Time Protocol, протокол синхронизации сетевого времени)— это один из протоколов, предназначенных для синхронизации внутренних часов уст- ройства с эталонным временем специального сервера через сеть Интернет или ло- кальную сеть. Сервер, получающий точное время непосредственно от атомного эталона времени, называется сервером первого стратума. Следующие за ним сер- веры называются серверами второго стратума и т. д. В организациях, где требу- ется постоянная точная синхронизация оборудования, могут быть установлены собственные серверы NTP, подключенные к локальной сети для уменьшения за- держек. В Интернете доступно множество открытых бесплатных серверов NTP, точности которых вполне достаточно для бытовых целей. Зачем нужна синхронизация времени в любительских и бытовых устройствах? Ра- зумеется, нам не требуется знать время с точностью до миллисекунд для домашней метеостанции или управления обогревом парника. Казалось бы, достаточно исполь- зовать недорогой миниатюрный модуль часов реального времени с резервным ис- точником питания. Увы, такое устройство не всегда выполняет свою задачу. На- пример, литиевая батарейка резервного источника питания часов перестает нор- мально работать при охлаждении до 10-12 градусов ниже нуля. Кроме того, она теряет заряд в результате естественного процесса саморазряда. Это означает, что вы должны предусмотреть в конструкции корпуса доступ к резервному источнику и можете внезапно оказаться в ситуации, когда встроенные часы потеряли настрой- ку. Кроме того, недорогим встроенным часам присуща довольно высокая погреш- ность хода при перепадах окружающей температуры. В основном это связано
Примеры программ и проектов для ESP8266 169_ с применением кварцевых резонаторов низкого качества. Желательно корректиро- вать встроенные часы хотя бы один раз в два-три месяца. С другой стороны, существует множество устройств, которые функционируют только при наличии подключения к сети Интернет. В таком случае встроенные ча- сы вообще не нужны. Ведь мы всегда можем получить значение точного времени от сервера NTP. Даже при наличии встроенных часов намного удобнее автоматиче- ски корректировать их через Интернет, а не использовать кнопки и индикатор для ручной настройки. Мы уже рассмотрели проект, в котором скетч Arduino получал значение системного времени Linux (см. разд. 7.1). Но ОС Linux, под управлением которой работает Dragino Yun, все равно получает точное время от сервера NTP. Сейчас мы научимся получать значение точного времени непосредственно от сер- вера. Исходный код примера приведен в листинге 9.1. Он базируется на стандартном примере для Arduino Yui, адаптированном для использования в SoC ESP8266. include <TimeLib.h> tinclude <ESP8266WiFi.h> ♦include <WiFiUdp.h> const char ssid[] = "YOURJSSID"; // SSID (имя) вашей точки доступа const char pass[] = "YOURJPASSWORD"; // пароль точки доступа // Публичные серверы NTP // Иногда некоторые серверы бывают недоступны, //в таком случае попробуйте раскомментировать другую строку //static const char ntpServerName[] = "time.nist.gov"; //static const char ntpServerName[] = "ua.pool.ntp.org"; static const char ntpServerName[] = "ru.pool.ntp.org"; //static const char ntpServerName[] = "time-a.timefreq.bldrdoc.gov"; //static const char ntpServerName[] = "time-b.timefreq.bldrdoc.gov"; //static const char ntpServerName[] = "time-c.timefreq.bldrdoc.gov"; // Ваш локальный часовой пояс относительно Гринвича // Информация на сайте http://www.epochconverter.com/timezones //const int timeZone =1; // Central European Time const int timeZone =7; // Krasnoyarsk Time // Создаем класс UDP WiFiUDP Udp; unsigned int localPort = 8888; // локальный порт для приема UDP-пакетов // Вызываем функцию запроса времени от NTP и присваиваем // значение текущего времени системной переменной time_t time_t getNtpTime () ;
170 Глава 9 /I Отображаем текущее время и дату void digitalClockDisplay(); void printDigits(int digits); void sendNTPpacket(IPAddress Saddress); void setup() { pinMode(2, OUTPUT); // Вывод GPIO2 настроен, как выход pinMode(2, HIGH); // Гасим светодиод (управление инверсное) Serial.begin(9600); Serial.print("Connecting to "); Serial.println(ssid); WiFi.begin(ssid, pass); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.printC1.") ; Serial.print("\nIP number assigned by DHCP is "); Serial.println(WiFi.locallP()) ; Serial.println("Starting UDP"); Udp.begin(localPort); Serial.print("Local port: "); Serial.println(Udp.localPort() ) ; Serial.println("waiting for sync"); setSyncProvider(getNtpTime); setSyndnterval (300) ; time_t prevDisplay =0; // когда время было отображено void loop () { if (timeStatusO != timeNotSet) { if (now() != prevDisplay) { // обновить, если время изменилось prevDisplay = now(); digitalClockDisplay(); void digitalClockDisplay() { // отобразить значение времени Serial.print(hour()); printDigits(minute());
Примеры программ и проектов для ESP8266 171 printDigits(second()); Serial.print(" "); Serial.print(day()); Serial.print (If.") ; Serial.print(month()); Serial.print("."); Serial.print(year()); Serial.println(); void printDigits(int digits) { // добавление разделителя ":" и ведущего нуля для лучшей читаемости Serial.print(":"); if (digits < 10) Serial.print('0'); Serial.print(digits); /* NTp Code */ const int NTP_PACKET_SIZE = 48; // Время NTP в первых 48 байтах byte packetBuffer[NTP_PACKET_SIZE]; // Буфер для пакетов UDP time_t getNtpTime() { IPAddress ntpServerIP; // Объявляем IP-адрес сервера NTP while (Udp.parsePacket() > 0) ; // Ждем, пока кончится ранее полученный пакет Serial.println("Transmit NTP Request"); WiFi.hostByName(ntpServerName, ntpServerIP); Serial.print(ntpServerName); Serial.print(": "); Serial.println(ntpServerIP); sendNTPpacket(ntpServerIP); uint32_t beginWait = millis (); while (millis() - beginWait < 1500) { int size = Udp.parsePacket(); if (size >= NTP_PACKET_SIZE) { Serial.println("Receive NTP Response"); digitalWrite(2, LOW); // Включаем светодиод модуля Udp.read(packetBuffer, NTP_PACKET_SIZE); // Читаем пакет в буфер unsigned long secsSincel900; // Время хранится в четырех байтах, начиная с позиции 40 // Преобразуем эти четыре байта в длинное целое // Получим количество секунд, начиная с 1 января 1900 года secsSincel900 = (unsigned long)packetBuffer[40] « 24;
172 Глава 9 secsSincel900 |= (unsigned long)packetBuffer[41] « 16; secsSincel900 |= (unsigned long)packetBuffer[42] « 8; secsSincel900 |= (unsigned long)packetBuffer[43]; // Время UNIX начинается с 1 января 1970 года // Для корректировки вычитаем 2208988800 секунд //и добавляем коррекцию часового пояса в секундах return secsSincel900 - 2208988800UL + timeZone * SECS_PER_HOUR; Serial.println("No NTP Response :-("); digitalWrite(2, HIGH); // Светодиод выключен return 0; // Возвращаем 0, если нет ответа от сервера // Посылаем NTP-запрос по заданному IP-адресу void sendNTPpacket(IPAddress Saddress) { // Сбрасываем все байты буфера в 0 memset(packetBuffer, 0, NTP_PACKET_SIZE); // Настраиваем байты в пакете запроса в соответствии со стандартом packetBuf fer[0] = 0Ы1100011; packetBuffer[l] = 0; packetBuffer[2] = 6; packetBuffer[3] = OxEC; //8 байт нулевых значений packetBuffer[12] = 49; packetBuffer[13] = 0x4E; packetBuffer[14] =49; packetBuffer[15] = 52; // Все поля NTP-запроса подготовлены // Теперь можно посылать запрос Udp.beginPacket(address, 123); // NTP-запрос на порт 123 Udp.write(packetBuffer, NTP_PACKET_SIZE); Udp.endPacketO ; Скачайте последнюю версию библиотеки TimeLib по адресу: https://github.com/ PaulStoffregen/Time и установите в Arduino ШЕ при помощи менеджера библио- тек. Это мощная библиотека, которая поддерживает множество функций для рабо- ты с временем. В скетче настройте имя и пароль домашней точки доступа. Задайте свою часовую зону. Уточнить значение часовой зоны своей местности относительно Гринвича можно по адресу: http://www.epochconverter.com/timezones. Обращение к серверу NTP происходит в функции getNtpTime (). Для этого мы по- сылаем серверу пакет UDP со специально сформированным запросом. Значение времени содержится в первых 48 байтах ответного пакета. Если сервер прислал
Примеры программ и проектов для ESP8266 173 корректный ответ, зажигается встроенный светодиод платы. Значение времени сер- вера представлено в виде количества секунд, прошедших с 1 января 1900 года. Библиотека TimeLib работает с эпохой UNIX — количеством секунд, прошедших с 1 января 1970 года. Чтобы учесть эту разницу в 70 лет вычитаем из количества секунд сервера число 2208988800. Это и есть 70 лет, выраженные в секундах. Теперь нам достаточно вызвать одну из функций библиотеки TimeLib, чтобы полу- чить значение секунд, минут, часов и даты. В нашем примере значение времени и даты выводится в терминал последовательного порта. Вы можете организовать отображение на индикаторе или обращение к процедуре корректировки встроенных часов. Обратите внимание на строки скетча: setSyncProvider(getNtpTime); setSyndnterval (300) ; Здесь мы задаем провайдера синхронизации времени и интервал обращения к про- вайдеру. Провайдером в нашем случае является функция скетча getNtpTime (), а об- ращение к провайдеру происходит каждые 300 секунд. Это сделано только для де- монстрационных целей. Слишком частые обращения от миллионов устройств по всему миру приводят к перегрузке бесплатных серверов и нарушают стабильность их работы. Старайтесь сделать так, чтобы ваше устройство получало значение точ- ного времени только при необходимости. В промежутках между обращениями к серверу вы можете отсчитывать время при помощи программного эмулятора ча- сов реального времени, основанного на прерываниях, или использовать аппаратный модуль часов. Не забывайте, что иногда сервер времени оказывается недоступен. Для таких случаев можно предусмотреть обращение к резервным серверам. 9.2. Получение уведомлений от устройств на Android Этот несложный проект позволяет получать текстовые системные уведомления от Android-устройства для последующей обработки. На телефоне или планшете с ОС Android в фоновом режиме работает небольшое приложение, которое перехватыва- ет системные уведомления о входящих звонках, SMS, уровне заряда батареи и т. д., и пересылает их в виде текстового сообщения на заданный IP-адрес внешнего сле- дящего устройства. При этом смартфон и внешнее устройство могут находиться в разных частях света. Установив дополнительное приложение, можно организо- вать отправку на следящее устройство уведомлений практически о любом событии, которое произошло со смартфоном, вплоть до изменения его положения в про- странстве. В качестве примера полезного устройства можно предложить домашнюю метео- станцию, которая стоит на прикроватной тумбочке и, кроме прогноза погоды и точного времени, отображает на экране количество поступивших за ночь сообще- ний и пропущенных звонков. При этом телефон может находиться в другой комна-
174 Глава 9 те с выключенным звуком. Вы можете заставить устройство определенным образом реагировать на текст SMS, поступающих на ваш телефон. При этом телефон может находиться где угодно. Важно лишь, чтобы телефон и устройство были подключе- ны к сети Интернет, и устройство было доступно по собственному IP-адресу. В данном случае не подойдет так называемый «серый» IP, который ваш провайдер выделяет целому дому или даже группе домов. Вы должны заказать у своего про- вайдера индивидуальный «белый» IP-адрес. Если смартфон и принимающее уве- домления устройство подключены по Wi-Fi внутри одной локальной сети (кварти- ра, офис), такая проблема не возникает. 9.2.1. Скетч для принимающего устройства Скетч для принимающего устройства приведен в листинге 9.2. Он обеспечивает подключение устройства на основе ESP8266 к точке доступа Wi-Fi и постоянный мониторинг входящих UDP-пакетов, отправленных со смартфона на локальный порт 10600. Содержимое пакета выводится в текстовый терминал. Для практиче- ского применения вам необходимо организовать дальнейшую обработку получен- ного текста в соответствии со своими нуждами. Например, устройство может выде- лять из текста SMS команду и выполнять ее. Или просто подсчитывать входящие звонки и сообщения и следить за состоянием батареи смартфона. Не забудьте перед загрузкой прошивки внести в скетч имя и пароль своей домашней точки доступа Wi-Fi. #include <ESP8266WiFi.h> #include <WiFiUdp.h> const char ssid[] = "YOUR_SSID"; // SSID (имя) вашей точки доступа const char pass[] = "YOUR_PASSWORD"; // пароль точки доступа char packetBuffer[255]; // Буфер для входящих пакетов char ReplyBuffer[] = "acknowledged"; // Строка ответа // Создаем класс UDP WiFiUDP Udp; unsigned int localPort = 10600; // локальный порт для приема UDP-пакетов void setup() { pinMode(2, OUTPUT); // Вывод GPIO2 настроен, как выход digitalWrite(2, HIGH); // Гасим светодиод на плате Serial.begin(9600); Serial.print("Connecting to "); Serial.println(ssid) ; WiFi.begin(ssid, pass);
Примеры программ и проектов для ESP8266 175 II Ждем подключение к Wi-Fi while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } digitalWrite(2, LOW); // Включаем светодиод, когда подключились к Wi-Fi Serial.print ("\ШР number assigned by DHCP is ") ; Serial. println (WiFi. locallP ()) ; Serial.println("Starting UDP"); Udp.begin(localPort); Serial.print("Local port: "); Serial.println(Udp.localPort()); Serial.println("waiting for UDP data"); void loop() { // Если есть данные, читаем их int packetSize = Udp.parsePacket(); if (packetSize) { Serial.print("Received packet of size "); Serial.println(packetSize); Serial.print("From "); IPAddress remotelp = Udp.remotelPO; Serial.print(remotelp); Serial.print(", port "); Serial.println(Udp.remotePort()); // Помещаем пакет UDP в буфер int len = Udp.read(packetBuffer, 255); if (len > 0) { packetBuffer[len] = 0; } Serial.println("Contents:"); Serial.println(packetBuffer); // Отвечаем отправителю, что пакет получен Udp.beginPacket(Udp.remoteIP(), Udp.remotePort())t Udp.write(ReplyBuffer); Udp.endPacketO ; 9.2.2. Установка и настройка приложения Android Установите приложение Remote Notifier for Android из хранилища Google Play на свой смартфон или планшет. Приложение работает в фоновом режиме, настройки очень просты:
176 Глава 9 ♦ Сервис уведомлений — настройка автозапуска сервиса и отображения значка уведомлений; ♦ Способы уведомлений — поставьте галочку в поле IP/Wifi и перейдите в сле- дующий пункт экрана настройки Настройки IP/Wifi; ♦ IP-адрес получателя — выберите пункт Пользовательский IP-адрес или имя хоста; ♦ Пользовательский адрес— введите здесь IP-адрес вашего устройства. Уве- домления будут отправлены на этот адрес. Можно ввести несколько адресов; ♦ Notification protocol — поставьте галочку в пункте Отправить с UDP; ♦ События для уведомлений — выберите здесь события, которые будут генери- ровать уведомления. Поставьте галочку в пункте Third-party apps, чтобы впо- следствии подключить нестандартные уведомления; ♦ Отправить тестовое уведомление — отправка проверочного сообщения. Стандартный монитор порта Arduino IDE не отображает символы кириллицы. Для настройки и отладки оповещений удобнее использовать терминал PuTTY, подклю- ченный в режиме Serial на скорости 9600 к тому же порту, который вы используете для записи прошивки. Пример текстовых сообщений показан на рис. 9.1. В данном случае мы видим, что плата ESP8266 получила в локальной сети IP-адрес 192.168.88.220. Этот адрес надо указать в настройках приложения Android Notifier. Далее отображается проверочное сообщение от приложения и входящая CMC от интернет-магазина. SDOz45hl$SyhS5Coiinecting to DELTA IP number assigned by DHCP is 192.168.88.220 Starting UDP Local port: 10600 waiting for UDP data Received packet of size 80 From 192.168.88.223, port 52415 Contents: v2/fd4ec9d2be6f74ae/54ccld38085c4/PING//Проверка уведомлений Received packet of size 133 From 192.168.88.223, port 36275 Contents: v2/fd4ec9d2be6f74ae/a44b769baf546a/SMS/FANKRAFT.RU/SMS от FASKRAFT.RU: Ваш зака з F1328 принят в обработку. Рис. 9.1. Окно терминала PuTTY для приема входящих уведомлений 9.2.3. Настройка расширенных уведомлений с приложением Tasker К сожалению, простое и удобное приложение Android Notifier было издано доста- точно давно и не умеет напрямую транслировать уведомления от популярных сто-
Примеры программ и проектов для ESP8266 177 ронних приложений, таких как Viber или WhatsApp. Но мы можем воспользоваться очень мощным и гибким приложением для автоматизации смартфона, которое называется Tasker. Работе с этим приложением посвящены многостраничные руко- водства и пользовательские форумы. В этой книге мы ограничимся только описа- нием простых настроек для своих целей. Приложение Tasker отслеживает абсолютно все доступные события ОС Android. Их очень много: запуск приложения, входящее сообщение, изменение координат GPS, подключение наушников и сотни других, более или менее очевидных событий. Любому из этих событий в приложении Tasker можно назначить обработчик. Это может быть некое системное действие (например, включение модуля Wi-Fi) или запуск стороннего приложения с передачей ему параметров. Нас интересует второй вариант. Некоторые приложения поддерживают прямую совместимость с Tasker, для других существуют стыковочные дополнения (плагины). Установите с Google Play приложение Tasker и плагин Locale Remote Notifier Plug- in. Это расширение для связи между приложениями Tasker и Android Notifier. Об- щая логика работы нашей системы уведомлений такова: 1. Tasker обнаруживает некое событие— например, системное уведомление про- граммы. 2. По этому событию Tasker запускает на выполнение плагин Locale Remote Notifier и передает через него параметры сообщения для Android Notifier. 3. Android Notifier передает сообщение в наше устройство на основе ESP8266. Настройка события Tasker — новое сообщение Viber В терминах программы Tasker происходящие в системе Android события называют- ся контекстом, а связь между контекстом и задачами называется профилем. Мы должны создать новый профиль для системного события (контекста), которое будем отслеживать. В качестве примера настроим передачу уведомления о поступ- лении нового сообщения в приложении Viber. Запустите приложение Tasker на смартфоне или планшете. Нажмите символ + в нижней части экрана и выберите пункт Приложение (рис. 9.2). В списке прило- жений найдите значок Viber и коснитесь его — приложение будет выделено рам- кой. Нажмите символ стрелки влево рядом со значком в левом верхнем углу экра- на. Если приложение Tasker попросит запустить службу отслеживания событий, нажмите ОК и запустите службу в открывшемся окне настроек. Теперь нажмите символ + в пункте меню Новая задача (рис. 9.3) и введите имя задачи. Пусть это будет ESPnotif ier. После ввода имени задачи мы сразу попадаем на экран добавления действий. Снова нажмите +, выберите пункт Плагин (рис. 9.4), затем Locale Remote Notifier (рис. 9.5). Нажмите на символ карандаша в пункте Конфигурация, настройте два текстовых параметра, передаваемых в Android Notifier, и нажмите кнопку ОК. Вернитесь к главному окну приложения Tasker и долгим нажатием на значке в левом верхнем углу активируйте его. На- строенный профиль должен выглядеть так, как показано на рис. 9.6. Если коснуться
178 Глава 9 Клию tasks tht1 Viber Enter Задача Новая задача Рис. 9.2. Добавление приложения для отслеживания в Tasker Рис. 9.3. Создаем новую задачу в приложении Tasker Рис. 9.4. Выбираем категорию исполнителя задачи в Tasker Рис. 9.5. Выбираем плагин для выполнения задачи Рис. 9.6. Настройка текста сообщений плагина
Примеры программ и проектов для ESP8266 179^ надписи ESPnotifier, то вы перейдете к окну задач, в котором можете принуди- тельно запустить задачу на выполнение для проверки. Теперь при поступлении нового сообщения в приложение Viber на самодельное устройство через Интернет будет поступать уведомление вида: USER/VIBER/ Viber message (рис. 9.7). Приложение Viber, как и большинство других мессенд- жеров, шифрует текст сообщений и не позволяет сторонним приложениям их извлекать. Поэтому Tasker может сообщить лишь о наличии входящих сообщений, но не может передать их текст. Аналогичным образом можно настроить передачу уведомлений от других прило- жений. Чтобы вести статистику поступивших уведомлений, ваш скетч может, например, выделять и подсчитывать заголовки уведомлений. Предлагаю вам само- стоятельно запрограммировать такую функцию скетча в качестве тренировки. Воспользуйтесь функциями работы со строковыми переменными языка Wiring/ Processing среды Arduino IDE. Received packet of size €0 [From 192.168.88.223, port 51038 Contents: |v2/fd4ec9d2be€f74ae/a45778481a9Sfe/USER/VIBER/Viber message Рис. 9.7. Уведомление о поступлении сообщения Viber 9.3. Модуль управления экшн-камерой Xiaomi Yui Недорогая, но качественная экшн-камера Xiaomi Yui (рис. 9.8) приобрела большую популярность у любителей фото- и видеосъемки с самодельных квадрокоптеров и радиоуправляемых моделей самолетов. Такое применение автоматически порожда- ет проблему дистанционного управления ею на большом расстоянии. Дело в том, что эта чрезвычайно популярная благодаря своей дешевизне и качеству камера ни- как не управляется дистанционно — ее вручную включают на запись перед взлетом и выключают после посадки. Камера оснащена встроенным модулем Wi-Fi для взаимодействия с фирменным приложением на смартфоне, а также модулем Bluetooth для связи с портативным пультом дистанционного управления. Оба способа беспроводного управления предназначены для съемки селфи на близком расстояниии и не подходят для управления камерой, установленной на беспилотный летательный аппарат, по- скольку она не имеет аппаратного входа для прямого управления режимами съемки сигналом с микроконтроллера или приемника радиоуправления.
180 Глава 9 «я Рис. 9.8. Экшн-камера Xiaomi Yui К счастью, протокол управления камерой по Wi-Fi легко поддается расшифровке. На основании этого протокола я разработал несложный модуль на основе ESP8266 для дистанционного управления камерой. Он успешно отработал два летних сезона полетов. Страница проекта и его обсуждение расположены в блоге автора по адре- су: http://forum.rcdesign.ru/blogs/7830/blog20971.html. Модуль вместе с камерой располагается на борту квадрокоптера. На вход модуля поступает стандартный сигнал радиоуправления с выхода бортового приемника. На сегодняшний день поддерживаются сигналы стандартов PWM и РРМ. Модуль де- кодирует управляющий сигнал и преобразовывает его в команду управления каме- рой. Команда передается в камеру по Wi-Fi. Поддерживаются команды пус- ка/остановки видеозаписи и спуска затвора для режима фотосъемки. 9.3.1. Аппаратная часть модуля В авторской конструкции используется ESP-09 — самый маленький и легкий из готовых модулей на основе ESP8266. Чтобы не создавать помехи бортовому обору- дованию, выходная мощность микросхемы ESP8266 снижена до предела, антенна Wi-Fi не используется. В этом случае канал, связи с камерой работает на расстоянии около 20-30 см и не мешает приемнику радиоуправления. Модуль ESP-09 припаи- вается к небольшой базовой плате, которая содержит стабилизатор питания, инди- каторный светодиод и резисторы для согласования логических уровней с внешними пятивольтовыми источниками сигнала. Модуль управления крепится на раме квад- рокоптера как можно ближе к камере. При наличии достаточного опыта монтажную плату можно изготовить самостоя- тельно по чертежам, приведенным в сопровождающем книгу электронном архиве, размещенном на сайте издательства (см. приложение). Готовую плату заводского изготовления можно заказать на сайте: http://www.fankraft.ru. Можно также ис- пользовать любой другой модуль на основе SoC ESP8266, но придется смириться с увеличением веса и объема, что нежелательно для летающих устройств.
Примеры программ и проектов для ESP8266 181_ Внешний вид смонтированного устройства показан на рис. 9.9. Модуль ESP-09 монтируется по безвыводной технологии. Порядок монтажа: 1. Нанесите безотмывочный флюс— например, TR-RMA или Amtech NC-559 на контактные площадки ESP-09. 2. Нанесите небольшое количество припоя ПОС-61 на каждую площадку ESP-09. Количество припоя должно быть достаточным для надежного примыкания к монтажной плате, но не слишком большим. 3. Нанесите безотмывочный флюс на монтажные площадки платы. Зажмите кром- ку платы в держателе «третья рука». Положите сверху модуль ESP-09, тщатель- но убедитесь, что он уложен правильно. 4. Снизу нагрейте монтажную плату при помощи фена паяльной станции, настро- енного на температуру около 320-330 градусов. Когда припой расплавится, и модуль слегка осядет на контактных площадках, прекратите нагрев и дайте пла- те остыть. Не пытайтесь прижать разогретый модуль ESP-09 к монтажной плате! Вы мо- жете сместить компоненты модуля. На хорошо прогретой плате модуль сориен- тируется и притянется сам, за счет сил поверхностного натяжения расплавлен- ного припоя. Не рекомендуется использовать канифольно-глицериновый флюс, который при на- гревании начинает кипеть и отталкивать ESP-09 от монтажной платы. +5 В GND Rx | +5 В Тх RCIN GND , 15 мм 20 мм Рис. 9.9. Внешний вид и назначение выводов модуля 9.3.2. Прошивка модуля Внешнее устройство управления, будь то смартфон или самодельный модуль, под- ключается к камере по протоколу Telnet. Для подтверждения подлинности сессии связи используется простейший механизм токенов. При успешном установлении связи с камерой она возвращает устройству управления некое число. В дальнейшем устройство должно подставлять это число в каждую команду. Благодаря токену камера определяет, от какого устройства поступила команда. Команды представляют собой текстовые сообщения, отформатированные в формате {параметр:значение}. В ответ камера отправляет текстовые сообщения о ходе выполнения команды,
182 Глава 9 текущем статусе камеры (ожидание, видеозапись, фотосъемка), уровне заряда бата- реи и т. д. Эти сообщения могут быть расшифрованы программой управляющего устройства. С точки зрения модуля управления камера является обычной точкой доступа Wi-Fi. Камера работает под управлением ОС Linux, к которой мы обращаемся по фик- сированному IP-адресу и порту. Скетч для управления камерой приведен в листин- ге 9.3. Это версия программы, которая работает с сигналом радиоуправления формата PWM (Pulse-Width Modulation). Версия для работы с сигналом PPM (Pulse- Position Modulation) доступна в сопровождающем книгу электронном архиве, раз- мещенном на сайте издательства (см. приложение). #include <ESP8266WiFi.h> // Подключаем оригинальные библиотеки Expressiff SDK 1.4.0 #ifdef ESP8266 extern "С" { #include "ets_sys.h" #include "os_type.h" #include "osapi.h" #include "mem.h" #include "user_interface.h" #include "cont.h" } #endif #define CAMERA_SSID "YDXJ_1234567" // Имя ВАШЕЙ камеры, типа "YDXJ_1234567"; отображается, как имя точки доступа Wi-Fi #define CAMERA_PAS SWORD "1234567890" // пароль точки доступа по умолчанию #define CAMERA_PORT 7878 //номер порта Telnet #define RC_FILTER 1 // Количество одинаковых импульсов радиоуправления для подтверждения команды #define DATA_DELAY 500 // задержка между блоками данных от камеры #define ATTEMPTS 40 // предельное количество попыток подключения к камере #define WIFI_TX_POWER 0 // мощность передатчика микросхемы ESP8266 (0 -> 0.25dBm) (диапазон 0...85) #define RC_INPUT 14 // GPIO14 - вы можете использовать другой GPIO *кроме* GPIO15, GPIO16, GPIO2, GPIO0 #define LED 2 // светодиод подключен к выводу GPIO2 String token = "", INcamera = ""; volatile unsigned long ppm_start = 0, ppm_stop = 0, ppm =0; volatile byte level = 0, count = 0; int ledState = LOW, conn = 0, state = 0;
Примеры программ и проектов для ESP8266 183 WiFiClient client; // ESP8266 в режиме "клиент" void setup() { ttifdef ESP8266 system_phy_set_max_tpw(WIFI_TX_POWER) ; // устанавливаем мощность передатчика Wi-Fi tendif pinMode(LEDf OUTPUT); digitalWrite(LED, LOW); delay(500); digitalWrite(LED, HIGH); pinMode (RC_INPUT, INPUT); Serial.begin(9600); delay(10); Serial.println("\nStart connection"); WiFi.begin(CAMERA_SSID, CAMERAJPASSWORD); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); digitalWrite(LEDf IdigitalRead(LED)); //blink count ++; if (count > ATTEMPTS) { Serial.println("\nCamera not found!"); digitalWrite(LED, HIGH); break; } } if (!client.connect("192.168.42.1", CAMERA_PORT)) { conn =0; Serial.println("\nNot connected!"); } else { Serial.println("\nConnected to camera"); conn = 1; //Установили флаг "подключено" digitalWrite(LED, LOW); ask_for_token(); Serial.println("token: " + token); // Заставляем камеру издать звуковой сигнал 0,4 сек при подключении buzzer_on(); delay(400); buzzer_off(); // Разрешаем прерывание по изменению уровня на входе сигнала радиоуправления attachlnterrupt(digitalPinToInterrupt(14), pwm_read, CHANGE);
184 Глава 9 void loop () { Обработка команды радиоуправления switch (level) { case 1: if (state ==0) { state = 1; break; } if (state == 2) { // если рукоятку переместили из середины в минимум if (count < RC_FILTER) { count ++; } else { count =0; state = 1; Serial.println("Take the photo"); take_photo(); // Сделать одиночный фотоснимок break; case 2: // Если рукоятку переместили в середину if (state == 0) { state = 2; break; } if (state == 1) { // Возврат из режима фотоснимка в режим ожидания if (count < RC_FILTER) { count ++; } else { count =0; state = 2; Serial.printIn("Standby"); if (state ==3) { // Если выходим из режима видео if (count < RC_FILTER) { count ++; } else { count = 0; state = 2; Serial.println("video OFF");
Примеры программ и проектов для ESP8266 185 video_off(); // отключить режим "видеосъемка" break; case 3: // если рукоятку переместили из середины в максимум if (state == 0) { state = 3; break; } if (state == 2) { if (count < RC_FILTER) { count ++; } else { count = 0; state = 3; Serial.println("video ON"); video_on(); // включить режим видеозаписи Serial.println(String(conn) + ";" + String(state) + ";" + camera_status() + ";" + battery_status()) delay(DATAJDELAY); /••••••••••••••••••••*•*•••••••••••••••••••••••••••*•• Запрос токена авторизации от камеры void ask_for_token(void) { // временно запрещаем прерывание по сигналу радиоуправления detachlnterrupt(digitalPinToInterrupt(RC_INPUT)); INcamera = ""; client.flush(); // очищаем буфер передачи // передаем в камеру строку запроса авторизации client.print("{\"msg_id\":257,\"token\":0,\"param\":0}"); while (!client.available()) { } // ждем ответ от камеры // если ответ поступил, читаем его while (client.available()) { char k = client.read(); INcamera += k; } //Serial.println(INcamera); INcamera.trim (); token = INcamera.substring(37, (INcamera.length() - 2)); INcamera = "";
186 Глава 9 // разрешаем прерывание по сигналу радиоуправления attachlnterrupt(digitalPinToInterrupt(RC_INPUT), pwm_read, CHANGE); Сделать одиночный снимок ••••**************************************^ void take_photo() { if (conn ==1) { // только если камера подключена detachlnterrupt(digitalPinToInterrupt(RC_INPUT)); INcamera = ""; client.flush(); client.print("{\"msg_id\":769,\"token\ff:ff + token + "}"); while (1) { if (INcamera.substring(24, 32) == "vf_start") { //Serial.println("photo taken"); Serial.println(String(conn) + ";" + String(state) + ";" + "4" + ";" + "0") delay(800); // Задержка на время отработки сохранения снимка в камере break; } INcamera = ""; while (!client.available()) { } while (client.availableO) { char k = client.read(); INcamera += k; if (k == •}■) { //Serial.println(INcamera); attachlnterrupt(digitalPinToInterrupt(RC_INPUT), pwm_read, CHANGE); /*•**•***••*•**•*••••*••*****•••*•••*****•*•** Включить режим записи видео void video_on() { if (conn ==1) { // только если камера подключена detachlnterrupt(digitalPinToInterrupt(RC_INPUT)); INcamera = ""; client.flush() ; client.print("{\"msg_id\n:513f\"token\":" + token + "}"); while (1) { if (INcamera.substring(24, 42) == "start_video_record") { Serial.println("video record ON"); break;
Примеры программ и проектов для ESP8266 187 INcamera = ""; while (!client.available()) { } while (client.available()) { char к = client.read(); INcamera += k; if (k == ■}') { //Serial.println(INcamera); attachlnterrupt(digitalPinToInterrupt(RC_INPUT), pwm_read, CHANGE); Выключить режим записи видео void video_of f () { if (conn ==1) { // только если камера подключена detachlnterrupt(digitalPinToInterrupt(RC_INPUT)); INcamera = ""; client.flush(); client.print(n{\"msg_id\":514,\"token\11:11 + token + "}"); while (1) { if (INcamera.substring(24, 32) == "vfjstart") { //Serial.println("video record OFF"); break; } INcamera = ""; while (!client.available()) { } while (client.available()) { char k = client.read(); INcamera += k; if (k == f}f) { //Serial.println(INcamera); attachlnterrupt(digitalPinToInterrupt(RC_INPUT), pwm_read, CHANGE); Включить звуковой сигнал камеры void buzzer_on() { detachlnterrupt(digitalPinToInterrupt(RC_INPUT));
188 Глава 9 INcamera = ""; client.flush(); client.print("{\"type\":\"buzzer_ring\",\"msg_id\":2Л"рагат\": \"on\ll,\"token\":" + token + "}"); while (!client.available()) { } while (client.available()) { char к = client.read(); INcamera += k; } //Serial.printIn(INcamera); attachInterrupt(digitalPinToInterrupt(RC_INPUT), pwm_read, CHANGE); Выключить звуковой сигнал камеры void buzzer_off() { detachlnterrupt(digitalPinToInterrupt(RC_INPUT)); INcamera = ""; client.flush(); client.print("{\"type\":\"buzzer_ring\",\"msg_id\":2,\ffparam\": \"off\",\"token\fl:" + token + "}"); while (!client.available()) { } while (client.available()) { char k = client.read(); INcamera += k; } //Serial.printIn(INcamera); attachlnterrupt(digitalPinToInterrupt(RC_INPUT), pwm_read, CHANGE); Запросить информацию о заряде батареи String battery_status() { detachlnterrupt(digitalPinToInterrupt(RC_INPUT)); // если камера не подключена, возвращаем "О" if (conn == 0) { attachlnterrupt(digitalPinToInterrupt(RC_INPUT), pwm_read, CHANGE); return "0"; } INcamera = ""; client.flush(); client.print("{\fImsg_id\":13f\"token\":" + token + "}"); while (!client.available()) { } while (client.available()) { char k = client.read();
Примеры программ и проектов для ESP8266 189 INcamera += к; } int param = INcamera. indexOf ("param"); String bat_status = INcamera.substring(param + 8, param + 10); attachlnterrupt(digitalPinToInterrupt(RC_INPUT), pwm_read, CHANGE); return String(bat_status.tolnt()); Запросить текущий статус камеры •••••••••••••••••••••*********************^ String camera_status () { detachlnterrupt(digitalPinToInterrupt(RC_INPUT)); int cam_stat = 0; // если камера не подключена, возвращаем "0" if (conn — 0) { attachlnterrupt(digitalPinToInterrupt(RC_INPUT), pwm_read, CHANGE); return "0"; } INcamera = ""; client.flush(); client.print("{\"type\":\"app_status\"f\lfmsg_id\fI:l,\"token\":" + token + "}"); while (!client.available ()) { } while (client.available()) { char k = client.read(); INcamera += k; } int param = INcamera. indexOf ("param") ; int bracket = INcamera.indexOf(f}f) - 1; String cam_status = INcamera.substring(param + 8, bracket); if (cam_status = "idle") { cam_stat = 1; } else if (cam_status = "record") { cam_stat =2; } else if (cam_status = "vf") { cam_stat = 3; } else if (cam_status == "capture") { cam_stat = 4; } attachlnterrupt(digitalPinToInterrupt(RC_INPUT), pwm_read, CHANGE); return String(cam_stat);
190 Глава 9 /•••••••••••••••••••••••******************^ Определение длительности импульсов сигнала радиоуправления PWM void pwm_read(void) { if (digitalRead(RC_INPUT) == 1) { ppm_start = micros(); } else { ppm_stop = micros(); ppm = ppm_stop - ppm_start; if (ppm < 1300) { level = 1; } else if (ppm > 1330 && ppm < 1660) { level = 2; } else if (ppm > 1690) { level = 3; Алгоритм работы устройства Перед подачей питания на устройство должна быть включена не только камера Xiaomi Yui, но и встроенный модуль Wi-Fi камеры. При этом синий светодиод на торце камеры будет мигать. В этом режиме камера работает, как точка доступа Wi-Fi. Имя точки доступа и пароль камеры можно узнать и изменить при помощи фирменного приложения .для смартфона. Не забудьте внести в скетч параметры точки доступа вашей камеры перед компиляцией программы! После подачи питания модуль управления пытается установить соединение с каме- рой. Выполняется 40 попыток с интервалом 0,5 секунды. При успешном соедине- нии в камеру отправляется команда включения звукового сигнала (режим «поиск камеры»). Камера должна издать короткий звуковой сигнал. Информация о процес- се подключения и дальнейшей работе модуля выводится в последовательный порт. Вы можете следить за работой устройства при помощи встроенного монитора пор- та Arduino IDE или любой терминальной программы. В режиме ожидания модуль измеряет длительность импульсов сигнала радио- управления, подаваемого на вход GPIO14. Используется три градации длитель- ности импульсов:
Примеры программ и проектов для ESP8266 191_ ♦ менее 1300 микросекунд — минимальная; ♦ от 1330 до 1660 микросекунд — средняя; ♦ более 1690 микросекунд — максимальная. Между этими градациями предусмотрен защитный интервал в 30 микросекунд для защиты от «дрожания» сигнала и ложных срабатываний от помех. Для управления режимом работы камеры рекомендую использовать трехпозицион- ный тумблер пульта радиоуправления. В зависимости от положения тумблера, пульт должен выдавать в канал один из трех вариантов длительности управляюще- го импульса: короткий, средний и длинный. Команда, отправляемая в камеру, зави- сит от направления перехода, в котором изменилось положение тумблера (длитель- ность импульсов): ♦ из среднего в максимальное— включить режим видеозаписи. Начинается запись видео на карту памяти камеры; ♦ из максимального обратно в среднее — выключить видеозапись. Прекращает- ся запись видео на карту памяти, файл закрывается. Камера переходит в режим ожидания; ♦ из среднего в минимальное — выполняется одиночный фотоснимок. Файл со- храняется на карту памяти. После финализации кадра камера сама переходит в режим ожидания; ♦ из минимального обратно в среднее— ничего не происходит. Готовность к отработке команды записи видео или одиночного фотоснимка. Задержка на выполнение команды Помните, что камере требуется время для выполнения команды! Даже команда пре- кращения видеозаписи не выполняется мгновенно. Камере нужна почти секунда для выгрузки содержимого внутреннего буфера на карту памяти и закрытия файлового потока. Обработка и запись одиночного фотоснимка, в зависимости от разрешения, может занимать более секунды. Не переключайте тумблер пульта слишком часто. При смене режима фиксируйте тумблер в среднем положении не менее секунды. Дайте камере время для завершения внутренних операций. В противном случае камера может «зависнуть» и перестать реагировать на команды модуля управления. Измерение длительности импульсов Для измерения длительности импульсов сигнала радиоуправления задействовано прерывание по изменению уровня на выводе GPIO14. Когда срабатывает прерыва- ние по нарастающему фронту сигнала (из логического уровня 0 в логический 1), фиксируется текущее количество микросекунд с момента включения микрокон- троллера: if (digitalRead(RC_INPUT) = 1) { ppm_start = micros();
192 Глава 9 Когда срабатывает прерывание по спаду импульса, вновь фиксируется текущее время микроконтроллера. Затем из времени окончания импульса вычитается время его начала. В зависимости от длительности импульса устанавливается его услов- ный статус: 1 (короткий), 2 (средний), 3 (длинный): ppm_stop = micros(); ррш = ppm_stop - ppm_start; if (ppm < 1300) { level = 1; } else if (ppm > 1330 && ppm < 1660) { level = 2; } else if (ppm > 1690) { level = 3; } Обратите внимание, что прерывания запрещаются на время передачи команды в камеру и чтения ответа из камеры, потому что в это время новые команды все равно не будут обработаны, и нет смысла прерывать исполнение программы. Совместимость программы модуля с разными версиями Arduino IDE и камеры Когда разрабатывался этот проект, в продаже была представлена версия камеры Z22L. Спустя год поступила в продажу версия Z23L, имеющая некоторые аппарат- ные отличия. Они не имеют значения для работы дистанционного управления, и мы не будем вникать в подробности. Однако для версии Z23L доступна более продви- нутая прошивка, в которую, например, добавлена функция серийной съемки. К со- жалению, у меня имеется только старая версия камеры, и не было возможности проверить и отладить новые функции. Поэтому новые функции для аппаратной версии Z23L не поддерживаются программой модуля управления, но могут быть добавлены любым энтузиастом технического творчества, имеющим новую версию камеры. Некоторые пользователи отмечали невозможность установить соединение с каме- рой, особенно версии Z23L, при помощи заведомо исправного модуля, проверенно- го с камерой Z22L. После многочисленных экспериментов мы предположили, что причина может быть вовсе не в камере, а в обновленной версии компилятора Arduino IDE. Проект разрабатывался и отлаживался, когда самой свежей была вер- сия среды 1.6.5. На момент написания книги для скачивания доступна версия 1.8.1. Если учесть, что использование Arduino IDE для программирования ESP8266 явля- ется довольно нестандартным подходом, который реализован группой энтузиастов, то появление некоторых редких скрытых ошибок компиляции вполне вероятно.
Примеры программ и проектов для ESP8266 При воспроизведении проекта рекомендую скачать и установить в отдельный ката- лог среду Arduino IDE версии 1.6.5 или 1.6.8 (см. разд. 5.4.1) и использовать эту версию для компиляции скетча проекта. Отдельно следует отметить совместимость с камерой Xiaomi Yui 4K. Когда книга готовилась к печати, один из пользователей модуля управления прислал мне фраг- мент кода для запроса токена, который адаптирован для этой версии камеры. Бла- годарю его за поддержку проекта и с удовольствием размещаю доработанную под- программу запроса токена (листинг 9.4). void ask_for_token (void) { INcamera = ""; client.flush(); client.print("{\"msg_id\":257,\"token\":0,\"param\":0}"); while (!client.available()) { } while (client.available()) { char k = client.read(); INcamera += k; } INcamera.trim(); token = INcamera.substring(31,(32)); INcamera = ""; Отличие от исходной программы заключается только в строке token = INcamera. substring(31,(32)). Как удалось выяснить владельцам новых версий камеры, несовместимость версий заключается в том, что в ответе камеры номер токена расположен в другой позиции текстовой строки. Следовательно, чтобы модуль управления начал работать с но- вой версией, достаточно лишь изменить в программе позицию символа, который выделяется из строки. 9.4. Адаптация взаимодействия с сервисом Теmboo В разд. 7.4 мы рассмотрели пример взаимодействия с облачным сервисом Temboo при помощи сетевого шилда Dragino Yun. Вполне логично было бы проделать то же самое при помощи ESP8266. У меня для вас две новости: плохая и хорошая. Плохая новость: не получится просто взять и загрузить скетч для Dragino Yun в плату на основе ESP8266. Хорошая новость: все уже придумано энтузиастами- разработчиками, и потребуются лишь минимальные переделки. Далее мы детально рассмотрим, что именно и с какой целью следует переделать. Фирменная библиотека Temboo входит в состав установочных файлов Arduino IDE. Мы должны заменить ее на версию, специально разработанную для ESP8266. Автор
194 Глава 9 этой версии свободно распространяемой библиотеки Марко Шварц (Marco Schwartz) написал полезную книгу о проектах для Интернета вещей на основе ESP8266. Книга называется «Internet of Things with ESP8266», и перевод ее на рус- ский язык готовится сейчас в издательстве «БХВ-Петербург». Доработанная версия библиотеки Temboo доступна для скачивания в составе сопровождающего книгу электронного архива, размещенного на сайте издательства (см. приложение), или по адресу: https://github.com/openhomeautomation/iot-esp8266-packt/tree/master/05 Найдите на своем компьютере старую версию библиотеки Temboo. Для Windows она хранится в каталоге C:\Program Files (x86)\Arduino\libraries. В случае с OS X щелк- ните на пункте Show package content для приложения Arduino IDE. Обязательно со- храните старую версию Temboo в резерве, она может понадобиться в будущем. Теперь замените ее на адаптированную версию для ESP8266. Когда работа над проектами для этой книги была завершена, сервис Temboo вне- запно изменил некоторые функции API и выпустил новую фирменную библиотеку для Arduino. Поэтому доработанная библиотека Марко Шварца в некоторых случаях не работает с новым API Temboo. Будем надеяться, что Марко вскоре выпустит но- вую версию. Кроме того, в стандартный код скетча, генерируемого Temboo, добав- лена проверка версии библиотеки в файле Temboo.h. Удалите эти строки из файла: #if TEMBOO_LIBRARY_VERSION < 2 #error "Your Temboo library is not up to date." #endif Внесем небольшие изменения в скетч (листинг 7.6). Учтем, что в шилде Dragino Yun задачу подключения к точке доступа Wi-Fi выполняет заранее настроенная ОС Linux, а в случае с ESP8266 подключение нужно выполнить непосредственно в скетче, средствами самой микросхемы: 1. Все команды вывода в консоль Linux: console.print о и console.printn о заме- ните на команды вывода в терминал последовательного порта: serial.print о и serial.println(). 2. Удалите вызовы библиотек Bridge и console, добавьте вызов библиотеки ESP8266WiFi. 3. Создайте подключение по Wi-Fi к локальной точке доступа и запрограммируйте включение встроенного синего светодиода на плате. 4. Создайте объект client. 5. В вызове метода TembooChoreo AppendRowChoreo () вместо пустых скобок исполь- зуйте ЯВНОе указание объекта client: TembooChoreo AppendRowChoreo (client). У вас должен получиться скетч, аналогичный приведенному в листинге 9.5. Изме- нения выделены жирным шрифтом. #include <ESP8266WiFi.h> #include <Temboo.h> #include "TembooAccount.h" // Файл содержит информацию об аккаунте Temboo
Примеры программ и проектов для ESP8266 195_ #define WTFIJSSID ******** // имя точки доступа #define WPA_PASSWORD ******* // пароль точки доступа WiFiClient client; // Создаем объект client // Введите здесь ваши данные доступа к аккаунту Google, // скопируйте их из кода, который автоматически сгенерирован сервисом Temboo const String GOOGLE_CLIENT_ID = "*********.apps.googleusercontent.com"; const String GOOGLE_CLIENT_SECRET = "*********************"; const String GOOGLE_REFRESH_TOKEN = "********************"; // Название существующей таблицы Google Sheets // Обратите внимание, что надо ввести именно название таблицы, а не ее URL, // как сказано в руководстве на Temboo const String SPREADSHEETJTITLE = "mysampledata"; int numRuns =1; // Счетчик количества обращений к таблице int maxRuns = 100; // Максимальное количество обращений, // будет добавлено не более 100 строк за время работы скетча void setup() { Serial.begin(9600); pinMode(2, OUTPUT); // Вывод 6Р1О2 настроен, как выход digitalWrite(2, HIGH); // Гасим светодиод Serial.begin(9600); Serial.print("Connecting to "); Serial.println(WIFI_SSID) ; WiFi.begin(WIFI_SSID, WPAJPAS SWORD); // устанавливаем соединение с Wi-Fi // Ждем, пока будет установлено соединение с точкой доступа Wi-Fi while (WiFi.status() !« WL_CONNECTED) { delay(500); Serial.print("."); } digitalWrite(2, LOW) ; // Включаем светодиод, когда соединение установлено void loop() // Повторяем запись новых значений в таблицу, пока не превышено число обращений if (numRuns <= maxRuns) { Serial.println("Running AppendRow - Run #" + String(numRuns++)); // получаем время в миллисекундах с момента запуска скетча unsigned long now = millis();
196 Глава 9 Serial.println("Getting sensor value..."); // получаем от сенсора измеренное значение unsigned long sensorValue = getSensorValue(); Serial.println("Appending value to spreadsheet..."); // создаем процесс для отправки запроса на добавление строки через Temboo TembooChoreo AppendRowChoreo(client); // запускаем клиента Teinboo // учтите, что клиент должен быть вызван и обеспечен данными в виде // соответствующих аргументов при каждом использовании метода run(). AppendRowChoreo.begin(); // определяем персональные данные аккаунта Temboo, из файла TembooAccount.h AppendRowChoreo. setAccountName (TEMBOO_ACCOUNT) ; AppendRowChoreo.setAppKeyName (TEMBOO_APP_KEY_NAME) ; AppendRowChoreo.setAppKey(TEMBOO_APP_KEY); // определяем библиотеку Temboo Choreo (Google > Spreadsheets > AppendRow) AppendRowChoreo.setChoreo("/Library/Google/Spreadsheets/AppendRow"); // определяем необходимые входные данные библиотеки // читайте https://www.teinboo.com/library/Library/Google/Spreadsheets/AppendRow/ // для детальной расшифровки требований к входным параметрам // определяем ваш Google Client ID AppendRowChoreo.addlnput("ClientID", GOOGLE_CLIENT_ID); // определяем ваш Google Client Secret AppendRowChoreo.addlnput("ClientSecret", GOOGLE_CLIENT_SECRET); // определяем ваш Google Refresh Token AppendRowChoreo.addlnput("RefreshToken", GOOGLE_REFRESH_TOKEN); // определяем название вашей таблицы AppendRowChoreo.addlnput("Spreadsheetstie", SPREADSHEET_TITLE); // преобразуем время и показания сенсора в строку, разделенную запятой String rowData(now); rowData += ","; rowData += sensorValue; // добавляем данные в набор строки "RowData" AppendRowChoreo.addlnput("RowData", rowData);
Примеры программ и проектов для ESP8266 197 // запускаем метод Ternboo Choreo и ждем результат // возвращаемый код принимает одно из значений: "успех" или "ошибка" unsigned int returnCode = AppendRowChoreo.runO; // возвращаемый код "ноль" (0) означает успех записи if (returnCode ==0) { Serial.println("Success! Appended " + rowData); Serial.printIn(""); } else { // код, отличный от ноля, означает наличие ошибки // читаем и выводим в консоль все сообщения об ошибках while (AppendRowChoreo.available()) { char с = AppendRowChoreo.read(); Serial.print(c); AppendRowChoreo.close(); // закрываем текущий процесс Serial.println("Waiting..."); delay(5000); // ждем 5 секунд перед следующим запуском цикла измерения-записи //в этой функции симулируем чтение значения из сенсора // считывается случайное значение с аналогового входа АО //вы можете заменить код этой функции на код чтения данных с реального датчика unsigned long getSensorValue() { return analogRead(AO);
ГЛАВА 10 Платформа NodeMCU для Интернета вещей Открытая платформа NodeMCU предназначена для изучения и разработки проектов Интернета вещей и работает на SoC ESP8266, о которой мы говорили в двух пре- дыдущих главах. Для разработки и отладки программ созданы различные приложе- ния. Большинство из них мультиплатформенные и могут работать на Windows, Mac OS и Linux. Есть приложения и для Android. Прошивка может быть запущена на любых модулях серии ESP-xx, поэтому наиме- нование платформы обозначает скорее программную, чем аппаратную часть. И, наоборот, на оригинальной отладочной плате NodeMCU DevKit может работать любая прошивка для ESP8266. NodeMCU концептуально отличается от Arduino. Программа для Arduino компили- руется в самостоятельно работающий бинарный код — при смене программы про- шивка полностью перезаписывается. Поэтому в памяти устройства может нахо- диться только одна программа, скомпилированная в среде Arduino IDE и стартую- щая при включении питания. NodeMCU— это интерпретатор с поддержкой файловой системы, постоянно находящийся в памяти устройства и не зависящий от выполняющихся программ. В устройство может быть загружено несколько про- грамм или модулей, которые можно запускать по выбору пользователя. Файлы программ хранятся в файловой системе SPIFFS (SPI Flash File System), раз- мещенной во внешней микросхеме флеш-памяти модуля. Файловая система пло- ская, т. е. папок (вложенных каталогов) в ней нет, — все файлы хранятся только в корневом каталоге. Многих разработчиков, особенно любителей, привлекает возможность работать в интуитивно понятной среде, предоставляющей им: ♦ файловую систему; ♦ несложный язык программирования; ♦ возможность простой построчной отладки программ. Программирование в среде NodeMCU осуществляется на Lua — скриптовом языке программирования. Программы хранятся во флеш-памяти модуля в виде текстовых
Платформа NodeMCU для Интернета вещей 199 файлов, которые извлекаются из нее для выполнения. Программа выполняется ин- терпретатором построчно. Точнее, как и все современные интерпретаторы, он по- строчно предкомпилирует программу, превращая ее из текста в машинный код. Этот код размещается в оперативной памяти микросхемы ESP8266. Объем ОЗУ невелик, поэтому большие программы приходится разделять на несколько файлов и запускать их по мере необходимости. В каждый момент времени NodeMCU может работать только с одним файлом. При помощи команд языка Lua можно обращаться к аппаратным ресурсам модуля. Например, считывать состояние выводов GPIO или значение АЦП, устанавливать выходные уровни GPIO, управлять работой Wi-Fi. В главе 11 мы рассмотрим при- меры, иллюстрирующие возможности языка Lua в сочетании с аппаратными ресур- сами ESP8266. Скриптовый язык помогает начинающим разработчикам экономить время. Когда вы работаете с компилирующим языком и вам нужно отладить программу, ее каж- дый раз приходится загружать в память устройства. Полноценная скомпилирован- ная программа может занимать от сотен килобайт до 2-3 мегабайт. Размер скомпи- лированного кода зависит от качества работы компилятора, поэтому экономия па- мяти устройства не всегда очевидна. Загрузка скомпилированной прошивки может длиться более минуты. Представьте, что вы осваиваете новую платформу или экспериментируете с новым языком и делаете множество ошибок. Если загрузить прошивку 100 раз, то процесс загрузки в сумме займет около 120 минут. Два рабочих часа, потраченных напрасно лишь на ожидание загрузки прошивок! По своему опыту могу отметить, что после двух десятков исправлений ожидание завершения загрузки начинает изрядно раздра- жать. Программа на скриптовом языке — это обычный текстовый файл небольшого раз- мера, как правило, не более нескольких килобайт. Загрузка скрипта в память зани- мает несколько секунд, и почти мгновенно можно наблюдать результат внесенных изменений. За экономию времени отладки приходится платить сниженным, по сравнению с компилированным кодом, быстродействием программы. Впрочем, ко- гда программа отлажена, ее можно перенести на компилирующий язык, который обеспечит высокую скорость работы. 10.1. Подготовка к использованию NodeMCU 10.1.1. Рекомендованное оборудование NodeMCU можно запустить на любом модуле ESP. Так, вы можете продолжать ис- пользовать отладочные платы WeMos D1 или WeMos Dl Mini (см. рис. 8.3), но я рекомендую приобрести готовую отладочную плату NodeMCU DevKit (рис. 10.1). Она содержит модуль ESP-12E с объемом памяти 4 Мбайт, встроенный конвертер USB-UART, стабилизатор питания 3,3 В и кнопки Flash и Reset. На разъемы по бо- кам платы разведены все рабочие выводы микросхемы ESP8266. Расположение и назначение выводов отладочной платы NodeMCU DevKit приведено на рис. 10.2.
200 Глава 10 Рис. 10.1. Стандартная отладочная плата NodeMCU DevKit на основе модуля ESP-12E Рис. 10.2. Расположение и назначение выводов отладочной платы NodeMCU DevKit Внешний вид платы и применяемая в ней микросхема конвертера USB-UART мо- гут быть разными в зависимости от производителя и даты выпуска. Небольшое увеличение цены по сравнению с одиночным модулем ESP-12 многократно окупа- ется удобством отладки. Внимание! Цифровые входы микросхемы ESP8266 работают с логическими уровнями трехволь- товой логики. Подача на цифровой вход сигнала с уровнем пятивольтовой TTL- логики может привести к выходу микросхемы из строя. Подача на аналоговый вход
Платформа NodeMCU для Интернета вещей 201 АЦП напряжения, превышающего напряжение питания, немедленно выведет из строя этот вывод или микросхему целиком. Тщательно контролируйте диапазон напряжений аналоговых сигналов. При использовании периферийных модулей с напряжением питания +5 В обязательно применяйте согласование уровней. Это относится и к конвертерам USB-UART. На плате NodeMCU DevKit уже установлены защитные резисторы в цепях TXD и RXD последовательного порта UART, а также входной делитель напряжения АЦП. 10.1.2. Подключение отладочной платы к компьютеру Постарайтесь определить, какая микросхема конвертера USB-UART установлена на вашей отладочной плате. Скорее всего, это FT232, СР2102 или СН340 (СН341). Если драйвер виртуального СОМ-порта для нужной микросхемы еще не установ- лен, скачайте и установите его. После подключения и распознавания устройства в системе появится новый вирту- альный СОМ-порт (рис. 10.3). Запомните номер этого порта. v Щ Парты (СОМ и LPT) jp ЕСР-порт принтера (LPT1) I Silicon Labs CP210x USB to UART Bridge (COM3) 1 Последовательный порт (С0М1) Рис. 10.3. Виртуальный СОМ-порт в системе В некоторых версиях Windows после подключения отладочной платы с прошивкой NodeMCU в системе вместо виртуального порта (или вместе с ним) появляется трекбол Microsoft BallPoint. Операционная система будет воспринимать поток дан- ных от платы как управляющие сигналы трекбола, и курсор начнет хаотически перемещаться по экрану, иногда имитируя нажатия кнопок мыши. Чтобы устранить это недоразумение, внесите небольшое изменение в реестр Windows. Для чего запустите системную утилиту Regedit, откройте ветку реестра: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\sermouse и измените значение параметра start с з на 4. Перезагрузите компьютер. Теперь трекбол в системе появляться не будет. 10.1.3. Обновление прошивки NodeMCU В зависимости от поставщика, отладочные платы и модули ESP после покупки могут содержать неизвестную версию прошивки NodeMCU, могут быть прошиты АТ-прошивкой, поддерживающей работу модуля в режиме моста Wi-Fi-UART, или вообще не иметь прошивки. Прошивка NodeMCU постоянно обновляется, в ней появляются новые функциональные модули и устраняются ошибки. Поэтому начи- нать работу следует с записи в отладочную плату самой свежей версии прошивки. Программная часть платформы NodeMCU основана на фирменном NONOS-SDK от производителя микросхем ESP8266. Производитель тоже регулярно обновляет вер-
202 Глава 10 сии SDK, устраняет старые ошибки и допускает новые. Иногда возникают сложно- сти с совместимостью версий SDK и приходится приложить дополнительные уси- лия. Это может вызвать затруднения у неопытных пользователей. Отнеситесь к инструкции по обновлению прошивки внимательно, в ней нет ненужных действий! 1. Скачайте приложение для записи прошивок ESP8266Fasher по адресу: https://github.com/nodemcu/nodemcu-flashei7. В зависимости от разрядности операционной системы, выберите для скачивания файл из папки Win32/Release или Win64/Release. 2. Скачайте приложение терминала последовательного порта Termite S232 Terminal по адресу: http://www.compuphase.com/software_termite.htm. 3. Скачайте приложение для разработки и отладки пользовательских программ ESPlorer IDE по адресу: http://esp8266.ru/esplorer-ide-esp8266/. 4. Мультиплатформенное приложение ESPlorer запускается в среде Java. Если Java еще не установлена на вашем компьютере, скачайте установочный файл с сайта Oracle: https://java.com/ru/download/. Этих инструментов достаточно для работы. Теперь пора загрузить в плату прошив- ку NodeMCU и проверить работоспособность платы и объем встроенной памяти. Пользователи собирают прошивку самостоятельно, исходя из своих потребностей. Конструктор прошивок Прошивка NodeMCU построена по модульному принципу. Каждый функциональ- ный модуль отвечает за определенный набор функций. Например, за работу с пор- тами ввода/вывода, определенными датчиками или флеш-памятью. В этом смысле функциональные модули NodeMCU похожи на библиотеки Arduino, которые пред- назначены для работы с EEPROM и периферийными устройствами. Перед тем как начать разработку прикладных программ, ознакомьтесь с подробным описа- нием функциональных модулей на сайте документации NodeMCU по адресу: http://nodenicu.readthedocs.io/en/master/. В этом справочнике вы найдете важные нюансы. Например, узнаете, что за работу с прерываниями отвечает стандартный модуль GPIO. Описание модулей и их функций постоянно дополняется. Разработано множество модулей NodeMCU. Если все модули включить в одну прошивку, она займет слишком много места в памяти. Поэтому, начиная с версии NodeMCU 1.4.0, прошивку следует собирать самостоятельно из нужных функ- циональных модулей при помощи облачного сервиса. В этом нет ничего сложного, но следует учитывать, какие модули будут задействованы в вашей программе, и при необходимости пересобирать прошивку в другом составе. Облачный сервис расположен по адресу: https://nodemcu-build.com/. Зайдите на сервис и введите свой адрес электронной почты. На этот адрес вы потом получите ссылки для скачивания двух вариантов прошивки: с целочисленной математикой и с поддержкой плавающей точки. Далее нужно выбрать ветку релиза прошивки: master или development. В первом случае вы получите прошивку на основе прове- ренного стабильного релиза, как минимум, двухнедельной давности. Во втором
Платформа NodeMCU для Интернета вещей 203 случае вы получите версию, находящуюся в процессе активной разработки, самую свежую, но с большей вероятностью незамеченных ошибок. Рекомендую оставить опцию master. Ниже располагается секция выбора модулей. Проставьте галочки возле нужных модулей— например, как показано на рис. 10.4. Позже вы сможете собрать про- шивку, которая соответствует вашим потребностям, убирая или добавляя модули по своему усмотрению. В описании практических примеров мы будем указывать, какие модули необходимо подключить для того или иного проекта. Выбрав нужные модули, нажмите кнопку Start your build в нижней части страницы. Вскоре вы получите два письма. В первом будет подтверждение заявки. Второе придет через 5-20 минут и будет содержать ссылки на две версии прошивки: с под- держкой вычислений с плавающей точкой (слово float в названии файла) и с цело- численной математикой (слово integer в названии файла). Скорость сборки прошив- ки зависит от загруженности сервиса. Файлы, доступные по ссылкам, хранятся сутки. Скачайте файлы прошивок и сохраните их в отдельном каталоге. ; Select modules to include j #' ADC Ш ADXL545*S' ; AM2320 Ж .„■. AmiO2i£ #. mm j BME280SC # 8MP085C£ Ф CJSOHM Co АРШ : crypto ££ # DHTiCi; . : encoder 'Ж •+i end user setup Щ у (Me Ш*] •„ 6РЮШ »; ! HMC5863L ikW Ф НТТРШЗ C: HX71I Ый ^; PC Ш s .:■ 13G4200DiiIi ..; mDMSilli .i MQTT ШЛ #; node Ш y- 1-vvireXi y-. PQf.J ;Л; ..: perf Ш: У PVVM 1С ...» RC fiio docs) : i rotarv ;B': 1",( RTC ?ifo :";C .. RTC mem CC RTC time C? :,.: Sigma-detta ■£& у; sntpci ^# SPI :£?.' • struct tin ; ■ Sivtiecicc TM1829 »ib' ■f: timer Ш : TSL2561m ■< иесэш): у: UART ir.Ui /; UCGivU' У WiF!!::K! ;,,,; WS2801 a.ii ■,' WS2812 Ш Рис. 10.4. Пример набора функциональных модулей для сборки прошивки NodeMCU Подключите плату к компьютеру и запустите приложение ESP8266Flasher. Обычно оно автоматически опознает последовательный порт, к которому подключена плата NodeMCU. Если обнаружение не сработало, выберите порт вручную. Перейдите на вкладку Config. В первой строке нажмите на значок шестеренки и выберите файл прошивки, которую недавно собрали (рис. 10.5). В данном случае используйте вер- сию с поддержкой плавающей точки, она пригодится для обучающих примеров. Для других проектов более подходящей может оказаться версия с целочисленной математикой. Вернитесь на вкладку Operation и нажмите кнопку Flash. Синий светодиод на пла- те должен начать быстро мигать.
204 Глава 10 Рис. 10.5. Выбор файла прошивки для записи BhhmahheI Если вы используете самодельную плату без функции автоматического сброса, то переведите ее в режим программирования вручную: отключите питание платы, со- едините вывод GPIO0 с общим проводом, подайте питание, отключите вывод GPIO0. После этого можете нажимать кнопку Flash. Примерно через минуту запись прошивки будет завершена. Ничего не делая с пла- той, запустите программу терминала порта и откройте порт, к которому подклю- чена плата. Теперь нажмите кнопку сброса на плате. Если прошивка обновилась нормально, она выдаст в терминал короткий символьный «мусор» и сообщение: Formatting file system. Please wait... Обязательно дождитесь окончания формати- рования, которое длится около 30-40 секунд. Если автоматическое форматирование не запустилось, значит, файловая система уже была создана предыдущей версией прошивки. В таком случае желательно отформатировать файловую систему прину- дительно командой file. format (), отправив ее из терминала. Возможная проблема: сбой обновления прошивки При первой загрузке прошивки вы можете столкнуться с небольшой проблемой. Дело в том, что в память устройства по строго определенному адресу записывается небольшой файл конфигурации SDK esp_Jnit_data_default.bin, в котором содержится стартовая конфигурация системы. Содержимое этого файла периодически меняется при выходе новой версии SDK от производителя микросхемы ESP8266, и должно соответствовать версии прошивки NodeMCU. Теоретически, при записи новой прошивки файл конфигурации должен заменяться новым либо создаваться автоматически, если он отсутствует. Но на практике заме- на происходит не всегда, и в памяти устройства может остаться старый файл кон- фигурации. Это приводит к тому, что после обновления прошивки она не стартует нормально, а выдает в последовательный терминал бесконечный символьный
Платформа NodeMCU для Интернета вещей 205 «мусор», иногда мигая синим светодиодом на плате. В таком случае вам поможет принудительное обновление файла конфигурации вручную. Благо, это достаточно сделать один раз для текущей версии, а затем обновлять только файл прошивки NodeMCU. Чтобы узнать номер версии прошивки, которую генерирует облачный сервис, зай- дите в хранилище релизов по адресу: https://github.com/nodemcu/nodemcu- firmware/releases. Самый свежий рабочий релиз NodeMCU будет помечен флаж- ком Latest release. Запомните номер версии. Затем зайдите на сайт производителя по адресу: https://espressif.com/en/support/ download/sdks-demos и найдите там ссылку, название которой содержит номер версии SDK, совпадающий с номером версии NodeMCU. На момент работы над книгой актуальной была версия прошивки 2.0.0. Скачайте архив с фирменным SDK, распакуйте его, в папке bin найдите файл espjnit_data_default.bin и скопируйте в папку с вашей новой прошивкой. За время подготовки книги к печати наверняка будут выпущены новые версии SDK и NodeMCU. Следует помнить правило: версия SDK, из которой вы извлекаете файл конфигура- ции, обязательно должна совпадать с версией NodeMCU. Учтите, что при смене версии NodeMCU и файла конфигурации будет автоматически отформатирована файловая система, и вы потеряете все скрипты, записанные вами в память устрой- ства. Снова запустите приложение ESP8266Flasher и перейдите на вкладку Config. В первой строке нажмите на значок шестеренки и выберите новый файл прошивки, которую вы собрали и скачали по ссылке из облачного сервиса. Адрес начала запи- си: 0x00000. Во второй строке таким же способом выберите новый файл конфигу- рации из патча SDK (рис. 10.6). Обязательно поставьте галочку слева от второй строки! Адрес записи файла конфигурации зависит от объема памяти модуля. Рис. 10.6. Принудительная запись файла конфигурации
206 Глава 10 Помните, мы проверяли объем памяти через запрос системной информации о пла- те? Теперь эти данные пригодились. В зависимости от фактического объема памяти выберите один из адресов для файла конфигурации: ♦ 512 Кбайт — 0х7С000 (модули ESP-01, -03, -07 и т. д.); ♦ 1 Мбайт — OxFCOOO (модули ESP8285, PSF-A85); ♦ 2 Мбайт — OxlFCOOO; ♦ 4 Мбайт— 0x3FC000 (модуль ESP-12E, отладочные платы NodeMCU DevKit, WeMos). На вкладке Advanced должен быть выбран правильный объем памяти. Опция SPI Mode принимает значение DIO для 4 Мбайт и QIO — для меньших объемов па- мяти. Запишите прошивку и файл конфигурации в плату. После завершения записи вновь запустите программу терминала и установите скорость порта 115200. Нажмите кнопку Reset на плате — в окне терминала должна появиться надпись: Formatting file system. Please wait... Обязательно дождитесь окончания форматирования, кото- рое длится около 30-40 секунд. Если автоматическое форматирование не запусти- лось, значит, файловая система уже была создана предыдущей версией прошивки. В таком случае желательно отформатировать файловую систему принудительно командой file. format (). Если не удалось с первой попытки обновить прошивку, уберите галочку напротив второй строки с патчем, повторно загрузите прошивку и дождитесь, пока завер- шится форматирование файловой системы. Теперь нужно проверить фактический объем флеш-памяти отладочной платы. По- купая недорогие модули в Китае, вы не можете быть уверены, что получите модуль с оговоренным объемом памяти. Причем реальный объем может'быть не только меньше, но и больше ожидаемого — приятный сюрприз! Введите в нижней строке терминала команду: = node.info() и нажмите кнопку Send. В окно терминала будет выведена информация о системе (рис. 10.7). Первые три числа— это номер версии прошивки. В моем случае — это 2.0.0. Далее следует идентификатор чипа микросхемы ESP8266, идентификатор чипа флеш-памяти, объем флеш-памяти в килобайтах, режим работы флеш-памяти и ее тактовая частота в герцах. В моем модуле объем памяти 4096 Кбайт или 4 Мбайт. В вашем модуле объем памяти может быть иным. Запомните его, это при- годится при обновлении прошивки и оценке свободной памяти для файловой сис- темы. Для распечатки результата команды вместо директивы print () можно использовать знак равенства. Например, вместо команды print (node, info о) в строку ввода можно ввести команду =node. info (). Это быстрее и удобнее. Итак, вы успешно прошили свою отладочную плату и заставили ее выполнить пер- вую команду на языке Lua. Теперь закрепим успех и попробуем программно управ-
Платформа NodeMCU для Интернета вещей 207 лять синим светодиодом на плате модуля ESP-12. На всех модулях он по умолча- нию подключается к аппаратному порту GPIO2, которому в системе обозначений NodeMCU (см. рис. 10.2) соответствует номер D4. В терминале поочередно введите следующие команды: gpio.mode(4, gpio.OUTPUT) gpio.write(4, gpio.LOW) gpio.write(4, gpio.HIGH) Первая команда переключает цифровой порт GPIO2 (4) в режим вывода. Вторая — переводит вывод в режим низкого уровня. При этом зажигается светодиод, потому что он подключен анодом к линии питания +3,3 вольт, а катодом— к выводу GPIO2. Третья команда возвращает высокий уровень на вывод и гасит светодиод. Termite 3.1 iby Сотру Phase) COM5 115200 taps, 8N1, no handshake I Settings Clear About Close > « node.mfoQ Рис. 10.7. Стартовое окно после выполнения команды: = node. info () Поздравляю! Аппаратная часть платформы полностью готова к разработке проек- тов. Пора приступать к освоению инструментов разработки. 10.2. Среда разработки ESPIorer IDE Это универсальное кроссплатформенное приложение предназначено для работы с прошивками NodeMCU, MicroPython и АТ-прошивками устройств на базе SoC ESP8266, а также с модулями RN2483 компании Microchip. Оно содержит встроен- ный редактор скриптов и множество настроек и команд для работы с ресурсами отлаживаемого устройства (рис. 10.8). Напоминаю, что для запуска ESPIorer требу- ется установить на компьютер движок Java. Для запуска программы откройте файл ESPIorer.jar, щелкнув на нем двойным щелч- ком. Иногда файлы с расширением jar ассоциированы в компьютере с одной из про- архиваторов: WinRAR, WinZIP или 7Zip. В этом случае откройте настройки
208 Глава 10 архиватора и в настройках ассоциации файлов уберите галочку напротив расшире- ния jar. Для запуска приложения на компьютере с Mac OS или Linux наберите в командной строке: sudo Java —jar ESPlorer.jar , t'...' SL ', fals -••^t.ir(^( t.t•')?№, s, fi, I» i .:} Рис. 10.8. Приложение ESPIorer IDE: подключена отладочная плата NodeMCU Наверняка вам не терпится скорее запустить первую программу на языке Lua? Сейчас мы это сделаем, а остальные настройки и функции IDE рассмотрим позд- нее. Подключите отладочную плату к компьютеру. Откройте вкладку Settings и отклю- чите опцию Autodetect firmware — она не работает с новой прошивкой и лишь приводит к ненужной задержке старта. Выберите нужный порт и задайте скорость подключения 115200. Нажмите кнопки DTR и RTS, чтобы в момент открывания порта автоматически сформировался сигнал сброса процессора. Нажмите кнопку Open. Если автоматическая перезагрузка платы не произошла, нажмите кнопку сброса на плате или кнопку Restart ESP на вкладке Command. После перезагрузки окно программы должно выглядеть так, как на рис. 10.8. Теперь напишем и запустим программу, которая будет один раз в секунду мигать синим светодиодом, встроенным на отладочной плате. Если вы используете модуль ESP без встроенного светодиода, необходимо подключить внешний светодиод че- рез резистор с сопротивлением 220 Ом к выводу GPIO2. Введите в левом окне код программы (листинг 10.1).
Платформа NodeMCU для Интернета вещей 209 light=O pin=4 gpio.mode(pin, gpio.OUTPUT) tmr.alarm(1, 1000, 1, function!) if light==0 then light=l gpio.write(pin, gpio.HIGH) else light=0 gpio.write(pin, gpio.LOW) end end) Сохраните программу в файле с именем init.lua и нажмите кнопку Save to ESP — скрипт будет построчно перенесен в память устройства и запущен на исполнение. Процесс переноса и запуска отобразится в окне терминала, светодиод начнет мигать. Мы только что создали в файловой системе NodeMCU стартовый файл init.lua, кото- рый автоматически извлекается из флеш-памяти и запускается при перезагрузке устройства. В тексте программы вы видите незнакомую функцию tmr. alarm о. Это встроенная функция таймера. Функциональный модуль таймера использует вложенную функ- цию обратного вызова. Понятие функции обратного вызова мы рассмотрим в разд. 10.5.11. Сейчас же вам достаточно знать, что таймер номер 1 раз в 1000 мил- лисекунд вызывает срабатывание вложенной функции, переключающей состояние светодиода на противоположное. Тело функции следует сразу за объявлением function (). Справа от окна терминала появилась кнопка с именем файла. Чтобы удалить файл, наберите в строке ввода терминала команду: file.remove("init.lua") или щелкните правой кнопкой мыши на кнопке с именем файла и выберите в кон- текстном меню опцию Remove. Обратите внимание, что после удаления файла программа продолжает работать, светодиод мигает. Это связано с тем, что файлы скриптов хранятся во внешней флеш-памяти модуля, а для выполнения извлекаются, проходят предкомпиляцию и помещаются в оперативную память SoC ESP8266. Если устройство перезагрузить, светодиод мигать перестанет. Свободной оперативной памяти мало и единовре- менно можно запустить один скрипт объемом около 110 строк. Поэтому большие программы принято разбивать на законченные функциональные фрагменты в виде отдельных файлов и запускать их по мере необходимости. Итак, вы убедились, что ваше отладочное устройство работает, и даже освоили ввод и запуск простых программ. Теперь настало время подробнее изучить ESPlorer
210 Глава 10 IDE. Главное окно программы разделено на две части. Слева находится панель редактора, справа — панель терминала и инструменты управления файловой сис- темой. Панели можно поочередно скрывать и работать только с редактором или только с терминалом. В верхней части панели терминала расположены инструменты управления подклю- чением (рис. 10.9): ♦ Выбор активного порта (1). К сожалению, перечень доступных портов не об- новляется автоматически при подключении устройства. Это проблема многих приложений, работающих на Java. Если вы подключаете новое устройство после запуска приложения ESPlorer IDE, то нажмите кнопку Refresh (2), чтобы порт появился в списке. Рис. 10.9. Инструменты управления подключением ESPlorer IDE ♦ Управление линиями DTR и RTS (3). Если вы используете плату NodeMCU DevKit или WeMos D1, то приложение ESPlorer сможет управлять выводами DTR и RTS встроенного на плату конвертера USB-UART. При установленном подключении нажмите и отпустите кнопку RTS. Это равносильно нажатию ап- паратной кнопки Reset на плате, и она перезагрузится. Если при установленном подключении нажать обе кнопки (3) и оставить их нажатыми, то в дальнейшем плата будет автоматически перезагружаться при первом подключении. ♦ Группа флажков (4) управляет автопрокруткой, показывает в тексте терминала символы конца строки EOL, управляет автоматическим добавлением символа возврата каретки CR и перевода строки LF в конец строки, отправляемой в уст- ройство, а также отображением панелей редактора и терминала. Если вы поста- вите галочку в поле Hide Terminal, то вернуть отображение терминала сможете только в главном меню View или сочетанием клавиш <Alt>+<F2>. Справа от окна терминала расположены кнопки управления файловой системой SPIFFS во флеш-памяти устройства (см. рис. 10.8): ♦ кнопка Format форматирует область хранения пользовательских файлов, не за- трагивая прошивку NodeMCU. Все находящиеся в пользовательской области памяти файлы при этом будут необратимо уничтожены; ♦ по нажатию кнопки FS Info выводится информация о свободной и занятой флеш-памяти устройства в целом;
Платформа NodeMCU для Интернета вещей 211 ♦ кнопка Reload обновляет и выводит в окно терминала список файлов, сохранен- ных в устройстве и данные о занимаемой памяти. После нажатия кнопки Reload под ней появляются кнопки с названиями отдельных файлов. Нажатие левой кнопки мыши на кнопке с именем файла запускает программу на выполнение. По нажатию правой кнопки открывается контекстное меню, содер- жание которого зависит от типа файла. Если это текстовый файл скрипта с рас- ширением lua, то откроется меню, показанное на рис. 10.10. Рис. 10.10. Меню управления файлами в памяти устройства Щелкните на пункте меню Compile. Файл пройдет предкомпиляцию и будет сохра- нен с расширением Ic. В окне терминала вы можете увидеть, что появился еще один файл. Его размер больше, чем у исходного, но выполняться он будет быстрее. Под окном терминала расположена строка ввода текстовых команд. Для удобства работы она содержит шаблоны часто употребляемых команд в раскрывающемся списке. Над панелью редактора расположено главное меню (рис. 10.11). Кроме обычных пунктов для работы с файлами и текстом, оно позволяет настроить внешний вид интерфейса программы, а также содержит полезные ссылки на тематические ресур- сы и магазины для покупки модулей и компонентов. Рис. 10.11. Меню панели редактора программ ESPIorer IDE
212 Глава 10 Приложение ESPlorer IDE и прошивка NodeMCU активно разрабатываются, поэто- му не всегда полностью совместимы. На момент подготовки книги некоторые функциональные кнопки отправляли в устройство команды с синтаксическими ошибками, а некоторые не работали вовсе. Периодически проверяйте обновления программы. В первом ряду вкладок мы выбираем платформу, с которой будем работать: ♦ NodeMCU & MicroPython — это скриптовые языки программирования, для них задействован одинаковый инструмент редактирования и отладки; ♦ AT-based — существует несколько вариантов прошивки модулей ESP, основан- ных на технологии работы с АТ-командами. Это текстовые команды, которые начинаются с префикса AT, далее следует команда и, при необходимости, пара- метры. Команды отправляет в устройство внешний микроконтроллер, a SoC ESP8266 последовательно выполняет их. В этой книге мы не рассматриваем ра- боту с АТ-командами, поскольку технология не позволяет исполнять автоном- ные пользовательские программы непосредственно внутри SoC; ♦ RN2483 — это модуль Wi-Fi производства компании Microchip. Описание рабо- ты с этим модулем также выходит за рамки книги. Состав второго ряда вкладок зависит от того, какая вкладка выбрана в первом ряду. Мы будем работать только с набором для NodeMCU. ♦ На вкладке Scripts пояснений требуют кнопки Block и Line. Первая отправляет в устройство для немедленного исполнения выделенный блок кода программы, а вторая — только одну строку, в которой находится курсор. ♦ Вкладка Commands (рис. 10.12) содержит инструменты для ввода наиболее час- тых стандартных команд NodeMCU: • Restart ESP— перезагрузка отладочной платы, равносильная нажатию на ней кнопки Reset. Работает только на платах, содержащих конвертер USB- UART и цепи сброса; • Chip Ш — выводит в терминал цифровой идентификатор микросхемы; • Heap — показывает свободный объем ОЗУ микросхемы ESP8266 в байтах, выделенный системой для выполнения программ пользователя; • Sleep 100... — служит для перевода микросхемы в режим глубокого сна deep sleep на 10 секунд по команде node.dsieep(ioooo). Чтобы устройство могло выйти из сна, вывод сброса PIN32(RST) должен быть соединен с выводом PIN8(GPIO16); • кнопка tmr.stop совместно с полем выбора номера таймера от 0 до 6 предна- значены для принудительной остановки соответствующего таймера; • кнопка List files выводит в терминал перечень файлов во флеш-памяти. А Будьте осторожны с идентификаторами! С параметром Chip ID сложилась запутанная ситуация, которую не могут прояснить даже сотрудники фирмы-производителя микросхем ESP8266. Пользователи перио- дически сталкивались с тем, что Chip ID совпадал у разных микросхем из одной про-
Платформа NodeMCU для Интернета вещей 213 изводственной партии. Производитель рекомендовал использовать в качестве уни- кального идентификатора МАС-адрес микросхемы. Затем выяснилось, что иногда Chip ID в явном виде совпадает с последними шестью цифрами МАС-адреса. Позд- нее Chip ID стал совпадать с десятичным представлением последних трех бай- тов МАС-адреса. Например, МАС-адрес моей отладочной платы 5C:CF:7F:07:53:36, a Chip ID 480054 является десятичной записью шестнадцатеричного числа 075336h. Если вам необходимо однозначно идентифицировать устройство, используйте пол- ный МАС-адрес. ЕГО МОЖНО узнать При ПОМОЩИ КОМаНДЫ print (wif i . sta. getmac () ). В любом случае рекомендуется убедиться в уникальности идентификаторов перед использованием нескольких устройств внутри одной сети. Рис. 10.12. Инструменты ввода стандартных команд NodeMCU На вкладке WiFi расположены инструменты для работы с беспроводной сетью: • Connect to АР — подключение к местной беспроводной точке доступа. Имя (SSID) и пароль точки доступа надо ввести в поля над кнопкой; • Scan network — сканирует доступные беспроводные сети и выводит их спи- сок; • Connect and send — соединение с нужным сайтом через заданный порт и от- правка ему строки запроса. Адрес сайта, порт подключения и строку запроса надо предварительно ввести в поля формы. Вкладка Snippets предназначена для редактирования сниппетов текста про- грамм. Нажмите кнопку с номером сниппета, введите его имя, фрагмент скрипта и сохраните его кнопкой Save. Если в меню View включить отображение кнопок сниппетов, то на кнопке будет написано название сниппета, которое вы ввели. По нажатию на кнопку Run или на кнопку под окном терминала сниппет будет
214 Глава 10 выгружен в устройство и запущен на выполнение. Для удаления сниппета из хранилища удалите текст программы из окна и сохраните пустой сниппет. ЧТО ТАКОЕ СНИППЕТ? В программировании сниппетом называют заранее приготовленный и сохраненный фрагмент исходного кода или набор команд операционной системы. Чтобы не терять время на поиск и копирование нужных текстовых фрагментов из файла, сниппеты обычно хранятся во внутреннем хранилище среды разработки, извлекаются при за- грузке приложения и запускаются одним нажатием кнопки или пункта меню. ♦ Вкладка Settings содержит опции для настройки сохранения и загрузки файлов: • Select firmware — выбор варианта прошивки, с которой вы работаете; • Serial Port: D Use custom serial port name — задает имя порта в Linux-системах. При этом отключается сканирование портов компьютера; D Autodetect firmware — приложение пытается автоматически определить версию прошивки и задать настройки последовательного порта. С новыми прошивками NodeMCU функция не работает. Чтобы не терять время на задержку автоопределения, рекомендую эту опцию отключить; п Command Echo — повтор команд, отправленных через терминал. Иногда это бывает полезно при просмотре лога терминала. • Data scrollback — задает максимальный размер лога и текста, прокручивае- мого в окне терминала. При превышении размера старые данные стираются; • Other — настройки автосохранения программы на диск и в память устройст- ва, а также цветовая схема редактора; • Send: D Turbo Mode — режим отправки файлов и команд в устройство с возмож- ностью настроить максимальное время ожидания ответа от устройства, а также задержку отправки следующей строки после получения ответа; D Dumb Mode — «тихий» режим передачи файла. Ответ от устройства не ожидается. 10.3. Пакет разработки Lua for Windows Если вы хотите иметь возможность изучать язык Lua, не используя отладочную плату NodeMCU, то можете установить на компьютер пакет разработки и выполне- ния программ Lua for Windows. Он состоит из редактора-отладчика SciTE, прило- жений для запуска Lua в окне терминала, а также примеров и документации. Разумеется, при помощи этих инструментов вы сможете запускать программы только на «чистом» языке Lua. Эти программы не должны содержать обращений к аппаратным ресурсам ESP8266 или к специфическим модулям прошивки NodeMCU. Но для изучения общих основ языка Lua, особенно во время ожидания посылки с оборудованием, эти программы очень удобны.
Платформа NodeMCU для Интернета вещей 215 Скачайте свежую версию установочного файла по адресу: https://github.com/ rjpcomputing/Iuaforwindows/releases. После установки запустите редактор SciTE (рис. 10.13). • п х | I File .Edit Search View look Opticns Language Buffers Debug Help j "copyrTglri: TcT"Ti§4'~2dl2'"Lua"7or'q7 "p J; cd» eh"г and edit also available Koh'SSd-O j Saved 26.09,2016 22:48:57 j [INS) [CR+lf j j S Рис. 10.13. Редактор-отладчик SciTE Выберите пункт меню Tools | Start Interactive Lua, чтобы открыть консоль интер- претатора Lua в нижней части окна. Вы можете вводить команды непосредственно в это окно, и они будут сразу выполняться. Введите код программы. Пока вы не сохраните его с расширением lua, вы не смо- жете запустить программу. После сохранения нажмите клавишу <F5> и наблюдай- те результаты работы программы в консоли. При помощи кнопок отладчика на па- нели меню вы можете выполнять программу пошагово и следить за значениями переменных. 10.4. Язык программирования Lua — освоим за один вечер Программы для NodeMCU пишут на языке eLua (embedded Lua). Это специальная реализация языка Lua 5.1, оптимизированная для встраиваемых (embedded) систем. Кроме того, в реализации этого языка для NodeMCU отсутствуют некоторые встро- енные функции. Чтобы понять принцип работы программной части платформы, следует рассмотреть ее структуру.
216 Глава 10 Ядро платформы NodeMCU состоит из набора фирменных библиотек SDK от про- изводителя SoC ESP8266. Интерпретатор языка Lua переводит текстовые команды скрипта в обращения к библиотекам SDK и при необходимости возвращает ответ- ные данные. Иногда программисты называют такие интепретаторы «оберткой» (wrapper) по отношению к SDK. Одна команда скрипта может быть преобразована в последовательное обращение к различным функциям нескольких библиотек SDK. Эта большая и сложная работа выполняется «за кадром», а программист использует простые и понятные текстовые команды. Кроме интерпретатора Lua существуют и развиваются прошивки MicroPython (интерпретатор языка Python) и Smart.js (ин- терпретатор JavaScript). Это тоже обертки для фирменного SDK. Если вы освоите работу с NodeMCU, то перейти на MicroPython или Smart.js будет очень легко. Языки встраиваемых систем всегда имеют ограничения возможностей. Это следст- вие компромисса между скромными аппаратными ресурсами и потребностями пользователя. С одной стороны, производитель SoC ESP8266 предоставляет сторонним разработ- чикам инструмент в виде готовых бинарных библиотек кода. К функциям библио- тек можно обращаться при помощи API (Application Programming Interface, интер- фейс для прикладного программирования). Иными словами, все функции системы реализованы в библиотеках SDK, а сторонним разработчикам остается пользовать- ся готовыми решениями. Это очень удобно, однако проблема в том, что производи- тель SoC ESP8266 не открывает доступ к исходному коду библиотек и не позволяет их модифицировать или дополнять. Разработчики сторонних приложений, таких как NodeMCU, могут использовать только те функции, которые заложены в SDK производителем микросхемы, а также вынуждены мириться с ограничениями и ошибками в этих функциях. Разработчики прошивки NodeMCU должны принимать специальные меры по эко- номии оперативной памяти. Так, например, в NodeMCU отсутствует библиотека math, которая вычисляет тригонометрические функции, квадратный корень и про- чие функции, занимающие большой объем памяти. Для таких функций требуется обязательная поддержка вычислений с плавающей точкой. Но прошивка платфор- мы NodeMCU всегда выпускается в двух вариантах: с поддержкой чисел с плаваю- щей точкой и без нее. Прошивка без поддержки плавающей точки заметно эконо- мит память, с ней не конфликтуют библиотеки поддержки некоторых стандартных периферийных датчиков. Внимание: асинхронный режим выполнения программ! NodeMCU — это платформа, работающая с аппаратными ресурсами. Все, что про- исходит с аппаратными ресурсами, с точки зрения программирования является со- бытиями. Если у вас есть опыт программирования на языках высокого уровня, то наверняка вы привыкли к процедурному стилю программирования. Опасайтесь со- вершить частую ошибку при написании встроенных приложений для физических устройств. Не думайте, что команды вашей программы будут выполняться мгно- венно и в том порядке, как вы их указали! Это не так! Например, если вы дали команду модулю Wi-Fi соединиться с точкой доступа, то следует доедаться, пока он действительно соединится (если вообще соединится!) и получит IP-адрес. Только после этого можно давать команду на передачу HTTP-запроса. Не забывайте, что
Платформа NodeMCU для Интернета вещей 217 встроенные приложения работают в реальном мире, где ничего не происходит мгно- венно и идеально в нужный момент. Мир, в котором мы живем— асинхронный. Представьте, что вам надо надеть футболку, джинсы и кроссовки. Вы сначала на- деваете кроссовки, потом футболку и лишь затем натягиваете джинсы. Неудобно? Да, но кроссовки располагались ближе, поэтому команда «надеть кроссовки» была физически реализована раньше, чем команда «надеть джинсы». Такова логика асин- хронного интерпретатора. Кроме того, интерпретатор вынужден оптимизировать код программы для эконо- мии памяти. Если не осознавать специфику работы встроенных программ, можно совершить ошибки, которые трудно выявить. Например, рассмотрим такой фраг- мент кода: node.restart () for i = 1, 20 do print("not quite yet — ",i) end В первой строке стоит команда перезагрузки системы. Вы можете ожидать, что следующий за этой командой цикл for.. .do никогда не будет выполнен, потому что устройство перезагрузится сразу, после первой же команды. А теперь введите этот фрагмент кода в окно редактора ESPlorer и запустите на выполнение в реаль- ной системе. Посмотрите, что успело появиться в окне терминала до перезагрузки. Вас ждет чрезвычайно неприятный сюрприз. Вот еще один простой пример. Вы открыли соединение с сервером, чтобы передать ему различные данные при помощи метода socket:send. Если расположить два об- ращения к этому методу в соседних строках программы, то это вовсе не значит, что сначала будет выполнена передача данных в первой строке, а затем во второй. На самом деле оба запроса всего лишь встанут в очередь на выгрузку данных! Интер- претатор Lua выполнит их, когда освободится от других задач. Если таких запросов поступит много, то память переполнится, и система рухнет со статусом Panic. Иными словами, команды выполняются асинхронно по отношению к порядку сле- дования в коде. В примерах к описаниям функциональных модулей вы увидите, как реализуется безопасный асинхронный режим исполнения встраиваемых приложе- ний. К сожалению, ошибки асинхронного программирования встречаются даже в примерах из книг про NodeMCU. Будьте внимательны. 10.4.1. Типы данных В языке Lua используются следующие типы данных: ♦ Nil (ничто) — соответствует отсутствию значения у переменной или отсутствию возвращаемого значения функции. Это особое значение. С ним нельзя выпол- нять арифметические действия или операции сравнения. Чтобы удалить из па- мяти среды переменную, строку, функцию или запись таблицы, им нужно при- своить значение nil; ♦ Boolean (логический) — к этому типу относятся значения false (ложь) и true (истина). При выполнении логических операций nil рассматривается как false.
218 Глава 10 Все остальные значения, включая ноль и пустую строку, рассматриваются как true; ♦ Number (числовой)— представляет числовые значения. Если вы используете прошивку с поддержкой чисел с плавающей запятой, то можно указывать дроб- ную часть и необязательный десятичный порядок: 314.1бе-2. В целочисленной версии прошивки попытка задать дробное число вызовет ошибку. Шестнадцате- ричные константы задают при помощи префикса Ох так: Oxde; ♦ String (строковый) — представляет строки, заданные в виде символов, заклю- ченных в одинарные или двойные кавычки. Строки в двойных кавычках интер- претируют escape-последовательности, начинающиеся с символа V Чаще всего, это символы перевода строки \п и возврата каретки \г. Строки в одинарных кавычках игнорируют их. Строка может быть задана при помощи двойных квад- ратных скобок: s = [[sample string]]. В этом случае она обрабатывается как есть, включая все символы, вплоть до табуляции и переноса строки; ♦ Function (функция) — в языке Lua функции могут быть записаны в переменные, переданы в качестве параметра в другие функции, возвращены как результат выполнения функций; ♦ Table (таблица)— представляет набор пар ключ-значение. Ключи и значения могут быть любого типа, кроме nil. Массив — это таблица, ключами которой являются целые положительные числа. Правила работы с таблицами рассмотре- ны далее ъразд. 10.4.4; ♦ Userdata (пользовательские данные) — особый тип данных. Значения этого типа не могут быть созданы или изменены непосредственно в скрипте. Используется в библиотеках расширений для представления новых объектов; ♦ Thread (поток)— соответствует потоку выполнения. На момент подготовки книги в NodeMCU не поддерживался. 10.4.2. Комментарии Комментарии в Lua начинаются с двух знаков «минус» и продолжаются до конца строки: local w = 5 —это однострочный комментарий Если после символов -- идут две открывающие квадратные скобки, это много- строчный комментарий. Он продолжается до пары закрывающих скобок: b = 5 —[[это многострочный комментарий, он завершается на второй строке]] 10.4.3. Переменные и преобразование типов Имена переменных могут содержать буквы, цифры и знак подчеркивания, но не должны начинаться с цифры. Нельзя использовать в качестве имен переменных зарезервированные слова языка. Все имена, начинающиеся с символа подчеркива-
Платформа NodeMCU для Интернета вещей 219 ния, за которым идут заглавные буквы (например, version), также являются заре- зервированными. Язык Lua различает регистр символов. Например, Ledi и ledi — это разные переменные. Чтобы определить переменную в Lua, достаточно присвоить ей значение. Тип переменной в явном виде задавать не нужно — он определяется интерпретатором в соответствии с содержимым. Переменные в Lua бывают глобальными и локальными. Глобальные переменные видны любому скрипту в среде выполнения программ и существуют, пока не будут удалены в явном виде. Глобальная переменная появляется в момент присвоения ей значения. До этого момента обращение к ней по имени не вызовет ошибку, но вер- нет значение nil. По умолчанию переменная считается глобальной. Локальную переменную можно объявить в любом месте скрипта. Для этого перед ее именем надо поставить ключевое слово local. Если не задано значение, то обра- щение к переменной вернет nil. local a — объявляем локальную переменную а, значение nil local b = 1 — объявляем локальную переменную Ь, значение 1 local с, d = 2, 3 — объявляем локальные переменные с и d, значения 2 и 3 Область видимости локальной переменной (область кода, где можно получить дос- туп к значению переменной) начинается от объявления и продолжается до конца блока. Под блоком понимают управляющие конструкции: ♦ if-then, else, for, while, repeat; ♦ тело функции; ♦ фрагмент кода между словами do... end. Локальная переменная, объявленная вне блока, видна до конца скрипта. Старайтесь использовать локальные переменные вместо глобальных. Это позволя- ет избежать замусоривания пространства глобальных имен, которое в виде таблицы хранится в ОЗУ, а также повышает быстродействие. К локальным переменным ин- терпретатор обращается быстрее. В критичных к объему памяти ситуациях рекомендуется определять локальную пе- ременную в начале блока. По окончании использования переменной ее удаляют присвоением значения nil. По окончании работы функции запускают так называе- мый «сборщик мусора» coiiectgarbage (), который перекомпоновывает таблицу имен переменных, удаляя устаревшие переменные и освобождая память. Введите в редакторе ESPlorer текст примера (листинг 10.2) и посмотрите, как меня- ется объем ОЗУ по мере присвоения значений переменным и очистке от них. Объ- ем памяти не обязательно точно возвращается к исходному, т. к. память частично используется для текущих нужд среды. print(node.heap()) s="abc0123456789abc\r\n" print(s)
220 Глава 10 print (node. heap ()) s=nil collectgarbage() print(node.heap()) Переменные типа table и function не содержат данные, а хранят ссылки на соот- ветствующие объекты в памяти. При присваивании, передаче в функцию в качестве аргумента и возвращении из функции в качестве результата объекты не копируют- ся. Копируются только ссылки на них: а = {} — создали таблицу. В переменную а помещена ссылка на эту таблицу b = а — теперь переменная b ссылается на ту же таблицу, что и а а[1] =10 —элементу таблицы с индексом 1 присвоили значение 10 print(а[1]) —на печать будет выведено 10 Ь[1] = 20 print(а[1]) —теперь на печать будет выведено 20 При необходимости Lua автоматически преобразует строку в число и наоборот: а = "10" + 2 —результат равен 12 а = "10" .. 2 —операция слияния строк, результат строка "10+2" а = "beer" + 2 —ошибка, невозможно преобразовать "beer" в число! Значение любого типа может быть явным образом преобразовано в строку при по- мощи стандартной функции tostring (): b = tostring(10) — b равно "10" b = tostring(true) — b равно "true" b = tostring(nil) — b равно "nil" t = {} t[l] = 2156 b = tostring(t[l]) — b равно "2156" e = tostring(t) — e равно "table: 00BCF680" Из последней строки примера видно, что содержимое таблицы функцией tostring о в строку не преобразуется. Вместо этого функция возвращает систем- ный идентификатор таблицы в ОЗУ. Для явного преобразования строки в число применяется функция tonumber (): р = tonumber("10") — р равно 10 р = tonumber("10"..".5") ~ р равно 10.51 р = tonumber(true) —p равно "nil" р = tonumber(nil) —p равно "nil" 1 Работает только в прошивках с поддержкой плавающей точки. В целочисленных прошивках возвра- щает nil.
Платформа NodeMCU для Интернета вещей 221 10.4.4. Работа с таблицами и массивами Рассмотрим создание таблиц и особенности работы с ними. Таблицы не имеют фиксированного количества элементов. В любое время к ним можно добавить про- извольное количество элементов. Для удаления произвольного элемента таблицы достаточно присвоить ему значение nil. t = {} — создали пустую таблицу t[l] = 10 — новое поле с ключом 1 и значением 10 t["food"] = "butter" — новое поле с ключом food и значением butter а = t[l] — переменная а получает значение 10 b = t["food"] — переменная b получает значение butter В случае строковых ключей вместо записи t["food"] можно использовать запись t.food: t = {} t.food = "potato" — присвоили ячейке t["food"] значение "potato" t.drink = "cola" — присвоили ячейке t["drink"] значение "cola" t.drink = "pepsi" — изменили значение ячейки t["drink"] Выражение t.food не равнозначно t[food]. В первом случае представлено поле Таблицы, КЛЮЧОМ КОТОРОГО ЯВЛЯеТСЯ Строка "name" (Т. е. раВНОЗНаЧНО t["name"]). ВО втором случае представлено поле, ключом которого является значение переменной name (равнозначно записи t [name] — без кавычек). Чтобы обратиться к значению поля через имя переменной, эту переменную сначала надо создать: name = "city" — создали переменную name со значением "city" t = {} t[name] = "Moscow" — в ячейку t["city"] поместили значение "Moscow" Таблицу можно заполнить значениями непосредственно при создании. Элементы разделяются запятыми или точкой с запятой: t= {["опе"]="один", ["two"]="nBa", ["three"]="три"} В случае строковых ключей квадратные скобки и двойные кавычки можно не ука- зывать: t = {опе="один", two="n.Ba", three="Tpn"} Эту запись можно упростить еще больше: t.one = "один"; t.two = "два"; t.three = "три" Можно создать таблицу, поля которой тоже являются таблицами: position = { а = {х=10, у=1}, b = {х=15, у=2}
222 Глава 10 Приведенная запись эквивалентна сокращенному коду: position = {} position.а = {х=10, у=1}, position.b = {х=15, у=2} Массив — это таблица, ключами которой являются целые положительные числа. Чтобы создать массив, достаточно перечислить в фигурных скобках значения его элементов: m = {"Ivanov", "Petrov", "Sidorov"} Оператор длины массива возвращает его максимальный индекс (размер массива): print(#m) — будет напечатано число 3 а = m[#m] —присвоили переменной а значение последнего элемента массива m[#m+l] = b —добавили значение переменной b в конец массива m Внимание! Особенности работы с массивами: • В языке Lua массивы индексируются с 1, а не с О!!! • Оператор # рассматривает любой не инициализированный элемент массива (имеющий значение nil) как конец массива. Для корректной работы оператора # необходимо, чтобы массив не содержал пустые элементы. • Если таблица не содержит целочисленные ключи (не является массивом) либо первый элемент равен nil, оператор # возвращает 0. ♦ Для перебора и просмотра всех элементов таблицы или массива можно восполь- зоваться оператором цикла for и функциями pairs () и ipairs (), как показано далее в листинге 10.3. 10.4.5. Условный оператор if Оператор if проверяет истинность заданного условия. Если условие является ис- тинным, выполняется часть кода, следующая за ключевым словом then. В против- ном случае выполняется код, следующий за ключевым словом else. if a > b then print(a) else print(b) end Секция else не обязательная. Вместо вложенных операторов if можно использо- вать конструкцию elseif: if a == I then print("Moscow") — если а равно 1 elseif a == 2 then print("Paris") — если а равно 2 elseif a = 3 then print("Vienna") — если а равно 3
Платформа NodeMCU для Интернета вещей 223 else print("Another city") —если ни одно из перечисленного end 10.4.6. Цикл с предусловием while Оператор while предназначен для организации циклов с предусловием: while <condition> do — тело цикла end Перед каждой итерацией проверяется условие <condition>. Если условие истинно, выполняется тело цикла, затем проверка повторяется. Если условие ложно, цикл завершается, и управление передается оператору, следующему после цикла while. Цикл while с постоянно истинным условием используется для организации беско- нечного цикла. Для досрочного выхода из цикла можно использовать оператор break. Такой метод применяют, если нужно прервать цикл только в случае некоего события, которое может произойти в произвольный момент времени и от самого цикла не зависит. Например, если нужно организовать ожидание поступления тек- стовой команды извне. 10.4.7. Цикл с постусловием repeat Оператор repeat предназначен для выполнения циклов с постусловием: repeat — тело цикла until <condition> Условие проверяется после выполнения тела цикла, поэтому в любом случае тело цикла выполнится хотя бы один раз. Для досрочного выхода из цикла можно ис- пользовать оператор break. 10.4.8 Цикл с оператором for Оператор for предназначен для организации циклов и допускает две формы записи: простую и расширенную. В простой форме оператор использует только числовые переменные. Если шаг равен 1, его можно не указывать: for i = 1, 10 do —цикл от 1 до 10 с шагом 1 print ("i равно If..i) end А Переменная цикла является локальной внутри цикла и после его окончания не опре- ^ делена. Попытка принудительно изменить значение этой переменной внутри цикла приведет к непредсказуемой ошибке.
224 Глава 10 В расширенной форме оператор for имеет вид: for varl, var2, ..., varN in <expression> do — тело цикла end где varl, var2, ..., varN — список переменных, получающих значения на каждом шаге цикла, a <expression> — это функция-генератор значений. Рассмотрим пример вывода на печать всех значений таблицы (листинг 10.3). t= {["опе"]="один", ["two"]=lfnBaff, [ "three" ]="три"} for key, val in pairs(t) do print ("key == "..key.."; val == "..val) end В этом примере pairs о — встроенная функция языка Lua, которая возвращает пару ключ-значение и вызывает встроенную функцию next (), переводя внутренний указатель на следующую запись таблицы. Работа цикла продолжается до тех пор, пока next о не вернет значение nil. Для перебора значений массива предназначена функция ipairs (). 10.4.9. Операторы break и return Оператор break прерывает выполнение циклов while, repeat или for, в теле которых встречается. Управление передается первой инструкции, следующей непосредст- венно за телом цикла (листинг 10.4). а = {-3, 5, 8, 0, 10, 4} — создаем тестовый массив for i = l,#a do — ищем в массиве нулевое значение if a[i] == 0 then — если нашли index = i — сохраняем индекс найденного элемента break —прерываем цикл end end print(index)— выводим индекс найденного элемента на печать Оператор return возвращает результаты из функции или блока: function f(x) return x*3 end Оператор return может просто завершать работу функции или блока, не возвращая никакой результат. Операторы break и return могут быть только последними опе- раторами блока, иначе следующие за ними операторы никогда не выполнятся.
Платформа NodeMCU для Интернета вещей 225 10.4.10. Функции Чтобы определить функцию, нужно указать ключевое слово function и задать имя функции, список аргументов (может быть пустым) и тело функции: function foo(x, у) х = х*2 return х+у end Это определение можно записать другим способом: foo = function (x,y) х = х*2 return х+у end В нашем примере создана функция с именем foo. Обратите внимание, что имя foo принадлежит переменной, в которую помещена ссылка на функцию, но не самой функции. В языке Lua функции анонимны. Когда говорят об имени функции, под- разумевают имя переменной, содержащей ссылку на эту функцию. С такими пере- менными можно работать, как с любыми другими. Можно даже создать таблицу, элементам которой присвоить ссылки на различные функции. Получится таблица функций. Эту хитрость можно использовать, например, чтобы выполнять действия в соответствии с числовыми командами, поступающими извне. Если функция передается в другую функцию в качестве параметра, она может быть безымянной. Если при вызове функции задано меньше входных значений, чем аргументов функ- ции, то последние аргументы получают значение nil. Если значений больше, чем аргументов, то лишние значения отсекаются. Аргументы функции являются ло- кальными переменными внутри функции. Функция может принимать неопределенное число аргументов. В этом случае пере- чень аргументов должен заканчиваться троеточием: function f (x, у, . . .) end Значения, скрытые за этим троеточием, передаются в функцию через служебную таблицу arg. Поле п этой таблицы содержит число фактически переданных аргу- ментов. Листинг 10.5 демонстрирует пример извлечения произвольного количества значений для обработки внутри функции. function foo(...) for i = 1, arg.n do print(tostring(arg[i])) end end food,2,3)
226 Глава 10 Функции могут возвращать одно или несколько значений или не возвращать значе- ния вообще. Чтобы присвоить возвращаемые значения переменным, достаточно перечислить их через запятую (множественное присваивание): function foo() return 1, 2, 3 end a, b, с = foo() —в результате а = 1, b = 2, с = 3 Если количество возвращаемых значений превышает число переменных, лишние значения отбрасываются. Если количество возвращаемых значений меньше коли- чества переменных, оставшиеся переменные получают значение nil. Функцию можно вызвать как оператор — например: myfunc (). В этом случае все возвращаемые значения будут проигнорированы. 10.4.11. Функции обратного вызова Функция обратного вызова (callback-функция) — это функция, которая передается другой функции в качестве параметра, и та, в свою очередь, вызывает переданную функцию. Фактически, мы передаем не саму функцию, а ссылку на ее определение. На этапе передачи определения передаваемая функция не вызывается. Так как вто- рая функция получила определение функции обратного вызова, то она может вы- звать ее в любое время. Важно понимать, что функция обратного вызова не выпол- няется немедленно! Зачем нужны функции обратного вызова? Дело в том, что язык Lua является асин- хронным. Действия в нем выполняются не тогда, когда поступила очередная коман- да программы, а тогда, когда произошло некое событие. Представьте, что в про- грамме есть функция, которая отправила запрос серверу, и надо обработать ответ. Но сервер не отвечает мгновенно! Функция, отправившая запрос, сначала должна получить ответ. Только после этого она должна запустить функцию обработки отве- та. Функция, которую она запустит, называется функцией обратного вызова. Образно говоря, вызываемая функция оставляет внешней функции свой «телефон- ный номер» и ничего не делает. При наступлении события внешняя функция «пере- званивает» (callback, обратный звонок) вложенной функции и просит начать работу. Так возникло название функций обратного вызова. Вернемся к примеру программы мигания светодиодом с использованием таймера (см. листинг 10.1) и рассмотрим внимательно ее фрагмент: tmr. alarm (1, 1000, 1, function () if light==0 then light=l gpio.write(pin, gpio.HIGH) else light=0 gpio.write(pin, gpio.LOW) end end)
Платформа NodeMCU для Интернета вещей 227 В первой строке фрагмента мы обращаемся к встроенной функции таймера NodeMCU. Мы последовательно задаем номер таймера, продолжительность отсче- та, режим таймера и далее определяем функцию обратного вызова, которая будет запущена по событию срабатывания таймера. Поскольку в нашем примере эта функция полностью определена внутри вызывающей функции, мы не даем ей имя. Мы могли бы определить эту функцию снаружи, в теле основной программы. Но тогда нам пришлось бы дать ей имя и подставить его в функцию таймера. Это зави- сит лишь от вашего удобства при написании и чтении программ. Итак, вы проделали большую работу — изучили основы языка Lua! Теперь можно приступать к работе над проектами.
ГЛАВА 11 Примеры программ и проектов для NodeMCU В этой главе мы рассмотрим примеры проектов, основанных на скриптах Lua. Вы уже должны уметь собирать прошивки NodeMCU с нужными модулями и загру- жать скрипты при помощи оболочки ESPlorer. Если вы пропустили главу 10, то сейчас самое время вернуться к ней и внимательно прочитать разд. 10.1 и 70.2. Предлагаю обойтись в этой главе без традиционных проектов с мигающими свето- диодами и начать освоение NodeMCU с подключения графических дисплеев. Это наглядно, полезно для будущих проектов и просто красиво. Любой любительский проект выглядит намного лучше, если в нем применяется вывод информации на качественный дисплей. За последнее время стоимость малогабаритных OLED- и TFT-дисплеев значительно снизилась. Они успешно конкурируют с традиционны- ми светодиодными и LCD-индикаторами, а по универсальности применения и ка- честву изображения существенно их превосходят. У начинающих пользователей могут возникнуть трудности с применением графических библиотек. Это самые насыщенные функциями модули из набора NodeMCU. Но если усвоить базовые правила, дальнейшая работа с графикой не составит труда. Этим мы сейчас и зай- мемся. Начнем с выбора и настройки нужного модуля NodeMCU. В целом, за поддержку дисплеев OLED и некоторых других матричных дисплеев отвечает модуль U8G, а с цветными TFT-дисплеями работает модуль UCG. Очень важный критерий — мик- росхема драйвера дисплея. Приобретая дисплей, вы должны точно знать, какой дисплейный чип в него установлен! Вам придется указать микросхему дисплея при настройке графического модуля перед сборкой прошивки NodeMCU. В случае ошибки дисплей не будет работать, и прошивку придется пересобрать. Полное описание всех возможностей и функций графических библиотек слишком велико для изложения в книге. Для детального изучения графических модулей по- сетите интернет-ресурсы по адресам: ♦ http://nodemcu.readthedocs.io/en/master/en/modules/u8g/ — библиотека U8G; ♦ http://nodemcu.readthedocs.io/en/master/en/modules/ucg/ — библиотека UCG;
Примеры программ и проектов для NodeMCU 229 ♦ https://github.com/nodemcu/nodemcu-firmware/blob/master/docs/en/ modules/u8g.md; ♦ https://github.com/olikraus/ucglib. 11.1. Использование графического OLED-дисплея В этом примере вы увидите, как отображать на OLED-дисплее текст и графические элементы, а также узнаете обязательные требования к структуре программы. Матрица OLED-дисплея состоит из миниатюрных органических светодиодов (Organic Light Emitting Diode). Достоинствами OLED-дисплеев являются очень вы- сокая контрастность, экономичность и небольшая толщина, потому что в них нет задней подсветки. А К сожалению, у OLED-дисплеев, особенно недорогих, есть существенный недоста- ток, о котором обычно не знают начинающие разработчики. Эти дисплеи очень быстро «выгорают», поэтому не подходят для устройств с постоянной индикацией: часов, метеостанций и т. п. При постоянном свечении яркость пикселов может упасть на 40-50% примерно через год. Поскольку выгорание пиксела зависит от длительности свечения, дисплей быстро приобретает неопрятный вид с разной яркостью пикселов и визуально заметными «выгоревшими» зонами. Поэтому OLED-дисплеи хорошо подходят только для устройств с относительно кратковременной индикацией. 11.1.1. Подключение дисплея Мы будем использовать стандартный дисплей OLED 128x64 на чипе SSD1306 (рис. 11.1) и любую плату ESP8266 с прошивкой NodeMCU. Конструкция платы может быть другой, но дисплей обязательно должен иметь выводы интерфейса 12С. Некоторые дисплеи снабжены интерфейсом SPI или позволяют выбирать ин- терфейс при помощи перемычки на плате. Будьте внимательны при покупке дис- плея. Соедините дисплей с платой NodeMCU четырьмя проводами: ♦ GND^GND; ♦ VCC-+3.3V; ♦ SDA->D1(GPIO5); ♦ SCL -> D2 (GPIO4). Можно использовать и другие выводы GPIO, указав нужные номера в коде про- граммы. Однако помните, что в скриптах используются номера в нотации NodeMCU см. (рис. 10.2), а не номера GPIO! Менять адрес дисплея в программе, перепаивать перемычку адреса 12С на плате дисплея или применять согласование логических уровней в нашем случае не требуется.
230 Глава 11 Рис. 11.1. Графический дисплей OLED 128x64 с интерфейсом I2C 11.1.2. Настройка модуля U8G Если вы еще не собрали прошивку с нужными модулями, то сделайте это сейчас. Обязательные МОДУЛИ ПрОШИВКИ: bit, file, GPIO, I2C, net, node, U8G, UART, WiFi. Подойдет прошивка, которую мы собрали в главе 10 по рис. 10.4. Когда на страни- це онлайн-конструктора прошивки вы ставите галочку напротив пункта U8G, от- крывается отдельное окно настроек этого модуля. Вы должны заранее знать, какой дисплей и шрифты будете использовать. Выбирайте только те шрифты, которые действительно вам необходимы! Добавление лишних шрифтов увеличивает объем прошивки и напрасно занимает память устройства. Чтобы сменить дисплей или шрифты, придется заново собирать и загружать прошивку NodeMCU. При этом будут стерты все ранее записанные в память платы скрипты. В настройках моду- ля U8G по умолчанию указан дисплей OLED 128x64 и универсальный шрифт 6x10 пикселов, поэтому для большинства проектов начального уровня можно ниче- го не менять. 11.1.3. Пример программы Рассмотрим пример простой программы из листинга 11.1. Этот скрипт на языке Lua рисует прямоугольную рамку, круг (окружность с заливкой) и выводит две строки текста (рис. 11.2). Для загрузки программы подключите отладочную плату к ком- пьютеру и запустите ESPlorer ГОЕ. Откройте файл скрипта в окне редактирования и нажмите кнопку Save to ESP. Скрипт будет загружен в отладочную плату и немед- ленно выполнен. Если на дисплее не появилось изображение, проверьте правиль- ность подключения соединительных проводов. — Назначение выводов I2C sda =1 — SDA (D1 на плате NodeMCU Dev Kit) scl = 2 — SCL (D2 на плате NodeMCU Dev Kit)
Примеры программ и проектов для NodeMCU 231 function init_OLED(sda,scl) — Инициализация библиотеки U8G sla = ОхЗС — адрес ведомого устройства 12С i2c.setup(0/ sda, scl, i2c.SLOW) disp = u8g.ssdl306_128x64_i2c(sla) disp:setFont(u8g.font_6xlO) disp:setFontRefHeightExtendedText() disp:setDefaultForegroundColor() disp:setFontPosTop() —disp:setRotl80() — развернуть на 180, если нужно end function print_OLED() — вывод изображения и текста на дисплей disp:firstPage() repeat disp:drawFrame(2,2,126, 62) — рисуем рамку disp:drawStr(5, 10, strl) — выводим первую строку disp:drawStr(5, 20, str2) — выводим вторую строку disp:drawDisc(18, 47, 14) — рисуем круг (х, у, радиус) until disp:nextPage() == false end — главная программа strl=" Hello World!!!" Str2=" www.FANKRAFT.ru" init_OLED(sda,scl) print_OLED() Функция initOLED () получает номера выводов I2C, инициализирует интерфейс 12С и библиотеку U8Glib. В строке: disp = u8g.ssdl306_128x64_i2c(sla) мы создаем объект disp для OLED 128x64 на чипе SSD1306. Эта строка описания объекта, слегка похожая на абракадабру, предоставлена в руководстве к модулю U8G. Если вы используете другой дисплей, то должны найти в руководстве соот- ветствующую строку. В дальнейшем мы обращаемся к объекту disp, чтобы задать шрифт, его начертание, отсчет позиции текста от верхнего левого угла дисплея, а также цвет фона по умолчанию: disp:setDefaultForegroundColor() Мы могли бы не указывать цвет фона для нашего монохромного дисплея и добави- ли эту строку исключительно для большей универсальности примера. Функция printOLED () отвечает за рисование рамки, круга и вывод двух текстовых строк. Содержимое этой функции требует пояснений. Строка: disp:firstPage() начинает цикл прорисовки страницы изображения. Далее следует цикл repeat.. .until, для которого условием выхода из цикла является окончание прори- совки страницы. Цикл заканчивается, когда вызов dispmextpageo возвращает зна- чение true. В нашем случае прорисовка экрана выполняется за один проход, но
232 Глава 11 возможны ситуации, когда полная прорисовка выполняется за несколько проходов. Поэтому настоятельно рекомендуется всегда применять стандартную конструкцию: disp:firstPage() repeat здесь расположены ваши команды рисования фигур или вывода текста until disp:nextPage() == false В качестве самостоятельной работы к этому примеру попробуйте нарисовать окружность вместо круга, изменить ее радиус и местоположение, изменить содер- жание и расположение текста. Рис. 11.2. На OLED-дисплее представлен результат работы программы из листинга 11.1 11.1.4. Монитор курса электронной валюты биткоин В этом проекте мы продолжим использовать дисплей OLED 128x64 и будем ото- бражать на нем текущий курс биткоинов по отношению к евро. Обязательные МОДУЛИ прОШИВКИ: bit, CJSON, file, GPIO, HTTP, I2C, net, node, timer, U8G, UART, wiFi. Подойдет прошивка, которую мы собрали в главе 10 по рис. 10.4. Схема под- ключения дисплея такая же, как и в предыдущем примере. За основу примера взят проект, размещенный по адресу: https://hackaday.io/project/12676-esp8266-btc-price-ticker-with-oled-display
Примеры программ и проектов для NodeMCU 233 В программе исправлены ошибки разработчика, из-за которых она неправильно обрабатывала строку данных, полученных с сервера. Это приводило к аварийной перезагрузке устройства. Добавлена проверка перехода через начало суток в 24:00. Программа состоит из трех файлов: init.lua, httpget.lua и update_display.lua— чтобы продемонстрировать разделение больших скриптов на короткие фрагменты, кото- рые вызываются по мере необходимости. Напомню, что скрипты хранятся во флеш-памяти платы, а для выполнения считываются в оперативную память ESP8266. Поскольку часть ОЗУ занимает интерпретатор NodeMCU, скрипт не дол- жен быть больше 100...ПО строк. Мы могли бы уместить всю программу этого примера в один скрипт, но в учебных целях сохраним разделение скрипта на файлы (листинги 11.2-11.4). wif i. setmode (wif i. STATION) wif i. sta. conf ig ("YOURJSSID", "YOUR_PASSWOKD") rate=0 offset=0 counter=0 hours=0 mins=0 timezone=3 — ваш локальный часовой пояс относительно UTC — для примера, UTC+3 - Москва, UTC+7 - Красноярск —инициализация дисплея OLED 128x64 sda = 1 — NodeMCU D3 scl = 2 -- NodeMCU D4 sla = ОхЗс i2c.setup(0, sda, scl, i2c.SLOW) disp = u8g.ssdl306_128x64_i2c(sla) — создаем объект disp disp:firstPage() repeat disp:drawFrame (0, 0, 128, 16) — рисуем рамку disp:setFont(u8g.font_6xlO) — мелкий шрифт dispidrawStr(7, 11, "Wait for connection") until dispmextPage () == false — отправка первого запроса dofile(f httpget.luaf) — запрашиваем текущий курс каждые 30 секунд tmr.alarm(0, 30000, 1, function() dofile('httpget.lua1) end ) Листинг 11.3- Скрипт формирования HTTP-запроса и обработки ответа http.get("http://api.coindesk.com/vl/bpi/currentprice/EUR.json", nil, funct ion(code, data) if (code < 0) then print("HTTP request failed")
234 Глава 11 else print(data) — Декодируем данные JSON t = cjson.decode(data) — Извлекаем отношение BTC/EUR из данных JSON rate = string.format("%.3f", t["bpi"]["EUR"]["rate_float"]); print(t["bpi"]["EUR"]["rate_float"]) — Извлекаем время UTC и пересчитываем его в локальное pos = string.find(t["time"]["updated"], ' i') hours = (string.sub(t["time"]["updated"], pos-2, pos-l)+timezone) if (hours >= 24) then —если переход через локальные сутки hours = hours - 24 end mins = string.sub(t["time"]["updated"], pos+1, pos+2) counter= counter +1; end dofile(f update_display.luaf) end) — Меняем положение картинки на дисплее через каждые 25 обновлений — чтобы уменьшить "выгорание" пикселов if (counter ==25) then offset = -3 elseif (counter == 26) then offset = 3 elseif (counter == 27) then counter = 0 offset = 0 end function printOLEDO — вывод рамок и текста на экран dispisetFont(u8g.font_6xlO) — мелкий шрифт disp:drawStr( 5+offset, 11, "Bitcoin Price Ticker") dispisetFont(u8g.font_10x20) — крупный шрифт для курса disp:drawStr( 29+offset, 32, "BTC/EUR") disp:drawStr( 23+offset, 50, rate) dispisetFont(u8g.font_6xlO) — мелкий шрифт dispidrawStr( 24+offset, 60, "Updated: "..hours..":"..mins.."") if (offset == 0) then dispidrawFrame(O, 0, 128, 16) dispidrawFrame(O, 16, 128, 48) end end
Примеры программ и проектов для NodeMCU 235 function newData() — обновление данных на экране disp:firstPage() repeat printOLED() until disp:nextPage() == false tmr.wdclr () end — главная программа newData() Загрузка программы в отладочную плату Подключите отладочную плату к компьютеру и запустите ESPlorer IDE. Откройте файл init.lua и исправьте параметры yourssid и yourpassword на имя и пароль своей домашней точки доступа. Сохраните исправленный файл. Для загрузки скриптов в память устройства воспользуйтесь кнопкой Upload, потому что она загружает файлы, не запуская их на выполнение. Дело в том, что если воспользоваться кноп- кой Save to ESP, как в предыдущем примере, то немедленно после загрузки скрипт будет исполнен. Поскольку при этом остальные части программы еще не будут за- гружены, возникнет ошибка, которая может привести к аварийной перезагрузке платы. Загрузив все три скрипта, нажмите кнопку сброса на плате. Служебные со- общения программы выводятся в окно терминала ESPlorer. Как только данные о курсе получены, они выводятся на дисплей (рис. 11.3). Рис. 11.3. Монитора курса биткоинов
236 Глава 11 Алгоритм работы программы При включении питания автоматически стартует скрипт init.lua. Он не выгружается из памяти при запуске других скриптов, поэтому всегда старайтесь делать этот скрипт небольшим. В первых двух строках скрипта задается подключение в режиме клиента. Не забудьте указать имя и пароль своей точки доступа. Далее объявляются переменные, которые будут глобальными, и устанавливается локальный часовой пояс. Затем происходит инициализация дисплея и создается объект disp. Рисуется рамка, в которую выводится стартовое сообщение об ожидании соединения с сер- вером. В завершение запускается на выполнение скрипт httpget.lua и настраивается таймер, по срабатыванию которого этот скрипт будет вызываться каждые 30 се- кунд. В первой строке скрипта httpget.lua формируется GET-запрос к бесплатному интер- нет-ресурсу, который сообщает курс биткоина. Данные поступают с некоторой задержкой относительно биржевого курса— это издержки бесплатности ресурса. Хотя можно было бы и заложить интервал ожидания, но для упрощения программы и ускорения начала работы наличие ответа сервера проверяется немедленно после подачи запроса. Поэтому сразу после первого запроса программа обычно выдает в терминал сообщение: HTTP request failed. В дальнейшем GET-запрос выполняется асинхронно (т. е. в фоновом режиме, во время выполнения других команд), и к мо- менту следующего обновления уже готовы данные предыдущего запроса. Введите в адресную строку браузера ссылку http://api.coindesk.com/vl/bpi/ currentprice/EUR.json и посмотрите, как выглядит строка ответа. Это массив дан- ных вида: {"имяГ1:"значение!", "имя2":"значение2"...} где некоторые значения сами являются вложенным массивом. Для декодирования этой строки применяется функция сjson.decode (data) из модуля cjson. В следую- щей строке мы извлекаем числовое значение из массива третьего уровня вложенно- сти с ключом ["bpi"] ["eur"] ["ratefioat"] и форматируем его, оставляя три деся- тичных знака после запятой. Далее находим позицию начала метки времени в стро- ке и извлекаем значения часов и минут. К полученному значению часов мы прибавляем локальный часовой пояс. Чтобы учесть начало новых локальных суток, мы проверяем, не превышает ли результат сложения 24. Автор исходного проекта живет в Великобритании, и у него такой заботы нет. Этот мелкий нюанс наглядно демонстрирует необходимость учитывать при разработке программ все факторы, включая регион проживания пользователя. В завершение скрипта инкрементирует- ся счетчик обновлений и запускается выполнение следующего скрипта — update_display.lua. Скрипт обновления дисплея содержит опцию периодического сдвига изображения в зависимости от счетчика обновлений, чтобы уменьшить «выгорание» пикселов. Также периодически гасится рамка вокруг текста. Основная функция newData () за- пускает процесс обновления страницы изображения — мы рассмотрели обязатель- ную конструкцию этой части кода в предыдущем примере (см. разд. 77.7). Внутри этой конструкции вызывается функция dispiayOLED (), которая формирует текст и
Примеры программ и проектов для NodeMCU 237 рамки для вывода на дисплей. По окончании обновления дисплея принудительно сбрасывается сторожевой таймер. По меркам процессора, запрос данных с сервера и обновление дисплея занимают довольно много времени, поэтому не исключена возможность ложного срабатывания сторожевого таймера, если его не обнулить. 11.1.5. Вывод на OLED-дисплей битовых изображений Для вывода битовых структур предназначены две функции библиотеки U8G: drawBitmap () и drawXBM (). Наш монохромный дисплей позволяет выводить изобра- жения только в битовом формате, в которых 1 соответствует светящемуся пикселу, а 0 — выключенному. Файл с таким изображением необходимо заранее пригото- вить и загрузить в память платы NodeMCU. Создание файла битового изображения При помощи любого подходящего графического редактора подготовьте исходное изображение размером 128x64 точки. Преобразуйте его в черно-белое графическое изображение формата GIF. При необходимости откорректируйте результат. Обра- тите внимание, что у дисплея цвет «бумаги» (фона) — черный, а изображение — белое. У исходного файла должен быть черный рисунок на белом фоне. Для конвертации файла изображения воспользуемся онлайновым сервисом: http://www.online-utility.org/image__converter.jsp. /\ Обратите внимание, что из-за некоторой терминологической путаницы в качестве /!\ выходного формата вы должны выбрать опцию MONO в нижней части страницы конвертера. Функция drawXBM () унаследовала свое название от библиотеки Arduino, где изображение сохраняется в памяти программ в виде текстовой строки байтов. В среде NodeMCU изображение сохраняется в отдельном файле формата MONO, хотя в проектах для таких файлов традиционно используют расширение xbm. Выбрав формат MONO, нажмите кнопку Select format и на следующей странице укажите исходный файл для конвертации. Процесс занимает долю секунды. Рас- ширение в имени файла можно не менять. Достаточно правильно указать имя фай- ла в скрипте. Загрузите графический файл в память отладочной платы при помощи кнопки Upload среды ESPlorer IDE. Пример программы Пример программы для вывода изображений битового формата приведен в листин- ге 11.5. Вместе с программой в память платы NodeMCU должен быть загружен готовый файл битовой графики. В нашем случае это файл BHVJogo.xbm (рис. 11.4). — настраиваем I2C и создаем объект дисплея function init_i2c_display() sda = 1 — SDA (D1 на плате NodeMCU Dev Kit) scl = 2 — SCL (D2 на плате NodeMCU Dev Kit)
238 Глава 11 sla = ОхЗс i2c.setup(0, sda," sclf i2c.SLOW) disp = u8g.ssdl306_128x64_i2c(sla) end function xbmjpicture() — вывод изображения на дисплей disp:firstPage() repeat — выводим рисунок 128x64 битов с позиции 0,0 disp:drawXBM( 0, 0, 128, 64, xbm_data ) until disp:nextPage() == false end — основная программа init_i2c_display() — читаем битовое изображение из файла file.open("BHV_logo.xbm", "r") xbm_data = file.read() file.close() xbm_picture() — вызываем функцию прорисовки изображения Рис. 11.4. Вывод битового логотипа на OLED-дисплей Сначала мы вызываем фунющю init_i2c_dispiay() для инициализации шины I С и дисплея. Затем открываем на чтение файл изображения и считываем его со- держимое в строковую переменную xbmdata. Вызываем функцию xbmpicture()
Примеры программ и проектов для NodeMCU 239 для побитового вывода содержимого строки на дисплей. С обязательной струк- турой этой функции вы уже знакомы из предыдущих примеров. Метод disp:drawXBM(x,y,w,h,data) выводит изображение с шириной w и высотой h из строки data. Вывод начинается из левого верхнего угла с координатами х, у. Изо- бражение не масштабируется, ширина и высота в параметрах вызова функции должны соответствовать реальному файлу. 11.2. Использование графического TFT-дисплея Цветные графические TFT-дисплеи с разрешением 160x128 и 320x240 пикселов широко применяются в любительских проектах, потому что стоят немногим доро- же OLED-дисплеев, зато имеют множество достоинств: цветное изображение, бо- лее просторное рабочее поле, не выгорают при длительной эксплуатации. Конечно, габариты и вес этих дисплеев заметно выше, чем у OLED. Но если нет особо жест- ких требований к миниатюрности устройства, то этот недостаток можно простить. Чем больше рабочее поле дисплея, тем больше объем данных, которые необходимо в него выгружать. Особенно, если это цветной дисплей. Поэтому практически во всех цветных дисплеях применяется быстрый интерфейс SPI. И чем быстрее рабо- тает SPI в процессорной части устройства, тем быстрее обновляется изображение. Обычно стараются использовать аппаратный SPI, а не его программную эмуляцию. Рис. 11.5. Цветной TFT-дисплей 320x240 точек с интерфейсом SPI на чипе ILI9341 В большинстве дисплеев китайского производства используется популярный чип ILI9341. Он имеет два режима интерфейса: данные и команды— в зависимости от логического уровня на входе D/C (Data/Command). Кроме этого, в дисплее есть вход сброса RES. Поэтому дисплей занимает не четыре порта GPIO, а шесть. Это неизбежная плата за возможность выводить на экран качественное цветное изобра- жение. Впрочем, оставшихся выводов GPIO на плате NodeMCU достаточно для
240 Глава 11 большинства проектов. С платами ESP, на которых разведены не все доступные порты, могут возникнуть проблемы. 11.2.1. Подключение дисплея к плате NodeMCU Графическая библиотека UCG, управляющая дисплеем, позволяет подключить вы- воды CS, D/C и RES к произвольным портам. Для передачи данных используются стандартные выводы SPI микросхемы ESP8266 (табл. 11.1). Таблица 11.1. Подключение выводов TFT-дисплея к плате NodeMCU Выводы дисплея MISO MOSI SCK CS RES D/C VCC GND Выводы платы NodeMCU GPIO12(D6) GPIO13(D7) GPIO14 (D5) GPIO15(D8)* GPIO16(D0) GPIO2 (D4) Vin (+5B) GND * Вывод CS необходимо соединить с общим проводом через резистор 10 кОм. 11.2.2. Пример использования графической библиотеки Обязательные МОДУЛИ ПрОШИВКИ: bit, file, GPIO, SPI, net, node, UCG, UART, WiFi. Подключение других модулей будет зависеть от проекта, в котором используется дисплей. В конструкторе прошивок после выбора модуля UCG ниже списка моду- лей открывается форма выбора модели дисплея. Если вы используете дисплей, ана- логичный изображенному на рис. 11.5, то выбирайте модель ILI9341_18x240x320. Пример скрипта, который выводит образцы шрифтов и некоторые графические элементы, приведен в листинге 11.6. Результат работы скрипта показан на рис. 11.6. function init_spi_display() — SPI CLK = GPIO14 (D5) — SPI MOSI = GPIO13 (D7) — SPI MISO = GPIO12 (D6, не используется) — SPI /CS = GPIO15 (D8, не используется) — CS, D/C и RES можно соединить с любыми свободными портами
Примеры программ и проектов для NodeMCU 241 cs =8 — GPI015, через резистор 10 кОм на GND dc = 4 — GPIO2 res = 0 — GPI016 spi.setup(1, spi.MASTER, spi.CPOL_LOW, spi.CPHA_LOW, 8, 8) — повторно деактивируем линию CS, т. к. не будем ее использовать gpio.mode(8, gpio.INPUT, gpio.PULLUP) — инициализация дисплея и создание объекта disp = ucg.ili9341_18x240x320_hw_spi(cs, dc, res) —disp = ucg.st7735_18xl28xl60_hw_spi(cs, dc, res) end init_spi_display() — инициализируем библиотеку disp:begin(ucg.FONT_MODE_TRANSPARENT) — разворачиваем отображение на 180 градусов disp:setRotatel80() — очищаем экран disp:clearScreen() — задаем параметры цвета градиентной заливки disp:setColor(0, 0, 40, 80) disp:setColor(l, 150, 0, 200) disp:setColor(2, 60, 0, 40) disp:setColor(3, 0, 160, 160) — выводим градиентную заливку на весь экран disp:drawGradientBox(0, 0, disp:getWidth(), disp:getHeight()) — задаем белый цвет основных объектов — направление печати горизонтально справа налево — шрифт с прозрачным фоном disp:setColor(255, 255, 255) disp:setPrintDir(0) disp:setFontMode(ucg.FONT_MODE_TRANSPARENT) — выводим доступные образцы шрифтов disp:setFont(ucg.font_7xl3B_tr) disp:setPrintPos(2,13) disp:print("font_7xl3B_tr") disp:setFont(ucg.font_helvB08_hr) disp:setPrintPos(2,25) disp:print("font_helvB08_hr") disp:setFont(ucg.font_helvB10_hr) disp:setPrintPos(2,40) disp:print("font_helvB10_hr")
242 Глава 11 disp: set Font (ucg. font_helvB12_hr) disp:setPrintPos(2,57) disp:print("font_helvB12_hr") disp:setFont(ucg.font_helvB18_hr) disp:setPrintPos(2,81) disp:print("font_helvB18_hr") disp:setFont(ucg.font_ncenR12_tr) disp:setPrintPos(2,98) disp:print("font_ncenR12_tr") disp:setFont(ucg.font_ncenR14_hr) disp:setPrintPos(2,116) disp:print("font_ncenR14_hr") disp:setFont(ucg.font_ncenB24_tr) disp:setPrintPos(2,144) di sp:print("font_ncenB2 4") — рисуем прямоугольную рамку disp:setColor(0, 255, 0) disp:drawFrame(O, 150, 240, 170) — рисуем рамку со скругленными углами disp:setColor(255, 255, 0) disp:drawRFrame(5, 155, 230, 160, 20) — рисуем два прилегающих треугольника disp:setColor(0, 255, 255, 255) disp:drawTriangle(42, 179, 73, 202, 37, 212) disp:drawTriangle(42, 225, 73, 202+1, 37, 212+1) — рисуем разноцветные сегменты круга disp:setColor(255, 255, 255) disp:drawDisc(180, 250, 40, 1) — правый верхний сегмент, белый disp:setColor(255, 0, 0) disp:drawDisc(180, 250, 40, 2) — левый верхний сегмент, красный disp:setColor(0, 255, 0) disp:drawDisc(180, 250, 40, 4) — левый нижний сегмент, зеленый disp:setColor(0, 0, 255) disp:drawDisc(180, 250, 40, 8) — правый нижний сегмент) синий Линии MISO (D6) и CS (D8) в данном случае для работы с дисплеем не использу- ются. Это единственное устройство на линии SPI, которое всегда находится в со- стоянии «выбрано», поэтому линия CS принудительно притянута в низкий уровень при помощи резистора 10 кОм, соединенного с общим проводом. Линия MISO для чтения данных из дисплея также не используется. Тем не менее, эти линии в дан- ном случае нельзя задействовать под другие нужды, потому что они входят в со- став аппаратного модуля SPI микросхемы ESP8266. В качестве линий D/C и RES можно использовать любые свободные выводы GPIO. После инициализации ин-
Примеры программ и проектов для NodeMCU 243 Рис. 11.6. Результат работы программы из листинга 11.6 терфейса SPI мы принудительно деактивируем линию CS (D8), переводя ее в ре- жим входа. В завершение процесса инициализации мы создаем объект disp и акти- вируем выводы управления дисплеем через библиотеку UCG. В основной части программы мы инициализируем библиотеку, задавая при этом режим вывода шрифта с прозрачным фоном ucg. font j^dejtrans parent. Стандарт- ное положение дисплея — вертикальное. В данном случае мне было удобнее раз- вернуть изображение на 180 градусов. Переходим к формированию градиентной заливки экрана. Библиотека UCG под- держивает четыре виртуальных цветовых слоя. Большинство графических объектов по умолчанию использует слой номер 0, если в явном виде не указан другой слой. Но при формировании градиентной заливки прямоугольной области задействованы все четыре слоя: левый верхний угол— цвет 0, правый верхний— 1, левый ниж- ний— 2, правый нижний— 3. Остальное пространство окрашено пропорциональ- ной комбинацией всех этих цветов. Прорисовка градиентной заливки происходит медленно, поскольку вычисляется цвет каждого пиксела. Поверх градиентной заливки мы выводим образцы текста. Доступны следующие шрифты: font_7xl3B_tr font_helvB08_hr font_helvBl0_hr font_helvB12_hr font helvB18 hr
244 Глава 11 font_ncenB2 4_tг font_ncenRl2_t r font_ncenRl4_hr На оставшейся части пространства дисплея рисуем геометрические фигуры: прямоугольную рамку, рамку со скругленными углами и разноцветные сегменты круга. В текущей ВерСИИ ПРОШИВКИ ВОЗМОЖНОСТИ фуНКЦИЙ drawDisc (x, у, г, р) И drawc±rcie(x,y,r,p) значительно шире, чем это сказано в официальном описании библиотеки UCG. Параметр р теперь может принимать значения от 1 до 15, что со- ответствует различным сегментам круга (окружности). Полному кругу или окружно- сти соответствует значение 15. Благодаря этой функции можно рисовать наглядные круговые диаграммы и прочие элементы графического интерфейса. В качестве самостоятельной работы напишите небольшую программу, которая будет в цикле перебирать значения параметра р от 1 до 15 и подставлять их в функцию drawDisc ().
ГЛАВА 12 Микрокомпьютер Omega2 Мы продолжаем изучение любительских платформ по мере нарастания их сложно- сти и возможностей. Сейчас мы переходим к знакомству с микрокомпьютером Omega2. Это относительно новый проект, который собрал на краудфандинге Kickstarter.com более 800 тыс. долларов всего за несколько месяцев после запуска. Разработчиком проекта является американский стартап Onion Corporation (www.onion.io). Продвижение проекта продолжается на краудфандинговой плат- форме Indiegogo по адресу: www.indiegogo.com/projects/omega2-5-linux-computer- with-wi-fi-made-for-iot#/. Микрокомпьютер Omega2 имеет «на борту» операционную систему Linux на осно- ве OpenWRT и заявлен, как самый маленький в мире Linux-сервер со встроен- ной поддержкой Wi-Fi. С этим рекламным лозунгом можно спорить, но возмож- ности устройства действительно дают большой простор для любительского твор- чества. Omega2 занимает промежуточное положение между модулями уровня NodeMCU и микрокомпьютерами уровня Raspberry Pi. Он поддерживает полноценную файло- вую систему и прочие функциональные возможности ОС Linux. Графической под- системы нет. В этом микрокомпьютере сделан акцент на небольших габаритах и низком энергопотреблении. Omega2 — не единственный микрокомпьютер промежуточного уровня. На рынке любительской электроники предлагают более десятка аналогичных устройств. Чи- татель, знакомый с ассортиментом современных микрокомпьютеров, может спро- сить, почему мы выбрали для этой книги именно Omega2. Позвольте напомнить, что любительская платформа— это не просто набор печатных плат. Нам нужна поддержка производителя в виде подробнейшей документации, готовых программ- ных библиотек, постоянного обновления прошивок, учебных проектов, примеров программ. Производитель с первых дней должен поддерживать и развивать сооб- щество пользователей. Продвижение и поддержка платформы — это нелегкая зада- ча, с которой справляются далеко не все.
246 Глава 12 12.1. Аппаратный состав платформы Микрокомпьютер Omega2 состоит из однокристальной системы МТ7688 и микро- схем памяти, закрытых защитным экраном (рис. 12.1). Снаружи расположены керамическая антенна Wi-Fi и разъем для подключения внешней антенны. Выпус- каются две аппаратные версии, которые различаются только объемом встроенной памяти и наличием слота для установки карты памяти MicroSD (табл. 12.1). Рис. 12.1. Микрокомпьютер Отеда2 Таблица 12.1. Сравнение характеристик 0теда2 и Отеда2 Plus Модификация Процессор (SoC) Тактовая частота Оперативная память Память программ USB-xoct Карта памяти Wi-Fi Порты GPIO Генератор ШИМ UART Аппаратный I2C Аппаратный SPI Отеда2 МТ7688 MIPS32 24КЕС 32 бит 580 МГц 64 Мбайт 16 Мбайт 1 xUSB2.0 Нет 802.11Ь/д/п 15 2 2 1 1 Отеда2 Plus МТ7688 MIPS32 24КЕс 32 бит 580 МГц 128 Мбайт 32 Мбайт 1 х USB 2.0 MicroSD 802.11Ь/д/п 15 2 2 1 1
Микрокомпьютер Отеда2 247 Таблица 12.1 (окончание) Модификация Аппаратный I2S Напряжение питания Потребляемый ток Цена Omega2 1 +з,зв 180...220МА $5 Omega2 Plus 1 +З.ЗВ 180...220мА $9 Имейте в виду, что рядные разъемы по краям платы имеют шаг 2,0 мм и не могут быть подключены к стандартной макетной плате. Выводы разъемов короткие и тон- кие, поэтому подключать обычные макетные провода затруднительно. Настоятельно рекомендую не экономить на покупке фирменной отладочной платы. Для комфортной работы с микрокомпьютером производитель предлагает несколько вариантов отладочных плат. Наиболее универсальной является плата Expansion Dock (рис. 12.2). Она содержит встроенный стабилизатор питания +3,3 В, конвер- тер USB-UART с разъемом miniUSB, разъем хоста USB и макетный разъем для подключения внешних модулей. Плата Power Dock (рис. 12.3) содержит преобразо- ватель питания от литий-полимерной батареи и контроллер зарядного устройства. На момент подготовки книги она была доступна для заказа только через страницу проекта на ftidiegogo. Рис. 12.2. Отладочная плата Expansion Dock Для совместимости с платформой Arduino предлагается комбинированная отладоч- ная плата Arduino Dock R2 (рис. 12.4). Она полностью совместима с модулями рас- ширения Arduino Uno. Микроконтроллер ATmega328 соединен с Omega2 через по-
248 Глава 12 следовательный порт. Принцип работы такой же, как и в случае с Arduino Yun или Dragino Yun (см. разд. 5.4.5). Вы можете программировать устройства Arduino через беспроводное соединение и продолжать использовать ваши модули Arduino вместе с компьютером Omega2. Рис. 12.3. Отладочная плата Power Dock Рис. 12.4. Отладочная плата Arduino Dock R2
Микрокомпьютер Отеда2 249 Минимальные возможности для коммуникации с Omega2 предоставляет отладоч- ная плата Mini Dock (рис. 12.5). Она содержит конвертер USB-UART, линейный стабилизатор напряжения, разъем miniUSB для подачи питания и подключения к настольному компьютеру и стандартное гнездо USB-хоста для подключения периферийных устройств. Например, можно подключить стандартную веб-камеру и транслировать через Wi-Fi потоковое видео невысокого качества. Рис. 12.5. Отладочная плата Mini Dock Кроме отладочных плат компания Onion выпускает фирменные периферийные мо- дули. Бизнес-модель этого стартапа вполне очевидна: продавать микрокомпьютер по цене, близкой к себестоимости, и зарабатывать на дополнительном оборудова- нии. Если микрокомпьютер, в зависимости от версии, можно купить за 5 или 9 дол- ларов, то даже самый примитивный модуль расширения стоит не менее 15 долла- ров. Для российского радиолюбителя покупка нескольких модулей может быть на- кладной. К счастью, практически все модули можно заменить недорогими аналогами из Китая, цена которых ниже в 4-6 раз. В главе 13 мы подробно расска- жем, как это сделать, а пока перечислим компоненты, которые обязательно следует приобрести. Полный перечень фирменных модулей расширения и отладочных плат, доступных для заказа со склада, приведен по адресу: https://onion.io/product-category/all/. На странице краудфандинга Indiegogo имеется также описание модулей сторонних производителей: https://www.indiegogo.com/projects/omega2-5-linux-computer- with-wi-fi-made-for-iot#/. Я настоятельно советую приобрести расширенную версию Omega2 Plus по цене 9 долларов. Дело в том, что операционная система Linux и приложение Onion Console занимают около 11,5 мегабайт в памяти программ. Кроме того, вам придет- ся установить поддержку хотя бы одного языка программирования и дополнитель- ные библиотеки для него. Если купить версию с флеш-памятью объемом 16 мега- байт, то для ваших нужд останется менее четырех мегабайт памяти. Этого доста- точно для обучения и несложных проектов, но остается риск внезапной нехватки
250 Глава 12 памяти в будущем. Потратив на четыре доллара больше, вы получаете удвоенный объем памяти программ и слот карты памяти MicroSD для хранения пользователь- ских данных. В разд. 12.7 рассказано, как расширить пространство встроенной памяти, чтобы хранить часть модулей прошивки и системные программы на карте памяти MicroSD. Следующий обязательный компонент— отладочная плата. Закажите ее вместе с микрокомпьютером. Как показал печальный опыт владельцев Omega2, попытка обойтись без отладочной платы создает множество неприятных проблем — от плохих контактов и путаницы проводов до сгоревшего от переполюсовки питания микрокомпьютера. Все фирменные модули расширения и учебные проекты рас- считаны на подключение к двухрядному разъему плат Power Dock или Expansion Dock. Как ни странно, у этих плат одинаковая цена. Поэтому имеет смысл заказать Power Dock с возможностью подключения литий-полимерной батареи. Если у вас имеются в запасе шилды для Arduino Uno и вы хотите разрабатывать комплексные проекты Arduino+Omega2, то лучшим выбором станет плата Arduino Dock R2. Если вы не планируете использовать фирменные модули расширения, то можете приобрести так называемый Breadboard Dock — адаптер для подключения микро- компьютера к беспаечной макетной плате (рис. 12.6). Штыревые разъемы адаптера имеют стандартный шаг 2,5 мм для установки в макетную плату. Внешний конвер- тер USB-UART следует подключать к выводам RX0, ТХО. Рис. 12.6. Отладочный адаптер Breadboard Dock 12.2. Подготовка к работе Нам доступны два способа начальной настройки: при помощи мастера настройки через встроенный веб-сервер Omega2 либо при помощи командной строки терми- нала Linux. Мастер настройки более удобен и нагляден для начинающих, но требу- ет наличия соединения по Wi-Fi. Поэтому, если вы используете стационарный ком- пьютер, он должен быть оснащен адаптером Wi-Fi. 12.2.1. Настройка при помощи мастера При первом включении Omega2 создает беспроводную точку доступа с именем Omega-ABCD, где ABCD— последние четыре символа МАС-адреса, указанного
Микрокомпьютер Отеда2 251 в наклейке на компьютере. Пароль по умолчанию: 12345678. Установите соедине- ние своего компьютера с этой точкой доступа. Для входа на страницу настроек можно воспользоваться символьным адресом вида http://omega-742?CDJocal/, где ABCD — последние четыре символа МАС-адреса. На компьютере с Windows должен быть установлен сервис Bonjoure. На компьютерах с ОС Windows он автоматически появляется при установке приложения iTunes for Windows либо может быть скачан отдельно по адресу: https://support.apple.com/kb/ DL999. На компьютерах с Mac OS X сервис работает по умолчанию. На компьютер с ОС Linux обычно по умолчанию установлен сервис Zeroconf. Если сервис символьных адресов не работает, введите прямой адрес: 192.168.3.1 — в браузере откроется мастер настройки. Логин по умолчанию: root, пароль: onioneer. На втором шаге вводим имя и пароль домашней точки доступа. Это обязательно, поскольку Omega2 будет соединяться с сервером для проверки и скачивания об- новлений прошивки. Проблема с роутерами MicroTik Многие пользователи, включая меня, обнаружили, что Отеда2 принципиально не может установить соединение с некоторыми моделями Wi-Fi маршрутизаторов MicroTik. Разумного объяснения или способов решения проблемы на момент подго- товки книги не существовало. Поэтому в процессе настройки и обновления поста- райтесь использовать точку доступа Wi-Fi любого другого производителя. После нажатия кнопки Configure встроенный модуль Wi-Fi будет перезагружаться примерно 30 секунд. В это время просто ждите, пока точка доступа Omega-ABCD вновь появится в эфире. После перезагрузки точки доступа ваш компьютер может потерять с ней связь, иногда требуется восстановить соединение вручную. Устранение конфликта IP-адресов Если вы уверены, что правильно ввели имя и пароль домашней точки доступа, но Отеда2 не может подключиться к сети, вероятная причина заключается в конфлик- те IP-адресов. Конфликт возникает, если точка доступа, которую создает Отеда2, и ваш домашний роутер находятся в одном адресном пространстве. Подсеть Отеда2 расположена в диапазоне 192.168.3.0/24 и существует вероятность, что этот диапа- зон пересекается с адресным пространством вашей домашней беспроводной сети. Имеются два способа решить проблему: изменить диапазон адресов роутера или изменить диапазон адресов микрокомпьютера Отеда2. Для каждой модели роутера существует отдельная инструкция по настройке, и не всегда допустимо менять ад- ресное пространство домашней сети. Проще изменить адрес подсети Отеда2. Для этого потребуется установить соединение с терминалом (см. разд. 12.2.2). Введите в окне терминала последовательность команд: uci set network.wlan.ipaddr=192.168.9.1 uci commit network /etc/init.d/network restart Для примера мы ввели здесь новый адрес встроенной точки доступа Отеда2: 192.168.9.1. Вы можете задать другой адрес. Вторая строка сохраняет сетевые на- стройки, третья строка перезагружает встроенный модуль Wi-Fi. Далее вам будет предложено зарегистрировать микрокомпьютер в облаке Onion Cloud. По отзывам пользователей, на этом этапе регистрация иногда работает не-
252 Глава 12 стабильно. Поэтому мы нажмем кнопку Skip (пропустить), а регистрацию в облаке выполним позже. Переходим к следующему шагу, где устанавливаем галочку в оп- ции Install Console и нажимаем кнопку Upgrade Firmware and Install Console (рис. 12.7). На этом этапе будет проверена и при необходимости обновлена про- шивка, а также установлен полезный онлайн-инструмент Console с функциями сре- ды разработки. 0 Onion LOGIN WIR CLOUD SOFTWARE Update your Omega to the latest and greatest firmware to get all the newest software goodies from Ornon Install Console «a The Onion Console is a web-based virtual desktop for the Omega that allows you to easily change settings and can be used as an IDE Рис. 12.7. Обновление прошивки и установка приложения Console Если доступна новая версия прошивки, начнется ее скачивание и установка (рис. 12.8). В это время категорически запрещается отключать питание устрой- ства! При неудачном стечении обстоятельств вы рискуете необратимо повредить загрузчик прошивки без возможности восстановления в домашних условиях. Об- новление длится ориентировочно 4-5 минут, еще минуту займет первая загрузка после обновления. В это время светодиод на плате мигает, а точка доступа отклю- чена. По окончании процедуры обновления светодиод должен перестать мигать, а точка доступа вновь заработает. В зависимости от исходной версии прошивки, некоторые экземпляры Omega2 не перезагружаются автоматически. Если вы увидели сообще- ние об успешном завершении настройки, а светодиод продолжает мигать, просто отключите питание Omega2 на несколько секунд, включите вновь и дождитесь окончания перезагрузки.
Микрокомпьютер Omega! 253 Рис. 12.8. Завершение процесса обновления прошивки 12.2.2. Настройка при помощи командной строки Если вы не можете использовать прямое беспроводное соединение с настольным компьютером, или мастер настройки работает неправильно, поможет настройка при помощи командной строки терминала. Далее подразумевается, что вы используете фирменную отладочную плату. Переведите выключатель питания на плате в поло- жение «выключено» и подключите плату к компьютеру кабелем USB. Запустите терминал PuTTY (см. разд. 2.9.1% выберите номер порта и задайте скорость обмена 115200 бод. Включите питание на плате. В окне терминала вы должны наблюдать процесс загрузки микрокомпьютера, который завершается появлением логотипа и строкой ввода (рис. 12.9). Если загрузка завершилась, а логотип не появился, на- жмите клавишу <Enter>. Введите команду конфигурирования: wif isetup. В терминал будет выведен ответ: root@Omega-BE07:/# wifisetup Onion Omega Wifi Setup Select from the following: 1) Scan for Wifi networks 2) Type network info q) Exit Selection:
254 Глава 12 #C0M5-PuTTY - □ X Select Channel 1 ^\ [ 37.0575383 Min Dirty - 0 j [ 37.060207] ExChannel =0,0 j [ 37.063211] BW = 20 | [ 37.0947383 br-wlan: port 2(raO) entered forwarding state i [ 37.1003193 br-wlan: port 2(raO) entered forwarding state [ 39.0986623 br-wlan: port 2(raO) entered forwarding state \ [ 42.5214123 M! АРСЫ LINK UP - IF(apcliO) AuthMode(7)=WPA2PSK, WepStatus(6)= \ AES! \ I 58.858685] random: nonblocking pool is initialized \ BusyBox vl.26.2 (> built-in shell (ash) / \ Г> / \ //_//_ \/ /_ \/ _ \ / /j / ' \/ -_> _ v _ / WHAT WILL YOU INVENT? / / fi-ware: 0.1.10 b!60 root80mega-BE07:/# I Рис. 12.9. Окно терминала командной строки Omega2 В ответ на запрос введите 1. В терминале появится список доступных точек доступа: Scanning for wifi networks... Select Wifi network: 1) MyHomeWiFi 2) DIR-300NRU 3) rostel61 4) 571 Selection: Вводим списочный номер вашей точки доступа, затем — пароль вашей домашней точки доступа, нажимаем клавишу <Enter> и ждем около 30 секунд, пока модуль Wi-Fi перезагружается. Когда вновь появляется строка ввода, проверяем успеш- ность подключения. Введите команду ia и проверьте результат в первых строчках: root@Qmega-BE07:/# ia apcliO Link encap:Ethernet HWaddr 42:A3:6B:00:BE:07 inet addr:192.168.1.238 Beast:192.168.1.255 Mask:255.255.255.0 Мы видим, что микрокомпьютер успешно подключился к домашней точке доступа и получил IP-адрес 192.168.1.238. В вашей сети адрес может быть другим, запиши- те его на будущее. Приступим к обновлению прошивки. Введите команду: oupgrade. Если компьютер уже содержит самую свежую прошивку, вы получите сообщение: root@Qmega-BE07:/# oupgrade > Device Firmware Version: 0.1.10 Ы60
Микрокомпьютер Отеда2 255 > Checking latest version online... > Repo Firmware Version: 0.1.10 Ы60 > Comparing version numbers > Device firmware is up to date! В ином случае начнется скачивание и обновление прошивки. Ни в коем случае не отключайте питание во время обновления! Вы можете (и даже должны) периоди- чески проверять обновления и при необходимости обновлять прошивку, но помни- те, что при этом будут удалены все пользовательские файлы, программы и на- стройки. Позаботьтесь об их резервном копировании. Для проверки номера версии без загрузки обновления используйте команду: oupgrade -с. После скачивания и установки прошивки микрокомпьютер автоматически переза- грузится. Теперь установим приложение Console. Поочередно введите команды: uci set onion.console.setup=l uci set onion.console.install=2 uci commit onion Перезагрузите Omega2 командой reboot или отключите и вновь включите питание. Последует достаточно длительная загрузка, во время которой будет установлено приложение Console. Теперь наш микрокомпьютер готов к установке приложений и началу эксплуа- тации. 12.3. Браузерное приложение Onion Console Onion Console— это виртуальный рабочий стол, который открывается в окне любого браузера. Вы можете настраивать микрокомпьютер, запускать различные приложения и управлять фирменными платами расширения, используя удобный графический интерфейс. Для доступа к Onion Console ваш настольный компьютер или планшет должен на- ходиться в одной сети с Omega2. Введите в адресную строку браузера адрес: http://omega-v42?CD.local/, где ABCD— последние четыре символа МАС-адреса, или цифровой адрес 192.168.3.1 (или новый адрес, который вы задали в случае конфликта адресов). Для входа в приложение используйте логин root и пароль onioneer. Впоследствии вы можете изменить логин и пароль. На рабочем столе расположены значки приложений (рис. 12.10): ♦ Terminal — окно эмулятора терминала SSH. Для входа в терминал по умолча- нию Также ИСПОЛЬЗУЮТСЯ ЛОГИН root И пароль onioneer; ♦ Settings — основные настройки микрокомпьютера Omega2; ♦ Editor — текстовый редактор файлов. При помощи этого приложения вы може- те создавать и редактировать файлы программ. Можно даже выгружать файлы со стационарного компьютера;
256 Глава 12 Рис. 12.10. Рабочий стол веб-приложения Onion Console ♦ GPIO Tool — тренировочное приложение для визуального управления портами ввода/вывода; ♦ OLED Control— приложение для тестирования фирменной платы OLED- дисплея; ♦ Relay Control — приложение для тестирования фирменной платы управления реле; ♦ PWM Control — приложение для тестирования фирменной платы ШИМ; ♦ Webcam — приложение для тестирования работы веб-камеры USB. При первом щелчке на значке запускается установка приложения в память про- грамм Omega2. Скачивание и установка могут занимать до 3-4 минут. Благодаря наличию приложений Terminal и Editor, можно обойтись без установки специальных программ терминала и редактора на стационарном компьютере и работать только в окне браузера. Интерфейс этих приложений прост и не требует пояснений. К приложениям для работы с фирменными модулями мы обратимся в главе 13, когда будем обсуждать самодельные аналоги фирменных плат расширения. А сей- час рассмотрим содержимое окна Settings: ♦ Status — информация об аппаратных ресурсах микрокомпьютера; ♦ General Settings — установка часового пояса, логина и пароля; ♦ Wi-Fi Settings — здесь можно добавлять и удалять настройки для подключения к беспроводным точкам доступа. Если доступно несколько точек из списка, то происходит автоматическое подключение к точке, указанной в списке раньше;
Микрокомпьютер Отеда2 257 ♦ Wi-Fi АР Settings — настройки встроенной точки доступа: имя, пароль и тип шифрования; ♦ Firmware Upgrade — проверка и установка обновлений прошивки. Иногда про- цедура проверки обновлений зависает. В таком случае следует использовать команду терминала oupgrade; ♦ Factory Restore — сброс к заводским настройкам. Эту опцию следует использо- вать в самом крайнем случае, если вы необратимо испортили системные на- стройки и не можете их восстановить. Сохраните пользовательские файлы перед сбросом! ♦ Cloud Settings — регистрация устройства в фирменном облачном сервисе Onion Cloud. Задайте короткое интуитивно понятное имя устройства и его описание и нажмите кнопку регистрации. Регистрация и подключение к облаку могут занять 1-3 минуты. После регистрации вашему устройству будет присвоен уникальный идентификатор. 12.4. Облачный сервис Onion Cloud После регистрации устройства в облачном сервисе и получения идентификатора щелкните на ссылке cloud.onion.io (рис. 12.11). Идентификатор устройства автома- тически передается по ссылке, поэтому пароль доступа к сервису не требуется. vi registered with ihe Device Id 7fe68d0cl-Qc08 :4toto6f. \ Рис. 12.11. Переход к работе с облачным сервисом Рабочий стол облачного сервиса похож на окно Onion Console (рис. 12.12). На нем вы можете видеть значки установленных ранее приложений для тестирования плат расширения и управления портами GPIO. Теперь при помощи облачного сервиса вы можете управлять этими платами или состоянием выводов GPIO удаленно. На рабочем столе сервиса имеются и новые значки: ♦ Арр Store — хранилище стандартных приложений. В этом окне можно добав- лять и удалять приложения; ♦ Calculator — простая утилита «калькулятор программиста» для перевода чисел между разными системами счисления и арифметических операций; ♦ Resistor Calculator— визуальный калькулятор для перевода цветового кода резисторов в числовой номинал и наоборот;
258 Глава 12 Рис. 12.12. Рабочий стол сервиса Onion Cloud Cloud Compile — облачный компилятор проектов, созданных на языке C/C++. Скомпилированное приложение выгружается в память Omega2 и становится доступным для выполнения; Device Manager — управление устройствами, подключенными к облаку Onion Cloud. При щелчке на значке подключенного устройства открывается окно с его настройками (рис. 12.13); Device Explorer— выводит список подключенных устройств для управления ими. По щелчку на устройстве запускается утилита, позволяющая передать команду в устройство через облако и просмотреть ответ. В открывшемся окне команд последовательно щелкните на file и list. В секции Command Editor вве- дите в поле path строку /etc/ и нажмите кнопку Send. Через две-три секунды в секции Device Responce будет выведен листинг каталога /etc в формате JSON. По нажатию на кнопку Generate Code вы получаете фрагмент готового кода за- проса, который можно использовать в собственных программах. Можно выбрать язык программирования; Key Manager — создание ключей API и управление ими. Если вы опробовали пример для приложения Device Explorer и сгенерировали код, то видели, что
Микрокомпьютер Отеда2 259 в него надо подставить значение API Key. Вы должны сгенерировать ключ и ас- социировать его со своим устройством. Можно сгенерировать несколько разных ключей для доступа к различным функциям. После этого, используя ключ API Key, вы получаете доступ к функциям устройства из своих программ через API облака по адресу api.onion.io. Device Ызте , .., #...... Device Seer»**1 '[.■■.'■X'-- ^' :^;;:; Local SP ''■«.•. :••■, t ;.'.■•; Status Em ail :iSS ' Actions Рис. 12.13. Настройки устройства, подключенного к облаку 12.5. Python 2.7 и дополнительные модули В наших учебных примерах мы будем использовать программы на языке Python. Это скриптовый язык, и для выполнения программ на нем необходимо установить интерпретатор языка Python, а также дополнительные модули для реализации спе- цифических функций. Подключитесь к терминалу командной строки Omega2 при помощи PuTTY или утилиты Terminal из веб-приложения Onion Console. Для гарантированной совмес- тимости с ранее разработанными модулями установим интерпретатор Python вер- сии 2.7, хотя версия 3.0 также доступна для установки из репозитория. Python 2 и Python 3 — это две параллельные ветки языка, которые разделились более десяти лет назад и различаются на 10-15%. Они существуют и развиваются независимо. Далее во всех примерах мы будем использовать только Python 2.7. Введите в терминале команды: opkg update оркд install python (полная версия, только для Omega2 Plus) или оркд install python-light (сокращенная версия)
260 Глава 12 Скачивание и установка полной версии Python 2.7 занимает около пяти минут. Она содержит почти все необходимые модули, но занимает больше места и подходит только для Omega2 Plus с удвоенным объемом памяти. Существует два способа установки дополнительных модулей. Первый основан на стандартном механизме оркд для загрузки дополнительных модулей из репози- тория. Чтобы ознакомиться со списком модулей, доступных через оркд, введите команды: opkg update оркд list | дгер python Для установки дополнительного модуля введите команду: opkg install <имя модуля> Например, команда: opkg install python-mysql установит модуль python-mysql для взаимодействия с сервером MySQL. Второй способ основан на использовании собственно менеджера пакетов Python, который называется pip. Для установки менеджера введите команды: opkg update оркд install python-pip Процесс установки менеджера занимает около пяти минут. Для установки пакета при помощи менеджера надо ввести команду: pip install <имя пакета> Например, команда: pip install paho-mqtt установит модуль paho-mqtt для работы с протоколом MQTT. Команда pip —help выводит список доступных опций pip. Имейте в виду, что для выполнения этой команды, а также некоторых других команд может потребо- ваться 1-2 минуты. Сейчас мы установим некоторые модули Python, необходимые для работы с порта- ми GPIO и платами расширений в учебных примерах. Эти модули представляют собой предкомпилированные библиотеки на языке С, «обернутые» в функции скриптового языка Python. Остальные модули можно устанавливать аналогичным способом по мере необходимости. 12.5.1. Управление портами GPIO Модуль Python Onion GPIO создает объект OnionGpio, который позволяет управлять линиями порта ввода/вывода. Модуль обращается к интерфейсу sysfs, который является частью ОС Linux.
Микрокомпьютер Отеда2 261 Для установки модуля введите команды: opkg update opkg install python-light pyOnionGpio Для использования модуля добавьте в программу строку импорта: import onionGpio Модуль Python GPIO поддерживает следующие функции: ♦ onionGpio.OnionGpio(gpioNumber) — KOHCTpyKTOp объекта, где gpioNumber— ЭТО числовой номер линии порта GPIO. Создает объект для заданной линии порта. Например, gpiol4 = onionGpio.OnionGpio (14) создает объект gpiol4, при ПОМОЩИ которого мы будем манипулировать портом номер 14; ♦ getDirection () — прочитать направление действия порта (ввод или вывод); ♦ setinputDirection () — назначить порт как ВХОД; ♦ setOutputDirection(defaultValue) —назначить порт как ВЫХОД; ♦ getvaiue () — прочитать логический уровень на входе; ♦ setvalue (value) — задать логический уровень на выходе. Подключим к выводу GPIO0 (0) разъема отладочной платы Expansion Dock свето- диод и резистор (рис. 12.14) и напишем простейшую программу «Мигающий све- тодиод». Текст программы приведен в листинге 12.1. Omega2 Dock Header — — — _ 1 R1 ч ]220 *J _ D1 ZZ J s*^ I GPIOO GND 1 2 3 4 5 6 7 8 Q 1 Л 11 12 13 14 15 16 17 18 19 20 21 22 23 24 27 28 29 30 Рис. 12.14. Схема подключения светодиода для листинга 12.1 import time ## подключаем библиотеку time import onionGpio ## подключаем библиотеку onionGpio gpioNum = 0 ## номер порта GPIO gpioObj = onionGpio.OnionGpio(gpioNum) ## создаем объект
262 Глава 12 ## настраиваем линию порта как выход status = gpioObj.setOutputDirection(O) loop = 1 value = 0 # запускаем "вечный" цикл while loop == 1: # меняем значение на противоположное if value = 0: value = 1 else: value = 0 # записываем новый логический уровень в порт status = gpioObj.setValue(value) # выводим на экран состояние порта # используем для этого формат с подстановкой print 'GPIO%d set to: %df%(gpioNum, value) # пауза 1 секунда time.sleep(1) Пользуясь случаем, глубже освоим среду разработки Onion Console. Подключите браузер к консоли, как сказано в разд. 12.3. Запустите онлайн-утилиты Terminal и Editor. В окне редактора войдите в каталог /root, нажмите кнопку New File и соз- Рис. 12.15. Окно редактора Editor в среде Onion Console
Микрокомпьютер Отеда2 263 дайте файл с именем blinkjed.py. Скопируйте из сопровождающего книгу электрон- ного архива, размещенного на сайте издательства (см. приложение), или введите вручную текст программы (рис. 12.15). Сохраните его. Вы должны задать права доступа к файлу программы, чтобы его можно было запустить на выполнение. Перейдите в окно терминала и введите команды: chmod 755 /root chmod 755 /root/blink_led.py Первая команда задает нужные права доступа к каталогу /root, вторая устанавли- вает права файла. Права задаются единожды и сохраняются после перезагрузки. Запускаем программу на выполнение командой: python /root/blink_led.py Если все было сделано правильно, светодиод начнет мигать. Чтобы прервать рабо- ту программы, нажмите комбинацию клавиш <Ctrl>+<C>. 12.5.2. Модуль Python SPI Аппаратная реализация протокола SPI поддерживается при помощи встроенного драйвера ядра Linux. Для установки модуля Python SPI, поддерживающего взаимо- действие с драйвером, введите команды: opkg update opkg install python-light pyOnionSpi Для использования модуля добавьте в программу строку импорта: import onionSpi Модуль Python создает объект OnionSpi, который ссылается на номер шины SPI в системе Linux и индекс устройства (так называемый адаптер SPI). В операцион- ной системе Linux все устройства рассматриваются как виртуальные файлы. Аппа- ратной шине SPI соответствует виртуальный файл /dev/spidev32766.1, где 32766 — это номер шины, а 1 — индекс внешнего устройства, для выбора которого исполь- зуется вывод CS1. Индекс 0 и вывод CS0 заняты под встроенную флеш-память микрокомпьютера. Импортируем модуль и создаем объект: import onionSpi spi = onionSpi.OnionSpi(1, 32766) После создания объекта производители Omega2 рекомендуют выполнить в коде программы следующую последовательность действий: 1. Проверить, зарегистрирован ли адаптер в системе. 2. Если нет, зарегистрировать адаптер. 3. Задать дополнительные параметры SPI и записать их в адаптер. 4. Приступить к обмену данными по SPI по мере необходимости.
264 Глава 12 С последними версиями прошивки можно обойтись без этих манипуляций, а просто создать объект SPI и приступить к работе с ним. Такие параметры шины, как ско- рость обмена, порядок битов, задержка передачи и т. д., по умолчанию соответст- вуют почти всем применяемым в любительской практике устройствам. Их следует изменять только в случае ясно понимаемой необходимости. С детальным описани- ем всех параметров можно ознакомиться по адресу: https://docs.onion.io/omega2- docs/spi-python-module.html. Модуль Python SPI поддерживает следующие функции: ♦ checkDevice () — проверяет, зарегистрировано ли устройство в системе. Возвра- щает 1, если устройство зарегистрировано, и 0, если устройство требует регист- рации; ♦ registerDevice () — регистрирует устройство с заданными параметрами. Снача- ла функция проверяет регистрацию. Если устройство уже зарегистрировано, функция возвращает 0 и больше ничего не делает. Если необходима регистра- ция, функция пытается инициализировать модуль SPI-gpio в ядре Linux. В слу- чае успеха возвращает 0, в случае неудачи — 1; ♦ setupDevice () — записывает в адаптер ранее заданные параметры устройства; ♦ readBytes(addr, size) — читает заданное количество байтов size из регистра устройства С заданным адресом addr. Пример: data = spi.readBytes(0xlA/2) — прочитать подряд 2 байта по адресу ОхОа; ♦ writeBytes (addr, values) — записывает в регистр устройства с заданным адре- сом addr набор значений values. Пример: spi.writeBytes (OxlC, [0x15, 0x7D, 0x33]); ♦ write (values) — записывает в устройство набор значений без указания адреса регистра. Пример: spi.write ([0x15,0x7d,0x33] ). Практические примеры работы с устройствами SPI рассмотрены в главе 13. 12.5.3. Модуль Python I2C Для установки модуля Python I2C введите в терминале команды: opkg update оркд install python-light pyOnionI2C Для использования модуля добавьте в программу строку импорта: import onionI2C Модуль Python I2C поддерживает следующие функции: ♦ onioni2c.onioni2co — создать объект для последующих обращений. Пример: i2c = onioni2c. Onioni2c (). Параметры функции не предусмотрены; ♦ readBytes (devAddr, addr, size) — прочитать заданное количество баЙТОВ size из регистра с адресом addr в устройстве с адресом devAddr. Пример: data = readBytes (0x30,0x14,3) — прочитать 3 байта ПОДРЯД ИЗ регистра 0x14 устройства с адресом на шине Охзс;
Микрокомпьютер Отеда2 265 ♦ writeByte (devAddr, addr, value) — записать ОДИНОЧНЫЙ байт В регистр addr устройства С адресом devAddr. Пример: writeByte (ОхЗС, 0xl4f OxFC); ♦ writeBytes (devAddr, addr, values) —записать последовательность байтов values в регистр addr устройства с адресом devAddr. Пример: writeBytes (ОхЗС, 0x14, [0хЕ4, ОхАА, OxlD]); ♦ write (devAddr, values) — записать последовательность байтов values в устрой- ство с адресом devAddr без указания регистра. Пример: write(0x3C,[ 0хЕ4,ОхАА,OxlD]). Практические примеры работы с устройствами 12С рассмотрены в главе 13. 12.6. Файловый менеджер Midnight Commander Midnight Commander— это популярный консольный файловый менеджер, рабо- тающий в псевдографическом окне терминала (рис. 12.16). Он облегчает переме- щение, копирование, просмотр и редактирование файлов. Сайт менеджера Midnight Commander расположен по адресу: https://midnight-commander.org/. Для установки менеджера введите команды: opkg update оркд install me Менеджер работает в окне терминала PuTTY или приложения Console Terminal. Для корректного отображения панели менеджера в PuTTY должна быть указана правильная кодировка: Window | Translation | Remote character set | UTF-8. COM:; - PuTTv П Рис. 12.16. Рабочая панель менеджера Midnight Commander
266 Глава 12 Менеджер запускается командой тс в окне терминала. Перечень команд и функций менеджера весьма обширен, но вы без труда освоите их в процессе работы. Пере- числим лишь основные команды управления. Клавиша <Alt> одновременно с числовой клавишей <1>...<9> — одна из команд нижнего ряда меню. Для переключения на верхнее меню можно использовать кла- вишу <F9>, а для выхода из программы— клавишу <F10>. Для переключения между правой и левой панелью используйте клавишу табуляции. Панели меню за- крываются двойным нажатием на клавишу <Esc>. В меню Options | Configuration можно настроить однократное нажатие. Если вам требуется перемещать файлы между Omega2 и стационарным компьюте- ром, или вы предпочитаете графический интерфейс Windows, воспользуйтесь при- ложением WinSCP (см. разд. 2.9.2). 12.7. Расширение пространства памяти Даже при использовании расширенной версии Omge2 Plus встроенной памяти мо- жет оказаться недостаточно. Нехватка может коснуться как флеш-памяти, в кото- рой хранятся прошивка и файлы пользователя, так и оперативной памяти. Расши- рить объем доступной памяти можно тремя способами: ♦ использовать USB-накопитель или карту MicroSD для хранения пользователь- ских файлов. Например, звуковые файлы, изображения или большие файлы ло- гов следует хранить на внешнем носителе; ♦ использовать USB-накопитель или карту MicroSD как загрузочный носитель; ♦ использовать USB-накопитель как хранилище своп-файла для расширения опе- ративной памяти (ОЗУ). Эти способы можно использовать одновременно. МЛ Л. Использование карты MicroSD и USB-накопителя В идеологии Linux любое внешнее устройство рассматривается как файл. После подключения внешний накопитель должен быть в системе смонтирован. Монтиро- вание означает подключение внешней памяти к области доступной памяти систе- мы. В Omega2 настроено автоматическое монтирование внешних носителей при их подключении. Все, что будет сказано далее, в равной степени относится к внешним USB-накопителям и картам MicroSD. По умолчанию внешние носители монтируются в каталог /tmp/mounts/. Подключите носитель к разъему USB или установите карту MicroSD в слот и введите команды: cd /tmp/mounts/ Is Внешний USB-накопитель будет смонтирован под именем usb-ai. Чтобы перейти в каталог накопителя, введите команду: cd /tmp/mounts /USB-Al
Микрокомпьютер Отеда2 267 Аналогично карта MicroSD будет смонтирована под именем sd-pi. В имени нако- пителя добавка pi означает номер раздела (Partition). Если накопитель разбит на несколько логических разделов, то вы увидите несколько накопителей— напри- мер: sd-pi и SD-P2, хотя установлена всего одна физическая карта памяти. По указанным путям вы можете найти нужный накопитель в программе WinSCP. Теперь вы можете сохранять на этом накопителе программы и запускать их с внешнего носителя либо записывать на него логи и данные. В главе 13 мы рас- смотрим пример использования торрент-клиента, который хранит файлы на внеш- нем диске. Размонтирование накопителя Перед отключением накопителя он должен быть обязательно размонтирован в сис- теме. В противном случае при следующем подключении носителя вы можете полу- чить в терминале сообщение об ошибке файловой системы. Для ремонтирования накопителя введите команду umount <накопитель> — например: umount / tmp /mounts /USB- Al Форматирование внешних накопителей Если подключить к Omega2 накопитель, отформатированный в ОС Windows, то в большинстве случаев он будет нормально распознаваться и работать. Но дня таких специфических применений, как размещение системного своп-файла, накопитель необходимо отформатировать в специальном формате ext4 для ОС Linux. ОС Windows не распознает файловую систему ext4 и просит заново отформатировать накопитель. Поэтому для работы с Omega2 желательно выделить отдельный нако- питель, который не понадобится для работы с Windows-компьютером. Установим инструменты для работы с файловой системой накопителей: opkg update оркд install kmod-usb-storage-extras e2fsprogs kmod-fs-ext4 Отмонтируем накопитель, который будем форматировать: ♦ карта MicroSD: umount /tmp/mounts/SD-PI ♦ накопитель USB: umount /tmp/mounts/USB-A1 Теперь мы будем обращаться к накопителю по имени физического устройства, которое отображается в каталоге /dev/. По умолчанию используются следующие имена: ♦ карта MicroSD: mmcbikOpi ♦ накопитель USB: sdai Чтобы убедиться в наличии адаптера этих устройств в системе, можно ввести команду: is /dev/. Если накопитель разбит на разделы, то будут отображаться не- сколько устройств — например: sda2, штсЫкОрЗ и т. д. Если использовать USB-хаб
268 Глава 12 и подключить к нему несколько накопителей, то они будут обозначены разными буквами: sdai, sdbi... Будьте очень внимательны и аккуратны при выборе накопителя! Данные с отформа- тированного носителя будут необратимо утрачены. Чтобы избежать путаницы, на время форматирования подключайте только тот накопитель, который надо отформа- тировать. Запускаем форматирование накопителя: ♦ карта MicroSD: mkfs.ext4 /dev/irmcblkOpl ♦ накопитель USB: mkfs.ext4 /dev/sdal Если накопитель содержит ранее созданную файловую систему, будет запрошено подтверждение. Вводим у, нажимаем клавишу <Enter> и ждем окончания формати- рования. Изменение точки монтирования по умолчанию Изменим путь, по которому будут доступны внешние накопители, на более корот- кий и понятный. Создайте новый каталог mydisk и откройте полный доступ к нему: mkdir mydisk chmod 777 mydisk Запустите файловый менеджер Midnight Commander, перейдите в каталог /etc/config и выделите файл mountd (рис. 12.17). Рис. 12.17. Редактирование файла mountd
Микрокомпьютер Отеда2 269 Нажмите комбинацию клавиш <Alt>+<4> для редактирования файла. По умолча- нию файл содержит строки: config mountd mountd option timeout 60 option path /tmp/mounts/ Измените путь /tmp/mounts/ на /mydisk/ и нажмите комбинацию клавиш <Alt>+<2> для сохранения файла. Дважды нажмите клавишу <F10> для выхода из редактора и файлового менеджера. Перезапустите сервис автомонтирования командой: /etc/init.d/mountd restart Если все сделано правильно, вы увидите сообщения об успешном монтировании накопителей. Теперь внешние накопители будут доступны в каталоге /mydisk. 12.7.2. Загрузка с внешней карты памяти Даже если вы храните свои программы и файлы данных на подключаемом внешнем накопителе, это лишь частично решает проблему переполнения флеш-памяти. Дело в том, что все пакеты расширений, которые вы скачиваете при помощи opkg, по умолчанию устанавливаются в корневую файловую систему. Например, при работе над этой книгой я интенсивно изучал возможности Omega2 Plus и буквально за неделю заполнил 28 мегабайт флеш-памяти из 32. Изучая возможности Linux и своего микрокомпьютера, вы тоже будете скачивать различные пакеты и экспериментировать с ними. Чем шире набор установленных утилит, тем меньше остается места во встроенной памяти. Удалять невостребован- ные пакеты или сбрасывать прошивку до заводских настроек — не всегда прием- лемые варианты. Существуют два метода расширения памяти программ за счет внешнего носителя: ♦ pivot-root— полная замена встроенной флеш-памяти внешним накопителем с переносом всех файлов. Обновления операционной системы также будут уста- навливаться на внешний накопитель; ♦ pivot-overlay— на внешний накопитель выносится только перезаписываемая часть файлов операционной системы. Защищенные от записи системные файлы остаются во встроенной памяти. Производитель рекомендует использовать именно этот метод, поскольку он проще в настройке и безопаснее. Этот метод было бы правильнее называть не загрузкой, а «подгрузкой» с внешнего накопи- теля. Давайте разберемся, как он работает. Файловая система Omega2 состоит из двух основных частей: ♦ /гот — содержит базовую часть прошивки, доступную только для чтения; ♦ /overlay— содержит дополнения и расширения базовой части— например, дополнительно установленные пакеты и файлы конфигурации. При загрузке эти две части объединяются в единую файловую систему с корневым каталогом /, в котором вы можете видеть остальные вложенные каталоги. Процеду-
270 Глава 12 pa pivot-overlay переносит часть /overlay на внешний накопитель прозрачно для пользователя, который замечает лишь увеличение доступной области памяти. Перенос системных файлов на внешний накопитель — это серьезная и в некоторой степени рискованная процедура. Если накопитель выйдет из строя или будет слу- чайно отформатирован, вы потеряете дополнительные пакеты (Python, Git и пр.), настройки для этих пакетов и системных программ, а также созданные вами пользо- вательские файлы. Рекомендуется создать резервную копию важных файлов перед расширением памяти, а также сделать копию содержимого внешнего накопителя после переноса файлов. Если вы используете версию Omega2 Plus, то можете расширить системную память при помощи карты MicroSD, а владельцам обычного Omega2 удастся использовать только USB-накопитель. Подключите выбранный накопитель к Omega2 и отформатируйте его в файловую систему ext4, как сказано в предыдущем разделе. Это обязательное требование к файловой системе для надежной работы. Запомните имя устройства, которое ука- зывали при форматировании. Введите следующие команды: mkdir /mnt/<MMH устройства> mount /dev/<HMH устройства> /mnt/Чимя устройства> Например, ДЛЯ MicroSD: mkdir /mnt/mmcblkOpl. Перенесем содержимое /overlay на внешний накопитель командой: mount /dev/<HMH устройства> /mnt/ ; tar -С /overlay -cvf - . I tar -C /mnt/ -xf - ; umount /mnt/ Эта команда вводится одной строкой! Теперь настроим автоматическое монтирование каталога /overlay при включении микрокомпьютера. Для этого сначала установим пакет block-mount: opkg update opkg install block-mount Создадим точку входа fstab: block detect > /etc/config/fstab При помощи встроенного редактора Midnight Commander или WinSCP отредакти- руем файл конфигурации по адресу /etc/config/fstab. Найдите в этом файле строку: option target щ /mnt/<иьля устройства^ и измените ее на: option target '/overlay1 Теперь найдите строку: option enabled f0f и замените ее на: option enabled f1•
Микрокомпьютер Отеда2 271 Сохраните файл и перезагрузите Omega2 командой reboot. После завершения за- грузки проверим объем доступной памяти (рис. 12.18). Я использовал в качестве внешнего накопителя быструю карту MicroSD SDHC Class 10 на 4 Гбайт. В вашем случае значения могут отличаться в зависимости от объема использованного нако- пителя. Обновление версии прошивки, сброс к заводским настройкам или повторная пере- запись прошивки аннулируют pivot-overlay— файловая система вернется к исход- ному состоянию, когда используется только флеш-память. Пользовательские файлы во флеш-памяти также будут удалены. \ Рис. 12.18. Объем доступной памяти программ после расширения на карту MicroSD 4 Гбайт 12.7.3. Своп-файл на внешнем носителе В предыдущих разделах мы разобрались, как увеличить объем памяти для хранения программ и данных. Но вы можете оказаться в ситуации, когда для работы про- грамм не хватит оперативной памяти (ОЗУ). Это далеко не редкость. Даже обыч- ные компьютеры, оснащенные гигабайтами ОЗУ, вынуждены использовать своп- файлы. Аналогичная технология применяется в мобильных устройствах. Своп-файл (Swap File) — это специальный файл на физическом носителе, который задействуется операционной системой для временного хранения данных из ОЗУ, которые в настоящий момент не используются. Это позволяет программам исполь-
272 Глава 12 зовать объем памяти ОЗУ больший, чем доступно физически. Для сохранения быст- родействия системы следует применять для хранения своп-файла максимально быстрые запоминающие устройства. Скачаем и установим пакеты, необходимые для создания и использования своп-файла: opkg update opkg install swap-utils block-mount Убедитесь, что нужный накопитель подключен к Omega2. Своп-файл можно соз- дать как на USB-накопителе, так и на карте памяти MicroSD. В нашем примере мы создадим своп-файл на той же самой карте памяти, на которую в предыдущем раз- деле перенесли содержимое /overlay, поскольку она теперь должна всегда нахо- диться в слоте. Если вы хотите использовать USB-накопитель, вместо sd-pi укажи- те устройство usb-ai. Введите команду: dd if=/dev/zero of=/tmp/mounts/SD-PI/swap.page bs=lM count=256 Утилита dd для создания, конвертации и записи файлов — это очень мощный инст- румент. Запись данных в неправильное место может нанести большой вред систе- ме. Будьте очень аккуратны с параметрами команды! В данном случае утилита создает файл с именем swap.page, состоящий из 256 блоков размером 1 мегабайт, заполненных байтами 0x00. Сообщаем операционной системе Linux, что теперь у нее есть своп-файл: mkswap /tmp/mounts/SD-Pl/swap.page и включаем его в работу командой: swapon /tmp/mounts/SD-Pl/swap.page Теперь введите команду free и посмотрите, что у вас получилось: root@Qmega-BE07:/# free free shared buffers cached 22748 212 5132 78560 106440 262140 В системе появился активный своп-файл размером 262 140 килобайт (256 мегабайт). 12.7.4. Автоматическое включение своп-файла после перезагрузки К сожалению, своп-файл, который мы так заботливо создали и подключили, от- ключится после перезагрузки. Но есть и хорошая новость. Можно сделать так, что- бы своп включался автоматически. Для этого нужно применить другой способ автомонтирования внешних накопителей, отличный от способа, установленного по умолчанию. Он работает одинаково для карт MicroSD и USB-накопителей — надо лишь подставить путь к нужному устройству. Mem: total 125748 -/+ buffers/cache: Swap: 262140 used 103000 19308 0
Микрокомпьютер Отеда2 273 Прочитаем информацию о подключенных накопителях и сохраним ее в файл кон- фигурации fstab: block detect > /etc/config/fstab Выводим конфигурацию на экран командой: uci show fstab Вы должны увидеть нечто, наподобие таких строк: fstab.Gglobal[0]=global fstab.@global[0].anon_swap=f 0f fstab.@global[0].anon_mount=f 0f fstab.@global[0].auto_swap=f1f fstab.^global[0].auto_mount=f1? fstab.Gglobal[0].delay_root=f 5f fstab.Gglobal[0].check_fs=f 0f fstab.@mount[0]=mount fstab. Amount [ 0 ] . target-' /mnt/mmcblkOpl • fstab.@mount[0].uuid='80173alf-084c-4a9e-a850-efeecf99e7dd» fstab.@mount[0].enabled='O' Полужирным шрифтом выделены строки, относящиеся к установленной в системе карте памяти MicroSD. Если бы был подключен накопитель USB, то ему бы соот- ветствовал путь: fstab.@mount[0].target=f/mnt/sdalf. Разрешим монтирование накопителя при запуске системы: uci set fstab.@mount[0].enabled=tll uci commit fstab и дадим команду использовать файл fstab при загрузке системы: /etc/init.d/fstab enable block mount Теперь при помощи встроенного редактора WinSCP или Midnight Commander откройте файл /etc/rc.local и перед строкой exit о вставьте скрипт, который будет автоматически срабатывать по окончании загрузки Omega2. Текст скрипта зависит от того, используете ли вы расширение памяти pivot-overlay, о котором рассказано в предыдущем разделе. Дело в том, что при переносе /overlay содержимое карты памяти в итоге оказывается подмонтировано к этому каталогу. В таком случае укажите в скрипте путь /overlay/swap.page, одинаковый для MicroSD и USB-накопителя. Содержимое файла rc.local должно в итоге выглядеть так: SWAP_FILE="/overlay/swap.page" if [ -e "$SWAP_FILE" ]; then swapon $SWAP_FILE fi exit 0
274 Глава 12 Если pivot-overlay не используется, то для карты памяти MicroSD строка пути к своп-файлу выглядит так: SWAP_FILE=" /mnt/mmcblkOpl/swap. page" Для USB-накопителя путь к своп-файлу по умолчанию будет таким: SWAP_FILE=f7mnt/sdal/swap. page" Перезагрузите Omega2 и при помощи команды free удостоверьтесь, что своп-файл действительно подключен. 12.8. Особенности использования Ошеда2 Микрокомпьютер Omega2 представляет собой модульное устройство, которое рассчитано на эксплуатацию совместно с одним из вариантов базовой платы и фирменных модулей расширения. При отклонении от стандартных вариантов у на- чинающих пользователей могут возникнуть некоторые проблемы. 12.8.1. Необходимость стабильного питания Omega2 относится к так называемым бурстовым потребителям тока (от англ. burst — скачок, выброс). Это означает, что потребляемый платой микрокомпьютера ток может изменяться резкими скачками, внезапно. Средний потребляемый ток ко- леблется в пределах 140-200 миллиампер, но во время загрузки, подключения к Wi- Fi и внешним носителям внезапные броски тока могут достигать 400 миллиампер. Поэтому производитель рекомендует использовать источник питания 5 вольт с максимальным током отдачи до 500 миллиампер. Не забывайте учитывать ток, потребляемый модулями расширения и внешними накопителями. Если применяет- ся дешевый линейный стабилизатор напряжения, то его вход и выход должны быть зашунтированы конденсаторами с емкостью не менее 1 мкФ. В идеале, на входе и выходе стабилизатора должны присутствовать подключенные пары из соединен- ных параллельно керамического конденсатора на 0,33-1 мкФ и электролитического на 5-10 мкФ. Признаком проблем с электропитанием может являться самопроиз- вольный сброс или зависание микрокомпьютера во время загрузки. 12.8.2. Необходимость буферизации выводов Ни один из выводов Omega2 не защищен при помощи буферных микросхем. По- этому превышение допустимого тока или разряд статического электричества могут вывести микрокомпьютер из строя. Впрочем, это слабое место почти любого уст- ройства, включая Raspberry Pi и стандартные платы Arduino. Но есть особый недостаток, который был выявлен автором в процессе работы с самодельными модулями расширения. Вывод CLK, который применяется для тактирования устройств на шине SPI, имеет очень низкую нагрузочную способность и не переносит наличия паразитной емко- стной нагрузки при подключении внешних устройств. Дело в том, что линия
Микрокомпьютер Отеда2 275 CLK — общая для всех устройств SPI, включая встроенную флеш-память, и рабо- тает на максимальной частоте для повышения быстродействия устройства. При подключении внешнего устройства SPI с паразитной емкостью входа CLK около 80-100 пФ, из-за этой емкости искажается форма тактирующих импульсов, и Omega2 перестает загружаться или загружается с ошибками. Решение проблемы заключается в использовании специального быстродействующего буфера шины. Для монтажа на макетной плате можно использовать многоканальные буферные микросхемы 74НС125 или 74HC244N. Символы НС обозначают повышенное быст- родействие. Для монтажа на печатной плате можно применить миниатюрный одно- канальный буфер M74VHC1GT125 в корпусе SOT23-5. Указанные буферные микросхемы могут работать как преобразователь выходного логического уровня, если нужно управлять пятивольтовым внешним устрой- ством, — достаточно запитать микросхему буфера напряжением +5 В. Пример использования буферной микросхемы приведен в главе 13.
ГЛАВА 13 Примеры программ и проектов для 0mega2 Микрокомпьютерная платформа Onion Omega построена по модульному принципу, причем модульность относится не только к аппаратной части,— программное обеспечение в виде специальных библиотек на языках Python и С также можно подгружать по мере необходимости. Дополнительные модули для микрокомпьютера Omega2 стоят весьма дорого, иногда дороже базового компьютера. К счастью, в большинстве случаев можно без труда использовать подходящие модули для платформы Arduino, которые стоят намного дешевле и продаются во множестве магазинов. На основе модулей Arduino можно разработать интересные и несложные проекты, иллюстрирующие приме- нение программных модулей. Рассмотрим подробнее подключение популярных модулей расширения для Arduino и простые проекты на их основе. 13.1. Подключение OLED-дисплея На рис. 13.1 изображены фирменный модуль Omega2 OLED (а) и популярный 12С OLED-дисплей для платформы Arduino (б). Эти дисплеи различаются только кон- струкцией платы, поэтому подключение их не составит труда. Мы уже использова- ли аналогичный OLED-дисплей в разд. ILL Настоятельно рекомендую приобрести именно такой дисплей. Он готов к использованию совместно с Omega2 сразу после покупки — вам не придется менять адрес дисплея на шине 12С или вносить иные доработки. Для подключения дисплея соедините четыре вывода Omega2 с соответствующими выводами дисплея (рис. 13.2): ♦ SCL->SCL; ♦ SDA->SDA; ♦ GND-+GND; ♦ 5V->VCC.
Примеры программ и проектов для Отеда2 277 a 6 Рис. 13.1. Модуль Omega2 OLED (а) и дисплей для Arduino (б) Рис. 13.2. Подключение к Omega2 OLED-дисплея Дисплей можно питать напряжением 5 В? потому что он оборудован встроенным источником питания 3,3 В. Согласование логических уровней не требуется. Прошивка Omega2 по умолчанию поддерживает команду oied-exp. Управлять дис- плеем из командной строки не очень удобно. Ограничимся простейшей проверкой исправности дисплея, а дальше будем использовать графический интерфейс Console и модуль OLED языка Python 2.7.
278 Глава 13 Инициализируйте дисплей: oled-exp -i Выведите текст на дисплей: oled-exp write "Hello, world!\n\nThis is my text!" Выключите питание дисплея и включите снова при помощи команд: oled-exp power off oled-exp power on Очистите дисплей: oled-exp -с Полный перечень команд и параметров можно вывести в терминал командой: oled-exp -h Если дисплей откликается на команды, можно продолжить изучение приемов рабо- ты с ним. Откройте браузерное приложение Onion Console (см. разд. 12.3). Запусти- те утилиту под названием OLED Control. Она позволяет выполнять основные дей- ствия с дисплеем: выводить текст и рисунки, очищать экран, инвертировать изо- бражение, менять яркость изображения, запускать циклическую прокрутку рисунка. Текст следует вводить непосредственно на изображении экрана дисплея, когда активна вкладка Text. Перейдите на вкладку Image и выберите изображение для вывода на дисплей. В принципе, это может быть любое изображение. Утилита OLED Control автомати- чески и очень быстро отмасштабирует и конвертирует его в битовое изображение с размерами 128x64 пиксела. Но если вы хотите быть уверены в результате, заранее приготовьте черно-белое изображение 128x64 пиксела. Сразу после того, как файл выбран, он конвертируется и выгружается в дисплей. На момент подготовки книги кнопка Save to Omega не работала. Конвертированный файл на самом деле автома- тически загружается в каталог /tmp под именем tmp.XXXXXX, где ХХХХХХ— случай- ный набор символов. Вы можете найти этот файл при помощи файлового менедже- ра — например, WinSCP, переименовать с расширением led и впоследствии исполь- зовать в своих прикладных программах на Python или С. Готовое изображение можно также вывести на дисплей из памяти Omega2 при помощи команды oled-exp draw <icd f iie>, например: oled-exp draw /trap/test_image. led Теперь установим модуль oledExp для интерпретатора Python 2.7. Введите в терми- нале команды: opkg update opkg install python-light pyOledExp На сегодняшний день библиотека OLED-дисплея не поддерживает рисование гра- фических примитивов (линий, окружностей, многоугольников). Кроме функций вывода текста и управления режимами дисплея поддерживаются функции выгрузки
Примеры программ и проектов для Omega2 279_ отдельных байтов и битовых изображений. Если необходимо изобразить на экране графические элементы, вам придется самостоятельно разработать функции побай- тового вывода этих элементов или выводить битовые изображения. С полным перечнем функций для работы с OLED-дисплеем и их описаниями мож- но ознакомиться по адресу: https://docs.onion.io/omega2-docs/oled-expansion- python-module.html#programming-flow-10. Пример простой программы на языке Python для управления OLED-дисплеем при- веден в листинге 13.1. Скопируйте из сопровождающего книгу электронного архива, размещенного на сайте издательства (см. приложение), файлы oled-exp.py и BHVJogo.lcd. Вы можете подготовить собственный файл монохромного битового изображения, заменив при этом имя файла в программе. Сохраните оба файла в каталог /root при помощи лю- бого файлового менеджера — например, WinSCP. Каталог /root должен иметь права доступа 755. Если это не так, установите права командой: chmod 755 /root. Запустите программу на выполнение: python /root/oled-exp.py Листинг 13,1, Г1р«мер протршшшы шт работы & OLED-дисплеем • # импортируем нужные библиотеки from OmegaExpansion import oledExp import time print 'Starting to use oled-exp functions...1 # Инициализация дисплея ret = oledExp.driverlnit() print "driverlnit return: ", ret if (ret != 0): exit() # выводим текст на экран ret = oledExp.write ("Welcome to the Omega") print "write return: ", ret if (ret != 0): exit() time, sleep (2) # задаем новую позицию курсора ret = oledExp.setCursor(3,8) print "write return: ", ret if (ret != 0): exit()
280 Глава 13 # выводим текст на экран ret = oledExp.write("Invent the future") print "write return: ", ret if (ret != 0): exit() time.sleep(2) # инвертируем изображение ret = oledExp.setDisplayMode(1) print "setDisplayMode return: ", ret if (ret != 0): exit() time.sleep(2) # отменяем инверсию изображения ret = oledExp.setDisplayMode(0) print "setDisplayMode return: ", ret if (ret != 0): exit() time.sleep(2) # устанавливаем уменьшенную яркость ret * oledExp.setBrightness(8) print "setBrightness return: ", ret if (ret != 0): exit() time.sleep(2) # устанавливаем максимальную яркость ret = oledExp.setBrightness(255) print "setBrightness return: ", ret if (ret != 0): exit() time.sleep(2) # очищаем дисплей ret = oledExp.clearO print "clear return: ", ret if (ret != 0): exit() # выводим битовое изображение ret = oledExp. drawFromFile (" root/bhv__logo. led") print "drawFromFile return: ", ret if (ret != 0): exit() time, sleep (2) print "Done"
Примеры программ и проектов для Отеда2 281 Аь Наличие в тексте реальной программы комментариев на русском языке нежела- /!\ тельно — интерпретатор Python может выдать сообщение об ошибке. В тексте книги эти комментарии вставлены для облегчения понимания. Программа начинается с импорта библиотек oledExp и time. Библиотека time потре- буется для формирования пауз продолжительностью две секунды между примера- ми при ПОМОЩИ функции time.sleep(2). Каждая функция для работы с дисплеем возвращает 09 если сработала успешно, и 1 в случае неудачи. При вызове каждой функции мы присваиваем возвращаемое значение переменной ret и проверяем ее. Если произошла ошибка обращения к дисплею, и функция возвратила значение 1, мы прекращаем выполнение скрипта. 13.2. Подключение модуля PWM Servo Широтно-импульсная модуляция, или ШИМ (PWM, Pulse Width Modulation), в лю- бительской практике обычно применяется для управления обычными сервомашин- ками (поэтому модуль и называют PWM Servo). Угол поворота вала сервомашинки зависит от длительности положительных импульсов сигнала. Другим стандартным применением ШИМ является плавная регулировка яркости светодиодов. Она осно- вана на инерционности человеческого зрения — чем короче активные импульсы и длиннее паузы между ними, тем меньше визуально воспринимаемая яркость свето- диода. На самом деле, светодиод вспыхивает с неизменной яркостью, меняется только длительность вспышек. ШИМ на выходе микросхемы можно генерировать аппаратно или программно. При аппаратной генерации используется встроенный таймер-счетчик микросхемы. В него записывают значение, при достижении которого счетчик сбрасывается, ме- няет логический уровень на выходе и начинает отсчет вновь. Процесс циклически повторяется, поэтому на выходе микросхемы генерируются импульсы, длитель- ность которых зависит от значения, предварительно записанного в счетчик. Ста- бильность таких импульсов достаточно высока, особенно у микроконтроллеров, потому что они тактируются кварцевым генератором. При программной эмуляции ШИМ используется программный цикл со счетчиком и управление логическим уровнем на выводе при помощи программного кода. Но кроме обработки счетчика процессор выполняет и другие задачи. Он может полу- чать и обрабатывать прерывания от внешних устройств и внутренних функцио- нальных модулей. Кроме того, длительность отработки цикла зависит от машинно- го кода, созданного компилятором. Поэтому сигнал ШИМ, выработанный про- граммно, очень нестабилен. Ему присуще «дрожание» длительности импульсов (джиттер). И если в случае регулировки яркости светодиодов это практически не- заметно, то сервомашинки очень чувствительны к джиттеру. Причем, чем выше качество и быстродействие сервомашинки, тем сильнее она реагирует на дрожание сигнала. Некоторые сервомашинки могут даже перегреться и сгореть. Запрет внеш- них прерываний приведет лишь к тому, что процессор не будет выполнять никакую полезную работу, кроме генерации импульсов ШИМ, а это обычно неприемлемо.
282 Глава 13 В тех случаях, когда микроконтроллер не оборудован аппаратной поддержкой ШИМ или выводов микроконтроллера не хватает, используют специальные микро- схемы генераторов ШИМ-сигнала. В любительской практике наиболее распро- странены модули ШИМ на основе микросхемы РСА9685. Эта микросхема управля- ется по шине 12С и содержит 16-канальный аппаратный генератор ШИМ. Микрокомпьютер Omega2 не оснащен аппаратной поддержкой ШИМ, и компания Onion предлагает фирменный модуль расширения (рис. 13.3, а). Но мы воспользу- емся недорогим модулем для Arduino, который собран на такой же микросхеме (рис. 13.3, б)1. Поэтому фирменная библиотека Python и утилита в браузерном при- ложении Onion Console полностью совместимы с этим модулем. а б Рис. 13.3. Фирменный модуль PWM Onion (а) и модуль PWM Arduino (б) Прежде всего, зададим нужный адрес модуля на шине 12С. Для этого на плате модуля капельками припоя установим перемычки А1, A3 и А4 (рис. 13.4). ,1. I ■ .1 Рис. 13.4. Перемычки для установки адреса модуля PWM Servo 1 Ключевые слова для поиска в интернет-магазинах: PWM Servo PCA9685.
Примеры программ и проектов для Отеда2 283 Для подключения модуля PWM Servo к Omega2 мы задействуем шесть проводов: ♦ SCL -»• SCL; SDA- GND V+^ VCC- ОЕ-» -►SDA; -+GND; 5V; -> 3.3V; GND. Вывод модуля V+ предназначен для раздельной подачи питающего напряжения на выходные каскады микросхемы. Например, можно питать логику микросхемы на- пряжением 3,3 В (вывод VCC) для совместимости логических уровней с Omega2, a выходные каскады (вывод V+) запитать напряжением +5 В для совместимости со стандартной сервомашинкой. На входе ОЕ должен быть низкий уровень. Этот вы- вод можно никуда не подключать, но лучше соединить с выводом GND для повы- шения помехоустойчивости. К любому из выводов ШИМ подключите обычную сервомашинку (рис. 13.5). Рис. 13.5. Пример подключения к Отеда2 модуля PWM Servo и сервомашинки Теперь установите библиотеку поддержки модуля PWM Servo для языка Python. Для этого введите в терминале команды: opkg update оркд install python-light pyPwmExp Откройте браузерное приложение Onion Console (см. разд. 12.3). Запустите утилиту под названием PWM Control (рис. 13.6). По умолчанию настройки действуют син- хронно на все каналы. Щелкая мышью на изображении разъемов, можно выбрать
284 Глава 13 отдельный канал. Имейте в виду, что частота импульсов устанавливается для всех каналов одновременно, — раздельно меняется только длительность импульсов. Для стандартной сервомашинки используется частота PWM Frequency 50 Гц и коэф- фициент заполнения Duty Cycle в диапазоне 3,5-13%. f.U . Hi PWm Channel Dyty Cycle * Рис. 13.6. Онлайн-приложение для тестирования модуля PWM Servo Попробуйте менять коэффициент заполнения в допустимых пределах. Вал серво- машинки должен реагировать на изменение длительности импульсов. Чтобы из- менение сработало, после ввода нового числа в поле Duty Cycle надо щелкнуть мышью снаружи этого поля. Набор функций модуля Python для управления модулем PWM Servo невелик, и мы можем полностью привести их в этой книге: ♦ pwmExp.driverinito — инициализация драйвера PWM. После выполнения этой команды можно начинать использовать остальные функции; ♦ pwmExp. checkinit () — проверка инициализации драйвера. Функция возвращает 1 при успешной инициализации и 0 — при неудачной; ♦ setFrequency(frequency) — настройка частоты генератора. Частота может быть задана только в диапазоне от 24 до 1526 Гц. Даже если в аргументе функции указать значение, лежащее вне диапазона, оно будет автоматически обрезано до ближайшего граничного значения; ♦ setupDriver (channel, duty, delay) — настройка параметров заданного канала channel. Если в качестве номера канала указать -1, настройки будут применены ко всем каналам; duty— коэффициент заполнения импульсов от 0 до 100%; delay— задержка импульса в канале в процентах. Для стандартной сервома- шинки delay = о, а параметр duty находится в диапазоне от 3,5 до 13%;
Примеры программ и проектов для Отеда2 285^ ♦ pwmExp.disabieChipo — отключение тактового генератора микросхемы. Коман- да используется, когда нужно отключить управление внешним устройством, не отключая питание микрокомпьютера Omega2. Для возобновления работы гене- ратора необходимо повторно использовать функцию pwmExp. driverinit (). Если при управлении через Onion Console схема функционирует нормально, можно испытать простейшую программу на языке Python (листинг 13.2). Эта программа циклически меняет длительность импульсов на выходе SO, заставляя вал сервома- шинки совершать колебательные движения между крайними положениями. # импортируем библиотеки from QmegaExpansion import pwmExp import time # инициализируем микросхему ret = pwmExp. driverlnit () print "driverlnit return: ", ret if (ret != 0): exit() # проверяем инициализацию ret = pwmExp.checklnit() print "checking if initialized: ", ret if (ret != 1): print "Initialisation failed!!!" exit() # устанавливаем частоту 50 Гц ret = pwmExp.setFrequency(50) print "setFrequency return: ", ret if (ret != 0): exit() # запускаем "вечный" внешний цикл t - 1 while t — 1: i = 3.5 # прогон от минимума к максимуму while i <= 13: pwmExp.setupDriver(0, i, 0) time.sleep(0.02) i += 0.1 time.sleep(0.5) # прогон от максимума к минимуму while i >= 3.5: pwmExp.setupDriver(0, i, 0) time.sleep(0.02) i -=0.1 time.sleep(0.5)
286 Глава 13 Полезный совет Модуль PWM Servo можно использовать для увеличения количества цифровых вы- ходов контроллера, например, для управления реле или светодиодами. Если задать на выходе канала наполнение 100%, то на нем будет присутствовать постоянный логический уровень 1, а при наполнении 0% — логический ноль. Таким образом, ис- пользуя этот модуль, можно одновременно управлять большим количеством серво- машинок, реле и других внешних устройств. Но такая микросхема работает только в качестве выходных портов. Для увеличения количества двунаправленных портов микроконтроллера необходимо использовать специальные модули расширителей. 13.3. Подключение модуля расширителя портов Для увеличения количества портов GPIO микроконтроллеров применяются специ- альные микросхемы регистров ввода/вывода. Эти микросхемы подключаются к микроконтроллеру по шине 12С или SPI. Внутри такой микросхемы содержится двунаправленный регистр, каждый разряд которого соответствует выводу порта микросхемы. Чтобы задать логические уровни на выходах расширителя, необхо- димо записать в регистр микросхемы двоичное число, разряды которого соответст- вуют логическим уровням. При этом за один цикл записи можно установить все логические уровни. Аналогично, чтобы узнать логические уровни на входах, необ- ходимо по последовательной шине прочитать содержимое входного регистра и определить логический уровень нужного разряда. Расширители портов очень часто применяются в микроконтроллерных устройст- вах. Например, микросхему расширителя портов можно вынести на переднюю па- нель устройства, подключить к ней все кнопки и светодиоды и связать с платой микроконтроллера по шине 12С. Это намного удобнее и надежнее, чем выводить шлейф соединительных проводов непосредственно от портов микроконтроллера, поскольку расширитель не занимает порты микроконтроллера и защищает его от разрядов статического электричества. Компания Onion не предлагает фирменный универсальный модуль расширителя портов. Вместо этого они выпускают модуль Omega Relay Expansion (рис. 13.7, а), который содержит микросхему МСР23008 компании Microchip и два реле с рабо- чим напряжением обмотки 5 В. Остальные линии виртуальных портов вво- да/вывода микросхемы не задействованы. На мой взгляд, это не самое удачное кон- структивное решение, потому что у микрокомпьютера Omega2 мало свободных портов, к которым можно подключить внешние органы управления и индикации. В такой ситуации намного полезнее окажется универсальный модуль расширителя с полным набором разведенных на плате портов. К нему при желании можно под- ключить что угодно, в том числе отдельный модуль реле. Мы воспользуемся недорогим универсальным модулем расширителя портов для платформы Arduino на основе микросхемы PCF8574 (рис. 13.7, б). Микросхемы фирменного модуля Omega2 и модуля Arduino взаимно не совместимы, поэтому мы не сможем воспользоваться готовым модулем Python и утилитой Onion Console. Но
Примеры программ и проектов для Отеда2 287 а б Рис. 13.7. Модуль Omega Relay Expansion (а) и расширитель портов для Arduino (б) нам ничто не мешает использовать стандартную библиотеку I2C Python и напрямую обращаться к регистрам микросхемы. Если вы еще не установили библиотеку I С, сделайте это при помощи команд: opkg update opkg install python-light py0nionI2C Теперь подключите модуль расширителя портов к микрокомпьютеру Omega2 (рис. 13.8). Для тестирования модуля я подключил к выходам расширителя свето- диоды последовательно с резисторами 330 Ом. Все перемычки адреса шины 12С установлены в положение L (Low, низкий уровень). В этом случае модуль доступен для чтения и записи по адресу 0x38. Рис. 13.8. Подключение модуля расширителя портов и светодйодов
288 Глава 13 Обратите внимание: выходы микросхемы PCF8574 построены по схеме с открытым стоком. Поэтому светодиоды последовательно с резисторами подключаются к шине питания VCC и зажигаются, когда на выходе низкий уровень. При подключении реле с оптической развязкой и других внешних устройств не забудьте включить нагрузоч- ный резистор с номиналом от 330 Ом до 1 кОм между выводом модуля и шиной пи- тания. Протестируйте модуль при помощи командной строки. Введите команду записи низкого логического уровня во все разряды выходного регистра: i2cset -у 0 0x38 0x00 Если модуль подключен правильно, все светодиоды должны зажечься. Погасите светодиоды командой: i2cset -у 0 0x38 Oxff Загрузите в Omega2 простейшую тестовую программу на языке Python (лис- тинг 13.3). Эта программа циклически записывает двоичные значения в выходной регистр микросхемы, создавая эффект «бегущего огня». from QmegaExpansion import onionI2C import time # создаем объект i2c i2c - onionI2C.OnionI2C() # организовываем «бесконечный» цикл i « 0 while i — 0: status = i2c.write (0x38, [0Ы1111110]) time.sleep(0.5) status = i2c.write (0x38, [0Ы1111101]) time.sleep(0.5) status = i2c.write (0x38, [0Ы1111011]) time.sleep(0.5) status = i2c.write (0x38, [0Ы1110111]) time.sleep(0.5) Немного сложнее организуется чтение входных сигналов. Микросхема PCF8574 не имеет регистра конфигурации, который определяет назначение отдельных выводов. Поэтому считываются логические уровни, которые фактически присутствуют на выводах микросхемы в момент чтения, и эти уровни зависят от содержимого вы- ходного регистра. Напомню, что выходы микросхемы построены по схеме с откры- тым стоком. Поэтому, если для вывода записан ноль в соответствующем разряде выходного регистра, то этот вывод принудительно притягивается к «земле», и с не- го всегда будет считываться логический ноль. Если на такой вывод напрямую по- дать напряжение питания, то микросхема выйдет из строя! Поэтому для тех выводов, которые будут работать как входы, в соответствующие разряды выходного регистра всегда должна быть записана единица. Если в схеме
Примеры программ и проектов для Отеда2 289 часть выводов используется как входы, а остальные работают выходами, то перед записью числа в регистр на него следует накладывать битовую маску, где в разря- дах, соответствующих входам, стоят единицы. Кроме того, в библиотеке onioni2C отсутствует функция прямого чтения по адресу устройства (без указания адреса регистра). В функции readBytes(Ai, A2, n) необ- ходимо указать адрес устройства ai, адрес регистра А2 и количество байтов, кото- рые надо прочитать. Когда эта функция пытается записать в микросхему PCF8574 адрес регистра, то микросхема воспринимает это, как запись значения в выходной регистр. Поэтому при чтении состояния входов приходится вторым параметром указывать нужное содержимое выходного регистра. Фактически, при каждом счи- тывании состояния входов предварительно происходит запись в регистр выходов. Имейте это в виду и предварительно приготовьте правильное значение для записи. В листинге 13.4 приведен пример программы, которая в бесконечном цикле читает состояние входов. При каждом чтении в выходной регистр записывается число Oxff, благодаря чему все выводы находятся в состоянии высокого уровня и могут работать как входы. Если на каком-то выводе должен поддерживаться низкий уро- вень, вместо Oxff должно быть число с нулем в соответствующем разряде. Запусти- те программу и попробуйте соединять выводы модуля Р0...Р7 с линией GND — число в окне терминала должно меняться. from QmegaExpansion import onionI2C import time i2c = onionI2C.OnionI2C() i = 0 while i == 0: i2cdata = i2c.readBytes(0x38, OxFF, 1) time.sleep(0.5) print i2cdata print ("\n") 13.4. Модуль светодиодной матрицы 8x8 До сих пор мы при помощи соединительных проводов и макетной платы успешно подключали к микрокомпьютеру Omega2 готовые модули. Но нам вполне по силам изготовить самодельные модули расширения, которые подключаются к разъему отладочной платы Expansion Dock (см. рис. 12.2). Проект, о котором сейчас пойдет речь, разработан автором этой книги специально для сообщества пользователей Omega2. Он попал в еженедельный бюллетень луч- ших проектов и получил статус «Favorite Project on the Onion Community» (люби- мый проект сообщества Onion): https://onion.io/2bt-custom-8x8-led-expansion/. Ha-
290 Глава 13 значение этого несложного проекта — показать, как можно изготовить самодель- ный модуль расширения из доступных компонентов. За основу конструкции взят широко распространенный и недорогой модуль свето- диодной матрицы 8x8 на микросхеме МАХ7219 (рис. 13.9, а). Готовое устройство изображено на рис. 13.9, б. а б Рис. 13.9. Модуль светодиодной матрицы 8x8 (а) и самодельный модуль расширения (б) Схема модуля приведена на рис. 13.10. Как было сказано в разд. 12.8, линию CLK интерфейса SPI необходимо буферизировать при помощи специальной быстродей- ствующей микросхемы. В авторской конструкции модуль светодиодной матрицы смонтирован на печатной плате, поэтому использована малогабаритная микросхема M74VHC1GT125 в корпусе SOT23-5. Но с равным успехом матрицу можно размес- тить на макетной плате и использовать буферную микросхему 74НС125 или 74HC244N в корпусе DIP. Проект разработан в онлайновом редакторе EasyEDA. Схема и чертеж модуля дос- тупны по адресу: https://easyeda.com/valeriy.yatsenkov. Р1 и а? 26 25 24 23 22 21 20 19 19 %7 ,1* If 14 13 12 П "CS1 [61 ш: U2 M74VHC1GT125DT1G For breadboard mounting and development use 1С in DIP package: 74HC125 or 74HC244N U1 8x8 LEO Matrix VCC GND DIN cs CLK VCC GND - DOUT-U- LODA-Z— 1u Рис. 13.10. Принципиальная электрическая схема модуля светодиодной матрицы
Примеры программ и проектов для Отеда2 291 Микросхема МАХ7219— это специализированный дешифратор для управления светодиодными индикаторами, подключаемый по шине SPI. Микросхема может работать в режиме дешифратора для стандартных семисегментных индикаторов или управлять матрицей из 64-х светодиодов. Поддерживается регулировка ярко- сти, режим пониженного энергопотребления и различные режимы дешифрации. В листинге 13.5 продемонстрированы основные приемы работы с дешифратором, если он управляет матрицей светодиодов. import onionSpi import time # создаем объект индикатора spi = onionSpi.OnionSpi(1, 32766) # установка начальной яркости spi.writeBytes(ОхОА, [OxOF]) # установка лимита сканирования spi.writeBytes(OxOB, [0x07]) # очистка всех знакомест (регистры 0x01 ... 0x08) i = 0x01 while i < 0x09: spi.writeBytes(i, [0x00]) i += 1 # выход из режима сна spi.writeBytes(OxOC, [OxOF]) # включение тестового режима на 1 секунду spi.writeBytes(OxOF, [OxOF]) time.sleep(1) spi.writeBytes(OxOF, [0x00]) # режим No Decode (не декодировать) spi.writeBytes(0x09, [0x0 0]) # эффект "бегущая полоса" j - 1 while j < 6: i = 0x08 while i > 0x00: spi.writeBytes(i, [OxFF]) time.sleep(O.l)
292 Глава 13 spi.writeBytes(i, [0x00]) # построчное отображение битовых значений spi.writeBytes(0x08, [ObOOOOOOOl]) spi.writeBytes(0x07, [ObOOOOOOll]) spi.writeBytes(0x06, [ObOOOOOlll]) spi.writeBytes(0x05, [ObOOOOllll]) spi.writeBytes(0x04, [ObOOOlllll]) spi.writeBytes(0x03, [ObOOllllll]) spi.writeBytes(0x02, [ObOlllllll]) spi.writeBytes(0x01, [Obllllllll]) Программа начинается с подключения библиотек SPI и Time. Далее мы создаем объект индикатора, с которым будем работать. Устанавливаем максимальную яр- кость, записывая в регистр ОхОА значение OxOF. Затем задаем лимит сканирования. Этот параметр имеет смысл только для семисегментных числовых индикаторов и означает число активных знакомест от 1 до 8. Мы работаем с матричным индикато- ром, поэтому задаем максимальный лимит, чтобы иметь доступ ко всем светодио- дам матрицы. Далее мы обнуляем все регистры знакомест, записывая в них нули. Обратите вни- мание, что сразу после включения микросхема находится в режиме «сна». В этом режиме индикатор не функционирует, но мы можем работать с любыми регистрами как обычно. Благодаря этому сразу после включения на индикаторе не отображает- ся случайный «мусор». Мы можем очистить регистры, настроить режим отображе- ния, записать в регистры начальные данные, и лишь потом включить индикацию, записав значение OxOF в регистр Охос. Затем мы включаем режим тестирования, при котором зажигаются все светодиоды, ждем одну секунду и выключаем тестирование. После этого мы включаем режим «No Decode» (без декодирования). В этом режиме микросхема отображает битовое содержимое регистров памяти «как есть» — единица в разряде регистра означает свечение соответствующего светодиода. Восемь восьмибитных регистров соответ- ствуют восьми строкам матрицы светодиодов. Поочередно зажигая строки матрицы, создаем эффект бегущей светящейся полосы. Программа завершается построчной записью двоичных значений в регистры инди- кации. На индикаторе должен отобразиться светящийся треугольник. 13.5. Модуль семисегментных светодиодных индикаторов Этот проект аналогичен рассмотренному в разд. 13.4, но вместо светодиодной матрицы используются семисегментные световые индикаторы. За основу конструк- ции взят готовый модуль (рис. 13.11, я), который смонтирован на плате с разъ-
Примеры программ и проектов для Отеда2 293 а б Рис. 13.11. Модуль семисегментного индикатора (а) и готовое устройство (б) емом (рис. 13.11, б). Схема устройства полностью аналогична изображенной на рис. 13.10. Проверочная программа на языке Python приведена в листинге 13.6. import onionSpi import time # создаем объект индикатора spi = onionSpi.OnionSpi(1, 32766) # установка начальной яркости spi.writeBytes(ОхОА, [OxOF]) # установка лимита сканирования spi.writeBytes(OxOB, [0x07]) # очистка всех знакомест (регистры 0x01 ... 0x08) i - 0x01 while i < 0x09: spi.writeBytes(i, [0x00]) i += 1 # выход из режима сна spi.writeBytes(OxOC, [OxOF]) # включение тестового режима на 1 секунду spi.writeBytes(OxOF, [OxOF]) time.sleep(1) spi.writeBytes(OxOF, [0x00]) # режим No Decode (не декодировать) spi.writeBytes(0x09, [0x00])
294 Глава 13 j = l while j < 6: i = 0x08 while i > 0x00: spi.writeBytes(i, [OxFF]) time.sleep(0.1) spi.writeBytes(i, [0x00]) i -= 1 j += 1 # режим Code В Decode для всех знакомест spi. writeBytes (0x09, [OxFF]) i = 0x08 j = 0x01 while i > 0x00j spi.writeBytes(i, [j]) i -= 1 Отличие от листинга 13.5 здесь заключается лишь в том, что в конце программы устанавливается режим декодирования «Code В Decode». В этом режиме число, записанное в регистр, декодируется для отображения на соответствующем знако- месте. Поддерживается отображение псевдобуквенных символов и цифр. Напри- мер, если в регистр 0x01 записать число 0x06, то на первом знакоместе отобразится цифра 6, а если записать число 0x0f— отобразится символ F. Полная таблица пере- вода символов приведена в фирменном описании микросхемы МАХ7219. Про- грамма завершается записью последовательности чисел от 1 до 8 по порядку в со- ответствующие знакоместа. 13.6. Автономный клиент BitTorrent Микрокомпьютер Omega2 можно без труда превратить в автономное устройство для скачивания и раздачи файлов по протоколу BitTorrent. Это удобное решение для тех, кто не имеет возможности постоянно держать включенным обычный ком- пьютер. Маленький и экономичный Omega2 может работать круглосуточно и бес- шумно, потребляя при этом минимум энергии. Нарушение авторских прав— это преступление. Мы призываем вас скачивать и раздавать только легальные материалы, предназначенные для свободного распро- странения. Например, это могут быть свежие дистрибутивы операционной системы для Raspberry Pi. Раздавая такие файлы, вы оказываете помощь открытому сообще- ству пользователей. Для хранения скачанных файлов необходимо подключить к микрокомпьютеру Omega2 внешний USB-накопитель или SD-карту памяти. При подключении внеш- него накопителя на жестком диске убедитесь, что источник питания обладает дос-
Примеры программ и проектов для Отеда2 295 таточной мощностью для обеспечения пикового потребления, особенно в момент разгона шпинделя жесткого диска. Рекомендуется использовать источник питания с выходным током не менее 2 А. О подключении внешних накопителей рассказано в разд. 12.7.1. Торрент-клиент для операционной системы Linux называется Transmission. Чтобы запустить его на микрокомпьютере Omega2, придется настроить своп-файл, как рассказано в разд. 12.7.3. У версии Omega2+ достаточно встроенной памяти, но если одновременно с торрент-клиентом запускать другие программы, то можно столкнуться с нехваткой оперативной памяти даже в расширенной версии. Поэтому я рекомендую развернуть своп-файл в любом случае. Установите торрент-клиент Transmission: opkg update opkg install transmission-daemon-openssl transmission-web Подключите внешний накопитель к микрокомпьютеру Omega2. В нашем примере будем считать, что это USB-накопитель, который при подключении автоматически монтируется как /tmp/mounts/USB-A1/. Создайте на нем каталоги для хранения файлов: mkdir -p /tmp/mounts/USB-Al/downloads/incomplete Если при попытке создания каталогов появляется сообщение об ошибке: сапЧ create directory Vtmp/mounts/USB-Al/*: Symbolic link loop, отформатируйте внешний накопитель в файловой системе ext4, как сказано ъразд. 12.7.1. Теперь настройте Transmission при помощи последовательности команд: uci set transmission.@transmission[0].enabled='lf uci set transmission.@transmission[0].config_dir='/etc/transmission1 uci set transmission.@transmission[0].download_dir=f/tmp/mounts/USB- Al/downloads1 uci set transmission.@transmission[0].download_dir='/tmp/mounts/USB- Al/downloads/incompletef uci set transmission.@transmission[0].rpc_whitelist_enabled='false Сохраните настройки Transmission: uci commit transmission Включите автоматический запуск Transmission при загрузке микрокомпьютера, если это необходимо: /etc/init.d/transmission enable Запустите Transmission, чтобы начать работу с ним прямо сейчас: /etc/init.d/transmission start Теперь в адресной строке браузера введите строку вида: http: //omega-ABCD. local: 9091/ где abcd— четыре последних символа на наклейке на корпусе микрокомпьютера. Если символьная ссылка не работает, введите DP-адрес микрокомпьютера в локаль-
296 Глава 13 ной сети,— например: http://i92.i68.1.238:9091/. В окне браузера должна от- крыться онлайн-панель Transmission. По щелчку мыши на значке папки открывает- ся форма для добавления торрент-файла (рис. 13.12). Настройки торрент-клиента очень просты и не нуждаются в пояснениях. <» .4*. .чГ; vjs- Рис. 13.12. Окно веб-интерфейса приложения Transmission Новое подключение tc Transmission Название подключения: | 0mega2 Пожалуйста, укажите как Transmisston Remote GUI будет подключаться к удаленному узлу, где работает демон (служба) Transmission. X Удаленный узел: \ 192J68.1.23В Порт; • 9091 *. Q Использовать SSL [,..,] Требуется авторизация LJ Псказ-зть расширенные параметры Отмена Рис. 13.13. Окно настройки подключения в приложении Transmission Remote GUI
Примеры программ и проектов для Отеда2 297 Кроме браузера для управления загрузками можно использовать кроссплат- форменное приложение Transmission Remote GUI. Скачайте его по адресу: https:// sourceforge.net/projects/transgui/. После запуска настройте подключение к удаленному хосту Transmission, который запущен на микрокомпьютере Omega2. Для этого достаточно ввести IP-адрес и имя подключения (рис. 13.13). Вы можете ассоциировать торрент-файлы с приложени- ем Transmission Remote GUI и управлять раздачами так, как вы привыкли это делать в приложениях |iTorrent и BitTorrent. Еще раз подчеркнем, что мы призываем читателей скачивать и раздавать только легальный контент!
ПРИЛОЖЕНИЕ Содержание электронного архива Электронный архив с материалами к этой книге можно скачать с FTP-сервера изда- тельства «БХВ-Петербург» по ссылке ftp://ftp.bhv.ru/9785977538633.zip или со страницы книги на сайте wvnv.bhv.ru. Архив (табл. П.1) содержит тексты основных программ, а также чертежи печатных плат и принципиальные электрические схемы для некоторых проектов, рассмот- ренных в книге. Таблица П.1. Содержание электронного архива, сопровождающего книгу Папка\Файл BeeperTiny\ Listing.7.7\ Listing.5.1.ino Listing.5.2.ino Listing.5.3.ino Listing.5.4.ino Listing.7.1.ino Listing.7.2.ino Listing.7.4.ino Listing.7.6.ino Listing.7.8.ino Listing.9. Lino Listing.9.2.ino Listing.9.3.ino Listing.9.4.jno Listing.9.5.ino Описание Принципиальная электрическая схема и чертеж печатной платы индика- тора разряда батареи в формате DipTrace Скетч прошивки самодельного анализатора помех Стандартный пример программы мигающего светодиода Модифицированный пример программы управления светодиодом Пример отправки сообщений в последовательный порт Пример скетча для связи через консоль Linux Запрос системного времени из шилда Yun Запись данных на встроенную карту памяти Скетч измерения температуры с сохранением данных в БД MySQL Скетч для работы с таблицей Google Sheets Скетч прошивки монитора литий-полимерной батареи Пример получения точного времени от сервера NTP Скетч для мониторинга пакетов UDP и получения уведомлений Скетч для модуля дистанционного управления камерой Xiaomi Yui Подпрограмма запроса токена для камеры Xiaomi Yui 4K Пример скетча для работы с Temboo при помощи ESP8266
300 Приложение Таблица П.1 (окончание) Папка\Файл Listing. 10.1.lua Listing. 11.1. lua Listing. 11.2. lua Listing. 11.3. lua Listng.11.4.lua Listing. 11.5. lua Listing. 11.6.lua Listing. 12.1.py Listing. 13.1.py Listing. 13.2.py Listing. 13.3.py Listing. 13.4.py Listing. 13.5.py Listing. 13.6.py Описание Скрипт для мигания светодиодом с частотой 1 Гц Пример работы с OLED-дисплеем Стартовый файл init.lua Скрипт формирования HTTP-запроса и обработки ответа httpget.lua Скрипт вывода данных на дисплей update_display.lua Пример вывода битовой графики на OLED-дисплей Пример управления графическим TFT-дисплеем 320x240 Скрипт для мигания светодиодом Пример скрипта для работы с OLED-дисплеем Пример скрипта для управления сервомашинкой Скрипт для проверки модуля расширителя портов Пример скрипта для чтения из расширителя портов Тестовый скрипт для проверки матричного индикатора Тестовый скрипт для проверки сегментного индикатора
Предметный указатель 1 1-Wire 47 А Android 0 Remote Notifier for Android 175 0 Taskerl76 0 уведомления 173 Arduino 80 0 Arduino IDE 85 0 Arduino Leonardo 96 0 Arduino Mega 2560 83 0 Arduino Nano 81 0 Arduino Pro Mini 82 0 Arduino Uno 82 0 Arduino Yun 96 0 нумерация выводов 84 0 описания плат 94 0 установка библиотек 92 Arduino Create ПО 0 Arduino Cloud 116 0 Arduino Project Hub 117 0 Arduino Web Editor 112 ATTiny24 (44, 84) 149 0 библиотека Arduino 154 Autodesk Circuits 59 в BitTorrent 294 Bonjoure, сервис адресации 251 Bootloader 89 с CC2500, модуль трансивера 138 D Dragino Yun 96 E ESP8266 159 0 модули ESP-** 160 0 расширение Arduino IDE 163 0 специальные функции 166 ESPlorer IDE (среда разработки) 207 F Fritzing 75 G GERBER74 Google Spreadsheet 128 H Hercules 55 1 1 I2C45 Internet of Things 110
302 Предметный указатель Lua (язык программирования) 198 Lua for Windows 214 м Midnight Commander 265 MSQL 126 N Network Time Protocol См. Протокол сетевого времени NodeMCU 198 О конструктор прошивок 202 0 плата NodeMCU DevKit 199 Notepad++ 57 OLED: подключение 276 OLED Control: онлайн-утилита 278 Omega2 245 0 Arduino Dock R2 247 0 Breadboard Dock 250 0 Console, онлайн-панель 252 0 Expansion Dock 247 0 Mini Dock 249 0 Onion Cloud, облачный сервис 257 0 Power Dock 247 0 особенности эксплуатации 274 0 расширение памяти 266 Omega2 Plus 249 OpenWRT 96 PuTTY 53 PWM Servo (модуль расширения) 0 настройка адреса 282 0 подключение 281 0 тестовая программа 285 Python 2.7 259 Real Time Clock См. Часы реального времени SPI46 System-on-Chip (SoC) См. Однокристальная система Temboo 128 0 библиотека для ESP8266 193 Termite 56 TimeLib, библиотека 172 Transmission (торрент-клиент) 295 0 установка на Omega2 295 Transmission Remote GUI 297 и UART41 0 конвертер USB-UART 43 UNIX 0 эпоха 173 0 формат времени 119 Viber, уведомления 177 W WinSCP 54 Xiaomi Yui 179 0 модуль управления 180
Предметный указатель 303 Анализатор эфира 137 и Измерительное оборудование 48 О цифровой мультиметр 49 О цифровой осциллограф 49 Индикатор сегментный 292 О подключение 293 О тестовая программа 293 Инструменты: зачистка проводов 23 Источники питания О импульсные преобразователи 31 О линейные стабилизаторы 28 О литиевые аккумуляторы 35 О никель-кадмиевые аккумуляторы 34 О noprUSB27 О сетевые источники 28 О смещение рабочего напряжения 31 л Логические уровни: согласование 39 м Макетные платы О беспаечные 19 О печатные 22 О соединительные провода 21 Монитор батареи LiPo 147 Монтажные провода: обозначение диаметра 23 Однокристальная система 159 п Паяльное оборудование 51 Протокол сетевого времени 119 Расширитель портов 286 О подключение 287 О тестовая программа 288 Светодиодная матрица 289 О схема модуля 290 0 тестовая программа 291 Система на кристалле См. Однокристальная система Стратум 168 Часы реального времени 119 Электронный архив 299