如何使用 dotnet/iot Mfrc522 库

Posted

技术标签:

【中文标题】如何使用 dotnet/iot Mfrc522 库【英文标题】:How to use the dotnet/iot Mfrc522 library 【发布时间】:2022-01-07 10:50:24 【问题描述】:

我想通过 RC522 连接到树莓派的 NFC 标签读取数据。比起 Python,我更喜欢 c# 编程,所以我决定使用 dotnet/iot 库 Mfrc522 (https://github.com/dotnet/iot/tree/main/src/devices/Mfrc522)。

但是使用 Mfrc522 库我没有得到任何卡信息。

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

但是

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

总是假的,我尝试了不同的卡片和标签。 在他们为 pinReset 设置 4 的文档中,这不起作用,所以我尝试了 22,因为 RST 是 Pin 22 但没有成功

接线是正确的,因为如果我运行 python 脚本

#!/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() 

一切正常。

我使用的是 Raspberry 3 B+ 和 RC522 (https://joy-it.net/de/products/SBC-RFID-RC522)。

编辑: 我买了一个 Raspberry Compute Module 4,使用新的 Raspberry 库可以工作,我得到了一张卡。

但如果我尝试读取我的 Mifare 1k 卡,我总是会收到“身份验证错误”,来自 Authcommand 的 ret 值始终为 -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");
        
    

我使用了不同的卡,但我总是出错,除了我第一次读卡时,第一次我得到内存转储直到 bloc 62 然后我也得到了身份验证错误。但它只工作了一次,从那以后它就再也没有工作了,我也重新启动了等等。

谢谢

【问题讨论】:

您是否尝试过提供的示例代码? 为什么要把CS线设为1?这将要求您将第二条 CS 线用于 SPI 总线 0,老实说,我从未使用过,因此可能会失败。如有疑问(并且此阅读器是您使用的唯一 SPI 设备),您也可以将阅读器的 CS 线硬连接到地进行测试。 我试过这个例子但没有成功。由于提供的示例,我将其设置为 1,但我也尝试了没有值(默认为 -1)。 rc522 是我唯一使用的 SPI 设备 我没有这样的设备,但我知道这是最近测试过的。我会尝试 ping 负责的开发人员。 我无法使用官方解决方案运行它,但我找到了另一个适合我的实现。 github.com/robertsundstrom/Iot-RPi-Sample/blob/master/src/Blink/… 【参考方案1】:

您需要确保您使用的是 GPIO7,因为它是芯片选择 1。 此绑定仅在正确使用芯片选择时才有效。它非常敏感。因此,请务必确保您使用的是正确的。

【讨论】:

我尝试使用 Pin 24 (GPIO8) 和 Chip Select 0 以及 Pin 26 (GPIO7) 和 Chip Select 1。python 示例使用 Pin 24,如果我使用 Pin 24 和 0 执行我的程序它阻塞 24 并且 python 代码停止工作,直到我重新启动,所以我认为我访问正确。 确保您还正确激活了 SPI,并且您在那里使用了正确的芯片选择。详细解释见:github.com/dotnet/iot/blob/main/Documentation/raspi-spi.md 使用 Raspberry Compute Module 4,该库可以工作,但现在我无法读取内存,它曾经工作过一次,但再也没有工作过。我尝试了不同的卡,会不会是某些注册条目有问题? 当你说它工作一次时,你到底是什么意思?任何关于你想要做什么的代码 sn-p? 我的意思是,我安装了新的测试程序,然后我把卡放在读卡器上,它工作了,授权成功,我可以从卡上读取 bloc 数据。但是在第一次尝试之后,它再也没有工作过,既不是同一张卡,也不是另一张卡。我用我用来读取数据的代码编辑了我的问题。 (其示例代码)

以上是关于如何使用 dotnet/iot Mfrc522 库的主要内容,如果未能解决你的问题,请参考以下文章

ESP3216.RFID门禁系统实验(SPI总线 / MFRC522库)

关于SI522替代FM17522和MFRC522的资料对比

13.56Mhz SI522兼容MFRC522的资料以及对比性能

STM32+MFRC522完成IC卡号读取密码修改数据读写

STM32+MFRC522完成IC卡号读取密码修改数据读写

智能门锁超低功耗:SI522(13.56芯片)替代MFRC522FM17522