아두이노 센서 모듈 활용

YX5300 모듈을 사용한 아두이노 MP3 플레이어

조이키트 블로그 2024. 5. 29. 20:28
728x90
반응형

YX5300 UART TTL 직렬 MP3 음악 플레이어 모듈은 다양한 기능을 제공하는 강력한 오디오 모듈이다.

 

1. 오디오 형식 : MP3, WAV, WMA 형식의 오디오 파일을 지원한다.

2. 직렬 통신 : UART TTL 직렬 인터페이스를 통해 마이크로컨트롤러에 쉽게 통신할 수 있다.

3. TF 카드 지원 : 최대 32GB의 Micro TF 카드를 지원하여 대용량의 오디오 파일을 저장하고 재생할 수 있다.

4. 내장형 오디오 디코더 : 내장된 오디오 디코더를 사용하여 오디오 파일을 고음질로 재생할 수 있다.

5. 다양한 재생 제어 : 재생, 일시정지, 정지, 다음트랙, 이전트랙, 볼륨_UP, 볼륨_DOWN, 등의 명령을 통해 오디오 재생을 제어할 수 있다.

6. 스피커 연결 : 모듈에 직접 스피커를 연결할 수 있는 단자를 제공하여 외부 앰프 없이도 오디오 출력을 제공한다.

 

실습 예제 :

YX5300 UART TTL 직렬 MP3 음악 플레이어 모듈을 아두이노와 함께 사용하여 MP3 플레이어를 만들어 보겠다.

구성품으로는 YX5300 MP3 플레이어 모듈, 아두이노 우노 R3, 0.91인치 128X32pixel 디스플레이 모듈, 푸시버튼 등이 사용된다.

 

구성품 : 

YX5300 MP3 모듈 아두이노 우노 R3 0.91인치 OLED 모듈 푸시버튼

 

 

회로도 : 

mp3 플레이어 회로도

 

mp3 플레이어 실물

 

위와 같이 회로를 연결하고 다음과 같이 코딩을 작성한다.

코딩 설명으로는 먼저 OLED와 YX5300 모듈을 위해 라이브러리를 설치해주어야 한다.

OLED 디스플레이 라이브러리 : Adafruit SSD1306, Adafruit GFX Library

YX5300 mp3 모듈 라이브러리 : DFRobotDFPlayerMini

I2C 통신을 위해 Wire 라이브러리를 포함한다.

#include <Wire.h>: I2C

 

 다음 디스플레이 너비 : 128,  높이 : 32로 정의하여 준다. 

#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 32

YX5300 mp3 모듈의 TX, RX를 디지털핀  D2, D3번으로 설정한다.

버튼설정 : 플레이/정지, 다음, 이전, 볼륨+, 볼륨-, 전원 ON/OFF 버튼을 디지털핀 D4, D5, D6, D7, D8, D9 순서대로 설정하여 준다.

// 버튼 핀 설정
const int playPauseButtonPin = 4;
const int nextButtonPin = 5;
const int prevButtonPin = 6;
const int volumeUpButtonPin = 7;
const int volumeDownButtonPin = 8;
const int powerButtonPin = 9;

 

초기 볼륨을 0~30 중 10으로, 트랙은 1번으로 변수 volume, trackNumber로 정의하여 준다. 

int volume = 10; // 초기 볼륨 (0-30)
int trackNumber = 1; // 재생할 트랙 번호

 

버튼 입력 모드를  INPUT_PULLUP으로 설정한다.

  pinMode(playPauseButtonPin, INPUT_PULLUP);
  pinMode(nextButtonPin, INPUT_PULLUP);
  pinMode(prevButtonPin, INPUT_PULLUP);
  pinMode(volumeUpButtonPin, INPUT_PULLUP);
  pinMode(volumeDownButtonPin, INPUT_PULLUP);
  pinMode(powerButtonPin, INPUT_PULLUP);

 

디스플레이의 I2C 주소를 0X3C로 설정한다. 

if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println(F("SSD1306 allocation failed"));
    while (true);
  }
  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(SSD1306_WHITE);

 

전원 버튼 설정 : 

if (digitalRead(powerButtonPin) == LOW) {
    delay(50); // 디바운스
    if (digitalRead(powerButtonPin) == LOW) {
      powerOn = !powerOn;
      if (powerOn) {
        myDFPlayer.start();
        isPlaying = true;
        Serial.println(F("Power ON"));
      } else {
        myDFPlayer.pause();
        isPlaying = false;
        Serial.println(F("Power OFF"));
      }
      updateDisplay();
      while (digitalRead(powerButtonPin) == LOW); // 버튼이 릴리스될 때까지 대기
    }
  }

 

재생/ 정지 버튼 설정 : 

if (digitalRead(playPauseButtonPin) == LOW && powerOn) {
    delay(50); // 디바운스
    if (digitalRead(playPauseButtonPin) == LOW) {
      if (isPlaying) {
        myDFPlayer.pause();
        Serial.println(F("Paused"));
      } else {
        myDFPlayer.start();
        Serial.println(F("Playing"));
      }
      isPlaying = !isPlaying;
      updateDisplay();
      while (digitalRead(playPauseButtonPin) == LOW); // 버튼이 릴리스될 때까지 대기
    }
  }

 

