槭枫方糖 发表于 2013-6-23 00:26:31

急!关于使用Arduino来播放SD卡里的音乐的问题

原帖:
http://www.geek-workshop.com/thread-2611-1-1.html
我是个刚学Arduino板的新人,学校里的老师上课都让我们自学的,所以有很多不懂的地方
上面这个很棒的实例我已经实验过,而且成功了,但是我想做进一步的改动,却不知道如何下手。
比如说,这个实验是要通过串口发送指令才能让扬声器播放音乐,要怎样才能做到不使用串口就让它播放音乐?
(最好能使用电池作为电源,而不是连接在电脑上)
另外,我还想通过添加人体感应模块实现当有人接近时播放音乐,远离时又停止播放,这个是否能实现,如果能的话要怎么做?
我是用的是arduino uno R3的板子,人体感应模块的型号是HC-SR501。
求各位大神指点。
如果真心无法实现,也希望各位提一提意见,把这个例子能改成一个带有一定交互性质的作品,谢谢大家了~

林定祥 发表于 2013-6-23 09:44:25

我想你已经试验过SD-MP3的播放程序,和人体感应模块的程序了吧,那应该对Arduino已经有所了解了。可以把两个程序拼接起来,Arduino程序分成三部分,定义,setup()和loop()部分,将2部分程序一一对应,先校验下,防止拼接过程中有失误。然后根据你的设想将人体感应到的反应,去替代通过串口发送的串口指令P。对于SD-MP3程序部分需要修改打开想播放MP3的文件,这部分可以在setup()里,也可以在loop(),接到人体感应后先打开文件再播放。两端文件没有读过,以上想法仅供参考。

林定祥 发表于 2013-6-23 09:50:43

这个学习后递进的想法很好,很有创意。对于摆脱USB的想法也很好,在调试过程中USB起到PC和Arduino通讯作用和供电双重作用,在程序调试完成后,程序下载了能独立正确运行了,就可以离开USB,当然Arduino需要电池供电了。

槭枫方糖 发表于 2013-6-23 10:59:58

林定祥 发表于 2013-6-23 09:44 static/image/common/back.gif
我想你已经试验过SD-MP3的播放程序,和人体感应模块的程序了吧,那应该对Arduino已经有所了解了。可以把两个 ...

谢谢你的回答,让我又多了一个新的思路,不过不精通语言是我的硬伤啊……
人体感应模块里感应到人的时候loop()部分的语句是这样的
int in = digitalRead(ledpin);
Serial.println(in); //有人的时候输出高电平1 无人0
delay(2000);
所以我一开始的设想是让播放音乐的部分不停地循环播放,无人时,电平低所以不会有声音,出现人时电平高,开始发声,但是这样的想法的难点就在于怎样让它不停地发出指令p(默认SD卡中只有一个文件)

你给我的想法我觉得也非常好,比我的靠谱多了的样子,但这样对我来说难点就在怎样将人体感应到的反应,去替代通过串口发送的串口指令P

其实主要还是代码的问题啊……刚接触这个只懂一些基本的语句,真心改不起来……

以下是SD卡播放音乐的代码:

#include <SimpleSDAudio.h>

// Callback target, prints output to serial
void DirCallback(char *buf) {
Serial.println(buf);
}

char AudioFileName;

// Create static buffer
#define BIGBUFSIZE (2*512)      // bigger than 2*512 is often only possible on Arduino megas!
uint8_t bigbuf;

// helper function to determine free ram at runtime
int freeRam () {
extern int __heap_start, *__brkval;
int v;
return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
}

void setup()
{

// Open serial communications and wait for port to open:
Serial.begin(9600);
   while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
}

Serial.print(F("Free Ram: "));
Serial.println(freeRam());

// Setting the buffer manually for more flexibility
SdPlay.setWorkBuffer(bigbuf, BIGBUFSIZE);

Serial.print(F("\nInitializing SimpleSDAudio V" SSDA_VERSIONSTRING " ..."));

// If your SD card CS-Pin is not at Pin 4, enable and adapt the following line:
SdPlay.setSDCSPin(10);

// Select between SSDA_MODE_FULLRATE or SSDA_MODE_HALFRATE (62.5kHz or 31.25kHz)
// and the output modes SSDA_MODE_MONO_BRIDGE, SSDA_MODE_MONO or SSDA_MODE_STEREO
if (!SdPlay.init(SSDA_MODE_FULLRATE| SSDA_MODE_MONO
)) {
    Serial.println(F("initialization failed. Things to check:"));
    Serial.println(F("* is a card is inserted?"));
    Serial.println(F("* Is your wiring correct?"));
    Serial.println(F("* maybe you need to change the chipSelect pin to match your shield or module?"));
    Serial.print(F("Error code: "));
    Serial.println(SdPlay.getLastError());
    while(1);
} else {
    Serial.println(F("Wiring is correct and a card is present."));
}


}


void loop(void) {

uint8_t count=0, c, flag;

Serial.println(F("Files on card:"));
SdPlay.dir(&DirCallback);

ReEnter:
count = 0;
Serial.println(F("\r\nEnter filename (send newline after input):"));
do {
    while(!Serial.available()) ;
    c = Serial.read();
    if(c > ' ') AudioFileName = c;
} while((c != 0x0d) && (c != 0x0a) && (count < 14));
AudioFileName = 0;

Serial.print(F("Looking for file... "));
if(!SdPlay.setFile(AudioFileName)) {
    Serial.println(F(" not found on card! Error code: "));
    Serial.println(SdPlay.getLastError());
    goto ReEnter;
} else {
   Serial.println(F("found."));
}   

Serial.println(F("Press s for stop, p for play, h for pause, f to select new file, d for deinit, v to view status."));
flag = 1;

while(flag) {
    SdPlay.worker();
    if(Serial.available()) {
      c = Serial.read();
      switch(c) {
         case 's':
         SdPlay.stop();
         Serial.println(F("Stopped."));
         break;
         
         case 'p':
         SdPlay.play();
         Serial.println(F("Play."));
         break;
         
         case 'h':
         SdPlay.pause();
         Serial.println(F("Pause."));
         break;   
   
         case 'd':
         SdPlay.deInit();
         Serial.println(F("SdPlay deinitialized. You can now safely remove card. System halted."));
         while(1) ;
         break;
            
         case 'f':
         flag = 0;
         break;
   
         case 'v':
         Serial.print(F("Status: isStopped="));
         Serial.print(SdPlay.isStopped());
         Serial.print(F(", isPlaying="));
         Serial.print(SdPlay.isPlaying());
         Serial.print(F(", isPaused="));
         Serial.print(SdPlay.isPaused());
         Serial.print(F(", isUnderrunOccured="));
         Serial.print(SdPlay.isUnderrunOccured());
         Serial.print(F(", getLastError="));
         Serial.println(SdPlay.getLastError());
         Serial.print(F("Free RAM: "));
         Serial.println(freeRam());
         break;      
      }
    }
}


}

林定祥 发表于 2013-6-23 13:28:55

你的人体传感器状态是in,而你的播放器的关键是c,原来loop中c=Serial.Read(),现在c=in就可以了,不过这个in需要有个转换,in是数字,c是字符,两边改一个与之匹配就好。至于0,1是STOP,PAUSE,PLAY就看你愿意怎么配了。试一下应该没有问题了,去实现你的愿望吧。

槭枫方糖 发表于 2013-6-24 08:56:29

林定祥 发表于 2013-6-23 13:28 static/image/common/back.gif
你的人体传感器状态是in,而你的播放器的关键是c,原来loop中c=Serial.Read(),现在c=in就可以了,不过这个i ...

好的,谢谢,我来试试。

whc2001 发表于 2013-8-2 14:51:22

首先SdPlay.setFile(你要的音乐名字);,然后不断的判断in的状态,if(in==1){SdPlay.play();}这样应该就好了

万马奔腾 发表于 2013-8-7 12:32:30

whc2001 发表于 2013-8-2 14:51 static/image/common/back.gif
首先SdPlay.setFile(你要的音乐名字);,然后不断的判断in的状态,if(in==1){SdPlay.play();}这样应该就好了

#include <SimpleSDAudio.h>

void setup()
{
// If your SD card CS-Pin is not at Pin 4, enable and adapt the following line:
// SdPlay.setSDCSPin(10);

// Init SdPlay and set audio mode
if (!SdPlay.init(SSDA_MODE_FULLRATE | SSDA_MODE_MONO)) {
    while(1); // Error while initialization of SD card -> stop.
}

// Select file to play
if(!SdPlay.setFile("wb.AFM")) {
    while(1); // Error file not found -> stop.
}   

// Start playback
SdPlay.play();

// Let the worker work until playback is finished
while(1) {
    SdPlay.worker();
}
}


void loop(void) {
}

蓝色骨骨头 发表于 2015-4-26 17:56:17

楼主 不知道你的这个控制音乐播放的代码弄好了么 可以分享一下么

whtech 发表于 2015-4-26 20:55:51

void playSound(char * filename)
{

if(!SdPlay.setFile(filename)) {
    Serial.println(F(" not found on card! Error code: "));
    Serial.println(SdPlay.getLastError());
    while(1); // loop forever
} else {
   Serial.println(F("found."));
}   
int flag = 1;
SdPlay.play();
while(flag) {
    SdPlay.worker();
    if(SdPlay.isStopped()){
      break;
    }
}

}

lein317 发表于 2016-1-6 14:51:42

请问你的人体感应程序做好了吗? 求分享
页: [1]
查看完整版本: 急!关于使用Arduino来播放SD卡里的音乐的问题