作为一个积累了许多乐器和杂音箱的音乐家,不起眼的Arduino是创建自定义MIDI控制器的理想工具。尽管树莓派(Raspberry Pi)可能已经赢得了物联网(IoT)的称号,但它在此项目上的功能已经足够。
首次使用Arduino?不用担心,在您完成该项目之前,我们已经阅读了完整的Arduino初学者指南。
什么是MIDI?
MIDI代表乐器数字接口。它概述了音乐设备相互通信的标准方法。如果您拥有电子键盘,则可能具有MIDI接口。尽管MIDI的实现涉及一些技术细节,但重要的是要记住MIDI不是音频! MIDI数据是一组简单的指令(一个指令称为“消息"),另一台设备可以实现该指令来发出不同的声音或控制参数。
MIDI支持16个通道。这意味着每根电缆可以支持16个相互独立通信的设备。使用5针DIN电缆连接设备。 DIN代表“德国标准化协会",并且只是连接器内部具有五个针脚的电缆。经常使用USB代替5针DIN,或者可以使用USB-MIDI接口。
MIDI消息主要有两种类型:控制更改和程序更改。
控制更改(CC)消息包含一个控制器号和一个介于0和127之间的值。CC消息通常用于更改设置,例如音量或音调。接受MIDI的设备应随附一本手册,说明默认情况下设置了哪些通道和消息以及如何更改它们(称为MIDI映射)。
程序更改(PC)消息比CC消息更简单。 PC消息由一个数字组成,用于更改设备上的预设或补丁。 PC消息有时被称为“补丁更改"。与CC消息类似,制造商应提供文档,概述特定消息会更改哪些预设。
您需要什么
构建计划
该项目将非常简单。您当然可以添加更多按钮或硬件以满足您的需求。几乎任何Arduino都适用-此示例仅需要三个引脚。该项目包括两个用于控制程序的按钮,一个用于发送数据的MIDI端口以及一个用于接收消息的设备。此电路是在面包板上构建的,但是可以将其传输到项目框和焊接的连接器,以提供可靠的解决方案。
电路组件
为MIDI接线插座如下:
按钮通过更改Arduino“看到"的电阻来工作。 Arduino引脚通过一个10k欧姆的电阻器(“下拉"电阻器,确保该值保持较低),将开关直接接地( LOW )。按下按钮后,在没有电阻( HIGH )的情况下,电路看到的值将变为+ 5v。 Arduino可以使用 digitalRead(pin)命令检测到此更改。将按钮连接到Arduino数字输入/输出(I / O)上的引脚6和7。连接两个按钮:
MIDI测试
现在,所有硬件都已完成,现在该进行测试了。您将需要一个USB-MIDI接口(许多音频接口可以做到这一点)和MIDI电缆。面包板上连接的MIDI端口正在发送数据,因此它是输出。您的计算机正在接收数据,因此它是输入。该项目使用了47种效果出色的Arduino MIDI库v4.2。安装库之后,可以通过转到草图>包含库> MIDI 将其包含在代码中。
您还需要一个程序来监视传入的MIDI数据:
将Arduino连接到计算机并上传以下测试代码(不要忘记从工具>板和工具>端口菜单中选择正确的板和端口)。
#include <midi.h>#include <midi_defs.h>#include <midi_message.h>#include <midi_namespace.h>#include <midi_settings.h>MIDI_CREATE_INSTANCE(HardwareSerial,Serial, midiOut); // create a MIDI object called midiOutvoid setup() { Serial.begin(31250); // setup serial for MIDI}void loop() { midiOut.sendControlChange(56,127,1); // send a MIDI CC -- 56 = note, 127 = velocity, 1 = channel delay(1000); // wait 1 second midiOut.sendProgramChange(12,1); // send a MIDI PC -- 12 = value, 1 = channel delay(1000); // wait 1 second}
此代码将发送CC消息,等待1秒钟,发送PC消息,然后无限期等待1秒钟。如果一切正常,您应该会在MIDI监视器中看到一条消息。
如果什么都没有发生,请不要惊慌!尝试进行故障排除:
如果您仍然遇到问题,可能值得检查一下面包板。廉价板有时可能会非常不稳定且质量低下–在我从事此项目时碰巧出现了这种情况。
按钮测试
现在是时候测试按钮是否正常工作了。上载以下测试代码。不需要连接MIDI即可测试该部分。
const int buttonOne = 6; // assign button pin to variableconst int buttonTwo = 7; // assign button pin to variablevoid setup() { Serial.begin(9600); // setup serial for text pinMode(buttonOne,INPUT); // setup button as input pinMode(buttonTwo,INPUT); // setup button as input}void loop() { if(digitalRead(buttonOne) == HIGH) { // check button state delay(10); // software de-bounce if(digitalRead(buttonOne) == HIGH) { // check button state again Serial.println("Button One Works!"); // log result delay(250); } } if(digitalRead(buttonTwo) == HIGH) { // check button state delay(10); // software de-bounce if(digitalRead(buttonTwo) == HIGH) { // check button state again Serial.println("Button Two Works!"); // log result delay(250); } } }
运行此代码(但保持USB电缆连接)并打开串行监视器(右上角>串行监视器) 。当您按下一个按钮时,根据所按下的按钮,您应该会看到“ Button One Works!"或“ Button Two Works!"。
此示例中有一个重要的注意事项–该软件去弹。这是检查按钮与再次检查按钮之间的简单10毫秒(ms)延迟。这可以提高按钮按下的准确性,并有助于防止噪声触发Arduino。尽管建议这样做,但您不必这样做。
创建控制器
现在所有的东西都已经连接好并且可以正常工作了,现在该组装完整的控制器了。
此示例将为每个按下的按钮发送不同的CC消息。我正在使用它来控制OS X上的Ableton Live 9.6。代码与上面的两个测试示例相似。
#include <MIDI.h>#include <midi_Defs.h>#include <midi_Message.h>#include <midi_Namespace.h>#include <midi_Settings.h>const int buttonOne = 6; // assign button pin to variableconst int buttonTwo = 7; // assign button pin to variableMIDI_CREATE_INSTANCE(HardwareSerial,Serial, midiOut); // create a MIDI object called midiOutvoid setup() { pinMode(buttonOne,INPUT); // setup button as input pinMode(buttonTwo,INPUT); // setup button as input Serial.begin(31250); // setup MIDI output}void loop() { if(digitalRead(buttonOne) == HIGH) { // check button state delay(10); // software de-bounce if(digitalRead(buttonOne) == HIGH) { // check button state again midiOut.sendControlChange(56,127,1); // send a MIDI CC -- 56 = note, 127 = velocity, 1 = channel delay(250); } } if(digitalRead(buttonTwo) == HIGH) { // check button state delay(10); // software de-bounce if(digitalRead(buttonTwo) == HIGH) { // check button state again midiOut.sendControlChange(42,127,1); // send a MIDI CC -- 42 = note, 127 = velocity, 1 = channel delay(250); } }}
注意-您将无法使用 Serial.println() 带有MIDI输出。
如果要发送PC消息而不是CC,只需替换:
midiOut.sendControlChange(42,127,1);
使用:
midiOut.sendProgramChange(value, channel);
有效
以下是作为Ableton Live(每种预算的最佳DJ软件)的控制器的演示。
您是否制作了MIDI控制器?
有一个自定义MIDI控制器的许多实际用途。您可以建造一个大型的脚踏控制单元,或者一个时尚的录音棚控制器。如果您有兴趣购买一个,这里是您可以购买的最好的USB MIDI控制器。
图片来源:Keith Gentry通过Shutterstock.com