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

要明白一个技术,首先要明白它到底是解决什么问题的?你是不是有以下的困扰
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即可。

 

 

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

 

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

 

posted @ 2022-08-28 14:48  dathlin  阅读(11591)  评论(2编辑  收藏  举报