Вы находитесь на странице: 1из 24

Создание гаджетов

на Arduino
Урок № 11

Рисующий робот

Содержание
Рисующий робот............................................................. 3
Сервопривод....................................................................... 6
Двигатель постоянного тока......................................... 10
Потенциометр.................................................................. 19

Материалы урока прикреплены к данному PDF-файлу. Для досту-


па к материалам, урок необходимо открыть в программе Adobe
Acrobat Reader.

2
Рисующий робот

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

Рисунок 1
Именно для таких задач необходимы различные мо-
торы. Для машинки будем использовать много различных
компонентов, и даже шилд для управления моторами!
Сначала нужно подготовить корпус для нашей ма-
шинки (рис. 2-3).

3
Урок № 11

Рисунок 2

Рисунок 3
Он может быть выполнен из пластика, дерева или обыч-
ного картона. Стоит лишь убедиться, что конструкция
достаточно крепкая, и выдержит большое количество
компонентов, которые будут расположены на платформе
(рис. 4-5).

4
Рисующий робот

Рисунок 4

Рисунок 5

5
Урок № 11

Сервопривод
Начнем с того, что познакомимся с сервоприводом.
Серво — это устройство, которое может поворачивать-
ся в заданное положение. Такие компоненты позволя-
ют роботу двигать конечностями, поднимать предметы
или фиксировать определенные элементы (рис. 6).

Рисунок 6
Главная задача сервопривода — поворот на заданный
угол и удерживание определенного положения. Устрой-
ство может поворачиваться на 180˚, а управлять им и по-
ворачивать его в нужную позицию можно с помощью
Arduino (рис. 7).
В сервомотор встроено все: двигатель, цепь обратной
связи и, самое главное, драйвер двигателя. Для работы
ему нужны напряжение, заземление и один управляющий
контакт. Определить, где какой пин, можно по цвету со-

6
Рисующий робот

единений. Коричневый соответствует GND, на красный


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

Рисунок 7

Рисунок 8
Подключаем библиотеку для управления сервопри-
водом:
#include <Servo.h>

7
Урок № 11

Определим пин, к которому подключен серво:


#define SERVO_MOTOR 5

Для управления сервоприводом нужно создать объект:


Servo myservo;

Также в программе понадобятся переменные. Servo­


Angle — это будет угол, на который разворачивается
сервопривод, а gameStatus — это мод игры, то есть то,
что должен делать робот:
int servoAngle = 90;
int gameStatus = 0;

Напишем функцию и установим режим работы серво:


void setup() {
Serial.begin(9600);
myservo.attach(SERVO_MOTOR);
myservo.write(servoAngle);
delay(1000);
}

В этой функции мы соединили объект myservo с пином


SERVO_MOTOR. После этого подали сигнал, чтобы повер-
нуть механизм на угол servoAngle, то есть на 90 градусов.
Затем переходим к циклу программы. Пока у нас есть
только один мод игры, вот его и настроим:
void loop() {
switch (gameStatus) {
case 0:

8
Рисующий робот

startDraw();
break;
//case 1:
// break;
}
}

Напишем функцию для управления сервоприводом.


Чтобы выполнить вращение, нужно передать значение
для управления приводом. Для сервопривода это угол
от 0 до 180. Передать это значение нужно в функцию
myservo.write():

void drawLeft() {
for (int i = 0; i <= 90; i += 1) {
if (i <= 45) {
servoAngle += 1;
}
else {
servoAngle -= 1;
}
myservo.write(servoAngle);
delay(15);
}
}

void drawRight() {
for (int i = 0; i <= 90; i += 1) {
if (i <= 45) {
servoAngle -= 1;
}
else {
servoAngle += 1;
}
myservo.write(servoAngle);

9
Урок № 11

delay(15);
}
}

В программе, чтобы активировать работу сервопри-


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

void startDraw() {
Serial.print("Angle: ");
Serial.println(servoAngle);
drawLeft();
drawRight();
// gameStatus = 1;
}

Отлично, теперь сервопривод выполняет вращения.


Пока не будем менять мод игры, поскольку наш робот умеет
лишь управлять сервоприводом. Как только добавим но-
вые компоненты и функции, сможем использовать строку
//gameStatus = 1, которая пока что закомментирована.
Двигатель постоянного тока
Двигатели — неотъемлемая часть робототехники. Без
двигателей невозможно реализовать механизм вращения
лопастей или колес. Двигатели постоянного тока (DC
Motors) — одни из самых простых и популярных видов
(рис. 9).
Управлять такими двигателями можно напрямую, без
дополнительных компонентов. Но такой подход доста-
точно сложно применить на практике. Для управления
двигателями постоянного тока используют драйвера дви-
гателей, и один из самых популярных — L293D (рис. 10).

10
Рисующий робот

Рисунок 9

Рисунок 10
На микроконтроллере L293D расположено 16 пинов.
Нумерация выводов производится строго против часо-
вой стрелки, а первый элемент находится возле выемки
на микроконтроллере (рис. 11).

11
Урок № 11

Рисунок 11
Подключим два двигателя постоянного тока, драйвер
мотора и аккумуляторную батарею 9V (рис. 12).

Рисунок 12
Мы подключили к пинам Output 1, Output 2 выхо-
ды одного двигателя, а к Output 3 и Output 4 — выходы
другого (рис. 13).

12
Рисующий робот

Рисунок 13
На реальной схеме нужно будет еще присоединить
колесо к двигателю (рис. 14).

Рисунок 14

13
Урок № 11

Теперь вернемся к нашей программе, и с помощью


инструкции #define определим константы для номеров
пинов:

#define PIN_ENA 6
#define PIN_IN1 7
#define PIN_IN2 8
#define PIN_IN3 9
#define PIN_IN4 10
#define PIN_ENB 11

Создадим константу. Ее будем использовать в качестве


скорости движения робота:
const int speed = 255;

Кроме того, создадим переменную, в которой будет


храниться длительность ожидания в миллисекундах:
const int waitTime = 3000;

Создаем два массива с пинами, к которыми подклю-


чены моторы:

const int pinMotorA[3] = {PIN_ENA, PIN_IN1, PIN_IN2};


const int pinMotorB[3] = {PIN_ENB, PIN_IN3, PIN_IN4};

Обязательно установим режим работы пинов. Для


этого добавим код в функцию setup():

void setup() {
...
...

14
Рисующий робот

pinMode(PIN_IN1, OUTPUT);
pinMode(PIN_IN2, OUTPUT);
pinMode(PIN_ENA, OUTPUT);
pinMode(PIN_IN3, OUTPUT);
pinMode(PIN_IN4, OUTPUT);
pinMode(PIN_ENB, OUTPUT);

delay(1000);
}

Мы запрограммируем новый мод игры. Добавим


в цикл название новой функции, которую позже напишем:

void loop() {
switch (gameStatus) {
case 0:
startDraw();
break;
case 1:
moveRobot();
break;
}
}

Теперь, как только сервопривод сделает несколько


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

void moveForward(const int pinMotor[3], int speed) {


digitalWrite(pinMotor[1], HIGH);
digitalWrite(pinMotor[2], LOW);
analogWrite(pinMotor[0], speed);
}

15
Урок № 11

void moveBackward(const int pinMotor[3], int speed) {


digitalWrite(pinMotor[1], LOW);
digitalWrite(pinMotor[2], HIGH);
analogWrite(pinMotor[0], speed);
}

Добавим функцию, которая будет полностью оста-


навливать моторы:

void fullStop(const int pinMotor[3]) {


digitalWrite(pinMotor[1], LOW);
digitalWrite(pinMotor[2], LOW);
analogWrite(pinMotor[0], 0);
}

Далее запрограммируем движение робота. Он должен


ехать вперед, назад и выполнять повороты вправо и влево:

void moveRobot() {
Serial.print("F ");
moveForward(pinMotorA, speed);
moveForward(pinMotorB, speed);
delay(waitTime);

Serial.print("R ");
moveForward(pinMotorA, speed); // move right
moveForward(pinMotorB, (speed / 2));
delay(waitTime);

Serial.print("B ");
moveBackward(pinMotorA, speed);
moveBackward(pinMotorB, speed);
delay(waitTime);
Serial.print("L ");

16
Рисующий робот

moveForward(pinMotorA, (speed / 2));


moveForward(pinMotorB, speed); // move left
delay(waitTime);
fullStop(pinMotorA);
fullStop(pinMotorB);
Serial.println();
gameStatus = 0;
}

Теперь более детально рассмотрим функцию move­


Robot(). Движение вперед и назад реализованы с помощью
функций moveForward() и moveBackward(). Самая инте-
ресная часть программы — программирование поворота.
Чтобы робот повернул направо, нужно подать на правое
колесо меньшую скорость, чем на левое, например, в два
раза меньше (рис. 15).

Рисунок 15

17
Урок № 11

Чтобы запрограммировать поворот налево, наобо-


рот, следует подать меньшую скорость на левое колесо
(рис. 16).

