Arduino小音响

news/2024/10/23 5:49:51/

实验内容

制作一个小音响。使用声音传感器,感受声音强弱变化,在LED显示中会显示当前采集的声音的大小并且提示当前播放的音乐,同时碰撞开关还能控制音乐播放状态(停止、暂停、继续播放,向下播放)。

实验具体步骤

可通过该视频观看具体步骤

准备制作小音响所需要的硬件

在这里插入图片描述
在这里插入图片描述
小音响需要小喇叭1对,核心+1个, SD卡模块1个,音频模块1个,OLED屏幕1块,传感器接口板1个,电池盒1个,碰撞开关1个,声音传感器1个,传感器线2条,USB数据线1根。

硬件功能介绍

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

硬件连接

在这里插入图片描述
将模块组合连接,并用USB线连接电池盒到电脑上

打开下载好的Arduino

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
新建,将写好的代码拷贝到Arduino界面的程序部分

代码展示

#include<U8glib.h>#include<Microduino_Key.h>  //引入按键相关库文件
#include <Microduino_AudioPro.h> //引入音频模块AudioPro相关库文件
#include <SD.h> //引入SD模块相关库文件U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE);//定义OLED连接方式
AudioPro_FilePlayer musicPlayer = AudioPro_FilePlayer(SD); //声明AudioPro对象,命名为mucisPlayer#define INTERVAL_OLED 100 //定义屏刷新时间
#define keyPin 4 //定义按键接在4号管脚(AudioPro和SD模块占用2,3,7,12,13,A2,A3需要避开)DigitalKey keyDigital(keyPin); //声明按键对象,命名为keyDigital,接在keyPin(4)号管脚uint8_t musicNum = 1; //定义变量musicNum, 用来存储歌曲序号
uint8_t fileNum = 0; //定义变量fileNum, 用来存储mp3音频文件数量//字体设置,大,中,小
#define setFont_L u8g.setFont(u8g_font_timB18)
#define setFont_M u8g.setFont(u8g_font_timB14)
#define setFont_S u8g.setFont(u8g_font_timB10)unsigned long OLEDShowTime = millis(); //定义变量用来记录系统运行时间(定时器)#include <Microduino_ColorLED.h>//引入彩灯库文件
#define LEDPIN 6 //LED灯引脚
ColorLED strip = ColorLED(1,LEDPIN); //声明接一颗彩灯,到LEDPIN (6)号管脚#define voice 30 //噪声临界值
#define micPin A0 //麦克风引脚
double db = 0.0; //显示在OLED上的当前分贝数
double recodeDB = 0.0; //显示在OLED上的最高分贝数void setup()
{//初始化函数,程序只在最初执行一次Serial.begin(115200); //初始化串口,并设置波特率为115200Serial.println(F("AudioPro(VS1053) Simple Test")); //串口打印信息,提示测试AudioPro是否可用pinMode(SD_PIN_SEL, OUTPUT); //先初始化AudioPro,所以先能使用SD卡pinMode(micPin, INPUT); //定义声音传感器mic所接引脚micPin(A0)为输入模式digitalWrite(SD_PIN_SEL,HIGH); //SD卡能操作:将SD_PIN_SEL(7)号管脚设置为高电压HIGHdelay(500); //等待SD能使完成if(! musicPlayer.begin())
{Serial.println(F("没有找到VS1053,检查管脚是否正确接入")); //如果没有找到AudioPro模块或者模块有问题则打印此消息while(1); //程序进入死循环,不再往下执行(只有检测到AudioPro模块才可以使用本程序)
}Serial.println(F("VS1053 found")); //如果初始化完成则打印此消息if(! SD.begin(SD_PIN_SEL))
{//SD模块初始化Serial.println(F("initialization failed!")); //初始化失败,打印此消息return; //跳出初始化函数,进入loop()函数,可以执行除了音频播放外的其他操作
}Serial.println(F("initialization done.")); //初始化完成,打印此消息musicPlayer.setVolume(96); //设置左右声道音量 0-127 数值越大则音量越大Serial.println(F("Enter Index of File to play")); //串口打印提示SD卡中检索到的歌曲fileNum = musicPlayer.getMusicNum(); //可以获取SD卡中曲目列表以及数量Serial.print(F("Music Files :"));Serial.println(fileNum); //串口打印歌曲数量for(uint8_t a = 0; a < fileNum; a++)
{//串口依次打印歌曲名,格式File[第几首]:歌曲名Serial.print(F("\t File["));Serial.print(a);Serial.print(F("]: "));Serial.println(musicPlayer.getMusicName(a));
}musicPlayer.useInterrupt(VS1053_PIN_DREQ); //使用中断方式控制音频播放delay(200);strip.begin(); //彩灯初始化strip.show();
}void loop() {//主循环程序,程序会无限次执行循环
db = getDB();//获得分贝数
analyticDB(db);
updateOLED();switch (keyDigital.readEvent())
{//检测当前按键的状态case SHORT_PRESS: //如果是短按if (musicPlayer.stopped()){//如果当前是停止播放状态Serial.println(F("Playing!")); //串口打印播放提示语playNum(musicNum - 1); //播放当前歌曲}else if(! musicPlayer.paused()){//否则,如果当前是播放状态Serial.println(F("Paused")); //串口打印提示语musicPlayer.pausePlaying(true); //暂停}else{//如果当前是暂停状态Serial.println(F("Resumed")); //串口打印继续播放提示语musicPlayer.pausePlaying(false); //取消暂停(继续播放)}break;case LONG_PRESS://如果是长按musicNum++; //歌曲数量加1if(musicNum > fileNum){//如果超出了SD中实际最大的歌曲数则重新重1开始musicNum = 1;}playNum(musicNum - 1); //播放第musicNum - 1首歌(-1是因为从0开始计数)break;
}delay(50);
}void playNum(uint8_t num)
{//控制播放第几首歌的函数, num = 第几首歌if(num > musicPlayer.getMusicNum() - 1){//如果num的数值大于最大歌曲数就不执行播放操作return;}if(!musicPlayer.stopped()){//判断当前是否正在播放歌曲musicPlayer.stopPlaying(); //停止播放 (必要,否则SD类得不到关闭,内存溢出)}musicPlayer.flushCancel(both); //清除缓存,播放MIDI等格式文件时必要String _name = musicPlayer.getMusicName(num); //获取第num首歌对应的歌曲名称存储到_nameSerial.print(F("Playing:")); //串口打印Playing: (用来提示当前正在播放)if(! musicPlayer.playMP3(_name)){//如果无法正常播放,则串口打印errorSerial.println(F("error"));}else{//如果正常播放,串口打印Ok File:和歌曲名Serial.print(F("Ok \t File:"));Serial.println(_name);}
}void updateOLED()
{//刷新OLEDif(OLEDShowTime > millis()) OLEDShowTime = millis(); //通常OLEDShowTime都应<定时器millis(),防止出错作对比if(millis() - OLEDShowTime > INTERVAL_OLED){//OLED每INTERVAL_OLED(200)毫秒刷新一次OLEDShow(); //调用显示率OLEDShowTime = millis(); //记录当前计时器,millis()时间.重新开始计算时间}}void OLEDShow(){//OLED显示函数u8g.firstPage();do{setFont_S; //以小字体,在(x=0, y=20)坐标显示“record:”以及最大分贝值u8g.setPrintPos(0,20);u8g.print("record:");u8g.print(recodeDB);setFont_M; //以中字体,在(x=0, y=50)坐标显示“your:”以及当前分贝值u8g.setPrintPos(0, 50);u8g.print("your:");u8g.print(db);setFont_L; //以大字体,在(x=90, y=40)坐标显示“dB”单位字样u8g.setPrintPos(90,40);u8g.print("dB");}while(u8g.nextPage());}double getDB(){//获得分贝数double voice_data = analogRead(micPin); //读取接在micPin(A0)管脚上剩余传感器数值(0~1023之间)voice_data = voice_data/204.6; //将读取数值0~1023转换为电压0~5double db = (20.*log(10)) * (voice_data/1.0); //将电压转换为分贝:20lg(电压值)if(db > recodeDB){//recodeDB存放最大分贝值,如果数值破纪录则覆盖记录recodeDB = db;}return db; //返回当前分贝值}void analyticDB(double db){//解析分贝值并控制彩灯其次控制音乐播放if(db > voice + 80){strip.setPixelColor(0,strip.Color(15,35,45));playNum(musicNum+0 - 1);
}else if(db > voice + 40){strip.setPixelColor(0,strip.Color(115,135,145));playNum((musicNum+1) - 1);}else if(db > voice){strip.setPixelColor(0,strip.Color(225,235,245));playNum(musicNum+2 - 1);}  else {  strip.setPixelColor(0, 0);}strip.show();}

