aardio调用HslCommunication.dll实现工业自动化通信研究学习

By 笑口常 at 2021-07-24 • 3人收藏 • 1717人看过

HslCommunication 专注于底层的技术通信及跨平台,由C#语言编写的dll类库, 可实现各种主流的PLC数据读写,实现modbus,机器人的各种协议读写等等 ,  提供统一接口 , 程序人员只需要关注读写内容即可 . 

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

官方文档: http://api.hslcommunication.cn/html/c136d3de-eab7-9b0f-4bdf-d891297c8018.htm


HslCommunication.zip


目前支持多家设备和仪器,列表如下:

image.png


13 个回复 | 最后更新于 2022-09-26
2021-07-24   #1

日志的读写测试:

image.png

//调用C#程序集 
import dotNet; 
var appDomain = dotNet.clr().createAppDomain();
//加载应用程序目录下的程序集
var HSIdll = appDomain.loadFile("\res\HslCommunication.dll");
//声明接口
var logNet = HSIdll.new("HslCommunication.LogNet.LogNetSingle","C:\Users\Administrator\Desktop\HSICOM\aardio工程15\log\123.txt");

logNet.WriteDebug( "Debug log test" );
logNet.WriteInfo( "Info log test" );
logNet.WriteWarn( "Warn log test" );
logNet.WriteError( "Error log test" );
logNet.WriteFatal( "Fatal log test" );

// 还有下面的几种额外的情况
logNet.WriteNewLine( );                       // 追加一行空行
logNet.WriteDescrition( "test" );             // 写入额外的注释的信息
logNet.WriteAnyString( "any string" );        // 写任意的数据,不受格式化影响

// 此处的5个等级有高低之分 debug < info < warn < error < fatal < all
// 如果我们需要屏蔽debug等级的话
logNet.SetMessageDegree( HSIdll.getEnum("HslCommunication.LogNet.HslMessageDegree.INFO") );

// 如果我们需要屏蔽debug及info等级的
logNet.SetMessageDegree( HSIdll.getEnum("HslCommunication.LogNet.HslMessageDegree.WARN") );

// 带关键字的功能
logNet.WriteDebug( "A","Debug log test" );
logNet.WriteInfo( "B", "Info log test" );
logNet.WriteWarn( "C", "Warn log test" );
logNet.WriteError( "A", "Error log test" );
logNet.WriteFatal( "B", "Fatal log test" );

// 有了关键字之后,我们就可以根据关键字过滤了
logNet.FiltrateKeyword( "B" ); // 我们不需要B的关键字的日志
logNet.RemoveFiltrate( "B" );  // 重新需要B的关键字的日志


2021-07-24   #2

以三菱PLC为例子 , 其他的plc调用方式基本是一模一样的,就是调用的类不一样,参数配置不一样而已。以下的逻辑都是适用的.

很遗憾, 我这边没有PLC测试, 也没有去安装PLC虚拟机 , 如果你有的话可以测试下.


image.png

//调用C#程序集 
import dotNet; 
var appDomain = dotNet.clr().createAppDomain();
//加载应用程序目录下的程序集
var HSIdll = appDomain.loadFile("\res\HslCommunication.dll");
//声明接口 , 地址和端口号
var melsecMc = HSIdll.new("HslCommunication.Profinet.Melsec.MelsecMcNet", "192.168.1.110", 6000);
//连接服务器
var connect = melsecMc.ConnectServer( );
//判断是否成功
if (!connect.IsSuccess)
{
    console.log( "connect failed:" + connect.Message );
}else {
	console.log( "connect success!");
}

// 举例读取D100的值
var D100 = melsecMc.ReadInt16( "D100" ).Content;
console.log("D100",D100);

// 实际上所有的读写都是返回是否成功的标记的,在实际的开发中,需要严格的判定,怎么判定呢?如下的代码
var readD100 = melsecMc.ReadInt16( "D100" );
if (readD100.IsSuccess)
{
    // 读取成功,这时候获取Content才是正确的值
    var value = readD100.Content;
    console.log("readD100",readD100);
}
else
{
    // 读取失败,如果仍然坚持去获取Content的值,就为0
}

// 读写是否成功的情况,应用于几乎所有的读写代码,只要看清楚返回的数据类型即可
melsecMc.ConnectClose( );


2021-07-24   #3

modbus的例子:

image.png

