Merge pull request #5 from kkloesener/master

Updated Version with TwoWire Support
This commit is contained in:
Semaf Electronics
2021-03-30 16:04:31 +02:00
committed by GitHub
7 changed files with 480 additions and 32 deletions

54
examples/MFRC522_i2c.ino Normal file
View File

@ -0,0 +1,54 @@
#include <Wire.h>
#include "MFRC522_I2C.h"
#define RST_PIN 6 // Arduino UNO Pin
// #define RST_PIN 14 // D5 Pin on NodeMCU
// 0x28 is i2c address on SDA. Check your address with i2cscanner if not match.
MFRC522 mfrc522(0x28, RST_PIN); // Create MFRC522 instance.
void setup() {
Serial.begin(115200); // Initialize serial communications with the PC
Wire.begin(); // Initialize I2C
mfrc522.PCD_Init(); // Init MFRC522
ShowReaderDetails(); // Show details of PCD - MFRC522 Card Reader details
Serial.println(F("Scan PICC to see UID, type, and data blocks..."));
}
void loop() {
// Look for new cards, and select one if present
if ( ! mfrc522.PICC_IsNewCardPresent() || ! mfrc522.PICC_ReadCardSerial() ) {
delay(50);
return;
}
// Now a card is selected. The UID and SAK is in mfrc522.uid.
// Dump UID
Serial.print(F("Card UID:"));
for (byte i = 0; i < mfrc522.uid.size; i++) {
Serial.print(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " ");
Serial.print(mfrc522.uid.uidByte[i], HEX);
}
Serial.println();
}
void ShowReaderDetails() {
// Get the MFRC522 software version
byte v = mfrc522.PCD_ReadRegister(mfrc522.VersionReg);
Serial.print(F("MFRC522 Software Version: 0x"));
Serial.print(v, HEX);
if (v == 0x91)
Serial.print(F(" = v1.0"));
else if (v == 0x92)
Serial.print(F(" = v2.0"));
else
Serial.print(F(" (unknown)"));
Serial.println("");
// When 0x00 or 0xFF is returned, communication probably failed
if ((v == 0x00) || (v == 0xFF)) {
Serial.println(F("WARNING: Communication failure, is the MFRC522 properly connected?"));
}
}

View File

@ -0,0 +1,113 @@
#include <Wire.h>
#include "MFRC522_I2C.h"
// I2C GPIOs
#define IIC_CLK 32 // internal
#define IIC_DATA 33 // internal
// 2nd I2C GPIOs
#define RST_PIN 12
#define ext_IIC_CLK 23 // 14-pin-header
#define ext_IIC_DATA 18 // 14-pin-header
TwoWire i2cBusOne = TwoWire(0);
TwoWire i2cBusTwo = TwoWire(1);
MFRC522 mfrc522(RST_PIN , 0x28, i2cBusTwo);
void setup() {
Serial.begin(115200); // Initialize serial communications with the PC
i2cBusOne.begin(IIC_DATA, IIC_CLK, 40000);
i2cBusTwo.begin(ext_IIC_DATA, ext_IIC_CLK, 40000);
}
void loop() {
scanBus1();
delay(3000);
scanBus2();
mfrc522.PCD_Init(); // Init MFRC522
ShowReaderDetails(); // Show details of PCD - MFRC522 Card Reader details
}
void scanBus1 () {
byte error, address;
int nDevices;
Serial.println("Scanning...");
nDevices = 0;
for(address = 1; address < 127; address++ ) {
i2cBusOne.beginTransmission(address);
error = i2cBusOne.endTransmission();
if (error == 0) {
Serial.print("Bus1: I2C device found at address 0x");
if (address<16) {
Serial.print("0");
}
Serial.println(address,HEX);
nDevices++;
}
else if (error==4) {
Serial.print("Unknow error at address 0x");
if (address<16) {
Serial.print("0");
}
Serial.println(address,HEX);
}
}
if (nDevices == 0) {
Serial.println("No I2C devices found\n");
}
else {
Serial.println("done\n");
}
}
void scanBus2 () {
byte error, address;
int nDevices;
Serial.println("Scanning...");
nDevices = 0;
for(address = 1; address < 127; address++ ) {
i2cBusTwo.beginTransmission(address);
error = i2cBusTwo.endTransmission();
if (error == 0) {
Serial.print("Bus2: I2C device found at address 0x");
if (address<16) {
Serial.print("0");
}
Serial.println(address,HEX);
nDevices++;
}
else if (error==4) {
Serial.print("Unknow error at address 0x");
if (address<16) {
Serial.print("0");
}
Serial.println(address,HEX);
}
}
if (nDevices == 0) {
Serial.println("No I2C devices found\n");
}
else {
Serial.println("done\n");
}
}
void ShowReaderDetails() {
// Get the MFRC522 software version
byte v = mfrc522.PCD_ReadRegister(mfrc522.VersionReg);
Serial.print(F("MFRC522 Software Version: 0x"));
Serial.print(v, HEX);
if (v == 0x91)
Serial.print(F(" = v1.0"));
else if (v == 0x92)
Serial.print(F(" = v2.0"));
else
Serial.print(F(" (unknown)"));
Serial.println("");
// When 0x00 or 0xFF is returned, communication probably failed
if ((v == 0x00) || (v == 0xFF)) {
Serial.println(F("WARNING: Communication failure, is the MFRC522 properly connected?"));
}
}

