Как собрать квадрокоптер самому – простая инструкция для начинающих как сделать дрон на Ардуино своими руками

Как собрать квадрокоптер самому – простая инструкция для начинающих как сделать дрон на Ардуино своими руками Мультикоптеры

На что обратить внимание?

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

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

Arduino дрон

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

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

Digitrode

Управлять квадрокоптером – это веселое и интересное занятие. Интереснее может быть только создание своей системы управления такой игрушкой на базе какой-нибудь популярной платформы, например, Arduino. Чем и занялся энтузиаст под ником Dzl. Первым делом он разобрал пульт дистанционного управления для того, чтобы посмотреть, какая радиосистема в нем используется.

Внутри, как и ожидалось, была пара дешевых печатных плат с небольшим количеством компонентов на них.

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

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

Благодаря «прослушке» с помощью Arduino UNO стал понятен порядок инициализации и режим связи. имеется порядок инициализации.

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

1. Пульт передает свой уникальный сетевой адрес или ID

2. Квадрокоптер принимает эту передачу, подтверждает ее и начинает прослушивать канал с данными от этого ID

3. После подтверждения пульт начинает передавать пакеты данных каждые 20 мс

Можно управлять одновременно несколькими квадрокоптерами, назначив им разные адреса. Передача ID проходит по одному фиксированному каналу, и данные передаются по одному из 12 случайных каналов. Квадрокоптеры автоматически сканируют радиоканалы, пока не найдут данные.

Данные передаются в пакете, состоящем из 8 байт, в следующем формате:

Байт 0 = throttle (газ) 0-255 Байт 1 =Yaw (рыскание) 0-255 Байт 2 =Yaw_trim (подстройка Yaw) 0-128 Байт 3 = Pitch (тангаж) 0-255 Байт 4 = Roll (крен) 0-255 Байт 5 = Pitch_trim (подстройка Pitch) 0-128 Байт 6 = Roll_trim (подстройка Roll) 0-128 Байт 7 = Fly/run 0=fly, 16=run

Затем была создана базовая станция, которая должна связываться квадрокоптерами. В качестве модулей использовались RFM-70, содержащие ту же микросхему BK2421. Следует отметить, что выводы BK2421 толерантны к 5 В, поэтому дополнительные резисторы для 3.3 В можно не ставить.

Для подключения одного и более квадрокоптеров к Arduino была написана специальная библиотека. Эта библиотека должна работать с любыми платами Arduino на базе чипов ATMEGA88 — ATMEGA328P. И в конце видео работы:

Код пид-регулятора:

float ERR[10] = {0,0,0,0,0,0,0,0,0,0};                 // Определяем массив последних ошибок
                                                       //
void loop(){                                           //
     i  ;     if( i>=10 ){ i=0; }                      // Переходим к следующему элементу массива «ERR»
     ERR[i] = bum.getErrPID();                         // Получаем текущую ошибку
     SUM    = 0; for( auto a:ERR ){ SUM =a; }          // Получаем сумму последних ошибок
     P      = ERR[i]            * kP;                  // Определяем пропорциональную составляющую регулятора
     I      = SUM               * kI;                  // Определяем интегральную составляющую регулятора
     D      = ( ERR[i]-ERR[j] ) * kD;                  // Определяем дифференциальную составляющую регулятора
     PID    = P   I   D;                               // Получаем результат ПИД-регулятора
     j      = i;                                       // Сохраняем номер элемента массива «ERR» в котором хранится текущая ошибка,
}                                                      // на следующем проходе цикла она станет предыдущей ошибкой
  • До цикла определяем массив ERR для хранения 10 последних ошибок;
  • Предполагается, что остальные переменные кода также объявлены;
  • Первая строка цикла увеличивает значение i на 1, со сбросом в 0 при достижении 10;
  • Вторая строка сохраняет текущую ошибку в элемент ERR[i];
  • Третьей строкой мы получаем в переменную SUM сумму последних 10 ошибок;
  • Следующие три строки определяют составляющие ПИД регулятора;
  • Предпоследняя строка получает результат PID как сумму составляющих P I D;
  • Последней строкой значение i сохраняется в j. Значит, при каждом новом проходе цикла элемент ERR[i] хранит текущую ошибку, а ERR[j]  хранит предыдущую ошибку.