编译上传

通过USB编译上传到电池盒,打开电池盒开关,小音响就做好啦!


http://www.ppmy.cn/news/195097.html

相关文章

杰理-广场舞音响

其实一款好音质的拉杆箱是需要配置更高效果的喇叭还是很重要的 软件之鞥起一个帮忙加修饰不同音效的作用 通话具有话筒功能&#xff1a;有的是有线MIC有的则为无线MIC 重点还是介绍无线MIC,这样大家都知道音响一般为接收器 那么同样无线MIC作为一个发射器把MIC信号&#xff08;…

1073: 骑车还是走路

时间限制 : 1.000 sec 内存限制 : 128 MB 题目描述 在大学校园里&#xff0c;没有自行车&#xff0c;上课办事会很不方便.但实际上,并非去办任何事情都是骑车快,因为骑车总要找车、开锁、停车、锁车等&#xff0c;这要耽误一些时间。假设找到自行车,开锁并车上自行车的时间为…

哈罗单车二维码被破坏怎么骑?

共享单车的理念是共享&#xff0c;但总有素质低下的人想独占。我们经常会遇到如图一二的情况&#xff0c;一般看到这种&#xff0c;我们可能就转身走了。但如果想一想&#xff0c;为什么那些搞破坏的人能骑呢&#xff1f;肯定是有方法的&#xff01; 其实很简单&#xff1a; 1、…

K11940 骑车上班

题目描述 科丁乐的很多工作人员住在一个叫Kzon的地方&#xff0c;住所距离办公室是4.5KM&#xff0c;由于交通堵塞严重&#xff0c;许多工作人员选择骑自行车上班。这些工作人员中除了小科外&#xff0c;其他人都以固定的速度从住所骑到办公室&#xff0c;但是小科骑车有个特殊…

失主深夜赤脚狂追2公里逼降窃贼

日前&#xff0c;记者在南京市雨花台区新林芳庭小区睹到了小弛&#xff0c;在抓获窃贼进程中&#xff0c;他摔得谦脸是血&#xff0c;有3颗牙齿脱降&#xff0c;脖子跟脸部皆有揩伤。 赤脚狂追两公里 记者懂得到&#xff0c;这3名见义勇为的小伙子有两个人为90后&#xff0c;其…

【躲不过的Java “锁事”】一文扫除对Java各种锁的困扰!

简介 锁是Java中快捷理解多线程的一条捷径&#xff0c;为我们开发多线程提供理论支持&#xff0c;想成为一个合格的工程师&#xff0c;Java中的锁是必定躲不过的一个知识点&#xff0c;并且内容繁多&#xff0c;本文点到为止&#xff0c;浅谈Java中的各种锁&#xff0c;带您理解…

程序员:我终于知道Java这些“锁”事了

作者&#xff1a;千珏 邮箱&#xff1a;wl625363199gmail.com 文章目录 前言悲观锁和乐观锁自旋锁和适应性自旋锁无锁和偏向锁和轻量级锁和重量级锁公平锁和非公平锁可重入锁和非可重入锁独享锁和共享锁总结 前言 每次面试的时候总是有面试官会甩出致命三连 高并发、高可用、高…

共享单车系统又被黑客盯上,多账户押金被盗

&#xff08;点击上方公众号&#xff0c;可快速关注&#xff09; 9 月 27 日消息&#xff0c;深圳市人民检察院对外通报&#xff0c;该院批捕了两名犯罪嫌疑人&#xff0c;他们涉嫌偷盗“共享单车”用户的资金&#xff0c;从 34 个账户里偷走两万多元人民币。 一次偶然的机会&a…