每家PLC厂商都有自己的通讯协议,三菱有MC、倍福有ADS,然而没有统一性的接口协议。
为适应每一家通讯,每一家设备商、MES和工厂等都需要针对每款产品开发相应的通讯接口。
OneConnectAPI为实现统一的接口,去适配每一家厂商的协议。为中国工控行业快速发展而贡献,每一家公司都需要重新制造轮子,这是非常浪费时间和金钱,同时也不能保证稳定性以及持续的维护。
我们采取高效的多线程处理方案,保证极其高效的读写性能,对电脑性能要求极其低,一直进行读写操作,CPU使用率不超过1%(Atom E3940下测试)。
用户可以在一台工控机上进行对上百台的PLC主动读写操作,我们在光伏行业大量应用和测试过。
我们在半导体行业深耕多年,积累大量的经验,实现功能的同时,也需要保证极其严格的稳定性,晶圆生成设备7*24小时不能出任何故障。
下边是我们的接口库以及源代码。
下载地址 金南瓜科技 软件及资料书
https://gitee.com/secsgem/one-api-connect/tree/master/
https://github.com/SECSGEM/Fins


#pragma once
#include
#include “InterfaceExport.h”
#include “ModuleDevelopH.h”

// 欧姆龙Fins协议
class CFins
{
public:
CFins();
virtual ~CFins();

// 参数
CResult SetIP(std::string pIP);             // 设置地址
CResult SetPort(int nPort);             // 设置端口号
CResult SetTimeout(int nTimeMs);        // 设置超时

// 读出
CResult Read(std::string pAddr, char& pData);
CResult Read(std::string pAddr, __int16& pData);
CResult Read(std::string pAddr, __int32& pData);
CResult Read(std::string pAddr, __int64& pData);

CResult Read(std::string pAddr, char* pData, int nSize);
CResult Read(std::string pAddr, __int16* pData, int nSize);
CResult Read(std::string pAddr, __int32* pData, int nSize);
CResult Read(std::string pAddr, __int64* pData, int nSize);

// 写入
CResult Write(std::string pAddr, char& pData);
CResult Write(std::string pAddr, __int16& pData);
CResult Write(std::string pAddr, __int32& pData);
CResult Write(std::string pAddr, __int64& pData);

CResult Write(std::string pAddr, char* pData, __int32 nSize);
CResult Write(std::string pAddr,  __int16* pData, __int32 nSize);
CResult Write(std::string pAddr,  __int32* pData, __int32 nSize);
CResult Write(std::string pAddr,  __int64* pData, __int32 nSize);

private:

CResult SetParament(std::string pName, std::string pValue);
CResult SetParament(std::string pName, int nValue);

private:

CInterfaceExport* m_pFins;
CMgrDllDelegate m_pLoadInterface;

};

#include “stdafx.h”
#include “FinsHandle.h”

CFinsHandle::CFinsHandle()
{
m_bEstablishCommunicationByFins = false;
m_nIpNode = 0;
}

// 重写数据接收,用于协议识别
void CFinsHandle::OnDataRecv(char* pData, int nSize)
{
if (nSize > 0)
{
m_pRecvData.Append(pData, nSize);
if (m_pRecvData.Size() >= FINS_TCP_HEAD_SIZE)
{
FINS_TCP_HEAD pHead;
pHead.SetData(m_pRecvData.GetString());
int nAllSize = pHead.GetLength();

     if (m_pRecvData.Size() >= nAllSize){SetRecvComplete(nAllSize);}}
}

}

// 重写数据接收,开始接收数据,用于协议识别
void CFinsHandle::OnBeginRecv()
{
m_pRecvData.SetSize(0);
}

// 通讯关闭
void CFinsHandle::OnCloseConnect()
{
m_bEstablishCommunicationByFins = false;
}

