Bluetooth-контролируемый моторизированный камерный слайдер на Arduino для плавных кинематографических кадров
Компоненты и материалы
| Arduino UNO | 1 |
| PCBWay Custom PCB | 1 |
| V-Slot 20×40 Linear Rail | 1 (длина по желанию) |
| Solid V Wheel Kit | 4 |
| Drop In Tee Nuts | 4 |
| Eccentric Spacer | 2 |
| 9mm Aluminium spacer | 2 |
| 3mm Aluminium spacer | 2 |
| Low Profile M5 screws length 20mm with nuts | 4 |
| Low Profile M5 screws length 10mm | 4 |
| M3 Allen HEX screws length 16mm with nuts | 8 |
| 8mm Self-aligning Pillow Flange Block Bearing | 2 |
| GT2 Bore 8mm 20 Teeth Timing Aluminum Pulley | 1 |
| 8mm linear rail shaft (60mm) | 1 |
| GT2 Bore 5mm 20 Teeth Timing Aluminum Pulley | 1 |
| GT2-6mm Open Timing Belt | 1 (длина зависит от рельса) |
| Bipolar Nema17 Stepper motor | 1 |
| A4988 Stepper motor driver | 1 |
| 12V 3A Rechargeable Battery | 1 |
| HC-05 Bluetooth Module | 1 |
Необходимые инструменты и станки
- 3D Printer (generic)
Приложения и онлайн-сервисы
- Autodesk Fusion 360
- Autodesk Eagle
- Arduino IDE
О проекте
Обзор проекта
Для любителя видеосъемки покупка моторизированного камерного слайдера может быть дорогой. Поэтому я решил построить свой собственный. В этом руководстве мы пошагово рассмотрим создание Bluetooth-управляемого моторизированного камерного слайдера.
Мы создадим слайдер, которым можно управлять беспроводно через Bluetooth с помощью кастомного Android-приложения. Приложение разработано с помощью MIT App Inventor и позволяет настраивать скорость движения, расстояние перемещения, ускорение/замедление и многое другое. Приложение поддерживает длину слайдера до 10 метров, поэтому вы можете собрать конструкцию любого размера.

В качестве привода используется шаговый двигатель NEMA17, что обеспечивает точное позиционирование. Для управления двигателем через Arduino применяется драйвер A4988 Pololu, предоставляющий 5 режимов микрошага (до 1/16 шага) для максимальной плавности и точности.

Проект спроектирован с учетом возможности изготовления в фэблабе/мейкерспейсе/хакерспейсе.
CAD и 3D-моделирование
Конструкция разработана в Fusion 360. Используются широко доступные механические компоненты, которые можно легко приобрести в любом онлайн или офлайн магазине.

Механическая основа основана на комплектующих OpenBuilds: V-slot 2040 линейная рельса для перемещения камеры. Два шкива — один на валу шагового двигателя, другой на 8-мм валке ссадины с подшипниками — соединены открытым зубчатым ремнем GT2 для преобразования вращательного движения в линейное.


8-мм вал закреплен между двумя самоцентрирующими опорными подшипниками, befestленными на верхней и нижней пластинах четырьмя винтами M5.

Четыре дельриновых колеса V-Slot катятся по V-образному профилю рельсы, обеспечивая исключительно плавное движение. На центральной пластине камеры имеется отверстие диаметром 1/4 дюйма для стандартного штативного крепления.

Все детали слайдера собираются на винтах M3×16 мм с гайками. Электроника размещается в корпусе.

Цифровая фабрикация (3D-печать)
Все детали корпуса печатаются на 3D-принтере со слоем 0.2 мм и заполнением 20%, кроме левой и правой ножек слайдера — они печатаются с заполнением 50%.
STL-файлы можно скачать на Thingiverse.
Сборка комплекта V-колес
Сборка проста. Каждый комплект твердого V-колеса содержит резиновое колесо, два подшипника, два точных шайбы и контровую гайку.

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



Механическая сборка камерного слайдера
Сначала соберите пластину камеры и четыре V-колеса, используя 9-мм алюминиевые распорки, точные шайбы и контровые гайки.


Повторите для остальных трех колес. Для двух правых колес используйте 9-мм распорки, для двух левых — эксцентриковую распорку с 3-мм распоркой.

Установите пластину камеры в V-slot профиль. Если пластина люфтит, затяните эксцентриковую гайку до устранения люфта.


Вставьте два вкладышных гайки (drop-in tee nuts) в каждый конец V-slot профиля для соединения с левой и правой ножками слайдера.



Установите ножки слайдера в профиль и закрепите их четырьмя винтами M5×10 мм.



Установите шаговый двигатель NEMA17 на свою пластину и закрепите четырех винтами M3×16 мм.




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


Установите пластину с двигателем на левую ножку и закрепите двумя винтами M3×16 мм.




На вал двигателя установите шкив GT2 с отверстием 5 мм и затяните зажимной винт.


В правой ножке вставьте четыре гайки M3 в предусмотренные места.


Установите две пластины с подшипниками на верхнюю часть правой ножки.


Закрепите их четырьмя винтами M3×16 мм.




Установите один из фланцевых подшипников 8 мм на верхнюю пластину правой ножки, используя два винта M5×20 мм и две гайки M5.



Повторите для второго фланцевого подшипника на нижней пластине.



Вставьте 8-мм вал в нижний фланцевой подшипник и протолкните его вверх. Затем вставьте шкив с отверстием 8 мм на вал и зафиксируйте зажимным винтом.



Контрольная точка: механизм собран, осталось натянуть ремень.

Натяните ремень GT2 6 мм на шкив двигателя (5 мм) и на шкив правой ножки (8 мм). Затем зафиксируйте ремень на пластине камеры.


Соберите плату управления: установите шилд Cairo Camera Slider на Arduino UNO.


Поместите Arduino с шилдом в корпус платы управления.


Вставьте две гайки M3 в левую ножку и закрепите корпус платы управления винтами M3×16 мм.




Закройте крышку корпуса двумя винтами M3 с гайками.



Тестирование управления шаговым двигателем
После сборки проверим работу. Подключите шаговый двигатель к Arduino через драйвер A4988 и загрузите тестовый скетч.
Драйвер шагового двигателя A4988
Для управления шаговым двигателем с Arduino нужен драйвер — преобразователь команд микроконтроллера в сигналы для мотора. Мы используем A4988: он управляет одним биполярным двигателем до 2А на катушку, требует всего два цифровых пина (STEP, DIR), имеет подстроечный резистор для установки тока и поддерживает 5 режимов микрошага (до 1/16).


VMOT, GND: питание двигателя 8–35В (у нас 12В 3А с конденсатором 100µF для защиты от скачков).
2B, 2A / 1A, 1B: выходы на катушки двигателя (до 2А каждая).
VDD, GND: логика 3–5.5В, гальванически развязана от VMOT.
EN (Enable): активный LOW (0В) — включен по умолчанию.
MS1, MS2, MS3: выбор микрошага. По умолчанию все LOW — полный шаг.
RST, SLP: Reset (активный LOW) и Sleep (активный LOW). По умолчанию Sleep HIGH.
STP, DIR: STEP — импульсы шагов, DIR — направление (HIGH — по часовой, LOW — против).

Шаговый двигатель NEMA17
Шаговые двигатели вращаются на точные углы, применяются в 3D-принтерах, ЧПУ. Управляются импульсами тока через обмотки. Каждый импульс = один шаг (или микрошаг). Преимущество: точная работа на очень низких скоростях без остановов.

Используем биполярный NEMA17 (4 провода, 2 обмотки). Угол шага 1.8°. Рабочее напряжение 9В, для максимальной мощности — 12В.

Схема подключения
Соедините двигатель, драйвер, Arduino UNO и батарею 12В 3А по схеме.

Код Arduino (тест)
Установка библиотеки AccelStepper
В Arduino IDE: Sketch → Include Library → Manage Libraries → поиск "AccelStepper" → установить (автор Mike McCauley).



Тестовый скетч (движение туда-сюда)
// Bounce stepper test program
#include <AccelStepper.h>
#define stepPin 2
#define dirPin 3
AccelStepper stepper(AccelStepper::DRIVER, stepPin, dirPin);
void setup() {
stepper.setMaxSpeed(100);
stepper.setAcceleration(20);
stepper.moveTo(500);
}
void loop() {
if (stepper.distanceToGo() == 0)
stepper.moveTo(-stepper.currentPosition());
stepper.run();
}
Логика: создаем объект AccelStepper с пинами STEP (2) и DIR (3). В setup задаем макс. скорость 100 шагов/с, ускорение 20 шагов/с², целевую позицию 500 шагов. В loop: если мотор достиг цели, меняем цель на противоположную и продолжаем движение.
Полноценное беспроводное управление
Теперь создадим мобильное приложение для управления слайдером и скетч Arduino для приема команд по Bluetooth.

Создание мобильного приложения
Использован MIT App Inventor — визуальное программирование для Android. Исходный код приложения открыт, можно редактировать.


На скриншоте ниже — описание функций кнопок.

Приложение общается со слайдером через Bluetooth. Следующий шаг — подключить модуль HC-05 к схеме и загрузить код для приема команд.
Схема подключения с Bluetooth
Подключаем HC-05 к существующей схеме. HC-05 работает как slave/master (в отличие от HC-06 — только slave), протокол SPP (Serial Port Profile). Соединение:
- Tx (Arduino) → Rx (HC-05)
- Rx (Arduino) → Tx (HC-05)
- 5V (Arduino) → VCC (HC-05)
- GND (Arduino) → GND (HC-05)

Печатная плата (PCB)
Для надежности разработан шилд для Arduino UNO: просто вставьте компоненты (HC-05, A4988, батарею) и установите шилд на Arduino. Плату заказывал на PCBWay — качество отлично, цена $5, отслеживание онлайн.




Файлы проекта и заказ платы на PCBWay: PCB Source Files & Ordering

Код Arduino и Bluetooth-коммуникация
Полный скетч с комментариями (протокол обмена данными с приложением):
/* Протокол данных:
LEFT arrow → 1
RIGHT arrow → 2
STOP → 3
Rail length (1–1000 cm) → 201–1200
Acceleration: Very High→14, High→11, Medium→12, Low→13, Very Low→15
Speed slider (1–4000 steps/s) → 5001–9000
Delayed start ON → 7, OFF → 8
Left homing → 16, Right homing → 17
Smooth (1/4 microstep) → 18, Very Smooth (1/16) → 19
*/
#include <MultiStepper.h>
#include <AccelStepper.h>
#define stepPin 2
#define dirPin 3
bool homingPositionFlag = false;
int startupSetupFlag = 0;
bool delayedStart = false;
int incomingData = 0;
int movementDistance = 50;
long steps = 0;
int microStepResolution = 0;
long railLength = 0;
int sliderSpeed = 10;
AccelStepper stepper(AccelStepper::DRIVER, stepPin, dirPin);
void setup() {
pinMode(stepPin, OUTPUT);
pinMode(dirPin, OUTPUT);
Serial.begin(9600);
stepper.setMaxSpeed(10.00);
stepper.setAcceleration(500.00);
while (startupSetupFlag < 3) {
if (Serial.available() > 1) {
unsigned int dataOne = Serial.read();
unsigned int dataOne1 = Serial.read();
unsigned int incomingData = (dataOne1 * 256) + dataOne;
// Homing
if (incomingData == 16) { // left end
stepper.setCurrentPosition(steps);
homingPositionFlag = false;
startupSetupFlag++;
} else if (incomingData == 17) { // right end
stepper.setCurrentPosition(-(steps));
homingPositionFlag = true;
startupSetupFlag++;
}
// Microstep resolution
if (incomingData == 18) {
microStepResolution = 4;
startupSetupFlag++;
} else if (incomingData == 19) {
microStepResolution = 16;
startupSetupFlag++;
}
// Rail length
if (incomingData >= 1301 && incomingData <= 2300) {
railLength = incomingData - 1300;
if (microStepResolution == 4) {
steps = ((6100L * railLength) / 50L);
startupSetupFlag++;
} else if (microStepResolution == 16) {
steps = ((25000L * railLength) / 50L);
startupSetupFlag++;
}
}
}
}
}
void loop() {
if (Serial.available() > 1) {
unsigned int dataOne = Serial.read();
unsigned int dataOne1 = Serial.read();
unsigned int incomingData = (dataOne1 * 256) + dataOne;
// Motor control
if (incomingData == 1 && !stepper.isRunning() && stepper.currentPosition() != 6050 && homingPositionFlag) {
if (delayedStart) delay(15000);
stepper.setCurrentPosition(0);
stepper.moveTo(steps);
homingPositionFlag = false;
}
else if (incomingData == 2 && !stepper.isRunning() && stepper.currentPosition() != -6050 && !homingPositionFlag) {
if (delayedStart) delay(15000);
stepper.setCurrentPosition(0);
stepper.moveTo(-(steps));
homingPositionFlag = true;
}
else if (incomingData == 3 && stepper.isRunning()) {
homing();
}
// Speed
else if (incomingData >= 5001 && incomingData <= 9000) {
sliderSpeed = incomingData - 5000;
stepper.setMaxSpeed(sliderSpeed);
}
// Delayed start
else if (incomingData == 7) delayedStart = true;
else if (incomingData == 8) delayedStart = false;
// Movement distance
else if (incomingData >= 201 && incomingData <= 1200) {
movementDistance = incomingData - 200;
if (microStepResolution == 4)
steps = ((6100L * movementDistance) / 50L);
else if (microStepResolution == 16)
steps = ((25000L * movementDistance) / 50L);
}
// Acceleration
else if (incomingData == 11 && !stepper.isRunning()) stepper.setAcceleration(3000);
else if (incomingData == 12 && !stepper.isRunning()) stepper.setAcceleration(1000);
else if (incomingData == 13 && !stepper.isRunning()) stepper.setAcceleration(500);
else if (incomingData == 14 && !stepper.isRunning()) stepper.setAcceleration(4000);
else if (incomingData == 15 && !stepper.isRunning()) stepper.setAcceleration(10);
}
stepper.run();
}
void homing() {
if (stepper.currentPosition() > 0) homingPositionFlag = true;
else homingPositionFlag = false;
stepper.moveTo(0);
}
Логика работы кода
Используется библиотека AccelStepper для точного управления. При запуске приложение запрашивает:
- Режим микрошага: 1/4 (Smooth) или 1/16 (Very Smooth). Критически важно выбрать правильный режим, иначе расчеты расстояния будут неверны.
- Длину рельса в см (до 1000 см).
- Позицию парковки (homing): левый или правый конец. Каретка должна находиться именно на выбранном конце.



В setup() происходит инициализация параметров через последовательный порт. В loop() обрабатываются команды: движение влево/вправо, стоп, изменение скорости, ускорения, расстояния, задержка запуска.
Руководство пользователя и устранение неполадок
- Подключите 12В питание к Arduino UNO.
- Включите Bluetooth на телефоне, найдите и сопряжитесь с HC-05 (пароль обычно 1234 или 0000).
- Запустите приложение, нажмите "Press here to connect with Cairo camera slider", выберите HC-05.
- Приложение запросит режим микрошага — выберите соответствующий настройкам драйвера (перемычки MS1-MS3 на A4988).
- Введите длину рельса в см.
- Выберите позицию парковки (левый/правый конец). Каретка должна быть именно там.
- После настройки появится сводка параметров. Нажмите OK — слайдер готов к работе.







Слайдер в действии
Видео демонстрации работы доступно в исходном проекте.
Исходный код
Полный скетч для Arduino (Cairo Camera Slider Final Code) приведен выше в разделе "Код Arduino и Bluetooth-коммуникация".
3D-модели (STL)
Файлы для 3D-печати доступны на Thingiverse: Cairo Camera Slider STLs
Схемы

Производственный процесс
- Эволюция и дизайн современных камер
- Понимание объективов камер: дизайн, история и будущие инновации
- BrickPi Bookreader: Автоматизация чтения Kindle на Raspberry Pi и LEGO Mindstorms
- Сборка Bluetooth-робота-шпиона на Arduino с управлением с телефона
- FlickMote: жестовое IR-пульт для умного дома на Arduino 101 и ультразвуковом датчике
- DIY Arduino TV-B-Gone: универсальный пульт для выключения любого телевизора
- Создание пользовательских LED-часов с будильником — видно с 12 метров
- Find Me: Умный поисковик вещей на Arduino и Bluetooth
- Оптимизированные решения питания для проектов на Arduino
- Продвинутая ТГц-камера для визуализации раскрывает высокоразрешающие внутренние виды твёрдых объектов