www.000webhost.com
MAKSIKI have come to you

На главную | Робот в домашних условиях | Программа для объезда припятствий | Простой робот № 2 в домашних условиях | Робот манипулятор | Подключение сервопривода к Arduino | Подключение сервопривода к микроконтроллеру | Генерация ШИМ в STM32 | Управление множеством сервомашинок с pic16f628a

Робот в домашних условиях

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

Введение

Итак. Что же такое робот? В большинстве случаев это автоматическое устройство, которое реагирует на какие-либо действия окружающей среды. Роботы могут управляться человеком или выполнять заранее запрограммированные действия. Обычно на роботе располагают разнообразные датчики (расстояния, угла поворота, ускорения), видеокамеры, манипуляторы. Электронная часть робота состоит из микроконтроллера (МК) – микросхема, в которую заключён процессор, тактовый генератор, различная периферия, оперативная и постоянная память. В мире существует огромное количество разнообразных микроконтроллеров для разных областей применения и на их основе можно собирать мощных роботов. Для любительских построек широкое применение нашли микроконтроллеры AVR. Они, на сегодняшний день, самые доступные и в интернете можно найти много примеров на основе этих МК. Чтобы работать с микроконтроллерами тебе нужно уметь программировать на ассемблере или на Cи и иметь начальные знания в цифровой и аналоговой электронике. В нашем проекте мы будем использовать Cи. Программирование для МК мало чем отличается от программирования на компьютере, синтаксис языка такой же, большинство функций практически ничем не отличаются, а новые довольно легко освоить и ими удобно пользоваться.


Что нам нужно

Для начала наш робот будет уметь просто объезжать препятствия, то есть повторять нормальное поведение большинства животных в природе. Всё что нам потребуется для постройки такого робота можно будет найти в радиотехнических магазинах. Решим, как наш робот будет передвигаться. Самым удачным я считаю гусеницы, которые применяются в танках, это наиболее удобное решение, потому что гусеницы имеют большую проходимость, чем колёса машины и ими удобнее управлять (для поворота достаточно вращать гусеницы в разные стороны). Поэтому тебе понадобится любой игрушечный танк, у которого гусеницы вращаются независимо друг от друга, такой можно купить в любом магазине игрушек по разумной цене. От этого танка тебе понадобится только платформа с гусеницами и моторы с редукторами, остальное ты можешь смело открутить и выкинуть. Так же нам потребуется микроконтроллер, мой выбор пал на ATmega16 – у него достаточно портов для подключения датчиков и периферии и вообще он довольно удобный. Ещё тебе потребуется закупить немного радиодеталей, паяльник, мультиметр.


Делаем плату с МК


Схема робота

В нашем случае микроконтроллер будет выполнять функции мозга, но начнём мы не с него, а с питания мозга робота. Правильное питание – залог здоровья, поэтому мы начнём с того, как правильно кормить нашего робота, потому что на этом обычно ошибаются начинающие роботостроители. А для того, чтобы наш робот работал нормально нужно использовать стабилизатор напряжения. Я предпочитаю микросхему L7805 – она предназначена, чтобы на выходе выдавать стабильное напряжение 5В, которое и нужно нашему микроконтроллеру. Но из-за того, что падение напряжения на этой микросхеме составляет порядка 2,5В к нему нужно подавать минимум 7,5В. Вместе с этим стабилизатором используются электролитические конденсаторы, чтобы сгладить пульсации напряжения и в цепь обязательно включают диод, для защиты от переполюсовки.
Теперь мы можем заняться нашим микроконтроллером. Корпус у МК — DIP (так удобнее паять) и имеет сорок выводов. На борту имеется АЦП, ШИМ, USART и много другого, что мы пока использовать не будем. Рассмотрим несколько важных узлов. Вывод RESET (9-ая нога МК) подтянут резистором R1 к «плюсу» источника питания – это нужно делать обязательно! Иначе твой МК может непреднамеренно сбрасываться или, проще говоря – глючить. Так же желательной мерой, но не обязательной является подключение RESET’а через керамический конденсатор C1 к «земле». На схеме ты так же можешь увидеть электролит на 1000 мкФ, он спасает от провалов напряжения при работе двигателей, что тоже благоприятно скажется на работе микроконтроллера. Кварцевый резонатор X1 и конденсаторы C2, C3 нужно располагать как можно ближе к выводам XTAL1 и XTAL2.
О том, как прошивать МК, я рассказывать не буду, так как об этом можно прочитать в интернете. Писать программу мы будем на Cи, в качестве среды программирования я выбрал CodeVisionAVR. Это довольно удобная среда и полезна новичкам, потому что имеет встроенный мастер создания кода.


Плата моего робота


Управление двигателями