//调用C#程序集 
import dotNet; 
var appDomain = dotNet.clr().createAppDomain();
//加载应用程序目录下的程序集
var HSIdll = appDomain.loadFile("\res\HslCommunication.dll");
//声明接口 , 参数: 站号
var BusRtuClient = HSIdll.new("HslCommunication.ModBus.ModbusRtu",com.Variant(1,0x11/*_VT_UI1*/));



mainForm.button.oncommand = function(id,event){
	BusRtuClient.SerialPortInni( "COM1",9600 );
	BusRtuClient.Open( ); // 打开
}

mainForm.button2.oncommand = function(id,event){
        //从100寄存器读取一个int32数据
	var short100 = BusRtuClient.ReadInt32("100").Content; // 读取寄存器100的short值
	console.log("short100",short100);
}

mainForm.button3.oncommand = function(id,event){
        //向寄存器100里面写入uint16类型的数据
	BusRtuClient.Write("100", com.Variant((tonumber(mainForm.edit.text)),0x12/*_VT_UI2*/) );// 写入寄存器100为12345
}

mainForm.button4.oncommand = function(id,event){
	BusRtuClient.Close( );	
}


这里需要特别注意: BusRtuClient.SerialPortInni( "COM1",9600 );其实可以有多个参数

BusRtuClient.Write("100", 123 );的第二个参数传过去后会变成 int32 , , 那么如果是其他参数类型, 那么就需要用

com.Variant(2,0x12/*_VT_UI2*/)

或者 用新版aardio的

com.Uint16(2);

image.png

来定义Uint16类型, 其他的依次类推.

数组的话, 用

com.SafeArray(3/*_VT_I4*/,12,34,56)

或者 新版aardio的 , 

com.int32({12,34,56})

来定义三个int32类型数组.


于是, 我们测试下读取两个uint16数据:

mainForm.button2.oncommand = function(id,event){
	var short100 = BusRtuClient.ReadInt16("100",com.Variant(2,0x12/*_VT_UI2*/)).Content; // 读取寄存器100的short值
	console.dump("short100",short100);
}

image.png

2021-07-25   #4

,之前看到也看到过这个,本来想用它WinTcpS7_Smart.dll使用西门子smartPLC通讯的,有站主的这个就准备抄代码了

2021-07-26   #5

等我抽空把这个HSI写个调用库,回报aardio

2021-07-28   #6

2021-08-06   #7

期待你的库,最近也在研究HslCommunication.dll


2021-09-20   #8

好期待...以后工作轻松多了

2022-09-25   #9
using System;
using System.Text;
using System.Threading;
using HslCommunication;
using HslCommunication.MQTT;

namespace MqttTestClient
{
    class Program
    {
        static void Main(string[] args)
        {
            MyClass mc = new MyClass();
            mc.Start();

            mc.Connect();//连接
            mc.Regist();//注册

            Console.WriteLine("输入“send”发送消息");
            string s = Console.ReadLine();
            if (s == "send")
            {
                Console.WriteLine("我发送成功了");
                mc.SendMsg();
            }

            Console.ReadLine();
        }

        public class MyClass
        {
            private MqttClient mqttClient = null;
            public void Start()
            {
                mqttClient = new MqttClient(new MqttConnectionOptions()
                {
                    ClientId = "ABC",
                    IpAddress = "127.0.0.1",
                    Port = 6666,
                    Credentials = new MqttCredential("admin", "admin"),   // 设置了用户名和密码
                });
            }

            public void Connect()
            {
                // 连接
                OperateResult connect = mqttClient.ConnectServer();
                if (connect.IsSuccess)
                {
                    Console.WriteLine("Success");
                }
                else
                {
                    Console.WriteLine("Failed");
                }
            }

            public void SendMsg()
            {
                // 测试发布
                mqttClient.PublishMessage(new MqttApplicationMessage()
                {
                    Topic = "A",                                                      // 主题
                    QualityOfServiceLevel = MqttQualityOfServiceLevel.AtMostOnce,     // 消息等级
                    Payload = Encoding.UTF8.GetBytes("This is test message!"),        // 数据
                    Retain = false,                                                   // 是否保留
                });
            }

            public void Regist()
            {
                // 订阅测试,在label1上显示结果
                mqttClient.OnMqttMessageReceived += MqttClient_OnMqttMessageReceived; // 调用一次即可
                mqttClient.SubscribeMessage("A");     // 订阅A的主题
            }

            private void MqttClient_OnMqttMessageReceived(string topic, byte[] payload)
            {          //topic是主题名字。payload是消息内容;
                Console.WriteLine("我收到了消息了");
                string s = Encoding.UTF8.GetString(payload);
                Console.WriteLine(s);
            }
        }
    }
}

