基于STEP Pico的音乐氛围灯
本项目基于STEP Pico完成音乐氛围灯,实现了播放音乐、切换灯效等功能。
标签
嵌入式系统
MicroPython
PICO
RP2040
2023寒假在家练
136ytr
更新2023-03-29
汕头大学
781

 

项目介绍

本项目基于STEP Pico嵌入式系统学习平台完成音乐氛围灯,实现了播放音乐、切换灯效等功能。

硬件介绍

本项目所用硬件为基于STEP Pico的嵌入式系统学习平台,配置如下图:
板卡功能及管脚映射表
本项目主要使用了如下硬件:

  • 2个按键输入
  • 12个WS2812B RGB三色灯
  • 1个128*64 OLED显示屏
  • 1个蜂鸣器
  • 1个可调电位计
软件工具
  • Thonny:用于代码编写、调试及上传
  • ampy:用于将资源文件上传到板卡中
设计思路
  • 音乐播放:利用awesome-micropython-lib代码库和PicoAudioPWM代码库提供的文件,通过PWM生成不同频率、持续时间不同的音调,驱动蜂鸣器播放.wav格式的音乐。
  • 氛围彩灯:利用eetree-mpy-lecture-code代码库中的ws2812b.py文件,利用板上的12个彩色LED灯,实现不同的显示效果,内置三种灯效。通过按键改变灯效模式全局变量led_mode,实现切换灯效的功能,同时通过ADC采集电位器电压值来调节彩灯亮度。
  • 按键控制:按键按下时产生下降沿信号,触发外部中断,callback函数对按键按下事件进行处理,改变控制音乐播放和灯效的全局变量,每次触发中断后设定最快下次触发中断时间,实现消抖功能。
  • 显示说明:利用eetree-mpy-lecture-code代码库中的ssd1306.py文件,在OLED屏幕上对操作进行简要说明。
  • 多线程控制:利用_thread库,给音乐播放和彩灯控制分别分配线程,实现同步运行。程序流程图
实现功能
  • 音乐播放:利用板上的蜂鸣器播放音乐
  • 氛围彩灯:利用板上的12个彩色LED灯,实现不同的显示效果,内置三种灯效
  • 亮度调节:利用板上的电位器调节彩色LED亮度
  • 按键控制:利用板上的按键控制音乐的播放和灯效的切换
  • 显示说明:利用板上的OLED显示屏显示简要说明
    实现功能示意图
主要代码片段
音乐播放

利用awesome-micropython-lib代码库和PicoAudioPWM代码库提供的文件,通过PWM生成不同频率、持续时间不同的音调,驱动蜂鸣器播放.wav格式的音乐。

from wavePlayer import wavePlayer
import machine

def music_play():
    lock.acquire()
    pwm = machine.PWM(machine.Pin(19))
    global k1_pressed
    while True:
        if k1_pressed:
            player = wavePlayer()
            player.play("/tkmyjx.wav")
            k1_pressed = 0
氛围彩灯

利用eetree-mpy-lecture-code代码库中的ws2812b.py文件,利用板上的12个彩色LED灯,实现不同的显示效果,内置三种灯效。通过按键改变灯效模式全局变量led_mode,实现切换灯效的功能,同时通过ADC采集电位器电压值来调节彩灯亮度。

import ws2812b
import machine
import time

def led_show():
    adc = machine.ADC(28)
    i = 0
    jj = 0
    while True:
        brightness = adc.read_u16()/65535  #通过ADC采集的电位器电压值来调节彩灯亮度
        if led_mode == 0:
            i = (i+15)%255
            for ii in range(12):
                pos = int(ii*256/12-i)%255
                ws2812b.set_24bit_rgb(ii, ws2812b.wheel(pos), brightness)
            time.sleep_ms(1)
        elif led_mode == 1:
            jj = (jj+1)%12
            ws2812b.google_home(jj, brightness)
        elif led_mode == 2:
            jj = (jj+1)%12
            ws2812b.amazon_alexa(jj, brightness)
按键控制

按键按下时产生下降沿信号,触发外部中断,callback函数对按键按下事件进行处理,改变控制音乐播放和灯效的全局变量,每次触发中断后设定最快下次触发中断时间,实现消抖功能。

import machine
import time

k1_pressed = 0
led_mode = 0
next_call_time = 0

def k1_callback(pin):
    global k1_pressed
    k1_pressed = 1

k1 = machine.Pin(12, machine.Pin.IN, machine.Pin.PULL_UP)
k1.irq(trigger=machine.Pin.IRQ_FALLING, handler=k1_callback)

def k2_callback(pin):
    global led_mode, next_call_time
    
    if time.ticks_diff(time.ticks_ms(), next_call_time) > 0:
        next_call_time = time.ticks_add(time.ticks_ms(), 20)
        led_mode += 1
        led_mode %= 3

k2 = machine.Pin(13, machine.Pin.IN, machine.Pin.PULL_UP)
k2.irq(trigger=machine.Pin.IRQ_FALLING, handler=k2_callback)
显示说明

利用eetree-mpy-lecture-code代码库中的ssd1306.py文件,在OLED屏幕上显示两行文字,对操作进行简要说明。

from ssd1306 import SSD1306_SPI
import machine

def oled_show():
    spi = machine.SPI(1, 100000, mosi = machine.Pin(11), sck = machine.Pin(10))
    oled = SSD1306_SPI(128, 64, spi, machine.Pin(9), machine.Pin(8), machine.Pin(29))
    oled.text("K1: Play music",8,20)
    oled.text("K2: Change LED",8,36)
    oled.show()
多线程控制

利用_thread库,双线程分别分配给音乐播放和彩灯控制,实现同步运行。

import _thread

lock = _thread.allocate_lock()
oled_show()
_thread.start_new_thread(music_play,())
led_show()
遇到主要难题及解决方法

调试多线程过程中意外导致整个板卡卡死,无法连接电脑。
通过烧录擦除flash的.uf2固件后,重新烧录.uf2启动文件解决。

存在问题
  1. 程序在跑灯效3时有时会卡死,导致整个系统死机,目前已较长时间未出现该问题,可能是之前调试过程中的小失误。
  2. _thread库的使用还不太熟练,特别是对于线程锁的使用,目前程序是误打误撞调试到能够成功运行,调试过程中还导致整个板卡卡死,无法连接电脑。
  3. 还不太了解wavePlayer库具体的工作原理,在其定义中使用2号引脚作为左声道,3号引脚作为右声道,4号引脚作为地,以此连接双声道耳机输出,实际使用中发现不应更改这几个引脚定义,而需要在主程序中初始化19号引脚的PWM输出,即可使用。
    class wavePlayer:
    	def __init__(self,leftPin=Pin(2),rightPin=Pin(3), virtualGndPin=Pin(4),
    	             dma0Channel=10,dma1Channel=11,dmaTimer=3,pwmBits=10):
    	    #left channel Pin needs to be an even GPIO Pin number
    	    #right channel Pin needs to be left channel + 1
    
未来计划
  1. 增加对音频的频谱分析功能,通过OLED屏幕或彩灯来动态展示音乐图谱,增强互动性。
  2. 可以增加电池,提高模块的便携性。
参考资料

用MicroPython开发ESP32-文件传输工具-ampy_晨之清风的博客-CSDN博客
GitHub - joeky888/awesome-micropython-lib: Awesome MicroPython libs
GitHub - danjperron/PicoAudioPWM:带有 8KHz 立体声波形文件的 pico 上的 PWM 音频
播放音频文件 - MicroPython for Kids
ESP32 MicroPython教程:外部中断_pin.irq_zhazhawoaini的博客-CSDN博客
树莓派Pico迷你开发板MicroPython多线程编程实践_袁易学的博客-CSDN博客
picospuch/eetree-mpy-lecture-code - 码云 - 开源中国

附件下载
PicoAudioAndLed.zip
全部代码及音频文件
团队介绍
汕头大学 姚罗然
团队成员
136ytr
评论
0 / 100
查看更多
目录
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2023 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号