Arduino案例实操

您所在的位置:网站首页 汤姆森二圣诞歌 Arduino案例实操

Arduino案例实操

2024-02-09 13:57| 来源: 网络整理| 查看: 265

你们也知道,圣诞节就快到了,让arduino完成一个比较应景的案例也会让节日过得更有意思。 arduino可以做的放歌案例除了用语音模块外,比较简单成本最低的就是利用蜂鸣器了,只要控制好频率和节拍,蜂鸣器也可以演奏音乐的,但你要准备的东西也会复杂一点。

文章标题导航 一、圣诞歌简谱二、音符频率对照表三、案例编程四、案例扩展

一、圣诞歌简谱

简谱不理解是什么??!! 很简单,你小学时候的音乐课本上面的谱子就是了,下面这张是Jingle Bells的简谱,歌词是中文版不用太认真,调子是一样的。 在这里插入图片描述 在这里插入图片描述 简谱上除了中文,其他的应该都看不懂了吧

敲黑板,这个地方要好好理解一下,后面要用到!!!

音符节奏分为一拍、半拍、1/4拍、1/8拍,我们规定一拍音符的时间为1,那么半拍为0.5,1/4拍为0.25;1/8拍为0.125……,为每个音符赋予这样的拍子播放出来,音乐的整个基调就出来了。确定简谱的调,在简谱歌名左下角(即整个简谱的左上角)处,有个 1 = F 4/4 ,这里的 F 表示这个曲子是 F 调的,下面会讲到,而 4/4 表示曲子是四四拍的音符(简谱中文字上面对应的每个数字)类型说明,举个栗子,Jingle Bells简谱第一小段音符 5 3 2 1 5 0 5 5 1)这里面5、3、2、1可以看到数字下面都带着下划线,这表示每个音符对应的节拍为0.5拍,即音符5为0.5拍,音符3为0.5拍,音符2和音符1也是0.5拍,0也是0.5拍,仔细看最后两个音符,两个5下面都是2条下划线,这表示0.25拍,这样就好理解了,每个音符都看成1拍,每带一条下划线就当前拍数除以2,这样一条下划线是1/2=0.5拍,两条下划线是1/2/2=0.25拍,ok吧;然后把这一小段音符 5 3 2 1 5 0 5 5的节拍数加起来是0.5+0.5+0.5+0.5+1+0.5+0.25+0.25 = 4拍,这样就跟简谱标的四四拍是吻合的了,也说明你这一小段的节拍数没算错,记住Jingle Bells简谱中每一小段都是4拍(这段话对照着简谱去理解) 2)聪明的你可能还发现有些音符还带有小点点,当音符不带点时,表示中音,例如第一小段中的音符3,表示中音音符3;当音符下面带小点时,表示低音,例如第一小段中的音符5,表示低音音符5;同样的,当音符上面带小点时,表示高音音符,这在Jingle Bells简谱中没有出现高音 3)音符后边带小数点的话,表示该音符节拍+0.5拍(音符带下划线的话,在计算完下划线节拍的基础上+0.5拍);音符后边带 - 的,音符+1拍(计算完下划线节拍的基础上+1拍) 4)有的两个连续的音符上面带弧线,表示连音,可以稍微改下连音后面那个音的频率,比如减少或增加一些数值(需自己调试),这样表现会更流畅,其实不做处理,影响也不大 二、音符频率对照表

简单了解简谱后,该怎么把音符转换成蜂鸣器对应频率呢,看看音符频率表 低音

音符→音调↓ 1# 2# 3# 4# 5# 6# 7# A221248278294330371416B248278294330371416467C131147165175196221248D147165175196221248278E165175196221248278312F175196221234262294330G196221234262294330371 中音 音符→音调↓ 1 2 3 4 5 6 7 A441495556589661742833B495556624661742833935C262294330350393441495D294330350393441495556E330350393441495556624F350393441495556624661G393441495556624661742 高音 音符→音调↓ 1# 2# 3# 4# 5# 6# 7# A88299011121178132214841665B990111211781322148416651869C525589661700786882990D5896617007868829901112E66170078688299011121284F700786882935104911781322G7868829901049117813221484 如上的频率表适用于arduino的各种蜂鸣器曲目,由于案例中Jingle Bells是F调的,所以在表中我把F调对应的音符都标红了,可以看到表格中第一列是曲目音调,每首曲子基本都是一个调的,第一行是每个调对应的音符频率1 到 7,也就是简谱中我们看到的那些数字,最后是以高音、中音、低音把频率分成了3个表,看懂了就可以开始编程了 三、案例编程

看明白简谱和频率表就开始写程序啦,首先宏定义曲目要用到的音符频率

//中音NTF 0为空拍 #define NTF0 -1 #define NTF1 350 #define NTF2 393 #define NTF3 441 #define NTF4 495 #define NTF5 556 #define NTF6 624 #define NTF7 661 //高音NTFH #define NTFH1 700 #define NTFH2 786 #define NTFH3 882 #define NTFH4 935 #define NTFH5 965 #define NTFH6 996 #define NTFH7 1023 //低音NTFL #define NTFL1 175 #define NTFL2 196 #define NTFL3 221 #define NTFL4 234 #define NTFL5 262 #define NTFL6 294 #define NTFL7 330

按照Jingle Bells简谱定义音符数组

