Python 使用 Python 控制伺服系统详解

在数字技术兴起之前,模拟仪表和仪器是显示数据的唯一方式。一旦转向数字,模拟仪表就不再流行了。随着时间的数字显示成为常态,学习用模拟时钟计时的一代人可能会突然发现这项技能已经过时

在本章中,我们将根据数字值改变伺服电机的位置,从而弥合数字世界和模拟世界之间的鸿沟。

本章将介绍以下主题:

读者需要掌握 Python 编程语言的实用知识才能完成本章。必须具备使用简单的试验板连接部件的知识。

在本项目中,我们将连接伺服电机和 LED,并使用GPIO Zero库对其进行控制。我们将首先在烧结中设计电路,然后组装它。

我们将开始使用 pythonshell 控制伺服。

最后,我们将通过创建一个 Python 类来扩展这方面的知识,该类将根据百分比量打开伺服电机,并根据传递给该类的数字打开、关闭或闪烁 LED。

这个项目需要大约 2 小时才能完成。

为完成本项目,需要以下各项:

  • Raspberry Pi 3 型(2015 型或更新型)
  • USB 电源
  • 计算机显示器
  • USB 键盘
  • USB 鼠标
  • 小型伺服电动机
  • 试验板
  • LED(任何颜色)
  • 用于试验板的跨接导线

这个项目包括连接伺服电机到我们的 Raspberry Pi。许多人把伺服电机与步进电机和直流电机混为一谈。让我们来看看这些类型的马达之间的差异。

步进电机是无刷直流电机,能够以相等的步数旋转一整圈。电机的位置控制无需使用反馈系统(开环系统)。这使得步进电机相对便宜,并且在机器人、3-D 打印机和 CNC 类型应用中广受欢迎。

以下是步进电机内部工作原理的简图:

通过依次打开和关闭线圈AB,旋转永磁体(附在电机轴上)。使用精确的步数,可以精确控制电机,因为步数很容易控制。

步进电机往往比其他类型的小型电机更重、更笨重。

下图显示了 3D 打印机中使用的典型步进电机:

直流电机类似于步进电机,但不会将运动分成相等的步长。它们是第一个被广泛使用的电动机,并且在电动汽车、电梯和任何其他不需要精确控制电动机位置的应用中使用。直流电机可以是刷式或无刷式。

Brushed motors are simpler to operate, but have limitations on revolutions per minute (RPM) and usage life. Brushless motors are more complicated, and require electronics for control—for example, the Electronic Speed Controllers (ESCs) used on some drones. Brushless motors may be operated at a much higher RPM, and have a longer usage life than brushed motors.

直流电机的响应时间比步进电机短得多,并且比可比的步进电机更轻。

以下是典型的小型有刷直流电机的照片:

伺服电机使用闭环反馈机制,以提供极其精确的电机位置控制。它们被认为是步进电机的高性能替代品。范围可能因伺服系统而异,有些伺服系统限制为 180 度移动,而另一些伺服系统可以移动 360 度。

Closed-loop control systems, unlike open-loop control systems, maintain an output by measuring the actual condition of the output, and comparing it to the desired outcome. Closed-loop control systems are often called feedback control systems, as it is this feedback that is used to adjust the condition.

伺服的角度由传递到伺服上控制销的脉冲决定。不同品牌的伺服具有不同的最大值和最小值来确定伺服针的角度。

以下为p**脉冲宽度调制**PWM与 180 度伺服位置关系示意图:

下面是我们将用于电路的小型伺服电机的照片。我们能够将此伺服直接连接到我们的 Raspberry Pi(对于较大的伺服,这可能不可能):

以下是伺服颜色代码的图表:

我们的电路将由一个简单的伺服和 LED 组成。

以下是电路的烧结图:

我们联系:

  • 伺服的正电源连接到 5V 直流电源,接地连接到 GND
  • 从伺服到 GPIO 17 的控制信号
  • LED 的正极端连接到 GPIO 14,电阻器连接到 GND

确保使用小型伺服电机,因为大型伺服电机可能需要比 Raspberry Pi 提供的功率更多的功率。电路应类似于以下内容:

现在我们的伺服已经连接到 Raspberry Pi,让我们在命令行编写一些代码来控制它。我们将使用 Raspberry Pi Python 库GPIO Zero来实现这一点。

加载 Thonny 并单击 Shell:

在 shell 中键入以下内容:

from gpiozero import Servo

短暂延迟后,光标应返回。我们在这里所做的是将servo对象从gpiozero加载到内存中。我们将使用以下语句分配 pin GPIO17

servo = Servo(17)

我们现在将伺服电机移动到最小(min位置。在命令行中键入以下命令:

servo.min()

您应该听到伺服电机移动,打捆针将移动到其最远的位置(如果尚未移动)。

让我们用以下命令将伺服电机移动到最大(max位置:

servo.max()

现在,使用以下命令将伺服移动到中间(mid位置:

servo.mid()

伺服电机应移到中间位置。

当您将手放在伺服电机上时,可能会感觉到轻微的抖动。要临时禁用伺服控制,请在命令行中键入以下内容并按 Enter 键:

servo.detach()

抖动运动应停止,连接到伺服的指针指示器应保持在其当前位置。

我们可以看到,将伺服电机移动到其最小、中间和最大值非常容易。但是,如果我们想对伺服系统进行更精确的控制,该怎么办?对于这些实例,我们可以使用servo对象的 value 属性。可使用介于-1(最小值)和1(最大值)之间的值移动伺服电机。

在命令行中键入以下命令:

servo.value=-1

servo应移动到其最小位置。现在,键入以下内容:

servo.value=1

servo现在应该移动到其最大位置。让我们使用 value 属性来指示天气条件。在命令行中键入以下命令:

weather_conditions = {'cloudy':-1, 'partly cloudy':-0.5, 'partly sunny': 0.5, 'sunny':1}

使用以下步骤在 shell 中测试代码:

weather_conditions['partly cloudy']

您应该在 shell 中看到以下内容:

-0.5

使用我们的servo对象和weather_conditions字典,我们现在可以使用伺服电机物理指示天气状况。在外壳中键入以下内容:

servo.value = weather_conditions['cloudy']

伺服电机应移动到最小位置,以指示天气条件为cloudy。现在,让我们试试sunny

servo.value = weather_conditions['sunny']

伺服应移动到最大位置,以指示sunny天气状况。

对于partly cloudypartly sunny条件,使用以下各项:

servo.value = weather_conditions['partly cloudy']
servo.value = weather_conditions['partly sunny']

杰瑞·宋飞曾经开玩笑说,我们需要知道的关于天气的一切就是:我们到底要不要带件外套?在本章的其余部分和下一章中,我们将构建一个模拟仪表指针仪表板,以指示天气条件所需的衣橱。

我们还将添加一个 LED,它将点亮以指示需要雨伞,并闪烁以指示非常恶劣的风暴

第 6 章中搭建仪表板之前,使用伺服控制代码控制模拟设备,我们需要控制伺服和 LED 的代码。我们将从创建一个类开始。

本课程将在我们的电路上设置伺服位置和 LED 状态:

  1. 从应用程序菜单|编程| Thonny Python IDE 打开 Thonny

  2. 单击新建图标创建一个新文件

  3. 键入以下内容:

from gpiozero import Servo
from gpiozero import LED

class WeatherDashboard:

    servo_pin = 17
    led_pin = 14

    def __init__(self, servo_position=0, led_status=0):      
        self.servo = Servo(self.servo_pin)
        self.led = LED(self.led_pin)      
        self.move_servo(servo_position)
        self.set_led_status(led_status)

    def move_servo(self, servo_position=0): 
        self.servo.value=self.convert_percentage_to_integer
        (servo_position)

    def set_led_status(self, led_status=0):       
        if(led_status==0):
            self.led.off()
        elif (led_status==1):
            self.led.on()
        else:
            self.led.blink()

    def convert_percentage_to_integer(self, percentage_amount):
        return (percentage_amount*0.02)-1

if __name__=="__main__":
    weather_dashboard = WeatherDashboard(50, 1)
  1. 将文件另存为WeatherDashboard.py
  2. 运行代码
  3. 您应该看到伺服移动到中间位置,LED 应该亮起

尝试其他值,看看是否可以将伺服移动到 75%并使 LED 闪烁。

让我们看一下代码。定义类后,我们为伺服和 LED 设置 GPIO 引脚值,如下所示:

servo_pin = 17
led_pin = 14

正如您在我们构建的电路中所看到的,我们连接了伺服,并分别连接到 GPIO17和 GPIO14GPIO Zero允许我们轻松分配 GPIO 值,无需样板代码。

在我们的类初始化方法中,我们分别创建了名为servoledServoLED对象:

self.servo = Servo(self.servo_pin)
self.led = LED(self.led_pin) 

从这里,我们调用类中移动伺服和设置 LED 的方法。让我们看一下第一种方法:

def move_servo(self, servo_position=0): 
        self.servo.value=self.convert_percentage_to_integer
        (servo_position)

在这个方法中,我们只需在servo对象中设置 value 属性。由于此属性只接受从-11的值,并且我们正在将一个值从0传递到100,因此我们需要转换我们的servo_position。我们采用以下方法:

def convert_percentage_to_integer(self, percentage_amount):
    return (percentage_amount*0.02)-1

In order to convert a percentage value to a -1 to 1 scale value, we multiply the percentage value by 0.02, and then subtract 1. It's easy to verify this math by using the percentage value of 50. The value of 50 represents the middle value in a 0 to 100 scale. Multiplying 50 by 0.02 produces the value of 1. Subtracting 1 from this value produces 0, which is the middle value in a -1 to 1 scale.

要设置 LED 的状态(offonblink,我们从初始化方法调用以下方法:

def set_led_status(self, led_status=0):       
    if(led_status==0):
        self.led.off()
    elif (led_status==1):
        self.led.on()
    else:
        self.led.blink()

set_led_status中,如果传入的值是0,我们将 LED 设置为off,如果传入的值是1,我们将 LED 设置为on,如果传入的值是1,我们将 LED 设置为blink,如果传入的值是任何其他值,我们将 LED 设置为off

我们使用以下代码测试我们的类:

if __name__=="__main__":
    weather_dashboard = WeatherDashboard(50, 1)

第 6 章中,我们将使用伺服控制代码来控制模拟设备,我们将使用此类来构建我们的模拟天气仪表板。

正如我们所看到的,使用 Raspberry Pi 可以相对容易地弥合数据显示的数字世界和模拟世界之间的差距。其 GPIO 端口允许轻松连接到各种输出设备,如电机和 LED。

在本章中,我们连接了伺服电机和 LED,并使用 Python 代码控制它们。我们将在第 6 章中对此进行扩展,使用伺服控制代码控制模拟设备,因为我们构建了带有模拟仪表显示屏的物联网天气仪表板。

  1. 对还是错?步进电机采用开环反馈系统控制。
  2. 如果你要造一辆电动汽车,你会用什么类型的电动机?
  3. 对还是错?伺服电机被认为是步进电机的高性能替代品
  4. 什么控制伺服电机的角度?
  5. 正确或错误?直流电机的响应时间比步进电机短。
  6. 我们使用哪个 Python 包来控制伺服?
  7. 对还是错?我们可以使用 Thonny 中的 Python shell 控制伺服
  8. 哪个命令用于将伺服移动到其最大位置?
  9. 对还是错?我们只能将伺服移动到其最小、最大和中间位置。
  10. 我们如何将百分比值转换为servo对象在代码中理解的相应值?

GPIO Zero文档提供了这个惊人的 Raspberry Pi Python 库的完整概述。更多信息请访问https://gpiozero.readthedocs.io/en/stable/

教程来源于Github,感谢apachecn大佬的无私奉献,致敬!

技术教程推荐

邱岳的产品手记 -〔邱岳〕

设计模式之美 -〔王争〕

说透敏捷 -〔宋宁〕

软件设计之美 -〔郑晔〕

TensorFlow 2项目进阶实战 -〔彭靖田〕

如何看懂一幅画 -〔罗桂霞〕

PyTorch深度学习实战 -〔方远〕

大厂广告产品心法 -〔郭谊〕

云时代的JVM原理与实战 -〔康杨〕