Arduino library for the STMicroelectronics CR95HF 13.56 MHz NFC/RFID transceiver.
- ISO14443-A (NFC-A) protocol support
- 4-byte and 7-byte UID detection
- Automatic anticollision handling
- SAK-based card type identification
- Built-in self-test and diagnostics
- Debug output option
Tested on:
- ESP32C6
- MIFARE Classic 1K/4K
- MIFARE Mini
- MIFARE Ultralight
- NTAG21x series (213, 215, 216)
- MIFARE Plus
- MIFARE DESFire
- Other ISO14443-A compatible tags
The CR95HF must be configured for UART mode:
| CR95HF Pin | Connection |
|---|---|
| SSI_0 | GND |
| SSI_1 | GND |
| TXD | MCU RX |
| RXD | MCU TX |
| VCC | 3.3V |
| GND | GND |
UART Configuration:
- Baud rate: 57600
- Data bits: 8
- Stop bits: 2 (critical!)
- Parity: None
Warning: The CR95HF requires 2 stop bits (8N2). Using 8N1 will cause communication failures.
- Open Arduino IDE
- Go to Sketch → Include Library → Manage Libraries
- Search for "CR95HF"
- Click Install
- Download this repository as ZIP
- In Arduino IDE: Sketch → Include Library → Add .ZIP Library
- Select the downloaded ZIP file
#include <CR95HF.h>
// ESP32-C6 example pins
#define NFC_RX_PIN 1
#define NFC_TX_PIN 2
#define NFC_BAUD 57600
CR95HF nfc(Serial1, NFC_RX_PIN, NFC_TX_PIN, NFC_BAUD);
void setup() {
Serial.begin(115200);
if (!nfc.begin()) {
Serial.println("CR95HF init failed!");
while (1);
}
Serial.println("CR95HF ready");
}
void loop() {
uint8_t uid[10];
uint8_t uidLen, sak;
if (nfc.iso14443aGetUID(uid, uidLen, sak)) {
// Print UID
Serial.print("Tag: ");
for (int i = 0; i < uidLen; i++) {
if (uid[i] < 0x10) Serial.print('0');
Serial.print(uid[i], HEX);
if (i < uidLen - 1) Serial.print(':');
}
// Print card type
Serial.print(" (");
Serial.print(nfc.getCardType(sak));
Serial.println(")");
}
delay(150);
}CR95HF(HardwareSerial& port, int rxPin, int txPin, uint32_t baudRate);| Method | Description |
|---|---|
begin(bool debug = false) |
Initialize CR95HF. Returns true on success. |
iso14443aGetUID(uid, uidLen, sak) |
Read tag UID and SAK byte. |
iso14443aGetUID(uid, uidLen) |
Read tag UID (without SAK). |
getCardType(sak) |
Get card type string from SAK byte. |
selfTest() |
Run self-test, print results to Serial. |
readIDN(out, maxLen) |
Read device identification string. |
measureFieldLevel(level) |
Measure RF field strength (0-100). |
antennaOK() |
Check if antenna is operational. |
| SAK | Card Type |
|---|---|
| 0x00 | MIFARE Ultralight / NTAG |
| 0x08 | MIFARE Classic 1K |
| 0x09 | MIFARE Mini |
| 0x18 | MIFARE Classic 4K |
| 0x20 | MIFARE Plus / DESFire |
| Member | Type | Description |
|---|---|---|
lastATQA[2] |
uint8_t[] | Last received ATQA (for debugging) |
deviceName[20] |
char[] | CR95HF identification string |
- TagReader - Basic tag reading example
- Check wiring connections
- Verify SSI_0 and SSI_1 are tied to GND
- Ensure correct RX/TX pin assignment (TXD→RX, RXD→TX)
- Verify 3.3V power supply
- Run
nfc.selfTest()to check RF field - Verify antenna connection
- Try different tag types
- Check for interference (metal surfaces)
- Increase retry count in your code
- Adjust scan interval
- Check antenna coupling distance
- None.
Copyright (c) 2025 B4E SRL. All rights reserved.
David Baldwin - B4E SRL