学习笔记:Arduino开发—DIY可红外遥控的MP3模块-Arduino中文社区 - Powered by Discuz! Archiver

c402703402 发表于 2015-4-3 12:13

学习笔记:Arduino开发—DIY可红外遥控的MP3模块

本帖最后由 c402703402 于 2015-4-3 12:13 编辑

   前几天从网上买来了几个MP3模块、红外发送接收模块、Arduino Pro MINI开发板、18650电池和电池盒子,昨天上午去实验室焊了2596稳压模块,将18V的电压稳压到5V给Arduino等器件供电。在网上没有找到Arduino MP3模块的开发教程,自己弄了两天,DIY了一个可以用红外遥控的MP3,当然也可以换成蓝牙模块,然后用手机遥控,都是同样的道理!这篇学习笔记不涉及内部原理,只是开发应用教程,如想学习内部原理,请自行百度。本篇教程根据淘宝店家所给的资料自行开发,如需要的朋友可以找我要Arduino库文件。
    一、所需材料:
       1、Arduino开发板一块 (我用的是Mega2560)
       2、红外接收模块一个
       3、迷你红外遥控器一个
       4、MP3模块一个(我用的是DFPlayer Mini)
       5、micro sd卡一个(目前用的256M的小卡)
       6、5V电源(为了提高续航能力,我用的是4节18650电池,每节容量6800毫安时,每节电压4.6V,然后用2596稳压模块稳压到5V)
       7、杜邦线若干、弹片开关一个
二、 硬件搭建:
具体介绍一下接线情况:
               1、DFPlayer Mini:

         具体内容及引脚功能请参考最后提供的资料链接
                      VCC——3.3V-5V电源
                     GND——接地
                     RX——接Arduino 6号引脚(软串口TX引脚)
                     TX——接Arduino 5号引脚(软串口RX引脚)
                     SPK_1——接小喇叭负极,可以驱动功率小于3W的小喇叭
                     SPK_2——接小喇叭正极,可以驱动功率小于3W的小喇叭
                     只需要接以上6个引脚即可
                  2、红外遥控:
                  发送器使用迷你红外遥控器,将红外接收模块接线到Arduino板上:红外接收模块共有三个引脚(VCC,GND,OUT),VCC接                  5V正极,GND接5V负极,OUT接到Arduino 3号引脚上,用于接收红外信号。
                     如图接线完毕!
三、程序编写(根据淘宝店家所给资料编写):
      1、先介绍一下DFPlayer Mini模块的串口命令:
         串口命令格式:   请参考资料链接
          部分串口控制指令(即上图中的CMD和para1、para2参数,此为部分命令,程序中用到其他的命令后面还会补充):
                         请参考资料链接
      2、 Arduino程序:
#include <IRSendRev.h>    //红外头文件
#include <SoftwareSerial.h>//软串口头文件

#define ARDUINO_RX 5
#define ARDUINO_TX 6
SoftwareSerial mySerial(ARDUINO_RX, ARDUINO_TX);   //模拟软串口

unsigned char playmode = 1;      //作为暂停/播放的标志
#define PLAY1
#define PAUSE 0
static int8_t Send_buf = {0} ;   //用于存储发送命令的数组

static int bai=0,shi=0,ge=0;         //bai表示百位,shi表示十位,ge表示各位,这三个变量用来指定播放曲目
static int num=0;             //用来记录用户设置播放曲目的位数,比如用户用红外遥控器依次按下1,2,3按键,则num=3,表示第123首曲子

int volumn1=0;            //用来表示是否静音
int single1=0;               //用来表示是否单曲循环

