AdaZhao 发表于 2016-1-14 19:20:58

party神器~Processing&Arduino音乐LED

Processing&Arduino音乐LED好像大家都陆陆续续开始放假了呢(虽然楼主只有一周就要开学了 泪目),要不要请朋友来家里聚一聚?想不想让聚会更加高大上?今天这个音乐LED可以随着电脑播放的歌曲闪烁,让你的party更加炫酷,只需一个按键就可以让你的客厅开启club模式!你还可以通过键盘的空格键、上下按键和退出键实现播放/暂停、切歌以及退出的功能。

一定要开声音!先来看一下效果吧(结尾有彩蛋)~如果在黑暗环境里效果会更好,然而我并不能把办公室的灯全关了> <https://v.qq.com/page/f/4/7/f01809ckb47.html


这个效果主要是依靠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 的模式外输至网络上发布。” ——度娘
官网:https://processing.org/
下载:https://processing.org/download/


[分析音频]
首先需要下载minim库。processing的库可以直接从编辑器中下载。速写本->引用库文件 -> 添加库文件,搜索minim,下载。
最基本的代码源自https://github.com/blyk/Music-Visualization/blob/master/MusicViz.pde, 删除了一些我们不需要的数据之后是这样滴,这也是最后视频中电脑界面效果的代码:import ddf.minim.*;
import ddf.minim.analysis.*;

Minim minim;
AudioPlayer player;
AudioMetaData meta;
BeatDetect beat;
intr = 200;
void setup()
{
size(displayWidth, displayHeight);
minim = new Minim(this);
//change the address to your file
player = minim.loadFile("D:/Cisum/Ragni MMS 2/Baby Doll - Ragini MMS 2 - .mp3");
meta = player.getMetaData();
beat = new BeatDetect();
player.play();
background(-1);
noCursor();
}