//音符频率数组 int tune[]= { NTF3,NTF3,NTF3,NTF3,NTF3,NTF3, NTF3,NTF5,NTF1,NTF2,NTF3,NTF0, NTF4,NTF4,NTF4,NTF4,NTF4,NTF3,NTF3,NTF3,NTF3, NTF5,NTF5,NTF4,NTF2,NTF1,NTF0, NTFL5,NTF3,NTF2,NTF1,NTFL5,NTF0,NTFL5,NTFL5, NTFL5,NTF3,NTF2,NTF1,NTFL6,NTF0, NTFL6,NTF4,NTF3,NTF2,NTFL7,NTF0, NTF5,NTF5,NTF4,NTF2,NTF3,NTF1,NTF0, NTFL5,NTF3,NTF2,NTF1,NTFL5,NTF0, NTFL5,NTF3,NTF2,NTF1,NTFL6,NTF0,NTFL6, NTFL6,NTF4,NTF3,NTF2,NTF5,NTF5,NTF5,NTF5, NTF6,NTF5,NTF4,NTF2,NTF1,NTF0 };

按简谱定义音符节拍数组

//音符节拍数组 float durt[]= { 0.5,0.5,1,0.5,0.5,1, 0.5,0.5,0.75,0.25,1.5,0.5, 0.5,0.5,1,0.5,0.5,0.5,0.5,0.25,0.25, 0.5,0.5,0.5,0.5,1.5,0.5, 0.5,0.5,0.5,0.5,1,0.5,0.25,0.25, 0.5,0.5,0.5,0.5,1,1, 0.5,0.5,0.5,0.5,1,1, 0.5,0.5,0.5,0.5,1,0.75,0.25, 0.5,0.5,0.5,0.5,1,1, 0.5,0.5,0.5,0.5,1,0.5,0.5, 0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5, 0.5,0.5,0.5,0.5,0.75,0.25 };

接着是主题函数部分

//定义蜂鸣器引脚,音符长度变量 int buzzer_pin = 9; int length; //setup函数,初始化引脚,计算长度 void setup() { pinMode(buzzer_pin, OUTPUT); length = sizeof(tune)/sizeof(tune[0]); } //loop函数 void loop() { //for循环演奏曲子 for(int x=0;x pinMode(buzzer_0, OUTPUT); pinMode(relay_0, OUTPUT); //OLED屏幕显示 Merry Christmas u8g_0.firstPage(); do { u8g_0.setFont(u8g_font_9x18); u8g_0.drawStr(5, 30, "Merry"); u8g_0.drawStr(40, 55, "Christmas"); } while (u8g_0.nextPage()); } //loop函数 void loop() { tone(buzzer_0, 441, 0); // T1-1 delay(0); delay(250); noTone(buzzer_0); tone(buzzer_0, 441, 0); delay(0); delay(250); noTone(buzzer_0); tone(buzzer_0, 441, 0); delay(0); delay(480); noTone(buzzer_0); digitalWrite(relay_0, HIGH); tone(buzzer_0, 441, 0); delay(0); delay(250); noTone(buzzer_0); tone(buzzer_0, 441, 0); delay(0); delay(250); noTone(buzzer_0); tone(buzzer_0, 441, 0); delay(0); delay(230); noTone(buzzer_0); digitalWrite(relay_0, LOW); tone(buzzer_0, 441, 0); // T1-2 delay(0); delay(250); noTone(buzzer_0); tone(buzzer_0, 556, 0); delay(0); delay(250); noTone(buzzer_0); tone(buzzer_0, 350, 0); delay(0); delay(355); noTone(buzzer_0); digitalWrite(relay_0, HIGH); tone(buzzer_0, 393, 0); delay(0); delay(125); noTone(buzzer_0); tone(buzzer_0, 441, 0); delay(0); delay(750); noTone(buzzer_0); tone(buzzer_0, -1, 0); delay(0); delay(230); noTone(buzzer_0); digitalWrite(relay_0, LOW); tone(buzzer_0, 495, 0); // T1-3 delay(0); delay(250); noTone(buzzer_0); tone(buzzer_0, 495, 0); delay(0); delay(250); noTone(buzzer_0); tone(buzzer_0, 495, 0); delay(0); delay(500); noTone(buzzer_0); tone(buzzer_0, 495, 0); delay(0); delay(230); noTone(buzzer_0); digitalWrite(relay_0, HIGH); tone(buzzer_0, 495, 0); delay(0); delay(250); noTone(buzzer_0); tone(buzzer_0, 441, 0); delay(0); delay(250); noTone(buzzer_0); tone(buzzer_0, 441, 0); delay(0); delay(250); noTone(buzzer_0); tone(buzzer_0, 441, 0); delay(0); delay(125); noTone(buzzer_0); tone(buzzer_0, 441, 0); delay(0); delay(105); noTone(buzzer_0); digitalWrite(relay_0, LOW); tone(buzzer_0, 556, 0); // T1-4 delay(0); delay(250); noTone(buzzer_0); tone(buzzer_0, 556, 0); delay(0); delay(250); noTone(buzzer_0); tone(buzzer_0, 495, 0); delay(0); delay(230); noTone(buzzer_0); digitalWrite(relay_0, HIGH); tone(buzzer_0, 393, 0); delay(0); delay(250); noTone(buzzer_0); tone(buzzer_0, 350, 0); delay(0); delay(750); noTone(buzzer_0); tone(buzzer_0, -1, 0); delay(0); delay(230); noTone(buzzer_0); ... //此处省略200+行重复代码 delay(1500); //循环演奏的时间间隔 }

上述代码只取了完整曲子的1/3段,因为每个音符都是以tone函数,delay函数,noTone函数的形式在循环,4个小段加起来30个音符左右,还有OLED显示和继电器控制的程序前前后后140行代码左右,全曲82个音符总370行代码,也是敲得心累,上面把后边200+行的重复函数代码省略了,只是频率跟延时不同。

案例扩展实现了简介控制圣诞树灯光闪烁,其实个人觉得接PWM引脚做成呼吸灯效果会更棒,也不用听继电器在滴答滴答叫,这个就看你们个人的idea了,分享到这,下回见~



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3