using System;
using System.Windows.Forms; using Microsoft.Win32; // for the registry table
using System.Runtime.InteropServices; // for the P/Invoke namespace WindowsApplication1
{
public partial class Form1 : Form
{
private IntPtr _hDmtDll; // handle of a loaded DLL private delegate void DelegateClose(int connNum); // function pointer for disconnection [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
private static extern IntPtr LoadLibrary(string dllPath);
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
private static extern bool FreeLibrary(IntPtr hDll); // 数据相关
[DllImport("DMT.dll", CharSet = CharSet.Auto)]
private static extern int RequestData(int commType, int connNum, int slaveAddr, int funcCode, byte[] sendbuf, int sendlen);
[DllImport("DMT.dll", CharSet = CharSet.Auto)]
private static extern int ResponseData(int commType, int connNum, ref int slaveAddr, ref int funcCode, byte[] recvbuf); // 串口通信
[DllImport("DMT.dll", CharSet = CharSet.Auto)]
private static extern int OpenModbusSerial(int connNum, int baudRate, int dataLen, char parity, int stopBits, int modbusMode);
[DllImport("DMT.dll", CharSet = CharSet.Auto)]
private static extern void CloseSerial(int connNum); public Form1()
{
InitializeComponent();
} private void Form1_Load(object sender, EventArgs e)
{ string path = Environment.CurrentDirectory; path = path.Remove(path.Length - );
path = path.Replace("\\", "\\\\");
path = path.Insert(path.Length, "DMT.dll"); // obtain the relative path where the DMT.dll resides
_hDmtDll = LoadLibrary(path); // explicitly link to DMT.dll
var myRegKey = Registry.LocalMachine.OpenSubKey("HARDWARE\\DEVICEMAP\\SERIALCOMM");
if (myRegKey == null) return;
foreach (var valueName in myRegKey.GetValueNames())
{
ComPort.Items.Add(myRegKey.GetValue(valueName)
.ToString());
}
} private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
FreeLibrary(_hDmtDll);
} private void button1_Click_1(object sender, EventArgs e)
{
string strReq = "";
string strRes = ""; ActStatus.Text = ""; int baud_rate = ;
int data_len = ;
char parity = 'E';
int stop_bits = ;
int modbus_mode = ; // ASCII
int comm_type = ; // RS-232
var connNum = Convert.ToInt32(ComPort.Text.Replace("COM", ""));
DelegateClose closeModbus = CloseSerial; var status = OpenModbusSerial(connNum, baud_rate, data_len, parity, stop_bits, modbus_mode);
if (status == -)
{
ActStatus.Text = @"串口打开失败";
}
byte[] sendbuf = new byte[];
byte[] recvbuf = new byte[];
int modbusAddr = ;
int modbusFunc = ;
int modbusAddrRet = ;
int modbusFuncRet = ;
int sendlen = ;
int i; strReq = ReqData.Text; const string strValid = "0123456789ABCDEF"; if (strReq.Length < )
{
ActStatus.Text = @"长度不够";
closeModbus(connNum);
return;
} if (strReq.Length % != )
{
ActStatus.Text = @"发送数据必须为偶数位";
closeModbus(connNum);
return;
} for (i = ; i < strReq.Length; i++)
{
if (strValid.IndexOf(strReq.ToUpper()[i]) == -)
{
ActStatus.Text = @"包含无效数据";
closeModbus(connNum);
return;
}
} for (i = ; i <= strReq.Length - ; i += ) // 将发送数据放入缓冲区
{
string strConvert = strReq[i] + strReq[i + ].ToString();
if (i == )
modbusAddr = Convert.ToByte(strConvert, );
else if (i == )
modbusFunc = Convert.ToByte(strConvert, );
else
{
sendbuf[sendlen] = Convert.ToByte(strConvert, );
sendlen++;
}
} // 发送数据
int req = RequestData(comm_type, connNum, modbusAddr, modbusFunc, sendbuf, sendlen); // modbus request
if (req == -)
{
ActStatus.Text = @"数据发送失败";
closeModbus(connNum);
return;
} // 接收数据
int res = ResponseData(comm_type, connNum, ref modbusAddrRet, ref modbusFuncRet, recvbuf); // modbus response
if (res > )
{
strRes += modbusAddrRet.ToString("X2");
strRes += modbusFuncRet.ToString("X2"); switch (modbusFuncRet)
{
case 0x01:
case 0x02:
case 0x03:
case 0x04:
case 0x11:
case 0x17:
strRes += res.ToString("X2");
break;
} for (i = ; i < res; i++) // recover a string from recvbuf
{
strRes += recvbuf[i].ToString("X2");
}
ActStatus.Text = @"数据接收完成";
ResData.Text = strRes;
} else
{
ActStatus.Text = @"未接受到数据";
ResData.Text = "";
}
closeModbus(connNum);
}
}
}

PLC与PC通讯的更多相关文章

  1. PC高级语言与施耐德、罗克韦尔、台达等PLC的Modbus通讯源代码(ModbusTCP.DLL/ModbusRTU.DLL)

    1.0  通讯组件概述 该类通讯组件适用于基于PC高级语言的工业自动化控制系统,用于PC与可编程控制器(PLC).智能仪表等进行数据通讯.组件采用动态链接库文件(*.DLL)的形式,在PC系统的项目工 ...

  2. PC-1500与PC通讯

    目录 第1章说明    2 第2章音频通讯    3 2.1 下载    3 2.2 上传    8 2.2.1 操作    8 2.2.2 音量    8 2.3 直接将BASIC代码转换为wav文 ...

  3. Android 手机应用开发经验 之 通过Socket(TCP/IP)与PC通讯

    Android 是一个开源的手机操作系统平台,已经被非常多的开发者视作未来最有潜力的智能手机操作系统.而且,在很短的时间内就在Android Market上出现大量的第三方应用程序,供用户下载与使用, ...

  4. c#上位机与三菱PLC(FX3U)串口通讯

    项目中会经常用到上位机与PLC之间的串口通信,本文介绍一下C#如何编写上位机代码 与三菱FX3U进行通讯 1. 第一种方法是自己写代码实现,主要代码如下: //对PLC的Y7进行置1 byte[] Y ...

  5. (原创)理解主机设备(PLC,PC机)之间的以太网通信

    主机设备:PC机,PLC 网络设备:家用路由器 局域网包括了有线局域网和无线局域网(WIFI).怎么去使用2者? 网络设备的职责最终目的为了帮助2台主机的数据传输.路由器,交换机范围不同,目的相同.在 ...

  6. 台达PLC开发笔记(二):台达PLC设置主机通讯参数为RTU并成功通讯

    前言   前面使用485和网口与台达成功建立通讯,但是485是使用用的ASICC模式,多数情况下是使用RTU模式提升通讯效率.   下载安装台达ISPSoft软件   官网下载地址:https://d ...

  7. C#与西门子PLC通讯

    1.0  通讯组件概述 通讯组件用于PC与可编程控制器(PLC).智能仪表等进行数据通讯,适用于基于PC高级语言的工业自动化控制系统.组件采用动态链接库文件(*.DLL)的形式,在PC系统的项目工程里 ...

  8. Arcgis for Js之加载wms服务

    概述:本节讲述Arcgis for Js加载ArcgisServer和GeoServer发布的wms服务. 1.定义resourceInfo var resourceInfo = { extent: ...

  9. Quartz动态添加,修改,删除任务(暂停,任务状态,恢复,最近触发时间)

    首页 博客 学院 下载 图文课 论坛 APP 问答 商城 VIP会员 活动 招聘 ITeye GitChat 写博客 小程序 消息 登录注册 关闭 quartz_Cron表达式一分钟教程 09-05 ...

随机推荐

  1. sql server第三方产品

    sql server第三方产商工具 双活: 1. Moebius for SQL Server :http://www.grqsh.com/Subpage/product_MoebiusDA.html ...

  2. Python 条件判断 和循环

    使用条件判断 if else # 条件派单 if else print('条件派单 if else') # s = input('请输入生日年号:') # birth = int(s) birth = ...

  3. EM 算法(一)-原理

    讲到 EM 算法就不得不提极大似然估计,我之前讲过,请参考我的博客 下面我用一张图解释极大似然估计和 EM 算法的区别 EM 算法引例1-抛3枚硬币 还是上图中抛硬币的例子,假设最后结果正面记为1,反 ...

  4. Java重要类之LinkedList

    一.ArrayList与LinkedList 基本概念:List是一个接口,Arraylist和LinkedList是它的两个实现类,只是实现的方式不一样.我在“单链表java实现”一文中已经对单链表 ...

  5. C语言No such file or directory错误

    昨天晚上因为这个错误,都没睡好觉 早上六点起来查资料,换了个绝对路径就行了 #include"D:\软工专业\数据结构PPT和作业\实验作业\实验上机\单链表的基本操作\HeadFile.h ...

  6. MySQL性能优化(七):其它优化

    原文:MySQL性能优化(七):其它优化 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/v ...

  7. O007、KVM 存储虚拟化

    参考https://www.cnblogs.com/CloudMan6/p/5273283.html   KVM 的存储虚拟化是通过存储池(Storage Pool) 和 卷(Volume)来管理的. ...

  8. wex5 file文件存储

    在js中需要引入file的cordova包 require("cordova!cordova-plugin-file"); 如果要存到手机的根目录下,在Native文件夹的对应项目 ...

  9. PHP高级进阶之路

    一:常见模式与框架 学习PHP技术体系,设计模式,流行的框架 常见的设计模式,编码必备 Laravel.ThinkPHP开发必不可少的最新框架 YII.Symfony4.1核心源码剖析 二:微服务架构 ...

  10. openCV3 Python编译指南

    这里主要对openCV官网的<Installation in Linux>文档进行了翻译和解释 原文见:https://docs.opencv.org/3.4.1/doc/tutorial ...