⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mprreader.cs

📁 WJ Communications RFID example code
💻 CS
📖 第 1 页 / 共 5 页
字号:
//==========================================================================================
//
//	WJ.MPR.Reader.MPRReader
//	Copyright (c) 2006, WJ Communications, Inc.
//
//==========================================================================================
using System;
using System.Collections;
using System.Threading;
using System.IO;
using WJ.MPR.WinAPI;
using WJ.MPR.Util;
using WJ.Serial;

namespace WJ.MPR.Reader
{
	/// <summary>
	///		This is the main class instantiated by Applications.
	///		- Manages a single WJ Multi-Protocol Reader.
	///		- Provides properties and methods for accessing features of the MPR.
	///		- Talks to the MPR via an MPRComm object.
	///		- Generates request frame payloads for MPR API commands.
	///		- Parses response frame payloads from MPR API commands.
	///		- Fires events when MPR public properties change
	///		- Manages an Inventory of Tags in the MPRs field of view.
	///		- Inventory can consist of Class 0, Class 1 and/or Gen 2 tags.
	///		- Periodically polls the MPR for its current Inventory to:
	///			1) add new tags when found
	///			2) expire old tags
	///		- Old Tags are expired if they have not been seen for at least "PersistTime"
	///		- InventoryUpdateGap is how long to wait between inventory requests to the MPR.
	///		- Has methods to enable bootloading new FW to the MPR.
	///		- Exposes MPR methods to Read/Program/Erase/Kill/Lock for 3 EPC Tag standards.
	/// </summary>
	public class MPRReader : IDisposable 
	{
		#region Events
		/// <summary>
		/// Raised when the communication state changes
		/// </summary>
		public event EventHandler DisconnectEvent;
		
		/// <summary>
		/// Fired when a new tag is added to the MPRReader's inventory.
		/// </summary>
		public event TagEventHandler TagAdded;
		/// <summary>
		/// Fired when a tag on the list is read again.
		/// </summary>
		public event TagEventHandler TagReRead;
		/// <summary>
		/// Fired when a tag expires, ie hasn't been read for the persist time period.
		/// </summary>
		public event TagEventHandler TagRemoved;

		/// <summary>
		/// Fired when the Active Antenna changes.
		/// </summary>
		public event EventHandler ActiveAntennaChanged;
		/// <summary>
		/// Fired when the Tx Power changes.
		/// </summary>
		public event EventHandler TxPowerChanged;
		/// <summary>
		/// Fired when the Class 0 Singulation Field changes.
		/// </summary>
		public event EventHandler Class0SingulationFieldChanged;
		/// <summary>
		/// Fired when the Class 1 Inventory Type changes.
		/// </summary>
		public event EventHandler Class1InventoryTypeChanged;
		/// <summary>
		/// Fired when the Tag Length Option changes.
		/// </summary>
		public event EventHandler TagLengthOptionChanged;
		/// <summary>
		/// Fired when the Persist Time changes.
		/// </summary>
		public event EventHandler PersistTimeChanged;
		/// <summary>
		/// Fired when the Inventory Update Period changes.
		/// </summary>
		public event EventHandler InvUpdateGapChanged;
		/// <summary>
		/// Fired when the Inventory Timer Enabled property changes.
		/// </summary>
		public event EventHandler InvTimerEnabledChanged;
		/// <summary>
		/// Fired when manufacturing information is read from the MPR.
		/// </summary>
		public event EventHandler ManufacturingInformationChanged;

		/// <summary>
		/// Fired when an Inventory Update occurs.
		/// </summary>
		public event EventHandler InvPollEvent;

		/// <summary>
		/// Fired when a message is recevied from the bootloader.
		/// </summary>
		public event StringEventHandler BootloaderBytesReceivedEvent;

		/// <summary>
		/// Fired when a string message is generated.
		/// These messages are generated contain:
		///		- Communication log information
		///		- Command results
		///		- Error Messages
		/// </summary>
		public event StringEventHandler StatusEvent;

		#endregion

		#region Constructor

		/// <summary>
		/// Construct a new MPRReader.
		/// </summary>
		public MPRReader()
		{
			try 
			{
				InventoryUpdateTimer = new System.Threading.Timer(
					new TimerCallback(InventoryUpdateCallback), null, Timeout.Infinite, Timeout.Infinite);
			} 
			catch(ApplicationException ex)
			{
				LogIt(ex.Message);
			}
		}
		#endregion

		#region Public Functions

