C# modbus 图表

news2024/9/21 2:40:42

控件:chart1(图表),cartesianChart1(第三方添加图表),timer(时间)

添加第三方:

效果:图标会根据连接的温度,湿度用timer时间进行改变

Chart1控件样式:Series添加线条,颜色,名称等数据

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
        //1 安装livecharts第三方; 安装livechartswinform第三方;
        timer1.Interval = 1000;
        timer1.Start();

        //给图表添加系列
        //new LineSeries() 添加一个线性的系列
        // values 指的是线性系列图表值是 ChartValues类型当中的float类型
       
        cartesianChart1.Series.Add(new LineSeries() { Values = new ChartValues<double>() }); //温度
        cartesianChart1.Series.Add(new LineSeries() { Values = new ChartValues<double>() });//湿度


        
        //给x轴加时间
       cartesianChart1.AxisX.Add(new LiveCharts.Wpf.Axis() { Labels = times });


       //创建客户端对象
        tcp = new TcpClient();//创建客户端对象
        tcp.Connect("192.168.107.5", 8014);
        stream = tcp.GetStream(); //获取网络基础流

    }
    TcpClient tcp;
    NetworkStream stream;


    public List<string> times = new List<string>();
    Random r = new Random();// 随机数对象
    double 温度;
    double 湿度;
    //实时更新数据
    private void timer1_Tick(object sender, EventArgs e)
    {


        // 模拟数据
        //float 温度 = r.Next(-100, 410) / 10F;//模拟请求 请求温度数据
        //float 湿度 = r.Next(-100, 410) / 10F; //读取湿度
        refresh();


        //给chart1 添加数据
        // 给系列1添加xy轴 ,x轴是时间,y轴是温度数据
        chart1.Series[0].Points.AddXY(DateTime.Now.ToString("HH:mm:ss"), 温度);
        chart1.Series[1].Points.AddXY(DateTime.Now.ToString("HH:mm:ss"), 湿度);

        //超出一定数值之后 删除一部分图表?
        if (chart1.Series[0].Points.Count>=10)
        {
            chart1.Series[0].Points.RemoveAt(0);
            chart1.Series[1].Points.RemoveAt(0);
            
        }
        // 给cartesianChart1添加数据
        times.Add(DateTime.Now.ToString());
        cartesianChart1.Series[0].Values.Add(温度);
        cartesianChart1.Series[1].Values.Add(湿度);
    }

    async void refresh()
    {
        try
        {

            //请求帧
            byte[] buffer = null;
            //响应帧
            byte[] res = null;
            //设备地址
            byte address = Convert.ToByte("1");
            //响应数据的个数
            int resCount = -1;
            //响应帧的crc
            byte[] crc;
            buffer = new byte[] { address, 0x03, 0x00, 0x02, 0x00, 0x02 };
            buffer = buffer.Concat(CRCCalc(buffer)).ToArray();

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

            //接收数据 响应帧。[地址码 功能码 有效个数,0x00,0x01,0x00,0x01,高位 地位]
            res = new byte[9];
            resCount = await stream.ReadAsync(res, 0, res.Length);

            //数据验证

            // 数据验证
            if (resCount == 0 || resCount != res.Length)
            {
                Console.WriteLine("读取湿度、温度时,数据长度不正确");
                return;
            }
            // 验证地址码和功能码
            if (res[0] != buffer[0] || res[1] != buffer[1])
            {
                Console.WriteLine("读取湿度、温度时,设备地址或功能码不匹配");
                return;
            }
            // 验证CRC
            crc = CRCCalc(res, 0, res.Length - 2);
            if (crc[0] != res[res.Length - 2] || crc[1] != res[res.Length - 1])
            {
                Console.WriteLine("读取湿度、温度时,CRC验证失败");
                return;
            }

            //数据解析 读取数据
            double humidity = (res[3] * 256 + res[4]) * 0.1; //湿度
            double wendu = (res[5] * 256 + res[6]) * 0.1;
            湿度 = humidity;
            温度 = wendu;


        }
        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;
    }
    public static byte[] CRCCalc(byte[] data, int offset, int length)
    {
        byte[] Tdata = data.Skip(offset).Take(length).ToArray();
        return CRCCalc(Tdata);
    }

}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

