当前位置: 首页 > 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玩吧。

http://www.xdnf.cn/news/670033.html

相关文章:

  • NSSCTF-[闽盾杯 2021]DNS协议分析
  • 为什么单张表索引数量建议控制在 6 个以内
  • InvokeAI 笔记, 简单了解一下 (生成图片,text2img )
  • MQTT over SSL/TLS:工业网关如何构建端到端加密的数据传输通道
  • MySQL 只知道表名不知道具体库?如何查询?information_schema入手
  • ssh 测试 是否可以连通docker 容器
  • Excel常用公式全解析(1):从基础计算到高级应用
  • 如何理解UDP 和 TCP 区别 应用场景
  • 笔记: 在WPF中ContentElement 和 UIElement 的主要区别
  • 2025年土建施工员备考考试真题及答案
  • 数据库MySQL学习——day13(索引与查询优化)
  • gcc clang
  • FastMoss 国际电商Tiktok数据分析 JS 逆向 | MD5加密
  • 安全监测预警系统的核心价值
  • Jmeter一些元件使用的详细记录
  • VR 赋能病毒分离鉴定:开启微观探索新视界
  • 微软开源bitnet b1.58大模型,应用效果测评(问答、知识、数学、逻辑、分析)
  • 数据分析实战1(Excel制作报表)
  • 【NLP基础知识系列课程-Tokenizer的前世今生第五课】从静态到可学:Tokenizer 的自适应演化之路
  • LVS负载均衡群集
  • 语音识别算法的性能要求一般是多少
  • Day128 | 灵神 | 二叉树 | 反转二叉树的奇数层
  • 软件同步机制-Peterson解决方案 简单讲解
  • 攻防世界-你猜猜
  • js判断当前设备是否为移动端
  • camera_venc_thread线程获取高分辨率编码码流
  • Vue组件化
  • Rust 学习笔记:关于闭包的练习题
  • Flink系列文章列表
  • 分布式系统中的网络编程