当前位置:网站首页>Mitsubishi PLC SLmP (MC) protocol

Mitsubishi PLC SLmP (MC) protocol

2022-07-07 23:05:00 weixin_ thirty-nine million nine hundred and twenty-six thousan

// For MITSUBISHI PLC, May refer to mx component5.0( See previous articles for details ) Communications

// This article self writes the resolution protocol .

// In this paper c++ builder The platform and FX5U Debugging successful
#ifndef _SlmpProtocolClient_
#define _SlmpProtocolClient_
#include <winsock2.h>
#include <stdlib.h>
#include <iostream>
#include <string>

// using System.Net.Socket;
class SlmpProtocolClient
{
public:
    SlmpProtocolClient();
    ~SlmpProtocolClient();
public    :
    int Open() ;
    int Close();
    int ReadDRegister(short address, short len, unsigned short* short_array);
    int ReadMBit(short adress, short len, unsigned short* short_array);
    int WriteDRegister(short address, unsigned short short_value);
    int WriteMBit(short address, unsigned short short_value);
    void init2();

public :
    bool Connected;
private:
    WSADATA wsaData;
    sockaddr_in sockAddr;
    SOCKET sock;
    std::string tipstr[20], tipstr2[20];
    void GetHighLowByte(const short addrss, unsigned char& HByte, unsigned char& LByte);

};
#endif

#include "SlmpProtocolClient.h"
//#include <winsock2.h> //

SlmpProtocolClient::SlmpProtocolClient()
{

    init2();
}
void SlmpProtocolClient::init2() {
    tipstr[0] = " Fix ";
    tipstr[1] = "----";
    tipstr[2] = "----";
    tipstr[3] = "----";
    tipstr[4] = "----";
    tipstr[5] = "----";
    tipstr[6] = " Fix ";
    tipstr[7] = " length L";
    tipstr[8] = " length H";
    tipstr[9] = " End code L";
    tipstr[10] = " End code H";
    tipstr[11] = " DXXXn-L";
    tipstr[12] = " DXXXn-H";
    tipstr[13] = " DXXXn+1-L";
    tipstr[14] = " DXXXn+1-H";
    tipstr[15] = " DXXXn+2-L";
    tipstr[16] = " DXXXn+2-H";


    tipstr2[0] = " Fix ";
    tipstr2[1] = "----";
    tipstr2[2] = "----";
    tipstr2[3] = "----";
    tipstr2[4] = "----";
    tipstr2[5] = "----";
    tipstr2[6] = " Fix ";
    tipstr2[7] = " length L";
    tipstr2[8] = " length H";
    tipstr2[9] = " End code L";
    tipstr2[10] = " End code H";
    tipstr2[11] = " Mn | Mn + 1";
    tipstr2[12] = " MXXX2n+2| MXXXn + 3";
    tipstr2[13] = " MXXXn+4| MXXXn + 5";
}
SlmpProtocolClient::~SlmpProtocolClient() 
{
    Close();
}
int SlmpProtocolClient::Close()
{
    closesocket(sock);
    // End of use DLL
    WSACleanup();
    Connected=false;
    return 0;

}

int SlmpProtocolClient::Open()
{
    WSAStartup(MAKEWORD(2, 2), &wsaData);
    // Create socket
    sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
    // Request to the server

    memset(&sockAddr, 0, sizeof(sockAddr));  // Every byte uses 0 fill
    sockAddr.sin_family = PF_INET;
    sockAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
   //sockAddr.sin_addr.s_addr = inet_addr("192.168.10.150");
    sockAddr.sin_port = htons(1234);
  // sockAddr.sin_port = htons(4999);
    int ret=connect(sock, (SOCKADDR*)&sockAddr, sizeof(SOCKADDR));
    if (ret==0) {
      Connected=true;
    }
    return ret;
}

