查看: 7047|回复: 17

【音乐项目】触摸竖琴

[复制链接]
本帖最后由 iooops 于 2016-4-1 00:09 编辑

这个项目的诞生来源其实是这样的:
近半年以来楼主从各方面接触了一下makeymakey,然后发现makeymakey好则好矣,就是还是要依赖电脑(操作系统),不能以特别独立的方式给人玩耍。
然后楼主恰巧在蘑菇云激光切割的余料里发现了一块好用的板子,正好又在附近的五金店买到了细钢丝,就心想做个触摸竖琴好了~~ 又想起半年前乐乐曾经给过我一段仅用导线实现触摸传感器的代码,于是这个小制作项目就这么速度地开展下来了~~~


【材料清单】
Arduino开发板
细钢丝 X 10
DFPlayer Mini 播放器模块 X 1
SD卡
小喇叭 X 1
导线若干

【制作过程】
IMG_20160331_222143.jpg
1. 把钢丝剪到合适的尺寸,然后分别黏上去。
2. 把钢丝连上导线。
3. 把导线连上Arduino。
4. 做测试。代码如下:
  1. int ledPin = 13;
  2. int capval;
  3. void setup()
  4. {
  5. pinMode(ledPin, OUTPUT);
  6. Serial.begin(9600);
  7. Serial.println("Touch senser");
  8. }

  9. void loop ()
  10. {
  11. digitalWrite(ledPin,LOW);
  12. capval = readCapacitivePin(6);    //各个引脚都尝试一下
  13. Serial.println(capval, DEC);
  14. if (capval > 2) {
  15. // turn LED on:
  16. digitalWrite(ledPin, HIGH);          // 如果该引脚有反应的话,Arduino上的13号灯会亮
  17. delay(10);
  18. }
  19. }

  20. uint8_t readCapacitivePin(int pinToMeasure) {
  21. // Variables used to translate from Arduino to AVR pin naming
  22. volatile uint8_t* port;
  23. volatile uint8_t* ddr;
  24. volatile uint8_t* pin;
  25. // Here we translate the input pin number from
  26. // Arduino pin number to the AVR PORT, PIN, DDR,
  27. // and which bit of those registers we care about.
  28. byte bitmask;
  29. port = portOutputRegister(digitalPinToPort(pinToMeasure));
  30. ddr = portModeRegister(digitalPinToPort(pinToMeasure));
  31. bitmask = digitalPinToBitMask(pinToMeasure);
  32. pin = portInputRegister(digitalPinToPort(pinToMeasure));
  33. // Discharge the pin first by setting it low and output
  34. *port &= ~(bitmask);
  35. *ddr |= bitmask;
  36. delay(1);
  37. // Make the pin an input with the internal pull-up on
  38. *ddr &= ~(bitmask);
  39. *port |= bitmask;

  40. // Now see how long the pin to get pulled up. This manual unrolling of the loop
  41. // decreases the number of hardware cycles between each read of the pin,
  42. // thus increasing sensitivity.
  43. uint8_t cycles = 17;
  44. if (*pin & bitmask) { cycles = 0;}
  45. else if (*pin & bitmask) { cycles = 1;}
  46. else if (*pin & bitmask) { cycles = 2;}
  47. else if (*pin & bitmask) { cycles = 3;}
  48. else if (*pin & bitmask) { cycles = 4;}
  49. else if (*pin & bitmask) { cycles = 5;}
  50. else if (*pin & bitmask) { cycles = 6;}
  51. else if (*pin & bitmask) { cycles = 7;}
  52. else if (*pin & bitmask) { cycles = 8;}
  53. else if (*pin & bitmask) { cycles = 9;}
  54. else if (*pin & bitmask) { cycles = 10;}
  55. else if (*pin & bitmask) { cycles = 11;}
  56. else if (*pin & bitmask) { cycles = 12;}
  57. else if (*pin & bitmask) { cycles = 13;}
  58. else if (*pin & bitmask) { cycles = 14;}
  59. else if (*pin & bitmask) { cycles = 15;}
  60. else if (*pin & bitmask) { cycles = 16;}

  61. // Discharge the pin again by setting it low and output
  62. // It's important to leave the pins low if you want to
  63. // be able to touch more than 1 sensor at a time - if
  64. // the sensor is left pulled high, when you touch
  65. // two sensors, your body will transfer the charge between
  66. // sensors.
  67. *port &= ~(bitmask);
  68. *ddr |= bitmask;

  69. return cycles;
  70. }
复制代码
  楼主测试下来发现,2、3、4、5、8、9、10、11是能用的。
5. 接DF mini player模块和小喇叭,如下所示

