RC522

enitalp
Posts: 60
Joined: Thu Jan 12, 2017 10:03 pm

RC522

Postby enitalp » Fri Feb 24, 2017 10:02 pm

Hi

Trying to use a RC522 RFID board with my ESP32.
Sparkfun ESP32 and https://home.ctw.utwente.nl/slootenvanf ... id-reader/



Started in ESP-IDF and as it was not working i switched to arduino with the same amount of success.
Don't know what i'm doing wrong :

Used https://github.com/Jorgen-VikingGod/ESP8266-MFRC522 as an example.

So :

MISO to GPIO19
MOSI to GPIO23
SCK to GPIO18

RST and SDA to two random GPIO , tried at different places

No crash, but no RFID tag are detected.
It could be that MFRC22.h and cpp are incompatible with the ESP32 somehow even if i manage to make it compile in both ESP-IDF and arduino.

Or i totally missunderstood the connection diagram.

Any idea ?
Thanks

WiFive
Posts: 3529
Joined: Tue Dec 01, 2015 7:35 am

Re: RC522

Postby WiFive » Fri Feb 24, 2017 10:51 pm

Did you set up the pins using spi_bus_initialize or spiattach functions?

enitalp
Posts: 60
Joined: Thu Jan 12, 2017 10:03 pm

Re: RC522

Postby enitalp » Fri Feb 24, 2017 11:12 pm

For ESP-IDF i stole the SPI class. Actually both the ESP-IDF and arduino code are the same as i stole the ESP32 implementation of the arduino part to include in ESP-IDF


Init :

Code: Select all

SPIClass SPI(VSPI);
SPI.begin();
frc522.PCD_Init();

Code: Select all

SPIClass::SPIClass(uint8_t spi_bus)
    :_spi_num(spi_bus)
    ,_spi(NULL)
    ,_use_hw_ss(false)
    ,_sck(-1)
    ,_miso(-1)
    ,_mosi(-1)
    ,_ss(-1)
    ,_div(0)
    ,_freq(1000000)
{}

void SPIClass::begin(int8_t sck, int8_t miso, int8_t mosi, int8_t ss)
{
    if(_spi) {
        return;
    }

    if(!_div) {
        _div = spiFrequencyToClockDiv(_freq);
    }

    _spi = spiStartBus(_spi_num, _div, SPI_MODE0, SPI_MSBFIRST);
    if(!_spi) {
        return;
    }

    _sck = sck;
    _miso = miso;
    _mosi = mosi;
    _ss = ss;

    spiAttachSCK(_spi, _sck);
    spiAttachMISO(_spi, _miso);
    spiAttachMOSI(_spi, _mosi);

}

ESP_Angus
Posts: 2344
Joined: Sun May 08, 2016 4:11 am

Re: RC522

Postby ESP_Angus » Mon Feb 27, 2017 4:41 am

Sorry I don't have an immediate answer for this, but I've moved it to the Arduino forum as it seems like you're using the Arduino SPI library in both cases.

Do you have access to a logic analyzer to capture the behaviour you're currently getting?

enitalp
Posts: 60
Joined: Thu Jan 12, 2017 10:03 pm

Re: RC522

Postby enitalp » Mon Feb 27, 2017 2:22 pm

Not yet. waiting for it in the mail.

I need to check if people have trouble using the spi lib on arduino with the esp32.
it's either the spi lib, the RC522 lib, or my understanding on how to wire the rc5222

enitalp
Posts: 60
Joined: Thu Jan 12, 2017 10:03 pm

Re: RC522

Postby enitalp » Mon Feb 27, 2017 6:40 pm

Fixed.

The SPI code for arduino works. It's the MFRC522 that doesn't work for the ESP32, i'm surprised that this lib works for a DUE or an ESP8266.
For people interested, here the two modifications i did (l_StartTime and l_EndTime):

Code: Select all

MFRC522::StatusCode MFRC522::PCD_CalculateCRC(	byte *data,		///< In: Pointer to the data to transfer to the FIFO for CRC calculation.
												byte length,	///< In: The number of bytes to transfer.
												byte *result	///< Out: Pointer to result buffer. Result is written to result[0..1], low byte first.
					 ) {
	PCD_WriteRegister(CommandReg, PCD_Idle);		// Stop any active command.
	PCD_WriteRegister(DivIrqReg, 0x04);				// Clear the CRCIRq interrupt request bit
	PCD_SetRegisterBitMask(FIFOLevelReg, 0x80);		// FlushBuffer = 1, FIFO initialization
	PCD_WriteRegister(FIFODataReg, length, data);	// Write data to the FIFO
	PCD_WriteRegister(CommandReg, PCD_CalcCRC);		// Start the calculation
	
	// Wait for the CRC calculation to complete. Each iteration of the while-loop takes 17.73μs.
	uint32_t l_StartTime = xTaskGetTickCount() * portTICK_PERIOD_MS;
	byte n;
	while (true) {
		n = PCD_ReadRegister(DivIrqReg);	// DivIrqReg[7..0] bits are: Set2 reserved reserved MfinActIRq reserved CRCIRq reserved reserved
		if (n & 0x04) {						// CRCIRq bit set - calculation done
			break;
		}
		uint32_t l_EndTime= xTaskGetTickCount() * portTICK_PERIOD_MS;
		if (l_EndTime-l_StartTime>89) {						// The emergency break. We will eventually terminate on this one after 89ms. Communication with the MFRC522 might be down.
			return STATUS_TIMEOUT;
		}
	}
	PCD_WriteRegister(CommandReg, PCD_Idle);		// Stop calculating CRC for new content in the FIFO.
	
	// Transfer the result from the registers to the result buffer
	result[0] = PCD_ReadRegister(CRCResultRegL);
	result[1] = PCD_ReadRegister(CRCResultRegH);
	return STATUS_OK;
} // End PCD_CalculateCRC()