Не менее важным компонентом в нашем роботе является драйвер двигателей, который облегчает нам задачу в управлении им. Никогда и ни в коем случае нельзя подключать двигатели напрямую к МК! Вообще мощными нагрузками нельзя управлять с микроконтроллера напрямую, иначе он сгорит. Пользуйтесь ключевыми транзисторами. Для нашего случая есть специальная микросхема – L293D. В подобных несложных проектах всегда старайтесь использовать именно эту микросхему с индексом «D», так как она имеет встроенные диоды для защиты от перегрузок. Этой микросхемой очень легко управлять и её просто достать в радиотехнических магазинах. Она выпускается в двух корпусах DIP и SOIC. Мы будем использовать в корпусе DIP из-за удобства монтажа на плате. L293D имеет раздельное питание двигателей и логики. Поэтому саму микросхему мы будем питать от стабилизатора (вход VSS), а двигатели напрямую от аккумуляторов (вход VS). L293D выдерживает нагрузку 600 мА на каждый канал, а этих каналов у неё два, то есть к одной микросхеме можно подключить два двигателя. Но, чтобы перестраховаться, мы объединим каналы, и тогда потребуется по одной микре на каждый двигатель. Отсюда следует, что L293D сможет выдержать 1.2 А. Чтобы этого добиться нужно объединить ноги микры, как показано на схеме. Микросхема работает следующим образом: когда на IN1 и IN2 подаётся логический «0», а на IN3 и IN4 логическая единица, то двигатель вращается в одну сторону, а если инвертировать сигналы – подать логический ноль, тогда двигатель начнёт вращаться в другую сторону. Выводы EN1 и EN2 отвечают за включение каждого канала. Их мы соединяем и подключаем к «плюсу» питания от стабилизатора. Так как микросхема греется во время работы, а установка радиаторов проблематична на этот тип корпуса, то отвод тепла обеспечивается ногами GND — их лучше распаивать на широкой контактной площадке. Вот и всё, что на первое время тебе нужно знать о драйверах двигателей.


Датчики препятствий

Чтобы наш робот мог ориентироваться и не врезался во всё, мы установим на него два инфракрасных датчика. Самый простейший датчик состоит из ик-диода, который излучает в инфракрасном спектре и фототранзистор, который будет принимать сигнал с ик-диода. Принцип такой: когда перед датчиком нет преграды, то ик-лучи не попадают на фототранзистор и он не открывается. Если перед датчиком препятствие, тогда лучи от него отражаются и попадают на транзистор – он открывается и начинает течь ток. Недостаток таких датчиков в том, что они могут по-разному реагировать на различные поверхности и не защищены от помех — от посторонних сигналов других устройств датчик, случайно, может сработать. От помех может защитить модулирование сигнала, но пока мы этим заморачиватся не будем. Для начала, и этого хватит.


Первый вариант датчиков моего робота


Прошивка робота

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

#include <mega16.h>
#include <delay.h>


Следующие строки условные, потому что значения PORTC зависят от того, как ты подключил драйвер двигателей к своему микроконтроллеру:

PORTC.0 = 1;
PORTC.1 = 0;
PORTC.2 = 1;
PORTC.3 = 0;


Значение 0xFF означает, что на выходе будет лог. «1», а 0x00 – лог. «0».

Следующей конструкцией мы проверяем, есть ли перед роботом препятствие и с какой оно стороны:

if (!(PINB & (1<<PINB.0)))
{
...
}


Если на фототранзистор попадает свет от ик-диода, то на ноге микроконтроллера устанавливается лог. «0» и робот начинает движение назад, чтобы отъехать от препятствия, потом разворачивается, чтобы снова не столкнуться с преградой и затем опять едет вперёд. Так как у нас два датчика, то мы проверяем наличие преграды два раза – справа и слева и потому можем узнать с какой стороны препятствие. Команда «delay_ms(1000)» указывает на то, что пройдёт одна секунда, прежде чем начнёт выполняться следующая команда.


Заключение

Я рассмотрел большинство аспектов, которые помогут тебе собрать твоего первого робота. Но на этом робототехника не заканчивается. Если ты соберёшь этого робота, то у тебя появится куча возможностей для его расширения. Можно усовершенствовать алгоритм робота, как например, что делать, если препятствие не с какой-то стороны, а прямо перед роботом. Так же не помешает установить энкодер – простое устройство, которое поможет точно располагать и знать расположение твоего робота в пространстве. Для наглядности возможна установка цветного или монохромного дисплея, который может показывать полезную информацию – уровень заряда аккумулятора, расстояние до препятствия, различную отладочную информацию. Не помешает и усовершенствование датчиков – установка TSOP (это ик-приёмники, которые воспринимают сигнал только определённой частоты) вместо обычных фототранзисторов. Помимо инфракрасных датчиков существуют ультразвуковые, стоят подороже, и тоже не лишены недостатков, но в последнее время набирают популярность у роботостроителей. Для того, чтобы робот мог реагировать на звук, было бы неплохо установить микрофоны с усилителем. Но по-настоящему интересным, я считаю, установка камеры и программирование на её основе машинного зрения. Есть набор специальных библиотек OpenCV, с помощью которых можно запрограммировать распознавание лиц, движения по цветным маякам и много всего интересного. Всё зависит только от твоей фантазии и умений.