6. 把准备好的音乐放入SD卡,注意格式,楼主发现用wav文件好像还不行,得用MP3。
问 :SD卡中的文件和文件夹名字有什么格式要求吗?

    答:函数mp3_play (1); 播放文件的格式为"0001***.mp3(或支持其他格式)". 您可能需要注意这些:

(1). 该音频文件的名称应该命名一个四位数字开始,如:

    0001.mp3
    0002Chasing The Sun.mp3
    0003.mp3
    0004Try.mp3
    0010FourFiveSeconds.mp3


(2).该音频文件应该放在“MP3”'它坐落在TF卡的根目录'文件夹;

7. 安装Arduino的DFPlayer_Mini MP3库
(上述两个步骤详细内容查阅DFPlayer Mini WIKI - - 这链接死活传不上来啊你们看着办吧直接在产品资料库里面搜就行
8. 在Arduino文件中把每根钢丝触摸开关对应到不同的MP3文件。

  1. #include <SoftwareSerial.h>
  2. #include <DFPlayer_Mini_Mp3.h>

  3. int ledPin = 13;
  4. int capval[8];

  5. void setup() {
  6.   Serial.begin(9600);
  7.   mp3_set_serial (Serial);  //set Serial for DFPlayer-mini mp3 module
  8.   delay(1);  //wait 1ms for mp3 module to set volume
  9.   mp3_set_volume (30);
  10.   
  11.   pinMode(ledPin, OUTPUT);
  12.   mp3_play (1);
  13. }

  14. void loop () {
  15.   digitalWrite(ledPin,LOW);
  16.   capval[0] = readCapacitivePin(2);
  17.   capval[1] = readCapacitivePin(3);
  18.   capval[2] = readCapacitivePin(4);
  19.   capval[3] = readCapacitivePin(5);
  20.   capval[4] = readCapacitivePin(8);
  21.   capval[5] = readCapacitivePin(9);
  22.   capval[6] = readCapacitivePin(10);
  23.   capval[7] = readCapacitivePin(11);
  24.   Serial.println(capval[0], DEC);
  25.   if (capval[0] > 2) {
  26.     mp3_play (2);
  27.     delay(100);
  28.   }
  29.   if (capval[1] > 2) {
  30.     mp3_play (3);
  31.     delay(100);
  32.   }  
  33.   if (capval[2] > 2) {
  34.     mp3_play (4);
  35.     delay(100);
  36.   }
  37.   if (capval[3] > 2) {
  38.     mp3_play (5);
  39.     delay(100);
  40.   }
  41.   if (capval[4] > 2) {
  42.     mp3_play (6);
  43.     delay(100);
  44.   }
  45.   if (capval[5] > 2) {
  46.     mp3_play (7);
  47.     delay(100);
  48.   }
  49.   if (capval[6] > 2) {
  50.     mp3_play (8);
  51.     delay(100);
  52.   }
  53.   if (capval[7] > 2) {
  54.     mp3_play (1);
  55.     delay(1000);
  56.   }
  57. }

  58. uint8_t readCapacitivePin(int pinToMeasure) {
  59.   // Variables used to translate from Arduino to AVR pin naming
  60.   volatile uint8_t* port;
  61.   volatile uint8_t* ddr;
  62.   volatile uint8_t* pin;
  63.   // Here we translate the input pin number from
  64.   // Arduino pin number to the AVR PORT, PIN, DDR,
  65.   // and which bit of those registers we care about.
  66.   byte bitmask;
  67.   port = portOutputRegister(digitalPinToPort(pinToMeasure));
  68.   ddr = portModeRegister(digitalPinToPort(pinToMeasure));
  69.   bitmask = digitalPinToBitMask(pinToMeasure);
  70.   pin = portInputRegister(digitalPinToPort(pinToMeasure));
  71.   // Discharge the pin first by setting it low and output
  72.   *port &= ~(bitmask);
  73.   *ddr |= bitmask;
  74.   delay(1);
  75.   // Make the pin an input with the internal pull-up on
  76.   *ddr &= ~(bitmask);
  77.   *port |= bitmask;

  78.   // Now see how long the pin to get pulled up. This manual unrolling of the loop
  79.   // decreases the number of hardware cycles between each read of the pin,
  80.   // thus increasing sensitivity.
  81.   uint8_t cycles = 17;
  82.   if (*pin & bitmask) { cycles = 0;}
  83.   else if (*pin & bitmask) { cycles = 1;}
  84.   else if (*pin & bitmask) { cycles = 2;}
  85.   else if (*pin & bitmask) { cycles = 3;}
  86.   else if (*pin & bitmask) { cycles = 4;}
  87.   else if (*pin & bitmask) { cycles = 5;}
  88.   else if (*pin & bitmask) { cycles = 6;}
  89.   else if (*pin & bitmask) { cycles = 7;}
  90.   else if (*pin & bitmask) { cycles = 8;}
  91.   else if (*pin & bitmask) { cycles = 9;}
  92.   else if (*pin & bitmask) { cycles = 10;}
  93.   else if (*pin & bitmask) { cycles = 11;}
  94.   else if (*pin & bitmask) { cycles = 12;}
  95.   else if (*pin & bitmask) { cycles = 13;}
  96.   else if (*pin & bitmask) { cycles = 14;}
  97.   else if (*pin & bitmask) { cycles = 15;}
  98.   else if (*pin & bitmask) { cycles = 16;}

  99.   // Discharge the pin again by setting it low and output
  100.   // It's important to leave the pins low if you want to
  101.   // be able to touch more than 1 sensor at a time - i
  102.   // the sensor is left pulled high, when you touch
  103.   // two sensors, your body will transfer the charge between
  104.   // sensors.
  105.   *port &= ~(bitmask);
  106.   *ddr |= bitmask;

  107.   return cycles;
  108. }
复制代码

OK!大功告成!!







其实它最后应该是这样玩的(哎呀手不够拍了 - - ):
IMG_20160331_232227.jpg




【制作心得】
楼主表示应该去买个好点的功放和喇叭 - - 这夜晚打更的喇叭效果实在是有点呵呵……



参考:
用arduino直接检测电容值:http://www.geek-workshop.com/thread-3335-1-1.html
DFPlayer Mini WIKI

hnyzcj  版主

发表于 2016-4-1 08:58:34

哈哈,不错不错
回复

使用道具 举报

大连林海  初级技神

发表于 2016-4-1 09:57:01

有时间做一个
回复

使用道具 举报

iooops  中级技匠
 楼主|

发表于 2016-4-1 10:42:25

hnyzcj 发表于 2016-4-1 08:58
哈哈,不错不错

回复

使用道具 举报

dsweiliang  初级技神

发表于 2016-4-1 17:51:12

弦改造成激光的就更炫酷了
回复

使用道具 举报

iooops  中级技匠
 楼主|

发表于 2016-4-1 21:33:28

dsweiliang 发表于 2016-4-1 17:51
弦改造成激光的就更炫酷了

激光的 - - 怎么改
回复

使用道具 举报

dsweiliang  初级技神

发表于 2016-4-2 08:36:54

iooops 发表于 2016-4-1 21:33
激光的 - - 怎么改

把钢丝触摸开关改成光电开关
回复

使用道具 举报

iooops  中级技匠
 楼主|

发表于 2016-4-2 13:30:25

dsweiliang 发表于 2016-4-2 08:36
把钢丝触摸开关改成光电开关

给个淘宝链接 - -
回复

使用道具 举报

hnyzcj  版主

发表于 2016-4-9 10:34:51

我想到当年的六指情魔
回复

使用道具 举报

tzlzy  中级技师

发表于 2016-4-10 15:44:37

一统江湖~~
回复

使用道具 举报

iooops  中级技匠
 楼主|

发表于 2016-4-10 21:56:53


你让我想到了统一方便面 - -
回复

使用道具 举报

zhengx84  见习技师

发表于 2016-6-12 16:09:37

大神啊
回复

使用道具 举报

iooops  中级技匠
 楼主|

发表于 2016-6-20 14:29:44

回复

使用道具 举报

我爱宋富珍  初级技师

发表于 2017-5-16 03:48:53

dsweiliang 发表于 2016-4-1 17:51
弦改造成激光的就更炫酷了

请问代码怎么改还有怎么连线
回复

使用道具 举报

lisper  中级技匠

发表于 2017-5-17 17:36:07

厉害啊!
回复

使用道具 举报

我爱宋富珍  初级技师

发表于 2017-6-14 14:38:45

楼主为什么我只检测到一个口可以用,请问这是为什么?
回复

使用道具 举报

iooops  中级技匠
 楼主|

发表于 2017-6-26 03:10:01

我爱宋富珍 发表于 2017-6-14 14:38
楼主为什么我只检测到一个口可以用,请问这是为什么?

= = 你用的是细钢丝吗
可以看一下Arduino的数值
回复

使用道具 举报

我爱宋富珍  初级技师

发表于 2017-6-28 10:40:55

iooops 发表于 2017-6-26 03:10
= = 你用的是细钢丝吗
可以看一下Arduino的数值

对啊我拆了一把伞,但是灯就亮了一下
回复

使用道具 举报

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

本版积分规则

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

硬件清单

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

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

mail