Роботизированная рука на микроконтроллере PIC16F877A


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

Внешний вид роботизированной руки на основе микроконтроллера PIC16F877A

В данной статье мы рассмотрим создание простой роботизированной руки на основе микроконтроллера PIC16F877A, управляемой с помощью 5 потенциометров и 5 серводвигателей. Проблема здесь заключается в том, что серводвигатели (сервомоторы) управляются с помощью сигналов широтно-импульсной модуляции (ШИМ), а у микроконтроллера PIC16F877A всего 2 стандартных контакта для формирования сигнала ШИМ. Поэтому мы будем формировать сигналы ШИМ на контактах ввода/вывода общего назначения микроконтроллера PIC16F877A, используя прерывания от таймеров. Подобную технику мы рассматривали в этой статье.

Механическая структура нашей роботизированной руки напечатана на 3D принтере и полностью совпадает с ее структурой из проекта роботизированной руки на основе платы Arduino. Если же у вас нет возможности использовать 3D принтер, то вы можете изготовить каркас роботизированной руки из обычных листов картона как показано в этой статье. Также на нашем сайте мы рассматривали проект управляемой жестами роботизированной руки на Arduino Nano.

Необходимые компоненты

  1. Микроконтроллер PIC16F877A (купить на AliExpress).
  2. Программатор PICkit 3 (купить на AliExpress).
  3. ЖК дисплей 16х2 (купить на AliExpress).
  4. Потенциометры – 5 шт. (купить на AliExpress).
  5. Сервомотор SG90 (купить на AliExpress) или MG-995 (купить на AliExpress) – 5 шт.
  6. Кварцевый генератор 20 МГц (купить на AliExpress).
  7. Конденсаторы 1 мкФ – 6 шт. (купить на AliExpress).
  8. Резистор 1 кОм (купить на AliExpress).
  9. Потенциометр 10 кОм (купить на AliExpress).
  10. Регулятор напряжения 7805 – 2 шт. (купить на AliExpress).

Схема проекта

Схема роботизированной руки на микроконтроллере PIC16F877A представлена на следующем рисунке. Она нарисована в редакторе EasyEDA.

Схема роботизированной руки на микроконтроллере PIC16F877AКак видите, схема достаточно проста и она запитывается от адаптера на 12V. Затем эти 12V преобразуются в 5V с помощью двух регуляторов напряжения 7805. Необходимость использования двух регуляторов напряжения обусловлена тем, что сервомоторы во время своего вращения потребляют значительное количество тока, что создает достаточно большой перепад напряжения в схеме, который может привести к перезагрузке микроконтроллера PIC.

Выходы пяти потенциометров подключены к контактам с An0 по AN4 микроконтроллера PIC. На них обеспечивается напряжение в диапазоне от 0V до 5V. Поскольку мы будем использовать таймеры для формирования сигналов ШИМ, мы можем подключить серводвигатели к любым контактам ввода/вывода микроконтроллера PIC, в нашем случае мы будем использовать контакты с RD2 по RD6, но вы можете изменить эти контакты по своему усмотрению.

Поскольку в программе нам потребуется выполнение достаточно большого количества операций отладки, то для упрощения процесса отладки мы добавили в схему проекта ЖК дисплей 16x2, подключенный к portB микроконтроллера PIC. На его экране мы будем отображать информацию о коэффициенте заполнения ШИМ сигнала для управляемых сервомоторов. Также мы использовали контакт программирования H1 для возможности непосредственного программирования микроконтроллера PIC с помощью программатора pickit3 через опцию ICSP (внутрисхемного программирования).

Формирование ШИМ сигналов для управления сервомоторами

Для лучшего понимания данного раздела рекомендуем прочитать статью на нашем сайте про формирование ШИМ сигналов на контактах GPIO микроконтроллера PIC с помощью прерываний от таймера потому что в этом проекте мы будем использовать точно такую же технику.

Любительские сервомоторы работают на частоте 50 Гц. Это значит что длительность одного периода ШИМ сигнала для управления данными сервомоторами составляет величину 20 мс (F=1/T, 1/50). Из этих 20 мс длительность управляющего сигнала будет составлять от 0 до 2 мс, остальное время сигнал будет в состоянии OFF. На следующем рисунке наглядно показано что состояние ON управляющего ШИМ сигнала варьируется от 0 до 2 мс из общей длительности периода сигнала 20 мс чтобы осуществить вращение оси серводвигателя на величину от 0 до 180 градусов.

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

Таким образом, в программе нам необходимо преобразовывать значения с выходов АЦП аналоговых контактов, к которым подключены потенциометры, из диапазона от 0 до 1024 в диапазон от 0 до 100 – эти значения и будут представлять собой коэффициенты заполнения ШИМ сигналов для управления сервомоторами. Используя этот коэффициент заполнения мы можем рассчитать время ON ШИМ сигнала. После этого мы можем записать в таймер такое значение, чтобы он переполнялся через данный промежуток времени и, соответственно, срабатывало прерывание от таймера. Фактически, мы получим аналог функции millis() в Arduino. Используя это мы будем переключать состояние контакта GPIO в high на необходимую длительность и переключать его в OFF после 20 мс (один полный период сигнала) и затем повторять этот процесс.

