查看: 16156|回复: 40

[讨论] 乐器随身带--教你制作各种触摸电子乐器和玩儿法。

[复制链接]
    网络上你可以看到很多牛人,用身体的某些部位或是各种物体或演奏出音乐。
    你可能看过这个

2.jpg

这个

1.jpg

还有这个

3.jpg


    常常让我们感叹:“高he手bi在zhe民me间lei!"
    今天我带来的是一种电子乐器通用的制作方法,简单,便宜,拓展性强。有了它,简直就是随身的乐器库。
我之前发过一篇MIDI鼓机的教程,但是,这种设备又常常依赖于音源和编曲软件,如果只是想要一些钢琴,贝斯,或是鼓等等一些常见乐器的音色,又想让设备外型简单点最好是控端和音源,输出端集成在一起。那么就跟我一起造起来吧。let's make some noise!
首先你需要准备的东西:
UNO一块
uno.jpg

UNO一块

vs1053.jpg

MP3模块一块(VS1053b)扩展板,
121.jpg

MPR121触摸板一块
还有一个音箱,一个充电宝。
一定猜到了,我用的MP3模块充当的音源,但是材料单里没有用到存储卡,那声音从哪来?其实除了MP3格式的声音素材,VS1053b其实本身就内建了丰富的MIDI音色库GM1+GM2。
先看看接线:
接线.PNG

mp3模块有好几种,如果是扩展板样式的,很简单,直接插UNO,如果是外形小一点的模块。就照着图接接线一样效果。
DREQ--D2
X-CS--D6
X-DCS--D7
X-RESET--D8
MOSI--D11
MISO--D12
SCK--D13
5V
GND
MPR121就接I2C接口,只接四根线,3.3v和GND,SDA,SCL对应UNO的A4,A5.
接好线,插上音箱

