与三菱PLC通信走MC协议,看了一下三菱通信方面文档,用C++写了一个通信类,目前实现读取M,X,Y,D区数据,写入M和D区数据(都可批量读写)
根据三菱 MELSEC iQ-FFX5用户手册(SLMP篇) 实现
具体需要看三菱文档
VS2022 纯C++版本源码
代码实现:
tcpclient.h
#ifndef TCPCLIENT_H
#define TCPCLIENT_H
#include <WinSock2.h>
#include <string>
using namespace std;
const int PORT = 4997;
#define MaxBufSize 2048
#define _CRT_SECURE_NO_WARINGS
enum COMMAND {
READ,
WRITE
};
enum SUB_COMMAND {
SUB_BIT,
SUB_WORD
};
enum TYPE {
XType,
YType,
MType,
DType
};
class TcpClient
{
public:
TcpClient();
public:
int slot_Connect(string ip,int port);
int ReadD(int address,int size,void *pData);
int ReadM(int address,int size,void *pData);
int ReadX(int address,int size,void *pData);
int ReadY(int address,int size,void *pData);
int WriteD(int address,int size,void *pData);
int WriteM(int address,int size,void *pData);
char* build(int address,int size,int command,int sub_command,int type);
int ResDataLen(char* data);
int ResError(char* data);
void ReConnect();
int ConnectStatus();
size_t customStrlen(const char* data);
private:
SOCKET SocketClient;
SOCKADDR_IN ClientAddr; //地址
int nNum = 0;
int nConnected = 1;
};
#endif // TCPCLIENT_H
tcpclient.cpp
#include "tcpclient.h"
#include <cstdio>
#include<iostream>
#include<string>
#include<WinSock2.h>
#include <cstring>
#include <WS2tcpip.h>
#pragma comment(lib,"ws2_32.lib")
TcpClient::TcpClient()
{
}
int TcpClient::slot_Connect(string ip, int port)
{
WSADATA wsd;
WSAStartup(MAKEWORD(2, 2), &wsd);
SocketClient = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
ClientAddr.sin_family = AF_INET;
// in_addr addr;
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) {
nConnected = 1;
closesocket(SocketClient);
return 1;
}
nConnected = 0;
nNum = 0;
return 0;
}
int TcpClient::ReadD(int address, int size, void *pData)
{
int nAllLen = 9;
char* data = build(address,size,READ,SUB_WORD,DType);
int nLen = 21;
//char buf[data.size()];
//memcpy(buf,data.data(),data.size());
int nReg;
nReg = send(SocketClient,data, nLen, 0);
if (nReg < 0) {
//qDebug() << "Faile" << endl;
delete [] data;
nConnected = 1;
// ReConnect();
return 1;
}
Sleep(5);
nReg = 0;
char RecvBuff[MaxBufSize];
nReg = recv(SocketClient, RecvBuff, sizeof(RecvBuff), 0);
if(nReg > 0) {
char* revData = new char[nReg];
//revData.resize(nReg);
memcpy(revData,RecvBuff,nReg);
int nLen = ResDataLen(revData);
nAllLen += nLen;
if(0 != ResError(revData)) {
delete[] data;
delete[] revData;
return 1;
}
memcpy(pData,revData+11,nLen-2);
delete[] data;
delete[] revData;
return 0;
} else {
delete[] data;
return 1;
}
delete[] data;
return 0;
}
int TcpClient::ReadM(int address, int size, void *pData)
{
int nAllLen = 9;
//QByteArray data;
//QByteArray revData;
int sizeM = size;
if(sizeM <= 2) {
sizeM = 1;
}else {
if(sizeM%2 == 0) {
sizeM = sizeM/2;
}else {
sizeM = (sizeM + 1)/2;
}
}
char* data = build(address,size,READ,SUB_BIT,MType);
int nLen = 21;
//char buf[data.size()];
//memcpy(buf,data.data(),data.size());
int nReg = 0;
nReg = send(SocketClient, data, nLen,0);
if (nReg < 0) {
//qDebug() << "Faile" << endl;
// ReConnect();
delete[] data;
nConnected = 1;
return 1;
}
Sleep(5);
nReg = 0;
char RecvBuff[MaxBufSize];
nReg = recv(SocketClient, RecvBuff, sizeof(RecvBuff), 0);
if(nReg > 0) {
//revData.resize(nReg);
char* revData = new char[nReg];
memcpy(revData,RecvBuff,nReg);
int nLen = ResDataLen(revData);
nAllLen += nLen;
if(0 != ResError(revData)) {
delete[] data;
delete[] revData;
return 1;
}
uint8_t *dataTemp = new uint8_t[sizeM];
uint8_t *dataM = new uint8_t[size];
memcpy(dataTemp,revData+11,nLen-2);
int nNum = 0;
for(int i = 0; i < sizeM; i++) {
uint8_t firstFourBits = (dataTemp[i] >> 4) & 0x0F; //firstFourBits
uint8_t lastFourBits = dataTemp[i] & 0x0F; //lastFourBits
if(0 == i) {
memcpy(dataM+nNum,&firstFourBits,1);
nNum += 1;
if(nNum < size) {
memcpy(dataM+nNum,&lastFourBits,1);
}
} else {
memcpy(dataM+nNum,&firstFourBits,1);
nNum += 1;
if((nNum) < size) {
memcpy(dataM+nNum,&lastFourBits,1);
}
}
nNum++;
}
memcpy(pData,dataM,size);
delete [] data;
delete [] revData;
delete [] dataM;
delete [] dataTemp;
return 0;
} else {
delete[] data;
return 1;
}
}
int TcpClient::ReadX(int address, int size, void *pData)
{
int nAllLen = 9;
//QByteArray data;
//QByteArray revData;
int sizeX = size;
if(sizeX <= 2) {
sizeX = 1;
}else {
if(sizeX%2 == 0) {
sizeX = sizeX/2;
}else {
sizeX = (sizeX + 1)/2;
}
}
char* data = build(address,size,READ,SUB_BIT,XType);
int nLen = 21;
//char buf[data.size()];
//memcpy(buf,data.data(),data.size());
int nReg = 0;
nReg = send(SocketClient,data, nLen,0);
if (nReg < 0) {
//qDebug() << "Faile" << endl;
// ReConnect();
delete[] data;
nConnected = 1;
return 1;
}
Sleep(5);
nReg = 0;
char RecvBuff[MaxBufSize];
nReg = recv(SocketClient, RecvBuff, sizeof(RecvBuff), 0);
if(nReg > 0) {
//revData.resize(nReg);
char* revData = new char[nReg];
memcpy(revData,RecvBuff,nReg);
int nLen = ResDataLen(revData);
nAllLen += nLen;
if(0 != ResError(revData)) {
delete[] data;
delete[] revData;
return 1;
}
uint8_t *dataTemp = new uint8_t[sizeX];
uint8_t *dataX = new uint8_t[size];
memcpy(dataTemp,revData+11,nLen-2);
int nNum = 0;
for(int i = 0; i < sizeX; i++) {
uint8_t firstFourBits = (dataTemp[i] >> 4) & 0x0F;
uint8_t lastFourBits = dataTemp[i] & 0x0F;
if(0 == i) {
memcpy(dataX+nNum,&firstFourBits,1);
nNum += 1;
if(nNum < size) {
memcpy(dataX+nNum,&lastFourBits,1);
}
} else {
memcpy(dataX+nNum,&firstFourBits,1);
nNum += 1;
if((nNum) < size) {
memcpy(dataX+nNum,&lastFourBits,1);
}
}
nNum++;
}
memcpy(pData,dataX,size);
delete [] data;
delete [] revData;
delete [] dataX;
delete [] dataTemp;
return 0;
} else {
delete[] data;
return 1;
}
}
int TcpClient::ReadY(int address, int size, void *pData)
{
int nAllLen = 9;
//QByteArray data;
//QByteArray revData;
int sizeY = size;
if(sizeY <= 2) {
sizeY = 1;
}else {
if(sizeY%2 == 0) {
sizeY = sizeY/2;
}else {
sizeY = (sizeY + 1)/2;
}
}
char* data = build(address,size,READ,SUB_BIT,YType);
int nLen = 21;
//char buf[data.size()];
//memcpy(buf,data.data(),data.size());
int nReg = 0;
nReg = send(SocketClient, data, nLen,0);
if (nReg < 0) {
//qDebug() << "Faile" << endl;
// ReConnect();
delete[] data;
nConnected = 1;
return 1;
}
Sleep(5);
nReg = 0;
char RecvBuff[MaxBufSize];
nReg = recv(SocketClient, RecvBuff, sizeof(RecvBuff), 0);
if(nReg > 0) {
//revData.resize(nReg);
char* revData = new char[nReg];
memcpy(revData,RecvBuff,nReg);
int nLen = ResDataLen(revData);
nAllLen += nLen;
if(0 != ResError(revData)) {
delete [] data;
delete [] revData;
return 1;
}
uint8_t *dataTemp = new uint8_t[sizeY];
uint8_t *dataY = new uint8_t[size];
memcpy(dataTemp,revData+11,nLen-2);
int nNum = 0;
for(int i = 0; i < sizeY; i++) {
uint8_t firstFourBits = (dataTemp[i] >> 4) & 0x0F;
uint8_t lastFourBits = dataTemp[i] & 0x0F;
if(0 == i) {
memcpy(dataY+nNum,&firstFourBits,1);
nNum += 1;
if(nNum < size) {
memcpy(dataY+nNum,&lastFourBits,1);
}
} else {
memcpy(dataY+nNum,&firstFourBits,1);
nNum += 1;
if((nNum) < size) {
memcpy(dataY+nNum,&lastFourBits,1);
}
}
nNum++;
}
memcpy(pData,dataY,size);
delete [] data;
delete [] revData;
delete [] dataY;
delete [] dataTemp;
return 0;
} else {
delete [] data;
return 1;
}
}
int TcpClient::WriteD(int address, int size, void *pData)
{
int nAllLen = 9;
//QByteArray data;
//QByteArray revData;
char* data = build(address,size,WRITE,SUB_WORD,DType);
int nDataLen = 21;//data.size();
int nLastLen = size*2;
//data.resize(nDataLen + nLastLen);
char* pDataAll = new char[nDataLen + nLastLen];
//char buf[data.size()];
memcpy(pDataAll,data, nDataLen);
memcpy(pDataAll + nDataLen, pData, size * 2);
int nReg = 0;
nReg = send(SocketClient, pDataAll, nDataLen + nLastLen,0);
if (nReg < 0) {
//qDebug() << "Faile" << endl;
// ReConnect();
delete[] data;
delete[] pDataAll;
nConnected = 1;
return 1;
}
Sleep(5);
nReg = 0;
char RecvBuff[MaxBufSize];
nReg = recv(SocketClient, RecvBuff, sizeof(RecvBuff), 0);
if(nReg > 0) {
//revData.resize(nReg);
char* revData = new char[nReg];
memcpy(revData,RecvBuff,nReg);
int nLen = ResDataLen(revData);
nAllLen += nLen;
if(0 != ResError(revData)) {
delete[] data;
delete[] pDataAll;
delete[] revData;
return 1;
}
delete[] data;
delete[] pDataAll;
delete[] revData;
return 0;
} else {
delete[] data;
delete[] pDataAll;
return 1;
}
return 0;
}
int TcpClient::WriteM(int address, int size, void *pData)
{
int nAllLen = 9;
//QByteArray data;
char* data;
//QByteArray revData;
data = build(address,size,WRITE,SUB_BIT,MType);
int nDataLen = 21;//data.size();
int nLastLen = size*1;
char* pDataAll = new char[nDataLen + nLastLen];
memcpy(pDataAll, data, nDataLen);
//data.resize(nDataLen + nLastLen);
memcpy(pDataAll +nDataLen,pData,size*1);
//char *buf = new char[strlen(pDataAll)];
//memcpy(buf,data.data(),data.size());
int nReg = 0;
nReg = send(SocketClient, pDataAll, nDataLen + nLastLen,0);
if (nReg < 0) {
//qDebug() << "Faile" << endl;
// ReConnect();
delete[] data;
delete[] pDataAll;
nConnected = 1;
return 1;
}
Sleep(5);
nReg = 0;
char RecvBuff[MaxBufSize];
nReg = recv(SocketClient, RecvBuff, sizeof(RecvBuff), 0);
if(nReg > 0) {
char* revData = new char[nReg];
//revData.resize(nReg);
memcpy(revData,RecvBuff,nReg);
int nLen = ResDataLen(revData);
nAllLen += nLen;
if(0 != ResError(revData)) {
delete[] data;
delete[] pDataAll;
delete[] revData;
return 1;
}
delete[] data;
delete[] pDataAll;
delete[] revData;
return 0;
} else {
delete[] data;
delete[] pDataAll;
return 1;
}
return 0;
}
char* TcpClient::build(int address, int size, int command, int sub_command, int type)
{
//QByteArray array;
//array.resize(21);
char *array = new char[21];
uint8_t data[21] = {0};
data[0] = 0x50;
data[1] = 0x00;
data[2] = 0x00;
data[3] = 0xFF;
data[4] = 0xFF;
data[5] = 0x03;
data[6] = 0x00;
if(command == READ) {
data[7] = 0x0C;
data[8] = 0x00;
data[9] = 0x10;
data[10] = 0x00;
data[11] = 0x01;
data[12] = 0x04;
}else if(command == WRITE) {
uint16_t reqLen = 0;
if(sub_command == SUB_BIT)
reqLen = 12 + (size*1);
else if(sub_command == SUB_WORD)
reqLen = 12 + (size*2);
memcpy(&data[7],&reqLen,2);
data[9] = 0x0A;
data[10] = 0x00;
data[11] = 0x01;
data[12] = 0x14;
}
if(sub_command == SUB_BIT) {
data[13] = 0x01;
data[14] = 0x00;
}else if(sub_command == SUB_WORD) {
data[13] = 0x00;
data[14] = 0x00;
}
memcpy(&data[15],&address,3);
if(type == XType)
data[18] = 0x9C;
else if(type == YType)
data[18] = 0x9D;
else if(type == MType)
data[18] = 0x90;
else if(type == DType)
data[18] = 0xA8;
uint16_t dataLen = size;
memcpy(&data[19],&dataLen,2);
memcpy(array,data,21);
return array;
}
int TcpClient::ResDataLen(char* data)
{
int nLen = 0;
memcpy(&nLen,data+7,2);
return nLen;
}
int TcpClient::ResError(char* data)
{
int nError = 0;
memcpy(&nError,data+9,2);
return nError;
}
void TcpClient::ReConnect()
{
nConnected = 1;
nNum += 1;
closesocket(SocketClient);
slot_Connect("127.0.0.1", 4999);
}
int TcpClient::ConnectStatus()
{
return nConnected;
}
size_t TcpClient::customStrlen(const char* data) {
size_t length = 0;
while (data[length] != '\0') {
++length;
}
return length;
}
应用
#include <iostream>
#include "tcpclient.h"
int main()
{
std::cout << "Hello World!\n";
TcpClient client;
int nReg = client.slot_Connect("127.0.0.1", 4999);
if (0 == nReg)
std::cout << "sucess" << endl;
else
std::cout << "failed" << endl;
Sleep(100);
//write D
int16_t data1 = 222;
int nReg1 = client.WriteD(100, 2, &data1);
if (0 == nReg1)
std::cout << "WriteD D100 sucess " << endl;
else
std::cout << "WriteD D100 failed " << endl;
//read D
int16_t data2;
int nReg2 = client.ReadD(100, 2, &data2);
if(0 == nReg2)
std::cout << "ReaD D100 = " << data2 << endl;
//write M
uint8_t data3 = 16; //16的十六进制就是10 如果写某一个M点写1要把写入之写成16 / 写0就不需要了直接写0就行
int nReg3 = client.WriteM(200, 1, &data3);
if (0 == nReg3)
std::cout << "WriteD M200 sucess " << endl;
else
std::cout << "WriteD M200 failed " << endl;
//read M
uint8_t data4;
int nReg4 = client.ReadM(200, 1, &data4);
if (0 == nReg4)
std::cout << "ReaD D200 = " << (int)data4 << endl;
//write 字符串
char pStr[] = "abcdefg";
int nReg5 = client.WriteD(300, 7, &pStr);
if (0 == nReg5)
std::cout << "WriteStr D300 sucess " << endl;
else
std::cout << "WriteStr D300 failed " << endl;
//read 字符串
char str2[30];
int nReg6 = client.ReadD(300, 15, &str2);
if (0 == nReg6)
std::cout << "ReadStr D300 = " << str2 << endl;
std::cin.get();
return 0;
}
以上就是全部源码,希望能帮到各位小伙伴
(不发邮箱了,麻烦)