Объяснение программы для микроконтроллера PIC

Полный код программы приведен в конце статьи, здесь же мы кратко рассмотрим его основные фрагменты.

В программе мы будем использовать модули АЦП, таймера и ЖК дисплея. Более подробно про их использование вы можете прочитать в соответствующих статьях:

Настройка Timer 0

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

Формула для расчета задержки в данном случае будет выглядеть следующим образом:

Используя регистры OPTION_REG и TMR0 мы будем устанавливать Timer 0 для работы с предделителем 32, а в REG будем записывать значение 248. Поскольку тактовая частота кварцевого генератора в нашем проекте будет составлять величину 20Mhz, то величину задержки можно вычислить следующим образом:

Таким образом, таймер у нас должен будет переполняться каждые 0.05ms. Для этого сделаем следующие настройки:

Таким образом, длительностью окна управления сервомотором, которое составляет величину от 0 до 2 мс, мы сможем управлять с разрешением 0.05msec, что обеспечивает 40 (2/0.05) различных позиций оси сервомотора в диапазоне от 0 до 180 градусов.

Функция обработки прерывания (Interrupt Service Routine, ISR)

Поскольку Timer 0 будет переполняться у нас каждые 0.05ms, то флаг установки прерывания TMR0IF будет также у нас устанавливаться каждые 0.05ms. Поэтому внутри функции обработки прерывания (ISR) мы сможем сбрасывать этот флаг и инкрементировать состояние переменной count на 1. Таким образом, состояние данной переменной будет увеличиваться на 1 каждые 0.05ms.

Расчет коэффициента заполнения

В программе нам необходимо будет рассчитывать значение коэффициента заполнения ШИМ сигнала для всех наших пяти сервомоторов, каждый из которых будет управлять своей секцией нашей роботизированной руки.

Значение коэффициента заполнения ШИМ сигнала мы будем рассчитывать на основе значения, считываемого с соответствующего выхода АЦП. С выхода АЦП мы будем получать значение в диапазоне от 0 до 1024, чтобы преобразовать его в значение коэффициента заполнения от 0 до 100% нам необходимо будет умножить его на значение 0.0976 (100/1024 = 0.0976). Теперь на основе значения коэффициента заполнения необходимо рассчитать значение времени ON ШИМ сигнала. Для угла поворота оси сервомотора 180 градусов это время должно составлять 2 мс, то есть умножив на 0.02 (2/100 = 0.02) значение коэффициента заполнения мы преобразуем его диапазон от о до 100% в диапазон времени от 0 до 2 мс. Но таймер в нашем проекте будет переполняться каждые 0.05ms. Это значит что значение переменной count будет равно 20 (1/0.05 = 20) каждую 1 мс. То есть мы должны умножить 20 на 0.02 чтобы рассчитать точное значение времени ON ШИМ сигнала для нашей программы, в итоге мы получим значение 0.4 (0.02*20 = 0.4). Все эти действия мы будем выполнять в цикле for для всех наших 5 потенциометров. Результирующие значения мы будем сохранять в массиве T_ON.

Выбор серводвигателя который необходимо вращать

Мы не можем одновременно управлять всеми 5 серводвигателями поскольку это сделает код функции обработки прерывания (ISR) слишком тяжелым для нашего микроконтроллера. Поэтому в один момент времени мы будем управлять только одним серводвигателем. Чтобы выбрать каким двигателем управлять мы будем анализировать значение времени ON ШИМ сигналов для всех 5 серводвигателей и сравнивать его с предыдущими значениями этого времени. Если обнаруживается разница между текущим и предыдущим значениями времени ON для какого то серводвигателя, это будет означать что положение оси данного серводвигателя необходимо изменить. Код для этого выглядит следующим образом.

Также мы будем отображать значение коэффициента заполнения на экране ЖК дисплея чтобы пользователь мог наглядно посмотреть текущее значение позиции оси сервомотора. На основе изменения времени ON в переменную servo будет записываться значение от 0 до 4, которое соответствует конкретному сервомотору.

Управление сервомотором внутри функции обработки прерывания

Внутри функции обработки прерывания переменная count будет инкрементироваться каждые 0.05ms, это значит, что ее значение будет инкрементироваться на 20 каждую 1 мс. Мы это будем использовать для управления сервомотором. Если значение переменной count будет меньше времени ON, мы будем подавать на соответствующий контакт GPIO уровень high с помощью следующей строчки кода:

В данном случае массив servo_code[] содержит состояние контактов для всех 5 управляемых сервомоторов и, основываясь на значении переменной servo, будет выбираться контакт для соответствующего сервомотора. Он с помощью OR (|) суммируется с состоянием контактов PORTD поэтому он не нарушает логику работу других сервомоторов и обновляет состояние только текущего сервомотора. Аналогичным образом для подачи на контакт уровня low мы будем использовать:

Мы будем переключать состояние контакта на обратное с помощью операции логического инвертирования (~) и затем выполнять операцию AND (&) на PORTD чтобы выключить только необходимый нам контакт, а все остальные контакты остались в исходном состоянии. Полный код этого сниппета выглядит следующим образом.