下面是代码
  1. #include <Adafruit_MPR121.h>
  2. #include <Wire.h>
  3. #include <SPI.h>
  4. Adafruit_MPR121 cap = Adafruit_MPR121();
  5. uint16_t lasttouched = 0;
  6. uint16_t currtouched = 0;
  7. byte drums[] = {39,40,42,86,54,28,33,31,58,68,67,56};//示例为鼓根据自己的喜好选择鼓的音色
  8. //byte drums[] = {60,61,62,63,64,65,66,67,68,69,70,71,};//钢琴
  9. /*在鼓库(0x78)中,没有不同的乐器,只有不同的音符。
  10. 要播放不同的声音,请选择一个乐器#5,然后播放音符27至87。
  11. 27高Q 43高层汤姆59骑Cy 2 75克拉
  12. 28 Sla 44踏板Hi帽[EXC 1] 60高邦戈76嗨木块
  13. 29推杆[EXC 7] 45低汤姆61低邦戈77低木块
  14. 30 Srcatch Pull [EXC 7] 46打开Hi帽[EXC 1] 62静音Hi Conga 78静音Cuica [EXC 4]
  15. 31棒47低中汤姆63开放嗨康加79开放cuica [EXC 4]
  16. 32广场点击48高中汤姆64低康加80静音三角[EXC 5]
  17. 33节拍器单击49撞击Cy 1 65高Tim 81 81开放三角[EXC 5]
  18. 34节拍器响铃50高汤姆66低Timbale 82振动器
  19. 35声贝斯鼓51骑Cy 1 67高阿戈戈83叮当铃
  20. 36低音鼓1 52中国Cy 68低音琴84铃铛树
  21. 37侧杆53 Ride Bell 69 Casbasa 85响板
  22. 38 Acoustic Snare 54 Tambourine 70 Maracas 86 Mute Surdo [EXC 6]
  23. 39手拍55飞溅Cy 71短哨[EXC 2] 87打开Surdo [EXC 6]
  24. 40电圈套56牛铃72长笛[EXC 2]
  25. 41低地板汤姆57坠毁Cy 2 73短Guiro [EXC 3]
  26. 42闭Hi [EXC 1] 58 Vibra-slap 74 Long Guiro [EXC 3]
  27. */
  28. //MP3板需要接线的引脚,当然除此之外还有11,12,13号的ICSP通信引脚。
  29. #define VS_XCS    6  
  30. #define VS_XDCS   7   
  31. #define VS_DREQ   4
  32. #define VS_RESET  8  
  33. void setup() {
  34. if (!cap.begin(0x5A)) //MPR121        地址
  35.   {
  36.   while (1);
  37.   }
  38.   pinMode(VS_DREQ, INPUT);
  39.   pinMode(VS_XCS, OUTPUT);
  40.   pinMode(VS_XDCS, OUTPUT);
  41.   digitalWrite(VS_XCS, HIGH);
  42.   digitalWrite(VS_XDCS, HIGH);
  43.   pinMode(VS_RESET, OUTPUT);
  44.   digitalWrite(VS_RESET, LOW);
  45.   SPI.begin();
  46.   SPI.setBitOrder(MSBFIRST);
  47.   SPI.setDataMode(SPI_MODE0);
  48.   SPI.setClockDivider(SPI_CLOCK_DIV64);
  49.   SPI.transfer(0xFF);
  50.   delayMicroseconds(20);  
  51.   digitalWrite(VS_RESET, HIGH);
  52. //加载实时MIDI插件
  53.   VSLoadUserCode();
  54.   delay(50);
  55. /* MIDI INSTRUMENT LIBRARY:
  56. MELODIC INSTRUMENTS(GM1)
  57. 当使用旋律银行(0x79  - 与默认相同)时,打开选择一个乐器和八度来映射
  58. 要使用下面的这些工具,请在setupMidi()中的talkMIDI(0xC0,number,0)中更改“number”
  59. 1声大钢琴          33声低音          65女高音萨克斯          97雨(FX 1)
  60. 2明亮的声学钢琴     34电子低音(手指)66 Alto Sax             98音轨(FX 2)
  61. 3电钢琴             35电贝司(选)     67男高音萨克斯         99水晶(FX 3)
  62. 4 Honky-tonk钢琴    36 Fretless贝司   68 Baritone Sax       100大气(FX 4)
  63. 5电钢琴1            37巴掌贝斯1        69双簧管                101(Brigthness)(FX 5)
  64. 6电钢琴2              38巴掌贝斯2      70英式号角            102哥布林(FX 6)
  65. 7大键琴             39合成贝司1        71巴松管              103回声(FX 7)
  66. 8 Clavi            40 Synth Bass 2     72 Clarinet         104科幻(FX 8)
  67. 9 Celesta          41小提琴            73 Piccolo          105 Sitar
  68. 10钟琴             42中提琴            74长笛               106班卓琴
  69. 11音乐盒           43大提琴            75录音机             107三味线
  70. 12 Vibraphone      44 Contrabass      76 Pan Flute         108 Koto
  71. 13 Marimba         45 Tremolo Strings  77吹瓶              109 Kalimba
  72. 14木琴             46咀嚼弦             78尺八              110袋
  73. 15管状铃            47管弦竖琴          79哨               111小提琴
  74. 16扬琴             48 Trimpani          80 Ocarina         112 Shanai
  75. 17拉杆风琴         49弦乐组合1           81方形导线(导线1) 113叮当铃
  76. 18打击乐器         50弦合奏2             82锯铅(铅)           114 Agogo
  77. 19 Rock Organ       51合成弦1          83 Calliope(Lead 3)       115倾斜的打击乐器
  78. 20教堂管风琴      52合成弦2            84辛弗铅(铅4)                  116木刻版
  79. 21芦苇器官          53合唱团           85 Charang铅(Lead 5 )       117 Taiko
  80. 22手风琴            54声音             86声线(主角)                118旋律汤姆
  81. 23口琴            55合成音色            87五分之一铅(Lead 7)          119合成鼓
  82. 24探戈手风琴      56管弦乐队打           88低音+铅(铅8)              120反Cy
  83. 25吉他(尼龙)        57小号             89新时代(垫1)              121吉他噪音
  84. 26 Acoutstic吉他(钢)58 Trombone        90暖垫(垫2)               122呼吸噪音
  85. 27电吉他(爵士)      59图巴              91 Polysynth(垫3)        123海滨
  86. 28电吉他(清洁)      60静音小号          92合唱团(垫4)           124鸟鸣叫
  87. 29电吉他(静音)      61法国号角          93鞠躬(Pad 5)           125电话铃声
  88. 30过度驱动吉他        62黄铜部分          94金属(垫6 )            126直升机
  89. 31失真吉他            63合成器黄铜1       95光晕(垫7)             127掌声
  90. 32吉他和声            64合成器黄铜2        96扫描(Pad 8)          128枪声
  91. */
  92. //===============================
  93. // 设置乐器的库talkMIDI(0xB0, 0, 0x00 or 0x78);
  94.   talkMIDI(0xB0,0, 0x78); //鼓
  95.   //talkMIDI(0xB0, 0, 0x00); //电钢
  96. //============================================
  97. // 选择乐器talkMIDI(0xC0, number, 0)
  98.    talkMIDI(0xC0, 0, 0);//鼓
  99.   //talkMIDI(0xC0, 5, 0); //电钢
  100. //=========================  
  101.   // 音量0-127
  102.   talkMIDI(0xB0, 0x07, 100);
  103. }
  104. void loop() {
  105.   currtouched = cap.touched();
  106.   for (uint8_t i=0; i<12; i++) {
  107.     if ((currtouched & _BV(i)) && !(lasttouched & _BV(i)) ) {
  108.       noteOn(0, drums</font></font><font face="微软雅黑"><font size="3">, 127);
  109.       delay(5);
  110.     }
  111.    
  112.     if (!(currtouched & _BV(i)) && (lasttouched & _BV(i)) ) {
  113.    
  114.     }
  115.   }
  116.   lasttouched = currtouched;
  117. }
  118. /*********************************************************
  119. * VS1053 functions
  120. * ******************************************************/
  121. //写入VS10xx寄存器
  122. // SCI:数据传输总是16位。当新的SCI操作进入时
  123. // DREQ变低。那么我们必须等待DREQ再次走高。
  124. // XCS在整个操作过程中应该是低的。
  125. void VSWriteRegister(unsigned char addressbyte, unsigned char highbyte, unsigned char lowbyte) {
  126.   while (!digitalRead(VS_DREQ)) ;
  127. //等待DREQ变高表明IC可用
  128.   digitalWrite(VS_XCS, LOW);
  129.   SPI.transfer(0x02);
  130.   SPI.transfer(addressbyte);
  131.   SPI.transfer(highbyte);
  132.   SPI.transfer(lowbyte);
  133.   while (!digitalRead(VS_DREQ)) ;
  134.   digitalWrite(VS_XCS, HIGH);
  135. }
  136. //将VS10XX放入实时内置MIDI模式的插件
  137. const unsigned short sVS1053b_Realtime_MIDI_Plugin[28] = { /* Compressed plugin */
  138.   0x0007, 0x0001, 0x8050, 0x0006, 0x0014, 0x0030, 0x0715, 0xb080, /*    0 */
  139.   0x3400, 0x0007, 0x9255, 0x3d00, 0x0024, 0x0030, 0x0295, 0x6890, /*    8 */
  140.   0x3400, 0x0030, 0x0495, 0x3d00, 0x0024, 0x2908, 0x4d40, 0x0030, /*   10 */
  141.   0x0200, 0x000a, 0x0001, 0x0050,
  142. };
  143. void VSLoadUserCode(void) {
  144.   int i = 0;
  145.   while (i < sizeof(sVS1053b_Realtime_MIDI_Plugin) / sizeof(sVS1053b_Realtime_MIDI_Plugin[0])) {
  146.     unsigned short addr, n, val;
  147.     addr = sVS1053b_Realtime_MIDI_Plugin[i++];
  148.     n = sVS1053b_Realtime_MIDI_Plugin[i++];
  149.     while (n--) {
  150.       val = sVS1053b_Realtime_MIDI_Plugin[i++];
  151.       VSWriteRegister(addr, val >> 8, val & 0xFF);
  152.     }
  153.   }
  154. }
  155. void sendMIDI(byte data)
  156. {
  157.   SPI.transfer(0);
  158. </font></font><font face="微软雅黑"><font size="3">  SPI.transfer(data);
  159. }
  160. void talkMIDI(byte cmd, byte data1, byte data2) {
  161.   
  162.   while (!digitalRead(VS_DREQ));
  163.   digitalWrite(VS_XDCS, LOW);
  164.   sendMIDI(cmd);
  165.   if ( (cmd & 0xF0) <= 0xB0 || (cmd & 0xF0) >= 0xE0) {
  166.     sendMIDI(data1);
  167.     sendMIDI(data2);
  168.   } else {
  169.     sendMIDI(data1);
  170.   }
  171. }
  172. //发送MIDI音符消息。就像按下钢琴键
  173. //通道范围从0-15
  174. void noteOn(byte channel, byte note, byte attack_velocity) {
  175. talkMIDI( (0x90 | channel), note, attack_velocity);
  176. //talkMIDI( (0xA0 | channel), note, 127);
  177. }
  178. //发送一个MIDI音符消息。就像释放钢琴键一样
  179. void noteOff(byte channel, byte note, byte release_velocity) {
  180.   talkMIDI( (0x80 | channel), note, release_velocity);
  181. }
