本文由 简悦 SimpRead 转码, 原文地址 zhuanlan.zhihu.com
2021 年 1 月底的时候,树莓派基金会发布了一个重磅消息,推出了进军微控制器领域的树莓派 Pico。
功能强劲,价格便宜的特性让 Pico 受到了全世界创客们的关注,这篇文章就来给大家介绍一下 Pico 这个小玩意儿。
文章原文来自 DroneBot Workshop,负责人是一个非常和蔼的老爷爷。有条件的小伙伴可以去油管关注一下他。
这篇文章使用 MicroPython 在树莓派 Pico 上编程,一起来看看三十块的微控制器究竟能做些什么。
【熟肉】目前全网最详细的树莓派 Pico 入门指南来了!边看还能边学英语!| 硬核分享_哔哩哔哩 (゜ - ゜) つロ 干杯~-bilibili
介绍
树莓派基金会发布微控制器本身就是一个大消息,毕竟在这之前,这个世界上最流行的单板电脑的制造商从来没有表示过对微控制器的兴趣。
不仅仅是树莓派 Pico 的公布让人感到意外,这次树莓派还自己打造了一款新的芯片。他们没有在现有代码的基础上,支持基于 ESP32 或 SAMD21 的设计,而是选择创建自己的微控制器。
所以谈到 Pico 时,我们都是新手。
树莓派也在官网发布了一大堆技术文档,还有一本名为《Get Started with MicroPython on Raspberry Pi Pico》的说明书。它有纸质版,也有 PDF 版下载。
除此之外,目前还没有关于 Pico 更深入的资料。不过随着时间的推移,这种情况很快就会改变,树莓派已经授权包括 Adafruit 在内的其他厂商在自己的设计中使用 RP2040 芯片。假以时日,就会给我们带来更多的代码和开发工具。
我们先来尝试一下,给 Pico 连接上一堆东西,会发生什么有趣的事情吧!
树莓派 Pico
Pico 是一块小小的板子,大小和 Arduino Nano 差不多。和所有树莓派一样,包装非常简陋,只是一个塑料包装内的 Pico,而塑料包装本身就是从一条条的包装上剪下来的,非常像小时候吃的咪咪虾条或者是糖果的包装。
看看 Pico 的板子
四刀买到的就仅仅是这么一款裸板,没有多的,就是这么环保。
裸板不带针脚,需要自己焊。这是一块做工精良的电路板,也可以作为 SMD 元件,直接焊接到印刷电路板上。
俯视图
从顶部看,Pico 是这样的。
板上最主要的功能是一端的 microUSB 连接器。它既用于通信,也用于给 Pico 供电。
在 microUSB 连接器旁边安装了一个板载 LED,它内部连接到 GPIO 针脚 25。
值得注意的是,这是整个 Pico 板上唯一的 LED。
开机按钮安装在离 LED 稍低一点的地方,它可以让你改变 Pico 的启动模式,这样你就可以在上面加载 MicroPython,进行拖拽式编程。
在板子的底部,你会看到三个连接点,这些连接点是用于串行 Debug 选项的,我们今天是入门,暂时不探讨这个问题,高级开发者会比较感兴趣。
在板子的中央是整个板子的 “大脑”——RP2040 MCU,我们一会儿就会研究它的功能。
接地引脚
板子上有好几个地线,8 个地线加上 3 针 Debug 连接器上的一个附加地线。
这些引脚很容易发现,它们是均匀的,而且是方形的,而不是像其他连接的圆形。
其中一个位于 33 号针脚的地线也被指定为模拟地线。
电源引脚
Pico 是一个 3.3V 的逻辑器件,但由于内置了电压转换器和稳压器,它可以用一系列电源供电。
所有与电源相关的引脚都被安排在了一起,靠近 microUSB 连接器。
- VBUS - 这是来自 microUSB 总线的电源,5 V。如果 Pico 不是由 microUSB 连接器供电,那么这里将没有输出。
- VSYS - 这是输入电压,范围为 2 至 5 V。板载电压转换器将为 Pico 将其改为 3.3 V。
- 3V3 - 这是 Pico 内部调节器的 3.3 伏输出。只要将负载保持在 300ma 以下,它就可用于为其他组件供电。
还有几个输入可以让你控制 Pico 的电源。
- 3V3_EN - 你可以使用此输入禁用 Pico 的内部电压调节器,从而关闭 Pico 和由其供电的任何组件。
- RUN - 可以启用或禁用 RP2040 微控制器,也可以将其复位。
GPIO 引脚
树莓派 Pico 板上有 26 个裸露的 GPIO 连接。
它们的排列顺序很好,在 GPIO 22 和 GPIO 26 之间有一个 "空隙"(这些 "缺失" 的引脚在内部使用)。
这些引脚都有多种功能,你可以为 PWM 配置多达 16 个引脚。
有两个 I2C 总线,两个 UART 和两个 SPI 总线,这些可以配置使用多种 GPIO 引脚。
模拟引脚
Pico 有三个模数转换器,还有一个内部用于板载温度传感器的转换器。
ADC 的分辨率为 12 位。
你也可以在ADC_VREF
引脚上提供一个外部精密电压参考。其中一个接地点,即 33 脚上的 ADC_GND 被用作该参考点的接地点。
RP2040 微控制器
树莓派 Pico 是围绕基金会的新芯片 RP2040 微控制器而设计的。下面是它的参数:
- 双核 32 位 ARM Cortex -M0 + 处理器
- 运行在 48MHz,但可以超频到 133MHz。
- 30 个 GPIO 引脚 (26 个暴露)
- 可支持 USB 主机或设备模式
- 8 可编程 I/O(PIO)状态机
RP2040 能够支持高达 16MB 的片外闪存,不过在 Pico 中只有 4MB。
树莓派基金会对这款芯片有很多计划,也已经授权给了很多其他厂商。
对 Pico 进行编程
你可以使用两种编程语言之一开始使用 Pico。
- MicroPython - 一种专门为微控制器制作的解释语言。
- C++ - 许多微控制器用户都熟悉 C++,因为它被用于 Arduino 和 ESP32 板上。
虽然我急于将 C++ 与 Pico 一起使用,以榨取它的每一克性能,但还是决定与大多数人一样,使用 MicroPython。在这个早期的开发阶段,C++ 的工具还在进行最后的开发,期待着 Pico 成为 PlatformIO 和 Arduino IDE 板系列的一部分。
开始使用 Pico
当我们拿到 Pico 板时,它被包装在一个塑料载体中,没有额外的零件。
除非你有计划将 Pico 表面贴装,或者你的唯一目的是只是点个灯,否则我们都需要一些引脚。
Pico 有 40 个引脚,每侧 20 个。另外三个针脚用于调试端口。
标准的公头针脚有 40 个针脚带,因此可以将其中一个针脚带减半,作为 Pico 的针脚使用。如果你想在 Debug 连接器上安装针脚,你需要另一个 3 针的公头,可以是直的或 90 度的。
焊接一个 Pico
在开始对 Pico 进行编程之前,我们需要进行一些焊接工作!除了杜邦公头引脚之外,我们还需要合适的烙铁和一些焊料。
电烙铁的头需要精细一点,我们还需要一块清洁海绵和一个支架。
此外,我们还需要想办法在焊接 Pico 引脚时把它固定住,因为它们需要以精确的 90 度角安装到电路板上,这样才能装入无焊料面包板。
许多实验都使用无焊面包板来固定引脚,虽然这种方法可行,但有可能因热力或焊料飞溅而损坏面包板。
所以最好的解决方法是,你有一块老旧的面包板,用它作为针座。
我个人喜欢用几块便宜的灌注板、打孔实验板。我说的 "便宜" 是指单面的东西,没有排孔,只有一面是裸铜的。
两片这种东西很适合固定引脚,每当要焊接一个小模块或者单片机的时候,我就经常用这个。
把电烙铁加热到一定温度,然后加热引脚与焊盘的连接处,在另一面涂上焊料,千万不要直接涂到电烙铁上。加热零件,而不是焊料。
如果你想焊接 Debug 的 3 个引脚连接器(这是可选的),你可能应该先做。这些引脚的方向与 GPIO 引脚的方向相反。我用了一个小的便签垫来固定电路板,因为 Debug 连接器与 GPIO 引脚在网格上并不一致。
之后就是焊接 40 个引脚了,一次 20 个! 真的不需要太长的时间,只需要用尽可能多的焊料,避免出现焊桥,完成后再检查一下。
焊接后清理 Pico
我喜欢在焊接完我的 PCB 后清洗它们,以去除焊料核心中的助焊剂和树脂。它表现为焊接连接处周围的褐色污渍。
这一步完全是可有可无的,因为助焊剂和树脂对元件的运行或寿命没有任何不利影响。它只是看起来更好看!
如果你想克隆你的板子,你需要一些 PCB 板清洗剂或 Flus Remover。由于它也往往会留下一点残留物,我用异丙醇来清理。
PCB 板清洗剂可以到网上购买。异丙醇可以在当地药店找到,一定要买纯酒精和水的混合物(70%),不要买有香味的。
我用一把旧牙刷和一些塑料容器,在一个盆子里进行工作。记得最好要准备好口罩、手套和护目镜。
我用牙刷蘸 PCB 清洁剂擦洗引脚,然后用牙刷蘸异丙醇冲洗。
让板子自然风干,也可以使用空气软管,这样之后,我们将拥有一个闪闪发光的新 Pico!
Pico 和 Thonny IDE
现在 Pico 的引脚已经连接好了,我们可以开始对它进行实验了。
建议你把它放在一个无焊的面包板上,以迎接我们即将到来的实验。
虽然有许多 IDE 可以让我们选择与我们的新 Pico 一起工作,但我的建议是使用树莓派推荐的 Thonny IDE。
Thonny IDE
Thonny 自称是 "Python IDE for Beginners",它适用于 Windows、Mac OSX 和 Linux。
它也是树莓派操作系统 (以前的 Raspbian) 的一部分。
我将在树莓派操作系统上使用 Thonny IDE,运行在 8GB 的树莓派 4 上,作为我今天实验的开发平台。当然,你可以使用任何你能运行 Thonny 的平台,但我想让它在树莓派家族中运行 -- 另外,由于 Thonny 已经安装在新构建的树莓派操作系统上,所以上手非常简单。
启动和安装 MicroPython
我们需要做的第一件事是将 MicroPython 安装到 Pico 上。
将 microUSB 连接到 Pico 上,并准备将另一端插入电脑。在插入之前,先按下 Pico 上的 Boot Select(开关)按钮。
按住 BOOTSEL 键,将 Pico 插入电脑的 USB 端口。按住 BOOTSEL 键几秒钟,然后松开。
你应该会看到一个新的驱动器在你的电脑上可用,信息看起来会有所不同,这取决于你所使用的操作系统,但它类似于你将 U 盘插入电脑时得到的信息。
打开新的 "驱动器",你会看到一个名为 RPI-RP2
的文件夹。在这个驱动器里,你会看到几个文件,其中一个是网页文档index.htm
。
点击该网页文件,浏览器就会打开,你会被重定向到树莓派 Pico 入门页面。
点击 MicroPython 入门的标签。你会看到一个链接来下载一个 UF2 文件,这就是可下载的 MicroPython 文件。把这个文件下载到你的电脑上。
现在将下载的文件拖到 Pico 的 RPI-RP2 文件夹中。一旦这样做了,文件夹就会消失,Pico 将以 MicroPython 模式启动。
配置 Thonny IDE
在 Pico 仍然被连接的情况下,打开 Thonny IDE,如果你和我一样使用树莓派操作系统,你会在编程工具菜单下找到 Thonny。
一旦 Thonny 打开,请看右下角的状态栏,它可能会显示一个 Python 的版本。这是当前在你的计算机上运行的 Python 版本,对于我们的实验来说,这一点并不重要。
点击该消息,应该会出现一个下拉菜单,还有其他环境可以选择。其中一个应该是 MicroPython (树莓派 Pico)。选择那一个。
你会注意到底部打开了一个新的 Shell,在这个 Shell 中,你应该会看到一些文字,表明你已经连接到 Pico。
是时候开始编程了!
Shell 测试
Shell 是 Pico 的 "命令行",你可以直接在这里执行代码。
一个简单的测试是输入以下内容(这也是查看你是否正确连接到 Pico 的好方法),然后按 Enter 键。
print(“Hello World”)
你应该在 shell 中看到 "Hello World" 被打印出来了,当然这是你告诉 Pico 要做的。
脚本测试
当然,你不会直接在 shell 中输入你的程序,一来,一旦你执行了程序,它们就会消失,二来,对于任何相当大的程序来说,也是不方便的。
你要用编辑器来输入你的程序,也就是 shell 上面的大文本区域,在 Thonny IDE 的屏幕上占主导地位。
进入这个编辑器,输入和刚才一样的文字,用一个漂亮的 "你好" 来迎接编程世界。
点击 "运行" 按钮(绿色带箭头的那个),系统会提示你先保存程序。你可以选择将其保存在本地电脑或 Pico 上,尝试保存在 Pico 上。给你的程序起个带 ".py" 后缀的名字,比如 "hello.py"。
程序将被保存并运行,你将在 shell 中看到 "Hello World" 的问候语。你可以按 "运行" 按钮再次看到它,再按一次。
所以,现在你知道了如何编写和保存 MicroPython 程序,我们就可以开始我们的实验了!
使用 LED 和开关
基本的数字 I/O 功能可以很容易地用 LED 和开关来说明,这正是我们开始 Pico 冒险的方式。
但请注意我们如何给开关布线,我们将以不同的方式进行操作。
RGB LED
最简单的输出设备可能是 LED。当在正确的方向上施加足够的电流时,这种输出设备就会工作。虽然简单,但它可以用来说明 I/O 技术,这些技术可以应用于其他设备,如继电器或晶体管。
我将使用一个 Common-Cathode RGB LED,但你也可以使用三个分立的 LED 来代替。无论哪种方式,你都还需要三个降压电阻,我在实验中使用了 330 欧姆的电阻。
如果你选择像我这样使用 RGB LED,一定要买一个标准的 RGB LED,而不是一个可编程的。
按钮开关
这是最简单的输入设备。我用的是一对瞬时常开按钮开关
一个红色和一个黑色,但在其他方面是相同的。
我们再次使用一个简单的输入设备来测试我们的小 Pico 的 I/O 能力。我们将以不同的方式为两个开关布线,使其更加有趣,而且我们也不会使用任何上拉或下拉电阻。
LED 和开关的连接
这里是我们的 LED 和开关的连接图,请记住,如果你没有共阴极 RGB LED,你可以使用三个独立的 LED。
请注意,这两个开关的接线方式不同。
黑色按钮开关的一侧连接到 Pico 的 GPIO 引脚,另一侧连接到地。
红色开关则相反,它的一侧连接到 GPIO 引脚,另一侧连接到 3.3 伏,这是 Pico 的工作电压和逻辑电压。
经典项目——点灯
我们要做的第一个实验是我们自己的 Arduino "Blink" 草图的变体。是的,从技术上讲,我们已经看到了如何闪烁板载 LED,但由于我们现在有一个 RGB LED 在我们的支配下,我们当然可以找到另一种方法来点灯!
在 Thonny 中打开以下代码。
# 树莓派 Pico RGB Blink
# rgb-blink.py
# RED LED - Pico GPIO 10 - Pin 14
# GREEN LED - Pico GPIO 11 - Pin 15
# BLUE LED - Pico GPIO 14 - Pin 19
# DroneBot Workshop 2021
# https://dronebotworkshop.com
import machine
import utime
led_red = machine.Pin(10, machine.Pin.OUT)
led_green = machine.Pin(11, machine.Pin.OUT)
led_blue = machine.Pin(14, machine.Pin.OUT)
while True:
led_red.value(1)
led_green.value(0)
led_blue.value(0)
utime.sleep(2)
led_red.value(0)
led_green.value(1)
led_blue.value(0)
utime.sleep(2)
led_red.value(0)
led_green.value(0)
led_blue.value(1)
utime.sleep(2)
led_red.value(1)
led_green.value(1)
led_blue.value(0)
utime.sleep(2)
led_red.value(1)
led_green.value(0)
led_blue.value(1)
utime.sleep(2)
led_red.value(0)
led_green.value(1)
led_blue.value(1)
utime.sleep(3)
led_red.value(1)
led_green.value(1)
led_blue.value(1)
utime.sleep(2)
print("End of Loop")
led_red.value(0)
led_green.value(0)
led_blue.value(0)
utime.sleep(2)
这是一个简单的脚本,肯定可以改进,但它可以很好地说明我们的观点。
我们先导入 machine 和 utime 库。你会发现,任何涉及 I/O 端口的活动都需要用到 machine,而只要我们想使用时间函数,就需要用到 utime。
然后,我们定义三个 LED 元件的连接,请注意,它们是以 GPIO 编号而非 Pico 上的物理引脚编号来表示的。我们将所有这些引脚定义为 machinePin.OUT,这意味着这些引脚现在被设置为输出引脚。
while True 条件类似于 Arduino 草图中的 Loop,这里的代码是连续执行的。
在本节中,我们对 LED 进行寻址,并将它们设置为开(值为 1)或关(值为 0)。我们通过一个序列,在最后一个序列,我们打印到控制台。
然后我们再做一遍。
将脚本加载到 Pico 上,然后观察 LED,你应该会看到一个彩色的闪烁。
开关测试
我们接下来的脚本是对两个开关进行一个非常基本的测试,我们用这样一个奇怪的方式来接线。
你会观察到的第一件奇怪的事情是它们的接线不同,黑色的开关将输入端连接到地,而红色的开关将输入端连接到 3.3 伏,用于逻辑 HIGH。
另一个有趣的事情是,这两个开关都没有采用上拉或下拉电阻,它们显然需要这些电阻,黑色开关需要上拉,红色开关需要下拉才能正常工作。
我们将在代码中加入所需的电阻!
# 树莓派 Pico Switch Test
# switchtest.py
# RED BUTTON - Pico GPIO 15 - Pin 20
# BLACK BUTTON - Pico GPIO 2 - Pin 4
# DroneBot Workshop 2021
# https://dronebotworkshop.com
import machine
import utime
button_red = machine.Pin(15, machine.Pin.IN, machine.Pin.PULL_DOWN)
button_black = machine.Pin(2, machine.Pin.IN, machine.Pin.PULL_UP)
while True:
if button_red.value() == 1:
print("Red")
if button_black.value() == 0:
print("Black")
utime.sleep(0.25)
请注意定义按钮的行的语法,你会看到它们是如何被定义为 Inputs 的,以及如何添加了下拉和上拉电阻。
在 while True: 循环中,你还会注意到我们是在监测不同的条件,红色的开关触发了一个 HIGH 输入,而黑色的开关触发了一个 LOW。
最后的微小时间延迟是一种简单的 debouncing 形式,如果你喜欢,你可以实验一下这个值。
这个脚本会在控制台中打印所有的结果,所以在你按下按钮的时候要注意。
中断和切换
接下来的实验引入了几个有用的概念。第一个,也可以说是这两个概念中最重要的,就是 "中断"。
中断
中断就像它的声音一样,是一个 "中断" 程序正常流程的事件。在我们的情况下,我们处理的是外部硬件中断,这意味着在程序继续运行之前,需要处理一个信号或状态变化。
在 Pico 上,我们按照以下方式创建一个中断。
- 我们将一个引脚定义为 "中断输入", 我们定义该点上的状态变化被认为是一个中断。在 Pico 上,我们可以使用任何 GPIO 引脚来实现这一点,而且我们可以定义多个引脚。
- 我们创建了一个 "中断处理程序" 函数,我们希望在检测到中断时运行该函数。
- 我们将 "中断处理程序" 与 "中断输入" 配对。
现在,每当中断输入条件发生时,Pico 将停止它正在做的任何事情,并执行 "中断处理程序"。然后它将恢复到原来的位置。
切换
虽然不像中断那样基本,但仍然非常有用。“切换” 只是将 Pico 上的输出状态反转。
因此,如果输出为高电平,而我们应用 "切换",它就会变为低电平。
我们不需要知道输出的当前状态,我们只需要知道当我们应用一个切换器时,它将变为相反的状态。
自然,这是写另一个 Blink 程序的理想函数,所以我们会这么做。只有我们的 Blink 程序才会有被中断的风险!
# 树莓派 Pico Interrupt & Toggle Demo
# interrrupt-toggle-demo.py
# RED LED - Pico GPIO 10 - Pin 14
# GREEN LED - Pico GPIO 11 - Pin 15
# RED BUTTON - Pico GPIO 15 - Pin 20
# DroneBot Workshop 2021
# https://dronebotworkshop.com
import machine
import utime
led_red = machine.Pin(10, machine.Pin.OUT)
led_green = machine.Pin(11, machine.Pin.OUT)
led_red.value(0)
led_green.value(0)
button_red = machine.Pin(15, machine.Pin.IN, machine.Pin.PULL_DOWN)
def int_handler(pin):
button_red.irq(handler=None)
print("Interrupt Detected!")
led_red.value(1)
led_green.value(0)
utime.sleep(4)
led_red.value(0)
button_red.irq(handler=int_handler)
button_red.irq(trigger=machine.Pin.IRQ_RISING, handler=int_handler)
while True:
led_green.toggle()
utime.sleep(2)
在这个 MicroPython 脚本中,我们将闪烁我们的 RGB LED 的绿色部分,使用一个切换器来改变它的状态。在正常的操作下,LED 状态将每两秒钟切换一次。
然而,我们可以通过按下红色按钮来中断闪烁。这将导致一个中断,这将关闭绿色的 LED,然后打开红色的。它将保持四秒,之后程序控制权将被恢复,因此我们可以继续进行绿色闪烁。
我们通过导入machine
和utime
库来开始我们的脚本,就像我们之前一样。
LED 段和红色按钮的定义和之前的脚本一样。LED 在程序启动时被关闭。
然后我们定义一个函数,这是我们的中断处理程序,叫做 "int_handler"。在这个函数中,我们做了以下工作。
- 关闭中断,这样我们就不会有多个中断了。
- 将 "中断检测" 打印到 Shell 上
- 打开红色 LED 段。
- 关闭绿色 LED 段。
- 睡眠四秒。
- 关闭红色段。
- 重新建立中断
- 退出
处理函数后的那一行将中断 "粘" 到我们定义为红色按钮输入的引脚上。需要注意的是,它指定了 "IRQ_RISING",这意味着如果输入从 0(地)上升到 1(3.3 伏),它将触发一个中断。这与我们红色按钮的接线方式一致。
在 True 循环中,我们只需使用定义为输出的任何 GPIO 引脚可用的 "toggle" 功能来闪烁 LED。
将它发送到 Pico 上,观察 RGB LED,它应该开始闪烁绿色。观察一段时间,然后按下红色按钮。LED 应该变成红色,Shell 应该显示 "Interrupt Detected"。四秒钟后,绿色闪烁将重新开始。
开关和 LED 演示
既然我们一直在研究开关和 LED,我们不妨把它们结合起来,再编写一个简单的脚本。
# 树莓派 Pico Switch & RGB LED Demo
# switch-led-demo.py
# RED LED - Pico GPIO 10 - Pin 14
# GREEN LED - Pico GPIO 11 - Pin 15
# BLUE LED - Pico GPIO 14 - Pin 19
# BLACK BUTTON - Pico GPIO 2 - Pin 4
# DroneBot Workshop 2021
# https://dronebotworkshop.com
import machine
import utime
led_red = machine.Pin(10, machine.Pin.OUT)
led_green = machine.Pin(11, machine.Pin.OUT)
led_blue = machine.Pin(14, machine.Pin.OUT)
led_red.value(0)
led_green.value(0)
led_blue.value(0)
button_black = machine.Pin(2, machine.Pin.IN, machine.Pin.PULL_UP)
while True:
if button_black.value() == 0:
led_red.value(1)
led_green.value(0)
led_blue.value(0)
utime.sleep(1)
led_red.value(0)
led_green.value(1)
led_blue.value(0)
utime.sleep(1)
led_red.value(0)
led_green.value(0)
led_blue.value(1)
utime.sleep(1)
led_red.value(0)
led_green.value(0)
led_blue.value(0)
这个很简单,现在大家应该对它的操作很熟悉了。我们用machine
库函数定义 RGB LED 和黑色按钮。
记住,黑色按钮是由我们定义的上拉保持 HIGH 的,当按钮被按下时,它就会变 LOW,因为另一边是接地线的。
所以在 True 循环中,我们寻找一个 "0" 的值,以表示按钮被按下。一旦我们检测到这个条件,我们就会通过它们的颜色循环 LED 段。
正如我所说,很简单的东西。
模拟输入测试
现在我们来谈谈模拟输入。
树莓派 Pico 有三个模拟输入,它们都有 12 位的分辨率。
这三个输入端如下。
- GPIO 26 - ADC0 (31 针)
- GPIO 27 - ADC1 (针脚 32)
- GPIO 28 - ADC2 (针脚 34)
还有第四个 ADC 用于内部温度传感器。
电位计的连接
在我们的测试中,我们将使用一个电位器在模拟输入端呈现一个可变电压,然后我们将读取该电压。我们将使用 ADC0 作为我们的电位计输入,但你也可以使用其他两个中的一个。
请注意,虽然我将 23 号针脚显示为地线,这只是为了方便,但你可以使用任何 Pico 地线针脚。在 33 号针脚处还有一个特殊的模拟地,你可以使用。在我的面包板上,我将 33 号针脚与其他一些地线相连。
电位计读数
我们要做的第一个实验是简单地读取我们在模拟输入端得到的值,这个值应该根据我们电位器的位置而波动。
# 树莓派 Pico Analog Input Test
# analog-input.py
# POT - Pico GPIO 26 ADC0 - Pin 32
# DroneBot Workshop 2021
# https://dronebotworkshop.com
import machine
import utime
potentiometer = machine.ADC(26)
while True:
print(potentiometer.read_u16())
utime.sleep(2)
这是一个简单的脚本,像往常一样,首先导入用于 GPIO 操作的machine
库和用于时间函数的utime
库。
然后我们定义我们的电位器连接。请注意我们如何使用 "ADC" 来表示我们要将 GPIO 26 针作为模拟输入。当然这只适用于具有模拟输入能力的三个 GPIO 引脚。
在 True 循环中,我们只需打印从电位器上得到的值,然后延迟几秒钟再做一次。
需要注意的是,我们用 "read_u16" 函数得到的值的类型是一个无符号的 16 位整数。这意味着它将在 0 和 65,535 之间变化,而不是你可能期望从 12 位 ADC 中得到的 4095。
这可能看起来很奇怪,但正如我们将在下一个脚本中看到的那样,能够传递具有相同数值数据类型的值实际上是有用的。
运行脚本并观察 Shell,你应该会看到那里的数值随着你移动电位器轴而改变。
LED PWM 控制
让我们在之前的脚本基础上进行扩展,使用电位器的输出来控制 LED 的亮度。
当然,我们将使用 PWM 进行控制,这个任务在 MicroPython 中非常简单。
# 树莓派 Pico LED PWM Test
# led-pwm.py
# POT - Pico GPIO 26 ADC0 - Pin 32
# RED LED - Pico GPIO 10 - Pin 14
# DroneBot Workshop 2021
# https://dronebotworkshop.com
import machine
import utime
led_red = machine.PWM(machine.Pin(10))
potentiometer = machine.ADC(26)
led_red.freq(1000)
while True:
led_red.duty_u16(potentiometer.read_u16())
在这个脚本中需要注意的一个关键项目是我们定义 "led_red" 的方式。我们将其定义为 "PWM",而不是输出。
电位器的定义与上一个脚本中的方式完全相同。
现在我们已经给输出赋予了 "PWM" 的属性,它继承了许多其他参数。其中之一是 PWM 频率,我们将其设置为 1000 Hz。
在 true 循环中,我们不断地从电位器中获取无符号的 16 位值,并将其传递给 LEDs 占空比,也方便地指定为无符号的 16 位整数。
这就说明了两者保持相同的编号方案的价值,不需要将模拟值,真的是 0 到 4095,映射到占空比,真的是 0 到 100。
运行程序,你应该可以顺利地控制红色 LED 段的亮度。
添加显示屏
我们将进行的下一个实验是将一个 OLED 显示器连接到我们的 Pico 上,当然,也可以在上面打印一些东西。
我们将使用 I2C 显示屏,因此我们也将看到 Pico 如何使用 I2C 连接工作。记住,Pico 有两条 I2C 总线。
我们的 OLED 是标准的 1602 型 OLED 显示器,到处都有。如果你愿意,也可以使用与我的显示屏尺寸不同的显示屏,只需在代码中更改尺寸即可。
0.91”128x32 I2C OLED 贴片焊盘单色显示屏
这是我们如何把这些东西都挂起来的,只有四根线。
我们的显示器需要一个库,我们可以使用 Thonny ID 安装。你可能会发现在全菜单模式下比在基本模式下更容易,但这两种方式都可以。
- 点击 "工具" 菜单
- 点击 "管理包"
- 搜索 "ssd1306"
- 找到 "ssd1306.py" 并安装它。
现在我们已经安装了库,我们可以看一下演示 OLED 显示屏的脚本。
# 树莓派 Pico OLED Display Test
# Uses ssd1306 module
# display-ssd1306-test.py
# DroneBot Workshop 2021
# https://dronebotworkshop.com
import machine
import utime
sda=machine.Pin(20)
scl=machine.Pin(21)
i2c=machine.I2C(0, sda=sda, scl=scl, freq=400000)
from ssd1306 import SSD1306_I2C
oled = SSD1306_I2C(128, 32, i2c)
print(i2c.scan())
oled.text('Welcome to the', 0, 0)
oled.text('Pi Pico', 0, 10)
oled.text('Display Demo', 0, 20)
oled.show()
utime.sleep(4)
oled.fill(1)
oled.show()
utime.sleep(2)
oled.fill(0)
oled.show()
while True:
oled.text("Hello World",0,0)
for i in range (0, 164):
oled.scroll(1,0)
oled.show()
utime.sleep(0.01)
我们的 OLED 显示屏是一个 I2C 设备,所以你会注意到,在脚本的开头,我们将两个 GPIO 引脚定义为 SDA (GPIO 20) 和 SCL (GPIO 21)。
Pico 有两条 I2C 总线,你可以使用几种不同的 GPIO 引脚来连接它们。但它们并不是随便的引脚,例如某些引脚被指定为总线 0 的 SDA,只有它们才能用于 SDA 总线 0。
然后我们使用机器库的 I2C 函数定义一个 I2C 连接。我们需要给它提供以下参数。
- I2C 总线号,在我们的例子中是 0。
- SDA 引脚
- SCL 引脚
- I2C 总线频率 -- 在我们的例子中是 400KHz。
然后我们添加 OLED 库,并创建一个 I2C OLED 对象。我们将大小参数和 I2C 连接信息传递给它。
注意,我们没有传递 I2C 地址。SD1306 OLED 显示器有一个固定的 I2C 地址,所以我们不需要指定它。
不过,我在这里添加了一行与显示器无关的内容,但可以让你扫描 I2C 总线,并打印出它发现占用的地址。请注意,在 Shell 中打印出来的是十进制,而不是你更可能习惯看到的十六进制。
回到 OLED 脚本!
我们开始在显示屏上打印,几行文字。注意我们如何指定每行开始的像素位置。
实际上,我们并没有直接打印到显示屏上,而是将数据发送到一个缓冲区。oled.show()
这一行将把该缓冲区的数据传输到显示器上。
在打印完欢迎信息并按住它四秒钟后,我们再执行oled.fill(1)
。这将打开显示器中的每一个像素,或者更准确地说,是缓冲区中的每一个像素。然后我们做一个oled.show()
来显示填充。
我们将填充物保持在显示屏上两秒钟,然后执行oled.fill(0)
,当我们显示它时,它将关闭显示屏中的每个像素。
现在进入 True 循环。
我们再次输入一些文本,经典的 "Hello World"。但我们没有进行 "显示" 来显示它,而是开始一个 for-loop。在这个循环中,我们使用 led.scroll(1,0) 将显示水平移动 1 像素(垂直移动 0 像素,这就是另一个参数)。
然后我们在屏幕上显示,然后休眠一段很短的时间。然后我们再做一次。
结果将是显示屏在屏幕上滚动。你可以在 for-loop 中使用参数来改变它。
将脚本加载到你的 Pico 上,然后观看显示。你应该看到欢迎文字,然后是显示填充,然后是空。之后,只要你让实验运行,滚动的 "Hello World" 就会继续。
驱动电机
微控制器比较流行的应用之一是驱动一个或几个直流电动机。
这是通过使用 H-Bridge 来实现的,H-Bridge 是一种功率晶体管或 MOSFET 的排列方式,可以处理电机电流,同时允许你控制电机的方向和速度。
我们将只用一个电机来实现这一点。我们将使用 TB6612FNG H-Bridge 和树莓派 Pico 来控制一个小型直流电机。
TB6612FNG H-Bridge
TB6612FNG H-Bridge 是我们之前使用过的,一款基于 MOSFET 的 H-Bridge,相比老款备用的 L-298N 有很多性能上的优势。
该设备其实有两个通道,我们只用通道 A 来演示。
通道 A 有三个输入。
- AI1 - 方向和模式
- AI2 - 方向和模式
- PWMA - 一个 PWM 输入,用于控制电机速度。
在它们之间,AI1 和 AI2 引脚控制电机方向和模式。模式包括短制动和停止模式。在我们的简单演示中,我们将只处理方向模式。
TB6612FNG H-Bridge 在板子的另一侧还有电源和电机的连接。
下面是我们将使用 TB6612FNG H-Bridge 和树莓 Pico 的连接方式。
请注意,由于我使用的是 6V 电机,我已经为它提供了一个 6V 电源。不要试图使用 Pico 的输出电压来为你的电机供电,单独的电源是必要的。我使用了四节 AA 型电池,这是一种简单而安全的安排。
电机的极性其实并不重要,它只是决定了哪条路是向前的,哪条路是向后的。
一旦它被全部连接起来,我们就需要一些代码来运行它。我建议这样做。
# 树莓派 Pico Motor Test
# motor-test.py
# POT - Pico GPIO 26 ADC0 - Pin 32
# RED BUTTON - Pico GPIO 15 - Pin 20
# BLACK BUTTON - Pico GPIO 2 - Pin 4
# RED LED - Pico GPIO 10 - Pin 14
# GREEN LED - Pico GPIO 11 - Pin 15
# BLUE LED - Pico GPIO 14 - Pin 19
# DroneBot Workshop 2021
# https://dronebotworkshop.com
import machine
import utime
potentiometer = machine.ADC(26)
mtr_AI1 = machine.Pin(8, machine.Pin.OUT)
mtr_AI2 = machine.Pin(7, machine.Pin.OUT)
mtr_PWMa = machine.PWM(machine.Pin(6))
button_red = machine.Pin(15, machine.Pin.IN, machine.Pin.PULL_DOWN)
button_black = machine.Pin(2, machine.Pin.IN, machine.Pin.PULL_UP)
led_red = machine.Pin(10, machine.Pin.OUT)
led_green = machine.Pin(11, machine.Pin.OUT)
led_blue = machine.Pin(14, machine.Pin.OUT)
led_red.value(0)
led_green.value(0)
led_blue.value(1)
mtr_PWMa.freq(50)
mtr_AI1.value(1)
mtr_AI2.value(0)
while True:
mtr_PWMa.duty_u16(potentiometer.read_u16())
if button_red.value() == 1:
mtr_AI1.value(0)
mtr_AI2.value(1)
led_red.value(1)
led_green.value(0)
led_blue.value(0)
if button_black.value() == 0:
mtr_AI1.value(1)
mtr_AI2.value(0)
led_red.value(0)
led_green.value(1)
led_blue.value(0)
utime.sleep(0.25)
我们要利用电位器、两个开关和 RGB LED,以及电机控制器。电位器将控制电机的速度,开关将控制电机的方向,而 LED 将用彩色指示灯显示当前的方向。
我们使用我们的之前的两个库,并像以前一样设置电位器。
接下来,我们将 Pico 与 TB6612FNG H-Bridge 的连接定义为输出。GPIO 6 上的 PWMA 输出被定义为 PWM,它将控制电机速度。
LED 和按钮的设置与之前相同。
PWM 频率设置为 50Hz,这是一个任意的选择。随意实验一下,看看是否能提高电机性能。
电机 AI1 和 AI2 输入被设置为正向旋转,所以电机将以正向启动。请注意,当我们启动时,RGB LED 的蓝段也会被打开。
在 True 循环中,我们读取电位器的值,并将其传递给电机 PWM 信号,以控制电机的速度。我们还要看按钮的状态。
如果红色按钮被按下,我们设置 AI1 和 AI2 信号,使电机反转。我们也会点亮红色 LED 段。
如果黑色按钮被按下,我们设置电机方向正向,并打开绿色 LED 段。
加载、检查代码。它应该用一个蓝色的 LED 启动,你应该能够控制电机的速度。按下按钮可以控制方向,还可以改变 LED 的颜色。
Pico Everything 演示
剩下的就是把所有的东西放在一起做一个大的最终演示。这一点我们已经做得不远了,因为在上一个脚本中,我们使用了所有的东西,除了 OLED 显示屏。
所以让我们把 OLED 显示屏添加到这个组合中。下面是我们需要做的代码。
# 树莓派 Everything Test
# everything.py
# POT - Pico GPIO 26 ADC0 - Pin 32
# RED BUTTON - Pico GPIO 15 - Pin 20
# BLACK BUTTON - Pico GPIO 2 - Pin 4
# RED LED - Pico GPIO 10 - Pin 14
# GREEN LED - Pico GPIO 11 - Pin 15
# BLUE LED - Pico GPIO 14 - Pin 19
# DroneBot Workshop 2021
# https://dronebotworkshop.com
import machine
import utime
potentiometer = machine.ADC(26)
mtr_AI1 = machine.Pin(8, machine.Pin.OUT)
mtr_AI2 = machine.Pin(7, machine.Pin.OUT)
mtr_PWMa = machine.PWM(machine.Pin(6))
button_red = machine.Pin(15, machine.Pin.IN, machine.Pin.PULL_DOWN)
button_black = machine.Pin(2, machine.Pin.IN, machine.Pin.PULL_UP)
led_red = machine.Pin(10, machine.Pin.OUT)
led_green = machine.Pin(11, machine.Pin.OUT)
led_blue = machine.Pin(14, machine.Pin.OUT)
sda=machine.Pin(20)
scl=machine.Pin(21)
i2c=machine.I2C(0, sda=sda, scl=scl, freq=400000)
from ssd1306 import SSD1306_I2C
oled = SSD1306_I2C(128, 32, i2c)
oled.text('Pico Motor Test', 0, 0)
oled.show()
utime.sleep(2)
led_red.value(1)
led_green.value(0)
led_blue.value(0)
utime.sleep(2)
led_red.value(0)
led_green.value(1)
led_blue.value(0)
utime.sleep(2)
led_red.value(0)
led_green.value(0)
led_blue.value(1)
mtr_PWMa.freq(50)
mtr_AI1.value(1)
mtr_AI2.value(0)
while True:
speedvalue = int((potentiometer.read_u16())/500)
mtr_PWMa.duty_u16(potentiometer.read_u16())
if button_red.value() == 1:
mtr_AI1.value(0)
mtr_AI2.value(1)
led_red.value(1)
led_green.value(0)
led_blue.value(0)
if button_black.value() == 0:
mtr_AI1.value(1)
mtr_AI2.value(0)
led_red.value(0)
led_green.value(1)
led_blue.value(0)
oled.fill_rect(1,15,speedvalue,25,1)
oled.show()
oled.fill_rect(1,15,speedvalue,25,0)
utime.sleep(0.25)
现在你应该能认出这段代码的大部分内容了,基本上就是之前的脚本,加上了 I2C OLED 显示屏的库和设置。除此之外,前几行都是一样的,都是 LED 颜色的序列,一切设置好后,会有一个 Display print。
在 True 循环中,我们看到正在计算一个名为 "speedvalue" 的整数。这个变量将用于设置 OLED 上条形图显示的大小。
红色和黑色的按钮和之前的操作完全一样。
然后,OLED 在其标题线下画一个矩形,并填入矩形。矩形的长度由 "speedvalue" 决定,所以随着速度的增加,矩形会变长。
从某种意义上说,我们是把 OLED 当做一个粗略的速度指示器,或者说是一个速度表!
装上所有的东西,看演示效果。它的操作应该和之前的实验一样,只是这次我们除了有一个显示电机速度的显示器外,还有一个指示其方向的 RGB LED。
在没有主机的情况下运行
到目前为止,我们所做的一切都是从 Thonny IDE 将程序加载到 Pico 上运行的。
但是,一旦你开发了程序,你就会希望它能够独立运行,由 microUSB 端口或通过 Pico VSYS 电源输入供电。
你的程序或程序已经存储在 Pico 上。那么我们如何让它在开机时运行程序呢?
答案是,我们更改程序名称!
主程序 main.py
当 Pico 启动时,它会查找名为 main.py 的程序。如果它找到了它,就会加载它并在启动时运行它。
因此,如果你想让你的程序在无人看管的情况下运行,你需要将其保存为 main.py。稍后,如果你愿意,你可以将 main.py 改成其他程序,或者完全删除它。
首先将你希望在启动时运行的程序加载到 Thonny IDE 中。现在点击 "文件",然后选择 "另存为"。
你会被问到是否要保存在本地计算机上或 Pico 上,你肯定要保存在 Pico 上。
现在把你的程序保存为 "main.py"。就像这样,全部用小写。
现在从电脑上拔下 Pico 的插头,并将其插入合适的电源,如 USB 适配器。你会看到 Pico 重新开机,并运行你保存为 "main.py" 的程序。
结束语
这显然只是树莓派 Pico 的开始。
我很希望看到 PlatformIO 和 Arduino IDE 能够为树莓派 Pico 提供支持,因为目前为 Pico 创建 C++ 程序的方法有些繁琐,特别是对于初学者来说。
但它是进入 MicroPython 的一个很好且廉价的入口,你会在这里看到更多的东西。
所以尽快拿起 Pico 开始实验吧!
资源简介
- Pico 代码 [1] - 本文中使用的所有 MicroPython 代码,放在一个方便的 ZIP 文件中。
- 树莓派 Pico[2] - 树莓派 Pico 的官方公告页面。
- Pico Pinout[3] - Pico Pinout 的树莓派 PDF 文件。
- Pico Datasheet[4] - 包含 Pico 技术规格和评级的 PDF 文档。
- RP2040 Datasheet[5] - 包含 RP2040 微控制器所有规格的 PDF 文件。警告,这是一个非常大的文档
- Pico MicroPython SDK[6] - 在树莓派 Pico 上使用 MicroPython 的良好 PDF 指南。
- Pico C++ SDK[7] - Pico 上的 C++ 的 PDF 指南。这也是一个非常大的文档。
译文首发于 DF 创客社区:https://mc.dfrobot.com.cn/thread-308442-1-1.html
原文链接:
Raspberry Pi Pico - Interface (almost) Everything!
转载请注明出处~
参考资料
[1]Pico 代码: http://dbot.ws/picocode
[2] 树莓派 Pico: https://www.raspberrypi.org/blog/raspberry-pi-silicon-pico-now-on-sale/
[3]Pico Pinout: https://datasheets.raspberrypi.org/pico/Pico-R3-A4-Pinout.pdf
[4]Pico Datasheet: https://datasheets.raspberrypi.org/pico/pico-datasheet.pdf
[5]RP2040 Datasheet: https://datasheets.raspberrypi.org/rp2040/rp2040-datasheet.pdf
[6]Pico MicroPython SDK: https://datasheets.raspberrypi.org/pico/raspberry-pi-pico-python-sdk.pdf
[7]Pico C++ SDK: https://datasheets.raspberrypi.org/pico/raspberry-pi-pico-c-sdk.pdf
Comments | NOTHING