Список компонентов:



Код прошивки:

/***************************
Прошивка для робота

Тип МК : ATmega16
Тактовая частота : 16,000000 MHz
Если у тебя частота кварца другая, то это нужно указать в настройках среды:
Project -> Configure -> Закладка "C Compiler"
**********************************/

#include <mega16.h>
#include <delay.h>

void main(void)
{
//Настраиваем порты на вход
//Через эти порты мы получаем сигналы от датчиков
DDRB=0x00;
//Включаем подтягивающие резисторы
PORTB=0xFF;

//Настраиваем порты на выход
//Через эти порты мы управляем двигателями
DDRC=0xFF;

//Главный цикл программы. Здесь мы считываем значения с датчиков
//и управляем двигателями
while (1)
{
//Едем вперёд
PORTC.0 = 1;
PORTC.1 = 0;
PORTC.2 = 1;
PORTC.3 = 0;
if (!(PINB & (1<<PINB.0)))
// Проверяем правый датчик
{
//Едем назад 1 секунду
PORTC.0 = 0;
PORTC.1 = 1;
PORTC.2 = 0;
PORTC.3 = 1;
delay_ms(1000);
//Заворачиваем
PORTC.0 = 1;
PORTC.1 = 0;
PORTC.2 = 0;
PORTC.3 = 1;
delay_ms(1000);
}
if (!(PINB & (1<<PINB.1)))
// Проверяем левый датчик
{
//Едем назад 1 секунду
PORTC.0 = 0;
PORTC.1 = 1;
PORTC.2 = 0;
PORTC.3 = 1;
delay_ms(1000);
//Заворачиваем
PORTC.0 = 0;
PORTC.1 = 1;
PORTC.2 = 1;
PORTC.3 = 0;
delay_ms(1000);
}
};
}



О моём роботе

В данный момент мой робот практически завершён.

На нём установлена беспроводная камера, датчик расстояния (и камера и этот датчик установлены на поворотной башне), датчик препятствия, энкодер, приёмник сигналов с пульта и интерфейс RS-232 для соединения с компьютером. Работает в двух режимах: автономном и ручном (принимает сигналы управления с пульта ДУ), камера также может включаться/выключаться дистанционно или самим роботом для экономии заряда батарей. Пишу прошивку для охраны квартиры (передача изображения на компьютер, обнаружение движений, объезд помещения).

По пожеланиям выкладываю видео:


UPD.

Статья была опубликована в журнале «Хакер» за август 2009 года.

к началу статьи


Программа для объезда припятствий

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

/**
ПРИМЕР 5 :: РОБОТ ДЛЯ СОРЕВНОВАНИЙ КЕГЕЛЬРИНГ
**/ 

#define F_CPU 1000000UL  // указываем частоту в герцах
#include <avr/io.h>
#include <util/delay.h>

int main(void) // начало основной программы
{
  
   DDRC = 0xff; // все выводы порта C сконфигурировать как выходы
   DDRD = 0x00; // все выводы порта D сконфигурировать как входы


   PORTD = 0xff; // установить "1" на всех выводах порта D,
		 // включаем подтягивающие резисторы

        while (1) {  // Бесконечный цикл

		// ПРОВЕРЯЕМ СИГНАЛ НИЗКОГО УРОНЯ ОТ ФОТОДАТЧИКА

		if (!(PIND & (1<<PIND1))) // проверить "0" на линии 1 порта D
		{
            		// -------------- включаем моторы вперед ---------------

            		PORTC |= _BV(PC1); // установить "1" на линии 1 порта C
            		PORTC &= ~_BV(PC2); // установить "0" на линии 2 порта C
            		PORTC |= _BV(PC3); // установить "1" на линии 3 порта C
            		PORTC &= ~_BV(PC4); // установить "0" на линии 4 порта C

            		// -----------------------------------------------------
		}
		else
		{
                        // ------------------ отъезд назад ------------------
                        // -------- включаем моторы назад на 1,8 сек --------

                        PORTC &= ~_BV(PC1); // установить "0" на линии 1 порта C
                        PORTC |= _BV(PC2); // установить "1" на линии 2 порта C
                        PORTC &= ~_BV(PC3); // установить "0" на линии 3 порта C
                        PORTC |= _BV(PC4); // установить "1" на линии 4 порта C

                        _delay_ms(1800); // ждем 1,8 сек.

                        // --------------------------------------------------

                        // --------------------- поворот --------------------
                        //  правый мотор вперед, левый мотор стоп на 0,6 сек 

            		PORTC |= _BV(PC1); // установить "1" на линии 1 порта C
            		PORTC &= ~_BV(PC2); // установить "0" на линии 2 порта C
            		PORTC |= _BV(PC3); // установить "1" на линии 3 порта C

                        _delay_ms(600); // ждем 0,6 сек.

                        // --------------------------------------------------
		}


        } // закрывающая скобка бесконечного цикла

} // закрывающая скобка основной программы


