C# modbus 图表

控件: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);
    }

}

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

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

相关文章

【算法】LRU缓存

难度&#xff1a;中等 题目&#xff1a; 请你设计并实现一个满足 LRU (最近最少使用) 缓存 约束的数据结构。 实现 LRUCache 类&#xff1a; LRUCache(int capacity) 以 正整数 作为容量 capacity 初始化 LRU 缓存int get(int key) 如果关键字 key 存在于缓存中&#xff0c;…

2024牛客暑期多校训练营1 A题 解题思路

前言&#xff1a; 今年和队友报了牛客暑期多校比赛&#xff0c;写了一下午结果除了签到题之外只写出了一道题&#xff08;A&#xff09;&#xff0c;签到题没什么好说的&#xff0c;其他题我也没什么好说的&#xff08;太菜了&#xff0c;根本写不出来&#xff09;&#xff0c;…

SAP ABAP性能优化

1.前言 ABAP作为SAP的专用的开发语言&#xff0c;衡量其性能的指标主要有以下两个方面&#xff1a; 响应时间&#xff1a;对于某项特定的业务请求&#xff0c;系统在收到请求后需要多久返回结果 吞吐量&#xff1a;在给定的时间能&#xff0c;系统能够处理的数据量 2. ABAP语…

FFMPEG录屏入门指南【转载】

文章非原创&#xff0c;为防失联而转载&#xff1a;【原创】FFMPEG录屏入门指南 - 博客园 (cnblogs.com) 【原创】FFMPEG录屏入门指南 最近部门内部在做技术分享交流&#xff0c;需要将内容录制成视频存档。很自然的想到了去网上找一些录屏的软件&#xff0c;试过了几款诸如屏幕…

昇思25天学习打卡营第13天|CycleGAN 图像风格迁移互换全流程解析

目录 数据集下载和加载 可视化 构建生成器 构建判别器 优化器和损失函数 前向计算 计算梯度和反向传播 模型训练 模型推理 数据集下载和加载 使用 download 接口下载数据集&#xff0c;并将下载后的数据集自动解压到当前目录下。数据下载之前需要使用 pip install dow…

LabVIEW设备检修信息管理系统

开发了基于LabVIEW设计平台开发的设备检修信息管理系统。该系统应用于各种设备的检修基地&#xff0c;通过与基地管理信息系统的连接和数据交换&#xff0c;实现了本地检修工位数据的远程自动化管理&#xff0c;提高了设备的检修效率和安全性。 项目背景 现代设备运维过程中信…

QT小细节

QT小细节 1 QTextToSpeech1.1 cmake1.2 qmake QT6 6.7.2 1 QTextToSpeech 从下图可以看到&#xff0c;分别使用qmake或者cmake编译情况下的&#xff0c;QTextToSpeech的使用方法 QTextToSpeech官方链接&#xff0c;也可以直接在QT Creator的帮助中搜索 1.1 cmake 将上图中的…

jmeter之变量随机参数化以及解决多线程不会随机变化

参考链接&#xff1a; https://www.cnblogs.com/Testing1105/p/12743475.html jmeter 使用random函数多线程运行时数据不会随机变化&#xff1f;_jmeter 线程组循环执行时 变量不变-CSDN博客 1、如下图所示&#xff0c;需要对请求参数 autor 和phone进行随机参数化 2、目前有…

FullCalendar日历组件集成实战(20)

背景 有一些应用系统或应用功能&#xff0c;如日程管理、任务管理需要使用到日历组件。虽然Element Plus也提供了日历组件&#xff0c;但功能比较简单&#xff0c;用来做数据展现勉强可用。但如果需要进行复杂的数据展示&#xff0c;以及互动操作如通过点击添加事件&#xff0…

【Java--数据结构】二叉树

欢迎关注个人主页&#xff1a;逸狼 创造不易&#xff0c;可以点点赞吗~ 如有错误&#xff0c;欢迎指出~ 树结构 树是一种非线性的数据结构&#xff0c;它是由n&#xff08;n>0&#xff09;个有限结点组成一个具有层次关系的集合 注意&#xff1a;树形结构中&#xff0c;子…