/************Command byte**************************/
#define CMD_NEXT_SONG 0X01            //下一首曲子
#define CMD_PREV_SONG 0X02         //上一首曲子
#define CMD_PLAY_W_INDEX 0X03      //指定播放曲目
#define CMD_VOLUME_UP 0X04         //音量增大
#define CMD_VOLUME_DOWN 0X05   //音量减小
#define CMD_SET_VOLUME 0X06       //设置音量
#define CMD_SET_EQ 0X07                //设置播放风格
#define CMD_SINGLE_CYCLE_PLAY 0X08   
#define CMD_SEL_DEV 0X09            //指定播放设备
#define DEV_TF 0X02                     //作为上一行的参数,表示指定TF卡为播放设备
#define CMD_SLEEP_MODE 0X0A      
#define CMD_WAKE_UP 0X0B
#define CMD_RESET 0X0C
#define CMD_PLAY 0X0D                  //播放
#define CMD_PAUSE 0X0E                //暂停
#define CMD_PLAY_FOLDER_FILE 0X0F
#define CMD_STOP_PLAY 0X16      //停止播放
#define CMD_FOLDER_CYCLE 0X17
#define CMD_SET_SINGLE_CYCLE 0X19    //设置当前曲目单曲循环
#define SINGLE_CYCLE_ON 0X00            //作为上一行的参数,开启当前曲目单曲循环
#define SINGLE_CYCLE_OFF 0X01         //同样作为0x19命令的参数,关闭当前曲目单曲循环
#define CMD_SET_DAC 0X1A            
#define DAC_ON0X00
#define DAC_OFF 0X01
#define CMD_PLAY_W_VOL 0X22            //带音量播放

#define IR_OUT_PIN 3    //连接红外接收模块引脚
void setup()
{
    Serial.begin(9600);
    mySerial.begin(9600);
    delay(200);
    IR.Init(IR_OUT_PIN);      //初始化红外模块
    sendCommand(CMD_SEL_DEV, DEV_TF);//指定TF卡为播放设备
    delay(200);
    sendCommand(CMD_PLAY_W_VOL, 0X0F01);   //带音量播放第一首曲目,音量为15
    sendCommand(0x18,0);    //设置播放模式为随机播放
}

unsigned char dta;    //作为红外接收数组
void loop()
{
   if(IR.IsDta())   //如果红外接收到数据
    {
      int length= IR.Recv(dta);   //取出数据放在dta数组中,并在length中记录下接收到的数据的长度
      switch(dta)      //每个红外遥控器的按键编码都不同,需要自行测定,接收到的数据有一定的格式,共传回九个字节的数据
                                              //每个按键传回的红外编码的最后一位均不同,可以此将按键区分开,以下case参数均是鄙人自行测定的
          {
         case 93:break;                //第一个键,下面按键为每行从左往右依次类推,目前本键保留
         case 157:single();unpara();break;   //设置/关闭当前曲目单曲循环
         case 29:unvolumn();unpara();break;   //设置静音/开启声音
         case 221:playOrPause();unpara();break; //设置暂停/播放
         case 253:sendCommand(CMD_PREV_SONG,0);unpara();break;//上一首
         case 61:sendCommand(CMD_NEXT_SONG,0);unpara();break;//下一首
         case 31:ModeChange();unpara();break;//改变播放(歌曲)风格
         case 87:sendCommand(CMD_VOLUME_DOWN,0);unpara();break;//声音减小
         case 111:sendCommand(CMD_VOLUME_UP,0);unpara();break;//声音增大
         case 151:selectsong(0);break;//按键0,返回数字0
         case 103:break;      //目前保留
         case 79:setsong(songnum());unpara();break; //指定播放曲目的确定键
         case 207:selectsong(1);break;    //按键1,返回数字1         
         case 231:selectsong(2);break;    //按键2,返回数字2,下同         
         case 133:selectsong(3);break;
         case 239:selectsong(4);break;
         case 199:selectsong(5);break;
         case 165:selectsong(6);break;
         case 189:selectsong(7);break;
         case 181:selectsong(8);break;
         case 173:selectsong(9);break;
         }
      }
    }
   
    void sendCommand(int8_t command, int16_t dat)//按指定命令格式发送命令,command表示CMD,dat表示对应的16位参数
{
delay(20);
Send_buf = 0x7e; //
Send_buf = 0xff; //
Send_buf = 0x06; //
Send_buf = command; //
Send_buf = 0x00;//
Send_buf = (int8_t)(dat >> 8);//datah
Send_buf = (int8_t)(dat); //datal
Send_buf = 0xef; //
for(uint8_t i=0; i<8; i++)//
{
    mySerial.write(Send_buf) ;
}
}

void playOrPause()          //暂停/播放
{
cli();    //关闭中断,Arduino内置函数
if(playmode == PLAY)
{
      playmode = PAUSE;
    sendCommand(CMD_PAUSE,0);   //暂停
}
else
{
      playmode = PLAY;
    sendCommand(CMD_PLAY,0);//播放
}
sei();//开启中断,Arduino内置函数
}

void ModeChange(){             //改变歌曲风格
static int n=0;                     //n用来记录累计是第几次按下
n++;
if(n>6)
    n=1;
switch(n)
   {
   case 1:sendCommand(CMD_SET_EQ,0);break;
   case 2:sendCommand(CMD_SET_EQ,1);break;
   case 3:sendCommand(CMD_SET_EQ,2);break;
   case 4:sendCommand(CMD_SET_EQ,3);break;
   case 5:sendCommand(CMD_SET_EQ,4);break;
   case 6:sendCommand(CMD_SET_EQ,5);break;
   
   }
   }

void setsong(int m){          //设置指定曲目播放
sendCommand(CMD_PLAY_W_INDEX,m);
}
void unpara(){    //参数置零
   bai=0;
shi=0;
ge=0;
num=0;
}
int songnum(){    //计算用户指定的曲目
int l=0;
if(num==1)   //如果只按下一位按键,则将bai赋给ge。
   {ge=bai;
      bai=0;
   }
   else
   if(num==2)
       {
          ge=shi;
          shi=bai;
          bai=0;}         
l=bai*100+shi*10+ge;
return l;
}

void selectsong(int shuzi){   //每次用户按下0~9按键,均对应一位数字,根据是第几次按下,分别将该数字分配给bai,shi,ge,
                                              //当前程序最多允许用户设置1~999,即用户最多设置三位数
num++;               //用于记录用户按下0~9键的次数
if(num>3)
    num=1;
if(num==1)
   {bai=shuzi;         //第一次按下的用bai记录
   
   }
else
   if(num==2)
   {
       shi=shuzi;
       }
      else
      ge=shuzi;
         
   
}

void unvolumn(){   //静音/开启音量
   if(volumn1==0)
      {
         volumn1=1;
         sendCommand(CMD_SET_VOLUME,0);//静音(设置音量为0)
       }
    else
      {
         volumn1=0;
         sendCommand(CMD_SET_VOLUME,25);//开启音量,并将音量设置为25
       }
   }

void single(){   //开启/关闭当前曲目单曲循环
if(single1==0)
      {
         single1=1;
         sendCommand(0x19,0);//开启
       }
    else
      {
         single1=0;
         sendCommand(0x19,1); //关闭
       }
}

注意:micro sd卡中的文件夹命名需要是mp3,放置在SD卡根目录下,而mp3文件命名需要是4位数字,例如"0001.mp3",放置在mp3文件夹下。如需中英文命名,可以添加在数字后,例如"0001hello.mp3"或者"0001后来.mp3"。

   硬件和程序都弄好之后,可红外遥控的MP3就DIY成功了!

PS:由于作者水平有限,程序或多或少会有一些漏洞,还望各位批评指正!
      鄙人QQ:402703402

                  
                                                                                                                                                                           2015年3月30日中午
                                                                                                                                                                                 山东大学(威海)
DFPlayer Mini模块参考资料:http://wiki.dfrobot.com.cn/index.php/%28SKU:DFR0299%29DFPlayer_Mini%E6%A8%A1%E5%9D%97

c402703402 发表于 2015-4-3 12:14

鄙人目前不懂如何使用该模块的查询命令,有会的大神请在楼下发出教程贴链接或者直接说明使用方法,谢谢分享!

suoma 发表于 2015-4-3 17:32

谢谢分享学习一下

小新的arduino 发表于 2018-11-21 16:53

请问在播放音乐的同时是都可以做其他事情啊,例如我在让它播放音乐,但是我又想在音乐播放的同时让这块arduino控制物体动
页: [1]
查看完整版本: 学习笔记:Arduino开发—DIY可红外遥控的MP3模块