Настоящая турель Portal 2 на Arduino: 3-осевое движение и звук
Компоненты и материалы
| Arduino Nano R3 | ×1 |
Необходимые инструменты и станки
| 3D-принтер |
О проекте
История
В этом Рождество я решил спроектировать и собрать рабочую турель из игры Portal 2. Для меня это было упражнением в полном моделировании сборки в Fusion 360 перед началом сборки. Конструкция использует Arduino Nano, MP3-плеер, датчик расстояния, сервоприводы, LED и 3D-печатные детали.
Цель — заставить её двигаться по 3 «осям», с речевыми звуками из игры и LED-имитацией стрельбы.
- Открыть «крылья» при обнаружении человека впереди. Использую кривошипно-штоковый механизм со слайдерами — просто потому что захотелось.
- Если человек остаётся после открытия — стрелять, пока не уйдёт. LED и звук пулемета.
- Если человек ушёл — запустить небольшую рутину сканирования.
- Закрыться и уснуть до следующего посетителя.
- Использовать звуки и голоса турели из игры.
Позволил себе свободы в дизайне, стремясь к узнаваемости, но с функциональностью и печатаемостью. Начал моделирование с базовых эскизов из интернета...
Звуки хранятся на microSD-карте, доступной сзади для обновления. Карта скрыта за чёрной вставкой — невидима после сборки. Использовано 18 отдельных звуковых файлов.
LIDAR-сенсор (Time-of-Flight) имеет прямоугольный профиль и почти невидим спереди после сборки.
Шаг 1: Моделирование в Fusion 360
Дизайн начался с эскизов из интернета. Использовал их как холсты, обвёл контуры трёх видов. Затем выдавил в 3D, сделал оболочку и вырезы. Все электронные компоненты смоделированы в Fusion как компоненты, вставлены и размещены логично. Ключевые параметры:
- Arduino Nano — доступ к разъёму для перепрошивки после сборки
- microSD — доступен так же, идеально невидим
- ToF-сенсор — невидим
- Разъём питания 2.1 мм сзади
- Печатные детали — максимально крупные (минимум мелких)
- Печать без поддержок
После добавки компонентов (Nano, чипы, сервы) в базовую форму — перемещал их, строил опорные структуры внутри оболочки.
Механизм открытия крыльев — кривошипно-штоковый. Почему? Потому что хотел использовать кривошип! Это добавило сложностей, но гарантирует повторяемость и чёткие пределы хода.
Когда модель была готова и я был уверен в работоспособности и собираемости — напечатал детали и собрал прототип. После проверки вернулсь к модели, сделал правки для внешнего вида и собираемости. Итог — текущая модель.
Было непросто: мало прямоугольных форм, всё сходится плотно, доступа для правок после сборки нет. Научился многому — в том числе использованию встроенных компонентов для быстрого доступа к подсборкам. Стоило того!
Шаг 2: 3D-печатные детали

Portal turret v4.zip — обновлённый архив со всеми деталями для последней версии.
— Новая «задняя тестовая ножка». Не по оригиналу, но сзади, позволяет использовать прямой mini-USB разъём вертикально. —
Печатал на Prusa Mk2, PLA для всех деталей. Ориентация печати очевидна. Корпус печатался вертикально без поддержок. Есть большой пролёт сбоку, который нужно мостить — при стандартных настройках проблем не было, кроме «бугра». Бугры спереди и сзади практически устраняются хорошим филаментом и настройками. 0.2 мм в слайсере дало хороший результат. Больше — появлялись просветы у вкладышей.
Каналы и выступы спроектированы с фаской 45° — минимум «висячих» элементов.
Почти не требовалось чистки перед сборкой. Вкладыши в каналы теперь простые, с уменьшенной шириной и постоянной толщиной. Можно использовать тонкий чёрный материал вместо печати на ребре.
Требует аккуратности — штоки слайдеров в рамке шага. Прямые гвозди (гвозди) в отверстиях, прошли 1/8" сверлом и смазка — залог успеха.
Файлы: Lens+v3b.stl, Body-RHS+v4.stl, Body-LHS+w+components+v4.stl, Wing+RH+bottom+v4.stl, Wing+RH+top+v4.stl, Wing+LH+bottom+v4.stl, Wing+LH+top+v4.stl, Pitch+Frame+v4.stl, Leg+-+REAR+v4.stl, Infill+strips+v3.stl, Leg+-+REAR+test.stl, Pitch+Frame+-+modified+1.stl, wings+v6.zip, Arduino+Base+w+Radio.stl, Portal+Turret+v4.zip
Шаг 3: Компоненты
V4 (Красная турель) имеет меньшие пролёты, требует v4 крыльев и рамки шага.
v6 крылья — опция для разных цветов «пушек». Сам не делал, но должно работать.
Когда модель готова и прототип устраивает — напечатал rev 2 с пластиковыми компонентами как на фото. Всё — PLA, чёрный и цвет дизайна (синий), немного прозрачного PLA для центрального «линзы» / лазерного глаза.
Фото хорошо передаёт компоненты, за исключением проводки.
Шаг 4: Электроника
Используемые компоненты:
- Arduino Nano (1)
- DFPlayer Mini MP3 player (или MP3-TF-16P) (1)
- VL53L0X Time-of-Flight дальномер (1)
- SG90 микросервы (3)
- Красные LED 5 мм (5)
- Резисторы 220 Ом для LED (5)
- Резистор 1 кОм (1)
- Динамик 4 см, 4 Ом, 3 Вт (1)
- Разъём питания 2.1 мм (1)
- Строительные гвозди 3" (4)
- Винты M2×6 (8), M2.5×8 (2), M3×8 (4), M3×12 (4), M3×16 (2)
- Термоусадка, мелкие стяжки
Все компоненты доступны в Arduino, Amazon, Banggood и др. Винты брал из набора — иначе купить больно.
Шаг 5: Механическая сборка






Большая часть механической сборки интуитивна. Детали печатаются с нарезанными резьбами там, где нужно — быстрый прогон винтом перед финальной сборкой упростит жизнь.
Arduino и MP3-чип вставляются в крэйдл без крепежа. VL53L0X вставляется в переднюю оболочку без крепежа. Сначала примерка, потом снимаем, паяем, устанавливаем обратно.
Слайдерная сборка использует 4 строительных гвоздя как направляющие. Диаметр ~3 мм, головки откусываются. Брал из ленты гвоздей DeWalt для электрошпильки. Гладкие гвозди — обязательно.
Сервы монтируются как показано. Ориентация важна. Шаг и пивот сервы «центрируются» при установке. Кривошип устанавливается так, что в открытом положении закрытие происходит поворотом против часовой стрелки (вид спереди). Открытое положение — штоки и кривошип в одной линии, ещё 10° до захвата.
Ножки — самая простая часть. Винты 2–2.5 мм, колпачки нащёлкиваются на локти ножек. Винты не должны выступать над плитой ножки — иначе поворачивающийся корпус зацепится.
Все соединения серв с печатями — через короткие белые рычажки из комплекта серв. Пробовал печатать шлицевые отверстия — ограниченный повторяемый успех. Рычажки из комплекта — намного проще.
Кривошипная сборка использует более длинные винты M2.5. Штоки не должны быть зажаты между половинками кривошипа. Можно попробовать короче винты без детали Crank2 — тоже должно сработать (надеюсь, момента мало, если крылья скользят свободно).
Динамик захвачен сервокреплением (2 детали), которые его держат. Динамик между «ногами», зафиксирован креплением к серве шага, затем серва подключена к слайдерной сборке шага, далее кривошипная сборка со штоками. Всё это собирается до установки в левую половину корпуса 4 маленькими винтами.
Когда основные внутренности установлены, с Arduino и MP3 временно на месте — начинается весёлое: проводка!
Шаг 6: Проводка



V5 — опция с радио (фото красной турели). Включает nRF24L01. Кардинально меняет распиновку Arduino для размещения всех соединений. Детали позже...
Финальная укладка тесная — время, потраченное на подбор длин проводов, окупится. Большинство межсоединений — 75–100 мм.
LED собраны с резисторами 220 Ом, термоусадкой, скруткой — отложены после теста. Использовал тонкий провод (витая пара) — не хотел, чтобы проводка бросалась в глаза.
Механика примеряется в корпусе, прокладывается проводка, затем режется и готовится.
Сервоконнекторы сделал разъёмными — можно заменить серву, если сломал зубья. Очень помогло после ошибок на первом прототипе.
Когда основная проводка устраивает — впаиваю LED в конце. Аккуратно укладываю собранную проводку в половинку корпуса. Последний шаг — припаять разъём питания к силовой проводке уже внутри.
Важно: Убедитесь, что проводка за Nano не давит на кнопку Reset! Это вызовет проблемы и блокирует работу. --
На этом этапе вся проводка готова, но перед финальной сборкой — загрузить код в Nano, включить питание, проверить LED, сервы, MP3. После этого — собирать остальную механику.


Шаг 7: Код Arduino
Обновлённый код! Очищен и доработан.
Прилагаемый файл — то, чем я управляю блоком, как в видео. Буду дорабатывать характер и поведение турели. Огромный простор для экспериментов.
Код структурирован подпрограммами — основной цикл чист, удобно было менять поведение. Много переменных в начале для настройки парковочных позиций, мин/макс диапазонов.
Использовал библиотеку DFMiniMP3. Пробовал DFRobot — были проблемы, вернулся к этому. Пришлось оставить 'static void' части для работоспособности. Не нужны для логики, но я не мастер кода. Рада услышать о более простой и чистой библиотеке, как VL53L0X. Дайте знать, если найдёте!
Со звуками: реализация простая — папка mp3 на SD, файлы 0001.mp3, 0002.mp3 и т.д. Первые 4 цифры обязательны в этом формате, суффикс любой для идентификации. См. https://www.dfrobot.com/blog-277.html. Прилагаю скрин с моими именами файлов. Номера соответствуют вызовам в коде.
Звуковые файлы взял со страницы Википедии про звуки турели Portal. Код выбирает случайный файл (1 из 2–3) для разнообразия.
Шаг 8: Финальная сборка корпуса
Сложновато из-за чёрных вкладышей. Масштаб мал — каналы и вкладыши крошечные. Нужно прочистить канал шилом или тонким скребком, чтобы вкладыши входили с малым усилием.
Аккуратная укладка проводов и стяжки — ключ к успеху.
Собрал уже несколько — проще сначала соединить две половины, потом вставлять вкладыши. Вставляю одну сторону в половину с «полкой», не дающей вкладышу уйти внутрь, затем слегка разжимаю и вдавливаю. Теперь не так сложно.
Это был один из самых капризных моментов. Может, когда-нибудь переосмыслю эту сборку, но нравится как выглядит и это надёжно.
Шаг 9: Сборка крыльев




Корпус собран, LED крыльев торчат — готовим и собираем крылья.
Критично: отверстия слайдеров нужно прочистить 1/8" сверлом, вычистить. Головки гвоздей откусывать кусачками, тисками, ножовкой или любимым инструментом. Штоки (гвозди без головок) прессованы в детали крыльев. Прямые, без заусенцев, отшлифованные гвозди — залог работы. Слайдеры и отверстия смазать и протестировать перед подключением штоков и запуском. Сухой графит или смазка для PLA. Я нашёл: небольшая туба личного смазки работает идеально, дешёво, очень скользко. Тоже требует объяснений, когда партнёр или родитель заходит и спрашивает, зачем это на верстаке!!
Сначала разбираюсь, какая деталь куда идёт, примеряю слайдер. Потом собираю верх и низ с установленными штоками, наношу смазку (ватная палочка удобна) и проверяю свободный ход. Без свободного хода без заеданий — будет больно. Доверьтесь...
Когда крылья готовы — вставляю их на место, натягиваю шток на отверстие в крылье, закрепляю одним винтом. LED вставляю в отверстия стволов, провода укладываю вдоль крылья — готово! Можно капнуть термоклея для фиксации после тестов.
Шаг 10: Напугай и шокируй друзей!!
Последний нюанс: угловой разъём питания — отличная идея, не мешает задней ножке при повороте. Переработанная задняя ножка v3 удлинена для запаса.
После сборки и подключения (5 В или подходящее для Nano) — тихо ждёт, пока кто-то не окажется в программируемой зоне, затем оживает и уничтожает всех, кто входит в её владения!!
Дайте знать, если соберёте (или больше) и придумаете новые фичи или концепции!
Код
- Portal turret w Radio (RED)
// Portal Turret - Option With Radio!!
// Chris Nowak - Feb 2019
// https://www.instructables.com/member/ChrisN219/
// https://create.arduino.cc/projecthub/Novachris/talking-portal-2-turret-gun-637bf3
// Includes Cara Mia Opera, Chat Time, Manual mode via Master Turret Control (MTC).
// MTC is separate controller on another build. Turret works autonomously without MTC.
// Built for three turrets, each operates independently. Lots of debug code left in.
// ================= RED ====================
#include <Wire.h>
#include <VL53L0X.h>
#include "Arduino.h"
#include <SoftwareSerial.h>
#include <Servo.h>
#include <DFMiniMp3.h>
#include <RF24.h>
#include <RF24Network.h>
#include <SPI.h>
class Mp3Notify {
public:
static void OnError(uint8_t errorCode) { Serial.println(); Serial.print("Com Error "); Serial.println(errorCode); }
static void OnPlayFinished(uint8_t globalTrack) { Serial.println(); Serial.print("Play finished for #"); Serial.println(globalTrack); }
static void OnCardOnline(uint8_t code) { Serial.println(); Serial.print("Card online "); Serial.println(code); }
static void OnCardInserted(uint8_t code) { Serial.println(); Serial.print("Card inserted "); Serial.println(code); }
static void OnCardRemoved(uint8_t code) { Serial.println(); Serial.print("Card removed "); Serial.println(code); }
};
Servo servo_pivot, servo_wings, servo_pitch;
VL53L0X sensor;
SoftwareSerial secondarySerial(4, 2); // RX, TX
DFMiniMp3<SoftwareSerial, Mp3Notify> mp3(secondarySerial);
RF24 radio(10, 9); // nRF24L01 (CE,CSN)
RF24Network network(radio);
const uint64_t this_node = 01; // Red
const uint64_t WHT = 02; // White
const uint64_t BLU = 03; // Blue
const uint64_t MTC = 00; // Master Turret Control
// ... (остальной код опущен для краткости, полный код в прилагаемом файле)
Кастомные детали и корпуса
- Lens+v3b.stl
- Body-RHS+v4.stl
- Body-LHS+w+components+v4.stl
- Wing+RH+bottom+v4.stl
- Wing+RH+top+v4.stl
- Wing+LH+bottom+v4.stl
- Wing+LH+top+v4.stl
- Pitch+Frame+v4.stl
- Leg+-+REAR+v4.stl
- Infill+strips+v3.stl
- Leg+-+REAR+test.stl
- Pitch+Frame+-+modified+1.stl
- Arduino+Base+w+Radio.stl
Схемы
Схема, которую я сделал для сборки турели.

Производственный процесс
- Янтарь: от древней смолы к научному сокровищу — история, свойства и современное использование
- Гильотина: история, конструкция и наследие
- Искусство и ремесло надгробий: история, материалы и современное производство
- Эволюция и мастерство современного купальника: от древних ванн к высокотехнологичным тканям
- Кремний: свойства, производство и рыночный обзор
- Водка: от древней дистилляции к современному производству
- Карусель: от древних вращающихся аттракционов к современному мастерству
- Диван: от древней роскоши к современному комфорту — подробное руководство
- Железо: свойства, история и повседневные применения
- Концевая револьверная головка сокращает время цикла для производства точных валов