Arduino入门教程17--DJ调音台「DFR0100」
本帖最后由 zoey不种土豆 于 2024-11-20 17:11 编辑通过控制蜂鸣器的频率和节拍可以产生不同的声音。那么,如果可以自由调整这两个变量,会产生什么样的效果呢?在本节课中,我们将制作一个简易的DJ调音台。通过使用两个电位器,你将能够分别控制声音的频率和节拍,从而体验像DJ一样实时调音的乐趣!
元件清单
硬件连接
按如下连线图连接。
图 1 DJ调音台连线图示例代码
样例代码:
//项目 - DJ调音台
int pitchPin = A0; // 电位器1 - 模拟引脚A0,用于控制音调
int beatPin = A1;// 电位器2 - 模拟引脚A1,用于控制节奏
int piezo = 8; // 压电蜂鸣器 - 数字引脚8
void setup() {
Serial.begin(9600); // 初始化串行端口,波特率为9600
}
void loop() {
int pitchVal = analogRead(pitchPin);
// 从音调电位器读取值
int beatVal = analogRead(beatPin);
// 从节奏电位器读取值
int frequency = map(pitchVal, 0, 1023, 0, 5000);
// 将音调值映射到频率范围0-5000 Hz
int duration = map(beatVal, 0, 1023, 100, 5000);
// 将节奏值映射到持续时间范围100-5000 ms
// 将频率和持续时间打印到串行端口
Serial.print("频率: ");
Serial.print(frequency);
Serial.print(" Hz, 持续时间: ");
Serial.print(duration);
Serial.println(" ms");
tone(piezo, frequency, duration);
// 在压电蜂鸣器上播放指定频率和持续时间的音调
int pauseBetweenNotes = duration * 1.30;
// 计算音符之间的暂停时间
delay(pauseBetweenNotes); // 等待暂停时间
noTone(piezo); // 停止播放音调
}
成功下载完程序后,打开Arduino IDE的串口监视器。设置串口监视器的波特率为9600。可以直接从串口读取当前的频率和节拍值,旋转旋钮即可看到读数变化。
代码回顾
这个程序读取两个电位器的值,用来控制压电蜂鸣器的音调频率和持续时间。这些值还会输出到串口监视器上,方便观察。
程序开始设置了三个变量,来定义两个电位器与蜂鸣器的引脚。
int pitchPin = A0;
int beatPin = A1;
int piezo = 8;在setup中,我们使用了一个新的函数:Serial.begin(9600);这个函数用于初始化串口波特率,也就是数据传输的速率,是使用串口必不可少的函数。直接输入相应设定的数值就可以了,如果不是一些特定的无线模块对波特率有特殊要求的话,波特率设置只需和串口监视器保持一致即可。我们这里就只是用于串口监视器。
在loop中设置了两个新的变量,用于记录两个电位器的读数。int pitchVal = analogRead(pitchPin);
int beatVal = analogRead(beatPin);通常,程序开头定义的变量称为全局变量,可在程序的任何部分访问和使用。相比之下,像 pitchVal 和 beatVal 这样的变量可在循环中定义为局部变量,因为它们只在循环内部使用。这里用到了一个新函数——analogRead(pin)。这个函数用于从模拟引脚读值,pin是指连接的模拟引脚。Arduino的模拟引脚连接到一个10位A/D转换,输入0~5V的电压对应读到0~1023的数值,每个读到的数值对应的都是一个电压值。我们读取的电位器输出的电压范围是从0到1023。在之前的多节关于蜂鸣器的课程中,我们已经了解到人类可以听到的声音频率大约在0到5000赫兹之间(请参考第项目【音乐蜂鸣器】的pitch文件)。因此,我们需要将0到1023的电压范围转换到0到5000赫兹的频率范围,这个功能称为映射。int frequency = map(pitchVal, 0, 1023, 0, 5000);Map函数格式如下:map(value, fromLow, fromHigh, toLow, toHigh)map函数会将 fromLow 到 fromHigh 之间的值映射到 toLow 在 toHigh 之间的值。还可以用来翻转数值的范围,例如:y = map(x, 1, 50, 50, 1)。同理,我们想要用另一个电位器控制声音的持续时间,范围是100毫秒到5秒之间。int duration = map(beatVal, 0, 1023, 100, 5000);那串口收到数据后,如何在串口监视器上显示呢?Serial.print(val);
Serial.println(val);println()与print()区别就是,println()比print()多了回车换行,其他完全相同。我们可以使用下面这两个函数输出不同格式的内容。Serial.print(“Frequency: ”);
Serial.print(frequency);这两条语句虽然看起来括号中的内容都是frequency,但第一条语句中加了双引号,将引号中的内容作为字符串原样输出;而第二句中的frequency代表的是frequency变量,将输出该变量当前的数值。在输出字符串时,可以在文字内容前后增加冒号和空格,让输出内容更容易阅读。Serial.print("频率: ");
Serial.print(frequency);
Serial.print(" Hz, 持续时间: ");
Serial.print(duration);
Serial.println(" ms");这段程序的输出的效果如下:使用与项目【音乐蜂鸣器】相同的程序来播放声音并设置间隔,如有疑问,请参考之前的内容。
硬件回顾电位器电位器可以理解为是一个电阻,只是这个电阻阻值可变。我们这里可调节的范围是0~10KΩ。电阻两端接电源,通过中间引脚调节阻值,随着电阻值的改变而带动电压变化。我们用模拟口0读取到这个变化中的电压值,并转换为对应的音调和节奏。这就是整个的控制过程。电位器在电路上的表示的图标为下图,分别对应器件上的3个引脚。 简单的看下原理,不知道还记不记得在第项目【可控舵机】中讲到的分压原理。电位器用的同样是分压原理。我们可以理解为,电位器被拆分为上下两个电阻R1和R2,随着转动电位器,上下阻值发生变化,从而对应的输出电压就不同。我们可以想象成切蛋糕,分到的蛋糕越多(电阻),吃下去的能量(电压Vout)也就越大。电压值大小的变化可以直接通过模拟口读到的值(0~1023)反应出来。
示例代码
下一课:Arduino入门教程18--敲击电子鼓「DFR0100」
页:
[1]