Сборка полноценного RC-самолета на Arduino с нуля
В этом уроке покажу, как построил Arduino-управляемый RC-самолет и как управлять им самодельным Arduino-передатчиком из прошлого видео.
Смотрите видео или читайте ниже.
Обзор
Самолет полностью из пенопласта (Styrofoam). Формы резал на своем DIY станке с ЧПУ для резки пенопласта (показывал ранее). Хотя использую ЧПУ, это 100% DIY — сам ЧПУ тоже DIY.
Управление — 100% DIY: Arduino + модуль NRF24L01 для радиосвязи.

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

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

И главное — самолет летает.
Проектирование RC-самолета — 3D-модель
Начал в Fusion 360. Ориентировался на коммерческие RC-модели и базовые правила проектирования.

Старт — размах крыла 80 см. Длина фюзеляжа — обычно 75% размаха. Профиль крыла — CLARK Y, популярен для RC.

Скачал профиль с airfoiltools.com (.SVG), импортировал в Fusion 360. Скорректировал размер: хорда крыла ~1/5 размаха.

Горизонтальное и вертикальное оперение — по тем же правилам. Базовые параметры:

Фюзеляж: два бока 10 мм + сердечник 50 мм (полый, под электронику).
3D-модель по ссылкам выше. Две версии: v1 (на фото), v2 — меньше нос, мотор вперед для лучшего обдува.
Генерация G-кода для DIY ЧПУ резака пенопласта
Рабочая зона ЧПУ 45 см, фюзеляж 60 см → фюзеляж в две части.

Резал фюзеляж на 34 см от носа, новый эскиз с проекцией формы и точкой рядом. Во вкладке Manufacture Fusion 360 генерирую G-код.

Новый Setup: эскиз как модель, добавленная точка — начало координат, оси X/Y настроены. Операция 2D Contour, инструмент Ø3 мм (размер реза горячего нити). Скорость подачи 150 мм/мин (зависит от нити и пенопласта).

Geometry: выбираю контур. Heights: всё 1 мм (нет Z-на моем резаке). Linking: Entry Position — край у начала координат.

Симуляция: траектория — замкнутый контур, один проход. Пост-процессор: GRBL, папка, имя файла, Post.

Сохраняю, вижу G-код в WordPad.

Загружаю в Universal G-code Sender, отправляю на ЧПУ.

Процесс не идеален/не профи, но работает для моего DIY ЧПУ. Подробнее про ЧПУ — в отдельном уроке (ссылка в описании видео).
Скачать G-код файлы:
Борта — пенопласт 1 см, сердечник — 5 см.

Крыло — пенопласт 10 см, резал ~30 см ширины (макс. захват нити). Два профиля в одном G-коде, резал несколько заходов.

Размах 80 см = 3 куска по 27 см. Концы подрезал вручную под перпендикуляр для ровного склеивания.
Сборка RC-самолета
Все детали пенопласта: 3 перед, 3 зад, 3 крыла. Сборка.

Начинаю с носа. Клеевой пистолет. Горячий клей немного плавит пенопласт, но склеить получается.

Хороший альтернативный клей — эпоксидка 5 минут. Перед склеиванием второго борта — делаю держатель мотора. Алюминиевый профиль 30 мм (легкий). Режу ~18 см, отмечаю/сверлю отверстия под мотор (3 мм), гну на 90°. Мотор на M3.

Этой сборкой пробиваю отверстие в носе пенопласта. Ножовкой расширяю до 30 мм (диаметр мотора).
На другой стороне держателя — 4 отверстия: крепление держателя + шасси. Переношу на фюзеляж, сверлю 4 мм вручную. Второй алюминиевый кусок ~7 см с теми же отверстиями — зажимаю держатель.

Болты M4 крепят держатель без повреждения пенопласта. Пока убрал, продолжаю склеивать зад. Тот же метод.
Стыковка носа и хвоста. Для прочности — шашлычные палочки между ними.

Лучше толще палочки — при крушении легко ломается тут. Много горячего клея, сжимаю. Фюзеляж готов, выглядит круто.

