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();
            }

        }
    }
    
}

相关推荐

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-11 22:16:02       67 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-11 22:16:02       72 阅读
  3. 在Django里面运行非项目文件

    2024-07-11 22:16:02       58 阅读
  4. Python语言-面向对象

    2024-07-11 22:16:02       69 阅读

热门阅读

  1. 数字化转型

    2024-07-11 22:16:02       16 阅读
  2. MySQL索引之索引类型

    2024-07-11 22:16:02       18 阅读
  3. 在 Linux 上安装 Miniconda

    2024-07-11 22:16:02       23 阅读
  4. 洛谷P7537-字典树+DFS

    2024-07-11 22:16:02       19 阅读
  5. SpringBoot使用@RestController处理GET和POST请求

    2024-07-11 22:16:02       19 阅读
  6. python的内置函数和模块(网安)

    2024-07-11 22:16:02       24 阅读
  7. (C++哈希02) 四数相加 赎金信

    2024-07-11 22:16:02       22 阅读
  8. 超详细Python教程——面向对象相关知识

    2024-07-11 22:16:02       16 阅读