/

用Arduino开发板演奏音乐

本篇介绍如何使用Arduino开发板配合无源蜂鸣器演奏音乐

制作前警告:请先通过搜索补充基础的音乐简谱知识,这些知识并不难,我也是现学的;另外需要很好的耐心,因为要输很多音符和拍子,最后调试拍速也很麻烦

材料准备

Arduino UNO开发板

这是Arduino最经典的开发板之一,本篇全部内容在此开发板上完成

Arduino UNO

相关链接

Arduino官网

Arduino UNO 开发板的官方介绍

Arduino IDE

用于写入程序,Arduino IDE支持的平台很多,在安卓,webAPP,MacOS,Linux,Windows都有相应版本,本质是一样的,哪个平台都可以编译。

ArduinoIDE

我使用的是GNU/Linux平台的ArduinoIDE

蜂鸣器

蜂鸣器是一种电子发声元器件,可以发出”beep”的声音。采用直流电压供电,广泛应用于计算机、打印机、复印机、报警器、电子玩具、汽车电子设备、电话机、定时器等电子产品中作发声器件。

蜂鸣器分为有源蜂鸣器和无源蜂鸣器两种。

有源蜂鸣器: 内部带有震荡源,只要一通电就会发出固定频率的声音。有源蜂鸣器特点是分正负极,正反电阻不同,类似二极管。

有源蜂鸣器

无源蜂鸣器:内部不带震荡源,需要使用2KHz到5KHz的脉冲信号驱动发声,声音频率可变。特点是不区分正负极,正反电阻相同,本质就是一个电磁铁驱动铁片发声。

无源蜂鸣器

LED灯(可选)

我这里为了增强效果使用LED灯,可以不用

电池

电路图

接线图

程序实现

定义蜂鸣器发声

预定义

为方便录入蜂鸣器发声频率,我们预定义了七个音符的中音和低音频率以及零音符

简谱音符频率对照表

我要使用的音乐只有中音和低音,所以我只定义了中音和低音,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#define Do 262    //1
#define Re 294 //2
#define Mi 330 //3
#define Fa 349 //4
#define Sol 392 //5
#define La 440 //6
#define Si 494 //7
#define Do_h 523 //1
#define Re_h 587 //2
#define Mi_h 659 //3
#define Fa_h 698 //4
#define Sol_h 784 //5
#define La_h 880 //6
#define Si_h 988 //7
#define No 0

录入简谱

以下是我要录入的歌曲 归去来兮 的简谱

归去来兮简谱

这里有个好玩的事,因为录入量很大(约375个音符)所以我继之前创新了“让Python帮我写JavaScript”以及“让JavaScript帮我写Web”的写法,我又创新了“让Python帮我写C”(Arduino基本语法与C类似,从C转到Arduino没什么压力),下面这个是代替我录入音符的Python

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#!/usr/bin/python3
# -*- coding: utf-8 -*-
totx=""
toty=""
totz=""
while True:
b=''
x=input("x=")
if str(x)=="exit":
print('yes')
doc = open('out.txt','w')
doc.write(totx)
doc.close()
if str(x)=="1":
b="Do_h"
elif str(x)=="2":
b="Re_h"
elif str(x)=="3":
b="Mi_h"
elif str(x)=="4":
b="Fa_h"
elif str(x)=="5":
b="Sol_h"
elif str(x)=="6":
b="La_h"
elif str(x)=="7":
b="Si_h"
elif str(x)=="10":
b="Do"
elif str(x)=="20":
b="Re"
elif str(x)=="30":
b="Mi"
elif str(x)=="40":
b="Fa"
elif str(x)=="50":
b="Sol"
elif str(x)=="60":
b="La"
elif str(x)=="70":
b="Si"
elif str(x)=="0":
b="No"
a=b
totx+=a
totx+=","
doc = open('out.txt','w')
doc.write(totx)
doc.write("\n\n\n")
doc.write(toty)
doc.write("\n\n\n")
doc.write(totz)
doc.write("\n\n\n")

#x=input("")

这个Python写的不好,连跳出都没有,仅仅临时使用,想关就强关就行了

另外再科普一下音符高低音看法

高低音标志

以及零音符意义

零音符

