让我们看看30个微控制器能做什么

2021-03-04 17:17 来源:电子说

2021年1月底,树莓Pi基金会发布大新闻,推出树莓Pi Pico,进入微控制器领域。

功能强大、价格低廉的特点使Pico吸引了世界各地制造商的注意。本文将介绍Pico这个小工具。

文章原文来自DroneBotWorkshop,负责人是一个很善良的爷爷。有条件的朋友可以去输油管道关注他。

本文利用MicroPython对树莓皮进行编程。让我们看看30片微控制器能做什么。

介绍

树莓Pi基金会发布微控制器是个大新闻。毕竟,在此之前,全球最受欢迎的单板计算机制造商从未对微控制器表示过兴趣。

13a3f96a-7b3b-11eb-8b86-12bb97331649.png

草莓派匹克的宣布不仅让人们大吃一惊,这次草莓派还自己做了一个新的芯片。他们没有支持基于现有代码的ESP32或SAMD21的设计,而是选择创建自己的微控制器。

所以说到皮科,我们都是初学者。

树莓Pi也在官网发布了很多技术文档,还有一本叫《GetStartedwithMicroPythononRaspberryPiPico》的手册。它有纸质版和PDF版。

另外,目前没有更多关于Pico的深入信息。但是,随着时间的推移,这种情况很快就会改变。覆盆子皮已经授权包括阿达果在内的其他制造商在自己的设计中使用RP2040芯片。假以时日,它会带给我们更多的代码和开发工具。

13e72ce4-7b3b-11eb-8b86-12bb97331649.png

我们先来试试,把一堆东西连接到Pico上,会发生什么有趣的事情!

覆盆子皮

Pico是一个和ArduinoNano差不多大小的小板。和所有的草莓派一样,包装很简陋,只是一个塑料包装的匹克,塑料包装本身是从包装的长条上切下来的,很像小时候咪咪虾或者糖果的包装。

14640232-7b3b-11eb-8b86-12bb97331649.png

看看皮科的板子

四刀只买这么一块光板,不多,这么环保。

14cc38a2-7b3b-11eb-8b86-12bb97331649.png

裸板没有引脚,需要自行焊接。这是一块制作精良的电路板,也可以作为SMD元件,直接焊接到印刷电路板上。

俯视图

从上面看,皮科是这样的。

155e8f9a-7b3b-11eb-8b86-12bb97331649.png

板的主要功能是一端的microUSB连接器。它既用于通信,也用于向Pico供电。

微型USB连接器旁边安装有板载LED,内部连接到GPIO引脚25。

值得注意的是,这是整个Pico板上唯一的LED。

开机按钮安装在比led低一点的位置,可以让你改变Pico的启动模式,这样你就可以在上面加载MicroPython进行拖放编程。

在板的底部,您将看到三个连接点,用于串行调试选项。今天才入门,暂时不讨论这个问题,高级开发人员会有兴趣。

板的中央是整个板的“大脑”——RP2040MCU,一会我们来研究它的功能。

接地引脚

板上有几条接地线,8条接地线加上3针调试连接器上的一条附加接地线。

15edc552-7b3b-11eb-8b86-12bb97331649.png

这些引脚很容易找到,它们是统一的方形,而不是像其他连接一样圆形。

1/M00/E3/22/o4YBAGBAmPyAcfPOAA8lzqkvfek541.png" alt="16c5b188-7b3b-11eb-8b86-12bb97331649.png" />

其中一个位于33号针脚的地线也被指定为模拟地线。

174070e4-7b3b-11eb-8b86-12bb97331649.png

电源引脚

Pico是一个3.3V的逻辑器件,但由于内置了电压转换器和稳压器,它可以用一系列电源供电。

179e3670-7b3b-11eb-8b86-12bb97331649.png

所有与电源相关的引脚都被安排在了一起,靠近microUSB连接器。

VBUS-这是来自microUSB总线的电源,5V。如果Pico不是由microUSB连接器供电,那么这里将没有输出。

VSYS-这是输入电压,范围为2至5V。板载电压转换器将为Pico将其改为3.3V。

3V3-这是Pico内部调节器的3.3伏输出。只要将负载保持在300ma以下,它就可用于为其他组件供电。

还有几个输入可以让你控制Pico的电源。

3V3_EN-你可以使用此输入禁用Pico的内部电压调节器,从而关闭Pico和由其供电的任何组件。

RUN-可以启用或禁用RP2040微控制器,也可以将其复位。

GPIO引脚

树莓派Pico板上有26个裸露的GPIO连接。

180fa062-7b3b-11eb-8b86-12bb97331649.png

它们的排列顺序很好,在GPIO22和GPIO26之间有一个"空隙"(这些"缺失"的引脚在内部使用)。

这些引脚都有多种功能,你可以为PWM配置多达16个引脚。

有两个I2C总线,两个UART和两个SPI总线,这些可以配置使用多种GPIO引脚。

模拟引脚

Pico有三个模数转换器,还有一个内部用于板载温度传感器的转换器。

1888c596-7b3b-11eb-8b86-12bb97331649.png

ADC的分辨率为12位。

你也可以在ADC_VREF引脚上提供一个外部精密电压参考。其中一个接地点,即33脚上的ADC_GND被用作该参考点的接地点。

RP2040微控制器

树莓派Pico是围绕基金会的新芯片RP2040微控制器而设计的。下面是它的参数:

双核32位ARMCortex-M0+处理器

运行在48MHz,但可以超频到133MHz。

30个GPIO引脚(26个暴露)

可支持USB主机或设备模式

RP2040能够支持高达16MB的片外闪存,不过在Pico中只有4MB。

树莓派基金会对这款芯片有很多计划,也已经授权给了很多其他厂商。

对Pico进行编程

你可以使用两种编程语言之一开始使用Pico。

18ce69ca-7b3b-11eb-8b86-12bb97331649.png

MicroPython-一种专门为微控制器制作的解释语言。

C++++-许多微控制器用户都熟悉C++,因为它被用于Arduino和ESP32板上。

虽然我急于将C++与Pico一起使用,以榨取它的每一克性能,但还是决定与大多数人一样,使用MicroPython。在这个早期的开发阶段,C++的工具还在进行最后的开发,期待着Pico成为PlatformIO和ArduinoIDE板系列的一部分。

开始使用Pico

当我们拿到Pico板时,它被包装在一个塑料载体中,没有额外的零件。

除非你有计划将Pico表面贴装,或者你的唯一目的是只是点个灯,否则我们都需要一些引脚。

Pico有40个引脚,每侧20个。另外三个针脚用于调试端口。

标准的公头针脚有40个针脚带,因此可以将其中一个针脚带减半,作为Pico的针脚使用。如果你想在Debug连接器上安装针脚,你需要另一个3针的公头,可以是直的或90度的。

焊接一个Pico

在开始对Pico进行编程之前,我们需要进行一些焊接工作!除了杜邦公头引脚之外,我们还需要合适的烙铁和一些焊料。

电烙铁的头需要精细一点,我们还需要一块清洁海绵和一个支架。

此外,我们还需要想办法在焊接Pico引脚时把它固定住,因为它们需要以精确的90度角安装到电路板上,这样才能装入无焊料面包板。

许多实验都使用无焊面包板来固定引脚,虽然这种方法可行,但有可能因热力或焊料飞溅而损坏面包板。

所以最好的解决方法是,你有一块老旧的面包板,用它作为针座。

1910f97a-7b3b-11eb-8b86-12bb97331649.png

我个人喜欢用几块便宜的灌注板、打孔实验板。我说的"便宜"是指单面的东西,没有排孔,只有一面是裸铜的。

两片这种东西很适合固定引脚,每当要焊接一个小模块或者单片机的时候,我就经常用这个。

把电烙铁加热到一定温度,然后加热引脚与焊盘的连接处,在另一面涂上焊料,千万不要直接涂到电烙铁上。加热零件,而不是焊料。

如果你想焊接Debug的3个引脚连接器(这是可选的),你可能应该先做。这些引脚的方向与GPIO引脚的方向相反。我用了一个小的便签垫来固定电路板,因为Debug连接器与GPIO引脚在网格上并不一致。

之后就是焊接40个引脚了,一次20个!真的不需要太长的时间,只需要用尽可能多的焊料,避免出现焊桥,完成后再检查一下。

焊接后清理Pico

我喜欢在焊接完我的PCB后清洗它们,以去除焊料核心中的助焊剂和树脂。它表现为焊接连接处周围的褐色污渍。

这一步完全是可有可无的,因为助焊剂和树脂对元件的运行或寿命没有任何不利影响。它只是看起来更好看!

197dc67c-7b3b-11eb-8b86-12bb97331649.png

如果你想克隆你的板子,你需要一些PCB板清洗剂或FlusRemover。由于它也往往会留下一点残留物,我用异丙醇来清理。

PCB板清洗剂可以到网上购买。异丙醇可以在当地药店找到,一定要买纯酒精和水的混合物(70%),不要买有香味的。

我用一把旧牙刷和一些塑料容器,在一个盆子里进行工作。记得最好要准备好口罩、手套和护目镜。

19d86262-7b3b-11eb-8b86-12bb97331649.png

我用牙刷蘸PCB清洁剂擦洗引脚,然后用牙刷蘸异丙醇冲洗。