劳易测应用案例 汽车零部件装配线光电传感器解决方案

汽车零部件种类繁多&#xff0c;形状、尺寸、功能各异&#xff0c;生产线的规划与布局必须紧密贴合产品的独特工艺、精细装配流程及高效生产需求。随着电动汽车时代的到来&#xff0c;生产标准愈加严格&#xff0c;对生产线的设计和装配周期提出了更高要求。市场要求生产线不仅…

EE trade:强平和爆仓的区别

在金融交易市场中&#xff0c;杠杆交易的引入&#xff0c;让投资者可以用少量的资金撬动更大的头寸&#xff0c;获取更大的收益。然而&#xff0c;杠杆交易也带来了更大的风险&#xff0c;一旦市场波动&#xff0c;投资者可能会面临强平或爆仓的风险。了解强平和爆仓的区别&…

MySQL-对数据库和表的DDL命令

文章目录 一、什么是DDL操作二、数据库编码集和数据库校验集三、使用步骤对数据库的增删查改1.创建数据库2.进入数据库3.显示数据库4.修改数据库mysqldump 5.删除数据库 对表的增删查改1.添加/创建表2.插入表内容3.查看表查看所有表查看表结构查看表内容 4.修改表修改表的名字修…

保障低压设备安全!中国星坤连接器精密工艺解析!

在现代电子设备中&#xff0c;连接器扮演着至关重要的角色&#xff0c;它们是电子系统之间沟通的桥梁。随着技术的发展&#xff0c;对连接器的需求也在不断提升&#xff0c;特别是在低电压应用领域。中国星坤最新推出的低压连接器&#xff0c;以其精密性和安全性&#xff0c;为…

Msql数据库之DDL(数据定义语言)的相关操作

数据定义语言(DDL)&#xff1a;用于创建、修改和删除数据库对象&#xff0c;如数据库、表、视图、索引等 一、数据库的相关操作&#xff1a; 1、创建数据库 语法&#xff1a;create database [if not exists ] 数据库名; 例&#xff1a;create database if not exists test…

2024-07-16 Unity插件 Odin Inspector6 —— Group Attributes

文章目录 1 说明2 Group 特性2.1 BoxGroup2.2 ButtonGroup2.3 FoldoutGroup2.4 ShowIfGroup / HideIfGroup2.5 HorizontalGroup2.6 ResponsiveButtonGroup2.7 TabGroup2.8 ToggleGroup2.9 VerticalGroup 1 说明 ​ 本文介绍 Odin Inspector 插件中有关 Group 特性的使用方法。…

【Apache POI】Java解析Excel文件并处理合并单元格-粘贴即用

同为牛马&#xff0c;点个赞吧&#xff01; 一、Excel文件样例 二、工具类源码 import org.apache.poi.ss.usermodel.*; import org.apache.poi.ss.util.CellRangeAddress; import org.apache.poi.xssf.usermodel.XSSFWorkbookFactory; import org.springframework.web.multip…

【B树、B-树、B+、B*树】

目录 一、B-树&#xff08;即B树&#xff09;的定义及操作1.1、定义1.2、操作1.2.1、查找1.2.2、插入1.2.3、删除 二、B树的定义及操作2.1、定义2.2、操作2.2.1、查找2.2.2、插入2.2.3、删除 三、B*树 一、B-树&#xff08;即B树&#xff09;的定义及操作 1.1、定义 B-tree即…

解决vue3中el-input在form表单按下回车刷新页面

问题&#xff1a;在input框中点击回车之后不是调用我写的回车事件&#xff0c;而是刷新页面 原因&#xff1a; 如果表单中只有一个input 框则按下回车会直接关闭表单 所以导致刷新页面 解决方法 &#xff1a; 再写一个input 表单 &#xff0c;并设置style"display:none&…

【对顶堆 优先队列】2102. 序列顺序查询

