蜂鸣器是我们常见的一个电子元器件,它可以发出类似蜂鸣的声音,采用低电压直流供电,广泛运用于计算机、打印机、报警器、电子玩具等众多场合,一般作为提示、警报较多;
我们不以结构论述,以工作原理可将其分为有源蜂鸣器和无源蜂鸣器;注意这里的源指的不是电源,而是振荡源,即有源蜂鸣器内部自带振荡源,通电就能发出声音;而无源蜂鸣器不带振荡源,必须用2-5k的方波去驱动;
蜂鸣器的发声装置由震动装置和谐振装置组成;
无源蜂鸣器的工作原理:方波信号输入谐振装置,转换为声音信号输出;
有源蜂鸣器的工作原理:直流电源输入经过振荡系统的放大取样电路,在谐振装置的作用下产生声音信号;
有源蜂鸣器和无源蜂鸣器的区别:
- 在外观上,有源蜂鸣器因为多了驱动电路,所以会比无源蜂鸣器要高(也正是因为多了驱动电路,所以有源的价格要比无源的高);
引脚朝上,可以看见绿色电路板的是无源蜂鸣器,用黑胶封起来的是有源蜂鸣器; - 通过发声条件,有源蜂鸣器直接接上额定电源就可以连续发声,而无源蜂鸣器需要接在音频输出电路中才能发声;
无源蜂鸣器的优点:
- 价格便宜
- 声音频率可控
- 在一些特殊场合中可复用端口(旋律灯)
有源蜂鸣器的优点:程序控制简单
好了,说了这么多,接下来我们就开始动手制作吧!
材料:arduino Nano*1、无源蜂鸣器、面板板*2、导线若干
硬件连线:
- 蜂鸣器正极(蜂鸣器上会标注+)→Nano 数字端口3
- 蜂鸣器负极 → Nano GND
- 外接电源(6V)正极 → Vin
- 外接电源负极 → GND
实现原理:
在开始制作之前,我们先来看看音乐简谱,看看在我们平常唱歌需要哪些信息:
这是一首我们最早接触的童谣,他本身也非常简单,我们就通过他来学习如何容蜂鸣器奏响这首音乐;我们通过上面的简谱可以得到如下信息:
- C 指的是音调,就是说我们要以怎么样的调子去唱,不同的调子发出声音的频率也是不一样的;
- 4/4 指的是节拍,可以理解成一个音的长短;
- 1234567- 就是哆喏咪发嗦啦唏,应该发出什么样的音;
好了,到这里我们可以总结一下了,我们想要唱一首歌,我们需要知道每个字应该用什么样的音去唱,这就需要音调和音符的配合了,两者结合就知道该用怎么样的音;光有了调子可不行,我们还得知道每个音应该发出多长时间,这就是节拍的作用;
我们一步一步来解决,第一个问题,蜂鸣器怎么知道每个音符应该发出什么样的声音呢?这就需要我们得到每个音的对应频率,然后让蜂鸣器按照频率发声就可以了;
对照音符和频率表,我们就可以很轻松的知道每个音的频率了(看音符是否带点,点在上还是在下到表中查找就可以了)
比如第一小节就是:262,262,393,393
频率的问题解决了,接下来就是节拍的问题了;这首歌是4/4,意思就是以四分音符为一拍,每小节有四拍;我们把一拍看做是单位1,那么1/2就是0.5,1/4就是0.25,1/8就是0.125;所以我们的每个音符配合这样的拍子演奏出来,就是我们想要的音乐啦;
程序实现:
- 我们用米思齐编程,首先先调整到高级视图,会相对灵活一点;
- 然后根据上面的简谱和频率对照表,我们创建三个数组,分别存储每个音的频率、节拍时间和音符;
这里可能会问了,为什么要建立两个数组来处理频率,不能直接转换过来嘛?当然可以,但是直接转换的话会比较麻烦,现在的音符比较少,后面复杂的音乐转换一下保准你看的眼花缭乱,所以还是让单片机帮我们转换吧,我们只需要将音符告诉他就好啦;
那么yindiao数组的最后一个元素为什么是-1呢?这是空拍,我们用-1代替; - 万事俱备只欠东风啦,接下来我们就需要调用函数来控制蜂鸣器发出第一个声音了
tone()函数可以产生固定频率的PWM信号来驱动扬声器发声,这也是为什么蜂鸣器需要连接在数字端口3的原因,或者连接在其他复用PWM功能的端口。tone()函数有两种用法: tone(端口, 频率) //没有定义时间,我们就需要自己手动用noTone()停止发声,不然他会一直发声 tone(3,262); delay(1000); noTone(3); tone(端口, 频率, 时间) tone(3,262,200); delay(200);
Arduino一次只能发出声音信号,当一个引脚正在通过tone()函数产生发声信号,那么第二个引脚想同时发声是不可能的;
(注意:使用tone()函数时会影响引脚3和引脚11的PWM信号输出)
这一部分就是通过简谱,对照频率表,转换成每个音符的对应频率;先从music数组中将音符提取出来(1 do),然后对应yindiao数组进行转换(yindiao[1-1]→262)
设置每个音的时间,这里的700指的是每个拍子的时间(毫秒) - 添加一个循环,自动播放音乐
这里为什么是1-48呢?因为这首小星星一共是48个音符,我们需要发出48个音,所以是1-48; - 好了,我们看一下完整的程序是怎么样的:
long yindiao[]={262,294,330,350,393,441,495,-1}; float time[]={1,0.5,0.25,0.125}; long music[]={1,1,5,5,6,6,5,8,4,4,3,3,2,2,1,8,5,5,4,4,3,3,2,8, 5,5,4,4,3,3,2,8,1,1,5,5,6,6,5,8,4,4,3,3,2,2,1,8}; void setup() { pinMode(3, OUTPUT); digitalWrite(3,LOW); } void loop() { for (int i = 1; i <= 48; i = i + (1)) { tone(3, yindiao[(int)(music[(int)(i - 1)] - 1)], time[(int)(0)] * 700); delay((time[(int)(0)] * 700)); } }