Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Arduino stuck at PCD_Init() with 3.3V power supply #426

Closed
SheldorAFK opened this issue Oct 7, 2018 · 8 comments
Closed

Arduino stuck at PCD_Init() with 3.3V power supply #426

SheldorAFK opened this issue Oct 7, 2018 · 8 comments
Labels
bug 🐛 a not intended feature

Comments

@SheldorAFK
Copy link

SheldorAFK commented Oct 7, 2018

Step 1: Describe your environment

  • OS version: Win10
  • Arduino IDE version: 1.8.7
  • MFRC522 Library version: v1.4.0 / v1.4.1
  • Arduino device: UNO (China clone)
  • MFRC522 device: RFID-RC522 (China clone)

Step 2: Describe the problem

Starting with library version 1.4.0 the method PICC_ReadCardSerial() is not returning any UID data. I tested with the example sketch DumpInfo.ino as well as with the following minimalistic read loop:

  if (mfrc522.PICC_IsNewCardPresent() && mfrc522.PICC_ReadCardSerial() ) {
    Serial.print("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(); 
    mfrc522.PICC_HaltA();
    delay(1000);
  }

If using any of the 1.3.x library versions (including 1.3.6) both sketches work fine. But when using the libraries 1.4.0 and 1.4.1 the PICC_ReadCardSerial() method fails (returns a status of 0). The only significant change I found in the MFRC522.cpp module was the changed handling of the reset pin initialization inside of the method PCD_Init(). I reverted the associated code section of the v1.4.1 module to the one used in v1.3.6 and after that the sketches worked with the modified v1.4.1 version as well.

This means that at least for my board combination the change introduced in v1.4.0 ("Fixed hang PCD_Init() on non-arduino boards @heziegl" according to the change log) broke the library. The example firmware_check.ino sketch worked flawlessly with any library version and returned the following output:

*****************************
23:38:20.761 -> MFRC522 Digital self test
23:38:20.761 -> *****************************
23:38:20.761 -> Firmware Version: 0x92 = v2.0
23:38:20.761 -> -----------------------------
23:38:20.761 -> Only known versions supported
23:38:20.761 -> -----------------------------
23:38:20.761 -> Performing test...
-----------------------------
23:38:20.808 -> Result: OK

Affected file(s) or example(s):

  • MFRC522.cpp - affected module, methods PCD_Init() and PICC_ReadCardSerial()
  • DumpInfo.ino - example sketch which can be used to reproduce the issue

Steps to reproduce:

  1. Install library version 1.4.0 or 1.4.1
  2. Compile and upload the example sketch DumpInfo.ino to the Arduino device
  3. Place any valid RFID token on the RFID-RC522 reader
  4. Verfiy that no data is logged to the serial output
  5. Revert to library version 1.3.6 or smaller
  6. Compile and upload the example sketch DumpInfo.ino to the Arduino device
  7. Place any valid RFID token on the RFID-RC522 reader
  8. Verfiy that the token data is dumped to the serial output

Observed Results:

  • PICC_ReadCardSerial() does not return any UID data, DumpInfo.ino does not display any information

Expected Results:

  • PICC_ReadCardSerial() populates the UID property and DumpInfo.ino dumps the token information like for versions 1.3.6 and prior:
Firmware Version: 0x92 = v2.0
00:23:57.482 -> Scan PICC to see UID, SAK, type, and data blocks...
Card UID: XX XX XX XX
00:24:14.143 -> Card SAK: 08
00:24:14.143 -> PICC type: MIFARE 1KB
00:24:14.143 -> Sector Block   0  1  2  3   4  5  6  7   8  9 10 11  12 13 14 15  AccessBits
00:24:14.143 ->   15     63   00 00 00 00  00 00 FF 07  80 69 FF FF  FF FF FF FF  [ 0 0 1 ] 
00:24:14.143 ->          62   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ] 
...

Relevant Code:

Original code section of PCD_Init() in version 1.4.0 and 1.4.1 of MFRC522.cpp causing the read issues

	// If a valid pin number has been set, pull device out of power down / reset state.
																					  
	if (_resetPowerDownPin != UNUSED_PIN) {
		// First set the resetPowerDownPin as digital input, to check the MFRC522 power down mode.
		pinMode(_resetPowerDownPin, INPUT);
	
		if (digitalRead(_resetPowerDownPin) == LOW) {	// The MFRC522 chip is in power down mode.
			pinMode(_resetPowerDownPin, OUTPUT);		// Now set the resetPowerDownPin as digital output.
			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);
			hardReset = true;
		}
	}