昇思MindSpore学习开始

昇思MindSpore是一个全场景深度学习框架&#xff0c;旨在实现易开发、高效执行、全场景统一部署三大目标。 其中&#xff0c;易开发表现为API友好、调试难度低&#xff1b;高效执行包括计算效率、数据预处理效率和分布式训练效率&#xff1b;全场景则指框架同时支持云、边缘以…

二叉树、B树/B-树

二叉树 在中文语境中,节点结点傻傻分不清楚,故后文以 node 代表 "结点",root node 代表根节点,child node 代表 “子节点” 二叉树是诸多树状结构的始祖,至于为什么不是三叉树,四叉树,或许是因为计算机只能数到二吧,哈哈,开个玩笑。二叉树很简单,每个 no…

在android11 上实现平行视界效果

前言&#xff1a; 平行视界是谷歌为了解决大屏横屏设备 适配为手机等竖屏设备开发的APP &#xff0c; 在这类APP显示时 在横屏设备上不方便用户观看。 android 13 上平行视界的效果如下&#xff1a; 正文: 在android13前 &#xff0c;各家有各自的解决方案&#xff0c;下面提…

[计算机网络] VPN技术

VPN技术 1. 概述 虚拟专用网络&#xff08;VPN&#xff09;技术利用互联网服务提供商&#xff08;ISP&#xff09;和网络服务提供商&#xff08;NSP&#xff09;的网络基础设备&#xff0c;在公用网络中建立专用的数据通信通道。VPN的主要优点包括节约成本和提供安全保障。 优…

心理健康服务小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;学生管理&#xff0c;最新资讯管理&#xff0c;心理产品管理&#xff0c;产品分类管理&#xff0c;音乐理疗管理&#xff0c;试题管理 微信端账号功能包括&#xff1a;系统首页&#xff0c;心理产品音…

学习大数据DAY17 PLSQL基础语法6和Git的基本操作

目录 包 存储过程调试功能 作业 阶段复习作业 Git课程目录 什么是版本控制 没有版本控制的缺点 常见的版本工具 版本控制分类 1. 本地版本控制 2. 集中版本控制 3. 分布式版本控制 Git与SVN主要区别 Git软件安装及配置 Windows系统安装Git 安装Tortoise Git(乌龟…

git和gitee的基本操作

目录 git常见命令 1.初始化工作区(在某一文件路径下) 2.查看当前工作区的代码文件状态 3.将工作区的代码文件提交到暂存区 4.将暂存区的代码文件提交到本地仓库 5.工作区和暂存区文件差异化比较 6.暂存区和本地仓库的差异化比较 7.工作区和本地仓库差异化比较 8.版本回…

自适应键盘,自带隐藏键盘的输入框(UITextField)

引言 在iOS开发中&#xff0c;输入框占据着举足轻重的地位。与安卓不同&#xff0c;iOS输入框经常面临键盘遮挡的问题&#xff0c;或者无法方便地取消键盘。为了解决这些问题&#xff0c;有许多针对iOS键盘管理的库&#xff0c;如IQKeyboardManager、TPKeyboardAvoiding和Keyb…

实习随笔【实现Json格式化与latex渲染】

【写在前面】在实习中&#xff0c;遇到了如下需求&#xff1a; 待格式化数据大概长这样&#xff0c;里面存在Json乱码以及由$$包裹的公式 目标格式&#xff1a; 一、Json格式化 我们这里的任务主要分为两部分&#xff1a; 解析一个可能包含嵌套的 JSON 字符串格式化 JSON 对象…

SAP ABAP性能优化分析工具

SAP系统提供了许多性能调优的工具&#xff0c;重点介绍下最常用几种SM50, ST05, SAT等工具&#xff1a; 1.工具概况 1.1 SM50 / SM66 - 工作进程监视器 通过这两个T-code, 可以查看当前SAP AS实例上面的工作进程&#xff0c;当某一工作进程长时间处于running的状态时&#…