Нам известно что полный период ШИМ сигнала у нас длится 20 мс. Отмерить этот промежуток времени мы можем с помощью переменной count – как только ее значение станет равно 400 можно сбрасывать ее значение в 0 и начинать счет сначала.

Моделирование работы роботизированной руки

Прежде чем собирать конструкцию проекта в реальном железе всегда полезно смоделировать ее работу в каком-нибудь симуляторе. В нашем случае мы использовали симулятор Proteus, схема нашего проекта, нарисованная в нем, представлена на рисунке ниже. Мы использовали осциллограф чтобы проверить корректность формирования ШИМ сигналов. Также можно проверить ЖК дисплей и сервомоторы на предмет того правильно ли они вращаются.

Схема нашего проекта, нарисованная в симуляторе Proteus

Как вы можете видеть в нашей симуляции ЖК дисплей показывает коэффициент заполнения ШИМ сигнала для двигателя D равный 07. Аналогичным образом можно проверить коэффициент заполнения ШИМ сигнала для любого другого двигателя. Внешний вид ШИМ сигнала на виртуальном осциллографе показан на следующем рисунке.

Внешний вид формируемого нами ШИМ сигнала на виртуальном осциллографе

С помощью курсора можно измерить полный период ШИМ сигнала – в нашем случае он равен 22.2ms, что достаточно близко к необходимым нам 20ms.

Проектирование печатной платы для проекта

Для проектирования печатной платы для данного проекта роботизированной руки его автор (ссылка на оригинал приведена в конце статьи) использовал онлайн редактор EasyEDA. После ее проектирования в этом же сервисе можно заказать и ее изготовление.

Дизайн печатной платы для нашего проекта доступен по следующей ссылке:

https://easyeda.com/circuitdigest/pic-development-board-for-robotic-arm

Вы можете его использовать и заказать себе изготовление точно такой же печатной платы. В редакторе EasyEDA также можно посмотреть 3D модель спроектированной печатной платы, для нашего проекта она приведена на рисунке ниже. Также можно отдельно посмотреть верхнюю и нижнюю часть платы.

3D модель спроектированной печатной платы для нашего проекта

Заказ изготовления печатной платы

Автор проекта заказал изготовление печатной платы на сервисе JLCPCB.com (разумеется, вы можете использовать любой другой подобный сервис по своему усмотрению). Для заказа изготовления печатной платы на сервисе JLCPCB.com необходимо загрузить в этот сервис Gerber файл печатной платы. Чтобы скачать его в редакторе EasyEDA нажмите кнопку Generate Fabrication File, либо же из этого редактора вы сразу можете нажать кнопку "Order at JLCPCB" как показано на рисунке ниже. После этого вас сразу перебросит на страницу заказа изготовления печатной платы на сервисе JLCPCB.com, где вам необходимо ввести количество экземпляров печатной платы, число ее слоев, толщину, цвет и другие параметры.

Страница заказа печатной платы на сервисе JLCPCB.com

После ввода параметров печатной платы нажмите на кнопку “Save to Cart” и вас перебросит на страницу, на которой необходимо будет загрузить Gerber файл платы. Загрузите его и нажмите на кнопку “Save to Cart”. Затем нажмите на Checkout Securely чтобы завершить оформление заказа. Через несколько дней ваша печатная плата будет изготовлена.

Страница оплаты изготовления печатной платы на сервисе JLCPCB.com

На странице сервиса JLCPCB.com вы также можете прогресс в выполнении вашего заказа, для этого в своем аккаунте на сервисе нажмите "Production Progress".

Прогресс изготовления печатной платы на сервисе JLCPCB.com

Через несколько дней после заказа автор проекта получил изготовленную печатную плату в упаковке.

Изготовленная печатная плата для нашего проекта в упаковке

Внешний вид изготовленной печатной платы для нашего проекта

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

Внешний вид конструкции проекта роботизированной руки

Вы можете заметить что на представленном рисунке виден всего один регулятор напряжения 7805. Он сначала думал что ему удастся обойтись всего одним регулятором напряжения, но потом пришел к выводу что их нужно два и на представленном рисунке вы можете видеть зеленый провод от внешнего источника питания, который запитывает сервомоторы. Исправленный на два регулятора напряжения 7805 образец печатной платы для нашего проекта вы можете скачать по следующей ссылке.

Тестирование работы проекта

После сборки аппаратной части проекта загрузите программу в микроконтроллер PIC. Коннектор для программирования уже выведен для плату, поэтому вы можете непосредственно к нему подключить программатор Pickit 3. После того как программа будет загружена в микроконтроллер на экране ЖК дисплея вы должны увидеть номер сервомотора, положение которого изменяется в данный момент.

Тестирование работы проекта роботизированной руки

Вращая потенциометры вы можете управлять положением нашей роботизированной руки. Более подробно работу проекта вы можете посмотреть на видео, приведенном в конце статьи.

Исходный код программы

Видео, демонстрирующее работу проекта

Источник статьи

(Проголосуй первым!)
Загрузка...
449 просмотров

Добавить комментарий

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