2023-09-10 20:28:27 +01:00
|
|
|
//
|
|
|
|
// Created by trotfunky on 10/09/23.
|
|
|
|
//
|
|
|
|
|
|
|
|
#ifndef JIN_BARBAPAPA_RFID_H
|
|
|
|
#define JIN_BARBAPAPA_RFID_H
|
|
|
|
|
|
|
|
#include <Arduino.h>
|
|
|
|
#include <Wire.h>
|
|
|
|
#include <SPI.h>
|
|
|
|
#include <SD.h>
|
|
|
|
#include <Metro.h>
|
|
|
|
|
|
|
|
#include <MFRC522v2.h>
|
|
|
|
#include <MFRC522DriverPinSimple.h>
|
|
|
|
#include <MFRC522DriverSPI.h>
|
|
|
|
|
2023-10-21 16:00:08 +01:00
|
|
|
#include "IDs.h"
|
2023-09-10 20:28:27 +01:00
|
|
|
#include "Pinout.h"
|
|
|
|
|
|
|
|
/***
|
|
|
|
* Linked list containing the uids of the tags and the corresponding IDs.
|
|
|
|
*/
|
|
|
|
struct uidNode {
|
|
|
|
MFRC522Constants::Uid uid{};
|
|
|
|
uidNode* next = nullptr;
|
2023-10-16 22:16:47 +01:00
|
|
|
// IDs should be positive integers < 127 as the sign bit is used for direction.
|
2023-09-10 20:28:27 +01:00
|
|
|
int8_t tag_ID = 0;
|
|
|
|
};
|
|
|
|
|
|
|
|
class RFID {
|
|
|
|
public:
|
2023-12-17 21:39:05 +00:00
|
|
|
/***
|
|
|
|
* Use the main SPI port and NFC chip select by default, but allow choosing
|
|
|
|
* an alternate chip select and/or SPI bus if needed to allow multiple
|
|
|
|
* RFID readers in parallel.
|
|
|
|
*/
|
|
|
|
explicit RFID(const uint8_t chipSelect = pin_NFC1_CS, SPIClass &spiBus = SPI) :
|
|
|
|
driverPin(chipSelect), driverSpi(driverPin, spiBus),
|
|
|
|
mfrc(driverSpi), comData{}, sd(SD) {};
|
|
|
|
|
2023-09-10 20:28:27 +01:00
|
|
|
void init();
|
|
|
|
/***
|
|
|
|
* Check if any new tags are present or have left. Only one event is reported
|
|
|
|
* at a time, another call would be needed to get eventual concurrent events.
|
|
|
|
* This updates the respective lists and returns the ID with the direction
|
|
|
|
* of the change.
|
2023-10-16 22:16:47 +01:00
|
|
|
* @return 0 if no change, ID if new tag detected, ID & sign bit if the tag left.
|
2023-09-10 20:28:27 +01:00
|
|
|
*/
|
|
|
|
int8_t checkTags();
|
|
|
|
private:
|
|
|
|
/* Used for "encrypted" communication with the tags. */
|
|
|
|
static MFRC522Constants::MIFARE_Key defaultKey;
|
|
|
|
static constexpr int maxTags = 2;
|
|
|
|
int currentActiveTags = 0;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The linked list tracking active tags.
|
|
|
|
* It is statically allocated so that the memory footprint is constant.
|
|
|
|
*/
|
|
|
|
uidNode activeTagsArray[maxTags];
|
|
|
|
uidNode* activeTags = nullptr;
|
|
|
|
uidNode* nextFreeTagSlot = activeTagsArray;
|
|
|
|
|
2023-12-17 21:39:05 +00:00
|
|
|
MFRC522DriverPinSimple driverPin;
|
|
|
|
MFRC522DriverSPI driverSpi;
|
|
|
|
MFRC522 mfrc;
|
2023-09-10 20:28:27 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Array used to read and write blocks to the tags. Blocks are 16 bytes but
|
|
|
|
* during reads a two-bytes CRC is added.
|
|
|
|
*/
|
|
|
|
byte comData[18];
|
|
|
|
|
|
|
|
SDClass &sd;
|
|
|
|
Metro checkGoneTimer{250};
|
|
|
|
|
|
|
|
/***
|
|
|
|
* Add a tag to the static linked list.
|
|
|
|
* @return The new node, or nullptr if all nodes are allocated.
|
|
|
|
*/
|
|
|
|
uidNode* addActiveTag(const MFRC522Constants::Uid &newTagUid);
|
|
|
|
/***
|
|
|
|
* Remove goneNode from the list and optionally update its predecessor.
|
|
|
|
* @param goneNode Node to remove from the list.
|
|
|
|
* @param previousNode Node to update, can be nullptr if goneNode is the head.
|
|
|
|
*/
|
|
|
|
void removeActiveTag(uidNode* goneNode, uidNode* previousNode);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Read block at blockADdr from tagUid and return if the read succeeded or not.
|
|
|
|
* The read block will be in comData.
|
|
|
|
* @param tagUid Uid of the tag to be read.
|
|
|
|
* @param blockAddr Address of the block to be read.
|
|
|
|
* @return True if read succeeded, false otherwise.
|
|
|
|
*/
|
|
|
|
bool readBlock(MFRC522Constants::Uid &tagUid, byte blockAddr);
|
|
|
|
};
|
|
|
|
|
|
|
|
#endif //JIN_BARBAPAPA_RFID_H
|