录入以后的音符是这样子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
int16_t scale[] = {
La , Do_h , Mi_h , Sol , Sol , Sol , Re_h , Mi_h , Do_h , La ,
La , La , Mi_h , Mi_h , Do_h , Re_h , Do_h , Re_h , Do_h , Mi_h , Mi_h , Do_h ,
Re_h , Do_h , Re_h , Do_h , Re_h , Do_h , Re_h , Do_h , Re_h , Mi_h , Fa_h , Mi_h ,
La , La , Mi_h , Mi_h , Do_h , Re_h , Do_h , Re_h , Do_h , Mi_h , Mi_h , Do_h ,
Re_h , Do_h , Re_h , Do_h , Re_h , Do_h , Re_h , Do_h , Re_h , Do_h , La , La ,
La_h , La_h , La_h , Mi_h , Do_h , Re_h , Do_h , Re_h , Do_h , Mi_h , Mi_h , Do_h ,
Re_h , Do_h , Re_h , Do_h , Re_h , Re_h , Do_h , Re_h , Re_h , Mi_h , Sol_h, Mi_h ,
La , La , Mi_h , Mi_h , Do_h , Re_h , Do_h , Re_h , Do_h , Mi_h , Mi_h , Do_h ,
Re_h , Do_h , Re_h , Re_h , Do_h , Re_h , Re_h , Re_h , Do_h , Re_h , La ,
La , La_h , Mi_h , Re_h , Mi_h , Re_h , Do_h , Re_h , Do_h , Re_h , Sol_h, Mi_h ,
La , Mi_h , Re_h , Do_h , Mi_h , Re_h , Do_h , Re_h , Mi_h , Re_h , Do_h , La ,
La , La_h , Mi_h , Re_h , Mi_h , Re_h , Do_h , Re_h , Do_h , Re_h , Sol_h, Mi_h ,
La , Mi_h , Re_h , Do_h , Mi_h , Re_h , Do_h , Re_h , Mi_h , Re_h , Do_h , La ,
No , La , Do_h , Re_h , Mi_h , Re_h , Mi_h , Mi_h , No , La , Do_h ,
Re_h , Mi_h , Re_h , Do_h , Do_h , No , La , Do_h , Re_h , Mi_h , Re_h , Mi_h , Mi_h , No , La , Do_h , Re_h , Mi_h , Re_h , Do_h , Do_h ,
La , La , Mi_h , Mi_h , Do_h , Re_h , Do_h , Re_h , Do_h , Mi_h , Mi_h , Do_h ,
Re_h , Do_h , Re_h , Do_h , Re_h , Do_h , Re_h , Do_h , Re_h , Mi_h , Fa_h , Mi_h ,
La , La , Mi_h , Mi_h , Do_h , Re_h , Do_h , Re_h , Do_h , Mi_h , Mi_h , Do_h ,
Re_h , Do_h , Re_h , Do_h , Re_h , Do_h , Re_h , Do_h , Re_h , Do_h , Re_h , La ,
La_h , La_h , La_h , Mi_h , Do_h , Re_h , Do_h , Re_h , Do_h , Mi_h , Mi_h , Do_h ,
Re_h , Do_h , Re_h , Do_h , Re_h , Do_h , Re_h , Do_h , Re_h , Mi_h , Fa_h , Mi_h ,
La , La , Mi_h , Mi_h , Do_h , Re_h , Do_h , Re_h , Do_h , Mi_h , Mi_h , Do_h ,
Re_h , Do_h , Re_h , Re_h , Do_h , Re_h , Do_h , Re_h , Do_h , Re_h , La ,
La , La_h , Mi_h , Re_h , Mi_h , Re_h , Do_h , Re_h , Do_h , Re_h , Sol_h, Mi_h ,
La , Mi_h , Re_h , Do_h , Mi_h , Re_h , Do_h , Re_h , Mi_h , Re_h , Do_h , La ,
La , La_h , Mi_h , Re_h , Mi_h , Re_h , Do_h , Re_h , Do_h , Re_h , Sol_h, Mi_h ,
La , Mi_h , Re_h , Do_h , Mi_h , Re_h , Do_h , Re_h , Mi_h , Re_h , Do_h , La ,
La , La_h , Mi_h , Re_h , Mi_h , Re_h , Do_h , Re_h , Do_h , Re_h , Sol_h, Mi_h ,
La , Mi_h , Re_h , Do_h , Mi_h , Re_h , Do_h , Re_h , Mi_h , Re_h , Do_h , La ,
La , La_h , Mi_h , Re_h , Mi_h , Re_h , Do_h , Re_h , Do_h , Re_h , Sol_h, Mi_h ,
La , Mi_h , Re_h , Do_h , Mi_h , Re_h , Do_h , Re_h , Mi_h , Re_h , Do_h , La
};