Настройка пид-регулятора:

  • Настройка ПИД-регулятора сводится к поиску коэффициентов для пропорциональной, интегральной и дифференциальной составляющих.
  • Сброс любого из коэффициентов в 0 приводит к отключению его составляющей:
    • Спрос kP в ПИД-регуляторе приведёт к получению ИД-регулятора;
    • Спрос kI в ПИД-регуляторе приведёт к получению ПД-регулятора;
    • Спрос kD в ПИД-регуляторе приведёт к получению ПИ-регулятора.
  • Получаем П-регулятор, сбросив в 0 коэффициенты kI и kD.
  • Подбираем значение kP, при котором бампер машины или не покидает линию трассы на всех её поворотах, или находится как можно ближе к линии на поворотах. При этом машина может “вилять” на прямых участках трассы — это нормально. Во время настройки допускается немного снизить скорость машины, но её прийдётся вновь повысить в следующем пункте.
  • Постепенно увеличиваем значение kD, получая ПД-регулятор. При этом машина будет всё меньше “вилять” на прямых участках трассы и лучше проходить крутые повороты:
    • Слишком высокий kD приведёт к тому, что машина начнёт “дрожать” на прямой линии;
    • Слишком низкий kD не избавит от “виляний” машины на прямых участках и не улучшит прохождение крутых поворотов;
    • Оптимальным является kD, при котором бампер машины не покидает линию на всех поворотах трассы. При этом машина не “виляет” и не “дрожит” на прямых участках;
    • После настройки kD можно снизить kP, если это не ухудшит движение машины;
  • Постепенно увеличиваем значение kI, получая ПИД-регулятор, уменьшая отклонение центра бампера от центра линии как на прямых участках трассы, так и на поворотах:
    • Слишком высокий kI похож на перерегулировку kP — машина начнёт “вилять”;
    • В процессе настройки kI можно снизить подобранные ранее kP и kD.
  • Коэффициенты kP, kI и kD являются константами, только если машина движется с одной скоростью.
  • Обычно kD > kP, так как разность ошибок меньше одной ошибки, значит, коэффициент больше.
  • Обычно kI < kP, так как сумма ошибок больше одной ошибки, значит, коэффициент меньше.

Немного теории

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

Перемещение дрона на Arduino и любом другом контролере осуществляется за счет изменения трех параметров:

Первый параметр определяет угол наклона вверх или вниз передней части квадрокоптера, позволяя выполнить снижение или подъем дрона. Крен определяет угол наклона, когда правая часть оказывает ниже или выше левой. Рыскание определяет угол поворота квадрокоптера Arduino вокруг вертикальной оси, проходящей через его центр тяжести, обеспечивая дрону поворот в горизонтальной плоскости на нужный угол.

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

ARDUINO

В итоге плата Arduino дает широкие возможности для создания различных гаджетов, среди которых дрон лишь один из примеров.

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

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

Не потребует Arduino и наличия при сборке паяльника, так как вполне можно обойтись макетной доской и набором перемычек, что одновременно упрощает работу, позволяет быстро исправить какие-то недочеты и ошибки при сборке.

Общие сведения о пид-регуляторе:

В прошлом уроке мы разобрались с работой ПД-регулятора.

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

Недостатком П-регулятора является то, что он не может работать на больших скоростях.

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

Дифференциальная составляющая (от лат. differentia – разность) — это разность между текущей и предыдущей ошибкой.

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

Чем выше скорость изменения ошибки, тем сильнее влияние Д-регулятора.

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

Смотрите про коптеры:  Помогите с роботами! :: Stellaris General Discussions

Недостатком Д-регулятора является его чувствительность к шумам (некорректным данным).

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

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

Интегральная составляющая(от лат. integra – составной) — это сумма нескольких последних ошибок.

Количество ошибок в сумме определяет скорость реакции И-регулятора:

  • Малое количество ошибок приведёт к тому, что их сумма будет мала для воздействия;
  • Большое количество ошибок придаст воздействию существенную инерционность;
  • В примере ниже мы будем использовать сумму из 10 последних ошибок.

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

И-регулятор помогает ПД-регулятору выровнять центр бампера с центром линии как на прямых участках, так и на поворотах.

Пример: представим, что машина едет по дуге, и бампер выдаёт ошибку 0,5. П-регулятор слабо доворачивает вправо, — этого хватает для движения по линии, но ошибка сохраняется на прежнем уровне до завершения поворота. Значит, весь путь центр бампера был смещён от центра линии.

Пример: предположим, что на линии трассы появилась царапина, — это будет шумом для Д-регулятора, который резко среагирует, и машина “дёрнется” на линии. Но И-регулятор сгладит воздействие Д-регулятора, так как изменение всего 1 из 10 ошибок является незначительным.

Относительно дешевый quadcopter на arduino с управлением от телефона, планшета, пк

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

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

Ноутбук или компьютер с Processing[/b], скачать можно от сюда. Что такое “Processing”? Вот, что пишет об этом википедия :

Processing — открытый язык программирования, основанный на Java. Представляет собой лёгкий и быстрый инструментарий для людей, которые хотят программировать изображения, анимацию и интерфейсы.Используется студентами, художниками, дизайнерами, исследователями и любителями, для изучения, прототипирования и производства. Он создан для изучения основ компьютерного программирования в визуальном контексте и служит альбомным программным обеспечением (имеется в виду то, что каждый *.pde файл визуальной оболочки Processing’а представляет собой отдельное изображение или анимацию, и т. д.) и профессиональным производственным инструментом.

