Skip to content

Make Processing

조회 수 10791 추천 수 0 댓글 7
?

단축키

Prev이전 문서

Next다음 문서

+ - Up Down Comment Print
?

단축키

Prev이전 문서

Next다음 문서

+ - Up Down Comment Print

안녕하세요. 

아두이노랑 Adafruit의 wave shield를 이용해서 컴퓨터와 연결 없이 사운드 파일을 플레이 하려고 합니다.

근데 그냥 플레이 하는 게 아니고, 가변저항(potentiometer)을 연결해서 저항 값에 따라 다른 음원이 재생하고 싶습니다.


adafruit에서 제공하는 라이브러리와 인터넷에서 찾은 코드를 통해 현재 가변저항으로 다른 음원이 재생되게끔 하는 것까진 성공 했는데, 

문제는 현재 재생 중인 곡이 완전히 끝나야만 다른 곡으로 넘어갑니다. 

저항값이 바뀌자마자 다른 음원이 플레이 되게 하고 싶은데(interrupt), 그게 안되네요...


playcompelete 명령어를 playfile로 바꾸라는 팁을 보고 따라해 봤는데, 

시리얼 모니터를 통해 보니 매 순간(밀리세컨?)마다 저항값을 읽어들여서 음악이 플레이가 되지 않습니다.  

deadband 라는 코드를 써보라는 얘기도 있었는데 그건 무슨 말인지 모르겠구욤...

아래는 제가 참고한 사이트들입니다. 


Adafruit wave shield 라이브러리 설명: http://learn.adafruit.com/adafruit-wave-shield-audio-shield-for-arduino/wavehc-library

Adafruit wave shield 응용 코드 예제: http://learn.adafruit.com/adafruit-wave-shield-audio-shield-for-arduino/examples

아래의 가변저항 응용 코드 출처: http://digitalmedia.risd.edu/pbadger/PhysComp/pmwiki/pmwiki.php?n=Sketches.WavpgmPot

저와 비슷한 질문 같은 영문 게시판 글: http://forums.adafruit.com/viewtopic.php?f=31&t=23513


아래는 제가 현재 사용 중인 코드 입니다.  (가변저항 값 바뀌면, 재생 중인 곡이 다 끝나야 다른 곡으로 넘어가는 상태)

// this program/sketch allows one to play specific files on an SD Card.

// reads POT on A0 and selects song using switch/case statement

// adapted LL2011

//

// stripped down LadyAda Wave Shield Code

//  adapted from:  http://www.ladyada.net/media/wavshield/daphc.pde

// Lucky and Dory

//

// we have moved the SD card functions and setup to the end of the program - leave them be please.

//  code you should modify is in the loop function


#include <FatReader.h>

#include <SdReader.h>

#include <avr/pgmspace.h>

#include "WaveUtil.h"

#include "WaveHC.h"


SdReader card;    // This object holds the information for the card

FatVolume vol;    // This holds the information for the partition on the card

FatReader root;   // This holds the information for the filesystem on the card

FatReader f;      // This holds the information for the file we're play

WaveHC wave;      // This is the only wave (audio) object, since we will only play one at a time


int sensorValue = 0;

int MappedVal = 0;

int NewVal = 0;

int SensorInPin = 0;  // analog sensor mapped to pin A0


void setup() 

{

    // set up serial port

    Serial.begin(9600);

    Serial.println("  setup  ");

    putstring_nl("WaveHC with 6 buttons");


    putstring("Free RAM: ");       // This can help with debugging, running out of RAM is bad

    Serial.println(freeRam());      // if this is under 150 bytes it may spell trouble!


    // Set the output pins for the DAC control. This pins are defined in the library

    pinMode(2, OUTPUT);

    pinMode(3, OUTPUT);

    pinMode(4, OUTPUT);

    pinMode(5, OUTPUT);


    // pin13 LED

    pinMode(13, OUTPUT);


    cardcheck();   // run function to check SD Card - i would leave this alone

}


void loop() 

{

    Serial.println(" beginning of  loop ");


// the code section below can be used (uncommented) to read an analog input pin and then map to one of the 5 WAV files

    sensorValue = analogRead(SensorInPin);        // read analog sensor (in)

    MappedVal = map(sensorValue, 0 , 1023, 0, 3);    // map - in our case Dory had 5 wav files, so we need a number from 0-4

    NewVal = constrain(MappedVal, 0, 3);


// Now use the number 0-4 to select the WAV file to play. 

    Serial.print(" Value used in selecting program to play = ");


    Serial.println(NewVal, DEC);

    switch (NewVal)         // look up in file:///Applications/Arduino.app/Contents/Resources/Java/reference/SwitchCase.html

    {

    case 0:

        playcomplete("01.wav");    //  here you must fill in your file names (wav files on the SD Card)

        break;

    case 1:

        playfile("02.WAV");

        break;

    case 2:

        playfile("03.WAV");

        break;

    case 3:

        playfile("04.WAV");

        break;

//    case 4:

//        playcomplete("4.WAV");

    }

    delay(random(5,200));    // slows program down (feel free to delete)

}


//void playcomplete(char *name)     // Plays a full file from beginning to end with no pause.

//{

//    Serial.println("  playcomplete  ");

//    // call our helper to find and play this name

//    playfile(name);

//    while (wave.isplaying) 

//    {

//        // do nothing while its playing

//    }

//    // now it's done playing

//}


void playfile(char *name) 

{

    Serial.println("  playfile  ");

    if (wave.isplaying)     // see if the wave object is currently doing something if already playing something, so stop it!

    {

        wave.stop(); // stop it

    }


    if (!f.open(root, name))      // look in the root directory and open the file

    {

        putstring("Couldn't open file ");

        Serial.print(name);

        return;

    }


    if (!wave.create(f))          // OK read the file and turn it into a wave object

    {

        putstring_nl("Not a valid WAV");

        return;

    }


    wave.play();         // ok time to play! start playback

}



int freeRam(void)    // this handy function will return the number of bytes currently free in RAM, great for debugging!

{

    Serial.println("  freeRAM  ");

    extern int  __bss_end;

    extern int  *__brkval;

    int free_memory;

    if((int)__brkval == 0) 

    {

        free_memory = ((int)&free_memory) - ((int)&__bss_end);

    }

    else 

    {

        free_memory = ((int)&free_memory) - ((int)__brkval);

    }

    return free_memory;

}


void sdErrorCheck(void)

{

    Serial.println("  dErrorCheck ");

    if (!card.errorCode()) return;

    putstring("\n\rSD I/O error: ");

    Serial.print(card.errorCode(), HEX);

    putstring(", ");

    Serial.println(card.errorData(), HEX);

    while(1);

}


void cardcheck()