另外解释一下为什么用”int16_t”,因为音符太多,会超内存,如果用默认32位int定义整形会浪费内存(ArduinoUNO的存储为4kb)

定义节拍

音乐中每个音时长不同,这个也要定义

简谱中节拍定义:

节拍

这个节拍我们后面会乘一个固定系数即为延迟,这取决于音乐本身速度,应该是和简谱左上角的几个字有关,自己听原版调也可以

定义节拍我也做了辅助录入的Python脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#!/usr/bin/python3
# -*- coding: utf-8 -*-
totx=""
toty=""
totz=""
while True:
b=''
x=input("x=")
if str(x)=="exit":
print('yes')
doc = open('out.txt','w')
doc.write(totx)
doc.close()
if str(x)=="1":
b="0.25"
elif str(x)=="2":
b="0.5"
elif str(x)=="3":
b="1"
elif str(x)=="4":
b="2"
a=b
totx+=a
totx+=","

录入后效果如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
int8_t durt[] =
{
2, 2, 2, 2, 8, 2, 2, 2, 2, 8,
2, 2, 2, 1, 1, 1, 1, 1, 1, 2, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 4,
2, 2, 2, 1, 1, 1, 1, 1, 1, 2, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 4,
2, 2, 1, 2, 1, 1, 1, 1, 1, 2, 1, 1,
1, 1, 1, 1, 2, 1, 1, 2, 1, 1, 2, 2,
2, 2, 2, 1, 1, 1, 1, 1, 1, 2, 1, 1,
1, 1, 2, 1, 1, 2, 1, 2, 1, 2, 2,
4, 4, 2, 2, 4, 2, 2, 2, 2, 2, 2, 4,
4, 4, 2, 2, 4, 2, 2, 2, 2, 2, 2, 4,
4, 4, 2, 2, 4, 2, 2, 2, 2, 2, 2, 4,
4, 4, 2, 2, 4, 2, 2, 2, 2, 2, 2, 4,
4, 4, 8, 2, 2, 2, 2, 8, 4, 4, 8,
2, 2, 2, 2, 8, 4, 4, 8, 2, 2, 2, 2, 8, 4, 4, 8, 2, 2, 2, 2, 8,
2, 2, 2, 1, 1, 1, 1, 1, 1, 2, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 4,
2, 2, 2, 1, 1, 1, 1, 1, 1, 2, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 4,
2, 2, 1, 2, 1, 1, 1, 1, 1, 2, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 4,
2, 2, 2, 1, 1, 1, 1, 1, 1, 2, 1, 1,
1, 1, 2, 1, 1, 1, 1, 1, 1, 2, 4,
4, 4, 2, 2, 4, 2, 2, 2, 2, 2, 2, 4,
4, 4, 2, 2, 4, 2, 2, 2, 2, 2, 2, 4,
4, 4, 2, 2, 4, 2, 2, 2, 2, 2, 2, 4,
4, 4, 2, 2, 4, 2, 2, 2, 2, 2, 2, 4,
4, 4, 2, 2, 4, 2, 2, 2, 2, 2, 2, 4,
4, 4, 2, 2, 4, 2, 2, 2, 2, 2, 2, 4,
4, 4, 2, 2, 4, 2, 2, 2, 2, 2, 2, 4,
4, 4, 2, 2, 4, 2, 2, 2, 2, 2, 2, 1
};

这里我们用了int8_t,定义成8位整数,这样能节约一半以上内存(我一开始用浮点数定义,内存直接爆了)

全局变量

上面的蜂鸣器发声定义使用的是全局变量,下面再定义其他必须全局变量

定义发声针脚为A0

1
int tonepin = A0;

定义长度,后面要用

1
int length;

初始化程序

此程序用于初始化开发板

