C# 串口数据转网口实现空气风速风向检测

1.窗体搭建

添加time(定时器)

因为需要风速和风向自动刷新

2.进行网口空气检测

①服务器连接按钮

 // 连接按钮
 private void button1_Click(object sender, EventArgs e)
 {
     if (button1.Text =="连接")
     {
         ConnectSocke();// 连接服务器
     }
     else
     {
         CloseSocket(); // 关闭服务器
     }
 }
 Socket soc;
 // 连接方法
 void ConnectSocke()
 {
     try
     {
         // 创建socket对象
         soc = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);// 套接字对象
         // 连接服务器ip地址,端口号
         soc.Connect(this.textBox1.Text, int.Parse(this.textBox2.Text));
         button1.Text = "关闭";
         textBox1.Enabled = false;
         textBox2.Enabled = false;
     }
     catch (Exception ex)
     {
         MessageBox.Show("串口服务器连接失败");
     }
 }
 // 关闭方法
 void CloseSocket()
 {
     if (soc!=null && soc.Connected)
     {
         soc.Close();
     }
     button1.Text = "连接";
     this.textBox1.Enabled = true;
     this.textBox2.Enabled = true;
 }
 // 连接方法
 void ConnectSocke()
 {
     try
     {
         // 创建socket对象
         soc = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);// 套接字对象

         // 连接服务器ip地址,端口号
         soc.Connect(this.textBox1.Text, int.Parse(this.textBox2.Text));
         button1.Text = "关闭";
         textBox1.Enabled = false;
         textBox2.Enabled = false;
     }
     catch (Exception ex)
     {

         MessageBox.Show("串口服务器连接失败");
     }
 }

判断button1.text是否为“连接”若是连接则进行ConnectSocke();运行服务器的方法,否则CloseSocket();关闭服务器方法。

连接方法:使用try catch异常处理,创建全局变量Socket soc;创建对象连接ip端口号,讲textbox1.text改成关闭,textBox1.Enabled=false;让输入框无法输,catch异常处理判断try里的代码是否报错,若报错运行catch里代码

断开方法:判断soc是否为空或者soc是否连接如果连接关闭soc.Close();,将button1.text=“连接”,让textbox1和2能Enabled=true;解除

