Text
                    MDUINO
для любознательных
или паровозик из Ромашково
ПРОСТО] о сложном:
iSlank -
О) { e(H (
.ten
Scan & DJVu
Bookrngofz /
.. (client, (client с = client
Sertal.wr (с) if you've charar* -
tad of the line <rere--!s blank, the http reque
ЗНАКОМСТВО С МИРОМ МИКРОКОНТРОЛЛЕРОВ:
• базовые эксперименты с модулем
• Scratch и AVRStudio для Arduino
• web-сервер из Arduino Uno
• радиоканал для робота
НиТ
издательства


Гололобов В. Н. ARDUINO ДЛЯ ЛЮБОЗНАТЕЛЬНЫХ ПАРОВОЗИК ИЗ РОМАШКОВО + ВИРТУАЛЬНЫЙ диск е^НиТ уиздательс i вцУ Наука и Техника, Санкт-Петербург
УДК 621.314:621.311.6 Гололобов В. Н. ARDUINO для любознательных или паровозик из Ромашково + виртуальный диск. - СПб.: Наука и Техника, 2018. - 368 с., илл. ISBN 978-5-94387-879-4 Эта книга написана для тех, кто хотел бы начать работать с микроконтроллерами. Оптимальным для этого оказывается модуль Arduino. Он не требует программатора, и проект Arduino предлагает удобную среду разработки программ для модуля Arduino. Появление проекта Arduino привлекло к нему столь пристальное внимание, что было создано много разновидностей модуля, различающихся и ценой, и возможностями. Разработано много дополнительных модулей (шилдов), позволяющих превратить, например, модуль Arduino Uno в web-сервер. Написан ряд полезных программ для модуля Arduino. С модулем Arduino можно успешно работать и в Windows, и в Linux, чему производители сегодня уделяют большое внимание. Но успех приходит только с опытом. А опыт начинается с первого шага, который вам предлагается сделать. В ходе беседы автора книги и любознательного Новичка все сложности изучения микроконтроллеров вообще и проекта Arduino, в частности, остаются позади. Книга сопровождается ВИРТУАЛЬНЫМ ДИСКОМ, который содержит проекты, о которых рассказывается в книге, сведения о среде разработки, программы для модуля Arduino, datasheets к микроконтроллерам Arduino Nano, Arduino Uno и многое другое. Обновляемый виртуальный диск размещен на странице этой книги на сайте Издательства www.nit.com.ru. Книга предназначена для широкого круга любознательных читателей, увлеченных микроконтроллерами, техническим творчеством, электронными самоделками. ISBN 978-5-94387-879-4 Автор и издательство не несут ответственности за возможный ущерб, причиненный в ходе использования материалов данной книги. Контактный телефон издательства (812) 412-70-26 Официальный сайт: www.nit.com.ru © Гололобов В. Н. © Наука и Техника (оригинал-макет) ООО «Наука и Техника». Лицензия № 000350 от 23 декабря 1999 года. 198097, г. Санкт-Петербург, ул. Маршала Говорова, д. 29. Подписано в печать 25.10.2017. Формат 70*100 1/16. Бумага офсетная. Печать офсетная. Объем 23 п. л. Тираж 1300 экз. Заказ № 9939. Отпечатано с готовых файлов заказчика в АО «Первая Образцовая типография» филиал «УЛЬЯНОВСКИЙ ДОМ ПЕЧАТИ» 432980, г. Ульяновск, ул. Гончарова, 14
СОДЕРЖАНИЕ Предисловие .................................................... 7 Глава 1. С чего все начинается: Arduino для паровозика из Ромашково................................... 10 Вам письмо!............................................ 10 Установка программы Arduino в Windows............... 12 Установка программы Arduino в Fedora 14................ 16 Установка программы Arduino в openSuse 11.5............ 17 Что изменилось сегодня................................. 22 Глава 2.Установка программы Arduino в ALTLinux 5.1............. 25 Скачиваем ALTLinux 5.1................................. 25 Запускаем программу.................................... 28 Беда к программе не приходит одна...................... 52 Осталось подключить модуль к USB порту................. 57 А если модифицировать программу?....................... 59 О вкусах не спорят..................................... 41 Глава 3. Начинаем работать с программой Arduino................ 42 На старт, внимание..................................... 42 Осндвное меню и инструментальная панель................ 44 Редактрование текста программы......................... 49 Подсказки или раздел помощи............................ 55 Инструментальная панель................................ 54 Строка состояния работы с проектом..................... 55 Ветер перемен не должен поднимать пыль................. 57 Глава 4. Осваиваем язык программирования Arduino............... 60 Что такое язык программирования Arduino................ 60 С чего начать программировать?......................... 62 Язык для программирования модуля Arduino............... 65 Функции как основа современного языка программирования .. 66 Проделаем эксперимент, заменив переменную типа int.... 68 Проделаем эксперимент с изменением длительности пауз.. 69 А теперь помигаем светодиодом.......................... 72 Модуль Arduino как макет для проверки программ......... 74 Встроенные в микроконтроллер аппаратные устройства.... 75 Программы, которые помогут освоить программирование... 77 Относительно перемен с S4A............................. 80 Прежде, чем перейти к пятой главе...................... 82 Глава 5. Arduino, визуальное программирование.................. 84 Linux дистрибутивы и S4A............................... 84
О главном - о самой программе S4A...................... 88 Кодирование или программирование?...................... 92 Проверка с модулем Arduino............................. 93 Добавление второго модуля Arduino...................... 97 Глава б. Учимся использовать язык программирования Scratch.... 98 Примеры программ для S4A............................... 98 Начало работы с программой.............................102 Вернемся к схеме с кнопкой и светодиодом...............105 Отладка программы......................................107 Глава 7. Полезная программа Fritzing.......................... 109 Глава 8. Реализация задуманного............................... 112 Что нужно сделать с «паровозиком и семафором»..........112 Ведет состав, как мы знаем, паровозик, не так ли?......113 О правке или подгонке параметров.......................119 Как Arduino покажет нам импульсы.......................121 Выбираем «осциллограф».................................121 Рисуем необходимые подключения для проведения экспериментов... 123 Электрическая схема................................... 127 Еще один «осциллограф» - программа xoscillo............129 Будет ли виртуальный осциллограф работать в Linux?....134 1)1ава 9. С чего начинаются роботы?........................... 138 Продолжаем реализацию проекта..........................138 Проверка программы на макете...........................144 Отладочная программа...................................146 Arduino и роботы.......................................153 Глава 10. Еще раз про «осциллограф», если не надоело.......... 156 Расширение возможностей................................156 Практическое определение количества отсчетов...........157 Лучше один раз увидеть, чем сто раз услышать...........160 «Заграничные штучки» и Arduino.........................162 Время преобразования...................................165 Прикладные программы для компьютера....................167 Разные режимы трансляции кода программы................175 Заглянем в раздел плат программы Arduino...............177 Глава 11. Работа с модулем Arduino в других средах разработки. 178 Программы для операционной системы Windows.............178 Пример «классической» программы для модуля Arduino....182 Если нет программатора для работы с AVR Studio.........185 И еще о программах для AVR-контроллера.................188 Не будем обижать и Linux...............................193
Дистрибутив Fedora 14 как полигон для наших экспериментов.......................194 Уточнение общих настроек для конкретного дистрибутива Linux........................210 Компилятор AVR-GCC........................................212 Обновление версий программ как компонент любопытства .... 214 Не без ложки дегтя........................................219 Глава 12. FLProg — графический язык программирования Arduino... 222 Где искать программу FLProg...............................222 Программа «Привет, мир!»..................................223 Еще раз о кнопке и светодиоде.............................230 Датчик и светодиод........................................233 Два датчика и светодиод.................................. 240 Когда в дверь стучится проблема...........................251 Глава 13. Arduino и плата расширения Ethernet.................... 251 Немного теории о сетевой работе...........................253 Пополнение в Arduino-домике...............................255 Опыт 1. Arduino и Ethernet................................257 Опыт 2. Ethernet-шилд и управление........................263 Опыт 3. Ethernet-шилд, управление и считывание данных.....268 1лава 14. И неприятности бывают полезны: приключения с SD-картой. 274 Карта microSD и Arduino...................................274 Немного об интерфейсе SPI.................................278 Поиск неисправности.......................................280 Радиомодуль...............................................285 Подготовка к работе с nRF24L01............................290 Глава 15. В завершении немного схемотехники...................... 297 Цифровой выход............................................297 Цифровой ввод.............................................298 Сильноточный выход........................................299 Выход pwm.................................................301 Ввод с потенциометра......................................301 Опыте переменным резистором...............................302 Серво вывод...............................................303 О руководстве к программе code::blocks....................305 Первые настройки проекта..................................305 Приложения ...................................................... 305 А. Рассказ о плагине wxSmith и приложении wxWidgets к code::blocks..........................................305 Б. Содержание виртуального диска..........................365 Ссылки на Интернет-ресурсы:...................................... Збб
ПРЕДИСЛОВИЕ Когда-то я написал рассказ «С чего начинаются роботы» о проекте Arduino для школьников. Рассказ был навеян одним письмом, время от времени я их получаю. С тех пор прошло много времени. Появились хорошие книги про Arduino, а то, о чем я написал, отчасти устарело. Ведь это был рассказ о программах, помогающих создать что-то, что превратило бы модуль Arduino в полезное устройство. Обычно я не возвращаюсь к уже написанным историям, но не в этот раз. В этот раз мне хотелось бы посмотреть, какие изменения произошли с программами, о которых я тогда писал. ЧТО ЕСТЬ ЧТО. Arduino - это открытый проект, основа которого аппаратный модуль и программа, в которой можно написать код для контроллера на разновидности языка Си. Модуль можно подключить к порту USB и запрограммировать без специального программатора. Это одна из наиболее привлекательных находок авторов проекта.
Другой находкой можно считать готовые библиотеки программы Arduino, что очень упрощает написание собственного кода. Помимо компонентов, обеспечивающих контакт с компьютером, модуль имеет множество выводов, которые легко соединяются с разными исполняющими устройствами, позволяя создавать и роботов, и устройства автоматики, и приборы. С момента появления проекта Arduino вокруг него собралось множество почитателей — достаточно ввести в поисковую строку слово arduino, как вы обнаружите множество сайтов, посвященных этой теме, и сотни проектов, основанных на Arduino. Хотя книга рассчитана на школьников, она может быть интересна радиолюбителям. А если не книга, то сам проект может быть интересен преподавателям, и не только работающим в школе, но и в других учебных заведениях, где изучают программирование и работу с микроконтроллерами. Так что же эта книга? Она в основном описывает ряд программ, которые предназначены для работы с модулем Arduino, как сама программа Arduino, как S4A... Все эти программы почти обычным образом устанавливаются в Windows. В Linux они работают, но в этой операционной системе есть особенности, которые описаны в книге. Помимо этого в книге рассказано о средах разработки AVR-контроллеров общего назначения, которые поддерживают работу с модулем Arduino — AVR Studio, WinAVR. ПРИМЕЧАНИЕ. Суть любого робота - это аппаратные средства с процессорной базой и программа (или набор программ). Поэтому программирование становится неотъемлемым элементом процесса создания даже самого простого робота. Научившись программировать модуль Arduino, а программа приходит с богатейшим набором примеров, касаю
щихся всех областей применения модуля, вы будете готовы создавать интересные и полезные электронные устройства, к которым относятся и роботы. Начните с простых проектов, а остальное в ваших руках. Возможно, школьники, познакомившись с увлекательнейшим проектом Arduino, выберут роботостроение своей будущей профессией. Но даже если нет, то, уверен, через много лет, вспоминая свои эксперименты в этой области, они будут рады, что не прошли мимо, не пожалели времени на освоение основ — им будет что вспомнить. Радиолюбители давно и успешно осваивают работу с микроконтроллерами. Они с упоением спорят, какой язык программирования лучше. Возможно, проект Arduino позволит им сделать окончательный выбор? Тем более что модуль Arduino может работать как программатор для программирования других микроконтроллеров. Словом, все интересное и полезное, что есть в проекте Arduino, можно узнать, только работая с ним в компании таких же увлеченных людей.
ГЛАВА 1 S С ЧЕГО ВСЕ НАЧИНАЕТСЯ: ® ARDUINO ДЛЯ ПАРОВОЗИКА ИЗ Р0МАШК0В0 Временами я получаю письма с просьбой помочь в чем-то разобраться. Чаще всего мне не удается ответить одним письмом с простым и ясным ответом. И тогда... Вам письмо! Новичок: У младшего брата есть железная дорога. Я хотел сделать семафор, и чтобы он открывался, когда подходит поезд. Я хочу купить микросхему, но не знаю, там нужно какой-то файл для нее, где его взять. Я спрашивал, но мне говорят, что нужно читать какое-то руководство, а мне не интересно. 1де мне взять этот файл? В те дни мне приходилось часто пользоваться электричкой. Размышляя об ответе и поглядывая в окно на называние станций, мимо которых я проезжал, я подумал, что будь письмо не электронным, а обычным, я обязательно пометил бы его так: «Паровозик из Ромашково». Если и у читателей возникают подобные вопросы, то постараюсь ответить на них. Я не думаю, что вы найдете готовый
файл, тем более что их потребуется два. Перед тем, как сделать устройство, вам понадобится: ♦ написать программу; ♦ записать и оттранслировать код; ♦ «залить» код в микросхему. Удобно использовать модуль Arduino. Запустите программу Arduino... Новичок: Я поискал на компьютере в списке программ Arduino, но не нашел. Где мне найти программу? Ах, да. Это у меня программа установлена, а у вас, возможно, нет. Тогда так. Можно в любом поисковике, например, Yandex, Bing, Google, в любом, ввести в окно поиска слова arduino download, и вы наверняка найдете ссылки на сайт проекта. На рис. 1.1 показан вид главной страницы проекта Arduino. На странице загрузки осталось выбрать нужную версию для вашей Операционной системы. ARDUINO http //arduino сс/ I .. ............JL Arduino Is an open-source electronics prototyping platform based on flexible, easy-to-use hardware and software, it's Intended for artists, designers, hobbyists, and anyone Interested in creating Interactive objects or environments Arduino can sense the environment by receiving input from a variety of sensors and cm affect its surroundings by controlling lights, motors, and other actuators. The microcontroller on the board is programmed using the Arduino programming language (based onWinBg) and the Arduino development environment (based on Processing). Arduino projects can be stand-alone or they can eommnmcate with software on running on a computer (eg. Flash, Processing, MaxMSP).
I Установка программы Arduino в Windows С Windows все просто — щелкнул по ссылке Windows, дождался конца загрузки, распаковал файл, а он в самом удобном варианте упаковки, который может распаковываться любым свободным архиватором, распаковал и все. Новичок: Я распаковал архив, можно оставить его здесь? Можно, но программу Arduino вместе с папкой сразу перенести в корневую директорию диска С. А для удобства, открыв папку с программой, выделить файл arduino.exe, щелкнуть правой клавишей, и из выпадающего меню выбрать пункт Создать ярлык. После создания ярлыка его мышкой можно перетащить на рабочий стол и запускать программу обычным образом — двойной щелчок мышки по ярлыку. Фу, вот и установили программу. Запускаем ее... Новичок: И больше ничего мне не нужно? Ах, да. Я-то уже купил модуль Arduino, а вы, возможно, нет. Как я это сделал? Я искал самый дешевый модуль. Модулей Arduino, поскольку проект открытый, много, и под разными именами, скажем, arduino, freeduino, craftduino и т. д., и цены у них разные. Самый дешевый модуль в Москве я нашел в Интернет-магазине CarMonitor.ru. Не слишком дорогие модули (и интересный сайт) в Интернет-магазине RoboCraft.ru. Вид модулей Arduino (рис. 1.2). Arduino Nano Arduino Uno Arduino Mega 2560 Рис. 1.2. Наиболее популярные сегодня разновидности модуля Arduino
Модули отличаются своим видом друг от друга, удобством использования, но все позволяют: ♦ подключить их к компьютеру; ♦ запустив программу arduino.exe, написать код; ♦ «прошить» полученную программу в модуль и проверить работу программы в живом виде. Почти все программы, о которых пойдет речь далее, будут работать даже с самым простым модулем Arduino Nano. ПРИМЕЧАНИЕ. Модули имеют возможность подключать к ним платы расширения: либо готовые, купленные в магазине, либо изготовленные самостоятельно. Особенно удобен в этом отношении - это только мое мнение - модуль Arduino Uno. Но в готовом устройстве небольшой модуль Arduino Nano может оказаться предпочтительнее. Кстати, проект открытый, то есть вы не только можете бесплатно скачать программу и использовать ее (и, к слову, переделать по своему вкусу, если вы умеете это делать), вы можете самостоятельно изготовить базовый модуль — есть его схема, есть прошивка, есть все для самостоятельного изготовления. ЭТО ИНТЕРЕСНО! Кроме базовых модулей, как показано выше, многие Интернет-магазины предлагают множество дополнений: макетные платы, материал для изготовления механических частей, моторы и сервоприводы, и разного рода датчики - и фото, и тензо, и пьезо, и т. п. Это целый мир устройств, из которых можно создавать и роботов, и устройства, автоматики, забавные и полезные игрушки, и «взрослые» полезные устройства.
Рис. 1.3. Подключение модуля Arduino в Windows Все. Все я, кажется, сказал, можно начинать. Или не все? Да, еще подключение. О том, как подключить модуль Arduino в операционной системе Windows, можно прочитать, например, на сайте RoboCraft.ru в статье о подготовке к работе с Arduino. На рис. 1.3 показана страница сайта с рассказом об этом. Моя операционная система Windows сама находит нужный ей драйвер и устанавливает драйвер для преобразователя USB в COM-порт, и добавляет С0М5 в список устройств системы. Новичок: Почему С0М5, если включаем модуль в порт USB? Модуль Arduino имеет микросхему преобразователя, интерфейс которой операционной системой воспринимается как виртуальный СОМ-порт.
ПРИМЕЧАНИЕ. Разные модули могут создавать разные виртуальные COM-порты. Более того, включая модуль в разные. USB гнезда, вы обнаружите, что виртуальные COM-порты разные. Так на стационарном компьютере в одном гнезде Arduino Uno создает COM4, в другом гнезде С0М8. Программа Arduino, если ее запустить после включения модуля, сама определяет появляющийся в систёме виртуальный СОМ-порт. В программе Arduino я указываю последовательный порт СОМ5 (Сервис -* Последовательный порт) и модуль Nano w/ ATMega 168 (Сервис -* Плата), поскольку мой модуль CarDuino именно таков. Теперь можно написать (конечно, я ее «срисую») какую-нибудь программу и попробовать ее отправить в модуль Arduino. Мне понравилось, как в книге «Arduino programming notebook» самую простую программу назвали «Hello World» мира микроконтроллеров (рис. 1.4). Теперь, наверное, все. Или нет? Рис. 1.4. Первая программа для модуля Arduino
ЭТО ИНТЕРЕСНО! Работа с микроконтроллерами требует работы за компьютером. Но многие сегодня используют не только операционную систему Windows, но и разные дистрибутивы Linux. С модулем Arduino можно прекрасно работать и в Linux. I Установка программы Arduino в Fedora 14 В дистрибутиве Fedora (из тех дистрибутивов, что есть на моем компьютере, среди которых Fedora 14) установка программы Arduino самая простая. Многие, пользуясь Linux, предпочитают работать в терминале. Я не из их числа, и без жестокой необходимости этого не делаю. Так, для установки программ я использую приложение под названием Yumex. Его можно найти в разделе «Приложения- Рис. 1.5. Поиск и установка программы Arduino в дистрибутиве Fedora 14
Система-Дополнение к Yum». Запустив приложение, дождавшись, когда оно закончит поиск всего ему нужного, следует выделить доступные программы (Available) и в окне поиска ввести Arduino. Теперь достаточно нажать клавишу Enter на клавиатуре, чтобы нашлась программа. Отметив ее (все три блока с именем arduino), нажимаем кнопку Применить, и программа устанавливается на компьютер, как, впрочем, и любые другие программы, а их в Linux великое множество. На рис. 1,5 показан менеджер программ. г Scan & DjVu^ L\ Bookrngolz . Установка прогр В 01 / по Г.3 Несколько сложнее устанавливается программа в openSuse 11.3. В операционной системе openSUSE есть пользовательский интерфейс для установки программ. Его легко найти, если Рис. 1.6. Программа настройки системы YaST в openSUSE
-У Запустить с правами доступе root — KDEsu г +. х, J Для выполнения данного действия необходимы привилегии пользователя «root*. Введите его пароль г* f или нажмите кнопку «Игнорировать» для продолжения работы с текущими правами Рис. 1.7. Ввод пароля root запустить управление системой от имени администратора. На рис. 1.6 показано меню настройки системы. Перед тем, как доступ будет предоставлен, потребуется пароль администратора компьютера (рис. 1.7). И, если пароль правильный, то в открывающемся окне можно найти, например, средство поиска нужных программ (пакетов, рис. 1.8). Рис. 1.8. Меню центра управления системой с выделенным разделом поиска
Рис. 1.9. Раздел поиска с окном поиска программ в составе openSuse Имя программы, если вы его знаете, вводится в окно поиска, как показано на рис. 1.9. К сожалению, если запустить поиск, то ничего не будет найдено. Но это не значит, что программы arduino для openSUSE нет. Обратимся к сайту по адресу [1], где можно найти не только нужную программу, но и подробную инструкцию по установке программы (рис. 1.10). Я перевел первый шаг установки. Что он означает? Рис. 1.10. Инструкция по установке программы на сайте Arudino
В любом дистрибутиве Linux есть терминал. Иногда только командами в терминале можно (но не часто) выполнить что-то нужное. Как в данном случае. Если в разделе «Избранное» основного меню у вас нет терминала, то его можно найти на закладке «Приложения» основного меню в разделе «Система». Достаточно щелкнуть мышкой по программе терминала, чтобы увидеть окно терминала. Теперь можно в открытом web-браузере скопировать полностью нужную строку команды, выделить, прочеркнув мышкой, и нажать правую клавишу мышки для получения выпадающего меню, из которого выбрать пункт копировать. Скопировав строку, ее можно вставить в окно терминала (перейти в окно терминала, нажать правую клавишу и выбрать команду «вставить», рис. 1.11). После вставки команды можно нажать клавишу Enter. Останется только ответить на ряд вопросов, чтобы программа была установлена. Конечно, следует повторить все команды, записанные в инструкции. Л vtaeimif: bach Файл Правка 0ид Журнал Закладки Настройка CiipaaKa vlcdinii r®l1nux-8hjk zypper ar http //doanload opensusr orj/reposi tories/hnme /кмк/ardulno/npen5U5E_l л 1 3 ardulnof viadimir bash Puc. 1.11. Ввод первой команды инструкции в окно терминала
ПРИМЕЧАНИЕ. Г Все строки инструкции следует копировать пол- ' ностью. \У После установки программы, как это и написано в конце инструкции, следует пользователя, то есть, вас, включить в две группы: lock и dialout. В этом опять поможет Yast (рис. 1.12). При входе в этот раздел открывается окно, где есть все пользователи компьютера (рис. 1.13). Рис. 1.12. Вход в раздел управления группами и пользователями Нажав кнопку Редактировать, мы попадаем в новое окно, где на вкладке «Подробности», есть возможность установить Рис. 1.13. Окно закладки «Пользователи» с перечнем всех пользователей компьютера
Рис. 1.14. Закладка «Подробности» для добавления пользователя в группы галочки рядом с нужными группами. Эти изменения можно видеть на рис. 1.14. Теперь кнопка ОК выводит нас (постепенно) из программы административного управления системой. Останется только перезагрузить компьютер и, возможно, добавить программу Arduino в основное меню. Далее предстоит установить программу на последнем из обитающих на моем компьютере дистрибутивов ALTLinux 5.1. Он, как и остальные, имеет удобную программу для установки других программ, но... Но об этом в следующей главе. |Что изменилось сегодня Часть из того, что было написано выше в первой главе, осталось без существенных перемен, но для сравнения я хочу
' ft| Й «’Susie -•* fHp* © Arduinc miftwe М -U X 'х 5 <-• ~> О (й 6 аяЫпо.г^п/Маг^П*в»е Ш ☆ | Д П $Ч99«*ес1»»« С WHrocn* to Interne Вде Т$Г Диос -ft Карте тУ Колл^ил -ft Янд«« -ft Лемтв •& Мфои -& Новосп. •£• Словари & Access the Online IDE Download the Arduino IDE Puc. 1.15. Изменения страницы загрузок Arduino показать, что вы увидите, если введете в поисковике arduino download (рис. 1.15). Конечно, эти изменения не столь разительны, но в моей операционной системе Windows 10 программа Arduino устанавливается так же, как и любые другие программы в директорию Program Files, и отображается в основном меню (рис. 1.16). Изменились цены на модули Arduino, так Arduino Nano можно купить за 200...300 рублей, но лучше купить на Aliexpress.com модуль Arduino Uno. Можно найти набор с этим модулем, который поможет провести ряд интересных экспериментов, и этот набор обойдется недорого. Конечно, если у вас с финансами полная свобода, вы можете купить более дорогой набор, включающий много датчиков, которые применяют с микроконтроллерами.
Рис. 1.16. Программа Arduino в основном меню Windows 10 ПРИМЕЧАНИЕ. За последние годы интерес к дистрибутивам Linux у нашего государство поугас, поугас интерес и у радиолюбителей. На моем компьютере установлен дистрибутив ROSA, который мне понравился, но установлен он в Virtual Box. Мне казалось, что по прошествии стольких лет проблем с Arduino, сродни тем, что описаны выше, не будет. И впрямь, загрузить программу и установить программу у меня получилось легко — достаточно было воспользоваться разделом настроек «Управление программами». После установки появилось и предложение добавить пользователя в нужные группы. Но после запуска программы я так и не смог оживить раздел выбора последовательного порта, который есть в основном меню программы Arduino. Я не исключаю, что проблема в том, что это виртуальная установка Linux. Для проверки следовало установить дистрибутив на компьютер, но этого желания у меня нет, поэтому следующую главу я оставлю (на всякий случай).
ГЛАВА 2 УСТАНОВКА ПРОГРАММЫ ARDUINO BALTLINUX5.1 Многие почитатели Windows предпочитают использовать Windows ХР и семерку, считая эти операционные системы самыми удачными. Выбор у почитателей Linux больше -разные дистрибутивы и операционные системы разных лет выпуска. У каждого есть свои предпочтения, но и свои трудности. Скачиваем ALTLinux 5.1 К сожалению, в ALTLinux 5.1 нет готового пакета, который можно скачать, как в дистрибутиве Fedora. И на сайте проекта Arduino нет описания, как установить программу в дистрибутиве ALTLinux. Новичок: По советам на форуме ALTLinuxможно скачать и установить программу Kontrollerlab, но будет ли она работать с модулем Arduino? Это вопрос. Тем не менее, можно, используя менеджер установки пакетов, загрузить необходимые файлы (если пакет
Рис. 2.1. Программа установки программ в ALTLinux java установлен, как рекомендуют на сайте Arduino); avr-gcc, avr-gcc++ (Система-Приложения-Менеджер пакетов). Используя кнопку Искать, в окне поиска ввести avr-gcc, найденные приложения отметить для установки, щелкнуть по приложению правой клавишей мышки, выбрать из выпадающего меню раздел «Отметить для установки», и, отметив все приложения, нажать кнопку Применить (рис 2.1). На сайте проекта Arduino в разделе загрузок, после перехода в этот раздел, можно скачать пакет для Linux, как показано на рис. 2.2. Для распаковки пакета используется Менеджер пакетов (в разделе «Система» основного меню). Можно перетащить скачанный пакет Arduino из папки «Загрузки» на рабочий стол, открыть его в Менеджере пакетов (если щелкнуть по загруженному файлу правой клавишей мышки, то можно использовать раздел «Открыть с помощью Менеджера архивов», рис. 2.3). Затем, используя кнопку Распаковать, следует распаковать полученный пакет. Имя распакованного пакета (arduino-0022 в данном случае) лучше изменить на arduino. Следующий шаг — перенести этот пакет в директорию /usr/share. Но, чтобы это
вид g$ypnar Закладки £ГР®т*а , ♦ ♦ * о о Д [^' •ittc .Varduino.cc/an^ain/Software * |х * i 11£ Most Molted* Л Getting Started g^unest Headlines* jgFiowtode (Ирадкопортал Найти •!• О £> ЛНаписать * vqololobov • -j Почта • i* Ф Arduino • Software By downloading thi loftwire from thu page, you agree to the specified terms THEA IMPLIED WARRAN) О WHATSOEVER WrH RESPECT TO ITS FUNCTIONALITY OFERABltH V, OR USE. thClUOING. WITH0UT:W.IW’Q4 ANY IMPLIED WARRANTIES Of MERCHANTABILITY; F.TftESS ^AFAKTtCOAR > OPPOSE. OR ibFR.LJCEMEMT W I EXPRESSLY DISCLAIM A№ IWUTT WHATSOEVER FOR ANY DIRECT, INDIRECT I CONSEQUENT (Au INuIDUTAL OR SPECIAL DAMAGES. INCLUDING. WITHOUT LIMITATION. ! LOST REVENUES CSrfWQBlX tO55BFE5UlTt . I ROM BUSINGS INTERNET жМ LOSS Of ОАТД PEGAADi£55 LATHE FORM OF At HON OR LEGAL THEORY UNDEflLWHCH THE LIABILITY MAY 8E ASSERTED, CHgN fF AJtLiSED Of TK POSSWUTV OR UKELIHGC3-Of SUCH DAMAGES Download Arduino 0022 (release notes), hosted by Gccgls Cods ♦ Windows ♦ Mac D S X p4 Lima (3211^1 ♦ source Next steps Getting Started Reference Enwronmint Exsmples Foundations FAS Downloads will slso bs svailibls from arduino cc Puc. 2.2. Пакет Arduino для Linux еайл Правка Вид Справка __________ Gi ~W"~ ~V Создать Открыть Распаковать J Добавить файлы Добавить лапку ф ф ф £ 1 Расположение: |Й Г [Имя Размер [тип Тдата изменения arduino-0022 7,5 МБ Папка Рис. 2.3. Распаковка пакета в менеджере архивов
Рис. 2.4. Менеджер файлов в ALTLinux сделать, нужно иметь права администратора системы. И проще всего воспользоваться теми возможностями, которые есть в дистрибутиве. Если в основном меню зайти в раздел «Система» на закладке «Приложения», то можно обнаружить подраздел «Дополнительные приложения». В этом подразделе есть ряд полезных программ и, в частности, «Менеджер файлов (в режиме администратора)». Запустив менеджер файлов, можно легко перенести в нужное место папку с программой (рис. 2.4). I Запускаем программу Хорошо бы программу запустить... Но, конечно, вы не обнаружите программу в основном меню. В Windows для этой цели используется командная строка, в Linux — терминал. В окно
Рис. 2.5. Первый запуск программы в терминале терминала вводим команду: /usr/share/arduino/arduino, и получаем то, что показано на рис. 2.5. Новичок: Могут ли на этом этапе появляться ошибки? Чем они вызваны? ЭТО ВАЖНО! В использовании терминала есть и ряд преимуществ - на рис. 2.5 видно, что запуск программы сопровождается рядом ошибок, отображаемых при запуске в окне терминала. Ошибки могут быть вызваны тем, что программа требует доступа к системным ресурсам, а вам, как рядовому пользователю, доступ к этим ресурсам запрещен. Если вы помните, в дистрибутиве openSUSE нам понадобилось добавить пользователя в несколько групп. Проверим, вызваны ли ошибки тем, что мы не сделали этого в ALTLinux?
Полностью повторить сделанные в openSuse операции не получится из-за отсутствия программы добавления пользователя в разные группы. Но это не значит, что этого нельзя сделать — Linux, если знать, как это сделать, позволяет сделать все, что захочется. Воспользуемся вновь терминалом для добавления пользователя (следуя рекомендациям для openSUSE и тому, что пишут на форуме) в группы: uucp, lock и dialout. Эти операции может выполнить только администратор, поэтому нужную команду мы начинаем с дополнительной команды sudo, что означает, выполнить команду от имени администратора (рис. 2.6). файл Правка Вид Журнал Звклйдки Настройцд Справку [vledimirgvlBdi -]$ sudo gpaaawd -a vladlmir uucp [udo] рваaward for vladimir: Adding uaer Vladimir to group uucp [vladiairgvladi ~]S audo gpaaawd -a vladimir lock unknown group: lock [vladimirgvladi -]$ audo gpaaawd -a vladimir dailout unknown group: dailout [vladimirgvladi -]$ | Puc. 2.6. Добавление пользователя в нужные группы Скоро сказка сказывается, да не скоро дело делается. Ладно, при вводе команды для включения пользователя в группу dialout я сделал опечатку. Исправив ее, я получил доступ в группу. Но! Группы lock в ALTLinux нет вообще! Новичок: Как попасть в группу, если ее нет, а программа arduino продолжает жаловаться «на недовес» (рис. 2.7)? Я не знаю, прав ли (или неправ), но я поступаю следующим образом: я добавляю себя в группу root (администраторов), используя ту же команду, что и раньше. Затем, используя файловый менеджер с правами администратора, нахожу директорию /var, где есть поддиректория lock (рис. 2.8). Щелкнув правой клавишей мышки по этой папке, я открываю из выпадающего меню пункт Свойства, открываю закладку
Рис. 2.7. Ошибки при запуске программы ,£айл Правка Вид Переход Закладки Одас Настройка Окна Справка Рис. 2.8. Расположение папки lock в файловой системе «Права» и меняю для группы root права, как это показано на рис. 2.9.
sfr « Ф 5 " Свсйгтва lack—Kcnqusror Рис. 2.9. Изменение прав группы администраторов |Беда к программе не приходит одна Теперь программа не жалуется, а прав ли я, покажет время. Но беда не приходит одна. Вот ее напарница: запускаем программу, заходим в основное меню: File —> Examples —> l.Basics-Blink и (рис. 2.10)... ...и получаем готовую программу, первая же попытка откомпилировать которую (основное меню «Sketch -* Verify/Compile» или кнопка на инструментальной панели с иконкой «Р1ау») приводит только к появлению длинного списка ошибок (рис. 2.11). ПРИМЕЧАНИЕ. Об истоках проблемы я был, думаю, предупрежден - при скачивании программы на сайте Arduino я видел рекомендации, касающиеся компилятора, а именно: версия avr-gcc должна быть не ниже 432 (со всеми надлежащими утилитами)^
Рис. 2.10. Список примеров в пакете Arduino Blink.jArdums 0022 «х Z File Edit Sketch Tools Help
В ALTLinux 5.1 версия 4.2.2. Если честно, то на этом месте следует остановиться, чтобы решить проблему, установив надлежащую версию. Однако мне хочется сейчас проверить подключение модуля, работает оно или нет? Вчитываясь в первую ошибку, я понимаю, что компилятор не находит файл заголовка stdlib.h, и ошибка возникает при обращении к файлу WProgram.h из состава пакета arduino-0022. Этому горю можно помочь. В директории /usr/include есть папка с именем avr (рис. 2.12). Откроем ее, выделим все и добавим туда, где обездоленный файл WProgram.h ожидает нашей помощи (рис. 2.13). При следующей попытке скомпилировать программу из примеров, приведенных в Arduino, появляется новый набор ошибок. Он связан с тем, что компилятор не понимает синтаксис одного из файлов (рис. 2.14). Откроем этот файл Топе.срр (на рис. 2.14 он обведен кружком). Как все файлы на языке Си, этот открывается в обычном Рис. 2.12. Местоположение папки avr в файловой системе
Рис. 2.13. Расположение файла в пакете Arduino Рис. 2.14. Сообщение об ошибке при компиляции файла
редакторе текста. Найдем строку 232, как указано в сообщении. В редакторе можно воспользоваться поиском, искать следует сочетание ОЬ (жалуется компилятор, похоже, на это сочетание, рис. 2.15). niumeAriadimir^duiho-0022^arthwife/ifik»infl/cores/afauin«none срр KEflit , Файл Правка Перейти Сервис Настройка ^правка . _—« ь; ----------------------------*——.------------ bitWrite(TC€R5B, WGM52, 1); bitWrite(TC€R5B, CS50, 1); tiner5_pin_port « portOutputRegister(digitalPinToPort( jpin)); tiner5_pin_nask * digitalPinToBitMask(pin); break; fendif return tiner; // frequency (in hertz) and duration (in irilliseconds). void tone(uinte_t _pin, unsigned int frequency, unsigned long duration) { uintfitprescalarbits «• ЭЭ1; _____ .....................................................................’:/BCT .'строка: 232 Столбец: 29 Рис. 2.15. Место «ошибки», вызывающее сбой при компиляции /hBmsV’adimirrafdwno-OOZZ/l’mrdware/arduini^cores/ardumon’one срр - KEdit Ш «И <£>айл Правка Перейти Сервис Наст ройка ^правка
Константа в строке 232 двоичная. Но написание, видимо, не нравится компилятору. Попробуем заменить это написание, то есть, двоичное ObOOl на шестнадцатеричное 0x01. Аналогично, используя поиск, заменим все двоичные числа, начинающиеся с 0Ь, на шестнадцатеричные числа, как показано на рис. 2.16. Сохранив файл, попытаемся вновь скомпилировать программу примера Blink (рис. 2.17). Рис. 2.17. Сообщение об удачном завершении компиляции Осталось подключить модуль || к USB порту || Как видно из рис. 2.17, компиляция прошла успешно. Осталось подключить модуль к USB порту. Кстати, до подключения, если зайти в основном меню в Tools -> Serial Port, то мы увидим только существующий COM-порт (в Linux это ttySO). А после подключения появляется ttyUSBO (рис. 2.18).
Н|4 Edit Sketch Help Board Blink Turns on an LED or This example code , Bum Bootloader -WQiFormet Archive Sketch Fix Encoding & Reload Serial Monitor Ctrl+Shift+M Blink ytoino 002? CtrkT ;dev-‘^O void setup() { // Initialize the digital pin as an output. // Pin 13 has an LED connected on most Arduino boards: p1nMode(13, OUTPUT); -Z-l ? <, // set the LED on // wait for a second // set the LED off // wait for a second void loopO { digitalWrite(13, HIGH): delay(lOOO); digitalWrite(13, LOW); delayClOOO); Puc. 2.18. Порт в Linux, к которому подключается модуль Arduino И когда мы нажимаем на кнопку инструментального меню, выполняющую команду загрузки программы, то в нижней части окна программы получаем сообщение, что загрузка выполнена (Done uploading). Что ж, мы и в дистрибутиве ALTLinux проверили подключение модуля. В других операционных системах мы это тоже сделали. Осталось понять, а что мы сделали? Если мы откомпилировали и загрузили программу в модуль Arduino, то, согласно программе, если мы подключим к выводу 13 светодиод с последовательно включенным резистором, он будет мигать. ПРИМЕЧАНИЕ. Не знаю все ли, но, например, CraftDuino или мой CarDuino для проведения эксперимента уже имеют такой резистор и светодиод. И после загрузки программы светодиод начинает мигать.
А если модифицировать программу? Чтобы убедиться, мигать светодиод может и без нашего вмешательства (рис. 2.19), можно изменить программу. int ledPin = 13; pinMode (ledPin, OUTPUT); void loop() { digitalwrite (ledPin, LOW); delay (1000); digitalWrite (ledPin, LOW); delay (1000); ’Novell Puc. 2.19. Работа программы Blink Теперь светодиод, после компиляции и загрузки, не мигает. Как и заказано. А, значит, мы действительно скомпилировали и загрузили программу. ПРИМЕЧАНИЕ. На сайте, о котором уже упоминалось, RoboCraft.ru, в статье о первой программе предлагается еще более интересная проверка - отклик модуля по СОМ-портуна состояние светодиода. int ledPin = 13; void setup() { pinMode(ledPin, OUTPUT); Serial.begin(9600); // инициализация работы с COM-портом J void loop() { digitalWrite(ledPin, HIGH);
Serial.print("H" ) ; // светодиод горит — пишем Н delay(1000) ; digitalWrite(ledPin, LOW); Serial.printIn("L") ; // светодиод погасили — пишем L delay(1000) ; J Загрузив программу в модуль, открыв монитор (Tools —► Serial Monitor), можно увидеть работу программы. Помимо мигания светодиода в окне монитора отображается состояние светодиода, включен ли он — приходит символ Н, или выключен — символ L, и это показано на рис. 2.20. И, главное, если отключить модуль при работающей программе, символы перестают приходить. Значит, символы отправляет модуль! Рис. 2.20. Работа модифицированной программы
О вкусах не спорят Много лет назад мне довелось столкнуться с операционной системой QNX, что завершилось интересом к другим операционным системам. Наиболее развитой из них на тот момент, с моей точки зрения пользователя, оказалась операционная система Linux. Она была представлена разными дистрибутивами. В то время эти дистрибутивы хорошо ладили друг с другом и с Windows. С началом гонений на пиратские программы бесплатная операционная система Linux казалась отличной альтернативой для тех, кто не мог купить Windows. Более того, в состав дистрибутивов входило почти все, что нужно рядовому пользователю. Но пользователи боялись трудностей в освоении новой операционной системы. Это, наверное, и подстегнуло меня к тому, чтобы больше рассказывать о Linux. Ряд рассказов я полностью написал в Linux. Мое мнение о достаточности Linux для рядового пользователя не изменилось, но с тех пор и Linux не стали так хорошо дружить, и однажды я столкнулся с проблемой установки обновлений для Windows. Поэтому сегодня дистрибутив Linux ROSA у меня на компьютере в виртуальном виде. Я не в полной мере согласен с гонениями на использование пиратского программного обеспечения, в котором, как мне кажется, заинтересованы и производители программ — где они еще найдут столько добровольных тестеров для проверки программ? Но без особой нужды я постараюсь не упоминать далее платные программы.
ГЛАВА 5 НАЧИНАЕМ РАБОТАТЬ С ПРОГРАММОЙ ARDUINO Я не встречал людей, которые знакомство с программой начинают с подробнейшего изучения руководства к ней. У меня, скажу честно, не хватает на это терпения. Видимо, по этой причине многие программы сегодня снабжают руководством, которое озаглавлено «Быстрый старт». На старт, внимание... Оставим на некоторое время несуразности, связанные с установкой программы и первым с ней знакомством. Если мы хотим собирать роботов, учить их двигаться, начать следует с того, чтобы самим научиться неторопливо, шаг за шагом, продвигаться вперед. Разберем, что предоставляет в наше распоряжение программа Arduino.
ПРИМЕЧАНИЕ. Основы языкоАгдшпо и ряд типовых подключений периферии можно найти, например, в переводе блокнота программиста Arduino (добавив в поисковую систему название). Большую часть окна программы занимает, в общем-то, поле обычного текстового редактора. Хотя не совсем обычного. Это окно специализированного текстового редактора (рис. 3.1). void setup() { pinMode (ledPin, OUTPUT); } void loop() digitalWnte (ledPin, HIGH); delay (1000); * digitalWnte (ledPin, LOW); delay (1000); Рис. 3.1. Окно редактора текста в программе Arduino Новичок: Почему редактор специализированный? Специализация редактора выражается и в том, что разным цветом выделяются служебные слова, и в том, что при написании программы автоматически выполняются отступы, формирующие более удобный текст для чтения. При компиляции, если возникает ошибка, строка, где компилятор «споткнулся», выделяется.
ЭТО ВАЖНО! Текущий текст программы имеет закладку, на которой отображено имя файла. При создании нового файла он автоматически получает имя с текущей датой. Если файлов в проекте несколько, то закладок тоже будет несколько. I Основное меню и инструментальная панель Над окном редактора располагаются основное меню и инструментальная панель. Основное меню, как и редактор, мало чем отличается от меню любой программы (рис. 3.2). i£>i sketch feblla | Arduino 0021 [ pile Edrt Sketch Tools Help __ __ Рис. 3.2. Основное меню программы File предполагает работу с файлами, Edit — команды редактирования. Но отличия, конечно, есть. Так, пункт Sketch — специализированный раздел работы с проектами, a Tools касается разных приложений к аппаратным средствам. Что такое Help, думаю, не нуждается в объяснении. ПРИМЕЧАНИЕ. В настоящее время программа Arduino имеет руссифицированный интерфейс. Но знать названия разделов на английском языке полезно. Рассмотрим все разделы основного меню последовательно, раскрывая подменю, как показано на рис. 3.3. Пункт New выпадающего меню из File создает новое окно с чистым листом в редакторе. Пункт Open... открывает диалоговое окно проводника, где можно найти нужный файл про-
Рис. 3.3. Содержание раздела «File» основного меню граммы. Многие программы используют системный менеджер файлов, но в данном случае проводник «принадлежит» программе (рис. 3.4). По умолчанию открывается та папка, где предполагается хранить файлы, она создается при установке программы. Новичок: А как производить перемещение по директориям файловой системы? Рис. 3.4. Файловый менеджер программы Arduino
Для перемещения по директориям файловой системы можно использовать: ♦ либо мышку — двойной щелчок по верхней строке перемещает вас в родительскую директорию; ♦ либо использовать клавиатуру, то есть, клавишу Enter для входа, клавиши стрелок курсорных клавиш для перемещений вверх и вниз. После выбора нужного файла, его имя появляется в окне «Enter file пате:» и после нажатия на кнопку ОК открывается в окне редактора. Следующий пункт в File — это Sketchbook. При установке программы (и первого запуска) в домашней папке появляется место, где можно хранить все свои проекты. Называется оно sketchbook. ПРИМЕЧАНИЕ. Если вы не сохраняли свои файлы, этот пункт пуст. Но, как только вы сохранили хотя бы свой первый файл, то, едва курсор мышки выделяет этот пункт, вы видите свои файлы (рис. 3.5). Рис. 3.5. Книга хранения программ
File Edit Sketch, tapis Help "ctrl+^l Cirl4-0 New Open... Sketchbook Cose Ctri+W Save Ctrl-hSi Save AS Ctrlf ShiiHS Upload to I/O Board Ctrl+-U Page Setup' Qfl>Shift4-Ps Print CtrUP Preferences CtrF+Comma’ Quit .. ...... Ethernet Firmata LiquidCrystal Matrix Servo SPI Stepper Wire eeprornjead । e epromjwrite, * -"Belay (1060). digitalwrite (ledPin, LOW); delay (1000); } > Рис. 3.6. Набор примеров, полученных вместе с пакетом Arduino Следующий пункт, Examples, отрывает примеры, которые вы получили вместе с программой. Набор примеров и их классификация зависят от версии программы. Так версия 21 показывает такие примеры (рис. 3.6). ПРИМЕЧАНИЕ. Я планирую рассказать о работе программы в разных операционных системах, так что, переходя к другим версиям, при случае, я покажу другой набор примеров. Следующий пункт Close закрывает программу, если вы сохранили файл, и выводит диалог, напоминающий вам, что вы еще не сохранили файл, и помогающий либо вернуться в редактор, либо сохранить файл. Пункт Save служит для сохранения файла. А пункт Save As... позволяет сохранить открытый, например, из раздела примеров файл под другим именем и/или в другом месте. Команда открывает менеджер файлов, о котором мы говорили выше, и вы вольны выбрать нужное место и имя, но следует избегать, как и при установке программы, директорий и имен, написанных не латиницей.
Следующий пункт Upload to I/O Board — это команда загрузки откомпилированного файла в модуль Arduino. Page Setup задает размеры и ориентацию страницы. А команда Print открывает диалоговое окно печати, где можно выбрать принтер и установки печати. Пункт Preferences открывает диалог предустановок программы (рис. 3.7). 0 Preferences Sketchbook location:_________________________________________________ |/home/vladimir/sketchbook!__________________________________________ | Editor font size jl2 | (requires restart of Arduino) | ® Delete previous applet or application folder on export j □ use external editor И Check for updates on startup More preferences can be edited directly in the fife /home/vladimir/ arduino/preferences.t (edit only when Arduino is not running! _____________ i °1_ 1' Cancel ] Рис. 3.7. Установки программы no умолчанию В предустановках можно задать место расположения вашей папки с проектами (sketchbook), изменить размер шрифта и т. д. Если вы хотите использовать вместо встроенного редактора иной, скажем, более привычный для вас или удобный, по вашему мнению, вы можете установить флажок рядом с Use external editor. ПРИМЕЧАНИЕ. И, обратите внимание, есть указание, где можно найти файл настроек. Это обычный текстовый файл, но имеющий много данных для настройки программы. Quit — выход из программы.
Редактрование текста II программы II Следующий раздел основного меню относится к возможностям редактирования (рис. 3.8). LdHz_Sketch Tools Help Undo' '; CtrlFz? Redo CtrtFY Cut Ctrl 4-X Copy Ctrl FC Copy for Forum CtriFShiftFC Copy as HTML OrfFAltFC Paste OtrlFV Select All Ctrl FA Comment/Uncomment CtriFSIash Increase indent CtrlF Close Bracket Decrease Indent CtriFOpen Bracket Find... CtriFF Find Next CtrlFG Рис. 3.8. Раздел редактирования основного меню Как во многих программах, меню контекстно-чувствительно. Первые два пункта Undo, отменить последнюю операцию, и Redo, вернуть отмененную операцию, не активны. До тех пор пока вы не выполнили никаких операций. Команда Cut вырезает выделенный текст (для выделения можно нажать левую клавишу мышки и «отчеркнуть» текст, а можно установить курсор в нужное место, нажать клавишу Shift на клавиатуре и использовать курсорные клавиши). Команда Сору копирует текст в буфер обмена. Команда Copy for Forum копирует в буфер обмена код для форума Arduino. Copy as HTML копирует текст в формате, удобном для размещения на сайте. Команда Paste вставляет текст из буфера обмена в место, указанное курсором. Select АП — удобная команда для копирования всего текста в окне редактора, например, тогда, когда вы хотите добавить выделенный код в свою программу. Comment/Uncomment — тоже удобное добавление к командам редактирования, когда вам при отладке программы нужно убрать на время из кода строку и вставить вновь. Вместо уда
ления строка будет закомментирована (или символы комментария будут удалены). Следующие две команды Increase Indent и Decrease Indent помогают форматировать текст, сдвигая его вправо или влево. Команда Find... открывает диалоговое окно для ввода искомого слова или замещения одного слова, например, имени переменной, другим. С помощью команды Find Next можно искать следующее появление искомого слова, если одно из них уже найдено. Раздел основного меню Sketch, понятно, отсутствует в других программах. Этот раздел специфический, относится к работе программы и ряду ее свойств (рис. 3.9). Рис. 3.9. Содержание раздела «Sketch» Команда Verify/Compile позволяет вам скомпилировать код, который вы создали в редакторе. Команда Stop останавливает компиляцию. Команда Show Sketch Folder открывает в системном проводнике то место, из которого был открыт файл или в котором он был сохранен. Import Library — импортирует нужную вам библиотеку (рис. 3.10). Add File... добавляет файл к проекту. Команда открывает встроенный проводник для выбора нужного файла. На рис. 3.11 показно подменю раздела инструментов (Tools). Раздел «Tools» — тоже особенность программы. Некоторые пункты этого меню открывают подменю, они отмечены стрелочками. Команда Auto Format позволяет вам включить автоматическое форматирование вводимого текста программы (или выключить). Это относится к отступам, расположению скобок.
Ethernet Firm ata Liquidcrystal Matrix Servo SoftwareSeriai SPI Sprite Stepper Wire I File Edit 'Ml Tools Help Verify / Compile Ctrl+R ImKsI stop J sketch Show Sketch Folder Ctri-l-K | Add File Puc. 3.10. Подраздел импорта библиотек File Edit SketchjToo^ Help Archive Sketch Fix Encoding & Reload Serial Monitor Soard j Serial Port j 8um Bootloader pinMode (ledPin, uu iruIt; sketch feblla int ledPin = 13 void setup!) CtrH-Shlfti-M Puc. 3.11. Содержание раздела инструментов программы Команда Archive Sketch архивирует проекты. Fix Encoding & Reload позволяет отменить все исправления и перезагрузить файл проекта. При работе с последовательным портом очень полезно подключить терминал, чтобы видеть, как модуль Arduid работал бы, будучи подключен к компьютеру по COM-порту. Для этой цели служит встроенная терминальная программа, запускаемая командой Serial Monitor. Ранее об этой программе уже упоминалось. Вот как работает эта связка в дистрибутиве Fedora 14 (рис. 3.12). Пункт Board служит для выбора вашей модели модуля Arduino из списка возможных версий, как показано на рис. 3.13. А следующий пункт Serial Port позволяет выбрать порт, к которому подключен модуль. Есть модели, которые подклю-
Рис.3.12. Работа программы, использующей терминал. г - Arduino Uno С Arduino Ouemilanove or Nano w/ ATmega328 $ Arduino Dieciniiia,. Duemilanove, or Nano w/ ATrnegal 58 ~ Arduino Mega/560 О Arduino Mega (ATmegal280) ( »Arduino Mini О Arduino Fio Arduino ВТ w/ ATmega328 О Arduino ВТ w/ATmegalBB О UlyPad Ardu«no w/ ATmegs328 C LilyPad Arduino w/ ATmegal68 • Arduino Pro or Pro Mini ( 5V, 1& MHzl wj ATmega328 j Arduino Pro or Pro Mini (5V. 16 MHz) w/ АТшеда168 Arduino Pro or Pro Mini (13V. 8 MHz) w/ ATmega328 О Arduino Pro or Pro Mini (3.3W 8 MHz) w/ ATmegal68 Arduino ti|G or older w/ АТтедаХбВ Ardinno WG or older w/ Mmegab Puc. 3.13. Список модулей, с которыми работает программа Arduino чались к COM-порту. До тех пор, пока модуль не подключен к USB-порту в Linux, вы видите только COM-порт (ttySO), иначе, подключив модуль и запустив программу, вы увидите и USB-порт (ttyUSBO).
ЭТО ВАЖНО! Пункт Burn Bootloader относится к выбору загрузчика вашего модуля Arduino и без предва-рительного выяснения, чем вам грозит выполнение этой команды, ее, пожалуй, лучше оставить в покое (до того момента, когда вы станете с модулем и программой «на коротке»). Подсказки или раздел помощи Раздел помощи в программе Arduino достаточно хорошо проработан (рис. 3.14). sketchfeblla | Arduino 0021 ®@ Ml | File Edit Sketch Tools _________________________________________ Getting Started Environment Troubleshooting ----------------_-------Reference int ledPin = 13; , Find (n Reference Ctrl 4-Shift+-F void setupf) { | Visit Arduino cc pinbtodefledPin, OU- About Arduino '«с»*' 'xS Рис. 5.14. Раздел помощи в программе Arduino Первый пункт, Getting Started, открывает в Интернет-проводнике инструкции по быстрому началу работы с программой (рис. 3.15). Я использую графическую оболочку KDE 4, в которой по умолчанию используется универсальный проводник Konqueror. Он и открывает страницу на сайте Arduino. Он же открывает следующую страницу по команде Environment, но уже на компьютере из места установки программы. Здесь можно найти описание того, чему посвящена эта глава, но пока на английском языке. Troubleshooting—страница, загружаемая с компьютера о тех проблемах, которые могут возникнуть при работе с программой и модулем Arduino.
Ardiflna playground Linux — Ko.nq.ueror Файл Правка Вид Переход Закладки Сервис Настройка Окно Справка Й* ’ ' V 4 V g http//Ww ward u in о. с <3 v jj vr ч* Release Notes Fedora Project v *3 Red Hat v Free Content v 1 ... I ...... MN,.. ...I -I .U.J.I!................................. .. r --.r.? I'.,..;. Playground Forum Help I Sign in or Register ARDUINO PLAYGROUND The playground is a publidy-editable wiki about Arduino. Manuals jnd СштгаЛши Board Setup and Configuration Development Tools Interfacing With Hardware • Output Installing Arduino on Linux For more defatted instructions, pick your distribution: • Debian • Fedora Puc. 3.15. Первый пункт раздела помощи Reference — краткий справочник по языковым конструкциям, которые вам предстоит использовать. Find in Reference — помогает отыскать в этом справочнике нужное место. Выделите, например, функцию и выполните команду. Откроется проводник с нужным описанием этой функции. Frequently Asked Questions — часто задаваемые вопросы, тоже страница, расположенная на компьютере, но из. опыта работы сайта проекта. Предпоследний пункт откроет в Web-браузере главную страницу сайта Arduino, а последний выведет на экран информацию о программе. Инструментальная панель Ниже основного меню расположена инструментальная панель программы. В основном кнопки панели повторяют
наиболее часто применяемые команды, а иконки на кнопках хорошо описывают эти команды. Более того, при наведении курсора мышки на кнопку вы можете видеть в правой части панели назначение этой кнопки, как на рис. 3.16. И Upload Рис. 3.16. Инструментальная панель программы Arduino Слева-направо назначение кнопок инструментальной панели: Проверить и компилировать. Остановить. Новая страница. Открыть. Сохранить. Загрузить в модуль. Открыть монитор. Строка состояния работы с проектом Ниже окна редактирования находится строка состояния, отображающая текущее состояние работы программы (рис. 3.17). Рис. 3.17. Строка состояния А под ней окно, в которое программа выводит сообщения, например, об ошибках (рис. 3.18). Рис. 3.18. Окно сообщений при работе программы
Рис. 3.19. Панель, указывающая номер строки в тексте программы Рис. 3.20. Выпадающее меню редактора текста
В самой нижней части можно увидеть, на какой строке текста находится курсор. Это весьма привлекательно, если вы отыскиваете ошибки, которые, как правило, имеют указание на строку текста программы (рис. 3.19). Вот, пожалуй, все, что можно сказать пока о программе. Осталось добавить, что, щелкнув в окне редактора правой клавишей мышки, вы увидите выпадающее меню, тоже контекстно-чувствительное, повторяющее основные команды редактирования (рис. 3.20). Ветер перемен II не должен поднимать пыль II Для начинающих, пользующихся операционной системой Windows, одно из изменений будет, наверное, приятно — русифицированный интерфейс (рис. 3.21). @ sketch_sepO9a | Arduino 1.8.2 — □ X Файл Правка Скетч Инструменты Помощь // put your setup code here, to run once: 4 } 5 € void loop О { 7 // put your main code here, to run repeatedly: 8 § } Puc. 3.21. Arduino в Windows 10
Рис. 3.22. Список примеров в Arduino версии 1.8.2 Однако содержимое и базовый вид интерфейса отличается не слишком сильно. А в том, что касается Linux, я не уверен, что во всех дистрибутивах не используется интерфейс с названиями разделов на английском языке. Показательно то, как расширился раздел примеров (рис. 3.22). ЭТО ИНТЕРЕСНО! Не будучи ярым приверженцем Linux, я хочу сказать для любознательных: если вам не нравится идея устанавливать на компьютер вторую операционную систему, загрузите программу VirtuaLBox, зарузите ISO образ дистрибутива Linux и установите эту операционную систему в виртуальном виде. Устанавливается она в созданную программой от Oracl папку, о когда вам надоест пользоваться второй операционной системой, вы легко удалите ее средствами VirtualBox. Вы можете установить не только дистрибутив Linux, но и Windows.
ПРИМЕЧАНИЕ. Работа в виртуальной операционной системе почти не отличается от работы в системе полностью установленной на компьютере. А это удобно для первого знакомства. Написав последнюю фразу, я вспомнил о неудачной попытке что-то сделать в программе Arduino для Linux ROSA, и мне стало стыдно. По этой причине я удаляю программу Arduino, захожу на сайт проекта Arduino, скачиваю программу для Linux (не перепутать бы разрядность, 32 или 64), распаковываю полученный архив в директорию /home/vladimir. Теперь приходится пользоваться консолью: команда cd /home/vladimir/arduino-1.8.4, такова последняя версия, перемещает меня в нужную папку, где достаточно ввести команду ./install.sh, чтобы процесс установки начался. Дождавшись его окончания, я вижу на рабочем столе ярлык для запуска Arduino, запускаю програму, выбираю нужный модуль и последовательный порт, выбираю простой пример и запускаю, модуль Arduino я подключил ранее, загрузку программы в модуль. И вы можете проверить, этот вариант программы ничем не отличается от своего собрата в Windows 10. Иной раз следует проявить терпение, следует поискать разные решения проблемы, чтобы добиться своего.
ГЛАВА 4 ОСВАИВАЕМ ЯЗЫК ПРОГРАММИРОВАНИЯ ARDUINO Языков программирования на сегодняшний день столько, что можно легко запутаться, если учесть, что многие из них имеют диалекты или расширения языка. Даже профессионалам приходится потрудиться, если возникает необходимость сменить язык программирования. Поэтому любителям не следует метаться от одного «крутого» языка программирования, к другому, который еще «круче». Что такое язык программирования Arduino Основа языка программирования модуля Arduino — это язык Си (скорее Си++). Еще точнее, этот диалект языка называется Processing/Wiring. Хорошее обозрение языка Arduino вы найдете в блокноте программиста Arduino (воспользуйтесь поисковой системой, найдете ряд предложений). А мне хочется больше рассказать не о языке, а о программировании. Новичок: А разве программирование и текст программы на языке программирования не одно и то же?
ЧТО ЕСТЬ ЧТО. Программа - это некий набор команд, которые понимает процессор, процессор вашего компьютера или процессор микроконтроллера модуля Arduino, не суть важно. Процессор читает команды и выполняет их. Любые команды, которые понимает процессор — это двоичные числа. Это только двоичные числа и ничто иное. Выполняя арифметические операции, для которых процессор некогда и предназначался, процессор оперирует с числами. Двоичными числами. И получается, что и команды, и то, к чему они относятся, это только двоичные числа. Вот так. Новичок: Но как же процессор разбирается в этой «куче» двоичных чисел? Отвечаю! Все эти двоичные числа записываются в последовательные ячейки оперативной памяти, имеющие адреса. Когда вы загружаете программу, и она начинает работать, процессор получает первый адрес программы, где обязательно должна быть записана команда. Те команды, которые требуют от процессора операций с числами, имеют «опознавательные знаки», например, что в следующих двух ячейках памяти два числа, которые нужно сложить. А счетчик, который называется счетчиком команд, где записан адрес следующей команды, в данном случае увеличивает адрес так, что в программе по этому адресу будет следующая команда. ПРИМЕЧАНИЕ. При неправильной роботе программы или сбоях процессор может ошибиться, и тогда, прочитав вместо команды число, процессор делает совсем не то, что должен делать, а программа «зависает».
Новичок: Теперь я понял, что любая программа — это последовательность двоичных чисел. А программирование — это умение правильно записывать правильные последовательности двоичных чисел. Достаточно давно для записи программ стали использовать специальные средства, которые называются языками программирования. Однако любая программа, в первую очередь, требует от вас ясного понимания того, что должна делать программа, и для чего она нужна. Чем яснее вы это понимаете, тем легче создать программу. Небольшие программы, хотя трудно сказать, какие программы небольшие, а какие нет, можно рассматривать целиком. Более сложные программы лучше разбить на части, которые можно рассматривать как самостоятельные программы. Так их проще создавать, легче отлаживать и проверять. С чего начать программировать? Новичок: Так с чего же мне начинать программировать? Я не готов спорить, но считаю, что программу удобнее начинать с описания на обычном языке. И в этом смысле я считаю, что программирование не следует путать с написанием кода программы. Когда программа описана обычными словами, вам легче определить, например, какой язык программирования выбрать для создания кода программы. ПРИМЕЧАНИЕ. Ближе всего к записи программы с помощью двоичных чисел стоит язык ассемблер. Для него характерно соответствие команд языка двоичным командам, понятным процессору. Но кодирование программ, на ассемблере требует опыта, больших усилий и ближе к искусству, чем к формальным операциям.
Более универсальны и легче в применении такие языки высокого уровня, как Бэйсик или Си. И давно для записи программ в общем виде используют графический язык, а в последнее время появились и «переводчики» с этого языка на язык процессоров. Новичок: А что за графический язык? Об одной из программ, использующих графический язык программирования, я расскажу позже. А сейчас... Язык для программирования II модуля Arduino || Кроме языков программирования общего применения, всегда существовала некоторая специализация языков программирования, и существовали специализированные языки. К последним я бы отнес и язык программирования модуля Arduino. Все, что нужно сказать модулю, чтобы он сделал что-то нужное нам, организовано в удобный набор команд. Но вначале о том, что нам нужно от Arduino? Модуль можно использовать в разных качествах — это и сердце (или голова) робота, это и основа прибора, это и удобный конструктор для освоения работы с микроконтроллерами ит.д. Выше мы уже использовали простые программы для проверки подключения модуля к компьютеру. Кому-то они могут показаться слишком простыми, а поэтому не интересными, но любые сложные программы состоят из более простых фрагментов, похожих на те, с которыми мы уже знакомились. Давайте посмотрим, о чем нам может рассказать самая простая программа «Помигать светодиодом, Blink». int ledPin = 13; void setup()
{ pinMode (ledPin, OUTPUT); } void loop() { .digitalWrite (ledPin, HIGH); delay (1000); digitalWrite (ledPin, LOW); delay (1000); } Вначале вспомним, что такое светодиод. В сущности это обычный диод, у которого, благодаря его конструкции, при протекании тока в прямом направлении начинает светиться р-n переход. То есть, для свечения светодиода нужно, чтобы через него протекал ток, а, значит, к светодиоду следует приложить напряжение. А чтобы ток не превысил допустимого значения, последовательно со светодиодом следует включить резистор, который называют токоограничительным. Новичок: Я знаю, что такое светодиод. Причем здесь программа? Причем программа? Напряжение к светодиоду прикладывает микроконтроллер, составляющий основу модуля Arduino. У микроконтроллера, кроме процессора, выполняющего наши команды, есть один или несколько портов ввода-вывода. Не вдаваясь в рассмотрение конкретного устройства порта, скажем так — когда вывод порта работает на выход, его можно представить как выход цифровой микросхемы с двумя состояниями, включено и выключено (есть напряжение на выходе, нет напряжения на выходе). Но этот же вывод порта может работать и как вход. В этом случае его можно представить, например, как вход цифровой микросхемы — на вход подается логический уровень, высокий или низкий. Как мы мигаем светодиодом: Включить выходной вывод порта. Выключить вывод порта.
Но процессор работает очень быстро. Мы не успеем заметить мигания. Чтобы заметить это мигание, нам нужно добавить паузы. То есть: Включить выходной вывод порта. Пауза 1 секунда. Выключить вывод порта. Пауза 1 секунда. Это наша программа. Процессор прочитает первую команду и включит вывод, светодиод загорится. Затем процессор сделает паузу в работе и выключит вывод, светодиод погаснет. Но он только один раз мигнул. Новичок: И что делать? ЧТО ЕСТЬ ЧТО. Повторение какого-либо процесса или набора команд называется в программировании циклом. Используются разные виды циклов. Есть цикл, который выполняется заданное число раз. Это цикл for. Есть циклы, которые выполняются до тех пор, пока не будет выполнено некоторое условие, которое является частью языковой конструкции цикла. А если условие не будет выполнено никогда, то цикл выполняется бесконечное число раз. Это бесконечный цикл. Я не думаю, что микроконтроллеры используются с программами того вида, который приведен выше. То есть, один раз выполнено несколько команд, и больше контроллер не работает. Как правило, он работает постоянно, как только на него подается питающее напряжение. А, значит, микроконтроллер должен работать в бесконечном цикле.
Функции как основа современного языка программирования Именно об этом говорит функция void loop(), loop — это петля, замкнутый цикл. Условия прекращения работы цикла нет, а, следовательно, нет условия его завершения. Кроме того, мы должны сообщить модулю Arduino, какой вывод порта и как мы хотим использовать, для выхода (OUTPUT) или для входа (INPUT). Этой цели служит функция void setupO, которая для языка Arduino является обязательной, даже если она не используется, и команда pinModeO для задания режима работы вывода. void setupO { pinMode (ledPin, OUTPUT); } И еще, языковая конструкция примера использует переменную для определения номера вывода: int ledPin = 13; Такое использование переменной удобно. Решив, что вы будете использовать не вывод 13, а 12, вы внесете изменение только в одной строке. Особенно сильно это сказывается в больших программах. СОВЕТ. Имя переменной можно выбирать по своему усмотрению, но, как правило, оно должно быть только символьным, и часто количество символов ограничивается. \_______________________________________________> Если вы неверно зададите имя переменной, думаю, компилятор вас поправит.
ПРИМЕЧАНИЕ. Иногда подобное определение вы встретите как заданную константу, что не меняет существа дела, или как определение с ключевым словом #define. Функция digitalWrite (ledPin, HIGH) устанавливает заданный вывод в состояние с высоким уровнем, то есть включает вывод. A delay (1000), как вы уже поняли, означает паузу в 1000 миллисекунд или 1 секунду. Новичок: А что такое int? Что означают такие приставки, как int, void? Любые значения, любые переменные размещаются в памяти, как и команды программы. В ячейки памяти записываются числа зачастую из 8 битов. Это байт. Но байт — это числа от 0 до 255. Для записи больших чисел нужно два байта или больше, то есть, две или больше ячеек памяти. Чтобы процессору было ясно, как работать с числом, разные типы чисел имеют разные названия. Так число типа byte, займет одну ячейку, int (integer, целое) больше. Кроме того, функции, используемые в языках программирования, тоже возвращают числа. Чтобы определить, какой тип числа должна вернуть функция, перед функцией записывают этот тип возвращаемого числа. Но некоторые функции могут не возвращать числа, такие функции предваряют записью void. Вот сколько интересного может рассказать даже самая простая программа. ПРИМЕЧАНИЕ. Многих, и не только начинающих, смущают программы из разряда «помигать светодиодом». Напрасно. Управление с помощью IR-кода -это тоже помигать светодиодом. Да, мигание
несколько сложнее, чем то, что представлено выше, но не более, чем мигание светодиодом. А использование последовательной передачи данных? А использование, скажем, протокола 1-wire? А сейчас проделаем простые эксперименты, используя только то, что мы уже знаем из возможностей языка. Проделаем эксперимент, заменив переменную типа int Заменим переменную типа int, которая занимает много места в памяти, на byte — одно место, одна ячейка памяти. Посмотрим, что у нас получится. byte ledPin = 13; void setup() { pinMode (ledPin, OUTPUT); } void loop() { digitalWrite (ledPin, HIGH); delay (1000); digitalWrite (ledPin, LOW); delay (1000); } После компиляции и загрузки программы в модуль мы не заметим изменений в работе программы. Хорошо. Тогда изменим программу так, чтобы заметить изменения в ее работе. Для этого мы заменим число в функции delay (1000) переменной, назвав ее my_del. Эта переменная должна быть целым числом, то есть, типа int. int my_del = 5000; delay(my_del);
СОВЕТ. Не забывайте заканчивать каждую команду точкой с запятой. Внесите изменения в программу, скомпилируйте ее и загрузите в модуль. Затем поменяйте переменную и повторите компиляцию и загрузку: byte my_del = 5000; Новичок: Разница, уверен, получится ощутимая! Проделаем эксперимент II с изменением длительности пауз II А вот еще один эксперимент с изменением длительности пауз. Уменьшение длительности пауз выполним, скажем, пять раз. Сделаем паузу в 2 секунды, а затем будем увеличивать тоже пять раз. И вновь сделаем паузу в 2 секунды. Цикл, выполняемый заданное количество раз, называется циклом for и записывается он так: for (int i - 0; i<5; i++) { что-то, что выполняется в цикле for } Для выполнения цикла ему нужна переменная, у нас это i, переменной нужно задать начальное значение, которое мы ей и присвоили. Затем следует условие завершения работы цикла, у нас i меньше 5. А запись i++ — это характерная для языка Си запись увеличения переменной на единицу. Фигурные скобки ограничивают набор команд, подлежащих выполнению в цикле for. В других языках программирования могут быть другие ограничители для выделения блока кода функции.
Внутри цикла мы выполняем то же, что и раньше, с небольшими изменениями: for (int i = 0; i<5; i++) { digitalWrite (ledPin, HIGH); delay (my_del); digitalWrite (ledPin, LOW); delay (my_del); my_del = my_del — 100; } Об изменении записи паузы мы говорили выше, а изменение самой паузы достигается уменьшением переменной на 100. Для второго цикла мы запишем этот же блок кода, но переменную длительности паузы будем увеличивать на 100. for (int i = 0; i<5; i++) { digitalWrite (ledPin, HIGH); delay (my_del); digitalWrite (ledPin, LOW); delay (my_del); my_del += 100; J Вы заметили, что запись уменьшения паузы и ее увеличения у меня выглядят по-разному. Это тоже особенность языка Си. Хотя для ясности следовало повторить эту запись, изменив только знак минус на плюс. Итак, мы получаем такую программу: int ledPin = 13; int my_del = 1000; void setup() { pinMode (ledPin, OUTPUT); } void loop() { for (int i = 0; i<5; i++)
digitalWrite (ledPin, HIGH); delay (my_del); digitalWrite (ledPin, LOW); delay (my_del); my_del -= 100; } delay (2000); for (int i = 0; i<5; i++) { digitalWrite (ledPin, HIGH); delay (my_del); digitalWrite (ledPin, LOW); delay (my_del); my—del += 100; } delay (2000); } Скопируем код нашей программы в программу Arduino, скомпилируем ее и загрузим в модуль. Изменение длительности пауз заметно. И будет еще заметнее, попробуйте, если цикл for выполнить, скажем, раз 8. ПРИМЕЧАНИЕ. То, что мы сейчас сделали, делают и профессиональные программисты - имея готовую программу, ее легко можно модифицировать под свои нужды или желания. Поэтому все свои программы они хранят. Что я советую делать и вам. Что мы упустили в своем эксперименте? Мы не прокомментировали нашу работу. Для добавления комментария используется либо двойная «прямая» косая черта, либо одиночная, но со звездочками.
ЭТО ВАЖНО! Я советую вам добавить комментарии самостоятельно, поскольку вернувшись к программе через некоторое время, вы легче в ней разберетесь, если будут пояснения, что вы делаете в том или ином месте программы. И еще советую в папке с каждой программой хранить ее описание на обычном языке, выполненное в любом текстовом редакторе. А теперь помигаем светодиодом Самая простая программа «помигать светодиодом» может послужить еще для десятка экспериментов (даже с одним светодиодом). Мне кажется эта часть работы, придумывать, что еще можно сделать интересного, самая интересная. Можно, например, попробовать в модифицированной программе, как работают другие типы цикла. Хотя процессор микроконтроллера, как любой другой, может производить вычисления (для того его и придумывали), и это используется, например, в приборах, все-таки наиболее характерной операцией для микроконтроллера будет установка выхода порта в высокое или низкое состояние. О внешних событиях микроконтроллер узнает, в основном, по состоянию входов. Настроив выводы порта на цифровой вход, мы можем следить за состояние вывода. Если исходное состояние входа — высокий уровень, а событие вызывается переходом входа в низкое состояние, то мы можем что-то сделать, реагируя на это событие. Новичок: А как это проверить? Самый простой пример — на входе кнопка. Когда кнопка не нажата, вход в высоком состоянии. Если нажать кнопку, то
вход переходит в низкое состояние, а мы можем «зажечь» светодиод на выходе. При следующем нажатии на кнопку светодиод можно погасить. Это опять пример простой программы. Даже начинающему она может показаться неинтересной. Однако и эта простая программа может найти вполне полезное применение. Приведу только один пример: мы можем после нажатия на кнопку не зажигать светодиод, а помигать (определенным образом). И светодиод возьмем с инфракрасным излучением. В результате мы получим пульт управления. Вот такая простая программа. В разных версиях программы есть различия в списке примеров. Я приведу одну программу: int ledPin = 13; int inPin = 2; void setup() { pinMode (ledPin, OUTPUT); pinMode (inPin, INPUT); } void loop() { if (digitalRead(inPin) -- HIGH) { digitalWrite(ledPin, HIGH); delay (1000); digitalWrite (ledPin, LOW); delay (1000); } } И, как вы видите, совершенно новую программу мы получаем, модифицируя старую. Теперь светодиод будет мигать только тогда, когда нажата кнопка, которая присоединена к выводу 2. Вывод 2 через резистор 10 кОм присоединен к общему проводу (земле, GND). Кнопка одним концом присоединена к питающему напряжению +5 В, а другим концом к выводу 2. Новичок: А что за if?
В программе мы встречаем новую языковую конструкцию if из раздела управления программой. Читается она так: если выполняется условие (заключенное в скобках), то выполняется блок программы, заключенный в фигурные скобки. ЭТО ВАЖНО! Обратите внимание, что в условии (digitolRead(inPin) == HIGH) равенство входа высокому состоянию выполнено с помощью двух знаков равенства! Очень часто в спешке об этом забывается, и условие получается неверным. Модуль Arduino как макет для проверки программ Программу можно скопировать и загрузить в модуль Arduino. Однако чтобы проверить работу программы, понадобится дополнить конструкцию модуля. Впрочем, это зависит от разновидности модуля. Оригинальный модуль имеет розетки для соединения с платами расширения. В этом случае можно вставить подходящие одножильные провода в нужные места разъема. Мой модуль Arduino Nano имеет ножевые контакты для соединения с платами расширения. Я могу либо поискать подходящий разъем, либо, что дешевле, использовать подходящую панельку для микросхемы в корпусе DIP. Новичок: А где у модуля те выводы микроконтроллера, которые можно встретить в программах? С этим поможет разобраться картинка (рис. 4.1), которую я взял с сайта [2].
Arduino vs (PCINT14/RESET) РС6 С RX - D0 (PCINT16/RXD) PD0E ТХ - DI (PCINT17/TXD) PD1 Е D2 (PCINT18/INT0) PD2 С PWM3 (PCINT19/OC2B/INT1) PD3 С D4 (PCINT20/XCK/T0) PD4 Е VCCE GNDE (PCINT6/XTAL1/TOSC1) РВ6 Е (PCINT7/XTAL2/TOSC2) РВ7 Е PWM5 (PCINT21/OCOB/T1) PD5 Е PWM6 (PCINT22/OCOA/AINO) PD6 Е D7 (PCINT23/AIN1) PD7 Е D8 (PCINT0/CLKO/ICP1) РВО Е АТМеда168 1 28 2 27 3 26 4 25 5 24 6 23 7 22 8 21 9 20 10 19 11 18 12 17 13 16 14 15 l chip pinouts □ РС5 (ADC5/SCL/PCINT13) AIN5 □ РС4 (ADC4/SDA/PCINT12) AIN4 □ РСЗ (ADC3/PCINT11) AIN3 □ РС2 (ADC2/PCINT10) AIN3 □ РС1 (ADC1/PCINT9) AIN1 □ РСО (ADC0/PCINT8) AIN0 □ GND □ AREF ZJAVCC □ РВ5 (SCK/PCINT5) D13 - LED □ РВ4 (MISO/PCINT4) D12 □ РВЗ (MOSI/OC2A/PCINT3) РИМ 11 □ РВ2 (SS/OC1B/PCINT2) PWM10 □ РВ1 (OC1A/PCINT1) D9 Рис. 4.1. Расположение и назначение выводов контроллера и модуля Arduino Все выводы моего модуля CarDuino промаркированы, так что найти нужный вывод не составит труда. Можно подключать кнопку и резистор, затем проверять работу программы. ПРИМЕЧАНИЕ. Кстати, на вышеупомянутом сайте RoboCraft весь процесс отображен на картинках (но программа использует не совсем такие выводы!). Советую посмотреть. Встроенные в микроконтроллер аппаратные устройства Многие микроконтроллеры в своем составе имеют дополнительные аппаратные устройства. Так, Atmegal68, на основе которого собран модуль Arduino, имеет UART — встроенный блок для связи с другими устройствами с помощью последо
вательного обмена данными. Например, с компьютером через COM-порт. Или с другим микроконтроллером с помощью его встроенного блока UART. Есть еще и аналого-цифровой преобразователь. И формирователь широтно-импульсной модуляции. Использование последнего иллюстрирует программа, которую я тоже скопирую с сайта RoboCraft. Но эту программу можно найти и в блокноте программиста Arduino (автор Brian W. Evans). И, возможно, она есть в примерах программы Arduino. //Fading LED by BARRAGAN //<http://people.interaction-ivrea.it/h.barragan> int value = 0; // переменная для хранения нужного значения int ledpin = 9; // светодиод подключен к digital pin 9 void setup() { // Нет необходимости вызвать функцию pinMode } void loop () { for(value = 0 ; value <= 255; value+=5) // постепенно зажигаем светодиод { analogWrite(ledpin, value); // значение вывода (от 0 до 255) delay(30); // ждем :) } for(value = 255; value >=0; value-=5) // постепенно гасим светодиод { analogWrite(ledpin, value); delay(30) ; } } Если в предыдущей программе новой для нас была функция digitalRead(inPin), чтение цифрового ввода, то в этой про
грамме новая для нас функция analogWrite(ledpin, value), хотя параметры этой функции — уже знакомые нам переменные. Новичок: Если есть функция analogWrite, то, может быть, есть и функция analogRead? Программы, которые помогут освоить II программирование II Об использовании аналогового входа, использовании АЦП (аналого-цифрового преобразователя), мы поговорим позже. А сейчас вернемся к общим вопросам программирования. Новичок: Считаю, что программирование это то, что доступно всем, но потребуется время, чтобы освоить и программирование, и какой-либо язык программирования. Читал, что сегодня есть ряд программ, помогающих освоить именно программирование. Да! И одна из них имеет непосредственное отношение к модулю Arduino. Называется она Scratch for Arduino или сокращенно S4A. Найти и скачать эту программу можно по адресу [3]. Я не знаю, как точно переводится название программы, но «to begin from scratch» переводится, как «начать с нуля». ПРИМЕЧАНИЕ. На сайте проекта S4A есть версии для Windows и Linux, но для последней операционной системы готовая к установке программа есть в версии дистрибутива Debian.
Не хочу сказать, что ее нельзя использовать с другими дистрибутивами Linux, но вначале посмотрим, как работать в программе с модулем Arduino в Windows. После установки программы обычным образом можно настроить интерфейс на русский язык, используя переключатель языков (рис. 4.2). Рис. 4.2. Переключатель языков интерфейса программы Первый значок инструментальной панели, если его нажать, отображает все возможные языки интерфейса программы. Русский язык можно найти (рис. 4.3) в разделе... ... отмеченном, как «больше...». Если ничего не предпринимать, то надпись в правом окне «Searching board...» остается, но модуль не находится. Чтобы модуль Arduino подключить к программе S4A, следует загрузить с сайта проекта еще кое-что, показанное на рис. 4.4. Этот файл не что иное, как программа для Arduino (Sketch). То есть, текстовый файл, который можно скопировать в редактор Arduino, откомпилировать и загрузить в модуль. После выхода из программы Arduino можно запустить программу S4A и теперь модуль находится (рис. 4.5).
Рис. 4.3. Список языков для использования в интерфейсе программы Рис. 4.4. Файл для загрузки в модуль Arduino для S4A
Рис. 4.5. Подключение модуля к программе Аналоговые входы модуля не подключены, как и цифровые, поэтому значения, отображаемые для модуля, постоянно меняются произвольным образом. I Относительно перемен cS4A По ссылке, указанной в списке Интернет-ресурсов, вы попадаете на главную страницу проекта, где следует выбрать раздел «Download», а на странице загрузки прочитать про установку программы. Дабы не быть голословным, я загружаю программу, которую устанавливаю обычным образом, соглашаясь с предложенными вариантами. Отличие от предыдущей версии программы, пожалуй, в том, что язык сразу меняется, не заставляя меня делать это вручную. Но плата, как написано в инструкции по установке, не находится. Загрузить описанную ранее дополнительную программу для Arduino можно там, где указано на рис. 4.6.
Installing the Firmware Into your Arduino This firmware is a piece of software you need to install into your Arduino board to be able to communicate with it from S4A. • Download and install the Arduino environment by following the instructions on http://arduino cc/en/Mam/Software Take in account Arduino Uno requires at least version 0022.___________ | • Download our firmware from | • Connect your Arduino board to a USB port in your computer • Open the firmware file (S4AFirmware16.ino) from the Arduino environment • In the Tools menu, select the board version and the senal port where the board is connected • Load the firmware into your board through File > Upload Puc.4.6. Файл для работы S4A c Arduino Но, нажав на ссылку here, я, например, вижу текст программы в ее формате. Я не хочу мудрствовать лукаво, нажимаю правую клавишу мышки на этой ссылке и выбираю «загрузить как...». Загрузив файл в формате html, я просто исправляю расширение на ino и получаю файл для загрузки в модуль Arduino. Можно, конечно, скопировать файл в тестовый редактор, но,
боюсь, потребуется разобрать текст, который может выглядеть как единственная очень длинная строка. Итак, после загрузки полученного файла запускаем S4A (рис. 4.7), и плата обнаруживается. I Прежде, чем перейти к пятой главе Прочитав следующую главу, я решил повторить то, о чем писал в ней, применительно к Linux ROSE — для этого дистрибутива готового установочного пакета не нашлось. Скачав пакет для Debian, я распаковал его, как и рассказывал ниже. Чтобы запустить менеджер файлов с правами администратора и скопировать все файлы программы в нужные места, приходится использовать консоль. В консоли нужно ввести kdesu dolphin, что открывает файловый менеджер, теперь достаточно правильно перенести все файлы в разделы директории /usr. Рис. 4.8. Программа S4A в LinuxROSE
Первый запуск я осуществляю в консоли, введя S4A. Но позже, обращаясь к меню, я нахожу нужный мне ярлычок программы в приложениях (рис. 4.8). И, если вы не забыли скачать файл для загрузки в модуль Arduino (сохранить и при необходимости переименовать расширение, сделав его ino), загрузить эту программу в модуль, то можно запустить программу S4A и увидеть, что плата обнаруживается (рис. 4.9). Рис. 4.9. Работающая программа S4A в Linux ROSE
ГЛАВА 5 ARDUINO, ВИЗУАЛЬНОЕ ПРОГРАММИРОВАНИЕ Возможно, правы разработчики операционных систем, считающие пользователя злейшим врагом и самым опасным вирусом. А, может быть, неправы - создают они свои творения не для себя, а для пользователей. Словом, не знаю. Но, что точно знаю, я хочу видеть работающую программу S4A не только в Windows, но в Linux, и не только в дистрибутиве Debian. I Linux дистрибутивы и54А Начинаю я этот процесс с загрузки версии для Debian на сайте разработчиков [4]. Все загружаемые файлы располагаются по завершении загрузки в папке «Загрузка»-или «Downloads». Архивированные файлы, предназначенные для Linux, распаковываются менеджером архивов. Скачанный мной в openSUSE файл имеет расширение deb, но, используя Ark, тот самый менеджер архивов, его можно распаковать. В openSUSE с графическим менеджером KDE 4 для этого достаточно щелкнуть правой клавишей мышки по файлу и выбрать пункт выпадающего меню Распаковать во вложенную папку. В итоге появляется папка с именем S4A. Заглянем в нее (рис. 5.1).
Д 6 S4A— OoipNfi ’ . - 4 Файл. Правка Вид Перейти Сврдие Насгтройкй Справка «фгНдеяд Вперед 4^ Вверх . Значки - Таблица Столбцы > 'Поиск Точки входа ° * О> Домашняя папка > Downloads > S4A Сведения * * л- Домашняя папка Ф Се^» ЙЙ Корневая папка ||И* i J* кврэина i Щ Жёсткий ДИСК (29 , 0 АКСНгЛ. data tar gz control tar gz debian-binary S4A ТиП’ Дата Сегодня 1B 37 иэдонеиия Оценка. ил A Метки Добавить Коммент арий Добавить . « part or Downloads I 3 файла (33.1 МиБ) в. ------------ Ъ Рис. 5.1. Содержимое скачанной папки S4A Два файла с расширением tar.gz подлежат дальнейшей разархивации, а так выглядит выпадающее меню, которое помогает это сделать (рис. 5.2). В результате рядом с архивами появляется ряд файлов и папка, озаглавленная «usr». ПРИМЕЧАНИЕ. Из опыта работы с Linux я знаю, что в этой попке могут находиться файлы, которые при установке размещаются по адресу/usr корневой файловой системы. Если открыть эту папку, то, действительно, в ней можно увидеть еще три папки (рис. 5.3). Эти три папки соответствуют разделам, которые можно увидеть, если открыть в файловом менеджере раздел «Корневая папка» и директорию /usr, как показано на рис. 5.4.
BageasT» CW’X Копировать Ctrl+C Г ВрШитыуй'Wewa. ctri-v Cd Переименовать. F2 ** Щ^итк! (йаэину ,pei Открыть с помощью > 1 ^етвия > • Упаковать *-л ЯйпаковШ в. и Распаковать 8 зтупапку Огшровзто > Переместить в > Рис. 5.2. Выпадающее меню работы с архивированными файлами ./ 1 Шайства,- Alt+EntefeaCH Рис. 5.3. Содержание распакованного файла Содержимое папок bin, lib и share, скачанное ранее, как я полагаю, следует разместить в папки, отмеченные выше. Но, конечно, простому пользователю менять что-то в файловой
в % Корзина Щ Жёсткий диск (29 И ARCHIVE . @ w usr — Dolphin Файл Правка вид Перейти Сервис Настройка Справка ф Назад ♦ 0пе<^ Точки входа * * Домашняя папка Л Сеть Корневая папка ' Рис. 5.4. Разделы директории usr файловой системы 1QUC Сведения о х uw j Дата вторник об ! аюля 2010 । 09; 24 ! ; I К!>лм^нто;к:ч Доравнгь | ! i I системе никто не позволит. Поэтому в разделе основного меню «Система» находим пункт Файловый менеджер, открывающий новое подменю, где есть «Менеджер файлов (с правами администратора)». Этот менеджер позволит перенести все нужные файлы ^операционную систему. Ничего не выдумывая, открывая параллельно папки в двух окнах проводника, просто последовательно открываем нужные (они все названы) папки до появления файлов, а файлы копируем (рис. 5.5). Новичок: Читал, что особенно внимательно следует отнестись к папке share, поскольку она имеет много вложенных папок, и соответствующие папки следует отыскивать в файловой системе. Завершив копирование, можно попытаться отыскать программу в основном меню. И, впрямь, на закладке «Приложения»
Рис. 5.5. Перенос файлов программы в openSUSE в разделе «Разработка» (у меня еще один раздел «Другие программы») появляется программа S4A. И ее даже можно запустить. Но она после нескольких движений мышкой начинает виснуть... В терминале, а в openSUSE есть терминал с правами суперпользователя, от имени суперпользователя, предварительно подключив модуль Arduino, запускаем программу. И она работает. Теперь ее можно запустить обычным образом. 10 главном - о самой программе S4A В других дистрибутивах Linux операции схоже с теми, что описаны выше, отличия не столь значительны. Хотя в Fedora 14 я просто сменил пользователя, войдя в систему под root, что делать, конечно, не следует, но так было проще все разместить в нужных местах. Установив программу в Linux, посмотрим, а для чего мы ее устанавливали?
Новичок: У меня не Linux, a Windows, я могу делать все то же? Конечно. Во-первых, программа работает с модулем, показывая, что происходит на аналоговых и цифровых входах модуля. Что уже неплохо. Но не это главное. Главное, во-вторых, — программа позволяет собирать программу, а не кодировать на языке Arduino. Когда программа начинает работать, в левом окне есть ряд элементов, которые можно, подцепив мышкой, перенести в среднее окно — рабочее «сборочное» поле. Перенесем так элемент, который называется Start, что показано на рис. 5.6. Рис. 5.6. Перенос нужных программных элементов Теперь, нажав клавишу с надписью «контроль» в окошке чуть выше, получим ряд новых элементов (рис. 5.7). Среди этих элементов выберем элемент «всегда», который перенесем к уже имеющемуся элементу, и добавим так, чтобы верхний вырез вошел в выступ (рис. 5.8). Вернемся к набору элементов, с которого начинали, нажав на клавишу движение, и выберем элемент «digital 13 оп», который перенесем и положим внутрь предыдущего (рис. 5.9).
Рис. 5.7. Список элементов в группе «Контроль» Рис. 5.8. Добавление элементов в программу Из набора элементов «контроль» возьмем элемент «ждать 1 секунду», который вставим внутрь элемента «всегда» под элемент «digital 13 on». Чтобы ускорить этот процесс, вставим элемент ожидания еще раз, вернемся к элементам движения и добавим элемент «digital 13 off» между двумя элементами ожидания (рис. 5.10). Вам эта конструкция ничего не напоминает?
Рис. 5.9. Команда включения цифрового вывода digital 13 on О Рис. 5.10. Программа Blink в графическом виде Новичок: А должна напоминать? Посмотрите, когда мы начинали описывать первую программу обычным языком, мы так и записывали ее. Дважды щелкните по элементу «start» левой клавишей мышки и посмотрите на модуль Arduino — молчавший до сих пор светодиод на выводе 13 исправно мигает раз в секунду.
I Кодирование или программирование? Мы собрали программу, запустили ее и заставили работать модуль согласно этой программе. И мы не написали ни строчки кода. Именно по этой причине я предпочитаю различать программирование и написание программного кода. Новичок: А, может быть, это работает ранее загруженная программа, а не эта, собранная? start да I digital 13 on ждать О секунд I digital 13 off Хорошо, остановим работу программы, вновь дважды щелкнув мышкой по элементу «start». Щелкнем левой клавишей по единичке элемента «ждать 1 секунду» (рис. 5.11). Впечатаем цифру 5 (как на нижнем элементе). Запустим программу... и убедимся, ничего мы не перепутали, светодиод мигает с интервалом раз в 5 секунд! Мы не проверяли работу цифрового входа в «живом» виде. Не пора ли это сделать? Соберем программу в S4A. Первые «кирпичики» те же, что и в предыдущей программе. ждать 0 секунд Рис. 5.11. Изменение параметров Новичок: А что делаем далее? программных элементов Далее... нам понадобится выполнить условие: если кнопка нажата, включить светодиод, иначе выключить. Такой элемент есть — это «если... или...». В его верхней части есть «гнездо», куда можно вставить нужное нам условие «цифровой вход...» (рис. 5.12). Осталось добавить действия, чтобы получить нужный вид программы, как это показано на рис. 5.13. Если сравнивать ее с программой, написанной на языке Arduino, то можно сказать, что отличия только те, что были внесены сознательно: когда кнопка отпущена, светодиод не горит, когда нажата, светодиод загорается.
Рис. 5И2. Добавление условия в элемент if ветвления программы start всегда если sensor Digitall pressed ? digital 13 on или digital 13 off |ж^^маившмммнш Рис. 5.13. Окончательное формирование программы Пора перейти к проверке. Проверка II с модулем Arduino II ЭТО ВАЖНО! Но схеме, приведенной в примерах, кнопка соединяется с выводом питания +5 В. Я бы советовал включить ее несколько иначе. Один конец кнопки подключить к положительному выводу питания через резистор 1 кОм. Второй вывод кнопки соединить
с выводом модуля Arduino, о вывод с землей через резистор 10 кОм. Особенно, если вы проверяете все «на весу». При случайной ошибке может получиться так, как было у меня однажды - из модуля пойдет дымок, который очень портит настроение. Проверив правильность соединений на макетной плате, подключив к ней модуль Arduino, можно включить его в разъем USB компьютера и запустить программу S4A. Обратите внимание — когда вы между цифровым входом и землей включили резистор 10 кОм, показания (в правом окошке программы) перестали случайным образом меняться между «false, ложно» и «true, истинно». Запускаем нашу программу двойным щелчком по элементу «start», добавим, зайдя в раздел основного меню «Редактировать», пошаговое выполнение (рис. 5.14). Рис. 5.14. Добавление пошагового выполнения в отладочную процедуру Можно еще в пункте установить единичный шаг... выбрать скорость выполнения. И теперь, пока кнопка не нажата, мы видим, что светодиод не горит, а программа выполняется только в той части, где это задано. Выполнение программы в пошаговом режиме показано на рис. 5.15. В правом верхнем окошке можно видеть состояние входа Digital 1 — false. Вход на земле, на входе низкий логический уровень, а это, с точки зрения программы, состояние «ложно». Нажмем кнопку (рис. 5.16). Изменилось состояние входа «true», горит светодиод, и программа входит в ту часть, где условие выполнено.
Рис. 5.15. Выполнение программы в режиме отладки Рис. 5.16. Работа программы при нажатой кнопке
всегда, если ) если если ИЯМ ж>а гь до повторять д Рис. 5.17. Гнезда для добавления условий в элементах контроля Если обратить внимание на оранжевые элементы в разделе «контроль», то видно, многие из них имеют «гнезда» для вставки условий (рис. 5.17). Условия могут быть разными. Выше мы использовали в качестве условия изменение состояния цифрового входа. Но это могут быть и другие условия. И еще — обратите внимание на черные стрелочки «вниз» рядом со многими элементами. Нажимаем эту стрелочку с помощью мышки (как показано на рис. 5.18)... ... и получаем возможность менять, например, как в этом случае использовать вход. В других случаях меняется, скажем, выходной вывод или аналоговый вход. У нас большой выбор возможностей для экспериментов с модулем Arduino. Впрочем, отчего с модулем? Мы вправе использовать несколько модулей. Достаточно, не скажу, что это единственный способ, перейти на закладку «костюмы», щелкнуть правой клавишей мышки по существующему «костюму» и выбрать раздел «переключиться к новому объекту». sensor Digital! pressed Digitall pressed Digital? pressed Puc. 5.18. Стрелка, открывающая список возможных сенсоров
Добавление II второго модуля Arduino II Появится еще один модуль Arduino. Если у вас он есть, вы его подключили к USB порту и запрограммировали (о программе для модуля написано выше), то можно, думаю, с ним тоже работать (рис. 5.19). ЭТО ИНТЕРЕСНОЕ Все, что мы делаем в программе S4A, мы делаем, используя язык программирования Scratch. Новичок: А это что за язык? Рис. 5.19. Добавление второго модуля Arduino
ГЛАВА 6 УЧИМСЯ ИСПОЛЬЗОВАТЬ ®язык ПРОГРАММИРОВАНИЯ SCRATCH Конечно, эта глава не имеет прямого отношения к Arduino. Но не сам проект Arduino. Поэтому она и включена в книгу. То, что сегодня кажется лишним, таковым не оказывается равтра! I Примеры программ для S4A Мы использовали программу S4A для работы с модулем Arduino. Но программа позволяет сделать больше. Она помогает научиться программировать (не путать с написанием кода программы на традиционных языках программирования). Для Linux (и для Windows в папке Program Files/S4A/ Projects), если заглянуть в раздел /usr/lib/s4a, то можно увидеть папку проектов (рис. 6.1). Запустим программу, выберем в основном меню раздел «File» и пункт Открыть.... Появится диалоговое окно выбора проекта. Используем клавишу Компьютер, чтобы начать перемещение по файловой системе. Используем движок прокрутки справа (или колесико мышки), чтобы перемещаться вниз, и двойным щелчком левой клавиши мышки будем открывать нужные нам папки (рис. 6.2).
Рис. 6.1. Место расположения учебных проектов S4A Дрйдд до папки S4A, откроем ее, откроем папку «Projects», в кото-ройтоже много папок, но мы используем сейчас первую «Animation», где выберем проект Playground, как показано на рис. 6.3. Рис. 6.2. Менеджер файлов в программе S4A
Рис. 6.3. Содержание папки примеров Можно выбрать другой проект. И я думаю, вам интересно будет посмотреть все предложенные проекты, но для начала разберемся с первым (рис. 6.4). Щелкнув по флажку над правым верхним окошком, вы увидите, как качели начинают качаться. Это работа программы, которая собрана в центральном окошке, и которая начинается с условия «когда щелкнут по флажку». Рис. 6.4. Один из проектов примеров
Рис. 6.5. Расположение примеров в Windows Рис. 6.6. Русскоязычное руководство к Scratch
Пользователи Windows найдут аналогичные примеры по адресу: C:\Program Files\S4A\Projects (рис. 6.5). Новичок: А можно что-то прочитать об этом языке? Да, есть руководство по использованию языка Scratch на русском языке (рис. 6.6), которое можно найти на сайте [5]. Я не вижу смысла пересказывать все руководство в этой книге, но для тех, кто не найдет руководства, я приведу пример. I Начало работы с программой Для соответствия описания, сделанного для программы Scratch, откроем проект в папке «Greetings» с длинным названием «HellowInManyLanguages». Удалим скрипт — щелчок правой клавишей мышки по блоку «когда щелкнут по флажку» программы и «Удалить» из выпадающего меню. Первое, что предлагается сделать в руководстве — перетащить блок «идти» (рис. 6.7). Если сделать двойной щелчок мышкой по этому блоку, котик сдвинется на картинке вправо. Затем из раздела «звук» перетаскиваем новый блок, который соединяем с предыдущим (рис. 6.8). Повторив двойной щелчок по любому блоку, мы услышим звук барабана. Из меню, которое можно найти, нажав на стре- Рис. 6.7. Начало работы с программой
Рис. 6.8. Добавление нужных действий идти © 1 барабану нагг С5 1 (35) Акустическая басовый барабан (36) Басовый барабан 1 (37) Side Stick ,L t (38) Acoustic Snare (39) Хлопок ладоней (40) Электрический малый барабан (41) Низкий напольный tomtom (42) Closed Hi-Hat i (43) Высокий напольный tomtom ' (44) Хэт (педалью) . (45) Низкий tomtom (46) Open Hi-Hat : (47) Низкий средний tomtom i (48) Hi-Mid Tom : (49) Крэш-тарелка1 (50) Высокий tomtom . (51) Райд-тарелка 1 (52) Китайские цимбылы , (53) Райд тарелка (54) Тамбурин (55) Splash Cymbal : (56) Колокольчик ' (57) Крэш-тарелка 2 (58) Вибрирующий слэп (59) Райд-тарелка 2 (60) Hi Bongo (61) Низкий бонго (62) Mute Hi Conga (63) Открытая конга ! (64) Низкая конга (65) Высокий тимбал больше Рис. 6.9. Выбор звука барабана лочку рядом с цифрой 48, можно выбрать другой звук, например, под номером 49 (рис. 6.9).
Добавим к программе еще один элемент «идти». Теперь, выделив цифру 10 внутри блока, заменим ее на -10. И добавим второй блок «играть барабану», заменив барабан. В итоге получим следующую программу (рис. 6.10). идти ф шагев барабану £ИЙ1 играть Дй тактов идти ffpl шагов барабану ДР играть fill тактов Рис. 6.10. Продолжение построения программы Двойной щелчок по любому блоку выполнит собранные команды. Осталось обернуть это в цикл, что и показано на рис. 6.11. Рис. 6.11. «Зацикливание» программы Новичок: А что-то еще можно сделать? Можно добавить смену костюмов (вида) из раздела «внешность». Запустите программу двойным щелчком по любому объекту и получите некоторое удовольствие от проделок этого котика. О, я и не заметил, увлекся, не заметил, как почти все пересказал. Но почти, еще не все. Остальное вы сами...
ПРИМЕЧАНИЕ. Используя язык Scratch, можно научиться программировать. И учиться с удовольствием, просматривая результаты работы сразу после создания программы. Вернемся к схеме с кнопкой и светодиодом Однако вернемся к модулю Arduino. Создавая свою программу, можно ошибиться. Я сейчас приведу такой пример. Вернемся к схеме с кнопкой и светодиодом. Мы можем рассуждать так: светодиод включается, если кнопка нажата, и выключен без нажатой кнопки. Соберем схему так, как показано на рис. 6.12. Рис. 6.12. Один из вариантов программы Запустите программу, нажмите кнопку и посмотрите на модуль. Светодиод не горит. В чем проблема? Что мы сделали не так, как следует? Программа S4A поможет разобраться в этом. Запустив пошаговое выполнение, мы можем убедиться, что при нажатой кнопке мы выполняем команду включения (напомню, раздел «Редактировать» пункт Начать пошаговое выполнение). Пошаговое выполнение показано на рис. 6.13.
Рис. 6.13. Пошаговая проверка программы start всегйЭ : если sensor Digitall pressed ? digital 13 on ждать 0 секунд digital 13 off ждть 0 секун д —Г Рис. 6.14. Изменение программы для отладочных целей Добавим паузы, это поможет разобраться, почему мы не видим включения (рис. 6.14). Вот теперь мы видим светодиод включенным. Когда кнопка нажата, светодиод мигает с интервалом раз в секунду. А, значит, в предыдущей версии он мигает так быстро, что мы не видим этого. То, что мы сейчас проделали, называется отладкой программы. И S4A помогает это сделать быстро, легко и понятно. Посмотрите, как изменится поведение светодиода, если изменить программу следующим образом (рис. 6.15).
Рис. 6.15. Модификация программы ЭТО ВАЖНО! Мы подчас забываем, что процессор модуля Arduino работает очень и очень быстро. И забываем, что одни команды выполняются быстро, а другие команды, работаем ли мы с языком Scratch или Си, для процессора разбиваются на множество команд, требующих на свое выполнение времени. Отладка II программы II Отладка программы позволяет разобраться с возникающими проблемами. Но прежде, чем продолжить рассказ об отладке программ, сделаю еще одно маленькое замечание. Хотя о состоянии цифровых входов можно узнать из сводной таблицы (рядом с изображением модуля), можно, если поставить галочку рядом с названием программного элемента (как отмечено на рис. 6.16), появится отдельное информационное окно, относящееся к цифровому входу.
Рис. 6.16. Вынос состояния цифрового входа ПРИМЕЧАНИЕ. Кроме программы S4A, есть еще одна, VBB, помогающая отлаживать программу, написанную для модуля Arduino. К сожалению, та версия программы, о которой я когда-то рассказывал, не работает в Windows 10. А новая версия прогромммы VirtualBreadBoard для работы с модулем Arduino платная. Поэтому рассказ о программе придется оставить в прошлом. А для тех, кто готов заплатить за программу есть возможность прочитать о ней в книге «С чего начинаются роботы», которую можно найти на моем сайте [17].
ГЛАВА 7 ПОЛЕЗНАЯ ПРОГРАММА FRITZING Часто, разбираясь со своими небольшими проблемами в Интернете, вы можете встретить рисунки, где показана беспаечная макетная плата с конденсаторами и транзисторами-резисторами. Согласитесь, это удобно, когда вы готовитесь к макетированию. Отчего бы вам не воспользоваться этим удобным инструментом? Найти программу Fritzing можно на сайте [5]. Новичок: А это что за программа? Познакомиться с ней помогут примеры. Запустим программу, а дальше в основном меню выполним «Файл —► Открыть —► scetches -> core» (рис. 7.1). Перед тем, как приступить к макетированию схемы, можно проделать это в программе Fritzing. Кроме макетной платы, а вы можете использовать такую плату, которая не требует пайки, кроме нее вы можете посмотреть принципиальную схему (рис. 7.2). И, если вы решите перенести схему с макетной платы на рабочую печатную плату, то можно увидеть, как выглядит печатная плата (рис. 7.3).
Рис. 7.1. Один из примеров, установленных с программой Fritzing Рис. 7.2. Окно электрической схемы
Рис. 7.3. Окно разводки печатной платы программы Fritzing 5k ПРИМЕЧАНИЕ. Такие платы, как платы расширения, легко добавляются к модулю Arduino, в результате вы получаете готовое устройство на базе модуля Arduino. Программа Fritzing поможет сделать дополнение к модулю Arduino. Используя эту программу в дальнейшей работе, мы больше узнаем о ней. А пока, пока пора вернуться к рассказу.
ГЛАВА 8 РЕАЛИЗАЦИЯ ЗАДУМАННОГО В языке Си используют заголовочные файлы, имеющие расширение «.h». В этих файлах находятся объявления функций. То есть, декларация о намерениях. Каждому такому файлу заголовков соответствует файл на языке Си, где находится реализация объявленных функций. В предыдущих главах мы создавали, скорее, заголовочный «файл» проекта. Теперь пора продолжить работу. Что нужно сделать с «паровозиком и семафором» Новичок: А не пора ли сделать что-то реальное, что-то спаять, собрать, не пора ли взять быка за рога? Взять быка за рога — это круто. Но и быки не лыком шиты — могут так наподдать, что мало не покажется. Оставим быков в покое, мы не ковбои, и постараемся без спешки разобраться, что нужно сделать с «паровозиком и семафором». Для начала упростим задачу, отбросив обмен сигналами между ними. Положим, паровозик имеет устройство, которое раз в секунду отправляет инфракрасный сигнал, а семафор имеет
другое устройство, которое постоянно «смотрит» на дорогу. Увидев сигнал паровозика, семафор зажигает зеленый свет на некоторое время, а затем вновь включает красный. Новичок: Да понял я, понял — нам нужно два устройства! И у нас теперь две задачи для двух устройств. Пусть устройство для паровозика будет выполнено на PIC-контроллере. А устройство для семафора мы выполним на модуле Arduino. Новичок: И что это за PIC-контроллер, и зачем он нужен, мы же говорили про Arduino? Это так, но чем ближе к реализации задуманного, тем чаще предстоит задумываться не только о программе, а обо всей конструкции. Чем меньше устройство, тем проще его встроить туда, куда нам нужно. Ведет состав, как мы знаем, паровозик, не так ли? Начнем с паровозика. Устройство «я свой» работает почти так же, как работают пульты управления телевизором, музыкальным центром или DVD-проигрывателем. Оно должно иметь излучатель ИК-сигнала. Для этой цели служит светодиод инфракрасного диапазона. Но мы вначале испытаем красный светодиод АЛ307. Если «дальнобойности» этого излучателя не хватит, испытаем другой светодиод. Пульты управления, работающие с инфракрасными излучателями, отправляют довольно сложные сигналы. При этом пульты разных производителей используют разные стандарты для кода управления. Однако почти все они, за редким исключением, излучают пачки импульсов, прерываемых паузами, на какой-то частоте в диапазоне от 20 кГц до 500 кГц. Используем частоту, ее называют несущей частотой, 36...37 кГц, предпола-
гая, что приемник семафора мы построим с помощью микросхемы TSOP. ПРИМЕЧАНИЕ. Есть такая микросхема, в состав которой входит фотоприемник, фильтр, выпрямитель и компаратор. Когда TSOP не получает сигнала нужной частоты, на его выходе высокий логический уровень. Когда сигнал приходит, на выходе микросхемы низкий логический уровень. Микросхема имеет три вывода: напряжение питания, выход и общий. Ее легко будет подключить к модулю Arduino. Теперь о сигнале, который будет излучать устройство паровозика. Мы не обязаны, как, впрочем, и производители пультов управления, придерживаться какого-либо стандарта. Поэтому используем простой код: импульсы с частотой 36 кГц в течение 4 миллисекунд, пауза 1 миллисекунда, импульсы в течении 1 миллисекунды, пауза 1 миллисекунда, импульсы в течение 2 миллисекунд. Вот и весь сигнал. Для написания кода используем версию программы mikroBasic Lite, которая имеет некоторые ограничения, но для нас сейчас не существенные. Найти эту версию можно на сайте производителя [6]. После запуска программы создадим новый проект (Project -> New Project...). В этом нам поможет помощник (рис. 8.1). Нажимая клавишу Next проходим все этапы создания проекта: задание модели нашего контроллера (PIC16F628A), выбор тактовой частоты, имя проекта и место его хранения и т. д. Сразу после создания проекта я настраиваю микроконтроллер так, чтобы работал внутренний тактовый генератор, а все остальное отключаю (основное меню, Project -> Edit Project, рис. 8.2). Новичок: А обязательно PIC16F628A?
Рис. 8.1. Помощник создания нового проекта в microBasic Рис. 8.2. Окно диалога создания слова конфигурации Нет, конечно. Но для этого микроконтроллера есть перевод на русский язык справочных данных (datasheet). Читать описание микроконтроллера приходится, а начинающим, мне кажется, лучше пользоваться переведенной версией. Итак.
Первое, что мне хотелось бы получить в программе, — генерацию несущей частоты. Сначала рассчитаем период для частоты 36 кГц. Для этого разделим 1/36000, а результат дважды умножим на 1000, чтобы получить ответ в микросекундах. Это около 27 микросекунд. Значит 13 микросекунд — это половина периода. Не мудрствуя лукаво, я открываю в примерах простую программу Blink, которую переделываю для себя. Выглядит она так (но не в сегодняшней версии программы, поэтому ориентируйтесь на рис. 8.3). Оттранслируем программу (Build Build). Полученный hex-файл можно загрузить в микроконтроллер, проверив с помощью осцллографа результат. У меня есть другая возможность, которой я в силу природной лени и воспользуюсь (рис. 8.4). Новичок: У меня нет такой программы, а где ее взять? Рис. 8.3. Рабочее окно программы microBasic
Рис. 8.4. Проверка результата в программе ISIS Рис. 8.5. Изменение программы в microBasic
ПРИМЕЧАНИЕ. Программа ISIS входит в пакет для сквозного проектирования Proteus. В ней особенно удобно проверять работу микроконтроллеров с внешними компонентами. Программа платная. А далеко не у всех есть знакомые, которые после смены программного обеспечения готовы подарить вам купленную программу. Я подозреваю, что им надоели мои появления с просьбой: «Можно я поработаю немного, мне вот...». вГ «а- ' FiU £drt ytew Piomct Build Kun Tools Help Compiled 0x00 PORTB.0 - 0x00 Me-sagelto. iSw ИШе TRUE tor 1 - 0 to 115 i PORTB.0 - 0x01 I Delay_UB{13) ! iPORTB.0 - 0x00 Delay_us(13) delayjma(1) 1 - 0 to 30 PORTB 0 » 0x01 Delayjus(13) PORTB.0 “ 0x00 Delay_us(13) delayms(1) 0x01 Delay_us(13) PORTB.0 = 0x00 Delay_us(13) next 1 delay ms (1000) EjWwrwgs set direction to be output Turn ON diod on PORTB ’ 13 microsecond delay 13 microsecond delay Turn ON diod on PORTB * 13 microsecond delay ' Turn OFF diod on PORTB * 13 microsecond delay Turn ON died on PORTB * 13 microsecond delay * Turn OFF diod on PORTB 13 microsecond delay Endless loop Message leset Used ROM program words): 88 (<%) Free ROM (program words); 1960 (96%) M 0><t i гйжо SuctmOV Pioxrt'toyjenl mbppT'c^i^jtefcedi !ДООШ .Finished «иссек,^/: 2 J. фее 2У11,18? 15:56 Used ROM (progr ar nsyjjenlMbppi
Будем считать, что получили несущую частоту около 36 кГц. Далее, многие предпочитают использовать таймеры и прерывания, но я не вижу в данном случае такой необходимости. Мне нужно вначале рассчитать, сколько раз помещается период несущей частоты в 1 миллисекунде. Разделим 1000 на 27 и получим 37. Теперь мы знаем, что для первой пачки импульсов нам нужно в 4 раза больше, то есть, 148. Добавим цикл for в программу, который отсчитает нам нужное количество периодов несущей частоты (рис. 8.5). Чтобы получить «правильную картинку», я подгоняю нужные значения. Теперь можно сформировать полный сигнал (рис. 8.6). Можно было бы сейчас собрать макет, но наблюдать пачки импульсов на обычном осциллографе, если паузы между посылками импульсов в 1 секунду, достаточно сложно. Поступим иначе. Отложим это до того момента, когда определимся со вторым устройством. О правке II или подгонке параметров II Несколько слов о «подгонке» для получения картинки. В конечном счете, когда устройство отправки кода будет собрано, нас будут интересовать длительности пачек импульсов. ПРИМЕЧАНИЕ. Выполняя определение длительностей на языке высокого уровня, мы можем получить ошибочный результат, если не учтем, что для выполнения операции прохождения цикла процессору потребуется выполнить больше команд, чем нам кажется. Практически все команды языка высокого уровня после трансляции в машинные коды (операции для процессора) рас
падаются на несколько команд. А выполнение каждой из них требует времени. Поэтому общее время прохождения цикла может оказаться больше ожидаемого, а при большом количестве этих циклов... вы уже поняли, о чем я говорю. Так что, программирование устройства излучения кода для паровозика мы отложим до того момента, когда сможем посмотреть полученный результат с помощью фотоприемника, тогда и подправим длительности пачек импульсов окончательно. Как мы уже говорили, в качестве фотоприемника мы используем микросхему TSOP. Рекомендации по подключению микросхемы от производителя на рис. 8.7. Учтем их. APPLICATION CIRCUIT R, and C5 are recommended for protection against EOS. Components should be in the range of 33 О < R1 < 1 kn, C, > 0.1 pF. Puc. 8.7. Рекомендации производителя no подключению фотоприемника TSOP Однако до того как начать работу над устройством приема сигналов, я предлагаю подумать о том, как посмотреть, что приходит с фотоприемником TSOP, используя для этой цели модуль Arduino. Новичок: Я что-то пропустил, пока искал Proteus? TSOP — микросхема, которая видит инфракрасный сигнал несущей частоты и превращает его в импульсы на выходе. Только что об этом говорили. Как Arduino покажет нам импульсы?
Как Arduino покажет II нам импульсы II Об этом я и собираюсь рассказать. Arduino имеет встроенный аналогово-цифровой преобразователь. Как ясно из названия, последний преобразует аналоговый сигнал в цифровые данные. Если аналоговый сигнал — это только постоянное напряжение, то понятно, напряжение переводится (каким-то образом) в число. А когда аналоговый сигнал меняется? Новичок: Аналогово-цифровой преобразователь делает как бы мгновенные снимки сигнала, то есть, в какой-то момент времени «прочитывает» его, как если бы это было постоянное напряжение. Последовательность таких «снимков» дает последовательность цифровых данных. Да! Программа на компьютере (или какой-то графический дисплей) может эти данные выводить в виде графика, подобно тому, как мы строим график кривой по точкам. В результате мы получим вид сигнала в таком виде, какой увидели бы на экране осциллографа. Мы используем компьютер и модуль Arduino в качестве осциллографа, чтобы посмотреть вид получаемого сигнала от фотоприемника (когда, конечно, спаяем и запрограммируем передатчик!). Выбираем II «осциллограф» II Новичок: А можно написать самостоятельно программу для получения данных от модуля Arduino и построения кривой? Думаю, что это очень интересная и полезная задача для освоения программирования. Можно! Но я планирую воспользоваться тем, что уже написано, что предназначено для работы с Arduino. Есть ряд гото
вых решений, из которых я выбираю одно под названием oscilloscope [7]. Код, загружаемый в модуль Arduino, можно скопировать на странице форума. Он невелик. //oscilloscope //http://compcar.ru byte MyBuff [800]; unsigned int i=0; void setup() { Serial.begin(115200) ; } void loop() { for (i=0; i < 800; i++) { MyBuff [i] = analogRead(O)/4; } Serial.write(MyBuff,800); } Программа для компьютера, oscilloscope.exe, не требует установки. Ее можно расположить, например, в своей папке, сделать ярлык на рабочем столе и запускать, подключив запрограммированный модуль Arduino. У модуля используется аналоговый вход АО. Есть некоторые ограничения: напряжение Рис. 8.8. Работа одной из программ осциллографа на базе модуля Arduino
на входе должно находиться в диапазоне 0...5 В, не больше; и напряжение не должно быть отрицательным; верхняя рабочая частота, обозначенная автором программ, 4 кГц. Этого должно хватить для многих экспериментов. Вот как выглядит сигнал на мониторе, если коснуться рукой входа осциллографа (рис. 8.8). Это наводки с частотой 50 Гц. Думаю, что для чтения сигнала с фотоприемника этого осциллографа будет достаточно. Рисуем необходимые подключения для проведения экспериментов Пришла пора спаять передатчик ИК кода, добавить фотоприемник к осциллографу и посмотреть результат. Если понадобится, то подогнать длительность фрагментов полученного сигнала. Перед пайкой воспользуемся программой Fritzing, чтобы нарисовать необходимые подключения для проведения экспериментов и для последующей работы с паяльником. Новичок: Я смотрел, в программе Fritzing нет микросхемы TSOP. Какой от нее прок? Это неприятно, но не страшно — мы добавим нужное сами. Для рисования, а понадобится нарисовать микросхему, используем графический редактор Inkscape. Сам я — не художник я — признаюсь, чаще использую простейший графический редактор как Paint в Windows. Иногда использую Gimp (это аналог Photoshop). Все эти графические редакторы работают как в Linux, так и в Windows. Но они, если я не ошибаюсь, не поддерживают формат svg векторной графики, a Inkscape для векторной графики и предназначен. Редактор тоже есть в версии для Windows, а скачать его можно на сайте [8]. Для создания рисунка в векторном графическом редакторе я считаю, что лучше всего использовать прототип, есть подхо-
Рис. 8.9. Рисунок элемента регулятора напряжения дящий — voltage_regulator. Рисунок можно найти в папке программы Fritzing по адресу, показанному на рис. 8.9. Открыв этот файл в Inkscape, преобразуем его во что-то похожее на TSOP. Можно воспользоваться рекомендациями, которые даются на сайте программы Fritzing, попасть туда можно из раздела «Помощь» основного меню (программы Fritzing!), где есть пункт Онлайн-руководство. ПРИМЕЧАНИЕ. Когда web-браузер откроет страницу руководства, то можно найти главу, которая называется «Creating Custom Parts». В зтой главе подробно описывается, как создать свой элемент.
Рис. 8.10. Раздел редактирования элемента в программе Fritzing Следуя Советам, запускаем Fritzing, выбираем стабилизатор напряжения 7805 (в качестве прототипа), переносим его на макетную плату и заходим в раздел редактирования (рис. 8.10). Как и написано в руководстве, щелкаем по заголовку, где меняем voltage_regulator на TSOP173x (рис. 8.11). Далее переходим к редактированию графики. Советую следовать всем рекомендациям руководства, конечно, если вся эта работа вам интересна. Я же только обозначу то, что делаю. Рис. 8.11. Настройка рисунков для добавления нового элемента
Рис. 8.12. Создание нового рисунка в программе Inkscape Загружаю в Inkscape рисунок стабилизатора из того места, о котором шла речь выше. В папке user программы Fritzing перед этим я создаю пустые папки с именами, которые видел в папке core. Далее, разгруппировав рисунок, удаляю ненужное, перемещаю, растягиваю и дорисовываю, используя средства графического редактора, все необходимое, чтобы получить свой рисунок. Последнее, что я делаю — группирую объект, выделив его (Объект —► сгруппировать). Сохраняю его в пользовательской папке как простой (есть такой формат) svg рисунок с именем tsop_breadboard.svg (рис. 8.12). Открываю файл иконки стабилизатора напряжения. Выделяю и удаляю все. Второе окно графического редактора я не закрывал, поэтому выделяю картинку, щелкнув по ней, копирую и вставляю в качестве иконки. Сохранив эти файлы, я могу использовать их при загрузке изображений в редакторе компонентов Fritzing. Остается подправить и сохранить файл schematic. СОВЕТ. Не следует менять соединения, достаточно исправить имена, но при желании можно переделать все полностью^какэто описано в руководстве.
Рис. 8.13. Появление нового элемента на закладке Mine Теперь я готов заменить все изображения и сохранить объект как новый. При выходе из программы Fritzingn отказываюсь от сохранения проекта, но соглашаюсь сохранить новый объект. При следующем запуске программы Fritzing на закладке «Mine» появляется новый элемент (рис. 8.13). И ничто уже не мешает нарисовать схему эксперимента по чтению кода с устройства передачи ИК-команды, используя программу осциллографа и аналоговые возможности модуля Arduino. Итак, вот вид эксперимента (рис. 8.14). Электрическая схема Так выглядит электрическая схема (рис. 8.15). А так может выглядеть печатная плата (хотя в данном случае она совсем лишняя сущность, рис. 8.16).
Рис. 8.14. Подготовка соединений для эксперимента Рис. 8.15. Электрическая схема соединений модуля с фотоприемником
Рис. 8.16. Возможный вид печатной платы расширения модуля Arduino Вместе с тем я рад, что потратил некоторое время на подготовку к эксперименту. Новичок: Если электрическая схема простая, а печатная плата не нужна, то зачем тратить время? Чтобы в следующий раз, когда схема будет сложнее, иметь опыт работы с программой Fritzing. Работая над проектом удобно использовать рабочую тетрадь (электронную или обычную), куда записывать все, и куда можно добавить рисунок, полученный в программе Fritzing. Позже это, как и комментарии в программе, будет очень полезно. Еще один «осциллограф» - II программа xoscillo | Так вот, пока я занимался с программой Fritzing, я понял, что используя программу осциллографа, о которой писал
раньше, я попаду в ситуацию такую же, что и с обычным осциллографом: короткие пачки импульсов кода и длинная пауза между ними. Новичок: Увидеть, а особенно разглядеть что-то, будет, мне кажется, невозможно. Что же делать? Когда я просматривал использование модуля Arduino в качестве осциллографа, я видел еще одну программу. От ее применения меня отвратило то, что файл для загрузки в модуль был не в формате языка Arduino, а был hex-файлом. То есть, файлом, предназначенным для загрузки с помощью программатора. Программа называется xoscillo [9]. Но если раньше я отверг эту программу, то теперь ситуация изменилась — программа, возможно, решит проблему, без чего нет смысла проводить эксперимент. Прочитав все, что сказано о работе программы и подготовке к ее реализации на модуле Arduino, я скачал программу и hex-файл, загружаемый в модуль. ПРИМЕЧАНИЕ. Все оказалось не так сложно, как это воображаешь, когда читаешь описание того, что нужно сделать. Хотя и там есть некоторые детали, которые приходится менять. В корневой директории диска С:\ у меня есть копия программы Arduino. Она лежит в папке с именем arduino. В корневую же директорию я копирую файл arduinooscillo.cpp.hex. На сайте xoscillo есть даже команда (ее следует ввести после запуска в Windows командной строки), ее можно скопировать и вставить в окно командной строки. Но приходится внести некоторые изменения (включая то, что виртуальный СОМ-порт для работы через USB у меня С0М5):
с:\arduino\arduino-0022\hardware\tools\avr\bin\ avrdude -с stk500vl -р ml68 -Р сот5 -Ь 19200 -U flash:w:c:\arduinooscillo.cpp.hex:i -С c:\arduino\ arduino-0 02 2\hardware\tools\avr\etc\avrdude.conf Какие изменения я вносил в команду, скопированную с сайта? Конечно, я изменил путь к файлу avrdude, убрал перед этим файлом в команде все, что было до папки bin. Кроме этого я добавил после hex-файла опцию «:i» и указал полный путь к файлу конфигурации avrdude. После этого команда полностью выполняется и не дает ошибок, которые я получал, пытаясь использовать команду с сайта. И, конечно, модуль Arduino я подключил до выполнения команды (рис. 8.17). Рис. 8.17. Выполнение команды в командной строке для загрузки hex-файла Сама программа xoscillo лежит у меня на рабочем столе в папке с этим же именем. Открыв эту папку, я запускаю программу обычным образом. В разделе «File» основного меню выбираю «New Arduino» (рис. 8.18). И через некоторое время появляется окно (рис. 8.19). У модуля Arduino, подготовленного мною к предыдущим опытам, есть вывод от аналогового входа АО. Коснувшись его рукой, я получаю картину наводок (рис. 8.20). Когда я убираю руку от вывода, картинка замирает. Теперь я могу сохранить изображение экрана осциллографа: «File ->
Рис. 8.18. Запуск программы осциллографа Рис. 8.19. Подключение программы к модулю Arduino Save as...», имя и место сохранения я ввожу сам. Позже я могу, запустив программу, открыть этот файл и еще раз внимательно рассмотреть получившуюся диаграмму. Пока я не вполне освоился, и для выхода из программы я нажимаю обычный значок «закрыть» и еще раз касаюсь рукой вывода аналогового входа. Программа закрывается. Я вновь открываю программу, но в этот раз загружаю файл, который перед этим сохранил. Да, я могу его просмотреть еще раз. Я
Рис. 8.20. Вид наводок на экране осциллографа на базе модуля Arduino Рис. 8.21. Выпадающий список времени отсчета могу изменить, выбрав новый интервал времени деления (рис. 8.21). Полагаю, эта программа будет удобнее, и она позволит мне провести нужный эксперимент, чтобы увидеть на выходе фотоприемника сигнал, передаваемый устройством излучения ИК-кода. Новичок: Если эта программа удобнее, то зачем нужно было возиться с первой программой?
Да, я потратил некоторое время на работу с первой программой осциллографа. Это так. Но она проще и позволяет наблюдать периодические сигналы, что тоже может понадобиться. И я потратил некоторое время, разбираясь с тем, как использовать вторую программу виртуального осциллографа, но она решает мои проблемы. Более того, открою еще одну тайну. ПРИМЕЧАНИЕ. Используя метод записи в Arduino hex-файла для осциллографа, вы (и я за компанию) можете создать такой файл, например, в программе AVRStudio, а загрузить в модуль Arduino с помощью утилиты avrdude. Будет ли виртуальный осциллограф работать в Linux? И еще одно, что осталось для меня интересным — будет ли этот осциллограф работать в Linux? На сайте проекта мое внимание привлекло то, что программа работает и в Windows, и в Linux. С примечанием об использовании Mono. И впрямь, программа работает. И, что более всего приятно, что все просто. В ALTLinux 5.1 и Fedora 14 Mono оказалось установлено со всеми необходимыми библиотеками и приложениями. Достаточно было использовать команду: mono /home/vladimir/Xoscillo/XOscillo.exe Программа xoscillo у меня в домашней папке. Создав команду запуска (в Windows ярлык), можно запустить осциллограф, получить осциллограмму, сохранить ее и рассмотреть при следующем запуске xoscillo (рис. 8.22). В openSUSE прошло не так гладко — я попытался загрузить только ядро Mono, но этого не хватило для работы осцилло-
Рис. 8.22. Работа программы осциллографа в дистрибутиве Fedora 14 графа, поэтому, не хватило и у меня терпения, я установил mono-complete, объем, конечно, больше, но загрузка решает все проблемы. Новичок: У меня Windows, и про Linux мне не очень интересно, не лучше ли продолжить? Хорошо. Что осталось сделать? Спаять, запрограммировать PIC-контроллер и проверить ИК-код. Рис. 8.23. Работа программы осциллографа в openSUSE
Перед программированием PIC-контроллера, поскольку я использую макетную плату, оставшуюся от предыдущих экспериментов, где установлена панелька для микросхемы, и где есть светодиод, транзистор и резистор, мне проще заменить в программе вывод ВО на АО, как это сделано на макете... Макетная плата передатчика ИК-кода готова. Красный светодиод АЛ307, который я использую при прямом токе 40 мА (средний за период ток меньше), раз в секунду мигает. К модулю Arduino подключен фотоприемник, выход которого соединен с аналоговым входом АО. Запускаем программу осциллографа, для проверки я делаю это в Windows и в openSUSE, и наблюдаем сигнал. ПРИМЕЧАНИЕ. Кстати, используя обычный светодиод, я заинтересован в определении расстояния, с которого сигнал «видит» фотоприемник. Сейчас это при-мерно 10... 15 см. Если дальности не хватит, можно будет разбить сопротивление, последовательно установленное со светодиодом, на два, сумма сопротивлений которых равна первоначальному, и одно из сопротивлений зашунтировать конденсатором. Это увеличит дальность считывания сигнала (вернее, увеличит «дальнобойность» светодиода за счет того, что появится короткий импульс большего тока). Работа фотоприемника отображена на рис. 8.23. ЭТО ВАЖНО! Напомню, что фотоприемник TSOPe отсутствии несущей частоты на выходе поддерживает высокий уровень, а при наличии несущей переходит в состояние низкого логического уровня.
Осциллограмма похожа на то, что я ожидал бы, если бы не два момента: ♦ я не вижу первой пачки импульсов; ♦ времена вдвое меньше ожидаемых. Новичок: Я могу предположить, что осциллограф запускается несколько позже, чем при приходе первой пачки импульсов. Так ли это? Ответ я могу получить, изменив программу излучения так, чтобы интервалы между кодами были меньше, не 1 секунда, а, скажем, 10 миллисекунд. Посмотрим, как выглядит такой вариант (рис. 8.24). Рис. 8.24. Проверка приема пачек импульсов сигнала фотоприемником Теперь все пачки импульсов на месте, а времена... я не калибровал осциллограф Xoscill. Можно, конечно, это сделать сейчас, но можно отложить до того времени, когда возникнут проблемы с работой приемного устройства. Если они возникнут.
ГЛАВА 9 С ЧЕГО НАЧИНАЮТСЯ РОБОТЫ? Сегодня обсуждается не вопрос: «Нужны ли нам роботы?». Сегдня обсуждается вопрос: «Будем ли мы нужны роботам?». Тем не менее, сегодня роботы широко применяются на производстве, появляются в быту. И для знакомства с ними нужно с чего-то начинать. Продолжаем реализацию проекта Пришло время написать программу для семафора, который будет работать под управлением модуля Arduino. Новичок: Давно пора, я уже заждался. Все хорошо, но мне интересно сделать то, что я хотел сделать. Начнем? Начнем. Как должна работать программа? В самом общем виде: если семафор «видит» ИК-код, он включает зеленый свет, который выключает через несколько секунд, включая красный. Видеть ИК-код семафор будет с помощью фотоприемника TSOP. Но не просто видеть какой-либо инфракрасный сигнал, а
«прочитывать» придуманный нами код. Если код совпадает, то семафор переключается. У осциллографа мы подключали фотоприемник к аналоговому входу. Но на выходе фотоприемника сигнал, который удобно читать цифровым входом. ПРИМЕЧАНИЕ. Как вы помните, а если забыли, то посмотрите программу еще раз, похожую работу выполняет программа для модуля Arduino, которая называется «Button, кнопка». Мы вполне можем себе представить работу фотоприемника, как работу кнопки, которую нажимают на определенные промежутки времени. Поэтому, взяв программу за основу, мы модифицируем ее. Вот эта программа на языке Arduino. // set pin numbers: const int buttonPin = 2; // номер вывода подключенной кнопки const int ledPin = 13; // номер вывода светодиода // variables will change: int buttonstate - 0; // переменная для чтения состояния кнопки void setup() { // инициализация вывода светодиода как выход pinMode(ledPin, OUTPUT); // инициализация вывода кнопки как вход pinMode(buttonPin, INPUT); } void loop(){ // читаем состояние кнопки как значение buttonstate = digitalRead(buttonPin); // проверяем, нажата ли кнопка // если да, то buttonstate имеет значение HIGH:
if (buttonstate == HIGH) { // включаем LED digitalWrite(ledPin, HIGH); } else { // выключаем LED digitalWrite(ledPin, LOW); } } В первую очередь изменим задание выводов. // установка выводов const int photoPin = 2; // номер вывода, к которому подключен фотоприемник const int ledPinGreen = 13; // номер вывода зеленого светодиода const int ledPinRed = 12; // номер вывода красного светодиода Зададим переменную для приема состояния цифрового входа D2. // переменная для хранения состояния входа int photoState = HIGH; // переменная для чтения состояния фотоприемника В разделе инициализации запишем: void setup () { // инициализируем выходы для светодиодов pinMode(ledPinGreen, OUTPUT); pinMode(ledPinRed, OUTPUT); // инициализируем вход для фотоприемника pinMode(photoPin, INPUT); } Основная программа будет похожа на оригинал — мы постоянно читаем состояние входа, а когда вход переходит в состояние с низким логическим уровнем, мы будем «прочитывать сигнал».
void loop(){ // включаем красный свет digitalWrite(ledPinRed, HIGH); // читаем состояние входа photoState - digitalRead(photoPin); // проверяем есть ли пачка импульсов // если есть, то photoState становится LOW if (photoState == LOW) { // начинаем читать код и переключать светодиоды, есл-и код «свой» } Новичок: А как мы будем читать сигнал? Мы получили переход на цифровом входе в низкое состояние, а с правильным сигналом это состояние продлится 4 мс. Затем последует пауза (нет несущей частоты), когда вход перейдет в высокое состояние. Пауза длится 1 мс. Для проверки нашего кода достаточно сделать паузу в 4,5 мс и проверить, перешел ли вход в высокое состояние? Затем будем проверять состояние, стараясь попадать в «середину» состояний после переходов (нашего кода), если это не так, то возвращаемся в начало программы. if (photoState -- LOW) { // начинаем читать код и переключать светодиоды, // если код «свой» delayMicroseconds(4500); // ждем 4.5 мС photoState = digitalRead(photoPin); if (photoState == HIGH){ delay(1); // ждем 1 мС photoState - digitalRead(photoPin); if (photoState == LOW){ delay(1); // ждем 1 мС photoState = digitalRead(photoPin); if (photoState == HIGH){ delay (1); // ждем 1 мС photoState = digitalRead(photoPin); if (photoState == LOW){ delayMicroseconds(3500);
/I ждем 3.5 мС if (photoState -- HIGH){ digitalWrite(ledPinRed, LOW) ; // выключаем красный digitalWrite(ledPinGreen, HIGH); //включаем зеленый delay(2000); // зеленый 2 секунды digitalWrite(ledPinGreen, LOW); //выключаем зеленый } } ) } } }// иначе ничего не делаем И теперь соберем всю программу вместе (в тексте программы есть ошибка, о которой мы поговорим позже!). // установка выводов const int photoPin = 2; // номер вывода, к которому // подключен фотоприемник const int ledPinGreen = 13; // номер вывода зеленого светодиода const int ledPinRed = 12; // номер вывода красного светодиода int photoState = HIGH; // переменная для чтения // состояния фотоприемника void setup() { // инициализируем выходы для светодиодов pinMode(ledPinGreen, OUTPUT); pinMode(ledPinRed, OUTPUT); // инициализируем вход для фотоприемника pinMode(photoPin, INPUT); } void loop(){ // включаем красный свет digitalWrite(ledPinRed, HIGH);
// читаем состояние входа photoState = digitalRead(photoPin); // проверяе, есть ли пачка импульсов // если есть, то photoState становится LOW if (photoState == LOW) { // начинаем читать код и переключать // светодиоды, если код «свой» delayMiегоseconds(4500); // ждем 4.5 мС photoState = digitalRead(photoPin); if (photoState == HIGH){ delay(1); // ждем 1 мС photoState - digitalRead(photoPin); if (photoState == LOW){ delay(1); // ждем 1 мС photoState = digitalRead(photoPin); if (photoState == HIGH){ delay(1); It ждем 1 мС photoState = digitalRead(photoPin); if (photoState == LOW){ delayMicroseconds(3500); // ждем 3.5 мС if (photoState == HIGH){ digitalWrite(ledPinRed, LOW); // выключаем красный digitalWrite(ledPinGreen, HIGH); //включаем зеленый delay(2000); // зеленый 2 секунды digitalWrite(ledPinGreen, LOW); //выключаем зеленый digitalWrite(ledPinRed, HIGH); // включаем красный } } } } } } // иначе ничего не делаем }
I Проверка программы на макете Для проверки работы программы используем макет. Генератора, способного формировать нужный сигнал, который имитировал бы работу фотоприемника, я не надеюсь найти, но хочу использовать в качестве такого генератора обычную кнопку. А для отладочных операций, кроме светодиодов семафора, я добавлю (и в программу, и на макетную плату) еще один светодиод. В результате макет выглядит следующим образом (рис. 9.1). Светодиоды семосрора Кнопка Рис. 9.1. Подготовка к проверке программы на макете В программу добавлена строка в раздел определения переменных и констант: const int ledPinDebug = 11; // отладочный светодиод И в начале основного цикла: digitalWrite(ledPinDebug, LOW); А в качестве первого шага проверки я добавляю в программу, проверяя вход расшифровки ИК-кода, несколько строк:
if (photoState -- LOW) { delayMicroseconds(4500) ; digitalWrite(ledPinDebug, HIGH); // первый тест } Запустив программу, щелкнем несколько раз кнопкой, чтобы убедиться, что при низком логическом уровне на цифровом входе мы попадаем в блок программы расшифровки кода (рис. 9.2). Рис. 9.2. Первая проверка программы Удалив строку проверки (закомментировав ее), скопируем ее в следующую проверку состояния цифрового входа: поскольку мы не успеем щелкнуть кнопкой, отладочный светодиод не должен загораться. Запустив программу, щелкая кнопкой несколько раз, убедимся, что это так. ПРИМЕЧАНИЕ. К сожалению, таких отладочных средств, как точка останова и пошаговое прохождение программы, мы лишены. Но можно проявить выдумку?! \______________________________________________
Рис. 9.3. Модификация эксперимента Добавим еще один светодиод на следующий выход. Добавим паузы по 3 секунды после каждого тестового включения светодиода отладки (или светодиодов). После этой хитрости можно успеть пощелкать кнопкой после каждого изменения состояния отладочных светодиодов, и можно проверить расшифровку кода (конечно, только логику работы программы) до самого конца (рис. 9.3). I Отладочная программа Отладочная программа выглядит так: const int photoPin = 2; const int ledPinGreen - 13;, const int ledPinRed = 12; const int ledPinDebugl =11; // отладочный светодиод 1 const int ledPinDebug2 = 10; // отладочный светодиод 2 int photoState = HIGH;
void setup() { pinMode(ledPinGreen, OUTPUT); pinMode(ledPinRed, OUTPUT); pinMode(ledPinDebug1, OUTPUT); pinMode(ledPinDebug2, OUTPUT); pinMode(photoPin, INPUT); void loop(){ . digitalWrite(ledPinRed, HIGH); digitalWrite(ledPinDebugl, LOW); digitalWrite(ledPinDebug2, LOW); photoState = digitalRead(photoPin); if (photoState == LOW) { delayMicroseconds(4500) ; digitalWrite(ledPinDebugl, HIGH); // первый тест delay(3000); photoState = digitalRead(photoPin); if (photoState == HIGH){ delay(1); digitalWrite(ledPinDebugl, LOW); // второй тест delay(3000); photoState = digitalRead(photoPin); if (photoState =- LOW){ delay(1) ; digitalWrite(ledPinDebug2, HIGH); // третий тест delay(3000); photoState - digitalRead(photoPin); if (photoState == HIGH){ delay(1) ; digitalWrite(ledPinDebug2, LOW); // четвертый тест delay(3000); photoState = digitalRead(photoPin); if (photoState == LOW){ delayMicroseconds(3500) ; digitalWrite(ledPinDebugl, HIGH); // пятый тест
digitalWrite(ledPinDebug2, HIGH); delay(3000); photoState = digitalRead(photoPin); if (photoState == HIGH){ digitalWrite(ledPinRed, LOW); digitalWrite(ledPinGreen, HIGH); delay(5000) ; digitalWrite(ledPinGreen, LOW); digitalWrite(ledPinRed, HIGH); // включаем красный } } } } } } } } Места проверки я выделил, чтобы было понятно, как должны вести себя отладочные светодиоды. Что ж, все что можно было проверить как за компьютером, так и на макете прототипов проверено! Настал момент, когда пора проверить совместную работу «живых» устройств на макетных платах. Тем более, что были сомнения относительно времен посылок кода. Загрузив программу в модуль Arduino (рис. 9.4), я включаю оба устройства и... и... и ничего интересного не вижу. Что-то, где-то не так. Новичок: Как проверить, где ошибка или неточность? Попробуем повторить отладку. Но, чтобы не делать лишних соединений, не добавлять отладочные светодиоды, используем тот светодиод, что уже стоит на плате модуля Arduino. Он на 13 цифровом выводе, который я использую для включения зеленого света. Поскольку программа не работает должным образом, это светодиод не загорается. Для начала я добавлю строку отладки в исходный текст при начале расшифровки кода:
Рис. 9.4. Загрузка программы в модуль Arduino if (photoState == LOW) { // начинаем читать код и переключать светодиоды, // если код «свой» delayMiегоseconds(4500); // ждем 4.5 мС digitalWrite(ledPinGreen, HIGH); photoState = digitalRead(photoPin); } Загружаем программу и, поднося излучатель ИК-кода к фотоприемнику, убеждаемся, что светодиод «зеленый свет» загорается. Скопируем эту строку, закомментируем ее в этом месте и вставим в следующую проверку.
Так, перемещаясь по программе вниз, доходим до того места, где появилась ошибка. if (photoState -= LOW){ delayMicroseconds(3500); // ждем 3.5 мС Место ошибки!!!! Нужно добавить: photoState = digitalRead(photoPin); if (photoState -- HIGH){ digitalWrite(ledPinRed, LOW); // выключаем красный digitalWrite(ledPinGreen, HIGH); //включаем зеленый delay(2000); // зеленый 2 секунды digitalWrite(ledPinGreen, LOW); //выключаем зеленый digitalWrite(ledPinRed, HIGH); // включаем красный } } Перед последней проверкой не было команды проверки состояния входа! И, следовательно, последняя проверка if (photoState == HIGH) не подтвердила код (рис. 9.5). Добавляем утерянную строку й проверяем, загрузив правильный текст программы в модуль, окончательную работу программы. Зеленый светодиод загорается, когда к фотоприемнику подносится излучатель ИК-кода, и гаснет через 5 секунд, что я выбрал в качестве паузы между переключениями семафора. Вот полный и правильный текст программы. // установка выводов const int photoPin - 2; // номер вывода, к которому подключен фотоприемник const int ledPinGreen - 13; // номер вывода зеленого светодиода const int ledPinRed = 12; // номер вывода красного светодиода int photoState - HIGH; // переменная для чтения состояния фотоприемника void setup() {
(photoState == HIGH){ delay(1); // ждем 1 мС digitalWrite(ledPinGreen, HIGH); photoState = digitalRead(photoPin); if (photoState =«• LOW) { delay(l); // ждем 1 мС digitalWrite(ledPinGreen, HIGH); photoState = digitalRead(photoPin); if (photoState «« HIGH)( delay(l); // ждем 1 мс digitalWrite(ledPinGreen, HIGH); photoState digitalRead(photoPin); if (photoState == LOW){ delayMicroseconds(3500); // ждём 3.5 мС ^,.^д.д.1Ха1.Ых.д.г.л..(..1.дхД,Рд1Г|Д>г.йяп.».HIGH)..;..... Г ^>hotoState = digitalRead(photoPin); J jTT^tdSratT^H^-------------------------------------- digitalWrite(ledPinRed, LOW); // выключаем красны? digitalWrite (ledPinGreen, HIGH);//включаем зелёны; delay(ZOOO); // зеленый 2 секунды digitalWrite(ledPinGreen, LOW);//выключаем зелены Рис. 9.5. Отладка (выделена пропущенная команда) в программе Arduino last_tes j Arduino File Edit Sketch Tools Help ®@ №20131 delayMicroseconds(4500); // ждем 4.5 мС digitalWrite(ledPinGreen, HIGH); photoState = digitalPead(photoPin); if // инициализируем выходы для светодиодов pinMode(ledPinGreen, OUTPUT); pinMode(ledPinRed, OUTPUT); // инициализируем вход для фотоприемника pinMode(photoPin, INPUT); } void loop(){ // включаем красный свет digitalWrite(ledPinRed, HIGH); // читаем состояние входа photoState = digitalRead(photoPin) ; // проверяем, есть ли пачка импульсов // если есть, то photoState становится LOW if (photoState == LOW) {
// начинаем читать код и переключать светодиоды, // если код «свой» delayMicroseconds(4500); // ждем 4.5 мС photoState = digitalRead(photoPin); if (photoState == HIGH){ delay(1); // ждем 1 мС photoState = digitalRead(photoPin); if (photoState == LOW){ delay(1); // ждем 1 мС photoState - digitalRead(photoPin); if (photoState == HIGH){ delay (1); // ждем 1 мС photoState = digitalRead(photoPin); if (photoState == LOW){ delayMicroseconds(3500); // ждем 3.5 мС photoState = digitalRead(photoPin); if (photoState -- HIGH){ // выключаем красный digitalWrite(ledPinRed, LOW); //включаем зеленый digitalWrite(ledPinGreen, HIGH); delay(2000); // зеленый 2 секунды digitalWrite(ledPinGreen, LOW); //выключаем зеленый digitalWrite(ledPinRed, HIGH); //включаем красный } } } } } } // иначе ничего не делаем }
Arduino и роботы Новичок: А почему глава называется про роботов? Прежде, чем робот сделает первое движение, вы должны сделать первые шаги в освоении этой техники. Вот вы и сделали эти шаги, если прочитали все предыдущие главы, повторили всё, о чем в них написано. Если ваши устройства для паровозика и семафора заработали, то вы можете модифицировать описанные ранее программы так, чтобы паровозик «видел» семафор — добавьте к нему фотоприемник TSOP — заставьте семафор отправлять сигнал паровозику о том, что горит красный свет. Паровозик, принимая сигнал, пусть отправит сигнал «я свой», а семафор, получив его, включит зеленый свет. Вы можете добавить реле (включив его через транзистор к устройству в паровозике), которое будет отключать двигатель паровозика, получив сигнал от семафора, что горит красный свет, а «увидев» зеленый, включало бы двигатель. И вы получите первый робот-паровозик. Для паровозика можно использовать Arduino Nano, модуль меньше по размерам, его легче встроить в готовую игрушку. Впрочем, оставим паровозик. Что нам мешает собранные и проверенные модули применить иначе. Например, если у вас есть тележка с электрическим моторчиком, умеющая поворачивать, то... Установим на эту тележку модуль Arduino. Он будет принимать тот ИК-код, который мы проверили. А модуль излучения ИК-кода мы модифицируем следующим образом: вместо одного светодиода (АЛ307А) включим две гирлянды из светодиодов. Если использовать напряжение 12 В, то можно включить в гирлянду 8-9 светодиодов. И ничто не мешает сделать не две, а скажем четыре гирлянды, подключив все транзисторы к одному выходу микроконтроллера. Новичок: И зачем эта новогодняя елка?
Выложим гирляндами периметр в виде прямоугольника. Внутрь поместим тележку-робота, которую запрограммируем так, чтобы, получив сигнал от излучателя, она останавливалась, отъезжала назад, поворачивала и вновь пыталась проехать к «ограде». Если мы оставим в ограде ворота, то получим робота, который должен найти выход из «загона». Экспериментируя с «дальнобойностью» излучателей, скоростью движения робота-тележки, вы наработаете некоторый материал, который поможет создавать более сложные устройства. Сегодня и в Интернете, и в магазинах можно поискать и найти многое (рис. 9.6), что позволит собрать робота. Есть Рис. 9.6. Компоненты для создания роботов в Интернет-магазине
Ф х Мобильные роботы / Чип и Дип электронные компоненты и приборы Моайа Hrefox .* * Файл Правка §ид Журнал Закладки Инструмен гы справка w •- v Ф Ba# ' й' bt^jtfwwwdapdip.n4/catrto9MiowAnobite-robotsaspx I *§] Most Visited1* j^Sn'art flookmaiks’* ggfedora Projectv gflRed'^t * Contentv <; ASPlmux j^ASPUnux CM> ^iRedHat enyft j|f edore’unwn Rombfer 44 V ( ~7 ~________ J ; : ^найти NT j Погода ; Аудио «Vision ’(Вход & ' ? .Hiii *** J w v ч vgoloiobov v dej V ir vOv r v Л VO V V:| ;A <Ян.Д*К.2 ......2... кК .Жмобиль^е роботы7ЧИП и Д ТТ+ V КНЯО АатоиоД>ым> на топливной KNS11 АвтоиоСилв не топливной KSR1 Набор "РоРот-автомобиль* KSR3 Набор "Робог липтшка" *! адаманта адаманта Рис. 9.7. Готовые модули и блоки в радиомагазине много таких полезных датчиков, как ультразвуковой датчик расстояния; исполнительных механизмов, таких как сервомоторы и т. д. Есть достаточно много заготовок, которые можно использовать в роботостроении. Вот, например, что можно найти в магазине (рис. 9.7).
ГЛАВА 10 ЕЩЕ РАЗ ПРО «ОСЦИЛЛОГРАФ», ЕСЛИ НЕ НАДОЕЛО С модулем Arduino можно проделать множество интересных экспериментов, не пользуясь приборами. Но мы уже столкнулись с необходимостью увидеть сигналы. Чем больше мы будем работать с Arduino, тем дальше нам потребуется выходить за «околицу» проекта Arduino. Так что, пойдем?! Расширение возможностей К тем экспериментам, которые вы проделаете с модулем Arduino, я хочу добавить еще один. Причин несколько. Во-первых, не будет лишним еще раз потренироваться, в программировании. Во-вторых, может быть, я этого не исключаю, вам пригодится это в работе с макетами. Наконец, полезно знать, как это устроено. Новичок: А это обязательно? Конечно, нет. Однако за первым устройством последуют другие, и рано или поздно все, что написано в этой главе может пригодиться.
ПРИМЕЧАНИЕ. Повторюсь, встроенный в Arduino аналого-цифровой преобразователь (АЦП) позволяет измерить постоянное напряжение от 0 до 5 В. Если на вход АЦП подать синусоидальный сигнал (с учетом допустимого напряжения), если через равные промежутки времени АЦП будет измерять значение напряжения, то полученные данные мы можем изобразить на листке бумаги. По оси х отложим равные интервалы, а полученные значения изобразим вертикальными отрезками прямой. Если теперь соединить концы этих вертикальных отрезков, мы получим график, очень похожий на синусоиду. Вопрос только в том, насколько он будет похож? Практическое определение количества отсчетов В математике есть теоремы, которые помогают рассчитать количество необходимых измерений, чтобы график стал очень похожим. Но я собираюсь «схитрить». Я использую программу моделирования работы электрической цепи Qucs. Это бесплатная и очень полезная в любительской практике программа. Если в режиме анализа переходного процесса понаблюдать за сигналом от генератора синусоидального напряжения, то меняя количество точек (а программа строит график так же, как описано выше), можно найти минимальное их количество, чтобы получить приемлемый вид графика (рис. 10.1). Аналого-цифровой преобразователь требует определенного времени для выполнения измерения (преобразования). Чтобы за один период синусоидального напряжения конвертер (АЦП) измерил напряжение в 20 точках, нужно чтобы период
Рис. 10.1. Вид графика синусоиды при разном количестве замеров был равен времени одного измерения, умноженному на 20. Это определит верхнюю рабочую частоту «осциллографа». В нашем случае частота будет 4...5 кГц. Программы, как правило, работают с переменными разного типа. Тип переменной определяется ее числовым характером. Так, символы используют код, для которого достаточно 255, поэтому тип символьных данных байт (byte или char). Небольшие целые числа без знака (немного больше шестидесяти тысяч) умещаются в два байта и т. д. Поскольку АЦП модуля Arduino 10-разрядное, работа с ним требует использования переменных целого типа. Мы могли бы задать 20 переменных целого типа, но это очень неудобно.
ЧТО ЕСТЬ ЧТО. Программисты давно придумали особенный вид переменной, которая называется массив. Нам подойдет одномерный массив с числами целого типа. Физически массив - это область памяти с последовательно организованными ячейками. Обозначают массив целых чисел так: int dat [20], где dat — имя массива, а число в квадратных скобках задает количество элементов массива. К слову, строковая переменная (любая строка, с которой оперирует программа) не более, чем массив байтовых данных. С программой на компьютере (с компьютером) Arduino будет общаться через встроенный модуль последовательного обмена данными (UART или USART). Программа для Arduino получается такой: byte dat [20]; // массив для данных byte i; // переменная для цикла for void setup() { Serial.begin (115200); // инициализация UART } void loop () { for (i=0; i<20;i++) { dat [i] - analogRead (0)/4; // заполняем массив данных // измеренными числами } Serial.write(dat,20); // отправляем данные на компьютер } t ПРИМЕЧАНИЕ. Ь | С программой есть одна проблема: АЦП прочитывает целое число, а модуль последовательного обмена данными оперирует с байтами. Поэтому мы используем массив байтовых данных, а прочи-тываемое АЦП число делим на четыре.
Лучше один раз увидеть, чем сто раз услышать Записав код, хотелось бы проверить, работает ли он? Программа Arduino имеет встроенный монитор порта (рис. 10.2). □ adc_2: Arduino 1.8.2 Файл Правка Скетч Инструменты Помощь аос ..2 1 byte dat[20]r 1 1 byte 1; .'/ neti' АвтоФорматирование Архивировать скетч Исправить кодировку и перезагрузить I М< CtrkT Плоттер по последовательному соединению Ctrl* Shift* L 4 void setup(j ( S Serial-begin ( 6 7 } WiFi 101 Firmware Updater 9 void looo() I 2 О for (i=Q; i<20 11 dat{ij « anala Плата: “Arduino/Genuino Uno“ Порт "COM3" Получить информацию о плате Программатор: "AVRISP mkll* Записать Загрузчик 13 Serial.write(‘3atT2^T~* 77“6тправлч~ • i--(t«0: t<20n»| { 15 .//Serial..printin(dat[ij) ; 16 //} 17 I ___________________________________________________ .. MH Ardufrto/Genuino Uno COMB Puc. 10.2. Монитор порта в Arduino Монитор порта можно использовать при отладке программы. Например, можно посмотреть переменные. Достаточно добавить команду 8епа1.рпп1(переменная), чтобы увидеть значение этой переменной. Я сейчас удалю в представленной выше программе вывод данных, заменив это выводом одного элемента массива dat[0] (удалять что-то необязательно, достаточно закомментировать строку или строки!): Serial. println(dat[O]); добавленное к слову печатать (print) сочетание
Рис. 10.5. Вывод переменной на монитор порта In означает переход на новую строку. Можно добавить и паузу после вывода на монитор, в противном случае вы увидите быстро бегущие числа, как показано на рис. 10.3. При отладке программ в разных средах разработки используют встроенные отладчики. Но и в программе Arduino можно использовать монитор порта не только для того, чтобы посмотреть значение переменной. Рис. 10.4. Вывод «метки» на монитор порта
Если вас интересует, а так бывает часто, проходит ли программа нужное вам место, вы можете добавить в это место Serial.println(“R здесь”) и, если программа проходит это место при работе, вы увидите (рис. 10.4). ПРИМЕЧАНИЕ. Если программа ориентирована на работу, например, с кнопкой, а так работают и некоторые датчики, то с монитором порта можно проверить и кнопку. Состояние вывода присваивается переменной. И никто не мешает нам на время отладки менять значение этой переменной. Режим пошагового прохода программы легко Организовать, добавляя паузы нужной длительности. Можно использовать массив для записи меток прохождения программы, а массив вывести на монитор порта в конце отладочной процедуры. ' «Заграничные штучки» и Arduino Возвращаясь к поставленной задаче, можно отметить, что программа работает, а массив данных не пуст. Загрузим исходную программу, оставив модуль Arduino подключенным. Однако нам предстоит много работы по созданию программы для компьютера, и хотелось бы быть уверенным, что это не станет сизифовым трудом, повышать производительность которого нет смысла... Модуль Arduino — это, в первую очередь, микроконтроллер, я сейчас использую Arduino Uno с микроконтроллером ATmega328. Производитель микроконтроллеров AVR для разработчиков предлагает среду разработки AVR Studio, о которой вы можете прочитать в следующей главе. Сегодня эта программа называется Atmel Studio. В седьмой версии, например, есть приклад-
Mesugei (435:18668. £О8м Си Репе! Added. • ' protocols SJhM*t»ICu Рис. 10.5. Программа Data Visualizer с развернутым меню ная программа, которая называется Data Visualizer. Очень полезная для нас сейчас программа. Запустим ее (рис. 10.5). Новичок: А могу я использовать эту программу вместо осциллографа? Конечно, там есть вариант и графика, и осциллогафа. Чтобы открыть меню, используйте стрелку, отмеченную на рисунке, а развернуть разделы позволяют стрелки слева от них. По умолчанию открывается интерфейс, который нам сейчас не нужен. Достаточно нажать на стандартную кнопку «закрыть» в правом верхнем углу интерфейса, чтобы его закрыть, а затем дважды щелкнуть левой клавишей мышки по разделу «Serial Port» (рис. 10.6). Мой модуль Arduino подключается к компьютеру через виртуальный COM-порт (хотя подключен к USB-порту), кото-
Рис. 10.6. Интерфейс последовательного порта обмена данными рый вы видите на рис. 10.6 как СОМ8. Его мы и выберем. Это касается раздела внешних подключений «External Connection». Следом в разделе визуализации выберем «Graph» (тем же двойным щелчком левой клавиши мышки), считая, что это программа построения графиков — такую программу мы и намерены написать для компьютера. После появления рабочего окна построителя графиков его нужно соединить с интерфейсом порта. Для этой цели служит штекер, который нужно вставить в гнездо New Plot (рис. 10.7). СОВЕТ. Галочку, отмеченную в правом верхнем углу рядом с Open Terminal, пока лучше снять, поскольку терминал нам сейчас не нужен. Кнопкой в правом верхнем углу Connect мы соединяем модуль Arduino с программой Data Visualizer. К модулю Arduino у меня подключен генератор синусоидального сигнала с амплитудой порядка 2 вольт и частотой 1 кГц. После подключения Arduino появляется почти сплошная полоса в рабочем поле плоттера. Это правильно. Нажимая кнопку с увеличительным стеклом и значком плюс (кнопка тоже отмечена), можно привести графику к виду, показанному на рис. 10.8. Так выглядит график, который построен на основании данных измерения АЦП.
Рис. 10.7. Подключение плоттера к СОМ-порту Новичок: График похож на синусоиду, но сильно искажен. Почему? Оценивая верхнюю граничную частоту в 4...5 кГц, я взял наименьшее время преобразования 13 микросекунд, указанное в справке к микроконтроллеру ATmega328. Но там указано максимальное значение 260 микросекунд. Время II преобразования II В справке к языку программирования Arduino (можно найти, введя в поисковик Arduino Reference) для функции analogRead() указано значение близкое к 100 микросекундам. Уменьшив в 10 раз верхнюю граничную частоту, мы получим
Рис. 10.8. Графическое изображение данных, получаемых от Arduino 500 Гц. Эту частоту я и выставлю у генератора, чтобы получить график, показанный на рис. 10.9. Искажений, согласитесь, меньше. Но главное — если программа построила график сигнала генератора, то и мы можем продолжить работу над поставленной задачей. Рис. 10.9. Частота генератора 500 Гц
Прикладные программы II для компьютера II Прикладные программы для компьютера можно создавать в разных средах разработки, используя разные языки программирования. Я приведу пример среды разработки Code::Blocks, используя язык C++. Это не будет законченная программа, но будет первая попытка общения между компьютером и модулем Arduino. Возможно, создав робота, вы захотите управлять им с компьютера. В этом случае вам понадобится программа для компьютера. Code::Blocks — бесплатная полнофункциональная программа, которая должна вполне вас устроить. Вдобавок в ней можно создавать код программ для микроконтроллеров AVR и ARM. Введите в поисковике code "blocks download и выбирайте версию для Windows или Linux, что вам ближе. Новичок: А если я пока не хочу пользоваться этой программой? Тогда можно пропустить эту главу. Когда придет время, и программа понадобится, можно вернуться к чтению этой главы. Конечно, программа предназначена для профессионалов, но и любители могут воспользоваться всеми возможностями визуального программирования, если используют плагин wxSmith и дополнение wxWidgets. Создавая программу для модуля Arduino, мы использовали функции и команды, не задумываясь о том, что они созданы для нас другими людьми, чтобы нам было удобнее и быстрее писать нашу программу. Аналогично и wxSmith существенно облегчает создания приложения для наших целей. Используйте поисковик, чтобы скачать wxWidgets. Нам понадобится еще одна библиотека функций для работы с портом последовательного обмена данными. Необходимые два файла можно найти здесь [10]. По завершении скачивания, установки и расположения программ и файлов можно начать создание программы с запуска Code::Blocks, где на начальной странице еле-
Рис. 10.10. Выбор типа проекта в Code::Blocks дует выбрать «Создать новый проект, Create New Project». Это начало приводит нас к диалогу выбора нужного типа проекта (рис. 10.10). Нажав на кнопку Go, мы начинаем путешествие по диалогу настройки проекта с помощью кнопки Next —> (рис. 10.11). Рис. 10.11. Настройки проекта
Рис. 10.12. Рабочее поле программы с заготовкой для проекта Результат этой работы — заготовка программы с формой в рабочем поле (рис. 10.12). Ниже формы можно увидеть инструментальную панель со всеми необходимыми компонентами для создания приложения. Щелкнем левой клавишей мышки по иконке с надписью ОК (четвертая слева), переместим курсор мышки на форму, где щелкнем еще раз. Каждый раз, когда я вижу результат, я удивляюсь — удивитесь и вы (рис. 10.13). А теперь аналогичным образом добавим еще одну кнопку (рис. 10.14). Вероятно, первая кнопка заняла всю форму согласно свойствам, заданным по умолчанию. Если выделить на форме элемент, то в левой нижней части окна программы отображаются свойства этого элемента. Выделив первую кнопку, в первой строке окна свойств с названием Label заменим название кнопки (рис. 10.15).
Рис. 10.13. Размещение первой кнопки на форме Рис. 10.14. Добавление еще одной кнопки на форму
Рис. 10.15. Изменение названия кнопки Вторую кнопку назовем «Стоп». И добавим на форму еще один элемент wxPanel. В свойствах каждого элемента есть параметры X, Y, size. Сняв галочку с Default size, вы сможете задать свои размеры элементов. Я сразу введу такие параметры: Form 789x267; Panel 60x180, Х=136 Y=32; Buttonl 48x23, Х=16 Y=32; Button2 48x23, X=72 Y=32. Добавляя элементы, задавая параметры, я проверяю, транслируется ли программа (основное меню, Build -* Build). При отсутствии ошибок при трансляции можно продолжать работу. Если этого не сделать, то ошибок может накопиться слишком много, и какие-то из них будут запутывать вас. Окно сообщений, отображающее ход трансляции программы, в нижней части рабочего поля программы. В папку проекта, где находится основной файл нашей программы, скопируем оба файла serialib.cpp и serialib.h, которые мы скачали ранее. Добавим эти файлы в проект, используя в
основном меню Project Add files. На этом завершим подготовку. Визуальное создание графических компонентов программы можно назвать событийно-ориентированным программированием. Любое событие будет отображаться в программе набором действий, которые должны описать вы. После двойного щелчка по первой кнопке вы получите в тексте программы заготовку для обработки этого события — щелчка по кнопке: void My_GraphFrame:: OnButtonlClick(wxCominandEvent& event) { } Двойной щелчок по панели создаст заготовку для работы с графикой на панели. Щелчок по первой кнопке на форме должен открыть СОМ-порт. Затем в массиве данных программы мы должны прочитать то, что отправила программа Arduino (отправил модуль Arduino), и, используя эти данные, нарисовать график. Новичок: Конечно, процесс должен повторяться до тех пор, пока мы не нажмем вторую кнопку, которая закроет СОМ-порт? После создания заготовок для событий на форме можно добавить к программе включение необходимых библиотечных файлов и ввести определения, добавить переменые. Теперь этот раздел программы должен выглядеть так: #include <<wx_pch.h>> #include <<My_GraphMain.h>> #include <wx/msgdlg.h> #include «serialib.h» #include <wx/graphics.h> #include <wx/dcclient.h> #define DEVICE_PORT «СОМ8» serialib LS;
//(*InternalHeaders(My_GraphFrame) #include <wx/intl.h> #include <wx/string.h> //*) char dat [1024]; // буфер данных int i; // вспомогательная переменная int j ; char trig = 0x24; bool f = true; // вспомогательный флаг В программе будет использована задержка (delay), поэтому перед обработкой щелчка по первой кнопке добавим функцию реализации задержки: void delay(unsigned int mseconds) ( clock_t goal - mseconds + clock(); while (goal > clock()); } Первая кнопка на форме должна так обработать событие: void My_GraphFrame:: OnButtonlClick(wxCommandEvent& event) { f = false; LS.Open(DEVICE_PORT, 115200); // открываем СОМ-порт Refresh(); // обновляем форму } С обработкой событий на панели, где мы будем рисовать график (сигнала), есть проблемы. Осциллограф «рисует» сигнал с началом координат в левом нижнем углу. А на панели начало координат в левом верхнем углу. Переместить начало координат? Может быть, может быть... Но я не знаю, как это сделать. По причине чего я попробую обойти эту проблему, манипулируя с у-координатой. Вторая проблема заключается в том, что данные приходят в байтах, а координаты (в функции работы с графиком) целые. И здесь нужно будет что-то придумать... В итоге обработка событий панели выглядит так:
void My_GraphFrame::OnPanellPaint(wxPaintEvent& event) { if (f == false) { for (i = 0;i < 1024;i++) { LS.Readchar (&dat [ i],0); } i = 0; while (dat [i] != trig) { i++; } j=i; wxPaintDC de( Panell ); de.SetPen( wxPen( *wxRED, 2 ) ); for (i = j;i < 512-j;i++) { dc.DrawLine( (i-j)*2, 150 - dat [i], ((i-j) + 1) * 2, 150 - dat [i +1] ); } delay(200) ; Refresh(); } } События по нажатию второй кнопки обрабатываются лаконичнее: void My_GraphFrame::OnButton2Click (wxCommandEvent&: event) { LS.CloseO ; f = true; } Это все изменения в шаблоне программы, созданном программой Code "Blocks. Если вы не забыли добавить два файла для работы с COM-портом (serialib.cpp, serialib.h), используя в основном меню раздел «Project -> Add Files», то можно запустить сборку «Build —> Build».
ЭТО ВАЖНО! Если вы не включили эти файлы, то после трансляции программы, включив эти файлы и повторно собрав проект, вы можете не получить доступа к COM-порту, кнопки не будут работать. Разные режимы трансляции II кода программы II Сборку проекта можно осуществить для отладки, а можно осуществить и для реальной программы. Переключение сборки проекта отмечено на рис. 10.16. Проверить работоспособность программы у меня получается с помощью проводника от беспаечной макетной платы, включенного в гнездо АО платы Arduino Uno. Сетевые наводки работают в качестве генератора сигнала (рис. 10.17). Рис. 10.16. Переключение сборки проекта
Рис. 10.17. Проверка программы Для проверки я запустил Realease сборку (файл My_Graph.exe), которую можно найти в папке проекта в директории /bin/Release/. Для проверки с генератором сигналов придется внести аппаратные изменения, необходимо подать смещение на вход АЦП. И сигнал на частоте 500 Гц будет выглядеть так, как на рис. 10.18. Можно подумать, что «овчинка не стоит выделки» — осциллограф до 500... 1000 Гц. Но цель этого рассказа в другом. Если вам захочется управлять роботом с компьютера, вы можете легко написать программу для компьютера в Code:.’Blocks, и вы могли видеть, что можно использовать COM-порт для управления. Рис. 10.18. Вид сигнала на частоте 500 Гц
А касательно верхней граничной частоты... Что ж, удобнее использовать с модулем Arduino графический дисплей, как это описано в книге Роберта Девиса, перевод которой можно найти на моем сайте. И еще. Заглянем в раздел плат II программы Arduino II Добро пожаловать в раздел плат программы Arduino (рис. 10.19). Есть недорогой модуль STM32F103C8 с гораздо более мощным и быстрым микроконтроллером типа ARM. Он очень похож на Arduino Nano, с которого начинался этот рассказ. Но программируется он иначе, чем модули Arduino, хотя написать программу можно в среде разработки Arduino. Лучше, и я советую, использовать другие программы для работы с этим модулем. Но это совсем другая история. 1 je edc_2 j Arduino 1A2 I Файт Правка О - “ ‘ Ctri*T Arduino Gemma Ctrl» Shift* М WiFilOl Firmware Updater Arduino Industrial 101 LininoOne Arduino Uno WiFi 4 void setup() 5 Serial.begin Adaftuit Circuit Playground Arduino Yun Mini АетоФорматиромнме Архивировать скетч Исправить кодировку и перезагрузить Монитор порта Плоттер по последовательному соединению Ctrl* Shift* L void. ioop() ( for (i-0; i<2C Oatfl] « analc 1 byte dat(20}; t byte i; // net Generic SIM32F1Q3R senes Generic STM32F1G3T senes Generic STM32F103V senes Genenc STM32F1O3Z series STM Nudeo F1&3R8 (SlUnk) Generic STM32F103C series Maple Mini Maple (Rev3) Maple (RET6) Mkrodumo Core STM32 to Flesh Рис. 10.19. Набор плат, с которыми работает программа Arduino Программатор: AVRISP mkll Записать Загрузчик Платы Arduino ARM (32-brts) Arduino Due (Programming Port) Serial.write(dal , . , ’ , .
ГЛАВА И РАБОТА С МОДУЛЕМ ARDUINO В ДРУГИХ СРЕДАХ РАЗРАБОТКИ Проект Arduino, поддержанный многочисленными примерами программ, самодостаточен. Но иной раз чего-то не хватает для реализации задуманного. Тогда можно вспомнить, что модуль Arduino построен на базе микроконтроллера AVR, для работы с которым есть другие программы. Программы для операционной системы Windows ЭТО ВАЖНО! При работе с модулем Arduino в других средах разработки следует внимательно относиться к конфигурации микроконтроллера (Fuses). До тех пор пока вы точно не знаете, к чему может привести изменение конфигурации, настоятельно советую, загружать в модуль только программу (Flash).
В основном речь пойдет о программах для Windows. Их установку и работу в Linux мы рассмотрим отдельно, как и программы для Linux, работающие с микроконтроллерами AVR. Советы по установке программ и самим программам можно найти на сайте RoboCraft, о котором часто упоминалось в книге, и на сайте «Электроники для всех» [11]. Первая из программ, это AVR Studio фирмы Atmel. ПРИМЕЧАНИЕ. Следуя советам бывалых, перед установкой этой программы следует установить программу WinAVR, которая и сама позволяет писать программы на Си и ассемблере. При работе с языком программирования Си используется свободная версия компилятора GCC. Новичок: А можно пропустить и эту главу, мне бы освоить Arduino? Рис. 11.1. Диалог выбора продолжения работы cAVR Studio
Несомненно. Но я советую, не повторяя эксперименты, хотя бы бегло просмотреть эти главы. Когда придет время, когда это понадобится, что-нибудь да всплывет в памяти. Итак, установив обе программы в Windows (использую версию AVR Studio 4.18), можно запускать программу, которая появится в основном меню в разделе «Atmel AVR Tools». При запуске программы вначале открывается диалог, позволяющий создать новый проект или открыть существующий. От этого диалога можно отказаться, но не советую это делать в самом начале работы с программой (рис. 11.1). ПРИМЕЧАНИЕ. Если снять галочку рядом с надписью «Show dialog at startup» (показывать диалог при запуске), то диалог не будет появляться. Выбрав кнопку (в верхней части) New Project, вы переходите в окно помощника создания нового проекта. Поначалу, пока не освоитесь полностью, обратите внимание на отмеченные на рис. 11.2 пункты. Рис. 11.2. Выбор языка программирования и атрибутов создаваемого файла
Отметив AVR GCC, вы предполагаете работу с языком Си. Проверьте, стоит ли галочка опции «Create folder». Иногда ее нет, и файл сохраняется вместе со всеми остальными, что создает через некоторое время трудности в отыскании нужного файла. ЭТО ВАЖНО! Местоположение файла. Играет ли это роль в данном случае, не берусь судить, но лучше размещать свои проекты при работе с программами разработки в директориях, названных одним словом, написанным латиницей. Так будет меньше проблем. Например, некоторые программы не могут работать, если путь к нужным им файлам выглядит как «Program Files». Или, если ваша папка с документами обозначена как «Документы». Можно, конечно, проверить это, но лучше сразу вырабатывать привычку избегать подобных осложнений. Иногда они выяв Рис. 11.3. Выбор отладочных средств и модели микроконтроллера
ляются легко, но в ряде случаев сообщения об ошибках столь туманны, что и не сразу поймешь, в чем дело. Закончив с атрибутикой файла, можно нажать кнопку Finish, если вам ничего больше не нужно, но лучше нажать кнопку Next» (рис. 11.3). В этом окне диалога вы выбираете отладочные средства и модель вашего микроконтроллера. Если у вас есть программа Proteus, очень хорошая, но не бесплатная, то выбирайте Proteus VSM Viewer. Завершив выбор, можно закончить работу помощника создания нового проекта (Finish). Пример «классической» программы для модуля Arduino Я не буду рассказывать о том, как работать с AVR Studio — есть руководство, есть много сайтов в Интернете, где хорошо рассказывается об этом. То же и о работе с компилятором AVR GCC. Приведу только один пример «классической» программы для модуля Arduino (рис. 11.4). Текст программы я приведу еще раз. #include <avr/io.h> #include <util/delay. h> ttdefine F_CPU 16000000UL int main( void ) { DDRB 1«5; while(1) { PORTB 1= 1«5; _delay_ms(5000); PORTB &= ~(1«5); _delay_ms(5000); } return 0; }
Рис. 11.4. Первый проект для модуля Arduino Программу я «срисовал», выбрав самую простую. Первый оператор в основной программе устанавливает вывод RB5 (вывод 13 модуля Arduino) на выход. В цикле while этот вывод переводится в состояние высокого уровня, а после паузы в 5 секунд, в состояние низкого уровня. Написав программу, в разделе «Build» основного меню выбираем команду «Build» и транслируем текст. Если нет ошибок, то вы получаете сообщение об удачном завершении сборки, если есть ошибки, то они будут выведены с предупреждающими красными пометками и расшифровкой характера ошибки. Нам нужен hex-файл, который вы найдете в папке проекта, где появится папка «default» (рис. 11.5). Среда разработки AVR Studio позволяет написать код программы и отладить его. Но она предназначена и для загрузки программы в микроконтроллер. Однако, хотя в списке программаторов (рис. 11.6) есть stkSOO, использовать эту возможность у меня не получилось. Найти этот список можно, если выбрать соединение с программатором (рис. 11.7).
Рис. 11.5. Созданная программой папка для размещения оттранслированных файлов Рис. 11.6. Список программаторов
Рис. 11.7. Переход к программатору Если нет программатора II для работы с AVR Studio II Возможно, проблема кроется в скорости работы с программатором. Вместе с тем, если вы вспомните, как мы поступили с hex-файлом для превращения модуля Arduino в осциллогаф, то можете аналогичным образом загрузить и полученную в AVRStudio программу. Программа программатора avrdude по мнению многих очень мощная. А ее единственный недостаток, по мнению некоторых (вроде меня), в отсутствии пользовательского интерфейса. Но, читая статьи на вышеуказанных сайтах, я выбрал достаточно удобную оболочку. Называется она SinaProg (рис. 11.8). Она не требует установки на компьютер, вы ее можете расположить по своему усмотрению там, где вам удобнее.
СОВЕТ. Единственное, на что я советую обратить внимание сразу, - версия программы. В версии 1.4.5.10 есть возможность изменить скорость работы с портом. По умолчанию скорость работы выбрана большая. Если попробовать, выбрав версию программатора и порт (у меня он после очередного обновления Windows изменился с СОМ5 на СОМ6), нажать кнопку Search, то поиск программатора (рис. 11.9) завершится неудачей. О причинах неудачи можно прочитать, если нажать по завершению процесса кнопку, отмеченную на рис. 11.10. Изменим скорость, задав 19200. Рис. 11.8. Запуск графической оболочки SinaProg для avrdude <Ц} SinaProg 14.5.10 Рис. 11.9. Поиск программатора и модели контроллера
Рис. 11.10. Удачная попытка подключения программатора Рис. 11.11. Диалоговое окно настроек проекта AVR Studio
Как видите, модель контроллера найдена. Следовательно, есть надежда, что программу, которую следует загрузить, используя кнопку рядом с окном, обозначенным как «Hex file», мы сможем получить не в отладочном, а в «живом» виде. Используем загрузку программы (кнопка Program под надписью «Flash»). Программа загружается, это видно по миганию светодиодов, связанных с портом, и светодиод мигает с частотой раз в 5 секунд. Если это не так, то загляните в меню AVR Studio в раздел «Project —> Configuration options» основного меню (рис. 11.11). Задайте правильную частоту процессора (хотя мы ее и задавали в программе), проверьте правильность модели контроллера. ЭТО ВАЖНО! При неправильном выборе частоты тактового генератора микроконтроллера программа неверно рассчитает временные интервалы. \_____________________________________________ И еще о программах для AVR-контроллера Впрочем, перед установкой AVRStudio мы установили программу WinAVR. Она сама позволяет работать с микроконтроллерами AVR, используя язык Си. Достаточно хорошо процесс описан на сайте RoboCraft [12]. Я постараюсь не повторять его полностью, но бегло перескажу, как и что следует делать. Начинать следует с загрузки блокнота — это текстовый редактор, приспособленный к работе с WinAVR. Его легко найти в основном меню операционной системы (рис. 11.12). Как и в предыдущем случае, текст программы можно «срисовать», то есть, скопировать и вставить в окно редактирования. Что я и сделаю, скопировав его выше и вставив в программу. Попутно я создам в месте хранения предыдущего про-
Рис. 11.12. Состав пакета WinAVR екта папку с подходящим названием, чтобы сохранить файл, записанный в редактор (рис. 11.13). Времена паузы я изменю, чтобы отличать результат от результата предыдущего эксперимента. Как советует автор статьи, переносим из пакета WinAVR шаблон makefile’a. Найти его нетрудно, но это зависит, видимо, от версии программы (рис. 11.14). Открываем его в редакторе (открывается второе окно) и правим: задаем модель, тактовую частоту, указываем наш рабочий файл, тип программатора и порт (рис. 11.15). Кроме тех строк, что есть на картинке, правка коснулась следующих строк: # MCU name MCU = atmegal68 # Processor frequency. F_CPU = 16000000
a*i («ооодооцк <1>тмх Ш|Л |ЮН (ями-f ь»... dW|«!|SniS«t<rftM |«3|i«|ETX(rwWt«« OWjxM|£OT(eneoftr«n_. Ml^JENQCenqwryj 006 | «061 ACK bckneurtetL. TO | TO | BE I (bell) TOIxOeiBSibKlopwe} 009 J TO | TAB (horaonta) t... 0I0|TOJlF(Nlnrwtme/l... OirjTOrjVT (vertical tab) miiatlHffomifewiN-. <B.3! ЛI CP (Mwiag* retv... OMtrOeiSO^Wi**; Otf |wO|0U(«aM«. C1T|41 jtkl «teioceco*. ш;«и|паи»»к*а>м_ 0Ж|иЩ»и{Лг,ке«г.С ‘’AijM&i the* Шаме* c.«nu •- ' .. 4* !>ld . - „ МШ1Д7 Т оык I- i-«s; 1р"Ж> ! t-1«$, : _drfTayj»s(i«>0) WKTB *- ~(1« I Jtelayjss<lOOO) i return 0: Рис. 11.13. Блокнот программиста пакета WinAVR
Рис. 11.15. Правка файла makefile # Output format, (can be srec, ihex, binary) FORMAT = ihex # Target file name (without extension). TARGET = test Внеся изменения, следует сохранить оба файла. И запустить преобразование исходного текста на языке Си в hex-файл (рис. 11.16). Рис. 11.16. Преобразование программы в hex-файл
Рис. 11.17. Состав папки с проектом после выполнения команды «Маке АН» Заглянув теперь в папку, где мы сохранили текст программы и makefile, мы увидим (рис. 11.17)... Если после проделанной нами работы подключить модуль Arduino и выполнить команду Program (ниже отмеченной команды), то мы получим сообщение об ошибке. Что же мы упустили? Скорость работы порта. Внесем еще одно изменение в makefile, там, где выполнены настройки программатора: # Programming hardware AVRDUDE_PROGRAMMER = stk500vl # coml = serial port. Use Iptl to connect to parallel port. AVRDUDE_PORT = сотб -Ы9200 # programmer connected to serial device AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex # AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep
Я выделил добавленный мною параметр -Ь19200. Теперь программировать можно непосредственно из программы WinAVR. ПРИМЕЧАНИЕ. Возможно, между двумя последовательными «заливками» программы модуль следует отключать. Не будем обижать || и Linux || Я не уверен, что рассказал обо всех интересных программах общего назначения для работы с контроллерами AVR. Но и то, что есть, предлагает достаточный выбор. Но это все о Windows. Новичок: А что же Linux?Не обошли ли его вниманием? Не обошли. Так, в Linux есть среда для работы Windows-программ, которая называется Wine. Пользуясь советами, я намерен повторить установку AVR Studio 4 и других программ в Linux на трех дистрибутивах: ♦ Fedora 14; ♦ ALTLinux 5.1; ♦ openSUSE 11.3. Все три дистрибутива я использую с графической оболочкой KDE 4. Процедуры установки и настройки нужных программ в разных дистрибутивах схожи, но могут отличаться деталями. Если такие отличия будут существенны, я о них расскажу. Итак, Fedora 14.
I Дистрибутив Fedora 14 как полигон для наших экспериментов Перед установкой WinAVR, которая должна предшествовать установке AVRStudio 4, следует скачать в Интернете одно дополнение к Wine. Называется оно winetricks. Для его получения используется терминал, как показано на рис. 11.18. | vladimtf@vfcdj^ew ~/Докум&^ айл Правка Вид Поиск Терминал Справка ' ladiai'ftoladi-new ДжументыЦ wget http ://www. feegel. coss/wine/wifletricte| Рис. 11.18. Строка загрузки добавления к Wine Строку, которую следует ввести, я повторю еще раз: wget http://www.kegel.com/wine/winetricks После нажатия на клавишу Enter вашей клавиатуры вы получите показанное на рис. 11.19. Вновь используя терминал, запускаем winetricks командой: bash winetricks. В окне диалога с приложением вы отмечаете те элементы, которые вам нужны (рис. 11.20). ,18 vladirntr(@\rtacfi-new -/Документ .&•' Файл правка Вид Поиск Терминал Справка ж tvladuir^ladi-WB* Дс-куменгwget http: kegel.сш/wine/winetricKs --2011-63-03 10:19:16--’ http://www.kegel.cae/wine/winetricks Распознаётся www.kegel.cce... 216.92.86.126 Устанавливается соединение с www.kegel.C@H216.92.86.126];80... соединение устаиЯ оапено. Запрос «ПР послан, они дается ответ... 200 ОК Длина, 202559 ЦЖ0 Itexr/plain] Я Saving to: «winetricks.1» 10^[==cx=t====«==========^x=ss======x===>] 202 5S9 190K/5 в l,fe 2011-03-03 10:19:18 (190 KB/s) - winetricks.1» saved [202559/202559] [vladiwirftfladi-new Документы]! |
Winetricks Select packages to install j Package □ 7 zip 7-zip file archiver О adobeair Adobe AIR runtime □ amstream MS ainstream dl! □ art2kmin MS Access 2007 runtime □ atmlib Adobe Type Manager Needed for Adobe CS4 [ 10 autohotkey Autohotkey (open source gui scnptmg language) □ baekmuk Baekmuk Korean foots □ cmake CMake. the cross-platform, open-source build system I □ colorproftie Standard RGB color profile □ comct!32 MS common controls 5 60 □ comctl32.ocx MS comctl32 ocx and mscomcti ocx. comctl32 Wrappers | О comdlg32.ocx MS comdlg32.ocx for VB6 □ controlpad MS ActiveX Control Pad О corefonts MS Anal, Courier. Times fonts !□ crypt32 MS crypt32.dl ...... ..... . . „ .. JEI : ( ф Отменить j [" OK s Рис. 11.20. Состав дополнений к Wine Из предлагаемого списка: ♦ corefonts ♦ dcom98 ♦ gdiplus ♦ gecko ♦ mdac28 ♦ msxml3 ♦ vcrun2005 ♦ allfonts ♦ fakeie6... ...находится не все, что-то может не установиться, но добавим то, что установится. A fakeie6, возможно, будет выглядеть как ie6. Дождавшись завершения установки приложений к Wine, можно начинать установку программ. В Fedora для установки программ в среде Wine достаточно щелкнуть по файлу установки правой клавишей мышки (я часто пакеты установки выкладываю в корневую директорию диска с:\ в Wine) и выбрать из выпадающего меню раздел запуска с помощью Wine (рис. 11.21).
Рис. 11.21. Выполнение установки Windows программы в Linux После установки двух программ, продолжая следовать советам, создадим ссылку: In —s /dev/ttyUSBO <путь к вашей домашней директории:» /. wine/dosdevices/coml Для создания этой ссылки используйте переход в терминале к работе с правами root: либо командой su (и введите пароль), либо командой sudo. Мне приходится повторить эту процедуру трижды. При этом в ALTLinux (я обновлял версию через Интернет, что может стать причиной этих повторов) установку я произвожу, используя файловый менеджер Wine. Но теперь в основном меню, где у меня есть раздел «Wine программы» я могу найти AVRStudio (рис. 11.22). Как и в Windows, при запуске программы появляется окно диалога, в котором можно открыть уже существующий проект, а можно создать новый (рис. 11.23). Как и в Windows, лучше, это мое мнение, создать новую папку, отметив соответствующую опцию «Create folder». И, по причине отсутствия — у вас может быть иначе — программы Proteus, я отмечаю AVR Simulator в следующем окне, когда нажимаю кнопку Next».
Рис. 11.22. Программа для Windows в Linux Рис. 11.23. Диалог создания нового проекта в AVR Studio 4 Как и в Windows, можно скопировать нужный файл и вставить в окно редактора (рис. 11.24). Но не как в Windows, следует обратить внимание на одну деталь. Откроем окно свойств проекта, Ptoject -»Configuration Options (рис. 11.25).
Рис. 11.24. Вид окна программы в Linux Рис. 11.25. Правка свойств проекта Думаю, что возникает некоторая проблема со шрифтами — вместо Atmegal68... Но это не беда, щелкнув по кнопке, открывающей список моделей, выбираем нужную модель (рис. 11.26).
Рис. 11.26. Выбор модели микроконтроллера И не забываем указать частоту в поле «Frequency:» 16000000. Запускаем трансляцию файла, сохранив его предварительно, и убеждаемся в наличии и папки default, которую создает программа, и в наличии всех нужных файлов в ней (рис. 11.27). ПРИМЕЧАНИЕ. Но при попытке соединиться с программатором в Fedora возникает фатальная ошибка и программа «виснет». Я не исключаю, что это происходит от неудачной попытки установить что-то в winetricks. Но это не огорчает меня, поскольку я почти уверен в безуспешности попытки работать с модулем Arduino. Как и в Windows, воспользуемся программой SinaProg (рис. 11.28). Отличие в том, что в Wine использован порт СОМ1. И работает ссылка.
default — Dolphin Файл Правка вид Переход Сервис Настройка Справка Назад . • . ' Значки - Таблица Столбцы ДО Миниатюры - Две панели * * Qf > Домашняя лапка > test > default Рис. 11.27. Содержание папки проекта после выполнения трансляции Сведения default Пи»IKK КШУЙн' IJ JStWjy.liJU. . - Рис. 11.28. Настройки программы SinaProg в Linux В ALTLinux эта программа не заработала. Но можно использовать команду в терминале. Или использовать WinAVR. Я почти забыл о ней (рис. 11.29).
Рис. 11.29. Программа WinAVR в Linux Переносим шаблон makefile (рис. 11.30), как мы это делали в Windows, и вносим те же правки. Обратите внимание на путь к нужному файлу шаблона. Внеся изменения, переименуем его, удалив слово шаблон. И попробуем запустить... И получаем ошибку (рис. 11.31). В данном случае проблема возникает с файлом, который нужен для работы с программой Proteus. Но это мешает. И, обращаясь к советам бывалых, я выбираю, удалить из makefile все, что касается elf-файла. ПРИМЕЧАНИЕ. Можно воспользоваться утилитой мастера создания makefile. Под именем MfiLe [WinAVR] она есть в основном меню рядом с блокнотом программиста. Запускаем утилиту, заходим в раздел «Makefile» и задаем нужные параметры (рис. 11.32).
Рис. 11.30. Расположение шаблона makefile Г warranty; not even tar MERCHANTABILITY or FITNESS РОЯ A PARTICULAR PURPOSE. I яаке.ехе: *** ло rule to яаке target test.eir, needed by elf. Stop. > Process Exit Code: 2 |> Ti«e Taken: 00:Ш Puc. 11.31. Сообщение об ошибке при трансляции файла в WinAVR Рис. 11.32. Использование утилиты создания makefile
Из числа нужных мне параметров не удалось изменить частоту и настройки скорости СОМ1. Для этого служит опция (в самом низу), разрешающая редактировать makefile. Но, отредактировав все, сохранив файл рядом с исходным, я не могу выполнить трансляцию. Все та же ошибка. Проверяю, перезагружаясь, как работает программа в ALTLinux и openSUSE. Все работает. Возвращаюсь в Fedora, повторяю все от начала и до конца. И... работает, включая загрузку программы в микроконтроллер. Что я могу сказать? Программа для Windows и, если с ней чудеса в Linux, то это мои трудности. ПРИМЕЧАНИЕ. В Linux есть своя программа для работы с AVR-контроллерами. Называется она kontrollerlab. В ALTLinux программа есть в репозитории. В Fedora и openSUSE ее можно установить из исходных файлов. В Fedora проблема возникает при использовании команды make. Появляются ошибки. Проще показать, что к чему, чем долго об этом рассказывать. Итак, скачиваем с сайта проекта исходный код [13]. Я его распаковываю в домашнюю папку, где он расположен в папке kontroller. В терминале вначале переходим в эту папку: cd /home/ vladimir/kontroller. Следом даем команду: ./configure. Эта команда в Fedora проходит успешно, но в openSUSE требуется установить еще ряд библиотек, касающихся X и Qt. Их можно отыскать по ключевым словам devel, XI1, Qt и т. п. Но (и в Fedora, и в openSUSE) после команды make появляются ошибки (рис. 11.33). Первая ошибка возникает в строке 235 файла kontrollerlab.cpp. О характере ошибки есть сообщение. Откроем этот файл (рис. 11.34)...
yl3dimir@vlsdi-new"f/kontroilaf ... ............................................|f d inti const1: R :klavrcpu.h:224:22: предупреждение: conversion to 'unsigned char’ from 'unsigned int’ nay alter its value klavrcpu.h:22A;43: предупреждение: conversion to 'unsigned char’ from 'unsigned int’ say alter its value jin file included frm kontrollerlab«cpp:78:0: kldebugger.h: В функции-qiime 'unsigned char KLDebugger:: resdR сияРСКай(unsigned ‘ int) *: kldebugger.h:179:89: предупреждение: conversion to ’unsigned char* fros 'unsigne d int’ may alter its value ! kontrollerlab.cpp: If constructor tontrollerlab.cpp:235:72: ошибка: directly kontrollerlab. cpp: 235:72: шибка: ant 1: ^Shortcut* tontr oilerlab, cpp: 238:72: шибка: directly ton t rollerlab. cpp: 238:72: шибка: ant '::KShortcut‘ tontroilerlab. cpp: 242:38: шибка: directly котtrollerlab.cpp:242:38: шибка: ant '; :KSh.artcuv kontrollerlab, cpp: 247:72: шибка: *Котtrollartab; :KOTti oUertsb (boolj cannot call constructor ’KShortcut::KShortcut for a function-style cast, remove the redund cannot call constructor 'KShortcut::KShortcut for a function-style cast, remove the redund 1 cannot call constructor 'KShortcut::KShortcut* for a function-style cast, remove the redund cannot call constructor 'KShortcut: :K5hortcut*pJ ri^Mwinirmwinii' 'wtwirrrriY /*«wii m иттз Puc. 11.33. Ошибки при создании программы kontrollerlab из исходного текста !» te * * iLr, ; :: tag fcJWND.. aiwidget cpp al widget \..Г* teptjrcpp klserialtennin alwidgetba klsevensegm ertwidgst... klsevensegm enrwidgeth klsenaltecmin alwidgetba. лрайна Справка МиШмгюры ' 1,.^.панем1 * klsenaftermm alwidget о т klsevensegm entwidget.o klsevensegm entwdget,. klsevenscgm enttwdget.. klsourcecode toasmrelat kisovrcecode teasffiFelat. !ifr fciwiordhead ersettrngxpp Hwizardhead ersettjng n Mwrzardhead ersett.mg.o ktwizarrihead ersettu.gs.. ko.-’tro»K>r!ab kontrollerlab desktop taMrollertab kontrollertab Ism kiwizardhead ersettmgs.h k.ontrollenaii moc 0 mairi.cpp Makefile Makefile, am Hakefee in registars.xnU ВЫ6НН ,kw«Mertab cpp. 1Л2.7 e «- al widget mbt kontronersb ktMitfuHert Hwizar ahead er settings о kisctrcecode toaamndat... kfcewnsegm ent^dget..,..
...и найдем нужную строку (рис. 11.35). Рис. 11.35. Строка, которую нужно править Lilt jflaw Reject »>zacds Qebug look Settings jtfmdow ныр 0 teste runwoherLab fiRW ’J»3 *OORO/Of 4 k!ab ЗМЮ) Data to send (#xy where xy is in HEX. sends the value xy) taxjcoMi int aoint wad I.. ?.€. I ЯЖ» » 255;.. ["wetted).».. rh r deUy 0x0000 0x000v 0x000.) 0x0004 0x0005 0x0000 0x000/ 0x0008 0x0009 iOxOOOii 0*03 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 ой» 0x00 0 00000003 - 000000011 00000050 ooooboow 00000000 000000015 oooooooo QOOOOOOt’ 0000000о 00000003) 000006® ЩОкНЛ.»»» Г : Memory сен 0x0 Name 'rOG i <*• "Ж. Oevitt |Ww/ttyUSao Baud га» , , Flow control UBfs/crs Q xom/xoff ; Disconnect gMt programmer >s acBva Oata л '43;' received Show as — — W
Заменим KShortcut::KShortcut("") на KShortcut(). Аналогично, просмотрев все указанные в перечне ошибок строки, вносим исправления. Запускаем make еще раз, убеждаемся, что все прошло без ошибок. И командой sudo make install устанавливаем программу. Устанавливается она по адресу: /usr/local/ kde/binAontrollerlab. Именно эту команду следует ввести в терминал, чтобы запустить программу (рис. 11.36). Свойства kontrollerlab desHop — Рабочее пространство Hasma 4 г' & CXHOftrioe Прага Приложение ведения Пеэдаармтельный просмотр Комментарий ~ " ж Команде: ^^tocdlAde/bm^ontrolertab Дросмдтр^. j > ; Рабочий путь. ’ ВО Поддерживаемые типы файлов тип mime а Описание Рис. 11.37. Командная строка запуска программы А для удобства при последующем использовании программы можно создать то, что называется: ♦ ярлыком в Windows; ♦ ссылкой на приложение в Linux. Там прописывается команда запуска на закладке «Приложение» (рис. 11.37). Подобрав подходящую картинку, кнопку запуска поместим на рабочий стол. После запуска kontrollerlab в разделе «Project» выбираем «New Project», а в появившемся диалоге указываем имя проекта и место, где он будет храниться. Устанавливаем конфигурацию проекта, «Project -> Configure Project» (рис. 11.38). На закладке «Compiler» устанавливаем опцию поддержки скорости работы процессора (рис. 11.39).
Рис. 11.58. Установка устройства и частоты в конфигурации проекта Project configuration Command: [an^^cc’"^— О -щсаН prologues: Expanded function prologues (smiler code) £. Wstnct-prototypes See ‘‘manavr-gcc’’ for detain. □ -Wall. Turn on all optional warnings £J -g. Produce debugging information_________________ „ Jjjjg (Mine ИУЦ symbpUfregueyy of ffie. cpu. see Common tab) J Optirhizauo^i level j <? t<o opumization ; 'ок ’ default Г Сапсё» | Puc. 11.39. Задание опции поддержки строки определения частоты в тексте программы
ЭТО ВАЖНО! Если эту опцию не установить, то проходит компиляция, можно загрузить программу, но работать она будет так, как если бы тактовая частота была той, что установлена в программе по умолчанию, а записанное в исходном тексте определение частоты игнорируется. Перед тем как закрыть диалог, следует нажать кнопку Set as default. Закрываем диалог кнопкой ОК. Теперь следует настроить программатор (Project -> Configure programmer): на первой закладке добавляем модель программатора, с которой работает модуль Arduino (рис. 11.40). На закладке «AVR DUDE» устанавливаем две опции. Нажимаем кнопку Set current settings as default и затем кнопку ОК (рис. 11.41). Рис. 11.40. Настройка программатора для работы с модулем Arduino
Рис. 11.41. Настройка на закладке программатора Создаем новый файл (File -> New, или кнопка на инструментальной панели), выбирая в окне диалога исходный файл на языке Си (рис. 11.42). В окно текстового редактора текст программы можно перенести копированием, а затем сохранить файл. Если в свойствах проекта поставить опцию «-g» (чуть выше опции поддержки тактовой частоты), то файл будет содержать информацию для отладчика. Рис. 11.42. Диалог создания нового файла
««* test? с - KortroBertxB i.\ 'J OOOOOOOO rS M OOfl ret U 00000000 rt ♦include «til/delay h>. •define F„CPU 1690069001. Q OOOOOOOO Г0 0 OOOOOOOO rl n OOOOOOOO r2 I W0M0M rl Ж W ’ 1 - Г' ' E*e £d< yi»w Pioject Wizxrds Qetwg loots Jettmg? Window Help rwm received ' Show as 0x0000ОкОО0 0x0001 0x00 0 0x0002 0x00 0 0x0003 0x00 0 0x0004 0x00 0 0x0005 0x00 0 0x0006 0x00 0 0x000/ 0x00 0 Device [/dev/ttyUSBO Baud IO 8TS/CTS Gt... ЯЖТВ 1= гжн deUy ssUBMh PORTB 4p -il«<5) 0x0009 0x00 0 0x000a 0x00 0 n 00000000 Г10 о ---------“~-------—----------~~~—;'‘’’i,<‘"!<------ Ж We induded Worn test? e 2'0 WwAb/gcr/avr/s 5 l/./j / /evr/wdudewol/deiey h 94 3 wxmmg *wermnq -Compiler optimizations disabled, function» from <utO/deiey h> wont work as av’ gee testa о mmcu»*tmegal68 g о mstrxrt -WL-Mep.teit.map opy R eeprom О *>ex test out teathex Mai Hi} -4‘ t»«a <»«•35161 Puc. 11.43. Успешная трансляция и компоновка проекта Запустив компиляцию и компоновку проекта командой «Build project» раздела «Project» основного меню, мы получаем (если все правильно) сообщение об удачной сборке (рис. 11.43). Загрузка программы в программатор выполняется командой «Upload» раздела «Project» основного меню, или можно использовать иконку с изображением ракеты на инструментальной панели. При удачной загрузке вы получите в окне вывода сообщение (рис. 11.44). СОВЕТ. Чтобы убедиться, что все правильно, можно изменить время паузы на 5 секунд и повторить операции по трансляции и загрузке.
Уточнение общих настроек II для конкретного дистрибутива Linux II Настройки программы kontrollerlab в ALTLinux имеют больше особенностей, чем в других дистрибутивах. Хотя и avr-gcc, и сама программа загружались из репозитория ALT, при попытке оттранслировать программу сразу появляется сообщение, что файлы включенных заголовков не найдены. Проблема решается, если указать место, где эти файлы находятся, явным образом. Заходим в пункт Configure Project раздела «Project» основного меню, открываем закладку «Compiler» и добавляем в команду несколько слов, указывающих нужное место в файловой системе (рис. 11.45). Рис. 11.45. Изменение команды вызова компилятора в ALTLinux Строка должна выглядеть так: avr-gcc -I/usr/include/avr Попутно устанавливаем опцию «Define F_CPU symbol». Эта проблема касается всех дистрибутивов: без этой опции тактовая частота остается равной заданной по умолчанию. Теперь компиляция (Project —► Build project) проходит. В настройках программатора, помимо выбора, сделанного в основном окне, установлены опции на закладке «AVR DUDE» (рис. 11.46).
Рис. 11.46. Окончательная настройка программатора в ALTLinux Хотя kontrollerlab имеет отладчик, но с ним у меня отношения не сложились. Конечно, можно было бы выяснить причину этого, но средства отладки модуля Arduino достаточно обширны и без поиска причин неудачи с отладчиком этой программы. I Компилятор AVR-GCC Почти все среды разработки на базе микроконтроллеров AVR, о которых рассказано выше, используют компилятор AVR-GCC, полнофункциональное СПО. Можно загрузить руководство по использованию компилятора в формате pdf на сайте [14]. Руководство на английском языке. Но: ♦ во-первых, основа — это язык Си, а книг на русском об этом языке программирования более чем предостаточно; ♦ во-вторых, если вы решили использовать язык Си, то как-то нужно приспосабливаться к английскому языку; ♦ в-третьих, если вы только начинаете работать с микроконтроллерами, с модулем Arduino, то пройдет достаточ
но много времени до того момента, когда вам потребуется программирование на чистом языке Си, и вы успеете освоиться с английским языком. Когда, работая над книгой, я коснулся темы AVR Studio, я обнаружил, что появилась новая версия этой среды разработки. Чтобы скачать программу, требуется регистрация. Не вполне ясно, отчего обязательными являются пункты, которые относятся только к пользователям в США, но, как получилось, я заполнил бланк. Если возможность скачать программу реализуется, я постараюсь рассказать немного о новой версии. Если же нет, то на нет и суда нет... ПРИМЕЧАНИЕ. Регистрируя программы при загрузке их с сайта производителя, вы рискуете только получать рас-сылки с рассказом о новых продуктах, не более тога Рис. 11.47. Установка компонентов от Microsoft
Однако все получилось. Пакет весит изрядно, но, будем надеяться, оно того стоило. Запускаем установку программы, которая начинается с установки необходимых компонентов Microsoft Visual Studio (рис. 11.47). I Обновление версий программ как компонент любопытства По окончании этой части процесса начинается установка AVR Studio (рис. 11.48). Рис. 11.48. Начало установки программы Хотя время в таких ситуациях тянется невыносимо долго, но всему неприятному приходит конец (рис. 11.49). После того, как вы нажмете кнопку Finish, благодаря установленной опции, запускается сама программа (рис. 11.50). Собственно, это еще не запуск программы, а диалог выбора: вы можете создать проект (New Project), использовать проект примера или открыть существующий проект (Open Project). Все это вы выбираете слева. А на основных закладках можете выбрать знакомство с программой на закладке «Get Starting», ознакомиться с инструментарием для работы с AVR-контроллерами (AVR Tools Help) и подписаться на новости.
Рис. 11.49. Завершение установки AVR Studio 5 Рис. 11.50. Первый запуск программы ПРИМЕЧАНИЕ. При выборе знакомства с программой следует учесть, что файл будет получен из Интернета, то есть, компьютер должен быть подключен к сети (рис. 11.51).
Рис. 11.51. Руководство по начальным шагам работы с программой Выбрав новый проект, вы можете продолжить выбор создания проекта: я, например, выбираю пустой проект для GCC компилятора. Там же выбираю имя проекта, а предлагаемое место хранения проекта оставляю без изменений. Далее есть возможность, об этом позаботился помощник создания нового проекта, выбрать модель микроконтроллера (рис. 11.52). Если вам лень продвигаться по списку вручную, можете ввести модель в окно поиска. Выбор завершен, вы получаете окно редактирования с готовым шаблоном, куда можете сразу скопировать текст вашей программы (рис. 11.53), если он, конечно, есть (у меня так). В окне меню вы можете выбрать режим работы: ♦ Debug для отладки; ♦ Release для готового проекта. В любом случае программа создаст необходимые папки для работы с файлами.
Рис. 11.52. Выбор модели контроллера Рис. 11.55. Добавление текста программы копированием готового варианта
СОВЕТ. Следует проверить свойства проекта, в разделе «Project» основного меню есть команда «test Properties». На первой закладке вы устанавливаете опции файлов, которые хотите получить в результате трансляции. А на последней закладке выбираете отладчик. Нажав кнопку подтверждения выбора, сохраните все, используя, например, иконку на инструментальной панели с множеством дискет. ПРИМЕЧАНИЕ. Можно запустить сборку (Build —► Build <имя вашей программы*). Если в программе есть ошибки - вы могли не добавить включение нужного файла заголовков - вы получите сообщение в окне выхода в нижней части экрана. Это полезно, когда вам нужно выяснить причины неудач. Новая версия стала мощнее, интереснее, несомненно, но меня более всего устраивает то, что теперь я могу использовать ее непосредственно с модулем Arduino. Заходим в раздел «Tools» основного меню и открываем «External Tools...». Предварительно скопировав два файла avrdude (исполняемый и конфигурации) в папку с документами, где программа создает новую папку «AVRStudio», я прописываю в окне диалога название программатора, место, где находится исполняемый файл программатора и те аргументы, которые будут переданы в программу avrdude (рис. 11.54).
Рис. 11.54. Создание нового программатора дляАУР Studio 5 Не без ложки дегтя Возможно, есть элегантное решение вопроса, но не при первом запуске. Вот эта ложка: ♦ с stkSOOvl -р ml68 -Р сотб -Ь 19200 -Uflash:w:C:\Users\ vladimir\Documents\AVRStudio\test\test\Debug\test.hex:i-C C:\Users\vladimir\Documents\AVRStudio\avrdude.conf Приходится прописывать полный путь и имя проекта. Пока работаешь с одним проектом, это не так страшно — один раз прописать все, и пользуйся на здоровье. СОВЕТ. Но при смене проекта эту строку нужно будет не забывать править. Впрочем, возможно, есть и «правильные» решения. Но теперь у вас появляется новый инструмент (рис. 11.55).
Рис. 11.55. Появление нового инструментального средства Рис. 11.56. Загрузка программы в модуль Arduino Оттранслировав программу (обратите внимание на рис. 11.54, где в диалоговом окне установлена опция «Use Output window»), вы используете команду avrdude для загрузки программы в модуль. Вывод всех сообщений в окно, определя-
Рис. 11.57. Программа AVR Studio 5 в режиме отладки емое опцией «Use Output window»), очень удобен — вы сразу можете прочитать, какие проблемы возникли при загрузке программы в модуль. И попытаться разобраться с ними, как это сделал я, поскольку далеко не сразу получил желаемый результат (рис. 11.56). В отличие от kontrollerlab отладка в AVR Studio устроена лучше (рис. 11.57). Что важно, согласитесь.
ГЛАВА 12 М® FLPROG-ёШ ГРАФИЧЕСКИЙ ЯЗЫК SB- ПРОГРАММИРОВАНИЯ ARDUINO Об этой программе мне хочется рассказать, в первую очередь, потому, что программа бесплатная, и она написана программистом, который живет и работает в нашей стране. |Где искать программу FLProg Скачать последнюю версию программы и узнать много интересного можно на сайте автора [15]. А я хочу привести только пару-тройку примеров из числа тех, что интересовали пользователей программы. ПРИМЕЧАНИЕ. Язык программы FLProg - графический, основанный на двух языках программирования промышленных контроллеров: FBD и LAD.
Программа II «Привет, мир!» II Но начнем мы этот рассказ с более простой программы, которую давно назвали «Привет, мир!». Микоконтроллер каждую минуту будет зажигать и гасить светодиод. ПРИМЕЧАНИЕ. Глава написана на основе версии 1.10.2, поэтому в дальнейшем часть написанного может устареть, но далеко не все. Итак, после установки программы, например, в Windows 10, на рабочем столе появляется ярлык программы, двойной щелчок по которому запускает FLProg. Но перед тем, как начать работу над своим проектом, вам следует воспользоваться разделом «Файл» основного меню (рис. 12.1). Рис. 12.1. Создание нового файла Происходит это потому, что предстоит сделать выбор модели модуля Arduino и языка программирования (рис. 12.2). ПРИМЕЧАНИЕ. Выбор модуля поможет сделать отмеченная кнопка справа, я язык вы отмечаете в рубрике «Язык программирования». По завершению процедуры настроек проекта на текущую работу нажмите клавишу Готово, но если ошиблись в чем-то, то можете нажать клавишу Отмена.
Рис. 12.2. Выбор модуля Arduino В рабочем поле проекта для вас заготовлена плата, на которую вы можете перенести нужные вам компоненты из «Библиотеки элементов», можете перенести переменные, входы и выходы из окна над рабочим полем. За содержанием проекта вы можете следить в окне его менеджера (рис. 12.3). ПРИМЕЧАНИЕ. В программе Arduino, вы знаете, что есть две части текста, первая относится к настройкам модуля, о вторая в бесконечном цикле выполняет программу.
Рис. 12.3. Главное окно программы Иначе при работе с программой FLProg: перенесем (рис. 12.4) из раздела таймеров генератор в рабочее поле (подцепим мышкой и перенесем)... ...щелкнем правой клавишей мышки по входу графического представления генератора (рис. 12.5), чтобы вставить константу (вход EN — это вход разрешения работы генератора)... ...и перейдем к обустройству выхода генератора: ♦ откройте раздел выходов в окне выбора; ♦ дважды щелкните по строке «Добавить выход» левой клавиши мышки; ♦ в открывающемся диалоге укажите тот выход, который вы собираетесь использовать, дайте ему имя, укажите тип вывода (рис. 12.6)... . ..после использования клавиши Готово вывод 13 появится в перечне выходов (рис. 12.7), его можно «подцепить мышкой» и перенести на рабочее поле (на выводе 13 у вас уже есть светодиод!)...
Рис. 12.4. Вставка компонента в рабочее поле И Константа Параметры [ Информацияj Тип: ВиСнеоП Значение по умолчанию 01'Z.C. □ false: (0) Рис. 12.5. Вставка константы В окне выбора вы можете: ♦ выбирать входы; ♦ выбирать выходы; ♦ создавать переменные.
Ш FL?ro9 ЧА Bci fpoeta Цкпрумакты JWCTpwm Лоношь Рис. 12.6. Оформление выхода
Все, что вам будет необходимо впоследствии, — это перенести нужное на рабочее поле. ПРИМЕЧАНИЕ. Собственно, выходы и входы, переменные и ряд других элементов - это все, что составляет вашу программу, что превратит ваш проект в готовое устройство. Если подвести мышку к левой границе выхода hello, то у него появится соединительный вывод, который вам следует, нажав левую клавишу мышки, довести до выхода генератора, где клавишу мышки отпустить. Этим вы соедините генератор с выходом модуля Arduino. Остается настроить генератор (рис. 12.8)... Рис. 12.8. Подключение вывода к элементу программы ...для чего щелкнуть левой клавишей мышки по его графическому представлению. В диалоговом окне выберем симметричный мультивибратор, зададим одну секунду в качестве паузы. Зеленый огонек для «Платы 1» показывает, что мы готовы загрузить программу в модуль Arduino. Для этого используем раздел «Проект» основного меню (рис. 12.9).
Проект (Штрутпы Настрсики Помощь $1 FLProg Файл Вид Проверить Компилировать 1©йв! Сменить контроллер Рис. 12.9. Компиляция программы Щелчком по разделу «Компилировать» запускается программа Arduino, где вам предстоит указать модель вашего модуля и порт, к которому он подключен. Осталось нажать пиктограмму загрузки на инструментальной панели программы Arduino, чтобы увидеть мигание светодиода. ПРИМЕЧАНИЕ. Для программы ISIS (Proteus) можно загрузить в Интернете библиотеку Simulino, работающую с модулями Arduino. Но это в том случае, если Proteus есть в наличии. Вам понадобится для моделирования работы hex-файл. В любом случае, если вам нужен hex-файл. Можно, например, воспользоваться разделом «Эскиз —> Проверить/ Скомпилировать» программы Arduino. Не выходя из программы, зайдите по следующему адресу (рис. 12.10). Рис. 12.10. Место, где можно найти hex-файл
ЭТО ВАЖНО! В Windows 10 (видимо, и в предыдущих версиях) проводник не слишком охотно дает добраться до нужного места. Можно поступить так: после выбора пользователя щелкнуть левой клавишей мышки по адресу, добавить обратную косую черту и ввести AppData, где уже обычным образом выбрать папку с временными файлами и найти ту, которая называется build... с длинным номером и расширением tmp. Таких папок может оказаться много, выбирайте ту, что создана последней. В ней и находится hex-файл. Загрузите его в модуль, получите моделирование работы (рис. 12.11). Рис. 12.11. Работа модуля после загрузки программы |Еще раз о кнопке и светодиоде Можно придумать ряд программ, которые можно назвать «Кнопка и светодиод». Вот одна из них, показанная на рис. 12.12. Использован элемент «И», к одному из входов которого «привязана» константа 1 (true), а к другому вход button. Вход создается аналогично тому, как создавался выход ранее. После компиляции программы ее можно проверить в программе ISIS (рис. 12.13). Осталось повторить эту программу с языком программирования LAD. Создаем новый проект, выбрав нужный модуль Arduino и язык LAD. Из свободных цифровых входов-выходов выберем вход 8. Соединим его с шиной питания (рис. 12.14).
Рис. 12.12. Создание программы с кнопкой и светодиодом Рис. 12.13. Моделирование программы в ISIS
Шина питания слева. Для завершения работы используем реле, выбрав его из раздела «Специальные реле» в окне «Библиотека элементов». В данном случае это будет реле времени. Соединим реле с выводом 8 модуля Arduino, а затем настроим его (рис. 12.15). На закладке «Надпись к блоку» можно назвать блок, скажем, светодиод. На закладке «Параметры» двойной щелчок по выводу 13 входов-выходов контроллера осуществит привязку реле к Pinl3. Этим завершим настройку, нажав на клавишу Готово (рис. 12.16). Программа готова к загрузке в модуль. Вы можете создать свой вариант программы, что будет не только полезно, но и принесет вам уверенность в собственных силах. Рис. 12.14. Шина в варианте языка LAD (3S Реле времени х ’ Параметры : Надпись к блоку | Информация ! Рис. 12.15. Настройка вывода
Рис. 12.16. Завершение создания программы Датчик II и светодиод | Задача №1: если температура меньше заданной, светодиод (он же обогреватель) включается. Есть такой датчик температуры DS18B20, весьма хороший датчик. Что светодиод не хуже в качестве исполнителя наших тестовых программ, это вы и сами знаете. Осталось посмотреть, насколько просто в программе FLProg заставить их подружиться. Где искать датчики, как не в разделе «Датчики» (рис. 12.17). ЭТО ВАЖНО! Почему DS18B20? Этот датчик работает по протоколу 1-wire, что может напугать начинающего. Но (рис. 12.18)...
Рис. 12.17. Раздел датчиков программы FLProg Рис. 12.18. Диалоговое окно настройки датчика Настроим датчик, открыв диалоговое окно двойным щелчком левой клавиши мышки по нему. Первой используем клавишу Новая, где в новом диалоге выберем вывод 10 для подключения датчика. Когда вы нажмете клавишу Создать, вы получите подключение датчика (его вывода данных) к Pin 10 модуля Arduino. Осталось заполнить остальные данные (рис. 12.19) и нажать клавишу Готово (заметьте, что адрес датчика в шестнадцатеричном виде).
Поскольку мы собираемся сравнивать показания датчика с заданной температурой, нам потребуется компаратор, который можно найти в библиотеке в разделе «Сравнение» (рис. 12.20). На вход И компаратора нужно подать константу (тип константы выберите float), а второй вход соединить с датчиком. К выходу подключим вывод 13, на котором у нас светодиод. При Рис. 12.20. Добавление компаратора в рабочее поле программы
Рис. 12.21. Константа на входе компаратора настройке свойств компаратора (диалог открывается двойным щелчком) выберем условие 11<12 (рис. 12.21). После загрузки программы в модуль Arduino светодиод на плате загорается (обогреватель включается). Нагрейте датчик (достаточно взять его корпус двумя пальцами), светодиод погаснет, через какое-то время он вновь зажжется (рис. 12.22). ПРИМЕЧАНИЕ. В приведенном примере есть одно слабое место, которое может вызывать у вас затруднение -это ввод адреса датчика DS18B20. Купив для экспериментов один-два датчика, вы не найдете в их маркировке нужных данных. Чтобы получить адрес, вам следует скачать последнюю версию библиотеки для Arduino, которая называется Рис. 12.22. Проверка работы программы в «живом» виде
Имя Дата изменения Тип Размер Da IhsTemperature 01.10201011:05 Палка с файлами , OneWire 17.02.2010 9:19 Папка с файлами □ README 17.0220109:21 Файл Рис. 12.25. Содержание распакованных библиотек DallasTemperature, и добавить ее, используя возможности программы Arduino. Найти последнюю версию (или версии для разных версий программы Arduino) можно здесь [16]. В данный момент версия называется TCL 3.6.0, после загрузки вы получите архивированный файл DallasTemperature_360.zip. Вы можете распаковать его и добавить в библиотеки Arduino, а может добавить и без распаковки. Содержание распакованного файла выглядит так (рис. 12.23). Добавьте обе библиотеки, то есть, и DallasTemperature, и OneWire. Все это вы можете проделать после запуска компиляции программы FLProg, если вместо ввода адреса укажете массив, которому дадите имя (рис. 12.24). телферагуры сер*»» DS Параметры Надпись к блоку ij Информация ; Шина OrteWre | Шина OneWire и~ П v I ОГ«эдивато каждые! 1
Manage Libraries... 3 Вход ы фЗ Выходы 5>* 3 Переменные pinMode (13, OUTPUT); DS18B20 One Wire jxkKUI&H vtnsigned long __di8X2xlTti « OUL; float _d!3xZxlG « 0.0'0; void setup(j Пгмгга: । 1Щ1М*МПНМф f Pf^ j Arduino 1.63 I Файл Правка Эскиз Инструменты Помощь Проверить / Скомпилировать Ctrl+R Показать папку эскиза Ctrl* К Добавить файл. void loop() Arduino/Avr libraries j EEPROM Esplora GSM LiquidCrystal Robot Control Robot Motor SO Servo SoftwareSenal SpecebrewYun SPI Stepper Temboo TFT WiFi Wire Рис. 12.25. Добавление библиотеки в программе Arduino Используя теперь в основном меню «Проект —► Компилировать», вы перейдете к программе Arduino, где можете добавить библиотеку (рис. 12.25). После добавления библиотек, вы получите доступ к примерам программ, работающих с датчиком DS18B20. Используйте (Файл —► Образцы —► Dallas Temperature) программу Tester. Загрузив ее в модуль Arduino, вы можете наблюдать на мониторе последовательного порта результат (рис. 12.26). Попутно вы проверите и правильность подключения датчика к модулю Arduino. Если датчик подключен неправильно, ни адреса, ни температуры вы не увидите. ПРИМЕЧАНИЕ. Прочитав адрес датчика, запишите его и храните вместе с датчиком, он может вам понадо-биться и позже.
@ COM4 - □ X jf || Отпран се:Dallas Temperature IC Control Library Demo Locating devices... Found 1 devices. Parasite power is: OFF ........ ............ Found device 0 with address: |281ЕВ2ЕВ0300009В| Setting resolution to 9 Resolution actually set to: 9 Requesting temperatures...DONE Temperature for device: 0 Temp C: 23.50 Temp F: 74.30 Requesting temperatures...DONE Temperature for device: 0 Temp C: 23.50 Temp F: 74.30 Requesting temperatures.. .DONE Temperature for device: 0 Temp C: 23.50 Temp F: 74.30 Requesting temperatures.. .DONE < f/j AffironpoKoyms He найдем конец строки v 9600 бод Рис. 12.26. Наблюдение с помощью монитора порта Заполнив массив данными полученного адреса, вы получите окончательное решение. Осталось повторить программу на языке LAD. Практически все операции повторяют то, что было сделано раньше, только вместо компаратора следует выбрать реле сравнения (рис. 12.27). Загрузив программу после компиляции, вы получите тот же результат, что и в прошлый раз: светодиод горит, вы нагреваете датчик, он гаснет, а через какое-то время зажигается вновь.
И вновь, если подготовиться заранее, то есть, выяснить адрес датчика, то создание программы займет меньше времени, чем чтение этого рассказа о том, как это сделать. И вновь, если вы взглянете на текст программы, который вам нужно было бы написать на языке, используемым в программе Arduino, вы оцените, сколько сил вы сэкономили, используя программу FLProg. |Два датчика и светодиод Задана №2: днем в помещении управлять обогревателем, а в ночное время не использовать обогрев. Используя предыдущую, уже проверенную программу с датчиком температуры, мы ее модифицируем для работы с двумя датчиками. Практика использования предыдущих разработок — это обычная практика в любой инженерной работе, и пренебрегать ею не следует. В качестве второго датчика используем доступный в программе FLProg датчик ВН1750. Загрузим предыдущую программу (надеюсь, вы ее сохранили). Удалим элемент «светодиод». Добавим из базовых элементов библиотеки программы FLProg компонент AND, который включим между схемой сравнения и светодиодом (добавим его еще раз). Для второго входа элемента «И» используем переменную, которую назовем Light, булева типа. В данный момент программа выглядит так, как показано на рис. 12.28. Для второго датчика используем вторую плату (рис. 12.29). На второй плате соберем программу, похожую на предыдущую (рис. 12.30). Теперь, когда освещенность в комнате достигнет заданного уровня, переменная Light примет значение true, а элемент AND позволит датчику температуры управлять обогревателем (светодиодом в эксперименте).
ПРИМЕЧАНИЕ. К слову, датчик освещенности работает по протоколу I2C, то есть, вы познакомились с работой двух протоколов, даже не заметив этого. Но очень полезно для вас прочитать, например, в wiki о работе с этими протоколами. Рис. 12.28. Первая часть программы Рис. 12.29. Добавление второй платы в программу
Рис. 12.30. Сборка второй части программы Это пригодится в будущем. И будет полезно самостоятельно повторить программу на языке LAD. Если у вас есть датчик освещения ВН1750, вы можете проделать эксперимент, проверив программу. Если у вас нет датчиков, но есть, скажем, диод и фоторезистор, вы можете модифицировать эксперименты, используя два аналоговых входа модуля Arduino для последней программы, и один для предыдущей. При использовании диода в качестве датчика температуры, как правило, применяют, скажем, операционный усилитель. Проблема в использовании диода без усиления сигнала заключается в маленьком приросте напряжения на диоде при изменении температуры — это около 3 мВ/градус. Для подтверждения этого проведем моделирование в программе Qucs для двух значений температуры: 24 и 25 градусов по Цельсию (рис. 12.31).
моделирование на постоянном токе Температура 24 градуса О 1N4148 1 3Z " Рис. 12.31. Моделирование в программе Qucs АЦП модуля Arduino использует 10 бит, то есть, разрешение 5/1024 = 0,005 В. Таким образом, нам следует нагреть диод на 2...3 градуса. При измерении напряжения, если не преобразовать полученное значение к привычному для нас виду, мы получим целое число. Можно «прикинуть», каким будет это число. Если напряжение на диоде составляет 0,650 В, то мы «увидим» число порядка 130. Многое будет зависеть от конкретного типа диода. Однако, включив диод через резистор 5...10 кОм, как показано на рис. 12.31, подключив его к аналоговому входу, мы постараемся определить нужное нам число, чтобы позже использовать его в программе при сравнении с константой. Соберем схему. Создадим новый проект, добавим вход, тип которого определим как аналоговый, и назовем его diod; для входа зададим номер контакта 0. Добавим в программу переменную типа integer, которую назовем, скажем, v.temp. Вход соединим с переменной, а переменную отправим в UART. Для этого из предлагаемых компонентов выберем «Отправка переменной в UART». Свойства этого элемента настроим так, выбрав порт, как показано на рис. 12.32. Программа должна выглядеть так, как показано на рис. 12.33. После компиляции и загрузки программы в модуль Arduino обратимся к монитору последовательного порта программы
Отправка переменной в UART X I П<ЖИТ^»Г^Надписъ к блоку ; Информация i ____________________ _________________ Рис. 12.32. Диалог выбора и настройки порта UART
52 Мрнвтар SanatfW ОЕС HEX ВмЧ • 45 45 Л 3 1 2 44 49 М; 11W 11Ш11 ТИШ 11Ж1 1ШН 1О bi паи ней «ж п» ши «а .'И 1115121 1Ю1 1115521 3 1 49 i Send ASCII ] ^enlCtofSendHEx' Send BIN Рис. 12.34. Наблюдение на мониторе порта за отправкой данных 02 •М 31 ж Ш 01 31 W 31 31 35 03 01 . одаоою й оаижн CW110110 : ooooooii -оос:хз1 ' €9110001 «xxmio (МИШИ 10 'П001 00110101 №001 00110001 FLProg (Инструменты —> Монитор Сот порта). Настройка порта сводится к выбору виртуального порта, к которому подключен модуль Arduino. Ниже это COM4. Отмеченная кнопка подключает порт, и вы увидите (рис. 12.34)... Начальное значение — 118, после разогрева диода пальцами значение уменьшается до 115. На мониторе можно видеть и ряд служебных символов, но они нам пока не нужны. Чтобы не возвращаться к этому вопросу, соберем аналогичную схему для датчика освещенности из резистора и фоторезистора. Напряжение на фоторезисторе будем измерять аналоговым входом А1 (номер контакта в программе 1). Переделаем программу, чтобы повторить наблюдение за освещением (полезно повторить программу, но можно и исправить). Если вид полученных данных не в полной мере ясен, как показано ниже, можно выделить значение, нажать правую клавишу мышки и скопировать значение, которое вставить, например, на страницу Word (рис. 12.35).
монитор SerialPoit Порт ___Скорость |<Я|СОМ4 g Э600 ASG_________________ 01 31® 3'1®1 24® Г10В1 DEC HEX Do it Ctrl+D Print ft Ctri4₽ Inspect ft Ctrl+Q * Debug ft Cfrl+8 Explain Ctrt4€ •П Undo Ctrl+Z f* Redo Shtft+Ctrl+Z ----------—---------------------------t>3 Л Cut Cffl+X L, BIN_ I 001101)01 j 00000011 00000001 00110001 00000010 00110010 00110001 00000011 00000001 00110001 00000010 00110010 00110100 00000011 Oh -Opv Ctrl+C jfv Paste Ctrl+X >2 Send ASCH | Send HEX Send BIN | Puc. 12.35. Выпадающее меню Хорошо освещенный фоторезистор даст значение порядка 30. Затемненный, в свою очередь, около 500, но это будет зависеть от конкретной модели датчика. Задача №3: включать обогреватель в дневное время суток; если температура превышает заданный уровень, обогреватель выключается; если температура опускается ниже заданного уровня, обогреватель включается (гистерезис). Мы знаем, как работать с входами и выходами. Создаем набор, показанный на рис. 12.36. И мы знаем, как создать переменные (рис. 12.37). Программу выполним на разных платах, начиная с показанных на рис. 12.38. На плате 1 с аналоговым входом, куда подключен диод, мы сравниваем напряжение на входе с заданным значением. Если оно больше (сопротивление диода падает при нагреве, падение
ЕЫЫ ?________________ __ Ф-В Входы г =* < Аналоговый 4bd ~ Pin О : Н®- <Аналоговый> light ~ Pinl j 'Добавить вход : Л Выходы [ <Цифровой> светодиод = Pin 13 I ' j» Добавить выход НИИ ( Добавить выход В-В Переменные I <Боо1езп> hot - false г ° <Всю1еап> light on - false \ <5‘оо1еап> off ~ false г'^ <Booiean> on = false 1 $=*• Добавить переменную Рис. 12.36. Выбор входов и выходов для программы Рис. 12.37. Создание переменных Рис. 12.38. Начало работы над программой напряжения на нем уменьшается, и наоборот) переменная «оп» становится «true». На плате 2 переменная «off» становится «true», когда падение напряжения на диоде становится меньше заданного значения (рис. 12.39). Плата 3 предназначена для формирования переменной «hot», которая будет включать и выключать обогреватель. Переменные «on-off» принимают значения 10,01 и 00 (последнее в промежутке между уровнями). Эти значения будут переключать триггер SR. Плата 4 формирует переменную «light_on», которая принимает значение «true» при освещении.
Рис. 12.39. Еще две платы в программе Рис. 12.40. Последняя плата, которая нужна в программе Наконец, плата 5 определяет (рис. 12.40), когда обогреватель работает (днем), а когда он выключен (ночью). Программа работает на макетной плате вполне адекватно. А в качестве упражнения вы можете повторить программу на языке LAD. Создавая программы, пусть и простые, очень важно использовать пояснения. Почти каждый диалог, которым мы пользуемся при настройке компонентов, имеет раздел, показанный на рис. 12.41. Это может быть и надпись к блоку. Комментарии и надписи помогут вам вспомнить назначение элементов и порядок работы с программой. Но особенно они будут полезны тем, кто будет пользоваться вашей программой.
Рис. 12.41. Диалог датчика температуры Рис. 12.42. Запись имени переменной кириллицей
FLProg позволяет ввести имя переменной кириллицей (рис. 12.42). ЭТО ВАЖНО! Будьте осторожны - далеко не все программы поддерживают кириллицу, а привычка сохраняется. Даже папка, где вы храните свой проект, если ее назвать «Мой проект», может стать причиной отказа в компиляции проекта для некоторых программ. Вам не обязательно знать, например, английский, достаточно назвать переменную, связанную с датчиком, «datchik». Но, главное, проверьте все эти особенности не в сложном проекте, а в самом простом, как проект «Привет, мир!».
ГЛАВА 13 ARDUINO И ПЛАТА РАСШИРЕНИЯ ETHERNET Для увлеченных людей время летит незаметно. И вчерашний школьник сегодня стал студентом. Вчера, будучи новичком, он задавал вопросы, на которые мне приходилось искать понятный и простой ответ, а сегодня мне приходится выступать в роли новичка, задающего вопросы. И мне не стыдно обращаться за помощью. Так что в этой главе новичок - это я. Когда в дверь стучится проблема Новичок: Есть проблема «с поуправлять». Недорого. Хорошо бы из разных мест, и разными людьми, но, конечно, не одновременно. Что бы придумать? Вы же сами рассказывали про Arduino. Откройте примеры в программе Arduino (рис. 13.1). Новичок: Я видел, конечно, но, признаться, не связывал напрямую с Arduino. А стоило?
Ф sketch_sep26d i Arduino 132 o x I Файл] Правка Скетч Ияструыешъз Гитмтр» Новый Ctri+N Открыть... Ctrl+0 О»»рыть недавние Пагша CO скетчами Закрыть .Тиранить мм ранить как... CtrkW Ctrf*S? ctti*ShlkB Д Встроенные Примеры Otiasks OZ.fhgrU! ОЗЛлакд 0СС^йкГпипка{«зк OXCfrntrol ObSensors > > * > Настройки страницы Ctrk Shifts P Печать ClrkP Настройки Ctrl* Comma ВЫХОД £M*CM: O7.D»splay OSStnngs O9.USB 1O.StarterKft_Bas»cKH VlArrtutnoISP > Примерыдля лки&ой'гшаты ArdwmoCktud Bridge-tsplora WM Примеры для Arduirw/Genutna Uho Temboo Firmata GSM LiquidCrystal SB «ян Adv an cedC hatServer Baromet ncPressureWebServer ChatServer DhcpAddressPrinter OhcpC hat Server TeinetCiient Od^pCIient WPSsrxiReceiMcStor^li WOent WebCIrentRepeatfcog Puc. 13.1. Примеры в программе Arduino Без сомнений. Вы сами писали про платы расширения для Arduino, поищите Ethernet-шилд в Интернете, купите и решите проблему. Новичок: Мне казалось, что Ethernet, если им заниматься на уровне микроконтроллера, это слишком сложно. Я неправ? И да, и нет. В теории это выглядит не так просто, как RS232, но разобраться можно. Вот приведу пару страниц из моего старого конспекта.
Немного теории II о сетевой работе II Каждая сетевая карта при изготовлении снабжается уникальным МАС-адресом (МАС, Управление доступом к среде), но при включении в сеть, локальную или при подключении к провайдеру Интернета, ей присваивается IP-адрес, который устройство запоминает. ПРИМЕЧАНИЕ. Что и понятно - компьютеров много, а для обращения к конкретному компьютеру нужен адрес. Поскольку обмен данными в сети достаточно многообразен, здесь и текстовые файлы, и изображения, и поиск в базах данных и т. п. Следует полагать, что и их «упаковка» гораздо сложнее, чем при работе COM-порта. Обмен данными описывается моделью OSL Википедия определяет процесс в этой модели как семиуровневый (рис. 13.2). Среда передачи данных, как указано в примерах таблицы (рис. 13.2), может быть разной: когда-то широко использо- Уровень (layer) Тип данных (PDU) Функции Примеры Host layers Уровень 7 Прикладной (application) Данные Доступ к сетевым службам HTTP, FTP, SMTP, RDP, SNMP, DHCP Уровень 6 Представительский (presentation) Представление и шифрование данных ASCII,EBCDIC, JPEG Уровень 5 Сеансовый (session) Управление сеансом связи RPC, PAP Уровень 4 Транспортный (transport) Сегменты (segment)/ Дейтаграммы (datagram) Обеспечение надежной передачи данных от отправителя к получателю TCP.UDP, SCTP, PORTS Media layers Уровень 3 Сетевой (network) Пакеты (packet) Определение маршрута и логическая адресация IPv4, IPv6, IPsec, AppleTalk Уровень 2 Канальный (data link) Биты (bit)/ Кадры (frame) Физическая адресация PPP, IEEE 802.22, Ethernet, DSL, ARP, L2TP, Network Cards Уровень 1 Физический (physical) Биты (bit) Работа со средой передачи, сигналами и двоичными данными USB, витая пара, коаксиальный кабель, опт. кабель Рис. 15.2. Уровни модели OSI
вался коаксиальный кабель, сегодня часто используют оптический кабель. Видимо, и сигналы могут быть разными. В нашем случае при использовании витой пары сигналы представлены разностным напряжением. Стандартными типами сетевых интерфейсов, относящимися к физическому уровню, являются: V.35, RS-232, RS-485, RJ-11, RJ-45, разъемы AUI и BNC. На втором уровне обеспечивается взаимодействие сетей, определяются ошибки, если они есть, и происходит формирование кадров данных. На этом уровне как подуровень работает МАС. С этим уровнем работают коммутаторы, мосты и другие устройства. На этом уровне осуществляется преобразование IP-адресов в МАС-адреса протоколом ARP. Третий, сетевой уровень, отвечает за пути передачи данных. Он преобразует логические адреса и имена в физические. Протоколы этого уровня маршрутизируют данные от источника к получателю. Примерами протокола этого уровня являются IP, IPv4, IPv6. Четвертый уровень — это транспортный уровень. Уровень, определяющий надежность передачи данных от отправителя к получателю. Степень надежности может быть разной. Например, протокол UDP ограничивается контролем целостности данных в рамках одной датаграммы, a TCP обеспечивает надежную непрерывную передачу данных. На пятом уровне отслеживается сеанс связи между двумя узлами, обеспечивая длительную связь. Шестой уровень связывает вышестоящий прикладной уровень с остальными уровнями, передавая на пятый уровень запросы приложений, полученные с прикладного уровня. На этом уровне запросы преобразуются в формат для передачи по сети, а полученные из сети данные преобразуются в формат приложений. Седьмой уровень — это и есть уровень приложений. Протоколы прикладного уровня: RDP, HTTP, SMTP, SNMP, POP3, FTP, XMPP, OSCAR, Modbus, SIP, TELNET и другие. О протоколах. В сеансе связи всегда участвуют два устройства, например, два компьютера. Поэтому каждый уровень модели OSI снабжается своим протоколом: устройства, реализу-
Рис. 13.3. Протоколы сетевой работы ющие модель, должны работать согласовано, что и управляется протоколами работы разных уровней. Это показано на рис. 13.3. Новичок: Про МАС-адрес я знаю давно, но, признаюсь, не знал, что это управление доступом к среде. И сколько времени у меня займет, чтобы во всем этом разобраться? Если вы намерены сдавать экзамен за какого-нибудь нерадивого студента, то много. Но можно подойти к этому опытным путем. Проделать ряд опытов с Arduino. ПРИМЕЧАНИЕ. Следуя совету «бывалого», я обзавелся Ethernet-шилдом. Понадобилось и дополнительно кое-что приобрести, о чем я расскажу по ходу дела. Пополнение II в Arduino-домике II Дополнительная плата легко соединяется с модулем Arduino, образуя подобие «электронного бутерброда» (рис. 13.4). Мой опыт работы с Интернетом ограничивается пользовательским интересом, за рамки которого приходится выходить очень редко и очень недалеко. Я знаю, что вводя в web-браузере
адрес страницы www.yandex.ru, я попадаю в привычную для меня среду: ♦ можно посмотреть почту, если у вас есть почтовый адрес на Яндексе; ♦ можно посмотреть погоду или программу телевидения; ♦ можно поискать в Интернете что-то, что в данный момент Рис. 15.4. Соединение Arduino с платой расширения вызывает интерес. Да, я знаю, что наш Интернет-проводник — это программа-клиент, работающая на нашем компьютере. Она получает данные с отдаленного web-сервера Яндекса и преобразует их в привычную для нас форму. Можно посмотреть на вид страницы, которые получает клиентская программа (рис. 13.5). Яндекс Рис. 13.5. Страница Яндекса в Интернете, получаемая с сервера
Но, и я это понимаю, сколько ни вглядывайся в подобные страницы, понять то, как превратить модуль Arduino в web-сервер, не получится. Поэтому я попросил прислать мне листинги программ для опытов, получив которые (не знаю, его это тексты, или он откуда-то их взял), я приступил к опытам. Опыт 1. Arduino и Ethernet | #include <SPI.h> #include <Ethernet.h> EthernetServer server(80); // Вместо выделенных жирным шрифтом значений // укажите значения для ваших устройств и сети byte mac [] - {0x00, ОхАА, ОхВВ, OxCC, OxDE, 0x01); IPAddress gateway(192,168,0,1); IPAddress subnet(255, 255, 255, 0); IPAddress ip(192,168,0,101); void setup() { // Запускаем модуль Ethernet,сервер и монитор порта Ethernet.begin(mac, ip, gateway, subnet); server.begin(); Serial.begin(9600); } void loop() { // Ждем подключений от клиентов EthernetClient client = server.available(); if (client) { while (client.connected()) { if (client.available()) { char thisChar = client.read(); Serial.write(thisChar); } }// Закрываем подключение: client.stop(); }
Модуль Ethernet я подключаю к своему домашнему роутеру, тем самым сделав его частью домашней сети. Для подключения используется патч-корд, который можно купить (рис. 13.6) или сделать самому из витой пары, но в последнем случае понадобятся специальные обжимные клещи для разъема RJ45, и два Рис. 13.6. Патч-корд таких разъема. Для экспериментов достаточно кабеля длиной 0,5 м. В верхней части листинга программы есть фраза о выделенных адресах, которые следует заменить собственными. С МАС адресом модуля Ethernet проще, этого вшитого адреса у модуля нет, поэтому можно использовать тот, что в программе. А для определения IP-адреса после того, как оба модуля, Ethernet и Arduino, подключены: ♦ первый патч-кордом к роутеру; ♦ второй своим кабелем к USB-порту... ...для определения адреса можно воспользоваться следующим приемом. Если вы не знаете IP-адреса своего компьютера, то в командной строке введите следующую команду: ipconfig/all.Вы получите все данные Ethernet карты вашего компьютера, включая тот IP-адрес, который ему автоматически присваивает роутер. У меня этот адрес 192.168.0.105, и сейчас в сети только мой компьютер. Проверяя командой ping в командной строке этот адрес, я получаю временные данные отклика. Записав в листинг адрес 192.168.0.101и остальные адреса, загрузив программу в модуль Arduino,я перебираю все адреса от 100 до 105, что позволяет увидеть отклик на адрес 192.168.0.101 (рис. 13.7). Если у вас остались сомнения, отключите патч-корд от Ethernet-шилда и повторите команду ping по адресу 101, вы не получите отклика. Маска подсети, как у всех домашних сетей, остается той же, что в примере, а адрес шлюза вы могли прочитать после выполнения команды ipconfig/all, где он называется «Основной шлюз».
Рис. 13.7. Выполнение команды ping из командной строки ЭТО ВАЖНО! Если у вас дома к роутеру подключены другие компьютеры, например, ноутбук жены или планшет сына, а роутер распределяет адреса автоматически, адрес модуля Ethernet может измениться. Случись это, вы будете вынуждены еще раз поискать новый адрес, которые модулю при-своил роутер. Теперь у вас есть все необходимые данные для того, чтобы запустить программу Arduino, ввести текст программы, загрузить программу в модуль Arduino и посмотреть, что из этого выходит (рис. 13.8). Ответ приходит тогда, когда вы заходите на Arduino-сервер из браузера по его адресу. Адрес у вас может быть другим, а в браузере вы ничего, наверное, пока не увидите. Чтобы увидеть в браузере отклик от web-сервера, следует несколько изменить программу, добавив переменные и изменив основной цикл так, как показано ниже:
Рис. 13.8. Ответ от модуля Ethernet в окне монитора char thisChar; char lineLength; void loop(){ // Ждем подключений от клиентов EthernetClient client = server.available(); if (client) { Serial.printin("Got a client"); String requestLine = ""; while (client .connectedO ) { if (client.available()) { char thisChar - client.read(); // Полученные перевод строки и пустая линия // запроса означают конец запроса: if (thisChar == '\n' &&lineLength< 1) { // Посылаем стандартный заголовок ответа HTTP: makeResponse(client); break; } // Перевод строки или возврат каретки означает, // что мы в конце строки: if (thisChar == '\n' I I thisChar =- '\r') { lineLength = 0; } else { // Для любого другого символа, увеличиваем // длину строки: lineLength++;
} } // Даем браузеру время, чтобы получить данные: delay(1); // Закрываем подключение: client.stop(); } } А в конец программы добавляем реализацию метода: void makeResponse(EthernetClient thisClient) { thisClient.print("HTTP/1.1 200 OK\n"); thisClient.print("Content-Type: text/html\n\n"); thisClient.print("This is the Arduino! </headxbody>\n") ; thisClient .printin ( "</bodyx/html>\n" ) ; } ЭТО ВАЖНО! При копировании программы из обычного текста будьте внимательны - текстовые процессоры часто приводят текст к виду для печати, заменяя одни символы другими. После вставки копии этого текста в редактор программы Arduino может появиться значительное количество ошибок, связанных с этой особенностью, например, кавычки, открывающие и закрывающие «строку», очень отличаются в этой фразе и в приведенном выше тексте. После устранения всех недоразумений можно увидеть отклик от сервера в браузере (рис. 13.9). Теперь наш Arduino-сервер такой же настоящий, как любой другой в Интернете. Впрочем, можно было воспользоваться и примером из программы Arduino, который показан на первом рисунке. Результат не хуже (рис. 13.10).
Рис. 13.9. Окно монитора последовательного порта и браузера о Л I Игиглаг. ! ir Й 4. Й U Su^getted Srte» Е Welcome to Internet ф Вмдео ф Диск Керты ☆ Коллекция analog input 0 is 313 analog input 1 is 295 analog input 2 is 328 analog input 3 is 326 analog input 4 is 294 analog input 5 is 296
Опыт 2. Ethernet-шилд и управление || Одной строки отклика с web-сайта едва ли достаточно для практического применения. В качестве примера можно привести программу, которая позволяет управлять светодиодом на плате Arduino. Напомню, что вместо светодиода можно использовать реле, контактами которого включать, скажем, обогреватель. Следующий листинг выглядит так: #include<SPI.h> #include<Ethernet.h> byte mac [] = {OxDE, OxAD, OxBE, OxEF, OxFE, OxED}; // MAC адрес byte ip [] = {192, 168, 0, 2); // IP адрес (В браузере вводим 192.168.0.2) EthernetServer server(80); int numPins - 4; int pins [] = {2, 3, 4, 5); // Выводы для реле int pin£>tate [] = {0, 0, 0, 0}; // Состояние выводов void setup() { // Изначально выключаем все реле for (int i - 0; icnumPins; i++) { pinMode(pins [i], OUTPUT); digitalWrite(pins [i], 1) ; } Serial.begin(9600) ; Ethernet.begin(mac, ip); server.begin(); } void loopO { EthernetClient client = server.available(); if (client) { // Проверяем, подключен ли клиент к серверу
while (client.connected()){ // Проверяем, идет ли запрос к серверу-int dataCount = client.available(); if (dataCount> 0){ // Считываем данные передаваемые серверу // от клиента (браузера) for (int i = 0; i<dataCount; i++){ char ch = client.read(); // Если данные передаются, то они будут переданы // POST запросом, который начинается с символа 'Р' if (i == 0 &&ch != 'Р')break; if (ch == '\n' &&i<dataCount - 1){ // Находим строку, в которой содержатся // передаваемые данные char chNext = client.read(); // Формат строки r2=on&r3=on&r4=on // (Пример, если нужно включены 2,3,4 реле) if (chNext == 'r'){ // Выключаем все реле pinState pinState pinState pinState [0] = 0; [1] = 0; [2] = 0; [3] = 0; // Считываем первый номер реле, // который нужно включить char relayNum = client.read(); pinState [relayNum - '0'] = 1; Serial.write(relayNum); // Считываем вспомогательную информацию (=on&) relayNum = client.read(); relayNum = client.read(); relayNum - client.read(); relayNum = client.read(); // Пока есть данные об остальных реле, // считываем и заносим в массив pinState while (relayNum != -1){ relayNum = client.read(); relayNum = client.read(); pinState [relayNum - '0'] = 1; Serial.write(relayNum); relayNum = client.read();
relayNum - client.read(); relayNum = client.read(); relayNum = client.read(); } } else{ // Если не было передано данных, // то выключаем все реле pinState [0] = 0; pinState [1] = 0; pinState [2] - 0; pinState [3] - 0; } } } } // В соответствие с переданными данными включаем реле for (int i = 0; i< 4; i++) { digitalWrite(pins [i], (pinState [i] ) ; } // Выводим HTML страницу, на которой пользователь // может включить или выключить нужные ему реле client.printIn("HTTP/1.1 200 OK"); client.printIn("Content-Type: text/html"); client.printin(); client.printIn("<html>"); client.printin("<head>"); client.printin("<title>Zelectro. Relay + Ethernet shield.</title>" ) ; client.printIn("</head>"); client.printin("<body>"); client.printin("<h3>Zelectro. Relay + Ethernet shield.</h3>"); client.printin("<form method='post'>"); client.print("<div>Relay 1 <input type='checkbox' ") ; if (pinState [0] == 1) client. print("checked"); client.printIn(" name='rO'></div>"); client.print("<div>Relay 2 <input type='checkbox' ");
if (pinState [1] =- 1) client, print("checked"); client .printIn (" name='rl'x/div>"); client.print("<div>Relay 3 <input type='checkbox' "); if (pinState [2] == 1) client, print("checked"); client.printIn(" name='r2'></div>"); client.print("<div>Relay 4 <input type='checkbox' "); if (pinState [3] == 1) client, print("checked"); client .printin ( " name=,r3'x/div>") ; client.printin("cinput type='submit' value='Refresh'>"); client.printin("</form>"); client.printIn("</body>"); client.printin("</html>"); client.stop(); } } } После загрузки программы, после подключения браузера можно увидеть то, что показано на рис. 13.11. В Zeted.ro Relay t Ether п X + □ X О 19Z168.10.116 tp О Suggested' Sites, Е Wcome to internet Йидео Диас X/ Zelectro. Relay + Ethernet shield. Relay 1 □ Relay! □ Relay 3 □ Relay 4 □ Puc. 13.11. Управление выводами Arduino через web-браузер
ПРИМЕЧАНИЕ. Правда, все реле оказываются включенными, а для их выключения следует отметить галочками все окошки и нажать кнопку Refresh. Если вас это не устраивает, постарайтесь переделать про-грамму - это будет хорошей практикой. Заголовок Zelectro натолкнул меня на мысль поискать этот сайт [21]. И, должен вам сказать, много интересного на нем обнаружилось (рис. 13.12). Не знаю, каку вас, а у меня, когда я читаю подобные статьи, чешутся руки начать что-нибудь делать. Но пока... > О (лГ «tectrwc *Й| М, ’*• (> Svcgwt.d-..-Л Л •: Уг -ft ймлишм & Ожцж -ЙГ Ms’s»»* Рис. 13.12. Сайт с рассказом о разных дополнительных модулях к Arduino
Опыт 3. Ethernet-шилд, управление и считывание данных В качестве датчика температуры в следующем опыте используется DS18B20, о котором упоминалось в главе 12 (Датчик и светодиод). #include <Ethernet.h> #include cOneWire.h> // Конфигурация Ethernet byte mac [] = {OxDE, OxAD, OxBE, OxEF, OxFE, OxED); IPAddress ip(192, 168, 0, 103); // Используется стандартный порт HTTP EthernetServer server(80); byte wirePin - 7; OneWire ds(wirePin); byte addr [8]; byte ledPin = 5; boolean isLedOn = false; unsigned long lastUpdate = 0; float temperature = -100.0; void setup(void) { // Необходимые настройки pinMode(ledPin, OUTPUT); Ethernet.begin(mac, ip); server.begin(); connectToSensor(); } void loop(void) { updateTemperature(); EthernetClient client - server.available(); if (client) { String request; boolean currentLinelsBlank - true; boolean requestLineReceived = false; while (client.connected()) { if (client.available()) {
char с - client.read(); if (с == '\n' &&currentLineIsBlank) { // извлекаем путь из запрашиваемой строки request = request.substring( request.indexOf(' ') + 1, request.lastlndexOf(' ')); if (request =="/") { successHeader(client); generatePage(client); } else if (request == "/switch-on") { digitalWrite(ledPin, HIGH); isLedOn = true; redirectHeader(client, "/"); } else if (request == "/switch-off") { digitalWrite(ledPin, LOW); isLedOn = false; redirectHeader(client, "/"); } ‘break; } if (c == '\n') { currentLinelsBlank = true; if ((requestLineReceived) { requestLineReceived - true; } } else if (c != '\r') { if ((requestLineReceived) { request += c; } currentLinelsBlank = false; } } } delay (1) ; client.stop(); } }
// Для работы нужны дополнительные функции, // которые записаны далее void successHeader(EthernetClient client) { client.printin("HTTP/1.1 200 OK"); client.printIn("Content-Type: text/html"); client.printin("Connnection: close"); client.printin("Refresh: 5"); // обновлениестраницыкаждые 5 секунд client.printIn(); } void redirectHeader(EthernetClient client, String path) { client.printin("HTTP/1.1 302 Moved Temporarily"); client.printin("Content-Type: text/html"); client.printin("Location: " + path); client.printIn("Connnection: keep-alive"); client.printIn(); } //создание страницы сервера void generatePage(EthernetClient client) { client.printIn("<!DOCTYPE HTML>"); client.printin("<html>"); client.printIn("<head>"); client.printin(" <title>Server</title>"); client.printIn("</head>"); client.printin("<body>"); String ledStatus = isLedOn ? "ON" : "OFF"; client.printin(" <hl>Led is " + ledStatus + "</hl>"); if (temperature 1= -100.0) { client.printin(" <hl>Temperature is " + floatToString(temperature, 100) +"</hl>"); } client.printin(" <a href=\"/switch-on\"> Switch ON</a>"); client.printin(" <br />"); client.printin(" <a href=\"/switch-off\"> Switch OFF</a>"); client.printIn("</body>"); client.printin("</html>");
// Преобразование данных с плавающей точкой в строку String floatToString(float value, byte precision) { int intVal = int(value); unsigned int frac; if (intVal>= 0) { frac = (value - intVal) * precision; } else { frac = (intVal - value) * precision; '} return String(intVal) + + String(frac); } void updateTemperature() { // обновление температуры unsigned long time = millisO; if ((time - lastUpdate) > 1000 I I lastUpdate == -100.0) { lastUpdate = time; temperature = getTemperature(); ‘temperature = temperature / 8.01; } } float getTemperature() { 11 считывание температуры ds.reset () ; ds.select(addr); ds .write(0x44); delay(750) ; ds.reset () ; ds.select(addr); ds.write(OxBE); byte data [9], i; for ( i = 0; i< 9; i++) { data [i] = ds.readO; } if (OneWire::crc8(data, 8) != data [8]) { return temperature; } unsigned int raw = (data [1] « 8) I data [0];
raw - raw « 3; if (data [7] == 0x10) { raw = (raw & OxFFFO) + 12 - data [6] ; } float Celsius; Celsius = (float)raw / 16.0; return celsius; } void connectToSensor () {//подключение к датчику-if ( Ids.search(addr)) ds.reset_search(); delay(250); } После входа на сервер можно нажать ссылки на включение-выключение светодиода на странице в браузере, а изменив температуру датчика, можно увидеть это изменения (рис. 13.13). Рис. 13.13. Работа web-cepeepa на базе Ethernet-шилда
Рис. 13.14. Вход на Arduino-сервер со смартфона Управлять и наблюдать за показаниями датчиков можно не только с компьютера, но и через смартфон (рис. 13.14). Я очень благодарен за присланные мне листинги программ, которые решили возникшую у меня проблему. И я рад, что повторил все предложенные мне опыты. В моем прежнем представлении о сервере как компьютере с серверной операционной системой появилось понимание того, что к теоретическим знаниям следует относиться с большим вниманием и уважением, даже тогда, когда задача решена опытным путем.
ГЛАВА 14 И НЕПРИЯТНОСТИ БЫВАЮТ ПОЛЕЗНЫ: ПРИКЛЮЧЕНИЯ С SD-КАРТОЙ Побродив в предыдущей главе по сайтам, и я уже говорил об этом, почувствовав зуд в руках от желания что-то сделать, я решил заняться SD-картой, гнездо для которой есть на плате Ethernet. I Карта microSD и Arduino Я изначально предполагал использовать при рассказе программу Cardinfo из состава примеров для Arduino, и у меня было несколько карт microSD: две 512М, одна 4G и одна 16G. Но ни одна из SD-карт не пошла дальше того, что можно увидеть на рис. 14.1. ПРИМЕЧАНИЕ. В этот раз я решил не беспокоить моего знакомого, выступая и в роли новичка, и в роли «гуру». Можно, конечно, заподозрить меня в раздвоении личности, но разве вам не доводилось при работе говорить себе: «Стоп-стоп-стоп, давай без спешки, дружочек!».
Рис. 14.1. Сообщение при инициализации microSD Новичок: Если карта не отвечает, то, может быть, виновата она? На некоторых форумах, где я пытался найти ответ, говорили, что SD-карты большого объема вообще не работают в подобном случае. Карты маленького объема были очень старыми, поэтому могли быть неисправны. Но не изменила ситуации и покупка microSD 2G. Если что-то не работает, хотя должно работать, то это никак не чудо, а простое недопонимание. И следует все тщательно проверить. Вот программа, которую я использовал (Cardinfo): // включаем библиотеку SD ttinclude <SPI.h> #include <SD.h> // задаем переменные, использующие функции библиотеки Sd2Card card; SdVolume volume; SdFile root; // измените константу для соответствия // вашим модулям Arduino и SD // Arduino Ethernet shield: pin 4 // Adafruit SD shields and modules: pin 10 // Sparkfun SD shield: pin 8 // MKRZero SD: SDCARD_SS_PIN const int chipSelect = 4;
void setup() { // Открываем последовательный порт и ждем, // когда он откроется Serial.begin(9600); while (’Serial) { ; // ждем подключения последовательного // порта. Необходимо только для USB } Serial.print("\nlnitializing SD card..."); //мы будем использовать код инициализации // библиотек, поскольку нам нужно только // проверить, что карта работает! if (!card.init(SPI_HALF_SPEED, chipSelect)) { Serial.printin("initialization failed. Things to check:"); Serial.printin("* is a card inserted?"); Serial.printIn("* is your wiring correct?"); Serial.printIn("* did you change the chipSelect pin to match your shield or module?"); return; } else { Serial.printIn("Wiring is correct and a card is present."); } // выведем тип карты Serial.print("\nCard type: "); switch (card.type()) { case SD_CARD_TYPE_SD1: Serial.printin("SD1"); break; case SD_CARD_TYPE_SD2: Serial.printin("SD2"); break; case SD_CARD_TYPE_SDHC: Serial.printIn("SDHC"); break; default: Serial.printin("Unknown"); }
// Теперь постараемся открыть 'volume'/ // 'partition': это будет FAT16 илиРАТ32 if (!volume.init(card)) { Serial.printin("Could not find FAT16/FAT32 partition.\n Make sure you've formatted the card"); return; } // выведем тип и размер первого тома FAT-типа uint32_t volumesize; Serial.print("\n Volume type is FAT"); Serial.printIn(volume.fatType(), DEC); Serial.printIn(); volumesize = volume.blocksPerCluster(); // кластеры — совокупность блоков volumesize *= volume.clustercount(); //мы получим много кластеров volumesize * = 512; // блоки SD-карты всегда по 512 байтов Serial.print("Volume size (bytes): "); Serial.printin(volumesize); Serial.print("Volume size (Kbytes): "); volumesize /= 1024; Serial.printin(volumesize); Serial.print("Volume size (Mbytes): "); volumesize /- 1024; Serial.printin(volumesize); Serial.printin("\n Files found on the card (name, date and size in bytes): "); root.openRoot(volume); // список всех файлов на карте с датой и размером root.ls(LS_R I LS_DATE I LS_SIZE); } void loop(void) { } Начинается программа с подключения библиотеки SPI.
I Немного об интерфейсе SPI Новичок: И что такое SPI? Это хороший вопрос. С выяснения этого, похоже, и следует начать. Интерфейс SPI расшифровывается как последовательный периферийный интерфейс. Используется несколько сигналов (рис. 14.2). Сигналы, используемые интерфейсом, следующие: ♦ сигнал SCLK служит для передачи тактовых импульсов, то есть, для синхронизации при чтении и передаче данных; ♦ MOSI — прием данных; ♦ MISO — передача данных; ♦ SS — выбор устройства. Ведущее устройство Ведомые устройства Рис. 14.2. Подключение устройств с интерфейсом SPI
Ведущее устройство (Master) может управлять несколькими ведомыми (Slave), и в этом случае у него должно быть несколько выводов SS (SSI, SS2, SS3 на рис. 14.2). ЭТО ВАЖНО! Обратите внимание на соединение ведущего устройства с ведомыми. Если для RS252 вывод передатчика Тх соединяется с приемником Rx, то в SPI соединяются одноименные выводы: MISO-MISO,MOSI-MOSI. Модуль Arduino имеет выводы SPI для внутрисхемного программирования. Модуль Ethernet работает с модулем Arduino через интерфейс SPI. И microSD тоже работает с модулем Arduino через интерфейс SPI. Возвращаясь к проблеме, констатируем, если посещение форумов в поиске причин отказа оборудования не помогает, то пора включить осциллограф. Осталось выяснить то, как подключить осциллограф, где нужные нам выводы? Для ответа на этот вопрос обратимся к рис. 4.1 на стр. 75 (для этого он и сделан). Просматривая соответствие выводов микроконтроллера с номерами выводов модуля, мы обнаружим, что: SCLK—>РВ5—>13; MISO—>РВ4—>12; MOSI—>РВЗ—>11; SS->PB2—>10 (в нашем случае 4). Вывод 4 для сигнала выбора прописан в программе: constintchipSelect = 4; Подключив осциллограф, я могу наблюдать на его экране сигналы (рис. 14.3). Наблюдать сигналы... это слишком громко сказано. Есть сигнал синхронизации, но никаких других сигналов не видно. Новичок: Обычно в подобных случаях полезно «прозвонить» соединения. Не так ли?
Рис. 14.3. Первое подключение осциллографа к модулю Arduino Я так и поступил, не обнаружив ничего подозрительного. Соединения с гнездом (рис. 14.4) было правильным. Питание карты пониженным напряжением было вполне учтено производителем платы — там, где это требовалось, добавлены резистивные делители. Рис. 14.4. Гнездо для microSD I Поиск неисправности Разглядеть что-либо, конечно, трудно — все очень мелкое. Но проверка соединений должна была убедить меня. Однако не убедила. Первые сомнения возникли, когда я решил измерить напряжение на выводах (на делителях) CS (SS), SCLK и MOSI без
карты и с вставленной картой. Если напряжение на выводах CS и SCLK немного уменьшалось, то напряжение MOSI оставалось неизменным. Мне показалось, что ламель этого сигнала не имеет контакта с выводами карты, несмотря на «прозвонку». Помогло следующее: я вырезал полоску алюминиевой фольги по ширине карты, вставил ее в гнездо, а поверх нее вставил карту. Проверяя соединение выводов, я обнаружил, что ни MOSI, ни питающее напряжение 3,3 В не доходят до места назначения. Пропаяв эти ламели в месте их пайки к плате, я еще раз поверил соединения. Теперь все соединения оказались в отличной форме. Чтобы убедиться в этом, я вновь обратился к осциллографу (рис. 14.5). Наличие сигналов на всех выводах интерфейса SPI говорило об устранении неисправности. Но окончательная проверка — это монитор порта в программе Arduino. При первом запуске программы SD-карта не обнаруживалась, но не теперь (рис. 14.6). Вывод информации о карте я проверил с разными картами, включая карту 16 Гбайт. И теперь мне осталось понять, почему проверяя соединения с помощью мультиметра, я не обнару- Рис. 14.5. Осциллограмма работающей SD-карты
Рис. 14.6. Отклик microSD после устранения неисправности жил дефекта? Ответ прост — когда ставишь щуп, то стараешься его прижать к ламели, иначе щуп соскользнет, а этого усилия достаточно, чтобы ламель прекрасно контактировала с площадкой для пайки, показывая, что соединение есть. И хорошо, что неисправность была, иначе я' никогда бы, наверное, не попытался разобраться с интерфейсом SPL Новичок: А что еще можно сказать про SPI? Лучше почитать про этот интерфейс, но в двух словах: ведущий формирует тактовые импульсы байтами, выставляя запрос или команду (рис. 14.7). Данные считываются либо по переднему, либо по заднему фронту тактовых импульсов. Это зависит от настроек интерфейса. В данном случае сигнал можно прочитать так: 11100101. Если ведомое устройство должно ответить, оно отвечает (рис. 14.8). Можно проверить и другие программы, которые есть в примерах. Там есть программа проверки записи на SD и чтения записанного текстового файла, называется она ReadWrite. Вот результат (рис. 14.9). Текстовый файл «test.txt» на SD-микро есть. Его можно прочитать (рис. 14.10).
Рис. 14.7. Запрос ведущего
Рис. 14.9. Проверка записи-чтения на карту I fl TFVT.TX1 — Б. и™ игг I Ф<1йл Правка Формат Вид Справка; (testing 1, 2, 3. testing 1, 2, 3. testing 1, 2, 3. testing 1, 2, 3. V Рис. 14.10. Текстовый файл, записанный программой ReadWrite Новичок: Хорошо, нашли неисправность, устранили, и что? Зачем эта SD-карта? Например, если вам нужно следить за изменением напряжения в течение какого-то времени. Достаточно использовать встроенный в модуль Arduino аналого-цифровой преобразователь, а прочитанные значения записывать на карту. Или, положим, вам нужно следить за температурой в теплице. Подключите датчик DS18B20, как рассказывалось ранее, а значения записывайте на карту.
Новичок: А не проще ли передавать данные с помощью UART? Для этого понадобится дополнительный преобразователь сигналов, и понадобится соединить Arduino с компьютером проводами, что не всегда удобно. Правда, есть еще один вариант — использовать радиоканал. Радиомодуль Есть такой модуль, который называется nRF24L01 (рис. 14.11). Рис. 14.11. Модуль nRF24L01+ и обозначение его контактов Кроме тех выводов, о которых шла речь раньше: SCLK (SCK), MISO, MOSI, есть три вывода, о назначении которых следует сказать дополнительно. Вывод СЕ — включение модуля в режим передачи-приема. При приеме активный уровень высокий. В режиме передачи уровень низкий, а для отправки байта — импульс высокого уровня не менее 10 мкс. Вывод CSN (SS) — вывод выбора модуля, которым управляет ведущее устройство. Активное состояние — низкий уро- вень при записи и чтении модуля. Вывод IRQ — вывод для использования прерывания. Активное состояние — низкий уровень. Модуль работает на частоте в несколько гигагерц, используя довольно много каналов. Посмотрев на обозначение контактов, можно понять, что модуль соединяется с другими устройствами через интерфейс SPI. Благодаря высокой рабочей частоте радиомодуль на небольших расстояниях прекрасно работает без антенны, а для увеличения дальности связи можно использовать антенну, но она имеет небольшие размеры.
□ X ф Webserver I Arduino 1 2>2 Файл Правка Скетч Инструменты Помощь Esptora Ethernet Firmata GSM LiquidCrystai SD Servo Stepper Temboo TFT // Enter а МАС address and II // The IP address will be dej byte аасП - { (JxuE, OxAD, cxfit, OxEc, Oxi CtrkP Настройки Ctrl*-Comma WtFt Выход QrkQ ♦include cBthemet.h.^ Wire CtrUN Ctrl* О Ctrt+W Ctri+S Ctrl* Shift* S Закрыть Сохранить Сохранить как... Примеры для Arduino/Genuino Uno EEPROM SoftwareSerial SPI Новый Открыть... Открыть недавние Папка со скетчами Настройки страницы Ctrl* Shift *P Печать Примеры из пользовательских библиотек | Adafrurt Circuit Playground ArdwnoUnrt DallasTemperature FreeRTOS Mrrf M$Timef2 OneWire OPC GettingStarted ledjemote nordicjob pmgpatf ptngpair.dyn pingpair_irq pingpairmapie pir«9paif_pl pingpair.sleepy scanner starping tests Puc. 14.12. Библиотека и примеры для работы с радиомодулем Работу этого модуля с Arduino обеспечивает библиотека nRF (рис. 14.12). Среди примеров есть небольшая, но очень интересная и полезная программа: ttinclude <SPI.h> ttinclude "nRF24L01.h" #include "RF24.h" #include "printf.h" // Конфигурация оборудования // Зададим nRF24L01 радио на шинеЭР!, // добавив выводы 9 & 10 RF24 radio(9,10);
// Информация о каналах const uint8_t num_channels = 128; uint8_t values [num_channels]; // Установки void setup(void) { 11 Выведем преамбулу Serial.begin(57600); printf_begin(); printf("\n\rRF24/examples/scanner/\n\r"); // Настройка и конфигурация rf radio.begin(); radio.setAutoAck(false); // Введем в режим ожидания radio.startListening(); radio.stopListening(); // Выведем наш заголовок: // сверху старшее число, снизу младшее int i = 0; while (i<num_channels){ printf("%х", i»4); ++i; } printf("\n\r" ) ; i = 0; while (i<num_channels){ printf("%x", i&Oxf); + + i; } printf("\n\r") ; } //Основной цикл const int num_reps = 100; void loop(void){ // Очистим полученные значения memset(values,0,sizeof(values)); // Сканируем все каналы, повторяя num_repspa3 int rep_counter = num_reps;
while (rep_counter--){ int i = num_channels; while (i--){ // Выберем этот канал radio.setchannel(i); // Немного послушаем radio.startListening(); delayMicroseconds(128); radio.stopListening(); // Получаем ли мы несущую? if (radio.testcarrier()) ++values [i]; } } // Выведем канал в виде шестнадцатеричного числа int i = 0; while (i<num_channels){ printf("%x", min(0xf, values [i]&0xf)); ++i; } printf(«\n\r»); } После соединения nRF24L01 c Arduino и запуска программы можно наблюдать на мониторе порта картину, показанную на рис. 14.13. Первые две строки — это номера всех каналов в шестнадцатеричном виде. Первые каналы, как вы видите, загружены другими устройствами. Для экспериментов можно выбрать канал 79 (0x4F), тоже отмеченный на рис. 14.13. ЭТО ВАЖНО! Не забываем, что напряжение питания радиомодуля составляет 1,9-3,6 В! При подключении к модулю Arduino можно использовать вывод 3,3 В на его плате. Работая по интерфейсу SPI, модуль nRF24L01 требует активного общения. Команды для работы с модулем можно
Рис. 14.13. Состояние каналов на частоте работы модуля найти в описании работы с ним. Выглядят они примерно так (рис. 14.14). Начиная эксперименты с новым устройством, следует быть готовым к тому, что можно столкнуться с некоторыми трудностями. Я столкнулся с необходимостью выполнить шаги, описанные далее. Instruction Name Instruction Format [binary] #Data Bytes Operation RJtFXHSTER 000A AAAA Ito 5 LSByte first Read registers. AAAAA 5 bit Memory Map Address W_REGISTER 001A АЛЛА Ito 5 LSByte first Write registers. AAAAA = 5 hit Memory Map Address Executable in power down or standby model only. RJRXJPAYLOAD 0110 0001 lto32 LSByte first Read RX-paylcad: 1 - 32 bytes. A read operation will always start at byte 0. Phyioad жШ be deleted from FIFO after it is read. Used in RX mode. W_TXJ>AYLOAD 1010 0000 Ito 32 LSByte first Used in TX mode. WriteTX-payload: 1—32 bytes. A write operation will always start at byte 0. FLUSHJTX 1110 0001 0 Flush TX FIFO, used in TX mode FLUSHRX 1110 0010 0 Flush RX FIFO, used in RX mode Should not be executed during transmisaton of acknowledge, i.e. acknowledge package will not be completed. REUSEL.TXJ’L 1110 0011 0 Used for a PTX device Reuse last sent payload. Packets will be repeatedly resent as long as CE is high. TX payload reuse is active until W_TX_PAYLOAD or FLUSH TX is executed. TX payload reuse must not be activated or deactivated during package transmission NOP 1111 1111 0 No Operation. Might be used to read the STATUS register
ПРИМЕЧАНИЕ. На просторах Интернета чаще всего можно встретить две библиотеки для работы с модулями nRF24L01: RF24 и Mirf. Обе содержат папки examples, где есть готовые примеры. I Подготовка к работе с nRF24L01 В библиотеке RF24 в папке примеров есть программа scanner, о которой рассказывалось в этой главе, а работа программы отображена на рис. 14.13. Но после разархивации нужно сделать следующее. Извлеките из папки RF24 папку RF24_gnulnuf (если у вас такой же вариант, что и у меня). Откройте эту папку и в блокноте операционной системы или в редакторе Wordpad откройте файл RF24.h. По совету «бывалых» перенесите функцию uint8_t flush_tx (void) ; в раздел public: класса RF24. Я, правда, сжульничал, я объявил все функции публичными. Теперь в программе Arduino откройте раздел, позволяющий импортировать библиотеки (рис. 14.15). Укажите папку с библиотекой RF24, чтобы завершить операцию импорта. Выводы Arduino для подключения модуля можно взять такие: ♦ вывод 13 — SCK; ♦ вывод 10 — CSN; ♦ вывод 12 — MISO; ♦ вывод 9 — СЕ. ♦ вывод 11 — MOSI; И еще, есть в библиотеке полезная функция print De tai Is (). Она покажет все параметры вашего радиомодуля (рис. 14.16). А программа, совмещающая обе полезные программы, выглядит так (я ее взял в Интернете):
Рис. 14.15. Импорт библиотеки RF24_gnulnuf Рис. 14.16. Параметры радиомодуля на мониторе порта ttinclude <SPI.h> #include "nRF24L01.h" #include "RF24.h" RF24 radio(9,10); // flnnArduino Uno //RF24 radio(9,53);// flnnArduino Mega
const uint8_t num_channels - 128; uint8_t values [num_channels]; void setup(void){ Serial.begin(57600); printf_begin(); radio.begin() ; radio.setAutoAck(false); radio.startListening(); radio.printDetails() ; // Вот эта строка напечатает нам что-то, //если все правильно соединили delay(5000); // И посмотрим на это пять секунд. radio.stopListening(); int i - 0; //А это напечатает нам заголовки всех 127 каналов while (i<num_channels) { printf("%x", i»4) ; ++i; } printf("\n\r") ; i = 0;' while (i<num_channels) { printf("%x",i&Oxf); ++i; } printf("\n\r") ; } const int num_reps = 100; void loop(void) { memset(values, 0, sizeof(values)); int rep_counter = num_reps; while (rep_counter--) { int i = num_channels; while (i--) { radio.setchannel(i); radio.startListening(); delayMicroseconds(128); radio.stopListening();
if (radio.testcarrier()) ++values [i]; } } int i = 0; while ( i<num_channels ) { printf("%x", min(Oxf,values [i]&0xf)); + + i; } printf (<<\n\r>>) ; } 11 Дополнительные функции int serial_putc( char c, FILE * ) { Serial.write( c ); return c; } void printf_begin(void) { fdevopen(&serial_putc, 0 ); } Эксперименты с радиоканалом я проводил с помощью двух модулей Arduino Uno, а, памятуя о дефектах соединений при макетировании, решил не рисковать, используя работающие программы для приемника и передатчика с форума «Амперка» от Игоря К. Приемник: ttinclude <SPI.h> ttinclude "nRF24L01.h" # include «RF24.h» RF24 radio(9,10); // Определяем рабочие выводы const uint64_t pipe - 0xE8E8F0F0ElLL; // Определяем адрес рабочей трубы void setup() { radio.begin(); // Старт работы radio.enableAckPayload(); // Разрешение отправки нетипового ответа //передатчику; radio.openReadingPipe(1,pipe); // Открываем трубу и radio.startListening(); //начинаем слушать }
void loop() { uint32_t message = 111; //Вот какой потенциальной длины сообщение - // uint32_t! туда можно поместить значение // температуры от датчика или еще что-то // полезное // Грузим сообщение для автоотправки radio.writeAckPayload( 1, &message, sizeof(message) ); if( radio.available() ) { //Просто читаем и очищаем буфер // при подтверждении приема int dataln;//передатчику приемник // ответит нашим сообщением bool done = false; while ((done) { done = radio.read( &dataln, sizeof(dataln)); // Значение dataln в данном случае не важно. //Но его можно использовать //и как управляющую команду } } } Передатчик: ttinclude <SPI.h> #include "nRF24L01.h" #include "RF24.h" RF24 radio(9,10); const uint64_t pipe - 0xE8E8F0F0ElLL; uint32_t message; // Эта переменная для сообщения от приемника void setup() { Serial.begin(57600) ; printf_begin() ; radio.begin(); radio.enableAckPayload(); radio.openWritingPipe(pipe); }
void loop() { int command - 555; II Не суть, что это, но приемнику надо // что-то передать, но это может быть и // полезная информация radio.write(&command, sizeof(command) ); //Отправляем команду if (radio.isAckPayloadAvailable()) { /I Ждем получения... radio.read(&message,sizeof(message)); II... иимеемпеременнуютезэаде // счислом 111 отприемника. } if (message == ill) { printf("Answer: "); printf("lll\n"); } delay(3000); } // Дополнительные функции int serial_putc( char c, FILE * ) { Serial.write( c ); return c; } void printf_begin(void) { fdevopen(&serial_putc, 0 ); } В программу передатчика я добавил выделенные строки, которые помогут мне понять, что происходит в диалоге приемника и передатчика. Вот результат (рис. 14.17). Перебирая разные варианты программы, добавив команду управления светодиодом, я завершил эту серию экспериментов. Окончательный результат приема команды по радиоканалу сохранился у меня на память (рис. 14.18). Затевая подобного рода эксперименты, стремишься как можно быстрее и проще получить результат. Но по прошествии времени понимаешь, что сам процесс был намного увлекательнее и полезнее, чем полученное решение.
Рис. 14.17. Результат первого опыта с готовыми программами Рис. 14.18. Прием команды управления светодиодом по радиоканалу Новичок: А тогда зачем решение? Например, если объединить Arduino-сервер с радиоканалом, то управлять роботом можно и с планшета, и со смартфона. ЭТО ВАЖНО! Сегодня можно купить многое для работы с микроконтроллерами, обзавестись модулями Arduino или STM32F103C8. Но самое главное, чем вам следует обзавестись, это желанием научиться всему, терпением и умением придумывать что-то свое и реализовывать эти задумки. Возможно, обретя эти навыки, вы выберете себе профессию, увлекательную и современную, созда-k теля роботов. Успехов вам!
ГЛАВА 15 В ЗАВЕРШЕНИИ НЕМНОГО СХЕМОТЕХНИКИ Очень полезна базовая программа «hello world», используемая для включения и выключения чего-нибудь при использовании плат Arduino. Цифровой ВЫХОД || В этом примере (рис. 15.1) светодиод подключен к выводу 13 и мигает каждую секунду. На многих платах Arduino светодиод со всем необходимым уже есть, но если потребуется подключить светодиод к другому выводу, например, при отладочных операциях, когда вывод 13 занят, то можно использовать эту схему подключения. Pin 13 220 Рис. 15.1. Подключение светодиода
#define LED_BUILTIN 13 // задаем вывод для светодиода // функция setup используется только один // раз, когда нажата кнопка сброса или к плате // подключается питание void setup() { // инициализация цифрового вывода LED_BUILTIN в // качестве выхода pinMode(LED_BUILTIN, OUTPUT); } // функция loop постоянно повторяется снова и снова void loop() { digitalWrite(LED_BUILTIN, HIGH); /I включение LED // (HIGH - уровень напряжения) delay(lOOO); // ждем секунду digitalWrite(LED_BUILTIN, LOW); // выключение LED, сделав // напряжение LOW delay(lOOO); // ждем секунду } Цифровой ввод Это простейшая форма ввода с двумя возможными состояниями: включено или выключено (рис. 15.2). Ряд простых датчиков работает похожим образом. В примере считывается состояние кнопки, подключенной к выводу 2. Когда контакты кнопки замкнуты, входной вывод читается как HIGH и включает светодиод. +5В 0 Pin > Рис. 15.2. Подключение кнопки к модулю Arduino // константы не должны меняться; здесь они // используются для задания номеров выводов
const int buttonPin - 2; // номер вывода нажимной кнопки const int ledPin = 13; // номер вывода светодиода (LED) // переменная будет меняться int buttonstate = 0; // переменная для чтения состояния кнопки void setup() { // инициализация вывода LED в качестве выхода pinMode(ledPin, OUTPUT); // инициализация вывода кнопки в качестве входа pinMode(buttonPin, INPUT); } void loop () { // читаем состояние кнопки через значение вывода buttonstate - digitalRead(buttonPin); // проверяем, нажата ли кнопка // если так, состояние buttonstate будет HIGH if (buttonstate == HIGH) { // включаем светодиод (LED) digitalWrite(ledPin, HIGH); } else { // выключаем светодиод (LED) digitalWrite(ledPin, LOW); } } Сильноточный выход Иногда возникает необходимость в управлении нагрузкой от платы Arduino, ток которой превышает 40 мА. В этом случае может использоваться транзистор биполярный или MOSFET (рис. 15.3). В следующем примере транзистор MOSFET быстро включается и выключается 5 раз в секунду.
ПРИМЕЧАНИЕ. Схема показывает мотор и диод защиты, но неиндуктивные нагрузки могут включаться без диода. +5 в... +24 в 0—•—1 1N4001 2 к (м) Р|п>_UKLIRFS10 Рис. 15.5. Подключение силовой нагрузки к плате Arduino int outPin = 5; // выходной вывод для транзистора void setup() { pinMode (outPin, OUTPUT); // инициализация вывода в качестве выхода } void loop() { for (int i = 0; i<=5; i++) { // цикл повторяется 5 раз digitalWrite (outPin, HIGH); I/ включаем выход delay (250); // ждем четверть секунды digitalWrite (outPin, LOW); // выключаем выход delay (250); // ждем четверть секунды } delay (1000); // пауза между циклами в секунду }
Выход pwm J Широтно-импульсная модуляция (PWM) — это способ имитировать аналоговый выход с помощью импульсного сигнала. Это можно использовать для уменьшения и увеличения яркости светодиода или позже для управления сервомотором (рис. 15.4). Следующий пример медленно увеличивает яркость, а затем гасит светодиод, используя цикл for. Рис. 15.4. Подключение светодиода к выводу PWM int ledPin =9; // PWM вывод для светодиода void setup() { // setup не нужен } void loop() { for (int i = 0; i<=255; i++) { analogWrite (ledPin, i); // увеличиваем яркость delay (100); // небольшая пауза } for (int i = 255; i>=0; i--) { analogWrite (ledPin, i); // уменьшаем яркость delay (100); // небольшая пауза } } Ввод с потенциометра Использование потенциометра и одного из аналоговых портов Arduino (аналого-цифрового преобразователя, ADC) позволяет читать аналоговые значения в диапазоне 0-1023. Следующий
Pin +5 В Рис. 15.5. Подключение потенциометра к Arduino пример (рис. 15.5) показывает использование потенциометра для управления временем мигания светодиода LED. int ledPin =13; // задаем вывод для светодиода int potPin =0; // вывод для входа void setup() { pinMode (ledPin, OUTPUT); // определяем вывод на выход } void loop() { digitalWrite (ledPin, HIGH); // включение светодиодд delay(analogRead (potPin)); 11 ждем digitalWrite (ledPin, LOW); // выключение светодиода delay(analogRead (potPin)); // ждем } Опыт с переменным резистором В качестве переменного резистора на практике могут использоваться фотоприемники, термисторы, тензодатчики и т. д. В опыте (рис. 15.6) используется функция чтения аналогового значения, которым задается время паузы. При этом меняется скорость, с которой реализуется яркость светодиода. Рис. 15.6. Схема подключения резистора с переменным сопротивлением
int ledPin =9; // PWM вывод для светодиода int analogPin - 0; // аналоговый вход для резистора void setup() { } // setup не нужен void loop() { for (int i = 0; i<=255; i++) { // увеличиваем значение i analogWrite (ledPin, i); // задаем яркость no i delay (delayVal); // берем значение для паузы } for (int i - 255; i>=0; i--) { // уменьшаем значение i analogWrite (ledPin, i); // устанавливаем яркость no i delay (delayVal); // берем значение для паузы } } int delayVal () { int v; // создаем локальную переменную v - analogRead (analogPin); // читаем аналоговое значение v /= 8; // преобразуем от 0-1024 к 0-128 return v; // возвращаем окончательное значение } Серво вывод Любительские серво-машинки — это разновидность полу-автономного мотор-редуктора, который может поворачиваться на 180 градусов. Все, что нужно для поворота — это отправлять импульсы каждые 20 мс. В данном примере (рис. 15.7) используется функция servoPulse для поворота мотора от 10 до 170 градусов и обратно.
+6 В Pin^-|--Л-П 220 *— г SERVO I— b Рис. 15.7. Подключение серводвигателя int servoPin = 2;// привод соединен с выводом 2 int myAngle; // угол привода грубо 0-180 int pulseWidth; // переменная функции servoPulse void setup() { pinMode (servoPin, OUTPUT); // определяем вывод в качестве выхода } void servoPulse (int servoPin, int myAngle) { pulseWidth - (myAngle * 10) + 600; // определяем паузу digitalWrite (servoPin, HIGH); // подаем напряжение на привод delayMicroseconds (pulseWidth); // пауза в микросекундах digitalWrite (servoPin, LOW); // снимаем напряжение } void loop () { for (myAngle = 10; myAngle <= 170; myAngle++) { servoPulse (servoPin, myAngle); // отправляем вывод и угол delay (20); // обновляем цикл } for (myAngle = 170; myAngle >= 10; myAngle--) { servoPulse (servoPin, myAngle); // отправляем вывод и угол delay (20); // обновляем цикл } }
ПРИЛОЖЕНИЯ При рассказе о создании программы для компьютера, которая может стать интерфейсом для управления роботом, я использовал среду разработки code::blocks вкупе с плагином wxSmith и приложением wxWidgets. ПРИЛОЖЕНИЕ А РАССКАЗ О ПЛАГИНЕ WXSMITH И ПРИЛОЖЕНИИ WXWIDGETS К CODE::BLOCKS О руководстве к программе code::blocks Руководство к code::blocks вы найдете на виртуальном диске (Приложение Б: файл codeblocks.pdf»), а о wxSmith и приложении wxWidgets я хочу рассказать здесь, поскольку при первом использовании столкнулся с некоторыми трудностями, которые вам, как я понимаю, совсем не нужны. Первые настройки проекта Повторение консольных программ путем простого копирования примеров в текстовый редактор Code::Blocks с последующей сборкой и запуском — это не то, чему мне хотелось бы научиться. Поэтому я решил повторить примеры в графическом виде с помощью wxSmith для начала. Благо с первыми шагами в создании wxWidgets project справиться удалось. Остались некоторые сомнения в правиль
ности выбранных настроек, которые можно проверить. В частности, мне не очень было понятно с дополнительными файлами — в прошлый раз я просто скопировал эти настройки. Сейчас можно неспешно, создавая новый проект, проверить достаточный выбор для первых опытов. Вот какие настройки в диалоге создания нового проекта (рис. АЛ). Рис.А.1. Первые настройки проекта Но при попытке собрать проект командой Build (я использую иконку на инструментальной панели) появляется сообщение, что нет Tiff (чего-то). Не будучи специалистом, я удаляю неудачную версию проекта и создаю ее заново, но теперь отмечаю и wxTiff тоже. После этого проходит сборка и программа запускается. Надпись на панели заголовка окна я хотел бы вывести из программы. Я знаю, что окно (по имени проекта) probaFrame наследник wx Window. Последнее имеет функцию SetTitlef), которую я и хотел бы использовать. В моем представлении это должно выглядеть так: probaFrame.SetTitle ("Привет, Мир!"); В файл «probaMain.cpp» я вписываю то, что надумал. Результат при сборке выведен в панель сообщений о сборке (рис. А.2). В поисках ответа на вопрос, в чем проблема, я встретил упрек участнику форума на аналогичный вопрос, что он плохо читал учебник в части статических членов (так я понял напи-
Рис.А.2. Сообщения о результатах сборки санное на английском, не вдаваясь в детали). Предложено было исправить фразу: probaFrame::SetTitle ("Привет, Мир!"); Совет помогает, сообщений об ошибке нет. Впрочем, если оставить только: SetTitle ("Привет, Мир!"); То результат тот же, ошибок нет, но и окно выглядит так, как если бы команд и не было — заголовок окна отсутствует. И что я заметил еще, вот фрагмент текста файла «probaMain.cpp» (рис. А.З). вини---------------------------------------------------- probaFrame::probaFrame(wzWindow* parent,wxWindowID id) 56 60 61 62 63 64 66 //(♦Initialize (p^pfe^Frame) jsetTztle ("Египет, irxManuItem* Nenultcm^ irxMenuItsD* Manultsml irxMenu* Nanni; vxNenuBar* NanuBarl; rxNenu* Nanni?; Puc.A.5. Фрагмент текста Если перейти на страницу формы, дважды щелкнув по файлу «probaframe.wxs» в менеджере проекта, на закладке предыдущего файла появляется метка изменения текста, а этот файл изменится следующим образом (рис. А.4).
\probaFrnme: rnrobaFrame twxWindow* parent, wxWixsdowXD id) к yjriNfcmultea* MenuIteaaJ?,* andiemHfcam* Manulteal; vxNfenm* jMenwl; vjiAtenufiar* Мвх?и®аг1; rjcMenu* ttenuS; Puc.A.4. Тот же фрагмент текста после перехода к окну формы То выражение, что я добавлял, исчезло. Конечно, я могу справиться с этой задачей, если просто впишу в свойство Title формы то, что хотел (рис. А.5). Рис. А.5. Текст в свойстве Title формы и форма после запуска Все эти манипуляции я проделал в Fedora 21, где пришлось добавить: SetTitle (wxT("Привет, Мир!")); Но результат в точности повторил все показанное выше. Конечно, когда я узнаю больше, когда научусь разбираться лучше, я, возможно, пойму, в чем здесь дело, а сейчас я хочу попробовать другие возможности вывода фразы «Привет, Мир!». В рабочее окно я могу поместить кнопку и некое текстовое поле. Если щелкнуть по кнопке, то в текстовое поле пусть будет выведено «Привет, Мир!» (рис. А.6).
Рис. А.6. Заготовка формы для эксперимента После двойного щелчка по первой кнопке в файле «probalMain.cpp» появляется заготовка под ответ на щелчок по кнопке. Туда я вписываю то, что мне кажется понятным и правильным: void probalFrame: :OnButtonlClick(wxCommandEvent& event) { StaticTextl.SetLabel(«Привет,Мир!»); } Сборка дает ошибку, но выводит и подсказку (рис. А.7). Рис.А.7. Сообщение об ошибке и подсказка Если заменить точку на оператор стрелки, то... void probalFrame::OnButtonlClick(wxCommandEvent& event) { StaticTextl —»• SetLabel («Привет, Мир!»); }
Рис. А. 8. Выполнение программы После сборки проекта, которая теперь проходит без ошибок, можно запустить программу, а щелчок по первой кнопке дает такой результат (рис. А.8). Что такое оператор стрелки? Определение дается в руководстве по языку C++. |Что есть что: давайте знакомиться ЭТО ВАЖНО! Оператор стрелки (—9 - это оператор разы-меновывония, который используется исключительно с указателями на объекты, которые имеют своих членов. Этот оператор используется для доступа к членом объекта непосред-ственно по их адресам. Подсказку я, признаться, увидел не сразу, а перед этим пробовал разные варианты. В частности, а что будет, если оставить только: void probalFrame::OnButtonlClick (wxCommandEvent& event) { SetTitle(«Привет, Мир!»); }
Рис. А.9. Неожиданный результат эксперимента Сборка проекта не дала ошибки. А запуск программы дал такой результат после щелчка по первой кнопке (рис. А.9). То есть, выражение установки этикетки для окна было правильным, но появилось только после некоторого события. Возможно, отсутствие событий в том месте программы, куда я пытался записать выражение для задания заголовка, и стало причиной первой неудачи. Возвращаясь к первой программе, я отыскиваю место, где с моей точки зрения есть событие (рис. А.10). Если бы я был внимательнее, то заметил бы, что в этом месте создается окно с пустым заголовком. Если бы... После трансляции и запуска получается следующее (рис. А. 11). 55 56 57 58 59 60 61 62 63 64 , 65 ! 66 ! 67 I 68 ! 69 । 70 i 71 I 72 I™ probafraae::probaFxa№e(««Window* parent, wxWiadowID id} Й ///* tiSOM* ь'хме n ui t e® ’ Men « i teaa.2 : кхМеnи I t.* fatgI teal ; vxtfenu* Menu.!/ ажМенуВяг* MenuBarl; vxtiem* Menus; wxDeteultPosi tian, vxDetxultSixe, vxDt&AULTjnti^~ST¥L6, J7*ie" MennBarl » neu FxMenuBarf/; i*snul » nesr юййпь’О; Menulteel * nev vjiMenuIte»(Nenul, idMenaQuxt, _ (the application’'? . vxlTW. Menu! Append (Menu!teal} ; ManuBeri >4ppend(Menui, ie4File”Ji; Puc.A.10. Новое место для задания выражения
Рис.А.11. Появление заголовка окна То есть, выражение для заголовка было вставлено до события, в котором создается окно с пустым заголовком. Поэтому заголовка и не было. Новичок: И теперь, пожалуй, станет понятным, что происходит, когда мы вписываем заголовок в поле свойств формы (я написал «Привет»).' Code::Blocs удаляет написанное мной выражение, а в команду создания окна (событие) вписывает заголовок (рис.А.12). Вот такая простейшая программа «Hello World!» получается. 55 56 57 58 59 60 61 62 63 69 65 66 67 68 probeFrane: sprobaFranM» ‘wx’W.indcw* parent,wxWindowID id.) b'x/tent’item» wxMeauI tea * ?fenul tea.;; s/xMenu"- Menul; жяМмиАвх'* MennBarl; „x>feni” Menui; Create,'parent, id . ^"Привет"} J vxDefaultPosxtion, vxDef&iilLSiae, vxDEFAULT^FRAME_smrLE/ JT!nid"),i, MenuJSKrl ' new Menu! » nev жяМетш : fcnuiteai • nev *хяепи I ten гмепи!, .xdMenuQuit, i'w£/uzt.\La! t-F*”}, (aQuit the application .. vxITSl^ Рис. A.12. Изменения, вносимые средой разработки
wxWidgets и Fedora 21 Программа Code::Blocks кросс-платформенная. Поэтому я решил, что следует повторить какое-нибудь упражнение в моем дистрибутиве Linux Fedora 21, используя графические возможности Code “Blocks. Первое, что следует сделать, исходя из моего предыдущего опыта, это добавить ряд файлов, чтобы использовать wxSmith. Новичок: Какие точно файлы следует добавлять, я не вполне понял, поэтому файлов, которые я добавил, может оказаться в переизбытке? И, кстати, это может зависеть от дистрибутива Linux. Несомненно, пожалуй, что следует установить нечто, что относится к wxWidgets. Если заглянуть в пакеты для Fedora 21 на mirror.yandex.ru, то можно обнаружить большое количество пакетов, начинающихся с «wx» (рис. А. 13). Первое, что с моей точки зрения следует установить, — это wxBase. Я установил обе версии: и wxBase-2.8.12, и wxBase-3.3.0, но не уверен, что не хватило бы и первой версии. Создание проекта в Code::Blocks для Linux не отличается от аналогичной процедуры в Windows: Create a new projects, затем выбрать тип проекта. Чтобы в проекте появилась возможность работы с wxSmith, я установил codeblocks-contrib. И, что называется «на всякий случай», codeblocks-contrib-libs и codeblocks-libs, установил wxGTK-2.8.12. Повторюсь, что-то, возможно, лишнее, а что-то я не упомянул. После завершения процедуры создания проекта (я выбрал Widgets 2.8.x в диалоге, wxSmith Frame Based, Use default wxWidgets configuration, путь для папки проекта я постарался выбрать без русскоязычных имен), я пробую собрать пустой, с одним только окном по умолчанию проект. Эти попытки я делаю до тех пор, пока не проходит без ошибок трансляция и сборка проекта.
« ... mtfw <* • им)) Hr*»» < , u ин» at frdo’ut -' и»Ле*« . Ж ' > . <• $'.-lbw.yand»* гиД^оглй’их/га’бi#£v«r>thir>g,, Ж_1 SBLXil 11. noarch.roi Sg£ WBdfdOt:»-... ..... ¥11 roteriJ 1.4.15 6. fc21.iMt, ;« WTMflrid йпГ1~4.15 e.fca.iM 11.16ЯВ.rn« 2f ьх дме.лн lP-Aug-2814 06 04 IB-Aug-2014 08 22 lO-Aug-2814 06 22 IB-Aug 2014 08 22 1В*Аид-2в14 06 22 lO-Aug-2014 08 22 19-Aug-2014 06 22 19-Aug-2014 08 22 1B-Aug-2614 06 22 1B-Aug-2614 06 22 1B-Aug-2614 06 22 1B-Aug-2O14 06 22 lB-Aug-2014 06 22 27-0ct-2814 10 38 27-Oct-2014 16 30 19-Aug 2614 07 31 19-Aug 2014 07)31 1B-Aug-2814 07 31 IB-Aug 2014 07 31 19-AUO-2014 07)31 11 Jul-2014 10 41 IB Aug 2014 08 05 IB-Aug-2014 06 00 11-Jul 2014 11 41 19-Aug 2014 06 33 IB Aug 2614 06 33 1B-Aug-2O14 06 33 19-Aug 2014 06 33 13-NOV 2014 05 S3 13-Nov 2014 05 52 13-Nov 2014 05 S3 13 NOV-2014 05 50 11-Jul 2014 12 53 13 Oct 2G14 IB 00 IB-Aug 2014 06 2B IB Aug 2014 08 29 19-Aug-2014 66 29 19-Aug 2014 06 01 20 Aug-2014 00 56 19-Aug-2014 06 32 1B-Aug-2O14 06 32 19 Aug 2014 06 25 10 Aug 2014 08 25 19-Aug-2014 06 13 1 4 5-В fc21 1606 roi v c |i Q> iinnex 31K Э95К IM 10-Aug-2O14 86 22 41K 106K S02K 185K 114K 248K 45GK 406K 171K 4ЭК 503K 263K 110K mac IM 952K IM IM 657K 10M 432K IM 510K 256K 6O0K 67K 156K 430K Puc.A.13. Список пакетов для wxWidgets Теперь можно добавить, например, кнопку и повторить сборку проекта, запустить программу. Правда, если я добавляю одну кнопку, она занимает все рабочее пространство окна, отчего я добавляю сразу две кнопки. Когда все необходимые для работы файлы установлены, программа собирается и запускается. Чуть не забыл. Все команды включения графики для препроцессора имеют вид: #include <wx/msgdlg.h>. Чтобы программа нашла нужные файлы заголовков, следует в терминале выполнить две команды: sudo cd /usr/include sudo In -sv wx-2.8/wx wx Этим будет создана ссылка на нужную папку. Убедившись, что с графическими возможностями Code "Blocks все в порядке, можно добавить создание заголовка, как это сделано раньше. Отличие, напомню, в следующем: SetTitle(ихТ("Привет, Мир!"));
Запуск показывает, что все проходит аналогично тому, как это имело место в Windows, но трансляция и сборка проходит гораздо быстрее (рис. А.14). ч Привет, Мир1 file Help <4 Рис. А.14. Окно с заголовком Сложение II двух чисел II Но вернемся к руководству. Одна из первых программ — это сложение двух чисел. В графическом изложении потребуется место, куда можно ввести слагаемые и куда можно вывести результат сложения. Для инициализации операции сложения я хочу использовать кнопку. Среди графических элементов есть wxTextCtrl (не буду настаивать, что это единственный выбор), рис. А.15. В первое окно я введу первое слагаемое, во второе окно — второе, а в третьем окне после щелчка по кнопке должен появиться результат. Вот такой у меня план. Для добавления элементов графики на рабочее поле окна достаточно щелкнуть по этому элементу, перенести курсор в нужное место, где щелкнуть повторно. В свойствах кнопки атрибут Label можно заменить надписью Сложить. Разместить все элементы в рабочем поле окна несложно — подцепить мышкой элемент и перенести в нужное место. Работа с графическими элементами не отменяет обычного программирования: чтобы работать со слагаемыми я пред-
Рис.А.15. Текстовое окно для ввода почитаю добавить в программу три переменные в заготовку щелчка по кнопке Сложить (рис. А. 16). Перед продолжением работы я хочу убедиться, что могу ввести нужные числа в текстовые поля. Оттранслировав заготовку программы, я мышкой выделяю в текстовом поле надпись Text, а затем ввожу какие-то числа (рис. А.17). Теперь пора задуматься, как этим переменным присвоить значения, введенные в текстовые поля. Особенно, если учесть, что вводятся строки, а не числа. Многие ответы на свои вопросы я нахожу здесь (рис. А. 18). ns 114 115 116 117 119 void ргоЬаЗFrame: :OnButton2Click{wxCcannandEvent& event) B< int a; int b; int result ;| 120 Puc. A. 16. Добавление переменных
Рис.А.17. Ввод чисел в текстовое поле Рис.А.18. Сайт с документацией по wxWidgets
Описание классов помогает найти подходящие функции. Для считывания введенных значений в текстовые поля можно использовать функцию: TextCtrll —> GetValueO; Поскольку переменные целого типа, а функция принимает строку, требуется преобразование текста в целое значение. И функция преобразования тоже есть: а = wxAtoi (TextCtrll —► GetValueO); Для обратного преобразования переменной result в текстовый вид для последующего ввода в окно результата функция выглядит несколько громоздко, но работает: wxString some = wxString: :Format (wxT (<<%i>>) rezult); А вывести ее в текстовое окно можно с помощью: TextCtrll —> SetValue(some) ; Таким образом, реакция на щелчок по кнопке Сложить выглядит так: void proba3Frame::OnButton2Click(wxCommandEvent& event) { int a ; int b; int rezult; a = wxAtoi(TextCtrll —► GetValueO); b = wxAtoi (TextCtrl2 —» GetValueO); rezult = a + b; wxString some - wxString:: Format (wxT(«%i>>) , rezult); TextCtrl3 —> SetValue(some); } Если на второй кнопке изменить надпись Label на «Вычесть», дважды щелкнуть по этой кнопке, а в качестве реак
ции повторить все, что показано выше, то... останется изменить результат: rezult = а - Ь; Теперь можно сложить два числа и вычесть (рис. А. 19). • Рис.А.19. Работа программы с двумя операциями Прямое копирование блока выражений, где мы не меняем имена переменных, позволительно по той причине, что это локальные переменные. Мы можем добавить еще две кнопки и повторить описанное выше для реализации умножения и деления. В любом рассказе о языке Си много внимания будет уделено стандартным типам данных, и достаточно подробно будет объясна важность указания типа. Попробуем при вычислениях использовать не целые числа, а десятичные числа, то есть, числа с плавающей точкой. Для переменных этого типа есть два идентификатора: ♦ float; ♦ double. При преобразовании используется тип double. Поэтому сложение по щелчку «Сложить» будет выглядеть несколько иначе. void proba4Frame::OnButtonlClick (wxCommandEvent& event) {
double а; double b; double rezult; wxString f_rezl - TextCtrll —► GetValue(); wxString f_rez2 = TextCtrl2 —> GetValueO; f_rezl.ToDouble(&a); f_rez2.ToDouble(&b); rezult = a + b; wxString some = wxString:: Format (wxT(«%f>>), rezult); TextCtrll —» SetValue(some); } А программа выполняет все операции, как и в первом случае, но с десятичными числами (рис. А.20). ПРИМЕЧАНИЕ. Использование оператора стрелки связано с тем, что во многие функции передаются не значения, а ссылки на эти значения. \______________________________________________. При первом знакомстве с языком Си использование указателей и определение значения переменной вызывают трудности. В рассказах о языке C++, как мне кажется, очень доходчиво изложена эта тема. А та простота, с которой можно написать программу калькулятора, обусловлена тем трудом, который был вложен разработчиками wxWidgwts в многочисленные классы графических объектов и функций-членов этих классов. Возможность использовать готовые библиотеки, написанные профессионалами, одна из самых сильных сторон языка Си.
Рис. А.20. Выполнение операций с десятичными числами Некоторые возможности II Code::Blocks II Если вам больше по душе русифицированный вариант программы, то поищите в Интернете, воспользовавшись строкой поиска, например: code-blocks ru_ru. Скачав пакет, распакуйте его. Зайдите в папку C:\Program Files\CodeBlocks\ share\CodeBlocks\ и создайте в ней папку «locale», после этого откройте ее и скопируйте папку «ru_RU». После этого запустите программу и зайдите на вкладку «Settings -> Environment», где и поставьте галочку на «Internationalization», выберите «Russian» из выпадающего списка справа (рис. А.21), нажмите ОК.
Рис.А.21. Место изменения языка После перезапуска программа будет иметь такой вид (рис. А.22). Рис. А.22. Русифицированная версия Code::Blocks
Для радиолюбителей, изучающих язык Си, программа Code::Blocks может оказаться интересной еще и тем, что позволяет писать программы для AVR-контроллеров, в частности, для модуля Arduino. Достаточно при выборе типа проекта выбрать AVR project. В качестве компилятора, возможно, используется WinAVR, который предварительно следует тоже установить. У меня в модуле Arduino — микроконтроллер ATMegal68, который я и выбираю при создании проекта Code::Blocks. Вместо заготовки основного файла я копирую готовую, написанную кем-то, программу (рис. А.23)... ...а после трансляции в папке bin\Release нахожу hex-файл с именем проекта. Я предпочитаю проверять в программе ISIS (Proteus), если она есть (рис. А.24). Для загрузки программы в модуль Arduino можно использовать программу avrdude. В качестве интерфейса для работы с программой можно использовать программу SinaProg (рис. А.25). Рис. А.23. Программа для микроконтроллера АТМеда168
U? PD0/RXD/PCINT16 PD1ZTXD/PCINT17 PD2>INT0/PCINT18 PD3/INT1/OC2B/PCINT19 P04/TO/XCK/PCINT2O ₽о5ш/осов.тоыта РОШНО/ОСПА/РС1ЫТ22 PD7/A1N1/PCINT23' Р 90/1С Р1 .• CLKO/PCINTO РВ1/ОС1А/РСЖТ1 PB2/£SXOCTB/PONT2 Р ВЗ/М О S I/O 02 А/РС1МГЗ PB4/M-S0/PCINT4 PB6/SCK/PCINT5 PB6/T0SCWAL1/PC№ Р В7/Т0 S С2/ХТ AL2/PCINT7 *14 лш. 17 _*W 1Q 10 AREF AVCC РСО/АРСО/РСШЗ PC1/A0C1ZPCINT9 PC2/A0C27FCINT10 PC3/ADC3/PCINT11 Р C4/AD C4/S D.A/P СINT12 PC5ZAD C5/SCL/P СINT13 PC6ZPBSEWCINT14 Jg3 Jfel Й1 26 •2Z. j29 ATMEGA168 <TEXT> Puc.A.24. Работа программы при проверке
СОВЕТ. О настройках конфигурации микроконтроллера (fuses) лучше прочитать внимательно, чтобы не заблокировать программную память, установив бит защиты от программирования. Новичок: Но поучиться использованию языка Си для программирования микроконтроллеров вполне можно, и даже, как мне кажется, можно удачно, с помощью Arduino. Мне об этом рано говорить, не настолько хорошо я знаю язык, но программа Code "Blocks позволяет создавать ваши собственные библиотеки, как статические, так и динамические. Пример создания статической библиотеки, чтобы не быть голословным, я «срисую» из руководства одного из ВУЗов. Итак. После запуска программы выбираем создание нового проекта, а тип будущего проекта определяем, как показано на рис. А.26. Рис. А. 2 6. Выбор создания проекта статической библиотеки
Имя исходного файла, созданного программой по завершении настроек проекта, следуя заветам руководства, я переименую: исходный файл языка Си хотелось бы видеть для C++, изменив его расширение. Если файл main.c открыт, его нужно закрыть. Выделив его в окне Проект, достаточно щелкнуть по выделению правой клавишей мышки, чтобы выбрать команду Переименовать (рис. А.27). Рис. А.27. Изменение расширения файла и имени В пункте Проект основного меню выбираем Properties (свойства), где на закладке Цели сборки отмечаем наш файл (рис. А.28). Рис.А.28. Отметка цели сборки
В проект предстоит добавить заголовочный файл. Для этого выбираем в основном меню «Файл -* New -> File...». И делаем надлежащий выбор (рис. А.29). Рис. А.29. Выбор создания заголовочного файла Далее в диалоге указываем полный путь к проекту и задаем оба типа режима, как отладочный, так и конечный, исполняемый (рис. А.30). В заготовку файла заголовка следует вставить имя функции, которая была создана в main.c (рис. А.31). После трансляции и сборки проекта нужная библиотека появится в папке Debug. Теперь, чтобы не усложнять работу, используем консольный проект. Текст заготовки заменим собственным (мной скопированный из оригинала), рис. А.32. Для успешной компиляции и сборки необходимо указать ряд деталей сборки. В основном меню: Проект —► Опции сборки (рис. А.ЗЗ)... Путь к файлам моего предыдущего проекта proba7 должен быть относительным. Раздел Search directories (директории поиска) для компилятора и компоновщика (рис. А.34).
Рис. А.ЗО. Диалог настройки файла проекта Рис.А.31.Дополнение заголовочного файла
Рис.А.32. Изменение текста программы Рис. А.ЗЗ. Закладка опций сборки компоновщика для режима Debug
Рис.А.34. Задание путей для компилятора и компоновщика После компиляции и сборки можно запустить программу в режиме отладки, чтобы увидеть (рис. А.35). Новичок: Программа использует библиотеку, которая была создана в предыдущем проекте? Да! В этом вы можете убедиться, если неверно настроите консольный проект или не настроите его. При создании исполняемого файла проекта требуется повторить оба проекта в режиме Release. Прежде, чем перейти к следующему разделу, хотелось бы упомянуть о еще одной особенности (рис. А.36). Рис. А.35. Работа программы в консольном режиме
. Рис.А.36. Подсказки в текстовом редакторе проекта Вверх и вниз II по лестнице знаний II Используя wxWidgets и wxSmith, спасибо их создателям, можно создавать свои программы. Но в какой мере это приближает к пониманию языка C++? Давайте сделаем несколько уроков [20] по применению wxWidgets без wxSmith. Новичок: А как создать самое простое окно собственными силами? Создавая wxWidgets проект, в диалоге изменим предыдущие установки (рис. А.37). Новичок: Не как в прошлый раз, сейчас в окне Проекты нет ни одного файла, и рабочее поле Code::Blocks пусто (рис. А.38)!
Рис. А. 37. Создание пустого проекта без wxSmith и его компонентов Рис.А.38. Рабочее поле программы проекта tutl Необходимо, следуя уроку, создать четыре файла: tutl.h, tutl.cpp, main.h и main.cpp. Для создания файлов используем Файл New -»• Empty file. Первое, что предлагается сделать, это дать имя файлу. Текст первого файла tutl.h:
Рис. А.39. Изменения в окне менеджера проекта #include <wx/wx.h> class Tutl : public wxFrame { public: Tutl (const wxString& title); }; После записи текста файла содержимое окна Проекты изменилось (рис. А.39). Следующий файл, который следует создать — это tutl.cpp: #include «tutl.h» Tutl::Tutl (const wxString& title) : wxFrame(NULL, wxID_ANY, title, wxDefaultPosition, wxSize(250, 150)) { Centre(); } Нет сомнений, что любая программа должна иметь функцию mainQ. Поэтому следующим будет файл main.h:
#include <wx/wx.h> class MyApp : public wxApp { public: virtual bool Onlnit(); }; Наконец, создадим файл main.cpp: #include «main.h» #include «tutl.h» IMPLEMENT_APP(MyApp) bool MyApp::Onlnit() { Tutl *tutl = new Tutl (wxT(«Проба»)); tutl —> Show(true); return true; } Все вновь созданные файлы появились в окне Проекты. Прежде, чем включить трансляцию и сборку проекта, вспомним, что следует включить поддержку последнего стандарта (для целей и Debug, и Release), рис. АЛО. Выполнив команду Сборка, можно запустить программу (рис. А.41). Новичок: Отлично! Мы поднялись на одну ступеньку по лестнице освоения языка C++. Поздравляю! Но предлагаю спуститься чуть ниже, вспомнив то, что написано в книге о языке C++. Рассмотрим заголовочный файл tutl.h. Он объявляет новый класс Tutl, производный от класса wxFrame. Синтаксис в этом случае: class имя_производного_класса: public имя_ базового_класса { /*...*/ }; В фигурных скобках у нас объявлена общедоступная функция Tutl(const wxString& title). В файле tutl.cpp реализуется
Рис.А.40. Включение дополнительных возможностей языка C++ Рис. А.41. Работа простейшей программы то, что объявлено в заголовочном файле в виде конструктора копии с инициализацией: Tutl::Tutl (const wxString& title) : wxFrame(NULL, wxID_ANY, title, wxDefaultPosition, wxSize(250, 150)) { CentreO; } Заголовочный файл основной функции main объявляет производный класс MyApp от базового класса wxAPP с виртуальной общедоступной функцией-членом OnlnitQ;
class МуАрр : public wxApp { public: virtual bool Onlnit(); }; Основная функция main.cpp использует эту функцию инициализации окна. Синтаксис показан выше. В файле есть одно выражение, которое мне не совсем понятно: IMPLEMENT_APP(МуАрр) Наведя справки, можно выяснить, что это используется в реализации класса приложения, чтобы класс приложения сделать известным для динамического конструктора wxWidgets. Новичок: Но меня интересует еще один урок—мне хочется добавить в рабочее окно кнопку. Если научиться это делать, то можно добавлять и другие элементы без использования готовых решений wxSmith. Хорошо! Начать я предполагаю с повторения урока, что называется «в лоб». Создаем новый проект с «пометкой» Empty project. Создаем, как написано в уроке, заголовочный файл button.h: ttinclude <wx/wx.h> class Button : public wxFrame { public: Button(const wxString& title); void OnQuit(wxCommandEvent & event); }; И второй файл button.cpp: #include «button.h» Button::Button(const wxString& title) : wxFrame(NULL, wxID_ANY, title, wxDefaultPosition, wxSize(270, 150)) { wxPanel *panel = new wxPanel(this, wxID_ANY); wxButton *button = new wxButton(panel, wxID_ EXIT, wxT(«Quit»), wxPoint(20, 20));
Connect(wxID_EXIT, wxEVT_COMMAND_BUTTON_ CLICKED, wxCommandEventHandler(Button::OnQuit)); button —» SetFocus(); Centre(); } void Button::OnQuit(wxCommandEvent & WXUNUSED(event)) { Close(true); } Следующий файл main.h, похоже, не изменился с прошлого урока: #include <wx/wx.h> class МуАрр : public wxApp { public: virtual bool Onlnit(); }; И последний файл main.cpp описывает все, что будет происходить с кнопкой: #include «main.h» #include «button.h» IMPLEMENT_APP(MyApp) bool MyApp::Onlnit() { Button *btnapp = new Button(wxT(«Button»)); btnapp —> Show(true); return true; Новичок: Этот файл очень похож на аналогичный в первом примере. Да! Но... вот, что появляется после трансляции программы и сборки (рис. А.42).
Рис.А.42. Работа программы второго урока Если щелкнуть мышкой по кнопке, то окошко программы исчезает, программа закончила работу. Вот какие есть пояснения тех изменений, что произошли: wxPanel *panel = new wxPanel(this, wxID_ANY); Вначале мы создаем wxPanel. Этот элемент будет располагаться внутри wxFrame. Строка: wxButton *button = new wxButton(panel, wxID_EXIT, wxT(«Quit>>), wxPoint(20, 20)); f Мы создаем wxButton. Кнопка расположится на панели. Мы используем предопределенный идентификатор wxID_EXIT для кнопки. Этим отобразится небольшая иконка выхода на кнопке. Название кнопки — это Quit. Кнопка будет позиционироваться в координатах х=20, у=20. Начало системы координат в верхнем левом углу. Connect(wxID_EXIT, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(Button::OnQuit)); Если мы щелкнем по кнопке, генерируется событие wxEVT_COMMAND_BUTTON_CLICKED. Мы соединяем (connect) событие с методом OnQuit() класса Button. Таким образом, когда мы щелкаем по кнопке, вызывается метод OnQuit(). button —> SetFocus (); Мы задаем фокус для клавиатуры на кнопке. При этом, если мы нажмем на клавиатуре клавишу Enter, кнопка будет нажата.
Close(true); Внутри метода OnQuit() мы вызываем метод Close(). Этим мы закроем наше приложение. Новичок: Исчерпывающие пояснения. Используя их, я предлагаю в первой программе добавить кнопку. Мне интересно, получится ли что-то у меня? Я создаю новый пустой проект и повторяю все, что было описано для первого урока [20]. Поскольку я копирую тексты из этого раздела приложения А (непосредственно с листа), я вношу изменения в имена, сопоставляя их с новым именем проекта tut3. Убедившись, что программа транслируется и запускается, я приступаю к изменениям программы. Я уверен, что заголовочный файл для кнопки я могу повторить без изменения. Или нет... Попытка совместить оба проекта полностью, повторяя оба урока [20], не слишком умное решение. Хотя программа транслируется и работает, но дает два рабочих окна «имени первого и второго проектов». Копирование без понимания всегда лишено смысла. Достаточно сравнить файлы обоих уроков [20], чтобы понять — оба примера создают свои окна, которые производятся от класса wxFrame. Удалив из второго урока [20] все, что относится к реакции на нажатие кнопки, можно яснее увидеть то общее, что есть в обоих случаях. Постепенно становится понятно, что нет необходимости использовать что-то кроме одного выражения, которое я добавляю в файл (первого урока) tut3.cpp: ttinclude <<tut3.h>> Tut3::Tut3(const wxString& title) : wxFrame(NULL, wxID_ANY, title, wxDefaultPosition, wxSize(250, 150)) { wxButton *button = iiew wxButton(this, wxID_ANY, wxT(«Button»))i Centre(); }
Обращаясь к руководству по языку C++, можно выяснить, что: динамическое выделение памяти осуществляется с помощью оператора new. Оператор возвращает указатель на начало нового блока памяти. Синтаксис такой: pointer = new type. После сборки проекта появляется следующее окно (рис. А.43). Вспоминая свой проект с использованием wxSmith, я добавляю еще одну кнопку. И получаю (рис. А.44). Рис. А.43. Окно первого урока с кнопкой Рис. А.44. Окно программы с двумя кнопками Новичок: И где вторая кнопка? Эта проблема решается с помощью параметра, который я не использовал: wxPoint(20, 20) Теперь для каждой кнопки можно указать координаты расположения с помощью этого параметра: wxButton *buttonl - new wxButton(this, wx!D_ANY, wxT(«Buttonl»), wxPoint(20, 20)); wxButton *button2 = new wxButton(this, wxID_ANY, wxT(«Button2>>) , wxPoint(20, 50)); Итог этой части работы (рис. А.45). Я добился решения поставленной задачи, но при этом меня заинтересовала проблема двух кнопок, которая возникла еще при использовании сборки с помощью wxSmith графического помощника. Если я добавлял одну кнопку, то она занимала весь
Рис.А.45. Окно программы после использования параметров координат экран. Тот же эффект возник и без wxSmith. Но во втором уроке [20], напомню: Мы создаем wxButton. Кнопка расположится на панели. Мне интересно, если я добавлю панель при работе с wxSmith, смогу ли я получить одну кнопку (рис. А.46)? Рис. А. 46. Одна кнопка на панели с использованием wxSmith Хотя автор уроков [20] только мельком отметил тот факт, что все элементы добавляются на панели, понять это помог придуманный мною третий урок. ПРИМЕЧАНИЕ. Кстати, выполняя его, я встретил еще одну особенность - попытка изменить название кнопки, написав его как «Кнопко», оказалась неудачна.
Программа не смогла транслироваться. Причины этого мне пока не понятны, но я надеюсь, что разберусь и с этим. Позже. I Уроки и современные технологии Любой инженер, начиная создание чего-то собственного, обращается к уже существующим решениям. Это правильный подход. Но не следует забывать о годах учебы инженера. Новичок: Повторяя уроки, пройденные в предыдущем разделе, мы использовали технологию копирования из одного окна (Интернет-браузера) в другое (окно текстового редактора Code:'.Blocks). Это позволило быстро получить результат. Но будет ли эффект долговременным? Давайте проверим это, повторив первый урок без копирования готовых текстов. Создавая пустой проект, я вспоминаю, что необходимо добавить поддержку последнего стандарта языка C++. И первый файл — это заголовочный файл, который я назвал tutor5.h: #include <wx/wx.h> class Tutor5::Tutor5(const wxString &name): wxFrame(wxWindow, wxID_ANY, label) { Centre(); }; Новичок: В заголовочном файле, как мне запомнилось из руководства по языку и из уроков, достаточно объявить новый класс и инициализировать его с помощью конструктора (я пока не уверен в правильности этой фразы, но за подсказкой не хочу обращаться). Посмотрим. Следующий файл — это tutor5.cpp, где следует реализовать новый класс:
#include <wx/wx.h> #include "tutors.h" Tutors = new Tutors * tutor(wxT(«Привет»)); Это все, что я вспомнил. Далее следует создать основной файл main, начиная с заголовочного файла. В этот момент я понимаю, что ничего вспомнить не могу. Придется обратиться к подсказке — взглянуть на правильные файлы, чтобы по памяти воспроизвести их. Для первого заголовочного файла, конечно, следует объявить приложение, создав новый класс: # include <wx/wx.h> class myAPP : public wxApp { public: туАрр onlnit(); }; И вот, что мне запомнилось для файла main.cpp: ttinclude <wx/wx.h> # include «main.h» myApp::Onlnit { Tutor5 - new Tutor * tutor(wxT(«Привет»)) ; tutor —► Show(); return tutor; } После запуска сборки появляются сообщения об ошибках (рис. А.47). Заглянем в справочник (это нормальная практика) по классу wxApp (рис. А.48). Попробуем привести «ошибку» к должному виду в файле main.h. # include <wx/wx.h> class myAPP : public wxApp { public: virtual bool Onlnit(); };
Рис.А.47. Первый запуск программы на сборку This must be provided by the application, and will usually create the application's main window, optionally caliktg SetTopWIndowQ You may use ОпЕхЩ) to dean up anything inRIallzed here, provided that the function returns true Notice that it you want to use tee command line processing provided by wxWidgets you have to caS the base class version In the derived class OnlnitQ Return true to continue processing f alao to exit tee application immediately Puc.A.48. Справка no классу wxApp и функции-члену OnlnitQ Следующая ошибка появляется в файле main.cpp (рис. А.49). Новичок: Первый опыт показывает, что копировать текст программы гораздо легче, чем писать самостоятельно. Согласен. Повторим этот опыт, но теперь начнем с правильной стороны, с «главной функции»: мы собираемся соз-
Рис.А.49. Следующая ошибка в файлах проекта дать новое приложение, стало быть, начинать надо с создание нового класса приложения. От нового класса требуется, чтобы при запуске приложения можно было создать окно. main.h #include <wx/wx.h> class MyApp : public wxApp { public: virtual bool Onlnit(); }; Теперь обратимся к основному файлу. main.cpp #include "main.h" IMPLEMENT_APP(MyApp) bool MyApp:: Onlnit() { return true; };
Подглядеть пришлось, чтобы добавить implement^ АРР(МуАрр). Теперь необходимо создать новый класс для окна в файле заголовка. Но прежде оттранслируем то, что есть — достаточно пропустить одну букву в ключевом слове или забыть поставить скобку, чтобы появились проблемы. tutor6 .h #include <wx/wx.h> class Tutor6 : public wxFrame { public: Tutors (const wxString &name); } ; Если не пытаться вспоминать, что было когда-то сделано, то можно повторить уже написанный заголовочный файл, подправив идентификаторы и ту функцию-член, которая нужна. Осталось написать файл срр к этому проекту... И вновь, как и ранее, я пытаюсь вспомнить, а не понять, что нужно делать... Видимо, я жертва современных технологий, мне проще скопировать: ttinclude <<tutor6.h>> Tutor6::Tutor6(const wxString& title) : wxFrame(NULL, wx!D_ANY, title, wxDefaultPosition, wxSize(270, 150)) { Centre(); } Добавив в файл main две строки: Tutor6 *tutor = new Tutor6 (wxT("Tutor")); tutor —> Show () ; Puc.A.50. Окно программы, полученное ручным написанием текста программы Последняя ошибка — не добавлено в основной файл #include “tutor6.h”. Итог (рис. А. 50).
ВЫВОД Но главный итог, главный вывод, который я могу сделать - нужно повторять собственное написание простых программ много раз, стараясь не подглядывать, не копировать, повторять до тех пор, пока не станет ясно, что нужно писать во всех файлах. Чтобы следовать этому совету, я добавляю в файл tutor.cpp (забыл добавить 6, когда создавал файл) две строки, создающие кнопку: wxPanel *panel = new wxPanel(this, wxID_ANY); wxButton *button = new wxButton (panel, wxID_ ANY,'wxT("button"), wxPoint(20,20)); Частью это происходит благодаря воспоминаниям, частью от понимания, а частью с помощью банального подглядывания. Меня йнтересует названия по-русски. Я меняю надпись в строке, создающей окно (рис. А.51), где приходится внести правку: Tutor6 *tutor - new Tutor6 ("Проба"); В прошлый раз при замене этикетки на кнопке кириллической надписью я получал ошибки. Но не в этот раз (рис. А. 52). В чем разница... может быть, когда-нибудь и это будет понятно (может быть, это связано с изменением языка интерфейса). Рис. А.51. Окно с кнопкой Рис.А.52. Изменение названия кнопки
Рис.А.53. Новая работа программы Повторение удавшегося приема настраивает на оптимистичный лад. Можно повторить строку, подправив ее и добавив к уже работающим выражениям. Этим мы добавим текстовое окно (рис. А.53). То есть: wxPanel *panel = new wxPanel(this, wxID_ANY); wxTextCtrl *control = new wxTextCtrl(panel, wxID_ANY); wxButton *button = new wxButton (panel, wxID_ ANY, wxT(«Кнопка»), wxPoint(20,50)); Казалось бы, что еще нужно? Однако попытка переместить текстовое поле, используя wxPoint(20,20), оказывается неудачна. Что означает, что уроки выучены плохо, а отсутствие знаний не покрывается современными технологиями: готовые библиотеки wxWidgets, прекрасный текстовый редактор Code “Blocks с подсказками, хороший компилятор, сообщающий об ошибках, и возможность найти в Интернете решение своих проблем. Уроки следует выполнять хорошо. |Что задали на дом? Новичок: На дом задали разобраться, почему не получилось сместить текстовое поле? Я не скажу, с какого раза я смог, не подглядывая и не копируя, создать новое приложение без остальных элементов, но попробую вспомнить, что мне мешало это сделать сразу. Создаем новый проект (рис. А.54). Выбираем wxWidgets project (рис. А.55) и нажимаем кнопку Go:
Рис.А.54. Создание нового проекта Рис.А.55. Выбор типа нового проекта В следующем диалоговом окне я ничего не меняю, нажимаю кнопку Next>. Затем выбираю ту версию wxWidgets, что установлена у меня, то есть, wxWidgets 3.0.x и нажимаю кнопку Next> (рис. А.56).
Рис.А.5б. Выбор версии wxWidgets Далее следует указать имя проекта, используя отмеченную на рис. А.57 кнопку, можно (и нужно, наверное) указать папку, в которой будет храниться проект (рис. А.57). Рис. А. 57. Задание имени и места расположения проекта
Следующее диалоговое окно предлагает внести все авторские данные, это, если нужно, а можно только имя, не исключаю, что можно и ничего не добавлять. Затем следует выбор метода построения проекта. В данном случае я хочу самостоятельно разобраться со всеми проблемами (рис. А.58). Далее следует указать место расположения wxWidgets — при первом запуске Code::Blocks, в следующий раз можно пользоваться кнопкой Next», равно как и в других диалогах (рис. А.59). Рис. А.58. Выбор метода сборки проекта Следующий диалог я оставил без изменений, а в предпоследнем диалоге указал, что создается пустой проект (рис. А.60). В появившемся сообщении есть возможность согласится, нажав кнопку ОК, что я делаю. Новичок: А по причине пустого проекта в следующем диалоговом окне можно ничего не выделять, нажав кнопку Finish?
Рис.А.59. Выбор места, где находится wxWidgets Рис. А. 60. Указание на создание пустого проекта Согласен. Но прежде, чем создавать новые файлы, я хочу отметить, что проект может использовать современную версию компилятора: Проект -* Опции сборки (рис. А.61).
Рис.А.61. Отметка о применении последнего стандарта в Debug и Release режимах Теперь следует создать все необходимые файлы. Первым создадим заголовочный файл основной функции программы main. В нем объявляем создание собственного класса, производного от класса приложений: Файл -> New —» Empty file. Добавляем имя заголовочного файла и соглашаемся, что используем его в обоих режимах и отладки, и окончательной сборки программы. В появившемся в редакторе поле начинаем с включения нужного заголовка (это я запомнил), стараясь не переврать ключевое слово #include <wx/wx.h>. Впрочем, достаточно начать со значка решетки, чтобы из выпадающего списка выбрать нужное (рис. А.62). Итак, я создаю свой класс на базе wxApp, который я называю MyApp. Из основного класса мне нужна одна функция Onlnit(), позволяющая при инициализации приложения увидеть окно, которое еще предстоит создать (рис. А.63).
Рис.А.62. Подсказка по выбору того, с чего следует начать Рис.А.бЗ. Создание заголовочного файла основной функции проекта Что здесь у меня вызывало проблемы? В первую очередь то, что я забывал, ведь это создание нового приложения, то есть, производного класса от wxApp. Затем, что это общедоступный класс. И тот факт, что мне нужна общедоступная (public) виртуальная функция, возвращающая булево значение. Аналогично созданию заголовочного файла создаем основной рабочий файл main.cpp.
ПРИМЕЧАНИЕ. В который не забываем включить ранее созданный заголовочный файл, поскольку нам нужно теперь уже не объявлять наше приложение, а реализовать его. Поскольку файл в папке проекта, его имя заключаем в кавычки. Следующее, что я всегда забываю, таинственная фраза о реализации, но здесь тоже прекрасно работает подсказка (рис. А.64). Рис. А.64. Подсказка после ввода нескольких букв В скобках указываем свой класс. Теперь можно вызвать функцию инициализации, указав границы применения. А проверить, что все сделано правильно, можно запустив сборку проекта (рис. А.65). Теперь приступаем к созданию окна. Начинаем с создания заголовочного файла, где объявим новый класс (я использую имя проекта), рис. А.66. В файле заголовка я тоже в прошлый раз забыл указать public, забыл, что мне нужна функция вставки заголовка (рис. А.67). И переходим к созданию файла tutor.cpp, начиная с включения файла заголовка. При создании окна его устанавливаем в центр (рис. А.68). В этом месте я, признаться, опять забуксовал, пришлось подсматривать и реализацию, и параметры. А при попытке
Рис.А.65. Предварительная проверка правильности создания приложения Рис.А.6б. Подсказка при выборе базового класса транслировать текст возникла еще одна проблема — исполняемый файл режима Debug оказался недоступен, отказано мне было в доступе (замучил я, наверное, программу). Попытка удалить файл .ехе из папки Debug тоже не удалась, отказано. Пришлось перезагрузить компьютер, удалить этот файл, собрать проект заново. Чтобы увидеть результат своих
Рис. А. 6 7. Создания файла tutorll.h Рис.А.68. Создание файла tutorll.cpp
Рис. А.69.Добавление в файл main.cpp трудов, мне осталось добавить два выражения в основной файл (рис. А.69). Хотя я сделал эти вставки по памяти, не обошлось тоже без ошибок: забыл вставить заголовочный файл своего класса Tutorll, при названии латиницей Tutorll(wxT(“Lesson И”)), а для кириллицы потребовалась та запись, которая есть на рисунке. Осталось добавить в файл tutor 1 l.cpp одно выражения для создания панели: wxPanel *panel = new wxPanel (this, wxID_ANY); СОВЕТ. Пора, наконец, перейти к тому, чего ради я все это затеял. И не думайте, что все выше написанное и показанное в картинках для вас, нет, это я сделал для себя, чтобы запомнить. И вам советую так делать, уроки, записывая, что вы делаете. Лучше запоминается, проще разобраться, что плохо усвоено.
Впрочем, у каждого свой стиль работы. Итак. Попытка добавить в файл tutorП.срр фразу: wxTextCtrl *text = new wxTextCtrl (panel, wxID_ANY); дает появление текстового поля на панели (рис. А.70). А добавление параметра wxPoint (20,20) приводит к ошибке. Эта загадка решилась просто (хотя я и не понял, почему так): добавление в строку выше кроме указания места расположения еще и пустого имени дает искомый результат. А можно еще (рис. А.71), как оказалось, добавить и размер: wxTextCtrl *text = new wxTextCtrl (panel, wxID_ ANY6 wxT(""), wxPoint(20,20), wxSize(80,20)); Puc.A.70. Рабочее окно с текстовым полем Рис. А.71. Совместное размещение кнопки и текстового поля Разыгравшийся аппетит (сознаюсь, что увидел это, пока разбирался с текстовым полем) заставляет меня... Добавить в мой файл tutorП.срр несколько строк: wxMenuBar *menubar = new wxMenuBar; wxMenu *file = new wxMenu; wxMenu *help = new wxMenu; menubar —+ Append(file, "Файл"); menubar —» Append(help, "Помощь"); SetMenuBar(menubar); И это дает (рис. А.72). Рис.А.72. Добавление основного меню
I События в мире кнопки Новичок: Убедился, что создание рабочего окна, меню, элементов рабочего поля окна важно и не так просто, как это могло показаться при использовании внешнего компоновщика интерфейса. Но оно бесполезно, если нельзя использовать элементы рабочего окна для обработки каких-то событий. Если есть кнопка, то ее хочется нажать, чтобы... Попробуем сделать так, чтобы при нажатии кнопки очищалось текстовое поле. Руководствуясь уроками, я для начала хочу внести в программу изменение, чтобы название кнопки при ее нажатии изменилось. Не пытаясь написать что-то самостоятельно, я просто копирую в свой файл tutl2.h дополнительно несколько строк: #include <wx/wx.h> class Tutl2 : public wxFrame { public: Tutl2(const wxString &title); void OnButtonClick(wxCommandEvent & event); private: DECLARE_EVENT_TABLE() }; И в файл tut 12.cpp копирую: void Tutl2::OnButtonClick(wxCommandEvent& WXUNUSED(event)) { SetLabel (wxT ("OK”) ) ; } BEGIN_EVENT_TABLE(Tut12, wxFrame) EVT_BUTTON(wxID_ANY, Tutl2::OnButtonClick) END_EVENT_TABLE() Конечно, я изменил, приведя в соответствие со своей «маркировкой», ряд названий. Кроме того, в классе wxButton подсмотрел выражение, касающееся задания этикетки. Почему
Рис. А.73. Первый результат по использованию событий я скопировал текст из уроков? Потому что достаточно одной опечатки, чтобы ничто не работало, чтобы появились ошибки, которые, возможно, понятны опытному программисту, но не мне. Результат, который я получил... Впрочем, смотрите сами (рис.А.73). Получается, что SetLabel(wxT(«OK»)) относится не к кнопке, а к окну. Попытка изменить эту строку на: button —> SetLabel(wxT(“ОК”) ) ; ...приводит к появлению ошибки, связанной с тем, что моя кнопка либо не находится в границах моего класса, либо не является членом семейства wxButton. Проблема решилась тем, что в файле tutl2.h я, следуя урокам, добавил: wxButton *button; В файле tutl2.cpp изменил создание кнопки: button = new wxButton (panel, wxID_ANY, wxT(“Кнопка”) , wxPoint(20,20)); И использовал изменение этикетки, как показано выше. Теперь все получилось (рис. А.74). Рис.А.74. Новый результат первого использования событий Для достижения окончательного результата осталось добавить текстовое поле. Я учитываю предыдущие искания и повторяю создание тестового поля, как сделал это с кнопкой. Добавив команду по смене этикетки у текстового поля, я полу-
чаю результат, который намеревался получить изначально (рис. А.75). Теперь мой заголовочный файл tutl2.h имеет вид: #include <wx/wx.h> class Tutl2 : public wxFrame { public: Tutl2(const wxString &title); void OnButtonClick(wxCommandEvent & event); wxButton *button; wxTextCtrl *text; private: DECLARE_EVENT_TABLE() ); И файл tutl2.cpp: #include <<tutl2.h>> Tutl2::Tutl2 (const wxString &title) : wxFrame (NULL, wxID_ANY, title, wxDefaultPosition, wxSize(500,200)) { wxPanel *panel = new wxPanel(this, wxID_ANY); button = new wxButton (panel, wxID_ANY, wxT (“Кнопка”), wxPoint(20,20)); text - new wxTextCtrl (panel, wxID_ANY, wxT(““), wxPoint(20,50)); Centre(); } void Tutl2::OnButtonClick(wxCommandEvent& WXUNUSED(event)) { text —> SetLabel(wxT(""));
button —» SetLabel(wxT("OK")); } BEGIN_EVENT_TABLE(Tutl2, wxFrame) EVT_BUTTON(wxID_ANY, Tutl2::OnButtonClick) END_EVENT_TABLE() Игра с названием текстового поля, которую я затеял, никак не связана с чем-то иным, как только с незнанием команды, которая могла бы очистить это текстовое поле. Возможно, такая команда (или функция) есть, но я ее не нашел. Теперь, когда первый положительный результат получен, я хочу замахнуться на современный стиль выполнения событий. В уроке, которому я следую, написано, что применение таблиц событий унаследовано от языка Си, а современный метод подразумевает использование ConnectQ. Я не забываю, что повторение мать учения. Поэтому не пытаюсь исправить предыдущий проект, а создаю новый, где постараюсь все (или большую часть) написать «от руки». Однако попытка перекопировать урок под мои нужды дает ошибку, природу которой я не понимаю (рис. А.76). Не помогло даже то, что я назвал этот проект Lesson 1, чтобы избежать названия Tutor 13. И я не понимаю, в чем причина, поскольку кнопка и объявлена и реализована... После скитаний по форумам в поисках ответа, после разных попыток вернуть кнопку «из заграницы» я, наконец, замечаю, что, копируя, допустил ошибку. Я много раз сравнивал исходный текст урока со своей копией, я же смотрел... но не видел. Очевидно, что сообщение об ошибке настолько привлекло мое внимание к кнопке, что остальное осталось вне поля моего зрения. Подсказка для опытного человека — это помощь, а для неопытного далеко не всегда. Я не исключаю, что свою лепту внесли многочисленные страницы классов wxWidgets, когда я отыскивал необходимые для замены элементы, но это и не отменяет того, что следует лучше изучать предмет. После исправления ошибки программа транслируется и выполняется (рис. А.77) так же, как и в предыдущем случае. А исправление было простым:
Рис.А.76. Ошибка, связанная с нарушением границы? Й8-СЛ й» Amxtocte ® «9* «Лйю wxPanel * passel = new wxPanel (thie, wxID_ANY); button ~ near wxButtonфаиеХ, wxWJAHY,.-««SeringfwxT{"^нодка"))» traBolnc{70,20})\ text » near wxTextCtrl«panel, wxID_ANY, witstring ^wxT(w*H » wxPclnt(28*<0j ) t COSOACX (wx£VT_CaMBU81S_BUTrOK CXIOCED, wxC'oemaMSEvenrKaswllee ijbeal: :OoBtittaBClicX’ Cencafe'i'?',* I~™------JhK^renrrw. Debug inl*e»cml (c<x»piler: <Жи <И ICnecicing fot *х1«жяф: C^XVwrw^vla^sL^OaxkeopMM^SeXparl Seay«*4' ! »<.Unir\l>‘«rter\h«_®C\5>»rtwVl*e«o»-.J.\»'irA' K.®> фА-’Jff !£•& JRtrfS- ИЙ* it_pt©g В®» IcwiBSVertlns ЬвИк Mttitag яфм» Щ fe* Natwnat teguments Dm ®» MLS Ute aag^ NVIDIA й» PeAog* ij0& PwUNe AB8YY ЯйМШмА UiW FfO^xrn F«lei MWI€2 «BrQt QucsShrito «•►«му. * .... Рис. A.77. Работа исправленной программы
void Lesl::OnButtonClick(wxCommandEvent & event) { button —> SetLabel (wxT(“OK”) ) ; }; Дойдя до этого места в рассказе, я вспомнил, что хотел отыскать руководство к программе Code "Blocks и перевести его. Перевод этого руководства вы найдете на виртуальном диске (файл codeblocks.pdf). ПРИЛОЖЕНИЕ Б СОДЕРЖАНИЕ ВИРТУАЛЬНОГО ДИСКА partX_projects — это проекты, о которых рассказывается в книге. S4AFirmware — программа для модуля Arduino, позволяющая ему работать с S4A. atmegal68 и atmega328 — datasheets к микроконтроллерам Arduino Nano и Arduino Uno. codeblocks.pdf — рассказ о среде разработки. Getting-Started-Guide-Scratch2 — быстрое знакомство с языком Scratch. wxWidgets.pdf — рассказ про wxWidgets. Виртуальный диск вы найдете на сайте издательства: www.nit.com.ru
ССЫЛКИ НА ИНТЕРНЕТ-РЕСУРСЫ: 1. Сайт проекта Arduino: http://arduino.cc/playground/Linux/ OpenSUSE 2. Ряд полезных данных и многое другое: http://robocraft.ru/ 3. Программа S4A (Scratch for Arduino): http://s4a.cat/ 4. Руководство по языку Scratch: https://resources.scratch. mit.edu/www/guides/ru/Getting-Started-Guide-Scratch2.pdf 5. Программа Fritzing: http://fritzing.org/ 6. Программа MicroBasic: https://www.mikroe.com/ mikrobasic/#pic 7. Программа oscilloscope: http://www.compcar.ru/forum/ showthread.php?t=4457 8. Графический редактор Inkscape: http://inkscape.org 9. Программа xoscillo: https://code.google.eom/p/xoscillo/ 10. Библиотека для работы с последовательным портом: http://serialib.free.fr/html/files.html 11. Сайт «Электроника для всех»: http://easyelectrohics.ru/ 12. Описание начала работы с WinAVR: http://robocraft.ru/ blog/arduino/116.html 13. Исходный код программы kontrollerlab: http://www. cadmaniac.org/projectMain.php?projectName=kontrollerlab&sect ion=download 14. Руководство к компилятору AVR-GCC: http://kindabook. org/avr-gcc-user-manual.pdf 15. Сайт автора программы FLProg: http://flprog.ru/ 16. Библиотека для Arduino датчика температуры: http:// milesburton.com/Dallas_Temperature_Gontrol_Library 17. Сайт автора книги: http://vgololobov.narod.ru 18. Сайт программы Code::Blocs: http://www.codeblocks.org/ 19. Сайт wxWidgets: http://www.wxwidgets.org/ 20. Уроки по wxWidgets: http://zetcode.com/gui/wxwidgets/