Reverted code section of PCD_Init() like used in version 1.3.6 of MFRC522.cpp fixing the read issues

	// If a valid pin number has been set, pull device out of power down / reset state.
	// 2018-10-07 - Section replaced with old approach from version 1.3.6 which still worked
	if (_resetPowerDownPin != UNUSED_PIN) {
		// Set the resetPowerDownPin as digital output, do not reset or power down.
		pinMode(_resetPowerDownPin, OUTPUT);
	
		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);
			hardReset = true;
		}
	}

Even though the new code section seems to implement the proper approach because the pinMode reflects the read and write actions accordingly, but for my combination of boards it definately does not work. Maybe switching the pinMode from input to output happens too quickly or is not supported at all by my UNO clone.

It would be great if you could check with other board combinations. Maybe boards from other vendors suffer from the same issue. I am not sure if it makes sense to revert the change in the library because I assume it had been incorporated for a good reason. But it would at least be worth noting for others which might suffer from the same problem.

@Rotzbua
Copy link
Collaborator

Rotzbua commented Oct 8, 2018

Can not reproduce your reported bug.
Just once directly after flashing, but was temporary and solved by dis- and reconnecting the arduino.

@Rotzbua Rotzbua added the need_feedback ↩️ awaiting feedback from people label Oct 8, 2018
@SheldorAFK
Copy link
Author

I tried with the original v1.4.1 lib once again with dis- and reconnecting the Arduino from the PC. But that did not change anything. Then I switched back to the modified MFRC522.cpp and it worked instantaneously (regardless if I try immediately after flashing or following a dis- and reconnect).

Could it be a nasty behaviour caused by the way the Arduinos are automatically enabling pull-up resistors on pins when switching modes depending on the states the pins are in before switching, like explained in https://www.arduino.cc/en/Tutorial/DigitalPins? Maybe the initial states of the reset pins differ on our setups?

Excerpt:

The pullup resistors are controlled by the same registers (internal chip memory locations) that control whether a pin is HIGH or LOW. Consequently, a pin that is configured to have pullup resistors turned on when the pin is an INPUT, will have the pin configured as HIGH if the pin is then switched to an OUTPUT with pinMode(). This works in the other direction as well, and an output pin that is left in a HIGH state will have the pullup resistors set if switched to an input with pinMode().

@SheldorAFK
Copy link
Author

I did not intend to close the case, did this by mistake. Please keep looking into it.

@SheldorAFK SheldorAFK reopened this Oct 8, 2018
@Rotzbua Rotzbua added need_confirmation 🧷 bug report must be confirmed by a second person, write if you have the same issue and removed need_feedback ↩️ awaiting feedback from people labels Oct 8, 2018
@Rotzbua
Copy link
Collaborator

Rotzbua commented Oct 8, 2018

Now tested with two different chinese arduino boards: genuine like version and smd version with ch340.
Both work with mfrc522 library version 1.4.1 and arduino avr board version 1.6.23.

I don't think it's a pullup resistor problem, because the external state should not affect whether there is a pullup or not.

