【问题标题】:RFID RC522 Raspberry PI 2 Windows IOTRFID RC522 树莓派 2 Windows 物联网
【发布时间】:2016-03-20 23:09:08
【问题描述】:

我正在寻找一种在 Windows IOT 上的 Raspberry Pi 2.0 上使用 RFID“RC522”的方法。

当然不是官方兼容的……

官方的(OM5577 演示板)在法国太贵了(我还没有找到任何经销商在没有大量运费的情况下出售它(总成本约为 80 美元))。

RC522 很便宜(

我实际上是在使用 arduino 作为桥梁...这不是最佳解决方案;但效果很好,价格总是比 OM5577 低一半。

我找到了this 项目并尝试将它们转换为带有 Windows IOT SIP 和 IO 的 VS (Visual C++) 项目...我惨败...

在我的梦想中,我将能够在 C# 中使用该设备和标准 windows IOT“ProximityDevice”类。

你有什么想法吗?

提前致谢。

【问题讨论】:

    标签: c# raspberry-pi2 iot windows-10-iot-core windowsiot


    【解决方案1】:

    补充:如果您想将 UID 视为表示十六进制字符的字符串,您可以在 TagIsPresent 部分中使用以下内容:

    var uid = mfrc.ReadUid();
    string txt_Result = "";
    foreach (byte byt in uid.FullUid)
    {
        txt_Result = txt_Result + byt.ToString("x2");
    }
    mfrc.HaltTag();
    

    【讨论】:

      【解决方案2】:

      我终于找到了解决办法。

      我在 arudino 可移植性方面没有成功;所以我使用this 项目作为起点。

      该项目是用 C# 编写的。我刚刚为 Windows IOT GPIO 和 SPI 调整了代码。它正在工作!

      主要

              var mfrc = new Mfrc522();
              await mfrc.InitIO();
      
              while (true)
              {
                  if (mfrc.IsTagPresent())
                  {
                      var uid = mfrc.ReadUid();
      
                      mfrc.HaltTag();
                  }
      
              }
      

      库 Mfrc522Lib.cs(多合一)

      using System;
      using System.Collections.Generic;
      using System.Threading;
      using System.Threading.Tasks;
      using Windows.Devices.Enumeration;
      using Windows.Devices.Gpio;
      using Windows.Devices.Spi;
      
      namespace Mfrc522Lib
      {
          public static class Registers
          {
              private const byte bitFraming = 0x0D;
              private const byte comIrq = 0x04;
              private const byte comIrqEnable = 0x02;
              private const byte command = 0x01;
              private const byte control = 0x0C;
              private const byte error = 0x06;
              private const byte fifoData = 0x09;
              private const byte fifoLevel = 0x0A;
              private const byte mode = 0x11;
              private const byte rxMode = 0x13;
              private const byte timerMode = 0x2A;
              private const byte timerPrescaler = 0x2B;
              private const byte timerReloadHigh = 0x2C;
              private const byte timerReloadLow = 0x2D;
              private const byte txAsk = 0x15;
              private const byte txControl = 0x14;
              private const byte txMode = 0x12;
              private const byte version = 0x37;
      
              public static byte BitFraming
              {
                  get
                  {
                      return bitFraming;
                  }
              }
      
              public static byte ComIrq
              {
                  get
                  {
                      return comIrq;
                  }
              }
      
              public static byte ComIrqEnable
              {
                  get
                  {
                      return comIrqEnable;
                  }
              }
      
              public static byte Command
              {
                  get
                  {
                      return command;
                  }
              }
      
              public static byte Control
              {
                  get
                  {
                      return control;
                  }
              }
      
              public static byte Error
              {
                  get
                  {
                      return error;
                  }
              }
      
              public static byte FifoData
              {
                  get
                  {
                      return fifoData;
                  }
              }
      
              public static byte FifoLevel
              {
                  get
                  {
                      return fifoLevel;
                  }
              }
      
              public static byte Mode
              {
                  get
                  {
                      return mode;
                  }
              }
      
              public static byte RxMode
              {
                  get
                  {
                      return rxMode;
                  }
              }
      
              public static byte TimerMode
              {
                  get
                  {
                      return timerMode;
                  }
              }
      
              public static byte TimerPrescaler
              {
                  get
                  {
                      return timerPrescaler;
                  }
              }
      
              public static byte TimerReloadHigh
              {
                  get
                  {
                      return timerReloadHigh;
                  }
              }
      
              public static byte TimerReloadLow
              {
                  get
                  {
                      return timerReloadLow;
                  }
              }
      
              public static byte TxAsk
              {
                  get
                  {
                      return txAsk;
                  }
              }
      
              public static byte TxControl
              {
                  get
                  {
                      return txControl;
                  }
              }
      
              public static byte TxMode
              {
                  get
                  {
                      return txMode;
                  }
              }
      
              public static byte Version
              {
                  get
                  {
                      return version;
                  }
              }
          }
          public static class PiccResponses
          {
              private const ushort answerToRequest = 0x0004;
              private const byte selectAcknowledge = 0x08;
              private const byte acknowledge = 0x0A;
      
              public static byte Acknowledge
              {
                  get
                  {
                      return acknowledge;
                  }
              }
      
              public static byte SelectAcknowledge
              {
                  get
                  {
                      return selectAcknowledge;
                  }
              }
      
              public static ushort AnswerToRequest
              {
                  get
                  {
                      return answerToRequest;
                  }
              }
          }
          public static class PiccCommands
          {
              private const byte anticollision_1 = 0x93;
              private const byte anticollision_2 = 0x20;
              private const byte authenticateKeyA = 0x60;
              private const byte authenticateKeyB = 0x61;
              private const byte halt_1 = 0x50;
              private const byte halt_2 = 0x00;
              private const byte read = 0x30;
              private const byte request = 0x26;
              private const byte select_1 = 0x93;
              private const byte select_2 = 0x70;
              private const byte write = 0xA0;
      
              public static byte AuthenticateKeyA
              {
                  get
                  {
                      return authenticateKeyA;
                  }
              }
      
              public static byte AuthenticateKeyB
              {
                  get
                  {
                      return authenticateKeyB;
                  }
              }
      
              public static byte Halt_1
              {
                  get
                  {
                      return halt_1;
                  }
              }
      
              public static byte Halt_2
              {
                  get
                  {
                      return halt_2;
                  }
              }
      
              public static byte Read
              {
                  get
                  {
                      return read;
                  }
              }
      
              public static byte Request
              {
                  get
                  {
                      return request;
                  }
              }
      
              public static byte Select_1
              {
                  get
                  {
                      return select_1;
                  }
              }
      
              public static byte Select_2
              {
                  get
                  {
                      return select_2;
                  }
              }
      
              public static byte Write
              {
                  get
                  {
                      return write;
                  }
              }
      
              public static byte Anticollision_1
              {
                  get
                  {
                      return anticollision_1;
                  }
              }
      
              public static byte Anticollision_2
              {
                  get
                  {
                      return anticollision_2;
                  }
              }
          }
      
          public static class PcdCommands
          {
              private const byte idle = 0x00;
              private const byte mifareAuthenticate = 0x0E;
              private const byte transceive = 0x0C;
      
              public static byte Idle
              {
                  get
                  {
                      return idle;
                  }
              }
      
              public static byte MifareAuthenticate
              {
                  get
                  {
                      return mifareAuthenticate;
                  }
              }
      
              public static byte Transceive
              {
                  get
                  {
                      return transceive;
                  }
              }
          }
      
      
          public class Uid
          {
              public byte Bcc { get; private set; }
              public byte[] Bytes { get; private set; }
              public byte[] FullUid { get; private set; }
              public bool IsValid { get; private set; }
      
              internal Uid(byte[] uid)
              {
                  FullUid = uid;
                  Bcc = uid[4];
      
                  Bytes = new byte[4];
                  System.Array.Copy(FullUid, 0, Bytes, 0, 4);
      
                  foreach (var b in Bytes)
                  {
                      if (b != 0x00)
                          IsValid = true;
                  }
              }
      
              public sealed override bool Equals(object obj)
              {
                  if (!(obj is Uid))
                      return false;
      
                  var uidWrapper = (Uid)obj;
      
                  for (int i = 0; i < 5; i++)
                  {
                      if (FullUid[i] != uidWrapper.FullUid[i])
                          return false;
                  }
      
                  return true;
              }
      
              public sealed override int GetHashCode()
              {
                  int uid = 0;
      
                  for (int i = 0; i < 4; i++)
                      uid |= Bytes[i] << (i * 8);
      
                  return uid;
              }
      
              public sealed override string ToString()
              {
                  var formatString = "x" + (Bytes.Length * 2);
                  return GetHashCode().ToString(formatString);
              }
          }
      
          public sealed class Mfrc522
          {
              public SpiDevice _spi { get; private set; }
              public GpioController IoController { get; private set; }
              public GpioPin _resetPowerDown { get; private set; }
      
              /* Uncomment for Raspberry Pi 2 */
              private const string SPI_CONTROLLER_NAME = "SPI0"; 
              private const Int32 SPI_CHIP_SELECT_LINE = 0;  
              private const Int32 RESET_PIN = 25;
      
              internal async Task InitIO()
              {
      
                  try
                  {
                      IoController = GpioController.GetDefault(); 
      
                      _resetPowerDown = IoController.OpenPin(RESET_PIN);
                      _resetPowerDown.Write(GpioPinValue.High);
                      _resetPowerDown.SetDriveMode(GpioPinDriveMode.Output);
                  }
                  /* If initialization fails, throw an exception */
                  catch (Exception ex)
                  {
                      throw new Exception("GPIO initialization failed", ex);
                  }
      
                  try
                  {
                      var settings = new SpiConnectionSettings(SPI_CHIP_SELECT_LINE);
                      settings.ClockFrequency = 1000000;
                      settings.Mode = SpiMode.Mode0;
      
                      String spiDeviceSelector = SpiDevice.GetDeviceSelector();
                      IReadOnlyList<DeviceInformation> devices = await DeviceInformation.FindAllAsync(spiDeviceSelector);
      
                      _spi = await SpiDevice.FromIdAsync(devices[0].Id, settings); 
      
                  }
                  /* If initialization fails, display the exception and stop running */
                  catch (Exception ex)
                  {
                      throw new Exception("SPI Initialization Failed", ex);
                  }
      
      
                  Reset();
              }
      
              public void Reset()
              {
                  _resetPowerDown.Write(GpioPinValue.Low);
                  System.Threading.Tasks.Task.Delay(50).Wait();
                  _resetPowerDown.Write(GpioPinValue.High);
                  System.Threading.Tasks.Task.Delay(50).Wait();
      
                  // Force 100% ASK modulation
                  WriteRegister(Registers.TxAsk, 0x40);
      
                  // Set CRC to 0x6363
                  WriteRegister(Registers.Mode, 0x3D);
      
                  // Enable antenna
                  SetRegisterBits(Registers.TxControl, 0x03);
              }
      
      
              public bool IsTagPresent()
              {
                  // Enable short frames
                  WriteRegister(Registers.BitFraming, 0x07);
      
                  // Transceive the Request command to the tag
                  Transceive(false, PiccCommands.Request);
      
                  // Disable short frames
                  WriteRegister(Registers.BitFraming, 0x00);
      
                  // Check if we found a card
                  return GetFifoLevel() == 2 && ReadFromFifoShort() == PiccResponses.AnswerToRequest;
              }
      
              public Uid ReadUid()
              {
                  // Run the anti-collision loop on the card
                  Transceive(false, PiccCommands.Anticollision_1, PiccCommands.Anticollision_2);
      
                  // Return tag UID from FIFO
                  return new Uid(ReadFromFifo(5));
              }
      
              public void HaltTag()
              {
                  // Transceive the Halt command to the tag
                  Transceive(false, PiccCommands.Halt_1, PiccCommands.Halt_2);
              }
      
              public bool SelectTag(Uid uid)
              {
                  // Send Select command to tag
                  var data = new byte[7];
                  data[0] = PiccCommands.Select_1;
                  data[1] = PiccCommands.Select_2;
                  uid.FullUid.CopyTo(data, 2);
      
                  Transceive(true, data);
      
                  return GetFifoLevel() == 1 && ReadFromFifo() == PiccResponses.SelectAcknowledge;
              }
      
              internal byte[] ReadBlock(byte blockNumber, Uid uid, byte[] keyA = null, byte[] keyB = null)
              {
                  if (keyA != null)
                      MifareAuthenticate(PiccCommands.AuthenticateKeyA, blockNumber, uid, keyA);
                  else if (keyB != null)
                      MifareAuthenticate(PiccCommands.AuthenticateKeyB, blockNumber, uid, keyB);
                  else
                      return null;
      
                  // Read block
                  Transceive(true, PiccCommands.Read, blockNumber);
      
                  return ReadFromFifo(16);
              }
      
              internal bool WriteBlock(byte blockNumber, Uid uid, byte[] data, byte[] keyA = null, byte[] keyB = null)
              {
                  if (keyA != null)
                      MifareAuthenticate(PiccCommands.AuthenticateKeyA, blockNumber, uid, keyA);
                  else if (keyB != null)
                      MifareAuthenticate(PiccCommands.AuthenticateKeyB, blockNumber, uid, keyB);
                  else
                      return false;
      
                  // Write block
                  Transceive(true, PiccCommands.Write, blockNumber);
      
                  if (ReadFromFifo() != PiccResponses.Acknowledge)
                      return false;
      
                  // Make sure we write only 16 bytes
                  var buffer = new byte[16];
                  data.CopyTo(buffer, 0);
      
                  Transceive(true, buffer);
      
                  return ReadFromFifo() == PiccResponses.Acknowledge;
              }
      
      
              protected void MifareAuthenticate(byte command, byte blockNumber, Uid uid, byte[] key)
              {
                  // Put reader in Idle mode
                  WriteRegister(Registers.Command, PcdCommands.Idle);
      
                  // Clear the FIFO
                  SetRegisterBits(Registers.FifoLevel, 0x80);
      
                  // Create Authentication packet
                  var data = new byte[12];
                  data[0] = command;
                  data[1] = (byte)(blockNumber & 0xFF);
                  key.CopyTo(data, 2);
                  uid.Bytes.CopyTo(data, 8);
      
                  WriteToFifo(data);
      
                  // Put reader in MfAuthent mode
                  WriteRegister(Registers.Command, PcdCommands.MifareAuthenticate);
      
                  // Wait for (a generous) 25 ms
                  System.Threading.Tasks.Task.Delay(25).Wait();
              }
      
              protected void Transceive(bool enableCrc, params byte[] data)
              {
                  if (enableCrc)
                  {
                      // Enable CRC
                      SetRegisterBits(Registers.TxMode, 0x80);
                      SetRegisterBits(Registers.RxMode, 0x80);
                  }
      
                  // Put reader in Idle mode
                  WriteRegister(Registers.Command, PcdCommands.Idle);
      
                  // Clear the FIFO
                  SetRegisterBits(Registers.FifoLevel, 0x80);
      
                  // Write the data to the FIFO
                  WriteToFifo(data);
      
                  // Put reader in Transceive mode and start sending
                  WriteRegister(Registers.Command, PcdCommands.Transceive);
                  SetRegisterBits(Registers.BitFraming, 0x80);
      
                  // Wait for (a generous) 25 ms
                  System.Threading.Tasks.Task.Delay(25).Wait();
      
                  // Stop sending
                  ClearRegisterBits(Registers.BitFraming, 0x80);
      
                  if (enableCrc)
                  {
                      // Disable CRC
                      ClearRegisterBits(Registers.TxMode, 0x80);
                      ClearRegisterBits(Registers.RxMode, 0x80);
                  }
              }
      
      
              protected byte[] ReadFromFifo(int length)
              {
                  var buffer = new byte[length];
      
                  for (int i = 0; i < length; i++)
                      buffer[i] = ReadRegister(Registers.FifoData);
      
                  return buffer;
              }
      
              protected byte ReadFromFifo()
              {
                  return ReadFromFifo(1)[0];
              }
      
              protected void WriteToFifo(params byte[] values)
              {
                  foreach (var b in values)
                      WriteRegister(Registers.FifoData, b);
              }
      
              protected int GetFifoLevel()
              {
                  return ReadRegister(Registers.FifoLevel);
              }
      
      
              protected byte ReadRegister(byte register)
              {
                  register <<= 1;
                  register |= 0x80;
      
                  var writeBuffer = new byte[] { register, 0x00 };
      
                  return TransferSpi(writeBuffer)[1];
              }
      
              protected ushort ReadFromFifoShort()
              {
                  var low = ReadRegister(Registers.FifoData);
                  var high = (ushort)(ReadRegister(Registers.FifoData) << 8);
      
                  return (ushort)(high | low);
              }
      
              protected void WriteRegister(byte register, byte value)
              {
                  register <<= 1;
      
                  var writeBuffer = new byte[] { register, value };
      
                  TransferSpi(writeBuffer);
              }
      
              protected void SetRegisterBits(byte register, byte bits)
              {
                  var currentValue = ReadRegister(register);
                  WriteRegister(register, (byte)(currentValue | bits));
              }
      
              protected void ClearRegisterBits(byte register, byte bits)
              {
                  var currentValue = ReadRegister(register);
                  WriteRegister(register, (byte)(currentValue & ~bits));
              }
      
      
              private byte[] TransferSpi(byte[] writeBuffer)
              {
                  var readBuffer = new byte[writeBuffer.Length];
      
                  _spi.TransferFullDuplex(writeBuffer, readBuffer);
      
                  return readBuffer;
              }
          }
      }
      

      架构

      【讨论】:

      • 我在我的项目中使用了这个Library Mfrc522Lib,它非常goog但不能用ReadBlock函数读取块。请帮我完成这项任务
      • 如何将库 Mfrc522Lib.cs 导入到我的项目中?
      【解决方案3】:

      因为它使用 SPI,所以不应该存在硬件兼容性问题。如果你不想翻译现有的 Arduino 代码,微软确实有一些技术可以让你使用现有的 Arduino 草图和库。你可以在这里阅读更多信息:http://ms-iot.github.io/content/en-US/win10/ArduinoWiringProjectGuide.htm

      【讨论】:

      • 谢谢。我正在尝试这个解决方案。代码在 Visual Studio 上编译。所有引脚都绑定。但是我已经有一些通信超时了。我在最后几天看更多,如果可行,我会发布解决方案。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-03
      • 1970-01-01
      相关资源
      最近更新 更多