mirror of
https://github.com/letscontrolit/ESPEasy.git
synced 2026-07-28 04:07:47 +00:00
Merge branch 'mega' into feature/taskvalueset_by_name
This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
.. include:: ../Plugin/_plugin_substitutions_p11x.repl
|
||||
.. _P111_page:
|
||||
|
||||
|P111_typename|
|
||||
==================================================
|
||||
|
||||
|P111_shortinfo|
|
||||
|
||||
Plugin details
|
||||
--------------
|
||||
|
||||
Type: |P111_type|
|
||||
|
||||
Name: |P111_name|
|
||||
|
||||
Status: |P111_status|
|
||||
|
||||
GitHub: |P111_github|_
|
||||
|
||||
Maintainer: |P111_maintainer|
|
||||
|
||||
Used libraries: |P111_usedlibraries|
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
This SPI device reads the tag ID from Mifare tags, cards and stickers using the NXP MFRC522 NFC chip.
|
||||
|
||||
The value is placed in the Tag variable, and can be read from rules and sent to controllers.
|
||||
|
||||
Settings
|
||||
--------
|
||||
|
||||
.. image:: P111_Settings.png
|
||||
|
||||
**Name**: The name for this task, should be unique.
|
||||
|
||||
**Enabled**: Allows to enable/disable the device.
|
||||
|
||||
This device is connected via SPI, so the SPI interface should be enabled on the Hardware tab. There, also the common SPI pin numbers are shown. CS and other optional pin configurations are to be set in the device cconfiguration.
|
||||
|
||||
The MFRC522 needs at least the CS pin configured, the RST (Reset) pin is optional.
|
||||
|
||||
**CS Pin**: The Chip Select signal, often labeled SDA on the board.
|
||||
|
||||
**RST Pin**: Optional pin that is pulled low when communication with the device fails a few times. Usually labeled RST on the board.
|
||||
|
||||
**Tag removal mode** After scanning a tag, it can be automatically removed (reset). There are 2 removal modes, 'None' and 'Autoremove after Time-out' (default).
|
||||
|
||||
**Tag removal Time-out** (Default 500 mSec) The timeout in milli seconds (range 0 - 60000) after which the last Tag will be automatically removed, if the Time-out option is selected.
|
||||
|
||||
**Value to set on Tag removal** (Default 0) Set a value to the Tag when the previous tag is removed. (Range 0 to 2147483647 as larger values are difficult to store in settings.)
|
||||
|
||||
**Event on Tag removal** (Disabled by default) When enabled sends the removed Tag value as an event and to all enabled controllers.
|
||||
|
||||
Supported hardware
|
||||
------------------
|
||||
|
||||
MFRC522 based NFC RFID reader connected via SPI.
|
||||
|
||||
|P111_usedby|
|
||||
|
||||
.. Commands available
|
||||
.. ^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. .. include:: P111_commands.repl
|
||||
|
||||
.. Events
|
||||
.. ~~~~~~
|
||||
|
||||
.. .. include:: P111_events.repl
|
||||
|
||||
Change log
|
||||
----------
|
||||
|
||||
.. versionadded:: 2.0
|
||||
...
|
||||
|
||||
|added|
|
||||
2021-02-07: Moved from PluginPlayground to main repository.
|
||||
|
||||
Added options for tag reset and event on tag reset.
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 34 KiB |
@@ -130,6 +130,7 @@ There's three different released versions of ESP Easy:
|
||||
":ref:`P106_page`","|P106_status|","P106"
|
||||
":ref:`P107_page`","|P107_status|","P107"
|
||||
":ref:`P108_page`","|P108_status|","P108"
|
||||
":ref:`P111_page`","|P111_status|","P111"
|
||||
|
||||
|
||||
Internal GPIO handling
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
.. |Plugin_Output| replace:: :ref:`P029_page`, :ref:`P038_page`, :ref:`P041_page`, :ref:`P042_page`, :ref:`P043_page`, :ref:`P070_page`
|
||||
.. |Plugin_Position| replace:: :ref:`P013_page`, :ref:`P082_page`
|
||||
.. |Plugin_Regulator| replace:: :ref:`P021_page`
|
||||
.. |Plugin_RFID| replace:: :ref:`P008_page`, :ref:`P017_page`, :ref:`P040_page`
|
||||
.. |Plugin_RFID| replace:: :ref:`P008_page`, :ref:`P017_page`, :ref:`P040_page`, :ref:`P111_page`
|
||||
.. |Plugin_Switch_input| replace:: :ref:`P001_page`, :ref:`P009_page`, :ref:`P019_page`, :ref:`P059_page`, :ref:`P080_page`, :ref:`P091_page`, :ref:`P097_page`
|
||||
.. |Plugin_Touch| replace:: :ref:`P097_page`, :ref:`P099_page`
|
||||
.. |Plugin_Weight| replace:: :ref:`P067_page`
|
||||
|
||||
@@ -9,3 +9,4 @@
|
||||
.. include:: ../Plugin/_plugin_substitutions_p08x.repl
|
||||
.. include:: ../Plugin/_plugin_substitutions_p09x.repl
|
||||
.. include:: ../Plugin/_plugin_substitutions_p10x.repl
|
||||
.. include:: ../Plugin/_plugin_substitutions_p11x.repl
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
|
||||
.. |P111_name| replace:: :cyan:`MFRC5222`
|
||||
.. |P111_type| replace:: :cyan:`RFID`
|
||||
.. |P111_typename| replace:: :cyan:`RFID - MFRC522`
|
||||
.. |P111_porttype| replace:: `.`
|
||||
.. |P111_status| replace:: :yellow:`TESTING`
|
||||
.. |P111_github| replace:: P111_RC522_RFID.ino
|
||||
.. _P111_github: https://github.com/letscontrolit/ESPEasy/blob/mega/src/_P111_RC522_RFID.ino
|
||||
.. |P111_usedby| replace:: `.`
|
||||
.. |P111_shortinfo| replace:: `RFID Reader`
|
||||
.. |P111_maintainer| replace:: `TD-er, twinbee77, tonhuisman`
|
||||
.. |P111_compileinfo| replace:: `.`
|
||||
.. |P111_usedlibraries| replace:: `https://github.com/miguelbalboa/rfid (local copy)`
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,371 @@
|
||||
/**
|
||||
* Library to use Arduino MFRC522 module.
|
||||
*
|
||||
* @authors Dr.Leong, Miguel Balboa, Søren Thing Andersen, Tom Clement, many more! See GitLog.
|
||||
*
|
||||
* For more information read the README.
|
||||
*
|
||||
* Please read this file for an overview and then MFRC522.cpp for comments on the specific functions.
|
||||
*/
|
||||
#ifndef MFRC522_h
|
||||
#define MFRC522_h
|
||||
|
||||
#include "require_cpp11.h"
|
||||
#include "deprecated.h"
|
||||
// Enable integer limits
|
||||
#define __STDC_LIMIT_MACROS
|
||||
#include <stdint.h>
|
||||
#include <Arduino.h>
|
||||
#include <SPI.h>
|
||||
|
||||
#ifndef MFRC522_SPICLOCK
|
||||
#define MFRC522_SPICLOCK (4000000u) // MFRC522 accept upto 10MHz, set to 4MHz.
|
||||
#endif
|
||||
|
||||
// Firmware data for self-test
|
||||
// Reference values based on firmware version
|
||||
// Hint: if needed, you can remove unused self-test data to save flash memory
|
||||
//
|
||||
// Version 0.0 (0x90)
|
||||
// Philips Semiconductors; Preliminary Specification Revision 2.0 - 01 August 2005; 16.1 self-test
|
||||
const byte MFRC522_firmware_referenceV0_0[] PROGMEM = {
|
||||
0x00, 0x87, 0x98, 0x0f, 0x49, 0xFF, 0x07, 0x19,
|
||||
0xBF, 0x22, 0x30, 0x49, 0x59, 0x63, 0xAD, 0xCA,
|
||||
0x7F, 0xE3, 0x4E, 0x03, 0x5C, 0x4E, 0x49, 0x50,
|
||||
0x47, 0x9A, 0x37, 0x61, 0xE7, 0xE2, 0xC6, 0x2E,
|
||||
0x75, 0x5A, 0xED, 0x04, 0x3D, 0x02, 0x4B, 0x78,
|
||||
0x32, 0xFF, 0x58, 0x3B, 0x7C, 0xE9, 0x00, 0x94,
|
||||
0xB4, 0x4A, 0x59, 0x5B, 0xFD, 0xC9, 0x29, 0xDF,
|
||||
0x35, 0x96, 0x98, 0x9E, 0x4F, 0x30, 0x32, 0x8D
|
||||
};
|
||||
// Version 1.0 (0x91)
|
||||
// NXP Semiconductors; Rev. 3.8 - 17 September 2014; 16.1.1 self-test
|
||||
const byte MFRC522_firmware_referenceV1_0[] PROGMEM = {
|
||||
0x00, 0xC6, 0x37, 0xD5, 0x32, 0xB7, 0x57, 0x5C,
|
||||
0xC2, 0xD8, 0x7C, 0x4D, 0xD9, 0x70, 0xC7, 0x73,
|
||||
0x10, 0xE6, 0xD2, 0xAA, 0x5E, 0xA1, 0x3E, 0x5A,
|
||||
0x14, 0xAF, 0x30, 0x61, 0xC9, 0x70, 0xDB, 0x2E,
|
||||
0x64, 0x22, 0x72, 0xB5, 0xBD, 0x65, 0xF4, 0xEC,
|
||||
0x22, 0xBC, 0xD3, 0x72, 0x35, 0xCD, 0xAA, 0x41,
|
||||
0x1F, 0xA7, 0xF3, 0x53, 0x14, 0xDE, 0x7E, 0x02,
|
||||
0xD9, 0x0F, 0xB5, 0x5E, 0x25, 0x1D, 0x29, 0x79
|
||||
};
|
||||
// Version 2.0 (0x92)
|
||||
// NXP Semiconductors; Rev. 3.8 - 17 September 2014; 16.1.1 self-test
|
||||
const byte MFRC522_firmware_referenceV2_0[] PROGMEM = {
|
||||
0x00, 0xEB, 0x66, 0xBA, 0x57, 0xBF, 0x23, 0x95,
|
||||
0xD0, 0xE3, 0x0D, 0x3D, 0x27, 0x89, 0x5C, 0xDE,
|
||||
0x9D, 0x3B, 0xA7, 0x00, 0x21, 0x5B, 0x89, 0x82,
|
||||
0x51, 0x3A, 0xEB, 0x02, 0x0C, 0xA5, 0x00, 0x49,
|
||||
0x7C, 0x84, 0x4D, 0xB3, 0xCC, 0xD2, 0x1B, 0x81,
|
||||
0x5D, 0x48, 0x76, 0xD5, 0x71, 0x61, 0x21, 0xA9,
|
||||
0x86, 0x96, 0x83, 0x38, 0xCF, 0x9D, 0x5B, 0x6D,
|
||||
0xDC, 0x15, 0xBA, 0x3E, 0x7D, 0x95, 0x3B, 0x2F
|
||||
};
|
||||
// Clone
|
||||
// Fudan Semiconductor FM17522 (0x88)
|
||||
const byte FM17522_firmware_reference[] PROGMEM = {
|
||||
0x00, 0xD6, 0x78, 0x8C, 0xE2, 0xAA, 0x0C, 0x18,
|
||||
0x2A, 0xB8, 0x7A, 0x7F, 0xD3, 0x6A, 0xCF, 0x0B,
|
||||
0xB1, 0x37, 0x63, 0x4B, 0x69, 0xAE, 0x91, 0xC7,
|
||||
0xC3, 0x97, 0xAE, 0x77, 0xF4, 0x37, 0xD7, 0x9B,
|
||||
0x7C, 0xF5, 0x3C, 0x11, 0x8F, 0x15, 0xC3, 0xD7,
|
||||
0xC1, 0x5B, 0x00, 0x2A, 0xD0, 0x75, 0xDE, 0x9E,
|
||||
0x51, 0x64, 0xAB, 0x3E, 0xE9, 0x15, 0xB5, 0xAB,
|
||||
0x56, 0x9A, 0x98, 0x82, 0x26, 0xEA, 0x2A, 0x62
|
||||
};
|
||||
|
||||
class MFRC522 {
|
||||
public:
|
||||
// Size of the MFRC522 FIFO
|
||||
static constexpr byte FIFO_SIZE = 64; // The FIFO is 64 bytes.
|
||||
// Default value for unused pin
|
||||
static constexpr uint8_t UNUSED_PIN = UINT8_MAX;
|
||||
|
||||
// MFRC522 registers. Described in chapter 9 of the datasheet.
|
||||
// When using SPI all addresses are shifted one bit left in the "SPI address byte" (section 8.1.2.3)
|
||||
enum PCD_Register : byte {
|
||||
// Page 0: Command and status
|
||||
// 0x00 // reserved for future use
|
||||
CommandReg = 0x01 << 1, // starts and stops command execution
|
||||
ComIEnReg = 0x02 << 1, // enable and disable interrupt request control bits
|
||||
DivIEnReg = 0x03 << 1, // enable and disable interrupt request control bits
|
||||
ComIrqReg = 0x04 << 1, // interrupt request bits
|
||||
DivIrqReg = 0x05 << 1, // interrupt request bits
|
||||
ErrorReg = 0x06 << 1, // error bits showing the error status of the last command executed
|
||||
Status1Reg = 0x07 << 1, // communication status bits
|
||||
Status2Reg = 0x08 << 1, // receiver and transmitter status bits
|
||||
FIFODataReg = 0x09 << 1, // input and output of 64 byte FIFO buffer
|
||||
FIFOLevelReg = 0x0A << 1, // number of bytes stored in the FIFO buffer
|
||||
WaterLevelReg = 0x0B << 1, // level for FIFO underflow and overflow warning
|
||||
ControlReg = 0x0C << 1, // miscellaneous control registers
|
||||
BitFramingReg = 0x0D << 1, // adjustments for bit-oriented frames
|
||||
CollReg = 0x0E << 1, // bit position of the first bit-collision detected on the RF interface
|
||||
// 0x0F // reserved for future use
|
||||
|
||||
// Page 1: Command
|
||||
// 0x10 // reserved for future use
|
||||
ModeReg = 0x11 << 1, // defines general modes for transmitting and receiving
|
||||
TxModeReg = 0x12 << 1, // defines transmission data rate and framing
|
||||
RxModeReg = 0x13 << 1, // defines reception data rate and framing
|
||||
TxControlReg = 0x14 << 1, // controls the logical behavior of the antenna driver pins TX1 and TX2
|
||||
TxASKReg = 0x15 << 1, // controls the setting of the transmission modulation
|
||||
TxSelReg = 0x16 << 1, // selects the internal sources for the antenna driver
|
||||
RxSelReg = 0x17 << 1, // selects internal receiver settings
|
||||
RxThresholdReg = 0x18 << 1, // selects thresholds for the bit decoder
|
||||
DemodReg = 0x19 << 1, // defines demodulator settings
|
||||
// 0x1A // reserved for future use
|
||||
// 0x1B // reserved for future use
|
||||
MfTxReg = 0x1C << 1, // controls some MIFARE communication transmit parameters
|
||||
MfRxReg = 0x1D << 1, // controls some MIFARE communication receive parameters
|
||||
// 0x1E // reserved for future use
|
||||
SerialSpeedReg = 0x1F << 1, // selects the speed of the serial UART interface
|
||||
|
||||
// Page 2: Configuration
|
||||
// 0x20 // reserved for future use
|
||||
CRCResultRegH = 0x21 << 1, // shows the MSB and LSB values of the CRC calculation
|
||||
CRCResultRegL = 0x22 << 1,
|
||||
// 0x23 // reserved for future use
|
||||
ModWidthReg = 0x24 << 1, // controls the ModWidth setting?
|
||||
// 0x25 // reserved for future use
|
||||
RFCfgReg = 0x26 << 1, // configures the receiver gain
|
||||
GsNReg = 0x27 << 1, // selects the conductance of the antenna driver pins TX1 and TX2 for modulation
|
||||
CWGsPReg = 0x28 << 1, // defines the conductance of the p-driver output during periods of no modulation
|
||||
ModGsPReg = 0x29 << 1, // defines the conductance of the p-driver output during periods of modulation
|
||||
TModeReg = 0x2A << 1, // defines settings for the internal timer
|
||||
TPrescalerReg = 0x2B << 1, // the lower 8 bits of the TPrescaler value. The 4 high bits are in TModeReg.
|
||||
TReloadRegH = 0x2C << 1, // defines the 16-bit timer reload value
|
||||
TReloadRegL = 0x2D << 1,
|
||||
TCounterValueRegH = 0x2E << 1, // shows the 16-bit timer value
|
||||
TCounterValueRegL = 0x2F << 1,
|
||||
|
||||
// Page 3: Test Registers
|
||||
// 0x30 // reserved for future use
|
||||
TestSel1Reg = 0x31 << 1, // general test signal configuration
|
||||
TestSel2Reg = 0x32 << 1, // general test signal configuration
|
||||
TestPinEnReg = 0x33 << 1, // enables pin output driver on pins D1 to D7
|
||||
TestPinValueReg = 0x34 << 1, // defines the values for D1 to D7 when it is used as an I/O bus
|
||||
TestBusReg = 0x35 << 1, // shows the status of the internal test bus
|
||||
AutoTestReg = 0x36 << 1, // controls the digital self-test
|
||||
VersionReg = 0x37 << 1, // shows the software version
|
||||
AnalogTestReg = 0x38 << 1, // controls the pins AUX1 and AUX2
|
||||
TestDAC1Reg = 0x39 << 1, // defines the test value for TestDAC1
|
||||
TestDAC2Reg = 0x3A << 1, // defines the test value for TestDAC2
|
||||
TestADCReg = 0x3B << 1 // shows the value of ADC I and Q channels
|
||||
// 0x3C // reserved for production tests
|
||||
// 0x3D // reserved for production tests
|
||||
// 0x3E // reserved for production tests
|
||||
// 0x3F // reserved for production tests
|
||||
};
|
||||
|
||||
// MFRC522 commands. Described in chapter 10 of the datasheet.
|
||||
enum PCD_Command : byte {
|
||||
PCD_Idle = 0x00, // no action, cancels current command execution
|
||||
PCD_Mem = 0x01, // stores 25 bytes into the internal buffer
|
||||
PCD_GenerateRandomID = 0x02, // generates a 10-byte random ID number
|
||||
PCD_CalcCRC = 0x03, // activates the CRC coprocessor or performs a self-test
|
||||
PCD_Transmit = 0x04, // transmits data from the FIFO buffer
|
||||
PCD_NoCmdChange = 0x07, // no command change, can be used to modify the CommandReg register bits without affecting the command, for example, the PowerDown bit
|
||||
PCD_Receive = 0x08, // activates the receiver circuits
|
||||
PCD_Transceive = 0x0C, // transmits data from FIFO buffer to antenna and automatically activates the receiver after transmission
|
||||
PCD_MFAuthent = 0x0E, // performs the MIFARE standard authentication as a reader
|
||||
PCD_SoftReset = 0x0F // resets the MFRC522
|
||||
};
|
||||
|
||||
// MFRC522 RxGain[2:0] masks, defines the receiver's signal voltage gain factor (on the PCD).
|
||||
// Described in 9.3.3.6 / table 98 of the datasheet at http://www.nxp.com/documents/data_sheet/MFRC522.pdf
|
||||
enum PCD_RxGain : byte {
|
||||
RxGain_18dB = 0x00 << 4, // 000b - 18 dB, minimum
|
||||
RxGain_23dB = 0x01 << 4, // 001b - 23 dB
|
||||
RxGain_18dB_2 = 0x02 << 4, // 010b - 18 dB, it seems 010b is a duplicate for 000b
|
||||
RxGain_23dB_2 = 0x03 << 4, // 011b - 23 dB, it seems 011b is a duplicate for 001b
|
||||
RxGain_33dB = 0x04 << 4, // 100b - 33 dB, average, and typical default
|
||||
RxGain_38dB = 0x05 << 4, // 101b - 38 dB
|
||||
RxGain_43dB = 0x06 << 4, // 110b - 43 dB
|
||||
RxGain_48dB = 0x07 << 4, // 111b - 48 dB, maximum
|
||||
RxGain_min = 0x00 << 4, // 000b - 18 dB, minimum, convenience for RxGain_18dB
|
||||
RxGain_avg = 0x04 << 4, // 100b - 33 dB, average, convenience for RxGain_33dB
|
||||
RxGain_max = 0x07 << 4 // 111b - 48 dB, maximum, convenience for RxGain_48dB
|
||||
};
|
||||
|
||||
// Commands sent to the PICC.
|
||||
enum PICC_Command : byte {
|
||||
// The commands used by the PCD to manage communication with several PICCs (ISO 14443-3, Type A, section 6.4)
|
||||
PICC_CMD_REQA = 0x26, // REQuest command, Type A. Invites PICCs in state IDLE to go to READY and prepare for anticollision or selection. 7 bit frame.
|
||||
PICC_CMD_WUPA = 0x52, // Wake-UP command, Type A. Invites PICCs in state IDLE and HALT to go to READY(*) and prepare for anticollision or selection. 7 bit frame.
|
||||
PICC_CMD_CT = 0x88, // Cascade Tag. Not really a command, but used during anti collision.
|
||||
PICC_CMD_SEL_CL1 = 0x93, // Anti collision/Select, Cascade Level 1
|
||||
PICC_CMD_SEL_CL2 = 0x95, // Anti collision/Select, Cascade Level 2
|
||||
PICC_CMD_SEL_CL3 = 0x97, // Anti collision/Select, Cascade Level 3
|
||||
PICC_CMD_HLTA = 0x50, // HaLT command, Type A. Instructs an ACTIVE PICC to go to state HALT.
|
||||
PICC_CMD_RATS = 0xE0, // Request command for Answer To Reset.
|
||||
// The commands used for MIFARE Classic (from http://www.mouser.com/ds/2/302/MF1S503x-89574.pdf, Section 9)
|
||||
// Use PCD_MFAuthent to authenticate access to a sector, then use these commands to read/write/modify the blocks on the sector.
|
||||
// The read/write commands can also be used for MIFARE Ultralight.
|
||||
PICC_CMD_MF_AUTH_KEY_A = 0x60, // Perform authentication with Key A
|
||||
PICC_CMD_MF_AUTH_KEY_B = 0x61, // Perform authentication with Key B
|
||||
PICC_CMD_MF_READ = 0x30, // Reads one 16 byte block from the authenticated sector of the PICC. Also used for MIFARE Ultralight.
|
||||
PICC_CMD_MF_WRITE = 0xA0, // Writes one 16 byte block to the authenticated sector of the PICC. Called "COMPATIBILITY WRITE" for MIFARE Ultralight.
|
||||
PICC_CMD_MF_DECREMENT = 0xC0, // Decrements the contents of a block and stores the result in the internal data register.
|
||||
PICC_CMD_MF_INCREMENT = 0xC1, // Increments the contents of a block and stores the result in the internal data register.
|
||||
PICC_CMD_MF_RESTORE = 0xC2, // Reads the contents of a block into the internal data register.
|
||||
PICC_CMD_MF_TRANSFER = 0xB0, // Writes the contents of the internal data register to a block.
|
||||
// The commands used for MIFARE Ultralight (from http://www.nxp.com/documents/data_sheet/MF0ICU1.pdf, Section 8.6)
|
||||
// The PICC_CMD_MF_READ and PICC_CMD_MF_WRITE can also be used for MIFARE Ultralight.
|
||||
PICC_CMD_UL_WRITE = 0xA2 // Writes one 4 byte page to the PICC.
|
||||
};
|
||||
|
||||
// MIFARE constants that does not fit anywhere else
|
||||
enum MIFARE_Misc {
|
||||
MF_ACK = 0xA, // The MIFARE Classic uses a 4 bit ACK/NAK. Any other value than 0xA is NAK.
|
||||
MF_KEY_SIZE = 6 // A Mifare Crypto1 key is 6 bytes.
|
||||
};
|
||||
|
||||
// PICC types we can detect. Remember to update PICC_GetTypeName() if you add more.
|
||||
// last value set to 0xff, then compiler uses less ram, it seems some optimisations are triggered
|
||||
enum PICC_Type : byte {
|
||||
PICC_TYPE_UNKNOWN ,
|
||||
PICC_TYPE_ISO_14443_4 , // PICC compliant with ISO/IEC 14443-4
|
||||
PICC_TYPE_ISO_18092 , // PICC compliant with ISO/IEC 18092 (NFC)
|
||||
PICC_TYPE_MIFARE_MINI , // MIFARE Classic protocol, 320 bytes
|
||||
PICC_TYPE_MIFARE_1K , // MIFARE Classic protocol, 1KB
|
||||
PICC_TYPE_MIFARE_4K , // MIFARE Classic protocol, 4KB
|
||||
PICC_TYPE_MIFARE_UL , // MIFARE Ultralight or Ultralight C
|
||||
PICC_TYPE_MIFARE_PLUS , // MIFARE Plus
|
||||
PICC_TYPE_MIFARE_DESFIRE, // MIFARE DESFire
|
||||
PICC_TYPE_TNP3XXX , // Only mentioned in NXP AN 10833 MIFARE Type Identification Procedure
|
||||
PICC_TYPE_NOT_COMPLETE = 0xff // SAK indicates UID is not complete.
|
||||
};
|
||||
|
||||
// Return codes from the functions in this class. Remember to update GetStatusCodeName() if you add more.
|
||||
// last value set to 0xff, then compiler uses less ram, it seems some optimisations are triggered
|
||||
enum StatusCode : byte {
|
||||
STATUS_OK , // Success
|
||||
STATUS_ERROR , // Error in communication
|
||||
STATUS_COLLISION , // Collission detected
|
||||
STATUS_TIMEOUT , // Timeout in communication.
|
||||
STATUS_NO_ROOM , // A buffer is not big enough.
|
||||
STATUS_INTERNAL_ERROR , // Internal error in the code. Should not happen ;-)
|
||||
STATUS_INVALID , // Invalid argument.
|
||||
STATUS_CRC_WRONG , // The CRC_A does not match
|
||||
STATUS_MIFARE_NACK = 0xff // A MIFARE PICC responded with NAK.
|
||||
};
|
||||
|
||||
// A struct used for passing the UID of a PICC.
|
||||
typedef struct {
|
||||
byte size; // Number of bytes in the UID. 4, 7 or 10.
|
||||
byte uidByte[10];
|
||||
byte sak; // The SAK (Select acknowledge) byte returned from the PICC after successful selection.
|
||||
} Uid;
|
||||
|
||||
// A struct used for passing a MIFARE Crypto1 key
|
||||
typedef struct {
|
||||
byte keyByte[MF_KEY_SIZE];
|
||||
} MIFARE_Key;
|
||||
|
||||
// Member variables
|
||||
Uid uid; // Used by PICC_ReadCardSerial().
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
// Functions for setting up the Arduino
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
MFRC522();
|
||||
MFRC522(byte resetPowerDownPin);
|
||||
MFRC522(byte chipSelectPin, byte resetPowerDownPin);
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
// Basic interface functions for communicating with the MFRC522
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
void PCD_WriteRegister(PCD_Register reg, byte value);
|
||||
void PCD_WriteRegister(PCD_Register reg, byte count, byte *values);
|
||||
byte PCD_ReadRegister(PCD_Register reg);
|
||||
void PCD_ReadRegister(PCD_Register reg, byte count, byte *values, byte rxAlign = 0);
|
||||
void PCD_SetRegisterBitMask(PCD_Register reg, byte mask);
|
||||
void PCD_ClearRegisterBitMask(PCD_Register reg, byte mask);
|
||||
StatusCode PCD_CalculateCRC(byte *data, byte length, byte *result);
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
// Functions for manipulating the MFRC522
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
void PCD_Init();
|
||||
void PCD_Init(byte resetPowerDownPin);
|
||||
void PCD_Init(byte chipSelectPin, byte resetPowerDownPin);
|
||||
void PCD_Reset();
|
||||
void PCD_AntennaOn();
|
||||
void PCD_AntennaOff();
|
||||
byte PCD_GetAntennaGain();
|
||||
void PCD_SetAntennaGain(byte mask);
|
||||
bool PCD_PerformSelfTest();
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
// Power control functions
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
void PCD_SoftPowerDown();
|
||||
void PCD_SoftPowerUp();
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
// Functions for communicating with PICCs
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
StatusCode PCD_TransceiveData(byte *sendData, byte sendLen, byte *backData, byte *backLen, byte *validBits = nullptr, byte rxAlign = 0, bool checkCRC = false);
|
||||
StatusCode PCD_CommunicateWithPICC(byte command, byte waitIRq, byte *sendData, byte sendLen, byte *backData = nullptr, byte *backLen = nullptr, byte *validBits = nullptr, byte rxAlign = 0, bool checkCRC = false);
|
||||
StatusCode PICC_RequestA(byte *bufferATQA, byte *bufferSize);
|
||||
StatusCode PICC_WakeupA(byte *bufferATQA, byte *bufferSize);
|
||||
StatusCode PICC_REQA_or_WUPA(byte command, byte *bufferATQA, byte *bufferSize);
|
||||
virtual StatusCode PICC_Select(Uid *uid, byte validBits = 0);
|
||||
StatusCode PICC_HaltA();
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
// Functions for communicating with MIFARE PICCs
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
StatusCode PCD_Authenticate(byte command, byte blockAddr, MIFARE_Key *key, Uid *uid);
|
||||
void PCD_StopCrypto1();
|
||||
StatusCode MIFARE_Read(byte blockAddr, byte *buffer, byte *bufferSize);
|
||||
StatusCode MIFARE_Write(byte blockAddr, byte *buffer, byte bufferSize);
|
||||
StatusCode MIFARE_Ultralight_Write(byte page, byte *buffer, byte bufferSize);
|
||||
StatusCode MIFARE_Decrement(byte blockAddr, int32_t delta);
|
||||
StatusCode MIFARE_Increment(byte blockAddr, int32_t delta);
|
||||
StatusCode MIFARE_Restore(byte blockAddr);
|
||||
StatusCode MIFARE_Transfer(byte blockAddr);
|
||||
StatusCode MIFARE_GetValue(byte blockAddr, int32_t *value);
|
||||
StatusCode MIFARE_SetValue(byte blockAddr, int32_t value);
|
||||
StatusCode PCD_NTAG216_AUTH(byte *passWord, byte pACK[]);
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
// Support functions
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
StatusCode PCD_MIFARE_Transceive(byte *sendData, byte sendLen, bool acceptTimeout = false);
|
||||
// old function used too much memory, now name moved to flash; if you need char, copy from flash to memory
|
||||
//const char *GetStatusCodeName(byte code);
|
||||
static const __FlashStringHelper *GetStatusCodeName(StatusCode code);
|
||||
static PICC_Type PICC_GetType(byte sak);
|
||||
// old function used too much memory, now name moved to flash; if you need char, copy from flash to memory
|
||||
//const char *PICC_GetTypeName(byte type);
|
||||
static const __FlashStringHelper *PICC_GetTypeName(PICC_Type type);
|
||||
|
||||
// Support functions for debuging
|
||||
void PCD_DumpVersionToSerial();
|
||||
void PICC_DumpToSerial(Uid *uid);
|
||||
void PICC_DumpDetailsToSerial(Uid *uid);
|
||||
void PICC_DumpMifareClassicToSerial(Uid *uid, PICC_Type piccType, MIFARE_Key *key);
|
||||
void PICC_DumpMifareClassicSectorToSerial(Uid *uid, MIFARE_Key *key, byte sector);
|
||||
void PICC_DumpMifareUltralightToSerial();
|
||||
|
||||
// Advanced functions for MIFARE
|
||||
void MIFARE_SetAccessBits(byte *accessBitBuffer, byte g0, byte g1, byte g2, byte g3);
|
||||
bool MIFARE_OpenUidBackdoor(bool logErrors);
|
||||
bool MIFARE_SetUid(byte *newUid, byte uidSize, bool logErrors);
|
||||
bool MIFARE_UnbrickUidSector(bool logErrors);
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
// Convenience functions - does not add extra functionality
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
virtual bool PICC_IsNewCardPresent();
|
||||
virtual bool PICC_ReadCardSerial();
|
||||
|
||||
protected:
|
||||
byte _chipSelectPin; // Arduino pin connected to MFRC522's SPI slave select input (Pin 24, NSS, active low)
|
||||
byte _resetPowerDownPin; // Arduino pin connected to MFRC522's reset and power down input (Pin 6, NRSTPD, active low)
|
||||
StatusCode MIFARE_TwoStepHelper(byte command, byte blockAddr, int32_t data);
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,28 @@
|
||||
/**
|
||||
* Copyright (c) 2016 by Ludwig Grill (www.rotzbua.de)
|
||||
* Simple deprecated workaround for Arduino IDE
|
||||
* IDE 1.6.8 use gcc 4.8 which do not support c++14 [[deprecated]]
|
||||
* Later versions should support c++14, then use c++14 syntax
|
||||
*/
|
||||
#ifndef DEPRECATED_H
|
||||
#define DEPRECATED_H
|
||||
|
||||
#ifdef __has_cpp_attribute
|
||||
#if __has_cpp_attribute(deprecated)
|
||||
#ifndef DEPRECATED
|
||||
#define DEPRECATED [[deprecated]]
|
||||
#endif
|
||||
#ifndef DEPRECATED_MSG
|
||||
#define DEPRECATED_MSG(msg) [[deprecated(msg)]]
|
||||
#endif
|
||||
#endif // __has_cpp_attribute(deprecated)
|
||||
#else
|
||||
#ifndef DEPRECATED
|
||||
#define DEPRECATED __attribute__((deprecated))
|
||||
#endif
|
||||
#ifndef DEPRECATED_MSG
|
||||
#define DEPRECATED_MSG(msg) __attribute__((deprecated(msg)))
|
||||
#endif
|
||||
#endif // __has_cpp_attribute
|
||||
|
||||
#endif // DEPRECATED_H
|
||||
@@ -0,0 +1,12 @@
|
||||
/**
|
||||
* Copyright (c) 2016 by Ludwig Grill (www.rotzbua.de)
|
||||
* Throws error if c++11 is not supported
|
||||
*/
|
||||
#ifndef REQUIRE_CPP11_H
|
||||
#define REQUIRE_CPP11_H
|
||||
|
||||
#if __cplusplus < 201103L
|
||||
#error "This library needs at least a C++11 compliant compiler, maybe compiler argument for C++11 support is missing or if you use Arduino IDE upgrade to version >=1.6.6"
|
||||
#endif
|
||||
|
||||
#endif // REQUIRE_CPP11_H
|
||||
@@ -290,6 +290,7 @@
|
||||
// #define USES_P105 // Atlas_EZO_ORP
|
||||
// #define USES_P106 // BME680
|
||||
// #define USES_P107 // Si1145
|
||||
// #define USES_P111 // RF522 RFID reader
|
||||
|
||||
|
||||
// Special plugins needing IR library
|
||||
|
||||
@@ -0,0 +1,214 @@
|
||||
#include "_Plugin_Helper.h"
|
||||
#ifdef USES_P111
|
||||
//#######################################################################################################
|
||||
//################################ Plugin-214: RC522 SPI RFID reader ####################################
|
||||
//#######################################################################################################
|
||||
|
||||
// Changelog:
|
||||
// 2021-03-13, tonhuisman: Disabled tag removal detection, as it seems impossible to achieve with the MFRC522.
|
||||
// Other takers to try and solve this challenge are welcome.
|
||||
// If this feature is desired, use a PN532 RFID detector, that does support removal detection properly and easily.
|
||||
// Set TimerOption to false as nothing is processed during PLUGIN_READ stage.
|
||||
// 2021-02-10, tonhuisman: Add tag removal detection, can be combined with time-out
|
||||
// 2021-02-07, tonhuisman: Rework to adhere to current plugin requirements, make pin settings user-selectable
|
||||
// Add options for tag removal time-out, as implemented before in P008 (Wiegand RFID) and P017 (PN532 RFID)
|
||||
// Implement PluginStruct to enable multiple instances
|
||||
// 2021-02-07, twinbee77: Adjustments to P129 from PluginPlayground
|
||||
|
||||
#define PLUGIN_111
|
||||
#define PLUGIN_ID_111 111
|
||||
#define PLUGIN_NAME_111 "RFID - RC522 [TESTING]"
|
||||
#define PLUGIN_VALUENAME1_111 "Tag"
|
||||
|
||||
#include "src/PluginStructs/P111_data_struct.h"
|
||||
|
||||
#define P111_NO_KEY 0xFFFFFFFF
|
||||
|
||||
// #define P111_USE_REMOVAL // Enable (real) Tag Removal detection options
|
||||
|
||||
boolean Plugin_111(byte function, struct EventStruct *event, String& string)
|
||||
{
|
||||
boolean success = false;
|
||||
|
||||
switch (function)
|
||||
{
|
||||
|
||||
case PLUGIN_DEVICE_ADD:
|
||||
{
|
||||
Device[++deviceCount].Number = PLUGIN_ID_111;
|
||||
Device[deviceCount].Type = DEVICE_TYPE_SPI2;
|
||||
Device[deviceCount].VType = Sensor_VType::SENSOR_TYPE_LONG;
|
||||
Device[deviceCount].Ports = 0;
|
||||
Device[deviceCount].PullUpOption = false;
|
||||
Device[deviceCount].InverseLogicOption = false;
|
||||
Device[deviceCount].ValueCount = 1;
|
||||
Device[deviceCount].SendDataOption = true;
|
||||
Device[deviceCount].TimerOption = false;
|
||||
Device[deviceCount].GlobalSyncOption = true;
|
||||
break;
|
||||
}
|
||||
|
||||
case PLUGIN_GET_DEVICENAME:
|
||||
{
|
||||
string = F(PLUGIN_NAME_111);
|
||||
break;
|
||||
}
|
||||
|
||||
case PLUGIN_GET_DEVICEVALUENAMES:
|
||||
{
|
||||
strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[0], PSTR(PLUGIN_VALUENAME1_111));
|
||||
break;
|
||||
}
|
||||
|
||||
case PLUGIN_GET_DEVICEGPIONAMES: //define 'GPIO 1st' name in webserver
|
||||
{
|
||||
event->String1 = formatGpioName_output(F("CS PIN")); // PIN(0)
|
||||
event->String2 = formatGpioName_output(F("RST PIN (optional)")); // PIN(1)
|
||||
break;
|
||||
}
|
||||
|
||||
case PLUGIN_SET_DEFAULTS:
|
||||
{
|
||||
PCONFIG_LONG(1) = 500; // Default 500 msec reset delay
|
||||
break;
|
||||
}
|
||||
|
||||
case PLUGIN_WEBFORM_LOAD:
|
||||
{
|
||||
addFormSubHeader(F("Options"));
|
||||
|
||||
{
|
||||
#ifdef P111_USE_REMOVAL
|
||||
#define P111_removaltypes 3
|
||||
#else // P111_USE_REMOVAL
|
||||
#define P111_removaltypes 2
|
||||
#endif // P111_USE_REMOVAL
|
||||
String removaltype[P111_removaltypes] = {
|
||||
F("None")
|
||||
,F("Autoremove after Time-out")
|
||||
#ifdef P111_USE_REMOVAL
|
||||
,F("Tag removal detection + Time-out")
|
||||
#endif // P111_USE_REMOVAL
|
||||
};
|
||||
int removalopts[P111_removaltypes] = { 1, 0
|
||||
#ifdef P111_USE_REMOVAL
|
||||
, 2
|
||||
#endif // P111_USE_REMOVAL
|
||||
}; // A-typical order for logical order and backward compatibility
|
||||
addFormSelector(F("Tag removal mode"), F("p111_autotagremoval"), P111_removaltypes, removaltype, removalopts, PCONFIG(0));
|
||||
}
|
||||
|
||||
addFormNumericBox(F("Tag removal Time-out"),F("p111_removaltimeout"), PCONFIG_LONG(1), 0, 60000); // 0 to 60 seconds
|
||||
addUnit(F("mSec. (0..60000)"));
|
||||
|
||||
addFormNumericBox(F("Value to set on Tag removal"),F("p111_removalvalue"), PCONFIG_LONG(0), 0, 2147483647); // Max allowed is int = 0x7FFFFFFF ...
|
||||
|
||||
addFormCheckBox(F("Event on Tag removal"), F("p111_sendreset"), PCONFIG(1) == 1);
|
||||
|
||||
success = true;
|
||||
break;
|
||||
}
|
||||
|
||||
case PLUGIN_WEBFORM_SAVE:
|
||||
{
|
||||
PCONFIG(0) = getFormItemInt(F("p111_autotagremoval"));
|
||||
PCONFIG(1) = isFormItemChecked(F("p111_sendreset")) ? 1 : 0;
|
||||
PCONFIG_LONG(0) = getFormItemInt(F("p111_removalvalue"));
|
||||
PCONFIG_LONG(1) = getFormItemInt(F("p111_removaltimeout"));
|
||||
|
||||
success = true;
|
||||
break;
|
||||
}
|
||||
|
||||
case PLUGIN_INIT:
|
||||
{
|
||||
initPluginTaskData(event->TaskIndex, new (std::nothrow) P111_data_struct(PIN(0), PIN(1)));
|
||||
P111_data_struct *P111_data = static_cast<P111_data_struct *>(getPluginTaskData(event->TaskIndex));
|
||||
|
||||
if (nullptr == P111_data) {
|
||||
return success;
|
||||
}
|
||||
|
||||
P111_data->init();
|
||||
|
||||
success = true;
|
||||
break;
|
||||
}
|
||||
|
||||
case PLUGIN_TIMER_IN:
|
||||
{
|
||||
// Reset card id on timeout
|
||||
if (PCONFIG(0) == 0
|
||||
#ifdef P111_USE_REMOVAL
|
||||
|| PCONFIG(0) == 2
|
||||
#endif // P111_USE_REMOVAL
|
||||
) {
|
||||
UserVar.setSensorTypeLong(event->TaskIndex, PCONFIG_LONG(0));
|
||||
addLog(LOG_LEVEL_INFO, F("MFRC522: Removed Tag"));
|
||||
if (PCONFIG(1) == 1) {
|
||||
sendData(event);
|
||||
}
|
||||
success = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case PLUGIN_TEN_PER_SECOND:
|
||||
{
|
||||
P111_data_struct *P111_data = static_cast<P111_data_struct *>(getPluginTaskData(event->TaskIndex));
|
||||
|
||||
if (nullptr == P111_data) {
|
||||
return success;
|
||||
}
|
||||
|
||||
P111_data->counter++; // This variable replaces a static variable in the original implementation
|
||||
if (P111_data->counter == 3) { // Only every 3rd 0.1 second we do a read
|
||||
P111_data->counter = 0;
|
||||
|
||||
unsigned long key = P111_NO_KEY;
|
||||
bool removedTag = false;
|
||||
byte error = P111_data->readCardStatus(&key, &removedTag);
|
||||
|
||||
if (error == 0) {
|
||||
unsigned long old_key = UserVar.getSensorTypeLong(event->TaskIndex);
|
||||
bool new_key = false;
|
||||
|
||||
#ifdef P111_USE_REMOVAL
|
||||
if (removedTag && PCONFIG(0) == 2) { // removal detected and enabled
|
||||
key = PCONFIG_LONG(0);
|
||||
}
|
||||
#endif // P111_USE_REMOVAL
|
||||
|
||||
if (old_key != key && key != P111_NO_KEY) {
|
||||
UserVar.setSensorTypeLong(event->TaskIndex, key);
|
||||
new_key = true;
|
||||
}
|
||||
|
||||
if (loglevelActiveFor(LOG_LEVEL_INFO) && key != P111_NO_KEY) {
|
||||
String log = F("MFRC522: ");
|
||||
if (new_key) {
|
||||
log += F("New Tag: ");
|
||||
} else {
|
||||
log += F("Old Tag: ");
|
||||
}
|
||||
log += key;
|
||||
if (!removedTag) {
|
||||
log += F(" card: ");
|
||||
log += P111_data->getCardName();
|
||||
}
|
||||
addLog(LOG_LEVEL_INFO, log);
|
||||
}
|
||||
|
||||
if (new_key && !removedTag) { // Removal event sent from PLUGIN_TIMER_IN, if any
|
||||
sendData(event);
|
||||
}
|
||||
Scheduler.setPluginTaskTimer(PCONFIG_LONG(1), event->TaskIndex, event->Par1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
#endif // USES_P111
|
||||
@@ -926,6 +926,7 @@ To create/register a plugin, you have to :
|
||||
#define USES_P106 // BME680
|
||||
#define USES_P107 // SI1145 UV index
|
||||
//#define USES_P108 // DDS238-x ZN MODBUS energy meter (was P224 in the Playground)
|
||||
// #define USES_P111 // RC522 RFID reader
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,155 @@
|
||||
#include "../PluginStructs/P111_data_struct.h"
|
||||
|
||||
#ifdef USES_P111
|
||||
|
||||
#include "../PluginStructs/P111_data_struct.h"
|
||||
// Needed also here for PlatformIO's library finder as the .h file
|
||||
// is in a directory which is excluded in the src_filter
|
||||
|
||||
#include <MFRC522.h>
|
||||
|
||||
P111_data_struct::P111_data_struct(byte csPin, byte rstPin) : mfrc522(nullptr), _csPin(csPin), _rstPin(rstPin)
|
||||
{}
|
||||
|
||||
void P111_data_struct::init() {
|
||||
if (mfrc522 == nullptr){
|
||||
mfrc522 = new MFRC522 (_csPin, _rstPin); // Instantiate a MFRC522
|
||||
mfrc522->PCD_Init(); // Initialize MFRC522 reader
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* read status and tag
|
||||
*/
|
||||
byte P111_data_struct::readCardStatus(unsigned long *key, bool *removedTag) {
|
||||
|
||||
byte error = 0;
|
||||
|
||||
uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 };
|
||||
uint8_t uidLength;
|
||||
|
||||
error = readPassiveTargetID(uid, &uidLength);
|
||||
|
||||
switch(error) {
|
||||
case 1: // Read error
|
||||
{
|
||||
errorCount++;
|
||||
removedState = false;
|
||||
String log = F("MFRC522: Read error: ");
|
||||
log += errorCount;
|
||||
addLog(LOG_LEVEL_ERROR, log);
|
||||
break;
|
||||
}
|
||||
case 2: // No tag found
|
||||
if (!removedState) {
|
||||
removedState = true;
|
||||
*removedTag = true;
|
||||
error = 0; // pass through that removal just once
|
||||
}
|
||||
errorCount = 0;
|
||||
break;
|
||||
default: // Read a tag correctly
|
||||
errorCount = 0;
|
||||
removedState = false; // No longer removed
|
||||
break;
|
||||
}
|
||||
|
||||
if (errorCount > 2) { // if three consecutive read errors, reset MFRC522
|
||||
reset(_csPin,_rstPin);
|
||||
}
|
||||
unsigned long tmpKey = uid[0];
|
||||
for (uint8_t i = 1; i < 4; i++) {
|
||||
tmpKey <<= 8;
|
||||
tmpKey += uid[i];
|
||||
}
|
||||
*key = tmpKey;
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns last read card (type) name
|
||||
*/
|
||||
String P111_data_struct::getCardName() {
|
||||
return mfrc522->PICC_GetTypeName(mfrc522->PICC_GetType(mfrc522->uid.sak));
|
||||
}
|
||||
|
||||
/*********************************************************************************************\
|
||||
* MFRC522 init
|
||||
\*********************************************************************************************/
|
||||
bool P111_data_struct::reset(int8_t csPin, int8_t resetPin) {
|
||||
if (resetPin != -1) {
|
||||
String log = F("MFRC522: Reset on pin: ");
|
||||
log += resetPin;
|
||||
addLog(LOG_LEVEL_INFO, log);
|
||||
pinMode(resetPin, OUTPUT);
|
||||
digitalWrite(resetPin, LOW);
|
||||
delay(100);
|
||||
digitalWrite(resetPin, HIGH);
|
||||
pinMode(resetPin, INPUT_PULLUP);
|
||||
delay(10);
|
||||
}
|
||||
|
||||
pinMode(csPin, OUTPUT);
|
||||
digitalWrite(csPin, LOW);
|
||||
|
||||
mfrc522->PCD_Init(csPin, resetPin); // Init MFRC522 module
|
||||
|
||||
//If you set Antenna Gain to Max it will increase reading distance
|
||||
mfrc522->PCD_SetAntennaGain(mfrc522->RxGain_max);
|
||||
|
||||
bool result = mfrc522->PCD_PerformSelfTest(); // perform the test
|
||||
|
||||
if (result) {
|
||||
//String log = F("RC522: Found");
|
||||
// Get the MFRC522 software version
|
||||
byte v = mfrc522->PCD_ReadRegister(mfrc522->VersionReg);
|
||||
|
||||
// When 0x00 or 0xFF is returned, communication probably failed
|
||||
if ((v == 0x00) || (v == 0xFF)) {
|
||||
String log=F("MFRC522: Communication failure, is the MFRC522 properly connected?");
|
||||
addLog(LOG_LEVEL_ERROR,log);
|
||||
return false;
|
||||
} else {
|
||||
String log=F("MFRC522: Software Version: ");
|
||||
if (v == 0x91)
|
||||
log+=F(" = v1.0");
|
||||
else if (v == 0x92)
|
||||
log+=F(" = v2.0");
|
||||
else
|
||||
log+=F(" (unknown),probably a chinese clone?");
|
||||
|
||||
addLog(LOG_LEVEL_INFO, log);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*********************************************************************************************\
|
||||
* RC522 read tag ID
|
||||
\*********************************************************************************************/
|
||||
byte P111_data_struct::readPassiveTargetID(uint8_t *uid, uint8_t *uidLength) { //needed ? see above (not PN532)
|
||||
// Getting ready for Reading PICCs
|
||||
if ( ! mfrc522->PICC_IsNewCardPresent()) { //If a new PICC placed to RFID reader continue
|
||||
return 2;
|
||||
}
|
||||
addLog(LOG_LEVEL_INFO, F("MFRC522: New Card Detected"));
|
||||
if ( ! mfrc522->PICC_ReadCardSerial()) { //Since a PICC placed get Serial and continue
|
||||
return 1;
|
||||
}
|
||||
|
||||
// There are Mifare PICCs which have 4 byte or 7 byte UID care if you use 7 byte PICC
|
||||
// I think we should assume every PICC as they have 4 byte UID
|
||||
// Until we support 7 byte PICCs
|
||||
addLog(LOG_LEVEL_INFO, F("MFRC522: Scanned PICC's UID"));
|
||||
for (uint8_t i = 0; i < 4; i++) { //
|
||||
uid[i] = mfrc522->uid.uidByte[i];
|
||||
}
|
||||
*uidLength = 4;
|
||||
mfrc522->PICC_HaltA(); // Stop reading
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#endif // ifdef USES_P111
|
||||
@@ -0,0 +1,32 @@
|
||||
#ifndef PLUGINSTRUCTS_P111_DATA_STRUCT_H
|
||||
#define PLUGINSTRUCTS_P111_DATA_STRUCT_H
|
||||
|
||||
#include "../../_Plugin_Helper.h"
|
||||
#ifdef USES_P111
|
||||
|
||||
#include <MFRC522.h>
|
||||
|
||||
struct P111_data_struct : public PluginTaskData_base {
|
||||
|
||||
P111_data_struct(byte csPin, byte rstPin);
|
||||
void init();
|
||||
byte readCardStatus(unsigned long *key, bool *removedTag);
|
||||
String getCardName();
|
||||
|
||||
MFRC522 *mfrc522;
|
||||
|
||||
byte counter = 0;
|
||||
|
||||
private:
|
||||
bool reset(int8_t csPin, int8_t resetPin);
|
||||
byte readPassiveTargetID(uint8_t *uid, uint8_t *uidLength);
|
||||
|
||||
byte _csPin;
|
||||
byte _rstPin;
|
||||
|
||||
byte errorCount = 0;
|
||||
bool removedState = true; // On startup, there will usually not be a tag nearby
|
||||
};
|
||||
|
||||
#endif // ifdef USES_P111
|
||||
#endif // ifndef PLUGINSTRUCTS_P111_DATA_STRUCT_H
|
||||
Reference in New Issue
Block a user