Arduino Software (IDE)[/b]
Андроид-устройство[/b], которое поддерживает режимUSB-хоста[/b](проверено на MotorolaXoom.
А так же паяльник, прямые руки, ножницы.

Что надо для изготовления рамы

Рама квадрокоптер делается из бамбуковых шашлычных палочек

Крепления двигателей к раме делаются из палочек для коктейля.

Изолента- используется для крепления платы приемника, электродвигателей к раме. Нитки нужны для скрепления деталей перед склейкой. Цианакриловый клей. Резинка для крепления аккумулятора к раме.

Список электроники для квадрокоптера.

Все эти детали могут быть повреждены во время пробных запусков или во время полетов, поэтому заказывайте с запасом. Ссылки даны для примера. Есть много поставщиков.
Лопасти для вертолета
Двигатели. Я не нашел двигатели с размерами 4х7 мм на Алиэкспресс нашел вот такие. Моторы должны быть без щеточные.

Плата приемника эта плата содержит все компоненты- гироскоп, акселометр, ESC (система курсовой устойчивости), CPU который все эти компоненты объединяет. Литий полимерный аккумулятор:1 x 240mah 1S ‘LiPo. Можно использовать разные аккумуляторы с меньшей или большей емкости. Если вы решите построить октакоптер, то вам понадобиться более емкая батарея.

Список аппаратного контроля квадрокоптера.

Это те части вашего будущего вертолета, которые позволят ему принимать ваши команды.
Приемопередатчик Учтите что в комплекте должны быть два модуля. И это не тоже самое что NRF24L01, что бы ни утверждал продаван.

Arduino DUE[/b]или аналогичный, он будет использоваться для связи вашего Андроид-устройства и A7105. Автор использовал именно эту плату Arduino потому, что она имеет USB подключенный к последовательному порту и может работать с 3.3в логикой, хотя можно применить преобразователь уровней 5-3.3в.

Макетная плата-на ней вы будете монтировать радио модуль и подключать его к Arduino. Резистор 22кОм- значение его не особо критично. Провода для соединения радио модуля. OTG переходник для вашего андроид устройства.

OTG
Hubsan-пульт дистанционного управления-это не обязательно, но удобно.

Создание каркаса.

Каркас изготавливается из бамбуковых палочек, скрепленных крест на крест с трубочками от коктейлей. Все это склеивается вместе супер клеем.
1: Распечатайте шаблон SVG в прикрепленном файле. Он сложнее, чем должен быть, но также используется для строительства октокоптера. Шаблон нужен, чтобы сделать правильный квадрат.

2. Отрежьте нитку по длине вашего предплечья.

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

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

5. Возьмите еще две палочки для канапе и закрепите их как в предыдущем шаге , только на расстоянии 4 пальцев от ранее прикрепленных. Точное расстояние не важно, вы исправите его далее.

6. Положите шаблон на ровную поверхность, лучше использовать стекло.

7. Разместите ваши связанные вместе палочки, как показано на фото.

На данном этапе важно все сделать как можно точно. Квадрокоптеры не очень чувствительны к распределению веса, но если ваши моторы не будут направлены вертикально, вертолет будет не очень хорошо летать, так что проверьте все два раза. Чтобы крепления моторов были строго вертикальными, а все диагонали одинаковыми.

8 Пропитайте все ваши нити, связывающие палочки, супер клеем. Надо пропитать нити насквозь, стремитесь не сдвигать при этом ваш каркас. Подождите 2 минуты и переверните ваш шаблон, чтобы пропитать нитки клеем с обратной стороны. Еще через две минуты первая квадратный кронштейн будет готов готова.

9. Повторите все тоже самое для второго кронштейна.

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

11. Обрежьте палочки примерно на длину 2 см с обеих сторон.

12. Отрежьте 4 палочки по 1.5 см , склейте их вместе квадратом, особо прочная склейка не нужна, это будет кронштейн для платы и батареи питания.

Следующий этап состоит из пайки ваших 4 моторов к плате 4Х приемника. Первое, что надо – это припаять провода питания на нижнюю часть платы. Далее мы будем ссылаться на эту ориентацию (плата лежит на “спине”)

Как подключать моторы.

На Hubsan х 4 платах есть контактные площадки для подключения светодиодов и моторов. Те, что для светодиодов имеют обозначение LED, туда НЕНАДО подключать моторы. Контакты для моторов помечены ve[/b]и–ve.[/b]

Возьмите один из ваших 4 моторов с черным и белым проводами и припаяйте их кЛЕВЫМ НИЖНИМ[/b]контактам платы, белым проводом к левому контакту пары. Возьмите мотор с красным и синим проводами и припаяйте его кЛЕВЫМ ВЕРХНИМ[/b]контактам, красным проводом к левому контакту пары.. Возьмите мотор с черными и белыми проводами и припаяйте их кПРАВЫМ ВЕРХНИМ[/b]контактам, черным проводом к левому контакту. Возьмите мотор с красным и синим проводами и припаяйте его кПРАВЫМ НИЖНИМ[/b]контактам, красным проводом к левому контакту пары.

В схеме подключения белый провод это черная пунктирная линия. Провода надо закрепить каплей горячего клея. Закрепите моторы двумя полосками изоленты шириной 5мм. Не стоит особо волноваться по поводу одинакового расположения моторов по высоте. После того,как моторы закреплены, надо надеть на оси пропеллеры. Используйте белый пропеллер для “переда”с противоположной стороны от проводов батареи) и чёрный пропеллер для”зада”. Это не так просто, как кажется, так. как одни лопасти сделаны для вращения по часовой стрелке, а другие , для вращения против часовой стрелки. На лопастях есть обозначения. Используйте лопасти с буквой “А[/b]” для левого верхнего и правого нижнего моторов. С буквой “В[/b]”, соответственно, для правого верхнего и левого нижнего моторов. Теперь вы можете прикрепить батарею к нижней части платы, автор использует для этой части резинку. Если у вас есть оригинальный hubsan контроллер, вы сможете поднять квадро в воздух. Если вертолёт трясёт в воздухе, значит, моторы стоят не строго вертикально. Подкладывая кусочки свернутой бумаги, можно выравнять моторы.

