精华内容
下载资源
问答
  • C#工控上位机学习????简述一、倒计时器的开发二、串口串口发数据串口助手的开发串口控制下位机开关三、图形化按钮设计 简述 c#的窗口项目,直接使用设计框进行拖拽即可。 一、倒计时器的开发 using System; using ...

    简述

    c#的窗口项目,直接使用设计框进行拖拽即可。

    一、倒计时器的开发

    using System;
    using System.Windows.Forms;
    
    namespace TimerC
    {
        public partial class Form1 : Form
        {
            int count;
            int time;
            public Form1()
            {
                // 初始化代码
                InitializeComponent();
            }
            /// <summary>
            /// 时间选择
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void Form1_Load(object sender, EventArgs e)
            {
                int i;
                //对选择时间块进行添加
                for (i = 1; i < 100; i++) {
                    comboBox2.Items.Add(i.ToString()+"  秒");
                }
                comboBox2.Text = "1 秒";
    
            }
              //倒计时还剩多少秒
            private void timer1_Tick(object sender, EventArgs e)
            {
                count++;
                label3.Text = (time - count).ToString() + "  秒";
                progressBar1.Value = time-count;
                if (count == time) {
                    timer1.Stop();//时间到计时器停止
                    System.Media.SystemSounds.Asterisk.Play();
                    MessageBox.Show("时间到了");
                }
    
            }
            //点击开始计时按钮
            private void button1_Click(object sender, EventArgs e)
            {
                string str = comboBox2.Text;
                string str2 = str.Substring(0, 2);
                time = Convert.ToInt16(str2);
                progressBar1.Maximum = time;
                timer1.Start();//计时器开始
            }
        }
    }
     
    

    运行效果:
    选择倒计时的时间,开始倒计时

    二、串口

    串口发数据

    using System;
    using System.Windows.Forms;
    
    namespace chuankou
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
    
            private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
            {
                
            }
    
            private void button1_Click(object sender, EventArgs e)
            {
                String data = comboBox1.Text;//获取选择的串口的数据
                String convertdata = data.Substring(2, 2);//将字符分开
                byte[] buffer = new byte[1];//数据一个字节就够了
                buffer[0] = Convert.ToByte(convertdata, 16);//将字符串转化为byte型变量
                try
                {
                    serialPort1.Open();
                    serialPort1.Write(buffer, 0, 1);
                    serialPort1.Close();
                }
                catch 
                {
                    if (serialPort1.IsOpen) {
                        serialPort1.Close();
                    }
                    MessageBox.Show("端口错误");
                }
    
            }
    
            private void Form1_Load(object sender, EventArgs e)
            {
                String str;
                for (int i = 0; i < 256; i++)
                {
                    str = i.ToString("x").ToUpper();// i.ToString("X")将十进制转换为十六进制,ToUpper()转换为大写
                    if (str.Length == 1)
                    {
                        str = "0" + str;
                    }
                    comboBox1.Items.Add("0X" + str);//转换为统一形式
                }
                comboBox1.Text = "0X00";
            }
        }
    }
    
    

    串口助手的开发

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.IO.Ports;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    
    namespace chuankouzhushou
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
    
            private void radioButton2_CheckedChanged(object sender, EventArgs e)
            {
    
            }
    
            private void radioButton1_CheckedChanged(object sender, EventArgs e)
            {
    
            }
    
            private void label4_Click(object sender, EventArgs e)
            {
    
            }
    
            private void Form1_Load(object sender, EventArgs e)
            {
                for (int i = 1; i < 20; i++) {
                    comboBox2.Items.Add("COM" + i.ToString());
                }
                comboBox2.Text = "COM1";//串口号设置为默认值
                comboBox1.Text = "4800";//波特率设为默认值
                //手动添加串口的事件
                serialPort1.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived);
                button2.Enabled = false;//关闭按钮可用
            }
    
            private void port_DataReceived(object sender, SerialDataReceivedEventArgs e) {
                if (radioButton1.Checked)
                { //如果接受模式为字符模式
                    String str = serialPort1.ReadExisting();//字符串的方式读取
                    textBox1.AppendText(str);//添加内容
                }
                else {//数值模式接受
                    byte data;
                    data = (byte)(serialPort1.ReadChar());
                    String str = Convert.ToString(data, 16).ToUpper();//转换为大写十六进制字符串
                    textBox1.AppendText("0X" + (str.Length == 1 ? "0"+str:str)+" ");//空位补“0”
                
                }
            }
    
            private void button1_Click(object sender, EventArgs e)
            {
                try {
                    serialPort1.PortName = comboBox1.Text;
                    serialPort1.BaudRate = Convert.ToInt32(comboBox2.Text);//转换为十进制
                    serialPort1.Open();
                    button1.Enabled = false; //打开串口不可用
                    button2.Enabled = true;//关闭按钮可用
    
                }catch{
                    MessageBox.Show("端口错误,请检查");
                }
            }
    
            private void button2_Click(object sender, EventArgs e)
            {
                serialPort1.Close();
                button1.Enabled = true;
                button2.Enabled = false;
            }
    
            private void button3_Click(object sender, EventArgs e)//串口发送部分
            {
                byte[] Data = new byte[1];
                if (serialPort1.IsOpen) {
                    if (textBox2.Text != "") {
                        if (!radioButton4.Checked)//如果发送的是字符数据 
                        {
                            try
                            {
                                serialPort1.WriteLine(textBox2.Text);//写数据
                            }
                            catch (Exception err)
                            {
                                MessageBox.Show("串口数据写入错误");//出错提示
                                serialPort1.Close();
                                button1.Enabled = true;
                                button2.Enabled = false;
                            }
                        }
                        else {
                            for (int i = 0; i < (textBox2.Text.Length - textBox2.Text.Length % 2) / 2; i++)
                            {
                                Data[0] = Convert.ToByte(textBox2.Text.Substring(i * 2, 2), 16);
                                serialPort1.Write(Data,0,1);//循环发送
                            }
                            if (textBox2.Text.Length % 2 != 0) {
                                Data[0] = Convert.ToByte(textBox2.Text.Substring(textBox2.Text.Length - textBox2.Text.Length %2,textBox2.Text.Length%2),16);
                                serialPort1.Write(Data, 0, 1);
                            }
                        }
                    }
                }
            }
    
            private void textBox1_TextChanged(object sender, EventArgs e)
            {
                textBox1.ScrollToCaret();//将滚动条调至最底下
            }
        }
    }
    
    

    实力

    串口控制下位机开关

    三、图形化按钮设计

    展开全文
  • C#工控机开发实例

    2018-08-08 14:11:05
    C#通过MODUBS TCP采集数据,有自定义控件实现流动快,如何进行数据绑定
  • 布局经验: 掌握两种布局方式足矣 流布局:弹性布局, FlowLayoutPanel控件,它可使控件随着用户拖动窗口的大小而放大缩小,类似安卓中的弹性布局,或者css中的box-sizing。 使用方法:拖拽一个FlowLayoutPanel,...

    布局经验:

    掌握两种布局方式足矣

    • 流布局:弹性布局, FlowLayoutPanel控件,它可使控件随着用户拖动窗口的大小而放大缩小,类似安卓中的弹性布局,或者css中的box-sizing。
      使用方法:拖拽一个FlowLayoutPanel,里面放你需要的控件。OK
    • 绝对大小(自命名的):类似N年前HTML中用几个DIV将页面按功能划分的那种。通过Panel控件作为容器,利用控件的dock和Anchor属性实现padding的那种效果。
      使用方法:拖拽一个Panel控件,点击控件的dock属性,可以放在form的上下左右中间。在panel里面放你需要的控件,点击anchor锚属性,选中的锚将会一直保持绝对的距离,不随差窗口大小变化而变化。
    展开全文
  • C#工控机作为Modbus从站的方法

    千次阅读 2020-02-10 14:15:16
    工作需要实现HMI作为Modbus主站,工控机作为modbus从站。在网上找了一些资料,但多数都是使用工控机作为主站的方案,于是自己根据一些网上的说明,再加上一些摸索,实现了工控机作为从站的方法,在这里给大家分享...

            工作需要实现HMI作为Modbus主站,工控机作为modbus从站。在网上找了一些资料,但多数都是使用工控机作为主站的方案,于是自己根据一些网上的说明,再加上一些摸索,实现了工控机作为从站的方法,在这里给大家分享一下。

            首先,工控机作为从站的话,是没有办法去读写主站的,也就是说,工控机端只能读取HMI写进来的数据,或者把数据写如到存储区,等待HMI来读取。这里使用的工具有虚拟串口,modbuspoll,modbusslave,打包下载在这里:

    https://download.csdn.net/download/gaooolianggg/12147467

            虚拟串口中添加好端口后,开启modbus poll,因为此时还没有启动从站程序,所以会报time out 的错误,这个先无所谓。

            接下来进入到正题,使用C#建立从站。我们使用的NModbus。NModbus的安装很简单,直接在NuGet包管理中搜索NModbus即可,也可以进入到NModbus的github主页,下载源码自己编译。这里建议从Github下载源码,在NModbus项目中的samples工程里,有很多使用示例,本文所列举的使用方法也是从示例中找到的。如果你想直接使用的话,那么从NuGet安装了NModbus后,直接调用以下方法即可。

            我的测试工程可以从这里下载,其中主要是开源samples,我自己测试用的工程为myTest,开发工具为vs2019社区版。希望可以帮助到有需要的人,如果有问题可以联系我605418966@qq.com

    代码下载链接

     

     

     

            private const string PrimarySerialPortName = "COM1";
            private const string SecondarySerialPortName = "COM2";
    
    
            public async Task StartModbusSerialRtuSlaveWithCustomStore()
            {
    
                using (SerialPort slavePort = new SerialPort(PrimarySerialPortName))
                {
                    // configure serial port
                    slavePort.BaudRate = 9600;
                    slavePort.DataBits = 8;
                    slavePort.Parity = Parity.None;
                    slavePort.StopBits = StopBits.One;
                    slavePort.Open();
    
                    var factory = new ModbusFactory();
                    var slaveNetwork = factory.CreateRtuSlaveNetwork(slavePort);
    
                    var dataStore = new SlaveStorage();
                    dataStore.HoldingRegisters.ReadPoints(0, 10);
                    ushort[] d = new ushort[3]{ 3, 4, 5 };
                    dataStore.HoldingRegisters.WritePoints(0, d);
                    dataStore.CoilDiscretes.StorageOperationOccurred += (sender, args) => textBox1.Invoke(new Action(()=> textBox1.AppendText($"Coil discretes: {args.Operation} starting at {args.StartingAddress},num {args.Points.Length} + from task "+Task.CurrentId+Environment.NewLine)));
                    dataStore.CoilInputs.StorageOperationOccurred += (sender, args) => textBox1.Invoke(new Action(() => textBox1.AppendText($"Coil inputs: {args.Operation} starting at {args.StartingAddress},num {args.Points.Length}" + Environment.NewLine)));
                    dataStore.InputRegisters.StorageOperationOccurred += (sender, args) => textBox1.Invoke(new Action(() => textBox1.AppendText($"Input registers: {args.Operation} starting at {args.StartingAddress},num {args.Points.Length}" + Environment.NewLine)));
                    dataStore.HoldingRegisters.StorageOperationOccurred += (sender, args) => textBox1.Invoke(new Action(() => textBox1.AppendText($"Holding registers: {args.Operation} starting at {args.StartingAddress},num {args.Points.Length} + from task " + Task.CurrentId + Environment.NewLine)));
                    IModbusSlave slave1 = factory.CreateSlave(1, dataStore);
    
                    slaveNetwork.AddSlave(slave1);
    
                    await slaveNetwork.ListenAsync();
                }
            }
    
    using NModbus;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    
        namespace myTest
    {
    
            public class SlaveStorage : ISlaveDataStore
            {
                private readonly SparsePointSource<bool> _coilDiscretes;
                private readonly SparsePointSource<bool> _coilInputs;
                private readonly SparsePointSource<ushort> _holdingRegisters;
                private readonly SparsePointSource<ushort> _inputRegisters;
    
                public SlaveStorage()
                {
                    _coilDiscretes = new SparsePointSource<bool>();
                    _coilInputs = new SparsePointSource<bool>();
                    _holdingRegisters = new SparsePointSource<ushort>();
                    _inputRegisters = new SparsePointSource<ushort>();
                }
    
                public SparsePointSource<bool> CoilDiscretes
                {
                    get { return _coilDiscretes; }
                }
    
                public SparsePointSource<bool> CoilInputs
                {
                    get { return _coilInputs; }
                }
    
                public SparsePointSource<ushort> HoldingRegisters
                {
                    get { return _holdingRegisters; }
                }
    
                public SparsePointSource<ushort> InputRegisters
                {
                    get { return _inputRegisters; }
                }
    
                IPointSource<bool> ISlaveDataStore.CoilDiscretes
                {
                    get { return _coilDiscretes; }
                }
    
                IPointSource<bool> ISlaveDataStore.CoilInputs
                {
                    get { return _coilInputs; }
                }
    
                IPointSource<ushort> ISlaveDataStore.HoldingRegisters
                {
                    get { return _holdingRegisters; }
                }
    
                IPointSource<ushort> ISlaveDataStore.InputRegisters
                {
                    get { return _inputRegisters; }
                }
            }
    
            /// <summary>
            /// Sparse storage for points.
            /// </summary>
            public class SparsePointSource<TPoint> : IPointSource<TPoint>
            {
                private readonly Dictionary<ushort, TPoint> _values = new Dictionary<ushort, TPoint>();
    
                public event EventHandler<StorageEventArgs<TPoint>> StorageOperationOccurred;
    
                /// <summary>
                /// Gets or sets the value of an individual point wih tout 
                /// </summary>
                /// <param name="registerIndex"></param>
                /// <returns></returns>
                public TPoint this[ushort registerIndex]
                {
                    get
                    {
                        TPoint value;
    
                        if (_values.TryGetValue(registerIndex, out value))
                            return value;
    
                        return default(TPoint);
                    }
                    set { _values[registerIndex] = value; }
                }
    
                public TPoint[] ReadPoints(ushort startAddress, ushort numberOfPoints)
                {
                    var points = new TPoint[numberOfPoints];
    
                    for (ushort index = 0; index < numberOfPoints; index++)
                    {
                        points[index] = this[(ushort)(index + startAddress)];
                    }
    
                    StorageOperationOccurred?.Invoke(this,
                        new StorageEventArgs<TPoint>(PointOperation.Read, startAddress, points));
    
                    return points;
                }
    
                public void WritePoints(ushort startAddress, TPoint[] points)
                {
                    for (ushort index = 0; index < points.Length; index++)
                    {
                        this[(ushort)(index + startAddress)] = points[index];
                    }
    
                    StorageOperationOccurred?.Invoke(this,
                        new StorageEventArgs<TPoint>(PointOperation.Write, startAddress, points));
                }
            }
    
            public class StorageEventArgs<TPoint> : EventArgs
            {
                private readonly PointOperation _pointOperation;
                private readonly ushort _startingAddress;
                private readonly TPoint[] _points;
    
                public StorageEventArgs(PointOperation pointOperation, ushort startingAddress, TPoint[] points)
                {
                    _pointOperation = pointOperation;
                    _startingAddress = startingAddress;
                    _points = points;
                }
    
                public ushort StartingAddress
                {
                    get { return _startingAddress; }
                }
    
                public TPoint[] Points
                {
                    get { return _points; }
                }
    
                public PointOperation Operation
                {
                    get { return _pointOperation; }
                }
            }
    
            public enum PointOperation
            {
                Read,
    
                Write
            }
    
    
        }

     

    展开全文
  • 通讯仿真环境搭建 3.snap7的dll库安装与常用函数介绍 4.C# 格式化 中文星期显示 5.C#清空数组方法 Array.Clear 6.微软官方-C#指南 7.Chart控件实现实时曲线 8.通过自定义控件实现在设计界面关联通讯地址 1.Snap7基础...
    • 本次学习上位机目标主要是通过snap7实现与西门子S7-1200系列PLC通讯;
    • 本博文主要对收集的资料进行整理。

    目录

    1.Snap7基础介绍

    2.通讯仿真环境搭建

    3.snap7的dll库安装与常用函数介绍

    4.C# 格式化 中文星期显示

    5.C#清空数组方法 Array.Clear

    6.微软官方-C#指南

    7.Chart控件实现实时曲线

    8.通过自定义控件实现在设计界面关联通讯地址

     


    1.Snap7基础介绍

    参考:https://blog.csdn.net/xiketangAndy/article/details/106160585

    2.通讯仿真环境搭建

    参考:https://www.bilibili.com/video/BV1gE411j7VZ?from=search&seid=15027083189517220100

    3.snap7的dll库安装与常用函数介绍

    参考:https://zhuanlan.zhihu.com/p/51964406

    4.C# 格式化 中文星期显示

    参考:https://www.cnblogs.com/duanchen/p/4464249.html

    5.C#清空数组方法 Array.Clear

    参考:https://www.cnblogs.com/Peng18233754457/p/9817794.html

    6.微软官方-C#指南

    连接:https://docs.microsoft.com/zh-cn/dotnet/csharp/

    7.Chart控件实现实时曲线

    参考:https://v.qq.com/x/page/l30066swy7w.html

    8.通过自定义控件实现在设计界面关联通讯地址

    参考:http://blog.csdn.net/sinat_38994591/article/details/108559447

    9.使用手机+PC通过NettoPlcSim搭建仿真环境(待写)

    展开全文
  • 生产线每完成一件产品的测试,扫码打包后, 实际产量要增加1, 所以要和生产数据库连接起来下载一个开源的C# Modbus的工具 https://github.com/stephan1827/modbusTCP-DotNET里面关键代码就是构建Modbus TCP的Header.....
  • 开源纯C#工控网关+组态软件

    千次阅读 2017-10-08 00:00:00
    看着.NET和C#在国外风生水起,国内却日趋没落,我也早觉得有写一点东西的必要了。 二、 为什么要开源,它能做什么 开源是大势所趋 现在已经不是兜售软件光盘卖授权的时代了。我自己开发这套系统也得益于...
  • 一、图元概述图元是构成人机界面的基本单元。如一个个的电机、设备、数据显示、仪表盘,都是图元。构建人机界面的过程就是铺排、挪移、定位图元的过程。图元设计是绘图和编码的结合。因为图元不仅有显示和动画,还有...
  • 一、引子因为最近很忙(lan),很久没发博了。不少朋友对那个右键弹出菜单和连线的功能很感兴趣,因为VS本身是不包含这种功能的。大家想这是什么鬼,怎么我的设计器没有,其实这是一个微软黑科技,如果用好,VS可以...
  • c#工控编程书籍

    2012-03-19 13:12:38
    c#串口编程,接收不同格式串口数据的方法 控制数据采集卡 c#工控机编程,控制电磁阀,控制接近开关,控制摄像头等。 就是工业自动化方向的 求好书
  • 这些已经足够吸引人了,对我这一工控狗而言,架构如果限定在Windows操作系统,有几个问题是难以解决但必须面对的: 实时性 Windows是非实时的操作系统;受限于操作系统,我的网关程序始终找不到高精度的定时器,对...
  • 传送门原程序架构出现的问题解决思路总结 原程序架构 此程序有一功能是通过ListBox记录按钮操作,包含【Initialize】、【Disable】、【Read Volt】和【Keep Read】。 其中【Initialize】、【Disable】、【Read Volt...
  • 一、引子之前都在讲网关,不少网友关注如何实现界面。想了解下位机变量变化,是怎样一步步触发人机界面动画的。这个步步触发,实质上是变量组(Group)的批量数据变化(DataChange)事件,引发了变量(Tag)的值更新...
  • 一、 引子 监控画面的主要功能之一就是跟踪下位机变量变化,并将这些变化展现为动画。大部分时候,界面上一个图元组件的某个状态,与单一变量Tag绑定,比如...考虑到工控行业大部分技术人员并非计算机专业出身,如
  • 一、引子监控画面的主要功能之一就是跟踪下位机变量变化,并将这些变化展现为动画。大部分时候,界面上一个图元组件的某个状态,与单一变量Tag绑定,...考虑到工控行业大部分技术人员并非计算机专业出身,如何能够用...
  • 开源纯C#工控网关+组态软件(三)加入一个新驱动:西门子S7 开源纯C#工控网关+组态软件(四)上下位机通讯原理 开源纯C#工控网关+组态软件(五)从网关到人机界面 原文:...
  • 开源纯C#工控网关+组态软件(三)加入一个新驱动:西门子S7 开源纯C#工控网关+组态软件(四)上下位机通讯原理 开源纯C#工控网关+组态软件(五)从网关到人机界面 开源纯C#工控网关+组态软件(六)图元组件 开源纯C#工控网关...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 388
精华内容 155
关键字:

c#工控

c# 订阅