当前位置: 首页 > news >正文

纯C++ 与欧姆龙PLC使用 FINS TCP通讯源码

目前实现DM区数据读写
废话少说,直接干代码!
OmronTcp.h

#pragma once#include <iostream>
#include <mutex>
#include <WinSock2.h>#pragma comment(lib,"ws2_32.lib")
#pragma warning(disable:4996)using namespace std;enum DATATYPE
{_BOOL,_INT,_DINT,_DOUBLE,_STRING
};enum READORWRITE
{READ,WRITE
};char HeadBuf[26] = { 0x46, 0x49, 0x4E, 0x53, 0x00, 0x00, 0x00, 0x1A, 0x00,0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00,0x02, 0x00, 0x0A, 0x00, 0x00, 0x6F, 0x00, 0x00 };class OmronTcp
{
public:OmronTcp();public:int Connect(string ip, int port,int nLoadNode,int nRemoteNode);void Handshake(uint8_t loadNode);int Read(int nAddress, int nSize, DATATYPE type, void* pData);int Write(int nAddress, int nSize, DATATYPE type, void* pData);int Read_Int(string area, string type, int address, int bit, int* value);int Write_Int(string area,string type,int address,int bit,int value);int Read_Double(string area, string type, int address, double* value);int Write_Double(string area, string type, int address, double value);int Read_String(string area, string type, int address, char* value, int size);int Write_String(string area, string type, int address, char* value,int size);private:SOCKET SocketClient;SOCKADDR_IN ClientAddr;int16_t m_nValue = 0;
};

OmronTcp.cpp

