Arduino教程 06 报警器「DFR0100」
【本篇课程内容于 2024年9月20日更新】>课程配套Arduino器材:Arduino入门套件 DFR0100这里我们要接触一个新的电子元件——蜂鸣器,从字面意思就可以知道,这是一个会发声的元件。这次做一个报警器,通过连接蜂鸣器到Arduino数字输出引脚,并配合相应的程序就可以产生报警器的声音。其原理是利用正弦波产生不同频率的声音。如果再结合一个LED,配合同样的正弦波产生灯光的话,就是一个完整的声光报警器了。
## 元件清单
## 硬件连接
按下图连接图连接,注意本项目蜂鸣器为无源蜂鸣器无正负之分。蜂鸣器的两个引脚分别接到GND和数字口8。
## 示例代码
输入下面的样例代码,这段代码引自《beginning-arduino》一书。
样例代码6-1:
```
//项目 - 报警器float sinVal;int toneVal;
void setup(){ pinMode(8, OUTPUT);}
void loop(){ for(int x=0; x<180; x++){ //将sin函数角度转化为弧度 sinVal = (sin(x*(3.1412/180))); //将sin函数角度转化为弧度 toneVal = 2000+(int(sinVal*1000)); //用sin函数值产生声音的频率 tone(8, toneVal); //将toneVal给引脚8 delay(2); } }```
下载程序完成后,你会听到平滑的一高一低的报警声,如同汽车报警器。
## 代码回顾
首先,定义两个变量:
float sinVal;
int toneVal;
浮点型变量sinVal用来存储正弦值,正弦波呈现一个波浪形的变化,变化比较均匀,所以我们选用正弦波的变化来作为我们声音频率的变换,toneVal从sinVal变量中获得数值,并把它转换为所需要的频率。
这里用的是sin()函数,一个数学函数,可以算出一个角度的正弦值,这个函数采用弧度单位。如图2,当弧度位于区间0~π,也就是角度位于区间0~180度时,sin()值为正。因为我们不想让函数值出现负数,所以设置for循环在0~179之间,也就是0≤x<180。
`for(int x=0; x<180; x++)`
函数sin()用的弧度单位,不是角度单位。要通过公式(3.1412/180)将角度转为弧度:
`sinVal = (sin(x*(3.1412/180)));`
这样sinVal的值将会根据角度的变化产生像波浪一样的起伏,之后,将这个值转变成相应的报警声音的频率:
`toneVal = 2000+(int(sinVal*1000));`
这里有个知识点——浮点型值转换为整型。
sinVal是个浮点型变量,也就是含小数点的值,而我们不希望频率出现小数点的,所以需要有一个浮点值转换为整型值得过程,也就是下面这句语句就完成了这件事:
`int toneVal;`
把sinVal乘以1000,转换为整型后再加上2000赋值给变量toneVal,现在toneVal就是一个适合声音频率了。
之后,我们用tone()函数把生成的这个频率给我们的蜂鸣器。
`tone(8, toneVal);`
下面我们来介绍一下tone相关的三个函数
1. `tone(pin,frequency)`
Pin都是指连接到蜂鸣器的数字引脚,frequency是以Hz为单位的频率值。
2. `tone(pin,frequency,duration)`
第二个函数,有个duration参数,它是以毫秒为单位,表示声音长度的参数。像第一个函数,如果没有指定duration,声音将一直持续直到输出一个不同频率的声音产生。
3. `noTone(pin)`
noTone(pin)函数,结束该指定引脚上产生的声音。
## 硬件回顾
### 蜂鸣器
蜂鸣器其实就是一种会发声的电子元件。蜂鸣器主要分为压电式蜂鸣器和电磁式蜂鸣器两种类型。
#### 压电式蜂鸣器和电磁式蜂鸣器区别
压电式蜂鸣器是以压电陶瓷的压电效应,来带动金属片的振动而发声。当受到外力导致压电材料发生形变时压电材料会产生电荷。电磁式的蜂鸣器,则是利用通电导体会产生磁场的特性,通电时将金属振动膜吸下,不通电时依振动膜的弹力弹回。不太明白也没太大关系,不影响我们使用。压电式蜂鸣器需要比较高的电压才能有足够的音压,一般建议为9V以上。电磁式蜂鸣器用1.5V就可以发出85dB以上的音压了,但消耗电流会大大的高于压电式蜂鸣器。所以还是建议初学者使用电磁式蜂鸣器。
#### 有源蜂鸣器和无源蜂鸣器区别
无论是压电式蜂鸣器还是电磁式蜂鸣器,都有有源蜂鸣器和无源蜂鸣器两种区分。
有源蜂鸣器和无源蜂鸣器的根本区别是输入信号的要求不一样。这里的“源”不是指电源,而是指振荡源,有源蜂鸣器内部带振荡源,说白了就是只要一通电就会响。而无源内部不带震荡源,所以如果仅用直流信号无法使其响,必须用2K-5K的方波去驱动它。
从外观上看,有源无源的区别在于,有源蜂鸣器有长短脚,也就是所谓正负极,长脚为正极,短脚为负极。而无源蜂鸣器则没有正负极,两个引脚长度相同。
在套件中,我们为初学者选用的蜂鸣器类型是无源蜂鸣器,可以演奏出不同的音乐效果。
蜂鸣器的应用有很多,我们也可以就蜂鸣器做一些好玩的东西,比如常见的会结合蜂鸣器的有,红外传感器,超声波传感器,用于监测物体靠近报警。温度传感器,测到温度过高报警。气体传感器,有气体泄漏报警等等。除了报警,还可以用来作为乐器,通过不同频率,调成乐谱的不同调式,是不是很amazing?
## 课后练习
1. 结合红色LED灯做一个完整的报警器。
提示:可以让LED也随着sin函数变化,使声音与灯光节奏保持一致。
2. 结合【交通信号灯】中介绍的按钮,做个简易门铃的效果,每次按下按钮,蜂鸣器发出提示音。
> DFRobot版权所有,欢迎转载。
转载请务必标注来源: DF创客社区+作者姓名+原文网址。
下一篇教程:Arduino教程 07 温度报警器
第二个小作业:
结合项目4我做出来了按一下按键后报警同时亮灯,但是我有两个小问题想请教一下
1. 报警完之后我想要buzzer静音,所以设置了tone(8,0),可是蜂鸣器还是会响。
2.代码要怎么改才能实现灯还有buzzer触发n轮? 具体点就是从报警器从最小声到最大到最小声响三遍。
附我改写的代码:
float sinVal;
int toneVal;
int ledVal;
int button=10;//pin for button
int presstime=5000;
unsigned long changeTime;//time after press the button
void setup(){
pinMode(8,OUTPUT);//buzzer引脚
pinMode(9, OUTPUT);//Led引脚
pinMode(button,INPUT);//按键引脚
}
void loop(){
int state = digitalRead(button);
//检测按钮是否被按下,并且是否距上次按下后有3秒的等待时间
if(state == HIGH && (millis() - changeTime)> 3000){
//调用变灯函数
changeLights();
}
}
void changeLights(){
for (int x=0;x<180;x++){
sinVal=(sin(x*(3.14/180)));
toneVal=2000+(int(sinVal*1000));
tone(8, toneVal);
ledVal=int(sinVal*200);
analogWrite(9, ledVal);
delay(20);
}
changeTime = millis();
tone(8,1);
analogWrite(9,0);
}
/*1、结合红色LED灯做一个完整的报警器。
提示:可以让LED也随着sin函数变化,使声音与灯光节奏保持一致。
*/
int ledPin=10;
int buzze=8;
void setup() {
// put your setup code here, to run once:
pinMode(ledPin,OUTPUT);
pinMode(buzze,OUTPUT);
}
void loop() {
// put your main code here, to run repeatedly:
float sinVal;
int toneVal;
int ledVal;
for(int x=0; x<180; x++){
//将sin函数角度转化为弧度
sinVal = (sin(x*(3.1412/180)));
//用sin函数值产生声音的频率
toneVal = 2000+(int(sinVal*1000));
//led输出值
ledVal = 55+(int(sinVal*200));
//给引脚8一个
tone(buzze, toneVal);
analogWrite(ledPin,ledVal);
delay(2);
}
}
课后第一题红灯和蜂鸣器int node = 8;
int led = 7;
float sinVal;
int toneVal;
void setup() {
// put your setup code here, to run once:
pinMode(node,OUTPUT);
pinMode(led,OUTPUT);
}
void loop() {
for(int i = 0; i < 180; i++){
sinVal = (sin(i*(3.14/180)));
toneVal = 1000 + (int(sinVal*(1000)));
tone(node,toneVal);
if(i <= 90){
digitalWrite(led,HIGH);
}else{
digitalWrite(led,LOW);
}
delay(2);
}
}
步骤6第一个我已经完成,代码如下:
float sinVal;
int toneVal;
int ledVal;
void setup(){
pinMode(8,OUTPUT);
pinMode(9, OUTPUT);
}
void loop(){
for (int x=0;x<180;x++){
sinVal=(sin(x*(3.14/180)));
toneVal=2000+(int(sinVal*1000));
tone(8, toneVal);
ledVal=int(sinVal*200);
analogWrite(9, ledVal);
delay(20);
}
}
但是联线的时候发现一个问题, LED的ground必须接在arduino uno上方的GND,如果使用prototyping shield也必须接在那里。如果接在prototyping 右边红色部分的GND,灯是不会亮的。
请问一下这是怎么回事啊?
谢谢 !
snakeqx 发表于 2014-6-26 19:27
步骤6第一个我已经完成,代码如下:
晕,我看错了,prototyping shield右边红色部分是5V输出,黑色部分才是GND.。。。
抱歉。 snakeqx 发表于 2014-6-26 19:31
晕,我看错了,prototyping shield右边红色部分是5V输出,黑色部分才是GND.。。。
抱歉。 ...
解决问题就好~ 买的配件里的是无源蜂鸣器。。。 顶一个,好好学习 半水 发表于 2015-1-30 20:38
买的配件里的是无源蜂鸣器。。。
是的 蜂鸣器有变动,不过不影响使用的 snakeqx 发表于 2014-6-26 19:27
步骤6第一个我已经完成,代码如下:
我想问一下ledVal=int(sinVal*200) 怎么保证ledVal的值在0到255之间 snakeqx 发表于 2014-6-26 19:27
步骤6第一个我已经完成,代码如下:
看了您的代码才明白基于过程的实现方法。我一直在想LED和蜂鸣器同时工作需要多线程来处理呢。 pinmode 9也输出了,是不是要在硬件电路接一个灯?还是? xuexideyang 发表于 2016-1-30 12:10
pinmode 9也输出了,是不是要在硬件电路接一个灯?还是?
样例代码没有用到9,只用了Pin 8
警报真的好难听,弄个小曲儿
本帖最后由 木龙小驴 于 2016-2-23 21:31 编辑警报真的好难听,弄个小曲儿float sinVal;
int toneVal;
static int times = 0;
int diaodiao = {262,294,330,349,392,440,494,523,478};//网上能搜到音律的赫兹数,用数组保存
char SUNANA="123556531233212.123556531233221.44466655312.123556531233221"; //随便搜个曲子,用字符数组保存
void setup() {
// put your setup code here, to run once:
pinMode(10, OUTPUT);
}
void loop() {
// put your main code here, to run repeatedly:
goSing(SUNANA);
}
void goSing(char *music){
for(int i=0;i<128;i++){
int index = music-48; //ascii码里字符 '1'= 49,所以需要减去48
if(index >0 && index <10){
tone(10, diaodiao,200); //发出声音,200毫秒持续时间
}else{
delay(500);
}
if(music == 0){ //由于C语言数组默认是0,所以遇到0就break(跳出循环)
break;
}
delay(200);
}
}
//整体还有些问题,就是tone这个函数,只有赫兹数变化才会发声,比如do ri,如果是dodo,就会发一个,希望哪位大神能指导小弟。 怎么看不到图啊 还有一个问题想要请教下我该怎么操作才能插入代码框==我弄了好一会儿还是弄不出来,发出来的代码看起来丑丑的 看不见图怎么办? 颖丸子 发表于 2017-3-21 14:43
看不见图怎么办?
或者你看这个吧 。https://www.dfrobot.com.cn/images ... 129112804mdoxsq.pdf undercoldwater 发表于 2017-3-14 16:00
第二个小作业:
结合项目4我做出来了按一下按键后报警同时亮灯,但是我有两个小问题想请教一下
1. 报警完之 ...
关闭蜂鸣器声音,noTone(pin) 请问硬件搭建的电路图怎么没有显示? xxlll66 发表于 2017-2-22 18:15
怎么看不到图啊
恢复得创造力?
页:
[1]
2