void draw()
{
beat.detect(player.mix);
fill(#1A1F18, 20);
noStroke();
rect(0, 0, width, height);
translate(width/2, height/2);
noFill();
fill(-1, 10);
stroke(-1, 50);
int bsize = player.bufferSize();
for (int i = 0; i < bsize - 1; i+=5)
{
    float x = (r)*cos(i*2*PI/bsize);
    float y = (r)*sin(i*2*PI/bsize);
    float x2 = (r + player.left.get(i)*100)*cos(i*2*PI/bsize);
    float y2 = (r + player.left.get(i)*100)*sin(i*2*PI/bsize);
    line(x, y, x2, y2);
}
beginShape();
noFill();
stroke(-1, 50);
for (int i = 0; i < bsize; i+=30)
{
    float x2 = (r + player.left.get(i)*100)*cos(i*2*PI/bsize);
    float y2 = (r + player.left.get(i)*100)*sin(i*2*PI/bsize);
    vertex(x2, y2);
    pushStyle();
    stroke(-1);
    strokeWeight(2);
    point(x2, y2);
    popStyle();
}
endShape();
}


[处理数据]
将1024分别按照灯环的LED数量分成12、16、24份,并应用player.left.get()读取缓冲区里的值,这个值是介于-1到1之间,然而在这里我们只需要整数,原因会在下个步骤中详述。for (int i = 0; i < 12; i++)
{
    int x = int(players.left.get(i*ring3)*average);
    if (x < 0) x = -x;
    if (x > 100) x = 100;
    rings = x;
}

for (int i = 12; i < 28; i++)
{
    int x = int(players.right.get((i-12)*ring4)*average);
    if (x < 0) x = -x;
    if (x < 40) x = 0;
    else x = x - 40;
    if (x > 100) x = 60;
    rings = x;
}

for (int i = 28; i < 52; i++)
{
    int x = int(players.left.get((i-28)*ring5)*average);
    if (x < 0) x = -x;
    if (x < 90) x = 0;
    else x = x - 90;
    if (x > 100) x = 10;
    rings = x;
}



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

void draw(){
rings = 255;
for (int i = 0; i < 53; i++) {
    myport.write(rings);
}
}


[接收并显示数据]引用三个库用来控制灯环上led的亮度以及颜色,用ring[]来储存接收到的数据,用255/200=1.275用来校准。采用hsb的色彩模式,三个参数分别为色相,饱和度以及亮度,色相在0-360之间渐变,收到的数据用来调整亮度#include <Adafruit_NeoPixel.h>//the library can be found at https://github.com/adafruit/Adafruit_NeoPixel
#include <DFRobot_utility.h>
#include <Metro.h>

#define PIN3 10
#define PIN4 9
#define PIN5 8

Adafruit_NeoPixel round3 = Adafruit_NeoPixel(12, PIN3, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel round4 = Adafruit_NeoPixel(16, PIN4, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel round5 = Adafruit_NeoPixel(24, PIN5, NEO_GRB + NEO_KHZ800);

float ring;
int color = 0;

void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
round3.begin();
round4.begin();
round5.begin();
for (int j = 0; j < 52; j++) {
    ring = 0;
}
round3.show();
round4.show();
round5.show();
}

void loop() {
// put your main code here, to run repeatedly:
if (Serial.available()) {
    if (color == 360) color = 0;
    static int i = 0;
   
    if (i == 52) i = 0;
   
    ring = Serial.read();
    ring = ring/200;
    if (ring == 1.275) {
      ring = 1.275;
      i = 0;
      return;
    }
    if (i < 12) {
      round3.setPixelColor(i, hsbToColor (color, 1, ring));
    } else if (i < 28) {
      round4.setPixelColor(i - 12, hsbToColor (color, 1, ring));
    } else if (i < 52){
      round5.setPixelColor(i - 28, hsbToColor (color, 1, ring));
    }
    if (i == 12) round3.show();
    if (i == 28) round4.show();
    if (i == 51) {
      round5.show();
      color += 5;
    }
    i ++;
}
}
[添加播放器功能,多首歌曲]
主要是把之前的主要功能提出来,写成一个function,再加上void keyPressed()读取键盘的输入。AudioPlayer players;
AudioPlayer player;
AudioPlayer player1;
int playernum=0;
void setup(){
player = minim.loadFile("I Really Like You.mp3", 1024);
player1 = minim.loadFile("TFBOYS.mp3", 1024);
}
void draw(){
switch (playernum) {
case 0:
    drawLED (player);
    break;
case 1:
    drawLED (player1);
    break;
}
}

void keyPressed() {
if (key==ESC) {
    myport.write(255);
    exit();
}
if (key == ' ') {
    if (pause) pause = false;
    else pause = true;
}
if (key == CODED) {
    if (keyCode == DOWN) {
      pause();
      playernum ++;
    }
    if (keyCode == UP) {
      pause();
      playernum --;
    }
}
}

void pause() {
switch (playernum) {
case 0:
    player.pause();
    break;
case 1:
    player1.pause();
    break;
}
}

void drawLED(AudioPlayer players) {
……
}

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






yokovs123tian 发表于 2016-1-24 14:45:17

请问压缩包里的文件相对应放哪

雅比斯 发表于 2017-3-15 04:51:18

楼主真是大好人啊!不过我刚刚接触arduino所以还是有一些不懂的地方先请教楼主。
把libraries压缩包里的文件拷贝到arduino-libraries里,然后把转给arduino的那些代码复制并烧录到arduino里面就可以了是吗?谢谢

AdaZhao 发表于 2016-1-27 22:21:30

yokovs123tian 发表于 2016-1-24 14:45
请问压缩包里的文件相对应放哪

是libraries压缩包里吗?要放在arduino-libraries里,如果arduino里面没有libraries的文件夹自己创建一个就好

大连林海 发表于 2016-1-14 22:51:26

沙发

孙毅 发表于 2016-1-15 12:10:04

恩,这个有点意思啊

dsweiliang 发表于 2016-1-15 17:05:06

有什么彩蛋?

单品蓝山 发表于 2016-1-15 21:08:13

效果很好,不过自己感觉已经过了迷恋这种闪光的年纪,所有不知道实际有什么用途

hnyzcj 发表于 2016-1-16 07:13:59

我看到拍照的是个妹子。哈哈

hnyzcj 发表于 2016-1-16 07:14:38

单品蓝山 发表于 2016-1-15 21:08
效果很好,不过自己感觉已经过了迷恋这种闪光的年纪,所有不知道实际有什么用途 ...

没有用就是最有用,哈哈

丄帝De咗臂 发表于 2016-1-17 19:20:06

这个灯光效果很不错

冰儿burning 发表于 2016-1-17 23:27:13

马上拿下

Phoebe 发表于 2016-1-18 10:01:47

效果好赞,圆盘的led灯带与音乐结合呈现的效果别有一番趣味{:5_157:}

kaka 发表于 2016-1-18 11:44:31

圆盘的led环形灯带哪里有售?

maker_王 发表于 2016-1-19 16:33:01

赞一个,我已成功移植到灯带上,效果也不错哦

AdaZhao 发表于 2016-1-20 10:49:39

maker_王 发表于 2016-1-19 16:33
赞一个,我已成功移植到灯带上,效果也不错哦

棒 求效果图~

AdaZhao 发表于 2016-1-20 10:50:58

dsweiliang 发表于 2016-1-15 17:05
有什么彩蛋?

洗脑神曲啊。。。之前在电梯里放了那个视频,出了电梯就有人开始唱歌了{:5_168:}

dsweiliang 发表于 2016-1-20 14:45:42

AdaZhao 发表于 2016-1-20 10:50
洗脑神曲啊。。。之前在电梯里放了那个视频,出了电梯就有人开始唱歌了 ...

我在办公室看视频都没敢开声音

maker_王 发表于 2016-1-20 17:11:51

AdaZhao 发表于 2016-1-20 10:49
棒 求效果图~
http://video.weibo.com/show?fid= ... a9c3958cabd16631bb7

iooops 发表于 2016-1-22 18:05:48

{:5_198:}

nxcosa 发表于 2016-1-25 15:25:19

这个好赞!!!!被最后的歌洗脑了{:5_171:}

AdaZhao 发表于 2016-1-27 22:20:39

nxcosa 发表于 2016-1-25 15:25
这个好赞!!!!被最后的歌洗脑了

啊 对的 就是要这个效果hhh
页: [1] 2 3
查看完整版本: party神器~Processing&Arduino音乐LED