View File

@ -0,0 +1,113 @@
#include <Wire.h>
#include "MFRC522_I2C.h"
// I2C GPIOs
#define IIC_CLK 32 // internal
#define IIC_DATA 33 // internal
// 2nd I2C GPIOs
#define RST_PIN 12
#define ext_IIC_CLK 23 // 14-pin-header
#define ext_IIC_DATA 18 // 14-pin-header
TwoWire i2cBusOne = TwoWire(0);
TwoWire i2cBusTwo = TwoWire(1);
MFRC522 mfrc522(RST_PIN , 0x28, i2cBusTwo);
void setup() {
Serial.begin(115200); // Initialize serial communications with the PC
i2cBusOne.begin(IIC_DATA, IIC_CLK, 40000);
i2cBusTwo.begin(ext_IIC_DATA, ext_IIC_CLK, 40000);
}
void loop() {
scanBus1();
delay(3000);
scanBus2();
mfrc522.PCD_Init(); // Init MFRC522
ShowReaderDetails(); // Show details of PCD - MFRC522 Card Reader details
}
void scanBus1 () {
byte error, address;
int nDevices;
Serial.println("Scanning...");
nDevices = 0;
for(address = 1; address < 127; address++ ) {
i2cBusOne.beginTransmission(address);
error = i2cBusOne.endTransmission();
if (error == 0) {
Serial.print("Bus1: I2C device found at address 0x");
if (address<16) {
Serial.print("0");
}
Serial.println(address,HEX);
nDevices++;
}
else if (error==4) {
Serial.print("Unknow error at address 0x");
if (address<16) {
Serial.print("0");
}
Serial.println(address,HEX);
}
}
if (nDevices == 0) {
Serial.println("No I2C devices found\n");
}
else {
Serial.println("done\n");
}
}
void scanBus2 () {
byte error, address;
int nDevices;
Serial.println("Scanning...");
nDevices = 0;
for(address = 1; address < 127; address++ ) {
i2cBusTwo.beginTransmission(address);
error = i2cBusTwo.endTransmission();
if (error == 0) {
Serial.print("Bus2: I2C device found at address 0x");
if (address<16) {
Serial.print("0");
}
Serial.println(address,HEX);
nDevices++;
}
else if (error==4) {
Serial.print("Unknow error at address 0x");
if (address<16) {
Serial.print("0");
}
Serial.println(address,HEX);
}
}
if (nDevices == 0) {
Serial.println("No I2C devices found\n");
}
else {
Serial.println("done\n");
}
}
void ShowReaderDetails() {
// Get the MFRC522 software version
byte v = mfrc522.PCD_ReadRegister(mfrc522.VersionReg);
Serial.print(F("MFRC522 Software Version: 0x"));
Serial.print(v, HEX);
if (v == 0x91)
Serial.print(F(" = v1.0"));
else if (v == 0x92)
Serial.print(F(" = v2.0"));
else
Serial.print(F(" (unknown)"));
Serial.println("");
// When 0x00 or 0xFF is returned, communication probably failed
if ((v == 0x00) || (v == 0xFF)) {
Serial.println(F("WARNING: Communication failure, is the MFRC522 properly connected?"));
}
}

View File