本文涉及知识点 对顶堆 优先队列 LeetCode 2102. 序列顺序查询 一个观光景点由它的名字 name 和景点评分 score 组成&#xff0c;其中 name 是所有观光景点中 唯一 的字符串&#xff0c;score 是一个整数。景点按照最好到最坏排序。景点评分 越高 &#xff0c;这个景点越好。…

再谈有关JVM中的四种引用

1.强引用 强引用就是我们平时使用最多的那种引用&#xff0c;就比如以下的代码 //创建一个对象 Object obj new Object();//强引用 这个例子就是创建了一个对象并建立了强引用&#xff0c;强引用一般就是默认支持的当内存不足的时候&#xff0c;JVM开始垃圾回收&#xff0c…

【Java--数据结构】二叉树oj题(上)

前言 欢迎关注个人主页&#xff1a;逸狼 创造不易&#xff0c;可以点点赞吗~ 如有错误&#xff0c;欢迎指出~ 判断是否是相同的树 oj链接 要判断树是否一样&#xff0c;要满足3个条件 根的 结构 和 值 一样左子树的结构和值一样右子树的结构和值一样 所以就可以总结以下思路…

js补环境系列之剖析:原型、原型对象、实例对象三者互相转化(不讲废话、全是干货)

【作者主页】&#xff1a;小鱼神1024 【擅长领域】&#xff1a;JS逆向、小程序逆向、AST还原、验证码突防、Python开发、浏览器插件开发、React前端开发、NestJS后端开发等等 思考下&#xff1a;js补环境中&#xff0c;什么场景会用到原型、原型对象、实例对象&#xff1f; 举…

最大文件句柄数

优质博文&#xff1a;IT-BLOG-CN 灵感来源 一、什么是文件句柄 文件句柄File Handle是操作系统中用于访问文件的一种数据结构&#xff0c;通常是一个整数或指针。文件句柄用于标识打开的文件&#xff0c;每个打开的文件都有一个唯一的文件句柄。 它们是对文件、网络套接字或…

商业数据分析思维的培训PTT制作大纲分享

商业数据分析思维的培训PTT制作大纲: 基本步骤: 明确PPT的目的和主题 收集并整理相关内容资料 构思并确定PPT的框架大纲 编写PPT的内容文字 插入图片、图表等视觉元素 设计PPT的版式和模板 排练并修改PPT 输出并备份最终版本 目的:数据思维培养; 主题:商业数据分…

【TensorRT】Yolov5-DeepSORT 目标跟踪

Yolov5-DeepSORT-TensorRT 本项目是 Yolo-DeepSORT 的 C 实现&#xff0c;使用 TensorRT 进行推理 &#x1f680;&#x1f680;&#x1f680; 开源地址&#xff1a;Yolov5_DeepSORT_TensorRT&#xff0c;求 star⭐ ~ 引言 ⚡ 推理速度可达25-30FPS&#xff0c;可以落地部署&…

PriorityQueue 阅读记录

1、前言 1、优先队列&#xff0c;底层通过数组来构造树&#xff08;二叉树) 来实现的。 2、默认是最小堆&#xff08;取出来的是最小值)&#xff0c;可以通过传入一个比较器 comparator 来构造一个最大堆。 3、传入的参数不能为空&#xff0c;否则抛出NPE问题。 4、最大堆的…

git自动pull同步远程若干分支与本地若干分支

git自动pull同步远程若干分支与本地若干分支 假设远程代码仓库有100个分支&#xff0c;而本地只有10个本地分支与远程分支一一对应&#xff0c;现在要保持本地的这个10个分支与远程一致&#xff0c;最笨的方法是checkout到每个分支&#xff0c;然后一个一个的 git pull origin…

第11章 规划过程组(四)(11.4规划质量管理)

第11章 规划过程组&#xff08;四&#xff09;11.4规划质量管理&#xff0c;在第三版教材第412~414页&#xff1b; 文字图片音频方式 第一个知识点&#xff1a;工具与技术 1、数据分析&#xff08;重要知识点&#xff09; 成本效益分析 确定质量活动的可能成本与预期效益&a…

HTML2048小游戏

源代码在效果图后面 效果图 源代码 <!DOCTYPE html> <html lang"zh-CN"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>2048 Game&l…