- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在寻找一种在 Windows IOT 上的 Raspberry Pi 2.0 上使用 RFID“RC522”的方法。
当然不是官方兼容的...
官方的(OM5577 演示板)在法国非常昂贵(我还没有找到任何经销商在没有大量运费的情况下出售它(总成本约为 80 美元))。
RC522 很便宜 (<10 美元)。它在 Arduino 和 Linux 上的 Raspberry Pi 2.0 上运行良好。但不幸的是,Windows IOT 还没有。
我实际上是在使用 arduino 作为桥梁……这不是最佳解决方案;但效果很好,而且价格总是比 OM5577 便宜一半。
我找到了 this项目并尝试使用 Windows IOT SIP 和 IO 将它们转换为 VS (Visual C++) 项目...我惨遭失败...
在我的梦想中,我将能够在 C# 中通过标准 Windows IOT“ProximityDevice”类使用此设备。
你对我有什么想法吗?
提前致谢。
最佳答案
我终于找到了解决办法。
我在 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;
}
}
}
架构
关于c# - RFID RC522 Raspberry PI 2 Windows 物联网,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34284498/
关闭。这个问题是off-topic .它目前不接受答案。 想改善这个问题吗? Update the question所以它是 on-topic对于堆栈溢出。 9年前关闭。 Improve this q
我使用了两个 RFID 阅读器(不同的供应商),它们为同一个 RFID 标签提供了两个不同的标识符: 读取器 A 显示 5BFA0746(十进制 1543112518) 读取器 B 显示 4607FA
当使用标签阅读器读取长距离无源 RFID 标签时,有没有办法计算/估计其物理距离?例如。确定书架中书籍的顺序,或判断一个物体是近还是远。 如果答案是“否 - 不符合标准”,是否可以构建具有此功能的阅读
我使用了两个 RFID 阅读器(不同的供应商),它们为同一个 RFID 标签提供了两个不同的标识符: 读取器 A 显示 5BFA0746(十进制 1543112518) 读取器 B 显示 4607FA
这些 PowerBurst 时间用于 TMS37157 Development Tool FAQ 中引用的示例代码。 ,但似乎不知道这些值是什么。看起来它们是由桌面应用程序提供的,但我只有二进制文件。
我正在做一个基于 RFID 的库存控制项目,我想制作一个写入器,通过它我可以在每个无源 RFID 标签上写入数据。我怎样才能做到这一点? 最佳答案 根据您的预算,购买一个 RFID 阅读器(也是一个写
猜猜我们有一个可以读取卡号的 RFID 阅读器,这些阅读器可以使用 RS232 或 USB 电缆等连接到 pc。我如何与这个设备互动。在简单的场景中,我想在读卡器读卡时读卡号。 任何操作系统(但首选
对于 iPhone,是否可以使用 IDBlue RFID 笔(蓝牙连接)与 RFID 标签进行通信并将数据存储到我的应用程序中? 如果是,那么是否有任何现成的组件或代码库可用于此? 最佳答案 最新的
我看到很多论坛都说 RFID 不同于 NFC。我完全同意这一点,因为两者都有不同的标准并且在不同的频率上运行。 经过进一步研究,我发现 13.56 MHz 频段中存在一些 RFID 标准 (HF-RF
我将 MFRC522 阅读器与 STM32f030CC 一起使用。我可以读取 RFID 卡的序列号,但在获得序列号后我无法选择标签并且无法验证卡的真实性。我使用的库与 Arduino、Rasberry
我正在尝试开发一种自定义加密安全协议(protocol),用于通过 RFID 智能卡进行身份验证,我在互联网上所能找到的只是有关如何将静态标签写入卡中的通用信息。对于我的项目,我需要读卡器向卡发送挑战
我一直在测试和研究我的 RFID 扫描器代码,但发现了一些奇怪的东西。当我点击卡片时,在某些情况下结果会被截断。 示例: 点击 1:[2]1,000,007,000242985 点击 2:7[3][2
我正在尝试开发一种自定义加密安全协议(protocol),用于通过 RFID 智能卡进行身份验证,我在互联网上所能找到的只是有关如何将静态标签写入卡中的通用信息。对于我的项目,我需要读卡器向卡发送挑战
我正在使用 raspberyy pi 3,RFID RC522。我想使用 WiringPi 来读取卡片。我正在尝试这段代码; #include #include #include #include i
我正在使用 LineaPro 5 peripheral 开发 Xamarin.iOS 应用程序,能够扫描条形码、RFID卡和刷磁卡。我有基本的 RFID 功能,我关心的来自 Linea 的数据是卡的
就目前情况而言,这个问题不太适合我们的问答形式。我们希望答案得到事实、引用资料或专业知识的支持,但这个问题可能会引发辩论、争论、民意调查或扩展讨论。如果您觉得这个问题可以改进并可能重新开放,visit
我正在测试带有连接到端口 1 的防护微型轨道天线的 Speedway 阅读器 420。 问题是我无法让它发挥作用。当我 telnet 到 Speedway 阅读器并发出“show rfid stat”
实际到达很简单,标签进入接收器天线范围,但是偏离是造成问题的原因。 首先,我们了解一些有关设置的信息。 标签: 它们以433Mhz的速度工作,每1.5秒钟发送一次“心跳”,移动时进入传输突发模式,这种
已关闭。这个问题是 off-topic 。目前不接受答案。 想要改进这个问题吗? Update the question所以它是on-topic用于堆栈溢出。 已关闭11 年前。 Improve th
我尝试从 RFID 读取代表设备版本号的字节。使用SPI协议(protocol)我得到0x92字节(RC522版本2.0),请求字节是0x37。除了字节的位置之外,一切都运行良好。在我按照计划得到正确
我是一名优秀的程序员,十分优秀!