地磅通讯接口开发
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); } } }
1 | XmlHelper |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | 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( "打开文件错误" ); } } } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现