Сборка радиоуправления на arduino.

Этот пункт проекта расскажет как управлять вертолетом с помощью Андроид устройства,через последовательный порт Arduino.

Вам нужны 6 контактов на плате А7105. Слева GND. Справа-SDIO, SCK, SCS, GND, VCC.

Припаяйте жесткий одножильный провод, длиной 2 см, к каждому указанному выводу. Вставьте А7105 в макетную плату, так как показано на фото. Соедините выводы GND на плате arduino и два на А7105. Соедините вывод 3.3V на Arduino c выводом VCC на плате А7105. На разъеме SPI Arduino, соедините вывод MOSI с одним из выводов резистора , другой конец резистора соедините с пином SIDO на А7501.

Смотрите про коптеры:  Как сделать из лего машину - пошаговое описание как собрать машину из конструктора LEGO

По этой ссылке можно посмотреть где находится вывод MOSI
Вывод SCK Arduino c выводом SCK А7105 , SCS с платы А7105 на пин 10 Arduino . Синий резистор на фото не является частью проекта.

Arduino софт

Нижеследующий скетч использует хакнутую версию PhracturedBlue’s hubsan X4 и A7105 оригинал кода можно посмотреть здесь.

Подключить Ваш DUO к компьютеру через ‘Programming Port’. Скачайте зип фаил, загрузите скетч в Arduino и выгрузите его в DUO. Этот скетч обрабатывает команды с последовательного порта и преобразует их в команды платы управления вашего квадрокоптера. Этот скетч связывается с платой Hubsan по радио без последовательного порта, так что, если включите ваш коптер, а затем Arduino, и огни на коптере перестанут моргать, значит все в порядке.

Программное обеспечение для Андроид

Это программноеобеспечениедает вам простой контролер полета на базе андроид устройства. Для управления используется акселерометр и сенсорный экран вашего устройства. Планшет или телефон будет обмениваться данными с Arduino через порт USB.

Установка софта:
1 Надо разрешить отладку по USB и разрешить установку приложений не google play. Скачать приложение можно здесь
2Подключитесвое устройство через переходник OTG к Arduino, он будетзапитыватьсяот вашего телефона или планшета, поэтому проверьте, чтобы аккумулятор был полностью заряжен.
3 Подключите аккумулятор к коптеру и положите его на плоскую поверхность. Если огни перестали моргать, значит все в порядке.
4 Большой палец левой руки медленно сдвиньте по экрану, пропеллеры должны начать вращаться. Уберите палец и пропеллеры остановятся.
5 Проделайте все тоже самое, только разместите большой палец правой руки тоже на экране. Это позволит вам управлять вертолетом с помощью акселерометра, наклоняя ваше устройство вперед/назад, влево/вправо. Перемещая большой палец правой руки влево или вправо, вы будете закручивать вертолет влево или вправо вокруг оси. Если убрать правую руку с экрана, вертолет должен выровняться, не зависимо от положения акселерометра. Попробуйте. Перемещайте палец левой руки до тех пор, пока вертолет не взлетит. Помните – если убрать оба пальца- моторы остановятся.

Программное обеспечение для ПК
В архиве программа, которая управляет коптером через последовательный порт. Управляется коптер с помощью курсорных кнопок, и кнопок “A”/”Z”- дроссель. Автор сделал попытку заставить следовать коптер за объектом определенного цвета, но это пока не работает. Обещал выкладывать обновления.

Пример

Остальные примеры смотри в examples!

/*   Пример работы ПИД регулятора в автоматическом режиме по встроенному таймеру   Давайте представим, что на 3 пине у нас спираль нагрева, подключенная через мосфет,   управляем ШИМ сигналом   И есть какой то абстрактный датчик температуры, на который влияет спираль*/// перед подключением библиотеки можно добавить настройки:// сделает часть вычислений целочисленными, что чуть (совсем чуть!) ускорит код// #define PID_INTEGER// режим, при котором интегральная составляющая суммируется только в пределах указанного количества значений// #define PID_INTEGRAL_WINDOW 50
#include"GyverPID.h"