初始化了发声针脚以及亮灯针脚并将所有针脚设定为零电势以保障安全

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void setup()
{
pinMode(tonepin, OUTPUT);//设置发声脚
pinMode(A2, OUTPUT);//设置LED输出脚
digitalWrite(A2, LOW);//设置输出脚电势
pinMode(A3, OUTPUT);//同上
digitalWrite(A3, LOW);
pinMode(A4, OUTPUT);
digitalWrite(A4, LOW);
pinMode(A5, OUTPUT);
digitalWrite(A5, LOW);
for (int i = 1; i <= 13; i++) {
pinMode(i, OUTPUT);
digitalWrite(i, LOW);
}
length = sizeof(scale) / sizeof(scale[0]);//定义音乐长度
}

循环播放音乐主程序

先看API:

noTone(tonepin);//停止发声

tone(tonepin, scale[x]);//发声,参数一发声脚,参数二频率

digitalWrite(i, HIGH);//用于修改LED输出脚电势,参数一输出脚,参数二电势(LOW为低电势,一般理解为零电势,HIGH为高电势,具体电势不明)

delay(a);//延时,参数为毫秒数

代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
void loop()
{
for (int x = 0; x < length; x++)
{
if (scale[x] == 0) {
noTone(tonepin);
}
else{
tone(tonepin, scale[x]);
}
//digitalWrite(ledpin,HIGH);
for (int i = 1; i <= 13; i++) {
if (i % 4 == 1) {
digitalWrite(i, HIGH);
}
}
digitalWrite(A3, LOW);
digitalWrite(A5, HIGH);
for (int i = 1; i <= 13; i++) {
if (i % 4 == 3) {
digitalWrite(i, LOW);
}
}
delay(750 * durt[x] / 4);//节拍延时
//digitalWrite(ledpin,LOW);
for (int i = 1; i <= 13; i++) {
if (i % 4 == 1) {
digitalWrite(i, LOW);
}
}
digitalWrite(A5, LOW);
digitalWrite(A3, HIGH);
for (int i = 1; i <= 13; i++) {
if (i % 4 == 3) {
digitalWrite(i, HIGH);
}
}
delay(150 * durt[x] / 4);//节拍延时
noTone(tonepin);
}
delay(3000);
}

开始使用

