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

MFRC522 Error 12 on ESP8266 #258

Closed
8eecf0d2 opened this issue Jun 10, 2016 · 30 comments
Closed

MFRC522 Error 12 on ESP8266 #258

8eecf0d2 opened this issue Jun 10, 2016 · 30 comments

Comments

@8eecf0d2
Copy link
Contributor

Error

Uncaught Error: MRFC522 Request Error 12
 at line 1 col 189
...("MRFC522 Request Error "+a);a=this.r(20);return this.ra(18,...
                              ^
in function "req" called from line 1 col 34
this.w(26,7);return 0<this.req(38).length
                                 ^
in function "isNewCard" called from line 1 col 16
this.isNewCard()&&a(this.getCardSerial())
               ^
in function "findCards" called from line 4 col 2
});
 ^

Code

SPI1.setup({ sck:D14, miso:D12, mosi:D13 });
var nfc = require("MFRC522").connect(SPI1, D15);
nfc.findCards(function(card) {
  print("Found card "+card);
  card = JSON.stringify(card);
});

Connection (NodeMCU)

RC522       NodeMCU,  ESP8266,  Espruino
CS     ->   D5,       GPIO15,   D15
SDA    ->   D8,       GPIO14,   D14
MISO   ->   D6,       GPIO12,   D12
MOSI   ->   D7,       GPIO13,   D13

Unsure what Error 12 is and why it's appearing, any help appreciated.

@ceremcem
Copy link

We are getting exact same error

@gfwilliams
Copy link
Member

It's not that you've wired it up to 5v rather than 3.3?

@ceremcem
Copy link

ceremcem commented Jun 17, 2016

We tried so many things, including switching to hardware SPI pins of ESP12, which solved that exception mentioned. Now, the only problem is that we can not get any NFC cards read by module via ESP12. We are only switching the reader's SPI pins between STM32F407-Discovery Board and ESP12 module. Same code (except for pin setup) works just great on STM32-Discovery, but fails to read NFC cards without throwing any exception.

@gfwilliams
Copy link
Member

Sounds like this is an SPI issue on ESP8266 rather than anything specific to this driver?

IMO you probably need to get a digital storage scope on it and look at the differences in signals that are sent - it may end up being pretty obvious.

@ceremcem
Copy link

We would try to compare whole communication sequence of STM32 and ESP12. We connected the logic analyzer to ESP12's SPI pins and we managed to capture all communication signals. Then we connected the logic analyzer to STM32-Discovery. The original exception is thrown when we connect MOSI pin to analyzer (other pins do not cause any exceptions). So we failed to compare.

FYI: I will try to convert current driver to use I2C.

@gfwilliams
Copy link
Member

have you tried a different MOSI pin? It sounds like the one you're using can't supply enough power for some reason. Could also be something to do with the ESP8266 not setting up the pin mode correctly to output?

@ceremcem
Copy link

nope, we haven't. you mean we should try to use different SPI pin group on Discovery?

@gfwilliams
Copy link
Member

Oh, I see what you mean - I thought you were talking about problems with ESP8266.

You could try different pins, but working out what's wrong with this is up to you I'm afraid since I can only afford to support the boards that I sell.

@gfwilliams
Copy link
Member

@tve I know we'd seen some glitches on the I2C implementation. Looking at jshPinSetValue there are two writes, and I wonder whether it's somehow causing glitches when changing the output, which is throwing some devices off when using software SPI?

@tve
Copy link
Contributor

tve commented Jun 17, 2016

Mhh, that's certainly possible and worth an experiment. The double writes come from Espressif's i2c code, if I remember correctly.

@gfwilliams
Copy link
Member

gfwilliams commented Jun 17, 2016

Interestingly the Arduino code looks slightly different:

https://github.com/esp8266/Arduino/blob/633e48f3aec5f1c3c11d4498fc90d378d49e6e9f/cores/esp8266/core_esp8266_wiring_digital.c#L79

Ours:

https://github.com/espruino/Espruino/blob/master/targets/esp8266/jshardware.c#L439

I wonder whether just writing '0' to the set/clear registers has some undesired effect.

... I am torn though. Doing !boolean is kind of clever, but at the same time it also feels dirty :)

@ceremcem
Copy link

ceremcem commented Jun 17, 2016

We managed to get samples via connecting the MOSI probe of analyzer while STM32 has setup its SPI port and started polling the reader. Here are the results:

Code

in Javascript, in Livescript

ESP (fail)

esp-fail-1

Logic analyzer dump - ESP (fail)

STM32 (success)

stm32-success-2

Logic analyzer dump - STM32 (success)

@8eecf0d2
Copy link
Contributor Author

I'll also add, using the same hardware / pinout with Arudino sketches / libraries works without any issue.

