diff --git a/examples/MFRC522_i2c.ino b/examples/MFRC522_i2c.ino new file mode 100644 index 0000000..5bb4ee0 --- /dev/null +++ b/examples/MFRC522_i2c.ino @@ -0,0 +1,54 @@ +#include +#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?")); + } +} + diff --git a/examples/dual_i2c_scanner.ino b/examples/dual_i2c_scanner.ino new file mode 100644 index 0000000..a6d2714 --- /dev/null +++ b/examples/dual_i2c_scanner.ino @@ -0,0 +1,113 @@ +#include +#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?")); + } +} + diff --git a/examples/dual_i2c_scanner/dual_i2c_scanner.ino b/examples/dual_i2c_scanner/dual_i2c_scanner.ino new file mode 100644 index 0000000..a6d2714 --- /dev/null +++ b/examples/dual_i2c_scanner/dual_i2c_scanner.ino @@ -0,0 +1,113 @@ +#include +#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?")); + } +} + diff --git a/examples/dual_i2c_scanner_new/dual_i2c_scanner_new.ino b/examples/dual_i2c_scanner_new/dual_i2c_scanner_new.ino new file mode 100644 index 0000000..9ea5b87 --- /dev/null +++ b/examples/dual_i2c_scanner_new/dual_i2c_scanner_new.ino @@ -0,0 +1,131 @@ +#include +#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�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"); + } +} \ No newline at end of file diff --git a/library.properties b/library.properties index d153156..35ef7c5 100644 --- a/library.properties +++ b/library.properties @@ -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=* diff --git a/MFRC522_I2C.cpp b/src/MFRC522_I2C.cpp similarity index 96% rename from MFRC522_I2C.cpp rename to src/MFRC522_I2C.cpp index 252256f..9c4675b 100644 --- a/MFRC522_I2C.cpp +++ b/src/MFRC522_I2C.cpp @@ -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�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. diff --git a/MFRC522_I2C.h b/src/MFRC522_I2C.h similarity index 98% rename from MFRC522_I2C.h rename to src/MFRC522_I2C.h index 298e7f6..8076829 100644 --- a/MFRC522_I2C.h +++ b/src/MFRC522_I2C.h @@ -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); };