Наконец, пришло время действовать в физическом мире более решительно, а именно, перемещать объекты. Раньше мы с вами в качестве исполнительных устройств использовали только светодиоды и пьезодинамик. Сегодня мы познакомимся с сервомоторчиком, который позволит вам собирать разнообразные манипуляторы, пауков и так далее, и так далее. В нашем примере мы будем строить радар, который должен сканировать пространство дальномером, то есть на сервомоторчике у нас будет установлен дальномер. Давайте познакомимся с моторчиком поближе. Мы используем вот такой вот маленький хобби-сервопривод, и, как большинство сервоприводов, он позволяет установить свой вал в определенное положение и удерживать этот угол. Естественно, здесь есть определенные ограничения. Большинство сервоприводов имеют ограничения по диапазону вращения, у нас это 180 градусов, и это довольно хорошо, бывает 60 или 120, и, естественно, удерживать положение он может только в определенных пределах, на которые рассчитан. Этот моторчик не выдержит не то, что вес моего тела, но даже, если я хорошенько надавлю рукой. Однако для перемещения дальномера, его будет вполне достаточно, как и для многих других действий. Давайте заглянем внутрь сервопривода. Во-первых, мы здесь видим сам моторчик, обычный моторчик, который вращает вот эту вот металлическую шестеренку. Сверху здесь есть пластмассовый редуктор, кстати, он добавляет своих ограничений, пластмассовый редуктор износится быстрее металлического, который преобразует вращение моторчика в в другую скорость и в другую мощность. Затем, внутри сервомоторчика мы можем разглядеть потенциометр, ту самую крутилку, с которой мы уже имели дело раньше. За счет неё, собственно, сервомотор и понимает, в каком положении сейчас находится его вал. А также свою управляющую электронику на вот этой маленькой плате, которая позволяет нам с Arduino всего лишь отправить задачу для сервомотора, дескать, «удерживай определенный угол», а дальше этой задачей занимается уже вот эта встроенная электроника. Теперь подключим его. Что касается подключения моторчика. Мы видим у него тройной шлейф, практически нам знакомый. Здесь немножко другая цветовая маркировка, коричневым здесь обозначена земля, красным, как всегда, питание, и сигнальный провод, через который мотор получает команды, обозначен оранжевым. Кстати, хочу обратить ваше внимание, что сигнальный провод здесь работает в одну сторону, мотор только получает команды, он не может сообщить контроллеру о том, в каком положении он сейчас фактически находится. Он сам за этим следит, но Arduino не докладывает. Такой тройной шлейф, конечно, нам хочется воткнуть в тройку Shield, мы сейчас так и поступим, но, хочу вас предостеречь, сервомоторчик является довольно большой нагрузкой, и подключать больше, чем один микро сервомоторчик к Arduino я бы, на вашем месте, не стал. В идеале, и этому моторчику лучше дать отдельный источник питания, но практика показывает, что, в большинстве случаев, один микросервомоторчик Arduino может выдержать. Вот такой вот, гораздо более мощный мотор, я уже сюда подключать не буду. Ему нужен отдельный источник питания, иначе вы, может быть, даже не повредите Arduino, но, в момент, когда мотор будет вращаться под нагрузкой, он начнет потреблять больший ток, питание на Arduino просядет, и контроллер перезагрузится. То есть, вместо того чтобы ваша программа нормально работала, она будет то и дело перезагружаться при попытке вращать сервомотор. Так вот, я снова отключу питание и подключу микросервочку, ну, например, на девятый пин. [ПАУЗА] Коричневый провод – это земля, красный – питание, оранжевый – сигнал. Каким же образом мы будем управлять сервомотором? Вот та маленькая микросхемка, которую мы видели на плате в разобранном моторчике, принимает определенные импульсы. Это называется pulse duration modulation, то есть импульсы могут быть разной длины, но приходят они с одинаковой частотой. Так вот, этот контроллер у моторчика ожидает каждые 20 миллисекунд импульс какой-либо длины, и в зависимости от длины этого импульса, он будет вставать в соответствующее положение. Естественно, мы можем написать весь этот код своими руками, включить напряжение на пине, подождать какое-то количество микросекунд, выключить его, подождать оставшееся до истечения 20 миллисекунд время с выключенным пином и так далее. Но можно поступить гораздо проще, потому что существует готовый инструмент. И мы снова пойдем в образцы, где найдем раздел Servo и пример Sweep. Вот я его открыл, и посмотрим, как он устроен. Здесь мы знакомимся с новой, очень важной и часто используемой вещью — использованием подключаемых библиотек. С чего начинается данный пример? Со строчки include <Servo.h>, ну или «Серво аш». Что это за <Servo.h>? Это так называемый заголовочный файл, который относится к библиотеке Servo. Там описаны все функции, которые создатель библиотеки предусмотрел для работы с тем или иным устройством, например, данная библиотека предназначена для управления сервомашинками, сервомоторами. Помимо заголовочного файла, там обычно есть файл реализации с расширением SPP, но сейчас он нас не интересует. Нас интересует, как библиотеку подключить. Подключается она с помощью вот этой вот самой директивы include, и теперь компилятор будет знать, что мы где-то в тексте, в коде, будем обращаться к функциям, которые могут быть определены, в том числе, вот в этой библиотеке, которые не определены прямо непосредственно в нашем скетче. Что происходит дальше? Дальше новая для нас строчка: Servo myservo; Здесь мы создаем объект, который называется myservo. Что такое объект – мы глубоко разбираться не будем, можно считать, что это некий специальный тип данных. На самом деле, это совокупность данных и методов работы с ними, то есть функции, которые к ним можно применить, и в данном случае это объект типа servo. Этот тип описывается, собственно, там же, в библиотеке. Чаще всего мы можем даже не заглядывать внутрь библиотеки, потому, что чаще всего они хорошо задокументированы, и мы по описанию можем понять, что же можно получить на входах и выходах определенных функций, что за данные там используются. В разделе Reference, на официальном сайте Arduino, можно найти описание библиотеки Servo, она стандартная, всегда есть вместе с дистрибутивом. Здесь можно подробнее прочитать про её методы, то есть про функции, которые мы можем использовать с объектами типа Servo. Мы же посмотрим, как они применяются. Первым делом, в разделе Setup, мы видим такую строчку: myservo.attach(9); Attach – это первый метод, который нам пригодится, он служит для того, чтобы подключить сервомашинку. Мы видим, что нету строчки pinMode(9), это всё включено в метод attach, собственно, 9 — это тот пин, к которому подключен сервомотор, который в нашей программе называется myservo. Когда нам понадобится работать больше, чем с одним сервомотором, мы создадим объект, например, myservo1, и у нас будет строчка myservo1.attach, и какой-то другой пин, куда сервомотор подключен. Что же происходит далее? В основном цикле, в разделе Loop, мы видим два цикла со счетчиком, наши знакомые for. Один изменяется от 0 до 180, по единице, а другой, наоборот, от 180 до 0. Каждый раз убавляется единица. Внутри каждого из этих циклов вызывается еще один метод, определенный в библиотеке Servo — myservo.write(pos); Что это за write? С помощью него мы сообщаем сервомотору, в какое положение ему нужно встать. Положение, в нашем случае, хранится в переменной счетчике pos, соответственно, на каждой итерации цикла сервомотору поступает новая команда: «встать в положение 0», затем, когда счетчик примет значение 1 – «встать в положение 1», и так далее до 180 градусов. Каждое перемещение разделено маленькой задержкой 15 миллисекунд, на самом деле, это не бесполезный момент, потому что одно дело подать команду сервомотору, другое дело – время, за которое он физически докрутится до данного положения, особенно, если он чем-то нагружен, это может не произойти мгновенно. Поэтому, если вы начнете дергать в программе сервомоторчик очень-очень часто, особенно в разные стороны, особенно под нагрузкой, скорее всего, вы быстро износите редуктор, если вообще добьетесь желаемого поведения. Не забывайте об этом. Ну, и соответственно, во втором цикле происходит всё то же самое, только переменная pos счетчик изменяется в обратном направлении – от 180 до 0. Давайте мы этот скетч загрузим и посмотрим, как себя будет вести сервомотор. Я уже надел на вал мотора вот такую белую детальку, её обычно называют «качелька», они бывают разных видов, и к ним, собственно, можно прикрутить ту деталь, которую вы хотите приводить в движение. В нашем случае это будет дальномер, чуть позже мы это соберем, а так, это может быть сустав какого-нибудь манипулятора, например. Итак, скетч загрузился, и мы видим, что сервомоторчик начал вращаться в одну и в другую сторону, преодолевая диапазон в 180 градусов. На самом деле, я вижу, что чуть меньше, но в каждом конкретном случае вы можете убедиться в том, какой диапазон действительно охватывает ваш сервомоторчик. Отлично, теперь мы сможем перемещать радар, сканировать пространство. Здесь я тоже хочу ваше внимание обратить на то, что, когда вы включаете в скетч библиотеку Servo, начинаете с ней работать, у вас перестает работать ШИМ на 9 и 10 пинах. теперь вы уже знаете, что такое широтно-импульсная модуляция, не забывайте о том, что тон выключает её на 3 и 11, а servo на 9 и 10.