393浏览
查看: 393|回复: 0

[入门教程] Arduino入门教程17--DJ调音台「DFR0100」

[复制链接]
本帖最后由 zoey不种土豆 于 2024-11-20 17:11 编辑

通过控制蜂鸣器的频率和节拍可以产生不同的声音。那么,如果可以自由调整这两个变量,会产生什么样的效果呢?在本节课中,我们将制作一个简易的DJ调音台。通过使用两个电位器,你将能够分别控制声音的频率和节拍,从而体验像DJ一样实时调音的乐趣!

元件清单
Arduino入门教程17--DJ调音台「DFR0100」图1

硬件连接
按如下连线图连接。
Arduino入门教程17--DJ调音台「DFR0100」图2
1 DJ调音台连线图
示例代码
样例代码:
  1. //项目 - DJ调音台  
  2. int pitchPin = A0; // 电位器1 - 模拟引脚A0,用于控制音调  
  3. int beatPin = A1;  // 电位器2 - 模拟引脚A1,用于控制节奏  
  4. int piezo = 8;     // 压电蜂鸣器 - 数字引脚8  
  5.   
  6. void setup() {  
  7.   Serial.begin(9600); // 初始化串行端口,波特率为9600  
  8. }  
  9.   
  10. void loop() {  
  11.   int pitchVal = analogRead(pitchPin);
  12. // 从音调电位器读取值  
  13.   int beatVal = analogRead(beatPin);   
  14. // 从节奏电位器读取值  
  15.   
  16.   int frequency = map(pitchVal, 0, 1023, 0, 5000);  
  17. // 将音调值映射到频率范围0-5000 Hz  
  18.   int duration = map(beatVal, 0, 1023, 100, 5000);  
  19. // 将节奏值映射到持续时间范围100-5000 ms  
  20.    
  21.   // 将频率和持续时间打印到串行端口  
  22.   Serial.print("频率: ");  
  23.   Serial.print(frequency);  
  24.   Serial.print(" Hz, 持续时间: ");  
  25.   Serial.print(duration);  
  26.   Serial.println(" ms");  
  27.   
  28.   tone(piezo, frequency, duration);
  29. // 在压电蜂鸣器上播放指定频率和持续时间的音调  
  30.   int pauseBetweenNotes = duration * 1.30;
  31. // 计算音符之间的暂停时间  
  32.   delay(pauseBetweenNotes); // 等待暂停时间  
  33.   noTone(piezo); // 停止播放音调  
  34. }
复制代码

成功下载完程序后,打开Arduino IDE的串口监视器。
Arduino入门教程17--DJ调音台「DFR0100」图4
设置串口监视器的波特率为9600。
Arduino入门教程17--DJ调音台「DFR0100」图5
可以直接从串口读取当前的频率和节拍值,旋转旋钮即可看到读数变化。

代码回顾
这个程序读取两个电位器的值,用来控制压电蜂鸣器的音调频率和持续时间。这些值还会输出到串口监视器上,方便观察。
程序开始设置了三个变量,来定义两个电位器与蜂鸣器的引脚。
  1. int pitchPin = A0;   
  2. int beatPin = A1;  
  3. int piezo = 8;
复制代码
在setup中,我们使用了一个新的函数:
  1. Serial.begin(9600);
复制代码
这个函数用于初始化串口波特率,也就是数据传输的速率,是使用串口必不可少的函数。直接输入相应设定的数值就可以了,如果不是一些特定的无线模块对波特率有特殊要求的话,波特率设置只需和串口监视器保持一致即可。我们这里就只是用于串口监视器。

在loop中设置了两个新的变量,用于记录两个电位器的读数。
  1. int pitchVal = analogRead(pitchPin);
  2. 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赫兹的频率范围,这个功能称为映射。
  1. int frequency = map(pitchVal, 0, 1023, 0, 5000);
复制代码
Map函数格式如下:
  1. map(value, fromLow, fromHigh, toLow, toHigh)
复制代码
map函数会将 fromLow 到 fromHigh 之间的值映射到 toLow 在 toHigh 之间的值。还可以用来翻转数值的范围,例如:y = map(x, 1, 50, 50, 1)。
同理,我们想要用另一个电位器控制声音的持续时间,范围是100毫秒到5秒之间。
  1. int duration = map(beatVal, 0, 1023, 100, 5000);
复制代码
那串口收到数据后,如何在串口监视器上显示呢?
  1. Serial.print(val);  
  2. Serial.println(val);
复制代码
println()与print()区别就是,println()比print()多了回车换行,其他完全相同。
我们可以使用下面这两个函数输出不同格式的内容。
  1. Serial.print(“Frequency: ”);  
  2. Serial.print(frequency);
复制代码
这两条语句虽然看起来括号中的内容都是frequency,但第一条语句中加了双引号,将引号中的内容作为字符串原样输出;而第二句中的frequency代表的是frequency变量,将输出该变量当前的数值。
在输出字符串时,可以在文字内容前后增加冒号和空格,让输出内容更容易阅读。
  1. Serial.print("频率: ");  
  2. Serial.print(frequency);  
  3. Serial.print(" Hz, 持续时间: ");  
  4. Serial.print(duration);  
  5. Serial.println(" ms");
复制代码
这段程序的输出的效果如下:
Arduino入门教程17--DJ调音台「DFR0100」图7
使用与项目【音乐蜂鸣器】相同的程序来播放声音并设置间隔,如有疑问,请参考之前的内容。

硬件回顾
电位器
电位器可以理解为是一个电阻,只是这个电阻阻值可变。我们这里可调节的范围是0~10KΩ。电阻两端接电源,通过中间引脚调节阻值,随着电阻值的改变而带动电压变化。我们用模拟口0读取到这个变化中的电压值,并转换为对应的音调和节奏。这就是整个的控制过程。
电位器在电路上的表示的图标为下图,分别对应器件上的3个引脚。
Arduino入门教程17--DJ调音台「DFR0100」图3
简单的看下原理,不知道还记不记得在第项目【可控舵机】中讲到的分压原理。电位器用的同样是分压原理。我们可以理解为,电位器被拆分为上下两个电阻R1和R2,随着转动电位器,上下阻值发生变化,从而对应的输出电压就不同。我们可以想象成切蛋糕,分到的蛋糕越多(电阻),吃下去的能量(电压Vout)也就越大。电压值大小的变化可以直接通过模拟口读到的值(0~1023)反应出来。
Arduino入门教程17--DJ调音台「DFR0100」图6

示例代码

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

为本项目制作心愿单
购买心愿单
心愿单 编辑
[[wsData.name]]

硬件清单

  • [[d.name]]
btnicon
我也要做!
点击进入购买页面
上海智位机器人股份有限公司 沪ICP备09038501号-4

© 2013-2024 Comsenz Inc. Powered by Discuz! X3.4 Licensed

mail