espruino / EspruinoDocs

See http://espruino.com for the complete Espruino Documentation - many links in this repository will not work
http://www.espruino.com/
Other
260 stars 284 forks source link

MFRC522 Error 12 on ESP8266 #258

Closed 8eecf0d2 closed 8 years ago

8eecf0d2 commented 8 years ago

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 commented 8 years ago

We are getting exact same error

gfwilliams commented 8 years ago

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

ceremcem commented 8 years ago

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 commented 8 years ago

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 commented 8 years ago

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 commented 8 years ago

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 commented 8 years ago

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

gfwilliams commented 8 years ago

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 commented 8 years ago

@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 commented 8 years ago

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

gfwilliams commented 8 years ago

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 commented 8 years ago

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 commented 8 years ago

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

ceremcem commented 8 years ago

@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 commented 8 years ago

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 commented 8 years ago

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 commented 8 years ago

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. https://github.com/tve/Espruino/commit/6e09066c679ca62634e7d9f732c8ff8e93b29cdc

tve commented 8 years ago

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 commented 8 years ago

@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 commented 8 years ago

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

screenshot_2016-06-23_12-30-22

gfwilliams commented 8 years ago

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

ceremcem commented 8 years ago

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 commented 8 years ago

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 commented 8 years ago

@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 commented 8 years ago

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 commented 8 years ago

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 commented 8 years ago

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 commented 8 years ago

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

ceremcem commented 8 years ago

Thanks @gfwilliams, thanks @tve!

elixirml commented 8 years ago

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