Raspberry Pi:Примеры/Управление сервоприводом с применением ServoBlaster
Содержание | Введение | Продукты | Операционная система | Настройка | Основы Linux | Аппаратные средства | Неисправности | Типовые проблемы | Часто возникающие вопросы | Библиотеки | Примеры |
Черновик |
Управление сервоприводом с применением ServoBlaster
Данный пример демонстрирует как задать угол поворота сервопривода.
Будьте осторожны! Если у вас старая модель Raspberry Pi, желательно запитать сервопривод от отдельного источника питания. В противном случае вы можете повредить контакты GPIO. К новым моделям Raspberry Pi можно подключать маломощные сервоприводы напрямую т.к. в них применяется усовершенствованный регулятор напряжения. |
При использовании функции PWM() модуля RPi.GPIO для управления сервоприводом можно столкнуться с нестабильным ШИМ-сигналом на выводах GPIO, что может выражаться дрожанием механизма сервопривода.
Эту проблему можно решить, установив ServoBlaster, разработанную Ричардом Херстом. В отличие от RPi.GPIO, в ServoBlaster за точность подачи импульсов управляющего сигнала отвечает аппаратный генератор тактовых сигналов процессора.
Установим ServoBlaster, введя поочередно в терминале команды:
git clone git://github.com/richardghirst/PiBit.git
cd PiBits/ServoBlaster/user
sudo make
sudo make install
Запустите программу из раздела код и вы увидите графический интерфейс со слайдером:
Изменяйте положение ползунка и понаблюдайте за положением рычага сервопривода, перемещение рычага сервопривода должны быть плавными.
Программа сначала вызывает функцию map(), которая масштабирует угол поворота сервопривода в длительность импульса исходя из значений servo_min и servo_max. Далее в функции set_angle() генерируется команда:
command = "echo {}={}us > /dev/servoblaster".format(servo, pulse)
в которой после echo, вместо {}={} будет указан номер сервопривода и длительность импульса, который будет на него подан. Строковая часть команда будет передана на /dev/servoblaster. После выполнения команды:
os.system(command)
сервопривод повернется на угол, соответствующий значению, которое определяется длительностью импульса.
При запущенной службе servo.d(ServoBlaster), выводы GPIO, к которым подключен сервопривод и аудио разъём будут недоступны другим процессам. Если вам временно нужно "убить" ServoBlaster, чтобы получить доступ к выводам GPIO можете выполнить команду: sudo killall servod
Если вы хотите отключить ServoBlaster, то выполните следующую команду: sudo update-rc.d servoblaster disable
После чего потребуется перезагрузка: sudo reboot
Если вы захотите вернуть ServoBlaster, то выполните следующую команду: sudo update-rc.d servoblaster enable
После чего потребуется перезагрузка: sudo reboot
|
В данном примере мы использовали только один канал управления сервоприводом, но драйвер ServoBlaster позволяет задействовать все выводы GPIO. По умолчанию ServoBlaster поддерживает 8 каналов управления:
Канал сервопривода | Номер BCM |
---|---|
0 | 4 |
1 | 17 |
2 | 18 |
3 | 27 |
4 | 22 |
5 | 23 |
6 | 24 |
7 | 25 |
Необходимое оборудование
- плата Raspberry Pi - 1шт.;
- сервопривод - 1 шт.;
- пара перемычек;
- макетная плата;
- резистор 1кОм(необязательно) - 1шт.;
- блок питания на 5В(необязательно) - 1шт.;
Схема
Будьте осторожны при обращении с портами GPIO вашего Raspberry Pi. Помните входы и выходы GPIO расссчитаны на напряжение +3,3В |
Резистор в схеме необязателен и установлен для защиты контакта от скачков управляющих сигналов.
Все манипуляции по подключению производите только при отключенном питании платы Raspberry Pi |
Код
Python 2.X
from Tkinter import *
import os
import time
servo_min = 500 # uS
servo_max = 2500 # uS
servo = 2 # GPIO 18
def map(value, from_low, from_high, to_low, to_high):
from_range = from_high - from_low
to_range = to_high - to_low
scale_factor = float(from_range) / float(to_range)
return to_low + (value / scale_factor)
def set_angle(angle):
pulse = int(map(angle, 0, 180, servo_min, servo_max))
command = "echo {}={}us > /dev/servoblaster".format(servo, pulse)
os.system(command)
class App:
def __init__(self, master):
frame = Frame(master)
frame.pack()
scale = Scale(frame, from_=0, to=180,
orient=HORIZONTAL, command=self.update)
scale.grid(row=0)
def update(self, angle):
set_angle(float(angle))
root = Tk()
root.wm_title('Servo Control')
app = App(root)
root.geometry("200x50+0+0")
root.mainloop()
Python 3.X
from tkinter import *
import os
import time
servo_min = 500 # uS
servo_max = 2500 # uS
servo = 2 # GPIO 18
def map(value, from_low, from_high, to_low, to_high):
from_range = from_high - from_low
to_range = to_high - to_low
scale_factor = float(from_range) / float(to_range)
return to_low + (value / scale_factor)
def set_angle(angle):
pulse = int(map(angle, 0, 180, servo_min, servo_max))
command = "echo {}={}us > /dev/servoblaster".format(servo, pulse)
os.system(command)
class App:
def __init__(self, master):
frame = Frame(master)
frame.pack()
scale = Scale(frame, from_=0, to=180,
orient=HORIZONTAL, command=self.update)
scale.grid(row=0)
def update(self, angle):
set_angle(float(angle))
root = Tk()
root.wm_title('Servo Control')
app = App(root)
root.geometry("200x50+0+0")
root.mainloop()