1109 字
6 分钟
页面浏览--访问次数--
Arduino|简易音乐播放器

1. 前言#

大家好,今天给大家带来一个有趣的 Arduino 小项目——使用无源蜂鸣器和 OLED 屏幕,完整播放《神のまにまに》(神的随波逐流)这首经典歌曲。

项目核心功能:

  • 通过 PWM 调波技术驱动无源蜂鸣器播放音乐
  • OLED 屏幕同步显示歌曲封面
  • 完整乐谱数据,支持歌曲循环播放

演示视频:


2. 简介#

本项目使用 Arduino 开发板驱动无源蜂鸣器播放《神のまにまに》(神的随波逐流),同时在 OLED 屏幕上显示歌曲封面图片。通过 PWM 调波技术实现音调控制,支持完整的歌曲循环播放结构。

2.1 硬件清单#

器件规格数量
Arduino 主控板ESP8266 等1
无源蜂鸣器3~5V 无源1
OLED 屏幕0.96寸 I2C 128×64 SSD13061
杜邦线根据开发板而定若干

2.2 接线说明#

Arduino 无源蜂鸣器
GPIO 1 ──────────── Signal
Arduino OLED屏幕
GPIO 4 ──────────── SDA
GPIO 5 ──────────── SCL
3V/5V ──────────── VCC
GND ──────────── GND

OLED 引脚Arduino 引脚
SDAA4 (SDA)
SCLA5 (SCL)
VCC3V/5V
GNDGND

2.3 软件依赖#

本项目使用以下开源库:

库名版本说明
Adafruit GFX Library≥1.10图形库核心
Adafruit SSD1306≥2.5OLED 驱动库
SPI内置SPI 通信库
Wire内置I2C 通信库

2.3.1 库安装方法#

在 VS Code 中的 PlatformIO 插件搜索并安装:

  • Adafruit GFX Library by Adafruit
  • Adafruit SSD1306 by Adafruit

3. 技术原理#

3.1 PWM 调波发声原理#

无源蜂鸣器需要外部电路提供交流脉冲信号才能发声。通过 Arduino 的 tone() 函数,我们可以:

  • 生成指定频率的方波信号:不同频率对应不同音高
  • PWM 占空比固定为 50%:确保信号稳定
  • 音调与频率对应关系:
    • 低音:262Hz (C4) ~ 494Hz (B4)
    • 中音:523Hz (C5) ~ 988Hz (B5)
┌─────────────┐
│ Arduino │ ──tone(440Hz)──▶ [蜂鸣器] ──▶ 发出 A4 音
└─────────────┘

3.2 乐谱数据结构设计#

本项目采用双数组存储乐谱信息:

数组作用数据示例
musicSentenceTones音调序列-5, -6, 1, 2, 2, 1...
musicSentenceTime时长序列4, 4, 4, 3, 1...

音调编码规则:

// 对照规则:低音 -1~-7; 中音 1~7; 高音 11~17; 2# 为 33
int lowTones[8] = {0, 262, 294, 330, 349, 392, 440, 494}; // 低音频率
int midTones[8] = {0, 523, 587, 659, 698, 784, 880, 988}; // 中音频率
int mid2sTone = 622; // 中音 2# 频率

3.3 OLED 显示原理#

使用 Adafruit_SSD1306 库驱动 128×64 分辨率的 OLED 屏幕:

  • 通信协议:I2C(只占用 2 个 GPIO 引脚)
  • 显示方式:位图数组直接绘制
  • 显存操作:双缓冲避免闪烁
OLED 引脚连接:
┌─────────────┐
│ Arduino │
│ GPIO 5 ────▶ SCL (时钟线)
│ GPIO 4 ────▶ SDA (数据线)
└─────────────┘

4. 代码展示#

Luquiescenekami-no-manimani-music-player-with-Arduino


5. 算法解读#

5.1 循环控制机制#

本项目的循环是通过 breakPoint 变量控制歌曲的反复段:

歌曲结构:
├── 前奏(0-6行)
├── A段(7-14行)
├── B段(15-32行)
├── 反复句1(33行)→ 回到前奏
├── 反复句2(34-38行)→ 回到B段
└── 结束句(39-51行)

断点控制逻辑:

breakPoint = 0 → 到达第33行时,反复到第6行
breakPoint = 1 → 到达第38行时,反复到第19行
breakPoint = 2 → 到达第32行时,进入结束句

5.2 时长计算公式#

thisTime = SIXTEENTH_NOTE * musicSentenceTime[rows][columns] - 40;
  • 基准单位:十六分音符(111ms)
  • 时长修正:乘以节拍数,再减去 40ms 作为音间间隔
  • 为什么要减40ms:为下一个音符的 noTone() 留出间隙

5.3 音调编码映射#

编码值实际音高计算方式
-1 ~ -7低音 1~7lowTones[abs(编码)]
1 ~ 7中音 1~7midTones[编码]
33中音 2#特殊值,查表 mid2sTone
0休止符无操作(需配合下一音判断)

6. 总结#

6.1 项目亮点#

其实是没有亮点,但是博主牵强附合(

  1. 资源占用少:仅使用 2 个 GPIO 引脚(I2C 通信)
  2. 代码结构清晰:数据与逻辑分离,便于维护和扩展
  3. 支持循环播放:通过断点机制实现复杂的歌曲结构

6.2 硬件清单#

器件数量说明
ESP8266 开发板1主控芯片
无源蜂鸣器1发声元件
OLED 屏幕 (SSD1306)1128×64 I2C 接口
杜邦线若干连接线路

6.3 可扩展方向#

实际情况是博主技术力不够,实现不了

  • 添加按钮实现”播放/暂停”功能
  • 增加音量调节
  • 支持多首歌曲切换
  • 添加歌词同步显示功能

Arduino|简易音乐播放器
https://luq-blog.xyz/posts/2026-05-28-beep-audio/
作者
Luquiescene
发布于
2026-05-28
许可协议
CC BY-NC-SA 4.0

分享文章

生成精美分享图或复制链接,与更多人分享本文。

继续阅读

沿着主题读

基于共同的标签与分类

换条路线

从其他文章中稳定抽取

评论

正在加载评论...

最后更新于 ,距今已过 105 天

部分内容可能已过时