差别
这里会显示出您选择的修订版和当前版本之间的差别。
两侧同时换到之前的修订记录 前一修订版 后一修订版 | 前一修订版 | ||
mp_key_led [2022/02/24 14:30] gongyusu |
mp_key_led [2023/07/31 15:59] (当前版本) group003 |
||
---|---|---|---|
行 1: | 行 1: | ||
## 用按键控制LED灯 | ## 用按键控制LED灯 | ||
- | 我们开始将基本的电子元件连接到你的树莓派Pico上,并编写程序来控制和感知它们,就像我们的大脑可以控制我们的四肢,通过感知器官获取外界的反应。树莓派Pico的RP2040微控制器在设计时就充分考虑到了对外部硬件器件的连接、感知和控制,它有许多通用输入/输出(GPIO)引脚来同各种元器件进行连接和通信,这样我们可以构建多种不同的项目,从最简单的点亮[[LED]]到记录关于你周围世界的数据。 | + | 我们开始将基本的电子元件连接到你的[[rpi_pico|树莓派Pico]]上,并编写程序来控制和感知它们,就像我们的大脑可以控制我们的四肢,通过感知器官获取外界的反应。树莓派Pico的[[RP2040]]微控制器在设计时就充分考虑到了对外部硬件器件的连接、感知和控制,它有许多通用输入/输出([[GPIO]])引脚来同各种元器件进行连接和通信,这样我们可以构建多种不同的项目,从最简单的点亮[[LED]]到记录关于你周围世界的数据。 |
行 80: | 行 80: | ||
</code> | </code> | ||
- | 然而,这一次运行这个程序,LED似乎永远不会亮起来,这是因为Pico的工作速度非常非常快,远远快于我们用肉眼看到的速度。LED亮了一下,在下一条指令就让它灭掉,亮的时间非常短暂,短暂到我们的眼睛无法看到。要解决这个问题,我们需要通过引入延迟来降低程序的执行速度进而延长LED亮的时间。 | + | 然而,这一次运行这个程序,[[LED]]似乎永远不会亮起来,这是因为[[rpi_pico|Pico]]的工作速度非常非常快,远远快于我们用肉眼看到的速度。LED亮了一下,在下一条指令就让它灭掉,亮的时间非常短暂,短暂到我们的眼睛无法看到。要解决这个问题,我们需要通过引入延迟来降低程序的执行速度进而延长LED亮的时间。 |
回到程序的顶部, 在第一行的末尾单击并按回车键以插入新的第二行。在这一行输入: | 回到程序的顶部, 在第一行的末尾单击并按回车键以插入新的第二行。在这一行输入: | ||
行 88: | 行 88: | ||
</code> | </code> | ||
- | 像导入“machine”库一样,这一行将一个新库 - 'utime'库导入到MicroPython。这个库处理与时间有关的所有事情,从测量时间到在程序中插入延迟。 | + | 像导入“machine”库一样,这一行将一个新库 - 'utime'库导入到[[MicroPython]]。这个库处理与时间有关的所有事情,从测量时间到在程序中插入延迟。 |
到程序的底部,单击行led_onboard.value(1)的末尾,然后按回车以插入新行。键入: | 到程序的底部,单击行led_onboard.value(1)的末尾,然后按回车以插入新行。键入: | ||
行 102: | 行 102: | ||
**UTIME vs TIME** | **UTIME vs TIME** | ||
- | 如果你以前用Python编写过程序,你将习惯于使用“time”的库。utime库是为像Pico这样的微控制器设计的版本——“u”代表“μ”,希腊字母“mu”,是“micro”的缩写。如果我们忘记并使用了导入时间,不要担心, MicroPython将自动使用utime库代替。 | + | 如果你以前用[[Python]]编写过程序,你将习惯于使用“time”的库。utime库是为像Pico这样的微控制器设计的版本——“u”代表“μ”,希腊字母“mu”,是“micro”的缩写。如果我们忘记并使用了导入时间,不要担心, MicroPython将自动使用utime库代替。 |
</WRAP> | </WRAP> | ||
行 120: | 行 120: | ||
</code> | </code> | ||
- | 记住,循环中的行需要缩进四个空格,这样MicroPython就知道它们构成了循环。 | + | 记住,循环中的行需要缩进四个空格,这样[[MicroPython]]就知道它们构成了循环。 |
- | 再次点击“Run”图标,我们会看到LED开关打开5秒、关闭5秒、再打开,不断重复在无限循环。LED将继续闪烁,直到我们点击停止图标取消我们的程序和重置我们的Pico。 | + | 再次点击“Run”图标,我们会看到[[LED]]开关打开5秒、关闭5秒、再打开,不断重复在无限循环。LED将继续闪烁,直到我们点击停止图标取消我们的程序和重置我们的Pico。 |
还有另一种方法可以处理相同的工作:使用toggle(切换),而不是显式地将LED的输出设置为0或1。删除程序的最后四行并替换它们,使其看起来像这样: | 还有另一种方法可以处理相同的工作:使用toggle(切换),而不是显式地将LED的输出设置为0或1。删除程序的最后四行并替换它们,使其看起来像这样: | ||
行 147: | 行 147: | ||
### 2. 控制学习板上的LED | ### 2. 控制学习板上的LED | ||
- | 到目前为止,我们一直在使用树莓派Pico核心板,在其RP2040微控制器上运行MicroPython程序,改变板载LED的点亮和熄灭的状态。微控制器通常与更多的外部元器件一起使用,也正是为此,我们设计了这个基于Pico的学习板。在MicroPython中控制学习板上的LED与控制Pico核心板内部的LED没有什么不同,只是管脚的编号发生了变化而已。 | + | 到目前为止,我们一直在使用树莓派Pico核心板,在其[[RP2040]]微控制器上运行[[MicroPython]]程序,改变板载LED的点亮和熄灭的状态。微控制器通常与更多的外部元器件一起使用,也正是为此,我们设计了这个基于Pico的学习板。在MicroPython中控制学习板上的LED与控制Pico核心板内部的LED没有什么不同,只是管脚的编号发生了变化而已。 |
打开Thonny,加载前面写好的的Blink.py程序。找到: | 打开Thonny,加载前面写好的的Blink.py程序。找到: | ||
行 155: | 行 155: | ||
</code> | </code> | ||
- | 修改引脚编号,将它从连接到Pico核心板内部LED的引脚25更改为连接到学习板上红色LED的引脚19。这个LED的名称也最好随之修改,比如改为led_red。程序中所有用到该LED的地方,都要把名字修改过来: | + | 修改引脚编号,将它从连接到Pico核心板内部LED的引脚25更改为连接到学习板上红色LED的引脚26。这个LED的名称也最好随之修改,比如改为led_red。程序中所有用到该LED的地方,都要把名字修改过来: |
<code python> | <code python> | ||
import machine | import machine | ||
import utime | import utime | ||
- | led_red = machine.Pin(19, machine.Pin.OUT) | + | led_red = machine.Pin(26, machine.Pin.OUT) |
while True: | while True: | ||
行 174: | 行 174: | ||
### 3. 输入: 读取按钮开关 | ### 3. 输入: 读取按钮开关 | ||
- | 前面的LED都是利用了GPIO的输出特性,其实RP2040的GPIO既可以做输出控制,也可以做输入状态监测使用。在树莓派Pico核心板上没有放置任何输入按键,在我们的学习板上特地放了两个轻触按键: | + | 前面的LED都是利用了GPIO的输出特性,其实[[RP2040]]的[[GPIO]]既可以做输出控制,也可以做输入状态监测使用。在树莓派Pico核心板上没有放置任何输入按键,在我们的学习板上特地放了两个轻触按键: |
|按键|GPIO管脚编号| | |按键|GPIO管脚编号| | ||
|KEY1|12| | |KEY1|12| | ||
行 182: | 行 182: | ||
**隐藏起来的阻抗** | **隐藏起来的阻抗** | ||
- | 与LED不同的是,按钮开关不需要限流电阻。但它仍需要一个电阻器,用于上拉或下拉,取决于你的电路如何工作。没有上拉或下拉电阻,输入被称为浮动 - 这意味着它有一个“噪声”信号,即使你不按按钮,它也会触发。电路中的电阻在哪里? 藏在Pico的微控制器RP2040里,可以为每一个GPIO管脚编程电阻,根据电路的需要在MicroPython中设置为下拉电阻或上拉电阻。 | + | 与LED不同的是,按钮开关不需要限流电阻。但它仍需要一个电阻器,用于上拉或下拉,取决于你的电路如何工作。没有上拉或下拉电阻,输入被称为浮动 - 这意味着它有一个“噪声”信号,即使你不按按钮,它也会触发。电路中的电阻在哪里? 藏在Pico的微控制器[[RP2040]]里,可以为每一个[[GPIO]]管脚编程电阻,根据电路的需要在[[MicroPython]]中设置为下拉电阻或上拉电阻。 |
有什么区别呢?一个下拉电阻连接引脚接地,意思是当按钮没有按下时,输入是0。一个上拉电阻将引脚连接到3V3,这意味着当按钮没有被按下时,输入将是1。所有的电路在这本书中使用可编程电阻在下拉模式。 | 有什么区别呢?一个下拉电阻连接引脚接地,意思是当按钮没有按下时,输入是0。一个上拉电阻将引脚连接到3V3,这意味着当按钮没有被按下时,输入将是1。所有的电路在这本书中使用可编程电阻在下拉模式。 | ||
</WRAP> | </WRAP> | ||
- | 加载Tonny,然后用通常的代码行启动一个新程序: | + | 加载[[Thonny_ide|Thonny]],然后用通常的代码行启动一个新程序: |
<code python> | <code python> | ||
行 218: | 行 218: | ||
import utime | import utime | ||
- | key1 = machine.Pin(12, machine.Pin.IN, machine.Pin.PULL_DOWN) | + | key1 = machine.Pin(12, machine.Pin.IN, machine.Pin.PULL_UP) |
while True: | while True: | ||
- | if key1.value() == 1: | + | if key1.value() == 0: |
print("You pressed the button!") | print("You pressed the button!") | ||
utime.sleep(2) | utime.sleep(2) | ||
行 233: | 行 233: | ||
实际上,这个电路将前两个电路合并成一个,你可能记得你使用引脚GP19驱动外学习板上红色的LED,并用引脚GP12读取学习板上的一个按键的状态,现在我们将输入按键和输出LED一起联动工作。 | 实际上,这个电路将前两个电路合并成一个,你可能记得你使用引脚GP19驱动外学习板上红色的LED,并用引脚GP12读取学习板上的一个按键的状态,现在我们将输入按键和输出LED一起联动工作。 | ||
- | 在Tonny中启动一个新程序,并开始导入程序需要的两个库: | + | 在Thonny中启动一个新程序,并开始导入程序需要的两个库: |
<code python> | <code python> | ||
行 243: | 行 243: | ||
<code python> | <code python> | ||
- | led_red = machine.Pin(19, machine.Pin.OUT) | + | led_red = machine.Pin(26, machine.Pin.OUT) |
- | key1 = machine.Pin(12, machine.Pin.IN, machine.Pin.PULL_DOWN) | + | key1 = machine.Pin(12, machine.Pin.IN, machine.Pin.PULL_UP) |
</code> | </code> | ||
行 250: | 行 250: | ||
<code python> | <code python> | ||
while True: | while True: | ||
- | if key1.value() == 1: | + | if key1.value() == 0: |
</code> | </code> | ||
行 271: | 行 271: | ||
import utime | import utime | ||
led_red = machine.Pin(19, machine.Pin.OUT) | led_red = machine.Pin(19, machine.Pin.OUT) | ||
- | key1 = machine.Pin(12, machine.Pin.IN, machine.Pin.PULL_DOWN) | + | key1 = machine.Pin(12, machine.Pin.IN, machine.Pin.PULL_UP) |
while True: | while True: | ||
- | if key1.value() == 1: | + | if key1.value() == 0: |
led_red.value(1) | led_red.value(1) | ||
utime.sleep(2) | utime.sleep(2) | ||
行 290: | 行 290: | ||
+ | <WRAP center round tip 60%> | ||
+ | 以下部分为其它与LED控制相关的参考案例。 | ||
+ | </WRAP> | ||
### 5. 案例汇总 | ### 5. 案例汇总 | ||
行 298: | 行 301: | ||
# rgb-blink.py | # rgb-blink.py | ||
- | # RED LED - Pico GPIO 19 | + | # RED LED - Pico GPIO 26 |
- | # GREEN LED - Pico GPIO 18 | + | # GREEN LED - Pico GPIO 22 |
- | # BLUE LED - Pico GPIO 17 | + | # BLUE LED - Pico GPIO 21 |
- | # YELLOW LED - Pico GPIO 16 | + | # YELLOW LED - Pico GPIO 20 |
# EETree Info & Tech 2021 | # EETree Info & Tech 2021 | ||
# https://www.eetree.cn | # https://www.eetree.cn | ||
行 309: | 行 312: | ||
import utime | import utime | ||
- | led_red = machine.Pin(19, machine.Pin.OUT) | + | led_red = machine.Pin(26, machine.Pin.OUT) |
- | led_green = machine.Pin(18, machine.Pin.OUT) | + | led_green = machine.Pin(22, machine.Pin.OUT) |
- | led_blue = machine.Pin(17, machine.Pin.OUT) | + | led_blue = machine.Pin(21, machine.Pin.OUT) |
- | led_yellow = machine.Pin(16,machine.Pin.OUT) | + | led_yellow = machine.Pin(20,machine.Pin.OUT) |
行 382: | 行 385: | ||
import utime | import utime | ||
- | key1 = machine.Pin(12, machine.Pin.IN, machine.Pin.PULL_DOWN) | + | key1 = machine.Pin(12, machine.Pin.IN, machine.Pin.PULL_UP) |
key2 = machine.Pin(13, machine.Pin.IN, machine.Pin.PULL_UP) | key2 = machine.Pin(13, machine.Pin.IN, machine.Pin.PULL_UP) | ||
while True: | while True: | ||
- | if key1.value() == 1: | + | if key1.value() == 0: |
print("key1 pressed") | print("key1 pressed") | ||
| | ||
行 400: | 行 403: | ||
# interrrupt-toggle-demo.py | # interrrupt-toggle-demo.py | ||
- | # RED LED - Pico GPIO 19 | + | # RED LED - Pico GPIO 26 |
- | # GREEN LED - Pico GPIO 18 | + | # GREEN LED - Pico GPIO 22 |
# KEY1 - Pico GPIO 12 | # KEY1 - Pico GPIO 12 | ||
行 411: | 行 414: | ||
import utime | import utime | ||
- | led_red = machine.Pin(19, machine.Pin.OUT) | + | led_red = machine.Pin(26, machine.Pin.OUT) |
- | led_green = machine.Pin(18, machine.Pin.OUT) | + | led_green = machine.Pin(22, machine.Pin.OUT) |
led_red.value(0) | led_red.value(0) | ||
led_green.value(0) | led_green.value(0) | ||
- | key1 = machine.Pin(12, machine.Pin.IN, machine.Pin.PULL_DOWN) | + | key1 = machine.Pin(12, machine.Pin.IN, machine.Pin.PULL_UP) |
def int_handler(pin): | def int_handler(pin): | ||
行 428: | 行 431: | ||
key1.irq(handler=int_handler) | key1.irq(handler=int_handler) | ||
- | button_red.irq(trigger=machine.Pin.IRQ_RISING, handler=int_handler) | + | key1.irq(trigger=machine.Pin.IRQ_FALLING , handler=int_handler) |
while True: | while True: | ||
行 441: | 行 444: | ||
# switch-led-demo.py | # switch-led-demo.py | ||
- | # RED LED - Pico GPIO 19 | + | # RED LED - Pico GPIO 26 |
- | # GREEN LED - Pico GPIO 18 | + | # GREEN LED - Pico GPIO 22 |
- | # BLUE LED - Pico GPIO 17 | + | # BLUE LED - Pico GPIO 21 |
# BLACK BUTTON - Pico GPIO 2 - Pin 4 | # BLACK BUTTON - Pico GPIO 2 - Pin 4 | ||
行 453: | 行 456: | ||
import utime | import utime | ||
- | led_red = machine.Pin(19, machine.Pin.OUT) | + | led_red = machine.Pin(26, machine.Pin.OUT) |
- | led_green = machine.Pin(18, machine.Pin.OUT) | + | led_green = machine.Pin(22, machine.Pin.OUT) |
- | led_blue = machine.Pin(17, machine.Pin.OUT) | + | led_blue = machine.Pin(21, machine.Pin.OUT) |
led_red.value(0) | led_red.value(0) | ||
行 503: | 行 506: | ||
</code> | </code> | ||
- | |||
- | 来自FPGA4FUN上的介绍 | ||
- | 理想的LED控制是电流源,控制器的引脚是电压控制的,所以一个简单的解决方案是添加一个电阻与LED串联,电阻的阻值从100Ω到1KΩ都很常见。 | ||
- | |||
- | LED (Light Emitting Diode)是一种半导体器件,当电流通过它时,它就会发光。LED符号看起来像一个二极管,有一个阳极(+)和阴极(-)。 | ||
- | 一个LED就像一个二极管,用一种方式导电,用另一种方式阻挡。 | ||
- | |||
- | 像所有二极管一样,它也有一个阈值电压。普通红色LED的阈值电压约为2.0V。2.0V以下不发光(无电流通过LED)。在2.0V以上,LED导电,光强度取决于通过LED的电流。 | ||
- | |||
- | LED有两个不能超过的物理极限: | ||
- | 最大正向电流(即最大光强)。最大值通常是几个10的mA。 | ||
- | 最大反向电压(即使当LED被反向偏置时没有电流通过,也不要反向偏置太多)。反向电压限制通常为5V…比普通二极管低得多! | ||