1a2a30a6-7b3b-11eb-8b86-12bb97331649.png

让板子自然风干,也可以使用空气软管,这样之后,我们将拥有一个闪闪发光的新Pico!

Pico和ThonnyIDE

现在Pico的引脚已经连接好了,我们可以开始对它进行实验了。

建议你把它放在一个无焊的面包板上,以迎接我们即将到来的实验。

虽然有许多IDE可以让我们选择与我们的新Pico一起工作,但我的建议是使用树莓派推荐的ThonnyIDE。

ThonnyIDE

Thonny自称是"PythonIDEforBeginners",它适用于Windows、MacOSX和Linux。

它也是树莓派操作系统(以前的Raspbian)的一部分。

我将在树莓派操作系统上使用ThonnyIDE,运行在8GB的树莓派4上,作为我今天实验的开发平台。当然,你可以使用任何你能运行Thonny的平台,但我想让它在树莓派家族中运行--另外,由于Thonny已经安装在新构建的树莓派操作系统上,所以上手非常简单。

启动和安装MicroPython

我们需要做的第一件事是将MicroPython安装到Pico上。

将microUSB连接到Pico上,并准备将另一端插入电脑。在插入之前,先按下Pico上的BootSelect(开关)按钮。

1a86c3ac-7b3b-11eb-8b86-12bb97331649.png

按住BOOTSEL键,将Pico插入电脑的USB端口。按住BOOTSEL键几秒钟,然后松开。

你应该会看到一个新的驱动器在你的电脑上可用,信息看起来会有所不同,这取决于你所使用的操作系统,但它类似于你将U盘插入电脑时得到的信息。

打开新的"驱动器",你会看到一个名为RPI-RP2的文件夹。在这个驱动器里,你会看到几个文件,其中一个是网页文档index.htm。

点击该网页文件,浏览器就会打开,你会被重定向到树莓派Pico入门页面。

点击MicroPython入门的标签。你会看到一个链接来下载一个UF2文件,这就是可下载的MicroPython文件。把这个文件下载到你的电脑上。

1b32afb4-7b3b-11eb-8b86-12bb97331649.png

现在将下载的文件拖到Pico的RPI-RP2文件夹中。一旦这样做了,文件夹就会消失,Pico将以MicroPython模式启动。

配置ThonnyIDE

在Pico仍然被连接的情况下,打开ThonnyIDE,如果你和我一样使用树莓派操作系统,你会在编程工具菜单下找到Thonny。

一旦Thonny打开,请看右下角的状态栏,它可能会显示一个Python的版本。这是当前在你的计算机上运行的Python版本,对于我们的实验来说,这一点并不重要。

点击该消息,应该会出现一个下拉菜单,还有其他环境可以选择。其中一个应该是MicroPython(树莓派Pico)。选择那一个。

你会注意到底部打开了一个新的Shell,在这个Shell中,你应该会看到一些文字,表明你已经连接到Pico。

是时候开始编程了!

Shell测试

Shell是Pico的"命令行",你可以直接在这里执行代码。

一个简单的测试是输入以下内容(这也是查看你是否正确连接到Pico的好方法),然后按Enter键。

print(“HelloWorld”)

你应该在shell中看到"HelloWorld"被打印出来了,当然这是你告诉Pico要做的。

脚本测试

当然,你不会直接在shell中输入你的程序,一来,一旦你执行了程序,它们就会消失,二来,对于任何相当大的程序来说,也是不方便的。

你要用编辑器来输入你的程序,也就是shell上面的大文本区域,在ThonnyIDE的屏幕上占主导地位。

进入这个编辑器,输入和刚才一样的文字,用一个漂亮的"你好"来迎接编程世界。

点击"运行"按钮(绿色带箭头的那个),系统会提示你先保存程序。你可以选择将其保存在本地电脑或Pico上,尝试保存在Pico上。给你的程序起个带".py"后缀的名字,比如"hello.py"。

程序将被保存并运行,你将在shell中看到"HelloWorld"的问候语。你可以按"运行"按钮再次看到它,再按一次。

所以,现在你知道了如何编写和保存MicroPython程序,我们就可以开始我们的实验了!

使用LED和开关

基本的数字I/O功能可以很容易地用LED和开关来说明,这正是我们开始Pico冒险的方式。

但请注意我们如何给开关布线,我们将以不同的方式进行操作。

RGBLED

最简单的输出设备可能是LED。当在正确的方向上施加足够的电流时,这种输出设备就会工作。虽然简单,但它可以用来说明I/O技术,这些技术可以应用于其他设备,如继电器或晶体管。

我将使用一个Common-CathodeRGBLED,但你也可以使用三个分立的LED来代替。无论哪种方式,你都还需要三个降压电阻,我在实验中使用了330欧姆的电阻。

如果你选择像我这样使用RGBLED,一定要买一个标准的RGBLED,而不是一个可编程的。

按钮开关

这是最简单的输入设备。我用的是一对瞬时常开按钮开关

一个红色和一个黑色,但在其他方面是相同的。

我们再次使用一个简单的输入设备来测试我们的小Pico的I/O能力。我们将以不同的方式为两个开关布线,使其更加有趣,而且我们也不会使用任何上拉或下拉电阻。

LED和开关的连接

这里是我们的LED和开关的连接图,请记住,如果你没有共阴极RGBLED,你可以使用三个独立的LED。

1b78a80c-7b3b-11eb-8b86-12bb97331649.png

请注意,这两个开关的接线方式不同。

黑色按钮开关的一侧连接到Pico的GPIO引脚,另一侧连接到地。

红色开关则相反,它的一侧连接到GPIO引脚,另一侧连接到3.3伏,这是Pico的工作电压和逻辑电压。

经典项目——点灯

我们要做的第一个实验是我们自己的Arduino"Blink"草图的变体。是的,从技术上讲,我们已经看到了如何闪烁板载LED,但由于我们现在有一个RGBLED在我们的支配下,我们当然可以找到另一种方法来点灯!

在Thonny中打开以下代码。

#树莓派PicoRGBBlink#rgb-blink.py#REDLED-PicoGPIO10-Pin14#GREENLED-PicoGPIO11-Pin15#BLUELED-PicoGPIO14-Pin19#DroneBotWorkshop2021#https://dronebotworkshop.comimportmachineimportutimeled_red=machine.Pin(10,machine.Pin.OUT)led_green=machine.Pin(11,machine.Pin.OUT)led_blue=machine.Pin(14,machine.Pin.OUT)whileTrue: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("EndofLoop")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,这意味着这些引脚现在被设置为输出引脚。

whileTrue条件类似于Arduino草图中的Loop,这里的代码是连续执行的。

在本节中,我们对LED进行寻址,并将它们设置为开(值为1)或关(值为0)。我们通过一个序列,在最后一个序列,我们打印到控制台。

1c6578c6-7b3b-11eb-8b86-12bb97331649.png

然后我们再做一遍。

将脚本加载到Pico上,然后观察LED,你应该会看到一个彩色的闪烁。

1c98bb64-7b3b-11eb-8b86-12bb97331649.png

开关测试

我们接下来的脚本是对两个开关进行一个非常基本的测试,我们用这样一个奇怪的方式来接线。

你会观察到的第一件奇怪的事情是它们的接线不同,黑色的开关将输入端连接到地,而红色的开关将输入端连接到3.3伏,用于逻辑HIGH。

另一个有趣的事情是,这两个开关都没有采用上拉或下拉电阻,它们显然需要这些电阻,黑色开关需要上拉,红色开关需要下拉才能正常工作。

我们将在代码中加入所需的电阻!

#树莓派PicoSwitchTest#switchtest.py#REDBUTTON-PicoGPIO15-Pin20#BLACKBUTTON-PicoGPIO2-Pin4#DroneBotWorkshop2021#https://dronebotworkshop.comimportmachineimportutimebutton_red=machine.Pin(15,machine.Pin.IN,machine.Pin.PULL_DOWN)button_black=machine.Pin(2,machine.Pin.IN,machine.Pin.PULL_UP)whileTrue:ifbutton_red.value()==1:print("Red")ifbutton_black.value()==0:print("Black")utime.sleep(0.25)

请注意定义按钮的行的语法,你会看到它们是如何被定义为Inputs的,以及如何添加了下拉和上拉电阻。

在whileTrue:循环中,你还会注意到我们是在监测不同的条件,红色的开关触发了一个HIGH输入,而黑色的开关触发了一个LOW。

最后的微小时间延迟是一种简单的debouncing形式,如果你喜欢,你可以实验一下这个值。

这个脚本会在控制台中打印所有的结果,所以在你按下按钮的时候要注意。

中断和切换

接下来的实验引入了几个有用的概念。第一个,也可以说是这两个概念中最重要的,就是"中断"。

中断

中断就像它的声音一样,是一个"中断"程序正常流程的事件。在我们的情况下,我们处理的是外部硬件中断,这意味着在程序继续运行之前,需要处理一个信号或状态变化。

在Pico上,我们按照以下方式创建一个中断。

我们将一个引脚定义为"中断输入",我们定义该点上的状态变化被认为是一个中断。在Pico上,我们可以使用任何GPIO引脚来实现这一点,而且我们可以定义多个引脚。

我们创建了一个"中断处理程序"函数,我们希望在检测到中断时运行该函数。

我们将"中断处理程序"与"中断输入"配对。

