115 lines
3.7 KiB
C++
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;
|
|
}
|
|
}; |