{

    Serial.println("cardcheck");

    //  if (!card.init(true)) [ //play with 4 MHz spi if 8MHz isn't working for you

    if (!card.init())          //play with 8 MHz spi (default faster!)

    {

        putstring_nl("Card init. failed!");  // Something went wrong, lets print out why

        sdErrorCheck();

        while(1);                            // then 'halt' - do nothing!

    }

    // enable optimize read - some cards may timeout. Disable if you're having problems

    card.partialBlockRead(true);


    // Now we will look for a FAT partition!

    uint8_t part;

    for (part = 0; part < 5; part++)      // we have up to 5 slots to look in

    {

        if (vol.init(card, part))

            break;                             // we found one, lets bail

    }

    if (part == 5)                        // if we ended up not finding one  :(

    {

        putstring_nl("No valid FAT partition!");

        sdErrorCheck();      // Something went wrong, lets print out why

        while(1);                            // then 'halt' - do nothing!

    }

    putstring("Using partition ");        // Let's tell the user about what we found

    Serial.print(part, DEC);

    putstring(", type is FAT");

    Serial.println(vol.fatType(),DEC);     // FAT16 or FAT32?

    if (!root.openRoot(vol))             // Try to open the root directory

    {

        putstring_nl("Can't open root dir!"); // Something went wrong,

        while(1);                             // then 'halt' - do nothing!

    }

    putstring_nl("Ready!");          // Whew! We got past the tough parts.

}

  • profile
    smileblue 2013.10.10 09:35
    하드웨어 장비가 없어서 어떻게 될지 모르겠지만 야간에 한번 봐야겠네요..^^
  • profile

    정확한 하드웨어가 없다보니 코드로만 유추해서 이야기하도록 하겠습니다. 코드를 보니 playfile 을 이용하는 것이 맞습니다. 하지만 루프에 의해서 계속 음악을 정지하고 재상하는 과정을 반복하다 보니 음악이 제대로 나오지를 않게 됩니다. 이부분은 현재 플레이 되고있는 트랙 NewVal 에 해당하는 값을 다른 변수에 저장해 놓고 swith 문에 같은 NewVal 의 값이 들어오게되면 swith 문을 무시하고 다른 NewVal 같이 들어오면 swith 문을 적용 시키게 하면 해결될것 같습니다. 저는 OldVal이라는 변수로 만들었습니다.


    // this program/sketch allows one to play specific files on an SD Card.
    // reads POT on A0 and selects song using switch/case statement
    // adapted LL2011
    //
    // stripped down LadyAda Wave Shield Code
    //  adapted from:  http://www.ladyada.net/media/wavshield/daphc.pde
    // Lucky and Dory
    //
    // we have moved the SD card functions and setup to the end of the program - leave them be please.
    //  code you should modify is in the loop function
    
    #include <FatReader.h>
    #include <SdReader.h>
    #include <avr/pgmspace.h>
    #include "WaveUtil.h"
    #include "WaveHC.h"
    
    SdReader card;    // This object holds the information for the card
    FatVolume vol;    // This holds the information for the partition on the card
    FatReader root;   // This holds the information for the filesystem on the card
    FatReader f;      // This holds the information for the file we're play
    WaveHC wave;      // This is the only wave (audio) object, since we will only play one at a time
    
    int sensorValue = 0;
    int MappedVal = 0;
    int NewVal = 0;
    int OldVal = 99; // add by smileblue
    int SensorInPin = 0;  // analog sensor mapped to pin A0
    
    void setup() 
    {
      // set up serial port
      Serial.begin(9600);
      Serial.println("  setup  ");
      putstring_nl("WaveHC with 6 buttons");
    
      putstring("Free RAM: ");       // This can help with debugging, running out of RAM is bad
      Serial.println(freeRam());      // if this is under 150 bytes it may spell trouble!
    
      // Set the output pins for the DAC control. This pins are defined in the library
      pinMode(2, OUTPUT);
      pinMode(3, OUTPUT);
      pinMode(4, OUTPUT);
      pinMode(5, OUTPUT);
    
      // pin13 LED
      pinMode(13, OUTPUT);
    
      cardcheck();   // run function to check SD Card - i would leave this alone
    }
    
    void loop() 
    {
      Serial.println(" beginning of  loop ");
    
      // the code section below can be used (uncommented) to read an analog input pin and then map to one of the 5 WAV files
      sensorValue = analogRead(SensorInPin);        // read analog sensor (in)
      MappedVal = map(sensorValue, 0 , 1023, 0, 3);    // map - in our case Dory had 5 wav files, so we need a number from 0-4
      NewVal = constrain(MappedVal, 0, 3);
    
      // Now use the number 0-4 to select the WAV file to play. 
      Serial.print(" Value used in selecting program to play = ");
    
      Serial.println(NewVal, DEC);
      if(OldVal != NewVal)  // add by smileblue
      {
        switch (NewVal)         // look up in file:///Applications/Arduino.app/Contents/Resources/Java/reference/SwitchCase.html
        {
        case 0:
          playcomplete("01.wav");    //  here you must fill in your file names (wav files on the SD Card)
          break;
        case 1:
          playfile("02.WAV");
          break;
        case 2:
          playfile("03.WAV");
          break;
        case 3:
          playfile("04.WAV");
          break;
          //    case 4:
          //        playcomplete("4.WAV");
        }
        OldVal = NewVal; // OldVal update!!-- add by smileblue
      }
      delay(random(5,200));    // slows program down (feel free to delete)
    }
    
    //void playcomplete(char *name)     // Plays a full file from beginning to end with no pause.
    //{
    //    Serial.println("  playcomplete  ");
    //    // call our helper to find and play this name
    //    playfile(name);
    //    while (wave.isplaying) 
    //    {
    //        // do nothing while its playing
    //    }
    //    // now it's done playing
    //}
    
    void playfile(char *name) 
    {
      Serial.println("  playfile  ");
      if (wave.isplaying)     // see if the wave object is currently doing something if already playing something, so stop it!
      {
        wave.stop(); // stop it
      }
    
      if (!f.open(root, name))      // look in the root directory and open the file
      {
        putstring("Couldn't open file ");
        Serial.print(name);
        return;
      }
    
      if (!wave.create(f))          // OK read the file and turn it into a wave object
      {
        putstring_nl("Not a valid WAV");
        return;
      }
    
      wave.play();         // ok time to play! start playback
    }
    
    
    int freeRam(void)    // this handy function will return the number of bytes currently free in RAM, great for debugging!
    {
      Serial.println("  freeRAM  ");
      extern int  __bss_end;
      extern int  *__brkval;
      int free_memory;
      if((int)__brkval == 0) 
      {
        free_memory = ((int)&free_memory) - ((int)&__bss_end);
      }
      else 
      {
        free_memory = ((int)&free_memory) - ((int)__brkval);
      }
      return free_memory;
    }
    
    void sdErrorCheck(void)
    {
      Serial.println("  dErrorCheck ");
      if (!card.errorCode()) return;
      putstring("\n\rSD I/O error: ");
      Serial.print(card.errorCode(), HEX);
      putstring(", ");
      Serial.println(card.errorData(), HEX);
      while(1);
    }
    
    void cardcheck()
    {
      Serial.println("cardcheck");
      //  if (!card.init(true)) [ //play with 4 MHz spi if 8MHz isn't working for you
      if (!card.init())          //play with 8 MHz spi (default faster!)
      {
        putstring_nl("Card init. failed!");  // Something went wrong, lets print out why
        sdErrorCheck();
        while(1);                            // then 'halt' - do nothing!
      }
      // enable optimize read - some cards may timeout. Disable if you're having problems
      card.partialBlockRead(true);
    
      // Now we will look for a FAT partition!
      uint8_t part;
      for (part = 0; part < 5; part++)      // we have up to 5 slots to look in
      {
        if (vol.init(card, part))
          break;                             // we found one, lets bail
      }
      if (part == 5)                        // if we ended up not finding one  :(
      {
        putstring_nl("No valid FAT partition!");
        sdErrorCheck();      // Something went wrong, lets print out why
        while(1);                            // then 'halt' - do nothing!
      }
      putstring("Using partition ");        // Let's tell the user about what we found
      Serial.print(part, DEC);
      putstring(", type is FAT");
      Serial.println(vol.fatType(),DEC);     // FAT16 or FAT32?
      if (!root.openRoot(vol))             // Try to open the root directory
      {
        putstring_nl("Can't open root dir!"); // Something went wrong,
        while(1);                             // then 'halt' - do nothing!
      }
      putstring_nl("Ready!");          // Whew! We got past the tough parts.
    }


  • ?
    망고 2013.10.11 04:23

    선생님, 답변 감사드립니다. 수정해주신 코드를 적용해보니 저항 값이 바뀌면 다른 사운드 파일이 재생됩니다! ^^
    그런데 한 가지 문제가 있는 게, 저항 값이 바뀌지 않은 상태에서는 기존 음원을 반복 재생하고 싶은데 현재 상태에서는 저항 값 변화가 없는 상태에서 음원 플레이가 끝나면 아무 음원도 재생되지 않는 상태가 됩니다.
    즉,
    1. 저항값이 바뀌지 않는 경우 현재 음원 반복 재생
    2. 저항값이 바뀌는 경우 다른 음원 재생 시작
    이렇게 하려면, 어떻게 해야할까요?
    else 구문을 넣어서 만들어보려고 하는데 잘 안되네요..음...

    끝으로 OldVal 값을 '99'로 지정하신 이유도 궁금합니다~

  • profile
    smileblue 2013.10.12 00:22
    if(OldVal != NewVal)  // add by smileblue 를
      if(OldVal != NewVal || !wave.isplaying)  // add by smileblue 바꾸면 되지 않을까요? ㅎㅎㅎㅎ;;;;;;;;;;;;

    플레이가 되지 않고 있다면 같은 숫자가 들어와도 실행해라~~ boolean 형태가 적용될지 모르겠네요..^^; 하드웨어가 없으니 막연한 추측 ㅋ
  • ?
    망고 2013.10.12 16:12
    선생님... 하드웨어도 없는데 대단하세요...
    코드 적용하니까 제가 원하는대로 됐어요!!! ^___^!!!
  • profile
    smileblue 2013.10.12 17:15
    휴~~~ 다행이네요~~ ^^ 좋은 작품 기대할께요~~ 종종 미국 소식도 알려주시고요~~~ 화이링!!!!
  • ?
    망고 2013.10.13 08:22
    네~ 작업 완성되면 보여드릴게요!! 항상 감사드려요!! :)