#include "OmronTcp.h"
#include <cstdio>
#include<iostream>
#include<string>
#include<WinSock2.h>
#include <cstring>
#include <WS2tcpip.h>uint16_t HighChangeLow(uint16_t data)
{uint16_t high = (data >> 8) & 0xff;uint16_t low = data & 0xff;uint16_t resultData = (low << 8) | high;return resultData;
}int16_t HighChangeLow(int16_t data)
{int16_t high = (data >> 8) & 0xff;int16_t low = data & 0xff;int16_t resultData = (low << 8) | high;return resultData;
}int HighChangeLow(int data)
{int temp = data;char* p = (char*)&temp;char t = p[0];p[0] = p[3];p[3] = t;t = p[1];p[1] = p[2];p[2] = t;return temp;
}int DataHighChangeLow(int data)
{int temp = data;char* p = (char*)&temp;char t = p[0];p[0] = p[1];p[1] = t;t = p[2];p[2] = p[3];p[3] = t;return temp;
}float DataHighChangeLow(float data)
{float temp = data;char* p = (char*)&temp;char t = p[0];p[0] = p[1];p[1] = t;t = p[2];p[2] = p[3];p[3] = t;return temp;
}int ResError(char* pBuff)
{int nError = 0;memcpy(&nError, pBuff + 12, 4);nError = HighChangeLow(nError);return nError;
}void ModifyHeadLength(int num)
{num = HighChangeLow(num);memcpy(&HeadBuf[4], &num, sizeof(int));
}OmronTcp::OmronTcp()
{
}/// <summary>
/// 建立连接  例:"192.168.0.1,9600,25,1"
/// </summary>
/// <param name="ip"> ip </param>
/// <param name="port"> 端口号 </param>
/// <param name="nLoadNode"> 本地地址最后一个值 例:192.168.0.1  这个值就是1 </param>
/// <param name="nRemoteNode"> 远程plc地址最后一个值 例:192.168.0.2 这个值就是2 </param>
/// <returns> 0-成功 1-失败 </returns>
int OmronTcp::Connect(string ip, int port, int nLoadNode, int nRemoteNode)
{WSADATA wsd;WSAStartup(MAKEWORD(2, 2), &wsd);SocketClient = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);ClientAddr.sin_family = AF_INET;inet_pton(AF_INET, ip.c_str(), &ClientAddr.sin_addr.S_un.S_addr);//ClientAddr.sin_addr.S_un.S_addrClientAddr.sin_port = htons(port);int n = 0;n = connect(SocketClient, (struct sockaddr*)&ClientAddr, sizeof(ClientAddr));if (n == SOCKET_ERROR) {closesocket(SocketClient);return 1;}uint8_t loadNode = nLoadNode;uint8_t remoteNode = nRemoteNode;HeadBuf[20] = remoteNode;HeadBuf[23] = loadNode;// 欧姆龙PLC连接后需要发送握手报文才算建立连接Handshake(loadNode);return 0;
}/// <summary>
/// TCP连接后握手报文发送
/// </summary>
/// <param name="loadNode"></param>
void OmronTcp::Handshake(uint8_t loadNode)
{char* buf = new char[20];buf[0] = 0x46;buf[1] = 0x49;buf[2] = 0x4E;buf[3] = 0x53;buf[4] = 0x00;buf[5] = 0x00;buf[6] = 0x00;buf[7] = 0x0C;buf[8] = 0x00;buf[9] = 0x00;buf[10] = 0x00;buf[11] = 0x00;buf[12] = 0x00;buf[13] = 0x00;buf[14] = 0x00;buf[15] = 0x00;buf[16] = 0x00;buf[17] = 0x00;buf[18] = 0x00;buf[19] = loadNode;send(SocketClient, buf, 20, 0);Sleep(5);char RecvBuff[2048] = { 0 };recv(SocketClient, RecvBuff, 2048, 0);delete[]buf;
}int OmronTcp::Read(int nAddress, int nSize, DATATYPE type, void* pData)
{int nLength = 26;char AllBuf[34];ModifyHeadLength(nLength);memcpy(&AllBuf, &HeadBuf, 26);AllBuf[26] = 0x01;AllBuf[27] = 0x01;AllBuf[28] = 0x82;uint16_t Address = nAddress;Address = HighChangeLow(Address);memcpy(&AllBuf[29], &Address, sizeof(uint16_t));AllBuf[31] = 0x00;AllBuf[32] = 0x00;if (1 == nSize && (type == _BOOL || type == _INT)) {AllBuf[33] = 0x01;}else if (2 == nSize && (type == _DINT || type == _DOUBLE)) {AllBuf[33] = 0x02;}if (type == _STRING) {AllBuf[33] = nSize;}int nReg = send(SocketClient, AllBuf, sizeof(AllBuf), 0);if (nReg < 0) {return 1;}char RecvBuff[2048] = { 0 };nReg = recv(SocketClient, RecvBuff, 2048, 0);int recvLen = 0;memcpy(&recvLen, &RecvBuff[4], 4);recvLen = HighChangeLow(recvLen);if (nReg != recvLen){}if (nReg > 0) {int nLength = 0;memcpy(&nLength, &RecvBuff[4], 4);nLength = HighChangeLow(nLength);int nAllLength = nLength + 8;if (nAllLength > 16) {nReg = ResError(RecvBuff);if (0 != nReg) {return 1;}}else {return 1;}if (type == _STRING) {int nNum = 2 * nSize;int nDataLen = nNum;nNum += 22;if (nNum == nLength) {nLength += 8;int nDataLen2 = nLength - nDataLen;int16_t* Data = new int16_t[nDataLen2 / 2];memcpy(Data, &RecvBuff[nLength - nDataLen], nDataLen);for (int i = 0; i < nDataLen2 / 2; i++){Data[i] = HighChangeLow(Data[i]);}memcpy(pData, Data, nDataLen2 / 2);delete[]Data;return 0;}else {return 1;}}else{if (24 != nLength && 1 == nSize) {return 1;}else if (24 == nLength && 1 == nSize) {int16_t data = 0;nLength += 8;memcpy(&data, &RecvBuff[nLength - 2], 2);data = HighChangeLow(data);int nData = data;memcpy(pData, &nData, sizeof(int));return 0;}if (26 != nLength && 2 == nSize) {return 1;}else if (26 == nLength && 2 == nSize) {nLength += 8;if (type == _DINT) {int data = 0;memcpy(&data, &RecvBuff[nLength - 4], 4);int16_t buf[2] = { 0 };memcpy(&buf, &data, sizeof(int));buf[0] = HighChangeLow(buf[0]);buf[1] = HighChangeLow(buf[1]);int nBuf = 0;memcpy(pData, &buf, sizeof(buf));return 0;}else if (type == _DOUBLE) {char buf[4] = { 0 };memcpy(&buf, &RecvBuff[nLength - 4], 4);char t = buf[0];buf[0] = buf[1];buf[1] = t;char t_ = buf[2];buf[2] = buf[3];buf[3] = t_;memcpy(pData, buf, sizeof(buf));return 0;}return 0;}}}else {return 1;}return 0;
}int OmronTcp::Write(int nAddress, int nSize, DATATYPE type, void* pData)
{int nLength = 26;int nNum = 0;if (type == _STRING){nNum = nSize;if (0 != (nNum % 2)){nNum = nNum + 1;}}else{nNum = 2 * nSize;}nLength += nNum;ModifyHeadLength(nLength);nLength += 8;char* AllBuf = new char[nLength];memcpy(AllBuf, &HeadBuf, sizeof(HeadBuf));AllBuf[26] = 0x01;AllBuf[27] = 0x02;AllBuf[28] = 0x82;uint16_t Address = nAddress;Address = HighChangeLow(Address);memcpy(&AllBuf[29], &Address, sizeof(uint16_t));AllBuf[31] = 0x00;AllBuf[32] = 0x00;if (type == _STRING) {AllBuf[33] = nNum / 2;}else {AllBuf[33] = nSize;}if (1 == nSize && (type == _BOOL || type == _INT)) {int16_t Data = 0;memcpy(&Data, pData, 2);Data = HighChangeLow(Data);memcpy(&AllBuf[34], &Data, sizeof(int16_t));}else if (2 == nSize) {if (type == _DINT) {int Data = 0;memcpy(&Data, pData, 4);Data = DataHighChangeLow(Data);memcpy(&AllBuf[34], &Data, sizeof(int));}else if (type == _DOUBLE) {float Data = 0;memcpy(&Data, pData, 4);Data = DataHighChangeLow(Data);memcpy(&AllBuf[34], &Data, sizeof(float));}}if (type == _STRING) {int dataL = nNum / 2;int16_t* Data = new int16_t[dataL];memcpy(Data, pData, nNum);for (int i = 0; i < dataL; i++){Data[i] = DataHighChangeLow(Data[i]);}memcpy(&AllBuf[34], Data, nNum);delete[]Data;}int nReg = send(SocketClient, AllBuf, nLength, 0);if (nReg < 0) {delete[]AllBuf;return 1;}char RecvBuff[2048] = { 0 };nReg = recv(SocketClient, RecvBuff, 2048, 0);if (nReg > 0) {delete[]AllBuf;return 0;}else {delete[]AllBuf;return 1;}
}/// <summary>
/// 读DM区BOOL、INT、DINT 例:"DM,BOOL,100,9"/"DM,INT,100"
/// </summary>
/// <param name="area"> PLC区块 目前实现DM </param>
/// <param name="type"> 数据类型 </param>
/// <param name="address"> 地址 </param>
/// <param name="bit"> 如果是bool 表示位 </param>
/// <param name="value"> 读到的值 </param>
/// <returns> 0-成功 1-失败 </returns>
int OmronTcp::Read_Int(string area, string type, int address, int bit, int* value)
{if (area.compare("DM") == 0) {			// 区域if (type.compare("BOOL") == 0) {	// 类型int rr = Read(address, 1, _BOOL, value);if (rr != 0) {return 1;}else {uint16_t DMData = *value;//位操作 进行BOOL赋值*value = ((DMData >> bit) & 1);return 0;}}else if (type.compare("INT") == 0) {int rr = Read(address, 1, _INT, value);if (rr != 0) {return 1;}else {return 0;}}else if (type.compare("DINT") == 0) {int rr = Read(address, 2, _DINT, value);if (rr != 0) {return 1;}else {return 0;}}}return 0;
}/// <summary>
/// 写DM区BOOL、INT、DINT
/// </summary>
/// <param name="area"></param>
/// <param name="type"></param>
/// <param name="address"></param>
/// <param name="bit"></param>
/// <param name="value"></param>
/// <returns></returns>
int OmronTcp::Write_Int(string area, string type, int address, int bit, int value)
{if (area.compare("DM") == 0) {	if (type.compare("BOOL") == 0) {m_nValue = 0;int rr = Read(address, 1, _BOOL, &m_nValue);if (rr != 0) {return 1;}else {if (value) {m_nValue = m_nValue |= (1 << bit);}else {m_nValue = m_nValue & ~(1 << bit);}rr = Write(address, 1, _INT, &m_nValue);if (rr != 0) {return 1;}return 0;}}else if (type.compare("INT") == 0) {int nData = value;int rr = Write(address, 1, _INT, &nData);if (rr != 0) {return 1;}else {return 0;}}else if (type.compare("DINT") == 0) {int nData = value;int rr = Write(address, 2, _DINT, &nData);if (rr != 0) {return 1;}else {return 0;}}}return 0;
}int OmronTcp::Read_Double(string area, string type, int address, double* value)
{if (area.compare("DM") == 0) {if (type.compare("DOUBLE") == 0) {float fData = 0.0;int rr = Read(address, 2, _DOUBLE, &fData);if (rr != 0) {return 1;}else {*value = fData;*value = floor(*value * 100) / 100;return 0;}}}return 0;
}int OmronTcp::Write_Double(string area, string type, int address, double value)
{if (area.compare("DM") == 0) {if (type.compare("DOUBLE") == 0) {float fData = value;int rr = Write(address, 2, _DOUBLE, &fData);if (rr != 0) {return 1;}else {return 0;}}}return 0;
}int OmronTcp::Read_String(string area, string type, int address, char* value, int size)
{if (area.compare("DM") == 0) {if (type.compare("STRING") == 0) {int nSize = size;	//Sizechar realByte[512] = { 0 };int rr = Read(address, nSize, _STRING, &realByte);if (rr != 0) {return 1;}else {string strval = "";strval = realByte;memcpy(value, strval.c_str(), nSize);return 0;}}}return 0;
}int OmronTcp::Write_String(string area, string type, int address, char* value, int size)
{if (area.compare("DM") == 0) {int byteLen = size;if ((type.compare("STRING") == 0 || type.compare("CHARS") == 0)) {char realByte[20] = { 0 };memcpy(realByte, value, 20);int rr = Write(address, byteLen, _STRING, &realByte);if (rr != 0) {return 1;}else {return 0;}}}return 1;
}

功能不多,可以自己修改添加功能
接口都写好了,自己连上支持FINS TCP的PLC玩吧。

相关文章:

  • 【Python训练营打卡】day37 @浙大疏锦行
  • 如何寻找大模型在企业业务中的价值?
  • 蓝桥杯b组c++赛道---字典树
  • IPv4地址的主要配置项介绍
  • 语音识别算法的性能要求一般是多少
  • 基于多流特征融合与领域知识整合的CNN-xLSTM-xAtt网络用于光电容积脉搏波信号的无创血压估计【代码已复现】
  • Matlab中gcb、gcbh、gcs的区别
  • Cursor 与DeepSeek的完美契合
  • 实时同步缓存,与阶段性同步缓存——补充理解《补充》
  • OpenCV 图像像素的读写操作
  • leetcode hot100刷题日记——18.搜索插入位置
  • PCB设计自检表
  • SAAS架构设计2-流程图-注册流程图
  • 【premiere教程】【01】【跑个流程】
  • 【新品发布】嵌入式人工智能实验箱EDU-AIoT ELF 2正式发布
  • 学习python day9
  • 为什么共现矩阵是高维稀疏的
  • 攻防世界-safer-than-rot13
  • 各个链接集合
  • Jenkins实践(7):Publish over SSH功能
  • 类网站建设/互联网推广中心
  • 做的网站手机打不开怎么回事啊/手机怎么做网站免费的
  • 合作社做网站有用吗/要看网的域名是多少
  • 大淘客做的网站打不开/学seo需要多久
  • 阳江市建设路龙源学校网站/如何创建自己的网址
  • 网站开发流程及进度安排/培训公司