Оперение: два куска пенопласта 10 мм — горизонтальное и вертикальное. Фасую края — эстетика + аэродинамика. Клеятся прямо к хвосту, но сначала — рули.

Отрезаю ~1/3 длины — это рули (элеватор и руль направления). Для шарниров фасую стыковку. Ножовкой, нужна острая для чистого реза.
Делаю оперение более аэродинамичным: наждачкой округляю входные края, немного — выходные.

Пенопласт хрупкий — обклеиваю всю площадь оперения и рулей упаковочным скотчем. Укрепляет + гладче = лучше аэродинамика.

Нижний край руля направления под 45° — место для элеватора.

Шарнир — тот же скотч: соединяю две части, крепкий шарнир.

То же для горизонтального. Скотч с двух сторон — надежнее. Обернул боковые края. Оперение готово.

Клею горизонтальное оперение к фюзеляжу горячим клеем. Вертикальное: 3 шашлычные палочки через горизонтальное и фюзеляж, клей, прижимаю сильно.

Оперение готово. Переходим к крылу.
Крыло — 3 части (лимит ЧПУ). Шашлычные палочки для прочности при склеивании. Для точного выравнивания — прямая деревянная рейка, по ней скользят части.

Крыло хрупкое (длинное, тонкое) — усиливаю деревянной палочкой. Режу под размер, отмечаю карман на крыле, ножовкой аккуратно вырезаю. Клей в карман, вставляю палочку не нарушая профиль.

Крыло прочнее. Все равно разобьется при ударе — обклеиваю بالكامل скотчом, как оперение. Начинаю с заднего края (trailing edge) к переднему (leading edge).

Встречный воздух не сдует скотч. Процесс простой, но надо терпение и ровные руки. Крыло получилось идеально: крепкое, аэродинамичное, красивое.
Элероны (рули крыла): 22 см ширина, ~1/4 хорды. Для свободы хода отрезаю ~0.5 см.

Обклеиваю все разрезы скотчем. Фасую нижний край элерона 45°, шарнир скотчем (как раньше). Для посадки на фюзеляж — вырезаю паз в центре крыла.

Сервы элеронов: 9g микросервы. Отмечаю место, ножовкой делаю отверстие под серву. Снимаю ушки крепления сервы — проще форма. Клею серву в отверстие.

Ножовкой канавка от сервы к центру крыла — для проводов. Заклеиваю скотчем. То же для другой стороны.
Рычаги управления: из того же алюминиевого профиля (как держатель мотора). Рисую от руки под высоту рога сервы и выступ над шарниром. Режу металлопилой.

Тяга — стальная проволока 2 мм. В рычаге отверстие 2.5 мм. В элероне паз, клею рычаг. Измеряю длину тяги, изготавливаю из проволоки 2 мм плоскогубцами. Важно: при измерении/установке тяг сервы должны быть в нейтрали.

Нейтраль: вручную в середину хода, или сервотестер, или Arduino. Повторяю для другой стороны. Крыло готово.
Сервы руля направления и элеватора: те же 9g. Установка аналогично. Рядом, валы в противоположные стороны.

Канавка в фюзеляже под провода. Заклеил сервы скотчем, вырезы под рога. Рычаги и тяги — как выше.

Два деревянных стержня 8 мм — крепление крыла к фюзеляжу. Отверстия сверлом 6 мм вручную. Стержины вылезают ~1 см по бокам. Клею к фюзеляжу горячим клеем.

Крыло на резинках — легко снимается, при крушении резинки гасят удар, сборка прочная.

Посадочное устройство: алюминиевый профиль + колеса из пенопласта (резал на ЧПУ). На профиле пазы для легкого гибания. Как должно выглядеть:

Колеса на профиль: болты M5 + алюминиевый шланг 6 мм внутр. диаметр. Шланг зажат болтом/гайкой M5, шайбы M5 по бокам — колесо вращается свободно. То же заднее колесо.

Все компоненты готовы. Переходим к электронике.
Электроника Arduino RC-самолета — схема
Передатчик и приемник — самоделки на Arduino Pro Mini.

Детальные уроки по передатчику/приемнику есть — смотрите для деталей. Здесь схема и принцип работы самолета.