		/// <summary>
		/// Destroys any existing connection, 
		/// then starts the attempt to connect to an MPR at the requested Serial Port and Baud Rate.
		/// </summary>
		/// <param name="SerialPortName">"COMx" style serial port name</param>
		/// <param name="BaudRate">The Baud Rate at which to connect (usually 57600)</param>
		/// <returns>Whether an MPR was found at requested Port and BaudRate</returns>
		public bool Connect(string SerialPortName, string BaudRate)
		{
			this.SerialPortName = SerialPortName;
			this.BaudRate = BaudRate;

			isConnected = false;

			// First destroy the existing comm
			if (comm != null)
				comm.Dispose();

			// Then, make a new one
			comm = new MPRComm(SerialPortName, BaudRate);

			// Define MPRComm event handlers
			comm.IsOpenChanged += new BoolEventHandler(comm_IsOpenChanged);
			comm.BLDataArrived += new StringEventHandler(comm_BLDataArrived);

			// Open the serial port connection to the MPR.
			comm.Open();

			// Wait MPR_BOOTUP_TIME msec between powering on (opening COM port) and 
			// querying the MPR
			Thread.Sleep(MPRBootupTime);

			// Try to read the Reader Information,
			// if successfull, set isConnected to true.
			isConnected = comm.IsOpen;

			comm.appModeSetup();
			
			if (isConnected)
			{
				isConnected &= UpdateReaderInfo();
			}

			return isConnected;
		}

		/// <summary>
		/// Connect using the last (or default) SerialPortName and BaudRate
		/// </summary>
		/// <returns>Whether an MPR was found at default Port and BaudRate</returns>
		public bool Connect() { return Connect(this.SerialPortName, this.BaudRate); }

		/// <summary>
		/// Destroys any existing connection, 
		/// then starts the attempt to connect to an MPR at the requested Serial Port and Baud Rate.
		/// </summary>
		/// <param name="SerialPortName">"COMx" style serial port name</param>
		/// <param name="BaudRate">The Baud Rate at which to connect (usually 57600)</param>
		/// <returns>Whether an MPR was found at requested Port and BaudRate</returns>
		public bool ConnectBL(string SerialPortName, string BaudRate)
		{
			this.SerialPortName = SerialPortName;
			this.BaudRate = BaudRate;

			isConnected = false;

			// First destroy the existing comm
			if (comm != null)
				comm.Dispose();

			// Then, make a new one
			comm = new MPRComm(SerialPortName, BaudRate);

			// Define MPRComm event handlers
			comm.IsOpenChanged += new BoolEventHandler(comm_IsOpenChanged);
			comm.BLDataArrived += new StringEventHandler(comm_BLDataArrived);

			// Open the serial port connection to the MPR.
			comm.Open();

			isConnected = comm.IsOpen;
			comm.blModeSetup();

			return isConnected;
		}

		/// <summary>
		/// Connect to the MPR's bootloader, using the current serial port, 
		/// and default (115200) baud rate.
		/// </summary>
		/// <returns></returns>
		public bool ConnectBL() { return ConnectBL(this.SerialPortName, "115200"); }

		/// <summary>
		/// Disable Inventory Timer and close MPRComm.
		/// </summary>
		public void Disconnect()
		{
			InvTimerEnabled = false;
			isConnected = false;
			if (comm != null)
				comm.Close();
		}

		/// <summary>
		/// Close MPRComm, but record that we should reconnect on Resume.
		/// </summary>
		public void Suspend()
		{
			ReconnectOnResume = IsConnected;
			comm.Close();
		}

		/// <summary>
		/// Re-connect to the MPR if we were supposed to (as recorded in Suspend())
		/// </summary>
		public void Resume() 
		{
			if (ReconnectOnResume)
				Connect();
		}


		#region Class0 Commands
		#region Matrics Class0+
		/// <summary>
		/// Read bits from a Matrics Class 0+ Tag.
		/// </summary>
		/// <param name="filter">a TagFilter specifying the tags to read from.</param>
		/// <param name="ReadBitCount">How many bits to read.</param>
		/// <param name="ReadPage">The page to read from.</param>
		/// <param name="TagBits">A bytelist in which to return the bits read.</param>
		/// <returns></returns>
		public int Class0PlusRead(TagFilter filter, byte ReadBitCount, byte ReadPage, out byteList TagBits)
		{
			TagBits = new byteList();
			// Can read at most 120 bits
			if (ReadBitCount > 120) return 0;

			byteList Params = new byteList(
				new byte[] { ActiveAntenna, TxPower, Class0SingulationField, ReadPage, ReadBitCount } );

			Params.Add(filter.Length);
			Params.Add(filter.Bits);

			MPRMsg aMsg = comm.Send(CmdCode.Class0PlusRead, Params);

			if (!ProcMsgStat(aMsg))
				return 0;

			return Class0PlusReadParse(out TagBits, aMsg.DataBytes, ReadBitCount);
		}