@ -0,0 +1,131 @@
#include <Wire.h>
#include "MFRC522_I2C.h"
// I2C GPIOs
#define IIC_CLK 32 // internal
#define IIC_DATA 33 // internal
// 2nd I2C GPIOs
#define RST_PIN 12
#define ext_IIC_CLK 23 // 14-pin-header
#define ext_IIC_DATA 18 // 14-pin-header
byte chipAddress = 0x28;
TwoWire i2cBusOne = TwoWire(0);
TwoWire i2cBusTwo = TwoWire(1);
MFRC522 mfrc522(chipAddress, RST_PIN, i2cBusTwo);
void setup() {
byte version;
byte value;
Serial.begin(115200); // Initialize serial communications with the PC
Serial.println("TwoWire Bus 1 initiieren");
i2cBusOne.begin(IIC_DATA, IIC_CLK, 40000);
Serial.println("TwoWire Bus 2 initiieren");
i2cBusTwo.begin(ext_IIC_DATA, ext_IIC_CLK, 40000);
Serial.println("MFRC522 initiieren");
mfrc522.PCD_Init();
Serial.println("MFRC522 Selbsttest");
}
void loop() {
// scanBus1();
scanBus2();
ShowReaderDetails(); // Show details of PCD - MFRC522 Card Reader details
if (mfrc522.PCD_PerformSelfTest()) {
Serial.println("Selftest OK");
} else Serial.println("Selftest not OK");
delay(5000);
}
void scanBus1 () {
byte error, address;
int nDevices;
Serial.println("Scanning...");
nDevices = 0;
for(address = 1; address < 127; address++ ) {
i2cBusOne.beginTransmission(address);
error = i2cBusOne.endTransmission();
if (error == 0) {
Serial.print("Bus1: I2C device found at address 0x");
if (address<16) {
Serial.print("0");
}
Serial.println(address,HEX);
nDevices++;
}
else if (error==4) {
Serial.print("Unknow error at address 0x");
if (address<16) {
Serial.print("0");
}
Serial.println(address,HEX);
}
}
if (nDevices == 0) {
Serial.println("No I2C devices found\n");
}
else {
Serial.println("done\n");
}
}
void scanBus2 () {
byte error, address;
int nDevices;
Serial.println("Scanning...");
nDevices = 0;
for(address = 1; address < 127; address++ ) {
i2cBusTwo.beginTransmission(address);
error = i2cBusTwo.endTransmission();
if (error == 0) {
Serial.print("Bus2: I2C device found at address 0x");
if (address<16) {
Serial.print("0");
}
Serial.println(address,HEX);
nDevices++;
}
else if (error==4) {
Serial.print("Unknow error at address 0x");
if (address<16) {
Serial.print("0");
}
Serial.println(address,HEX);
}
}
/* if (nDevices == 0) {
Serial.println("No I2C devices found\n");
pinMode(RST_PIN, OUTPUT);
if (digitalRead(RST_PIN) == LOW) { //The MFRC522 chip is in power down mode.
digitalWrite(RST_PIN, HIGH); // Exit power down mode. This triggers a hard reset.
// Section 8.8.2 in the datasheet says the oscillator start-up time is the start up time of the crystal + 37,74<37>s. Let us be generous: 50ms.
delay(200);
}
else {
Serial.println("done\n");
}
} */
}
void ShowReaderDetails() {
byte version = mfrc522.PCD_ReadRegister(mfrc522.VersionReg);
switch (version) {
case 0x88: // Fudan Semiconductor FM17522 clone
Serial.println("Fudan Semiconductor FM17522 clone");
break;
case 0x90: // Version 0.0
Serial.println("Version 0.0");
break;
case 0x91: // Version 1.0
Serial.println("Version 1.0");
break;
case 0x92: // Version 2.0
Serial.println("Version 2.0");
break;
default: // Unknown version
Serial.println("Unknown version");
}
}

View File

@ -2,8 +2,8 @@ name=MFRC522 i2c Library
version=1.0
author=arozcan semaf
maintainer=Semaf Electronics
sentence=MFR522 i2c Library to read NFC Tags with Arduino or ESP2866 (NodeMCU)
paragraph=MFR522 i2c Library to read NFC Tags with Arduino or ESP2866 (NodeMCU)
sentence=MFR522 i2c Library to read NFC Tags with Arduino or ESP2866/ESP32 (NodeMCU)
paragraph=MFR522 i2c Library to read NFC Tags with Arduino or ESP2866/ESP32 (NodeMCU)
category=Communication
url=https://github.com/semaf/mfrc522_i2c
url=https://github.com/kkloesener/MFRC522_I2C_Library
architectures=*