GyverPID regulator(0.1, 0.05, 0.01, 10);  // коэф. П, коэф. И, коэф. Д, период дискретизации dt (мс)// или так:// GyverPID regulator(0.1, 0.05, 0.01);	// можно П, И, Д, без dt, dt будет по умолч. 100 мсvoidsetup() {
  regulator.setDirection(NORMAL); // направление регулирования (NORMAL/REVERSE). ПО УМОЛЧАНИЮ СТОИТ NORMAL
  regulator.setLimits(, 255);    // пределы (ставим для 8 битного ШИМ). ПО УМОЛЧАНИЮ СТОЯТ 0 И 255
  regulator.setpoint = 50;        // сообщаем регулятору температуру, которую он должен поддерживать// в процессе работы можно менять коэффициенты
  regulator.Kp = 5.2;
  regulator.Ki  = 0.5;
  regulator.Kd = ;
}

voidloop() {
  int temp;                 // читаем с датчика температуру
  regulator.input = temp;   // сообщаем регулятору текущую температуру// getResultTimer возвращает значение для управляющего устройства// (после вызова можно получать это значение как regulator.output)// обновление происходит по встроенному таймеру на millis()analogWrite(3, regulator.getResultTimer());  // отправляем на мосфет// .getResultTimer() по сути возвращает regulator.output
}

Скетч для диапазона скоростей:

В предыдущем скетче все коэффициенты были найдены для скорости 60%. Если уменьшить скорость движения машины speed с 60% до 30%, то найденные ранее коэффициенты будут слишком велики, и мы получим перерегулирование.

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

Теперь можно написать скетч, у которого скорость можно менять от 20 до 60%:

#include <Wire.h>                                 // Подключаем библиотеку для работы с аппаратной шиной I2C
#include <iarduino_I2C_Motor.h>                   // Подключаем библиотеку для работы с мотором I2C-flash
#include <iarduino_I2C_Bumper.h>                  // Подключаем библиотеку для работы с бампером I2C-flash
                                                  //
iarduino_I2C_Motor mot_R (0x0A);                  // Объявляем объект mot_R для правого мотора, указав адрес модуля на шине I2C
iarduino_I2C_Motor mot_L (0x0B);                  // Объявляем объект mot_L для правого мотора, указав адрес модуля на шине I2C
iarduino_I2C_Bumper bum(0x0C);                    // Объявляем объект bum  для работы с бампером I2C-flash, указав адрес модуля на шине I2C
                                                  //
float   speed   = 60;                             // Скорость машины в %.
float   kP      = 3   0.125*(speed-20);           // Коэффициент пропорциональной составляющей
float   kI      = 0.1;                            // Коэффициент интегральной составляющей
float   kD      = speed*speed/250;                // Коэффициент дифференциальной составляющей
float   ERR[10] = {0,0,0,0,0,0,0,0,0,0};          // Определяем массив последних ошибок
uint8_t i;                                        // Объявляем переменную, указывающую на элемент массива «ERR», который хранит текущую ошибку
                                                  //
void setup(){                                     //
     mot_R.begin();                               // Инициируем работу с левым  мотором I2C-flash
     mot_L.begin();                               // Инициируем работу с правым мотором I2C-flash
     bum.begin();                                 // Инициируем работу с бампером I2C-flash
     mot_R.setDirection(true);                    // Указываем правому мотору, что его вращение должно быть прямым (по часовой стрелке при положительных скоростях)
     mot_L.setDirection(false);                   // Указываем левому мотору, что его вращение должно быть обратным (против часовой стрелки при положительных скоростях)
}                                                 //
                                                  //
void loop(){                                      //
           i  ;     if( i>=10 ){ i=0; }           // Переходим к следующему элементу массива «ERR»
           ERR[i] = bum.getErrPID();              // Получаем текущую ошибку
     float SUM    = 0; for(auto j:ERR){SUM =j;}   // Получаем сумму последних ошибок
     float P      = ERR[i]                 * kP;  // Определяем пропорциональную составляющую регулятора
     float I      = SUM                    * kI;  // Определяем интегральную составляющую регулятора
     float D      = (ERR[i]-ERR[(i 9)]) * kD;  // Определяем дифференциальную составляющую регулятора
     float PID    = P   I   D;                    // Получаем результат ПИД-регулятора
     mot_R.setSpeed( speed - PID, MOT_PWM );      // Устанавливаем скорость правого мотора
     mot_L.setSpeed( speed   PID, MOT_PWM );      // Устанавливаем скорость левого  мотора
}

Этот скетч отличается от предыдущего только тем, что значения kP и kD определены не числами, а формулами.

При изменении значений скорости speed в пределах от 20% до 60%, будут автоматически пересчитываться коэффициенты kP и kD, и машина продолжит корректно двигаться по линии

Итак, мы получили ПИД-регулятор — зачастую самый оптимальный способ регулирования. При грамотной настройке можно добиться невероятно точной и в то же время быстрой езды. Обязательно “поиграйтесь” с коэффициентами, если Вы этого еще не делали.

Скетч для одной скорости:

Скорость колёс в скетче задаётся функцией setSpeed() в процентах.Выберем скорость машины, равную 60%. Именно эту скорость мы и указываем обоим колёсам.Предположим, что при kI = 0, kD = 0, kP = 8 машина не покидает повороты трассы.

#include <Wire.h>                                 // Подключаем библиотеку для работы с аппаратной шиной I2C
#include <iarduino_I2C_Motor.h>                   // Подключаем библиотеку для работы с мотором  I2C-flash
#include <iarduino_I2C_Bumper.h>                  // Подключаем библиотеку для работы с бампером I2C-flash
                                                  //
iarduino_I2C_Motor mot_R (0x0A);                  // Объявляем объект mot_R для правого мотора, указав адрес модуля на шине I2C
iarduino_I2C_Motor mot_L (0x0B);                  // Объявляем объект mot_L для правого мотора, указав адрес модуля на шине I2C
iarduino_I2C_Bumper bum(0x0C);                    // Объявляем объект bum  для работы с бампером I2C-flash, указав адрес модуля на шине I2C
                                                  //
float   speed   = 60;                             // Скорость машины в %
float   kP      = 8;                              // Коэффициент пропорциональной составляющей
float   kI      = 0.1;                            // Коэффициент интегральной составляющей
float   kD      = 14.4;                           // Коэффициент дифференциальной составляющей
float   ERR[10] = {0,0,0,0,0,0,0,0,0,0};          // Определяем массив последних ошибок
uint8_t i;                                        // Объявляем переменную указывающую на элемент массива «ERR» хранящий текущую ошибку
                                                  //
void setup(){                                     //
     mot_R.begin();                               // Инициируем работу с левым  мотором I2C-flash
     mot_L.begin();                               // Инициируем работу с правым мотором I2C-flash
     bum.begin();                                 // Инициируем работу с бампером I2C-flash
     mot_R.setDirection(true);                    // Указываем правому мотору, что его вращение должно быть прямым (по часовой стрелке при положительных скоростях)
     mot_L.setDirection(false);                   // Указываем левому мотору, что его вращение должно быть обратным (против часовой стрелки при положительных скоростях)
}                                                 //
                                                  //
void loop(){                                      //
           i  ;     if( i>=10 ){ i=0; }           // Переходим к следующему элементу массива «ERR»
           ERR[i] = bum.getErrPID();              // Получаем текущую ошибку
     float SUM    = 0; for(auto j:ERR){SUM =j;}   // Получаем сумму последних ошибок
     float P      = ERR[i]                 * kP;  // Определяем пропорциональную составляющую регулятора
     float I      = SUM                    * kI;  // Определяем интегральную составляющую регулятора
     float D      = (ERR[i]-ERR[(i 9)]) * kD;  // Определяем дифференциальную составляющую регулятора
     float PID    = P   I   D;                    // Получаем результат ПИД-регулятора
     mot_R.setSpeed( speed - PID, MOT_PWM );      // Устанавливаем скорость правого мотора
     mot_L.setSpeed( speed   PID, MOT_PWM );      // Устанавливаем скорость левого  мотора
}

Немного пояснений к кодуloop():

  • Текущая ошибка сохраняется в элемент ERR[i];
  • Цикл for(auto j:ERR) проходит по всем элементам массива ERR, копируя их значения в переменную j. В теле цикла выполняется суммирование всех значений в SUM;
  • Запись ERR[(i 9)] равносильна записи ERR[i-1] , только при i=0 получим ERR[9]. Эта запись позволяет получить предыдущую ошибку.

Уроки ардуино. разработка пид-регулятора скорости вращения двигателя постоянного тока. | оборудование, технологии, разработки

ПИД-регулятор

Проверим измеритель скорости вращения на реальном двигателе, управляя им без обратной связи. Разработаем ПИД-регулятор стабилизации скорости вращения.

Предыдущий урок     Список уроков     Следующий урок

В предыдущем уроке мы научились измерять период импульсов дискретного сигнала. Теперь мы можем определить скорость вращения двигателя, используя сигнал с датчика Холла.

Смотрите про коптеры:  Комплект для сборки DJI F450 ARF KIT (обзор, видео, фото), цена 15590 руб

Измерение скорости вращения двигателя.

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

Программа позволяет регулировать скорость вращения мотора с помощью ШИМ, без обратной связи. Кроме того она измеряет скорость и выводит ее значение в последовательный порт.

Вычисление скорости происходит в строке:

Serial.print( 60000000. / ((float)tempPeriodTime * 0.0625 * NUM_PULS_REV));

  • 60000000. – это минута, переведенная в микросекунды;
  • tempPeriodTime * 0.0625 – реальное время периода импульсов на выходе датчика Холла;
  • NUM_PULS_REV – число импульсов на один оборот.

Загружаем, запускаем монитор последовательного порта.

Монитор

Вместо датчика у нас к выводу 8 подключен тестовый сигнал (вывод 5). На нем формируются импульсы с периодом примерно 10 мс, что соответствует скорости 3000 об/мин. Убеждаемся, что программа показывает такое значение скорости. Вращением переменного резистора проверяем, что ШИМ регулируется во всем диапазоне.

