首页 > 其他分享 >让你的PLC支持多连接,多电脑同时访问一个PLC 连接PLC的权限设置,PLC同时多连接

让你的PLC支持多连接,多电脑同时访问一个PLC 连接PLC的权限设置,PLC同时多连接

时间:2022-08-28 14:55:23浏览次数:87  
标签:HslCommunication System server PLC new using 权限 连接

要明白一个技术,首先要明白它到底是解决什么问题的?你是不是有以下的困扰
1. 我有个三菱的PLC,只能配置一个端口,但是有多台电脑需要从PLC进行读写,因为三菱是单链接的,所以直接读写会报错。

2. 我得三菱PLC不希望对所有的客户端都开放权限读写,比如输入正确的用户名密码,才能通信

3. 我得PLC是在一个很小型的现场组网的,和公司内网不一个网络,但是有个工控机既连着PLC,也连着公司内网,但是内网的客户端程序也需要读写PLC,这时候也可以使用下面的注册PLC功能来解决

 

好了,有了这个需求,我们再来看怎么操作。依旧是使用hslcommunication组价

HslCommunication 软件,详细可以参考下面的地址:

github地址:https://github.com/dathlin/HslCommunication

官网:http://www.hslcommunication.cn

加群咨询学习信息:http://www.hslcommunication.cn/

在Visual Studio 中的NuGet管理器中可以下载安装,也可以直接在NuGet控制台输入下面的指令安装如果需要教程:Nuget安装教程:http://www.cnblogs.com/dathlin/p/7705014.html

1 Install-Package HslCommunication

组件的api地址:http://api.hslcommunication.cn

 

 

 

 

我们先写服务器的代码:

新建好控制台项目后,我们就可以安装hslcommunication了

 

 

 

然后就是写代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using HslCommunication;
using HslCommunication.ModBus;
using HslCommunication.MQTT;
using HslCommunication.Profinet.Melsec;
using HslCommunication.Profinet.Siemens;

namespace ConsoleApp1
{
	internal class Program
	{
		static void Main( string[] args )
		{
			MqttServer server;
			MelsecMcNet melsec;
			SiemensS7Net siemens;
			ModbusRtu modbus;

			melsec = new MelsecMcNet( "118.24.36.220", 6000 );                // ip及端口需要改成你自己实际的参数
			melsec.SetPersistentConnection( );

			siemens = new SiemensS7Net( SiemensPLCS.S1200, "118.24.36.220" ); // ip需要改成你自己实际的参数
			siemens.SetPersistentConnection( );

			modbus = new ModbusRtu( 1 );                                      // 指定站号实例化
			modbus.SerialPortInni( "COM2", 9600 );                            // 初始化串口信息
			modbus.DataFormat = HslCommunication.Core.DataFormat.CDAB;        // 根据实际情况设置

			server = new MqttServer( );
			server.ClientVerification += Server_ClientVerification;           // 启动账户密码,如果不需要验证,则注释即可

			server.RegisterMqttRpcApi( "MelsecPLC", melsec );                 // API分类随便写,方便客户端指定就行,需要唯一
			server.RegisterMqttRpcApi( "SiemensPLC", siemens );               // API分类随便写,方便客户端指定就行,需要唯一
			server.RegisterMqttRpcApi( "Modbus", modbus );                    // API分类随便写,方便客户端指定就行,需要唯一

			server.ServerStart( 1883 );                                       // 启动服务
			Console.WriteLine( "已经启动" );
			Console.ReadLine( );
		}

		private static int Server_ClientVerification( MqttSession mqttSession, string clientId, string userName, string passwrod )
		{
			// 这里举例只能账户密码登录
			// if (userName == "admin" && passwrod == "123456") return 0;
			// else return 1;

			//不校验用户名密码
			return 0;
		}
	}
}

  

 我们假设了三种设备需要远程访问的操作。服务器端的代码已经写好了,这时候,这个PLC已经支持从外部直接读写数据了。

 

 

 大致的架构如图所示:

现在我们可以使用客户端来测试是否可以成功访问了,如果端口拒绝连接,则需要检查防火墙是否端口隔离了。

 

我们先打开hslcommunicationdemo测试:如果没有demo的话,从这里下载:http://www.hsltechnology.cn/Home/Download

 

 

 

在这里,为了支持注册多个PLC的数据。每个实体通信对象需要指定一个唯一的识别码,也就是上面服务器注册的三个数据

  • MelsecPLC
  • SiemensPLC
  • Modbus

 

这个数据在客户端时,为了找到唯一的接口对象,则需要指定。也就是Demo测试界面的 设备主题

当然,如果你设备比较多,设备间又有层级的概念,所以使用分隔符 / 来区分,例如

  • 分厂一/车间A/硫化机A01
  • 分厂一/车间A/硫化机A02
  • 分厂一/车间B/成型机B01

 

我们已经在demo客户端上测试成功。那么我们用代码怎么写呢?

同样是新建一个控制台项目,安装 hslcommunication组件,然后写入代码

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using HslCommunication;
using HslCommunication.Core;
using HslCommunication.LogNet;
using HslCommunication.Profinet.GE;
using HslCommunication.BasicFramework;
using System.IO.Ports;
using HslCommunication.MQTT;

namespace NetFrameworkConsole
{
	class Program
	{
		static void Main( string[] args )
		{
			// 我们接下来在客户端访问当前的数据信息
			MqttRpcDevice rpcMelsec = new MqttRpcDevice( new MqttConnectionOptions( )
			{
				IpAddress = "127.0.0.1",    // 服务器的IP地址
				Port = 1883,
				Credentials = new MqttCredential( "admin", "123456" ),  // 如果配置了用户名密码
				UseRSAProvider = true,                                  // 是否加密通信
			},
				"MelsecPLC" );

			MqttRpcDevice rpcSiemens = new MqttRpcDevice( new MqttConnectionOptions( )
			{
				IpAddress = "127.0.0.1",    // 服务器的IP地址
				Port = 1883,
				Credentials = new MqttCredential( "admin", "123456" ),  // 如果配置了用户名密码
				UseRSAProvider = true,                                  // 是否加密通信
			},
				"SiemensPLC" );

			MqttRpcDevice rpcModbus = new MqttRpcDevice( new MqttConnectionOptions( )
			{
				IpAddress = "127.0.0.1",    // 服务器的IP地址
				Port = 1883,
				Credentials = new MqttCredential( "admin", "123456" ),  // 如果配置了用户名密码
				UseRSAProvider = true,                                  // 是否加密通信
			},
				"Modbus" );

			// 就可以进行读取了,例如读取三菱设备的D100的short值
			OperateResult write1 = rpcMelsec.Write( "D100", (short)123 );
			OperateResult<short> read1 = rpcMelsec.ReadInt16( "D100" );
			Console.WriteLine( "Read Value1 D100: " + read1.Content );

			// 例如读取西门设备的float值
			OperateResult write2 = rpcSiemens.Write( "M100", 1.23f );
			OperateResult<float> read2 = rpcSiemens.ReadFloat( "M100" );
			Console.WriteLine( "Read Value2 M100: " + read2.Content );

			// Modbus设备读取int值
			OperateResult write3 = rpcModbus.Write( "100", 123 );
			OperateResult<int> read3 = rpcModbus.ReadInt32( "100" );
			Console.WriteLine( "Read Value3 100: " + read3.Content );

			// 用法上和普通的三菱,西门子,modbus是没有区别的。
		}
	}
}

  

我们运行它

 

 

嗯,非常好。对客户端来说,支持多个设备的实例化对象,和服务器通信时,对于同一个PLC连接而言,内部会自动加锁通信。

所以这种情况不太适合,很多客户端同时频繁读写PLC,大数据的时候,读取的地址也是一样的。这种情况下,适合服务器先采集PLC数据,自动推送到所有的客户端,这样性能可以差很多。

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using HslCommunication;
using HslCommunication.ModBus;
using HslCommunication.MQTT;
using HslCommunication.Profinet.Melsec;
using HslCommunication.Profinet.Siemens;

namespace ConsoleApp1
{
	internal class Program
	{
		static void Main( string[] args )
		{
			MqttServer server;
			MelsecMcNet melsec;
			SiemensS7Net siemens;
			ModbusRtu modbus;

			melsec = new MelsecMcNet( "118.24.36.220", 6000 );                // ip及端口需要改成你自己实际的参数
			melsec.SetPersistentConnection( );

			siemens = new SiemensS7Net( SiemensPLCS.S1200, "118.24.36.220" ); // ip需要改成你自己实际的参数
			siemens.SetPersistentConnection( );

			modbus = new ModbusRtu( 1 );                                      // 指定站号实例化
			modbus.SerialPortInni( "COM2", 9600 );                            // 初始化串口信息
			modbus.DataFormat = HslCommunication.Core.DataFormat.CDAB;        // 根据实际情况设置

			server = new MqttServer( );
			server.ClientVerification += Server_ClientVerification;           // 启动账户密码,如果不需要验证,则注释即可

			server.RegisterMqttRpcApi( "MelsecPLC", melsec );                 // API分类随便写,方便客户端指定就行,需要唯一
			server.RegisterMqttRpcApi( "SiemensPLC", siemens );               // API分类随便写,方便客户端指定就行,需要唯一
			server.RegisterMqttRpcApi( "Modbus", modbus );                    // API分类随便写,方便客户端指定就行,需要唯一

			server.ServerStart( 1883 );                                       // 启动服务
			Console.WriteLine( "已经启动" );

			while (true)
			{
				Thread.Sleep( 1000 );

				// 读取PLC的数据,并且把数据分发出去
				OperateResult<short> read1 = melsec.ReadInt16( "D100" );
				if (read1.IsSuccess)
				{
					// 这里的topic没有什么规则,都是自己设定的,注意不和其他数据冲突就行
					server.PublishTopicPayload( "MelsecPLC.A", Encoding.UTF8.GetBytes( read1.Content.ToString( ) ) );

					Console.WriteLine( DateTime.Now.ToString( ) + " success! " );
				}
				else
				{
					Console.WriteLine( DateTime.Now.ToString( ) + " failed: " + read1.Message );
				}
			}
		}

