Raspberry Pi:Примеры/Управление сервоприводом с применением ServoBlaster

Материал из Онлайн справочника
Перейти к навигацииПерейти к поиску

Проверка/Оформление/Редактирование: Мякишев Е.А.


Черновик


Управление сервоприводом с применением 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

Необходимое оборудование

Схема

Будьте осторожны при обращении с портами 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()

См.также

Внешние ссылки