Firmware flow
Receive and inspect a reader frame
Control flow reconstructed from the selected readFrame() implementation.
Timeouts, oversized payloads and an invalid trailer stop reception. A checksum mismatch only emits a warning before the routine returns the command and payload length.
This explains a source variant, not a verified RFID read. Checksum warnings do not reject a frame, and the separate EPC scanner does not validate CRC.
Read the implementation
code.txt — framed UART receiver.
static bool readFrame(uint8_t &outCmd, uint8_t *buf, uint16_t &outLen, uint16_t timeoutMs = 300) {
// Seek 0xBB
uint32_t t0 = millis();
while (millis() - t0 < timeoutMs) {
if (Reader.available()) {
if (Reader.read() == 0xBB) break;
}
}
if (millis() - t0 >= timeoutMs) return false;
uint8_t addr, cmd, lh, ll;
if (!readByteWait(addr, timeoutMs)) return false;
if (!readByteWait(cmd, timeoutMs)) return false;
if (!readByteWait(lh, timeoutMs)) return false;
if (!readByteWait(ll, timeoutMs)) return false;
uint16_t len = (uint16_t(lh) << 8) | ll;
if (len > 512) return false; // sanity guard for our fixed buffer
// Read payload
for (uint16_t i = 0; i < len; i++) {
if (!readByteWait(buf[i], timeoutMs)) return false;
}
// CS + tail
uint8_t csh, csl, tail;
if (!readByteWait(csh, timeoutMs)) return false;
if (!readByteWait(csl, timeoutMs)) return false;
if (!readByteWait(tail, timeoutMs)) return false;
if (tail != 0x7E) return false;
// (Optional) verify checksum
uint32_t sum = addr + cmd + lh + ll;
for (uint16_t i = 0; i < len; i++) sum += buf[i];
uint16_t cs = sum & 0xFFFF;
uint16_t got = (uint16_t(csh) << 8) | csl;
if (cs != got) {
Serial.print(F("[WARN] Checksum mismatch, calc=0x"));
Serial.print(cs, HEX);
Serial.print(F(" got=0x"));
Serial.println(got, HEX);
}
outCmd = cmd;
outLen = len;
return true;Technical notes
The reader protocol
The matched source uses ESP32 UART1 with GPIO17 for transmit and GPIO16 for receive. Requests use a 0xBB header, command and length fields, a checksum and a 0x7E trailer. This is a UHF RFID interface, correcting the earlier NFC label.
Bounded frame reception
The receiver waits for each byte, rejects a payload length above 512 and checks the trailer. It reports a checksum mismatch but still returns the frame as received; that diagnostic is not an integrity guarantee.
Inventory inspection
The main loop requests inventory about once per second and also drains unsolicited frames. The EPC scanner prints candidate identifiers from bounded payload positions and skips CRC bytes; reader compatibility and successful tag reads were not tested in this review.