Getting the RC522 RFID to work with the Wemos D1 R1

Posted on
  • I want to make this post mostly for documenting my attempts at getting an RC522 RFID sensor to work with my small ESP8266 centered project.

    When trying to use the sensor with an adapted version of the MFRC522 example code, it gives an error :

    Uncaught Error: MFRC522 Request Error 16

    I understand the error code should be representing a bit register on the RC522 module itself, expressing an error. However I do not understand the page describing the errors in the datasheet (page 41) and how to relate it to my error code.

    I managed to get error 15 too, by using a different CS pin on my WemosD1.
    And error 255 by swapping MISO and MOSI pins.

    I know the sensor works properly. I tested it with an Arduino Nano, and most importantly, with my ESP8266 board (D1), with the same sketch as the Nano, using the Arduino IDE, using the same pinouts as with Espruino. It works fine this way. The Arduino library requires the RST pin to be wired to a pin, but I left it unplugged and set it to an empty pin. It didnt prevent it working.

    I've tried using both software and hardware SPI.
    I only get the error code with hardware SPI.
    MFRC522.findCards returns undefined with software SPI. Nothing else.

    At this point i'm suspecting there is something wrong with the MFRC522 library, probably something minor. The library is not very big but I don't understand the inner workings of the RC522.

    The options I'm considering:

    • Delve more into the SPI protocol, the MFRC522 library and datasheet, possibly re-making a library of my own.
    • Somehow compile the Arduino library into Espruino, if at all possible.
    • Drive the RFID with an additional MCU, like an Arduino Nano and communicate over existing i2C setup.
    • Drop Espruino. Javascript is only icing in this project. All components are working with the Arduino libraries.

    Any help welcome!

    Important links regarding this issue or similar ones :
    (Using software SPI)­/issues/258
    (Pico, KeyesStudio, similar error code)­299035/

    Specific gear:
    Wemos D1 R1 (Uno form factor ESP8266 board)
    Keyestudio RFID-RC522 Module

  • you can try the pins named in EspruinoESP8266#spi-implementation

  • Mon 2019.12.30

    Good Morning @Drumline18 and thank you for your interest in Espruino. Nicely written inquiry, with all the detail required.

    'At this point i'm suspecting there is something wrong with the MFRC522 library'

    Nope. That module written prior to my usage, was developed for the Original and Pico boards. I eventually got it to work with other boards as have many others. See last pp. ref 'finiky'

    Thank you for referencing my forum thread 299035. That was the second module I worked with, when I first started with Espruino and three years ago, Yikes! where did the time go? I intended to follow up in that thread with a solution I found, just nine months ago, but it is a back burner project at this time. Can't remember all the detail, and there have been many firmware chnges, upgrades and improvements since, but I think it had something to do with pin naming. See this associated thread:

    Attempting to get SPI running on ESP8266

    I also solved this using a logic analyzer, which enabled me to actually observe the bus data. Worth every penny and around twenty dollars. See resultant images in an un-related post at:

    Programming the Ublox NEO-6M

    'Somehow compile the Arduino library into Espruino'

    When one analyzes the detail ('C' vs Javascript) in volume of code lines Arduino requires, then gets the epiphany after working with Espruino (less code, WebIDE debugging, instant patch fix without recompile, tutorial modules that just work - with official supported boards), you may, like myself rarely do these tasks using Arduino. (I dove into Arduino nealy two years after starting with micros three years ago)

    Also, purchased a different CH manufacturer board to compare, but did eventually get the KeyeStudio flavor working with the logic analyzer. The RF detection was finiky for both, until it's working reliably. Watch the RFID ID digits too, as I muxed (fubar) decimal with hex.

  • this might help to build a map nodemcu to esp8266 pin names:­b/master/targets/esp8266/jswrap_nodemcu.­c

  • Thank you both for your prompt responses to this non-official board.
    Hope everyone is having good holidays.

    Pin mapping was the first issue I got to when getting this Wemos D1 (r1) board.
    So I created my own object to store the mapping to my board :

    const WemosD1 = {
      D0: 3,
      D1: 1,
      D2: 16,
      D3: 5,
      D4: 4,
      D5: 14,
      D6: 12,
      D7: 13,
      D8: 0,
      D9: 2,
      D10: 15,
      D11: 13,
      D12: 12,
      D13: 14,
      D14: 4,
      D15: 5

    Simple numbers representing the GPIOXX equivalent from the ESP8266. D pins overlap each other (ie. D5 & D13 are GPIO14).
    This object was built using the silkscreen on the board itself. I have not tested every one of them yet. I will probably get around to it tonight.

    My SPI setup looks likes this : (GPIO equivalents in comments)

        sck: WemosD1.D5, // GPIO14
        miso: WemosD1.D6, // GPIO12
        mosi: WemosD1.D7 // GPIO13
      // And then the MFRC522 
      const rfid = require('MFRC522').connect(SPI1, WemosD1.D2); //CS -> GPIO16 (also tried GPIO15)

    When comparing the GPIO pins to a pinout image or a bare ESP8266, it looks like it fits with the pins labeled MISO, MOSI and SCLK. GPIO15 being labeled as CS, it gives an error 15 instead of 16.

    I will have more time tonight to go through the jswrap C file.

    "I also solved this using a logic analyzer [...] around twenty dollars."

    Wow I didn't know something like this existed, at such a low cost. I must get one now.

    I will receive a NodeMCU V3 in a week or two, that should be the actual module that I will be implementing in my system. Hopefully the NodeMCU.XX pin mapping will work with this one.

    Professionally, I'm a front-end developer. I LOVE Javascript. I LOVE how Espruino implements it on microcontrollers. My javascript sketch is indeed about half the size the C one for the same tasks, and it feels much more elegant. Although for this time it might be more effort than C, I'm looking forward to the challenge.

    So tonight's jobs :

    • Verify my pin mapping object
    • Go through the jswrap C file that @MaBe linked to confirm pin mapping
    • Read on SPI communication (need more understanding) and try to confirm SPI communication is working.
    • Shopping for a logic analyzer

    EDIT: Formatting correction 2019-12-30

  • Mon 2019.12.30

    Just checked my notes, @Drumline18 and the SPI setup is identical to mine. So that should be good to go. Wire it up to the D1 and let us know of your success!

    Post #1 mentioned KeyeStudio, but the datasheet points to the MIFARE flavor. A few subtle differences. Dug up the link I used: (datasheet .pdf in link close to page end)­0067_keyestudio_RC522_RFID_Module_for_Ar­duino

    'Wow I didn't know something like this existed'

    Yeah, I kept seeing the data line image diagrams in other posts back then. First figured I couldn't afford a S.W.A.G. guess of $1000, as scopes cost that and sidelined the thought. Later, just did a little searching like you are doing to find one suitable for my kitchen table projects.

    shhhhh . . . While Amazon carries the FX2 for just under twenty dollars, Banggood has (unvetted to me) a different label CN knockoff for half that cost, should shipping wait time not be an issue. they are probably from the same chip mfg anyway

  • Tonight is proving to be quite a learning experience.

    In the MFRC522 module :

    MFRC522.prototype.w = function(addr,data) {
      this.spi.write(addr, data, this.cs);

    In the SPI reference :

    data, ... - One or more items to write. May be ints, strings, arrays, or special objects (see E.toUint8Array for more info).
    If the last argument is a pin, it is taken to be the NSS pin

    My "pins" are simple Numbers, not Pin objects.
    Inspecting the C file using the reference link, it looks like the function is looking for a Pin object. Link here, line 215.

    So here I'm thinking that is my problem, it doesn't know what the SS pin is.
    In fact the second phenomenon making me think about that is that the error code is the same as the pin number entered.

    So I re-read the Espruino on ESP8266 page, again, and again. Now I understand my WemosD1 object is no longer required. I can refer to the Dxx pins directly, by referencing the GPIO number instead.(Duh!). So I dropped my WemosD1 object to use D pins exclusively.

    Giving the MFRC522.connect function a proper Pin object changed the behavior drastically I think. I still get the same Error message, but the error code is now 12, regardless of what SS pins I use.

    Now I can't help but notice this is the exact same error code as in Github issue #258 previously linked.

    Their code was using software SPI, which I have just re-tried. MFRC522.findCards returns undefined without errors. Its not doing anything.

    Shorting MISO to MOSI allowed me to verify that both HW and SW SPI are working (following the quick tip from Gordon here).

    If I physically disconnect the SS pin, the error is 255. The error is consistent on 3 different pins now, D15, D16 and D0.

    Its getting late now.
    I'll have to take a look at the code on the Keyestudio Wiki, to compare it with the values in the MFRC522.js library. @Robin, sadly I cannot find the datasheet PDF you are referring to. The page you linked tells me there is no text there. And the page I was able to find only has a garbage PDF full with the same information as the wiki page.

    I did not need special numbers or modifications with the Arduino library, so I'm assuming they will be the same, unless they have something special for Keyestudio detection.

    I also want to try and communicate manually with the RFID sensor, essentially emulating what the library is trying to do.

    No success tonight but digitalWrite(myHopes, HIGH);

  • Tue 2019.12.31

    var r = digitalRead( pagelink ); console.log( "r = " + r ); >r = verified

    'sadly I cannot find the datasheet PDF you are referring to. The page you linked tells me there is no text there'

    Wow! and can verify the same. Interestingly, the page was there yesterday. I copy-n-paste'd the URL myself, at least I thought it was myself, and I double checked the link went there!

    So, I did what the page suggested and used search, with the 'site:' qualifier keyword:

    Google:   RC522

    The first link returned, does go to that source, but in the Google results, one may observe it is a dynamically built link. (look for the right arrow in the Google returned result) Note the subtle difference in that result:­tudio_RC522_RFID_Module_for_Arduino
    I wonder which server is misbehaving?

    The .pdf there (page bottom) is a dynamically built link too, that goes to:­tHHQI40PYx_bER9iw_LE40p9K/view

    Now I know I'm dreaming, but in my dream I clicked on the above links to make sure ;-)

    'I can refer to the Dxx pins directly, by referencing the GPIO number instead.(Duh!). So I dropped my WemosD1 object to use D pins exclusively.'


    'The error is consistent on 3 different pins now, D15, D16 and D0.'

    Has the 'NodeMCU' prefix been attempted? The one mentioned in the first link in conversation #12951616 found in #3 post, and I believe what MaBe was referencing also?

    'I did not need special numbers or modifications with the Arduino library'

    Is an attempt to re-write that library underway? IMO, while a nice exercise in functionality language translation, actually a big waste of time. Both my different mfg modules worked with the simple eleven line snippet from the tutorial in the link from #1 post.

    'it doesn't know what the SS pin is'
    re: NSS pin

    Double check the pin mode. Have been burned many times when resetting a board and not explicity (re-)setting. I have seen NSS pins with both pull-up and pull-down internal. That would mess with chip select.­obal_getPinMode

  • Happy 2020 everyone!

    Thanks again for the answers.

    'Is an attempt to re-write that library underway?'

    Not really. I'm trying to understand how the current one works by dissecting it. If it has to come to a full re-write, Espruino will probably get "phase 2".

    'Double check the pin mode.'

    This somewhat gives me hope that my problem is still something fairly simple like that.
    However I'm not sure what pinMode each pin should be in!
    In my current test, with the same error 12 setup, before calling MFRC522.connect, all the affected (D14, D12, D13, D15) are "input_pullup". After calling it, the NSS pin is now "output".

    'Has the 'NodeMCU' prefix been attempted? '

    I stripped everything from the board, setup a breadboard with and LED and tested each NodeMCU pins. At this point, I'm fairly sure this 'prefix' is not useful to my board. Here are the results from the experiment :

    NodeMCU.D0   NOT OK      (D2 on board, GPIO16)
    NodeMCU.D1   NOT OK      (D3 on board, GPIO5)
    NodeMCU.D2   NOT OK      (D4 on board, GPIO4)
    NodeMCU.D3   NOT OK      (D8 on board, GPIO0)
    NodeMCU.D4   NOT OK      (D9 on board, GPIO2, ESP8266_LED)
    NodeMCU.D5   OK          (SCK_LED)
    NodeMCU.D6   OK
    NodeMCU.D7   OK
    NodeMCU.D8   NOT OK      (D10 on board, GPIO)
    NodeMCU.D9   BREAKS CMD  (D0 on board, RX, GPIO3)
    NodeMCU.D10  BREAKS CMD  (D1 on board, TX, GPIO1)
    NodeMCU.D11+ UNDEFINED   (11,12,13,14,15 undefined)
    // OK          Control + correct silk screen D pin
    // NOT OK      Control + Incorrect silk screen
    // BREAKS CMD  No more Espruino IDE console, unknown usability unplugged
    // UNDEFINED   These pins do not exist in the NodeMCU 'prefix'

    However the GPIO numbers visible from under the board are easy to use with the normal D pins.

    'save() with modules where .connect() initializes device (such as RFID reader MFRC522)'

    Good read, but I understand how save() works, at least I think I do. Getting the Espruino to work without a computer was 1st order priority on Day 1, coming from Arduino. If I can get even just one read from the RFID using Espruino, I will feel confident dealing with everything else.

  • @Drumline18 - Happy happy New Year too to you! ...and growing positive experience w/ Espruino in 2020 and many years following...

    It is - in your case -

    • 1st) not about how the save() works but - unfortunately - many of the example take not into account that create or connect_to or create_by_connecting_to set state in the connecting software component and/or the peripheral device itself that cannot be saved by Espruino and later restored on power cycling.

    • 2nd) about possible trouble beyond your dealings because some of the peripheral devices lack a bit quality or convey information as clearly as possible (as this particular device @Robin was working with at that particular time).

    Nobody doubts you feeling confident dealing with everything else. Believe me, it * IS * very frustrating that something is just not doing what one thinks it should do and even has doing it before, but for no obvious and more so obscure reasons it's just not doing so.

    I really appreciate your venturing from Arduino into Espruino... I made significant investments - money and more so time in getting things going even with precursors of the very successful Arduino... but they had to clear stage the moment Espruino showed up. Having a flexible and logically powerful - high level and easy to use - language and very easy to use IDE at hand did not need much conviction... after all I liked Smalltalk, and JS was the new similarly power full world / platform after major entities abandoned the st ship in the war of SUN/Java and MS/... hype.

    Spending countless hours on details others just left out ore did not think of to matter made me chip up the few extra bucks to buy Espruino hardware for which the Espruino Firmware and Software was built for and match up to @Gordon's standard and leave possible experiments for later... Some of these experiments were very disheartening because even among boards from the same source/manufacturer(?) were go and no go differences. It took me several attempts to get the Espruino on ESP8266 ESP-09 - 1 powerful cm2 going... and I would consider myself not unaccustomed to low level challenges from the Z8 and ubicom times doing similar things that at that time were more bleeding than edge.

    Regarding use of ESP8266EX as a platform is a challenge since the Wifi stack has hard, non-negotiable demands and spending my time to work around these (in a non-commercial) setting I consider for myself not being the most effective use of my (life) time (left to me). Kind of 'oximoronic' though and not completely self less, I rather spend that 'saved' time in helping / enabling others to have success, even if it is not my way.

    Since dedicated controllers are so readily available - almost every sensor has one built in - why should I not follow the same pattern? Use dedicated controllers for communication and (high level part/congtrol of) application rather than cramming all (cycle needs) into one single processor. Therefore, I prefer a combination Espruino (or a-like) hardware for the application with a communication hardware such as the ESP866EX.

    Btw, I liked your abstraction layer for pin mapping... and it almost made it there. Even though I see portability / adaptability / moving on to new platforms is not the primary aspect for - dedicated -micro controller software, it is always nice to not be prisoner and being locked into a particular setup.

  • 'Spending countless hours on details others just left out ore did not think of to matter made me chip up the few extra bucks to buy Espruino hardware for which the Espruino Firmware and Software was built for[...]'

    Although I love how Espruino is currently implemented, I think I'll prefer donating directly to support the project instead of buying the boards. At the price points, donating and buying a Raspberry Pi Zero W makes more economical sense to me while allowing me to use fully featured JS and toolchains and not really supporting the "board building" effort part of the project. You guys seem to be more experienced than me with microcontrollers so maybe I'm just missing the point, please enlighten me. The fact I'm running JS and Wifi from this 2$ chip is what makes it interesting to me.

    Btw, I liked your abstraction layer for pin mapping[...]

    Thank you. Thinking about it, it would work, by using D pins instead of Numbers, essentially recreating a NodeMCU-like prefix for my board.

    At this point I'll share my exact errors and test script for reference and documentation.
    There doesn't seem to be a spoiler feature on the Forum so sorry for the long post.

    I built a script to test everything using the console :

    const MFRC522 = require("MFRC522");
    var nfc;
    var spi;
    const SPI_PINS = {
      sck: D14,
      miso: D12,
      mosi: D13
    function softwareSPI() {
      spi = new SPI();
    function hardwareSPI() {
    function connect(_spi) {
      nfc = MFRC522.connect(_spi, D15);
    function log(c) {console.log('Card : ', c);}
    function test() {
    // softwareSPI() or hardwareSPI()
    // connect(spi) or connect(SPI1)
    // test()

    As you can see, it's not doing much at upload time, only definitions. I then run the commands that are commented, using the Espruino IDE console.

    Hardware SPI results :

     ____                 _
    |  __|___ ___ ___ _ _|_|___ ___
    |  __|_ -| . |  _| | | |   | . |
    |____|___|  _|_| |___|_|_|_|___|
     2v04 (c) 2019 G.Williams
    Espruino is Open Source. Our work is supported
    only by sales of official boards and donations:
    Flash map 4MB:512/512, manuf 0x20 chip 0x4016
    Uncaught Error: MFRC522 Request Error 12
     at line 1 col 189
    ...("MFRC522 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
    in function "findCards" called from line 1 col 18
    in function "test" called from line 1 col 6

    Software SPI results :

     ____                 _
    |  __|___ ___ ___ _ _|_|___ ___
    |  __|_ -| . |  _| | | |   | . |
    |____|___|  _|_| |___|_|_|_|___|
     2v04 (c) 2019 G.Williams
    Espruino is Open Source. Our work is supported
    only by sales of official boards and donations:
    Flash map 4MB:512/512, manuf 0x20 chip 0x4016

    To make sure, I double checked that each D pins referenced was the actual physical pin I was plugging into, so I'm fairly sure that my wiring is fine, again.

    Removing each pin one by one changes the error code :

    All pins connected : Error 12
    Without NSS pin :    Error 158
    Without SCK :        Undefined
    Wihtout MOSI :       Undefined
    Without MISO :       Error 255
    Swapping MISO and MOSI : Error 255

    I'll try to dissect the MFRC522 library a little more tonight. If that doesn't do it, I'll wait for the NodeMCU and I'll try to get another RC522 module from another mfg. My local supplier seems to like Keyestudio alot.

    I may try flashing to an earlier version of Espruino too. Just in case.

    EDIT: typo 2020-01-01

  • I'll try to dissect the MFRC522 library a little more tonigh

    use this style to include module code directly into your tests­169/

  • got a pico, esp8266 and a MFRC522 on my desk and will give it a try.

  • I think I'll prefer donating directly to support the project instead of buying the boards

    Sure, any financial support is helpful, especially from people that are using unsupported board.
    So go and get your Donated label below your Avatar.

    Stopping Wifi is helpful during testing

      status: "off",
      ssid: "",
      password: "",
      savedSsid: null }
      status: "disabled",
      authMode: "open",
      hidden: false, maxConn: 4,
      ssid: "ESP-0D17D4",
      password: "",
      savedSsid: null }

    Eye-catching observation taken from post #12

    Flash map 4MB:512/512, manuf 0x20 chip 0x4016

    If you like you can flash the 4MB build after you got the MFRC522 working :)

  • Yesterday I tried to reverse engineer the MFRC522 library and I failed, receiving varying data depending largely on the SPI setup.

    I've also tried earlier versions of Espruino, just in case. No changes.

    The board I have, the Wemos D1 R1 is no longer in production, they are doing the R2 now, mostly pin changes apparently. But I can't help but wonder if that is the root of my problem.

    I should get the NodeMCUV3 and an ESP32 any time now. I'll try with that and make sure to keep this thread updated.

    'If you like you can flash the 4MB build after you got the MFRC522 working :)'

    I thought that was that I had going?? I got the 4MB version, in directory form and flashed it with : --port COM3 --baud 115200 write_flash --flash_freq 80m --flash_mode qio --flash_size 32m 0x0000 boot_v1.6.bin 0x1000 espruino_esp8266_user1.bin 0x3FC000 esp_init_data_default.bin 0xFE000 blank.bin

    After running the esptool erase_flash, of course.

    'So go and get your Donated label below your Avatar.'

    I've become a small patron on patreon, I'll make sure to update that as well when I get back to full time employment.

    'Stopping Wifi is helpful during testing'

    I figured that would help with @allObjects's comment on the non-negotiable demands of the wifi stack. It didn't seem to affect the results I was getting (not like changing NSS pin or using software SPI)

    'got a pico, esp8266 and a MFRC522 on my desk and will give it a try.'

    If you get to dig deep, I'd be interested in what the communication looks like in a working MFRC522!

    Sooo... In the meantime I gave in to the dark side, plugged the MFRC522 in the Arduino Nano and wrote a small C script for it to be slave I2C and report back to the ESP8266 running Espruino. Within 30 minutes I was reading cards, that felt good.

    I'm not giving up on having it directly on an ESP, but I'll take a break from it until I get further gear (or the logic analyzer!). Thanks again for the answers.

  • It works !

    I've received the NodeMCU board first.

    Plugging the rc522 module in the hardware SPI pins leads to crashing and breaking the IDEs console. Just connecting it, no running code. So until further investigation, no hardware SPI.

    Using software SPI and pins D1, D2, D3 and D4, it worked right away, using the NodeMCU prefix.

    For reference :

    let spi = new SPI();
    spi.setup({sck:NodeMCU.D2, miso:NodeMCU.D4, mosi:NodeMCU.D3});
    var nfc = require("MFRC522").connect(spi, NodeMCU.D1);

    I got everything else to work using software I2C too using D5 and D6.

  • That's great and thanks for sharing!

  • Post a reply
    • Bold
    • Italics
    • Link
    • Image
    • List
    • Quote
    • code
    • Preview

Getting the RC522 RFID to work with the Wemos D1 R1

Posted by Avatar for Drumline18 @Drumline18