前言:
上一章博客已经介绍了无源电磁式蜂鸣器的结构和工作原理!
看看我制作的音乐效果
arduino+无源蜂鸣器制作音乐
这是我们小时候看过的动画片《洛洛历险记》的主题曲《诺言》!!!这里我只展示了一部分!
在开始编程之前需要先识读简乐谱,与音符频率对照表相结合!
先大概普及一下乐理知识:
1=bB 是指:简谱上的1等于五线谱中的降B(即降si)
4/4 是节拍,意思是以四分音符为一拍,每小节有四拍
音符节奏分为一拍、半拍、1/4拍、1/8拍,我们规定一拍音符的时间为1;半拍为0.5;1/4拍为0.25;1/8拍为0.125……,
所以我们可以为每个音符赋予这样的拍子播放出来,音乐就成了。
规律就是时间上单个音符没有下划线,就是一拍(1),
有下划线是半拍(0.5),
两个下划线是四分之一拍(0.25),
有“—”=前面音符的拍子+1【有几个+1就有几拍】;
如果音符后面带“·”点,那么这个音符的拍子+0.5
频率上就是按照音符是否带点,点在上还是在下到下表中查找就可以了。
音符频率对照表|||||
从简谱照片的左上角可以看到,这首歌曲的音调为E调,那么E调所对应的音符频率我已经用绿色方框给框出来了!
1、识读音符对应的频率
现在我们已经知道整首曲子的音调为E调,那么如何从简谱上面去看音符呢?
例如这段:它所对应的音符频率,我用编程怎么写呢?
0默认等于-1(整首歌曲都是的)。数字上面有点代表高音,下面有点代表低音,不带点则是中音,先这么理解。(这样就可以在对应的音符频率对照表里面去找了)
就是像下面这样编程的:(你可以像我一样,定义完频率再写到程序里,也可以直接像下面这样把频率直接写进去,你随意!!!)
-1,393,
661,624,661,700,661,
624,495,624,
556,
-1,-1,-1,393,
2、如何把简谱中的节拍以程序的方式写出来
从刚才的乐理知识当中,我们知道了有一条下划线是0.5拍,有两条下划线是0.25拍,没有下划线则是1拍,音符后面有横线是表示前面的音符+1,有几个横线就+几个1,有点则前面的音符+0.5......接下来我还是用下面这一段来举一个例子展示拍子用程序怎么写
注意:0也代表1拍(整首歌曲都是的)
0.5,0.5,
1+1+1,0.25,0.25,0.25,0.25,
1+1+1,0.5+0.5,0.25,
1+1+1+1,
1,1,1,1,
准备好之后,我们开始吧!!!
需要准备的材料
1、无源蜂鸣器(直插式)
2、Arduino UNO板
3、杜邦线(两根)
接线图:
编程逻辑:
程序部分:
/*把每一个音符对应的频率都定义出来*/
/*低音部分*/
#define A0 -1
#define A1 165
#define A2 175
#define A3 196
#define A4 221
#define A5 248
#define A6 278
#define A7 312
/*中音部分*/
#define B1 330
#define B2 350
#define B3 393
#define B4 441
#define B5 495
#define B6 556
#define B7 624
/*高音部分*/
#define C1 661
#define C2 700
#define C3 786
#define C4 882
#define C5 990
#define C6 1112
#define C7 1248
/*定义所有E调的节拍*/
#define WHOLE 1
#define HALF 0.5
#define QUARTER 0.25
#define EIGHTH 0.25
#define SIXTEENTH 0.625
int num[]=
{
A0,B3,
C1,B7,C1,C2,C1,
B7,B5,B7,
B6,
A0,A0,A0,B3,/*第一行*/
C1,B3,
B7,B5,
B6,B6,B6,B5,B4,
B3,B3,
C1,B5,/*第二行*/
C2,A0,B5,
B6,C1,B7,B5,B6,
B6,
A0,A0,A0,B3,
C1,C1,C1,B6,/*第三行*/
B7,B3,B3,A0,B5,
B6,B6,B6,B5,B4,
B3,A0,B3,
C1,C1,C1,B5,/*第四行*/
B7,C2,C2,A0,B5,
C4,C4,C4,C1,C2,
C3,
/*第五行*/
};
float zi[]={
0.5,0.5,
1+1+1,0.25,0.25,0.25,0.25,
1+1+1,0.5+0.5,0.25,
1+1+1+1,
1,1,1,1,/*第1行*/
1+1+1,1,
1+1+1,1,
1+0.5,0.5,0.5,0.5,1,
1+1+1,1,
1+1+1,1,/*第2行*/
1+1+1,0.5,0.5,
1,0.5,1,0.5,1,
1+1+1+1,
1+0.5,0.5,1,1,/*第3行*/
1,0.5,1+0.5,0.5,0.5,
1+0.5,0.5,0.5,0.5,1,
1+1,1,1,
1+0.5,0.5,1,1,/*第4行*/
1+0.5,0.5,1,0.5,0.5,
1+0.5,0.5,0.5,0.5,1,
1+1+1+1,
/*第5行*/
};
int changdu;//此定义用存储音符长度
int tonepin = 3;//这个就是输出端口
void setup()//子函数
{
pinMode(tonepin,OUTPUT);
changdu=sizeof(num)/sizeof(num[0]);
}
void loop()
{
for(int x=0;x<changdu;x++)
{
tone(tonepin,num[x]);
delay(500*zi[x]); //这里用来根据节拍调节延时,500这个指数可以自己调整,在该音乐中,我发现用500比较合适。
noTone(tonepin);
}
delay(2000);
}