@ceremcem
Copy link

ceremcem commented Jun 19, 2016

@gfwilliams I didn't mange to find the line in the source code which the software SPI clock frequency is set. I wonder if I would get a workaround for this job if I could set the software SPI clock frequency to 400 kHz. A hardcoded solution would satisfy for now.

@gfwilliams
Copy link
Member

You can't change the software SPI frequency... Are you 100% sure you're capturing the same communications in each case? On STM32 it looks like it's sending 2 bytes each time rather than 1.

@mesutevin
Copy link
Contributor

mesutevin commented Jun 21, 2016

We are working with @ceremcem and we are still chasing this problem. Current situation is that
new SPI() call does not seem to create a working SPI object.

In our ESP-12 - MFRC522 pin configuration is :

ESP8266.12 -- MFRC522
GPIO15 <--> SDA
GPIO14 <--> SCK
GPIO13 <--> MOSI
GPIO12 <--> MISO

My test code is as follows:

var spiPins, cs, rfid;
spiPins = {
  sck: D14,
  mosi: D13,
  miso: D12
};
cs = D15;
SPI1.setup(spiPins);
rfid = require("MFRC522").connect(SPI1, cs);
rfid.findCards(function(card){
  return console.log("Found " + card);
});

I want to use software SPI port. I created new object from SPI class.
Firstly, I tried pins which are different hardware SPI pins. I can not solve.
Secondly, I tried with hardware SPI pins and software created SPI object as following code. Nothing changed.

var spiPins, cs, mySpi, rfid;
spiPins = {
  sck: D14,
  mosi: D13,
  miso: D12
};
cs = D15;
mySpi = new SPI();
mySpi.setup(spiPins);
rfid = require("MFRC522").connect(mySpi, cs);
rfid.findCards(function(card){
  return console.log("Found " + card);
});

What am i doing wrong ?

Wiring Question:

As you know the GPIO15 is used as CS in SPI.
But i have to connect GPIO15 pin to GND before booting. (If i do not this, /dev/ttyUSB0 console can not open.) Could it be the source of the problem ?

@tve
Copy link
Contributor

tve commented Jun 23, 2016

I just did some tests. I'm not seeing any glitches, other than cross-talk between the lines. Both HW and SW SPI seem to work fine. I don't have an SPI device handy so I just looped MISO & MOSI back into one another. SW SPI runs at just under 1Mhz, HW you can control. Here's my little test program:

// Test hardware or software SPI

var esp8266 = require("ESP8266");
esp8266.setLog(2); // log to memory and uart0
console.log("hello");

// Hardware SPI
var spi = SPI1;
spi.setup({baud:500000});

// Software SPI, approx 1Mhz
//var spi = new SPI();
//spi.setup({sck:D14, miso:D12, mosi:D13});

var data = new Uint8Array([0xAA,0x55,0x5A]);
spi.send([0x33]);
spi.send([0x99]);
setInterval(function(){
  console.log("Got:", spi.send(data));
}, 2000);

Output should be:

Got: new Uint8Array([170, 85, 90])
Got: new Uint8Array([170, 85, 90])
...

@gfwilliams I switched the i2c and digitalWrite implementations to use a single I/O write with an if statement like they do in arduino 'cause I tried it to see whether it makes a difference and I found that it's just so slightly faster. But no difference WRT glitches or so. tve/Espruino@6e09066

@tve
Copy link
Contributor

tve commented Jun 23, 2016

But i have to connect GPIO15 pin to GND before booting. (If i do not this, /dev/ttyUSB0 console can not open.) Could it be the source of the problem ?

Not if you use an appropriate pull-down resistor. 10k works for me

@gfwilliams
Copy link
Member

@tve thanks! Interesting that it's faster...
Worth swapping over then I guess - also, it might be slightly less cryptic :)

Most likely it's wiring then. I'd say use software SPI - there are less possible things to go wrong.

It getting 12 returned sounds like either an MOSI or CS not working properly.

@ceremcem
Copy link

Our original PCB design was using software SPI in the first place.

screenshot_2016-06-23_12-30-22

@gfwilliams
Copy link
Member

I'm pretty sure GPIO16 is known not to work?

@ceremcem
Copy link

