树莓派5控制SG90舵机

/ 默认分类 / 0 条评论 / 242浏览

一、舵机知识回顾

复习了一下舵机的基础原理和控制方式。

1. 什么是舵机?

舵机是一种可以精准控制转动角度的小型电机,在机器人、模型飞机、摄像头云台等场景中应用非常广泛。我使用的是 SG90,这是一种微型模拟舵机。

SG90 的几个基本特性:

2. 舵机的工作原理

SG90 每秒接收 50 次 PWM 信号(周期为 20ms)。每个信号中,高电平持续的时间决定了舵机要转到的角度。

对应关系大概如下:

占空比是指高电平在整个周期中所占比例:

这个原理后面在代码中会具体用到。

下面这张图会更加形象:

二、准备工作

这里我整理了控制舵机需要准备的所有材料,并梳理了接线方案。

1. 材料清单

2. SG90 舵机引脚说明

舵机有三根引线,接线如下:

| 引脚颜色 | 功能 | 对应连接 | | --- | --- | --- | | 棕色 | GND | 接树莓派 GND | | 红色 | VCC | 接 5V 电源(建议外接) | | 橙色 | PWM信号 | 接树莓派 GPIO18(BCM) |

我选择了 GPIO18,是因为它支持硬件 PWM,控制精度更好。主要是便宜!!!

三、GPIO 和 PWM 基础

我重新了解了下树莓派 GPIO 的基础知识。树莓派的 GPIO 引脚可以通过 Python 脚本输出高低电平,实现控制舵机的 PWM 信号。

两种常见的引脚编号方式:

我这次使用的是 BCM 编号,也就是 GPIO18。

树莓派的几个 GPIO(比如 12、13、18)支持硬件 PWM,使用它们控制舵机更加稳定。

四、安装开发环境

我已经用 pip 安装好了两个常用的库:RPi.GPIO 和 gpiozero。

安装命令如下:

sudo apt update
sudo apt install python3-pip
pip3 install RPi.GPIO gpiozero

RPi.GPIO 提供更底层的控制方式,gpiozero 更简单一些,适合快速上手。

五、Python 控制舵机代码

接下来我测试了两种方式控制 SG90,一个是用 RPi.GPIO,另一个是用 gpiozero。

1. 用 RPi.GPIO 控制 SG90

import RPi.GPIO as GPIO
import time

servo_pin = 18  # 使用 GPIO18

GPIO.setmode(GPIO.BCM)
GPIO.setup(servo_pin, GPIO.OUT)

pwm = GPIO.PWM(servo_pin, 50)  # 50Hz 的 PWM 信号
pwm.start(0)

def set_angle(angle):
    duty = 2 + (angle / 18)
    GPIO.output(servo_pin, True)
    pwm.ChangeDutyCycle(duty)
    time.sleep(0.5)
    GPIO.output(servo_pin, False)
    pwm.ChangeDutyCycle(0)

try:
    while True:
        for angle in [0, 90, 180, 90]:
            set_angle(angle)
            time.sleep(1)

except KeyboardInterrupt:
    pwm.stop()
    GPIO.cleanup()

2. 用 gpiozero 控制 SG90

from gpiozero import Servo
from time import sleep

servo = Servo(18, min_pulse_width=0.5/1000, max_pulse_width=2.5/1000)

while True:
    servo.min()  # 对应 0°
    sleep(1)
    servo.mid()  # 对应 90°
    sleep(1)
    servo.max()  # 对应 180°
    sleep(1)

这个方式很简洁,不过背后还是封装了 PWM 信号。

六、调试中遇到的问题和总结

在测试过程中我遇到了一些问题,也做了排查和记录。

| 问题描述 | 排查与解决方法 | | --- | --- | | 舵机不动 | 电源不够稳定,接了外接 5V 电源就解决了 | | 舵机轻微抖动 | 加上 pwm.ChangeDutyCycle(0),让电机休息 | | 舵机角度不准确 | 调整角度转占空比的公式 | | 舵机发热严重 | 加了 sleep 延时,每次转动后让它冷却一下 |