#8 Эксперимент “Управляемая авто-платформа”
На этом занятии мы научимся работать с сервоприводом – одним из самых востребованных электронных компонентов в робототехнике. В ходе нашего занятия мы соберём схему и запрограммируем механическую часть управляемой авто-платформы. Для управления авто-платформой будем использовать джойстик, который будет помогать нам управлять шаговым двигателем, как основным мотором платформы, и сервоприводом для осуществления поворотов колёс нашей платформы на нужный нам угол.
Перед выполнением эксперимента прочтите:
Шаговый двигатель – основа точной робототехники. В отличие от двигателей постоянного вращения, один оборот «шаговика» состоит из множества микроперемещений, которые и называют шагами. Другими словами, мы можем повернуть вал двигателя в любой заданный угол, и зафиксировать его в этом положении. Грубым аналогом шагового двигателя является сервопривод. В отличие от сервопривода, шаговый двигатель не имеет ограничений в повороте вала и может вращаться на 360º. Кроме этого, управляя шаговым двигателем, мы можем не только контролировать его положение, но и скорость.
Шаговым двигателем можно управлять напрямую, подавая цифровой или аналоговый сигнал на катушки двигателя, но для уменьшения количества кода, мы будем использовать встроенную в Arduino IDE библиотеку [stepper.h]. Эта библиотека разработана специально для управления шаговыми двигателями.
СБОРКА УСТРОЙСТВА НА МАКЕТНОЙ ПЛАТЕ
Нам понадобятся следующие компоненты:
- Arduino Uno;
- USB-кабель для подключения к компьютеру;
- Беспаечная макетная плата;
- Шаговый двигатель и его драйвер;
- Сервопривод;
- Джойстик;
- 10 соединительных проводов типа папа-мама различных цветов;
- 4 соединительных провода типа папа-папа различных цветов.
Соберите устройство по следующей схеме:
Схема устройства на макетной плате |
Принципиальная схема устройства |
Обратите внимание! Для облегчения сборки схемы, подключения всех пинов приведены в виде таблиц:
Подключение шагового двигателя | |
Пины драйвера шагового двигателя | Пины Arduino |
IN1 | pin 5 |
IN2 | pin 3 |
IN3 | pin 4 |
IN4 | pin 2 |
Пины IN2 и IN3 в таблице “перепутаны” намеренно, т.к. только при таком подключении шаговый двигатель имеет возможность вращаться не только по часовой стрелке, но и в обратном направлении.
Подключение Джойстика | |
Пины джойстика | Пины Arduino |
GND | GND |
+5V | +5V |
VRx | A0 |
VRy | A1 |
Пин SW джойстика, который позволяет получать сигнал кнопки на джойстике, мы в этом эксперименте задействовать не будем.
Подключение Сервопривода | |
Пины сервопривода | Пины Arduino |
Жёлтый (сигнальный) | pin 8 |
Красный (питание) | +5V |
Коричневый (земля) | GND |
Теперь, после того, как наша схема собрана, поставим задачу: нам необходимо собрать устройство, состоящее из шагового двигателя, сервопривода и джойстика. Устройство должно работать следующим образом:
- При перемещении джойстика вверх (по оси Y), вал шагового двигателя должен начинать вращаться по часовой стрелке;
- При перемещении джойстика вниз (по оси Y), вал шагового двигателя должен начинать вращаться против часовой стрелки;
- При перемещении джойстика влево (по оси X), вал сервопривода должен поворачиваться в положение 0º;
- При перемещении джойстика вправо (по оси X), вал сервопривода должен поворачиваться в положение 180º;
- Когда джойстик находится в центральном положении по всем осям, вал шагового двигателя должен быть неподвижен, а вал сервопривода должен находится в положении 90º.
ПРОГРАММИРОВАНИЕ
Для начала, давайте разберём основы работы с джойстиком. Джойстик – комбинированное устройство ввода, которое позволяет получать сигнал о положении стика и сигнал с кнопки (при нажатии на стик). Для этого, джойстик оснащён двумя потенциометрами, находящимися в одном корпусе. Один из потенциометров отвечает за горизонтальные перемещения джойстика. Сигнал с этого потенциометра принимает значение 0 в крайнем левом положении и 1023 в крайнем правом положении стика. Аналоговый сигнал с этого потенциометра можно снять с пина [VRx] джойстика.
Точно также обстоят дела и с перемещением стика по вертикали. В крайнем верхнем положении, с пина джойстика [VRy] можно снять нулевое значение аналогового сигнала, а в крайнем нижнем значение сигнала должно принять значение в 1023. К сожалению, из-за конструктивных особенностей таких джойстиков, очень редко получается снять как сигнал 0, так и сигнал 1023. Чаще всего минимальный и максимальный сигналы лежат в диапазоне [0…50] и [950…1023]. Давайте напишем программу, которая позволит нам пронаблюдать как изменяются сигналы с потенциометров джойстика в реальном времени:
void setup() { Serial.begin(9600); } void loop() { Serial.print(analogRead(A0)); // сигнал с "горизонтального" потенциометра Serial.print(" "); // пробел для разделения значений сигналов Serial.println(analogRead(A1)); // сигнал с "вертикального" потенциометра }
Для более удобного отображения сигнала в мониторе порта, можно воспользоваться плагином для Google Chrome, который называется Serial projector. Вы можете перейти по ссылке и установить данный плагин из магазина Chrome. Теперь, загрузите скетч программы в плату Arduino и запустите монитор порта. Двигая стик джойстика вы сможете наблюдать изменение значений сигналов с обоих потенциометров:
Стик джойстика находится в центральном положении |
Горизонтальный потенциометр в крайнем левом положении |
Вертикальный потенциометр в крайнем нижнем положении |
Давайте напишем скетч, который позволит управлять сервоприводом с помощью горизонтального потенциометра. Но сначала немного теории:
- Сигнал, который мы будем принимать с горизонтального потенциометра, приходит в порт A0 Arduino и лежит в диапазоне [0…1023];
- Вал сервопривода имеет ограничения по углу поворота, который лежит в диапазоне [0…180];
Как превратить сигнал с потенциометра [0…1023] в сигнал для сервопривода [0…180]? Очень просто, для этого нам понадобится команда [map]:
- map(volue, inmin, inmax, outmin, outmax);
- где volue – переменная значений, или источник сигнала; inmin – минимальное значение входящего сигнала; inmax – максимальное значение входящего сигнала; outmin – минимальное значение преобразованного сигнала; outmax – максимальное значение преобразованного сигнала.
Сигнал с пина A0 мы будем получать с помощью команды [analogRead(A0)]. Управлять сервоприводом мы будем с помощью команды [my_servo.write()]. Таким образом наша команда будет выглядеть так:
- my_servo.write(map(analogRead(A0), 0, 1023, 0, 180));
А скетч будет представлять собой следующее:
#include <Servo.h>; // подключаем библиотеку для управления сервоприводом Servo my_servo; // Объявляем переменную типа Servo void setup() { my_servo.attach(8); // инициализируем сервопривод на 8-м пине } void loop() { my_servo.write(map(analogRead(A0), 0, 1023, 0, 180)); // вращаем вал сервопривода }
В случае, если вал вращается в противоположную сторону, угол поворота можно легко инвертировать, добавив вместо команды [my_servo.write(map(analogRead(A0), 0, 1023, 0, 180));] команду [my_servo.write(180 – map(analogRead(A0), 0, 1023, 0, 180));].
Теперь, разберёмся с подключением шагового двигателя. Для того, чтобы управление двигателем было простым, мы воспользуемся встроенной библиотекой [Stepper.h]. Для корректной работы шагового двигателя, необходимо грамотно задать все необходимые параметры, такие как скорость вращения вала, количество шагов на один оборот и порядок подключения пинов драйвера двигателя к Arduino. В следующем скетче мы попробуем заставить двигатель вращаться по часовой и против часовой стрелки:
#include <Stepper.h> // подключаем библиотеку шагового двигателя const int IN1 = 2; // указываем пины, к которым подключён драйвер const int IN2 = 3; // при подключении, пины IN1 и IN4 "перепутаны" намеренно const int IN3 = 4; // только такое "неправильное подключение" позволит const int IN4 = 5; // шаговику вращаться в обе стороны const int stepsPerRevolution = 256; // шагов за один оборот вала Stepper myStepper(stepsPerRevolution, IN1, IN2, IN3, IN4); // инициализируем шаговик void setup() { myStepper.setSpeed(60); // скорость: около 60 оборотов вала в минуту } void loop() { myStepper.step(2048); // 2048 шагов против часовой стрелки delay(500); // пауза в 0,5 секунды myStepper.step(-2048); // 2048 шагов по часовой стрелке delay(500); // пауза в 0,5 секунды }
Пояснения к коду:
- Скорость в 60 об/мин является максимальной для данного типа сервоприводов (проверено практическим методом);
- Количество шагов на оборот можете выставлять по своему желанию, значение в 250-300 шагов, также является максимальным;
- Количество шагов двигателя существенно влияет на его скорость;
- Т.к. мотор оборудован редуктором с передаточным числом 8:1, следует понимать, что речь идёт об оборотах внутреннего вала мотора. Т.е. фактическая скорость оборота вала редуктора в 8 раз меньше и составляет 60/8=7,5 об/мин;
- При этом, количество шагов, необходимых для того, чтобы вал редуктора сделал полный оборот составляет 2048 шагов. Если в команде для поворота шаговика, вы зададите другое количество шагов, то вал редуктора вашего мотора повернётся на другой угол.
Теперь мы можем управлять вращением шагового двигателя. Давайте напишем программу, которая позволит управлять двигателем с помощью джойстика с точностью до 10 шагов:
#include <Stepper.h> // подключаем библиотеку шагового двигателя const int IN1 = 2; // указываем пины, к которым подключён драйвер const int IN2 = 3; // при подключении, пины IN1 и IN4 "перепутаны" намеренно const int IN3 = 4; // только такое "неправильное подключение" позволит const int IN4 = 5; // шаговику вращаться в обе стороны const int stepsPerRevolution = 256; // шагов за один оборот вала Stepper myStepper(stepsPerRevolution, IN1, IN2, IN3, IN4); // инициализируем шаговик void setup() { myStepper.setSpeed(60); // скорость: около 60 оборотов вала в минуту } void loop() { // если джойстик в верхнем положении, вращаем по часовой if (analogRead(A1)<100){myStepper.step(-10);} // если джойстик в нижнем положении, вращаем против часовой if (analogRead(A1)>900){myStepper.step(10);} }
Загрузите в Arduino данный скетч и попробуйте управлять нашим шаговым двигателем. Теперь мы можем закрепить наш шаговик на жёсткий каркас и с помощью ременных или шестерёночных передач, соединить его с колёсами. Тогда мы сможем управлять направлением движения нашей авто-платформой. Осталось добавить код для сервопривода, который будет управлять поворотом колёс:
#include <Servo.h>; // подключаем библиотеку для управления сервоприводом #include <Stepper.h> // подключаем библиотеку шагового двигателя const int IN1 = 2; // указываем пины, к которым подключён драйвер const int IN2 = 3; // при подключении, пины IN1 и IN4 "перепутаны" намеренно const int IN3 = 4; // только такое "неправильное подключение" позволит const int IN4 = 5; // шаговику вращаться в обе стороны const int stepsPerRevolution = 256; // шагов за один оборот вала Stepper myStepper(stepsPerRevolution, IN1, IN2, IN3, IN4); // инициализируем шаговик Servo my_servo; // Объявляем переменную типа Servo void setup() { myStepper.setSpeed(60); // скорость: около 60 оборотов вала в минуту my_servo.attach(8); // инициализируем сервопривод на 8-м пине } void loop() { // если джойстик в верхнем положении, вращаем по часовой if (analogRead(A1)<100){myStepper.step(-10);} // если джойстик в нижнем положении, вращаем против часовой if (analogRead(A1)>900){myStepper.step(10);} my_servo.write(180 - map(analogRead(A0), 0, 1023, 0, 180)); // вращаем вал сервопривода }
Загрузите программу в плату Arduino и проверьте устройство в работе.
ЗАДАНИЯ ДЛЯ САМОСТОЯТЕЛЬНОГО ВЫПОЛНЕНИЯ:
Задание 1:
Вернитесь к примеру для вращения двигателя по часовой и против часовой стрелки:
Измените количество шагов на один оборот в шаговом двигателе на 128. Посмотрите как изменилась работа устройства. Самостоятельно задайте такое количество шагов мотора, чтобы он сначала делал 1/2 оборота по часовой стрелке, а потом 1/4 против часовой.
Задание 2:
Заставьте ваш двигатель с помощью джойстика двигаться с разной скоростью. Чем больше вы отклоняете джойстик вверх, тем быстрее должен вращаться двигатель по часовой стрелке, а чем больше вы отклоняете джойстик вниз, тем быстрее он должен вращаться против часовой стрелки. В центральном положении стика, мотор должен быть неподвижен. Добейтесь того, чтобы на максимальной скорости, редуктор двигателя делал полный оборот ровно за 10 секунд. В качестве базовой программу, можете использовать программу ниже:
Задание 3*:
Подключите к Arduino датчик освещённости и увеличивайте скорость вращения шагового двигателя в зависимости от освещения. Чем светлее, тем быстрее вращается вал мотора.