复制代码
Ada的mpr121库下载https://github.com/adafruit/Adafruit_MPR121
上传完代码后,摸一摸MPR121的12个电极。是不是来声了?

一直没有说用MPR121触摸模块的原因,相信你一定知道MakeyMakey,BareconductiveTouchboard,这两块板,让我们感受到了水果钢琴,导电墨水画的神奇。刚才我们实现了引出12个触摸点并能够赋予它们反馈出不同乐器的声音的能力。接下来了就可以发挥出你的想象力了。
你可以蚀刻一个专属的鼓面贴在木盒上变成随身带着的手指鼓。
2018-03-28 110355.jpg
还可以用导电丝线和布料缝一个钢琴卫衣或T恤。
2018-03-28 110517.jpg
就介绍到这,如果你也正在制作这个小项目,过程中如果有任何问题请及时指出,同时,也希望大家分享更有趣的点子。感谢!

emDT0lIS  1 学徒

发表于 2019-5-23 19:09:46

  1. Arduino:1.8.9 (Windows 7), 开发板:"Arduino/Genuino Uno"
  2. The sketch name had to be modified.
  3. Sketch names must start with a letter or number, followed by letters,
  4. numbers, dashes, dots and underscores. Maximum length is 63 characters.
  5. arduino_mp3:135:7: error: stray '\345' in program
  6.        noteOn(0, drums, 127);
  7.        ^
  8. arduino_mp3:135:7: error: stray '\276' in program
  9. arduino_mp3:135:7: error: stray '\256' in program
  10. arduino_mp3:135:7: error: stray '\350' in program
  11. arduino_mp3:135:7: error: stray '\275' in program
  12. arduino_mp3:135:7: error: stray '\257' in program
  13. arduino_mp3:135:7: error: stray '\351' in program
  14. arduino_mp3:135:7: error: stray '\233' in program
  15. arduino_mp3:135:7: error: stray '\205' in program
  16. arduino_mp3:135:7: error: stray '\351' in program
  17. arduino_mp3:135:7: error: stray '\273' in program
  18. arduino_mp3:135:7: error: stray '\221' in program
  19. arduino_mp3:198:1: error: stray '\345' in program
  20.   SPI.transfer(data);
  21. ^
  22. arduino_mp3:198:1: error: stray '\276' in program
  23. arduino_mp3:198:1: error: stray '\256' in program
  24. arduino_mp3:198:1: error: stray '\350' in program
  25. arduino_mp3:198:1: error: stray '\275' in program
  26. arduino_mp3:198:1: error: stray '\257' in program
  27. arduino_mp3:198:1: error: stray '\351' in program
  28. arduino_mp3:198:1: error: stray '\233' in program
  29. arduino_mp3:198:1: error: stray '\205' in program
  30. arduino_mp3:198:1: error: stray '\351' in program
  31. arduino_mp3:198:1: error: stray '\273' in program
  32. arduino_mp3:198:1: error: stray '\221' in program
  33. C:\Users\Administrator\Desktop\arduino_mp3\arduino_mp3.ino: In function 'void loop()':
  34. arduino_mp3:135:23: error: expected primary-expression before '/' token
  35.        noteOn(0, drums, 127);
  36.                        ^
  37. arduino_mp3:135:24: error: 'size' was not declared in this scope
  38.        noteOn(0, drums, 127);
  39.                         ^
  40. arduino_mp3:135:30: error: expected primary-expression before '/' token
  41.        noteOn(0, drums, 127);
  42.                               ^
  43. arduino_mp3:135:31: error: 'font' was not declared in this scope
  44.        noteOn(0, drums, 127);
  45.                                ^
  46. arduino_mp3:135:54: error: expected primary-expression before ']' token
  47.        noteOn(0, drums, 127);
  48.                                                       ^
  49. C:\Users\Administrator\Desktop\arduino_mp3\arduino_mp3.ino: In function 'void sendMIDI(byte)':
  50. arduino_mp3:198:2: error: expected identifier before '/' token
  51.   SPI.transfer(data);
  52.   ^
  53. C:\Users\Administrator\Desktop\arduino_mp3\arduino_mp3.ino: In lambda function:
  54. arduino_mp3:198:8: error: expected '{' before '[' token
  55.   SPI.transfer(data);
  56.         ^
  57. C:\Users\Administrator\Desktop\arduino_mp3\arduino_mp3.ino: In function 'void sendMIDI(byte)':
  58. arduino_mp3:198:9: error: expected primary-expression before '/' token
  59.   SPI.transfer(data);
  60.          ^
  61. arduino_mp3:198:10: error: 'font' was not declared in this scope
  62.   SPI.transfer(data);
  63.           ^
  64. arduino_mp3:198:33: error: expected primary-expression before ']' token
  65.   SPI.transfer(data);
  66.                                  ^
  67. arduino_mp3:198:35: error: 'size' was not declared in this scope
  68.   SPI.transfer(data);
  69.                                    ^
  70. exit status 1
  71. stray '\345' in program