к началу статьи


Простой робот № 2 в домашних условиях

Простого робота на микроконтроллере можно собрать на основе драйвера управления двигателями и непосредственно самого микроконтроллера.

В качестве драйвера двигателей используем микросхему L293D, входы которой подсоединим к выводам микроконтроллера так, как показано на схеме. В данном примере будет рассмотрен микроконтроллер ATmega8, хотя можно использовать и другой микроконтроллер (например, ATtiny26 или какой-либо микроконтроллер из семейства Mega).


Схема робота на микроконтроллере AVR


В приведенной схеме рекомендуется использовать электродвигатели с током потребления до 150 мА и напряжением питания 3-5 В. При использовании более мощных моторов рекомендуется применить раздельное питание электронной схемы и электродвигателей, а также предусмотреть меры по стабилизации работы микроконтроллера
На схеме робота входы драйвера двигателей L293D подключены к выводам порта C микроконтроллера ATmega8, но их можно подключить к любому из портов микроконтроллера (при этом будет необходимо внести изменения в программную часть, указав порт и непосредственно его выводы в соответствующих строках программы, приводимой ниже).

Электролитический конденсатор C3 (1000 мкф, 10-25 в.) необходим для того, чтобы сгладить броски по питанию, вызванные работой моторов. Этот конденсатор очень важен. Именно он дает возможность работать схеме с необходимым уровнем стабильности. Вместо одного конденсатора можно использовать два. Номинал каждого из них в этом случае может быть около 470 мкф. При этом один из конденсаторов устанавливают в непосредственной близости от выводов питания микроконтроллера, а второй - рядом с выводом Vs микросхемы драйвера моторов L293D. Обеспечение стабилизации питания - один из важнейших аспектов проектирования устройств на микроконтроллерах.

Для того чтобы еще больше стабилизировать работу микроконтроллера, хорошим решением может служить керамический конденсатор емкостью около 0,1 мкф, подсоединенный между выводами питания VCC, GND (ножки 7 и 8) и располагающийся в непосредственной близости от них (на схеме не указан).

Механическая схема рассматриваемого робота должна быть собрана по "танковому" принципу: левый мотор передает движение на левое колесо, правый - на правое. По-другому такая механическая схема называется схемой с двумя ведущими колесами.
Для того чтобы собранный робот "ожил", напишем для него программу. Откомпилируем ее и загрузим в микроконтроллер.

/**
ПРИМЕР 1 :: ВРАЩЕНИЕ МОТОРАМИ ВПЕРЕД-НАЗАД
**/

#define F_CPU 1000000UL  // указываем частоту в герцах
      #include <avr/io.h>
   #include <util/delay.h>

int main(void) // начало основной программы
{
   
   DDRC = 0xff; // все выводы порта C сконфигурировать как выходы

        while (1) {  // Бесконечный цикл

            // ---------- вращаем моторы вперед 1 сек ----------

            PORTC |= _BV(PC1); // установить "1" на линии 1 порта C
            PORTC &= ~_BV(PC2); // установить "0" на линии 2 порта C
            PORTC |= _BV(PC3); // установить "1" на линии 3 порта C
            PORTC &= ~_BV(PC4); // установить "0" на линии 4 порта C

            _delay_ms(1000); // ждем 1 сек.

            // --------------------------------------------------


                        // ---------- вращаем моторы назад 1 сек ----------

                        PORTC &= ~_BV(PC1); // установить "0" на линии 1 порта C
                        PORTC |= _BV(PC2); // установить "1" на линии 2 порта C
                        PORTC &= ~_BV(PC3); // установить "0" на линии 3 порта C
                        PORTC |= _BV(PC4); // установить "1" на линии 4 порта C

                        _delay_ms(1000); // ждем 1 сек.

                        // --------------------------------------------------


                   } // закрывающая скобка бесконечного цикла

} // закрывающая скобка основной программы

Отсоединив программатор, проверим направление вращения колес робота. Если моторы вращают колеса в противоположные стороны, поменяйте местами их выводы.

Следующим шагом будет создание программы, реализующей поворот на необходимый угол остановкой одного из моторов.


/**
ПРИМЕР 2 :: ДВИЖЕНИЕ ПРЯМО С ПОВОРОТОМ
**/ 

#define F_CPU 1000000UL  // указываем частоту в герцах
      #include <avr/io.h>
   #include <util/delay.h>

int main(void) // начало основной программы
{
   
   DDRC = 0xff; // все выводы порта C сконфигурировать как выходы

        while (1) {  // Бесконечный цикл

            // ---------- вращаем моторы вперед 1 сек ------------

            PORTC |= _BV(PC1); // установить "1" на линии 1 порта C
            PORTC &= ~_BV(PC2); // установить "0" на линии 2 порта C
            PORTC |= _BV(PC3); // установить "1" на линии 3 порта C
            PORTC &= ~_BV(PC4); // установить "0" на линии 4 порта C

            _delay_ms(1000); // ждем 1 сек.

            // ----------------------------------------------------


                        // ---------- останавливаем мотор M2 на 0,5 сек ------

                        PORTC |= _BV(PC1); // установить "1" на линии 1 порта C
                        PORTC |= _BV(PC2); // установить "1" на линии 2 порта C

                        _delay_ms(500); // ждем 0,5 сек.

                        // ----------------------------------------------------


                   } // закрывающая скобка бесконечного цикла

} // закрывающая скобка основной программы

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

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

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

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

Интересные результаты можно получить, используя маркеры и фломастеры разных типов, толщины и фактуры. Красиво выглядит фактурная прерывистая линия, оставляемая мягким толстым стеклографом. А самые необычные результаты дают подогреваемые восковые палочки для рисования. Устройство подогрева легко сделать из небольшого кусочка нихромовой проволоки и стеклянной трубки. (Батареи питания робота при этом быстро садятся.)

к началу статьи


Робот манипулятор



к началу статьи


Подключение сервопривода к Arduino

Многие сервоприводы могут быть подключены к Arduino непосредственно. Для этого от них идёт шлейф из трёх проводов:
красный — питание; подключается к контакту 5V или напрямую к источнику питания
коричневый или чёрный — земля
жёлтый или белый — сигнал; подключается к цифровому выходу Arduino.
Для подключения к Arduino будет удобно воспользоваться платой-расширителем портов, такой как Troyka Shield. Хотя с несколькими дополнительными проводами можно подключить серву и через breadboard или непосредственно к контактам Arduino.
Можно генерировать управляющие импульсы самостоятельно, но это настолько распространённая задача, что для её упрощения существует стандартная библиотека Servo.
Ограничение по питанию
Обычный хобби-сервопривод во время работы потребляет более 100 мА. При этом Arduino способно выдавать до 500 мА. Поэтому, если вам в проекте необходимо использовать несколько сервоприводов, есть смысл задуматься о выделении сервоприводов в контур с дополнительным питанием.
Ограничение по количеству подключаемых сервоприводов
На большинстве плат Arduino библиотека Servo поддерживает управление не более 12 сервоприводами, на Arduino Mega это число вырастает до значения 48. При этом есть небольшой побочный эффект использования этой библиотеки: если вы работаете не с Arduino Mega, то становится невозможным использовать функцию analogWrite() на 9 и 10 контактах независимо от того, подключены сервоприводы к этим контактам или нет. На Arduino Mega можно подключить до 12 сервоприводов без нарушения функционирования ШИМ/PWM, при использовании большего количества сервоприводов мы не сможем использовать analogWrite() на 11 и 12 контактах.

Функционал библиотеки Servo
Библиотека Servo позволяет осуществлять программное управление сервоприводами. Для этого заводится переменная типа Servo. Управление осуществляется следующими функциями: attach() — присоединяет переменную к конкретному пину. Возможны два варианта синтаксиса для этой функции: servo.attach(pin) и servo.attach(pin, min, max). При этом pin — номер пина, к которому присоединяют сервопривод, min и max — длины импульсов в микросекундах, отвечающих за углы поворота 0° и 180°. По умолчанию выставляются равными 544 мкс и 2400 мкс соответственно.
write() — отдаёт команду сервоприводу принять некоторое значение параметра. Синтаксис следующий: servo.write(angle), где angle — угол, на который должен повернуться сервопривод.
writeMicroseconds() — отдаёт команду послать на сервоприводимульс определённой длины, является низкоуровневым аналогом предыдущей команды. Синтаксис следующий: servo.writeMicroseconds(uS), где uS — длина импульса в микросекундах.
read() — читает текущее значение угла, в котором находится сервопривод. Синтаксис следующий: servo.read(), возвращается целое значение от 0 до 180.
attached() — проверка, была ли присоединена переменная к конкретному пину. Синтаксис следующий: servo.attached(), возвращается логическая истина, если переменная была присоединена к какому-либо пину, или ложь в обратном случае.
detach() — производит действие, обратное действию attach(), то есть отсоединяет переменную от пина, к которому она была приписана. Синтаксис следующий: servo.detach().
Пример использования библиотеки Servo #include <Servo.h>   Servo myservo;   void setup() { myservo.attach(9); }   void loop() { myservo.write(90); // устанавливаем сервопривод в серединное положение delay(500); myservo.write(0); // устанавливаем сервопривод в крайнее левое положение delay(500); myservo.write(180); // устанавливаем сервопривод в крайнее правое положение delay(500); }
Отличия для сервопривода постоянного вращения
Вы могли обратить внимание, что приводы постоянного вращения такие как FS5103R и FS5113R являются сервоприводами, которые поддерживают заданную скорость.
Такими приводами можно также управлять с помощью библиотеки Servo, теми же функциями. Небольшое отличие заключается в том, что функция Servo.write(angle) задаёт не угол, а скорость вращения привода. Угол 0° задаёт полный ход в одном направлении, 180° — полный ход в обратном направлении, угол 90° задаёт остановку привода.

