├── .gitignore
├── .npmignore
├── CODE_OF_CONDUCT.md
├── Changelog.md
├── LICENSE.md
├── README.md
├── commands.js
├── docs
├── demo.md
└── demonstration
│ ├── 1.jpg
│ ├── 2.jpg
│ ├── 3.jpg
│ ├── 4.jpg
│ ├── 5.jpg
│ ├── 6.jpg
│ ├── 7.jpg
│ ├── 8.jpg
│ ├── 9.jpg
│ ├── demo.gif
│ └── demo.mp4
├── index.js
├── package-lock.json
├── package.json
├── project-diagram
├── mfrc-522-node.fzz
└── modules
│ ├── AMS1117
│ ├── AMS1117.fzpz
│ ├── AMS1117_bb.svg
│ ├── AMS1117_pcb.svg
│ └── AMS1117_schematic.svg
│ └── RFID RC522 SIP - 8 pins.fzpz
├── test
├── dumpCard.js
├── dumpNTAG213.js
├── read.js
├── write.js
└── writeAuthenticationKey.js
└── wiki
├── GPIO-pins.png
├── RC522.jpg
├── ams1117.png
├── buzzer.jpg
├── diff-passive-active-buzzer.jpg
├── gpio-map.png
├── mfrc522-node.png
├── rpi-mfrc522-wiring2.PNG
└── youtube.png
/.gitignore:
--------------------------------------------------------------------------------
1 | # Created by .ignore support plugin (hsz.mobi)
2 | ### Node template
3 | # Logs
4 | logs
5 | *.log
6 | npm-debug.log*
7 |
8 | # Runtime data
9 | pids
10 | *.pid
11 | *.seed
12 | *.pid.lock
13 |
14 | # Directory for instrumented libs generated by jscoverage/JSCover
15 | lib-cov
16 |
17 | # Coverage directory used by tools like istanbul
18 | coverage
19 |
20 | # nyc test coverage
21 | .nyc_output
22 |
23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
24 | .grunt
25 |
26 | # node-waf configuration
27 | .lock-wscript
28 |
29 | # Compiled binary addons (http://nodejs.org/api/addons.html)
30 | build/Release
31 |
32 | # Dependency directories
33 | node_modules
34 | jspm_packages
35 |
36 | # Optional npm cache directory
37 | .npm
38 |
39 | # Optional eslint cache
40 | .eslintcache
41 |
42 | # Optional REPL history
43 | .node_repl_history
44 |
45 | # Output of 'npm pack'
46 | *.tgz
47 |
48 | # Yarn Integrity file
49 | .yarn-integrity
50 |
51 |
52 | .idea
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | docs
3 | wiki
4 | project-diagram
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Contributor Covenant Code of Conduct
2 |
3 | ## Our Pledge
4 |
5 | In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
6 |
7 | ## Our Standards
8 |
9 | Examples of behavior that contributes to creating a positive environment include:
10 |
11 | * Using welcoming and inclusive language
12 | * Being respectful of differing viewpoints and experiences
13 | * Gracefully accepting constructive criticism
14 | * Focusing on what is best for the community
15 | * Showing empathy towards other community members
16 |
17 | Examples of unacceptable behavior by participants include:
18 |
19 | * The use of sexualized language or imagery and unwelcome sexual attention or advances
20 | * Trolling, insulting/derogatory comments, and personal or political attacks
21 | * Public or private harassment
22 | * Publishing others' private information, such as a physical or electronic address, without explicit permission
23 | * Other conduct which could reasonably be considered inappropriate in a professional setting
24 |
25 | ## Our Responsibilities
26 |
27 | Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
28 |
29 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
30 |
31 | ## Scope
32 |
33 | This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
34 |
35 | ## Enforcement
36 |
37 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at info@teufel-it.de. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
38 |
39 | Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
40 |
41 | ## Attribution
42 |
43 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
44 |
45 | [homepage]: http://contributor-covenant.org
46 | [version]: http://contributor-covenant.org/version/1/4/
47 |
--------------------------------------------------------------------------------
/Changelog.md:
--------------------------------------------------------------------------------
1 | # Change Log
2 |
3 | ## [2.1.1 - 2019-12-14]
4 |
5 | ### Fixed
6 |
7 | - Add Docs to .npmignore
8 |
9 | ## [2.1.0 - 2019-12-14]
10 |
11 | ### Added
12 |
13 | - Update node-rpio from 1.0.13 to 1.3.0
14 | - Extended Information about card register
15 | - Example how to change authentication key for card register (test\writeAuthenticationKey.js)
16 | - Extended Readme & Documentation
17 | - Buzzer Notifications (optional)
18 | - Circuit Diagram
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 Tristan Teufel
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # mfrc522-rpi
2 |
3 | :key: JavaScript class to control MFRC522 RFID Module with your Raspberry-pi
4 |
5 | MFRC522 is integrated in all types of 13.56MHz RFID passive contactless communication methods and protocols.
6 |
7 | It uses the ISO14443 specification to communicate to MIFARE cards (also known as NTAG, NFC)
8 | [MIFARE wiki](https://en.wikipedia.org/wiki/MIFARE)
9 | [ISO14443 wiki](https://de.wikipedia.org/wiki/ISO/IEC_14443)
10 |
11 | ## Features
12 |
13 | - Read uid & card memory
14 | - Write card memory & card key
15 | - Buzzer notification (Optional)
16 |
17 | ## Demo
18 |
19 | 
20 |
21 | [Watch on Youtube (with sound)](https://youtu.be/e5D_fy8IIjY)
22 |
23 | ## Enable SPI
24 |
25 | The SPI master driver is disabled by default on Raspbian. To enable it, use raspi-config, or ensure the line dtparam=spi=on isn't commented out in /boot/config.txt. When it is enabled then reboot your pi. If the SPI driver was loaded, you should see the device /dev/spidev0.0
26 |
27 | [more info about SPI](https://www.raspberrypi.org/documentation/hardware/raspberrypi/spi/README.md)
28 |
29 | ## Install
30 |
31 | [](https://badge.fury.io/js/mfrc522-rpi)
32 |
33 | ```
34 | npm install mfrc522-rpi
35 | ```
36 |
37 | ## [node-rpio Compatibility](https://github.com/jperkin/node-rpio/blob/master/README.md#compatibility)
38 |
39 | * Raspberry Pi Models: A, B (revisions 1.0 and 2.0), A+, B+, 2, 3, 3+,
40 | 3 A+, 4, Compute Module 3, Zero.
41 | * Node.js Versions: 0.8, 0.10, 0.12, 4, 5, 6, 7, 8, 9, 10, 11, 12
42 |
43 | ## Usage
44 |
45 | The examples in the `test` folder will help you get things started
46 |
47 | #### read uid
48 |
49 | `node /node_modules/mfrc522-rpi/test/read.js`
50 |
51 | #### dump card
52 |
53 | `node /node_modules/mfrc522-rpi/test/dumpCard.js`
54 |
55 | #### dump NTAG213 (sticker)
56 |
57 | `node /node_modules/mfrc522-rpi/test/dumpNTAG213.js`
58 |
59 | #### write NTAG213
60 |
61 | https://github.com/firsttris/mfrc522-rpi/issues/5 Thanks to [musdom](https://github.com/musdom)
62 |
63 | #### write card
64 |
65 | `node /node_modules/mfrc522-rpi/test/write.js`
66 |
67 | ### Card Register
68 |
69 | Your MiFare NFC chip consists of multiple sectors, each containing 4 blocks.
70 | The first 3 blocks of every sector are used to store data, the last block
71 | contains security features (access keys and bits).
72 | Every block holds 16 bytes of data. A typical MiFare Classic 1K chip
73 | has 16 of these sectors, accounting to 64 blocks with 1024 bytes in total.
74 |
75 | The first sector is reserved for manufacturer data, while the second sector
76 | is supposed to contain card holder data.
77 | So, to be on the safe side, start writing your data on the third sector, starting
78 | with block 8.
79 |
80 | Every last block of a sector is called a trailer block. It contains two access
81 | keys, which are used for protecting the data against unpermitted access, and
82 | access bits controlling what can be done with this sector.
83 | The first 6 bytes of such a block contain access key A, the following 4 bytes
84 | are the access bits, and the last 6 bytes are access key B (optional key).
85 |
86 | Please note that when reading a trailer block with this module, it will always return
87 | the same (incorrect) values regardless of its actual content. This might be a security
88 | feature of the chips.
89 |
90 | For simplicity reasons, this module will always authenticate with and refer to key A only.
91 | The default key A on new cards is always `[0xff, 0xff, 0xff, 0xff, 0xff, 0xff]`.
92 |
93 | The access bits in the middle of a sector trailer block should never be changed without
94 | exactly knowing what you're doing. They control what can be done with the current sector
95 | and which of the access key(s) can be used for authentication.
96 | If they don't make sense, the sector (4 blocks) is irreversively blocked and can never
97 | be used again.
98 |
99 | If you want to safely change the access key for a sector, please use the
100 | `writeAuthenticationKey` method (see the `writeAuthenticationKey.js` example in `test`).
101 | Always store the new access key(s) somewhere safe.
102 |
103 | Physical memory content of the chip/card which was included on the RFID-RC522 Module
104 |
105 | ```
106 | Block: 0 Data: 89,229,151,26,49,8,4,0,98,99,100,101,102,103,104,105
107 | Block: 1 Data: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
108 | Block: 2 Data: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
109 | Block: 3 Data: 0,0,0,0,0,0,255,7,128,105,255,255,255,255,255,255
110 | Block: 4 Data: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
111 | Block: 5 Data: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
112 | Block: 6 Data: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
113 | Block: 7 Data: 0,0,0,0,0,0,255,7,128,105,255,255,255,255,255,255
114 | Block: 8 Data: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
115 | Block: 9 Data: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
116 | Block: 10 Data: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
117 | Block: 11 Data: 0,0,0,0,0,0,255,7,128,105,255,255,255,255,255,255
118 | Block: 12 Data: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
119 | Block: 13 Data: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
120 | Block: 14 Data: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
121 | Block: 15 Data: 0,0,0,0,0,0,255,7,128,105,255,255,255,255,255,255
122 | Block: 16 Data: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
123 | Block: 17 Data: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
124 | Block: 18 Data: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
125 | Block: 19 Data: 0,0,0,0,0,0,255,7,128,105,255,255,255,255,255,255
126 | Block: 20 Data: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
127 | Block: 21 Data: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
128 | Block: 22 Data: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
129 | Block: 23 Data: 0,0,0,0,0,0,255,7,128,105,255,255,255,255,255,255
130 | Block: 24 Data: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
131 | Block: 25 Data: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
132 | Block: 26 Data: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
133 | Block: 27 Data: 0,0,0,0,0,0,255,7,128,105,255,255,255,255,255,255
134 | Block: 28 Data: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
135 | Block: 29 Data: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
136 | Block: 30 Data: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
137 | Block: 31 Data: 0,0,0,0,0,0,255,7,128,105,255,255,255,255,255,255
138 | Block: 32 Data: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
139 | Block: 33 Data: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
140 | Block: 34 Data: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
141 | Block: 35 Data: 0,0,0,0,0,0,255,7,128,105,255,255,255,255,255,255
142 | Block: 36 Data: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
143 | Block: 37 Data: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
144 | Block: 38 Data: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
145 | Block: 39 Data: 0,0,0,0,0,0,255,7,128,105,255,255,255,255,255,255
146 | Block: 40 Data: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
147 | Block: 41 Data: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
148 | Block: 42 Data: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
149 | Block: 43 Data: 0,0,0,0,0,0,255,7,128,105,255,255,255,255,255,255
150 | Block: 44 Data: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
151 | Block: 45 Data: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
152 | Block: 46 Data: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
153 | Block: 47 Data: 0,0,0,0,0,0,255,7,128,105,255,255,255,255,255,255
154 | Block: 48 Data: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
155 | Block: 49 Data: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
156 | Block: 50 Data: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
157 | Block: 51 Data: 0,0,0,0,0,0,255,7,128,105,255,255,255,255,255,255
158 | Block: 52 Data: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
159 | Block: 53 Data: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
160 | Block: 54 Data: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
161 | Block: 55 Data: 0,0,0,0,0,0,255,7,128,105,255,255,255,255,255,255
162 | Block: 56 Data: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
163 | Block: 57 Data: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
164 | Block: 58 Data: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
165 | Block: 59 Data: 0,0,0,0,0,0,255,7,128,105,255,255,255,255,255,255
166 | Block: 60 Data: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
167 | Block: 61 Data: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
168 | Block: 62 Data: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
169 | Block: 63 Data: 0,0,0,0,0,0,255,7,128,105,255,255,255,255,255,255
170 | ```
171 |
172 | ### Changing Authentication Keys
173 |
174 | This has so far only been tested with MiFare Classic 1K cards (the ones that come with the reader)!
175 | Please use the `writeAuthenticationKey` method
176 | (see the `writeAuthenticationKey.js` example in `test`).
177 |
178 | ## Documentation
179 |
180 | Manufacturer documentation of MFRC522
181 |
182 | [MFRC522-Doc.pdf](https://www.nxp.com/documents/data_sheet/MFRC522.pdf)
183 |
184 | [NFC-TAG Types](http://www.nfc-tag-shop.de/info/ueber-nfc-tags/nfc-tag-typen.html)
185 |
186 | [NTAG213_215_216.pdf](https://www.nxp.com/documents/data_sheet/NTAG213_215_216.pdf)
187 |
188 | ### Wiring
189 |
190 | Follow the map here to do the interface pins.
191 |
192 | | Name | Pin # | Pin name |
193 | | ------ | ----- | ------------------ |
194 | | SDA | 24 | CE0 |
195 | | SCK | 23 | SCLK1 |
196 | | MOSI | 19 | MOSI1 |
197 | | MISO | 21 | MOSO1 |
198 | | IRQ | None | None |
199 | | GND | Any | Any Ground |
200 | | RST | 22 | GPIO5C3 |
201 | | 3.3V | 1 | 3V3 |
202 | | Buzzer | 18 | GPIO5B3 (Optional) |
203 |
204 | Note that the pins number is different from the BCM number.
205 |
206 | 
207 |
208 | 
209 |
210 | ### Which hardware is used?
211 |
212 | List of hardware which are used with links to `amazon.de`:
213 |
214 | - [Raspberry Pi 3 B+](https://www.amazon.de/Raspberry-1373331-Pi-Modell-Mainboard/dp/B07BDR5PDW/ref=sr_1_3?crid=78XCCBIEFSD9&keywords=raspberry+pi+3+b%2B&qid=1565892766&s=gateway&sprefix=raspberry%2Caps%2C173&sr=8-3)
215 | - [RFID kit RC522](https://www.amazon.de/AZDelivery-Reader-Arduino-Raspberry-gratis/dp/B01M28JAAZ/ref=sr_1_1?keywords=MFRC522&qid=1565892804&s=gateway&sr=8-1)
216 |
217 | ## Buzzer Notifications (optional)
218 |
219 | It's possible to get buzzer notifications when the module reads a chip, simply connect a piezo speaker to your PI.
220 |
221 | ### Components for Buzzer
222 |
223 | - [DC to DC regulator (5V to 3.3V)](https://www.amazon.de/PEMENOL-AMS1117-Stromversorgungsmodul-Raspberry-Mikrocontroller/dp/B07FSLGPR8/ref=sr_1_1?keywords=AMS1117&qid=1565868927&s=ce-de&sr=1-1) (optional) used only if you want to interface buzzer with the system.
224 | 
225 | - [Active buzzer (NOT passive)](https://www.amazon.de/BETAFPV-Terminals-Electronic-Continuous-12X9-5mm/dp/B073RH8TQK/ref=sr_1_2?keywords=Active+buzzer&qid=1565892971&s=ce-de&sr=1-2) (optional)
226 | 
227 | - [NPN transistor](https://www.amazon.de/100pcs-S8050-S8050D-Transistor-40Volts/dp/B00CZ6K2SM/ref=sr_1_1?keywords=s8050&qid=1565894051&s=computers&sr=1-1) (Optional)
228 |
229 | Those three optional component are required to run the buzzer with 5V. The RC522 is running at 3.3V so we need to step down the voltage a bit.
230 |
231 | ### Wiring with Buzzer
232 |
233 | 
234 |
235 | ## Demonstration
236 |
237 | - Some images and video demonstration can be found [here](docs/demo.md)
238 |
239 | ## Circuit Diagram:
240 |
241 | Inside `project-diagram` folder there is a diagram for the system. You can run it with `Fritzing` application and make a printable PCB after aligning components on your wish.
242 |
243 | ### Sources
244 |
245 | https://github.com/miguelbalboa/rfid
246 |
247 | https://github.com/mxgxw/MFRC522-python
248 |
249 | ## Code of Conduct
250 |
251 | See the [CODE](CODE_OF_CONDUCT.md)
252 |
253 | ## License
254 |
255 | See the [LICENSE](LICENSE.md) file for license rights and limitations (MIT).
256 |
--------------------------------------------------------------------------------
/commands.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | module.exports = {
3 | PCD_IDLE: 0x00,
4 | PCD_AUTHENT: 0x0E,
5 | PCD_RECEIVE: 0x08,
6 | PCD_TRANSMIT: 0x04,
7 | PCD_TRANSCEIVE: 0x0C,
8 | PCD_RESETPHASE: 0x0F,
9 | PCD_CALCCRC: 0x03,
10 |
11 | PICC_REQIDL: 0x26,
12 | PICC_REQALL: 0x52,
13 | PICC_ANTICOLL: 0x93,
14 | PICC_SELECTTAG: 0x93,
15 | PICC_AUTHENT1A: 0x60,
16 | PICC_AUTHENT1B: 0x61,
17 | PICC_READ: 0x30,
18 | PICC_WRITE: 0xA0,
19 | PICC_DECREMENT: 0xC0,
20 | PICC_INCREMENT: 0xC1,
21 | PICC_RESTORE: 0xC2,
22 | PICC_TRANSFER: 0xB0,
23 | PICC_HALT: 0x50,
24 |
25 | Reserved00: 0x00,
26 | CommandReg: 0x01,
27 | CommIEnReg: 0x02,
28 | DivlEnReg: 0x03,
29 | CommIrqReg: 0x04,
30 | DivIrqReg: 0x05,
31 | ErrorReg: 0x06,
32 | Status1Reg: 0x07,
33 | Status2Reg: 0x08,
34 | FIFODataReg: 0x09,
35 | FIFOLevelReg: 0x0A,
36 | WaterLevelReg: 0x0B,
37 | ControlReg: 0x0C,
38 | BitFramingReg: 0x0D,
39 | CollReg: 0x0E,
40 | Reserved01: 0x0F,
41 |
42 | Reserved10: 0x10,
43 | ModeReg: 0x11,
44 | TxModeReg: 0x12,
45 | RxModeReg: 0x13,
46 | TxControlReg: 0x14,
47 | TxAutoReg: 0x15,
48 | TxSelReg: 0x16,
49 | RxSelReg: 0x17,
50 | RxThresholdReg: 0x18,
51 | DemodReg: 0x19,
52 | Reserved11: 0x1A,
53 | Reserved12: 0x1B,
54 | MifareReg: 0x1C,
55 | Reserved13: 0x1D,
56 | Reserved14: 0x1E,
57 | SerialSpeedReg: 0x1F,
58 |
59 | Reserved20: 0x20,
60 | CRCResultRegM: 0x21,
61 | CRCResultRegL: 0x22,
62 | Reserved21: 0x23,
63 | ModWidthReg: 0x24,
64 | Reserved22: 0x25,
65 | RFCfgReg: 0x26,
66 | GsNReg: 0x27,
67 | CWGsPReg: 0x28,
68 | ModGsPReg: 0x29,
69 | TModeReg: 0x2A,
70 | TPrescalerReg: 0x2B,
71 | TReloadRegH: 0x2C,
72 | TReloadRegL: 0x2D,
73 | TCounterValueRegH: 0x2E,
74 | TCounterValueRegL: 0x2F,
75 |
76 | Reserved30: 0x30,
77 | TestSel1Reg: 0x31,
78 | TestSel2Reg: 0x32,
79 | TestPinEnReg: 0x33,
80 | TestPinValueReg: 0x34,
81 | TestBusReg: 0x35,
82 | AutoTestReg: 0x36,
83 | VersionReg: 0x37,
84 | AnalogTestReg: 0x38,
85 | TestDAC1Reg: 0x39,
86 | TestDAC2Reg: 0x3A,
87 | TestADCReg: 0x3B,
88 | Reserved31: 0x3C,
89 | Reserved32: 0x3D,
90 | Reserved33: 0x3E,
91 | Reserved34: 0x3F
92 | }
--------------------------------------------------------------------------------
/docs/demo.md:
--------------------------------------------------------------------------------
1 | # Demonstration
2 |
3 | Those are some images related to a real module build with `mfrc522-rpi` library.
4 |
5 | 
6 | 
7 | 
8 | 
9 | 
10 | 
11 | 
12 | 
13 |
14 | **Video demo**
15 |
16 | 
17 |
18 | [Watch on Youtube (with sound)](https://youtu.be/e5D_fy8IIjY)
19 |
--------------------------------------------------------------------------------
/docs/demonstration/1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/firsttris/mfrc522-rpi/867d273ede5ac27c5a28408d307ffab7b86dcb8a/docs/demonstration/1.jpg
--------------------------------------------------------------------------------
/docs/demonstration/2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/firsttris/mfrc522-rpi/867d273ede5ac27c5a28408d307ffab7b86dcb8a/docs/demonstration/2.jpg
--------------------------------------------------------------------------------
/docs/demonstration/3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/firsttris/mfrc522-rpi/867d273ede5ac27c5a28408d307ffab7b86dcb8a/docs/demonstration/3.jpg
--------------------------------------------------------------------------------
/docs/demonstration/4.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/firsttris/mfrc522-rpi/867d273ede5ac27c5a28408d307ffab7b86dcb8a/docs/demonstration/4.jpg
--------------------------------------------------------------------------------
/docs/demonstration/5.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/firsttris/mfrc522-rpi/867d273ede5ac27c5a28408d307ffab7b86dcb8a/docs/demonstration/5.jpg
--------------------------------------------------------------------------------
/docs/demonstration/6.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/firsttris/mfrc522-rpi/867d273ede5ac27c5a28408d307ffab7b86dcb8a/docs/demonstration/6.jpg
--------------------------------------------------------------------------------
/docs/demonstration/7.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/firsttris/mfrc522-rpi/867d273ede5ac27c5a28408d307ffab7b86dcb8a/docs/demonstration/7.jpg
--------------------------------------------------------------------------------
/docs/demonstration/8.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/firsttris/mfrc522-rpi/867d273ede5ac27c5a28408d307ffab7b86dcb8a/docs/demonstration/8.jpg
--------------------------------------------------------------------------------
/docs/demonstration/9.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/firsttris/mfrc522-rpi/867d273ede5ac27c5a28408d307ffab7b86dcb8a/docs/demonstration/9.jpg
--------------------------------------------------------------------------------
/docs/demonstration/demo.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/firsttris/mfrc522-rpi/867d273ede5ac27c5a28408d307ffab7b86dcb8a/docs/demonstration/demo.gif
--------------------------------------------------------------------------------
/docs/demonstration/demo.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/firsttris/mfrc522-rpi/867d273ede5ac27c5a28408d307ffab7b86dcb8a/docs/demonstration/demo.mp4
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | const CMD = require("./commands");
3 | const rpio = require("rpio");
4 | const OK = true;
5 | const ERROR = false;
6 | let BUZZERCount = 1;
7 | let isCycleEnded = true;
8 |
9 | class MFRC522 {
10 | /**
11 | * Initialize MFRC522
12 | *
13 | * @param {any} SoftSPI object
14 | * @param {any} reset pin number
15 | * @memberof MFRC522
16 | */
17 | constructor(spi) {
18 | this.spi = spi;
19 | this.spi.open();
20 | return this;
21 | }
22 |
23 | setResetPin(pin = 22) {
24 | if (!pin) {
25 | throw new Error(
26 | "Invalid parameter! reset pin parameter is invalid or not provided!"
27 | );
28 | }
29 | this.reset_pin = pin;
30 | // Hold RESET pin low for 50ms to hard reset the reader
31 | rpio.open(this.reset_pin, rpio.OUTPUT, rpio.LOW);
32 | setTimeout(function() {
33 | rpio.write(this.reset_pin, rpio.HIGH);
34 | }.bind(this), 50);
35 | return this;
36 | }
37 |
38 | setBuzzerPin(pin) {
39 | // Set Alert mode and initial value.
40 | if (!pin) {
41 | throw new Error(
42 | "Invalid parameter! buzzer pin parameter is invalid or not provided!"
43 | );
44 | }
45 | this.buzzer_pin = pin;
46 | rpio.open(this.buzzer_pin, rpio.OUTPUT);
47 | rpio.write(this.buzzer_pin, rpio.LOW);
48 | return this;
49 | }
50 |
51 | /**
52 | * Initializes the MFRC522 chip.
53 | *
54 | * @memberof MFRC522
55 | */
56 | reset() {
57 | this.writeRegister(CMD.CommandReg, CMD.PCD_RESETPHASE); // reset chip
58 | this.writeRegister(CMD.TModeReg, 0x8d); // TAuto=1; timer starts automatically at the end of the transmission in all communication modes at all speeds
59 | this.writeRegister(CMD.TPrescalerReg, 0x3e); // TPreScaler = TModeReg[3..0]:TPrescalerReg, ie 0x0A9 = 169 => f_timer=40kHz, ie a timer period of 25μs.
60 | this.writeRegister(CMD.TReloadRegL, 30); // Reload timer with 0x3E8 = 1000, ie 25ms before timeout.
61 | this.writeRegister(CMD.TReloadRegH, 0);
62 | this.writeRegister(CMD.TxAutoReg, 0x40); // Default 0x00. Force a 100 % ASK modulation independent of the ModGsPReg register setting
63 | this.writeRegister(CMD.ModeReg, 0x3d); // Default 0x3F. Set the preset value for the CRC coprocessor for the CalcCRC command to 0x6363 (ISO 14443-3 part 6.2.4)
64 | this.antennaOn(); // Enable the antenna driver pins TX1 and TX2 (they were disabled by the reset)
65 | }
66 |
67 | /**
68 | * Writes a bit to the specified register in the MFRC522 chip.
69 | * The interface is described in the datasheet section 8.1.2.
70 | *
71 | * @param {any} addr
72 | * @param {any} val
73 | * @memberof MFRC522
74 | */
75 | writeRegister(addr, val) {
76 | const data = [(addr << 1) & 0x7e, val];
77 | const uint8Data = Uint8Array.from(data);
78 | this.spi.write(uint8Data);
79 | }
80 |
81 | /**
82 | * Alert card holder that the card has been read.
83 | */
84 | alert() {
85 | if (this.buzzer_pin) {
86 | setTimeout(() => {
87 | rpio.write(this.buzzer_pin, 1);
88 | setTimeout(() => {
89 | rpio.write(this.buzzer_pin, 0);
90 | BUZZERCount++;
91 | if (BUZZERCount == 3) {
92 | BUZZERCount = 1;
93 | isCycleEnded = true;
94 | } else {
95 | isCycleEnded = false;
96 | this.alert();
97 | }
98 | }, 80);
99 | }, 180);
100 | }
101 | }
102 |
103 | /**
104 | * Reads a bit from the specified register in the MFRC522 chip.
105 | * The interface is described in the datasheet section 8.1.2.
106 | *
107 | * @param {any} addr
108 | * @returns
109 | * @memberof MFRC522
110 | */
111 | readRegister(addr) {
112 | const data = [((addr << 1) & 0x7e) | 0x80, 0];
113 | const uint8Data = Uint8Array.from(data);
114 | const uint8DataResponse = this.spi.transfer(uint8Data);
115 | return uint8DataResponse[1];
116 | }
117 |
118 | /**
119 | * Sets the bits given in mask in register reg.
120 | *
121 | * @param {any} reg
122 | * @param {any} mask
123 | * @memberof MFRC522
124 | */
125 | setRegisterBitMask(reg, mask) {
126 | let response = this.readRegister(reg);
127 | this.writeRegister(reg, response | mask);
128 | }
129 |
130 | /**
131 | * Clears the bits given in mask from register reg.
132 | *
133 | * @param {any} reg
134 | * @param {any} mask
135 | * @memberof MFRC522
136 | */
137 | clearRegisterBitMask(reg, mask) {
138 | let response = this.readRegister(reg);
139 | this.writeRegister(reg, response & ~mask);
140 | }
141 |
142 | /**
143 | *
144 | *
145 | * @memberof MFRC522
146 | */
147 | antennaOn() {
148 | let response = this.readRegister(CMD.TxControlReg);
149 | if (~(response & 0x03) != 0) {
150 | this.setRegisterBitMask(CMD.TxControlReg, 0x03);
151 | }
152 | }
153 |
154 | /**
155 | *
156 | *
157 | * @memberof MFRC522
158 | */
159 | antennaOff() {
160 | this.clearRegisterBitMask(CMD.TxControlReg, 0x03);
161 | }
162 |
163 | /**
164 | *
165 | * RC522 and ISO14443 card communication
166 | * @param {any} command - command - MF522 command word
167 | * @param {any} bitsToSend - sent to the card through the RC522 data
168 | * @returns {{status: boolean, data: Array, bitSize: number}}
169 | * @memberof MFRC522
170 | */
171 | toCard(command, bitsToSend) {
172 | let data = [];
173 | let bitSize = 0;
174 | let status = ERROR;
175 | let irqEn = 0x00;
176 | let waitIRq = 0x00;
177 |
178 | if (command == CMD.PCD_AUTHENT) {
179 | irqEn = 0x12;
180 | waitIRq = 0x10;
181 | }
182 | if (command == CMD.PCD_TRANSCEIVE) {
183 | irqEn = 0x77;
184 | waitIRq = 0x30;
185 | }
186 | this.writeRegister(CMD.CommIEnReg, irqEn | 0x80); //Interrupt request is enabled
187 | this.clearRegisterBitMask(CMD.CommIrqReg, 0x80); //Clears all interrupt request bits
188 | this.setRegisterBitMask(CMD.FIFOLevelReg, 0x80); //FlushBuffer=1, FIFO initialization
189 | this.writeRegister(CMD.CommandReg, CMD.PCD_IDLE); // Stop calculating CRC for new content in the FIFO.
190 | //Write data to the FIFO
191 | for (let i = 0; i < bitsToSend.length; i++) {
192 | this.writeRegister(CMD.FIFODataReg, bitsToSend[i]);
193 | }
194 | //Excuting command
195 | this.writeRegister(CMD.CommandReg, command);
196 | if (command == CMD.PCD_TRANSCEIVE) {
197 | this.setRegisterBitMask(CMD.BitFramingReg, 0x80); //StartSend=1,transmission of data starts
198 | }
199 | //Wait for the received data to complete
200 | let i = 2000; //According to the clock frequency adjustment, operation M1 card maximum waiting time 25ms
201 | let n = 0;
202 | do {
203 | n = this.readRegister(CMD.CommIrqReg);
204 | i--;
205 | } while (i != 0 && !(n & 0x01) && !(n & waitIRq));
206 |
207 | this.clearRegisterBitMask(CMD.BitFramingReg, 0x80); //StartSend=0
208 | if (i != 0) {
209 | if ((this.readRegister(CMD.ErrorReg) & 0x1b) == 0x00) {
210 | //BufferOvfl Collerr CRCErr ProtecolErr
211 | status = OK;
212 | if (n & irqEn & 0x01) {
213 | status = ERROR;
214 | }
215 | if (command == CMD.PCD_TRANSCEIVE) {
216 | n = this.readRegister(CMD.FIFOLevelReg);
217 | let lastBits = this.readRegister(CMD.ControlReg) & 0x07;
218 | if (lastBits) {
219 | bitSize = (n - 1) * 8 + lastBits;
220 | } else {
221 | bitSize = n * 8;
222 | }
223 | if (n == 0) {
224 | n = 1;
225 | }
226 | if (n > 16) {
227 | n = 16;
228 | }
229 | //Reads the data received in the FIFO
230 | for (let i = 0; i < n; i++) {
231 | data.push(this.readRegister(CMD.FIFODataReg));
232 | }
233 | }
234 | } else {
235 | status = ERROR;
236 | }
237 | }
238 | return { status: status, data: data, bitSize: bitSize };
239 | }
240 |
241 | /**
242 | * Alert card holder that the card has been read.
243 | */
244 | static alert() {
245 | setTimeout(() => {
246 | WiringPi.digitalWrite(BUZZER, 1);
247 | setTimeout(() => {
248 | WiringPi.digitalWrite(BUZZER, 0);
249 | BUZZERCount++;
250 | if (BUZZERCount == 3) {
251 | BUZZERCount = 1;
252 | isCycleEnded = true;
253 | } else {
254 | isCycleEnded = false;
255 | this.alert();
256 | }
257 | }, 80);
258 | }, 180);
259 | }
260 |
261 | /**
262 | * Find card, read card type
263 | * TagType - Returns the card type
264 | * 0x4400 = Mifare_UltraLight
265 | * 0x0400 = Mifare_One (S50)
266 | * 0x0200 = Mifare_One (S70)
267 | * 0x0800 = Mifare_Pro (X)
268 | * 0x4403 = Mifare_DESFire
269 | *
270 | * @returns {{status: *, bitSize: *}}
271 | * @memberof MFRC522
272 | */
273 | findCard() {
274 | if (isCycleEnded) {
275 | this.writeRegister(CMD.BitFramingReg, 0x07);
276 | const tagType = [CMD.PICC_REQIDL];
277 | let response = this.toCard(CMD.PCD_TRANSCEIVE, tagType);
278 | if (response.bitSize != 0x10) {
279 | response.status = ERROR;
280 | }
281 | return { status: response.status, bitSize: response.bitSize };
282 | }
283 | return { status: null, bitSize: null };
284 | }
285 |
286 | /**
287 | * Anti-collision detection, get uid (serial number) of found card
288 | * 4-bit card to return the serial number, the first five bit for the check bit
289 | *
290 | * @returns {{status: *, data: Array, bitSize: *}}
291 | * @memberof MFRC522
292 | */
293 | getUid() {
294 | this.alert();
295 | this.writeRegister(CMD.BitFramingReg, 0x00);
296 | const uid = [CMD.PICC_ANTICOLL, 0x20];
297 | let response = this.toCard(CMD.PCD_TRANSCEIVE, uid);
298 | if (response.status) {
299 | let uidCheck = 0;
300 | for (let i = 0; i < 4; i++) {
301 | uidCheck = uidCheck ^ response.data[i];
302 | }
303 | if (uidCheck != response.data[4]) {
304 | response.status = ERROR;
305 | }
306 | }
307 | return { status: response.status, data: response.data };
308 | }
309 |
310 | /**
311 | * Use the CRC coprocessor in the MFRC522 to calculate a CRC
312 | *
313 | * @param {any} data
314 | * @returns {array}
315 | * @memberof MFRC522
316 | */
317 | calculateCRC(data) {
318 | this.clearRegisterBitMask(CMD.DivIrqReg, 0x04); // Clear the CRCIRq interrupt request bit
319 | this.setRegisterBitMask(CMD.FIFOLevelReg, 0x80); // FlushBuffer = 1, FIFO initialization
320 | //Write data to the FIFO
321 | for (let i = 0; i < data.length; i++) {
322 | this.writeRegister(CMD.FIFODataReg, data[i]);
323 | }
324 | this.writeRegister(CMD.CommandReg, CMD.PCD_CALCCRC);
325 | //Wait for the CRC calculation to complete
326 | let i = 0xff;
327 | let n;
328 | do {
329 | n = this.readRegister(CMD.DivIrqReg);
330 | i--;
331 | } while (i != 0 && !(n & 0x04)); //CRCIrq = 1
332 | //CRC calculation result
333 | return [
334 | this.readRegister(CMD.CRCResultRegL),
335 | this.readRegister(CMD.CRCResultRegM)
336 | ];
337 | }
338 |
339 | /**
340 | * Select card by, returns card memory capacity
341 | *
342 | * @param {any} uid
343 | * @returns
344 | * @memberof MFRC522
345 | */
346 | selectCard(uid) {
347 | let buffer = [CMD.PICC_SELECTTAG, 0x70];
348 | for (let i = 0; i < 5; i++) {
349 | buffer.push(uid[i]);
350 | }
351 | buffer = buffer.concat(this.calculateCRC(buffer));
352 | let response = this.toCard(CMD.PCD_TRANSCEIVE, buffer);
353 | let memoryCapacity = 0;
354 | if (response.status && response.bitSize == 0x18) {
355 | memoryCapacity = response.data[0];
356 | }
357 | return memoryCapacity;
358 | }
359 |
360 | /**
361 | * Verify the card password
362 | * Auth at Block N+1 with Key from Block N
363 | * Examle: Block 7 has Credentials from Block 8, in Block 7 there are 2 Keys A and B
364 | * @param address - block address
365 | * @param key - password for block
366 | * @param uid - card serial number, 4 bit
367 | * @returns {*}
368 | * @memberof MFRC522
369 | */
370 | authenticate(address, key, uid) {
371 | /* Password authentication mode (A or B)
372 | * 0x60 = Verify the A key are the first 6 bit
373 | * 0x61 = Verify the B key are the last 6 bit
374 | * Second bit is the block address
375 | */
376 | let buffer = [CMD.PICC_AUTHENT1A, address];
377 | // Key default 6 bit of 0xFF
378 | for (let i = 0; i < key.length; i++) {
379 | buffer.push(key[i]);
380 | }
381 | // Next we append the first 4 bit of the UID
382 | for (let j = 0; j < 4; j++) {
383 | buffer.push(uid[j]);
384 | }
385 | // Now we start the authentication itself
386 | let response = this.toCard(CMD.PCD_AUTHENT, buffer);
387 | if (!(this.readRegister(CMD.Status2Reg) & 0x08)) {
388 | response.status = ERROR;
389 | }
390 | return response.status;
391 | }
392 |
393 | /**
394 | *
395 | *
396 | * @memberof MFRC522
397 | */
398 | stopCrypto() {
399 | this.clearRegisterBitMask(CMD.Status2Reg, 0x08);
400 | }
401 |
402 | /**
403 | * Get Data for Block
404 | *
405 | * @param {any} address
406 | * @returns
407 | * @memberof MFRC522
408 | */
409 | getDataForBlock(address) {
410 | let request = [CMD.PICC_READ, address];
411 | request = request.concat(this.calculateCRC(request));
412 | let response = this.toCard(CMD.PCD_TRANSCEIVE, request);
413 | if (!response.status) {
414 | console.log(
415 | "Error while reading! Status: " +
416 | response.status +
417 | " Data: " +
418 | response.data +
419 | " BitSize: " +
420 | response.bitSize
421 | );
422 | }
423 | return response.data;
424 | }
425 |
426 | /**
427 | *
428 | *
429 | * @param {any} buffer
430 | * @returns
431 | * @memberof MFRC522
432 | */
433 | appendCRCtoBufferAndSendToCard(buffer) {
434 | buffer = buffer.concat(this.calculateCRC(buffer));
435 | let response = this.toCard(CMD.PCD_TRANSCEIVE, buffer);
436 | if (
437 | !response.status ||
438 | response.bitSize != 4 ||
439 | (response.data[0] & 0x0f) != 0x0a
440 | ) {
441 | console.log(
442 | "Error while writing! Status: " +
443 | response.status +
444 | " Data: " +
445 | response.data +
446 | " BitSize: " +
447 | response.bitSize
448 | );
449 | response.status = ERROR;
450 | }
451 | return response;
452 | }
453 |
454 | /**
455 | * Write Data To Block
456 | *
457 | * @param {any} address
458 | * @param {any} sixteenBits
459 | * @memberof MFRC522
460 | */
461 | writeDataToBlock(address, sixteenBits) {
462 | let buffer = [];
463 | buffer.push(CMD.PICC_WRITE);
464 | buffer.push(address);
465 | let response = this.appendCRCtoBufferAndSendToCard(buffer);
466 | if (response.status) {
467 | buffer = [];
468 | // Write 16 bit of data to the FIFO
469 | for (let i = 0; i < 16; i++) {
470 | buffer.push(sixteenBits[i]);
471 | }
472 | response = this.appendCRCtoBufferAndSendToCard(buffer);
473 | if (response.status) {
474 | console.log("Data written successfully");
475 | }
476 | }
477 | }
478 |
479 | /**
480 | * Write a new authentication key
481 | * @param {Number} address - block address
482 | * @param {Array} newKey - new key A, 6 bytes
483 | * @returns {Boolean}
484 | * @memberof MFRC522
485 | */
486 | writeAuthenticationKey(address, newKeyA) {
487 | if (!address || !newKeyA) {
488 | return false;
489 | }
490 |
491 | if (address % 4 !== 3) {
492 | const offset = 3 - (address % 4);
493 | console.log(
494 | "Error: Chosen block is not a sector trailer! " +
495 | "Please write authentication key to block " +
496 | (address + offset) +
497 | "!"
498 | );
499 | return false;
500 | }
501 |
502 | if (newKeyA.length !== 6) {
503 | console.log("Error: Key length must be 6!");
504 | return false;
505 | }
506 |
507 | const data = this.getDataForBlock(address);
508 | const newData = newKeyA.concat(data.slice(6));
509 | return this.writeDataToBlock(address, newData);
510 | }
511 | }
512 |
513 | module.exports = MFRC522;
514 |
--------------------------------------------------------------------------------
/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "mfrc522-rpi",
3 | "version": "2.1.4",
4 | "lockfileVersion": 1,
5 | "requires": true,
6 | "dependencies": {
7 | "bindings": {
8 | "version": "1.5.0",
9 | "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz",
10 | "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==",
11 | "requires": {
12 | "file-uri-to-path": "1.0.0"
13 | }
14 | },
15 | "file-uri-to-path": {
16 | "version": "1.0.0",
17 | "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz",
18 | "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw=="
19 | },
20 | "nan": {
21 | "version": "2.14.1",
22 | "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.1.tgz",
23 | "integrity": "sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw=="
24 | },
25 | "rpi-softspi": {
26 | "version": "1.0.5",
27 | "resolved": "https://registry.npmjs.org/rpi-softspi/-/rpi-softspi-1.0.5.tgz",
28 | "integrity": "sha512-b9umzQUk7p6HRSmQV3U9+ooboBOaodzJwqvZjX993D88geQePNzLaZDDQkMW2Ny14FwSUB3IvpBP3KFzv2rdaA==",
29 | "requires": {
30 | "rpio": "*"
31 | }
32 | },
33 | "rpio": {
34 | "version": "1.7.1",
35 | "resolved": "https://registry.npmjs.org/rpio/-/rpio-1.7.1.tgz",
36 | "integrity": "sha512-jjccmmNHDOK4jsKNQVZcXCa1fKPUlO4BOcYZk5pdU8cPWyjcCh6D1/tpNYq5fOjeyGuemE6o9AZSRx6q7ICPcw==",
37 | "requires": {
38 | "bindings": "~1.5.0",
39 | "nan": "~2.14.0"
40 | }
41 | }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "mfrc522-rpi",
3 | "version": "2.1.4",
4 | "description": "small JavaScript interface to control RFID reader MFRC522 with Raspberry-pi",
5 | "main": "index.js",
6 | "scripts": {
7 | "read": "node test/read.js",
8 | "write": "node test/write.js",
9 | "dump": "node test/dumpCard.js"
10 | },
11 | "keywords": [
12 | "mfrc522",
13 | "rfid",
14 | "nfc",
15 | "rpi",
16 | "internet-of-things",
17 | "iot",
18 | "javascript",
19 | "nodejs"
20 | ],
21 | "author": "Tristan Teufel",
22 | "license": "ISC",
23 | "repository": {
24 | "type": "git",
25 | "url": "https://github.com/firsttris/mfrc522-rpi.git"
26 | },
27 | "dependencies": {
28 | "rpi-softspi": "^1.0.5",
29 | "rpio": "^1.3.0"
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/project-diagram/mfrc-522-node.fzz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/firsttris/mfrc522-rpi/867d273ede5ac27c5a28408d307ffab7b86dcb8a/project-diagram/mfrc-522-node.fzz
--------------------------------------------------------------------------------
/project-diagram/modules/AMS1117/AMS1117.fzpz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/firsttris/mfrc522-rpi/867d273ede5ac27c5a28408d307ffab7b86dcb8a/project-diagram/modules/AMS1117/AMS1117.fzpz
--------------------------------------------------------------------------------
/project-diagram/modules/AMS1117/AMS1117_bb.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/project-diagram/modules/AMS1117/AMS1117_pcb.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
162 |
--------------------------------------------------------------------------------
/project-diagram/modules/AMS1117/AMS1117_schematic.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
315 |
--------------------------------------------------------------------------------
/project-diagram/modules/RFID RC522 SIP - 8 pins.fzpz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/firsttris/mfrc522-rpi/867d273ede5ac27c5a28408d307ffab7b86dcb8a/project-diagram/modules/RFID RC522 SIP - 8 pins.fzpz
--------------------------------------------------------------------------------
/test/dumpCard.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | const Mfrc522 = require("./../index");
3 | const SoftSPI = require("rpi-softspi");
4 |
5 | //# This loop keeps checking for chips. If one is near it will get the UID and authenticate
6 | console.log("scanning...");
7 | console.log("Please put chip or keycard in the antenna inductive zone!");
8 | console.log("Press Ctrl-C to stop.");
9 |
10 | const softSPI = new SoftSPI({
11 | clock: 23, // pin number of SCLK
12 | mosi: 19, // pin number of MOSI
13 | miso: 21, // pin number of MISO
14 | client: 24 // pin number of CS
15 | });
16 |
17 | // GPIO 24 can be used for buzzer bin (PIN 18), Reset pin is (PIN 22).
18 | // I believe that channing pattern is better for configuring pins which are optional methods to use.
19 | const mfrc522 = new Mfrc522(softSPI).setResetPin(22).setBuzzerPin(18);
20 |
21 | setInterval(function() {
22 | //# reset card
23 | mfrc522.reset();
24 |
25 | //# Scan for cards
26 | let response = mfrc522.findCard();
27 | if (!response.status) {
28 | return;
29 | }
30 | console.log("Card detected, CardType: " + response.bitSize);
31 |
32 | //# Get the UID of the card
33 | response = mfrc522.getUid();
34 | if (!response.status) {
35 | console.log("UID Scan Error");
36 | return;
37 | }
38 | //# If we have the UID, continue
39 | const uid = response.data;
40 | console.log(
41 | "Card read UID: %s %s %s %s",
42 | uid[0].toString(16),
43 | uid[1].toString(16),
44 | uid[2].toString(16),
45 | uid[3].toString(16)
46 | );
47 |
48 | //# Select the scanned card
49 | const memoryCapacity = mfrc522.selectCard(uid);
50 | console.log("Card Memory Capacity: " + memoryCapacity);
51 |
52 | //# This is the default key for authentication
53 | const keyA = [0xff, 0xff, 0xff, 0xff, 0xff, 0xff];
54 | const keyB = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00];
55 |
56 | //# dump 64 bit fifo buffer
57 | for (let i = 0; i < 64; i++) {
58 | if (mfrc522.authenticate(i, keyA, uid)) {
59 | console.log("Block: " + i + " Data: " + mfrc522.getDataForBlock(i));
60 | } else {
61 | console.log("Authentication Error");
62 | break;
63 | }
64 | }
65 |
66 | //# Stop
67 | mfrc522.stopCrypto();
68 | }, 500);
69 |
--------------------------------------------------------------------------------
/test/dumpNTAG213.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | const Mfrc522 = require("./../index");
3 | const SoftSPI = require("rpi-softspi");
4 |
5 | //# This loop keeps checking for chips. If one is near it will get the UID and authenticate
6 | console.log("scanning...");
7 | console.log("Please put chip or keycard in the antenna inductive zone!");
8 | console.log("Press Ctrl-C to stop.");
9 |
10 | const softSPI = new SoftSPI({
11 | clock: 23, // pin number of SCLK
12 | mosi: 19, // pin number of MOSI
13 | miso: 21, // pin number of MISO
14 | client: 24 // pin number of CS
15 | });
16 |
17 | // GPIO 24 can be used for buzzer bin (PIN 18), Reset pin is (PIN 22).
18 | // I believe that channing pattern is better for configuring pins which are optional methods to use.
19 | const mfrc522 = new Mfrc522(softSPI).setResetPin(22).setBuzzerPin(18);
20 |
21 | setInterval(function() {
22 | //# reset card
23 | mfrc522.reset();
24 |
25 | //# Scan for cards
26 | let response = mfrc522.findCard();
27 | if (!response.status) {
28 | return;
29 | }
30 | console.log("Card detected, CardType: " + response.bitSize);
31 |
32 | //# Get the UID of the card
33 | response = mfrc522.getUid();
34 | if (!response.status) {
35 | console.log("UID Scan Error");
36 | return;
37 | }
38 | //# If we have the UID, continue
39 | const uid = response.data;
40 | console.log(
41 | "Card read UID: %s %s %s %s",
42 | uid[0].toString(16),
43 | uid[1].toString(16),
44 | uid[2].toString(16),
45 | uid[3].toString(16)
46 | );
47 |
48 | //# Select the scanned card
49 | const memoryCapacity = mfrc522.selectCard(uid);
50 | console.log("Card Memory Capacity: " + memoryCapacity);
51 |
52 | //# dump fifo buffer
53 | for (let i = 0; i < 45; i++) {
54 | console.log("Block: " + i + " Data: " + mfrc522.getDataForBlock(i));
55 | }
56 | }, 500);
57 |
--------------------------------------------------------------------------------
/test/read.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | const Mfrc522 = require("./../index");
3 | const SoftSPI = require("rpi-softspi");
4 |
5 | //# This loop keeps checking for chips. If one is near it will get the UID and authenticate
6 | console.log("scanning...");
7 | console.log("Please put chip or keycard in the antenna inductive zone!");
8 | console.log("Press Ctrl-C to stop.");
9 |
10 | const softSPI = new SoftSPI({
11 | clock: 23, // pin number of SCLK
12 | mosi: 19, // pin number of MOSI
13 | miso: 21, // pin number of MISO
14 | client: 24 // pin number of CS
15 | });
16 |
17 | // GPIO 24 can be used for buzzer bin (PIN 18), Reset pin is (PIN 22).
18 | // I believe that channing pattern is better for configuring pins which are optional methods to use.
19 | const mfrc522 = new Mfrc522(softSPI).setResetPin(22).setBuzzerPin(18);
20 |
21 | setInterval(function() {
22 | //# reset card
23 | mfrc522.reset();
24 |
25 | //# Scan for cards
26 | let response = mfrc522.findCard();
27 | if (!response.status) {
28 | console.log("No Card");
29 | return;
30 | }
31 | console.log("Card detected, CardType: " + response.bitSize);
32 |
33 | //# Get the UID of the card
34 | response = mfrc522.getUid();
35 | if (!response.status) {
36 | console.log("UID Scan Error");
37 | return;
38 | }
39 | //# If we have the UID, continue
40 | const uid = response.data;
41 | console.log(
42 | "Card read UID: %s %s %s %s",
43 | uid[0].toString(16),
44 | uid[1].toString(16),
45 | uid[2].toString(16),
46 | uid[3].toString(16)
47 | );
48 |
49 | //# Select the scanned card
50 | const memoryCapacity = mfrc522.selectCard(uid);
51 | console.log("Card Memory Capacity: " + memoryCapacity);
52 |
53 | //# This is the default key for authentication
54 | const key = [0xff, 0xff, 0xff, 0xff, 0xff, 0xff];
55 |
56 | //# Authenticate on Block 8 with key and uid
57 | if (!mfrc522.authenticate(8, key, uid)) {
58 | console.log("Authentication Error");
59 | return;
60 | }
61 |
62 | //# Dump Block 8
63 | console.log("Block: 8 Data: " + mfrc522.getDataForBlock(8));
64 |
65 | //# Stop
66 | mfrc522.stopCrypto();
67 | }, 500);
68 |
--------------------------------------------------------------------------------
/test/write.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | const Mfrc522 = require("./../index");
3 | const SoftSPI = require("rpi-softspi");
4 |
5 | //# This loop keeps checking for chips. If one is near it will get the UID and authenticate
6 | console.log("scanning...");
7 | console.log("Please put chip or keycard in the antenna inductive zone!");
8 | console.log("Press Ctrl-C to stop.");
9 |
10 | const softSPI = new SoftSPI({
11 | clock: 23, // pin number of SCLK
12 | mosi: 19, // pin number of MOSI
13 | miso: 21, // pin number of MISO
14 | client: 24 // pin number of CS
15 | });
16 |
17 | // GPIO 24 can be used for buzzer bin (PIN 18), Reset pin is (PIN 22).
18 | // I believe that channing pattern is better for configuring pins which are optional methods to use.
19 | const mfrc522 = new Mfrc522(softSPI).setResetPin(22).setBuzzerPin(18);
20 |
21 | setInterval(function() {
22 | //# reset card
23 | mfrc522.reset();
24 |
25 | //# Scan for cards
26 | let response = mfrc522.findCard();
27 | if (!response.status) {
28 | console.log("No Card");
29 | return;
30 | }
31 | console.log("Card detected, CardType: " + response.bitSize);
32 |
33 | //# Get the UID of the card
34 | response = mfrc522.getUid();
35 | if (!response.status) {
36 | console.log("UID Scan Error");
37 | return;
38 | }
39 | //# If we have the UID, continue
40 | const uid = response.data;
41 | console.log(
42 | "Card read UID: %s %s %s %s",
43 | uid[0].toString(16),
44 | uid[1].toString(16),
45 | uid[2].toString(16),
46 | uid[3].toString(16)
47 | );
48 |
49 | //# Select the scanned card
50 | const memoryCapacity = mfrc522.selectCard(uid);
51 | console.log("Card Memory Capacity: " + memoryCapacity);
52 |
53 | //# This is the default key for authentication
54 | const key = [0xff, 0xff, 0xff, 0xff, 0xff, 0xff];
55 |
56 | //# Authenticate on Block 8 with key and uid
57 | if (!mfrc522.authenticate(8, key, uid)) {
58 | console.log("Authentication Error");
59 | return;
60 | }
61 |
62 | //# Variable for the data to write
63 | let data = [
64 | 0xff,
65 | 0xff,
66 | 0xff,
67 | 0xff,
68 | 0xff,
69 | 0xff,
70 | 0xff,
71 | 0xff,
72 | 0xff,
73 | 0xff,
74 | 0xff,
75 | 0xff,
76 | 0xff,
77 | 0xff,
78 | 0xff,
79 | 0xff,
80 | 0xff
81 | ];
82 |
83 | console.log("Block 8 looked like this:");
84 | console.log(mfrc522.getDataForBlock(8));
85 |
86 | console.log("Block 8 will be filled with 0xFF:");
87 | mfrc522.writeDataToBlock(8, data);
88 |
89 | console.log("Now Block 8 looks like this:");
90 | console.log(mfrc522.getDataForBlock(8));
91 |
92 | data = [
93 | 0x00,
94 | 0x00,
95 | 0x00,
96 | 0x00,
97 | 0x00,
98 | 0x00,
99 | 0x00,
100 | 0x00,
101 | 0x00,
102 | 0x00,
103 | 0x00,
104 | 0x00,
105 | 0x00,
106 | 0x00,
107 | 0x00,
108 | 0x00,
109 | 0x00
110 | ];
111 |
112 | console.log("Now we fill it with 16 x 0");
113 | mfrc522.writeDataToBlock(8, data);
114 |
115 | console.log("It is now empty:");
116 | console.log(mfrc522.getDataForBlock(8));
117 |
118 | mfrc522.stopCrypto();
119 |
120 | console.log("finished successfully!");
121 | }, 500);
122 |
--------------------------------------------------------------------------------
/test/writeAuthenticationKey.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | const Mfrc522 = require("./../index"); // when using module, change this to: require("mfrc522-rpi")
3 | const SoftSPI = require("rpi-softspi");
4 |
5 | //# This loop keeps checking for chips. If one is near it will get the UID and authenticate
6 | console.log("scanning...");
7 | console.log("Please put chip or keycard in the antenna inductive zone!");
8 | console.log("Press Ctrl-C to stop.");
9 |
10 | const softSPI = new SoftSPI({
11 | clock: 23, // pin number of SCLK
12 | mosi: 19, // pin number of MOSI
13 | miso: 21, // pin number of MISO
14 | client: 24 // pin number of CS
15 | });
16 |
17 | // GPIO 24 can be used for buzzer bin (PIN 18), Reset pin is (PIN 22).
18 | // I believe that channing pattern is better for configuring pins which are optional methods to use.
19 | const mfrc522 = new Mfrc522(softSPI).setResetPin(22).setBuzzerPin(18);
20 |
21 | setInterval(function() {
22 | //# reset card
23 | mfrc522.reset();
24 |
25 | //# Scan for cards
26 | let response = mfrc522.findCard();
27 | if (!response.status) {
28 | return;
29 | }
30 |
31 | console.log("Card detected, CardType: " + response.bitSize);
32 |
33 | //# Get the UID of the card
34 | response = mfrc522.getUid();
35 | if (!response.status) {
36 | console.log("UID Scan Error");
37 | return;
38 | }
39 | //# If we have the UID, continue
40 | const uid = response.data;
41 | console.log(
42 | "Card read UID: %s %s %s %s",
43 | uid[0].toString(16),
44 | uid[1].toString(16),
45 | uid[2].toString(16),
46 | uid[3].toString(16)
47 | );
48 |
49 | //# Select the scanned card
50 | const memoryCapacity = mfrc522.selectCard(uid);
51 | console.log("Card Memory Capacity: " + memoryCapacity);
52 |
53 | //# oldKey is the default key for authentication
54 | const oldKey = [0xff, 0xff, 0xff, 0xff, 0xff, 0xff];
55 | const newKey = [0x11, 0x22, 0x33, 0x44, 0x55, 0x66];
56 |
57 | //# Authenticate on Block 11 with key and uid
58 | if (!mfrc522.authenticate(11, oldKey, uid)) {
59 | console.log("Authentication Error");
60 | return;
61 | }
62 |
63 | console.log("Changing access key in block 11 for blocks 8-11 to:", newKey);
64 | mfrc522.writeAuthenticationKey(11, newKey);
65 |
66 | console.log("Now we can use the new access key to store data in block 10...");
67 |
68 | if (!mfrc522.authenticate(10, newKey, uid)) {
69 | console.log("Authentication Error");
70 | return;
71 | }
72 |
73 | const oldData = mfrc522.getDataForBlock(10);
74 | console.log("Block 10 previous data: ", oldData);
75 | const newData = [
76 | 0x00,
77 | 0x01,
78 | 0x02,
79 | 0x03,
80 | 0x04,
81 | 0x05,
82 | 0x06,
83 | 0x07,
84 | 0x08,
85 | 0x09,
86 | 0x0a,
87 | 0x0b,
88 | 0x0c,
89 | 0x0d,
90 | 0x0e,
91 | 0x0f
92 | ];
93 | console.log("Data to write: ", newData);
94 | mfrc522.writeDataToBlock(10, newData);
95 | console.log("Block 10 data is now: ", mfrc522.getDataForBlock(10));
96 | console.log("Change block 10 back to previous data");
97 | mfrc522.writeDataToBlock(10, oldData);
98 |
99 | console.log("Now we change the access key back to factory default");
100 | mfrc522.writeAuthenticationKey(11, oldKey);
101 |
102 | mfrc522.stopCrypto();
103 |
104 | console.log("finished successfully!");
105 | process.exit();
106 | }, 500);
107 |
--------------------------------------------------------------------------------
/wiki/GPIO-pins.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/firsttris/mfrc522-rpi/867d273ede5ac27c5a28408d307ffab7b86dcb8a/wiki/GPIO-pins.png
--------------------------------------------------------------------------------
/wiki/RC522.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/firsttris/mfrc522-rpi/867d273ede5ac27c5a28408d307ffab7b86dcb8a/wiki/RC522.jpg
--------------------------------------------------------------------------------
/wiki/ams1117.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/firsttris/mfrc522-rpi/867d273ede5ac27c5a28408d307ffab7b86dcb8a/wiki/ams1117.png
--------------------------------------------------------------------------------
/wiki/buzzer.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/firsttris/mfrc522-rpi/867d273ede5ac27c5a28408d307ffab7b86dcb8a/wiki/buzzer.jpg
--------------------------------------------------------------------------------
/wiki/diff-passive-active-buzzer.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/firsttris/mfrc522-rpi/867d273ede5ac27c5a28408d307ffab7b86dcb8a/wiki/diff-passive-active-buzzer.jpg
--------------------------------------------------------------------------------
/wiki/gpio-map.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/firsttris/mfrc522-rpi/867d273ede5ac27c5a28408d307ffab7b86dcb8a/wiki/gpio-map.png
--------------------------------------------------------------------------------
/wiki/mfrc522-node.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/firsttris/mfrc522-rpi/867d273ede5ac27c5a28408d307ffab7b86dcb8a/wiki/mfrc522-node.png
--------------------------------------------------------------------------------
/wiki/rpi-mfrc522-wiring2.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/firsttris/mfrc522-rpi/867d273ede5ac27c5a28408d307ffab7b86dcb8a/wiki/rpi-mfrc522-wiring2.PNG
--------------------------------------------------------------------------------
/wiki/youtube.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/firsttris/mfrc522-rpi/867d273ede5ac27c5a28408d307ffab7b86dcb8a/wiki/youtube.png
--------------------------------------------------------------------------------