3.连接方法

 // 发送按钮
 private void button2_Click(object sender, EventArgs e)
 {
     string sendS = this.textBox3.Text.Trim();// 发送字符串
     if (soc == null || !soc.Connected)
     {
         MessageBox.Show("服务器没连接");
         return;
     }
     if (string.IsNullOrEmpty(sendS))
     {
         MessageBox.Show("指令不能为空");
         return;
     }

     //1 把字符串转成字符数组
     byte[] data = StringToHexByte(sendS);
     //2 计算校检码
     byte[] b1 = CRCCalc(data);
     //3 合并字节数组和校检码数组
     data = data.Concat(b1).ToArray();

     button2.Enabled = false;
     Task.Run(() =>
     {
         //4 发起请求帧
         soc.Send(data);// 发消息 请求 温度请求帧data = []

         Thread.Sleep(1000);// 休眠1秒

         //5 接受数据 // 接收温度
         byte[] rec = new byte[1024]; // rec = 
         int length = soc.Receive(rec);

         // 6 解析数据并且展示数据 把字节数组转成字符串
         string s = ByteToString(rec, length);
         s += "\r\n";
         int temp = (rec[3] * 256 + rec[4]) / 10;// 温度
         this.richTextBox1.Invoke((Action)(() =>
         {
             richTextBox1.AppendText(s);// 响应帧
             richTextBox1.AppendText($"当前温度温度为:{temp}摄氏度,时间为:{DateTime.Now.ToString()}r\n");
             button2.Enabled = true;
         }));

     });
 }
 string ByteToString(byte[] b1,int l)
 {
     StringBuilder sb = new StringBuilder();// 可变字符串
     for (int i = 0; i < l; i++)
     {
         sb.Append(b1[i].ToString("X2")+" ");
     }

     return sb.ToString();
 }


 // 字符串转成字符数组
 byte[] StringToHexByte(string s)
 {
     string[] ss = s.Split(' ');
     byte[] result = new byte[ss.Length];// 字节数组
     for (int i = 0; i < ss.Length; i++)
     {
         result[i] = Convert.ToByte(ss[i], 16);//转成16进制字节
     }
     return result;
 }
 // 校检方法
 public static byte[] CRCCalc(byte[] data)
 {
     //crc计算赋初始值
     int crc = 0xffff;
     for (int i = 0; i < data.Length; i++)
     {
         //XOR
         //(1) 0^0=0,0^1=1  0异或任何数=任何数
         //(2) 1 ^ 0 = 1,1 ^ 1 = 0  1异或任何数-任何数取反
         //(3) 1 ^ 1 = 0,0 ^ 0 = 0  任何数异或自己=把自己置0
         //异或操作符是^。异或的特点是相同为false,不同为true。
         crc = crc ^ data[i]; //和^表示按位异或运算。
                              //0x0fff ^ 0x01 Console.WriteLine(result.ToString("X")); 
                              // 输出结果为4094,即十六进制数1001
         for (int j = 0; j < 8; j++)
         {
             int temp;
             temp = crc & 1; // & 运算符(与) 1 & 0 为 0  ;0 & 0 为0;1 & 1 为1

             //右移 (>>) 将第一个操作数向右移动第二个操作数所指定的位数,空出的位置补0。右移相当于整除. 右移一位相当于除以2;右移两位相当于除以4;右移三位相当于除以8。
             //int i = 7;
             //int j = 2;
             //Console.WriteLine(i >> j);   //输出结果为1
             crc = crc >> 1;
             crc = crc & 0x7fff;
             if (temp == 1)
             {
                 crc = crc ^ 0xa001;
             }
             crc = crc & 0xffff;
         }
     }
     //CRC寄存器的高低位进行互换
     byte[] crc16 = new byte[2];
     //CRC寄存器的高8位变成低8位,
     crc16[1] = (byte)((crc >> 8) & 0xff);
     //CRC寄存器的低8位变成高8位
     crc16[0] = (byte)(crc & 0xff);
     return crc16;
 }

3.刷新按钮

        // 刷新按钮
        private void button3_Click(object sender, EventArgs e)
        {
            Refresh1();
        }
        void Refresh1()
        {
            if (soc == null || !soc.Connected)
            {
                MessageBox.Show("没连接");
                return;
            }
            Task.Run(() =>
            {
                // 请求帧的组织
                byte[] bs = new byte[] {0x01,0x03,0x00,0x00,0x00,0x02};// 风速和风向请求放在一起

                // 数据和校检
                bs = bs.Concat(CRCCalc(bs)).ToArray();

                soc.Send(bs);// 发送

                Thread.Sleep(1000);

                // 接受数据表
                byte[] rec = new byte[1024];
                int length = soc.Receive(rec);

                double wind = (rec[3] * 256 + rec[4]) * 0.01;
                double dir = (rec[5] * 256 + rec[6]);
                this.Invoke((Action)(() =>
                {
                    this.textBox4.Text = wind + "m/s";
                    this.textBox5.Text = dir + "";
                }));


            });
        }

        // 定时器
        private void timer1_Tick(object sender, EventArgs e)
        {
            if (checkBox1.Checked)// 复选框被选中
            {
                Refresh1();
            }

        }
    }
    
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/792970.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

苹果提出RLAIF:轻量级语言模型编写代码

获取本文论文原文PDF&#xff0c;请在公众号【AI论文解读】留言&#xff1a;论文解读 代码生成一直是一个充满挑战的领域。随着大型语言模型&#xff08;LLM&#xff09;的出现&#xff0c;我们见证了在自然语言理解和生成方面的显著进步。然而&#xff0c;当涉及到代码生成&a…

XD文件打开神器:这个在线工具你一定要试试!

你有没有遇到过对设计师发来的XD文件没有头绪&#xff1f;不知道XD文件深层含义&#xff1f;如何打开XD文件最省时省力&#xff1f;这篇文章告诉你答案。 https://ad.js.design/online/xd/?sourcecsdn&planxy711 XD文件是什么&#xff1f; 事实上&#xff0c;XD文件就是…

C++入门基础篇(1)

欢迎大家来到海盗猫鸥的博客—— 断更许久&#xff0c;让我们继续好好学习吧&#xff01; 目录 1.namespace命名空间 命名空间的存在价值&#xff1a; 命名空间的定义&#xff1a; 命名空间的使用&#xff1a; 2.C输入输出函数 使用&#xff1a; 3.缺省参数 4.函数重载…

界面组件Kendo UI for React 2024 Q2亮点 - 生成式AI集成、设计系统增强

随着最新的2024年第二季度发布&#xff0c;Kendo UI for React为应用程序开发设定了标准&#xff0c;包括生成式AI集成、增强的设计系统功能和可访问的数据可视化。新的2024年第二季度版本为应用程序界面提供了人工智能(AI)提示&#xff0c;从设计到代码的生产力增强、可访问性…

linux-5.10.110内核源码分析 - Freescale ls1012a pcie msi中断

1、dts msi控制器描述 1.1、dts描述 msi: msi-controller11572000 {compatible "fsl,ls1012a-msi";reg <0x0 0x1572000 0x0 0x8>;msi-controller;interrupts <0 126 IRQ_TYPE_LEVEL_HIGH>; };ls1012a msi控制器具体介绍可以参考官网手册”25.1.1 PC…

【cocos creator】2.x,伪3d拖拽,45度视角,60度视角,房屋装扮

伪3d拖拽,45度视角,60度视角 工程下载:(待审核) https://download.csdn.net/download/K86338236/89530812 dragItem2.t s import mapCreat2 from "./mapCreat2";const {ccclass, property } = cc._decorator; /*** 拖拽类,挂在要拖拽的节点上*/ @ccclass export…

电影购票小程序论文(设计)开题报告

一、课题的背景和意义 随着互联网技术的不断发展&#xff0c;人们对于购票的需求也越来越高。传统的购票方式存在着排队时间长、购票流程繁琐等问题&#xff0c;而网上购票则能够有效地解决这些问题。电影购票小程序是网上购票的一种新型应用&#xff0c;它能够让用户随时随地…

MacOS可以玩什么游戏 苹果笔记本电脑能打游戏吗 macbook能打什么游戏

长期以来&#xff0c;Mac电脑在游戏方面的局限性一直是用户关注的问题。在最新的 macOS Sonoma 14 系统中&#xff0c;苹果首次引入了全新的 Game mode&#xff08;游戏模式&#xff09;&#xff0c;将 M 系列芯片的超强能力在游戏中进一步释放&#xff01; Mac 不能玩游戏的难…

Fragment(未完结)

什么是Fragment? 1:具备生命周期,小Activity 2:必须委托在activity中才能运行 Fragment初体验 1、创建fragment_blank.xml <LinearLayout xmlns:android"http://schemas.android.com/apk/res/android"xmlns:tools"http://schemas.android.com/tools&qu…

一进四出学生公寓电表功能对比

一进四出学生公寓对比石家庄光大远通电气有限公司产品使用功能&#xff1a;预收费功能&#xff1a;用户应先到学校购电处购电,售电计算机将在十秒钟内自动将数据发送到控电柜各个用电单元,然后系统会给用户供电,当用户剩余电量为零时,系统可自动切断该单元供电,只有当用户重新购…

MYSQL审批流程判断同一层级审批人是否全部通过审批

