В этом обучающем проекте будет рассмотрено управление несколькими сервоприводами для позиционирования PI-камеры с помощью механизма поворота/наклона с использованием Raspberry Pi 3 Model B и программы на Python.
У подобной камеры с механизмом поворота/наклона множество применений. Это может быть система видеонаблюдения или робот с дистанционным управлением. У Raspberry PI вычислительной мощности достаточно и что бы реализовать относительно несложную обработку изображений и к примеру, реализовать автоматическое слежение за движущимся объектом или поиск нужного объекта. И многое другое. Примеры реализации некоторых подобных вещей будут рассмотрены в будущих обучающих проектах.
С помощью ШИМ (широтно-импульсная модуляция) можно управлять мощностью нагрузки, яркостью свечения светодиода, скоростью вращения моторов, регулировать напряжение в преобразователях напряжения и т.д.
Принцип работы следующий. Генератор создаёт прямоугольные импульсы определённой частоты. Эта частота постоянна, а длительность импульса можно изменять. К примеру, если нужно управлять яркостью свечения светодиода, для этого можно использовать ЦАП (цифро-аналоговый преобразователь, DAC). У Raspberry Pi нет аналогового выхода (ЦАП), вместо него можно использовать ШИМ. Чем больше длительность импульса, тем больше среднее значение напряжения и наоборот, чем меньше длительность импульса, тем меньше среднее напряжение.
В случае со светодиодом, если частота будет слишком низкая, визуально светодиод будет мигать, а не менять яркость.
Кроме уже упомянутого, ШИМ используется и при управлении некоторых сервоприводов, контроллеров оборотов коллекторных или BLDC моторов и прочих вещах, используемых в моделизме и робототехнике. В данном случае нас интересуют сервоприводы. Угол, на который будет проворачиваться сервопривод задаётся длительностью импульса.
Сервоприводы будут подключены к внешнему источнику питания 5В, а управляющий провод к Raspberry Pi. Цвета проводов у различных сервоприводов могут отличаться, в данном случае для SG90 распиновка следующая:
К GPIO 17 подключается управляющий провод сервопривода наклона, к GPIO 27 сервопривод поворота. Дополнительно для защиты выводов Raspberry Pi можно использовать резистор 1кОм.
Если Вы также будете использовать отдельные источники питания для Raspbery Pi и сервоприводов, обязательно соедините их земли, в противном случае электроника может выйти из строя. В данном случае земля от внешнего источника питания для сервоприводов подключена к выводу земли (возле GPIO 17) на Raspberry Pi.
У 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%. Давайте сделаем вычисления для всех углов:
Таким образом коэффициент заполнения варьируется от 5% до 10%.
Давайте откалибруем сервоприводы. Для этого откроем терминал на Raspberry и запустим редактор Python 3 с правами от суперпользователя (нужно для работы с GPIO):
sudo python3Python Shell:
>>>Импортируем модуль RPI.GPIO и называем его GPIO:
import RPi.GPIO as GPIOОпределите, какие схемы нумерации выводов хотите использовать (BCM или BOARD). Я провел этот тест с BOARD, поэтому используемые контакты были физическими (GPIO 17 это контакт 11 и GPIO 27 это контакт 13). Мне было легко их идентифицировать и не ошибиться во время теста (в финальной программе я буду использовать BCM). Выбираем:
GPIO.setmode(GPIO.BOARD)Определяем вывод сервопривода, который будет использоваться:
tiltPin = 11Если хотите использовать схему BCM, последние 2 команды должны быть заменены на:
GPIO.setmode(GPIO.BCM)Теперь указываем, что этот вывод будет работать как выход:
GPIO.setup(tiltPin, GPIO.OUT)Настраиваем частоту, для SG90 нужно 50 Гц:
tilt = GPIO.PWM(tiltPin, 50)Включаем генерацию сигнала ШИМ на выводе и задаём начальный коэффициент заполнения равный нулю:
tilt = start(0)Теперь мы можем устанавливать различные значения коэффициента заполнения и наблюдать за движением сервопривода. Давайте начнем с 5% и посмотрим, что происходит:
tilt.ChangeDutyCycle(5)Сервопривод перешел в "нулевое положение". Сервопривод продолжал вращаться, при задании заполнения вплоть до 3%. При задании заполнения 2% сервопривод оставался в том же положении. После чего начав задавать значения больше 2%, движение сервопривода в моём случае начало происходить при установке коэффициента заполнения более 3%. Итак, 3% - это минимальное заполнение (позиция "0 градусов") для этого сервопривода.
То же самое произошло и с максимальным коэффициентом заполнения. Для начала установлено 10%:
tilt.ChangeDutyCycle(10)Затем задавались большие значения, сервопривод продолжал проворачиваться при установке коэффициента заполнения вплоть до 13%. Таким образом максимальный коэффициент заполнения для данного сервопривода это 13%, угол, на который проворачивается вал сервопривода составил примерно 180 градусов (но это в данном случае, в зависимости от сервопривода физический угол может оказаться и больше и меньше). Итак, в результате калибровки получены следующие данные:
0 градусов ==> заполнение 3%После окончания калибровки останавливаем ШИМ и очищаем GPIO:
tilt=stop()Для второго сервопривода процедура калибровки аналогична.
Для управления сервоприводами с использованием ШИМ, функции на Python нужно передавать значение коэффициента заполнения, указываемого в процентах. В данном случае удобней будет оперировать не коэффициентом заполнения, а градусами.
Сделать это очень просто. Мы знаем, что диапазон заполнения в пределах от 3% до 13% и что это эквивалентно диапазону углов от 0 до 180 градусов. Так же мы знаем, что зависимость линейная.
Позже в коде пересчёт заданного угла в коэффициент заполнения соответственно будет таким:
dutycycle = angle/18 + 3Давайте создадим файл "angleServoCtrl.py" скрипта на Python для выполнения тестов. По сути, мы повторим то, что мы делали раньше в Python Shell:
from time import sleep import RPi.GPIO as GPIO GPIO.setmode(GPIO.BCM) GPIO.setwarnings(False) def setServoAngle(servo, angle): pwm = GPIO.PWM(servo, 50) pwm.start(8) dutyCycle = angle / 18. + 3. pwm.ChangeDutyCycle(dutyCycle) sleep(0.3) pwm.stop() if __name__ == '__main__': import sys servo = int(sys.argv[1]) GPIO.setup(servo, GPIO.OUT) setServoAngle(servo, int(sys.argv[2])) GPIO.cleanup()
Функция setServoAngle(servo, angle) получает в качестве аргументов номер вывода GPIO, к которому подключен сервопривод и значение угла, в который сервопривод должен провернуться.
В консоли этот скрипт запускается так:
sudo python3 angleServoCtrl.py 17 45Вышеприведенная команда установит сервопривод, подключенный к GPIO 17, под углом 45 градусов.
Файл "angleServoCtrl.py" можно скачать по ссылке.
На следующем изображении показано, как работает механизм:
В этом проекте pan/tilt механизм будет вращать камеру только в диапазоне углов от 30 до 150 градусов.
Этого диапазона будет достаточно для камеры.
Вы можете взять готовый механизм поворота и наклона, на подобии как на изображении в предыдущем шаге или сделать свой собственный.
В этом проекте будет использован самодельный:
После сборки механизма поворота/наклона, подключите сервоприводы по схеме из третьего шага. Последовательность подключения электроники:
Подключать и настраивать камеру пока не будем, это будет рассмотрено в следующем обучающем проекте.
Создадим скрипт "servoCtrl.py" для одновременного управления обоими сервоприводами:
from time import sleep import RPi.GPIO as GPIO GPIO.setmode(GPIO.BCM) GPIO.setwarnings(False) pan = 27 tilt = 17 GPIO.setup(tilt, GPIO.OUT) # white => TILT GPIO.setup(pan, GPIO.OUT) # gray ==> PAN def setServoAngle(servo, angle): assert angle >=30 and angle <= 150 pwm = GPIO.PWM(servo, 50) pwm.start(8) dutyCycle = angle / 18. + 3. pwm.ChangeDutyCycle(dutyCycle) sleep(0.3) pwm.stop() if __name__ == '__main__': import sys if len(sys.argv) == 1: setServoAngle(pan, 90) setServoAngle(tilt, 90) else: setServoAngle(pan, int(sys.argv[1])) # 30 ==> 90 (middle point) ==> 150 setServoAngle(tilt, int(sys.argv[2])) # 30 ==> 90 (middle point) ==> 150 GPIO.cleanup()
При запуске скрипта в качестве параметров нужно указать углы для обоих сервоприводов:
sudo python3 servoCtrl.py 45 120Приведенная выше команда установит сервопривод поворота в позицию "45 градусов", сервопривод наклона в позицию "120 градусов". Если скрипту не будут переданы параметры, оба сервопривода провернуться в позицию "90 градусов".
Файл крипта "servoCtrl.py" можно скачать по ссылке.
Создадим скрипт " servoTest.py" для автоматического движения обоими сервоприводами в диапазоне углов от 30 до 150 градусов:
Осциллограф только для иллюстрации теории ШИМ, как объяснялось ранее.
Приведенный выше код скрипта "servoTest.py" можно скачать по ссылке.
Сделанное в этом обучающем проекте можно использовать для различных целей, некоторые примеры реализации будут рассмотрены в следующих обучающих проектах. К примеру управление и просмотр изображения с RPi-камеры через веб-страницу:
Или создание автоматического слежения за предметом:
Или слежения за лицом человека: