C# HuaYun出口服务器

发布于:2024-07-15 ⋅ 阅读:(157) ⋅ 点赞:(0)

直连 

串口转网口:通过请求帧写入波特率 或者地址位 或者温度 湿度等数据

读取时候 [0x01,0x03]

写入的时候[0x01,0x03]

写入波特率的时候请求帧 [0x01,0x06,0x07,0xD1,0x01,0x14] 把波特率改成0x01,0x14

namespace _01_HuaYun出口服务器
{
    public partial class Form1 : Form
    {
        string[] botelvs;
        public Form1()
        {
            InitializeComponent();
            botelvs = new string[] { "2400", "4800", "9600", "19200" };
            comboBox1.DataSource = botelvs;
        }

        NetworkStream stream;
        TcpClient tcp;
        private void button1_Click(object sender, EventArgs e)
        {

            // 连接网口
            if (button1.Text == "连接")
            {
                try
                {
                    tcp = new TcpClient();// 创建客户端对象
                    tcp.Connect(textBox1.Text, int.Parse(textBox2.Text));
                    stream = tcp.GetStream();// 获取网络基础流
                    button1.Text = "断开";
                }
                catch 
                {
                    MessageBox.Show("连接服务器失败");
                }
            }
            else
            {
                if (tcp!=null&&tcp.Connected)
                {
                    tcp.Close();
                    tcp = null;
                    stream = null;
                }
                button1.Text = "连接";
            }
        }
        // 刷新功能
        private void button2_Click(object sender, EventArgs e)
        {
            if (tcp == null || tcp.Connected == false)
            {
                MessageBox.Show("请先连接服务器");
                return;
            }
            Task.Run(refresh);
        }
        async void refresh()
        {
            try
            {
                // 请求帧
                byte[] buffer = null;
                // 响应帧
                byte[] res = null;
                // 设置地址
                byte address = Convert.ToByte(label12.Text);
                // 相应数据的个数
                int resCount = -1;
                // 响应帧crc
                byte[] crc;

                // 读取PM2.5 PM10 湿度 温度数据 寄存器个数是4个
                // 有效数组字节数8个字节
                buffer = new byte[] { address,0x03,0x00,0x00,0x00,0x04 };
                buffer = buffer.Concat(CRCCalc(buffer)).ToArray();

                // 异步发请求 发送请求帧
                await stream.WriteAsync(buffer, 0, buffer.Length);

                // 接受数据 响应帧
                res = new byte[13];
                resCount = await stream.ReadAsync(res, 0, res.Length);

                // 数据验证

                // 数据解析 读取数据
                int pm25 = res[3] * 256 + res[4];
                int pm10 = res[5] * 256 + res[6];
                double humidity = (res[7] * 256 + res[8])*0.1; // 湿度
                double wendu = (res[9] * 256 + res[10]) * 0.1;// s

                //更新界面
                Invoke((Action)(() =>
                {
                    textBox3.Text = pm25.ToString();
                    textBox4.Text = pm10.ToString();
                    textBox5.Text = humidity.ToString();
                    textBox6.Text = wendu.ToString();
                }));


            }
            catch 
            {
                MessageBox.Show("获取数据失败");
             
            }
        }
        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;
        }

        private void button4_Click(object sender, EventArgs e)
        {
            if (tcp == null || tcp.Connected ==false)
            {
                MessageBox.Show("未连接服务器");
                return;
            }
            Task.Run((() =>
            {
                this.Invoke((Action)(() =>
                {
                    // 获取选中的波特率
                    byte botelv = Convert.ToByte(comboBox1.SelectedIndex);

                    // 当前设备地址
                    byte address = Convert.ToByte(label12.Text);

                    // 询问帧
                    byte[] buffer = new byte[] { address, 0x06, 0x07, 0xD1, 0x00, botelv };
                    buffer = buffer.Concat(CRCCalc(buffer)).ToArray();

                    // 发送 
                    stream.Write(buffer, 0, buffer.Length);

                    // 读取
                    byte[] bs = new byte[8];
                    int count = stream.Read(bs, 0, bs.Length);
                    // 数据验证

                    byte newBotelv = bs[5];
                    comboBox1.SelectedIndex = newBotelv;
                    MessageBox.Show(comboBox1.SelectedIndex + "" + newBotelv.ToString());
                }));
            }));
        }
    }
}

网站公告

今日签到

点亮在社区的每一天
去签到