国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

一個(gè)簡(jiǎn)單的電子稱數(shù)據(jù)接收/解析類(C#)

isaced / 3569人閱讀

摘要:一個(gè)寫(xiě)的接收電子稱數(shù)據(jù)并解析出重量數(shù)據(jù)的類。之前單位購(gòu)買了兩架電子稱,同時(shí)多帶帶購(gòu)買了配套的軟件。電子稱參數(shù)類有些電子稱發(fā)送的數(shù)據(jù)格式是沒(méi)有小數(shù)點(diǎn)分隔符例如耀華沒(méi)有小數(shù)點(diǎn)的數(shù)中整數(shù)部分長(zhǎng)度數(shù)據(jù)接收處理類比較簡(jiǎn)單,請(qǐng)參考注釋即可。

一個(gè)C#寫(xiě)的接收電子稱數(shù)據(jù)并解析出重量數(shù)據(jù)的類。

之前單位購(gòu)買了兩架電子稱,同時(shí)多帶帶購(gòu)買了配套的軟件。該軟件是用Delphi 7寫(xiě)就的,界面老舊就不說(shuō)了,關(guān)鍵是功能太弱了,基本只能簡(jiǎn)單地記錄一下稱重的數(shù)據(jù),打印的標(biāo)簽效果亦只能是簡(jiǎn)單的文字打印,基本上無(wú)法使用。想著之前曾經(jīng)有用POS指令控制串口打印機(jī)的經(jīng)驗(yàn),應(yīng)該不是很難,就自己寫(xiě)了一個(gè),以解決零散分包標(biāo)簽打印和裝箱標(biāo)簽打印的需要。

數(shù)據(jù)格式說(shuō)明

共接觸到三種電子稱數(shù)據(jù)格式,如數(shù)據(jù)格式不在此列,則使用例如串口調(diào)試助手之類的工具接收電子稱數(shù)據(jù)自行分析并作相應(yīng)調(diào)整即可。

輔助類

電子稱狀態(tài)變更通告事件類,注意此輔助助類原處于不同的命名空間,請(qǐng)自行修改或合并到相同的命名空間。

using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace CommonLib{	/// 	/// 電子稱狀態(tài)變更通告事件類定義	/// 	public class ScaleStateChangeEventArgs:EventArgs	{		public int ScaleID { get; private set; }		public float? Weight { get; private set; }		public bool Disconnected { get; private set; }				public bool PortOpenError { get; private set; }		/// 		/// 電子稱狀態(tài)變更通告事件		/// 		/// 電子稱標(biāo)號(hào),對(duì)應(yīng)數(shù)據(jù)庫(kù)中的ID		/// 實(shí)時(shí)屏顯重量		/// 連接已丟失		/// 端口(串口)打開(kāi)錯(cuò)誤		public ScaleStateChangeEventArgs(int scaleID, float? weight, bool disconnected, bool portOpenError)		{			this.ScaleID = scaleID;			this.Weight = weight;			this.Disconnected = disconnected;			this.PortOpenError = portOpenError;		}	}}

電子稱參數(shù)類,作為主類構(gòu)造函數(shù)的參數(shù),用于封裝電子稱的主要參數(shù):串口及數(shù)據(jù)格式的參數(shù)。

using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace DataReceiver{	/// 	/// 電子稱參數(shù)類	/// 	public class ScaleParam	{		public int ScaleID { get; set; }		public string Name { get; set; }						public string COMPortName { get; set; }		public int BaudRate { get; set; }		public int DataBits { get; set; }		public string StopBits { get; set; }		public string Parity { get; set; }		public int CheckingInterval { get; set; }		public int DataLength { get; set; }		public int BeginByte { get; set; }		public int EndByte { get; set; }		public int ScaleDataBeginLoc { get; set; }		public int ScaleDataLength { get; set; }		/// 		/// 有些電子稱發(fā)送的數(shù)據(jù)格式是沒(méi)有小數(shù)點(diǎn)分隔符例如:耀華 Xk3190		/// 		public bool HasDecimalSeparatorFlag { get; set; }		/// 		/// 沒(méi)有小數(shù)點(diǎn)的數(shù)中整數(shù)部分長(zhǎng)度		/// 		public short IntegerPortionLength { get; set; }	}}

數(shù)據(jù)接收處理類

比較簡(jiǎn)單,請(qǐng)參考注釋即可。

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading;using System.IO;using System.IO.Ports;using System.Runtime.InteropServices;using CommonLib;using DataReceiver;namespace DataReceiver{	/// 	/// 電子稱數(shù)據(jù)接收類 Receiver	/// 	public class Receiver	{		/// 		/// 電子稱狀態(tài)變更通告事件		/// 		public event EventHandler<ScaleStateChangeEventArgs> ScaleStateChange;		/// 		/// 電子稱參數(shù)		/// 		private ScaleParam scale;		/// 		/// 連接類型:串口		/// 		private SerialPort comport;		/// 		/// (從電子稱)最后一次收到的正確的字節(jié)數(shù)據(jù)		/// 		private byte[] lastReceivedBytes = new byte[1];		/// 		/// (從電子稱)最后一次收到的正確的重量		/// 		private float? lastReceivedWeight;		/// 		/// 電子稱發(fā)送的有效數(shù)據(jù)長(zhǎng)度		/// 		int DataLength = -1;		/// 		/// 從串口讀取的數(shù)據(jù)長(zhǎng)度,為保證接到的數(shù)據(jù)包含有效數(shù)據(jù),		/// 讀取的數(shù)據(jù)長(zhǎng)度為:DataLength * 2		/// 此處或可再優(yōu)化,實(shí)際使用正常,故未作深究		/// 		int bytesToRead = -1;						/// 		/// 電子稱連接丟失標(biāo)志		/// 		private bool lostConnectionFlag = false;		/// 		/// 接收到錯(cuò)誤的數(shù)據(jù)標(biāo)志		/// 通常,電子稱開(kāi)機(jī)時(shí)、波特率不匹配時(shí)數(shù)據(jù)格式會(huì)有問(wèn)題		/// 		private bool errorDataReceivedFlag = false;		/// 		/// 定時(shí)讀取串口數(shù)據(jù)的定時(shí)器		/// 		private Timer DataChecker;		/// 		/// 		/// 		//private GlobalData globalData = GlobalData.Instance;		public Receiver() { }		/// 		/// 自定義構(gòu)造器		/// 		/// 電子稱參數(shù)		public Receiver(ScaleParam targetScale) 			:base()		{			scale = targetScale;			DataLength = scale.DataLength;			bytesToRead = DataLength * 2;			Initializer();			DataChecker = new Timer(DataProcessor, null, scale.CheckingInterval, scale.CheckingInterval);		}		public void Reset()		{			DataChecker.Change(Timeout.Infinite, Timeout.Infinite); // Stop 			comport.Close();			Initializer();			DataChecker.Change(scale.CheckingInterval, scale.CheckingInterval); // Start		}		public void ClosePort()		{			comport.Close();		}				/// 		/// 初始化招收器		/// 設(shè)置標(biāo)志、初始化接收數(shù)組、打開(kāi)串口等		/// 		public void Initializer()		{			lastReceivedBytes = new byte[DataLength];			lostConnectionFlag = false;			errorDataReceivedFlag = false;			bool error = false;			comport = new SerialPort();			if (comport.IsOpen) comport.Close();			else			{				comport.PortName = scale.COMPortName;				comport.BaudRate = scale.BaudRate; 				comport.DataBits = 8; 				comport.StopBits = StopBits.One; 				comport.Parity = Parity.None; 				comport.DtrEnable = true;				comport.RtsEnable = true;				try				{					comport.Open();				}				catch (UnauthorizedAccessException) { error = true; }				catch (IOException) { error = true; }				catch (ArgumentException) { error = true; }				if (error)				{					ScaleStateChange?.Invoke(this, new ScaleStateChangeEventArgs(scale.ScaleID, null, true, true));				}				else				{				}			}		}		/// 		/// 電子稱數(shù)據(jù)處理例程		/// 		/// 		private void DataProcessor(object state)		{			// 如果串口未打開(kāi)或緩沖區(qū)接收到的數(shù)據(jù)長(zhǎng)度少于 bytesToRead 的定義值			if (!comport.IsOpen || comport.BytesToRead < bytesToRead)			{				if (!lostConnectionFlag)				{					lostConnectionFlag = true;					ScaleStateChange?.Invoke(this, new ScaleStateChangeEventArgs(scale.ScaleID, null, true, false));				}				// 直接返回以直至收到足夠的數(shù)據(jù)				return;			}			// 已接收到足夠的數(shù)據(jù),無(wú)須繼續(xù)接收(因?yàn)殡娮臃Q的數(shù)據(jù)是連繼重復(fù)發(fā)送的)			DataChecker.Change(Timeout.Infinite, Timeout.Infinite); // Stop 						byte[] buffer = new byte[bytesToRead];			// 從緩沖區(qū)讀長(zhǎng)度為 bytesToRead 的數(shù)據(jù)			comport.Read(buffer, 0, bytesToRead);						// 定位有效數(shù)據(jù)首字節(jié)出現(xiàn)的位置			int begingOffset = -1;			for (int i= 0; i < buffer.Count(); i++)			{				if (buffer[i] == scale.BeginByte) // 				{					begingOffset = i;					break;				}			}			            try            {                byte[] data = new byte[DataLength];				// 復(fù)制完整數(shù)據(jù)至字節(jié)緩存數(shù)組                Buffer.BlockCopy(buffer, begingOffset, data, 0, DataLength);				// 調(diào)用數(shù)據(jù)處理例程				ProcessingScaleData(data);            }            catch (Exception ex)            {                //Console.WriteLine(">>>>>>>>>>>>>>>>>>>>>> Exception: " + ex.Message);            }			// 清空串口接收緩沖區(qū)以保證數(shù)據(jù)實(shí)時(shí)性			comport.DiscardInBuffer(); //Start over			// 重新啟動(dòng)數(shù)據(jù)接收定時(shí)器			DataChecker.Change(scale.CheckingInterval, scale.CheckingInterval); // Start                 }		/// 		/// 電子稱數(shù)據(jù)處理例程		/// 		/// 電子稱發(fā)送的字節(jié)數(shù)據(jù)		private void ProcessingScaleData(byte[] receivedBytes)		{			// 只有和最后一次收到的數(shù)據(jù)不同時(shí)才需要處理			if (!ByteArrayCompare(lastReceivedBytes, receivedBytes)) 			{				ProcessingData(receivedBytes);			}			// 收到相同數(shù)據(jù)時(shí)檢查電子稱的串口連接是否斷開(kāi)			// 如果曾經(jīng)斷開(kāi)過(guò)連接,屏幕會(huì)顯示 ERROR			// 此時(shí)需重置標(biāo)志并更新顯示			else if (lostConnectionFlag)			{				lostConnectionFlag = false;				ProcessingData(receivedBytes);			}		}		/// 		/// 更新 lastReceivedBytes 變更數(shù)據(jù)		/// 并調(diào)用數(shù)據(jù)解析例程		/// 		/// 電子稱發(fā)送的字節(jié)數(shù)據(jù)		private void ProcessingData(byte[] receivedBytes)		{			lastReceivedBytes = receivedBytes;			// 字節(jié)數(shù)據(jù)轉(zhuǎn)換為字符串?dāng)?shù)據(jù)并傳給解析例程			ParseData(Encoding.ASCII.GetString(receivedBytes));		}		string tmpWeightData = string.Empty;		string weightData = string.Empty;		float weightResult;		/// 		/// 電子稱數(shù)據(jù)解析例程		/// 支持3種電子稱數(shù)據(jù)格式,請(qǐng)參考圖示		/// 可根據(jù)需要擴(kuò)充		/// 		/// 電子稱發(fā)送過(guò)來(lái)的字符串?dāng)?shù)據(jù)		private void ParseData(string data)		{			try			{				weightData = data.Substring(scale.ScaleDataBeginLoc, scale.ScaleDataLength);				if (!scale.HasDecimalSeparatorFlag)				{					tmpWeightData = weightData;					weightData = tmpWeightData.Substring(0, scale.IntegerPortionLength) + "." +						tmpWeightData.Substring(scale.IntegerPortionLength, scale.ScaleDataLength-scale.IntegerPortionLength);				}				if (float.TryParse(weightData, out weightResult))				{					errorDataReceivedFlag = false;                    lastReceivedWeight = weightResult;					ScaleStateChange?.Invoke(this, new ScaleStateChangeEventArgs(scale.ScaleID, weightResult, false, false));				}				else if (!errorDataReceivedFlag)				{					errorDataReceivedFlag = true;					ScaleStateChange?.Invoke(this, new ScaleStateChangeEventArgs(scale.ScaleID, lastReceivedWeight, false, false));					lastReceivedBytes = new byte[1];				}			}			catch (Exception ex)			{				ScaleStateChange?.Invoke(this, new ScaleStateChangeEventArgs(scale.ScaleID, null, false, false));				lastReceivedBytes = new byte[1];			}		}		[DllImport("msvcrt.dll", CallingConvention = CallingConvention.Cdecl)]		static extern int memcmp(byte[] b1, byte[] b2, long count);		/// 		/// 字節(jié)數(shù)組比較例程		/// 		/// 字節(jié)數(shù)組1		/// 字節(jié)數(shù)組2		/// 相同則返回True;否則False		static bool ByteArrayCompare(byte[] b1, byte[] b2)		{			// Validate buffers are the same length.			// This also ensures that the count does not exceed the length of either buffer.  			return b1.Length == b2.Length && memcmp(b1, b2, b1.Length) == 0;		}		/// 		/// TXT日志記錄例程		/// 		/// 待寫(xiě)入日志文件中的字符串?dāng)?shù)據(jù)		private void WriteFile(string data)		{			FileStream fs = new FileStream(AppDomain.CurrentDomain.BaseDirectory + "Logger.txt", FileMode.Append);			StreamWriter sw = new StreamWriter(fs);			sw.Write(data);			sw.Flush();			sw.Close();			fs.Close();		}	} // class ends}

實(shí)際使用效果,供參考

程序界面使用了MahApps.Metro.Controls,具體請(qǐng)參考 https://mahapps.com/docs/controls/metrowindow

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/121828.html

相關(guān)文章

  • 【轉(zhuǎn)】php命名空間

    摘要:命名空間可以解決以下兩類問(wèn)題用戶編寫(xiě)的代碼與內(nèi)部的類函數(shù)常量或第三方類函數(shù)常量之間的名字沖突。在命名空間內(nèi)部訪問(wèn)全局類函數(shù)和常量調(diào)用全局函數(shù)訪問(wèn)全局常量實(shí)例化全局類命名空間和動(dòng)態(tài)語(yǔ)言特征命名空間的實(shí)現(xiàn)受到其語(yǔ)言自身的動(dòng)態(tài)特征的影響。 PHP 命名空間(namespace)是在PHP 5.3中加入的,如果你學(xué)過(guò)C#和Java,那命名空間就不算什么新事物。 不過(guò)在PHP當(dāng)中還是有著相當(dāng)重要...

    Jrain 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<