다음곡 버튼 설정 : 

if (digitalRead(nextButtonPin) == LOW && powerOn) {
    delay(50); // 디바운스
    if (digitalRead(nextButtonPin) == LOW) {
      myDFPlayer.next();
      trackNumber++;
      Serial.print(F("Next track: "));
      Serial.println(trackNumber);
      updateDisplay();
      while (digitalRead(nextButtonPin) == LOW); // 버튼이 릴리스될 때까지 대기
    }
  }

 

이전곡 버튼 설정 : 

 if (digitalRead(prevButtonPin) == LOW && powerOn) {
    delay(50); // 디바운스
    if (digitalRead(prevButtonPin) == LOW) {
      myDFPlayer.previous();
      if (trackNumber > 1) trackNumber--;
      Serial.print(F("Previous track: "));
      Serial.println(trackNumber);
      updateDisplay();
      while (digitalRead(prevButtonPin) == LOW); // 버튼이 릴리스될 때까지 대기
    }
  }

 

볼륨 증가 버튼 설정 : 

if (digitalRead(volumeUpButtonPin) == LOW && powerOn) {
    delay(50); // 디바운스
    if (digitalRead(volumeUpButtonPin) == LOW) {
      if (volume < 30) volume++;
      myDFPlayer.volume(volume);
      Serial.print(F("Volume increased to "));
      Serial.println(volume);
      updateDisplay();
      while (digitalRead(volumeUpButtonPin) == LOW); // 버튼이 릴리스될 때까지 대기
    }
  }

 

볼륨 감소 버튼 설정 :

if (digitalRead(volumeDownButtonPin) == LOW && powerOn) {
    delay(50); // 디바운스
    if (digitalRead(volumeDownButtonPin) == LOW) {
      if (volume > 0) volume--;
      myDFPlayer.volume(volume);
      Serial.print(F("Volume decreased to "));
      Serial.println(volume);
      updateDisplay();
      while (digitalRead(volumeDownButtonPin) == LOW); // 버튼이 릴리스될 때까지 대기
    }
  }

 

자동재생 처리 설정 :

자동재생처리는 음악 재생시 첫 곡이 끝나면 다음곡으로 자동재생하는 기능이다. 

if (myDFPlayer.available() && powerOn) {
    uint8_t type = myDFPlayer.readType();
    if (type == DFPlayerPlayFinished) {
      Serial.println(F("Track finished, playing next track"));
      myDFPlayer.next();
      trackNumber++;
      updateDisplay();
    }
  }

 

디스플레이 업데이트 설정 :

void updateDisplay() {
  display.clearDisplay();
  display.setCursor(0, 0);
  if (powerOn) {
    display.print(F("Power: ON"));
    display.print(F("  Volume: "));
    display.println(volume);
    display.print(F("Track: "));
    display.println(trackNumber);
    display.print(F("Status: "));
    display.println(isPlaying ? "Playing" : "Paused");
  } else {
    display.println(F("Power: OFF"));
  }
  display.display();
}

 

전체 코딩 : 

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <SoftwareSerial.h>
#include <DFRobotDFPlayerMini.h>

#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 32
#define OLED_RESET    -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

SoftwareSerial mySerial(2, 3); // RX, TX
DFRobotDFPlayerMini myDFPlayer;

// 버튼 핀 설정
const int playPauseButtonPin = 4;
const int nextButtonPin = 5;
const int prevButtonPin = 6;
const int volumeUpButtonPin = 7;
const int volumeDownButtonPin = 8;
const int powerButtonPin = 9;

// 볼륨과 트랙 상태 변수
int volume = 10; // 초기 볼륨 (0-30)
int trackNumber = 1; // 재생할 트랙 번호
bool isPlaying = false;
bool powerOn = true;

void setup() {
  Serial.begin(9600);
  mySerial.begin(9600);

  // 버튼 입력 모드 설정
  pinMode(playPauseButtonPin, INPUT_PULLUP);
  pinMode(nextButtonPin, INPUT_PULLUP);
  pinMode(prevButtonPin, INPUT_PULLUP);
  pinMode(volumeUpButtonPin, INPUT_PULLUP);
  pinMode(volumeDownButtonPin, INPUT_PULLUP);
  pinMode(powerButtonPin, INPUT_PULLUP);

  // OLED 디스플레이 초기화
  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println(F("SSD1306 allocation failed"));
    while (true);
  }
  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(SSD1306_WHITE);
  
  // DFPlayer 초기화
  if (!myDFPlayer.begin(mySerial)) {
    Serial.println(F("Unable to begin:"));
    Serial.println(F("1. Please recheck the connection!"));
    Serial.println(F("2. Insert the SD card!"));
    while (true);
  }
  Serial.println(F("DFPlayer Mini online."));
  
  // 초기 볼륨 설정
  myDFPlayer.volume(volume);
  Serial.print(F("Volume set to "));
  Serial.println(volume);

  // 첫 번째 트랙 재생
  myDFPlayer.play(trackNumber);
  isPlaying = true;
  Serial.print(F("Playing track "));
  Serial.println(trackNumber);

  // OLED 디스플레이에 초기 정보 표시
  updateDisplay();
}

void loop() {
  // 전원 버튼 읽기
  if (digitalRead(powerButtonPin) == LOW) {
    delay(50); // 디바운스
    if (digitalRead(powerButtonPin) == LOW) {
      powerOn = !powerOn;
      if (powerOn) {
        myDFPlayer.start();
        isPlaying = true;
        Serial.println(F("Power ON"));
      } else {
        myDFPlayer.pause();
        isPlaying = false;
        Serial.println(F("Power OFF"));
      }
      updateDisplay();
      while (digitalRead(powerButtonPin) == LOW); // 버튼이 릴리스될 때까지 대기
    }
  }

  // 재생/정지 버튼 읽기
  if (digitalRead(playPauseButtonPin) == LOW && powerOn) {
    delay(50); // 디바운스
    if (digitalRead(playPauseButtonPin) == LOW) {
      if (isPlaying) {
        myDFPlayer.pause();
        Serial.println(F("Paused"));
      } else {
        myDFPlayer.start();
        Serial.println(F("Playing"));
      }
      isPlaying = !isPlaying;
      updateDisplay();
      while (digitalRead(playPauseButtonPin) == LOW); // 버튼이 릴리스될 때까지 대기
    }
  }

  // 다음곡 버튼 읽기
  if (digitalRead(nextButtonPin) == LOW && powerOn) {
    delay(50); // 디바운스
    if (digitalRead(nextButtonPin) == LOW) {
      myDFPlayer.next();
      trackNumber++;
      Serial.print(F("Next track: "));
      Serial.println(trackNumber);
      updateDisplay();
      while (digitalRead(nextButtonPin) == LOW); // 버튼이 릴리스될 때까지 대기
    }
  }

  // 이전곡 버튼 읽기
  if (digitalRead(prevButtonPin) == LOW && powerOn) {
    delay(50); // 디바운스
    if (digitalRead(prevButtonPin) == LOW) {
      myDFPlayer.previous();
      if (trackNumber > 1) trackNumber--;
      Serial.print(F("Previous track: "));
      Serial.println(trackNumber);
      updateDisplay();
      while (digitalRead(prevButtonPin) == LOW); // 버튼이 릴리스될 때까지 대기
    }
  }

  // 볼륨 증가 버튼 읽기
  if (digitalRead(volumeUpButtonPin) == LOW && powerOn) {
    delay(50); // 디바운스
    if (digitalRead(volumeUpButtonPin) == LOW) {
      if (volume < 30) volume++;
      myDFPlayer.volume(volume);
      Serial.print(F("Volume increased to "));
      Serial.println(volume);
      updateDisplay();
      while (digitalRead(volumeUpButtonPin) == LOW); // 버튼이 릴리스될 때까지 대기
    }
  }

  // 볼륨 감소 버튼 읽기
  if (digitalRead(volumeDownButtonPin) == LOW && powerOn) {
    delay(50); // 디바운스
    if (digitalRead(volumeDownButtonPin) == LOW) {
      if (volume > 0) volume--;
      myDFPlayer.volume(volume);
      Serial.print(F("Volume decreased to "));
      Serial.println(volume);
      updateDisplay();
      while (digitalRead(volumeDownButtonPin) == LOW); // 버튼이 릴리스될 때까지 대기
    }
  }

  // 자동재생 처리
  if (myDFPlayer.available() && powerOn) {
    uint8_t type = myDFPlayer.readType();
    if (type == DFPlayerPlayFinished) {
      Serial.println(F("Track finished, playing next track"));
      myDFPlayer.next();
      trackNumber++;
      updateDisplay();
    }
  }
}

void updateDisplay() {
  display.clearDisplay();
  display.setCursor(0, 0);
  if (powerOn) {
    display.print(F("Power: ON"));
    display.print(F("  Volume: "));
    display.println(volume);
    display.print(F("Track: "));
    display.println(trackNumber);
    display.print(F("Status: "));
    display.println(isPlaying ? "Playing" : "Paused");
  } else {
    display.println(F("Power: OFF"));
  }
  display.display();
}

 

위와 같이 코딩을 작성한 후 아두이노에 업로드 하면 다음과 같이 MP3 플레이어가 작동하는 결과를 볼 수 있다.

 

출력 결과 : 

https://www.youtube.com/watch?v=iIHMpeOKoBc

 

YX5300모듈을 사용하여 기본적인 MP3 플레이어를 만들어 보았다. 여기서 조금만 더 기능을 추가하면 다양한 형태의 플레이어를 만들 수 있다. 

728x90
반응형