View File

@ -19,10 +19,12 @@
* Prepares the output pins.
*/
MFRC522::MFRC522( byte chipAddress,
byte resetPowerDownPin ///< Arduino pin connected to MFRC522's reset and power down input (Pin 6, NRSTPD, active low)
byte resetPowerDownPin, ///< Arduino pin connected to MFRC522's reset and power down input (Pin 6, NRSTPD, active low)
TwoWire *TwoWireInstance
) {
_chipAddress = chipAddress;
_chipAddress = (uint8_t) chipAddress;
_resetPowerDownPin = resetPowerDownPin;
_TwoWireInstance = TwoWireInstance;
} // End constructor
@ -37,10 +39,10 @@ MFRC522::MFRC522( byte chipAddress,
void MFRC522::PCD_WriteRegister( byte reg, ///< The register to write to. One of the PCD_Register enums.
byte value ///< The value to write.
) {
Wire.beginTransmission(_chipAddress);
Wire.write(reg);
Wire.write(value);
Wire.endTransmission();
_TwoWireInstance->beginTransmission(_chipAddress);
_TwoWireInstance->write(reg);
_TwoWireInstance->write(value);
_TwoWireInstance->endTransmission();
} // End PCD_WriteRegister()
/**
@ -51,12 +53,16 @@ void MFRC522::PCD_WriteRegister( byte reg, ///< The register to write to. One o
byte count, ///< The number of bytes to write to the register
byte *values ///< The values to write. Byte array.
) {
Wire.beginTransmission(_chipAddress);
Wire.write(reg);
for (byte index = 0; index < count; index++) {
Wire.write(values[index]);
if (count == 0) {
return;
}
Wire.endTransmission();
uint8_t regist = (uint8_t) reg;
_TwoWireInstance->beginTransmission(_chipAddress);
_TwoWireInstance->write(regist);
for (byte index = 0; index < count; index++) {
_TwoWireInstance->write(values[index]);
}
_TwoWireInstance->endTransmission();
} // End PCD_WriteRegister()
/**
@ -66,13 +72,16 @@ void MFRC522::PCD_WriteRegister( byte reg, ///< The register to write to. One o
byte MFRC522::PCD_ReadRegister( byte reg ///< The register to read from. One of the PCD_Register enums.
) {
byte value;
uint8_t _size = 1;
uint8_t regist;
regist = (uint8_t) reg;
//digitalWrite(_chipSelectPin, LOW); // Select slave
Wire.beginTransmission(_chipAddress);
Wire.write(reg);
Wire.endTransmission();
_TwoWireInstance->beginTransmission(_chipAddress);
_TwoWireInstance->write(regist);
_TwoWireInstance->endTransmission();
Wire.requestFrom(_chipAddress, 1);
value = Wire.read();
_TwoWireInstance->requestFrom(_chipAddress, _size);
value = _TwoWireInstance->read();
return value;
} // End PCD_ReadRegister()
@ -88,13 +97,14 @@ void MFRC522::PCD_ReadRegister( byte reg, ///< The register to read from. One o
if (count == 0) {
return;
}
byte address = reg;
uint8_t _count = (uint8_t) count;
uint8_t regist = (uint8_t) reg;
byte index = 0; // Index in values array.
Wire.beginTransmission(_chipAddress);
Wire.write(address);
Wire.endTransmission();
Wire.requestFrom(_chipAddress, count);
while (Wire.available()) {
_TwoWireInstance->beginTransmission(_chipAddress);
_TwoWireInstance->write(regist);
_TwoWireInstance->endTransmission();
_TwoWireInstance->requestFrom(_chipAddress, _count);
while (_TwoWireInstance->available()) {
if (index == 0 && rxAlign) { // Only update bit positions rxAlign..7 in values[0]
// Create bit mask for bit positions rxAlign..7
byte mask = 0;
@ -102,12 +112,12 @@ void MFRC522::PCD_ReadRegister( byte reg, ///< The register to read from. One o
mask |= (1 << i);
}
// Read value and tell that we want to read the same address again.
byte value = Wire.read();
byte value = _TwoWireInstance->read();
// Apply mask to both current value of values[0] and the new data in value.
values[0] = (values[index] & ~mask) | (value & mask);
}
else { // Normal case
values[index] = Wire.read();
values[index] = _TwoWireInstance->read();
}
index++;
}
@ -180,8 +190,6 @@ byte MFRC522::PCD_CalculateCRC( byte *data, ///< In: Pointer to the data to tra
* Initializes the MFRC522 chip.
*/
void MFRC522::PCD_Init() {
// Set the chipSelectPin as digital output, do not select the slave yet
// Set the resetPowerDownPin as digital output, do not reset or power down.
pinMode(_resetPowerDownPin, OUTPUT);
@ -189,7 +197,7 @@ void MFRC522::PCD_Init() {
if (digitalRead(_resetPowerDownPin) == LOW) { //The MFRC522 chip is in power down mode.
digitalWrite(_resetPowerDownPin, HIGH); // Exit power down mode. This triggers a hard reset.
// Section 8.8.2 in the datasheet says the oscillator start-up time is the start up time of the crystal + 37,74<37>s. Let us be generous: 50ms.
delay(50);
delay(100);
}
else { // Perform a soft reset
PCD_Reset();
@ -219,6 +227,7 @@ void MFRC522::PCD_Reset() {
delay(50);
// Wait for the PowerDown bit in CommandReg to be cleared
while (PCD_ReadRegister(CommandReg) & (1<<4)) {
Serial.println("PCD Still restarting after SoftReset");
// PCD still restarting - unlikely after waiting 50ms, but better safe than sorry.
}
} // End PCD_Reset()
@ -1212,6 +1221,29 @@ const __FlashStringHelper *MFRC522::PICC_GetTypeName(byte piccType ///< One of t
}
} // End PICC_GetTypeName()
/**
* Dumps debug info about the connected PCD to Serial.
* Shows all known firmware versions
*/
void MFRC522::PCD_DumpVersionToSerial() {
// Get the MFRC522 firmware version
byte v = PCD_ReadRegister(VersionReg);
Serial.print(F("Firmware Version: 0x"));
Serial.print(v, HEX);
// Lookup which version
switch(v) {
case 0x88: Serial.println(F(" = (clone)")); break;
case 0x90: Serial.println(F(" = v0.0")); break;
case 0x91: Serial.println(F(" = v1.0")); break;
case 0x92: Serial.println(F(" = v2.0")); break;
case 0x12: Serial.println(F(" = counterfeit chip")); break;
default: Serial.println(F(" = (unknown)"));
}
// When 0x00 or 0xFF is returned, communication probably failed
if ((v == 0x00) || (v == 0xFF))
Serial.println(F("WARNING: Communication failure, is the MFRC522 properly connected?"));
} // End PCD_DumpVersionToSerial()
/**
* Dumps debug info about the selected PICC to Serial.
* On success the PICC is halted after dumping the data.

View File

@ -321,7 +321,8 @@ public:
/////////////////////////////////////////////////////////////////////////////////////
// Functions for setting up the Arduino
/////////////////////////////////////////////////////////////////////////////////////
MFRC522(byte chipAddress, byte resetPowerDownPin);
// MFRC522(byte chipAddress, byte resetPowerDownPin, TwoWire & TwoWireInstance = Wire);
MFRC522(byte chipAddress, byte resetPowerDownPin, TwoWire *TwoWireInstance = &Wire);
/////////////////////////////////////////////////////////////////////////////////////
// Basic interface functions for communicating with the MFRC522
@ -383,6 +384,9 @@ public:
// 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);
const __FlashStringHelper *PICC_GetTypeName(byte type);
// Support functions for debuging
void PCD_DumpVersionToSerial();
void PICC_DumpToSerial(Uid *uid);
void PICC_DumpMifareClassicToSerial(Uid *uid, byte piccType, MIFARE_Key *key);
void PICC_DumpMifareClassicSectorToSerial(Uid *uid, MIFARE_Key *key, byte sector);
@ -399,8 +403,9 @@ public:
bool PICC_ReadCardSerial();
private:
byte _chipAddress;
uint16_t _chipAddress;
byte _resetPowerDownPin; // Arduino pin connected to MFRC522's reset and power down input (Pin 6, NRSTPD, active low)
TwoWire *_TwoWireInstance = NULL; // TwoWire Instance
byte MIFARE_TwoStepHelper(byte command, byte blockAddr, long data);
};