Community project

RFID Music Assistant Controller

marc nongmaithem

Published August 17, 2026

ESP32
Photo of RFID Music Assistant ControllerGenerated with AI

This project turns RFID tags into wireless music controls by connecting an MFRC522 RFID reader to an ESP32 microcontroller. When a tag is scanned, the device sends the tag's unique ID over WiFi to Home Assistant via MQTT, enabling automation routines that can play, pause, skip, or switch playlists based on which tag is presented to the reader.

The guide provides a complete parts list, wiring diagram showing all five connections between the MFRC522 and ESP32, step-by-step assembly instructions, and ready-to-use firmware that handles WiFi connection, MQTT communication, and tag detection. Readers will learn how to configure WiFi credentials and MQTT settings, then deploy a smart home controller that works with any Home Assistant setup.

Wiring diagram

Interactive · read-only
Wiring diagram for RFID Music Assistant Controller

Pan and zoom to explore the wiring. Remix the project to edit it in your own workspace.

Parts list

Bill of materials
ComponentQtyNotes
MFRC522 RFID ModuleREES52 RFID-RC522 with card/key fob113.56 MHz RFID reader/writer module based on the NXP MFRC522 IC. Communicates over SPI and is commonly sold as an RC522 breakout with an onboard antenna.

Assembly

4 steps
  1. Keep the reader unpowered while wiring

    Unplug the ESP32-C3 from USB before connecting anything. Put the REES52 RC522 module beside the board with its printed pin labels visible.

    • Tip: The RC522 pin marked SDA is its select wire, not the same kind of SDA wire used by some other sensors.
    • Do not connect the RC522 VCC pin to 5V — this reader is a 3.3 V part and 5V can damage it.
  2. Connect power and ground

    Connect RC522 VCC to the ESP32-C3 3V3 pin (power). Connect RC522 GND to any ESP32-C3 GND pin (ground). These two wires let both boards share the same safe power supply.

    • Tip: Use red for the 3V3 wire and black for the GND wire if you have coloured jumper wires.
    • Make sure VCC and GND are not swapped — swapped power can damage the RFID reader.
  3. Connect the four data wires

    Connect RC522 SCK to ESP32-C3 GPIO4 (clock). Connect RC522 MOSI to GPIO6 (data to the reader). Connect RC522 MISO to GPIO5 (data back from the reader). Connect RC522 SDA to GPIO7 (select signal).

    • Tip: Follow the printed GPIO names or numbers on your particular ESP32-C3 board, not just the physical position along the header.
    • Tip: Keep these four wires short and firmly seated so the reader can reliably hear the card.
    • Do not use the RC522 SDA pin as an I2C wire; on this module it is the reader-select signal.
  4. Connect the reset wire

    Connect RC522 RST to ESP32-C3 GPIO3 (reset control). Check that no loose wire can touch a neighbouring pin, then plug the ESP32-C3 into USB.

    • Tip: The supplied white card or key fob should be held flat and close to the reader antenna when testing.
    • Do not place the RFID card directly on exposed metal or loose wires, because that can reduce its read range.

Pin assignments

Board wiring reference
PinConnectionType
3V3rc522_1 VCCpower
GNDrc522_1 GNDground
GPIO 4rc522_1 SCKspi
GPIO 6rc522_1 MOSIspi
GPIO 5rc522_1 MISOspi
GPIO 7rc522_1 SDAspi
GPIO 3rc522_1 RSTdigital

Firmware

ESP32
main.cppDeploy to device
#include <Arduino.h>
#include <WiFi.h>
#include <PubSubClient.h>
#include <SPI.h>
#include <MFRC522.h>

// Replace these three values with the Wi-Fi and MQTT details used by Home Assistant.

// Forward declarations
void connectWiFi();
void connectMqtt();
String tagUid();

const char *WIFI_SSID = "YOUR_WIFI_NAME";
const char *WIFI_PASSWORD = "YOUR_WIFI_PASSWORD";
const char *MQTT_HOST = "192.168.1.50";
const uint16_t MQTT_PORT = 1883;
const char *MQTT_USER = "";
const char *MQTT_PASSWORD = "";

const char *TAG_TOPIC = "home/rfid_reader/tag";
const char *STATUS_TOPIC = "home/rfid_reader/status";

constexpr uint8_t RC522_SCK_PIN = 4;
constexpr uint8_t RC522_MISO_PIN = 5;
constexpr uint8_t RC522_MOSI_PIN = 6;
constexpr uint8_t RC522_CS_PIN = 7;
constexpr uint8_t RC522_RST_PIN = 3;

WiFiClient wifiClient;
PubSubClient mqttClient(wifiClient);
MFRC522 rfid(RC522_CS_PIN, RC522_RST_PIN);

String lastTag = "";
unsigned long lastTagMillis = 0;
constexpr unsigned long RESCAN_DELAY_MS = 2000;

void connectWiFi() {
  if (WiFi.status() == WL_CONNECTED) return;

  WiFi.mode(WIFI_STA);
  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
  Serial.print("Connecting to Wi-Fi");
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print('.');
  }
  Serial.println(" connected");
}

void connectMqtt() {
  while (!mqttClient.connected()) {
    String clientId = "rfid-reader-" + String((uint32_t)(ESP.getEfuseMac() & 0xFFFFFF), HEX);
    Serial.print("Connecting to MQTT");

    bool connected;
    if (strlen(MQTT_USER) > 0) {
      connected = mqttClient.connect(clientId.c_str(), MQTT_USER, MQTT_PASSWORD,
                                     STATUS_TOPIC, 0, true, "offline");
    } else {
      connected = mqttClient.connect(clientId.c_str(), STATUS_TOPIC, 0, true, "offline");
    }

    if (connected) {
      mqttClient.publish(STATUS_TOPIC, "online", true);
      Serial.println(" connected");
    } else {
      Serial.print(" failed, code ");
      Serial.println(mqttClient.state());
      delay(3000);
    }
  }
}

String tagUid() {
  String uid;
  for (byte i = 0; i < rfid.uid.size; i++) {
    if (rfid.uid.uidByte[i] < 0x10) uid += '0';
    uid += String(rfid.uid.uidByte[i], HEX);
  }
  uid.toUpperCase();
  return uid;
}

void setup() {
  Serial.begin(115200);
  SPI.begin(RC522_SCK_PIN, RC522_MISO_PIN, RC522_MOSI_PIN, RC522_CS_PIN);
  rfid.PCD_Init();
  delay(50);
  connectWiFi();
  mqttClient.setServer(MQTT_HOST, MQTT_PORT);
  Serial.println("Present an RFID card or key fob.");
}

void loop() {
  connectWiFi();
  if (!mqttClient.connected()) connectMqtt();
  mqttClient.loop();

  if (!rfid.PICC_IsNewCardPresent() || !rfid.PICC_ReadCardSerial()) return;

  String uid = tagUid();
  const unsigned long now = millis();
  if (uid != lastTag || now - lastTagMillis >= RESCAN_DELAY_MS) {
    mqttClient.publish(TAG_TOPIC, uid.c_str(), false);
    Serial.print("Published RFID tag: ");
    Serial.println(uid);
    lastTag = uid;
    lastTagMillis = now;
  }

  rfid.PICC_HaltA();
  rfid.PCD_StopCrypto1();
  delay(100);
}

“Deploy to device” opens this project in Schematik, where you can flash it to your board over USB.

Remix this project

Make it yours in one click

Open a full copy of this project in your own Schematik workspace — diagram, code, parts, and assembly steps included. Swap the sensor, add features, or redesign the whole thing with AI. The author's original stays untouched.

Open in Schematik