How to use the dotnet/iot Mfrc522 library

660 Views Asked by At

I want to read data from a NFC tag with my RC522 connected to a raspberry pi. I like c# programming much more then Python so i decided to use the dotnet/iot library Mfrc522 (https://github.com/dotnet/iot/tree/main/src/devices/Mfrc522).

But with the Mfrc522 Library i do not get any card information.

int pinReset = 22;
board = Board.Create();
GpioController gpioController = board.CreateGpioController();

SpiConnectionSettings connection = new(0, 1);
// Here you can use as well MfRc522.MaximumSpiClockFrequency which is 10_000_000
// Anything lower will work as well
connection.ClockFrequency = 5_000_000;
SpiDevice spi = board.CreateSpiDevice(connection);
mfrc522 = new(spi, pinReset, gpioController, false);

bool res;

Console.WriteLine("Start Listening");

Data106kbpsTypeA card;
do
{
    res = mfrc522.ListenToCardIso14443TypeA(out card, TimeSpan.FromSeconds(2));
    Thread.Sleep(res ? 0 : 200);
}
while (!res);

Console.WriteLine("CardFound");


Console.WriteLine();
if (UltralightCard.IsUltralightCard(card.Atqa, card.Sak))
{
    Console.WriteLine("Ultralight card detected, running various tests.");
    ProcessUltralight();
}
else
{
    Console.WriteLine("Mifare card detected, dumping the memory.");
    ProcessMifare();
}

but

res = mfrc522.ListenToCardIso14443TypeA(out card, TimeSpan.FromSeconds(2));

is always false, i tried different cards and tags. In the documentation they set 4 for pinReset, this didn't work, so i tried 22 because RST is Pin 22 but without success

The wiring is correct because if i run the python script

#!/usr/bin/env python
import RPi.GPIO as GPIO
from mfrc522 import SimpleMFRC522
reader = SimpleMFRC522()
try:
    id, text = reader.read()
    print(id)
    print(text)
finally:
    GPIO.cleanup() 

Everything works without problems.

I use a Raspberry 3 B+ and RC522 (https://joy-it.net/de/products/SBC-RFID-RC522).

EDIT: I bought a Raspberry Compute Module 4, with the new Raspberry the library works and i get a card.

But if i try to read my Mifare 1k Cards i always get "Authentication error" the ret value from the Authcommand is always -1.

static void ProcessMifare()
{
    Console.WriteLine($"ID: {Encoding.UTF8.GetString(card.NfcId)}");
    var mifare = new MifareCard(mfrc522!, 0);
    mifare.SerialNumber = card.NfcId;
    mifare.Capacity = MifareCardCapacity.Mifare1K;
    mifare.KeyA = MifareCard.DefaultKeyA.ToArray();
    mifare.KeyB = MifareCard.DefaultKeyB.ToArray();
    int ret;

    for (byte block = 0; block < 64; block++)
    {
        mifare.BlockNumber = block;
        mifare.Command = MifareCardCommand.AuthenticationB;
        ret = mifare.RunMifareCardCommand();
        if (ret < 0)
        {
            // If you have an authentication error, you have to deselect and reselect the card again and retry
            // Those next lines shows how to try to authenticate with other known default keys
            mifare.ReselectCard();
            // Try the other key
            mifare.KeyA = MifareCard.DefaultKeyA.ToArray();
            mifare.Command = MifareCardCommand.AuthenticationA;
            ret = mifare.RunMifareCardCommand();
            if (ret < 0)
            {
                mifare.ReselectCard();
                mifare.KeyA = MifareCard.DefaultBlocksNdefKeyA.ToArray();
                mifare.Command = MifareCardCommand.AuthenticationA;
                ret = mifare.RunMifareCardCommand();
                if (ret < 0)
                {
                    mifare.ReselectCard();
                    mifare.KeyA = MifareCard.DefaultFirstBlockNdefKeyA.ToArray();
                    mifare.Command = MifareCardCommand.AuthenticationA;
                    ret = mifare.RunMifareCardCommand();
                    if (ret < 0)
                    {
                        mifare.ReselectCard();
                        Console.WriteLine($"Error reading bloc: {block}");
                    }
                }
            }
        }

        if (ret >= 0)
        {
            mifare.BlockNumber = block;
            mifare.Command = MifareCardCommand.Read16Bytes;
            ret = mifare.RunMifareCardCommand();
            if (ret >= 0)
            {
                if (mifare.Data is object)
                {
                    Console.WriteLine($"Bloc: {block}, Data: {BitConverter.ToString(mifare.Data)}");
                }
            }
            else
            {
                mifare.ReselectCard();
                Console.WriteLine($"Error reading bloc: {block}");
            }

            if (block % 4 == 3)
            {
                if (mifare.Data != null)
                {
                    // Check what are the permissions
                    for (byte j = 3; j > 0; j--)
                    {
                        var access = mifare.BlockAccess((byte)(block - j), mifare.Data);
                        Console.WriteLine($"Bloc: {block - j}, Access: {access}");
                    }

                    var sector = mifare.SectorTailerAccess(block, mifare.Data);
                    Console.WriteLine($"Bloc: {block}, Access: {sector}");
                }
                else
                {
                    Console.WriteLine("Can't check any sector bloc");
                }
            }
        }
        else
        {
            Console.WriteLine($"Authentication error ret is {ret}");
        }
    }
}

I used different cards but i'm getting always an error, exept the first time I read card, at the first time i got the memory dump until bloc 62 then i also got the Authentication error. But it only worked one time since then it never worked again, i also rebooted etc.

thanks

1

There are 1 best solutions below

6
On

you need to make sure you are using GPIO7 as it's the Chip Select 1. This binding works only when the chip select is properly used. It is very sensitive. So really make sure you are using the correct one.