Подключаем к выводу 8 датчик Холла и подаем питание 12 В.

Монитор

Скорость вращения мотора изменяется переменным резистором, измеритель показывает правильную скорость.

Но ШИМ стабильно держится на значении 200, а скорость все время “дергается” в небольших пределах. Логично предположить, что я не смог приклеить постоянные магниты на абсолютно одинаковом расстоянии друг от друга. А значит, время прохождения одного магнита под датчиком отличается от другого. В результате два соседних импульса датчика Холла имеют разные периоды.

Давайте усредним период для двух соседних импульсов.

Если раньше при стабильном ШИМ равном 200 скорость “прыгала” от 2305 до 2357, то после усреднения диапазон изменений стал значительно уже 2310…2312.

Монитор

Это всего 0,09 %, или ± 0,045 %.

Определяем, в каком диапазоне скоростей работает наш мотор. У меня двигатель равномерно вращается, начиная со скорости 300 об/мин. Его максимальная скорость вращения немногим более 2600 об/мин. Эти параметры потребуются в следующем разделе.

Теперь у нас есть все, чтобы стабилизировать скорость вращения двигателя.

Разработка ПИД-регулятора скорости вращения.

Кто не знает, что такое ПИД-регулятор убедительно советую прочитать урок 40.Он полностью посвящен пропорционально-интегрально-дифференцирующим регуляторам.  Еще надо  просмотреть начало урока 39. Там есть раздел ”Общие сведения о регуляторах”.

Скажу только, что в нашем устройстве:

  • регулируемый параметр – это измеренная скорость;
  • регулирующий элемент – значение ШИМ.

Вот окончательный скетч устройства.

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

  • В основном цикле loop() происходит измерение напряжения на аналоговом входе A0, усреднение его значения и вычисления заданной скорости.

Константа NUM_AVERAGE_ADC задает количество выборок для усреднения, а значит и инерционность реакции на изменение заданной скорости.

Полный диапазон задатчика скорости – напряжения на выводе A0 масштабируется в диапазон допустимых скоростей регулятора. При изменении напряжения в диапазоне 0…5 В, заданная скорость меняется в диапазоне, определенном константами  MIN_VELOCITY …  MAX_VELOCITY (минимальное и максимальное значения скорости).

setVelocity= MIN_VELOCITY (MAX_VELOCITY – MIN_VELOCITY) * (float)averageAdc / NUM_AVERAGE_ADC / 1023.;

  • В обработчике прерывания по переполнению таймера 1 вырабатывается признак остановки двигателя flagVelZerro.

if( numOverflowTimer1 > periodTimeStop ) flagVelZerro= true;

Если таймер 1 переполнился заранее рассчитанное количество раз (periodTimeStop), то это означает, что в течение соответствующего времени с датчика Холла не пришел ни один импульс. Время, при котором двигатель считается остановленным, рассчитывается исходя из константы ZERRO_VELOCITY.

// вычисление периода импульсов остановленного двигателя
periodTimeStop= 14648 / NUM_PULS_REV / (unsigned long)ZERRO_VELOCITY;

  • Если двигатель вращается (flagVelZerro != true), то в основном цикле вычисляется измеренная скорость.

measuredVelocity= 60000000. / ( (float)averageVel / NUM_AVERAGE_VEL * 0.0625 * NUM_PULS_REV);

Число выборок для усреднения измеренной скорости определяется константой NUM_AVERAGE_VEL. При готовом результате формируется признак flagVel.

  • При остановленном двигателе (flagVelZerro == true) искусственно вырабатывается признак  flagVel= true;. Это необходимо для того, чтобы ПИД-регулятор работал при остановленном двигателе. Что-то же должно начинать его крутить.
  • В основном цикле проверяется состояние сигнала включения (вывод PIN_ON). Если работа мотора запрещена, то программный блок ПИД-регулятора пробрасывается. Запрещается работа ШИМ и интегральное звено устанавливается на начальное значение (константа INT_BEGIN).
  • Блок собственно ПИД-регулятора вызывается при условии, что:
    • разрешена работа двигателя;
    • рассчитана новая измеренная скорость
    • с предыдущего вызова прошло время не менее REG_TIME мс.

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

  • Математика самого регулятора полностью повторяет формулы из учебников.
  • В основном цикле с периодом, заданным константой DISPLAY_TIME, в последовательный порт выводятся: заданная и измеренная скорости, период импульсов датчика Холла и значение ШИМ.

Основное по программе все.

Проверка работы ПИД-регулятора на тестовом сигнале.

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

Отключим питание 12 В, отключим датчик Холла от 8 вывода, соединим 8 и 5 выводы. Т.е. подадим на вход измерения скорости тестовый сигнал.

Загрузим программу в плату.

Подадим разрешающий сигнал на вывод PIN_ON.

Проверяем, что:

  • Заданная скорость меняется вращением переменного резистора в пределах 300 … 2600.
  • Измеренная скорость определяется частотой тестового сигнала и равна 1500.

Выключаем интегральную часть. Пропорциональный коэффициент задаем равным 0,01.

#define K_P 0.01 // пропорциональный коэффициент
#define K_I 0.  // интегральный коэффициент

Загружаем скетч в плату, открываем монитор последовательного порта.

Устанавливаем заданную скорость больше измеренной и проверяем, что:

ШИМ = начальное значение интегрального звена (заданная скорость – измеренная скорость) * пропорциональный коэффициент.

Монитор

В моем случае ШИМ = 25 (2217 – 1500) * 0,01 = 32

Проверяем тоже самое для заданной скорости меньше измеренной.

Монитор

В моем случае ШИМ = 25 (1100 – 1505) * 0,01 = 21

Проверяем интегральное звено. Отключаем пропорциональную часть, интегральный коэффициент устанавливаем равным 0,001.

#define K_P 0. // пропорциональный коэффициент
#define K_I 0.001  // интегральный коэффициент

Загружаем, открываем монитор.

Устанавливаем заданное значение скорости 1600. Убеждаемся, что ШИМ нарастает начиная со значения 25 со скоростью 1 единица в сек. С учетом того, что в монитор данные выводятся каждые 0,2 сек, нарастание ШИМ на 1 должно происходить через каждые 5 строк.

Монитор

Поясню.

Ошибка рассогласования равна 1600 – 1500 = 100. За одну временную дискретность регулятора (0,1 сек) приращение = 100 * 0,001 = 0,1. Приращение 0,1 десять раз в секунду получается 1 в секунду.

Проверяем для отрицательного рассогласования. Задаем скорость равной 1400.

Монитор

Измеряемая скорость ”прыгает” потому, что программа разрослась и цикл loop() стал в значительных пределах изменять свою длительность. Период тестовых импульсов становиться все менее стабильным. Вот почему я стараюсь использовать для таких целей только прерывания по таймеру. Но таймеров у нас уже не осталось.

В принципе ПИД-регулятор работает. В следующем уроке будем настраивать работу с реальным двигателем. Я разработал для этого программу верхнего уровня с регистратором и графическим отображением параметров в реальном времени.

Предыдущий урок     Список уроков     Следующий урок

1

Шаг №1. делаем корпус

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

Обратим внимание, что желательно передние лучи или пропеллеры выполнить другим цветом.

Это позволит проще ориентироваться в пространстве и всегда понимать, где передняя часть дрона, чтобы быстрее им управлять в полете.

Квадрокоптер на Ардуино своими руками 3D

Если у вас нет доступа к 3D-принтеру, то альтернативой станет покупка уже готовых лучей в одном из интернет-магазинов. Еще одним вариантом станет изготовление корпуса из подручных средств. Например, раму можно изготовить из куска фанеры, а для лучей, удерживающих двигатели, подойдут пластиковые трубы.

Шаг №2. подключение arduino

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

  • VDD-3.3V;
  • GND-GND;
  • INT-digital2;
  • SCL-A5;
  • SDA-A4;
  • VIO-GND.

Подключение Arduino схема

Для питания платы MPU6050 Arduino допускается использование напряжения 3,3В, а если оно составит 5В, то произойдет выход из строя. На многих платах есть встроенный предохранитель, защищающий систему от повышенного напряжения, но рисковать мы не советуем.

Шаг №3. скетч для arduino

После подключения к Arduino платы MPU-6050 необходимо загрузить скетч I2C scanner code, куда вставляется код программы. Обратим внимание, что на этом этапе пригодятся хоть минимальные познания в программировании на Arduino, поэтому при отсутствии даже них стоит сделать небольшую паузу и разобраться с особенностями.

I2C scanner code для Arduino

Теперь откройте серийный монитор Arduino IDE (он находится в разделе Tools на вкладке Serial Monitors) и убедиться в наличии подключенного 9600. Если все предыдущие этапы были выполнены верно, то будет обнаружено устройство I2C с присвоенным адресом 0х69 или 0х68, который нужно записать.

Теперь можно загрузить один из скетчей, который будет постоянно обрабатывать информацию с акселерометра и гироскопа. В интернете подобных скетчей для Arduino достаточно много, поэтому выбирайте любой, но ориентируйтесь на отзывы пользователей. После скачивания подобного скетча проведите его разархивирование.

Теперь обязательно откройте файл MPU6050_DMP6. Если у вас был присвоен адрес 0х69, то обязательно нужно расскоментировать строку после #includes, так как по умолчанию присваивается 0х68. На этом этапе уже можно получить первые значения с гироскопа и акселерометра. Для этого загрузите программу и откройте с 115200 окно серийного монитора, следуя дальнейшим инструкциям.

Arduino гироскоп

После сборки квадрокоптера на Arduino нужно будет откалибровать параметры акселерометра и гироскопа. Для этого достаточно найти ровную плоскую поверхность и поставить на нее плату. Теперь достаточно запустить скетч для проведения калибровки, после которой имеющиеся отклонения записываться и учитываются в скетче MPU6050_DMP6.

Оцените статью
Радиокоптер.ру
Добавить комментарий

Adblock
detector