目前实现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玩吧。