You can try a delay between:

		// First set the resetPowerDownPin as digital input, to check the MFRC522 power down mode.
		pinMode(_resetPowerDownPin, INPUT);
	
		if (digitalRead(_resetPowerDownPin) == LOW) {	// The MFRC522 chip is in power down mode.

Or add some debug messages.

@SheldorAFK
Copy link
Author

I tried several delays between pinMode switching, this did not change a thing. So I grabbed my oszilloscope and checked the differences of the RST pin signal between the two lib versions. By doing so I realized that in OUTPUT mode the voltage level of the PIN9/RST connection is at around 4.8V (the HIGH of the Arduino). After switching it to INPUT mode, the voltage level drops to 3.3V (the HIGH of the RC522 board).

That in turn made me realize that with the new lib version PIN9 stays in INPUT mode in case the RC522 board is not in power down mode (i.e. it's RST pin is HIGH) while it will be left at OUTPUT mode if the board was powered down.

So I added an else branch to the if which sets PIN9 back to OUTPUT mode. Unfortunately that broke the communication with the board completely (probably because the initial level is LOW which sends the RC522 to sleep).

Firmware Version: 0x0 = (unknown)
WARNING: Communication failure, is the MFRC522 properly connected?
Scan PICC to see UID, SAK, type, and data blocks...

So I added a digitalWrite(_resetPowerDownPin, HIGH) to the pinMode(_resetPowerDownPin, OUTPUT) of the else branch which not only brought back the communication with the board but made the library work. But basically that means that the else branch is doing almost the same as the if branch (except for the delay and skipping the soft reset). However one might assume that because the RST pin of the RC522 was in HIGH state before (at 3.3V) putting the PIN9 to HIGH (at 4.8V) should not trigger a reset. In that case the problem with my setup is the "left over" INPUT mode of PIN9. But if setting it to HIGH after putting it to OUTPUT mode did trigger a reset on the RC522, the issue might just be solved by that reset which does not proof anything.

	// If a valid pin number has been set, pull device out of power down / reset state.
	if (_resetPowerDownPin != UNUSED_PIN) {
		// First set the resetPowerDownPin as digital input, to check the MFRC522 power down mode.
		pinMode(_resetPowerDownPin, INPUT);

		if (digitalRead(_resetPowerDownPin) == LOW) {	// The MFRC522 chip is in power down mode.
			pinMode(_resetPowerDownPin, OUTPUT);		// Now set the resetPowerDownPin as digital output.
			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);
			hardReset = true;
		}
		else {
			pinMode(_resetPowerDownPin, OUTPUT);		// Now set the resetPowerDownPin as digital output.			
			digitalWrite(_resetPowerDownPin, HIGH);		// Exit power down mode. This triggers a hard reset.
		}
	}

However I am on a business trip the next two days so I will not be able to make further tests. But maybe you have some additional thoughts in the meantime. Thanks for your support so far.

@Rotzbua Rotzbua added bug 🐛 a not intended feature and removed need_confirmation 🧷 bug report must be confirmed by a second person, write if you have the same issue labels Oct 8, 2018
@Rotzbua Rotzbua changed the title Issue with changed PCD_Init() Arduino stuck at PCD_Init() with 3.3V power supply Oct 8, 2018
@Rotzbua
Copy link
Collaborator

Rotzbua commented Oct 10, 2018

@SheldorAFK Can you do two more tries?:

1. Use only software based reset

  • disconnect rst connection
  • use pin definition:

#define RST_PIN 0xff // Configurable, see typical pin layout above

This disables the hardware pin based reset. Only the software based is done.

2. Use 5V power instead of 3.3V

  • Maybe you got a bad designed board.. just a try

My short analysis

My mfrc board is "active" if power is connected. So the rst pin should have 3.3V or 5V (depending on powering). According to this, the library does not perform a hardware reset or power up by reset pin.

I don't need the hardware based reset and it also works with the software based reset.

Data sheet

After reading the datasheet I improved the reset code a bit. See 3592862 .

@SheldorAFK
Copy link
Author

I ran the sketch with a disconnected RST pin as well as with the RST pin set to UNDEFINED (0xFF). With that configuration the DumpInfo.ino sketch partially worked. It did return the RC522 board version number at startup. And if an RFID token was placed on the reader, it's UID could be read. However reading the data blocks of the token still failed.

So I checked the signal levels again with the Oszilloscope. When the RF522 was powered on the state of the RST PIN was HIGH (3.3V). PIN 9 of the Arduino was at LOW level at power on. Thus with the pre 1.4.0 PCD_Init() version, the if condition was met and the PIN9 of the Arduino was set to HIGH (5V). Even though the RST pin of the RF522 was already at HIGH (3.3V), I could verify that by setting the pin to the 5V HIGH of the Arduino, my RF522 board performed a hard reset. And after the hard reset it worked properly.

That on the other hand made me wonder if driving the 3.3V signals with 5V levels is really a good idea. I ordered a set of active level shifters which arrived today. With the level shifters placed between the Arduino and the RF522 board the sketch still did not work. The behaviour was similar to the tests with the disconnected RST pin without the shifters. I checked the MOSI and MISO signals with the Oszilloscope and could see that the raising edges were closer to sine waves than to square signals. In addition the RST signal was jittering heavily. So I added an external 3.3V (actually 3.6V) power supply to the RF522 board and the level shifters. Before I was using the 3.3V output of the Arduino. With the additional power supply in place the signal edges improved significantly and the RST jitter was gone.

Reading tokens with the DumpInfo.ino sketch worked instantaneously. This means my issues were related to driving the 3.3V board with 5V levels. Unfortunately those issues did not have any effect if the board was hard reset during PCD_Init(). I have to admit that I fell to the many direct wiring proposals available at various web sites without questioning their validity. I am sorry for all the hassle caused by my stupidity.

To make a long story short, the current version of the library is correct. It only breaks badly wired circuits like in my case. Once again sorry for all the confusion and thank you very much for your quick and profound support.

@SwapUNaph
Copy link

Hi,
I was facing similar issues. My RC522 firmware version is 0x92 v2.0 and I was getting no output on card read with the dumpinfo.ino sketch.
I fixed it by connecting the vcc of RC522 and arduino to 5V instead of 3V3 and it works perfectly.
Though I don't know how safe it is to use 5V.

Regards.

@Rotzbua Rotzbua closed this as completed Oct 27, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug 🐛 a not intended feature
Projects
None yet
Development

No branches or pull requests

3 participants