Рисунок 16
Чтобы программа работала правильно, раскоммен-
тируем строку gameStatus:

void startDraw() {
...
...
gameStatus = 1;
}

Запустим проект. Все работает, а робот уже может


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

18
Рисующий робот

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

Рисунок 17
Давайте ознакомимся с работой потенциометра и будем
использовать его для управления скоростью вращения
двигателей. При повороте вала (управляющего элемен-
та) на потенциометре меняется сопротивление. То есть
в результате сигнал передается с измененным значением.
Плата Arduino оснащена конвектором, который мо-
жет преобразовывать аналоговое значение в цифровое.
В результате потенциометр вернет значение от 0 до 1023.
Если вал полностью повернуть в одну сторону, на пин по-
ступит значение равное 0, то есть напряжение, равное 0V.
Если вал полностью повернуть в другую сторону, на пин
поступит значение равное 1023 или напряжение в 5V.

19
Урок № 11

Добавим потенциометр и подключим его к пину A0


(рис. 18).

Рисунок 18
Добавим в программу код для управления потенци-
ометром. Сначала определим константу:
#define PIN_POT A0

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


рость — это константа:
//const int speed = 255;

Теперь скорость — это переменная, которая будет


зависеть от сигнала с потенциометра:
int speed;

Установим режим работы пина. Добавим в код лишь


одну строку кода перед ожиданием delay():

20
Рисующий робот

void setup() {
...
...
pinMode(PIN_POT, INPUT);

delay(1000);
}

С потенциометра программа может получить число от


0 до 1023. Если оно будет равно 0, то нет смысла запускать
программу, потому что тогда скорость моторов будет
нулевая. И еще раз немного изменим код внутри цикла,
чтобы управлять скоростью моторов с потенциометра:

void loop() {
int value = analogRead(PIN_POT);
Serial.print("Value: ");
Serial.println(value);
if (value > 0) {
speed = map(value, 0, 1023, 0, 255);
Serial.print("Speed: ");
Serial.println(speed);
switch (gameStatus) {
case 0:
...
case 1:
...
}
}
}

Итак, в цикле в переменную value записываем значение


от 0 до 1023. Если оно больше 0, то переходим к основ-
ному циклу программы, иначе цикл снова повторяется.

21
Урок № 11

В функции loop() мы используем функцию map(), чтобы


конвертировать числа из одного представления в другое.
Как вы помните, потенциометр может возвращать числа
от 0 до 1023. В то время как на моторы можем подавать
числа от 0 до 255. Чтобы преобразовать целые числа из од-
ного представления в другое, используем функцию map().
Первый ее параметр — это значение, которое будет пре-
образовывать. Второй и третий параметры — это верхняя
и нижняя границы числа, которое поступает, то есть от
0 до 1023. Последние два числа — это верхняя и нижняя
границы нового диапазона, к которому приводим число.
Наконец, программа готова. Можем запустить ее
в эмуляторе. Если все работает корректно, собираем ро-
бота и загружаем код на плату Arduino (рис. 19).

Рисунок 19
Каким в результате будет ваш робот, зависит только
от фантазии и комплектации. Это может быть необычный
механизм или удивительная конструкция. Более того,
мы с помощью кода мы самостоятельно задаем рисунок,
который воссоздаст робот (рис. 20-21).
22
Рисующий робот

Рисунок 20

Рисунок 21

23
Урок № 11
Рисующий робот

© Компьютерная Академия «Шаг»


www.itstep.org

Все права на охраняемые авторским правом фото-, аудио- и видеопро-


изведения, фрагменты которых использованы в материале, принадле-
жат их законным владельцам. Фрагменты произведений используются
в иллюстративных целях в объёме, оправданном поставленной задачей,
в рамках учебного процесса и в учебных целях, в соответствии со ст. 1274
ч. 4 ГК РФ и ст. 21 и 23 Закона Украины «Про авторське право і суміжні
права». Объём и способ цитируемых произведений соответствует
принятым нормам, не наносит ущерба нормальному использованию
объектов авторского права и не ущемляет законные интересы автора
и правообладателей. Цитируемые фрагменты произведений на момент
использования не могут быть заменены альтернативными, не охраня-
емыми авторским правом аналогами, и как таковые соответствуют
критериям добросовестного использования и честного использования.
Все права защищены. Полное или частичное копирование материалов
запрещено. Согласование использования произведений или их фраг-
ментов производится с авторами и правообладателями. Согласованное
использование материалов возможно только при указании источника.
Ответственность за несанкционированное копирование и коммерческое
использование материалов определяется действующим законодатель-
ством Украины.

Вам также может понравиться