Q&A

질문하는 공간입니다. 회원이면 누구나 질문/답변 할 수 있습니다.

List of Articles
번호 제목 글쓴이 날짜 조회 수
297 Video 관련 하여 질문드립니다. 2 s8848m 2013.09.06 17451
296 Max/Msp 에서 OSC externals 파일들을 넣는 곳이 어딘지 궁금해서 질문드립니다. 1 file beautyfullcastle 2013.08.30 17121
» 아두이노 관련 질문드립니다. 7 망고 2013.10.09 10791
294 프로세싱 폰트관련 질문입니다. 1 방보람 2012.06.01 9628
293 프로세싱 캠에 대해 문의좀 해보려구요 ,, 4 조아진 2012.06.04 9620
292 감사합니다 ㅎ 3 방보람 2012.06.03 9292
291 프로세싱문의요 1 file 조아진 2012.06.04 8964
290 움직이는 오브제를 정지시키고 프린터로 출력.. 1 오후세시 2011.10.26 8563
289 프로세싱 시리얼통신에 관련하여 질문드립니다^^ 3 file songyun114 2013.06.12 8291
288 필터 이미지를 넣는 부분에서 문제가 . 4 file 조아진 2012.06.06 8278
287 키넥트 관련 질문드립니다 4 songyun114 2013.07.15 8117
286 processing 외부 txt 파일 한글 깨짐문제 1 biclen 2013.07.27 7881
285 사용자가 직접 타이핑 하기. 3 오후세시 2011.10.15 7708
284 processing과 vvvv 2 맨땅 2013.10.05 7578
283 다시올립니다 급해요 ㅜ 1 file 조아진 2012.10.12 7435
282 이재중 선생님께 질무운~ 5 file 망고 2013.09.27 7417
281 [질문] 프로세싱 2.0 b8에서 스탠드 얼론의 형태로 어플리케이션 생성시 오류가 납니다. 2 file soundnscape 2013.04.28 7147
280 한 번 더 질문 드릴게요 4 file 유구르트 2012.12.20 7005
279 이재중 선생님께, 프로세싱 워크샵 질문~ 2 file 망고 2013.06.18 6708
278 안녕하세요 :) 3 yuriri 2012.06.14 6637
Board Pagination ‹ Prev 1 2 3 4 5 6 7 8 9 10 ... 15 Next ›
/ 15

나눔글꼴 설치 안내


이 PC에는 나눔글꼴이 설치되어 있지 않습니다.

이 사이트를 나눔글꼴로 보기 위해서는
나눔글꼴을 설치해야 합니다.

설치 취소

Designed by sketchbooks.co.kr / sketchbook5 board skin

Sketchbook5, 스케치북5

Sketchbook5, 스케치북5

Sketchbook5, 스케치북5

Sketchbook5, 스케치북5

Copyright (c) 2012 Make Processing. All Right Reserved.

smileblue

sketchbook5, 스케치북5

sketchbook5, 스케치북5

나눔글꼴 설치 안내


이 PC에는 나눔글꼴이 설치되어 있지 않습니다.

이 사이트를 나눔글꼴로 보기 위해서는
나눔글꼴을 설치해야 합니다.

설치 취소