Управление несколькими сервоприводами на Raspberry Pi для механизма поворота/наклона PI-камеры
Содержание
- Шаг 1: компоненты
- Шаг 2: ШИМ
- Шаг 3: схема подключения
- Шаг 4: калибровка сервоприводов
- Шаг 5: создание скрипта Python
- Шаг 6: Механизм поворота и наклона
- Шаг 7: самодельный механизм поворота и наклона
- Шаг 8: подключение электроники
- Шаг 9: скрипт Python
- Шаг 10: циклический тест для сервоприводов
- Шаг 11: Заключение
В этом обучающем проекте будет рассмотрено управление несколькими сервоприводами для позиционирования PI-камеры с помощью механизма поворота/наклона с использованием Raspberry Pi 3 Model B и программы на Python.
У подобной камеры с механизмом поворота/наклона множество применений. Это может быть система видеонаблюдения или робот с дистанционным управлением. У Raspberry PI вычислительной мощности достаточно и что бы реализовать относительно несложную обработку изображений и к примеру, реализовать автоматическое слежение за движущимся объектом или поиск нужного объекта. И многое другое. Примеры реализации некоторых подобных вещей будут рассмотрены в будущих обучающих проектах.
Шаг 1: компоненты
Основные используемые детали:
1 x Raspberry Pi 3b
1 x RPI-камера OV5647 (5-мегапикселей, 1080p)
2 x сервопривод SG90
1 x самодельное или готовое крепление поворота/наклона для SG90
2 x резистор 1кОм, опционально
Шаг 2: ШИМ
С помощью ШИМ (широтно-импульсная модуляция) можно управлять мощностью нагрузки, яркостью свечения светодиода, скоростью вращения моторов, регулировать напряжение в преобразователях напряжения и т.д.
Принцип работы следующий. Генератор создаёт прямоугольные импульсы определённой частоты. Эта частота постоянна, а длительность импульса можно изменять. К примеру, если нужно управлять яркостью свечения светодиода, для этого можно использовать ЦАП (цифро-аналоговый преобразователь, DAC). У Raspberry Pi нет аналогового выхода (ЦАП), вместо него можно использовать ШИМ. Чем больше длительность импульса, тем больше среднее значение напряжения и наоборот, чем меньше длительность импульса, тем меньше среднее напряжение.
В случае со светодиодом, если частота будет слишком низкая, визуально светодиод будет мигать, а не менять яркость.
Кроме уже упомянутого, ШИМ используется и при управлении некоторых сервоприводов, контроллеров оборотов коллекторных или BLDC моторов и прочих вещах, используемых в моделизме и робототехнике. В данном случае нас интересуют сервоприводы. Угол, на который будет проворачиваться сервопривод задаётся длительностью импульса.
Шаг 3: схема подключения
Сервоприводы будут подключены к внешнему источнику питания 5В, а управляющий провод к Raspberry Pi. Цвета проводов у различных сервоприводов могут отличаться, в данном случае для SG90 распиновка следующая:
- коричневый — "земля"
- красный — "+5В"
- желтый — сигнальный
К GPIO 17 подключается управляющий провод сервопривода наклона, к GPIO 27 сервопривод поворота. Дополнительно для защиты выводов Raspberry Pi можно использовать резистор 1кОм.
Если Вы также будете использовать отдельные источники питания для Raspbery Pi и сервоприводов, обязательно соедините их земли, в противном случае электроника может выйти из строя. В данном случае земля от внешнего источника питания для сервоприводов подключена к выводу земли (возле GPIO 17) на Raspberry Pi.
Шаг 4: калибровка сервоприводов
У SG90 от различных производителей (могут выпускаться со своей наклейкой, например, "FeeTech FS90" или как в оригинальной "TowerPro SG90") параметры сервопривода могут немного отличаться. Если питающее напряжение обычно до 4.8-5в, частота управляющих импульсов 50Гц (т.е. период следования сигнала 20мс), а угол, на который проворачивается сервопривод примерно 180градусов, то длительность управляющего импульса очень часто отличается.
К примеру длительность управляющего импульса может быть от 1мс до 2мс или от 0.75мс до 1.85мс или от 0.5мс до 2.4мс и т.д. Для сервоприводов от одного производителя, длительность управляющего импульса тоже может немного отличаться. Калибровка — это определение, какие длительности импульсов соответствуют минимальной и максимальной длительность управляющего импульса и каким углам проворачивания вала сервопривода они соответствуют.
Под нейтральным положением может подразумеваться то положение, в которое проворачивается вал при средней длительности импульса (в данном случае это 1.5мс). Обозначать в градусах могут как на картинке выше, т.е. нейтральное 90 градусов и крайние положения как 0 и 180. Или под нейтральным подразумевать 0 градусов, а крайние обозначать как -90 и +90. С обозначениями углов это условность, могут быть и другие варианты. В данном случае будет использоваться первый вариант.
Для программирования позиции сервопривода с использованием Python очень важно знать соответствующий коэффициент заполнения (англ. duty cycle) для вышеуказанных позиций (задаётся в процентах). К примеру длительность импульса 2мс, при периоде следования сигнала 20мс это коэффициент заполнения 10%. Давайте сделаем вычисления для всех углов:
- исходное положение == (0 градусов) длительность импульса 1мс == коэффициент заполнения = 1мс/20мс*100% = 5%
- нейтральное положение == (90 градусов) длительность импульса 1,5мс == коэффициент заполнения = 1,5мс/20мс*100% = 7,5%
- конечная позиция == (180 градусов) длительность импульса 2мс == коэффициент заполнения = 2мс/20мс*100% = 10%
Таким образом коэффициент заполнения варьируется от 5% до 10%.
Давайте откалибруем сервоприводы. Для этого откроем терминал на Raspberry и запустим редактор Python 3 с правами от суперпользователя (нужно для работы с GPIO):
Импортируем модуль RPI.GPIO и называем его GPIO:
import RPi.GPIO as GPIO
Определите, какие схемы нумерации выводов хотите использовать (BCM или BOARD). Я провел этот тест с BOARD, поэтому используемые контакты были физическими (GPIO 17 это контакт 11 и GPIO 27 это контакт 13). Мне было легко их идентифицировать и не ошибиться во время теста (в финальной программе я буду использовать BCM). Выбираем:
Определяем вывод сервопривода, который будет использоваться:
Если хотите использовать схему BCM, последние 2 команды должны быть заменены на:
GPIO.setmode(GPIO.BCM)
tiltPin = 17
Теперь указываем, что этот вывод будет работать как выход:
Настраиваем частоту, для SG90 нужно 50 Гц:
tilt = GPIO.PWM(tiltPin, 50)
Включаем генерацию сигнала ШИМ на выводе и задаём начальный коэффициент заполнения равный нулю:
Теперь мы можем устанавливать различные значения коэффициента заполнения и наблюдать за движением сервопривода. Давайте начнем с 5% и посмотрим, что происходит:
Сервопривод перешел в "нулевое положение". Сервопривод продолжал вращаться, при задании заполнения вплоть до 3%. При задании заполнения 2% сервопривод оставался в том же положении. После чего начав задавать значения больше 2%, движение сервопривода в моём случае начало происходить при установке коэффициента заполнения более 3%. Итак, 3% — это минимальное заполнение (позиция "0 градусов") для этого сервопривода.
То же самое произошло и с максимальным коэффициентом заполнения. Для начала установлено 10%:
Затем задавались большие значения, сервопривод продолжал проворачиваться при установке коэффициента заполнения вплоть до 13%. Таким образом максимальный коэффициент заполнения для данного сервопривода это 13%, угол, на который проворачивается вал сервопривода составил примерно 180 градусов (но это в данном случае, в зависимости от сервопривода физический угол может оказаться и больше и меньше). Итак, в результате калибровки получены следующие данные:
0 градусов == заполнение 3%
90 градусов == заполнение 8%
180 градусов == заполнение 13%
После окончания калибровки останавливаем ШИМ и очищаем GPIO:
Для второго сервопривода процедура калибровки аналогична.
Шаг 5: создание скрипта Python
Для управления сервоприводами с использованием ШИМ, функции на Python нужно передавать значение коэффициента заполнения, указываемого в процентах. В данном случае удобней будет оперировать не коэффициентом заполнения, а градусами.
Сделать это очень просто. Мы знаем, что диапазон заполнения в пределах от 3% до 13% и что это эквивалентно диапазону углов от 0 до 180 градусов. Так же мы знаем, что зависимость линейная.
Позже в коде пересчёт заданного угла в коэффициент заполнения соответственно будет таким:
dutycycle = angle/18 + 3
Давайте создадим файл "angleServoCtrl.py" скрипта на Python для выполнения тестов. По сути, мы повторим то, что мы делали раньше в Python Shell:
Функция setServoAngle(servo, angle) получает в качестве аргументов номер вывода GPIO, к которому подключен сервопривод и значение угла, в который сервопривод должен провернуться.
В консоли этот скрипт запускается так:
sudo python3 angleServoCtrl.py 17 45
Вышеприведенная команда установит сервопривод, подключенный к GPIO 17, под углом 45 градусов.
Файл "angleServoCtrl.py" можно скачать по ссылке.
Шаг 6: Механизм поворота и наклона
На следующем изображении показано, как работает механизм:
В этом проекте pan/tilt механизм будет вращать камеру только в диапазоне углов от 30 до 150 градусов.
Этого диапазона будет достаточно для камеры.
Шаг 7: самодельный механизм поворота и наклона
Вы можете взять готовый механизм поворота и наклона, на подобии как на изображении в предыдущем шаге или сделать свой собственный.
В этом проекте будет использован самодельный:
Шаг 8: подключение электроники
После сборки механизма поворота/наклона, подключите сервоприводы по схеме из третьего шага. Последовательность подключения электроники:
- отключить питание Raspberry Pi и сервоприводов
- соберите всю схему
- на всякий случай ещё раз всё перепроверьте
- включите питание Raspberry Pi
- если все в порядке, подключите питание сервоприводов
Подключать и настраивать камеру пока не будем, это будет рассмотрено в следующем обучающем проекте.
Шаг 9: скрипт Python
Создадим скрипт "servoCtrl.py" для одновременного управления обоими сервоприводами:
При запуске скрипта в качестве параметров нужно указать углы для обоих сервоприводов:
sudo python3 servoCtrl.py 45 120
Приведенная выше команда установит сервопривод поворота в позицию "45 градусов", сервопривод наклона в позицию "120 градусов". Если скрипту не будут переданы параметры, оба сервопривода провернуться в позицию "90 градусов".
Файл крипта "servoCtrl.py" можно скачать по ссылке.
Шаг 10: циклический тест для сервоприводов
Создадим скрипт " servoTest.py" для автоматического движения обоими сервоприводами в диапазоне углов от 30 до 150 градусов:
Осциллограф только для иллюстрации теории ШИМ, как объяснялось ранее.
Приведенный выше код скрипта "servoTest.py" можно скачать по ссылке.
Шаг 11: Заключение
Сделанное в этом обучающем проекте можно использовать для различных целей, некоторые примеры реализации будут рассмотрены в следующих обучающих проектах. К примеру управление и просмотр изображения с RPi-камеры через веб-страницу:
Источник: