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. 【VS开发】【图像处理】直方图均衡与平台直方图

    目录(?)[-] 直方图均衡化Histogram Equalization 直方图均衡化的主要过程 一个简单的例子 关键的代码实现 平台直方图及均衡化 平台直方图的概念 平台阈值的确定 关键代码实现 ...

  2. HDU 1260 Tickets (动态规划)

    Tickets Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Sub ...

  3. Elasticsearch-日期类型

    Elasticsearch-日期类型 date类型用于存储日期和时间.它是这样运作的:通常提供一个表示日期的字符串,例如2019-06-25T22:47.然后,ES解析这个字符串,然后将其作为long ...

  4. std::tr1::function和bind组件

    C++中std::tr1::function和bind 组件的使用 在C++的TR1中(Technology Report)中包含一个function模板类和bind模板函数,使用它们可以实现类似函数 ...

  5. Thinkphp5.0快速入门笔记(3)

    学习来源与说明 https://www.kancloud.cn/thinkphp/thinkphp5_quickstart 测试与部署均在windows10下进行学习. 快速入门第三节 获取当前的请求 ...

  6. eclipse 保存web.xml 和 loading description from 问题的解决

    Eclipse 版本为 2019-06 (4.12.0) 发现开启的时候一直有loading description from ***  ,这个loading description 是web项目加载 ...

  7. 编写 Bash 补全脚本

    编写 Bash 补全脚本   对于Linuxer来说,自动补全是再熟悉不过的一个功能了.当你在命令行敲下部分的命令时,肯定会本能地按下Tab键补全完整的命令,当然除了命令补全之外,还有文件名补全. B ...

  8. 客户端相关知识学习(四)之H5页面如何嵌套到APP中

    Android原生如何渲染H5页面 Android与 H5 的交互方式大概有以下 1 种: 利用WebView进行交互(系统API) iOS原生如何渲染H5页面 iOS 与 H5 的交互方式大概有以下 ...

  9. @RequestMapping-占位符映射

    占位符映射

  10. js文件的框架

    Ext.define("BeidaSoft.SFJCGL.rcjwgl.bdgl.BdglGrid", { extend : "BeidaSoft.XTGL.base.Q ...