Cirkit Designer Logo
Cirkit Designer
Your all-in-one circuit design IDE
Home / 
Project Documentation

RFID-Activated Music Player with Arduino Nano and DFPlayer Mini

Image of RFID-Activated Music Player with Arduino Nano and DFPlayer Mini

Circuit Documentation

Summary

This circuit integrates an RFID reader (RFID-RC522), a DFPlayer Mini MP3 player, a loudspeaker, and an Arduino Nano microcontroller. The RFID reader detects RFID cards and triggers the DFPlayer Mini to play specific audio tracks through the loudspeaker based on the detected card. The Arduino Nano serves as the central controller, managing the RFID reader and the DFPlayer Mini.

Component List

  1. RFID-RC522

    • Description: RFID reader module used to read RFID tags.
    • Pins: VCC (3.3V), RST, GND, IRQ, MISO, MOSI, SCK, SDA
  2. DFPlayer MINI

    • Description: MP3 player module that can play audio files from a microSD card.
    • Pins: VCC, BUSY, RX, USB -, TX, USB +, DAC_R, K2/ADC_KEY, DAC_L, K1/ADC_KEY, SPK1, IO 2, GND, SPK2, IO 1
  3. Loudspeaker

    • Description: Audio output device.
    • Pins: pin1, pin2
  4. Arduino Nano

    • Description: Microcontroller board based on the ATmega328P.
    • Pins: D1/TX, D0/RX, RESET, GND, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11/MOSI, D12/MISO, VIN, 5V, A7, A6, A5, A4, A3, A2, A1, A0, AREF, 3V3, D13/SCK

Wiring Details

RFID-RC522

  • VCC (3.3V): Connected to Arduino Nano 3V3
  • GND: Connected to Arduino Nano GND
  • SDA: Connected to Arduino Nano D10
  • MOSI: Connected to Arduino Nano D11/MOSI
  • MISO: Connected to Arduino Nano D12/MISO
  • SCK: Connected to Arduino Nano D13/SCK

DFPlayer MINI

  • VCC: Connected to Arduino Nano 5V
  • GND: Connected to Arduino Nano GND
  • SPK2: Connected to Loudspeaker pin2
  • IO 1: Not connected

Loudspeaker

  • pin1: Connected to Arduino Nano GND
  • pin2: Connected to DFPlayer MINI SPK2

Arduino Nano

  • 3V3: Connected to RFID-RC522 VCC (3.3V)
  • GND: Connected to DFPlayer MINI GND, RFID-RC522 GND, Loudspeaker pin1
  • 5V: Connected to DFPlayer MINI VCC
  • D10: Connected to RFID-RC522 SDA
  • D11/MOSI: Connected to RFID-RC522 MOSI
  • D12/MISO: Connected to RFID-RC522 MISO
  • D13/SCK: Connected to RFID-RC522 SCK

Code Documentation

#include <SPI.h>
#include <MFRC522.h>
#include "SoftwareSerial.h"
#include "DFRobotDFPlayerMini.h"

// RFID RC522 設定
#define RST_PIN 9   // RST 引腳
#define SS_PIN 10   // SDA 引腳
MFRC522 mfrc522(SS_PIN, RST_PIN);

// DFPlayer 設定
SoftwareSerial mySerial(5, 6); // RX 引腳, TX 引腳
DFRobotDFPlayerMini myDFPlayer;

// 預設的卡片 UID
byte card1[] = {0x63, 0x2D, 0x20, 0x28}; // 卡片 1 的 UID
byte card2[] = {0x33, 0x52, 0xDF, 0x26}; // 卡片 2 的 UID

