这篇文章来源于DevicePlus.com英语网站的翻译稿。
不久前,我们研究了如何使用Raspberry Pi的I2C总线来控制Arduino Uno,以及如何使用它来输出模拟电压。
令人兴奋的是,完成这些项目后,您就已经掌握构建一个简单合成器的大部分方法了。
并且一家名叫dzl的制造商已经发布了一组名为the_synth的Arduino库,我们可以马上安装并使用该库。
那么,就让我们来一起完成这个项目吧!现在,我们来构建一个波表合成器。
“波表”合成器是什么意思?
一个波表合成器可以将一系列简单波形以不同电压电平波表文件的形式存储在存储器中。
合成器将这些电压以不同的速率输出,来产生相应频率的音调。
我们只需要存储每种波形的一个周期,这是一种可以高效节省内存的方法,因此非常适用于内存有限的简单微控制器。
在the_synth里,您可以在tables.h文件中找到波表。您也可以通过编辑该文件来创建自己的波表。
然后,我们通过把Arduino Uno的PWM硬件连接到低通滤波器,将内存中的这些数值转换为模拟电压,如之前的项目中所描述的那样。
所需部件
Raspberry Pi | |
一个GPIO扩展板 | |
一个无焊面包板 | |
一个Arduino Uno | |
一个1k欧姆电阻 | |
一个10nF电容 | |
一个220uF电容 | |
一个有源扬声器 |
最好不要使用昂贵的有源扬声器来构建和测试DIY合成器或音频项目。虽然这样的电路不一定会损坏您的东西,但是为什么要冒险呢?
我一直使用的都是从二手商店花5美元购买的大型旧固态高保真音响。一些旧的电脑扬声器也是不错的选择。
安装示例
The_synth附带了许多示例用于演示其使用方法,我们可以直接使用它们。在深入研究代码之前,我们先试一下其中一个示例。
如果想要在您的Arduino IDE中安装库和其中的示例,请前往 https://github.com/dzlonline/the_synth并点击在页面右上方标有Code.的绿色按钮。
点击Download ZIP,并保存该文件。
现在打开Arduino IDE。在Sketch菜单中,将光标放在Include Library处,然后点击Add .ZIP library…。
找到我们之前保存的.zip文件,选择它并点击“OK”。
您现在已经成功将the_synth安装到了您的IDE中,并且可以从菜单中访问库和示例了。让我们试试any_hertz示例,它可以循环遍历四种不同的频率。
您可以打开“File”菜单,将鼠标停留在Examples处,然后滚动到底部至the_synth-master.找到该示例。将鼠标停留在该选择上,并点击any_hertz来打开草图。
现在通过USB连接Arduino Uno,请再次确认您选择了Arduino Uno,确认后上传草图。
接线
现在,我们需要将Arduino Uno连接到一个简单的低通滤波器,就像之前构建项目中所做的那样,然后将它连接到我们的扬声器。
首先,从连接电源引脚开始:
将引脚11(即PWM引脚)连接到面包板的中间。我们还需要接地来构建低通滤波器,因此将接地引脚连接到负电源轨。
现在构建低通滤波器。将1k电阻连接到PWM引脚,然后将10nF电容连接到电阻的另一端和接地轨,如下所示:
现在我们需要一个耦合电容器,以确保不会通过任何直流电。需要记住的一点是电解电容器是有极性的,因此请将阳极(较长端)连接到低通滤波器,另一端连接到面包板下方。
将扬声器连接到耦合电容器的阴极,如有需要可以接地。
如果您已经正确完成了所有连接,您现在将会听到一组包含四种音调的声音。
使用I2C 和Raspberry Pi控制合成器
您现在可以听到自己所构建的波表合成器所发出的声音了,是不是很酷?
但只是一遍又一遍地听着这四种音调并不是很有趣。我们想要能够使用Raspberry Pi对其进行控制。
我们可以在I2C总线上使用Arduino的Wire库和Python中的SMBus模块(我们之前介绍过)来完成此操作。
对Arduino Uno编程
我们真正需要做的是将这个any_hertz示例和之前编写的I2C程序整合在一起,以播放我们发送的音符。
我们先导入I2C和synth库。
#include
#include
每个Arduino草图都需要一个设置函数,在我们的设置函数中,需要完成三件事情:作为从机加入I2C总线;初始化我们的合成器;以及在收到I2C指令时调用另一个函数。
我们可以按照如下所示编写:
void setup() {
edgar.begin(); //-Start up a synth
edgar.setupVoice(0,TRIANGLE,60,ENVELOPE1,127,64); //-Set up voice 0
Wire.begin(0x8); // Join the I2C Bus as a slave at address 0x8
Wire.onReceive(readInstruction); // On
}
现在我们需要编写readInstruction()函数。该函数用于从I2C总线读取一个数字。如果读取了0,那么将不播放任何东西。如果读取了1到8之间的数字,那么将会播放A1到A2之间的一个音符。
void readInstruction(int bitstream) {
byte option = Wire.read();
switch (option) {
case 0:
edgar.setFrequency(0, 0.0); // Play nothing
edgar.trigger(0);
break;
case 1:
edgar.setFrequency(0, 55.0); // Play A1
edgar.trigger(0);
break;
case 2:
edgar.setFrequency(0, 61.74); // Play B1
edgar.trigger(0);
break;
case 3:
edgar.setFrequency(0, 65.41); // Play C2
edgar.trigger(0);
break;
case 4:
edgar.setFrequency(0, 73.42); // Play D2
edgar.trigger(0);
break;
case 5:
edgar.setFrequency(0, 82.41); // Play E2
edgar.trigger(0);
break;
case 6:
edgar.setFrequency(0, 87.31); // Play F2
edgar.trigger(0);
break;
case 7:
edgar.setFrequency(0, 98.0); // Play G2
edgar.trigger(0);
break;
case 8:
edgar.setFrequency(0, 110.0); // Play A2
edgar.trigger(0);
break;
}
}
最后,每个Arduino草图都需要一个循环函数。但实际上我们没有需要循环运行的工作,所以我们只在其中写入一个sleep函数。
void loop() {
sleep(10000);
}
保存该草图,并将其上传到您的Arduino Uno。
连接I2C总线
这部分内容与我们在之前的文章中所介绍的完全相同:将Raspberry Pi的SDA引脚连接到Arduino Uno的A4引脚,将SCL引脚连接到A5引脚。
播放一首简单的歌曲
现在让我们用该项目来播放歌曲《Mary Had a Little Lamb》。
这首歌有两种不同长度的音符:四分音符和半音符(或二分音符)。我们现在来编写两个快速函数来播放这些音符。
我们需要计时功能,因此在这里导入sleep函数。
from time import sleep
但是中间需要暂停多久?我们的歌曲是每分钟122拍。根据该数值,我们可以计算出每个音符需要多少秒:四分音符是492微秒。我们在结尾处设置一段非常短的暂停,以便能够在播放相同音调时分辨这些音符。
def playCrotchet(int pitch):
i2cbus.write_byte(pitch)
sleep(0.472)
i2cbus.write_byte(arduino, 0)
sleep(0.02)
现在我们来写一个半音符函数:
def playMinim(int pitch):
i2cbus.write_byte(pitch)
sleep(0.964)
i2cbus.write_byte(arduino, 0)
sleep(0.02)
然后:
def playMary():
playCrotchet(E2)
playCrotchet(D2)
playCrotchet(C2)
playCrotchet(D2)
playCrotchet(E2)
playCrotchet(E2)
playMinim(E2)
playCrotchet(D2)
playCrotchet(D2)
playMinim(D2)
playCrotchet(E2)
playCrotchet(G2)
playMinim(G2)
playCrotchet(E2)
playCrotchet(D2)
playCrotchet(C2)
playCrotchet(D2)
playCrotchet(E2)
playCrotchet(E2)
playCrotchet(E2)
playCrotchet(E2)
playCrotchet(D2)
playCrotchet(D2)
playCrotchet(E2)
playCrotchet(D2)
playMinim(C2)
想要播放该歌曲,请输入:
playMary()
多尝试一些内容,看看有没有什么新的想法。
下一步该做什么?
这是探索合成器构建方法的一个很好的开端:您还可以基于该内容制作一些很酷的低音线。
但是将所有音乐都写成代码是相当麻烦的,而且我们目前只有有限的音符和简单的波形。
接下来如果可以使用图形界面以及改变音符的音色不是会更好么?
请继续关注我们——我们将会很快进行这些内容的探索。
DevicePlus 编辑团队
设备升级版适用于所有热爱电子和机电一体化的人。
审核编辑黄宇
-
合成器
+关注
关注
0文章
270浏览量
25336 -
Arduino
+关注
关注
187文章
6464浏览量
186665 -
Raspberry Pi
+关注
关注
1文章
557浏览量
22165
发布评论请先 登录
相关推荐
评论