party神器~Processing&Arduino音乐LED

2016-01-146.9万
精华项目
AI 快速预览详细 收起
音乐LED项目通过Processing和Arduino实现,利用Processing的minim库分析音频,并通过Serial将处理好的数据传给Arduino,控制LED灯随音乐节奏闪烁。项目包括音频分析、数据处理和LED显示三个主要步骤。最终效果是LED灯能够根据音乐节奏变化,支持多首歌曲切换和键盘控制。
Processing&Arduino音乐LED
好像大家都陆陆续续开始放假了呢(虽然楼主只有一周就要开学了 泪目),要不要请朋友来家里聚一聚?想不想让聚会更加高大上?今天这个音乐LED可以随着电脑播放的歌曲闪烁,让你的party更加炫酷,只需一个按键就可以让你的客厅开启club模式!你还可以通过键盘的空格键、上下按键和退出键实现播放/暂停、切歌以及退出的功能。
party神器~Processing&Arduino音乐LED图2


一定要开声音!先来看一下效果吧(结尾有彩蛋)~如果在黑暗环境里效果会更好,然而我并不能把办公室的灯全关了> <



这个效果主要是依靠processing实现的:利用processing的minim库分析音频,在通过Serial将处理好的数据传给Arduino,Arduino只要负责把收到的数据显示在led上就可以了。下面给大家分步再现一下做这个项目的过程。


[下载并安装processing]

“Processing是一种具有革命前瞻性的新兴计算机语言,它的概念是在电子艺术的环境下介绍程序语言,并将电子艺术的概念介绍给程序设计师。它是Java 语言的延伸,并支持许多现有的 Java 语言架构,不过在语法 (syntax) 上简易许多,并具有许多贴心及人性化的设计。Processing 可以在 Windows、MACOS X、MAC OS 9 、Linux 等操作系统上使用。目前最新版本为Processing 3。以 Processing 完成的作品可在个人本机端作用,或以Java Applets 的模式外输至网络上发布。” ——度娘





[分析音频]

首先需要下载minim库。processing的库可以直接从编辑器中下载。速写本->引用库文件 -> 添加库文件,搜索minim,下载。

