地磅通讯接口开发

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("打开文件错误");
            }
        }
    }

  

posted @ 2020-11-06 17:23  MrKing&  阅读(2794)  评论(0编辑  收藏  举报