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

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,053
  • 17
  • 30
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
  • 41
  • 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

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()