int SlmpProtocolClient::ReadDRegister(short address,short len, unsigned short * short_array)
{
    SYSTEMTIME sys, sy2;
    int a = 0;
    char* str = new char[30];
    while (a <1)
    {
      /*  GetLocalTime(&sys);
        std::cout << sys.wSecond << ":" << sys.wMilliseconds << std::endl;*/


        //50 00 00 FF FF 03 00 0C 00 10 00 01 04 00 00 64 00 00 A8 14 00
        str[0] = 0x50;// The bank started 7 Row fixation
        str[1] = 0x00;
        str[2] = 0x00;
        str[3] = 0xFF;
        str[4] = 0xFF;
        str[5] = 0x03;
        str[6] = 0x00;// This bank and above are fixed
        str[7] = 0x0C;// length L byte
        str[8] = 0x00;// length H byte
        str[9] = 0x10;// Monitor timer L
        str[10] = 0x00;// Monitor timer H
        str[11] = 0x01;//CMD- Bulk read -L
        str[12] = 0x04;//CMD- Bulk read -H
        str[13] = 0x00;// Son CMD-L
        str[14] = 0x00;// Son CMD-H
        //str[15] = 0x64;// Start address -L
        //str[16] = 0x00;// Start address -Middle
        //str[15] = 0x40;// Start address -L
        //str[16] = 0x01;// Start address -Middle
        unsigned char hByte, lByte;
        GetHighLowByte(address, hByte, lByte);
        str[15] = lByte;// Start address -L
        str[16] = hByte;// Start address -Middle
        str[17] = 0x00;// Start address -H

        str[18] = 0xA8;// Express D spot
        unsigned char hByte2, lByte2;
        //str[19] = 0x03;// Read length -L
        //str[20] = 0x00;// Read length -H
        GetHighLowByte(len, hByte2, lByte2);

        str[19] = lByte2;// Read length -L
        str[20] = hByte2;// Read length -H
         
     
        send(sock, str, 21, NULL);// Read D The length of the message sent by the register =21 byte

        // Sleep(1);
         // Receive data from server
        char szBuffer[MAXBYTE] = { 0 };
        int m;
        m=recv(sock, szBuffer, MAXBYTE, NULL);

        // Output received data
        //printf("Message form server: %s\n", szBuffer);
        //printf("Message form server:\n ");

      /*  for (size_t i = 0; i < 13; i++)
        {
            if ((unsigned char)szBuffer[i] < 16)
            {
                printf("0%x  ", (unsigned char)szBuffer[i]);
            }
            else
            {
                printf("%x  ", (unsigned char)szBuffer[i]);
            }
            std::cout << "--" << tipstr[i] << std::endl;
        }*/

        // Put the read ones in the array , The following is based on the index number of the array from 0 Begin to explain the meaning

        //    szBuffer[0]:0xD0,-- Fix
        //    szBuffer[1]:0X00,-- Fix
        //    szBuffer[2]:0X00,-- Fix
        //    szBuffer[3]:0XFF,-- Fix
        //    szBuffer[4]:0XFF,-- Fix
        //    szBuffer[5]:0X03,-- Fix
        //    szBuffer[6]:0X00,-- Fix
        //    szBuffer[7]: The response data is long L byte , As read 1 A word :0x04,2 word :0x06, Three words 0x08, By analogy
        //    szBuffer[8]: The response data is long and high bytes
        // -------- from szBuffer[9] Start calculating the length -----
        //    szBuffer[9]:0x00,-- End code , If not 0 Is abnormal
        //    szBuffer[10]:0x00,-- End code , If not 0 Is abnormal
        //    szBuffer[11]:Dn Of L byte
        //    szBuffer[12]:Dn Of H byte
        //    szBuffer[13]:Dn+1 Of L byte
        //    szBuffer[14]:Dn+1 Of H byte
        //    szBuffer[15]:Dn+2 Of L byte
        //    szBuffer[16]:Dn+2 Of H byte
        
        //   When the reception is complete , The first step is to check whether the end code is 0, If 0, Go to the next step , Otherwise, the data will be discarded
        //   The second step is to judge whether the response data length is equal to 2* Number of words +2, If equal , Go to the next step
        //   The third step is from szBuffer[11] Start taking a few words of data , Pay attention to the high and low bytes , Such as Dn=256*szBuffer[12]+szBuffer[11]
        short end_code= 256 * (unsigned char)szBuffer[10] + (unsigned char)szBuffer[9];
        if (end_code != 0)
        {
            return -1;
        }

        short response_len= 256 * (unsigned char)szBuffer[8] + (unsigned char)szBuffer[7];
        if (response_len!=(len*2+2))
        {
            return -1;
        }

        for (size_t i = 0; i < len; i++)
        {
            *(short_array+i) = 256 * (unsigned char)szBuffer[12+i*2] + (unsigned char)szBuffer[11+i*2];
            //std::cout << " Read page "<<i+1<<" A word =" << *short_array << std::endl;
        }
        /*std::cout << " Read page 1 A word =" << 256 * (unsigned char)szBuffer[12] + (unsigned char)szBuffer[11] << std::endl;
        std::cout << " The first 2 A word =" << 256 * (unsigned char)szBuffer[14] + (unsigned char)szBuffer[13] << std::endl;
        std::cout << " The first 3 A word =" << 256 * szBuffer[16] + szBuffer[15] << std::endl;*/
       
        /*GetLocalTime(&sy2);
        std::cout << std::endl;
        std::cout << sy2.wSecond << ":" << sy2.wMilliseconds << std::endl;
        std::cout << std::endl;*/

        a++;
       // Sleep(1);
    }
    delete[] str;
    return  0;
}
int SlmpProtocolClient::WriteDRegister(short address, unsigned short short_value)
{
    SYSTEMTIME sys, sy2;
    int a = 0;
    char* str = new char[30];
    while (a < 1)
    {
        GetLocalTime(&sys);
        std::cout << sys.wSecond << ":" << sys.wMilliseconds << std::endl;


        //50 00 00 FF FF 03 00 0C 00 10 00 01 04 00 00 64 00 00 A8 14 00
        str[0] = 0x50;// The bank started 7 Row fixation
        str[1] = 0x00;
        str[2] = 0x00;
        str[3] = 0xFF;
        str[4] = 0xFF;
        str[5] = 0x03;
        str[6] = 0x00;// This bank and above are fixed
        //str[7] = 0x12;// length L byte -------- Write three words 0x12, Write 2 A word ,0x10, Write a word ,0X0E
        str[7] = 0x0E;// length L byte -------- Write three words 0x12, Write 2 A word ,0x10, Write a word ,0X0E
        str[8] = 0x00;// length H byte --------
        str[9] = 0x10;// Monitor timer L
        str[10] = 0x00;// Monitor timer H
        str[11] = 0x01;//CMD- Batch write -L
        str[12] = 0x14;//CMD- Batch write -H
        str[13] = 0x00;// Son CMD-L
        str[14] = 0x00;// Son CMD-H
        //str[15] = 0x64;// Start address -L----- change
        //str[16] = 0x00;// Start address -Middle----- change
        unsigned char hByte, lByte;
        GetHighLowByte(address, hByte, lByte);
        str[15] = lByte;// Start address -L
        str[16] = hByte;// Start address -Middle
        str[17] = 0x00;// Start address -H----- change
        str[18] = 0xA8;// Express D spot
        //str[19] = 0x03;// Write length -L------- change
        str[19] = 0x01;// Write length -L------- change
        str[20] = 0x00;// Write length -H------- change

        //str[21] = 0x0C;// write in Dn-L------- change
        //str[22] = 0x00;// write in Dn-H------- change
        unsigned char hByte2, lByte2;
        GetHighLowByte(short_value, hByte2, lByte2);

        str[21] = lByte2;// Read length -L
        str[22] = hByte2;// Read length -H


        //str[23] = 0x0D;// write in Dn+1-L------- change
        //str[24] = 0x00;// write in Dn+1-H------- change
        //str[25] = 0x0E;// write in Dn+2-L------- change
        //str[26] = 0x00;// write in Dn+2-H------- change
            //"00 FF FF 03 00 0C 00 10 00 01 04 00 00 64 00 00 A8 01 00
        //send(sock, str, strlen(str) + sizeof(char), NULL);
        send(sock, str, 23, NULL);//------------- Pay attention to the length , Write 3 A word :len=27,2 A word :len=25,1 A word :len=23

        // Sleep(20);
         // Receive data from server
        char szBuffer[MAXBYTE] = { 0 };

        recv(sock, szBuffer, MAXBYTE, NULL);
        //  PLC feedback : D0 00 00 FF FF 03 00 02 00 00 00 (00:14:55:188)

        // Output received data
        //printf("Message form server: %s\n", szBuffer);
        if (0xD0 != (unsigned char)(szBuffer[0])  ) return 1;
        if (0x02 != (unsigned char)szBuffer[7]) return 2;
        if (0 != szBuffer[9]) return 3;
        if (0 != szBuffer[10]) return 4;

       /* GetLocalTime(&sy2);
        std::cout << std::endl;
        std::cout << sy2.wSecond << ":" << sy2.wMilliseconds << std::endl;
        std::cout << std::endl;*/

        a++;
        Sleep(1);
    }
    delete[] str;
    return 0;
}

