计算机接口使19世纪管风琴自行弹奏
苏格兰爱丁堡的一群工程师如何利用赛灵思 Spartan-3E入门套件创造出机器人管风琴手
正如许多新奇的创造一样,这一切都始于酒吧里的一次谈话。
“您知道楼上森林咖啡屋里的管风琴吗?”
“知道。”
“我们应该创造一个机器人管风琴手来演奏它。”
“当然,我们应该这样做!”
一次漫不经心的交谈促使我们着手开展“WaldflOte项目”。
我的日常工作是担任赛灵思苏格兰公司IP部门的设计经理,但在业余时间,我是“dorkbot”这个非正式组织的一分子,该组织旨在推进工程科学界与艺术界之间的草根协作;活动口号是“用电做离奇的事情”。我属于爱丁堡地区的dorkbot(可以称作“dorkbot alba”或“dorkbot Edinburgh”,主要取决于您对谁讲)。我们的成员创造了很多新奇的东西,包括像素映射LED礼帽、自动牙刷、幻觉魔术设备、电磁改锥和各种噪音发生盒。鲜有意外伤害事故发生。
dorkbot Edinburgh团队每隔一周于周二在森林咖啡屋聚会,这间咖啡屋位于爱丁堡大学附近,是由志愿者经营的非赢利性聚会场所。我参加了几周在这家咖啡屋举行的聚会,一天晚上,当我到楼上修理舞台照明设备时,惊奇地发现自己置身教堂之中,这里有布道台和唱诗班楼座,最重要的是,这里有一台16英尺高的管风琴。
事实上,咖啡屋所在的建筑曾经是爱丁堡公理教会的会场——因此有管风琴。但这里并不是这台管风琴最初的家。19世纪末,伦敦著名的管风琴制造商Gray和Davison首次将这台管风琴安装在爱尔兰的都柏林城堡,1900年,不知什么原因,这台管风琴被转移到爱丁堡。自此,这台管风琴经过数次维修,一直留在爱丁堡。
酒吧闲聊之后,我们并没有立即行动起来。在随后7个月的聚会中,我们不断地思考、探究、讨论,最后设计出了几种操纵管风琴键盘的方式。
我们将这个项目取名为“Project WaldflOte”,是因为管风琴上的一个音栓叫“WaldflOte”。在德语中,它的意思是“森林长笛”。由于管风琴位于森林咖啡屋,因此听起来还有些诗情画意。
采用正确的机械部件
在开发的初始阶段我们就明确地将问题分为机械和电子两部分。如果我们能够找到解决机械问题的方案,就能相对独立地打造这两个部分。
制约我们的主要因素之一是资金——我们没有多少资金可用,全部资金仅为我们几个核心成员自己筹集的资金。我们走遍尾货市场,找到了一些价格合适的电磁铁。我们能够以1英磅左右(约合1.5美元)的单价得到100个这样的电磁铁,我们订购了6个在管风琴上进行试验。
我们发现电磁铁的尺寸非常理想,但电磁铁芯的运动距离比要始终如一地触动管风琴白键所需的运动距离略短。尽管我们可以直接利用电磁铁芯来驱动黑键,但我们仍然需要某种杠杆来驱动白键。
电磁铁组装的首个原型如图1所示,图1为电磁铁的工作原理图。对于白键而言,顶部的胶合板杠杆的后面用管道胶带作铰链连接,当电磁铁通电时,它会受到下拉的力量。当电磁铁断电时,管风琴键自身会提供向上力——因此无需另外使用弹簧。对于黑键而言,从电磁铁底部伸出的小销可以足够的力量直接按压琴键,弹奏音符。
图1:电磁体组件原型。
图2:机械布局。
组件测试表明的确可以成功地按压琴键。同时也表明,我无法做到将放置电磁铁的空间七等分,其间隔无法接近键盘八度音阶的实际间隔,因此,我们只能一次测试一个键。但我们证实了这个原理是可行的,因此,我们继续开发工作,订购了适用于整个键盘的部件,然后开始着手电子设计。
电子设计
在进行电子设计时,我们大家坐下来,粗略地设计出电子结构;图3为基本结构图。在图的左侧,MIDI消息由外部传入(我将在下文详细介绍MIDI协议)。图的右侧是一个位移寄存器链;控制器在驱动相应的“数据”值填充位移寄存器链时,负责切换“时钟”信号,然后通过“选通”信号将位移寄存器链的内容并行发送至电磁铁驱动器的输入端。
图3:电子结构。
我们在位移寄存器/驱动器链上采用了74HC595位移寄存器IC。不过,电磁铁试验显示每个电磁铁大约需要15V电源提供350mA驱动电流——超出了CMOS输出级的提供范围。这了满足这个要求,我们在每个位移寄存器IC上增加了一个ULN2803A Darlington输出级。这个芯片还具备一个保护二极管,对切断电流时电磁铁生成的高反激电压进行分流,避免增加一个分立式二极管。我们在万用板上制作了几个驱动器电路板原型,每个可驱动16个电磁铁。
控制器设计
尽管我们可以采取多种方法设计控制器(包括利用Arduino平台或采用其他微控制器),但我们最终还是选择使用赛灵思Spartan-3E入门套件,因为我在赛灵思的日常工作中用过这种开发板,对相关工具了如指掌。特别是,我知道如何使用Platform Studio SDK和ChipScope等调试工具,由于这有可能是一个现场调试项目,这样做可节省时间。我们使用赛灵思嵌入式开发套件,开发核心组件MicroBlaze子系统(图4)。
图4:MicroBlaze 子系统。
除了MIDI接口和位移寄存器接口,我们还选择增加了串行RS-232控制端口,帮助我们调试系统。RS-232协议看起来有点老套,但在此类项目中,它的价值非凡。我们也增加了一些GPIO端口,用于驱动LED,读取开关和按钮,以便在无需使用控制端口的情况下,完成某些交互操作。
写入MicroBlaze固件
我们已经确定系统的最佳输入接口是MIDI端口。自20世纪80年代以来,乐器数字接口(MIDI)已经成为连接合成器等数控乐器与其他乐器或控制计算机的标准接口,因此,显然我们也应当采用这种接口。MIDI将使我们取得了管风琴连接的最大灵活性。
MicroBlaze可从内部显示整个键盘的状态以及系统正在按压哪些键——即系统正在为哪些电磁铁加电。
MIDI是一种单向低速串行协议,传输速率为31250波特。它包含多种类型的信息,但就我们的目的而言,只有NOTE ON和NOTE OFF是重要的信息类型。每个NOTE ON信息由3个字节构成。
第一个字节是0x9n,这里的n代表通道数。
第二个字节是0至127的音符数,中间的C为第60号。
第三个字节是0至127的速度值。
NOTE OFF除第一个字节是0x8n外,其余与此非常相似。
在我们的设计中,我们决定同步听取所有通道的信息( “omni”操作)。由于管风琴键盘对速度并不敏感,因此,我们可安全地忽略所有速度字节。
EDK UART IP核接收MIDI消息,然后通过FIFO,一次向MicroBlaze处理器发送一条信息。MicroBlaze可从内部显示整个键盘的状态和系统正在按压哪些键(即系统正在为哪些电磁铁加电)。固件采用一个静态查找表,指出与这个音符相关的电磁铁,将这个用做内部图的索引;到达的NOTE ON消息将相应entry值设为“1”,而NOTE OFF消息将entry值设为“0”。
内部图更新后,利用图的全部内容更新电磁铁寄存器;通过GPIO端口的位拆裂,MicroBlaze处理器一次将一位的图内容写入位移寄存器的数据输入端,然后切换时钟信号,移动一下位移寄存器。一旦利用图内容对整个位移寄存器进行了更新,MicroBlaze会将一个上升沿写入STROBE行,这能够将位移寄存器的值拷贝至输出寄存器,为正确的电磁铁加电或断电,从而产生悦耳的音乐。
我们将固件用作软件状态机;对于不采用实时操作系统的嵌入式应用而言,这可提供某些多线程应用功能,但没有实际线程实现开销。静态结构数组根据当前的状态,指出系统针对特定事件应当采取什么措施。
const midi_state_table_entry_t MIDI_STATE_TABLE[] =
{
{INHIBITED,PANIC,
MidiSM_Panic,INHIBITED},
{ANY_STATE,PANIC,
MidiSM_Panic,INIT},
{ANY_STATE,INHIBIT,
MidiSM_DoNothing,INHIBITED},
{ANY_STATE,OTHER_STATUS_RECEIVED
,MidiSM_ClearMessage,INIT},
{INIT,NOTE_ON_OR_OFF_RECEIVED,
MidiSM_StoreStatusByte,NOTE_
ON_OR_OFF},
{INIT,DATA_RECEIVED,
MidiSM_DoNothing,INIT},
{NOTE_ON_OR_OFF,NOTE_ON_
OR_OFF_RECEIVED,MidiSM_
我们成功演奏了一些非常复杂、快节奏的音乐,从古典到摇滚;电磁铁和驱动器在速度方面并没有表现出太大的局限性。
StoreStatusByte,NOTE_ON_OR_OFF},
{NOTE_ON_OR_OFF,DATA_RECEIVED,
MidiSM_StoreNoteNumber,NOTE_ON_OR
_OFF_NUMBER},
{NOTE_ON_OR_OFF_NUMBER,
NOTE_ON_OR_OFF_RECEIVED,MidiSM_St
oreStatusByte, NOTE_ON_OR_OFF},
{NOTE_ON_OR_OFF_NUMBER,
DATA_RECEIVED,MidiSM
_NoteOnOrOffComplete,
NOTE_ON_OR_OFF},
{INHIBITED,ENABLE,
MidiSM_DoNothing,INIT},
{LAST_STATE, LAST_EVENT, 0,
LAST_STATE},
};
在该结构体中的第一个entry表示当前状态;第二个entry表示事件到达;第三个entry表示处理该事件需要使用状态转换功能;第四个entry表示下一状态。
状态机业务端采用的代码如下:
XStatus MidiSM_
DoStateTransiTIon
(midi_state_machine_t *pInstance,
u8 event)
{
const midi_state_table_
entry_t *pTable = pInstance-
>pStateTable;
// Search for a match in the
state table
do {
if ((event == pTable-
>received_event)
&& ((pInstance-
>current_state == pTable-
>state)
|| (pTable->state ==
ANY_STATE)))
{
(*pTable-
>transiTIon_funcTIon)((v
oid *)pInstance);
pInstance->current_state
= pTable->next_state;
return XST_
SUCCESS;
}
pTable++;
} while (pTable->state !=
LAST_STATE);
// Aaargh, something bad happened - should never get here
XASSERT_NONVOID_ALWAYS();
}
事件循环提供的事件是对这种功能的论证,根据当前的状态和事件,采取某种措施和改变系统状态。事件的类型包括字节到达MIDI接口,字符到达控制端口和按下重启按钮(panic button)。所有经验丰富的MIDI玩家都知道重启按钮是保护耳朵和电源必备的特性——它可无条件地关闭所有电磁铁,使系统恢复到已知安全状态。
演奏WaldflOe
安装了这种应用精致的控制器, 机器人管风琴手可演奏从狂想曲到摇滚的所有风格音乐。隐藏在琴键底部的是电磁铁木制背板——每块板上安装30个或更多的电磁铁,同时还安装了一些回收利用的罐状电容器,为电磁铁提供电能。我们将整个驱动器组件与管风琴连接。在图的上方,您可看到Spartan-3E入门套件开发板和其右侧的接口万用板;我们利用回收利用的CAT5电缆将这些装置与驱动器组件连接。
用文字很难说明管风琴的运行情况,因此,我建议您点击本文结尾的互联网链接地址,收看我们上传的视频。当机器人管风琴手演奏《月光奏鸣曲》或《Jump》时,您将会听到电磁铁发出的咔嗒声——这是电磁铁铁芯降至线圈底部时发出的声音,不是杠杆敲击琴键的声音。不过,您若是坐在大厅里,而不是站在讲道台上,电磁铁发出的声音就会小很多。您所能听到的只是管风琴流淌出的优美音乐。
我们利用这套系统成功演奏了一些非常复杂、快节奏的音乐,从古典到摇滚;电磁铁和驱动器在速度方面并没有表现出太大的局限性。即使在弹奏要求最苛刻的曲目时,电磁铁电源在15V电压条件下通常电流不超过4A。即使我们稍微过度使用电磁铁,电磁铁线圈也没有出现明显升温的情况。总而言之,我们对这个系统非常满意,同时为参与开发这套系统深感自豪。
WaldflOe下一步是什么?噢,我们已经非正式地邀请了一些音乐家为这种新乐器创作曲目(尤其是对拥有53根手指、从不感到疲倦的演奏者感兴趣的作曲家),我们还考虑举办一个独奏会。另一种可能是实现管风琴音栓运作的机械化,便于我们在电子演奏过程中改变音量和音色。我们还在考虑采取某些方法驱动管风琴的低音踏板,使最长的低音管发音。最后也是最有可能完成的是,我们正打算在互联网上推出一项服务,使公众能够把他们的MIDI文件上传至这个系统,然后再聆听管风琴的实时演奏。