复制代码


在文件 -> 首选项开启
“编译过程中显示详细输出”选项
这份报告会包含更多信息。

回复

使用道具 举报

robo027  6 初级技匠
 楼主|

发表于 2018-12-8 05:25:59

gada888 发表于 2018-11-25 19:27
连线也有疑问,mpr121的IRQ没连。

这样,你试试把库文件Adafruit_MPR121.cpp中最后那段代码中的括号里加个ture.
  1. /**************************************************************************/
  2. void Adafruit_MPR121::writeRegister(uint8_t reg, uint8_t value) {
  3.     Wire.beginTransmission(_i2caddr);
  4.     Wire.write((uint8_t)reg);
  5.     Wire.write((uint8_t)(value));
  6.     Wire.endTransmission();
  7. }
复制代码

改为
  1. /**************************************************************************/
  2. void Adafruit_MPR121::writeRegister(uint8_t reg, uint8_t value) {
  3.     Wire.beginTransmission(_i2caddr);
  4.     Wire.write((uint8_t)reg);
  5.     Wire.write((uint8_t)(value));
  6.     Wire.endTransmission(true);
  7. }
复制代码

再试试,如果成功记得回来告诉我.
回复

使用道具 举报

robo027  6 初级技匠
 楼主|

发表于 2019-1-17 09:57:42

