首页 > 编程语言 >C#WinForm实操串口通讯使用GtkSharp库实现跨平台

C#WinForm实操串口通讯使用GtkSharp库实现跨平台

时间:2024-12-05 16:01:37浏览次数:4  
标签:return string C# private 跨平台 仪表 串口 using public

 

Linux下运行.NET项目:

1、环境安装

2、cd 项目路径

3、dotnet 项目dll,即可运行

 

部分代码分享:

using Gtk;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Reflection.Emit;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO.Ports;
using GLib;
using Application = Gtk.Application;
using Pango;

namespace GTKWinFormsApp
{
    public partial class Form4 : Form
    {
        public Form4()
        {
            InitializeComponent();
        }

        private SerialPort comService; // 端口控件
        private StringBuilder tmpBuilder; // 可重复使用
        private bool isStart; // 该仪表是否已启动
        private double scaler; // 换算关系
        private double scalerAscii; // 使用Ascii时的scaler
        private string[] flagStrings; // string.Split需要


        private string flagString = "";

        /// <summary>
        /// 仪表数据段的标识位
        /// </summary>
        [Category("自定义-Ascii"), DefaultValue(""), Description("仪表数据段的标识位")]
        public string FlagString
        {
            get { return flagString; }
            set
            {
                flagString = value;
            }
        }

        #region Com

        private string portName = "COM1";

        /// <summary>
        /// 仪表的端口
        /// </summary>
        [Category("自定义-Com"), DefaultValue("COM1"), Description("仪表的端口")]
        public string PortName
        {
            get { return portName; }
            set
            {
                portName = value;
            }
        }

        private int baudRate = 9600;

        /// <summary>
        /// 仪表的波特率
        /// </summary>
        [Category("自定义-Com"), DefaultValue(9600), Description("仪表的波特率")]
        public int BaudRate
        {
            get { return baudRate; }
            set
            {
                baudRate = value;
            }
        }

        private Parity parity = Parity.None;

        /// <summary>
        /// 仪表的奇偶校验位
        /// </summary>
        [Category("自定义-Com"), DefaultValue(Parity.None), Description("仪表的奇偶校验位")]
        public Parity Parity
        {
            get { return parity; }
            set
            {
                parity = value;
            }
        }

        private int dataBits = 8;

        /// <summary>
        /// 仪表的数据长度
        /// </summary>
        [Category("自定义-Com"), DefaultValue(8), Description("仪表的数据长度")]
        public int DataBits
        {
            get { return dataBits; }
            set
            {
                dataBits = value;
            }
        }

        private StopBits stopBits = StopBits.One;

        /// <summary>
        /// 仪表的停止位
        /// </summary>
        [Category("自定义-Com"), DefaultValue(StopBits.One), Description("仪表的停止位")]
        public StopBits StopBits
        {
            get { return stopBits; }
            set
            {
                stopBits = value;
            }
        }

        #endregion Com



        public void StopCOM()
        {
            if (!isStart) { return; }

            try
            {
                if (comService != null && comService.IsOpen)
                {
                    comService.Close();
                    comService = null;
                }

                isStart = false;
            }
            catch (Exception e)
            {
                throw new Exception("关闭仪表出错:" + e.Message, e);
            }
        }

        public void StartCOM()
        {
            if (isStart) { return; }
            isStart = true;

            tmpBuilder = new StringBuilder();
            flagStrings = new[] { FlagString };

            comService = new SerialPort(PortName, BaudRate, Parity, DataBits, StopBits);
            comService.NewLine = "\r\n"; // 指定换行符
            comService.RtsEnable = true; // 启用RTS/CTS握手(解决隐藏设备的问题?)
            comService.DataReceived += ComService_DataReceived;
            scalerAscii = 0.001;
            try
            {
                comService.Open();
            }
            catch (Exception e)
            {
                isStart = false;
                throw new Exception("打开仪表出错:" + e.Message, e);
            }
        }

        //正在接收数据
        bool IsReceivingData = false;

        private void ComService_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            try
            {
                IsReceivingData = true;
                DataProgress();
            }
            catch
            {
                IsReceivingData = false;
            }
        }


        private void DataProgress()
        {
            byte[] buffer;
            try
            {
                int num = comService.BytesToRead; // 该次接收到的byte数
                if (num == 0) { return; }

                buffer = new byte[num]; // 可能会以十六进制展示,所以按byte[]接收而不是char[]
                comService.Read(buffer, 0, num);

                DataReceivedMethod(buffer);
                AscDataProgress(buffer);
            }
            catch (Exception)
            {
            }
        }
        private void DataReceivedMethod(byte[] buffer)
        {
            try
            {
                string readString = System.Text.Encoding.Default.GetString(buffer, 0, buffer.Length);
                string readStringHex = ByteToHex(buffer);

                TxtBoxMessage2(readStringHex);
            }
            catch (Exception ex)
            {
                TxtBoxMessage2(ex.Message);
            }
        }


        private int signStart = 1;

        /// <summary>
        /// 仪表数据段的正负号标记起始位
        /// </summary>
        [Category("自定义-Ascii"), DefaultValue(1), Description("仪表数据段的正负号标记起始位")]
        public int SignStart
        {
            get { return signStart; }
            set
            {
                signStart = value;
            }
        }


        private int signBits = 1;

        /// <summary>
        /// 仪表数据段的正负号标记长度
        /// </summary>
        [Category("自定义-Ascii"), DefaultValue(1), Description("仪表数据段的正负号标记长度")]
        public int SignBits
        {
            get { return signBits; }
            set
            {
                signBits = value;
            }
        }

        private int numberStart = 2;

        /// <summary>
        /// 仪表数据段的数据起始位
        /// </summary>
        [Category("自定义-Ascii"), DefaultValue(2), Description("仪表数据段的数据起始位")]
        public int NumberStart
        {
            get { return numberStart; }
            set
            {
                numberStart = value;
            }
        }

        private int numberBits = 6;

        /// <summary>
        /// 仪表数据段的数据长度
        /// </summary>
        [Category("自定义-Ascii"), DefaultValue(6), Description("仪表数据段的数据长度")]
        public int NumberBits
        {
            get { return numberBits; }
            set
            {
                numberBits = value;
            }
        }

        private bool isAntitone;

        /// <summary>
        /// 仪表数据段的数据是否反序
        /// </summary>
        [Category("自定义-Ascii"), DefaultValue(false), Description("仪表数据段的数据是否反序")]
        public bool IsAntitone
        {
            get { return isAntitone; }
            set
            {
                isAntitone = value;
            }
        }
        private string signNegativeString = "-";

        /// <summary>
        /// 仪表数据段的正负号标记为负号时的字符串表示
        /// </summary>
        [Category("自定义-Ascii"), DefaultValue("-"), Description("仪表数据段的正负号标记为负号时的字符串表示")]
        public string SignNegativeString
        {
            get { return signNegativeString; }
            set
            {
                signNegativeString = value;
            }
        }

        private int precision = 2;
        private string precisionFormat1 = "#0.000"; // double.ToString会使用
        private string precisionFormat2 = "#0.";

        /// <summary>
        /// 仪表控件的精度(影响控件本身的展示)
        /// </summary>
        [Category("自定义-数据"), DefaultValue(3), Description("仪表控件的精度(影响控件本身的展示)")]
        public int Precision
        {
            get { return precision; }
            set
            {
                precision = value;
                precisionFormat1 = precisionFormat2 + "".PadRight(precision, '0');
            }
        }
        private void AscDataProgress(byte[] buffer)
        {
            try
            {
                byte[] tempbuffer = new byte[buffer.Length];
                tmpBuilder.Append(System.Text.Encoding.ASCII.GetString(buffer));
                string completeData = tmpBuilder.ToString();
                if (completeData.LastIndexOf(FlagString) != -1)
                {
                    string[] tmps = completeData.Split(flagStrings, StringSplitOptions.None);
                    if (tmps.Length > 2) // 即至少有两个FlagString
                    {
                        tmpBuilder.Remove(0, tmpBuilder.Length).Append(FlagString).Append(tmps[tmps.Length - 1]);
                        string data = tmps[tmps.Length - 2];

                        if (SignStart < 1)
                        {
                            SignStart = 1;
                        }
                        if (data.Length < SignStart - 1 + SignBits)
                        {
                            SignBits = data.Length - (SignStart - 1);
                        }
                        string signPart = data.Substring(SignStart - 1, SignBits); // 符号段
                        if (data.Length < NumberStart - 1 + NumberBits)
                        {
                            NumberBits = data.Length - (NumberStart - 1);
                        }
                        string dataPart = data.Substring(NumberStart - 1, NumberBits); // 数据段

                        if (IsAntitone)
                        {
                            char[] arr = dataPart.ToCharArray();
                            Array.Reverse(arr);
                            dataPart = new string(arr);
                        }
                        double result = Math.Round((Convert.ToDouble(dataPart) * scalerAscii) * (signPart == SignNegativeString ? -1 : 1), Precision, MidpointRounding.AwayFromZero);

                        TxtBoxMessage(result.ToString());
                    }
                }
            }
            catch (Exception e)
            {
                throw new Exception(e.Message);
            }
        }



        /// <summary>
        /// 转换字节数组到十六进制字符串
        /// </summary>
        /// <param name="comByte">待转换字节数组</param>
        /// <returns>十六进制字符串</returns>
        public string ByteToHex(byte[] comByte)
        {
            StringBuilder builder = new StringBuilder(comByte.Length * 3);
            foreach (byte data in comByte)
            {
                builder.Append(Convert.ToString(data, 16).PadLeft(2, '0').PadRight(3, ' '));
            }
            return builder.ToString().ToUpper();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            PortName = textBox1.Text.Trim();
            //BaudRate = 9600;
            BaudRate = 115200;
            Parity = Parity.None;
            DataBits = 8;
            StopBits = StopBits.One;

            StartCOM();
            TxtBoxMessage2("COM打开");
        }

        private void button2_Click(object sender, EventArgs e)
        {
            StopCOM();
            TxtBoxMessage2("COM关闭");
        }

        public void TxtBoxMessage(string message)
        {
            Application.Invoke(delegate
            {
                textBox3.Text = message;
            });
        }

        string lastTxtBoxMessage = "";
        public void TxtBoxMessage2(string message)
        {
            Application.Invoke((EventHandler)(delegate
            {
                if (lastTxtBoxMessage == message) { return; }
                lastTxtBoxMessage = message;

                message = System.DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:fff") + "  " + message + Environment.NewLine;

                richTextBox1.AppendText(message);
            }));
        }
    }
}

 

标签:return,string,C#,private,跨平台,仪表,串口,using,public
From: https://www.cnblogs.com/lijunzaizi/p/18588767

相关文章

  • 描述器(Descriptor)
    描述器(又称描述符)(Descriptor)描述器:如果一个类中实现了__get__,__set__,__delete__三个方法中的任何一个,那么这样的类的实例就称为描述器。当某一个类的类属性是一个描述器的时候,通过这个类或者类的实例来访问、修改或删除这个类属性时,就会分别触发描述器的__get__,__set_......
  • S10MC-ASEMI小家电专用整流二极管S10MC
    编辑:llS10MC-ASEMI小家电专用整流二极管S10MC型号:S10MC品牌:ASEMI封装:SMC特性:整流二极管正向电流:10A反向耐压:1000V恢复时间:35ns引脚数量:2芯片个数:1芯片尺寸:MIL浪涌电流:200A漏电流:10ua工作温度:-55℃~125℃包装方式:500/盘;5000/箱备受欢迎的S10MC-ASEMI整流二极管ASE......
  • RCE极限挑战-1
    源码<?phperror_reporting(0);highlight_file(__FILE__);$code=$_POST['code'];$code=str_replace("(","括号",$code);$code=str_replace(".","点",$code);eval($code);?>payload:code=echols/;......
  • CMUX-CMUX协议讲解
    目录  1.CMUX协议  2.CMUX协议帧结构  3.示例1.CMUX协议CMUX(ConnectionMultiplexing),是一种串口多路复用协议,其功能主要在一个真实的物理通道上虚拟多个并行的逻辑通信通道的能力,一般应用于TE(TerminalEquipment)与MS(MobileStation)之间,TE相当于智......
  • 洛谷二刷P4715 【深基16.例1】淘汰赛(c嘎嘎)
    题目链接:P4715【深基16.例1】淘汰赛-洛谷|计算机科学教育新生态题目难度:普及 刷题心得:本题是我二刷,之前第一次刷是在洛谷线性表那个题单,当时印象深刻第 一篇题解是用的树来做,当时我不屑一顾(觉得花里胡哨),现在我开始刷树的题目着字分析,第一次学习到线性树的用法现......
  • docker-compose yaml version
    在DockerCompose文件中,version字段是必需的,它告诉DockerCompose工具使用哪个版本的YAML文件格式来解析Compose文件。目前,DockerCompose支持的版本有1, 2, 2.x, 3, 3.x等。其中,3及以上版本支持更多的特性,比如多服务网络 FROMopenjdk:8-jreRUNmkdir/app#复制jar......
  • C++(fprintf())
    目录1.函数定义2.常见格式说明符3.示例代码4.适用场景fprintf()是C和C++中用于格式化输出到文件的标准库函数。它的功能类似于printf(),但与printf()不同的是,fprintf()将格式化后的数据输出到指定的文件,而不是标准输出流(通常是屏幕)。1.函数定义intfprintf(FILE......
  • GZY.EFCore.BulkExtensions 支持达梦数据库的EF Core批量操作库详解
    前言EFCore.BulkExtensions是一个常用的EFcore批量处理数据的库.但是支持的数据库相对较少.特别是.NET5.0版本连MySQL都无法支持这个库就是改造的最新EFCore.BulkExtensions的代码让它能在.NET5.0中支持Mysql和达梦数据库由于5.0在升到最新9.0的过程中有比较重大的改变,所......
  • 轻松掌控视频_摄像头世界,下载 CameraStudio 体验更专业的摄像头管理!
    还在为管理多个摄像头或直播时视频质量参差不齐而烦恼吗?CameraStudio专为macOS用户打造,帮助你轻松管理视频源、添加高级滤镜,甚至创建定制虚拟摄像头,为你的视频管理带来革命性的体验。https://apps.apple.com/app/camerastudio-virtual-camera/id6738224213为什么选择Came......
  • Unlock Professional Camera Control with CameraStudio !
    Tiredofstrugglingwithmultiplecamerasandinconsistentvideoqualityduringlivestreams,meetings,orcontentcreation?CameraStudioisheretochangethat!DesignedexclusivelyformacOS,CameraStudioempowersyoutomanagevideosources,applyfilt......