C#实现上位机与欧姆龙PLC通讯(FINS)
c#实现上位机与欧姆龙plc通讯(fins)
先介绍下一些基本定义
串行通信:通过的是plc上的串行口rs232/rs422/485口,上位机链接系统 hostlink系统是对于fa系统一种及优化有经济的通信方式。
适用于一台上位机与一台或者多台的plc进行数据通信。
通讯协议分两种
1:c-mode commands
只可以通过串口进行通讯
2:fins commands
既可以通过串口通讯也可以通过各类网络通讯(适应性较强)
本文只介绍fins通讯
fins (factory in terfave network service) 通讯协议是欧姆龙公司开发的一款自动化控制网络指令/响应系统的通讯协议;运用fins指令可实现各种网络间的无缝通信
fins帧结构
- 发送命令结构 命令码2个字节
- 响应命令结构 命令码2个字节
- 命令码 01 01读数据
- 命令码 01 02写数据
- 结束码 00 00无错误
1、获取plc节点地址
上位机和plc建立tcp通讯之后,可以发送以下命令来获得plc的节点地址;
帧结构见下表:
| 列表 | content(十六进制) | description(说明) |
|---|---|---|
| 头 | 46 49 4e 53 | ascii分别代表的是 f i n s |
| 长度 | 00 00 00 0c | 从command之后的数据包的长度 |
| 错误代码 | 00 00 00 00 | 目前暂时没用,因为在服务器不需要检测内部错误 |
| 连接的节点地址 | 00000000~000000fe | 分别是0~254,当设置为0时表示自动获取客户端的fins节点地址 |
2、命令码介绍
详细内容说明介绍见下表:
| 命令内容 | 命令代码(mr sr) | 说明 | 功能 |
|---|---|---|---|
| 访问i/o存储区 | 01 01 | 读内存区 | 读连续i/o存储区字的内容 |
| 访问i/o存储区 | 01 02 | 写内存区 | 写连续i/o存储区字的内容 |
| 访问i/o存储区 | 01 03 | 填充内存区 | 将相同的数据写入指定范围的i/o存储器区 |
| 访问i/o存储区 | 01 04 | 多个存储区读取 | 读取指定的非连续i/o存储区字 |
| 访问i/o存储区 | 01 05 | 存储区传输 | 将连续存储i/o存储区字内容复制到另外的i/o存储区 |
| 访问参数区 | 02 01 | 读取参数区 | 读取连续参数区字内容 |
| 访问参数区 | 02 02 | 写入参数区 | 写入连续参数区字内容 |
| 访问参数区 | 02 03 | 填充参数区 | 将相同数据写入到指定范围参数区域字 |
| 改变操作模式 | 04 01 | 设置cpu操作模式为run | 将cpu单元的操作模式更改为run或monitor |
| 改变操作模式 | 04 02 | 设置cpu操作模式为stop | 将cpu单元的操作模式更改为编程 |
| 改变操作模式 | 06 01 | 读取cpu单元状态 | 读取cpu单元状态 |
| 错误日志 | 21 01 | 错误清除 | 清除错误或错误信息 |
| 错误日志 | 21 02 | 读取错误日志 | 读取错误日志 |
| 错误日志 | 21 03 | 清除错误日志 | 清除错误日志指针 |
3、i / o存储器地址标识
| 区域 | 数据类型 | 存储区代码 | 存储区地址范围 | 存储地址 | 字节长度 |
|---|---|---|---|---|---|
| dm | bit | 02 | d0000000到d3276715 | 000000到7fff0f | 1 |
| dm | word | 82 | d00000到d32767 | 000000到7fff00 | 2 |
鉴于我们在和plc通讯时,一般只需要进行读取dm区寄存器操作,因为本文只介绍读取和写入dm区寄存器。其他的有需要的童鞋进行自己功能拓展。
举例:
读取dm区地址100,连续10个地址的数据
发送命令:010182006400000a
返回命令:010100000102030405060708090a
发送的命令进行说明:
- 1、01 01代表功能码,读连续i/o存储区字的内容
- 2、82代表进行字操作
- 3、00 64转成十进制就是100代表的是我们要读取的起始地址
- 4、00000a转成十进制就是10代表的是我们要读取得长度
响应的命令说明
- 1、01 01代表功能码,读连续i/o存储区字的内容
- 2、00 00代表结束码,当不是00 00的时候表明数据帧不对
- 3、01 02 03 04 05 06 07 08 09 0a分别代表要读取的十个寄存器的数据值
具体协议可以查看百度文库:欧姆龙fins通讯协议
综上,结合之前的博客,c#socket客户端:c#socket客户端我们可以整合得到一个欧姆龙fins的类,如下所示:
using system;
using system.collections.generic;
using system.text;
using system.net;
using system.net.sockets;
using system.threading;
namespace omrentfins
{
public class omronfins
{
/// <summary>
/// 客户端连接socket
/// </summary>
private socket clientsocket;
/// <summary>
/// 连接状态
/// </summary>
public boolean connected = false;
/// <summary>
/// 发送数据
/// </summary>
private byte[] sendmess;
/// <summary>
/// 连接点
/// </summary>
private ipendpoint hostendpoint;
/// <summary>
/// 连接信号量
/// </summary>
private static autoresetevent autoconnectevent = new autoresetevent(false);
/// <summary>
/// 接受到数据时的委托
/// </summary>
/// <param name="info"></param>
public delegate void receivemsghandler(byte[] info);
/// <summary>
/// 接收到数据时调用的事件
/// </summary>
public event receivemsghandler onmsgreceived;
/// <summary>
/// 开始监听数据的委托
/// </summary>
public delegate void startlistenhandler();
/// <summary>
/// 开始监听数据的事件
/// </summary>
public event startlistenhandler startlistenthread;
/// <summary>
/// 发送信息完成的委托
/// </summary>
/// <param name="successorfalse"></param>
public delegate void sendcompleted(bool successorfalse);
/// <summary>
/// 发送信息完成的事件
/// </summary>
public event sendcompleted onsended;
/// <summary>
/// 监听接收的socketasynceventargs
/// </summary>
private socketasynceventargs listenersocketasynceventargs;
int plcport;
public omronfins(string hostname, int32 port, int32 plcstaion)
{
plcport = plcstaion;
ipaddress[] addresslist = dns.gethostaddresses(hostname);
this.hostendpoint = new ipendpoint(addresslist[addresslist.length - 1], port);
this.clientsocket = new socket(this.hostendpoint.addressfamily, sockettype.stream, protocoltype.tcp);
}
/// <summary>
/// 连接服务端
/// </summary>
private bool connect()
{
using (socketasynceventargs connectargs = new socketasynceventargs())
{
connectargs.usertoken = this.clientsocket;
connectargs.remoteendpoint = this.hostendpoint;
connectargs.completed += new eventhandler<socketasynceventargs>(onconnect);
clientsocket.connectasync(connectargs);
//等待连接结果
bool autores = autoconnectevent.waitone(1000);
if (this.connected)
{
listenersocketasynceventargs = new socketasynceventargs();
byte[] receivebuffer = new byte[1024];//设置接收buffer区大小
listenersocketasynceventargs.usertoken = clientsocket;
listenersocketasynceventargs.setbuffer(receivebuffer, 0, receivebuffer.length);
listenersocketasynceventargs.completed += new eventhandler<socketasynceventargs>(onreceive);
startlistenthread();
// socketextensions.setkeepalive(clientsocket, 3000, 1000);
return true;
}
else
return false;
}
}
/// <summary>
/// 开始监听线程的入口函数
/// </summary>
private void listen()
{
(listenersocketasynceventargs.usertoken as socket).receiveasync(listenersocketasynceventargs);
}
public static list<socketasynceventargs> s_lst = new list<socketasynceventargs>();
/// <summary>
/// 发送信息
/// </summary>
/// <param name="message"></param>
private void send(byte[] message)
{
if (this.connected)
{
byte[] sendbuffer = message;
socketasynceventargs sendersocketasynceventargs = null;// new socketasynceventargs();
lock (s_lst)
{
if (s_lst.count > 0)
{
sendersocketasynceventargs = s_lst[s_lst.count - 1];
s_lst.removeat(s_lst.count - 1);
}
}
if (sendersocketasynceventargs == null)
{
sendersocketasynceventargs = new socketasynceventargs();
sendersocketasynceventargs.usertoken = this.clientsocket;
sendersocketasynceventargs.remoteendpoint = this.hostendpoint;
sendersocketasynceventargs.completed += (object sender, socketasynceventargs _e) =>
{
lock (s_lst)
{
s_lst.add(sendersocketasynceventargs);
}
};
}
sendersocketasynceventargs.setbuffer(sendbuffer, 0, sendbuffer.length);
clientsocket.sendasync(sendersocketasynceventargs);
}
else
{
this.connected = false;
}
sendmess = message;
}
/// <summary>
/// 断开连接
/// </summary>
private bool disconnect()
{
bool returndis = true;
try
{
this.clientsocket.shutdown(socketshutdown.both);
this.clientsocket.close();
//this.clientsocket.dispose();
//clientsocket.disconnect(true);
//clientsocket.disconnect(false);
}
catch (exception)
{
returndis = false;
}
finally
{
}
this.connected = false;
return returndis;
}
/// <summary>
/// 连接的完成方法
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void onconnect(object sender, socketasynceventargs e)
{
this.connected = (e.socketerror == socketerror.success);
autoconnectevent.set();
}
/// <summary>
/// 接收的完成方法
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void onreceive(object sender, socketasynceventargs e)
{
if (e.bytestransferred == 0)
{
//console.writeline("socket is closed", socket.handle);
if (clientsocket.connected)
{
try
{
clientsocket.shutdown(socketshutdown.both);
}
catch (exception)
{
//client already closed
}
finally
{
if (clientsocket.connected)
{
clientsocket.close();
}
}
}
byte[] rs = new byte[0];
onmsgreceived(rs);
this.connected = false;
}
else
{
byte[] buffer = new byte[e.bytestransferred];
for (int i = 0; i < e.bytestransferred; i++)
{
buffer[i] = e.buffer[i];
}
this.onmsgreceived(buffer);
listen();
}
}
/// <summary>
/// 发送的完成方法
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void onsend(object sender, socketasynceventargs e)
{
if (e.socketerror == socketerror.success)
{
onsended(true);
}
else
{
onsended(false);
this.processerror(e);
}
}
/// <summary>
/// 处理错误
/// </summary>
/// <param name="e"></param>
private void processerror(socketasynceventargs e)
{
socket s = e.usertoken as socket;
if (s.connected)
{
try
{
s.shutdown(socketshutdown.both);
}
catch (exception)
{
//client already closed
}
finally
{
if (s.connected)
{
s.close();
}
}
this.connected = false;
}
//throw new socketexception((int32)e.socketerror);
}
#region idisposable members
public void dispose()
{
autoconnectevent.close();
if (this.clientsocket.connected)
{
this.clientsocket.close();
}
}
#endregion
#region 欧姆龙通讯协议
/// <summary>
/// 发送命令反馈
/// </summary>
/// <param name="successorfalse"></param>
void omronfins_onsended(bool successorfalse)
{
if (!successorfalse)
{
}
else
{
}
}
byte pcs;
byte plcs;
int sendorrev;
int sendorrev2;
byte[] sendback;
byte[] recvback;
/// <summary>
/// 接受命令反馈
/// </summary>
/// <param name="info"></param>
void omronfins_onmsgreceived(byte[] info)
{
if (sendmesshas)
{
if (info.length >= 24)
{
if (int.parse(info[23].tostring("x").trim(), system.globalization.numberstyles.hexnumber) == plcport)
{
pcs = info[19];
plcs = info[23];
sendmesshas = false;
}
}
}
else
{
if (info.length > 0)//plc连接错误no
{
if (sendorrev2 == 1)//发送命令
{
sendback = info;
sendorrev2 = 0;
}
else if (sendorrev == 2)//接受命令
{
recvback = info;
sendorrev = 0;
}
}
else
{
if (sendorrev2 == 1)//发送命令
{
sendback = new byte[1];
sendback[0] = 0x00;
sendorrev2 = 0;
}
else if (sendorrev == 2)//接受命令
{
recvback = new byte[1];
recvback[0] = 0x00;
sendorrev = 0;
}
}
}
}
void omronfins_startlistenthread()
{
this.listen();
}
bool sendmesshas = false;
/// <summary>
/// 打开连接
/// </summary>
/// <returns></returns>
public bool openlinkplc()
{
bool ret = false;
this.startlistenthread += new startlistenhandler(omronfins_startlistenthread);
this.onmsgreceived += new receivemsghandler(omronfins_onmsgreceived);
this.onsended += new sendcompleted(omronfins_onsended);
ret = this.connect();
if (ret)
{
sendmesshas = true;
this.send(getpcadress());
int addns = 0;
while (sendmesshas && addns < 500)
{
thread.sleep(2);
addns++;
}
if (addns < 500)
{
ret = true;
}
else
{
ret = false;
}
}
return ret;
}
/// <summary>
/// 关闭连接
/// </summary>
/// <returns></returns>
public bool closelinkplc()
{
return this.disconnect();
}
/// <summary>
/// 写入值(word)
/// </summary>
/// <param name="typeint">起始寄存器地址</param>
/// <param name="numdata">个数</param>
/// <param name="intvalue">值</param>
/// <returns>true,成功;false,失败</returns>
public bool writeplcdata(string typeint, int numdata, ref int[] intvalue)
{
bool sendrerun = false;
if (numdata > 0)
{
byte[] numdata = bitconverter.getbytes(numdata);//use numdata[0] and numdata[1]
byte[] sendmessage = new byte[34 + numdata * 2];
if (gettype(typeint, 0) != 0x00 && address != null && address.length > 1)
{
byte[] getsendfunc = this.setplcvalue(plcs, pcs, gettype(typeint, 0), address[1], address[0], 0x00, numdata[1], numdata[0], numdata);
for (int i = 0; i < 34 + numdata * 2; i++)
{
if (i < 34)
{
sendmessage[i] = getsendfunc[i];
}
else
{
if ((i - 33) % 2 != 0)
{
byte[] buffinvalue = bitconverter.getbytes(intvalue[(i - 33) / 2]);
sendmessage[i] = buffinvalue[1];
}
else
{
byte[] buffinvalue = bitconverter.getbytes(intvalue[(i - 33) / 2 - 1]);
sendmessage[i] = buffinvalue[0];
}
//sendmessage[i]
}
}
sendorrev2 = 1;
this.send(sendmessage);
int outtime = 0;
while (sendorrev2 != 0 && this.connected && outtime < 600)
{
thread.sleep(2);
outtime++;
}
if (outtime < 600 && sendback != null)
{
try
{
//if (sendback.length > 1 && sendback[26] == 0x01 && sendback[27] == 0x02 && sendback[28] == 0x00 && sendback[29] == 0x00)
//{
if (sendback.length > 1 && sendback[26] == 0x01 && sendback[27] == 0x02 && sendback[28] == 0x00)
{
sendrerun = true;
}
else
{
sendrerun = false;
}
}
catch (exception)
{
}
}
else
{
sendorrev2 = 0;
}
}
}
return sendrerun;
}
/// <summary>
/// 读取值(word)
/// </summary>
/// <param name="typeint">起始寄存器地址</param>
/// <param name="numdata">个数</param>
/// <param name="intvalue">值</param>
/// <returns></returns>
public bool readplcdata(string typeint, int numdata, out int[] intvalue)
{
bool getplcret = false;
intvalue = new int[1];
if (numdata > 0)
{
intvalue = new int[numdata];
byte[] numdata = bitconverter.getbytes(numdata);//use numdata[0] and numdata[1]
byte[] recivemessage = new byte[34];
if (gettype(typeint, 0) != 0x00 && address != null && address.length > 1)
{
byte[] getrecivefunc = this.getplcvalue(plcs, pcs, gettype(typeint, 0), address[1], address[0], 0x00, numdata[1], numdata[0]);
this.send(getrecivefunc);
sendorrev = 2;
int outtime = 0;
while (sendorrev != 0 && this.connected && outtime < 600)
{
thread.sleep(2);
outtime++;
}
if (outtime < 600 && recvback != null)
{
try
{
//if (recvback.length > 1 && recvback[26] == 0x01 && recvback[27] == 0x01 && recvback[28] == 0x00 && recvback[29] == 0x00)
if (recvback.length == 30 + numdata * 2 && recvback[26] == 0x01 && recvback[27] == 0x01 && recvback[28] == 0x00)
{
getplcret = true;
for (int i = 0; i < numdata; i++)
{
intvalue[i] = int.parse(recvback[30 + i * 2].tostring("x").padleft(2, '0') + recvback[30 + i * 2 + 1].tostring("x").padleft(2, '0'), system.globalization.numberstyles.hexnumber);
}
}
else
{
getplcret = false;
}
}
catch (exception)
{
}
}
else
{
sendorrev = 0;
}
}
}
return getplcret;
}
/// <summary>
/// 读取值(word)
/// </summary>
/// <param name="typeint">起始寄存器地址</param>
/// <param name="numdata">个数</param>
/// <param name="intvalue">值</param>
/// <returns></returns>
public bool readplcdatacio(string typeint, int numdata, out int[] intvalue)
{
bool getplcret = false;
intvalue = new int[1];
if (numdata > 0)
{
intvalue = new int[numdata];
byte[] numdata = bitconverter.getbytes(numdata);//use numdata[0] and numdata[1]
byte[] recivemessage = new byte[34];
if (gettype(typeint, 0) != 0x00 && address != null && address.length > 1)
{
byte[] getrecivefunc = this.getplcvalue(plcs, pcs, gettype(typeint, 0), address[1], address[0], 0x00, numdata[1], numdata[0]);
this.send(getrecivefunc);
sendorrev = 2;
int outtime = 0;
while (sendorrev != 0 & this.connected & outtime < 800)
{
thread.sleep(2);
outtime++;
}
if (outtime < 800 && recvback != null)
{
//try
//{
//if (recvback.length > 1 && recvback[26] == 0x01 && recvback[27] == 0x01 && recvback[28] == 0x00 && recvback[29] == 0x00)
if (recvback.length > 30 && recvback[26] == 0x01 && recvback[27] == 0x01 && recvback[28] == 0x00)
{
getplcret = true;
for (int i = 0; i < numdata; i++)
{
intvalue[i] = int.parse(recvback[30 + i * 2].tostring("x").padleft(2, '0') + recvback[30 + i * 2 + 1].tostring("x").padleft(2, '0'), system.globalization.numberstyles.hexnumber);
}
}
else
{
getplcret = false;
}
//}
//catch (exception)
//{
//}
}
else
{
sendorrev = 0;
}
}
}
return getplcret;
}
/// <summary>
/// 读取值(bit)
/// </summary>
/// <param name="typeint">起始寄存器地址</param>
/// <param name="intvalue">值</param>
/// <returns></returns>
public bool readplcbitdata(string typeint, out int intvalue)
{
bool getplcret = false;
intvalue = 0;
byte[] recivemessage = new byte[34];
if (gettype(typeint, 1) != 0x00 && address != null && address.length > 1)
{
byte[] getrecivefunc = this.getplcvalue(plcs, pcs, gettype(typeint, 1), address[1], address[0], addressbit[0]);
this.send(getrecivefunc);
sendorrev = 2;
int outtime = 0;
while (sendorrev != 0 & outtime < 600)
{
thread.sleep(2);
outtime++;
}
if (outtime < 600)
{
if (recvback.length > 1 && recvback[26] == 0x01 && recvback[27] == 0x01 && recvback[28] == 0x00 && recvback[29] == 0x00)
{
getplcret = true;
intvalue = int.parse(recvback[30].tostring("x").padleft(2, '0'), system.globalization.numberstyles.hexnumber);
}
}
else
{
sendorrev = 0;
}
}
return getplcret;
}
/// <summary>
/// write值(bit)
/// </summary>
/// <param name="typeint">寄存器地址(ciox.x)</param>
/// <returns></returns>
public bool writebitplcdata(string typeint, int itemvalue)
{
bool sendrerun = false;
byte[] sendmessage = new byte[35];
if (gettype(typeint, 1) != 0x00 && address != null && address.length > 1)
{
byte[] getsendfunc = this.writeplcbitvalue(plcs, pcs, gettype(typeint, 1), address[1], address[0], addressbit[0]);
for (int i = 0; i < 35; i++)
{
if (i < 32)
{
sendmessage[i] = getsendfunc[i];
}
else if (i == 32)
{
sendmessage[i] = 0x00;
}
else if (i == 33)
{
sendmessage[i] = 0x01;
}
else
{
if (itemvalue == 1)
sendmessage[i] = 0x01;
else
sendmessage[i] = 0x00;
}
}
this.send(sendmessage);
sendorrev2 = 1;
int outtime = 0;
while (sendorrev2 != 0 & outtime < 600)
{
thread.sleep(2);
outtime++;
}
if (outtime < 600)
{
if (sendback.length > 1 && sendback[26] == 0x01 && sendback[27] == 0x02 && sendback[28] == 0x00 && sendback[29] == 0x00)
{
sendrerun = true;
}
}
else
{
sendorrev2 = 0;
}
}
return sendrerun;
}
/// <summary>
/// set 值(bit)
/// </summary>
/// <param name="typeint">寄存器地址(ciox.x)</param>
/// <returns></returns>
public bool setplcdata(string typeint)
{
bool sendrerun = false;
byte[] sendmessage = new byte[35];
if (gettype(typeint, 1) != 0x00 && address != null && address.length > 1)
{
byte[] getsendfunc = this.setplcbitvalue(plcs, pcs, gettype(typeint, 1), address[1], address[0], addressbit[0]);
for (int i = 0; i < 35; i++)
{
if (i < 34)
{
sendmessage[i] = getsendfunc[i];
}
else
{
sendmessage[i] = 0x00;
}
}
this.send(sendmessage);
sendorrev2 = 1;
int outtime = 0;
while (sendorrev2 != 0 & outtime < 600)
{
thread.sleep(2);
outtime++;
}
if (outtime < 600)
{
if (sendback.length > 1 && sendback[26] == 0x01 && sendback[27] == 0x02 && sendback[28] == 0x00 && sendback[29] == 0x00)
{
sendrerun = true;
}
}
}
return sendrerun;
}
/// <summary>
/// rest 值(bit)
/// </summary>
/// <param name="typeint">寄存器地址(ciox.x)</param>
/// <returns></returns>
public bool restplcdata(string typeint)
{
bool sendrerun = false;
byte[] sendmessage = new byte[35];
if (gettype(typeint, 1) != 0x00 && address != null && address.length > 1)
{
byte[] getsendfunc = this.rstplcbitvalue(plcs, pcs, gettype(typeint, 1), address[1], address[0], addressbit[0]);
for (int i = 0; i < 35; i++)
{
if (i < 34)
{
sendmessage[i] = getsendfunc[i];
}
else
{
sendmessage[i] = 0x00;
}
}
this.send(sendmessage);
sendorrev2 = 1;
int outtime = 0;
while (sendorrev2 != 0 & outtime < 600)
{
thread.sleep(2);
outtime++;
}
if (outtime < 600)
{
if (sendback.length > 1 && sendback[26] == 0x01 && sendback[27] == 0x02 && sendback[28] == 0x00 && sendback[29] == 0x00)
{
sendrerun = true;
}
}
}
return sendrerun;
}
byte[] address;
byte[] addressbit;
private byte gettype(string typeint, int sizeofint)
{
byte ms = 0x00;
if (typeint.indexof("d") == 0 | typeint.indexof("d") == 0)
{
if (sizeofint == 0)
{
ms = 0x82;
if (typeint.indexof(".") == -1)
address = bitconverter.getbytes(int.parse(typeint.substring(1, typeint.length - 1)));
else
{
address = new byte[1];
addressbit = new byte[1];
}
}
else
{
ms = 0x02;
if (typeint.indexof(".") > 1)
{
address = bitconverter.getbytes(int.parse(typeint.substring(1, typeint.indexof(".") - 1)));
addressbit = bitconverter.getbytes(int.parse(typeint.substring(typeint.indexof(".") + 1, typeint.length - typeint.indexof(".") - 1)));
}
else
{
address = new byte[1];
addressbit = new byte[1];
}
}
}
else if (typeint.indexof("cio") == 0 | typeint.indexof("cio") == 0)
{
if (sizeofint == 0)
{
ms = 0xb0;
if (typeint.indexof(".") == -1)
address = bitconverter.getbytes(int.parse(typeint.substring(3, typeint.length - 3)));
else
{
address = new byte[1];
addressbit = new byte[1];
}
}
else
{
ms = 0x30;
if (typeint.indexof(".") > 3)
{
address = bitconverter.getbytes(int.parse(typeint.substring(3, typeint.indexof(".") - 3)));
addressbit = bitconverter.getbytes(int.parse(typeint.substring(typeint.indexof(".") + 1, typeint.length - typeint.indexof(".") - 1)));
}
else
{
address = new byte[1];
addressbit = new byte[1];
}
}
}
else if (typeint.indexof("w") == 0 | typeint.indexof("w") == 0)
{
if (sizeofint == 0)
{
ms = 0xb1;
if (typeint.indexof(".") == -1)
address = bitconverter.getbytes(int.parse(typeint.substring(1, typeint.length - 1)));
else
{
address = new byte[1];
addressbit = new byte[1];
}
}
else
{
ms = 0x31;
if (typeint.indexof(".") > 1)
{
address = bitconverter.getbytes(int.parse(typeint.substring(1, typeint.indexof(".") - 1)));
addressbit = bitconverter.getbytes(int.parse(typeint.substring(typeint.indexof(".") + 1, typeint.length - typeint.indexof(".") - 1)));
}
else
{
address = new byte[1];
addressbit = new byte[1];
}
}
}
else if (typeint.indexof("h") == 0 | typeint.indexof("h") == 0)
{
if (sizeofint == 0)
{
ms = 0xb2;
if (typeint.indexof(".") == -1)
address = bitconverter.getbytes(int.parse(typeint.substring(1, typeint.length - 1)));
else
{
address = new byte[1];
addressbit = new byte[1];
}
}
else
{
ms = 0x32;
if (typeint.indexof(".") > 1)
{
address = bitconverter.getbytes(int.parse(typeint.substring(1, typeint.indexof(".") - 1)));
addressbit = bitconverter.getbytes(int.parse(typeint.substring(typeint.indexof(".") + 1, typeint.length - typeint.indexof(".") - 1)));
}
else
{
address = new byte[1];
addressbit = new byte[1];
}
}
}
else if (typeint.indexof("a") == 0 | typeint.indexof("a") == 0)
{
if (sizeofint == 0)
{
ms = 0xb3;
if (typeint.indexof(".") == -1)
address = bitconverter.getbytes(int.parse(typeint.substring(1, typeint.length - 1)));
else
{
address = new byte[1];
addressbit = new byte[1];
}
}
else
{
ms = 0x33;
if (typeint.indexof(".") > 1)
{
address = bitconverter.getbytes(int.parse(typeint.substring(1, typeint.indexof(".") - 1)));
addressbit = bitconverter.getbytes(int.parse(typeint.substring(typeint.indexof(".") + 1, typeint.length - typeint.indexof(".") - 1)));
}
else
{
address = new byte[1];
addressbit = new byte[1];
}
}
}
return ms;
}
/// <summary>
/// get plc da1 sna1
/// </summary>
/// <returns></returns>
private byte[] getpcadress()
{
byte[] returngetpc = new byte[20];
returngetpc[0] = 0x46;//f
returngetpc[1] = 0x49;//i
returngetpc[2] = 0x4e;//n
returngetpc[3] = 0x53;//s
returngetpc[4] = 0x00;
returngetpc[5] = 0x00;
returngetpc[6] = 0x00;
returngetpc[7] = 0x0c;
returngetpc[8] = 0x00;
returngetpc[9] = 0x00;
returngetpc[10] = 0x00;
returngetpc[11] = 0x00;
returngetpc[12] = 0x00;
returngetpc[13] = 0x00;
returngetpc[14] = 0x00;
returngetpc[15] = 0x00;
returngetpc[16] = 0x00;
returngetpc[17] = 0x00;
returngetpc[18] = 0x00;
returngetpc[19] = 0x00;
return returngetpc;
}
/// <summary>
/// read word
/// </summary>
/// <param name="da1"></param>
/// <param name="sa1"></param>
/// <param name="datavalue"></param>
/// <param name="address1"></param>
/// <param name="address2"></param>
/// <param name="address3"></param>
/// <param name="datanum1"></param>
/// <param name="datanum2"></param>
/// <returns></returns>
private byte[] getplcvalue(byte da1, byte sa1, byte datavalue, byte address1, byte address2, byte address3, byte datanum1, byte datanum2)
{
byte[] sendfun = new byte[34];
sendfun[0] = 0x46;
sendfun[1] = 0x49;
sendfun[2] = 0x4e;
sendfun[3] = 0x53;
sendfun[4] = 0x00;
sendfun[5] = 0x00;
sendfun[6] = 0x00;
sendfun[7] = 0x1a;
sendfun[8] = 0x00;
sendfun[9] = 0x00;
sendfun[10] = 0x00;
sendfun[11] = 0x02;
sendfun[12] = 0x00;
sendfun[13] = 0x00;
sendfun[14] = 0x00;
sendfun[15] = 0x00;
sendfun[16] = 0x80;
sendfun[17] = 0x00;
sendfun[18] = 0x02;
sendfun[19] = 0x00;
sendfun[20] = da1;
sendfun[21] = 0x00;
sendfun[22] = 0x00;
sendfun[23] = sa1;
sendfun[24] = 0x00;
sendfun[25] = 0x01;
sendfun[26] = 0x01;
sendfun[27] = 0x01;
sendfun[28] = datavalue;
sendfun[29] = address1;
sendfun[30] = address2;
sendfun[31] = address3;
sendfun[32] = datanum1;
sendfun[33] = datanum2;
return sendfun;
}
/// <summary>
/// write word
/// </summary>
/// <param name="da1"></param>
/// <param name="sa1"></param>
/// <param name="datavalue"></param>
/// <param name="address1"></param>
/// <param name="address2"></param>
/// <param name="address3"></param>
/// <param name="datanum1"></param>
/// <param name="datanum2"></param>
/// <returns></returns>
private byte[] setplcvalue(byte da1, byte sa1, byte datavalue, byte address1, byte address2, byte address3, byte datanum1, byte datanum2, int num)
{
byte[] sendfun = new byte[34];
sendfun[0] = 0x46;
sendfun[1] = 0x49;
sendfun[2] = 0x4e;
sendfun[3] = 0x53;
sendfun[4] = 0x00;
sendfun[5] = 0x00;
sendfun[6] = 0x00;
sendfun[7] = (byte)(26 + 2 * num);
sendfun[8] = 0x00;
sendfun[9] = 0x00;
sendfun[10] = 0x00;
sendfun[11] = 0x02;
sendfun[12] = 0x00;
sendfun[13] = 0x00;
sendfun[14] = 0x00;
sendfun[15] = 0x00;
sendfun[16] = 0x80;
sendfun[17] = 0x00;
sendfun[18] = 0x02;
sendfun[19] = 0x00;
sendfun[20] = da1;
sendfun[21] = 0x00;
sendfun[22] = 0x00;
sendfun[23] = sa1;
sendfun[24] = 0x00;
sendfun[25] = 0x01;
sendfun[26] = 0x01;
sendfun[27] = 0x02;
sendfun[28] = datavalue;
sendfun[29] = address1;
sendfun[30] = address2;
sendfun[31] = address3;
sendfun[32] = datanum1;
sendfun[33] = datanum2;
return sendfun;
}
/// <summary>
/// read bit
/// /// </summary>
/// <param name="da1"></param>
/// <param name="sa1"></param>
/// <param name="datavalue"></param>
/// <param name="address1"></param>
/// <param name="address2"></param>
/// <param name="address3"></param>
/// <param name="datanum1"></param>
/// <param name="datanum2"></param>
/// <returns></returns>
private byte[] getplcvalue(byte da1, byte sa1, byte datavalue, byte address1, byte address2, byte address3)
{
byte[] sendfun = new byte[34];
sendfun[0] = 0x46;
sendfun[1] = 0x49;
sendfun[2] = 0x4e;
sendfun[3] = 0x53;
sendfun[4] = 0x00;
sendfun[5] = 0x00;
sendfun[6] = 0x00;
sendfun[7] = 0x1a;
sendfun[8] = 0x00;
sendfun[9] = 0x00;
sendfun[10] = 0x00;
sendfun[11] = 0x02;
sendfun[12] = 0x00;
sendfun[13] = 0x00;
sendfun[14] = 0x00;
sendfun[15] = 0x00;
sendfun[16] = 0x80;
sendfun[17] = 0x00;
sendfun[18] = 0x02;
sendfun[19] = 0x00;
sendfun[20] = da1;
sendfun[21] = 0x00;
sendfun[22] = 0x00;
sendfun[23] = sa1;
sendfun[24] = 0x00;
sendfun[25] = 0x01;
sendfun[26] = 0x01;
sendfun[27] = 0x01;
sendfun[28] = datavalue;
sendfun[29] = address1;
sendfun[30] = address2;
sendfun[31] = address3;
sendfun[32] = 0x00;
sendfun[33] = 0x01;
return sendfun;
}
/// <summary>
/// write bit
/// </summary>
/// <param name="da1"></param>
/// <param name="sa1"></param>
/// <param name="datavalue"></param>
/// <param name="address1"></param>
/// <param name="address2"></param>
/// <param name="address3"></param>
/// <returns></returns>
private byte[] writeplcbitvalue(byte da1, byte sa1, byte datavalue, byte address1, byte address2, byte address3)
{
byte[] sendfun = new byte[32];
sendfun[0] = 0x46;
sendfun[1] = 0x49;
sendfun[2] = 0x4e;
sendfun[3] = 0x53;
sendfun[4] = 0x00;
sendfun[5] = 0x00;
sendfun[6] = 0x00;
sendfun[7] = 0x1b;
sendfun[8] = 0x00;
sendfun[9] = 0x00;
sendfun[10] = 0x00;
sendfun[11] = 0x02;
sendfun[12] = 0x00;
sendfun[13] = 0x00;
sendfun[14] = 0x00;
sendfun[15] = 0x00;
sendfun[16] = 0x80;
sendfun[17] = 0x00;
sendfun[18] = 0x02;
sendfun[19] = 0x00;
sendfun[20] = da1;
sendfun[21] = 0x00;
sendfun[22] = 0x00;
sendfun[23] = sa1;
sendfun[24] = 0x00;
sendfun[25] = 0x01;
sendfun[26] = 0x01;
sendfun[27] = 0x02;
sendfun[28] = datavalue;
sendfun[29] = address1;
sendfun[30] = address2;
sendfun[31] = address3;
return sendfun;
}
/// <summary>
/// set bit
/// </summary>
/// <param name="da1"></param>
/// <param name="sa1"></param>
/// <param name="datavalue"></param>
/// <param name="address1"></param>
/// <param name="address2"></param>
/// <param name="address3"></param>
/// <returns></returns>
private byte[] setplcbitvalue(byte da1, byte sa1, byte datavalue, byte address1, byte address2, byte address3)
{
byte[] sendfun = new byte[35];
sendfun[0] = 0x46;
sendfun[1] = 0x49;
sendfun[2] = 0x4e;
sendfun[3] = 0x53;
sendfun[4] = 0x00;
sendfun[5] = 0x00;
sendfun[6] = 0x00;
sendfun[7] = 0x1b;
sendfun[8] = 0x00;
sendfun[9] = 0x00;
sendfun[10] = 0x00;
sendfun[11] = 0x02;
sendfun[12] = 0x00;
sendfun[13] = 0x00;
sendfun[14] = 0x00;
sendfun[15] = 0x00;
sendfun[16] = 0x80;
sendfun[17] = 0x00;
sendfun[18] = 0x02;
sendfun[19] = 0x00;
sendfun[20] = da1;
sendfun[21] = 0x00;
sendfun[22] = 0x00;
sendfun[23] = sa1;
sendfun[24] = 0x00;
sendfun[25] = 0x01;
sendfun[26] = 0x23;
sendfun[27] = 0x01;
sendfun[28] = 0x01;
sendfun[29] = 0x00;
sendfun[30] = 0x01;
sendfun[31] = datavalue;
sendfun[32] = address1;
sendfun[33] = address2;
sendfun[34] = address3;
return sendfun;
}
/// <summary>
/// rst bit
/// </summary>
/// <param name="da1"></param>
/// <param name="sa1"></param>
/// <param name="datavalue"></param>
/// <param name="address1"></param>
/// <param name="address2"></param>
/// <param name="address3"></param>
/// <returns></returns>
private byte[] rstplcbitvalue(byte da1, byte sa1, byte datavalue, byte address1, byte address2, byte address3)
{
byte[] sendfun = new byte[35];
sendfun[0] = 0x46;
sendfun[1] = 0x49;
sendfun[2] = 0x4e;
sendfun[3] = 0x53;
sendfun[4] = 0x00;
sendfun[5] = 0x00;
sendfun[6] = 0x00;
sendfun[7] = 0x1b;
sendfun[8] = 0x00;
sendfun[9] = 0x00;
sendfun[10] = 0x00;
sendfun[11] = 0x02;
sendfun[12] = 0x00;
sendfun[13] = 0x00;
sendfun[14] = 0x00;
sendfun[15] = 0x00;
sendfun[16] = 0x80;
sendfun[17] = 0x00;
sendfun[18] = 0x02;
sendfun[19] = 0x00;
sendfun[20] = da1;
sendfun[21] = 0x00;
sendfun[22] = 0x00;
sendfun[23] = sa1;
sendfun[24] = 0x00;
sendfun[25] = 0x01;
sendfun[26] = 0x23;
sendfun[27] = 0x01;
sendfun[28] = 0x01;
sendfun[29] = 0x00;
sendfun[30] = 0x00;
sendfun[31] = datavalue;
sendfun[32] = address1;
sendfun[33] = address2;
sendfun[34] = address3;
return sendfun;
}
#endregion
}
}
至此,我们就可以用上述的类和欧姆龙plc进行fins通讯。
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持硕编程。