Компоненты:
- NRF24L01 + PA + LNA …………..…..…….
- Arduino Pro Mini………………..……….…..
- Сервопривод ……………………………………
- Бесколлекторный мотор ………………………..……
- ESC 30A ……………………………….…………
- Li-Po батарея ……………………..……………
Радиосвязь — NRF24L01. Передатчик кажется сложным, но прост: джойстики, потенциометры, кнопки → постоянно шлют данные. Приемник принимает по NRF24L01, выдает команды сервам и бесколлекторнику.
Управление сервами и бесколлекторником на Arduino — просто, концепция понятна. Бесколлекторник 1000KV, ESC 30A. ESC питание мотора + BEC 5V для Arduino и серв. Питание ESC и мотора — 3S LiPo.
Добавил индикатор разряда батареи: делитель напряжения 12V→~5V на аналоговый вход Arduino, при <11V зажигает LED. У приемника свободные каналы — можно добавить стробоскопы, флапы, сброс груза и т.д.
Финал сборки
Собрал по схеме. Канал 1 — руль направления, 2 — элеватор, 3 и 4 — элероны, 6 — LED. LED с одной стороны, выключатель — с другой.

Шасси крепится к держателю мотора двумя болтами (как раньше). Вставляю мотор с держателем сверху, болчу, креплю шасси. Резинки держат батарею.

Подключаю батарею к ESC, укладываю всё внутрь. Удлинителями соединяю элероны крыла с приемником, надеваю крыло на фюзеляж.

Пропеллер на мотор. Осталось проверить ЦМ (центр массы).

ЦМ — критичный фактор полета.

Сначала самолет был хвостотяжелым. Сдвинул батарею вперед, добавил груз (болты/гайки) — выровнял.

Arduino RC-самолет готов. Выезжаем на испытания.
Испытания Arduino RC-самолета
Первый полет (maiden) — неудача. Результат крушения:

Вывод: всё еще хвостотяжелый, мотора маловато. Другого мотора/пропеллера не было — модифицировал нос: меньше, мотор вперед (лучше обдув), закруглил края. Усилил конструкцию деревянными палочками и алюминиевыми профилями внутри фюзеляжа.

Внизу отсека электроники: отверстие для выхода воздуха из носового входа, второе — для антенны NRF24L01 наружу (дальность).
Попытка 2. Похоже, лучше обдув/тяга.

Фюзеляж снова сломан — пенопласт слаб. Новый фюзеляж + немного скотча для прочности.
Попытка 3. Надежда, но взлётная полоса плохая. Самолет ушел вправо, задел край дороги, сломан.

Починил, обклеил почти весь фюзеляж armé/упаковочным скотчем. Сделал бы раньше — фюзеляж не ломался даже после нескольких крушений.
Проблема: после крушений сломаны все 4 пропеллера. Клееный пропеллер — развалился на разбеге.
Еще один клееный из двух сломанных — повезло, самолет взлетел нормально.

Удача недолгая — пропеллер сломан в воздухе.

Тем не менее, первый опыт полета RC — считаю проект успешным: доказал концепцию полностью Arduino-системы управления RC-самолетом.
Из полета: управление от передатчика слишком резкое. Джойстики плохие — малый ход, плохой отклик.

Решение в прошивке: правый потенциометр — чувствительность (travel adjust), левый — трим руля направления.
Код Arduino RC-самолета
Код тот же, что в прошлом уроке (сервы + бесколлекторник через NRF24L01).
Полный код:
/* Arduino RC Airplane == Receiver Code = by Dejan, www.HowToMechatronics.com Library: TMRh20/RF24, https://github.com/tmrh20/RF24/ */ #include #include #include #include #define led 9 RF24 radio(3, 2); // nRF24L01 (CE, CSN) const byte address[6] = "00001"; unsigned long lastReceiveTime = 0; unsigned long currentTime = 0; Servo throttle; Servo rudderServo; Servo elevatorServo; Servo aileron1Servo; Servo aileron2Servo; int throttleValue, rudderValue, elevatorValue, aileron1Value, aileron2Value, travelAdjust; struct Data_Package { byte j1PotX; byte j1PotY; byte j1Button; byte j2PotX; byte j2PotY; byte j2Button; byte pot1; byte pot2; byte tSwitch1; byte tSwitch2; byte button1; byte button2; byte button3; byte button4; }; Data_Package data; void setup() { Serial.begin(9600); radio.begin(); radio.openReadingPipe(0, address); radio.setAutoAck(false); radio.setDataRate(RF24_250KBPS); radio.setPALevel(RF24_PA_MAX); radio.startListening(); resetData(); throttle.attach(10); rudderServo.attach(4); elevatorServo.attach(5); aileron1Servo.attach(6); aileron2Servo.attach(7); pinMode(led, OUTPUT); } void loop() { currentTime = millis(); if ( currentTime - lastReceiveTime > 1000 ) { resetData(); } if (radio.available()) { radio.read(&data, sizeof(Data_Package)); lastReceiveTime = millis(); } throttleValue = constrain(data.j1PotY, 80, 255); throttleValue = map(throttleValue, 80, 255, 1000, 2000); throttle.writeMicroseconds(throttleValue); travelAdjust = map(data.pot2, 0, 255, 0, 25); elevatorValue = map(data.j2PotY, 0, 255, (85 - travelAdjust), (35 + travelAdjust)); elevatorServo.write(elevatorValue); aileron1Value = map(data.j2PotX, 0, 255, (10 + travelAdjust), (80 - travelAdjust)); aileron1Servo.write(aileron1Value); aileron2Servo.write(aileron1Value); if (data.j1PotX > 127) { rudderValue = data.pot1 + (data.j1PotX - 127); } if (data.j1PotX < 127) { rudderValue = data.pot1 - (127 - data.j1PotX); } rudderValue = map(rudderValue, 0, 255, (10 + travelAdjust), (90 - travelAdjust)); rudderServo.write(rudderValue); int sensorValue = analogRead(A3); float voltage = sensorValue * (5.00 / 1023.00) * 3; if (voltage < 11) { digitalWrite(led, HIGH); } else { digitalWrite(led, LOW); } } void resetData() { data.j1PotX = 127; data.j1PotY = 80; data.j2PotX = 127; data.j2PotY = 127; data.j1Button = 1; data.j2Button = 1; data.pot1 = 1; data.pot2 = 1; data.tSwitch1 = 1; data.tSwitch2 = 1; data.button1 = 1; data.button2 = 1; data.button3 = 1; data.button4 = 1; }
Описание: кратко основные функции, детали — в прошлом уроке. После приема данных: джойстик1 Y → газ (преобразование 80–255 → 1000–2000 мкс для ESC). Элеватор — джойстик2 Y → 85–35° (с учетом travelAdjust от правого потенциометра — уменьшает ход серв). Элероны — джойстик2 X, тот же travelAdjust. Руль направления — джойстик1 X + трим от левого потенциометра (pot1). Напряжение батареи — делитель на A3, при <11V зажигает LED.
Всё. Жду мнения в комментариях, особенно от опытных аэромоделистов. Новичкам — канал FliteTest (ссылка в описании) — лучший ресурс по RC.
Надеюсь, понравилось. Вопросы — в комментариях. Коллекция Arduino-проектов.
Производственный процесс
- Сделай свой LUMAZOID: DIY Arduino музыкальный визуализатор
- Сборка домашней машины для написания домашних заданий (плоттер-писатель)
- DIY-консоль управления Photoshop на Arduino Nano RP2040 Connect
- Умный вольтметр на Arduino и смартфоне — простое DIY-проект
- Сборка DIY VR-скейтборда на Arduino, Google Cardboard и Bluetooth
- Самодельный осциллограф на Arduino Nano (10 Гц – 50 кГц) с ЖК-дисплеем 128×64
- DIY Arduino Radionics EMR Treatment Device — радионическое устройство
- DIY 2D гоночный симулятор движения на Arduino Nano и сервоприводах SG90
- Программируемый набор 3-осевой манипулятора — локальное и удаленное управление через Arduino и Bluetooth
- Создание портативного RFID-замка на Arduino — пошаговое руководство