至此,你的开发板已可以唱歌,全部代码如下(伸手党请看这里)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
#define Do 262    //1
#define Re 294 //2
#define Mi 330 //3
#define Fa 349 //4
#define Sol 392 //5
#define La 440 //6
#define Si 494 //7
#define Do_h 523 //1
#define Re_h 587 //2
#define Mi_h 659 //3
#define Fa_h 698 //4
#define Sol_h 784 //5
#define La_h 880 //6
#define Si_h 988 //7
#define No 0
int length;
int16_t scale[] = {
La , Do_h , Mi_h , Sol , Sol , Sol , Re_h , Mi_h , Do_h , La ,
La , Do_h , Mi_h , Sol , Sol , Sol , Re_h , Mi_h , Do_h , La ,
La , La , Mi_h , Mi_h , Do_h , Re_h , Do_h , Re_h , Do_h , Mi_h , Mi_h , Do_h ,
Re_h , Do_h , Re_h , Do_h , Re_h , Do_h , Re_h , Do_h , Re_h , Mi_h , Fa_h , Mi_h ,
La , La , Mi_h , Mi_h , Do_h , Re_h , Do_h , Re_h , Do_h , Mi_h , Mi_h , Do_h ,
Re_h , Do_h , Re_h , Do_h , Re_h , Do_h , Re_h , Do_h , Re_h , Do_h , La , La ,
La_h , La_h , La_h , Mi_h , Do_h , Re_h , Do_h , Re_h , Do_h , Mi_h , Mi_h , Do_h ,
Re_h , Do_h , Re_h , Do_h , Re_h , Re_h , Do_h , Re_h , Re_h , Mi_h , Sol_h, Mi_h ,
La , La , Mi_h , Mi_h , Do_h , Re_h , Do_h , Re_h , Do_h , Mi_h , Mi_h , Do_h ,
Re_h , Do_h , Re_h , Re_h , Do_h , Re_h , Re_h , Re_h , Do_h , Re_h , La ,
La , La_h , Mi_h , Re_h , Mi_h , Re_h , Do_h , Re_h , Do_h , Re_h , Sol_h, Mi_h ,
La , Mi_h , Re_h , Do_h , Mi_h , Re_h , Do_h , Re_h , Mi_h , Re_h , Do_h , La ,
La , La_h , Mi_h , Re_h , Mi_h , Re_h , Do_h , Re_h , Do_h , Re_h , Sol_h, Mi_h ,
La , Mi_h , Re_h , Do_h , Mi_h , Re_h , Do_h , Re_h , Mi_h , Re_h , Do_h , La ,
No , La , Do_h , Re_h , Mi_h , Re_h , Mi_h , Mi_h , No , La , Do_h ,
Re_h , Mi_h , Re_h , Do_h , Do_h , No , La , Do_h , Re_h , Mi_h , Re_h , Mi_h , Mi_h , No , La , Do_h , Re_h , Mi_h , Re_h , Do_h , Do_h ,
La , La , Mi_h , Mi_h , Do_h , Re_h , Do_h , Re_h , Do_h , Mi_h , Mi_h , Do_h ,
Re_h , Do_h , Re_h , Do_h , Re_h , Do_h , Re_h , Do_h , Re_h , Mi_h , Fa_h , Mi_h ,
La , La , Mi_h , Mi_h , Do_h , Re_h , Do_h , Re_h , Do_h , Mi_h , Mi_h , Do_h ,
Re_h , Do_h , Re_h , Do_h , Re_h , Do_h , Re_h , Do_h , Re_h , Do_h , Re_h , La ,
La_h , La_h , La_h , Mi_h , Do_h , Re_h , Do_h , Re_h , Do_h , Mi_h , Mi_h , Do_h ,
Re_h , Do_h , Re_h , Do_h , Re_h , Do_h , Re_h , Do_h , Re_h , Mi_h , Fa_h , Mi_h ,
La , La , Mi_h , Mi_h , Do_h , Re_h , Do_h , Re_h , Do_h , Mi_h , Mi_h , Do_h ,
Re_h , Do_h , Re_h , Re_h , Do_h , Re_h , Do_h , Re_h , Do_h , Re_h , La ,
La , La_h , Mi_h , Re_h , Mi_h , Re_h , Do_h , Re_h , Do_h , Re_h , Sol_h, Mi_h ,
La , Mi_h , Re_h , Do_h , Mi_h , Re_h , Do_h , Re_h , Mi_h , Re_h , Do_h , La ,
La , La_h , Mi_h , Re_h , Mi_h , Re_h , Do_h , Re_h , Do_h , Re_h , Sol_h, Mi_h ,
La , Mi_h , Re_h , Do_h , Mi_h , Re_h , Do_h , Re_h , Mi_h , Re_h , Do_h , La ,
La , Do_h , Mi_h , Sol , Sol , Sol , Re_h , Mi_h , Do_h , La ,
La , Do_h , Mi_h , Sol , Sol , Sol , Re_h , Mi_h , Do_h , La ,
La , La_h , Mi_h , Re_h , Mi_h , Re_h , Do_h , Re_h , Do_h , Re_h , Sol_h, Mi_h ,
La , Mi_h , Re_h , Do_h , Mi_h , Re_h , Do_h , Re_h , Mi_h , Re_h , Do_h , La ,
La , La_h , Mi_h , Re_h , Mi_h , Re_h , Do_h , Re_h , Do_h , Re_h , Sol_h, Mi_h ,
La , Mi_h , Re_h , Do_h , Mi_h , Re_h , Do_h , Re_h , Mi_h , Re_h , Do_h , La ,
La , Do_h , Mi_h , Sol , Sol , Sol , Re_h , Mi_h , Do_h , La ,
La , Do_h , Mi_h , Sol , Sol , Sol , Re_h , Mi_h , Do_h , La
};
int8_t durt[] =
{
2, 2, 2, 2, 8, 2, 2, 2, 2, 8,
2, 2, 2, 2, 8, 2, 2, 2, 2, 8,
2, 2, 2, 1, 1, 1, 1, 1, 1, 2, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 4,
2, 2, 2, 1, 1, 1, 1, 1, 1, 2, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 4,
2, 2, 1, 2, 1, 1, 1, 1, 1, 2, 1, 1,
1, 1, 1, 1, 2, 1, 1, 2, 1, 1, 2, 2,
2, 2, 2, 1, 1, 1, 1, 1, 1, 2, 1, 1,
1, 1, 2, 1, 1, 2, 1, 2, 1, 2, 2,
4, 4, 2, 2, 4, 2, 2, 2, 2, 2, 2, 4,
4, 4, 2, 2, 4, 2, 2, 2, 2, 2, 2, 4,
4, 4, 2, 2, 4, 2, 2, 2, 2, 2, 2, 4,
4, 4, 2, 2, 4, 2, 2, 2, 2, 2, 2, 4,
4, 4, 8, 2, 2, 2, 2, 8, 4, 4, 8,
2, 2, 2, 2, 8, 4, 4, 8, 2, 2, 2, 2, 8, 4, 4, 8, 2, 2, 2, 2, 8,
2, 2, 2, 1, 1, 1, 1, 1, 1, 2, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 4,
2, 2, 2, 1, 1, 1, 1, 1, 1, 2, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 4,
2, 2, 1, 2, 1, 1, 1, 1, 1, 2, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 4,
2, 2, 2, 1, 1, 1, 1, 1, 1, 2, 1, 1,
1, 1, 2, 1, 1, 1, 1, 1, 1, 2, 4,
4, 4, 2, 2, 4, 2, 2, 2, 2, 2, 2, 4,
4, 4, 2, 2, 4, 2, 2, 2, 2, 2, 2, 4,
4, 4, 2, 2, 4, 2, 2, 2, 2, 2, 2, 4,
4, 4, 2, 2, 4, 2, 2, 2, 2, 2, 2, 4,
2, 2, 2, 2, 8, 2, 2, 2, 2, 8,
2, 2, 2, 2, 8, 2, 2, 2, 2, 8,
4, 4, 2, 2, 4, 2, 2, 2, 2, 2, 2, 4,
4, 4, 2, 2, 4, 2, 2, 2, 2, 2, 2, 4,
4, 4, 2, 2, 4, 2, 2, 2, 2, 2, 2, 4,
4, 4, 2, 2, 4, 2, 2, 2, 2, 2, 2, 1,
2, 2, 2, 2, 8, 2, 2, 2, 2, 8,
2, 2, 2, 2, 8, 2, 2, 2, 2, 8
};
int tonepin = A0;
void setup()
{
pinMode(tonepin, OUTPUT);
pinMode(A2, OUTPUT);
digitalWrite(A2, LOW);
pinMode(A3, OUTPUT);
digitalWrite(A3, LOW);
pinMode(A4, OUTPUT);
digitalWrite(A4, LOW);
pinMode(A5, OUTPUT);
digitalWrite(A5, LOW);
for (int i = 1; i <= 13; i++) {
pinMode(i, OUTPUT);
digitalWrite(i, LOW);
}
length = sizeof(scale) / sizeof(scale[0]);
}
void loop()
{
for (int x = 0; x < length; x++)
{
if (scale[x] == 0) {
noTone(tonepin);
}
else {
tone(tonepin, scale[x]);
}
//digitalWrite(ledpin,HIGH);
for (int i = 1; i <= 13; i++) {
if (i % 4 == 1) {
digitalWrite(i, HIGH);
}
}
digitalWrite(A3, LOW);
digitalWrite(A5, HIGH);
for (int i = 1; i <= 13; i++) {
if (i % 4 == 3) {
digitalWrite(i, LOW);
}
}
delay(660 * durt[x] / 4);
//digitalWrite(ledpin,LOW);
for (int i = 1; i <= 13; i++) {
if (i % 4 == 1) {
digitalWrite(i, LOW);
}
}
digitalWrite(A5, LOW);
digitalWrite(A3, HIGH);
for (int i = 1; i <= 13; i++) {
if (i % 4 == 3) {
digitalWrite(i, HIGH);
}
}
delay(150 * durt[x] / 4);
noTone(tonepin);
}
delay(3000);
}

其他音乐同理,不做解释,建议自行搜索学习音乐基础知识。

最后一步,测试

这是最重要的一步,我测试了很长时间才能保证我的开发板可以和原音乐拍子对上,测试主要测两个,一是拍速,而是音符是否正确