3

I am building a Raspberry Pi B+ powered survey device. It would use NFC scanners for multiple choice questions. It should display a question on LCD screen and the user should have his NFC tag scanned by NFC scanner corresponding to his choice.

I am planning on using SunFounder's NFC scanner for Raspberry Pi, however, if I use separate GPIO pins for separate scanners, I can only read from 3 scanners which is not enough.

According to the user manual, NFC scanner uses 5 GPIO pins + 5V + GND out 26 available like this:

  • one is connected to GPIO 10 (SPIO_MOSI)
  • GPIO 9 (SPIO_MISO)
  • GPIO 8 (SPI_CE0)
  • GPIO 17
  • 5V, GND

I found no comments whatsoever which pin is used for what.

The device needs to identify NFC tag and the answer chosen (ie, scanner which read NFC tag).

Now the questions are can I reuse some (all) of the pins used to transfer NFC tag information and do I need to use some logic, for example, Charlieplexing to identify scanner?

julka
  • 141
  • 1
  • 4
  • Can you give a better link to the NFC scanner you plan to use than some PDF document? Ideally give us the details in your answer instead of in an external link, so this question stays readable and relevant even if the link document disappears? – Phil B. May 21 '15 at 10:21
  • That PDF is the user manual of the scanner. I guess, I could try extracting the relevant details. – julka May 21 '15 at 10:36
  • Why not just buy some USB NFC readers? – user1133275 May 23 '15 at 22:49

4 Answers4

2

According to the documentation, the device you link can be used as an SPI device. Unfortunately, with the default pins for SPI, as far as I know, you only get 2 Chip Select pins, so you can drive maximum 2 cards this way when using standard available libraries. If you want to drive all 4, you cannot rely on those libraries and will need to do some bit-banging (unless my quick google search skipped something of course), but it only requires 2 extra GPIO pins (Easily available) or can even be done with the original 2 pins if you use a demultiplexer IC (0,0 = card 1; 0,1 = card 2; 1,0 = card 3 and 1,1 = card 4).

Now for some alternatives:

  1. Have you thought about giving your contestants 4 different tags, one for each answer? That way you can bring your setup down to 1 reader, no reading conflicts, and you replicate just the cheapest component in your setup (the RFID tag)
  2. You might want to look into different RFID readers - This one from Adafruit does UART, SPI and I2C. Since all of those mechanisms are available on the Pi (and it supports 2 devices via SPI) you could put one via UART, one via I2C and 2 via SPI. The card seems to have 2 select pin headers on it as well, I'm not sure if this would allow you to set different I2C addresses, but if it does and depending on how many different addresses it supports, you might be able to plug all of those on the same I2C bus and use them this way.

UPDATE: The two select headers are to select SPI, UART or I2C mode, not to set the I2C address. That address is fixed at 0x48 for all PN532 based cards, so you cannot put two of them on the same I2C bus, not even if you buy them from different board suppliers.

Phil B.
  • 5,043
  • 15
  • 30
  • Can I send data to say UART pin from several cards and use demultiplexing logic (additional GPIO pins) to extend the number of scanners it can support? Assume only one scanner reads a tag at any single time. – julka May 21 '15 at 11:07
  • UART is a serial protocol - it is really designed for communication between 2 devices, one on each end, not one-to-many. Even if you managed to multiplex devices, they wouldn't be able to identify themselves as being different, so how would you determine from which NFC reader the response comes? – Phil B. May 21 '15 at 13:58
  • I am a total newbie when it comes to hardware. I only needed "use friggin I2C that allows you to speak to multiple slaves as https://www.raspberrypi.org/forums/viewtopic.php?f=44&t=20852 suggests". – julka May 21 '15 at 17:50
  • I2C indeed allows you to control multiple devices on the same bus, BUT, if those devices are the same make & model, you need to be sure that you can set a separate I2C address for each of them, otherwise they both (or all 4) listen to the same address and you get conflicts, or cannot determine which reader the signal comes from. The NFC card you mention does not have an I2C connection, the one I mentioned from Adafruit does. – Phil B. May 21 '15 at 17:58
  • Both the Adafruit and the Sunfounder board use the same NXP PN532 NFC chip, but the adafruit one has the clear, documented ability to select SPI, I2C or UART as the communication mode. The Sunfounder board claims to support the same, but I guess you need to find the right pins in the "Raspberry Pi 20 pin header" they put on their board, unless you use the separate breakout for SPI on the 8-pin header. Since they both have the same chip, you could mix them and use the Sunfounder for your 2 SPI ones, and then the Adafruit one as I2C (address 0x48) and UART. – Phil B. May 21 '15 at 18:16
  • 3
    This post over at the Adafruit forums confirms you cannot change the I2C address on the PN532. – Phil B. May 21 '15 at 18:17
1

I know this is an old question and likely resolved but for anyone still finding this, maybe this will help:

I've been working on a Project using multiple NFC Readers (MFRC522). I used pimylifeup's MFRC522-Python Library and wrote my own NFC class based on the SimpleMFRC522 class provided by the Library. It closes the SPI Connection whenever I want to switch to a different reader and reopens it after setting the appropiate reader's RST Pin to high.

The order of events to copy the contents of a chip on Reader1 to a chip on Reader2 would look a little something like this:

  1. Set Reader1's RST Pin HIGH
  2. Set Reader2's RST Pin LOW
  3. Initialize SPI (see line 129-131 in MFRC522.py)
  4. Read Chip
  5. Close SPI (see line 166 in MFRC522.py)
  6. Set Reader1's RST Pin LOW
  7. Set Reader2's RST Pin HIGH
  8. Initialize SPI
  9. Write Chip
  10. Close SPI

The readers are all connected in parallel and only the RST Pins are connected to individual GPIOs. This has worked fine for me using 5 readers and should (theoretically) work with an unlimited amount of readers at the same time. Of course, you can't use them at the exact same time, but swapping through them at high speeds did the trick as well.

TLDR:

Schematic using 2 readers

Schematic using 4 readers

Code example for a class supporting multiple NFC Readers using this method:

import RPi.GPIO as GPIO
from mfrc522 import SimpleMFRC522
import spidev

class NFC(): def init(self, bus=0, device=0, spd=1000000): self.reader = SimpleMFRC522() self.close() self.bus self.boards = {}

    self.bus = bus
    self.device = device
    self.spd = spd

def reinit(self):
    self.reader.READER.spi = spidev.SpiDev()
    self.reader.READER.spi.open(self.bus, self.device)
    self.reader.READER.spi.max_speed_hz = self.spd
    self.reader.READER.MFRC522_Init()

def close(self):
    self.reader.READER.spi.close()

def addBoard(self, rid, pin):
    self.boards[rid] = pin

def selectBoard(self, rid):
    if not rid in self.boards:
        print("readerid " + rid + " not found")
        return False

    for loop_id in self.boards:
        GPIO.output(self.boards[loop_id], loop_id == rid)
    return True

def read(self, rid):
    if not self.selectBoard(rid):
        return None

    self.reinit()
    cid, val = self.reader.read_no_block()
    self.close()

    return val

def write(self, rid, value):
    if not self.selectBoard(rid):
        return False

    self.reinit()
    self.reader.write_no_block(value)
    self.close()
    return True


if name == "main": nfc = NFC() nfc.addBoard("reader1",5) nfc.addBoard("reader2",6)

data = nfc.read("reader1")
nfc.write("reader2",data)

Lugico
  • 31
  • 3
0

I am new to Python wiring as per above from the above i understand that you have created a class how do i use this class.. i copied your class and named it as MultiNFC.py

my program to read 2 RFID is

from MultiNFC import NFC nfc = NFC() while True: nfc.addboard("reader1",5) #5 is GPIO 5 at pin number 29 nfc.addboard("reader2",6) #6 is GPIO 6 at pin number 31 data1 =nfc.read("reader1") data2 =nfc.read("reader2") GPIO.cleanup()

is this correct

Regards

Amogh Walvekar

  • As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center. – Community Mar 14 '23 at 17:33
0

I updated Lugico's code with Amogh's advice to work with 2 readers on a Raspberry Pi 3B+.

Make sure you're supplying sufficient power to your pi or it will not be able to power all of your readers. dmesg will report if your pi is not able to supply enough power. Use something like this https://www.sparkfun.com/products/114 at 3.3V on your breadboard instead of using the lines from your Pi if you can't supply enough power natively.

from mfrc522 import SimpleMFRC522
import RPi.GPIO as GPIO
import signal
import spidev
import sys
import time

class NFC(): def init(self, bus=0, device=0, spd=1000000): self.reader = SimpleMFRC522() self.close() self.boards = {}

    self.bus = bus
    self.device = device
    self.spd = spd

def reinit(self):
    self.reader.READER.spi = spidev.SpiDev()
    self.reader.READER.spi.open(self.bus, self.device)
    self.reader.READER.spi.max_speed_hz = self.spd
    self.reader.READER.MFRC522_Init()

def close(self):
    self.reader.READER.spi.close()

def addBoard(self, rid, pin):
    self.boards[rid] = pin
    GPIO.setup(pin, GPIO.OUT)
    print(pin)

def selectBoard(self, rid):
    if not rid in self.boards:
        print("readerid " + rid + " not found")
        return False

    for loop_id in self.boards:
        GPIO.output(self.boards[loop_id], loop_id == rid)
    return True

def read(self, rid):
    if not self.selectBoard(rid):
        return None

    self.reinit()
    cid, val = self.reader.read_no_block()
    self.close()

    return val

def write(self, rid, value):
    if not self.selectBoard(rid):
        return False

    self.reinit()
    self.reader.write_no_block(value)
    self.close()
    return True

clean up gpios on ctrl+c

def signal_handler(sig, frame): GPIO.cleanup() print() sys.exit(0)

def main(): signal.signal(signal.SIGINT, signal_handler) GPIO.setmode(GPIO.BCM)

nfc = NFC()

readers = [
    # rid, pin
    ("reader1", 5),
    ("reader2", 6),
]

for r in readers:
    nfc.addBoard(r[0], r[1])

while True:
    for r in readers:
        try:
            r_name = r[0]
            data = nfc.read(r_name)
            if data:
                print(f"{r_name}: {data}")
        except Exception as e:
            print("e", e)

GPIO.cleanup()

if name == "main": main()