现在,每当中断输入条件发生时,Pico将停止它正在做的任何事情,并执行"中断处理程序"。然后它将恢复到原来的位置。

切换

虽然不像中断那样基本,但仍然非常有用。“切换”只是将Pico上的输出状态反转。

因此,如果输出为高电平,而我们应用"切换",它就会变为低电平。

我们不需要知道输出的当前状态,我们只需要知道当我们应用一个切换器时,它将变为相反的状态。

自然,这是写另一个Blink程序的理想函数,所以我们会这么做。只有我们的Blink程序才会有被中断的风险!

#树莓派PicoInterrupt&ToggleDemo#interrrupt-toggle-demo.py#REDLED-PicoGPIO10-Pin14#GREENLED-PicoGPIO11-Pin15#REDBUTTON-PicoGPIO15-Pin20#DroneBotWorkshop2021#https://dronebotworkshop.comimportmachineimportutimeled_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)defint_handler(pin):button_red.irq(handler=None)print("InterruptDetected!")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)whileTrue:led_green.toggle()utime.sleep(2)

在这个MicroPython脚本中,我们将闪烁我们的RGBLED的绿色部分,使用一个切换器来改变它的状态。在正常的操作下,LED状态将每两秒钟切换一次。

然而,我们可以通过按下红色按钮来中断闪烁。这将导致一个中断,这将关闭绿色的LED,然后打开红色的。它将保持四秒,之后程序控制权将被恢复,因此我们可以继续进行绿色闪烁。

我们通过导入machine和utime库来开始我们的脚本,就像我们之前一样。

LED段和红色按钮的定义和之前的脚本一样。LED在程序启动时被关闭。

然后我们定义一个函数,这是我们的中断处理程序,叫做"int_handler"。在这个函数中,我们做了以下工作。

关闭中断,这样我们就不会有多个中断了。

将"中断检测"打印到Shell上

打开红色LED段。

关闭绿色LED段。

睡眠四秒。

关闭红色段。

重新建立中断

退出

处理函数后的那一行将中断"粘"到我们定义为红色按钮输入的引脚上。需要注意的是,它指定了"IRQ_RISING",这意味着如果输入从0(地)上升到1(3.3伏),它将触发一个中断。这与我们红色按钮的接线方式一致。

在True循环中,我们只需使用定义为输出的任何GPIO引脚可用的"toggle"功能来闪烁LED。

1d2f3256-7b3b-11eb-8b86-12bb97331649.png

将它发送到Pico上,观察RGBLED,它应该开始闪烁绿色。观察一段时间,然后按下红色按钮。LED应该变成红色,Shell应该显示"InterruptDetected"。四秒钟后,绿色闪烁将重新开始。

开关和LED演示

既然我们一直在研究开关和LED,我们不妨把它们结合起来,再编写一个简单的脚本。

#树莓派PicoSwitch&RGBLEDDemo#switch-led-demo.py#REDLED-PicoGPIO10-Pin14#GREENLED-PicoGPIO11-Pin15#BLUELED-PicoGPIO14-Pin19#BLACKBUTTON-PicoGPIO2-Pin4#DroneBotWorkshop2021#https://dronebotworkshop.comimportmachineimportutimeled_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)whileTrue:ifbutton_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库函数定义RGBLED和黑色按钮。

记住,黑色按钮是由我们定义的上拉保持HIGH的,当按钮被按下时,它就会变LOW,因为另一边是接地线的。

所以在True循环中,我们寻找一个"0"的值,以表示按钮被按下。一旦我们检测到这个条件,我们就会通过它们的颜色循环LED段。

正如我所说,很简单的东西。

模拟输入测试

现在我们来谈谈模拟输入。

树莓派Pico有三个模拟输入,它们都有12位的分辨率。

这三个输入端如下。

GPIO26-ADC0(31针)

GPIO27-ADC1(针脚32)

GPIO28-ADC2(针脚34)

还有第四个ADC用于内部温度传感器。

电位计的连接

在我们的测试中,我们将使用一个电位器在模拟输入端呈现一个可变电压,然后我们将读取该电压。我们将使用ADC0作为我们的电位计输入,但你也可以使用其他两个中的一个。

1d7950f2-7b3b-11eb-8b86-12bb97331649.png

请注意,虽然我将23号针脚显示为地线,这只是为了方便,但你可以使用任何Pico地线针脚。在33号针脚处还有一个特殊的模拟地,你可以使用。在我的面包板上,我将33号针脚与其他一些地线相连。

电位计读数

我们要做的第一个实验是简单地读取我们在模拟输入端得到的值,这个值应该根据我们电位器的位置而波动。

#树莓派PicoAnalogInputTest#analog-input.py#POT-PicoGPIO26ADC0-Pin32#DroneBotWorkshop2021#https://dronebotworkshop.comimportmachineimportutimepotentiometer=machine.ADC(26)whileTrue:print(potentiometer.read_u16())utime.sleep(2)

这是一个简单的脚本,像往常一样,首先导入用于GPIO操作的machine库和用于时间函数的utime库。

然后我们定义我们的电位器连接。请注意我们如何使用"ADC"来表示我们要将GPIO26针作为模拟输入。当然这只适用于具有模拟输入能力的三个GPIO引脚。

在True循环中,我们只需打印从电位器上得到的值,然后延迟几秒钟再做一次。

需要注意的是,我们用"read_u16"函数得到的值的类型是一个无符号的16位整数。这意味着它将在0和65,535之间变化,而不是你可能期望从12位ADC中得到的4095。

这可能看起来很奇怪,但正如我们将在下一个脚本中看到的那样,能够传递具有相同数值数据类型的值实际上是有用的。

1dd59a2e-7b3b-11eb-8b86-12bb97331649.png

运行脚本并观察Shell,你应该会看到那里的数值随着你移动电位器轴而改变。

LEDPWM控制

让我们在之前的脚本基础上进行扩展,使用电位器的输出来控制LED的亮度。

当然,我们将使用PWM进行控制,这个任务在MicroPython中非常简单。

#树莓派PicoLEDPWMTest#led-pwm.py#POT-PicoGPIO26ADC0-Pin32#REDLED-PicoGPIO10-Pin14#DroneBotWorkshop2021#https://dronebotworkshop.comimportmachineimportutimeled_red=machine.PWM(machine.Pin(10))potentiometer=machine.ADC(26)led_red.freq(1000)whileTrue:led_red.duty_u16(potentiometer.read_u16())

在这个脚本中需要注意的一个关键项目是我们定义"led_red"的方式。我们将其定义为"PWM",而不是输出。

电位器的定义与上一个脚本中的方式完全相同。

现在我们已经给输出赋予了"PWM"的属性,它继承了许多其他参数。其中之一是PWM频率,我们将其设置为1000Hz。

在true循环中,我们不断地从电位器中获取无符号的16位值,并将其传递给LEDs占空比,也方便地指定为无符号的16位整数。

这就说明了两者保持相同的编号方案的价值,不需要将模拟值,真的是0到4095,映射到占空比,真的是0到100。

1e13a85a-7b3b-11eb-8b86-12bb97331649.png

运行程序,你应该可以顺利地控制红色LED段的亮度。

添加显示屏

我们将进行的下一个实验是将一个OLED显示器连接到我们的Pico上,当然,也可以在上面打印一些东西。

我们将使用I2C显示屏,因此我们也将看到Pico如何使用I2C连接工作。记住,Pico有两条I2C总线。

我们的OLED是标准的1602型OLED显示器,到处都有。如果你愿意,也可以使用与我的显示屏尺寸不同的显示屏,只需在代码中更改尺寸即可。

这是我们如何把这些东西都挂起来的,只有四根线。

1e711c4c-7b3b-11eb-8b86-12bb97331649.png

我们的显示器需要一个库,我们可以使用ThonnyID安装。你可能会发现在全菜单模式下比在基本模式下更容易,但这两种方式都可以。

点击"工具"菜单

点击"管理包"

搜索"ssd1306"

找到"ssd1306.py"并安装它。

现在我们已经安装了库,我们可以看一下演示OLED显示屏的脚本。

#树莓派PicoOLEDDisplayTest#Usesssd1306module#display-ssd1306-test.py#DroneBotWorkshop2021#https://dronebotworkshop.comimportmachineimportutimesda=machine.Pin(20)scl=machine.Pin(21)i2c=machine.I2C(0,sda=sda,scl=scl,freq=400000)fromssd1306importSSD1306_I2Coled=SSD1306_I2C(128,32,i2c)print(i2c.scan())oled.text('Welcometothe',0,0)oled.text('PiPico',0,10)oled.text('DisplayDemo',0,20)oled.show()utime.sleep(4)oled.fill(1)oled.show()utime.sleep(2)oled.fill(0)oled.show()whileTrue:oled.text("HelloWorld",0,0)foriinrange(0,164):oled.scroll(1,0)oled.show()utime.sleep(0.01)

我们的OLED显示屏是一个I2C设备,所以你会注意到,在脚本的开头,我们将两个GPIO引脚定义为SDA(GPIO20)和SCL(GPIO21)。

Pico有两条I2C总线,你可以使用几种不同的GPIO引脚来连接它们。但它们并不是随便的引脚,例如某些引脚被指定为总线0的SDA,只有它们才能用于SDA总线0。

然后我们使用机器库的I2C函数定义一个I2C连接。我们需要给它提供以下参数。

I2C总线号,在我们的例子中是0。

SDA引脚

SCL引脚

I2C总线频率--在我们的例子中是400KHz。

然后我们添加OLED库,并创建一个I2COLED对象。我们将大小参数和I2C连接信息传递给它。

注意,我们没有传递I2C地址。SD1306OLED显示器有一个固定的I2C地址,所以我们不需要指定它。

不过,我在这里添加了一行与显示器无关的内容,但可以让你扫描I2C总线,并打印出它发现占用的地址。请注意,在Shell中打印出来的是十进制,而不是你更可能习惯看到的十六进制。

回到OLED脚本!

我们开始在显示屏上打印,几行文字。注意我们如何指定每行开始的像素位置。

实际上,我们并没有直接打印到显示屏上,而是将数据发送到一个缓冲区。oled.show()这一行将把该缓冲区的数据传输到显示器上。

在打印完欢迎信息并按住它四秒钟后,我们再执行oled.fill(1)。这将打开显示器中的每一个像素,或者更准确地说,是缓冲区中的每一个像素。然后我们做一个oled.show()来显示填充。

我们将填充物保持在显示屏上两秒钟,然后执行oled.fill(0),当我们显示它时,它将关闭显示屏中的每个像素。

现在进入True循环。

我们再次输入一些文本,经典的"HelloWorld"。但我们没有进行"显示"来显示它,而是开始一个for-loop。在这个循环中,我们使用led.scroll(1,0)将显示水平移动1像素(垂直移动0像素,这就是另一个参数)。

然后我们在屏幕上显示,然后休眠一段很短的时间。然后我们再做一次。

结果将是显示屏在屏幕上滚动。你可以在for-loop中使用参数来改变它。

1ec813da-7b3b-11eb-8b86-12bb97331649.png

将脚本加载到你的Pico上,然后观看显示。你应该看到欢迎文字,然后是显示填充,然后是空。之后,只要你让实验运行,滚动的"HelloWorld"就会继续。

驱动电机

微控制器比较流行的应用之一是驱动一个或几个直流电动机。

这是通过使用H-Bridge来实现的,H-Bridge是一种功率晶体管或MOSFET的排列方式,可以处理电机电流,同时允许你控制电机的方向和速度。

我们将只用一个电机来实现这一点。我们将使用TB6612FNGH-Bridge和树莓派Pico来控制一个小型直流电机。

TB6612FNGH-Bridge

TB6612FNGH-Bridge是我们之前使用过的,一款基于MOSFET的H-Bridge,相比老款备用的L-298N有很多性能上的优势。

该设备其实有两个通道,我们只用通道A来演示。

通道A有三个输入。

AI1-方向和模式

AI2-方向和模式

PWMA-一个PWM输入,用于控制电机速度。

在它们之间,AI1和AI2引脚控制电机方向和模式。模式包括短制动和停止模式。在我们的简单演示中,我们将只处理方向模式。

TB6612FNGH-Bridge在板子的另一侧还有电源和电机的连接。

下面是我们将使用TB6612FNGH-Bridge和树莓Pico的连接方式。

1f36c49c-7b3b-11eb-8b86-12bb97331649.png

请注意,由于我使用的是6V电机,我已经为它提供了一个6V电源。不要试图使用Pico的输出电压来为你的电机供电,单独的电源是必要的。我使用了四节AA型电池,这是一种简单而安全的安排。

电机的极性其实并不重要,它只是决定了哪条路是向前的,哪条路是向后的。

一旦它被全部连接起来,我们就需要一些代码来运行它。我建议这样做。

#树莓派PicoMotorTest#motor-test.py#POT-PicoGPIO26ADC0-Pin32#REDBUTTON-PicoGPIO15-Pin20#BLACKBUTTON-PicoGPIO2-Pin4#REDLED-PicoGPIO10-Pin14#GREENLED-PicoGPIO11-Pin15#BLUELED-PicoGPIO14-Pin19#DroneBotWorkshop2021#https://dronebotworkshop.comimportmachineimportutimepotentiometer=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)whileTrue:mtr_PWMa.duty_u16(potentiometer.read_u16())ifbutton_red.value()==1:mtr_AI1.value(0)mtr_AI2.value(1)led_red.value(1)led_green.value(0)led_blue.value(0)ifbutton_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)

我们要利用电位器、两个开关和RGBLED,以及电机控制器。电位器将控制电机的速度,开关将控制电机的方向,而LED将用彩色指示灯显示当前的方向。

我们使用我们的之前的两个库,并像以前一样设置电位器。

接下来,我们将Pico与TB6612FNGH-Bridge的连接定义为输出。GPIO6上的PWMA输出被定义为PWM,它将控制电机速度。

LED和按钮的设置与之前相同。

PWM频率设置为50Hz,这是一个任意的选择。随意实验一下,看看是否能提高电机性能。

电机AI1和AI2输入被设置为正向旋转,所以电机将以正向启动。请注意,当我们启动时,RGBLED的蓝段也会被打开。

在True循环中,我们读取电位器的值,并将其传递给电机PWM信号,以控制电机的速度。我们还要看按钮的状态。

如果红色按钮被按下,我们设置AI1和AI2信号,使电机反转。我们也会点亮红色LED段。

如果黑色按钮被按下,我们设置电机方向正向,并打开绿色LED段。

1f81101a-7b3b-11eb-8b86-12bb97331649.png

加载、检查代码。它应该用一个蓝色的LED启动,你应该能够控制电机的速度。按下按钮可以控制方向,还可以改变LED的颜色。

PicoEverything演示

剩下的就是把所有的东西放在一起做一个大的最终演示。这一点我们已经做得不远了,因为在上一个脚本中,我们使用了所有的东西,除了OLED显示屏。

所以让我们把OLED显示屏添加到这个组合中。下面是我们需要做的代码。

#树莓派EverythingTest#everything.py#POT-PicoGPIO26ADC0-Pin32#REDBUTTON-PicoGPIO15-Pin20#BLACKBUTTON-PicoGPIO2-Pin4#REDLED-PicoGPIO10-Pin14#GREENLED-PicoGPIO11-Pin15#BLUELED-PicoGPIO14-Pin19#DroneBotWorkshop2021#https://dronebotworkshop.comimportmachineimportutimepotentiometer=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)fromssd1306importSSD1306_I2Coled=SSD1306_I2C(128,32,i2c)oled.text('PicoMotorTest',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)whileTrue:speedvalue=int((potentiometer.read_u16())/500)mtr_PWMa.duty_u16(potentiometer.read_u16())ifbutton_red.value()==1:mtr_AI1.value(0)mtr_AI2.value(1)led_red.value(1)led_green.value(0)led_blue.value(0)ifbutton_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)

现在你应该能认出这段代码的大部分内容了,基本上就是之前的脚本,加上了I2COLED显示屏的库和设置。除此之外,前几行都是一样的,都是LED颜色的序列,一切设置好后,会有一个Displayprint。

在True循环中,我们看到正在计算一个名为"speedvalue"的整数。这个变量将用于设置OLED上条形图显示的大小。

红色和黑色的按钮和之前的操作完全一样。

然后,OLED在其标题线下画一个矩形,并填入矩形。矩形的长度由"speedvalue"决定,所以随着速度的增加,矩形会变长。

1fcde14c-7b3b-11eb-8b86-12bb97331649.png

从某种意义上说,我们是把OLED当做一个粗略的速度指示器,或者说是一个速度表!

装上所有的东西,看演示效果。它的操作应该和之前的实验一样,只是这次我们除了有一个显示电机速度的显示器外,还有一个指示其方向的RGBLED。

在没有主机的情况下运行

到目前为止,我们所做的一切都是从ThonnyIDE将程序加载到Pico上运行的。

但是,一旦你开发了程序,你就会希望它能够独立运行,由microUSB端口或通过PicoVSYS电源输入供电。

202cc7b6-7b3b-11eb-8b86-12bb97331649.png

你的程序或程序已经存储在Pico上。那么我们如何让它在开机时运行程序呢?

答案是,我们更改程序名称!

主程序main.py

当Pico启动时,它会查找名为main.py的程序。如果它找到了它,就会加载它并在启动时运行它。

因此,如果你想让你的程序在无人看管的情况下运行,你需要将其保存为main.py。稍后,如果你愿意,你可以将main.py改成其他程序,或者完全删除它。

首先将你希望在启动时运行的程序加载到ThonnyIDE中。现在点击"文件",然后选择"另存为"。

你会被问到是否要保存在本地计算机上或Pico上,你肯定要保存在Pico上。

现在把你的程序保存为"main.py"。就像这样,全部用小写。

21089822-7b3b-11eb-8b86-12bb97331649.png

现在从电脑上拔下Pico的插头,并将其插入合适的电源,如USB适配器。你会看到Pico重新开机,并运行你保存为"main.py"的程序。

结束语

这显然只是树莓派Pico的开始。

我很希望看到PlatformIO和ArduinoIDE能够为树莓派Pico提供支持,因为目前为Pico创建C++程序的方法有些繁琐,特别是对于初学者来说。

但它是进入MicroPython的一个很好且廉价的入口,你会在这里看到更多的东西。

所以尽快拿起Pico开始实验吧!

责任编辑:lq

延伸 · 阅读