C++上位機通過socket讀寫PLC


做上位機的同行應該有切實體會:由於某些廠家的通信協議不開放的緣故,通信是個很費勁的事,特別是和西門子的通信。就我目前所知,通信手段主要依賴於兩條路:

a.OPC,我們自己開發client端,server端借助simatic net 或者kepserver 

b.組態軟件,組態軟件就不說了,稍微會點編程的人都不想用這東西。

OPC服務端和組態軟件都需要花錢購買(當然盜版除外),並且是一次性的,使用體驗感非常不爽,基於如此,我一直想找一個可替換的方案用於和PLC通信,經過多方面的探索驗證,終於找出一條不用經過任何中轉,借助socket完全用代碼實現的通信路徑,主要特征如下:

1.VS2015 C++ MFC開發

2.可實現和200,300,400,1500,1200對接通信(200沒測過)

3.可直接讀寫台達(ModBus)信息

1.台達指令示意

 

     //*********************0F功能碼,寫多個位寄存器的值**********************************//

     /*********************************************************************************/

    //****00 00  00 00     00 08         01       0F    A0 00  00 08   01     81********//

    //**** 事務 | 協議  |Modbus數據長度|Modbus站號|功能碼|首地址|寫入個數|字節數| 值*******//

     CString CDelta::WriteMoreRegistersBit(int FunNum, int Mod_Sta, int FristAds, int bitNum, int* pVal)

     {  

          CString strModlen,//modbus數據長度

          strFun,//功能碼

          strMsta, //PLC站

          strFristAds,//首地址

         strWtbitnum,//寫入個數

         strWtbytenum,//地址個數(字節)

         strWtVal,//數值

         strlabel;//指令

        

         strModlen.Format(_T("%04X"), (int)ceil(bitNum /15.0) + 7);//modbus數據長度

         strFun.Format(_T("%02X"), 15);

         strMsta.Format(_T("%02X"), Mod_Sta);

         strFristAds.Format(_T("%04X"), FristAds);

         strlabel = _T("00 00 00 00 ") + strModlen + _T(" ") + strMsta + _T(" ") + strFun + _T(" ") + strFristAds;

         strWtbitnum.Format(_T("%04X"), bitNum);

         strWtbytenum.Format(_T("%02X"), (int)ceil(bitNum / 15.0));

         strlabel = strlabel + _T(" ") + strWtbitnum + _T(" ") + strWtbytenum;

         for (int i = 0; i < (int)ceil(bitNum / 15.0); i++)

         {

               strWtVal.Format(_T("%02X"), *(pVal + i));

               strlabel += _T(" ") + strWtVal;

         }

         return strlabel;

    }

   2.西門子指令示意

  

    /**01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23  24 25      26 27   28 29 30 31**/

    /**03 00 00 1F 02 F0 80 32 01 00 00 00 01 00 0E 00 00 07 01 12 0A 10 02  00 02      00 0A   82 00 00 00**Y-output/

    CString CSimatic::ReadRegXYBit(int seqnum, int Fun, int Rdlen, int DataType, int offset)//讀取X-input

    {

       CString strHead = _T("03 00"),                   

       strtolen = _T("00 1F"),                         

       strconst1 = _T("02 F0 80 32 01 00 00"),          

       strseqnum,                                        //序列號

       strconst2 = _T("00 0E"),                       

       strconst3 = _T("00 00"),                       

       strFun,                                           //功能碼

       strconst4 = _T("01 12 0A 10 02"),              

       strRdlen,                                         //讀取長度

       strDB = _T("00 00"),                             

       strDataType,                                      //訪問數據類型

       stroffset;

      

       strseqnum.Format(_T("%04X"), seqnum);

       strFun.Format(_T("%02X"), Fun);

       strRdlen.Format(_T("%04X"), Rdlen);

       strDataType.Format(_T("%02X"), DataType);

       stroffset.Format(_T("%06X"), offset);

       CString strlabel;

       strlabel = strHead + _T(" ") + strtolen + _T(" ") +

       strconst1 + _T(" ") + strseqnum + _T(" ") +

       strconst2 + _T(" ") + strconst3 + _T(" ") +

       strFun + _T(" ") + strconst4 + _T(" ") +

       strRdlen + _T(" ") + strDB + _T(" ") +

       strDataType + _T(" ") + stroffset;

     

    return strlabel;

    }

試用版工具可免費試用,

有意者請訪問https://blog.csdn.net/li634471989/article/details/90291056,

或加q:634471989了解


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM