如何用Raspberry Pi Pico W和脉冲宽度调制(PWM)来控制伺服机
伺服机是学习使用Raspberry Pi的脉冲宽度调制的最基本方法之一。
让我们来学习如何用Raspberry Pi Pico W做这件事。
PWM教程的目标

- 学习如何使用PWM来控制伺服机的角度
- 用Pico W建立一个服务器
- 服务器提供带有滑块的网页来控制伺服系统
需要的零件
- 带头盔的树莓派Pico W
- 跳线
- 舵机(我们使用的是Tower Pro SG90微型舵机)
什么是脉冲宽度调制?
孩子们觉得反复开关灯很有趣。
对他们来说,当他们拨动电灯开关时,看到灯光忽明忽暗,真是太有趣了。父母可能不觉得有趣,但这为我们所有人提供了一个学习的机会。
如果你或你的孩子做过这样的事,那么你就经历了一种原始形式的脉冲宽度调制。
有了Raspberry Pi,你可以很容易地以自动化的方式实现这一目标。从本质上讲,你可以告诉Raspberry Pi你希望在一个特定的时期内有多少次 "打开"。
这使你可以调暗LED。

同样,这也允许你控制伺服机臂的角度。
一个重要的PWM概念:占空比
占空比基本上是指电路保持 "高 "的时间,这意味着它被打开。
所以,假设你的电路有一半的时间是开着的。因此,我们可以说,占空比为50%。
如果你让它一直开着,它的占空比将是100%,反之亦然,一直关闭意味着0

回到孩子以常规速度开灯和关灯的例子,灯没有完全亮起或完全变暗的原因是我们只在特定的时间内提供电压输出。
对于LED来说,这意味着LED被点亮一段时间,然后拉开电源,然后再次送电,如此反复。
因此,LED永远不会有足够的亮度来达到其全部亮度,也没有足够的时间来完全变暗。
带PWM的SG90伺服控制
我们在这里要谨慎,因为不是所有的舵机都以同样的方式操作。本教程是专门针对Tower Pro SG90微型舵机的。
SG90有一个180度的旋转,但有些伺服机是120度的伺服机。无线电控制爱好者的舵机最有可能是120度的舵机,所以一定要检查你想操纵的舵机的数据表,因为如果你给它一个超范围的信号,就有可能损坏舵机。
这是SG90的数据表,来自Luxor Parts。

数据表告诉你两件重要的事情:哪种颜色对应于正极、地极和信号,以及脉冲频率/工作周期。
- 棕色=负数
- 红色 = 正面
- 橙色=信号
而对于脉冲频率/工作周期
- 你将需要有一个20ms或50Hz的占空比。
- 一个1ms的信号=零度
- 一个2ms的信号=180度的旋转

这意味着,每隔一毫秒,伺服机就会寻找一次更新。如果你继续向它发送2ms的信号,它将保持全速旋转(180度)。如果你把它改为1.5ms,它将旋转90度,而在1ms时,它将旋转0度。

将伺服机与Pico W连接起来
为了使用我们的代码,你必须将 信号线到GPIO 0.信号线是SG90上的橙色线。
然后,将红线连接到 呼叫中心 (这给你提供了5V的电压)。你可以从数据表中看到,SG50的工作电压是4.8V到6V,所以Pico W上的3.3V引脚无法工作。
对Pico W的伺服控制进行编码
你可以 在这里找到代码 在我们的Github上。
让我们来看看这段代码。
在 main.py,这是我们想在启动时运行的文件的命名规则,我们为伺服机创建一个类并将其实例化。
class Servo:
def __init__(self, MIN_DUTY=300000, MAX_DUTY=2300000, pin=0, freq=50):
self.pwm = machine.PWM(machine.Pin(pin))
self.pwm.freq(freq)
self.MIN_DUTY = MIN_DUTY
self.MAX_DUTY = MAX_DUTY
def rotateDeg(self, deg):
if deg < 0:
deg = 0
elif deg > 180:
deg = 180
duty_ns = int(self.MAX_DUTY - deg * (self.MAX_DUTY-self.MIN_DUTY)/180)
self.pwm.duty_ns(duty_ns)
servo = Servo()
伺服类使用MicroPython中的machine.PWM类。 请看这里的文件。
在这个例子中,我们将Pico W作为一个接入点使用。下面是实现这一目的的代码。
ssid = 'Servo-Control'
password = 'PicoW-Servo'
ap = network.WLAN(network.AP_IF)
ap.config(essid=ssid, password=password)
ap.active(True)
while ap.active() == False:
pass
print('Connection successful')
print(ap.ifconfig())
从前两行可以看出,你要找的SSID是 伺服控制 而密码是 PicoW-Servo.
一旦你签入了WiFi网络,你就可以去查Pico W的IP地址,默认情况下是192.168.4.1。另外,你也可以查看Thonny上的日志,看看你的Pico的IP地址是什么。
网页如何与伺服机进行通信?

当你登录到Pico W的IP地址时,你会收到index.html文件,该文件可以在Github repo上找到。
index.html文件有这些重要的行。
<form id="form">
<input type="range" class="slider" min="0" max="180" value="slider_value" name="servo" id="servo">
<output></output>
</form>
正如你所看到的,有一个对象,是滑块。
还有一个,显示旋转的程度。
JavaScript部分更新了以及更新了URL,以便Pico W能够捕获数据并旋转伺服。
和元素都有一个父元素。
这是在前端的脚本。
<script>
let i = document.getElementById('servo'),
o = document.querySelector('output');
o.innerHTML = i.value;
i.addEventListener('input', function () {
o.innerHTML = i.value;
}, false);
i.addEventListener('change', function () {
document.getElementById("form").submit();
}, false);
</script>
你会注意到这里有两个EventListeners。当你与滑块互动时,它触发了对字段的更新,也导致的提交。
当被提交时,它会导致URL有一个参数 "servo=[度]"。例如,如果你把滑块拉到180,它将是 "index.html?servo=180"。
这个参数被Pico W的后台(main.py)捕捉到,经过处理,找到用户指定的度数,然后将 旋转度 方法被调用。
index = request.find('servo=') + len('servo=')
if request[index].isdigit():
offset = 1
if request[index+1].isdigit():
offset = 2
if request[index+2].isdigit():
offset = 3
deg = int(request[index:index+offset])
print(deg)
servo.rotateDeg(deg)
实际用途
伺服机是一个非常重要的机械工具,因为它可以在许多场合使用。事实上,即使是像机器人手臂这样复杂的项目,也是由许多舵机协同工作组成的。
你现在可以建立一个关闭你卧室灯光的项目。

另一方面,你也可以建造谷物分类器。 像这样的小分拣机,使用人工智能和一个微控制器制作。

如果你仔细观察顶部的鹅眼位置,后面有一个SG90伺服机。