1.准備工具
地磅開發如果有真實環境的地磅連接最好,沒有也沒關系,我們可以用模擬工具。1.Virtual Serial Port Driver 串口虛擬化,可以虛擬串口,模擬地磅接口,這個軟件是收費的,但是免費白嫖的功能足用了,也有破解版的.2.串口助手,這里推薦SerialPortUtility(友善串口調試助手),模擬地磅端口向程序發送數據。
2.開發階段
2.1 .配置文件寫在xml文件中,從Setting.xml讀取端口配置。
2.2 C#提供了SerialPort類用於實現串口控制。
3.解析數據
將接收到的數據轉成十六進制然后解析,這里解析的方式根據廠家提供的通訊方式進行解析。
給個通訊方式參考:
4.源碼
using System; using System.Collections.Generic; using System.IO.Ports; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; using System.IO; using System.Threading; namespace WeighbridgeDemo { /// <summary> /// MainWindow.xaml 的交互邏輯 /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } public string strReceiveMessage = null;//十六進制 public string WeightMessage = null;//ASCII SerialPort port=new SerialPort(); private void Window_Loaded(object sender, RoutedEventArgs e) { if (port.IsOpen == true) { port.Close(); } string appPath = AppDomain.CurrentDomain.BaseDirectory; string iniFile = appPath + "Setting.xml"; if (File.Exists(iniFile)) { port.BaudRate = Convert.ToInt32(XmlHelper.GetElementByName(iniFile, "BaudRate")); port.DataBits = Convert.ToInt32(XmlHelper.GetElementByName(iniFile, "DataBits")); port.StopBits = (StopBits)Convert.ToInt32(XmlHelper.GetElementByName(iniFile, "StopBits")); port.Parity = (Parity)Convert.ToInt32(XmlHelper.GetElementByName(iniFile, "Parity")); var portName = XmlHelper.GetElementByName(iniFile, "PortName"); if (null != portName) port.PortName = portName; } try { port.Open();//打開串口 port.DtrEnable = true;//設置DTR為高電平 port.RtsEnable = true;//設置RTS位高電平 } catch (Exception ex) { //打開串口出錯,顯示錯誤信息 MessageBox.Show(ex.Message); } if (false == this.port.IsOpen) return; port.DataReceived -= new SerialDataReceivedEventHandler(sp1_IsLegal_DataReceived); port.DataReceived += new SerialDataReceivedEventHandler(sp1_IsLegal_DataReceived); } private void sp1_IsLegal_DataReceived(object sender, SerialDataReceivedEventArgs e) { // Thread.Sleep(500); Byte[] receivedData = new Byte[port.BytesToRead]; //創建接收字節數組 port.Read(receivedData, 0, receivedData.Length); //讀取數據 port.DiscardInBuffer(); //清空SerialPort控件的Buffer for (int i = 0; i < receivedData.Length; i++) { strReceiveMessage += receivedData[i].ToString("X2"); //16進制顯示 } //完整的一組數據 if (strReceiveMessage != null) { if (strReceiveMessage.StartsWith("02") && strReceiveMessage.Substring(0, strReceiveMessage.Length - 2).EndsWith("0D") && strReceiveMessage.Length == 36) { int pt = Convert.ToInt32(strReceiveMessage.Substring(2, 2), 16); //十六進制轉成二進制 var dec = System.Convert.ToString(pt, 2); var flag = dec.Substring(dec.Length - 3);//判斷小數點在第幾位 string flag2 = ""; for (int k = flag.Length - 1; k >= 0; k--)//倒序 { flag2 += flag[k]; } //十六進制轉成ASCII string s = strReceiveMessage.Substring(8, 12); byte[] buff = new byte[s.Length / 2]; int index = 0; for (int i = 0; i < s.Length; i += 2) { buff[index] = Convert.ToByte(s.Substring(i, 2), 16); ++index; } //根據flag2判斷小數點位置 var WeightMessagetmp = Encoding.Default.GetString(buff); if (flag2 == "111") { WeightMessage = WeightMessagetmp.Substring(0, 1) + "." + WeightMessagetmp.Substring(1, 5); WeightMessage = double.Parse(WeightMessage).ToString() + "Kg"; } if (flag2 == "011") { WeightMessage = WeightMessagetmp.Substring(0, 2) + "." + WeightMessagetmp.Substring(2, 4); WeightMessage = double.Parse(WeightMessage).ToString() + "Kg"; } if (flag2 == "101") { WeightMessage = WeightMessagetmp.Substring(0, 3) + "." + WeightMessagetmp.Substring(3, 3); WeightMessage = double.Parse(WeightMessage).ToString() + "Kg"; } if (flag2 == "001") { WeightMessage = WeightMessagetmp.Substring(0, 4) + "." + WeightMessagetmp.Substring(4, 2); WeightMessage = double.Parse(WeightMessage).ToString() + "Kg"; } if (flag2 == "110") { WeightMessage = WeightMessagetmp.Substring(0, 5) + "." + WeightMessagetmp.Substring(5, 1); WeightMessage = double.Parse(WeightMessage).ToString() + "Kg"; } if (flag2 == "010") { WeightMessage = int.Parse(WeightMessagetmp).ToString() + "Kg"; } } } //啟動線程處理 Thread thread1 = new Thread(UpdateBtn); thread1.IsBackground = true;//設置為后台線程,當主線程結束后,后台線程自動退出,否則不會退出程序不能結束 thread1.Start(); // lst.Items.Add(strReceiveMessage); } //線程方法,修改List內容 private void UpdateBtn() { Action action1 = () => { // lst.Items.Add(WeightMessage); lst.Text += WeightMessage; strReceiveMessage = null; }; lst.Dispatcher.BeginInvoke(action1); // 如果不設置等待,整個程序死循環 Thread.Sleep(500); } } }
XmlHelper
public class XmlHelper { public static string GetElementByName(string xmlFileName, string tagName) { try { string result = null; XmlDocument doc = new XmlDocument(); doc.Load(xmlFileName); XmlNodeList nodes = doc.GetElementsByTagName(tagName); foreach (XmlNode v in nodes) { result = v.InnerText; } return result; } catch { throw new Exception("打開文件錯誤"); } } }