Опубликовано

Ардуино подключение сервопривода

Устройство сервомотора (servo)

Сервопривод (сервомотор) является важным элементом при конструировании различных роботов и механизмов. Это точный исполнитель, который имеет обратную связь, позволяющую точно управлять движениями механизмов. Другими словами, получая на входе значение управляющего сигнала, сервомотор стремится поддерживать это значение на выходе своего исполнительного элемента.

Что такое сервопривод. Схема устройства сервопривода

Сервоприводы широко используются для моделирования механических движений роботов. Сервопривод состоит из датчика (скорости, положения и т.п.), блока управления приводом из механической системы и электронной схемы. Редукторы (шестерни) устройства выполняют из металла, карбона или пластика. Пластиковые шестерни сервомотора не выдерживают сильные нагрузки и удары.

Сервомотор имеет встроенный потенциометр, который соединен с выходным валом. Поворотом вала, сервопривод меняет значение напряжения на потенциометре. Плата анализирует напряжение входного сигнала и сравнивает его с напряжением на потенциометре, исходя из полученной разницы, мотор будет вращаться до тех пор пока не выравняет напряжение на выходе и на потенциометре.

Управление сервоприводом с помощью широтно импульсной модуляции

Схема подключения сервопривода к Arduino обычно следующая: черный провод присоединяем к GND, красный провод присоединяем к 5V, оранжевый/желтый провод к аналоговому выводу с ШИМ (Широтно Импульсная Модуляция). Управление сервоприводом на Ардуино достаточно просто, но по углам поворота сервомоторы бывают на 180° и 360°, что следует учитывать в робототехнике.

Для занятия нам понадобятся следующие детали:

  • Плата Arduino Uno / Arduino Nano / Arduino Mega;
  • Макетная плата;
  • USB-кабель;
  • 1 сервопривод;
  • 1 потенциометр;
  • Провода «папа-папа» и «папа-мама».

Схема подключения сервопривода к Ардуино UNO

В первом скетче мы рассмотрим как управлять сервоприводом на Arduino с помощью команды myservo.write(0). Также мы будем использовать стандартную библиотеку Servo.h. Подключите сервомашинку к плате Ардуино, согласно схеме на фото выше и загрузите готовый скетч. В процедуре void loop() мы будем просто задавать для сервопривода необходимый угол поворота и время ожидания до следующего поворота.

Скетч для сервопривода на Ардуино

#include <Servo.h> // подключаем библиотеку для работы с сервоприводом Servo servo1; // объявляем переменную servo типа «servo1» void setup() { servo1.attach(11); // привязываем сервопривод к аналоговому выходу 11 } void loop() { servo1.write(0); // ставим угол поворота под 0 delay(2000); // ждем 2 секунды servo1.write(90); // ставим угол поворота под 90 delay(2000); // ждем 2 секунды servo1.write(180); // ставим угол поворота под 180 delay(2000); // ждем 2 секунды }

Пояснения к коду:

  1. Стандартная библиотека Servo.h содержит набор дополнительных команд, которая позволяет значительно упростить скетч;
  2. Переменная Servo необходима, чтобы не запутаться при подключении нескольких сервоприводов к Ардуино. Мы назначаем каждому приводу свое имя;
  3. Команда servo1.attach(10) привязывает привод к аналоговому выходу 10.
  4. В программе мы вращаем привод на 0-90-180 градусов и возвращаем в начальное положение, поскольку процедура void loop повторяется циклично.

Управление сервоприводом потенциометром

Подключение сервопривода и потенциометра к Ардуино Уно

Ардуино позволяет не только управлять, но и считывать показания с сервопривода. Команда myservo.read(0) считывает текущий угол поворота вала сервопривода и его мы можем увидеть на мониторе порта. Предоставим более сложный пример управления сервоприводом потенциометром на Ардуино. Соберите схему с потенциометром и загрузите скетч управления сервоприводом.

Скетч для сервопривода с потенциометром

#include <Servo.h> // подключаем библиотеку для работы с сервоприводом Servo servo; // объявляем переменную servo типа «servo» void setup() { servo.attach(10); // привязываем сервопривод к аналоговому выходу 10 pinMode(A0, INPUT); // к аналоговому входу A0 подключим потенциометр Serial.begin(9600); // подключаем монитор порта } void loop() { servo.write(analogRead(A0)/4); // передает значения для вала сервопривода Serial.println (analogRead(A0)); // выводим показания потенциометра на монитор Serial.println (analogRead(A0)/4); // выводим сигнал, подаваемый на сервопривод Serial.println (); // выводим пустую строчку на монитор порта delay(1000); // задержка в одну секунду }

  1. В этот раз мы присвоили имя для сервопривода в скетче, как servo;
  2. Команда servo.write(analogRead(A0)/4) передает значения для вала сервопривода — получаемое напряжение с потенциометра мы делим на четыре и оправляем данное значение на сервопривод.
  3. Команда Serial.println (servo.read(10)) считывает значение угла поворота вала сервопривода и передает его на монитор порта.

Сервомоторы часто используются в различных проектах на Ардуино для различных функций: повороты конструкций, движение частей механизмов. Так как мотор серво постоянно стремится удерживать заданный угол поворота, то будьте готовы к повышенному расходу электроэнергии. Это будет особенно чувствительно в автономных роботах, питающихся от аккумуляторов или батареек.

Серводвигатель (устройство и принцип работы)

Сервопривод (лат.servus – слуга, помощник; следящий привод) — привод с управлением через отрицательную обратную связь, позволяющую точно управлять параметрами движения.

Сервопривод чаще всего встречается в робототехнике. Без него невозможно обойтись, особенно когда речь идет о решении задачи точного перемещения грузов или предметов. Такая задача возникает при выполнении какой-либо механической работы (покраска, сварка, шлифовка, перемещение изделий на конвейере и т. д.). Выполняют такую работу манипуляторы, которые выглядят как механические руки. Собственно говоря, знаменитая промышленная робототехника, которая используется для автоматизации производства по всему миру, представлена прежде всего манипуляторами. И не один такой манипулятор не обходится без сервоприводов, которые приводят в действие его звенья. Почему?

Все дело в свойствах сервопривода. Сервопривод — это привод, в котором используется отрицательная обратная связь, позволяющая точно управлять параметрами движения исполнительного(выходного) звена привода (чаще всего это выходной вал). Для создания такой обратной связи обычно используется датчик положения выходного звена сервопривода, но могут применяться и датчики скорости, усилия и т. д. Получается, что сервопривод — это привод, на который подается сигнал, указывающий выдвинуться или повернуться в определенное положение. Он в это положение устанавливается и «ждет», пока не поступит команда об изменении положения. Например, подается сигнал об установке вала в угловое положение 90 градусов. Вал поворачивается в это положение и держит его, пока не придет сигнал о новом положении. Такие возможности управления серьезно отличают сервопривод от обычного мотор-редуктора, который способен только непрерывно вращаться, пока на него подано напряжение. В результате, если такими приводами оснащен робот, то он может двигаться подобно руке человека и выполнять всю ту работу, которую можем выполнять мы.

Разновидностей сервоприводов в промышленности многоВ этой статье мы будем рассматривать электрические сервоприводы вращательного действия. Проще говоря, у таких сервоприводов выходным исполнительным звеном является вращающийся вал. Для простоты мы рассмотрим устройство хобби-сервопривода SG-90 (рис. 1), который активно применяется для создания учебных моделей роботов и прочих плавающих, летающих или ходящих механизмов. Хобби-сервопривод в отличие от промышленного существенно меньше по размерам, развивает меньшее усилие, по-другому управляется, но по общему принципу действия абсолютно идентичен промышленному собрату.

Рисунок 1

Устройство хобби-сервопривода показано на рисунке 2. В его состав входит электродвигатель, редуктор с набором шестеренок, потенциометр (выполняет функцию датчика положения для обратной связи), электронная плата управления электродвигателем и корпус, в который заключено все содержимое. На этом же рисунке показан провод, посредством которого сервопривод питается и управляется. Он состоит из 3-х жил: питание «плюс», питание «минус» и провод, на который подается управляющий сигнал. На разных моделях хобби-сервоприводов провода могут иметь разный цвет. Но практически всегда провод питания «плюс» окрашен в красный цвет, а провод питания «минус» — в черный. В отношении же сигнального провода (для передачи управляющего сигнала) четких цветовых стандартов нет. У разных производителей сервоприводов сигнальный провод может быть белым, оранжевым или желтым.

Рисунок 2

Для управления такими двигателями принят стандарт управляющего сигнала. Он представляет собой постоянно повторяющиеся импульсы или, как мы говорим, череду импульсов (Рис. 3). Частота этих импульсов все время остается постоянной и составляет 50 Гц. Получается, что временной период импульсов (время между передними фронтами соседних импульсов) составляет 1с/50 = 0,02 секунды, т. е. 20 миллисекунд.

Рисунок 3

Что интересно, угловое положение выходного вала сервопривода задается продолжительностью подаваемого импульса. Для пояснения на рисунке 4 показано приблизительное соотношение ширины импульса во временных координатах и угла поворота вала сервопривода. Управление поворотом вала сервопривода выполняется с помощью импульсов продолжительностью от 1 до 2 мс (миллисекунд).

Рисунок 4

Как видно из графика, для управления сервоприводом используется не что иное как сигнал с широтно импульсной модуляцией — ШИМ. Что такое ШИМ можно узнать из соответствующей статьи на нашем сайте.

А как ширина импульса превращается в угол вала на выходе?

Как указано на рисунке 2, в корпусе сервопривода присутствует еще и электронный модуль управления мотором. Подаваемый на сервопривод сигнал попадает на эту плату. А вот то, что происходит с этим сигналом дальше, показано на блок-схеме рисунок 5, которую мы проанализируем поэтапно. Каждый этап изображен прямоугольником или кружочком и пронумерован. Внутри этих прямоугольников изображены устройства, на которых происходит преобразование или обработка сигнала.

Рисунок 5

Итак, входной управляющие сигнал Sупр с ШИМ модуляцией приходит на специальную микросхему с логическими элементами, с помощью которой преобразуется в напряжение Uупр (этап №1). После этого сигнал Uупр (управляющее напряжение) поступает на элемент сравнения напряжений. Данный элемент называется сумматором, но на самом деле он из входного сигнала Uупр вычитает напряжение Uобр (напряжение обратной связи), приходящее через обратную связь с переменного резистора (этап №2).

Получившаяся разница Uкорр (корректирующее напряжение) усиливается встроенным усилителем (этап №3) и подается на электродвигатель. Мотор вращается (этап №4) и приводит в движение выходной вал сервопривода, а вместе с ним и датчик обратной связи в виде потенциометра. При вращении ручки потенциометра изменяется напряжение и получается, что поворот вала преобразуется в напряжение Uобр (этап №5). Это напряжение Uобр сравнивается (снова этап №2) с напряжением Uупр, и разница в виде Uкорр снова идет на усилитель (этап №3) и так далее. Сигнал «ходит» по цепи с обратной связью до тех пор, пока не выполнится соотношение Uупр = Uобр. Тогда Uкорр станет равно 0, и двигатель остановится. Произойдет это тогда, когда вал сервопривода займет положение, соответствующее входному управляющему сигналу Sупр.

Обобщим все сказанное. Вал сервопривода механически соединен с ручкой потенциометра. Из-за этого вместе с поворотом вала сервопривода поворачивается потенциометр, в результате чего изменяется его сопротивление и выходное напряжение Uобр. Соответственно, выходное напряжение с потенциометра Uобр прямо зависит от угла поворота сервопривода. Одновременно входной в сервопривод сигнал Sупр с продолжительностью импульсов от 0,001 до 0,002 секунды задает уровень напряжения Uупр, которое определяет угол на который должен повернуться вал сервопривода. Остановка электродвигателя в момент, когда вал сервопривода именно в нужном положении, достигается за счет вычитания из сигнала Uупр сигнала обратной связи Uобр. А усилитель этапа №3 необходим для того, чтобы на электродвигатель подавалось усиленное напряжение и двигатель переводил вал сервопривода в заданное положение максимально быстро.

Примеры управления серводвигателем

Как было сказано выше, для управления серводвигателем приминяется ШИМ с определенными параметрами. Сгенерировать такую ШИМ можно различными способами. Покажем некоторые из них.

1. Управление серводвигателем при помощи 555 таймера. Микросхема таймера 555 может работать в режиме генератора импульсов (подробнее об этой микросхеме читайте соответствующую статью). Следовательно можно подобрать такие параметры работы этой микросхемы, что бы она выдавала нужные нам импульсы. Путем изменения скважности этих импульсов, т. е. изменения продолжительности импульсов от 0,001 до 0,002 секунды, мы и будем задавать угол поворота вала сервопривода.

Для того чтобы реализовать ШИМ сигнал, необходимо использовать схему с регулируемой скважностью импульсов при неизменной частоте 50 Гц. Параметры компонентов на схеме (рис.6) подобраны таким образом, чтобы обеспечить эти условия. Но чтобы сигнал управления удовлетворял всем условиям, его необходимо инвертировать. Транзистор в схеме необходим именно для этого. Чтобы управлять скважностью в заданных пределах, потребовался бы потенциометр на максимальное сопротивление 20 кОм. Мы будем использовать два потенциометра по 10 кОм (так как именно такие потенциометры используются в Основном наборе 1-ого уровня Эвольвектор, где эта схема подробно описана. Рабочий ход серводвигателя составляет 180 градусов. В этом случае при вращении ручки одного потенциометра сервопривод будет поворачиваться на 90 градусов, а при дополнительном вращении другого — на вторые 90 градусов.

Рисунок 6

Более подробно изучить данную схему, а так же собрать ее, вы сможете купив Основной набор 1-ого уровня Эвольвектор.

2. Управление серводвигателем при помощи контроллера. Сгенерировать нужный сигнал ШИМ так же можно при помощи контроллера. Например можно использовать программируемый контроллер на платформе Ардуино. Чтобы максимально упростить программирование алгоритма управления серводвигателем (генерацию ШИМ) применяются заранее написанные программы, называемые библиотеками. Их сложный программный код скрыт от пользователя, предлагается только вызов нужных нам функций посредством коротких команд при подключении библиотеки к нашей основной программе. Все это делает сложное с алгоритмической точки зрения управление такими устройствами как серводвигатель крайне простым и удобным.

Схема подключения, а так же Скетч (программа) для управления серводвигателем контроллером Arduino показаны на рисунке 7.

Для реализации данной схемы на макетной плате Вам потребуются:
1. Контроллер
2. Макетная плата
3. Сервопривод
4. Провода

Рисунок 7

ВНИМАНИЕ: Подключение питания серводвигателя к плате напрямую, как в нашем примере (рисунок 7), нежелательно. У нас на рисунке подключен один серводвигатель из категории «мини», потребляющий очень небольшие токи, отчего он вполне штатно работает, питаясь непосредственно от платы. Сервопривод стандартного размера требует большей мощности, что может привести к перегреву и повреждению контроллера. Подключение питания двигателей следует осуществлять только через отдельный источник, особенно если предполагается управление одновременно несколькими сервоприводами.

#include <Servo.h> — эта команда означает подключение библиотеки для управления сервоприводом. Эта библиотека присутствует на диске Эвольвектор, который поставляется совместно с нашими наборами 2-ого уровня. Так же её можно найти в интернете и положить в папку «libraries» вашей Arduino IDE.
Подключенная нами библиотека имеет большое количество команд, мы рассмотрим только те, который используются в программе.

Servo dvig; — это объявление переменной специального типа. dvig – это переменная (название выбираем произвольно). Servo – это тип переменной (специальный тип, который задается в присоединенной библиотеке). Можно задать до 12 переменных этого типа, то есть для управления 12 серво-приводами. Иными словами, этой командой мы сообщили плате, что у нас есть сервопривод, который мы назвали dvig.
dvig.attach(9); — эта команда означает, что серво-привод (dvig) присоединен к 9 пину (выводу).
dvig.write(90); – эта команда заставляет сервопривод (dvig) повернуться в среднее положение (90 градусов).
dvig.write(0); – поворачивает сервопривод в положение 0 градусов.
dvig.write(180); – поворачивает сервопривод в положение 180 градусов.

Что означают остальные строки в программе вы можете найти на страницах нашего сайта или узнать из учебных пособий которые входят в состав наборов Эвольвектор 2 ого уровня.


Сервопривод представляет собой электропривод с обратной связью, который поддерживает заданные параметры на исполнительном органе. Конструктивно состоит из электродвигателя, редуктора и блока управления. На выходном валу редуктора установлен датчик положения, с помощью которого блок управления отслеживает положения выходного вала, обеспечивая обратную связь. Я буду рассматривать китайский сервопривод под названием Tower Pro SG90, диапазон угла поворота вала составляет 180 градусов, скорость поворота 60 градусов/0,3 секунды, применяется в основном в радиоуправляемых игрушках, роботах и т.д. Сервопривод имеет три вывода для подключения, два вывода красный (+) и коричневый (-) для питания, оранжевый вывод для управления, напряжение питания составляет 5В.

Сервоприводы я заказывал здесь. Управляется сервопривод повторяющимися импульсами определенной длительности. Ниже представлена картинка с управляющими импульсами для сервопривода SG90:

При подаче импульсов длительностью в 1,5 мс, вал сервопривода установится в среднее положение. Для импульсов шириной в 0,6 мс, вал повернется на 90 градусов по часовой стрелке относительно среднего положения (если смотреть на вал сервопривода сверху). Если ширина импульсов составит 2,5 мс, вал повернется на 90 градусов против часовой стрелки относительно среднего положения. Таким образом, положение вала задается шириной управляющего импульса. Период следования импульсов может составлять от 10 до 20 мс, за стандарт принято значение 20 мс (частота 50Гц). На самом деле данный сервопривод (SG90) может повернуться еще на несколько градусов от крайних положений, то есть диапазон угла поворота чуть больше 180 градусов. Фактически угол поворота ограничивается механическими упорами на шестеренке редуктора, вышеприведенные временные интервалы управляющих импульсов ограничивают диапазон угла поворота в пределах 180 градусов, не позволяя поворачиваться валу до механических упоров.

Ниже представлена схема подключения сервопривода к микроконтроллеру PIC16F628A:

Управление сервоприводом осуществляется двумя кнопками, при нажатии кнопки SB1 вал сервопривода плавно поворачивается по часовой стрелке, то есть происходит уменьшение ширины управляющих импульсов на линии RB4, кнопка SB2 соответственно поворачивает вал против часовой стрелки, ширина импульсов увеличивается.
Ниже представлен код программы для микроконтроллера:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 #include <P16F628A.INC> LIST p=16F628A __CONFIG H’3F10′ ;конфигурация микроконтроллера Sec equ 20h ;присвоение названий регистрам ОЗУ Sec1 equ 21h t1L equ 22h ;младший регистр счета длит. импульса управления t1H equ 23h ;старший регистр счета длит. импульса управления t1LL equ 24h ;промежуточный регистр t1HH equ 25h ;промежуточный регистр tmp_off equ 26h ;регистр счетчика времени flag equ 7Dh ;дополнительный регистр флагов W_TEMP equ 7Eh ;регистр для хранения значения аккумулятора W STATUS_TEMP equ 7Fh ;регистр для хранения значения STATUS ;присвоение названий линиям ввода-вывода #DEFINE serv PORTB,4 ;управляющий сигнал для сервопривода #DEFINE knp_1 PORTB,0 ;кнопка 1 #DEFINE knp_2 PORTB,1 ;кнопка 2 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; org 0000h ;начать выполнение программы с адреса 0000h goto Start ;переход на метку Start ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;Подпрограмма обработки прерываний org 0004h ;начать выполнение подпрограммы с адреса 0004h movwf W_TEMP ;сохранение значений ключевых регистров swapf STATUS,W ; clrf STATUS ; movwf STATUS_TEMP ; prov_tmr1 bcf T1CON,TMR1ON ;остановка таймера TMR1 btfsc flag,0 ;проверка флага очередности goto t2 ;флаг установлен (1):перход на метку t2 t1 movf t1HH,W ;флаг очередности равен 0:перезапись длительности movwf TMR1H ;управляющего импульса из промежуточных регистров movf t1LL,W ;в регистры таймера TMR1 movwf TMR1L ; bsf flag,0 ;установка флага очередности bsf serv ;установить в 1 линию ввода/вывода serv goto extmr1 ;переход на метку extmr1 t2 bcf serv ;сбросить в 0 линию ввода/вывода serv bcf flag,0 ;сбросить флаг очередности movlw .183 ;запись длительности паузы между управляющими movwf TMR1H ;импульсами в 18,5 мс movlw .187 ; movwf TMR1L ; movlw .24 ;проверка регистра счетчика времени xorwf tmp_off,W ; btfss STATUS,Z ; goto extmr2 ;значение счетчика не равно 24:переход на extmr2 bcf PIR1,TMR1IF ;значение счетчика равно 24: сброс флага прерываний ;по переполнению TMR1 goto exxit ;переход на метку exxit extmr2 incf tmp_off,F ;инкремент регистра счетчика времени extmr1 bcf PIR1,TMR1IF ;сброс флага прерываний по переполнению TMR1 bsf T1CON,TMR1ON ;запуск таймера TMR1 exxit swapf STATUS_TEMP,W ;восстановление содержимого ключевых регистров movwf STATUS ; swapf W_TEMP,F ; swapf W_TEMP,W ; ; retfie ;выход из подпрограммы обработки прерывания ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;Основная программа Start clrf PORTB ;сброс регистра PORTB clrf PORTA ;сброс регистра PORTA movlw b’00000111′ ;выключение компараторов movwf CMCON bsf STATUS,RP0 ;выбрать 1-й банк movlw b’11101111′ ;настройка линий ввода\вывода порта B movwf TRISB ;RB4 на выход, остальные на вход bcf STATUS,RP0 ;выбрать 0-й банк bcf flag,0 ;сброс флага очередности clrf tmp_off ;сброс счетчика времени movlw .220 ;запись длительности (1,5 мс) управляющего импульса movwf t1L ;в регистры счета и промежуточные регистры comf t1L,W ;для установки сервопривода в среднее положение movwf t1LL movlw .5 movwf t1H comf t1H,W movwf t1HH movlw b’00000000′ ;коэффициент предд. TMR1 1:1, внутренний movwf T1CON ;тактовый сигнал Fosc clrf TMR1L ;сброс регистров тймера TMR1 clrf TMR1H bsf INTCON,PEIE ;разрешение прерываний периферийных модулей bcf PIR1,TMR1IF ;сброс флага прерываний по переполнению TMR1 bsf STATUS,RP0 ;выбрать 1-й банк bsf PIE1,TMR1IE ;разрешение прерываний по переполнению TMR1 bcf STATUS,RP0 ;выбрать 0-й банк bsf T1CON,TMR1ON ;запуск таймера TMR1 bsf INTCON,GIE ;глобальное разрешение прерываний opros_knp btfsc knp_1 ;опрос кнопки 1 goto met_1 ;кнопка 1 не нажата: переход на метку met_1 call povorot_1 ;кнопка 1 нажата: вызов подпрограммы povorot_1 call pausknp ;вызов подпрограммы паузы met_1 btfsc knp_2 ;опрос кнопки 2 goto opros_knp ;кнопка 2 не нажата: переход на метку opros_knp call povorot_2 ;кнопка 2 нажата: вызов подпрограммы povorot_2 call pausknp ;вызов подпрограммы паузы goto opros_knp ;переход на метку opros_knp povorot_1 movlw .2 ;проверка длительности управляющего импульса subwf t1H,W ;в регистрах счета btfss STATUS,C ; return ;длительность меньше 600 мкс, сервопривод в крайнем ;положении, выход из подпрограммы povorot_1 btfss STATUS,Z ; goto met_p11 ;длительность больше 600 мкс, переход на метку met_p11 movlw .88 ; subwf t1L,W ; btfss STATUS,C ; return ;длительность меньше 600 мкс, сервопривод в крайнем ;положении, выход из подпрограммы povorot_1 met_p11 movlw .10 ;уменьшение длительности управляющего импульса subwf t1L,F ;на 10 мкс btfsc STATUS,C ; goto met_p12 ; decf t1H,F ; met_p12 call perezap ;вызов подпрограммы perezap return ;выход из подпрограммы povorot_1 povorot_2 movf t1H,W ;проверка длительности управляющего импульса sublw .9 ;в регистрах счета btfss STATUS,C ; return ;длительность больше 2,5 мс, сервопривод в крайнем ;положении, выход из подпрограммы povorot_2 btfss STATUS,Z ; goto met_p21 ;длительность меньше 2,5 мс: переход на метку met_p21 movf t1L,W ; sublw .196 ; btfss STATUS,C ; return ;длительность больше 2,5 мс, сервопривод в крайнем ;положении, выход из подпрограммы povorot_2 met_p21 movlw .10 ;увеличение длительности управляющего импульса addwf t1L,F ;на 10 мкс btfss STATUS,C ; goto met_p22 ; incf t1H,F ; met_p22 call perezap ;вызов подпрограммы perezap return ;выход из подпрограммы povorot_1 ; perezap bsf STATUS,RP0 ;выбрать 1-й банк bcf PIE1,TMR1IE ;запрещение прерываний по переполнению TMR1 bcf STATUS,RP0 ;выбрать 0-й банк comf t1L,W ;перезапись значений регистров счета в промежуточные movwf t1LL ;регистры comf t1H,W ; movwf t1HH ; clrf tmp_off ;сброс счетчика времени bsf T1CON,TMR1ON ;включение таймера TMR1 bsf STATUS,RP0 ;выбрать 1-й банк bsf PIE1,TMR1IE ;разрешение прерываний по переполнению TMR1 bcf STATUS,RP0 ;выбрать 0-й банк return ;;выход из подпрограммы perezap pausknp movlw .14 ;подпрограмма паузы 10,5 мс movwf Sec1 ; p3 movlw .250 ; movwf Sec ; p2 decfsz Sec,F ; goto p2 ; decfsz Sec1,F ; goto p3 ; return ; ; end ; ;

Микроконтроллер работает от внутреннего тактового генератора на частоте 4 МГц. Длительность временных интервалов для управляющих импульсов отсчитываются внутренним 16-ти разрядным таймером TMR1. При частоте в 4 МГц и коэффициенте предделителя таймера 1:1, переполнение наступит через 65536 мкс. Используя прерывание по переполнению таймера, можно отсчитывать различные временные интервалы, в диапазоне 1-65536 мкс.

Управляющие импульсы для сервопривода генерируются в подпрограмме обработки прерываний. В начале основной программы в регистры счета (t1H, t1L) записывается число 1500, соответствующее временной задержке в 1500 мкс (среднее положение вала сервопривода), следом в промежуточные регистры (t1HH, t1LL) записывается инвертированное значение числа 1500. Регистры счета используются для хранения текущей длительности импульса, промежуточные регистры выступают в роли буфера, из которых инвертированное значение длительности копируется в регистры таймера TMR1 (TMR1H, TMR1L). В регистрах счета, значение длительности представлено в удобной форме для математических операций сложения и вычитания, но перед записью в регистры таймера TMR1, значение длительности необходимо инвертировать, так как прерывание генерируются по переполнению таймера, а не по достижении конкретного значения.

Далее настраивается таймер TMR1, разрешается прерывание периферийных модулей, сбрасывается флаг переполнения, разрешается прерывание по переполнению таймера, запуск таймера, ну и разрешение глобальных прерываний.

По переполнению таймера происходит переход в обработчик прерываний, где в первую очередь выполняется остановка таймера и опрос флага очередности flag,0 (в начале основной программы флаг сбрасывается). Если флаг сброшен, происходит переход на метку t1, далее происходит перезапись длительности управляющего импульса (1500 мкс) из промежуточных регистров (t1HH, t1LL) в регистры таймера TMR1, установка флага очередности, установка в 1 линии RB4 (название линии serv). После этого сбрасывается флаг прерывания, запуск таймера и выход из обработчика прерываний. Через 1,5 мс произойдет очередной переход в обработчик прерываний по переполнению таймера, на этот раз флаг очередности равен 1, и произойдет переход на метку t2. Далее происходит сброс флага очередности и линии RB4 в 0, затем в регистры таймера записывается значение длительности паузы между импульсами, равное 18,5 мс. Дополнительно проверяется значение регистра tmp_off , который выступает в роли счетчика времени для отключения таймера TMR1, о нем будет сказано позже. Если значение регистра tmp_off не равно 24, происходит инкремент регистра, далее сброс флага прерывания, запуск таймера и выход из подпрограммы обработки прерываний.

По истечении 18,5 мс произойдет прерывание и переход в обработчик прерываний, и цикл повторится заново. Таким образом, один период управляющего сигнала (цикл) генерируется за 2 прерывания, причем длительность периода будет меняться в пределах 19,1-21 мс, в зависимости от длительности управляющего импульса.

В основной программе идет опрос кнопок SB1 и SB2, при нажатии которых происходит вызов подпрограмм povorot_1 и povorot_2 соответственно. В подпрограмме povorot_1 происходит уменьшение длительности управляющего импульса на 10 мкс (вычитание числа 10 из регистров счета t1H, t1L), в подпрограмме povorot_2 увеличение на 10 мкс (прибавление числа 10 к регистрам счета t1H, t1L). Если значение длительности меньше 0,6 мс или больше 2,5 мс выполняется выход из подпрограмм без изменения значений регистров счета, то есть происходит ограничение длительности управляющего импульса. После изменения длительности импульса происходит вызов подпрограммы perezap, в которой значения регистров счета перезаписывается в промежуточные регистры (t1HH, t1LL) в инвертированном виде. Во время перезаписи запрещается прерывание по переполнению таймера TMR1, это необходимо для получения корректного значения длительности управляющего импульса в регистрах таймера. Если не запретить прерывания, возможен случай, когда прерывание произойдет после записи старшего промежуточного регистра t1HH, а значение младшего регистра t1LL при этом останется без изменений. В таком случае в обработчике прерываний, в регистры таймера TMR1 запишется некорректное значение длительности управляющего импульса из промежуточных регистров (t1HH, t1LL). После возврата из подпрограмм perezap и povorot_1, povorot_2, вызывается подпрограмма паузы pausknp (10,5 мс), после возврата продолжается опрос кнопок.

После экспериментов с сервоприводом я заметил одну особенность, когда на вал сервопривода действует небольшой по величине постоянный внешний момент силы (нахождение под нагрузкой), происходит микро-поворот вала, сервопривод при этом пытается поддерживать заданное положение, в результате чего постоянно “жужжит”, потребляя энергию. Без нагрузки такого поведения не возникает. Чтобы избавится от этого явления, я реализовал в программе счетчик времени, если в течение определенного времени длительность управляющего импульса не меняется, то генерирование импульсов на линии RB4 прекращается. Импульсы возобновляются при нажатии кнопок SB1, SB2.

В качестве счетчика времени используется регистр tmp_off , о котором я упоминал выше, значение регистра инкрементируется в обработчике прерывания, во втором прерывании, когда выполняется запись длительности паузы между импульсами (18,5 мс) в таймер TMR1. Таким образом, счетчик инкрементируется один раз за период управляющего сигнала. Там же в обработчике прерываний происходит проверка значения счетчика, если оно равно числу 24, происходит выход из обработчика прерываний без запуска таймера TMR1, в результате генерирование управляющих импульсов прекращается. При среднем значении периода в 20 мс, генерация импульсов прекратиться через (20мс)х24=480 мс.

Генерация импульсов возобновляется при нажатии кнопок SB1, SB2, в подпрограмме perezap выполняется запуск таймера TMR1, там же происходит очистка регистра tmp_off. При длительном нажатии кнопок, подпрограмма perezap вызывается многократно и регистр tmp_off постоянно обнуляется, то есть прекращение подачи управляющих импульсов не происходит.

Величина, на которую изменяется длительность управляющего импульса при вызове подпрограмм povorot_1, povorot_2 составляет 10 мкс, всего получается (2500мкс-600мкс)/10мкс=190 дискретных значений длительности управляющего импульса. Дискретность угла поворота составит 180/190=0,94 градуса. Пауза после каждого дискретного изменения равна 10,5 мс, соответственно поворот вала сервопривода на 180 градусов займет (10,5мс)х190=1,995 секунды.

На основе этих сервоприводов я разработал поворотную платформу с радиоуправлением.


Ниже представлен видеоролик демонстрирующий работу сервопривода:

Прошивка МК и исходник + модель Proteus 7.10
Прошивка МК и исходник (автоматический возврат вала сервопривода в среднее положение)

>Последние записи:

  • Стробоскоп своими руками
  • Часы на индикаторах ИВ-11
  • Солнечный трекер
  • Подключение радиомодулей HC-12 на основе трансивера Si4463
Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *