这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » DIY与开源设计 » 电子DIY » Let'sdo-2025年第3期-DIY拾色播放器-过程帖4:蜂鸣器

共1条 1/1 1 跳转至

Let'sdo-2025年第3期-DIY拾色播放器-过程帖4:蜂鸣器

助工
2025-12-09 17:33:45     打赏

上一贴学习测试了 D2按钮,特别是使用 Debounce库进行了消抖处理:

    https://forum.eepw.com.cn/thread/398114/1

这次赶紧来测试下beep蜂鸣器,并且让它跟着D1 和 D2按钮的动作鸣起来~~

 

l  Beep硬件和接线

蜂鸣器我使用的是手头的存货,比较简单的3根线,丝印上显著位置标着:低电平触发。如图

 image.png


      图中可以看出,三根线除了GND和VCC外,只有一个IO口控制发声,低电平触发(有声音)。接线图如下:

          Beep的GND引脚-------- 板子的GND引脚

          I/O引脚-------- 板子的D13(GPIO13)

          VCC引脚-------- 板子的 VCC(3.3V)

 

l  Beep播放音符原理

       我们本次任务选择了8个音阶:“哆瑞米发嗦啦西哆”,主要组成是C大调,每个音符都有其特定的频率,八个音符的名字及其对应的音高分别是:

       哆(Do) : C4    261.63 Hz

       瑞(Re) : D4    293.66 Hz

       米(Mi) : E4    329.63 Hz

       发(Fa)  : F4    349.23 Hz

       嗦(Sol): G4    392.00 Hz

       啦(La) : A4    440.00 Hz

       西(Ti)  : B4    493.88 Hz

       哆(Do): C5    523.25 Hz

       蜂鸣器要播放这些音阶,需要通过不同频率的PWM来实现。根据上面的接线图,在D13引脚上输出对应这些频率的PWM信号,从而Beep发出不同频率的音调声音,也就是对应的音符。

   实现PWM信号输出,可以使用内置的pwmio模块功能,其官方文档地址:

            https://docs.circuitpython.org/en/latest/shared-bindings/pwmio/index.html

其实主要是设置PWM发生器的占空比 duty_cycle频率(Hz)。其中占空比是个16位整数,取值范围为0~65535,对应就是duty的0—100%。 控制beep发声时,我们始终采用 duty=50%,也就是 2**15 =32767。而PWM的频率呢则需要根据音符来控制输出对应的Hz数,比如要让beep发出啦(La)这个音符,就把PWM的频率设置为对应的 440Hz。通过使用pwmio库可以很方便地实现上述功能。

   需要注意的是,我手头这个存货 Beeper,是低电平触发,所以输出为高电平时不发声,为LOW时才会发声。所以要停止beep鸣叫,需要占空比100%即全是高电平才行;而需要beep发声时,占空比认为 50%即设置duty_cycle值为 2**15。

 

l  按钮动作要求

     将按钮D1 和 D2 的动作也配合上。我这里对老师的代码做了点更改,因为要用示波器测量频率和波形,我去掉了超时音符自动停止播放的功能,改为按下D2键上升沿触发,播放下一个音符,一直保持播放;按下D1键上升沿触发时,才停止当前音符的播放。

     配合我的Beep低电平触发的不同,加上使用 Debounce库来消除按键抖动,我最终的代码如下:

import board
import digitalio
import time
from adafruit_debouncer import Debouncer
import pwmio

# 按钮D1配置:Configure the digital input pin
pin = digitalio.DigitalInOut(board.D1)
pin.direction = digitalio.Direction.INPUT
pin.pull = digitalio.Pull.DOWN  #下拉,默认低电平
# Initialize the debouncer with the pin
button1 = Debouncer(pin)

# 按钮D2配置:Configure the digital input pin
pin2 = digitalio.DigitalInOut(board.D2)
pin2.direction = digitalio.Direction.INPUT
pin2.pull = digitalio.Pull.DOWN  #下拉,默认低电平
# Initialize the debouncer with the pin
button2 = Debouncer(pin2)

# 设置蜂鸣器连接的引脚 D13 为PWM
pwm = pwmio.PWMOut(board.D13, duty_cycle=65535, frequency=440, variable_frequency=True)

# 定义8音阶的频率(C4, D4,E4,F4,G4,A4,B4,C5)
note_names = ['C4', 'D4','E4','F4','G4','A4','B4','C5']
frequencies = [261, 293, 329, 349, 392, 440, 493, 523]

# 音符播放时长(秒)
NOTE_DURATION = 0.5 #每个音符的最大播放时长(秒)

# 音符播放控制函数----------------------------------
def play_note(note):
    if note in range(len(note_names)):
        name = note_names[note]
        freq = frequencies[note]
        print(f"Playing {name} at {freq} Hz")
        pwm.frequency = int(freq)
        pwm.duty_cycle = 2**15  #占空比50%
    else:
        print(f"Note {name} is not valid in the scale")
        
# 停止播放音符
def stop_playing():
    pwm.duty_cycle = 65535
    #print(f"Stoped playing note")
# --------------------------------------------------

note_index = 0  #当前音符的索引
note_start_time = time.monotonic() #记录音符开始播放的时间
is_playing = False  #记录当前是否在播放

#示例调用
while True:
    # Update the debouncer state
    button1.update()
    button2.update()
   
    if button2.rose:  #电平由0-->1,按键刚被按下
        #print("D2 Just pressed")
        if is_playing:
            stop_playing()  #停止当前音符
            is_playing = False
            
        play_note(note_index)  #播放下一个音符
        note_start_time = time.monotonic() #重置音符开始播放的时刻
        is_playing = True
        
        #切换到下一个音符,若达到最后一个音符则从头开始
        note_index = (note_index + 1 ) % len(note_names)
    
    if button1.rose:  #电平由0-->1,按键刚被按下
        #print("D1 Just pressed")
        if is_playing:
            stop_playing()  #停止当前音符
            is_playing = False
        
    #自动停止音符播放
    #if is_playing and time.monotonic() - note_start_time > NOTE_DURATION:
    #    stop_playing()  #超过最大时长后停止播放
    #    is_playing = False     
        
       
    time.sleep(0.01)  #稍等一下,避免CPU占用过高

 

在online ide中输入上述代码,保存后自动运行:

image.png

看下效果,每按下一次D2键,播放下一个音符。Gif动图听不到声音,所以我接上示波器查看PWM频率,果然跟屏幕上显示的音符Hz数完全一样!

beep播放音符.gif

----------------------------------------------------

完成了beep蜂鸣器的输出控制,就剩最后一个,颜色传感器啰~~~


                                   zhw  2025.12.9 





关键词: 拾色      蜂鸣器      音符     频率 PWM    

共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]