Yes, sorry, I forgot to mention; we have re-discovered that, cut the PCB route and soldered it to another GPIO (I can't recall right now).

FYI: I suspect that the firmware may be somewhat wrong since it was one of those I had compiled by myself (as you may remember)

@tve
Copy link
Contributor

tve commented Jun 23, 2016

gpio15 shouldn't be connected to gnd but to a pull-down resistor. If something decides to output a '1' you're goinna get quite some heat and current leading to issues.
gpio2 should be connected to a pull-up.
if you used HW spi you could tune the clock rate...

@mesutevin
Copy link
Contributor

@tve Regarding to your suggestion, I connected GPIO15 to GND via 10K resistor and GPIO2 to VDD (3.3V) via 2.2K resistor, then tried your test code.

When I tried software SPI, output was as expected, and as follows:

Got: new Uint8Array([170, 85, 90])
Got: new Uint8Array([170, 85, 90])
...

But when I tried hardware SPI, output wasn't the same as before:

Got: new Uint8Array(3)
Got: new Uint8Array(3)
...

After this successful test, I used software spi in my test code.

It is WORKING

This is my test code:

var spiSoftware, chipSelect, rfid, rfidTest;
spiSoftware = new SPI();
spiSoftware.setup({
  sck: D14,
  miso: D12,
  mosi: D13
});
chipSelect = D15;
rfid = require('MFRC522').connect(spiSoftware, chipSelect);
rfidTest = function(){
  console.log("trying to find card");
  return rfid.findCards(function(card){
    return console.log("Found " + card);
  });
};
setInterval(function(){
  return rfidTest();
}, 2000);

Output is :

trying to find card
trying to find card
trying to find card
trying to find card
Found 70,134,245,19
trying to find card
trying to find card
Found 70,134,245,19
trying to find card
trying to find card
trying to find card
...

But I have some problems.

When I put the setInterval function in onInit as follows, I am getting Error 136 request error.

...
var onInit;
onInit = function(){
  return setInterval(function(){
    return rfidTest();
  }, 2000);
};

rfid-problem-2

After I got this error, i reverted the code to exclude onInit function. Then it seem to start working but it stucked at trying to the find card state. Then I reset the reader module and started working.

@gfwilliams
Copy link
Member

You need to initialise the reader on onInit - it's not able to save it's state :)

var spiSoftware, chipSelect, rfid, rfidTest;
function onInit() {
  spiSoftware = new SPI();
  spiSoftware.setup({
    sck: D14,
    miso: D12,
    mosi: D13
  });
  chipSelect = D15;
  rfid = require('MFRC522').connect(spiSoftware, chipSelect);
  setInterval(rfidText, 2000);
}

function rfidTest(){
    console.log("trying to find card");
    return rfid.findCards(function(card){
      return console.log("Found " + card);
    });
  };

So basically the 'bug' here was that you'd shorted pin D15 to ground, and then also connected it to CS?

I think we can probably close this issue.

@mesutevin
Copy link
Contributor

mesutevin commented Jun 24, 2016

everything works as expected, with a little hack: we need to call setup() twice

Steps to regenerate the problem:

  1. load the first code, with one setup() line before onInit().
  2. see it works (it runs and detects cards).
  3. toggle power of circuit, see it doesn't work.
  4. add one more setup() call inside onInit() function and load the code
  5. see it works as expected.
  6. toggle power, see it works as expected.
  7. remove the unnecessary setup() call above the onInit() function
  8. load the code, see it doesn't work.
  9. toggle the power, see it doesn't work.
  10. re-add the unnecessary(!) setup() call above the onInit() function.
  11. see everything works as expected.

Why do we need two setup() calls?

@gfwilliams
Copy link
Member

It's probably because by default chip select will be pulled low because you are using D15 which has a pull down. If you add digitalWrite(D15,1) alongside SPI.setup it'll probably fix it.

@mesutevin
Copy link
Contributor

It's exactly right. It is working... Thanks @gfwilliams and @tve

@ceremcem
Copy link

Thanks @gfwilliams, thanks @tve!

@elixirml
Copy link

Hello friends I'm new to developing with esp8266, I'm trying to connect both an RFID reader rc522 and screen nextion 2.4 "in a NodeMCU 1.0, using arduino IDE v 1.6.11 to read an RFID tag and display the UID in Nextion 2.4 screen ".

I managed to connect and work with each separately, but I can not make them work together.

when the connections operate separately in NodeMCU v 1.0 are the following:

Nextion 2.4 "||| MCU Node 1.0

5V-------------- 5V
RX ------------ (D7) - GPIO13 - RXD2 - HMOSI
TX ------------ (D8) - GPIO15 - TXD2 - HCS
GND ----------GND

RC522 ||| MCU Node 1.0

3.3V------ 3.3V
RST ------ (D2) - GPIO4
GND------- GND
IRQ -----
MISO -------(D6) - GPIO12 - HMISO
MOSI -------(D7) - GPIO13 - RXD2 - HMOSI
SCK --------(D5) - GPIO14 - HSCLK
SS ----------(D4) - GPIO2 - TXD1

Both devices need to use the pin D7 (RXD2), I would like to use both at the same time, I read that I use UART but do not understand how to apply.

any help is welcome
thank you very much

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants