蜂鸣器播放音乐——让 Arduino 唱出旋律

前面我们学了 LCD1602 显示屏,让 Arduino 能"看"到数据。现在给它加上"嘴巴"------蜂鸣器,让它能发出声音,甚至播放音乐!

学完这篇,你会完成:

  • 基础发声:让蜂鸣器发出不同频率的声音
  • 播放音符:用代码演奏简单的旋律
  • 综合项目:电子琴:用按键控制蜂鸣器,弹奏简单的乐曲

一、蜂鸣器是什么?

蜂鸣器是一种电子发声器件,分为两种类型:

有源蜂鸣器
  • 内部自带振荡电路
  • 只需要给电就会响(固定频率)
  • 只能发出一种音调
  • 适合做简单的提示音
无源蜂鸣器
  • 内部没有振荡电路
  • 需要 Arduino 提供特定频率的方波信号
  • 可以发出不同频率的声音
  • 可以播放音乐(本篇重点)

本篇使用无源蜂鸣器,因为它可以控制频率,播放不同的音符。


二、声音的原理

声音是由振动产生的,振动的快慢用频率 表示,单位是赫兹(Hz)。

  • 频率越高,音调越高(声音越尖)
  • 频率越低,音调越低(声音越沉)
音乐中的音符与频率
音符 频率(Hz)
Do(C4) 262
Re(D4) 294
Mi(E4) 330
Fa(F4) 349
Sol(G4) 392
La(A4) 440
Si(B4) 494
Do(C5) 523

这些频率是标准音高,Arduino 可以通过 tone() 函数精确产生这些频率。


三、接线方式

蜂鸣器引脚 接到
正极(+) Arduino D8
负极(-) GND

无源蜂鸣器没有极性,但通常标有 "+" 的一端接 Arduino 引脚,另一端接 GND。


四、实验一:基础发声

让蜂鸣器发出一个固定频率的声音。

复制代码
#define BUZZER 8  // 蜂鸣器接 D8

void setup() {
  pinMode(BUZZER, OUTPUT);
}

void loop() {
  // 产生 440Hz 的声音(La 音),持续 500ms
  tone(BUZZER, 440);
  delay(500);
  
  // 停止发声
  noTone(BUZZER);
  delay(500);
}
代码解读
  • tone(pin, frequency):在指定引脚产生指定频率的方波信号
  • noTone(pin):停止指定引脚的方波输出
  • delay(500):发声 500ms,静音 500ms,形成"嘀-嘀-嘀"的效果

五、实验二:播放简单旋律

播放《小星星》的旋律。

复制代码
#define BUZZER 8

// 音符频率定义
#define NOTE_C4 262
#define NOTE_D4 294
#define NOTE_E4 330
#define NOTE_F4 349
#define NOTE_G4 392
#define NOTE_A4 440
#define NOTE_B4 494
#define NOTE_C5 523

// 《小星星》旋律
// 音符数组
int melody[] = {
  NOTE_C4, NOTE_C4, NOTE_G4, NOTE_G4, NOTE_A4, NOTE_A4, NOTE_G4,
  NOTE_F4, NOTE_F4, NOTE_E4, NOTE_E4, NOTE_D4, NOTE_D4, NOTE_C4
};

// 每个音符的持续时间(毫秒)
int durations[] = {
  400, 400, 400, 400, 400, 400, 800,
  400, 400, 400, 400, 400, 400, 800
};

void setup() {
  pinMode(BUZZER, OUTPUT);
}

void loop() {
  // 播放旋律
  for (int i = 0; i < 14; i++) {
    tone(BUZZER, melody[i]);      // 播放当前音符
    delay(durations[i]);          // 持续指定时间
    noTone(BUZZER);               // 停止发声
    delay(100);                   // 音符间隔 100ms
  }
  
  delay(2000);  // 播放完后等待 2 秒,然后重复
}
代码解读
  • melody[]:存储旋律中每个音符的频率
  • durations[]:存储每个音符的持续时间
  • for 循环:依次播放数组中的每个音符
  • delay(100):音符之间的间隔,让旋律更清晰
《小星星》简谱
复制代码
1 1 5 5 6 6 5 -
4 4 3 3 2 2 1 -

六、综合项目:简易电子琴

用 4 个按键控制蜂鸣器,弹奏 Do、Re、Mi、Fa 四个音符。

所需元件
  • Arduino Uno
  • 无源蜂鸣器
  • 4 个按键
  • 4 个 10kΩ 电阻(下拉电阻)
  • 面包板 + 杜邦线
接线
元件 引脚 接到
蜂鸣器 + D8
蜂鸣器 - GND
按键1 一端 D2
按键1 另一端 5V(经 10kΩ 电阻到 GND)
按键2 一端 D3
按键2 另一端 5V(经 10kΩ 电阻到 GND)
按键3 一端 D4
按键3 另一端 5V(经 10kΩ 电阻到 GND)
按键4 一端 D5
按键4 另一端 5V(经 10kΩ 电阻到 GND)

按键接法:一端接 Arduino 引脚,另一端接 5V。同时 Arduino 引脚通过 10kΩ 电阻接 GND(下拉电阻),这样按键未按下时引脚为低电平,按下时为高电平。

代码
复制代码
#define BUZZER 8
#define KEY1 2  // Do
#define KEY2 3  // Re
#define KEY3 4  // Mi
#define KEY4 5  // Fa

// 音符频率
#define NOTE_C4 262
#define NOTE_D4 294
#define NOTE_E4 330
#define NOTE_F4 349

void setup() {
  pinMode(BUZZER, OUTPUT);
  pinMode(KEY1, INPUT);
  pinMode(KEY2, INPUT);
  pinMode(KEY3, INPUT);
  pinMode(KEY4, INPUT);
}

void loop() {
  // 读取按键状态
  int key1 = digitalRead(KEY1);
  int key2 = digitalRead(KEY2);
  int key3 = digitalRead(KEY3);
  int key4 = digitalRead(KEY4);

  // 根据按键播放对应音符
  if (key1 == HIGH) {
    tone(BUZZER, NOTE_C4);
  } else if (key2 == HIGH) {
    tone(BUZZER, NOTE_D4);
  } else if (key3 == HIGH) {
    tone(BUZZER, NOTE_E4);
  } else if (key4 == HIGH) {
    tone(BUZZER, NOTE_F4);
  } else {
    noTone(BUZZER);  // 没有按键按下时停止发声
  }
}
代码解读
  • digitalRead():读取按键状态,HIGH 表示按下,LOW 表示未按下
  • if-else if 结构:依次检查每个按键,按下哪个就播放对应音符
  • noTone(BUZZER):没有按键按下时停止发声
使用方法

按下不同的按键,蜂鸣器会发出不同的音符,可以组合起来弹奏简单的旋律!


七、进阶:播放完整乐曲

播放《生日快乐》歌。

复制代码
#define BUZZER 8

#define NOTE_C4 262
#define NOTE_D4 294
#define NOTE_E4 330
#define NOTE_F4 349
#define NOTE_G4 392
#define NOTE_A4 440

// 《生日快乐》旋律
int melody[] = {
  NOTE_C4, NOTE_C4, NOTE_D4, NOTE_C4, NOTE_F4, NOTE_E4,
  NOTE_C4, NOTE_C4, NOTE_D4, NOTE_C4, NOTE_G4, NOTE_F4,
  NOTE_C4, NOTE_C4, NOTE_C5, NOTE_A4, NOTE_F4, NOTE_E4, NOTE_D4,
  NOTE_A4, NOTE_A4, NOTE_G4, NOTE_F4, NOTE_E4, NOTE_F4
};

int durations[] = {
  200, 200, 400, 400, 400, 800,
  200, 200, 400, 400, 400, 800,
  200, 200, 400, 400, 400, 400, 800,
  200, 200, 400, 400, 400, 800
};

void setup() {
  pinMode(BUZZER, OUTPUT);
}

void loop() {
  for (int i = 0; i < 26; i++) {
    tone(BUZZER, melody[i]);
    delay(durations[i]);
    noTone(BUZZER);
    delay(50);
  }
  delay(3000);
}

八、常见问题

问题 解决方法
蜂鸣器不响 确认使用的是无源蜂鸣器,有源蜂鸣器只能发固定频率
声音很小 检查接线,确保蜂鸣器正极接 Arduino 引脚
音调不准 检查频率值是否正确,标准音符频率参考表格
按键无反应 检查下拉电阻是否接好,按键是否接触良好
旋律太快/太慢 调整 durations[] 数组中的数值

九、本篇小结

回顾一下今天学到的核心知识:

  • 蜂鸣器类型:有源蜂鸣器(固定频率)vs 无源蜂鸣器(可控频率)
  • 声音原理:频率决定音调,频率越高音调越高
  • tone() 函数:产生指定频率的方波信号
  • noTone() 函数:停止发声
  • 播放旋律:用数组存储音符频率和持续时间,循环播放
  • 电子琴项目:用按键控制不同音符

蜂鸣器广泛应用于闹钟、门铃、电子琴、游戏音效等项目。下一篇,我们学习红外遥控器------让 Arduino 接收遥控信号!

相关推荐
朝朝辞暮i10 小时前
C++ 第 23 课:class —— 开始真正进入面向对象
开发语言·c++·算法
Zw-awa11 小时前
编码器读到的到底是什么:从脉冲到速度
stm32
郑同学的笔记11 小时前
【c++随笔28】strcmp 和 memcmp对比
开发语言·c++
随意起个昵称11 小时前
【背包dp】输出方案路径
c++·动态规划
炸膛坦客11 小时前
单片机开发工具篇:(十四)配置输出 .map 文件及其本地路径
c语言·单片机·嵌入式硬件
朝朝辞暮i12 小时前
C++ 第 27 课:智能指针 shared_ptr
开发语言·c++·算法
by2099912 小时前
学会使用std::string类,并理解其内部是如何管理字符串的详细阐述(上)
c++·笔记·字符串·类和对象·string
沙漠之主12 小时前
C++编程教学设计资料:从入门到实战的完整课程方案
java·前端·c++
朝朝辞暮i12 小时前
C++ 第 29 课:回调函数 Callback
开发语言·c++·算法
笨笨饿13 小时前
140_AI新手村MCP与Skills是干嘛的
开发语言·人工智能·python·stm32·单片机·嵌入式硬件·物联网