к началу статьи


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


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

Конструктив

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

В качестве обратной связи применяются потенциометры. Поэтому эти сервы имеют ограничения по углу поворота вала вокруг оси. Так, в приобретенных мной сервах Futaba S3003, угол поворота выходного вала составляет 225°.

Технические характеристики Futaba S3003
    Параметр                             Напряжение питания, В                  
  4,8    6,0  
 Усилие на валу   3,2 кг/см    4,1 кг/см   
 Скорость позиционирования     0,23 sec/60°    0,19 sec/60° 
 Размер, Д х Ш х В 41мм х 20мм х 36мм
 Масса, г37 

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

Управление

В качестве управляющего сигнала служит импульсный сигнал с периодом 20 мс и с длительностью от 0,8 до 2,2 мс. Это некий стандарт управления сервомашинок. Чем длинее пришел импульс, тем на больший угол повернется вал сервомашинки. Для разгона сервомашинки период следования импульсов можно уменьшить до 10 мс.

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


Программная часть

Как видно управлять сервой достаточно просто - достаточно гнать импульсный сигнал с нужной частотой и скважностью. Этот сигнал можно генериовать ШИМ, или написать свою функцию обработки прерывания по таймеру. Но в Bascom-AVR уже есть встроенная команда для управления сервомашинками - Servo. Ее и рассмотрим.
Для начала необходимо сконфигурировать подключение сервомашинок:

Config Servos = X , Servo1 = Portb., Servo2 = Portb., Reload = Var

Servos = X ;  указывается количество подключаемых сервомашинок, возможно подключение до 14 серв.

Servo1 = Portb.0 ; указывается порт подключения  первой сервы

Servo2 = Portb.1 ; указывается порт подключения  второй сервы

Reload = Var ; здесь   Var  время  в микросекундах, которое проходит между прерываниями от таймера.


По умолчанию для организации прерываний используется Timer0, поэтому использовать его в своих целях уже не получиться. Bascom-AVR позволяет перебросить обслуживание прерываний на любой другой таймер, например чтобы освободить Timer0 и задествовать Timer1 достаточно указать это в строке конфигурации:

Config Servos = 2, Servo1 = Portb., Servo2 = Portb., Reload = 10 , Timer = Timer1

После того как все сконфигурировали остается только рулить нашей сервомашинкой. Это делается следующей командой
Servo(a) = F

а - порядковый номер сервомашинки

F - переменная, значение которой задает угол поворота вала сервы

Тестовый код целиком:

$regfile = "m8def.dat"                                   'микроконтроллер ATmega8
$crystal = 8000000                                       'частота работы 8МГц

'конфигурируем порты для подключения сервоприводов
Config Portb.= Output
Config Portb.= Output

'настраиваем подключения двух сервомашинок
Config Servos = 2 , Servo1 = Portb., Servo2 = Portb., Reload = 15

Dim F As Byte                                            'переменная для первой сервы
Dim S As Byte                                            'переменная для второй сервы

'разрешаем прерывания
Enable Interrupts

= 15                 'значением переменной задается угол поворота вала сервомашинки
= 70

Do

Servo(1) = F
Servo(2) = S

Loop

End

Схему подключения не привожу, думаю один сигнальный провод проблем не вызовет ;) Его можно подключать к порту микроконтроллера напрямую, а можно через резистор сопротивлением пару сотен ом - для перестраховки.
Меняя значения перемменных F и S можем менять угол поворота первой и второй сервомашинок соответственно. Чем меньше значение параметра Reload, тем шустрее наши сервомашинки будут поворачиваться на нужный угол.
Для своих серв подобрал рабочий диапазон значений Servo(a), в которых вал может вращаться. Крайнее положения вал занимает при значении 0 и 150, соответственно при значении 75 вал занимает промежуточное положение.
Servo(a) =0  Servo(a) =75  Servo(a) =150

Servo(a) =0
Servo(a) =75
Servo(a) =150

к началу статьи


Генерация ШИМ в STM32

В предыдущей статье про базовые таймеры, мы в очередной раз мигали светодиодами, а в этот раз пойдем гораздо дальше и попробуем вкурить как заставить контроллер STM32 генерировать ШИМ. Для этого нам придётся использовать один из таймеров общего назначения, ведь именно у них есть всё что для этого нужно. Весь остальной функционал этих таймеров конечно впечатляет, но в моей практике он пока не пригодился. Хотя возможно, что в будущем мне пригодятся такие полезные фичи как функция подсчёта внешних импульсов и возможность аппаратно обрабатывать повороты энкодера. Но пока займемся ШИМом. Есть вот такая схема из контроллера, трех резисторов и RGB светодиода которым мы будем управлять. Управление заключается в том, чтоб плавно зажечь и погасить каждый цвет. Разумеется можно взять три разных светодиода если нет RGB.

Мы подключили светодиод к этим выводам не случайно. Таймеры общего назначения могут генерировать ШИМ только на определённых ножках. Поскольку мы будем использовать таймер 2, то в нашем распоряжении есть 4 ноги (PA0-PA3). Чтоб таймер мог их использовать нужно разрешить это аж в двух местах: Настроить три ноги (PA1-PA3) как выход с альтернативной функцией и разрешить в настройках таймера дергать эти ноги для генерации ШИМа. Для этого нам потребуется регистр CCER

Если установить в единицу один из битов выделенных синим цветом, то таймеру будет позволено использовать для ШИМа соответствующую ногу. Из схемы видно, что нам потребуется установить биты CC2E, CC3E и CC4E. Теперь нам нужно настроить режим ШИМа: Прямой или инверсный (я не претендую на правильность терминологии). Разница вполне очевидна - при прямом ШИМе чем больше число в регистре сравнения - тем больше коэффициент заполнения ШИМа. В случае инверсного ШИМа все наоборот. Записали ноль в регистр сравнения - коэффициент заполнения 100%. Для выбора режима используются два регистра CCMR1 и CCMR2:

На настройку каждого канала выделяется аж по 8 бит! Но к счастью нам интересны только три бита OCxM[2:0] которые я отметил синим. То что отмечено серым - это те же самые биты но с другим названием, они используются если канал таймера работает в режиме захвата. Рассматривать все комбинации битов я не буду, так как большинство из них к ШИМу отношения не имеют. Нам потребуются только две комбинации бит:

OCxM2

OCxM1

OCxM0

Режим

1

1

0

Прямой ШИМ

1

1

1

Инверсный ШИМ


RGB светодиод у меня с общим катодом и поэтому я использую инверсный ШИМ. Таким образом нам следует установить все три бита OCxM для трех каналов на которых висят светодиоды. И это всё! Настройка ШИМа закончена, теперь нужно только запустить таймер установив бит CEN в регистре CR1. Для управления скважностью просто пишем число от 0x0000 до 0xFFFF в регистры CCRx, где x номер канала. Собственно следующий код реализует то что было задумано в начале этой статьи: Наращивает яркость светодиода а потом снижает её до нуля и переходит к следующему. Процесс повторяется бесконечно, смотрится красиво :)

#include "stm32f10x.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_rcc.h"
void delay(void) {
  volatile uint32_t i;
    for (i=1; i != 0xF000; i++);
  }
 
int main()
{
  //Включем порт А
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA , ENABLE);
  //Включаем Таймер 2
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
 
  GPIO_InitTypeDef PORT;
  // Настроим ноги со светодиодами на выход
  PORT.GPIO_Pin = (GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3);
  //Будем использовать альтернативный режим а не обычный GPIO
  PORT.GPIO_Mode = GPIO_Mode_AF_PP;
  PORT.GPIO_Speed = GPIO_Speed_2MHz;
  GPIO_Init(GPIOA, &PORT);
  //Разрешаем таймеру использовать ноги PA1,PA2,PA3 для ШИМа
  TIM2->CCER |= (TIM_CCER_CC2E|TIM_CCER_CC3E|TIM_CCER_CC4E);
  // Для всех трех каналов задаем инверсный ШИМ.
  TIM2->CCMR1|=(TIM_CCMR1_OC2M_0| TIM_CCMR1_OC2M_1 | TIM_CCMR1_OC2M_2);
  TIM2->CCMR2|=(TIM_CCMR2_OC3M_0 | TIM_CCMR2_OC3M_1 | TIM_CCMR2_OC3M_2 |
  TIM_CCMR2_OC4M_0 | TIM_CCMR2_OC4M_1 | TIM_CCMR2_OC4M_2);
  //Запускаем таймер!
  TIM2->CR1 |= TIM_CR1_CEN;
  //После этого пишем данные в TIM2->CCRx - и яркость светодиодов меняется
 
  uint32_t pwm_arr[]={0,0,6553,13107,19660,26214,32768,
                                  39321,45875,52428,58982,65535};
 
  uint8_t i;
  while(1)
  {
    for (i=1;i<=11;i++) {
        TIM2->CCR3=pwm_arr[i];
        delay();
    }
    for (i=11;i>=1;i--) {
      TIM2->CCR3=pwm_arr[i];
      delay();
    }
    for (i=1;i<=10;i++) {
      TIM2->CCR2=pwm_arr[i];
      delay();
    }
    for (i=11;i>=1;i--) {
      TIM2->CCR2=pwm_arr[i];
      delay();
    }
    for (i=1;i<=10;i++) {
      TIM2->CCR4=pwm_arr[i];
      delay();
    }
    for (i=11;i>=1;i--) {
      TIM2->CCR4=pwm_arr[i];
      delay();
    }
  }
}


к началу статьи


Управление множеством сервомашинок с pic16f628a

В этой статье будет рассмотрено, как управлять множеством сервомашинок с одного МК при помощи таймера TMR1. Также этими сервоприводами будем управлять с компьютера.


2 подключенных сервопривода

Идея

Идея в следующем: таймер отсчитывает такты на высокой частоте, при каждом такте переменная T увеличивается на 1 (подсчитывает такты). Эти такты формируют посылки для управления сервоприводами. В начале каждой посылки T=0 и на всех вывода, которые идут на сервомашинки, установлен высокий уровень сигнала. При каждом «тике таймера» значение переменной T сверяется с максимальным количеством тактов в посылке и со значениями количества тактов позиций всех сервоприводов, на совпавших приводах будет установлен низкий уровень сигнала. По достижению конца посылки, T обнулиться и на всех выходах будет установлен высокий уровень сигнала, т.е. текущая посылка будет завершена и начнётся всё с начала.


Посылки для сервоприводов

Все эти действия происходят в обработчике прерываний (по прерываниям от таймера), в фоне, и не мешают выполнению главной функции.

Посылка через COM порт


Вид посылки через COM порт

В примере в главной функции разместилась связь с компьютером через USART. Для облегчения работы и уменьшению размера посылки, но в небольшой ущерб количеству позиций валов сервоприводов, была выбрана одно байтовая посылка через COM порт. 6 младших бит в этом байте отвечают за положение вала, всего 64 позиции, старшие 2 бита отвечают за выбор одного из 4-х сервоприводов. 64 позиции – это 2,8 градуса для сервопривода со 180 градусным ходом вала, соответственно для 90 градусного шаг составит 1,4 градуса, для большинства задач этого вполне достаточно. Также в качестве индикации о приходе байта будет мигать светодиод.

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

Прошивка

В главной функции разместилась обработка посылки с последовательного порта.

if(RCIF)			//	Ожидание прихода байта
{
temp=getch_Usart();	//	Чтение байта
temp2=temp%64+20;	//	Вычисление положение вала (первые 6 разрядов)
switch(temp/64)		//	Выбор сервопривода (старшие 2 разряда)
{
case 0:T1=temp2;break; 	//Запись позиции вала 1 сервопривода
case 1:T2=temp2;break;
case 2:T3=temp2;break;
case 3:T4=temp2;break;
}
LED=40;				//	Мигнём светодиодом
LED_on();
}

Установки регистров для таймера выглядит следующим образом:

INTCON=0b10100000;//Глобальные прерывания и от TMR0 разрешены.
OPTION=0b00001000;

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

void interrupt isr(void)			//	Обработчик прерываний
{
if(T0IF)			//	Произошло прерывание по таймеру
{
T++;			//Увеличение счётчика
if(T==T1) 		//Сработка 1 сервопривода
{
ClrBit(BUF,7);//Низкий уровень сигнала на 1 серве
}
if(T==T2) 		//Сработка 2 сервопривода
{
ClrBit(BUF,6); //Низкий уровень сигнала на 2 серве
}
if(T==T3) 		//Сработка 3 сервопривода
{
ClrBit(BUF,5); //Низкий уровень сигнала на 3 серве
}
if(T==T4) 		 //Сработка 4 сервопривода
{
ClrBit(BUF,4); //Низкий уровень сигнала на 4 серве
}

if(T==600) 		//Конец посылки
{
BUF|=0xF0; 	//Высокие уровень логического сигнала на всех сервах
T=0; 		//Обнуление счётчика
}
PORTB=BUF; 	//Запись в порт
TMR0=180; 		//Установка начального значения 0 таймера
T0IF=0; 		//Обнуление флага
}
}

Программа на ПК

Для управлениями сервами с компьютера была написана небольшая программа.


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

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

Перейти к программе

Небольшое видео, демонстрирующее работу. К сожалению всего 2 сервопривода в наличие.

Видео

Плата


Схема

Питание платы производиться стабилизированными 5 вольтами. В схеме применена развязка цепи контроллера от сервоприводов с помощью диода шотки D1 и сглаживающего конденсатора C1. Плата при работе сервоприводов может потреблять ток до 0,8 А и больше, в зависимости от используемых сервоприводов и их количества. При больших токах ёмкость входного конденсатора C2 следует увеличить.


Печатка

Печатная плата содержит микроконтроллер PIC16F628A, MAX232 и разъём DB-9M для согласования уровней USART для связи с компьютером через COM порт и обвязку. Для связи с компьютером нужен 0-модемный кабель. Можно подключить по USB, для этого понадобиться COM-USB переходник.

Одно из возможных применений данной конструкции – управление камерой.

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

Скачать исходник, прошивку и печатку



к началу статьи


Смотрите также:
Конструирование часть_1

Комментарии

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



Яндекс.Метрика
© Все права защищены. Распространение и копирование запрещено. Разработано Maksimus. 2011г.