Основы ARDUINO. Что же такое Ардуино?
В 2004 году несколько инженеров и преподавателей института в ита- льянском городе Ивреа поставили перед собой цель научить студентов неэлектронных специальностей создавать электронные устройства. Создавать быстро и, желательно, без углубленного изучения электро- ники, электротехники и программирования. Серия специальных плат, которую они создали, получила название Arduino от имени реально существовавшего короля Ардуина, правившего Италией в 1002—1014 годах.
Авторы идеи взяли за основу Arduino один из самых популярных универсальных микроконтроллеров своего времени под названием ATmega8. Эта микросхема относится к семейству так называемых AVR-контроллеров, которую разрабатывает и выпускает фирма Atmel. За годы существования семейства Arduino AVR-контроллеры посте- пенно совершенствовались, и сейчас основой для большинства плат Arduino служит контроллер ATmega328. В первую очередь он обладает значительно большим объемом памяти, чем его предки ATmega8 и ATmega168, но по подключению ничем от них не отличается. Есть и платы Arduino на других контроллерах — более мощных или обла- дающих другим набором функций.
Идея итальянских инженеров оказалась настолько плодотворной, что они образовали коммерческую компанию, которая стала проекти- ровать и выпускать платы Arduino. Очень важным моментом во всей этой истории был тот факт, что, кроме названия Arduino, компания Arduino LLC не закрепляла за собой какие-то права на разработанные платы. Схемы плат и среда для их программирования распространяются под свободной лицензией и могут выпускаться и модифицироваться любым желающим.
Это в значительной степени способствовало взрывному росту популяр- ности Arduino не только среди радиолюбителей, но и среди произво- дителей комплектующих. За прошедшие годы по всему миру появилось множество клонов плат Arduino, нередко с теми или иными измене- ниями и усовершенствованиями, под разными названиями в том же стиле: Freeduino, Craftduino, Carduino и многие другие. Все подобные копии (клоны) совместимы с оригинальными платами Arduino, в том числе и по размерам. Они могут иметь те или иные усовершен- ствования: например, российский Craftduino имеет больше выводов в целях доступности использования различных функций контроллера, Freeduino — усовершенствованные способы питания и так далее.
В настоящее время название Arduino означает целую отрасль промыш- ленности, выпускающей комплектующие для быстрого проектирования и самостоятельной сборки устройств самого различного назначения — от игрушек и бытовой автоматики до крупных электронных проектов. Трудно найти такую задачу в области электроники, для которой бы не существовало Arduino-решения. Платформой заинтересовались
и серьезные «взрослые» компании: так, Google создала специальный программный интерфейс для взаимодействия Arduino-устройств с опера- ционной системой Android в коммуникаторах и планшетах, а компания iRobot — для подключения Arduino-модулей к ее роботам-пылесосам. Поддержка Arduino также включена в состав AVR Studio — професси- ональной среды программирования AVR-контроллеров фирмы Atmel.
Не стоит, конечно, думать, что владение Arduino заменит профес- сиональный подход к проектированию электронных устройств на основе микроконтроллеров. Однако, Arduino — отличная стартовая площадка для новичков, позволяющая своими руками пощупать, что это такое — современная электроника. И на ее основе можно сделать много интересных и пригодных для практического использования вещей, которые доставят вам немало радости!
Автор предполагает, что читатель уже знаком с макетными платами, мультиметром, знает, что такое осциллограф, и умеет определять величину резистора по цветовому коду. Если это не так, то советую обратиться к первой книге — «Азбука электроники. Электронные устройства своими руками», где подобные сведения изложены во всех подробностях.
Основные платы Arduino
В предисловии также упоминалось, что ранее платы Arduino использо- вали контроллер ATmega168 (а еще ранее — самый первый представи- тель этой линейки ATmega8). И до сих пор на многих ресурсах в Сети можно встретить ссылки
на принципиальные схемы и обозначения выводов плат, где показан именно ATmega168. Это не должно вас смущать, потому что эти контроллеры устроены одинаково и различаются лишь объемом памяти для различных целей, в том числе — для загрузки программы. Так что схем с обозначениями выводов на основе любой из этих разновидностей AVR-контроллеров пригодны для использования.
Сами платы, конечно, совершенствуются со временем и потому могут несколько отличаться. Хотя все новые их разновидности можно без раздумий ставить вместо старых — изменения почти не затрагивают главных особенностей.
Различных плат Arduino существует более полутора десятка разно- видностей. Примеры из этой книги ориентированы на три варианта: самую известную плату Arduino Uno, а также две миниатюрных платы, удобных для применения в автономных малогабаритных конструк- циях — Arduino Nano и еще меньшую по размерам Arduino Mini (не путать с Arduino Micro!). С точки зрения программирования эти платы устроены одинаково, и программу, отлаженную на наиболее удобной для макетирования плате Arduino Uno, можно без проблем закачивать в Nano и Mini.
Arduino Uno (см. рисунок на предыдущей странице) — основная (базовая) модель Arduino, на нее равняются все остальные. Ее размер (54 69 мм, без учета разъемов, выступающих за пределы платы) и конфигурация контактов стали стандартом, на который равняется множество электронных изделий, включая даже далекие от собственно Arduino. На размеры Arduino Uno обычно ориентируются также про- изводители плат расширения, так называемых «шилдов» (shields). «Шилды», содержащие дополнительные компоненты или гнезда для их подключения, могут устанавливаться на плату Arduino Uno «в эта- жерку» друг над другом.
Другие платы и внешние датчики под- ключаются к Arduino Uno с помощью широко распространенных контактных колодок с шагом 2,5 мм (см. рисунок слева). Такие разъемы со штырями носят название PLS, ответные части-гнезда (такие, как установлены на плате Arduino Uno) называются PBS. Платы расширения имеют такие же разъемы, как на плате Arduino Uno, но с противоположной гнездам стороны разъемов у них торчат штыри, что и позволяет устанавливать платы «в этажерку».
Рассмотрим кратко основные компоненты платы Arduino Uno. Самая большая микро- схема с 28 выводами (по 14 с каждой сто- роны) — это сам контроллер ATmega328.
Здесь он установлен на панельку, что позволяет извлекать его и, например, использовать отдельно в других схемах. Таким путем Arduino Uno можно использовать в качестве программатора для этой микросхемы.
На любой плате Arduino обязательно имеются, как минимум, контактные площадки для установки такого разъема, позволяющего программировать контроллер, не извлекая его из схемы. Такая система носит название ISP, что означает In System Programming («программирование в системе»). Через нее же закачивается программа Bootloader, которая всегда присутствует в Arduino — именно она позволяет программировать контроллер через USB без лишних проблем. Возможно и обратное: платы Arduino можно применять в качестве программатора — для загрузки программ, созданных в среде про- граммирования Arduino IDE, в другие типы контроллеров семейства AVR. Тогда их можно использовать отдельно в схемах, где дополнительные устройства, размещенные на плате, не требуются, а возможности довольно-таки навороченного контроллера ATmega328 излишни.
На другом торце платы Arduino Uno размещен, во-первых, основной коммуникационный USB-разъем для подключения к компьютеру. По традиции он самого большого размера из всех многочисленных раз- новидностей USB (такие разъемы устанавливают сейчас только на крупногабаритной технике, например, на принтерах или сканерах). Потому к нему придется приобретать отдельный кабель, называемый USB-кабелем типа AB. Сторона A – это обычный прямоугольный USB, всем хорошо знакомый по флэш-накопителям, он вставляется в компьютер, а сторона B — квадрат со скошенными гранями, он и вставляется в разъем на плате. Через USB-разъем производится про- граммирование платы в среде Arduino и одновременно он же служит для посылки сообщений через последовательный порт контроллера при его работе.
Во-вторых, на той же стороне платы размещено гнездо для подключения внешнего источника питания. При подключении к компью- теру через USB-разъем плата будет получать питание 5 вольт через него, таким образом при программировании отдельного внешнего источника обычно не требуется. Если в гнездо питания вставить штекер от сетевого адаптера, то тогда уже питания от USB не требуется, и плата может работать отдельно от компьютера. Напряжение, которое выдает адаптер, может быть нестабилизированным и должно находиться в пределах 7–12 вольт. Теоретически преобразователь питания, встроенный в Arduino, позволяет подавать внешнее питание до 20 вольт, но он не установлен на радиатор и может перегреваться при значительной разнице напряжений между входом и выходом. Потому в описаниях Arduino обычно ограничивают питание значением 12 вольт, хотя при небольшой нагрузке платы можно подавать питание и немного выше этого значения.
Кстати, если внешний источник стабилизированный, то нижнее значение в 7 вольт также соблюдать необязательно — при необходимости Uno отлично работает от 5-вольтовых адаптеров или от батарейных блоков с напряжением даже ниже 5 вольт. При покупке адаптера надо учитывать, что диаметр штекера разъема питания составляет 5,5 мм, и более тонкие разъемы (например, от мобильных зарядников) сюда не подойдут. При необходимости подключения нестандартных источников или батарейных блоков можно приобрести универсальный разъем 5,5 мм, в котором установлена колодка для непосредственного подключения проводов от источника «под винт» (см. рисунок справа).
На контакты боковых разъемов, о которых мы говорили ранее, в основном выведены напрямую выводы самого контроллера, иногда их еще называют портами (хотя это и не совсем точно). Часть из этих выводов обозначается просто цифрами от 0 до 13 — это цифровые порты ввода-вывода, которые могут переключаться из состояния работы «на выход» в состояние «на вход» для приема сигналов логических уровней нуля и единицы. На схемах их часто обозначают цифрой функции отдельных выводов, о которых мы поговорим при рассмотрении различным схем.
Шесть выводов с буквой А в обозначении могут работать в качестве аналоговых входов — к ним подключен аналогово-цифровой преоб- разователь (АЦП). Наличие таких входов — одно из самых главных преимуществ Arduino. Именно это качество превращает процесс проектирования, например, цифрового термометра в рутинную операцию, состоящую из написания нескольких строк в программе. Заметим, что аналоговые порты, если они не использованы по назначению, могут также служить в виде обычных цифровых портов ввода-вывода с номерами от 14 до 19.
Кроме портов ввода-вывода, на боковые разъемы с другой стороны платы выведены многочисленные выводы, связанные с питанием, назначение которых понятно из надписей рядом. Следует отметить, что напряжение 3,3 вольта получается из отдельного преобразователя, установленного на плате, и часто бывает необходимо для питания внешних датчиков. Напряжение Vin повторяет то, что подается на разъем внешнего питания (можно подавать внешнее питание сюда вместо внешнего разъема). Особую функцию выполняет вывод, обозначенный, как AREF — в необходимых случаях на него подается отдельное опорное напряжение для АЦП, в обычном режиме на него никаких напряжений подавать нельзя. Назначение остальных выводов мы постепенно разберем при рассмотрении конкретных схем.

Платы Adruino Nano и mini
Платы Arduino Nano и Mini (см. рисунки вверху) в целом повторяют устройство Arduino Uno. Поэтому программы, отлаженные на Uno, обычно можно без переделок загружать в Nano и Mini. Только рас- положены эти версии Arduino на миниатюрных платах и используют самые малогабаритные корпуса контроллеров. Потому они не могут устанавливаться «в этажерку» стандартных Arduino-габаритов, а кон- троллер из них извлечь нельзя.
При этом Arduino Mini, самый миниатюрный из этих вариантов, лишен USB-разъема и может программироваться или через специ- альный отдельный адаптер USB-UART, или с помощью платы Arduino Uno (см. Приложение 1). Есть и другие мелкие отличия — так, у Mini отсутствует вывод AREF для подключения внешнего опорного напря- жения АЦП, зато есть стабилизатор питания 3,3 вольта для внешних датчиков, как у Uno. У Nano, который почти идентичен Uno по всем остальным компонентам платы, такой стабилизатор отсутствует: видимый на рисунке вывод 3,3 вольта работает только при питании от USB. Нет у этих плат и отдельного разъема для подключения внешнего питания — его следует подключать к контакту Vin. Как вариант, можно подавать от внешнего адаптера стабилизированное напряжение 5 вольт или ниже на вывод с таким же обо- значением. Но в этом случае нельзя одно- временно подключать плату к USB, потому лучше таким способом не пользоваться — Arduino прекрасно работает от 5-вольтового адаптера, включенного в качестве внешнего питания.
На платах Mini и Nano имеются допол-нительные аналоговые входы A6 и A7,
которые обусловлены бо́льшим количеством контактов корпуса примененной миниатюрной версии контроллера ATmega328.
В отличие от обычных аналоговых входов A0-A5, входы A6 и A7 не могут служить в качестве цифровой линии общего назначения.
В интернет-магазинах очень часто можно встретить так называ-емый Arduino Pro Mini (см. рисунок вверху справа). Плата разработана компанией SparkFun Electronics и отличается от обычного Mini наличием дополнительных контактов по коротким сторонам платы, большей частью повторяющих уже имеющиеся. По кон- тактам на длинных сторонах платы Pro Mini и Mini полностью совместимы. Arduino Pro Mini обычно продается в виде набора — плата и отдельно штырьковые разъемы к ней. Разработчик должен сам запаять те разъемы, которые необходимо. Если все разъемы запаять заранее, плату Mini Pro может быть трудно установить на беспаечную макетную плату.
Как уже говорилось в предисловии, в продаже можно встретить много версий плат Arduino, выпускаемых различными фирмами: Freeduino, Seeeduino, CraftDuino и так далее. Их часто называют «клонами», что не совсем правильно: так называют точную копию, и истинные клоны Arduino выпускают многие китайские фирмы. А упомянутые версии в чем-то обязательно отличаются от оригинала — имеют больше кон- тактов, более мощный источник питания и так далее.
В качестве примера приведем отечественную версию Uno под назва- нием «Нейтрино» (рисунок внизу). Ее выпускает фирма RobotDyn по заказу ООО «Киберфизика». Плата «Нейтрино» очень хорошо подходит как раз к задачам нашей книги. У нее все сигнальные выводы контроллера дублированы в виде штыревого разъема на задней стороне платы, причем напротив каждого имеется по отдель-ному выводу питания и «земли». Поэтому к «Нейтрино» без всякой макетной платы удобно подключать различные датчики и исполни- тельные устройства.
«Нейтрино» входит в комплект кибер- нетических конструкторов «Роботы и устройства», который производит ком- пания «Киберфизика» (рисунок слева). Недорогой конструктор «Роботы и устройства. Старт», включает в себя многие компоненты и детали, — начиная прямо с контроллера, беспаечной макетной платы. и набора соединительных проводов со штекерами (о проводах см. следующий раздел). Конечно, для наших целей только этого набора будет недостаточно, и придется приобретать многие компоненты отдельно. Но он может стать хорошей основой для начала, а остальное появится постепенно, по мере того, как вы будете осваивать материал.
Подключение датчиков и исполнительных устройств к платам Arduino
Для подключения различных датчиков и других устройств к Arduino к ним часто прилагаются многопроводные кабели с разъемами (см. рисунок внизу слева). Они обычно рассчитаны на подключение к какой-либо из упомянутых плат расширения (shield). На все случаи жизни таких плат, естественно, не напасешься, потому для подключения датчиков удобно иметь наборы проводов с разъемами. На рисунке внизу справа показан такой набор с разъемами «штырь»- «штырь», но они бывают разной конфигурации («штырь»-«гнездо», «гнездо»-«гнездо»).
Обычная проблема при этом заключается в недостатке контактов на платах Arduino для подключения нескольких датчиков или внешних устройств. Особенно этим отличаются датчики с интерфейсом TWI (см. главу 4), потому что он разрешает подключать к одним и тем же линиям в принципе сколько угодно датчиков. На современных платах Arduino Uno имеются дублирующие контакты для сигнальных линий этого интерфейса (SDA и SCL), но отсутствует дополнительное гнездо для подключения питания.
На монтажных схемах различных примеров использования датчиков для «размножения» контактов обычно показывают подключение через макетную плату, но в реальности это не очень удобно. Тут как раз и может при- годиться «Нейтрино», которая во многом заменяет дополнительные «шилды», хотя бы наличием большого количества контактов питания.
Иногда можно встретить в продаже шлейфы для датчиков, в которых провода разветвляются на два или более разъемов. Такие разветвители вполне можно изготовить самостоятельно, используя проводники с разъемами из наборов.
Среда программирования Arduino IDE
В настоящее время существуют две компании — американская и евро- пейская, — официально выпускающие продукты под маркой Arduino. Они представлены сайтами arduino.cc и arduino.org. Соответственно, какое-то время были два варианта среды программирования Arduino IDE, которые можно отличить по номерам версий. Номера версий с сайта arduino.cc начинались с цифр 1.6, а с сайта arduino.org — с 1.7. Эта книга уже была наполовину готова, когда компании, нако- нец, сумели объединить усилия, и последняя версия на обоих сайтах носит номер 1.8.0. На различных сайтах вы можете встретить при- меры, сделанные под предыдущими версиями — они, как правило, пригодны для любой из версий среды Arduino.
Заметьте, что мы предполагаем наличие у читателя ноутбука или настольного компьютера, работающего под Windows. Если у вас другие платформы (Mac OS или Linux), то вам придется разбираться с установкой среды самостоятельно, по инструкции, имеющейся на сайте arduino.cc, а также на многих других сайтах, в том числе рус- скоязычных.
Сама среда программирования Arduino IDE (что расшифровывается, как Integrated Development Environment, интегрированная среда разработки) отличается от других подобных продуктов простотой и компактностью. Можно вообще ее не устанавливать автоматически — просто скачайте ZIP-архив с официального сайта (http://www.arduino. cc/en/Main/Software) и распакуйте его на компьютере в любую папку. На рисунке внизу страницы воспроизведена страница сайта arduino.cc с последней версией среды программирования, где видны ссылки на автоматический установщик (Windows Installer) и простой ZIP-архив для самостоятельной распаковки (non admin install).
Проще, конечно, воспользоваться автоматическим установщиком, причем, если у вас русская версия Windows, то вы получите среду сразу на русском языке. Будут также установлены все нужные драйверы. Если у вас имелась старая версия, которая была установлена тем же «инсталлером», то ее лучше предварительно удалить (запустив uninstall.exe из папки Arduino). Перед этим сохраните копию папки с библиотеками (Arduino\libraries), которую вы неизбежно дополняли сторонними библиотеками, и, возможно, папку с проектами (о ней далее).
В процессе установки вам, разумеется, предложат установить среду в системный каталог Program Files (или в Program Files (x86) для 64-разрядных Windows). Настоятельно советуем установить ее в отдельный каталог вне системных папок. В этом случае все вновь созданные программы и новые библиотеки можно хранить в том же месте, где саму среду Arduino. В противном случае они окажутся разбросанными по всему диску (частично в Program Files, частично в недрах пользовательских папок). Способ неудобный и опасный — высока вероятность потерять пользовательские папки при переустановке программы, и еще выше — при обновлении самой системы Windows. Кроме того, если вы захотите внести изменения в какие-то официальные библиотеки, входящие в Arduino по умолча- нию, то изменять файлы внутри системной Program Files вам могут и не разрешить. Потому лучше заранее от та- ких трудностей застраховать- ся, разместив все, относяще- еся к Arduino, в одном месте (см. также далее о настройках среды Arduino).
По умолчанию папка с установленной средой будет называться Arduino. Можно сразу добавить к этому имени номер версии, чтобы потом в них не путаться (мы далее папку будем называть просто Arduino).
Для проверки работы драйвера сразу после установки подсоедините имеющуюся плату Arduino Uno или Nano к порту USB компьютера. Для этого, как мы уже говорили, потребуется либо обычный AB-кабель USB (плата Arduino Uno), либо кабель с разъемом USB mini (плата Arduino Nano). На плате должен при этом загореться зеленый или желтый светодиод ON. В Диспетчере устройств Windows (Панель управления | Диспетчер устройств) в разделе Порты (COM и LPT) появится название платы — например, Arduino UNO (СОМхх). На рисунке внизу предыдущей страницы показано окно Диспетчера устройств, где подключенная плата отмечена галочкой.
В процессе изучения Arduino обязательно возникнет необходимость установки дополнительных библиотек для работы с различными дат- чиками и исполнительными устройствами. В этой книге для каждого конкретного случая указывается ссылка, откуда можно скачать такую библиотеку, если она не входит в установочный комплект. Скачанная библиотека оказывается в архиве типа ZIP. Распаковать и установить ее в Arduino IDE можно через пункт меню Скетч | Подключить библиотеку | Добавить ZIP-библиотеку. Но не сложнее это сделать и вручную: просто скопировать из архива всю имеющуюся там папку библиотеки в каталог Arduino\libraries (не путать с ката- логом Arduino\LIB!).
Настройки Arduino IDE
Для запуска среды запустите файл Arduino.exe из папки, куда была установлена Ardino IDE (при автоматической установке возникнет соответствующий значок на Рабочем столе). После запуска Arduino IDE первым делом обратитесь к пункту Файл | Настройки (см. рисунок внизу). Там вы можете поменять язык самой программы (и, кстати, также и язык сообщений об ошибках), отказаться от проверки наличия обновлений (иначе при каждом запуске будете получать назойливые предложения сменить версию) и, главное, поменять размещение текстов ваших программ (скетчей), заданное по умолчанию. Для этого просто создайте внутри папки, содержащей arduino.exe, каталог с названием, например, Projects, и укажите его в самом первом пункте настроек через кнопку Обзор.
Пробная загрузка
Так как среда Arduino создавалась для любителей, то программы в ней носят несерьезное название «скетчи» (от англ. sketch — эскиз, набросок). Для пробы проще всего воспользоваться каким-то из готовых примеров, которые размещаются в папке Arduino\Examples (они также доступны через меню Файл | Примеры). Для большего разнообразия целесообраз- но дополнить их примерами, созданными компанией «Амперка». Архив с этими примерами можно скачать с сайта автора по адресу http://revich. lib.ru/AVR/amperka-primery.zip. Распакуйте все его содержимое в папку Examples, внутри которой теперь должна образоваться папка с именем Amperka, содержащая много дополнительных примеров из разных областей.
Попробуем что-нибудь загрузить в контроллер. Сразу подключать плату необязательно, сначала стоит проверить и при необходимости отладить скетч. Для загрузки примера войдите в меню Файл | При- меры, разыщите в списке пункт Амперка и, пройдя по стрелочке, загрузите пример под названием p13_serial_hello. В результате в окне появится текст примера (см. рисунок на следующей странице). Следующим шагом следует текст превратить в загружаемую программу на языке, понятном контроллеру. Такая процедура называется компиля- цией. При ее выполнении программа-компилятор, встроенная в Arduino IDE, заодно проверяет текст на наличие ошибок. Скомпилировать скетч можно через пункт меню Скетч | Проверить/скомпилировать (или через нажатие комбинации клавиш Ctrl+R). При успешном окончании процесса в нижней части окна появится надпись «Компиля- ция завершена», а еще ниже на черном поле отобразятся сведения о количестве занима- емой памяти контроллера (см. рисунок). Если в тексте про- граммы (скетча) будут ошибки, то компиляция прервется и со- общения о причинах появятся в том же черном окне внизу.
Затем подключите плату к компьютеру через USB- кабель. Можно проверить, что плата определилась и заодно узнать соответствующий ей номер COM-порта через Дис- петчер устройств, как описано ранее. При последующих под- ключениях через то же самое
гнездо USB компьютера номер порта будет тот же самый. Зайдите в меню Инструменты | Порт и выберите из списка нужный номер, после чего он появится в самом низу окна (в примере на рисунке это COM8). К сожалению, Ardiuno IDE не определяет подключенную плату авто- матически, потому ее тип тоже обязательно нужно указать. Указание типа подключенной платы выполняется через пункт Инструменты | Плата, после чего название появится перед наименованием порта (в нашем случае это Arduino/Genuino Uno).
Вот теперь все подготовлено для загрузки программы. Обратитесь к меню Скетч | Загрузка (или нажмите сочетание клавиш Ctrl+U). Отметьте, что программа перед загрузкой будет компилироваться зано- во, так что ошибки не пройдут, даже если вы забыли проверить текст. Если все правильно, то по окончании процесса внизу окна с текстом появится надпись «Загрузка завершена». В некоторых версиях такое строгое сообщение заменялось на лаконичное «Вгрузили», вписанное, несомненно, каким-то юмористом-переводчиком — в английском оригинале это сообщение звучит вполне официально, как Done uploading, что в переводе и значит «Загрузка завершена».
Работа с Монитором порта
Программа, которую мы загрузили, выполняет следующие действия: сначала она посылает через последовательный порт в компьютер традиционное сообщение «Hello, world!», что означает «Здравствуй, мир!». После его посылки она переходит к ожиданию сообщений со стороны компьютера через тот же порт. Каждый из принятых символов контроллер будет тут же отсылать обратно. Как проверить, что программа работает?
Последовательный (serial) порт в данном случае — тот же самый USB, через который осуществлялось программирование (подробнее про Serial-порт Arduino рассказано в начале главы 4). Но сама по себе среда программирования может только загружать программы, она не может ни принимать, ни посылать никаких сообщений. Для этого нужна отдельная связная (коммуникационная) программа, которая обычно называется «монитор порта». Программ таких существует множество, но для отладки наших скетчей удобнее всего пользоваться простейшим Монитором порта, входящим в состав пакета программирования Arduino.
Для его запуска обратитесь к меню Инструменты | Монитор порта. В момент вызова контроллер будет перезагружен и отработает с самого начала заново. Вручную перезагрузку можно осуществить нажатием кнопочки Reset, которая имеется на всех платах Arduino (на Uno она размещается рядом с USB-разъемом, см. рисунок на странице 11.).
В результате после вызова у вас появится окно, показанное на рисунке внизу. Через пару секунд (когда отработает проце- дура перезагрузки) в окне появится надпись «Hello, world!» (см. верхнюю строку в окне на рисунке). Это означает, что программа в контроллере работает, как надо. Чтобы проверить остальную часть, установите курсор в строку ввода вверху окна и наберите в нем строку по-русски, например, «азбука электроники». Перед тем, как посылать ее в контроллер, через выпадающий список внизу окна выберите пункт «Новая строка» (иначе новые принятые символы выстроятся вслед принятыми ранее без какого-либо промежутка). Теперь нажмите на кнопку «Отправить». Результат вы видите на том же рисунке — набранная строка без изменений возвратилась в компьютер.
Язык программирования Arduino
Язык программирования Arduino представляет собой несколько упрощенный вариант языка С (произносится, как «си»), с элементами объектно-ориентированного языка С++. Такой вариант получил на- звание Wiring, хотя официально так называется другая ветвь того же языка, и потому применительно к Arduino обычно просто говорят о «языке Arduino». Программа-компилятор языка С/C++, специально приспособленная для программирования AVR-микроконтроллеров фирмы Atmel, называется AVR GCC и лежит в основе среды программирования Arduino.
Если вы с языком C до сих пор не знакомы, то учтите, что логики и стройности в нем немного, зато очень много лишнего и непонятного. В этой книге нет никакой возможности сколько-нибудь подробно останавливаться на особенностях и правилах написания программ на языке С, но не унывайте: чтобы овладеть Adrduino, заканчивать специальные курсы не потребуется.
Получить необходимые сведения можно прямо в процессе изучения Arduino, просто копируя и изменяя примеры, приведенные в этой книге и на других ресурсах. В процессе внесения изменений неизбежно будут возникать вопросы по правилам написания тех или иных выражений. На этот случай автор рекомендует положить в закладки своего браузера следующую ссылку: http://cpp.com.ru/shildt_spr_po_c/02/0210.html. По этому адресу расположен раздел «Операции» известного издания за авторством Герберта Шилдта под названием «Полный справочник по С» в русском переводе. Большую часть нужных ответов читатель найдет в этом пособии, остальное можно освоить на образцах из этой книги и Сети.
А вот общее устройство программ Arduino необходимо знать обязательно. О нем мы поговорим подробнее чуть дальше, а сейчас кратко напомним читателю о том, с чем он будет сталкиваться ежедневно: о типах для представления чисел, а также о различных системах счисления и кодировках.
Представление чисел в языке Arduino
Память контроллеров, как и любых компьютеров, состоит из отдельных ячеек, которые полагаются размером в один байт. Заметим, что
в 8-разрядных контроллерах (в отличие от больших компьютеров) это действительно один байт, а не некая условная величина, введенная для простоты подсчетов. Один байт — это целое положительное число в диапазоне от 0 до 255 или целое число со знаком в диапазоне от -128 до 127. Знак числа всегда хранится в старшем бите, и если там единица, то число считается отрицательным.
Этим величинам соответствуют типы byte или unsigned char — для беззнаковых чисел размером в один байт, и просто char — для числа в том же диапазоне, но со знаком. Тип char еще может означать символ (то есть графическое представление буквы, цифры или иного знака), но считать его числом или символом — целиком и полностью зависит от функции, в которой он фигурирует.
О числах и символах мы поговорим чуть позже, а пока вернемся к представлению чисел. Вы можете еще встретить наиболее универ- сальное представление для типа числа размером в один байт: это int8_t или uint8_t. Буквы «int» в этих обозначениях означают integer (целое), 8 — число бит, буква «t» — type (тип), приставка «u» , как вы догадались, unsigned («без знака»). Эти типы не входят в перечень типов данных на официальных сайтах Arduino, но очень часто встре- чаются в функциях библиотек Arduino и во многих текстах скетчей.
Для более длинных целых чисел наиболее употребляемый тип — int или unsigned int, соответственно, целое со знаком или без знака. Этот тип в случае Arduino занимает два байта (в отличие от больших компьютеров, где он длиннее). То есть диапазон чисел для типа int — от – 32768 до 32767, а для unsigned int — от 0 до 65536. Существуют и аналогичные типы под названием int16_t и uint16_t.
Для того, чтобы записать числа, выходящие за пределы диапазона двух байт, применяются типы long (диапазон от -2 147 483 648 до 2 147 483 647) и unsigned long (от 0 до 4 294 967 295). Они занимают четыре байта в памяти (32 двоичных разряда). Наиболее частое применение этого типа — число миллисекунд с момента запуска про- граммы, которое возвращает функция millis(). При применении этих величин в программах нужно быть очень осторожным: так, при сравнении результата функции millis() с числом типа int или unsigned int могут быть всякие неожиданности. Так как количество миллисекунд 65535 (диапазон типа unsigned int) — это всего чуть более минуты, то каждую минуту при таком сравнении будет возникать ложный результат. Во избежание неприятностей лучше в таких случаях употреблять одинаковые типы, невзирая на экономию памяти контроллера.
Наконец, для дробных чисел с десятичной точкой практически единственный употребляемый в Arduino тип называетсяя float. Для 8-разрядных Arduino он ничем не отличается от типа double. И float и double занимают в памяти 4 байта, причем в них упакованы ман- тисса и порядок, потому диапазон представляемых чисел огромен (от -3.4028235 10+38 до 3.4028235 10+38), а вот сама точность представления числа не очень велика и составляет от 6 до 7 десятичных знаков. При использовании типа float нужно быть осторожным в операциях сравнения: так, условие temperature<10 (где temperature — значение температуры типа float) может выполниться, хотя округленное зна- чение, выводимое на дисплей, уже равно 10,0 градуса.
Представление чисел в различных системах счисления
Все знают, что в обычной жизни мы пользуемся десятичной позиционной системой счисления. «Десятичная» означает, что цифр — то есть разных значков (символов) для записи чисел — у нас десять (от 0 до 9), а слово «позиционная» — что значение каждой цифры зависит от ее позиции в написании числа. Позиции эти иначе называются раз- рядами числа. Кстати, немногие задумываются, что порядок записи разрядов по старшинству — справа налево — европейцы унаследо- вали от арабов, у которых десятичную систему счисления когда-то заимствовали. Это не очень удобно в нашей системе письма слева направо, но приходится смиряться.
В записи десятичного числа значение каждого разряда возрастает справа налево в десять раз по сравнению с предыдущим. То есть в записи 123 крайняя справа цифра 3 означает три единицы, следующая 2 озна- чает два десятка, а последняя 1 означает одну сотню. Итого получается 1 100+2 10+3 = сто двадцать три. Точно так же можно расшифровать любое число, например 30 768 = 3 10 000+0 1000+7 100+6 10+8. Для удобства отсчета на письме между тройками разрядов в десятичной системе принято ставить пробелы, хотя они не несут никакого содержательного смысла. Попробуйте быстро прочесть многоразрядное число, записанное без таких пробелов: 4294967296, и вы поймете, зачем они нужны.
В
Множитель 10, на который увеличивается значение каждого разряда, называется основанием системы счисления. Основание определяет не- обходимое количество отдельных значков-цифр для записи любого чис- ла. Никто, разумеется, не запрещает придумывать системы счисления с основаниями, отличными от десяти. В древнем Вавилоне, напри- мер, были в ходу шестидесятиричная и двенадцатиричная системы, что сохранилось по сей день в исчислении времени: в часе 60 минут, а в полусутках 12 часов. И вообще счет дюжинами (то есть по 12 штук) был довольно распространен до самого недавнего времени.
Десятичная система удобна для человеческого счета — очевидно, потому что у нас по десять пальцев на руках и ногах. Для электронных схем она неудобна до крайности: приходится придумывать десять различимых состояний электрической цепи, что очень сложно и ненадежно. Но ведь у компьютеров нет никаких десяти пальцев, и им все равно, в какой именно системе считать. Потому для них принята самая простая и надежная система — двоичная. В ней всего два отдельных знака для цифр: 0 и 1, а величина каждого следующего разряда увеличивается вдвое, а не в десять раз.
Например, число 123 в двоичной системе запишется, как 111 1011 (в двоичной записи принято пробелы ставить между каждой четверкой цифр). Расшифруем его так, как мы это делали ранее, с учетом дво- ичной системы: 111 10112 = 1 26+1 25+ 1 24+1 23+0 22+1 21+1 20 = 1 64+1 32+1 16+1 8+0 4+1 2+1 = 12310. Как видите, запись получается довольно громоздкая — в десятичном представлении три цифры (разряда), а в двоичном целых семь.
Поэтому для удобства чтения двоичные числа при записи принято представлять в шестнадцатеричной системе, которая кратна двоичной. Здесь требуется целых шестнадцать значков для цифр — для них используются обычные цифры от 0 до 9 и первые шесть букв латинского алфавита: A=10; B=11; C=12; D=13; E=14 и F=15. Для лучшего запоминания ниже приведена таблица, в которой первые 16 чисел натурального ряда приведены в десятичной (DEC), двоичной (BIN) и шестнадцатеричной (HEX) форме.
Как мы видим из этой таблицы, в шестнадцатеричной записи каждая двоичная четверка (24=16) представляется одной из перечисленных цифр, причем до значения 9 они совпадают с десятичными цифрами. Наше число 123 будет отображаться уже двумя разрядами: 111 10112 = 7B16. Обратите внимание, что двоичные четверки разрядов (тетрады) можно переводить в шестнадцатеричные по отдельности: 1112=716 и 10112=B16. Точно так же производится обратное преобразование — по разрядам. Например, шестнадцатеричное число FF в двоичном виде будет выглядеть, как восемь единиц: 1111 1111. В десятичный вид это переводится, как FF16=F 16+F или 15 16+15 = 25510.
Шестнадцатеричное число 0xFF стоит запомнить: 255 есть максимальное значение числа размером в один байт. Байт как раз и есть восемь двоичных разрядов, или два шестнадцатеричных. Разрядность микроконтроллеров и микропроцессоров всегда указывается в двоич- ной системе, отсюда понятно, почему наши 8-разрядные контроллеры оперируют именно числами размером в байт. Чтобы эти контроллеры могли оперировать числами большей разрядности, приходится выстраивать специальные алгоритмы арифметических действий, состоящие из многих отдельных команд, каждая из которых оперирует с отдельными байтами многоразрядного числа.
В среде Arduino такие действия выполняются автоматически — за это отвечает компилятор AVR GCC, на котором базируется Arduino IDE. Потому здесь программисту не приходится вспоминать правила арифметики и задумываться об алгоритмах действий с многоразрядными числами. Стоит, однако, всегда иметь в виду, что диапазон чисел, с которыми оперирует 8-разрядный контроллер, ограничен: например, широко (и чаще всего бездумно) применяемый тип int может отображать числа лишь в диапазоне -32 768 до 32 767. Результат, например, перемножения переменных такого типа легко может выйти за эти пределы, и вы получите полную несуразицу вместо правильного ответа. По этим причинам за правильностью применения различных типов данных в среде Arduino нужно следить особенно внимательно.
Числа и символы
Языковые символы (буквы, знаки препинания и т. п.) используются в электронной технике исключительно для взаимодействия с человеком. Для микроконтроллеров (и вообще микропроцессоров) сим- волы — такие же числа, как любые другие. Поэтому тип char, как и положено, может означать символ, а может число, причем со знаком. Давайте немного разберемся, как именно представляются символы в контроллере.
Для этого немного изменим текст нашего пробного скетча «Hello, word!». Как можно понять из рассмотрения его текста (см. рисунок на странице 26.), обратная отсылка принятых символов (обозначенных в программе переменной под названием b типа byte) осуществляется в строке программы, где написано Serial.write(b). Самостоятельно замените эту единственную строку в тексте скетча на следующую последовательность строк:
Не забывайте ставить точку с запятой после каждого оператора. Загрузите полученную программу в контроллер и вновь вызовите мо- нитор порта. Убедитесь, что строка «Hello world!» принимается, как надо. После этого верните пункт в выпадающем списке внизу окна монитора порта в исходное значение «Нет конца строки» и наберите в строке ввода, например, слово «азбука» по-русски. Результат при- веден на рисунке внизу. Что же мы там получили?
В первой внесенной нами строке стоит функция Serial.println(), которая посылает единственный невидимый символ — символ конца строки. Он предназначен для того, чтобы новая посылка начиналась с новой строки (то есть для того же, для чего ранее мы устанавливали пункт «Новая строка»). Следующая функция Serial.write(b); оставлена от исходной программы — она передает посланный в программу символ обратно без изменений. Функция Serial.print(” “); (в тексте она повторяется дважды) передает строку из двух разделяющих пробелов. И наконец, функции Serial.print(b, DEC); и Serial.print(b, HEX); посылают в компьютер не сам символ, как ранее это делала функция Serial.write, а его десятичный (DEC) и шестнадцатеричный (HEX) коды.
Таким образом, в каждой строке ответа на посылку располагается сам посланный символ, его десятичный код, отделенный пробелами, и, наконец, шестнадцатеричный код. Аналогично можно вывести дво- ичное (BIN) представление символов (попробуйте добавить вариант Serial.print(b, BIN)). Заметьте, что только самый простой вариант (тот, который представлен строкой Serial.write(b)) посылает в ответе реальный цифровой код символа, который затем приемной программой (монитором порта) выводится в виде буквы. Все остальные варианты посылают целую строку символов, соответствующую текстовому написанию цифрового значения в указанной системе счисления.
Попробуем разобраться в том, что представлено в каждой строке. Строчная русская буква «а», как мы видим, кодируется десятичным значением 224 (шестнадцатеричное E0), «б» — следующим по порядку значением 225 (шестнадцатеричное E1) и так далее. Эти значения укладываются в диапазон одного байта, потому такая кодировка называется однобайтовой, и для ее приема-посылки в программе достаточно переменной типа byte.
Так как в байте укладывается всего 256 значений, то все символы всех языков в этот диапазон не помещаются, и разных одно- байтовых кодировок существует много. Так, например, для Европы принята отдельная кодировка, включающая символы разных национальных языков, для кириллицы — отдельная (причем, разная для русского, украинского или, например, болгарского языков). Мало того, для кириллицы существуют не одна, а несколько общепринятых однобайтовых кодировок: кодировка под названием KOI-8 действует в Интернете, в старой операционной системе DOS действовала «альтернативная» кодировка 866, на Мак’ах действует кодировка MacCyrillic, есть малоупотребляемая «основная» кодировка ГОСТ (отраженная в международном стандарте ISO 8859-5) и так далее. В нашей про- грамме мы видим представление кириллических символов в кодировке Windows-1251, принятой в системе Windows.
Все это многообразие с одной стороны упростилось, с другой — еще больше усложнилось, когда компьютерные системы стали переходить на многобайтовую кодировку Unicode («Юникод»). В ней теоретически можно единообразно представить все символы всех существующих языков и одновременно вывести их в едином тексте. На практике чаще всего употребляют более экономичный вариант Юникода под названием UTF-8, где русские символы представлены в двухбайтовой форме, причем первый (старший) байт всегда равен значению 0xD0 или 0xD1. Кодировку UTF-8, в частности, использует и редактор языка Arduino, что полезно знать при составлении программ с использованием русскоязычных символов. Преобразование символов в однобайтовую. кодировку Windows-1251, которую мы наблюдаем тут, производится программой Монитор порта автоматически.
А вот попытки заставить отобразить русский текст различными устройствами (например, дисплеями) будут восприниматься очень по-разному. Осложняется дело еще тем, что некоторые дисплеи имеют собственные встроенные таблицы шрифтов, устроенные самым экономичным способом: когда отдельно кодируются только символы, не имеющие аналогов в латинском шрифте. Например, русские буквы «Б», «Д», «Ц» или строчное «в» будут иметь свой код, а буквы «A» или «Т» одинаковый с латинскими. Поэтому кириллические символы в такие устройства приходится посылать непосредственно в виде их кодов (в десятичной, восьмеричной или шестнадцатеричной форме). Номера (коды) таких символов никаким таблицам стандартов соответствовать не будут, и хотя они часто бывают одни и те же, узнать их можно только из документации на устройства.
Устройство программы Arduino
Любая программа в среде Arduino состоит из трех основных блоков: сек- ции определений, функции установок и бесконечного цикла, который и составляет собственно программу. Блок определений (в нашей пробной программе «Hello, World!» он отсутствует) содержит обычные для почти любого языка программирования ссылки на включаемые библиотеки, объявления имен и определения глобальных переменных, например:
Строчные и заглавные буквы в языке С различаются: попытка обра- титься к последней переменной Temperature или TEMPERATURE вызовет сообщение об ошибке. Двумя косыми чертами (символ называется «прямой слэш») отделяются комментарии, которые служат только для удобства чтения, в самой программе ни на что не влияют и компи- лятором игнорируются.
Объявление имен выводов, как констант:
Выводы можно определять и как переменные целого типа:
Определение выводов, как переменных, встречается очень часто ввиду простоты и понятности, но строго говоря, так поступать неправильно. Ведь менять значение такой переменной мы не собираемся и только зря будем занимать место в памяти. Способ с применением директивы #define экономичнее по отношению к ресурсам контроллера, и к тому же программа будет выполняться чуть быстрее: при обращении к памяти контроллер тратит время на то, чтобы извлечь оттуда текущее значение переменной. Потому при прочих равных следует предпочесть способ с директивой #define, которая всего лишь незначительно замедлит компиляцию.
В языке С любые определения можно делать в любом месте программы, выносить их в начало необязательно. Только надо учесть, что вызов переменной, определенной внутри некоей функции (то есть локальной переменной; в программе «Hello, World!» это переменная b), в другой функции вызовет сообщение об ошибке. Для того, чтобы переменная действовала для всей программы, она должна быть определена именно в начале, до всех функций (глобальная переменная). Глобальная переменная займет ресурсы контроллера на все время работы программы, тогда как локальная освободит их по окончании действия функции и при следующем ее вызове будет инициализироваться заново. В условиях ограниченных ресурсов МК это может оказаться существенным
Между фигурными скобками здесь размещаются те операторы, которые должны выполняться при запуске программы один раз. Следует заметить, что в языке C служебное слово void («пустота») обозначает, что за ним последует то, что в более строгих языках носит название «процедура» — то есть функция, не возвращающая никакого значения. Поэтому применительно к подобным функциям мы будем иногда упо- треблять слово «процедура», как более подходящее по смыслу.
После setup обычно идет функция (на самом деле тоже процедура) бесконечного цикла, которая обозначается словом loop («петля»):
В бесконечном цикле loop программы Arduino обычно выполняют основные действия. Этот способ не единственный и не всегда правильный, но не будем затягивать затянувшееся вступление. Заметим еще только, что кроме этих двух обязательных функций, программа для Arduino может включать в себя любое количество других функций (или процедур), определяемых пользователем, и примеры этого мы увидим далее.
Материал из Википедии — свободной энциклопедии: