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

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

#pragma once

#include 
#include 
#include 

#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 
#include
#include
#include
#include 
#include 

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()
{
}

/// 
/// 建立连接  例:"192.168.0.1,9600,25,1"
/// 
///  ip 
///  端口号 
///  本地地址最后一个值 例:192.168.0.1  这个值就是1 
///  远程plc地址最后一个值 例:192.168.0.2 这个值就是2 
///  0-成功 1-失败 
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_addr
	ClientAddr.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;
}

/// 
/// TCP连接后握手报文发送
/// 
/// 
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;
	}
}

/// 
/// 读DM区BOOL、INT、DINT 例:"DM,BOOL,100,9"/"DM,INT,100"
/// 
///  PLC区块 目前实现DM 
///  数据类型 
///  地址 
///  如果是bool 表示位 
///  读到的值 
///  0-成功 1-失败 
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;
}

/// 
/// 写DM区BOOL、INT、DINT
/// 
/// 
/// 
/// 
/// 
/// 
/// 
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;	//Size
			char 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玩吧。

你可能感兴趣的:(欧姆龙PLC,c++,tcp/ip,开发语言)