任务要求
- 了解树莓派Pico平台控制LEDs行为流程方法
- 能够改变LEDs发光顺序以及停留时间
- 可以通过按钮来延长红灯时间,并通过蜂鸣器发出警报,即仿真马路上的交通灯的工作状态切换,利用板上的红、黄、绿三种颜色的LED显示道路状态的切换,行人按键时,具有优先功能
一、配置环境
1、thonny:
Thonny是基于python内置图形库tkinter开发出来的支持多平台(windows,Mac,Linux)的python IDE,支持语法着色、代码自动补全、debug等功能,如果你正在寻找一种“轻量级”的python IDE,那么可以试一试Thonny。作为官方推荐的开发软件,thonny页面简洁,基础功能齐全,简单易上手,非常适合初学者。安装的教程网上比较多,有两种方式可以安装Thonny,从官网下载exe文件,然后安装,或者直接使用pip安装。
2、硬禾学堂树莓派pico平台:
硬禾学堂为“暑期一起练”制作了一个平台,基于树莓派PICO的嵌入式系统学习平台,可以通过C/C++以及Micro-Python编程来学习嵌入式系统的工作原理和应用。STEP PICO为兼容树莓派官方PICO的核心模块,在其基础上增加了WS2812彩色灯,以及一个复位按键 。
二、程序实现
整个系统运作流程主要通过控制树莓派Pico上的LED灯和蜂鸣器,实现一个交通灯系统。代码的解释如下:
- 首先,导入一些需要用到的模块,如time(时间模块),ws2812b(LED灯控制模块),button(按钮模块),machine(硬件控制模块)和board(引脚配置模块)。
import time
import ws2812b
from button import k1
from machine import PWM, Pin
from board import pin_cfg
- 然后,创建一个PWM对象,用来控制蜂鸣器的频率和占空比。PWM是一种调制方式,可以用来产生不同音调的声音。
pwm = PWM(Pin(pin_cfg.buzzer))
- 接着,定义一个pitch函数,用来设置蜂鸣器的频率和持续时间,并让它发出声音。
def pitch(frequency, duration=0):
pwm.freq(frequency)
pwm.duty_u16(3000)
time.sleep_ms(duration)
- 然后,定义三个函数,分别用来点亮红色,黄色和绿色的LED灯。每个函数都使用ws2812b.on方法来设置每个LED灯的颜色。绿色灯还有一个特殊的效果,就是在亮四秒后会闪烁五次。
def red_light():
for i in range(1, 13):
ws2812b.on(i, "#ff0000")
def yellow_light():
for i in range(1, 13):
ws2812b.on(i, "#ffff00")
def green_light():
for i in range(1, 13):
ws2812b.on(i, "#00ff00")
time.sleep(4)
i = 0
while i < 5:
ws2812b.on_all("#00ff00")
time.sleep(0.2)
ws2812b.off_all()
time.sleep(0.2)
i=i+1
- 最后,使用一个while循环来不断重复以下步骤:
- 如果检测到按钮被按下,则点亮红色灯。然后使用两个for循环来产生一个上升和下降的音阶效果,并关闭蜂鸣器。
while True:
if k1.value() == True:
red_light()
print("+5 start")
for i in range(10):
for freq in range(880, 1760, 16):
pitch(freq, 6)
for freq in range(1760, 880, -16):
pitch(freq, 6)
print("+5 end")
pwm.deinit()
- 点亮红色灯并等待七秒。
- 点亮绿色灯并执行闪烁效果。
- 点亮黄色灯并等待两秒。
red_light()
time.sleep(7)
green_light()
yellow_light()
time.sleep(2)
这样就完成了一个简单的交通灯系统。
程序流程并不复杂,整体设计上基本满足了一个小型化路口所需要的交通指示需求,实现了在原本交通情况下路人优先的原则。以下为基本程序框图:
三、优化方向
我做的这个项目难度系数很低,后来我也想了很多方法去优化整个过程,使得内存占用尽量少。
针对导入模块到创建PWM对象,我找到了一些优化的方式和方法:
• 将导入模块放在文件开头,并按照标准库、第三方库、本地库的顺序进行排序。这样可以提高代码可读性和规范性。
• 如果只需要使用模块中的部分功能,则可以只导入需要的名称,而不是整个模块。这样可以减少命名空间污染和内存占用。例如:
from machine import SPI, Pin,PWM
from ssd1306 import SSD1306_SPI
from button import k1
• 如果可能的话,尽量避免使用全局变量,并将相关的功能封装成类或函数。这样可以提高代码可维护性和复用性 (stackify.com) (realpython.com)。例如:
class TrafficLight:
def __init__(self):
self.spi = SPI(1, 100000, mosi=Pin(pin_cfg.spi1_mosi), sck=Pin(pin_cfg.spi1_sck))
self.oled = SSD1306_SPI(128, 64, self.spi, Pin(pin_cfg.spi1_dc),Pin(pin_cfg.spi1_rstn), Pin(pin_cfg.spi1_cs))
self.pwm = PWM(Pin(pin_cfg.buzzer))
# Clear the oled display in case it has junk on it.
self.oled.fill(0)
def pitch(self,frequency, duration=0):
self.pwm.freq(frequency)
self.pwm.duty_u16(3000)
time.sleep_ms(duration)
四、项目总结
我觉得基于树莓派pico平台完成的交通灯系统是一个有趣和实用的项目。树莓派pico是一款低成本、高性能、易于使用的微控制器板,可以用来控制各种外部设备,如LED灯、蜂鸣器、OLED显示屏等。它也支持Python语言,可以让编程更简单和快速。我认为这个项目可以展示树莓派pico的功能和特点,也可以锻炼编程和硬件操作的能力。这次也是自己时间规划上的问题,并没有做出更有意思和挑战性的项目,但是在完成这个项目之后,我也有了一些其他的想法:基于这个平台还能实现一些不同的交通控制系统,例如:
• 基于物联网的交通灯控制系统,可以根据车辆计数来更新信号灯的时间,并通过WI-FI模块将当前路口的车流量传输给下一个路口,从而减少拥堵。
• 基于CircuitPython的交通灯和行人过街模拟器,可以使用多个LED灯来模拟不同的信号灯,并使用按钮来检测行人是否按下过街请求。
• 基于Pico W的无线控制项目,可以使用Pico W上的Wi-Fi和蓝牙功能来远程控制交通灯或其他设备。
这些项目涉及到了树莓派pico的基本使用,包括如何连接外部设备,如何编程控制GPIO引脚,如何使用UART、SPI、I2C等通信协议。CircuitPython的基本语法和特性,包括如何导入模块,如何定义函数和类,如何使用迭代器和生成器,如何处理异常和错误。物联网的基本概念和应用,包括如何使用WI-FI或蓝牙模块进行无线通信,如何使用云服务或数据库存储和分析数据,如何实现远程控制和监测。图像处理的基本方法和技术,包括如何使用MATLAB或OpenCV等工具进行图像采集、预处理、分割、特征提取、识别等操作。感谢电子森林为知识传播做出的贡献,我也会在自己感兴趣的道路上继续走下去。