- /*用简谱制作一首《传奇》
- 1=E,1=G两种调;采用了Excel表格函数将简谱的1、2、3、4、5、6、7变成频率,还把频率变成数组,统计出数组的个数
- 在这个基础上,做了一组音乐彩灯:用不同的频率,驱动不同的6种颜色的灯*/
- //6个频率指示灯的频率界值:
- int ledbd1=560;
- int ledbd2=661;
- int ledbd3=760;
- int ledbd4=880;
- int ledbd5=1000;
- /***************曲子中各个音符的频率及节拍数组*****************/
- //旋律的频率,按照E调,旋律中各个音符的频率值
- int melody[]=
- {
- 0,660,660,660,825,733,733,733,660,660,660,733,733,660,550,550,0,619,619,619,660,733,619,550,495,412,412,
- 0,825,733,825,825,733,733,733,660,660,733,550,550,550,733,660,0,619,619,619,660,733,733,550,495,412,
- 990,733,825,990,733,660,550,0,733,550,825,733,660,660,495,
- 990,733,825,990,733,660,550,0,733,550,825,733,660,660,733,733,
- 0,660,660,660,495,660,990,879,825,733,660,0,660,825,990,1100,990,1100,990,1100,990,825,825,733,825,
- 0,660,660,660,495,660,990,879,825,733,660,0,660,825,990,1100,990,1100,990,1100,990,825,990,990,
- 1188,990,879,990,1188,1320,660,879,990,1056,990,1056,990,879,879,990,
- 1188,990,879,990,1188,1320,1584,1320,879,990,1056,990,1056,990,879,879,990
- };
-
- // 各个音符的节拍,16:1/4拍;8:1/2拍;4:1拍;2:2拍;等等
- int noteDurations[]=
- {
- 8,16,16,8,8,8,16,16,16,8,16,8,8,16,16,2,8,16,16,8,16,5.3,8,16,8,16,2,
- 8,16,16,8,16,16,8,16,16,4,8,8,16,16,16,2,8,16,16,8,16,5.3,8,16,5.3,2,
- 5.3,5.3,8,5.3,5.3,8,2,8,5.3,5.3,8,5.3,5.3,8,2,
- 5.3,5.3,8,5.3,5.3,8,2,8,5.3,5.3,8,5.3,5.3,16,16,2,
- 8,16,16,8,16,5.3,8,8,8,5.3,2,16,16,16,16,8,16,8,5.3,8,16,16,16,8,2,
- 5.3,16,16,8,16,5.3,8,8,8,5.3,2,16,16,16,16,8,16,8,5.3,8,8,16,5.3,2,
- 3,8,8,8,8,8,1,2,8,4,16,16,16,16,16,2,
- 3,8,8,8,8,8,2,2,4,8,4,16,16,16,16,16,2
- };
- /************************初始化函数****************************/
- void setup()
- {
- //设置数字口的输入/输出模式
- for(int i=2; i<14;i++)
- pinMode(i,OUTPUT); //设置数字口D2-D13为输出口
- }
- /**************************主函数******************************/
- void loop()
- {
- for(int i=3; i<12;i=i+2)//6个频率指示灯的负极接点:GND、3、5、7、9、11
- digitalWrite(i,LOW); //即熄灭所有灯
- //用循环语句演奏整个旋律,要注意音符的数量(这个可以用excel表格统计出来)
- for (int thisNote = 0; thisNote < 166; thisNote++)
- {
- //用除法计算演奏时间,
- //用传奇录音校对节奏,采用3132毫秒,很接近
- int noteDuration = 3132/noteDurations[thisNote]; //赋值
- tone(14, melody[thisNote],noteDuration);//D14口-A0口,用压电陶瓷片,也可用8欧姆喇叭
- int pauseBetweenNotes = noteDuration *1.2;//两个音符之间应该以最短的间隔分开,从经验中得知,延迟时间是音符的1.1~1.3倍左右
- delay(pauseBetweenNotes);
- noTone(14);//停止演奏
- //频率赋值给变量,控制相应的LED灯亮
- int melodytN = melody[thisNote+1];
- //为了使灯与音乐保持同步,这里的melody[]必须+1
- if (melodytN<ledbd1)
- { //最低的频率区间
- for (int i=2;i<13;i=i+2)
- {
- digitalWrite(i,LOW); //其余灯熄灭
- }
- digitalWrite(2,HIGH); //最左边的灯亮
- }
- if (melodytN>ledbd1&&melodytN<ledbd2)
- { //第二个频率区间
- for (int i=2;i<13;i=i+2)
- digitalWrite(i,LOW); //其余灯熄灭
- digitalWrite(4,HIGH); //从左往右第二个灯亮
- }
- if (melodytN>ledbd2&&melodytN<ledbd3)
- { //第三个频率区间
- for (int i=2;i<13;i=i+2)
- digitalWrite(i,LOW); //其余灯熄灭
- digitalWrite(6,HIGH); //从左往右第三个灯亮
- }
- if (melodytN>ledbd3&&melodytN<ledbd4)
- { //第四个频率区间
- for (int i=2;i<13;i=i+2)
- digitalWrite(i,LOW); //其余灯熄灭
- digitalWrite(8,HIGH); //从左往右第四个灯亮
- }
- if (melodytN>ledbd4&&melodytN<ledbd5)
- { //第五个频率区间
- for (int i=2;i<13;i=i+2)
- digitalWrite(i,LOW); //其余灯熄灭
- digitalWrite(10,HIGH); //从左往右第五个灯亮
- }
- if (melodytN>ledbd5)
- { //最高的频率
- for (int i=2;i<13;i=i+2)
- digitalWrite(i,LOW); //其余灯熄灭
- digitalWrite(12,HIGH); //最右边的灯亮
- }
- }
- }
复制代码