在做流程审批的时候&#xff0c;通常会出现某一层有多个审批人的情况&#xff0c;这个时候需要所有人都通过才会进入到下一步 数据结构如下图表格所示 每一个审批申请对应一个apply_id serial_no相同的代表是同一层级审批人 approval_status是审核状态 下面我们可以用一个SQL来…

[leetcode]circular-array-loop 环形数组是否存在循环

. - 力扣&#xff08;LeetCode&#xff09; class Solution { public:bool circularArrayLoop(vector<int>& nums) {int n nums.size();auto next [&](int cur) {return ((cur nums[cur]) % n n) % n; // 保证返回值在 [0,n) 中};for (int i 0; i < n; i…

【UE5.1】NPC人工智能——01 准备NPC角色

效果 步骤 1. 之前我们已经创建了“BP_NPC”&#xff08;见&#xff1a;【UE5.1 角色练习】06-角色发射火球-part2&#xff09; 该蓝图继承于角色类 我们在该蓝图中添加了两个方法和两个变量。方法一个是用于修改角色HP值的&#xff0c;另一个是在收到伤害后执行的逻辑。两个…

AIGC爬虫类代码示例:Scrapy和OpenAI API实现抓取内容并生成内容

对于我从事爬虫行业多年的经验来说&#xff0c;编程各种需求代码真是非常吃力且细致的活&#xff0c;随着AI的大火&#xff0c;我在设想有没有可能通过AI自动化程序实现自动抓取生成想要的文本内容。前提我是打算通过结合爬虫技术&#xff08;如Scrapy&#xff09;和生成式AI模…

Affnity 值得购买吗?有Affinity 优惠码?

今年&#xff0c;Affinity 提供了全场 7 折优惠活动&#xff0c;这里包括桌面应用、插件、工作手册等内容&#xff0c;另外针对 iPad 应用提供更为给力的 5 折优惠&#xff01;对于从事图形设计、排版的用户来说&#xff0c;由于 Affinity 的创意设计应用均采用了一次买断制&am…

如何在函数中使用return返回axios的请求结果

使用场景&#xff1a;在添加学生上课记录的时候&#xff0c;需要先获取学生的剩余课时&#xff0c;需要通过接口获取。所以需要封装一个方法&#xff0c;能够通过接口获取学生的课时数量。 解决方案&#xff1a;通过异步解决 封装方法的代码如下&#xff1a; const getStude…

Linux--安装VMware步骤

安装VMware VMware Desktop Hypervisors for Windows, Linux, and Mac 复制链接打开浏览器下载即可 从官网下载软件&#xff0c;完成后为确保后续正常使用&#xff0c;需要检查虚拟网卡是否安装完成 检查虚拟网卡的安装步骤 Windows--设置--高级设置--网络适配器--看是否有显…

浅谈后置处理器组件提取器相关的Apply to

浅谈后置处理器组件提取器相关的Apply to 在Apache JMeter中&#xff0c;“提取器”&#xff08;通常指的是正则表达式提取器、JSON路径提取器或CSS/JQuery提取器等&#xff09;是用来从服务器响应中提取信息的重要组件。这些信息可以是cookies、session IDs、特定的文本或者任…

Nuxt框架中内置组件详解及使用指南(五)

title: Nuxt框架中内置组件详解及使用指南&#xff08;五&#xff09; date: 2024/7/10 updated: 2024/7/10 author: cmdragon excerpt: 摘要&#xff1a;本文详细介绍了Nuxt框架中和组件的使用方法与配置&#xff0c;包括安装、基本用法、属性详解、示例代码以及高级功能如…

纹波电流与ESR:解析电容器重要参数与应用挑战

电解电容纹波电流与ESR&#xff08;Equivalent Series Resistance&#xff09;是电容器的重要参数&#xff0c;用来描述电容器对交流信号的响应能力和能量损耗。电解电容纹波电流是指电容器在工作时承受的交流信号电流&#xff0c;而ESR则是电容器内部等效电阻&#xff0c;影响…