Preview build — page text is a draft awaiting human review. Code badges come from real compiles. The flasher is real but not yet hardware-tested; the Playground is still a preview.

RDM6300 125 kHz RFID with Arduino Uno — read EM4100 cards and fobs

Wire an RDM6300 125 kHz RFID reader to an Arduino Uno R3 on SoftwareSerial D2, check each frame’s checksum and print the card number printed on the tag.

Arduino C++Verified — core avr 1.8.8, 3 Nov 2026Compile-only

Community draft — report a mistake

The RDM6300 is a ₹150 reader for 125 kHz RFID cards and key fobs (EM4100 type). It suits attendance registers, door locks and “tap to start” machines where cheap fobs are already in use.

It is one of the simplest RFID readers to connect to an Uno. It runs from 5V and sends each card’s ID as serial data on its TX pin. The Uno’s hardware serial is busy with USB, so TX goes to SoftwareSerial on D2. The reader needs no commands, so nothing goes back to it.

The sketch collects each 14-byte frame, checks its checksum, and prints both the full tag code and the card number usually printed on the fob. Holding a card in place doesn’t flood the output: repeats of the same tag are ignored for 1.5 s.

Wiring

Arduino Uno R3Only the pins used are shown · 5 V logicRDM6300 125 kHz RFID reader (EM4100)5VGNDD2TXRX (not connected)GND+5VANT1 → Coil antenna wire 1ANT2 → Coil antenna wire 2LED (not connected)
Every connection
Arduino Uno R3RDM6300 125 kHz RFID reader (EM4100)WireNotes
—ANT1—To Coil antenna wire 1 (not drawn)
—ANT2—To Coil antenna wire 2 (not drawn)
D2TXyellow5 V serial at 9600 baud → Uno SoftwareSerial RX.
5V+5VredAbout 50 mA.
GNDGNDblack

5 V (4.5–5.5 V) part, 5 V board. The module needs 5 V and its TX outputs 5 V. On ESP32 and Pico put a 1 kΩ / 2 kΩ divider between RDM6300 TX and the board’s RX. Uno connects directly. RX on the module is unused.

Board quirks

  • The RDM6300 reads 125 kHz EM4100 cards — the thick white cards and grey key fobs used in many Indian offices and hostels. It can’t read 13.56 MHz cards (Mifare, most metro and ID cards); those need an RC522.
  • Everything is 5 V, so TX connects straight to the Uno. Only TX is used; the module’s RX pin stays unconnected.
  • D0/D1 belong to USB, so the reader goes on SoftwareSerial. The sketch parses the 14-byte frame itself and checks its XOR checksum — no extra library needed (the rdm6300 library isn’t in the Arduino Library Manager index we compile against).
  • Keep the coil away from the Uno, metal and switching supplies; noise from them shortens the read range (normally 3–5 cm).

Code

rdm6300-uno.inoArduino C++Open in PlaygroundOpen in PlaygroundFlash
// RDM6300 125 kHz RFID reader on an Arduino Uno R3, read with SoftwareSerial.
// TX → D2 (Uno RX), +5V → 5V, GND → GND, ANT1/ANT2 → the coil antenna. RX unused.
// Each tag sends a 14-byte frame: 0x02, 10 hex chars of data, 2 hex chars of checksum, 0x03.
#include <SoftwareSerial.h>

SoftwareSerial rfid(2, 3);  // RX on D2; D3 is unused (the reader never listens)
char frame[14];
uint8_t pos = 0;
unsigned long lastTag = 0, lastTime = 0;

uint8_t hexVal(char c) {
  if (c >= '0' && c <= '9') return c - '0';
  if (c >= 'A' && c <= 'F') return c - 'A' + 10;
  if (c >= 'a' && c <= 'f') return c - 'a' + 10;
  return 0;
}

uint8_t hexByte(const char* p) { return hexVal(p[0]) << 4 | hexVal(p[1]); }

void handleFrame() {
  uint8_t sum = 0;
  for (uint8_t i = 0; i < 5; i++) sum ^= hexByte(frame + 1 + i * 2);  // XOR of the 5 data bytes
  if (sum != hexByte(frame + 11)) {
    Serial.println(F("Checksum error - ignored"));
    return;
  }
  // The last 4 data bytes are the number printed on most cards and fobs.
  unsigned long id = 0;
  for (uint8_t i = 1; i < 5; i++) id = id << 8 | hexByte(frame + 1 + i * 2);
  if (id == lastTag && millis() - lastTime < 1500) {  // the reader repeats while a tag is held
    lastTime = millis();
    return;
  }
  lastTag = id;
  lastTime = millis();
  Serial.print(F("Tag "));
  Serial.write((const uint8_t*)frame + 1, 10);
  Serial.print(F("  card number "));
  Serial.println(id);
}

void setup() {
  Serial.begin(9600);
  rfid.begin(9600);
  Serial.println(F("RDM6300 on D2 - hold a 125 kHz card near the coil"));
}

void loop() {
  while (rfid.available()) {
    char c = rfid.read();
    if (c == 0x02) pos = 0;  // start of a frame
    if (pos < sizeof(frame)) frame[pos++] = c;
    if (c == 0x03 && pos == sizeof(frame)) handleFrame();
  }
}

Expected serial output

Serial Monitor · 9600Output
RDM6300 on D2 - hold a 125 kHz card near the coil
Tag 1A0049E3B2  card number 4842418
Tag 0F00A13C55  card number 10566741

Common errors

Nothing prints when a card is near

Wrong card type (13.56 MHz), the coil not plugged into ANT1/ANT2, or TX not on D2. The module’s LED (if fitted) blinks on a read.

“Checksum error” often

Noise from a nearby supply or long wires on TX. Move the coil away from the Uno and keep the TX wire short.

The number differs from the one printed on the card

Cards print the last 3 bytes in two parts (e.g. 073,58290) or in decimal. The full 10-character tag code is the unique ID — use that.

↑↓ to move · Enter to open