		private static int Server_ClientVerification( MqttSession mqttSession, string clientId, string userName, string passwrod )
		{
			// 这里举例只能账户密码登录
			// if (userName == "admin" && passwrod == "123456") return 0;
			// else return 1;

			//不校验用户名密码
			return 0;
		}
	}
}

新增加的代码就是

			while (true)
			{
				Thread.Sleep( 1000 );

				// 读取PLC的数据,并且把数据分发出去
				OperateResult<short> read1 = melsec.ReadInt16( "D100" );
				if (read1.IsSuccess)
				{
					// 这里的topic没有什么规则,都是自己设定的,注意不和其他数据冲突就行
					server.PublishTopicPayload( "MelsecPLC.A", Encoding.UTF8.GetBytes( read1.Content.ToString( ) ) );

					Console.WriteLine( DateTime.Now.ToString( ) + " success! " );
				}
				else
				{
					Console.WriteLine( DateTime.Now.ToString( ) + " failed: " + read1.Message );
				}
			}

  

运行之后的效果:

 

 

 

我们只需要打开hslcommunication的demo,测试mqtt即可。

 

 

实际可以根据情况再进行针对性的优化操作。

 

如果还有什么问题,可以通过最上方的连接找到作者。

 

标签:HslCommunication,System,server,PLC,new,using,权限,连接
From: https://www.cnblogs.com/dathlin/p/16632767.html

相关文章

  • 通过自定义指令对button进行权限的校验
    通过自定义指令对button进行权限的校验场景:左侧菜单栏通过调接口获取,每一个菜单下的还有该菜单下的button的权限操作,在mentType为2时,该children就是button权限列表1.先获......
  • 启动HDFS伪分布式环境时报权限错误
    问题描述操作系统:Ubuntu18.04LTSHDFS版本:hadoop-3.2.3普通用户登录,参照官方文档在单机上安装伪分布式环境时,启动HDFS报权限错误。具体报错信息如下:$./sbin/start-df......
  • koa连接mysql数据库
    app.js中的代码:constKoa=require('koa2');constapp=newKoa();constport=5050;constRouter=require('koa-router');constrouter=newRouter();cons......
  • c# linq 左连接
    vartodayFinish=ds.Tables[0].AsEnumerable();varlistTodayFinish=todayFinish.Select(p=>newTodayFinishRate......
  • RabbitMQ web管理页面正常访问,但是使用程序连接被拒绝
    软件版本Windowsserver2012R2 RabbitMQ版本3.6.14erlang版本20.3问题描述按照安装教程安装后,web管理页面可以正常访问,也可以设置新用户及其权限,端口监听显示正常。......
  • TP5框架 之连接其他数据库配置
    一、代码/***@throws\think\Exception*/protectedfunctiongetDb(){if(!$this->my_db){$this->my_db=Db::connect(config('db2'));}}co......
  • java 连接 redis
    Jedis导入对应的依赖<dependencies><!--jedis--><dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId>......
  • 西门子SmartPLC自由口通讯封装兼容Modbus_可自定义报文格式
    最近一直在用西门子SmartPLC,由于项目需求自定义协议,为了数据的准确性用了CRC校验,模块兼容Modbus_RTU,自定义报文格式。此模块主要用的是SmartPLC,指针类型,通过寻......
  • Mysql----外连接,约束
    《外连接》这个外连接其实就是解决多张表笛卡尔集的问题:比如:    我有如上两张表,我想要显示出全部学生的成绩,没有成绩的同学默认成绩为NULL按照以前的方法,要将......
  • 一台服务器最大并发 tcp 连接数多少?65535?
    转载:https://www.jianshu.com/p/0154dff4be77首先,问题中描述的65535个连接指的是客户端连接数的限制。在tcp应用中,server事先在某个固定端口监听,client主动发起连接,经......