C# 坤宏电子秤取重量

 坤宏电子秤计重串口通讯格式说明

 winform示例:

复制代码
using System;
using System.Text;
using System.IO.Ports;
using System.Windows.Forms;

namespace ElectronicBalance
{
    /// <summary>
    /// 坤宏电子称
    /// </summary>
    public class WeightMeterKH
    {
        SerialPort _serialPort = new SerialPort();
        Form _frm;

       // 添加两个bool变量,作为状态标记,保证串口关闭时,串口事件已处理完
        private volatile bool is_serial_listening = false;//串口正在监听标记
        private volatile bool is_serial_closing = false;//串口正在关闭标记

        //日志路径
        string strSysLogPath = Application.StartupPath + "\\" + "Log" + System.DateTime.Now.ToString("yyyyMMdd") + ".log";

        /// <summary>
        /// 称重数据返回事件。
        /// </summary>
        public event EventHandler WeightDataReceived;

        /// <summary>
        /// 重量值
        /// </summary>
        public decimal WeightData
        {
            get
            {
                return _WeightData;
            }
        }
        decimal _WeightData;
        /// <summary>
        /// 单位
        /// </summary>
        public string Unit
        {
            get
            {
                return _Unit;
            }
        }
        string _Unit;

        /// <summary>
        /// 私有构造函数,防止类被实例化
        /// </summary>
        private WeightMeterKH()
        {
        }

        /// <summary>
        /// 创建一个单例。只能通过CreateInstance方法来创建
        /// </summary>
        public static WeightMeterKH CreateInstance()
        {
            return instance;
        }
        private static readonly WeightMeterKH instance = new WeightMeterKH();

        /// <summary>
        /// 打开设备
        /// </summary>
        /// <param name="portName">串口号</param>
        /// <param name="frm">调用这个类的窗体。</param>
        public void Open(string portName, Form frm)
        {
            try
            {
                // 初始化窗体对象
                _frm = frm;
                _frm.FormClosing += new FormClosingEventHandler(_frm_FormClosing);
                //初始化SerialPort对象
                _serialPort.PortName = portName;
                _serialPort.BaudRate = 9600; // 设备的波特率
                _serialPort.Open();
                _serialPort.DataReceived += _serialPort_DataReceived;   //添加事件注册
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message);
            }
        }

        /// <summary>
        /// 关闭设备。
        /// </summary>
        public void Close()
        {
            if (_serialPort.IsOpen == true)
            {

                _serialPort.Close();
                _serialPort.Dispose();
            }
        }

        /// <summary>
        /// 是否已经连接设备
        /// </summary>
        /// <returns></returns>
        public bool IsOpen()
        {
            if (_serialPort.IsOpen == true) return true;
            return false;
        }


        /// <summary>
        /// 在电子称的模式用不上,使用指令取得重量值
        /// </summary>
        public void GetWeightData()
        {
            if (_serialPort.IsOpen == true)
            {
                _serialPort.Write("RN");  // Read Net weight
            }
            else
            {
                MessageBox.Show("读值失败:串口没有打开。");
            }
        }



        /// <summary>
        /// 串口数据接收函数。
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void _serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            if (is_serial_closing)
            {
                is_serial_listening = false; //准备关闭串口时,reset串口侦听标记
                return;
            }

            try
            {
                string strRaw = _serialPort.ReadLine();
                //其数据由三个部分构成,用逗号分隔的,可以转换为一个数组。数据示例:ST,NT,   74.06 kg
                string[] strs = strRaw.Split(new char[] { ',' });
                string str3 = strs[2].Trim(); // 重量数据的第三个部分,返回的数据就是 74.06 kg
                string strWeight = str3.Substring(0, str3.Length - 2).Trim();

                _Unit = str3.Trim().Substring(str3.Length - 2, 2);

                is_serial_listening = true;

                bool flag = decimal.TryParse(strWeight, out _WeightData);

                if (flag == false)
                {
                    MessageBox.Show("电子称数据转换失败!");
                    // 写入日志
                    StringBuilder sb = new StringBuilder();
                    sb.AppendLine(DateTime.Now.ToString() + " 电子称数据转换失败");
                    sb.AppendLine("    原始数据为:" + strRaw);
                    sb.AppendLine("    第三部分去除单位后的数据为:" + strWeight + "\r\n");
                    //Trace.Write(sb.ToString());

                    TWays.Core.Loger.LogMessage(this.strSysLogPath, sb.ToString() + "\r\n", true);
                }
                else
                {
                    if (this.WeightDataReceived != null)
                    {
                        _frm.Invoke((EventHandler)(delegate
                        {
                            this.WeightDataReceived(this, new EventArgs());
                        }));
                    }
                }
            }
            finally
            {
                is_serial_listening = false;//串口调用完毕后,reset串口侦听标记
            }

        }


        /// <summary>
        /// 在窗体关闭的时候关闭串口连接。
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void _frm_FormClosing(object sender, FormClosingEventArgs e)
        {
            is_serial_closing = true;//关闭窗口时,置位is_serial_closing标记
            while (is_serial_listening) Application.DoEvents();
            this.Close();
        }

    }
}
View Code
复制代码
复制代码
using System;
using System.Windows.Forms;
using TWays;

namespace ElectronicBalance
{
    public partial class Form1 : Form
    {
        WeightMeterKH _meter = WeightMeterKH.CreateInstance();

        /// <summary>
        /// 设置文件的名称LocalSet.ini,将界面上设置的端口号保存到文件中
        /// 方便下一次打开程序时读取,就不用重复设置了
        /// </summary>
        string strFileName = Application.StartupPath + "\\" + StaticConst.LocalSetIniFileName;
        string _Port = string.Empty;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //如果设置的文件地址存在,读取端口号显示在界面上
            if (System.IO.File.Exists(strFileName))
            {
                this.txtPort.Text = Utils.ReadIniFile(StaticConst.LocalSetIniFileName, StaticConst.LocalSetSectionOption, StaticConst.LocalSetKeyPort);
            }
        }

        private void _meter_WeightDataReceived(object sender, EventArgs e)
        {
            lblWeight.Text = _meter.WeightData.ToString();
            labUnit.Text = _meter.Unit.ToString();

        }

        private void btnBegin_Click(object sender, EventArgs e)
        {
            //未连接的时候打开设备
            if (!_meter.IsOpen())
            {
                _Port = txtPort.Text.ToUpper();
                if (string.IsNullOrEmpty(_Port))
                {
                    TWays.Message.Show(MessageText.MSG_PORT_IS_NOTNULL);
                    return;
                }

                //保存端口号
                Utils.WriteIniFile(StaticConst.LocalSetIniFileName, StaticConst.LocalSetSectionOption, StaticConst.LocalSetKeyPort, this.txtPort.Text.Trim());

                _meter.Open(_Port, this);
                _meter.WeightDataReceived += new EventHandler(_meter_WeightDataReceived);
            }
            else
            {
                TWays.Message.Show(MessageText.MSG_CONNECT);
            }

        }

    }
}
View Code
复制代码

 

posted @   Haoeaoi  阅读(828)  评论(0编辑  收藏  举报
编辑推荐:
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
点击右上角即可分享
微信分享提示