树莓派学习之旅:交通信号灯
学习资料来自Get started with MicroPython on Raspberry Pi Pico
所需材料
- 树莓派Pico
- 一块面包板
- 一个绿色LED,一个黄色(或琥珀色)LED,一个红色LED
- 三个330Ω的电阻
- 一个压电式蜂鸣器
- 公对公跳线若干
简单信号灯
连接电路
与之前一样,使LED跨国中心缝,并组装电阻,如下图所示:
实物图(效果图):
一定要牢记LED需要一个限流的电阻。如果忘了连接电阻,最好的结果是LED烧坏并停止工作,最坏的结果是Pico损坏。
代码实现
首先,还是导入所需模块
1 | import machine |
定义每一个LED
1 | led_red = machine.Pin(15, machine.Pin.OUT) |
真正的信号灯不会停掉,所以要实现无限循环。
1 | while True: |
“海鹦”式路口信号灯
项目设计
真正的信号灯并不是只为车辆服务的,它们也需要保护行人。在英国,最常见的信号灯被称为pedestrian-operated user-friendly intelligent crossings或puffin crossings。
为使之成为“海鹦”式路口信号灯,我们还需要一个开关(以使行人能告知信号灯以便安全地穿过马路)和一个蜂鸣器(以便使行人能知道他们该合适穿过马路)
连接电路
代码实现
拆解分析
定义按钮与蜂鸣器
1 | button = machine.Pin(16, machine.Pin.IN, machine.Pin.PULL_DOWN) |
对于基本的信号灯,这足够了。但如果要实现“海鹦”式,那么我们需要记录按钮是否被摁下,同时不打断信号灯亮的进程。为实现这一点,我们需要再导入一个库_thread:
1 | import _thread |
在开始另一个线程之前,我们需要使新线程能像主线程传递信息。为实现这一点,我们可以是用全局变量。
在buzzer =这一行下面,添加
1 | global button_pressed |
上面的代码将button_pressed设置为全局变量,并设定默认值为False——也就是说程序开始时按钮尚未被按下。
下一步就是定义新线程
1 | def button_reader_thread(): |
第一行我们给新的线程定义了一个形象的名字。
第二行让Micro
Python知道我们即将改变全局变量button_pressed的值。如果没有这一行,我们就无法改变该全局变量的值。
接着,我们又开始了一个循环。
下一行,我们检查button_value()是否等于1。当按钮被按下时,值为1;未被按下时,值为0。只有button_value()为1时,我们才把button_pressed设置为True,以便让程序后面知道该按钮被按下了。
随后,用utime.sleep(0.01)让程序停下非常短的时间,以免循环运行地太快了。
注意到在此线程中,按钮被释放我们并没有把button_pressed重设为False,原因如下:在一个信号灯周期中,行人随时可以按下按钮,但只有信号灯变红和能够安全通过时才能起作用。新线程所要做的就是在按钮摁下时改变变量,当行人安全通过路口后我们的主线程会将其重设为False。
仅仅定义一个线程并不会直接让它运行,要想开始一个线程,我们需要告知_thread库。
在我们定义的线程后再加一行,并删去自动生成的缩进:
1 | _thread.start_new_thread(button_reader_thread, ()) |
找到主循环,并在while True那一行下面添加
1 | if button_pressed == True: |
这一部分代码用于检查全局变量button_pressed的值以确定按钮是否被按下。如果确被按下,那么使红灯亮并使蜂鸣器响十次的那部分代码就会开始运行。
完整代码
1 | import machine |