羁绊 发表于 2018-12-24 09:34
请问这个怎么实现按住键 像钢琴那样发声,求指导。。。。

我代码里面包含一套鼓的和钢琴的, 需要自己手动换下,另外我这个是发送的MIDI协议,它与调用内置的MP3文件来播放的方式有本质的区别,它可以同时按多个按键,并且能够用按下的时间来给予不同的声音深度的,基本上是模拟钢琴的效果的.\
回复

使用道具 举报

rzyzzxw  版主

发表于 2018-3-28 19:46:34

这个好厉you害qu。
回复

使用道具 举报

Yuan  1 学徒

发表于 2018-4-2 11:11:31

nice,我试试
回复

使用道具 举报

代花轮  1 学徒

发表于 2018-4-19 17:02:12

我也试试
回复

使用道具 举报

robo027  6 初级技匠
 楼主|

发表于 2018-4-20 22:47:10

大家都成功了吗?
回复

使用道具 举报

铁熊  9 初级技神

发表于 2018-4-21 13:03:51

本帖最后由 铁熊 于 2018-4-21 16:45 编辑

我试了下,稳定性不是很高,有时会有音乐,有时没有,难道跟我淘宝买的元器件有关?
回复

使用道具 举报

robo027  6 初级技匠
 楼主|

