Count Taps With a Cheap Tag: The NTAG21x Counter and ASCII Mirror
NTAG213/215/216 tags can count taps and mirror their own UID into a URL for a few cents of extra memory. Here's how the counter and ASCII mirror actually work, how to set them up, and why they're analytics — not proof a tag is genuine.
Quick answer
NTAG213, NTAG215, and NTAG216 chips have a built-in 24-bit counter and an ASCII mirror feature that can write the tag's UID, its tap count, or both as plain hex text straight into a URL you've already written to the tag. No app server, no per-tag database lookup — the chip does the substitution itself on every read. It's a cheap way to get a unique link and a live tap count out of a tag that costs pennies. It's also not proof that a tag is genuine, and you shouldn't treat it as one.
How the ASCII mirror works
The 24-bit counter
Every NTAG213/215/216 chip includes an NFC counter you turn on with a single configuration bit, NFC_CNT_EN. Once enabled, the counter increments automatically the first time the tag is read after each power-up — the first tap wakes the chip and bumps the count, and it holds steady until the next tap. Writing to the tag doesn't move it, and there's no reset from your side: once it climbs, it only climbs.
MIRROR_CONF, MIRROR_PAGE, and MIRROR_BYTE
The mirror is a separate 2-bit setting, MIRROR_CONF, controlling what gets written into memory as readable text: nothing, the UID alone, the counter alone, or both. Two more settings, MIRROR_PAGE and MIRROR_BYTE, tell the chip exactly where to start writing that text — which is what lets you drop a placeholder inside a URL you've already programmed and have the chip fill it in on every read.
The memory cost is small: a UID ASCII mirror needs 14 bytes (the tag's UID as ASCII hex), and a counter mirror needs 6 bytes. Turn both on and you've spent 20 bytes — real estate you'll notice on a NTAG213's 144-byte budget, a rounding error on a 215 or 216.
Setting it up on NTAG213/215/216 with NFCore
Step-by-step:
- Write your NDEF URL record first, with a placeholder segment where you want the UID and/or counter to appear.
- Enable NFC_CNT_EN and set MIRROR_CONF to match what you want mirrored (UID, counter, or both).
- Set MIRROR_PAGE and MIRROR_BYTE so the mirror lands exactly on your placeholder.
- Do a test read and confirm the URL comes back with real hex values in place of the placeholder.
Common problems and fixes:
- Counter looks stuck. Expected — it only increments once per power-up, on the first read, so back-to-back reads without lifting the tag away won't move it.
- Mirror text isn't showing up. Almost always a MIRROR_PAGE or MIRROR_BYTE offset that doesn't line up with the placeholder in the NDEF record. Recheck the byte math before assuming it's broken.
- Can't change the settings anymore. If the configuration pages are locked (CFGLCK), that's permanent — plan your layout before locking a batch of tags.
Doing this on NFCore specifically: NFCore reads the raw configuration and counter/mirror pages directly, not just the rendered NDEF text, so you can confirm NFC_CNT_EN and MIRROR_CONF are actually set before you ship a batch.
Why this doesn't prove authenticity
Here's the honest limitation: a plain counter or UID mirror isn't cryptographically tied to the tap that produced it. Someone can capture the URL from a single genuine read — UID and counter frozen at that moment — and print it on a fake tag or sticker. Nothing stops that URL from being reused as many times as someone likes, unless whatever's reading it explicitly checks that the counter only ever moves forward.
That's a different job from what NTAG 424 DNA's SUN and SDM features do: they encrypt the UID and counter together with a key unique to that chip, so the URL changes unpredictably on every tap and can be verified server-side. If your goal is NFC product authentication — proving an item is genuine, not just counting scans — a NTAG213/215/216 counter and mirror is the wrong tool.
For tap analytics on packaging, event stickers, or a poster you own and control, it's a good fit. Just don't let "the counter went up" stand in for "this is real."
Frequently Asked Questions
Does the NFC counter increment every time I write to the tag, or only on reads?
Only on reads. The NFC_CNT_EN counter increments on the first valid read after each power-up of the chip — writing to the tag with an app or programmer doesn't touch it.
How much memory does enabling both the UID and counter mirror cost me?
Both together run 20 bytes: 14 for the UID as ASCII hex, 6 for the counter. That's a dent in a NTAG213's 144-byte budget, but on a 215 or 216 you won't even notice.
Can I use the counter to prove a tag hasn't been cloned?
No — don't lean on it for that. It just records that a tap happened. Capture one genuine URL and you can print it on a fake tag as many times as you want; nothing in a plain counter stops the replay. NTAG 424 DNA's encrypted SUN messaging is built for that job instead.
Will the mirror still work once I lock the tag's configuration?
Yes — locking the configuration pages prevents anyone from changing MIRROR_CONF, MIRROR_PAGE, or MIRROR_BYTE afterward, but the mirror itself keeps updating on every read. That's the normal setup for a shipped product: configure once, lock it, then let every unit mirror its own UID and counter forever.
The takeaway
A NTAG213 that costs a few cents can do dynamic-feeling tap tracking with zero backend — two configuration bits and one placeholder in a URL you already wrote. Just be clear-eyed about what it's telling you: a count of taps, not proof of anything. If what you actually need is to prove a tag is genuine, that's a different chip and a different feature set. Open NFCore, check a tag's configuration pages, and confirm NFC_CNT_EN and MIRROR_CONF are set the way you expect before you ship it.