// 狀態變數
bool isPlaying = false; // 是否正在播放音樂
bool isPaused = false;  // 是否暫停播放
bool cardDetected = false; // 是否有卡片被偵測到
unsigned long lastCheckTime = 0; // 記錄最後檢查時間
const unsigned long checkInterval = 250; // 檢查間隔(毫秒)
const unsigned long stableDelay = 200; // 卡片移開後等待時間(毫秒)
unsigned long lastCardRemoveTime = 0; // 記錄卡片移開的時間
byte lastUID[10]; // 儲存最後一次偵測到的 UID
byte lastUIDSize = 0; // 儲存最後一次偵測到的 UID 大小

bool compareUID(byte *uid1, byte *uid2, byte size); // 比較兩個 UID 是否相同
void copyUID(byte *source, byte *destination, byte size); // 複製 UID

void setup() {
  Serial.begin(9600); // 初始化序列通信
  SPI.begin(); // 啟用 SPI 接口
  mfrc522.PCD_Init(); // 初始化 RC522 模組
  Serial.println("RFID OK");

  mySerial.begin(9600); // 設定軟體串口通信速率
  if (!myDFPlayer.begin(mySerial)) {
    Serial.println("DFPlayer 無法初始化!");
    while (true); // 若 DFPlayer 初始化失敗,則停滯程序
  }
  Serial.println("DFPlayer OK");

  myDFPlayer.volume(10); // 設置音量(0-30)
  Serial.println("音量設置完成");
}

void loop() {
  unsigned long time = millis();
  // 檢查 DFPlayer 狀態
  if (myDFPlayer.available()) {
    if (myDFPlayer.readType() == DFPlayerPlayFinished) {
      Serial.println("音樂播放完成");
      isPlaying = false; // 重置播放狀態
      isPaused = false;  // 重置暫停狀態
    }
  }

  // 每隔一段時間檢查卡片是否仍在範圍內
  if (time - lastCheckTime >= checkInterval) 
  {
    lastCheckTime = time; // 更新最後檢查時間
    // 檢查是否有新卡片被偵測到
    if (mfrc522.PICC_IsNewCardPresent() && mfrc522.PICC_ReadCardSerial()) 
    {
      byte *uid = mfrc522.uid.uidByte; // 讀取卡片 UID
      cardDetected = true; // 設置卡片偵測標誌為 true

      Serial.print("卡片 UID: ");
      for (byte i = 0; i < mfrc522.uid.size; i++) {
        Serial.print(uid[i], HEX);
        Serial.print(" ");
      }
      Serial.println();

      // 如果是相同卡片且音樂暫停,恢復播放
      if (isPaused && compareUID(uid, lastUID, mfrc522.uid.size)) {
        Serial.println("相同卡片恢復播放");
        myDFPlayer.start(); // 恢復播放
        isPlaying = true; // 設置播放狀態為 true
        isPaused = false; // 重置暫停狀態
        return;
      }

      // 比對 UID 並播放對應音樂
      if (compareUID(uid, card1, mfrc522.uid.size)) {
        if (!isPlaying) { // 如果未播放音樂
          Serial.println("播放音樂 1");
          myDFPlayer.play(1); // 播放第 1 首音樂
          isPlaying = true; // 設置播放狀態為 true
          copyUID(uid, lastUID, mfrc522.uid.size); // 儲存當前 UID
          lastUIDSize = mfrc522.uid.size; // 儲存當前 UID 大小
        }
      } else if (compareUID(uid, card2, mfrc522.uid.size)) {
        if (!isPlaying) { // 如果未播放音樂
          Serial.println("播放音樂 2");
          myDFPlayer.play(2); // 播放第 2 首音樂
          isPlaying = true; // 設置播放狀態為 true
          copyUID(uid, lastUID, mfrc522.uid.size); // 儲存當前 UID
          lastUIDSize = mfrc522.uid.size; // 儲存當前 UID 大小
        }
      } else {
        Serial.println("未知卡片");
      }

      // 更新卡片被偵測的時間
      lastCardRemoveTime = time;
    } 
    // 如果卡片沒有被偵測到並且已經過了一段時間
    else if (cardDetected && (time - lastCardRemoveTime >= stableDelay))
    {
      Serial.println("卡片移開,停止