发表于 2018-4-26 11:28:33

铁熊 发表于 2018-4-21 13:03
我试了下,稳定性不是很高,有时会有音乐,有时没有,难道跟我淘宝买的元器件有关? ...

主要体现在哪里?看你能不能发一下你的图片。我帮你看看。
回复

使用道具 举报

杯杯心里苦  2 见习技师

发表于 2018-11-7 16:26:43

接好后用耳机接进去听不到声音,一定要用音响吗?
回复

使用道具 举报

沐阳心  1 学徒

发表于 2018-11-15 22:25:46

我是个新手,刚接触这方面,现在我也想做一个,那个程序是直接用这个还是去那个网址上下载,下载的话下哪一个
回复

使用道具 举报

robo027  6 初级技匠
 楼主|

发表于 2018-11-18 01:51:26

沐阳心 发表于 2018-11-15 22:25
我是个新手,刚接触这方面,现在我也想做一个,那个程序是直接用这个还是去那个网址上下载,下载的话下哪一 ...

您的意思是?
回复

使用道具 举报

DFHJwIPhCT7  1 学徒 来自手机

发表于 2018-11-19 20:47:03

robo027 发表于 2018-3-28 11:24
网络上你可以看到很多牛人,用身体的某些部位或是各种物体或演奏出音乐。
    你可能看过这个    这个
...

这个触摸没反应 是什么原因
回复

使用道具 举报

Utwhhobd  1 学徒

发表于 2018-11-22 21:21:55

robo027 发表于 2018-4-20 22:47
大家都成功了吗?

我们有问题 您能帮我们解决一下吗
回复

使用道具 举报

苏格小麦嘤  1 学徒

发表于 2018-11-22 22:46:00

新手求问一下为什么我的没有反应。。。。QAQQQQQQ
回复

使用道具 举报

robo027  6 初级技匠
 楼主|

发表于 2018-11-24 02:01:11

我刚才又试了一次 完全没问题啊!可否提供连线的图我看看
回复

使用道具 举报

苏格小麦嘤  1 学徒

发表于 2018-11-24 17:22:55

完全不知道哪里错了。。。
截图201811241721235166.png
截图201811241721565921.png
回复

使用道具 举报

gada888  版主

发表于 2018-11-24 18:29:02

不错不错
回复

使用道具 举报

gada888  版主

发表于 2018-11-24 18:31:53

各位给大家提个醒,这个就是adafruit的mp3库样例和MPR121样例的结合。
回复

使用道具 举报

gada888  版主

发表于 2018-11-24 18:32:25

问题是在程序。我现在忙,有空会去调下那个程序
回复

使用道具 举报

DFHJwIPhCT7  1 学徒

发表于 2018-11-24 21:02:05

gada888 发表于 2018-11-24 18:32
问题是在程序。我现在忙,有空会去调下那个程序

调完那个代码可以发一下吗 我的也是连接没问题但是出来的声音12种都是一样的
回复

使用道具 举报

Utwhhobd  1 学徒

发表于 2018-11-24 21:59:40

robo027 发表于 2018-11-24 02:01
我刚才又试了一次 完全没问题啊!可否提供连线的图我看看

十二个触摸点的声音都是一样的
回复

使用道具 举报

gada888  版主

发表于 2018-11-25 19:27:00

你要用那个耳机插孔做外放,或者连喇叭。‘’十二个触摸点的声音都是一样的‘’那是正常的,因为没有从程序里看到对每一个电极点的定义。
回复

使用道具 举报

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

本版积分规则

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

硬件清单

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

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

mail