超简单基于arduino音乐控制全彩灯条视频效果+代码解析+原...-Arduino中文社区 - Powered by Discuz!
查看: 21188|回复: 13

超简单基于arduino音乐控制全彩灯条视频效果+代码解析+原...

[复制链接]

该用户从未签到

发表于 2015-11-12 09:21 | 显示全部楼层 |阅读模式
本帖最后由 唯_lose 于 2015-11-12 09:21 编辑

设计准备器件:
Arduino 开发板(什么系列都行)                        x1
WS281X系列智能全彩灯条                              x1   
咪头音乐采集传感器                                                             x1
LCD1602液晶显示                                     x1
1uF 无极性电容                                        x1
9014 NPN三极管                                       x1
150欧电阻                                             x1
1K电阻                                               x2
10K电阻                                              x1
1M电阻                                               x1
导线若干
以上是准备条件有这些器件你就可以开搞了。
首先你需要搭建一个音乐采集电路,这里我提供一个本人所用的电路。
(咪头器件可能与图中不符,请不要在意这些细节)
接下来我们搭建LCD液晶显示电路这个电路在Arduino绘图软件中有接法,这里我也贴一个电路出来。
图片太小看不清你可以将其放大就可以了。至于为什么要搭建显示电路下面有解释^_^
以上是音乐控制灯条所需搭建的全部电路。接下来就要在Arduino写相应的驱动程序了。(如果你之前有下载Adafruit_NeoPixel.h头文件下面你可以不看0.0在写程序之前我们还要下载一个Adafruit_NeoPixel.h库函数。我有上传的,你可以在下面进行下载!下载好你需要对其进行解压,在去掉后面的尾巴“—master”去掉放到Arduino软件安装路径下的libraries文件下面。具体操作你可以看我发的另一篇文章超简单基于arduino控制全彩LED那里我有对如何操作上述函数有更详细的解释。
下面我将对代码进行讲解!
[mw_shl_code=bash,true]
#include<LiquidCrystal.h>            //该头文件是软件自带的。
#include <Adafruit_NeoPixel.h>      //这个头文件是需要自己下载。

#define MusicSenors A0                //定义音乐传感器接口为模拟接口5
#define PIN 6                        
#define LED_Numbers 30                //定义点亮LED灯的最大个数
typedef unsigned char u8;

LiquidCrystal lcd(12,11,5,4,3,2);   //初始化LiquidCrystal,设置相应的接口,其中RS为12号接口引脚,E为11号引脚,5~2为数据输入引脚。

/*初始化MAX_LED为点亮LED的最大个数,PIN为LED数据线与开发板所连的端口,
NEO_RGB + NEO_KHZ800 为LED的灯条类型,一般都用这个,
如果灯条类型不同请用NEO_KHZ400 + NEO_RGB这个参数。*/
Adafruit_NeoPixel strip = Adafruit_NeoPixel( LED_Numbers, PIN, NEO_RGB + NEO_KHZ800 );


/*一下是变量参数的设置后面会陆续解释*/
float volume=0;
uint8_t a=0;
uint16_t WheelPos=0,times=0;
uint32_t color;
char Direction=0,Flag=0;

void setup()
{
  Serial.begin(9600);                     //初始化串口;
  pinMode(MusicSenors,INPUT);             //设置端口为输入模式;
  lcd.begin(16,2);                        //初始化LCD;
  
  strip.begin();                          // 初始化Adafruit_NeoPixel;
  strip.show();                           //初始化LED灯条输出状态;
}

void loop()
{
MusicCllect ();                         //调用音乐采集函数;
ColorSelect();                          //调用颜色选择函数;

if(volume<3)                            //判断声音大小;
  {
   times++;
   if(times>100) times=51;
   Silent();                            //调用静默函数;
  }
else  
{
   times=0;
   LitPixel();                         //调用点亮LED灯条函数;
}
}

void MusicCllect ()                    //音乐采集函数;
{
  volume=analogRead(MusicSenors);     //读取音乐传感器的模拟值;
  volume=(volume/10);                 //将读取的值缩小10倍;

  if(volume>66+1)
     volume=volume-66;
  else if(volume<59)
     volume=59-volume;
  else volume=0;
  
  if(volume>=59) volume=59;         //限制音量的最大值;
  else if(volume<=0) volume=0;      //限制音量最小值;
  
  if(LED_Numbers>=50) volume=volume*1.5;
  if(LED_Numbers>=100) volume=volume*2;
  if(LED_Numbers>=200) volume=volume*4;
  
  lcd.clear();                      //LCD清屏;
  
  lcd.print("Music Volume is:");     //LCD第一行显示的内容;
  lcd.setCursor(0,1);                //LCD切换到第二行;
  lcd.print((uint16_t)volume);      //显示采集到的数;
}

void LitPixel()                      //点亮LED灯条函数;
{
    u8 i;                          //灯条个数变量;
    switch(Flag)                     //switch选择判断语句,Flag为标志位用;
    {
      case 1:
        for(i=0;i<LED_Numbers;i++)           //以下函数所执行的是先发送数据使LED灯全关,防止上一次数据干扰;
        {
         strip.setPixelColor(i,0);   
        }
        /*以下函数是灯条花样的一种算法,因为如果不用这种算法直接用采集
        的数来点亮LED的个数会很突然,没有一种过渡的感觉,所以用以下
        算法进行一种平稳的过渡,让采集的音量来点亮LED更具有节奏感*/
        if(a<volume)  a++;     
        else if(a>volume) a=a-1.5;
        
        if(a>=LED_Numbers) a=LED_Numbers;
        else if(a<=0) a=0;
        
         for(i=0;i<a;i++)            //花样效果哦,有兴趣的好好想想呗。
        {
         strip.setPixelColor(i,100,100,100);
        }   
        for(i=0;i<a-1;i++)            //将经过处理的数赋值给a,来控制LED灯点亮的个数;
        {
         strip.setPixelColor(i,color);
        }
        
        strip.show();               //将点亮的LED显示出来;
        break;  

        /*以下代码是与上面花样效果方向相反,具体是使所有LED点亮,
        然后使总的点亮个数减采集个数的LED灯变灭这样就会出现与上
        面方向相反的效果*/
     case 0:                    
       for(i=0;i<LED_Numbers;i++)            
       {
        strip.setPixelColor(i,color);
       }   
       if(a<volume)  a++;
       else if(a>volume) a=a-1.5;
      
       if(a>=LED_Numbers) a=LED_Numbers;
       else if(a<=0) a=0;
      
       for(i=0;i<LED_Numbers-a+1;i++)            
       {
        strip.setPixelColor(i,100,100,100);
       }   
      
       for(i=0;i<LED_Numbers-a;i++)
       {
        strip.setPixelColor(i,0);
       }
       strip.show();
       break;
         
    case 2:            
      for(i=0;i<LED_Numbers/2;i++)            
       {
        strip.setPixelColor(i,color);
       }   
       if(a<volume)  a++;
       else if(a>volume) a=a-1.5;
      
       if(a>=LED_Numbers) a=LED_Numbers;
       else if(a<=0) a=0;
      
      for(i=0;i<(LED_Numbers-a)/2+1;i++)            
       {
        strip.setPixelColor(i,100,100,100);
       }   
      for(i=0;i<(LED_Numbers-a)/2;i++)
       {
        strip.setPixelColor(i,0);
       }
      
      for(i=LED_Numbers/2;i<LED_Numbers;i++)           //以下函数所执行的是先发送数据使LED灯全关,防止上一次数据干扰;
        {
         strip.setPixelColor(i,0);   
        }
    /*    以下函数是灯条花样的一种算法,因为如果不用这种算法直接用采集
        的数来点亮LED的个数会很突然,没有一种过渡的感觉,所以用以下
        算法进行一种平稳的过渡,让采集的音量来点亮LED更具有节奏感*/
        if(a<volume)  a++;     
        else if(a>volume) a=a-1.5;
        
        if(a>=LED_Numbers) a=LED_Numbers;
        else if(a<=0) a=0;
        
        for(i=LED_Numbers/2;i<LED_Numbers/2+a/2;i++)            //花样效果哦,有兴趣的好好想想呗。
        {
         strip.setPixelColor(i,100,100,100);
        }   
        for(i=LED_Numbers/2;i<LED_Numbers/2+a/2-1;i++)            //将经过处理的数赋值给a,来控制LED灯点亮的个数;
        {
         strip.setPixelColor(i,color);
        }
       strip.show();
       break;  
    }
}

/*该函数主要是对点亮LED的颜色进行改变严格的来说该LED
支持256颜色变换,以下为其中颜色的几种其主要是通过内部
的一个变量进行计数当满足某个条件时点亮哪种颜色*/
void ColorSelect()
{
  if(WheelPos<200)
    color=strip.Color(80, 0, 0);
  if(WheelPos>=200&&WheelPos<400)
    color=strip.Color(80, 80, 0);
  if(WheelPos>=400&&WheelPos<600)
    color=strip.Color(0, 80, 0);
  if(WheelPos>=600&&WheelPos<800)
    color=strip.Color(0,80,80);
  if(WheelPos>=800&&WheelPos<1000)
    color=strip.Color(0,0,80);
  if(WheelPos>=1000&&WheelPos<1200)
    color=strip.Color(0,0,80);
  WheelPos++;
  if(WheelPos==1200)     //当计数达到1200时执行以下语句;
  {
    WheelPos=0;
    Direction++;
    if(Direction==4) Flag=1;       //Direction为方向选择变量,但计数到4时控制方向标志位置为1;
    else if(Direction==8)  Flag=2;   //Direction为方向选择变量,但计数到8时控制方向标志位置为2;
    else if(Direction==12)         //当Direction计到12是清零,并控制标志位置为0;
    {
      Flag=0;
      Direction=0;
    }
}     
}

/*该函数主要是检测声音的大小,当音乐声音很小或者没有时进入静默状态*/
void Silent()
{
  uint8_t i,b;
  uint16_t SceneVolume;   //场景音量变量;
  SceneVolume=volume;    //将采集音量赋值给的场景音量;
  if(times>50)         //内部进行计数放音量低于3是且times大于200时进入内部语句;
  {
    ClearColor();        //清除灯条颜色,防止干扰;
    if(SceneVolume<3)     //再对场景音量进行判断是否确实小于3;小于执行内部语句;
    {
     color=strip.Color(50, 0, 0);//color颜色赋值为静默状态时的颜色,该颜色也可执行调节,只需改变strip.Color(50, 0, 0);内部的3个参数值就可以,但参数值不能超过255.  
     b=random(4,LED_Numbers+1);      //用到了随机函数,其随机的值为4-40之间;
     for(i=0;i<b;i++)          //首先将随机到的LED数值全部赋值颜色;
     {
       strip.setPixelColor(i,color);   
     }  
     for(i=0;i<b-4;i++)   //再把随机数的最后面4个数,前面的数颜色全都关掉;
     {
       strip.setPixelColor(i,0);
     }
     strip.show();        //这样就会出现随机的4个LED灯点亮的效果了;
     if(SceneVolume<3) delay(1500); //该语句主要作用是防止灯闪一下就灭的情况;同时判断场景声音是否小于3;
     }
   }
}

void ClearColor()         //LED灯条清屏操作,防止有其他颜色干扰;
{
    uint8_t i;
     for(i=0;i<LED_Numbers;i++)
     {
        strip.setPixelColor(i,0);
     }
     strip.show();  
}[/mw_shl_code]

图片2.png
图片1.png

musicanalog.rar

3.04 KB, 下载次数: 229

Adafruit-GFX-Library-master.zip

10.82 KB, 下载次数: 174

Adafruit_NeoMatrix-master.zip

23.3 KB, 下载次数: 181

musicanalog.rar

3.03 KB, 下载次数: 175

该用户从未签到

发表于 2016-12-28 00:01 | 显示全部楼层
厉害
真希望,能像你一样

该用户从未签到

发表于 2017-6-4 20:37 | 显示全部楼层
楼主 ,代码输入arduino显示有误。然后在压缩包里找到无误的代码,连接了却没有反应

该用户从未签到

发表于 2017-7-29 10:39 | 显示全部楼层
楼主你好! 请问你的灯条是在哪里买的呀?淘宝上搜不到唉!

该用户从未签到

发表于 2017-8-10 11:04 | 显示全部楼层
唔黑五黑 发表于 2017-6-4 20:37
楼主 ,代码输入arduino显示有误。然后在压缩包里找到无误的代码,连接了却没有反应 ...

我也是同样的情况!请问现在解决了吗?谢谢

该用户从未签到

发表于 2017-12-7 20:55 | 显示全部楼层
楼主你好,请问还有视频吗?网上看不了视频了

该用户从未签到

发表于 2018-1-7 17:06 | 显示全部楼层
做了下实验,不是用咪头是直接接的小功放输出到模拟口,有效果,不知道LED可以并列几行来显示不

签到天数: 1 天

[LV.1]初来乍到

发表于 2019-9-6 10:53 | 显示全部楼层
这个程序写的非常不错,很有参考价值

该用户从未签到

发表于 2019-12-26 21:15 | 显示全部楼层
十分感谢楼主的分享,你的这个教程给了我很大的帮助。

签到天数: 141 天

[LV.7]常住居民III

发表于 2020-7-20 13:49 | 显示全部楼层
楼主,R8,R9相差那么大,音频会起作用吗?
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

热门推荐

【Arduino】168种传感器模块系列实验(159)---MAX9814咪头传感器
【Arduino】168种传感器模
37款传感器与模块的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是
【Arduino】108种传感器模块系列实验(61)---WS2812直条8位模块
【Arduino】108种传感器模
37款传感器与模块的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是
【Arduino】108种传感器系列实验(06)---声音传感器模块
【Arduino】108种传感器系
37款传感器与模块的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是
有没有大佬用过CC1101 模拟433遥控器的 来帮忙解答一下感谢
有没有大佬用过CC1101 模
主控用的是 ESP-WROOM-02(ESP8266) CC1101 用的是这个!对应ESP8266的脚位图 库用
开学季新/老会员回馈活动!
开学季新/老会员回馈活动
开学季:社区会员回馈活动!Arduino中文社区联合openjumper推出开学季会员福利回馈活
Copyright   ©2015-2016  Arduino中文社区  Powered by©Discuz!   
快速回复 返回顶部 返回列表