Files
2026-10-14 00:44:21 +02:00

115 lines
3.7 KiB
C++

#pragma once
#include <Arduino.h>
class RfidReader {
static constexpr int BUFFER_SIZE = 14; // RFID DATA FRAME FORMAT: 1byte head (value: 2), 10byte data (2byte version + 8byte tag), 2byte checksum, 1byte tail (value: 3)
public:
RfidReader(UART& serial)
: _serial(serial) {
}
void begin() {
_serial.begin(9600);
}
void flush() {
while (_serial.available() > 0) {
_serial.read();
}
}
uint32_t tick() {
if (_serial.available() > 0) {
bool call_extract_tag = false;
int val = _serial.read(); // read
if (val == -1) { // no data was read
return 0;
}
if (val == 2) { // RDM630/RDM6300 found a tag => tag incoming
_index = 0;
} else if (val == 3) { // tag has been fully transmitted
call_extract_tag = true; // extract tag at the end of the function call
}
if (_index >= BUFFER_SIZE) { // checking for a _buffer overflow (It's very unlikely that an _buffer overflow comes up!)
Serial.println("Error: Buffer overflow detected!");
return 0;
}
_buffer[_index++] = val;
if (call_extract_tag == true) {
if (_index == BUFFER_SIZE) {
auto tag = extractTag();
return tag;
} else {
_index = 0;
return 0;
}
}
}
return 0;
}
private:
static constexpr int DATA_SIZE = 10; // 10byte data (2byte version + 8byte tag)
static constexpr int DATA_VERSION_SIZE = 2; // 2byte version (actual meaning of these two bytes may vary)
static constexpr int DATA_TAG_SIZE = 8; // 8byte tag
static constexpr int CHECKSUM_SIZE = 2; // 2byte checksum
UART& _serial;
int _index{};
char _buffer[BUFFER_SIZE];
void printVal(const char* label, const char* buff, int size) {
Serial.println(label);
for (int i = 0; i < size; ++i) {
Serial.print(buff);
}
}
uint32_t extractTag() {
char msg_head = _buffer[0];
char* msg_data = _buffer + 1; // 10 byte => data contains 2byte version + 8byte tag
char* msg_data_version = msg_data;
char* msg_data_tag = msg_data + 2;
char* msg_checksum = _buffer + 11; // 2 byte
char msg_tail = _buffer[13];
Serial.println("### Message RawData");
Serial.println(" HHVVVV_______ID_______CKCKTT");
char buff[256];
size_t p = sprintf(&buff[0], " ");
for (size_t i = 0; i < BUFFER_SIZE; i++) {
p = p + sprintf(&buff[p], "%02x", _buffer[i]);
}
Serial.println(buff);
uint32_t tag = hexstr_to_value(msg_data_tag, DATA_TAG_SIZE);
Serial.print("Extracted Tag: ");
Serial.println(tag);
uint32_t checksum = 0;
for (int i = 0; i < DATA_SIZE; i += CHECKSUM_SIZE) {
uint32_t val = hexstr_to_value(msg_data + i, CHECKSUM_SIZE);
checksum ^= val;
}
Serial.print("Extracted Checksum (HEX): ");
Serial.print(checksum, HEX);
if (checksum == hexstr_to_value(msg_checksum, CHECKSUM_SIZE)) {
Serial.print(" (OK)");
} else {
Serial.print(" (NOT OK)");
}
Serial.println("");
Serial.println("--------");
return tag;
}
uint32_t hexstr_to_value(char* str, unsigned int length) {
char temp[16];
memcpy(temp, str, length);
temp[DATA_TAG_SIZE] = '\0';
uint32_t val = strtol(temp, NULL, 16);
return val;
}
};