这是个mqtt客户端,但是处理 

mqttClient.OnMqttMessageReceived += MqttClient_OnMqttMessageReceived; // 调用一次即可

总是报错,不知道怎么写了,现在连接成功,就是不知道如何输出消息,请求高手能指点下不


import console; 
//调用C#程序集 
import dotNet; 
var appDomain = dotNet.clr().createAppDomain();
//加载应用程序目录下的程序集
var HSIdll = appDomain.loadFile("\res\HslCommunication.dll");

 var options=  HSIdll.new("HslCommunication.MQTT.MqttConnectionOptions");
             
options.CleanSession = false; 
options.IpAddress="127.0.0.1";  
options.Port=1883;  
options.ClientId="abc123";  
 var mqttClient= HSIdll.new("HslCommunication.MQTT.MqttClient",options);
     
     
    mqttClient.OnMqttMessageReceived = MqttClient_OnMqttMessageReceived;  // 绑定事件显示总是报错 
     
//连接服务器
  var connect =   mqttClient.ConnectServer();
//判断是否成功
if (!connect.IsSuccess)
{
    console.log( "connect failed:" + connect.Message );
}else {
    console.log( "connect success!");
}


var sub = mqttClient.SubscribeMessage( "/Pub" );

if (sub.IsSuccess)
{
	
	 
      console.log( "订阅"++ sub.Message );
}
else
{
    console.log( "connect failed:" + sub.Message );
} 


mqttClient.OnMqttMessageReceived=function(topic,payload) begin

 
    Console.log( "Topic:" + topic );

end;


console.pause(true);


2022-09-25   #10

回复#9 @你又变了 :

干嘛要加绑定事件那句?

aar里事件直接用就可以了, 

你去其他帖子里看看,人家的事件是怎么调用的, 不都是直接使用嘛.......... ,

所以删掉你疑惑的那句就可以了

2022-09-25   #11

直接用事件没有数据回掉,但是程序也没有报错,看API,好像有个委托函数

public delegate void MqttMessageReceiveDelegate(
	MqttClient client,
	string topic,
	byte[] payload
)
public event MqttClient.MqttMessageReceiveDelegate OnMqttMessageReceived


基础不太好,实在是搞不出来了,估计其他使用MQTT客户端的朋友,也许会用到吧,我研究到这里真的搞不下去了。


2022-09-26   #12

回复#11 @你又变了 :

image.png


实测可以收到, 是你自己代码写的有问题,  都说了让你删掉那句你纠结的...... , 另外回调参数有三个 .... , 为什么有三个参数你楼上自己函数原型都写出来了

image.png

import win.ui;
/*DSG{{*/
var winform = win.form(text="aardio mqtt";right=354;bottom=190)
winform.add()
/*}}*/

import console; 
console.open()

//调用C#程序集 
import dotNet; 
//加载应用程序目录下的程序集
var HSIdll = dotNet.load("\HslCommunication.dll");
var options = HSIdll.new("HslCommunication.MQTT.MqttConnectionOptions");
              
options.CleanSession = false; 
options.IpAddress="127.0.0.1";  
options.Port=1883;  
options.ClientId="abc123";  
var mqttClient= HSIdll.new("HslCommunication.MQTT.MqttClient",options);
  
//连接服务器
var connect =   mqttClient.ConnectServer();
//判断是否成功
if (!connect.IsSuccess)
{
    console.log( "connect failed:" + connect.Message );
}else {
    console.log( "connect success!");
}

mqttClient.OnMqttMessageReceived=function(client,topic,payload){
    console.log("client:",client.ToString())
	console.log("topic:",topic)
	console.log("payload:",payload)
}

winform.show();
win.loopMessage();


2022-09-26   #13

@admin 感谢!!!确实可以了,我之前没出来数据是因为没有套界面(win.loopMessage),可能习惯在golang或者python中没有win ui界面,做成服务模式。暂时不清楚数据量大的时候会不会卡界面。

登录后方可回帖

登 录
信息栏
公 告:

专注分享

谢绝纯提问

谢谢合作!
本站域名:HtmLayout.Cn
aardio可以快速开发上位机,本站主要记录了学习过程中遇到的问题和解决办法及aardio代码分享

这里主要专注于aardio学习交流和经验分享.
纯私人站,当笔记本用的,学到哪写到哪.

Aardio 官方站:Aardio官方
Aardio最新功能:Aardio官方更新日志
本 站 主 站:Stm32cube中文网
Sciter中文在线文档Sciter在线学习文档
空间赞助:才仁机械
打赏本站
Loading...