- Выбор деталей для самобалансирующегося робота
- 3D-печать и сборка нашего самобалансирующегося робота
- Принципиальная электрическая схема
- Код самобалансирующегося робота
- Работа самобалансирующегося робота Arduino
Вдохновленный двигателями RYNO и другими самобалансирующимися самокатами от Segway, я всегда хотел построить что-то свое, своего собственного робота Arduino Segway. Поразмыслив, я решил создать самобалансирующегося робота на Arduino. Таким образом я смогу понять основную концепцию всех этих самокатов, а также узнать, как работает алгоритм PID.
Когда я начал создавать, я понял, что создать этого бота непросто. Существует так много вариантов выбора, и поэтому путаница начинается с правильного выбора двигателей и сохраняется до настройки значений ПИД. И нужно учитывать так много вещей, как тип аккумулятора, положение аккумулятора, сцепление колеса, тип привода двигателя, поддержание центра тяжести (центр тяжести) и многое другое.
Но позвольте мне рассказать вам об этом, как только вы его построите, вы согласитесь, что это не так сложно, как кажется. Итак, давайте посмотрим правде в глаза, в этом уроке я задокументирую свой опыт создания самобалансирующегося робота. Вы можете быть абсолютным новичком, который только начинает работать или, возможно, приземлились здесь после долгого разочарования из-за того, что ваш бот не заработал. Это место станет вашим последним пунктом назначения. Итак, приступим…
Выбор деталей для самобалансирующегося робота
Прежде чем я расскажу вам обо всех вариантах создания бота, позвольте мне перечислить элементы, которые я использовал в этом проекте самобалансирующегося робота.
- Arduino UNO
- Мотор-редукторы постоянного тока (желтого цвета) - 2 шт.
- Модуль драйвера двигателя L298N
- MPU6050
- Пара колес
- Литий-ионный аккумулятор 7,4 В
- Соединительные провода
- Тело с 3D-принтом
Вы можете смешивать и выбирать любой из вышеперечисленных компонентов в зависимости от наличия возможности создать собственный комплект самобалансирующегося робота, просто убедитесь, что компоненты соответствуют следующим критериям.
Контроллер: Контроллер, который я здесь использовал, - это Arduino UNO, потому что он прост в использовании. Вы также можете использовать Arduino Nano или Arduino mini, но я бы рекомендовал вам придерживаться UNO, поскольку мы можем программировать его напрямую, без какого-либо внешнего оборудования.
Двигатели: Лучшим выбором двигателя, который вы можете использовать для самобалансирующегося робота, без сомнения, будет шаговый двигатель. Но для простоты я использовал мотор-редуктор постоянного тока. Да, шаговый двигатель не является обязательным; бот также отлично работает с этими дешевыми общедоступными мотор-редукторами постоянного тока желтого цвета.
Драйвер двигателя: если вы выбрали мотор- редукторы постоянного тока, подобные моему, вы можете использовать модуль драйвера L298N, как я, или даже L293D должен работать нормально. Узнайте больше об управлении двигателем постоянного тока с помощью L293D и Arduino.
Колеса: Не недооценивайте этих ребят; Мне было трудно понять, что проблема была в моих колесах. Поэтому убедитесь, что ваши колеса хорошо сцепляются с полом, который вы используете. Внимательно следите, ваша хватка не должна позволять вашим колесам скользить по полу.
Акселерометр и гироскоп: лучшим выбором акселерометра и гироскопа для вашего бота будет MPU6050. Поэтому не пытайтесь создать его с помощью обычного акселерометра, такого как ADXL345 или чего-то подобного, он просто не сработает. Вы узнаете, почему, в конце этой статьи. Вы также можете ознакомиться с нашей специальной статьей об использовании MPU6050 с Arduino.
Батарея: нам нужна как можно более легкая батарея, а рабочее напряжение должно быть более 5 В, чтобы мы могли питать нашу Arduino напрямую без модуля повышения. Так что идеальным выбором будет литий-полимерный аккумулятор на 7,4 В. Здесь, поскольку у меня был под рукой литий-ионный аккумулятор 7,4 В, я использовал его. Но помните, что Li-po лучше, чем Li-ion.
Шасси: Еще одно место, где вы не должны идти на компромисс, - это шасси вашего бота. Вы можете использовать картон, дерево, пластик, все, что у вас хорошо получается. Но просто убедитесь, что шасси прочное и не должно покачиваться, когда бот пытается балансировать. Я спроектировал собственное шасси на Solidworks, основываясь на данных других ботов, и распечатал его на 3D-принтере. Если у вас есть принтер, вы также можете распечатать дизайн, файлы дизайна будут прикреплены в следующем заголовке.
3D-печать и сборка нашего самобалансирующегося робота
Если вы решили напечатать на 3D-принтере то же шасси, которое я использую для создания своего бота, то файлы STL можно загрузить из thingiverse. Я также добавил файлы дизайна вместе с ним, чтобы вы также могли изменить его в соответствии с предпочтениями персонала.
Детали не имеют нависающих структур, поэтому вы можете легко распечатать их без каких-либо опор, а заполнение 25% подойдет. Дизайн довольно прост, и любой базовый принтер должен легко справиться с этим. Я использовал программное обеспечение Cura, чтобы разрезать модель и распечатать ее с помощью своего Tevo Tarantula, настройки показаны ниже.
Вам нужно будет распечатать часть корпуса, а также четыре детали для крепления двигателя. Сборка довольно проста; используйте 3-миллиметровые гайки и болты, чтобы закрепить двигатель и платы на месте. После сборки он должен выглядеть примерно так, как показано на рисунке ниже.
Фактическая конструкция была запланирована с приводным модулем L298N в нижней стойке Arduino и батареей наверху, как показано выше. Если вы следуете тому же порядку, вы можете напрямую вкрутить плату через предусмотренные отверстия и использовать проводную бирку для Li-po батареи. Эта компоновка также должна работать, за исключением супер гладких колес, которые мне пришлось менять позже.
В моем боте я поменял местами аккумулятор и плату Arduino UNO для простоты программирования, а также должен был представить перфокарную плату для завершения соединений. Так что мой бот на начальном этапе выглядел не так, как я планировал. После завершения тестирования программирования проводки и всего остального, мой двухколесный робот, наконец, выглядит так
Принципиальная электрическая схема
Установить соединения для этого самобалансирующегося робота на базе Arduino довольно просто. Это самобалансирующийся робот, использующий Arduino и MPU6050, поэтому мы хотим связать MPU6050 с Arduino и подключать двигатели через модуль драйвера двигателя. Вся установка питается от литий-ионной батареи 7,4 В. Принципиальная схема для этого же показана ниже.
Модуль драйвера двигателя Arduino и L298N получает питание напрямую через контакты Vin и 12 В соответственно. Встроенный стабилизатор на плате Arduino преобразует входное напряжение 7,4 В в 5 В, и от него будут питаться микросхемы ATmega и MPU6050. Двигатели постоянного тока могут работать от 5 В до 12 В. Но мы будем подключать положительный провод 7,4 В от аккумулятора к входной клемме 12 В модуля драйвера двигателя. Это заставит двигатели работать с напряжением 7,4 В. В следующей таблице будет показано, как модуль драйвера двигателя MPU6050 и L298N подключен к Arduino.
Компонент Pin |
Штырь Arduino |
MPU6050 |
|
Vcc |
+ 5В |
Земля |
Gnd |
SCL |
A5 |
ПДД |
A4 |
INT |
D2 |
L298N |
|
В 1 |
D6 |
IN2 |
D9 |
IN3 |
D10 |
IN4 |
D11 |
MPU6050 взаимодействует с Arduino через интерфейс I2C, поэтому мы используем контакты SPI A4 и A5 Arduino. Двигатели постоянного тока подключаются к контактам D6, D9, D10 и D11 ШИМ соответственно. Нам нужно подключить их к контактам PWM, потому что мы будем контролировать скорость двигателя постоянного тока, изменяя рабочий цикл сигналов PWM. Если вы не знакомы с этими двумя компонентами, рекомендуется прочитать руководство по интерфейсу MPU6050 и драйверу двигателя L298N.
Код самобалансирующегося робота
Теперь нам нужно запрограммировать нашу плату Arduino UNO для балансировки робота. Здесь происходит вся магия; концепция, лежащая в основе этого, проста. Мы должны проверить, наклоняется ли бот вперед или назад, используя MPU6050, а затем, если он наклоняется вперед, мы должны повернуть колеса в прямом направлении, а если он наклоняется назад, мы должны повернуть колеса в обратном направлении.
В то же время мы также должны контролировать скорость вращения колес: если бот немного дезориентирован из центрального положения, колеса вращаются медленно, и скорость увеличивается по мере удаления от центрального положения. Для достижения этой логики мы используем алгоритм PID, который имеет центральное положение как уставку и уровень дезориентации как выход.
Чтобы узнать текущее положение бота, мы используем MPU6050, который представляет собой совмещенный 6-осевой акселерометр и датчик гироскопа. Чтобы получить надежное значение положения от датчика, нам необходимо использовать значение как акселерометра, так и гироскопа, потому что значения акселерометра имеют проблемы с шумом, а значения гироскопа имеют тенденцию дрейфовать со временем. Таким образом, мы должны объединить оба и получить значение угла рыскания и крена нашего робота, из которых мы будем использовать только значение рыскания.
Кажется, голова кружится, правда? Но не волнуйтесь, благодаря сообществу Arduino у нас есть легко доступные библиотеки, которые могут выполнять вычисление PID, а также получать значение рыскания от MPU6050. Библиотека разработана br3ttb и jrowberg соответственно. Прежде чем продолжить загрузку их библиотек, воспользуйтесь следующей ссылкой и добавьте их в каталог библиотек Arduino.
github.com/br3ttb/Arduino-PID-Library/blob/master/PID_v1.h
github.com/jrowberg/i2cdevlib/tree/master/Arduino/MPU6050
Теперь, когда у нас есть библиотеки, добавленные в нашу среду разработки Arduino. Приступим к программированию нашего самобалансирующегося робота. Как всегда, полный код балансировочного робота MPU6050 приведен в конце этой страницы, здесь я просто объясняю наиболее важные фрагменты кода. Как было сказано ранее, код построен поверх кода примера MPU6050, мы просто собираемся оптимизировать код для наших целей и добавить PID и технику управления для нашего самобалансирующегося робота.
Сначала мы включаем библиотеки, необходимые для работы этой программы. Они включают встроенную библиотеку I2C, библиотеку PID и библиотеку MPU6050, которую мы только что загрузили.
#include "I2Cdev.h" #include
Затем мы объявляем переменные, которые необходимы для получения данных от датчика MPU6050. Мы считываем значения вектора гравитации и кватерниона, а затем вычисляем значение угла рыскания и крена бота. YPR поплавок массив будет содержать конечный результат.
// переменные управления / состояния MPU bool dmpReady = false; // устанавливаем истину, если инициализация DMP прошла успешно uint8_t mpuIntStatus; // содержит текущий байт состояния прерывания из MPU uint8_t devStatus; // возвращаем статус после каждой операции с устройством (0 = успех,! 0 = ошибка) uint16_t packetSize; // ожидаемый размер пакета DMP (по умолчанию 42 байта) uint16_t fifoCount; // подсчет всех байтов в FIFO uint8_t fifoBuffer; // буфер хранения FIFO // переменные ориентации / движения Quaternion q; // контейнер кватернионов VectorFloat gravity; // вектор гравитации float ypr; // контейнер рыскания / тангажа / крена и вектор силы тяжести
Затем идет очень важный сегмент кода, и именно здесь вы будете долго настраивать правильный набор значений. Если ваш робот построен с очень хорошим центром тяжести и компоненты расположены симметрично (что в большинстве случаев не является), тогда значение вашей уставки будет 180. Или подключите своего бота к последовательному монитору Arduino и наклоните его до вы находите хорошее положение балансировки, считываете значение, отображаемое на последовательном мониторе, и это ваше заданное значение. Значения Kp, Kd и Ki должны быть настроены в соответствии с вашим ботом. Никакие два одинаковых бота не будут иметь одинаковые значения Kp, Kd и Ki, поэтому от них невозможно сбежать. Посмотрите видео в конце этой страницы, чтобы получить представление о том, как настроить эти значения.
/ ********* Настройте эти 4 значения для вашего BOT ********* / двойное заданное значение = 176; // устанавливаем значение, когда бот находится перпендикулярно земле с помощью последовательного монитора. // Прочтите документацию по проекту на сайте circuitdigest.com, чтобы узнать, как установить эти значения double Kp = 21; // Устанавливаем это первое двойное Kd = 0.8; // Устанавливаем этот второй двойной Ki = 140; // Наконец, устанавливаем это / ****** Конец установки значений ********* /
В следующей строке мы инициализируем алгоритм PID, передавая входные переменные input, output, setpoint, Kp, Ki и Kd. Из них мы уже установили значения уставок Kp, Ki и Kd в приведенном выше фрагменте кода. Значение входа будет текущим значением рыскания, считываемым датчиком MPU6050, а значение выхода будет значением, вычисленным алгоритмом PID. Таким образом, в основном алгоритм PID даст нам выходное значение, которое следует использовать для корректировки входного значения, чтобы оно было близко к заданному значению.
PID PID (& вход, & выход, & уставка, Kp, Ki, Kd, DIRECT);
Внутри функции настройки void мы инициализируем MPU6050, настраивая DMP (цифровой процессор движения). Это поможет нам объединить данные акселерометра с данными гироскопа и обеспечить надежное значение рыскания, тангажа и крена. Мы не будем углубляться в это, так как это выйдет далеко за рамки темы. В любом случае один сегмент кода, который вы должны искать в функции настройки, - это значения смещения гироскопа. Каждый датчик MPU6050 имеет свои собственные значения смещений. Вы можете использовать этот эскиз Arduino для расчета значения смещения вашего датчика и соответствующим образом обновить следующие строки в своей программе.
// укажите здесь свои собственные смещения гироскопа, масштабированные для минимальной чувствительности mpu.setXGyroOffset (220); mpu.setYGyroOffset (76); mpu.setZGyroOffset (-85); mpu.setZAccelOffset (1688);
Мы также должны инициализировать выводы цифрового ШИМ, которые мы используем для подключения наших двигателей. В нашем случае это D6, D9, D10 и D11. Поэтому мы инициализируем эти контакты, поскольку выходные контакты делают их по умолчанию НИЗКИМИ.
// Инициализируем выводы вывода двигателя pinMode (6, OUTPUT); pinMode (9, ВЫХОД); pinMode (10, ВЫХОД); pinMode (11, ВЫХОД); // По умолчанию выключаем оба мотора analogWrite (6, LOW); analogWrite (9, LOW); analogWrite (10, LOW); analogWrite (11, LOW);
Внутри функции основного цикла мы проверяем, готовы ли данные из MPU6050 к чтению. Если да, мы используем его для вычисления значения PID, а затем отображаем входное и выходное значение PID на последовательном мониторе, просто чтобы проверить, как PID реагирует. Затем на основе значения вывода мы решаем, должен ли бот двигаться вперед, назад или стоять на месте.
Поскольку мы предполагаем, что MPU6050 вернет 180, когда бот находится в вертикальном положении. Мы получим положительные значения коррекции, когда бот падает вперед, и мы получим отрицательные значения, если бот падает назад. Поэтому мы проверяем это условие и вызываем соответствующие функции для перемещения бота вперед или назад.
while (! mpuInterrupt && fifoCount <packetSize) { // нет данных mpu - выполнение вычислений PID и вывод в двигатели pid.Compute (); // Распечатываем значение ввода и вывода на последовательном мониторе, чтобы проверить, как оно работает. Serial.print (ввод); Serial.print ("=>"); Serial.println (вывод); if (input> 150 && input <200) {// Если бот падает if (output> 0) // падает вперед Forward (); // Повернуть колеса вперед else if (output <0) // Падение назад Reverse (); // Повернуть колеса назад } else // Если бот не падает Stop (); // Удерживайте колеса неподвижно }
Выходная переменная PID также определяет, насколько быстро двигатель должен вращаться. Если бот вот-вот упадет, мы делаем небольшую поправку, медленно вращая колесо. Если эти незначительные исправления не работают, но бот все равно падает, мы увеличиваем скорость двигателя. Значение скорости вращения колес будет определять алгоритм PI. Обратите внимание, что для функции Reverse мы умножили значение output на -1, чтобы мы могли преобразовать отрицательное значение в положительное.
void Forward () // Код для поворота колеса вперед { analogWrite (6, output); analogWrite (9,0); analogWrite (10, вывод); analogWrite (11,0); Serial.print («F»); // Отладочная информация } void Reverse () // Код для поворота колеса назад { analogWrite (6,0); analogWrite (9, вывод * -1); analogWrite (10,0); analogWrite (11, вывод * -1); Serial.print («R»); } void Stop () // Код для остановки обоих колес { analogWrite (6,0); analogWrite (9,0); analogWrite (10,0); analogWrite (11,0); Serial.print ("S"); }
Работа самобалансирующегося робота Arduino
Когда вы будете готовы с оборудованием, вы можете загрузить код на свою плату Arduino. Убедитесь, что соединения выполнены правильно, поскольку мы используем литий-ионный аккумулятор, поэтому необходима особая осторожность. Поэтому дважды проверьте наличие короткого замыкания и убедитесь, что клеммы не соприкасаются, даже если ваш бот получит небольшие удары. Включите модуль и откройте монитор последовательного порта. Если ваш Arduino может успешно взаимодействовать с MPU6050 и все работает должным образом, вы должны увидеть следующий экран.
Здесь мы видим входные и выходные значения алгоритма PID в формате input => output . Если бот идеально сбалансирован, значение вывода будет равно 0. Входное значение - это текущее значение датчика MPU6050. Буква «F» означает, что бот движется вперед, а буква «R» означает, что бот движется назад.
На начальных этапах PID я рекомендую оставлять кабель Arduino подключенным к боту, чтобы вы могли легко контролировать значения ввода и вывода, а также было легко исправить и загрузить вашу программу для значений Kp, Ki и Kd. На видео ниже показана полная работа бота, а также показано, как исправить значения PID.
Надеюсь, это поможет создать собственного самобалансирующегося робота, если у вас возникнут проблемы с его работой, тогда оставляйте свои вопросы в разделе комментариев ниже или используйте форумы для получения дополнительных технических вопросов. Если вы хотите получить больше удовольствия, вы также можете использовать ту же логику для создания робота, балансирующего мяч.