最基本的代码源自https://github.com/blyk/Music-Visualization/blob/master/MusicViz.pde, 删除了一些我们不需要的数据之后是这样滴,这也是最后视频中电脑界面效果的代码:
  1. import ddf.minim.*;
  2. import ddf.minim.analysis.*;
  3. Minim minim;
  4. AudioPlayer player;
  5. AudioMetaData meta;
  6. BeatDetect beat;
  7. int  r = 200;
  8. void setup()
  9. {
  10.   size(displayWidth, displayHeight);
  11.   minim = new Minim(this);
  12.   //change the address to your file
  13.   player = minim.loadFile("D:/Cisum/Ragni MMS 2/Baby Doll - Ragini MMS 2 - [SongsPk.CC].mp3");
  14.   meta = player.getMetaData();
  15.   beat = new BeatDetect();
  16.   player.play();
  17.   background(-1);
  18.   noCursor();
  19. }
  20. void draw()
  21. {
  22.   beat.detect(player.mix);
  23.   fill(#1A1F18, 20);
  24.   noStroke();
  25.   rect(0, 0, width, height);
  26.   translate(width/2, height/2);
  27.   noFill();
  28.   fill(-1, 10);
  29.   stroke(-1, 50);
  30.   int bsize = player.bufferSize();
  31.   for (int i = 0; i < bsize - 1; i+=5)
  32.   {
  33.     float x = (r)*cos(i*2*PI/bsize);
  34.     float y = (r)*sin(i*2*PI/bsize);
  35.     float x2 = (r + player.left.get(i)*100)*cos(i*2*PI/bsize);
  36.     float y2 = (r + player.left.get(i)*100)*sin(i*2*PI/bsize);
  37.     line(x, y, x2, y2);
  38.   }
  39.   beginShape();
  40.   noFill();
  41.   stroke(-1, 50);
  42.   for (int i = 0; i < bsize; i+=30)
  43.   {
  44.     float x2 = (r + player.left.get(i)*100)*cos(i*2*PI/bsize);
  45.     float y2 = (r + player.left.get(i)*100)*sin(i*2*PI/bsize);
  46.     vertex(x2, y2);
  47.     pushStyle();
  48.     stroke(-1);
  49.     strokeWeight(2);
  50.     point(x2, y2);
  51.     popStyle();
  52.   }
  53.   endShape();
  54. }
复制代码


[处理数据]

将1024分别按照灯环的LED数量分成12、16、24份,并应用player.left.get()读取缓冲区里的值,这个值是介于-1到1之间,然而在这里我们只需要整数,原因会在下个步骤中详述。
  1. for (int i = 0; i < 12; i++)
  2.   {
  3.     int x = int(players.left.get(i*ring3)*average);
  4.     if (x < 0) x = -x;
  5.     if (x > 100) x = 100;
  6.     rings[i] = x;
  7.   }
  8.   for (int i = 12; i < 28; i++)
  9.   {
  10.     int x = int(players.right.get((i-12)*ring4)*average);
  11.     if (x < 0) x = -x;
  12.     if (x < 40) x = 0;
  13.     else x = x - 40;
  14.     if (x > 100) x = 60;
  15.     rings[i] = x;
  16.   }
  17.   for (int i = 28; i < 52; i++)
  18.   {
  19.     int x = int(players.left.get((i-28)*ring5)*average);
  20.     if (x < 0) x = -x;
  21.     if (x < 90) x = 0;
  22.     else x = x - 90;
  23.     if (x > 100) x = 10;
  24.     rings[i] = x;
  25.   }
复制代码



[传给Arduino]

Processing和arduino的交互主要有两种方法,一种是Serial,一种是Firmata。Firmata更适用于少量数据的交互,更适用于在arduino里没有引用库文件的情况。只需要给arduino烧录standard firmata这个程序,在processing端引用arduino库,就可以直接控制arduino了。而这个音乐led用的是Serial,就是通过串口在processing端用write()输出数据,用read()读取数据。Arduino连接在电脑不同的端口上,StringportName = Serial.list()[0]中的“0”也要根据端口进行变化,可以把整个Serial.list()[]都打印出来找到自己需要的那一个。Serial只可以传整数,所以在上一个步骤中进行了int x =int(players.right.get((i-12)*ring4)*average);取整处理。经过测试发现发出的数据和接收的数据之间有错位的现象所以增加了数列中第53个数:rings[52] = 255;用来矫正。
  1. import processing.serial.*;
  2. Serial myport;
  3. void setup(){
  4. String portName = Serial.list()[0];
  5. myport = new Serial(this, portName, 9600);
  6. }
  7. void draw(){
  8.   rings[52] = 255;
  9.   for (int i = 0; i < 53; i++) {
  10.     myport.write(rings[i]);
  11.   }
  12. }
复制代码


[接收并显示数据]
引用三个库用来控制灯环上led的亮度以及颜色,用ring[]来储存接收到的数据,用255/200=1.275用来校准。采用hsb的色彩模式,三个参数分别为色相,饱和度以及亮度,色相在0-360之间渐变,收到的数据用来调整亮度
  1. #include <Adafruit_NeoPixel.h>//the library can be found at https://github.com/adafruit/Adafruit_NeoPixel
  2. #include <DFRobot_utility.h>
  3. #include <Metro.h>
  4. #define PIN3 10
  5. #define PIN4 9
  6. #define PIN5 8
  7. Adafruit_NeoPixel round3 = Adafruit_NeoPixel(12, PIN3, NEO_GRB + NEO_KHZ800);
  8. Adafruit_NeoPixel round4 = Adafruit_NeoPixel(16, PIN4, NEO_GRB + NEO_KHZ800);
  9. Adafruit_NeoPixel round5 = Adafruit_NeoPixel(24, PIN5, NEO_GRB + NEO_KHZ800);
  10. float ring[53];
  11. int color = 0;
  12. void setup() {
  13.   // put your setup code here, to run once:
  14.   Serial.begin(9600);
  15.   round3.begin();
  16.   round4.begin();
  17.   round5.begin();
  18.   for (int j = 0; j < 52; j++) {
  19.     ring[j] = 0;
  20.   }
  21.   round3.show();
  22.   round4.show();
  23.   round5.show();
  24. }
  25. void loop() {
  26.   // put your main code here, to run repeatedly:
  27.   if (Serial.available()) {
  28.     if (color == 360) color = 0;
  29.     static int i = 0;
  30.    
  31.     if (i == 52) i = 0;
  32.    
  33.     ring[i] = Serial.read();
  34.     ring[i] = ring[i]/200;
  35.     if (ring[i] == 1.275) {
  36.       ring[52] = 1.275;
  37.       i = 0;
  38.       return;
  39.     }
  40.     if (i < 12) {
  41.       round3.setPixelColor(i, hsbToColor (color, 1, ring[i]));
  42.     } else if (i < 28) {
  43.       round4.setPixelColor(i - 12, hsbToColor (color, 1, ring[i]));
  44.     } else if (i < 52){
  45.       round5.setPixelColor(i - 28, hsbToColor (color, 1, ring[i]));
  46.     }
  47.     if (i == 12) round3.show();
  48.     if (i == 28) round4.show();
  49.     if (i == 51) {
  50.       round5.show();
  51.       color += 5;
  52.     }
  53.     i ++;
  54.   }
  55. }
复制代码
[添加播放器功能,多首歌曲]

主要是把之前的主要功能提出来,写成一个function,再加上void keyPressed()读取键盘的输入。
  1. AudioPlayer players;
  2. AudioPlayer player;
  3. AudioPlayer player1;
  4. int playernum=0;
  5. void setup(){
  6.   player = minim.loadFile("I Really Like You.mp3", 1024);
  7.   player1 = minim.loadFile("TFBOYS.mp3", 1024);
  8. }
  9. void draw(){
  10.   switch (playernum) {
  11.   case 0:
  12.     drawLED (player);
  13.     break;
  14.   case 1:
  15.     drawLED (player1);
  16.     break;
  17.   }
  18. }
  19. void keyPressed() {
  20.   if (key==ESC) {
  21.     myport.write(255);
  22.     exit();
  23.   }
  24.   if (key == ' ') {
  25.     if (pause) pause = false;
  26.     else pause = true;
  27.   }
  28.   if (key == CODED) {
  29.     if (keyCode == DOWN) {
  30.       pause();
  31.       playernum ++;
  32.     }
  33.     if (keyCode == UP) {
  34.       pause();
  35.       playernum --;
  36.     }
  37.   }
  38. }
  39. void pause() {
  40.   switch (playernum) {
  41.   case 0:
  42.     player.pause();
  43.     break;
  44.   case 1:
  45.     player1.pause();
  46.     break;
  47.   }
  48. }
  49. void drawLED(AudioPlayer players) {
  50. ……
  51. }
复制代码

程序都是一部分一部分介绍的,可能会有些小遗落,完整版的在这里:






libraries.rar

62.16 KB, 下载次数: 21932

创作许可协议

本项目采用 None(不开放任何权利,保留所有权利) 进行许可。

评论(32)
JOVI
JOVI
学习学习
诩
赞一个
gray6666
gray6666
炫酷的黑科技。。。。。。。。。。。。。。
KHtUnGcu
KHtUnGcu
学习一下
别问问就是一定有书读
别问问就是一定有书读
你好,请问ring3 ring4 ring5参数是在哪里设置的 是什么意思?初学者不太理解
神奇海螺
神奇海螺
好看呀,学习了
神奇海螺
神奇海螺
好看呀,学习了
gray6666
gray6666
很赞的创意,可惜processing没进入信息技术课改的大纲中
gada888
gada888
这个厉害呀。一直想好好学processing。苦于不得法。
请别输入昵称
请别输入昵称
当然要看看
MhEi264B
MhEi264B
666
雅比斯
雅比斯
楼主真是大好人啊!不过我刚刚接触arduino所以还是有一些不懂的地方先请教楼主。
把libraries压缩包里的文件拷贝到arduino-libraries里,然后把转给arduino的那些代码复制并烧录到arduino里面就可以了是吗?谢谢
SAW
SAW
彩蛋超级意外洗脑,装置很酷啊!!!
13250621216
13250621216
小白求解,怎么接单个RGBLED,没反应,一定要灯带???
13250621216
13250621216回复qq215104863549
好的,非常感谢你的回复和建议,库看不太懂,我去琢磨琢磨
qq215104863549
qq215104863549回复13250621216
因为有灯带的库文件,而一个RGB自己写写吧
萝卜
萝卜
请问这个RGB灯环是级联的吗?
qq215104863549
qq215104863549回复萝卜
这个就一条1米的灯带
yoyojacky
yoyojacky
这个有意思,可以试试,哈哈穿戴设备。
qq215104863549
qq215104863549
这是最后完整的,3D打印的,自己建的模
qq215104863549
qq215104863549
我已经把这个随音乐闪灯和时钟融合在一起了,哈哈哈
AdaZhao
AdaZhao
作者
回复qq215104863549
cool 壳子自己做的吗 用什么做的啊
qq215104863549
qq215104863549

nxcosa
nxcosa
这个好赞!!!!被最后的歌洗脑了
AdaZhao
AdaZhao
作者
回复nxcosa
啊 对的 就是要这个效果hhh