long CFinsHandle::ReadMemoryData(int nAddr, int nSize, FINS_DATA_TYPE::ENUM nType, __int16* pData)
{
long nCode = 0;
if(nCode = EstablishCommunicationByFins())
{
return nCode;
}

CMyString pSendData;// 获取发送内存
int nAllSize;
nAllSize  = FINS_TCP_HEAD_SIZE;
nAllSize += FINS_CONTROL_HEAD_SIZE;
nAllSize += FINS_MEMORY_AREA_READ_SIZE;
pSendData.SetSize(nAllSize);
char* pBuff = pSendData.GetString();// 头部信息
FINS_TCP_HEAD pHead;
pHead.nCommand = FINS_TCP_CMD_DATA;
pHead.SetLength(nAllSize);      //长度
pHead.GetData(pBuff);// control部分
FINS_CONTROL_HEAD pControlHead;
pControlHead.nDA1 = 0;
pControlHead.nSA1 = m_nIpNode;
pControlHead.nCmd1 = 0x01;
pControlHead.nCmd2 = 0x01;
pControlHead.GetData(pBuff + FINS_TCP_HEAD_SIZE);// 数据部分
FINS_MEMORY_AREA_READ pMemory;
pMemory.nAreaCode = nType;
pMemory.nAddr = nAddr;
pMemory.nBitNo = 0;
pMemory.nLength = nSize;
pMemory.GetData(pBuff + FINS_TCP_HEAD_SIZE + FINS_CONTROL_HEAD_SIZE);//   // 发送数据
CMyString pRecvData;
nCode = SendSyncData(pSendData, pRecvData);
if (nCode == 0)
{// 先判断答复数据的头数据是否正确 if(nCode = CheckReplyDataIsError(pRecvData.GetString(), pRecvData.Size())){return nCode;}// 数据头FINS_TCP_HEAD pHeadReply;pHeadReply.SetData(pRecvData.GetString());// 答复长度要求int nMinSize = FINS_TCP_HEAD_SIZE + FINS_CONTROL_HEAD_SIZE + FINS_MEMORY_AREA_READ_FIX_R_SIZE + nSize * 2;if(pHeadReply.GetLength() < nMinSize){return FINS_REPLY_READ_DATA_TOO_SHORT;}else{// FINS协议部分FINS_CONTROL_HEAD pControlHeadReply;pControlHeadReply.SetData(pRecvData.GetString());if (pControlHeadReply.nCmd1 != pControlHead.nCmd1 ||pControlHeadReply.nCmd2 != pControlHead.nCmd2){// 命令不一致return FINS_REPLY_CMD_NO_IS_REQUST_CMD;}// 答复数据FINS_MEMORY_AREA_READ_REPLY pReplyData;pReplyData.SetData(pRecvData.GetString(), pRecvData.Size());  if(pReplyData.nEndCode != 0){return FINS_REPLY_READ_DATA_FAIL; }// 拷贝数据int nReadByte = nSize * 2;if (pReplyData.GetDataBytsSize() == nReadByte){memcpy(pData, pReplyData.GetData(), nReadByte);}else{               return FINS_REPLY_READ_DATA_TOO_SHORT;              }}
}
return nCode;

}