int SlmpProtocolClient::ReadMBit(short address, short len, unsigned short* short_array)
{
    SYSTEMTIME sys, sy2;
    int a = 0;
    char* str = new char[30];
    unsigned short temp;
    unsigned short q;
    unsigned short m;
    unsigned short n;
    unsigned short k;
    m = len % 16;
    
    n = (m==0)? (len - m) / 16:(len - m) / 16+1;
    while (a < 1)
    {
      //  GetLocalTime(&sys);
        //std::cout << sys.wSecond << ":" << sys.wMilliseconds << std::endl;


        //50 00 00 FF FF 03 00 0C 00 10 00 01 04 00 00 64 00 00 A8 14 00
        str[0] = 0x50;// The bank started 7 Row fixation
        str[1] = 0x00;
        str[2] = 0x00;
        str[3] = 0xFF;
        str[4] = 0xFF;
        str[5] = 0x03;
        str[6] = 0x00;// This bank and above are fixed
        str[7] = 0x0C;// length L byte
        str[8] = 0x00;// length H byte
        str[9] = 0x10;// Monitor timer L
        str[10] = 0x00;// Monitor timer H
        str[11] = 0x01;//CMD- Bulk read -L
        str[12] = 0x04;//CMD- Bulk read -H
        str[13] = 0x00;// Son CMD-L
        str[14] = 0x00;// Son CMD-H
        //str[15] = 0x64;// Start address -L--- change
        //str[16] = 0x00;// Start address -Middle--- change
        unsigned char hByte, lByte;
        GetHighLowByte(address, hByte, lByte);
        str[15] = lByte;// Start address -L
        str[16] = hByte;// Start address -Middle
        str[17] = 0x00;// Start address -H--- change
        str[18] = 0x90;// Express M spot
        unsigned char hByte2, lByte2;
        //str[19] = 0x03;// Read length -L
        //str[20] = 0x00;// Read length -H
        GetHighLowByte(n, hByte2, lByte2);

        str[19] = lByte2;// Read length -L
        str[20] = hByte2;// Read length -H
        
        
        send(sock, str, 21, NULL);// / Read M The length of the sent message =21 byte

        // Sleep(20);
         // Receive data from server
        char szBuffer[MAXBYTE] = { 0 };

        recv(sock, szBuffer, MAXBYTE, NULL);

        // Output received data
        //printf("Message form server: %s\n", szBuffer);
       /* printf("Message form server:\n ");
        for (int i = 0; i < 13; i++)
        {

            if ((unsigned char)szBuffer[i] < 16)

            {

                printf("0%x  ", (unsigned char)szBuffer[i]);
            }
            else
            {
                printf("%x  ", (unsigned char)szBuffer[i]);
            }
            std::cout << tipstr2[i] << std::endl;

        }

        GetLocalTime(&sy2);*/
        // Put the read ones in the array , The following is based on the index number of the array from 0 Begin to explain the meaning

      //    szBuffer[0]:0xD0,-- Fix
      //    szBuffer[1]:0X00,-- Fix
      //    szBuffer[2]:0X00,-- Fix
      //    szBuffer[3]:0XFF,-- Fix
      //    szBuffer[4]:0XFF,-- Fix
      //    szBuffer[5]:0X03,-- Fix
      //    szBuffer[6]:0X00,-- Fix
      //    szBuffer[7]: The response data is long L byte , As read <=16:0x04,2 word :0x06, Three words 0x08, By analogy
      //    szBuffer[8]: The response data is long and high bytes
      // -------- from szBuffer[9] Start calculating the length -----
      //    szBuffer[9]:0x00,-- End code , If not 0 Is abnormal
      //    szBuffer[10]:0x00,-- End code , If not 0 Is abnormal
      //    szBuffer[11]:Mn~M(n+7)
      //    szBuffer[12]:M(n+8)~M(n+15)

      //   When the reception is complete , The first step is to check whether the end code is 0, If 0, Go to the next step , Otherwise, the data will be discarded
      //   The second step is to judge whether the response data length is equal to 2* Number of words , If equal , Go to the next step
      //   The third step is from szBuffer[11] Start taking a few words of data , Pay attention to the high and low bytes ,
        // Such as Mn= szBuffer[12]& 0x01,Mn(n+1)= szBuffer[12]& 0x02,M(n+15)= szBuffer[13]& 0x80,Mn(n+1)= szBuffer[12]& 0x02,

        short end_code = 256 * (unsigned char)szBuffer[10] + (unsigned char)szBuffer[9];
        if (end_code != 0)
        {
            return -1;
        }

        short response_len = 256 * (unsigned char)szBuffer[8] + (unsigned char)szBuffer[7];
        if (response_len != (n * 2 + 2))
        {
            return -1;
        }
           
        
       
    
            k = 0;
            unsigned u;
            for (size_t i = 0; i <n; i++)
            {
                
                temp = 256 * (unsigned char)szBuffer[12 + i * 2] + (unsigned char)szBuffer[11 + i * 2];
                u = temp;
                for (size_t j = 0; j< 16; j++)
                {
                    
                    short_array[k] =( ((u & 1) == 0) ? 0 : 1);
                    u = u >> 1;
                    k++;
                    if (k>=len)
                    {
                        break;
                    }
                }
            }

           
           
        

      /*  unsigned short temp = 256 * (unsigned char)szBuffer[12] + (unsigned char)szBuffer[11];
        bool b;
        for (int i = 0; i < 16; i++)
        {
            b = (temp == 1) ? true : false;
            std::cout << " The first " << i + 1 << " position :" << b << std::endl;
            temp = temp >> 1;
        }*/


    /*    std::cout << std::endl;
        std::cout << sy2.wSecond << ":" << sy2.wMilliseconds << std::endl;
        std::cout << std::endl;*/
        // delete[] str;
        a++;
        Sleep(1);
    }
    delete[] str;
    return 0;
}

int SlmpProtocolClient::WriteMBit(short address, unsigned short short_value)
{
    //SYSTEMTIME sys, sy2;
    int a = 0;
    char* str = new char[30];
    while (a < 1)
    {/*
        GetLocalTime(&sys);
        std::cout << sys.wSecond << ":" << sys.wMilliseconds << std::endl;*/


        //50 00 00 FF FF 03 00 0C 00 10 00 01 04 00 00 64 00 00 A8 14 00
        str[0] = 0x50;// The bank started 7 Row fixation
        str[1] = 0x00;
        str[2] = 0x00;
        str[3] = 0xFF;
        str[4] = 0xFF;
        str[5] = 0x03;
        str[6] = 0x00;// This bank and above are fixed
        str[7] = 0x0D;// length L byte -------- Write three words 0x12, Write 2 A word ,0x10, Write a word ,0X0E
        str[8] = 0x00;// length H byte --------
        str[9] = 0x10;// Monitor timer L
        str[10] = 0x00;// Monitor timer H
        str[11] = 0x01;//CMD- Batch write -L
        str[12] = 0x14;//CMD- Batch write -H
        str[13] = 0x01;// Son CMD-L
        str[14] = 0x00;// Son CMD-H
        //str[15] = 0x64;// Start address -L----- change
        //str[16] = 0x00;// Start address -Middle----- change
        unsigned char hByte, lByte;
        GetHighLowByte(address, hByte, lByte);
        str[15] = lByte;// Start address -L
        str[16] = hByte;// Start address -Middle
        str[17] = 0x00;// Start address -H----- change
        str[18] = 0x90;// Express M spot
        str[19] = 0x01;// Write length -L------- change
        str[20] = 0x00;// Write length -H------- change
        str[21] = ((short_value==0)?0x00:0x10);// write in Mn,M(n+1)------- change
        //str[22] = 0x00;// write in M(n+2),M(n+3)------ change

            //"50 00 00 FF FF 03 00 0D 00 10 00 01 14 01 00 64 00 00 90 01 00 10 
        //send(sock, str, strlen(str) + sizeof(char), NULL);
        send(sock, str, 22, NULL);//------------- Pay attention to the length , Write 3 A word :len=27,2 A word :len=25,1 A word :len=23

        // Sleep(20);
         // Receive data from server
        char szBuffer[MAXBYTE] = { 0 };

        recv(sock, szBuffer, MAXBYTE, NULL);

        // Output received data
        //printf("Message form server: %s\n", szBuffer);
       /* printf("Message form server:\n ");
        for (size_t i = 0; i < 11; i++)
        {

            if ((unsigned char)szBuffer[i] < 16)
            {
                printf("0%x  ", (unsigned char)szBuffer[i]);
            }
            else
            {
                printf("%x  ", (unsigned char)szBuffer[i]);
            }
            std::cout << "--" << tipstr[i] << std::endl;

        }


        GetLocalTime(&sy2);
        std::cout << std::endl;
        std::cout << sy2.wSecond << ":" << sy2.wMilliseconds << std::endl;
        std::cout << std::endl;*/
        //  PLC feedback : D0 00 00 FF FF 03 00 02 00 00 00 (00:14:55:188)

       // Output received data
       //printf("Message form server: %s\n", szBuffer);
        if (0xD0 != (unsigned char)(szBuffer[0])) return 1;
        if (0x02 != (unsigned char)szBuffer[7]) return 2;
        if (0 != szBuffer[9]) return 3;
        if (0 != szBuffer[10]) return 4;
        a++;
        Sleep(1);
    }
    delete[]  str;
    return 0;
}
void SlmpProtocolClient::GetHighLowByte(const short addrss, unsigned char & HByte, unsigned char & LByte)
{
    LByte = addrss % 256;
    HByte = (addrss - LByte) / 256;
}

原网站

版权声明
本文为[weixin_ thirty-nine million nine hundred and twenty-six thousan]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/188/202207071920562872.html