Code: Select all

MFRC522::StatusCode MFRC522::PCD_CommunicateWithPICC(	byte command,		///< The command to execute. One of the PCD_Command enums.
														byte waitIRq,		///< The bits in the ComIrqReg register that signals successful completion of the command.
														byte *sendData,		///< Pointer to the data to transfer to the FIFO.
														byte sendLen,		///< Number of bytes to transfer to the FIFO.
														byte *backData,		///< NULL or pointer to buffer if data should be read back after executing the command.
														byte *backLen,		///< In: Max number of bytes to write to *backData. Out: The number of bytes returned.
														byte *validBits,	///< In/Out: The number of valid bits in the last byte. 0 for 8 valid bits.
														byte rxAlign,		///< In: Defines the bit position in backData[0] for the first bit received. Default 0.
														bool checkCRC		///< In: True => The last two bytes of the response is assumed to be a CRC_A that must be validated.
									 ) {
	byte n, _validBits;
	uint16_t i;
	
	// Prepare values for BitFramingReg
	byte txLastBits = validBits ? *validBits : 0;
	byte bitFraming = (rxAlign << 4) + txLastBits;		// RxAlign = BitFramingReg[6..4]. TxLastBits = BitFramingReg[2..0]
	
	PCD_WriteRegister(CommandReg, PCD_Idle);			// Stop any active command.
	PCD_WriteRegister(ComIrqReg, 0x7F);					// Clear all seven interrupt request bits
	PCD_SetRegisterBitMask(FIFOLevelReg, 0x80);			// FlushBuffer = 1, FIFO initialization
	PCD_WriteRegister(FIFODataReg, sendLen, sendData);	// Write sendData to the FIFO
	PCD_WriteRegister(BitFramingReg, bitFraming);		// Bit adjustments
	PCD_WriteRegister(CommandReg, command);				// Execute the command
	if (command == PCD_Transceive) {
		PCD_SetRegisterBitMask(BitFramingReg, 0x80);	// StartSend=1, transmission of data starts
	}
	
	uint32_t l_StartTime = xTaskGetTickCount() * portTICK_PERIOD_MS;
	while (true) 
	{
		n = PCD_ReadRegister(ComIrqReg);	// ComIrqReg[7..0] bits are: Set1 TxIRq RxIRq IdleIRq HiAlertIRq LoAlertIRq ErrIRq TimerIRq
		if (n & waitIRq) {					// One of the interrupts that signal success has been set.
			break;
		}
		if (n & 0x01) 
		{						// Timer interrupt - nothing received in 25ms
			return STATUS_TIMEOUT;
		}
		uint32_t l_EndTime = xTaskGetTickCount() * portTICK_PERIOD_MS;
		
		if (l_EndTime-l_StartTime>35) 
		{						// The emergency break. If all other conditions fail we will eventually terminate on this one after 35.7ms. Communication with the MFRC522 might be down.
			return STATUS_TIMEOUT;
		}
	}
	

teonivalois
Posts: 1
Joined: Fri Apr 14, 2017 8:55 pm

Re: RC522

Postby teonivalois » Fri Apr 14, 2017 8:57 pm

@enitalp, I still didn't get it to work... It simply won't detect my ESP32 dev board...

User avatar
kolban
Posts: 1683
Joined: Mon Nov 16, 2015 4:43 pm
Location: Texas, USA

Re: RC522

Postby kolban » Sat Jul 15, 2017 11:24 pm

See also this sample that provides the Arduino based MFRC522 library executing only using ESP-IDF without Arduino library dependencies:

https://esp32.com/viewtopic.php?f=18&t=2442
Free book on ESP32 available here: https://leanpub.com/kolban-ESP32

TiglathIII
Posts: 1
Joined: Fri Nov 10, 2017 5:10 pm

Re: RC522

Postby TiglathIII » Fri Nov 10, 2017 5:27 pm

I had the same problem with my DOIT ESP-WROOM-32 dev kit. I just could not get the MFRC522 board to be initialised. I connected the pins as per recommended even though you can configure the pins:

Code: Select all

#define RFID_SDA 5
#define RFID_SCK 18
#define RFID_MOSI 23
#define RFID_MISO 19
#define RFID_RST 21
Originally I had the RST pin set to 22 then someone suggested that his ESP32 froze until he moved the RST pin to 21. That did not solve my problem though.

I even used the extended constructor for the SPI interface:

Code: Select all

SPI.begin(RFID_SCK, RFID_MISO, RFID_MOSI);
I then started commenting out code related to the RFID reader. I found that I could create an instance of the MFRC522 class:

Code: Select all

MFRC522 rfid = MFRC522(RFID_SDA, RFID_RST);
but as soon as I called:

Code: Select all

rfid.PCD_Init();


my ESP32 froze. I then read somewhere that NodeMCU boards no longer needed the hard reset and found that there was another constructor for the MFRC522 class that removes the need for the reset pin:

Code: Select all

MFRC522 rfid = MFRC522(RFID_SDA);
This fixed the problem! :D

Who is online

Users browsing this forum: No registered users and 62 guests