long CFinsHandle::WriteMemoryData(int nAddr, int nSize, FINS_DATA_TYPE::ENUM nType, __int16* pData)
{
long nCode = 0;
if(nCode = EstablishCommunicationByFins())
{
return nCode;
}

CMyString pSendData;
int nBytsSize = nSize * 2;// 获取发送内存
int nAllSize;
nAllSize  = FINS_TCP_HEAD_SIZE;
nAllSize += FINS_CONTROL_HEAD_SIZE;
nAllSize += FINS_MEMORY_AREA_READ_SIZE;
nAllSize += nBytsSize;
pSendData.SetSize(nAllSize);
char* pBuff = pSendData.GetString();// 头部信息
FINS_TCP_HEAD pHead;
pHead.nCommand = FINS_TCP_CMD_DATA;
pHead.SetLength(nAllSize);      //长度
pHead.GetData(pBuff);// control部分
FINS_CONTROL_HEAD pControlHead;
pControlHead.nDA1 = 0;
pControlHead.nSA1 = m_nIpNode;
pControlHead.nCmd1 = 0x01;
pControlHead.nCmd2 = 0x02;
pControlHead.GetData(pBuff + FINS_TCP_HEAD_SIZE);// 数据部分
FINS_MEMORY_AREA_WRITE pMemory;
pMemory.nAreaCode = nType;
pMemory.nAddr = nAddr;
pMemory.nBitNo = 0;
pMemory.nLength = nSize;
pMemory.pData.Append((char*)pData, nBytsSize);
pMemory.GetData(pBuff + FINS_TCP_HEAD_SIZE + FINS_CONTROL_HEAD_SIZE);//   // 发送数据
CMyString pRecvData;
nCode = SendSyncData(pSendData, pRecvData);
if (nCode == 0)
{// 先判断答复数据的头数据是否正确         if(nCode = CheckReplyDataIsError(pRecvData.GetString(), pRecvData.Size())){return nCode;}// 数据头FINS_TCP_HEAD pHeadReply;pHeadReply.SetData(pRecvData.GetString());// 答复长度要求int nMinSize = FINS_TCP_HEAD_SIZE + FINS_CONTROL_HEAD_SIZE + FINS_MEMORY_AREA_WRITE_R_SIZE;if(pHeadReply.GetLength() < nMinSize){return FINS_REPLY_READ_DATA_TOO_SHORT;}else{// FINS协议部分FINS_CONTROL_HEAD pControlHeadReply;pControlHeadReply.SetData(pRecvData.GetString());if (pControlHeadReply.nCmd1 != pControlHead.nCmd1 ||pControlHeadReply.nCmd2 != pControlHead.nCmd2){// 命令不一致return FINS_REPLY_CMD_NO_IS_REQUST_CMD;}// 答复数据FINS_MEMORY_AREA_WRITE_REPLY pReplyData;pReplyData.SetData(pRecvData.GetString());               if(pReplyData.nEndCode != 0){return FINS_REPLY_WRITE_DATA_FAIL;    }}}
return nCode;

}

// 获取fins节点地址

long CFinsHandle::GetFinsNodeAddress()
{
return 0;
}

// 检查答复数据是否错误
long CFinsHandle::CheckReplyDataIsError(char* pData, int nSize)
{
if (nSize < FINS_TCP_HEAD_SIZE)
{
// 小于最小要求数据
return FINS_REPLY_DATA_TOO_SHORT;
}

// 消息错误
FINS_TCP_HEAD pHeadReply;
pHeadReply.SetData(pData);
if (pHeadReply.nErrorCode)
{return FINS_REPLY_ERROR_BY_MESSAGE;
}return 0;

}

// 建立通讯
long CFinsHandle::EstablishCommunicationByFins()
{
if (m_bEstablishCommunicationByFins)
{
// 已经建立通讯连接了
return 0;
}

long nCode = 0;
CMyString pSendData;// 获取发送内存
int nAllSize;
nAllSize  = FINS_TCP_HEAD_SIZE;
nAllSize += FINS_CONNECT_REQUST_SIZE;
pSendData.SetSize(nAllSize);
char* pBuff = pSendData.GetString();// 头部信息
FINS_TCP_HEAD pHead;
pHead.nCommand = FINS_TCP_CMD_CONNECT_REQUST;
pHead.SetLength(nAllSize);      //长度
pHead.GetData(pBuff);// IP地址
FINS_CONNECT_REQUST pConnectRequst;
pConnectRequst.GetData(pBuff + FINS_TCP_HEAD_SIZE);

// 发送数据
CMyString pRecvData;
if(nCode = SendSyncData(pSendData, pRecvData))
{
return nCode;
}

// 处理返回值
FINS_TCP_HEAD pHeadReply;
pHeadReply.SetData(pRecvData.GetString());// 检查头信息
if (pHeadReply.nErrorCode == 0 &&pHeadReply.nCommand == FINS_TCP_CMD_CONNECT_RESPONSE)
{// 提取 IP Node信息if (pHeadReply.GetLength() == FINS_TCP_HEAD_SIZE + FINS_CONNECT_RESPONS_SIZE){// 提取FINS_CONNECT_RESPONSE pConnectResponse;pConnectResponse.SetData(pRecvData.GetString());m_nIpNode = pConnectResponse.pClientAddrss[3];// 建立通讯成功m_bEstablishCommunicationByFins = true;return 0;}
}   return FINS_REQUST_CONNECT_FAIL;

}

OneAPIConnect(一) 欧姆龙FINS协议实现源代码相关推荐

  1. 欧姆龙CJ2M 与海利普变频器通讯 协议宏方式 欧姆龙通讯模块协议宏 功能:通过触摸屏进行启停和点动,频率设定,加减速时间,点动频率设定

    欧姆龙CJ2M 与海利普变频器通讯 协议宏方式可直接拿来实用了,欧姆龙CJ2M PLC与变频器协议宏通讯 采用器件:欧姆龙CJ2M的PLC,1个CJ1W SCU21 V1通讯模块,1台海利普HLP-B ...

  2. 欧姆龙PLC协议网关

    物通博联欧姆龙PLC协议网关即wtblnet iot Gateway,是一款支持单网口/两网口/五网口,支持4G/3G/WIFI/PPPOE/WAN有线网络,内嵌工业控制协议,支持远程自定义配置.远程 ...

  3. Fins协议-欧姆龙PLC数据采集读写操作上位机软件工具

    本软件基于.net开发,可支持主流PLC通信协议测试,支持读取写入操作:支持ModBus.Bacnet等常用工业通讯协议 支持功能如下: ModBusTcp读写操作 ModBusRtu读写操作 Mod ...

  4. 苹果蓝牙协议的源代码质量都这么差了吗?!研究员找到10个 0day

     聚焦源代码安全,网罗国内外最新资讯! 编译:奇安信代码卫士团队 苹果用于保护蓝牙外围设备的 MagicPairing协议被曝存在10个 0day 漏洞. 德国达姆斯塔特工业大学的研究人员查看了 Ma ...

  5. 计算机网络RIP协议的源代码

    RIP的算法思想: (1)收到相邻路由器(其地址为X)的一个RIP报文,先修改此RIP报文中的所有项目:将"下一跳"字段中的地址都改为X,并将所有的"距离"字段 ...

  6. autojs快阅读协议脚本源代码免费分享

    //此代码由飞云脚本圈整理提供(www.feiyunjs.com) var page = 1; while (true) {var page=1;var getArticleList = http.p ...

  7. Fins TCP协议

    ** PLC通讯协议剖析及应用 ** Fins协议在TCP/IP网段上的应用 modbus协议 都完全公开的 西门子S7协议,是不公开的 三个PLC,以太网通讯/TCP通讯 西门子S7-1200 19 ...

  8. 欧姆龙CJ2M 与海利普变频器通讯 协议宏方式可直接拿来实用了,欧姆龙CJ2M PLC与变频器协议宏通讯

    欧姆龙CJ2M 与海利普变频器通讯 协议宏方式可直接拿来实用了,欧姆龙CJ2M PLC与变频器协议宏通讯 采用器件:欧姆龙CJ2M的PLC,1个CJ1W SCU21 V1通讯模块,1台海利普HLP-B ...

  9. 使用Wireshark分析工控协议

    在工控系统中通信协议存在众多标准,也存在众多私有协议,如果你有过使用组态软件的经历,你便会发现,在第一步连接设备时除连接设备的方式有以太网/串行等方式外,各家基本上都存在自己的私有通信协议. 上图为, ...

  10. 【IIOT】欧姆龙PLC数采之CP系列

    [IIOT]欧姆龙PLC数采之CP系列 前言 一.车间级数采系统架构 二.欧姆龙PLC介绍 三.CP系列产品说明 3.1. CPU规格 3.2. 内部寄存器 3.3. 支持协议 四.数采方案 4.1. ...

最新文章

  1. jQuery获取HTML标签自定义属性值或data值
  2. [Python从零到壹] 八.数据库之MySQL和Sqlite基础知识及操作万字详解
  3. django models中批量导入数据
  4. 数据库:MySQL、SqlServer、Oracle对比
  5. 单反录像按钮在哪_单反与微单到底哪不同
  6. 打不开磁盘配额linux,九度OJ 1455 珍惜现在,感恩生活 -- 动态规划(背包问题)...
  7. Assets和Raw区别
  8. javaweb通过iis实现域账号免登陆_聊天小程序的Java实现
  9. OpenCV-Python实战(番外篇)——利用 KNN 算法识别手写数字
  10. 读书日当天冲上销量榜Top1和Top3,来听听携程人写书背后的故事
  11. 百度网盘下载神器度盘下载器
  12. 抖音超火的罗马时钟html代码,最近抖音上挺火的圆形文字时钟
  13. python对excel指定数据提取并保存到另一excel表中(一)
  14. 小红书探店流程有哪些?小红书探店博主如何联系?
  15. GitHub进行版本回退
  16. js日历控件html,jQuery日历插件sys-calendar.js
  17. mysql查询数据库结构_mysql查询数据库下的表结构
  18. 安卓手机可以用python编程软件-有哪些可以在手机上敲Python代码的App
  19. ubuntu使用python读串口_Win10的Linux子系统Ubuntu使用串口
  20. 014:Django商城项目静态文件修改

热门文章

  1. 怎么还原打开方式为计算机程序,W10电脑系统如何还原打开方式
  2. 高中计算机上册知识总结怎么写,高中计算机总结范文
  3. [Sencha ExtJS amp; Touch] 在Sencha(Extjs/Touch)应用程序中使用plugins(插件)和mixins(混入)...
  4. 【申论】钟君讲申论(听课笔记)
  5. as常用固定搭配_语法必看:as的几种固定用法
  6. 研发思维09----嵌入式智能产品开发经过思考
  7. Java多重选择switch
  8. loadlibrary函数失败,错误码:126
  9. 怎么把qlv格式转成mp4
  10. 论文参考文献批量改为上角标,简单好用!!!