		/// <summary>
		/// Write a Row of data to a Matrics Class 0+ Tag.
		/// </summary>
		/// <param name="filter">A Filter to match the Tags to write.</param>
		/// <param name="programData">The bits to write to the Tags.</param>
		/// <param name="IDPage">The IDPage (ID0-ID15) to Write.</param>
		/// <param name="StartBit">The bit in the page at which to start writing.</param>
		/// <param name="eraseFirst">Whether to Erase the IDPage first.</param>
		/// <param name="lockAfter">Whether to Lock the IDPage after writing.</param>
		/// <param name="clearTIB">Clear the Traversal Inhibit Bit (ID2 only).</param>
		/// <param name="setTIB">Set the Traversal Inhibit Bit (ID2 only).</param>
		/// <returns>The Number of Tags written.</returns>
		public int Class0PlusWrite(TagFilter filter, TagFilter programData, byte IDPage,
			byte StartBit, bool eraseFirst, bool lockAfter, bool clearTIB, bool setTIB)
		{
			// Can write at most 120 bits
			if (programData.Length > 120) return 0;
			if (IDPage > 15) return 0;

			byteList Params = new byteList(
				new byte[] { ActiveAntenna, TxPower, Class0SingulationField } );

			byte options = (byte)(IDPage & 0x0F);
			if (eraseFirst) options |= 0x10;
			if (lockAfter) options |= 0x20;
			if (clearTIB) options |= 0x40;
			if (setTIB) options |= 0x80;

			Params.Add(options);
			Params.Add(StartBit);

			Params.Add(programData.Length);
			Params.Add(programData.Bits);

			Params.Add(filter.Length);
			Params.Add(filter.Bits);

			MPRMsg aMsg = comm.Send(CmdCode.Class0PlusWrite, Params);

			if (!ProcMsgStat(aMsg))
				return 0;

			return ProcessSummary(aMsg.DataBytes.subList(aMsg.DataBytes.Count - 6));
		}

		/// <summary>
		/// Read bits from a Matrics Class 0+ Tag in global mode.
		/// </summary>
		/// <param name="ReadBitCount">Number of bits to read.</param>
		/// <param name="ReadPage">Page to read from.</param>
		/// <param name="TagBits">The bits read from the tag.</param>
		/// <returns></returns>
		public int Class0PlusGlobalRead(byte ReadBitCount, byte ReadPage, out byteList TagBits)
		{
			TagBits = new byteList();
			// Can read at most 120 bits
			if (ReadBitCount > 120) return 0;

			byteList Params = new byteList(
				new byte[] { ActiveAntenna, TxPower, ReadPage, ReadBitCount } );

			MPRMsg aMsg = comm.Send(CmdCode.Class0PlusGlobalRead, Params);

			if (!ProcMsgStat(aMsg))
				return 0;

			return Class0PlusReadParse(out TagBits, aMsg.DataBytes, ReadBitCount);
		}

		/// <summary>
		/// Program an EPC into a Matrics Class0+ tag.
		/// </summary>
		/// <param name="programData"></param>
		/// <param name="eraseFirst"></param>
		/// <param name="lockAfter"></param>
		/// <param name="clearTIB"></param>
		/// <param name="setTIB"></param>
		/// <returns>0 if error; otherwise # tags programmed.</returns>
		public int Class0PlusProgram(TagFilter programData, 
			bool eraseFirst, bool lockAfter, bool clearTIB, bool setTIB)
		{
			// Can write at most 120 bits
			if (programData.Length > 120) return 0;
			//			if (IDPage > 15) return 0;

			byte options = 0;
			if (eraseFirst) options |= 0x10;
			if (lockAfter) options |= 0x20;
			if (clearTIB) options |= 0x40;
			if (setTIB) options |= 0x80;

			byteList Params = new byteList(
				new byte[] { ActiveAntenna, TxPower, options} );

			Params.Add(programData.Length);
			Params.Add(programData.Bits);

			MPRMsg aMsg = comm.Send(CmdCode.Class0PlusProgram, Params);

			if (!ProcMsgStat(aMsg))
				return 0;

			return ProcessSummary(aMsg.DataBytes.subList(aMsg.DataBytes.Count - 6));
		}

		/// <summary>
		/// Erase a page of a Matrics Class 0+ tag's Internal Tag Memory (ITM).
		/// </summary>
		/// <param name="filter">A filter to match the tag ID of the tag to Erase.</param>
		/// <param name="page">The page (0-15) to erase.</param>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -