MCU & PLC

C# Melsec MxComponent V4 #3 코딩편 (double word 단위로 보내기 받기)

sheepone 2021. 7. 6. 10:02
반응형

실행 화면

 

Form 구성

using System;
using System.Configuration;
using System.Windows.Forms;

namespace MxComponentV4
{
    public partial class Form1 : Form
    {
        public static Plc_MxComponentV4 mxComponent ;

        public Form1()
        {
            InitializeComponent();
            int iNo = int.Parse(Option.Plc_MxComponentNo);
            mxComponent = new Plc_MxComponentV4(iNo);
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            if(mxComponent != null)
            {
                bool bIsOnline = mxComponent.IsOnline();

                if(!bIsOnline) lbConnected.Text = "PLC DISCONNECTED";
                else           lbConnected.Text = "PLC CONNECTED";
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            /*
             * //int  iRead = 0 ; //비트로 읽을때
             * //bool bCheck = mxComponent.GetDevice(Option.Plc_AddReadBit, out iRead);
             * string sRead = ""; //블럭으로 읽을때 
             * mxComponent.ReadDeviceBlock(Option.Plc_AddRead, out sRead);
             * listBox1.Items.Add("Read Block : " + sRead);
             */ 
            
            //Get Double Word
            int i1 = mxComponent.GetDoubleDevice(Option.Plc_AddRead);
            listBox1.Items.Add("Read Block : " + i1.ToString());
            
        }

        private void button1_Click(object sender, EventArgs e)
        {
            /*
             * //mxComponent.SetDevice(Option.Plc_AddReadBit,0); //비트로 쓸때
             * string sWrite = textBox1.Text ; //블럭으로 쓸때
             * mxComponent.WriteDeviceBlock(Option.Plc_AddRead, sWrite);
             * listBox1.Items.Add("Write Block : " + sWrite);
             */
            
            //Set Double Word
            string sWrite = textBox1.Text ; //
            int    i1 = Convert.ToInt32(sWrite)    ;
            mxComponent.SetDoubleDevice(Option.Plc_AddWrite,i1);
            listBox1.Items.Add("Write Block : " + i1);
        }
    }

    public static class Option
    {
        public static string Plc_MxComponentNo{ get; } = ConfigurationManager.AppSettings["Plc_MxComponentNo" ];
        public static string Plc_AddRead      { get; } = ConfigurationManager.AppSettings["Plc_AddRead"       ];
        public static string Plc_AddReadBit   { get; } = ConfigurationManager.AppSettings["Plc_AddReadBit"    ];
        public static string Plc_AddWrite     { get; } = ConfigurationManager.AppSettings["Plc_AddWrite"      ];
        
    }
}

 

MxComponent 모듈 구성

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Timers;
using System.Windows.Forms;

namespace MxComponentV4
{
    //ActProgTypeLib 로 하면 Communication Setup Utility 안쓰고 오픈 할수 있다
    //ActUtlTypeLib 로 하면 Communication Setup Utility 로 등록하고 써야 한다 0~
    public class Plc_MxComponentV4
    {
        public enum CpuStsType
        {
            RUN   = 0,
            STOP  = 1,
            PAUSE = 2
        }

        private int    iErrorCode   = 0 ;
        private string sErrorCode   = "";

        private int iLogicalStationNumber = 0;

        // public  bool m_IsOnline = false;
        private Object thisLock = new Object();

        private ActUtlTypeLib.ActUtlType actUtlType;
        //private ActProgTypeLib.ActMLProgType ActMLProgType ;
        
        private bool   bConnected = false ;
        public  bool   BConnected { get => bConnected; }
        public  string SErrorCode { get => sErrorCode; }
        public  int    IErrorCode { get => iErrorCode; }

        System.Timers.Timer timer = new System.Timers.Timer();

        public Plc_MxComponentV4(int iLogicalStationNumber)
        {
            actUtlType = new ActUtlTypeLib.ActUtlType();

            actUtlType.OnDeviceStatus += new ActUtlTypeLib._IActUtlTypeEvents_OnDeviceStatusEventHandler(OnDeviceStatusEvent);

            this.iLogicalStationNumber = iLogicalStationNumber ;

            timer.Interval = 1000;
            timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elasped);
            timer.Enabled = true ;
           
        }

        void timer_Elasped(object sender, System.Timers.ElapsedEventArgs e)
        {
            timer.Enabled = false;

            if (!IsOnline())
            {
                Debug.WriteLine("!IsOnline() ReOpen Stt");
                Open(iLogicalStationNumber);
                Debug.WriteLine("!IsOnline() ReOpen End");
            }

            timer.Enabled = true;
        }


        /// <summary>
        /// Get double word //2Word 4Byte 32bit
        /// </summary>
        /// <param name="device"></param>
        /// <param name="data"></param>
        /// <returns></returns>
        public int GetDoubleDevice(string device)
        {
            int[] data = new int[2];
            int Yint = -100000;
            try
            {
                actUtlType.ReadDeviceBlock(device, 2, out data[0]);
                string value1 = Convert.ToString(data[0], 2);
                string value2 = Convert.ToString(data[1], 2);
                string bitString = value2 + value1;
                Yint = Convert.ToInt32(bitString, 2);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            return Yint;
        }

        /// <summary>
        /// Set double word //2Word 4Byte 32bit
        /// </summary>
        /// <param name="address"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public bool SetDoubleDevice(string address, int value)
        {
            Int32 n = -2;
            string nt = Convert.ToString(n, 2);
           // Int32 n1 = Convert.ToInt32(nt, 2);
            UInt32 n2 = Convert.ToUInt32(nt, 2);

            int[] dataTemp = new int[2];
            long a = int.MaxValue;
            long b = int.MinValue;
            long c = a - b;
            long d = 0;
            if (value > 0)
            {

                dataTemp[0] = (int)(value & 0x0000ffff);
                dataTemp[1] = (int)(value >> 16);
            }
            else
            {
                //  c + value( 异或)  反码 => 补码
                d = c + value + 1;
                
                dataTemp[0] = (int)(d & 0x0000ffff); //后16位 数据
                dataTemp[1] = (int)(d >> 16); //前16位 符号
            }
            int result = actUtlType.WriteDeviceBlock(address, 2, ref dataTemp[0]);
            if (0 == result)
                return true;
            else
                return false;
            
        }

        //-------------------------------------------------------------------------------------------
        //비전 폴더 이름 넘기고 받기 
        //-------------------------------------------------------------------------------------------
        //int  [] iInt = new int  [100];
        short[] sInt = new short[100];
        
        public bool WriteDeviceBlock(string _sAdd, string _str)
        {
            if(_str == "")
            {
                sInt = new short[10];
                Array.Clear(sInt, 0, sInt.Length);
                bool bCheck1 = WriteDeviceBlock2(_sAdd,sInt.Length,ref sInt[0]);
                return bCheck1;
            }
            //if(!_str.Contains(Option.Save_Path)) return false ;
            //
            ////
            ////string sStr = @"D:\DWAMSaveImage\2020Y\12M\17D\131511_K30" ;
            //int    iStt = _str.IndexOf(Option.Save_Path) ;
            //int    iLen = Option.Save_Path.Length;
            //string sStr = _str.Substring(iStt + iLen,20);

            string str = _str;
            string[] str_temp ;

            if (str.Length % 2 == 0)
            {
                str_temp = new string[str.Length / 2];
                sInt     = new short [str_temp.Length];

                for (int i = 0; i < str.Length / 2; i++)
                {
                    str_temp[i] = str.Substring(i * 2, 2);
                }

                for (int i = 0; i < str_temp.Length; i++)
                {
                    byte[] bytes = Encoding.ASCII.GetBytes(str_temp[i]);
                    short sh = BitConverter.ToInt16(bytes, 0);
                    sInt[i] = sh;
                }
            }
            else
            {
                str_temp = new string[(str.Length / 2) + 1];
                sInt     = new short [str_temp.Length];

                for (int i = 0; i < str.Length / 2 + 1; i++)
                {
                    if (i < (str.Length - 1) / 2)
                        str_temp[i] = str.Substring(i * 2, 2);
                    else
                        str_temp[i] = str.Substring(i * 2, 1);
                }

                for (int i = 0; i < str_temp.Length; i++)
                {
                    if (i < str_temp.Length - 1)
                    {
                        byte[] bytes = Encoding.ASCII.GetBytes(str_temp[i]);
                        short sh = BitConverter.ToInt16(bytes, 0);
                        sInt[i] = sh;
                    }
                    else
                    {
                        char data = Convert.ToChar(str_temp[i].Substring(0, 1));
                        sInt[i] = (short)data;
                    }
                }
            }

            bool bCheck2 = WriteDeviceBlock2(_sAdd,sInt.Length,ref sInt[0]);
            return bCheck2 ;
           
        }
        public bool ReadDeviceBlock(string _sAdd, out string _str)
        {
            sInt = new short[10];
            Array.Clear(sInt, 0, sInt.Length);
            bool bCheck = ReadDeviceBlock2(_sAdd, sInt.Length, out sInt[0]);

            _str = "";
            if (bCheck)
            {
                for (int i = 0; i < sInt.Length; i++)
                {
                    byte[] bytes = BitConverter.GetBytes(sInt[i]);
                    _str += Encoding.Default.GetString(bytes);
                }
            }

            return bCheck ;

            //_str = "" ;
            //Array.Clear(sInt, 0, sInt.Length);
            //bool bCheck = ReadDeviceBlock2(_sAdd, sInt.Length,out sInt[0]);
            //for (int i = 0; i < sInt.Length; i++)
            //{
            //    if(sInt[i] != 0) _str += Convert.ToChar(sInt[i]);
            //}
            //return bCheck ;
        }

        public int Initialization(int iLogicalStationNumber)
        {
            this.iLogicalStationNumber = iLogicalStationNumber;

            return 0;
        }

        public bool IsOnline()
        {
            //SM400 항상 ON • 항상 ON한다. S (매회END) M9036
            //SM401 항상 OFF • 항상 OFF한다. S (매회END) M9037

            int iRst  = -1;
            int iData =  0;           

            lock (thisLock)
            {
                try
                {
                    iRst = actUtlType.GetDevice("SM400" , out iData);
                }   
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }
            
            if (iRst == 0 && iData == 1)
            {
                bConnected = true ;
                return true;
            }

            bConnected = false ;
            return false;
        }

        public bool Open(int iLogicalStationNumber)
        {
            int iRst = -1;

            this.iLogicalStationNumber = iLogicalStationNumber;

            actUtlType.ActLogicalStationNumber = this.iLogicalStationNumber;

            actUtlType.ActPassword = "";
            Debug.WriteLine("!IsOnline() ReOpen 1");
            lock (thisLock)
            {
                try
                {
                    //ActMLProgType.ActUnitType = iact
                    //ActMLProgType.Open();
                    actUtlType.Close();
                    iRst = actUtlType.Open();
                }
                catch (Exception ex)
                {
                    Debug.WriteLine("!IsOnline() ReOpen 2");
                    MessageBox.Show(ex.Message);
                }
            }
            Debug.WriteLine("!IsOnline() ReOpen 3");
            if (iRst == 0)
            {
                //int[] arrDeviceValue = { 1 };
                //EntryDeviceStatus("SM400",1,1,ref arrDeviceValue[0]);
                //actUtlType.OnDeviceStatus += new ActUtlTypeLib._IActUtlTypeEvents_OnDeviceStatusEventHandler(OnDeviceStatusEvent);
                return true;
            }
            else
            {
                //SetError(iRst);
                return false;
            }
        }

        private void SetError(int _iErrorCode)
        {
            /*
            0xF0000001 라이선스 없음 에러 PC 에 라이선스가 부여되지 않았다 . • 라이선스 키 FD 에서 PC 에 라이선스를 부여하십시오 .
            0xF0000002 설정 데이터 읽기 에러 논리 국번의 설정 데이터 읽기에 실패하였다 . • 올바른 논리 국번을 지정하십시오 . • 통신 설정 유틸리티에서 논리 국번을 설정하십시오 .
            0xF0000003 오픈 완료 에러 오픈 상태에서 Open 메소드를 실행하였다 . • 통신 대상 CPU를 변경하는 경우, Close 후 Open 메소드를 실행 하십시오 .
            0xF0000004 미오픈 에러 Open 메소드를 실행하고 있지 않다 . • Open 메소드 실행 후 해당 메소드를 실행하십시오 .                
            0xF0000005 초기화 에러 MX Component 내부 유지 오브젝트의 초기화에 실 패하였다 . • 프로그램을 종료하고 나서 PC 를 재기동하십시오 . • MX Component 를 재인스톨하십시오 .
            0xF0000006 메모리 확보 에러 MX Component 내부 메모리의 확보에 실패하였 다 . • 프로그램을 종료하고 나서 PC 를 재기동하십시오 . • 다른 프로그램을 종료하여 사용 가능 메모리를 확보하십시오 . 
            */

            //0x01809001 GX Simulator2 미기동 에러 GX Simulator2 가 기동되어 있지 않다 • GX Simulator2 를 기동하십시오 .
            sErrorCode = String.Format("0x{0:x8} [HEX]", iErrorCode);
            iErrorCode = _iErrorCode   ;
            MessageBox.Show("MxComponent Error" + sErrorCode);
            //MessageBox.Show(sErrorCode);
        }

        public bool Close()
        {
            timer.Enabled = false;
            if(!bConnected) return true ;

            int iRst = -1;
            lock (thisLock)
            {
                try
                {
                    iRst = actUtlType.Close();
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }

            if (iRst == 0) return true;

            SetError(iRst);
            return false ;
        }

        /// <summary>
        /// 디바이스 1 점을 설정합니다 .
        /// </summary>
        /// <param name="szDevice"></param>
        /// <param name="lData"></param>
        /// <returns></returns>
        public bool SetDevice(string sDevice, int iData)
        {
            if(!bConnected) return false ;

            int iRst  = -1;

            lock (thisLock)
            {
                try
                {
                    iRst = actUtlType.SetDevice(sDevice, iData);
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }
            if (iRst == 0) return true;

            SetError(iRst);
            return false;
        }

        public bool GetDevice(string sDevice, out int lplData)
        {
            lplData = 0;

            if(!bConnected) return false ;

            int iRst  = -1;

            lock (thisLock)
            {
                try
                {
                    iRst = actUtlType.GetDevice(sDevice, out lplData);
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }
            if (iRst == 0) return true;

            SetError(iRst);
            return false;
        }

        /// <summary>
        /// 2 바이트 데이터로 디바이스 1 점을 설정합니다 .
        /// </summary>
        /// <param name="szDevice"></param>
        /// <param name="lData"></param>
        /// <returns></returns>
        public bool SetDevice2(string szDevice, short lData)
        {
            if (!bConnected) return false ;

            int iRst  = -1;
            lock (thisLock)
            {
                try
                {
                    iRst = actUtlType.SetDevice2(szDevice, lData);
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }
            if (iRst == 0) return true;

            SetError(iRst);
            return false;
        }

        public bool GetDevice2(string szDevice, out short lplData)
        {
            lplData = 0;

            if (!bConnected) return false ;

            int   iRst  = -1;

            lock (thisLock)
            {
                try
                {
                    iRst = actUtlType.GetDevice2(szDevice, out lplData);
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }
            if (iRst == 0) return true;

            SetError(iRst);
            return false ;
        }

        public bool ReadDeviceBlock(string szDevice, int iSize, out int lplData)
        {
            lplData = 0 ;

            if (!bConnected) return false ;

            int iRst  = -1;

            lock (thisLock)
            {
                try
                {
                    iRst = actUtlType.ReadDeviceBlock(szDevice, iSize, out lplData);
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }
            if (iRst == 0) return true;

            SetError(iRst);
            return false ;
        }

        /// <summary>
        /// 디바이스의 일괄 쓰기를 실행합니다 .
        /// </summary>
        /// <param name="szDevice">디바이스 명</param>
        /// <param name="iSize">쓰기 점수</param>
        /// <param name="iData">쓰기 디바이스 값</param>
        /// <returns></returns>
        public bool WriteDeviceBlock(string szDevice, int iSize, ref int iData)
        {
            if (!bConnected) return false ;

            int iRst  = -1;

            lock (thisLock)
            {
                try
                {
                    iRst = actUtlType.WriteDeviceBlock(szDevice, iSize, ref iData);
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }
            if (iRst == 0) return true;

            SetError(iRst);
            return false ;
        }

        public bool ReadDeviceBlock2(string szDevice, int iSize, out short lplData)
        {
            lplData = 0;

            if (!bConnected) return false ;

            int   iRst  = -1;

            lock (thisLock)
            {
                try
                {
                    iRst = actUtlType.ReadDeviceBlock2(szDevice, iSize, out lplData);
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }
            if (iRst == 0) return true;

            SetError(iRst);
            return false ;
        }

        /// <summary>
        /// 2 바이트 데이터로 디바이스의 일괄 쓰기를 실행합니다 .
        /// </summary>
        /// <param name="szDevice"></param>
        /// <param name="iSize"></param>
        /// <param name="iData"></param>
        /// <returns></returns>
        public bool WriteDeviceBlock2(string szDevice, int iSize, ref short iData)
        {
            if (!bConnected) return false ;

            int iRst  = -1;

            lock (thisLock)
            {
                try
                {
                    iRst = actUtlType.WriteDeviceBlock2(szDevice, iSize, ref iData);
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }
            if (iRst == 0) return true;

            SetError(iRst);
            return false ;
        }


        public bool ReadBuffer(int lStartIO, int lAddress, int lSize, out short lplData)
        {
            lplData = 0;

            if (!bConnected) return false ;

            int   iRst  = -1;

            lock (thisLock)
            {
                try
                {
                    iRst = actUtlType.ReadBuffer(lStartIO, lAddress, lSize, out lplData);
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }
            if (iRst == 0) return true;

            SetError(iRst);
            return false ;
        }

        /// <summary>
        /// 특수 기능 모듈 버퍼메모리의 값을 씁니다 .
        /// </summary>
        /// <param name="lStartIO"></param>
        /// <param name="lAddress"></param>
        /// <param name="lSize"></param>
        /// <param name="lpsData"></param>
        /// <returns></returns>
        public bool WriteBuffer(int lStartIO, int lAddress, int lSize, ref short lpsData)
        {
            if (!bConnected) return false ;

            int iRst  = -1;

            lock (thisLock)
            {
                try
                {
                    iRst = actUtlType.WriteBuffer(lStartIO, lAddress, lSize, ref lpsData);
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }
            if (iRst == 0) return true;

            SetError(iRst);
            return false ;

        }

        public bool SetCpuStatus(int iOperation)
        {
            if (!bConnected) return false ;

            int iRst  = -1;

            lock (thisLock)
            {
                try
                {
                    iRst = actUtlType.SetCpuStatus(iOperation);
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }

            if (iRst == 0) return true;

            SetError(iRst);
            return false ;

        }

        /// <summary>
        /// EntryDeviceStatus FreeDeviceStatus OnDeviceStatusEvent 셋트
        /// </summary>
        /// <param name="szDeviceList"></param>
        /// <param name="lSize"></param>
        /// <param name="lMonitorCycle">• iMonitorCycle 은 1 초 ~1 시간의 범위 (1~3600 의 초 단위로 설정 ) 로 지정하십시오 .</param>
        /// <param name="lplData"></param>
        /// <returns></returns>
        public bool EntryDeviceStatus(string szDeviceList, int lSize, int lMonitorCycle, ref int lplData)
        {
            if (!bConnected) return false ;

            int iRst  = -1;

            lock (thisLock)
            {
                try
                {
                    iRst = actUtlType.EntryDeviceStatus(szDeviceList, lSize, lMonitorCycle, ref lplData);
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }

            if (iRst == 0) return true;

            SetError(iRst);
            return false ;
        }

        public bool FreeDeviceStatus()
        {
            if (!bConnected) return false ;

            int iRst  = -1;

            lock (thisLock)
            {
                try
                {
                    iRst = actUtlType.FreeDeviceStatus();
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }

            if (iRst == 0) return true;

            SetError(iRst);
            return false ;
            
        }

        public virtual void OnDeviceStatusEvent(String szDevice, int iData, int iReturnCode)
        {
            if (iReturnCode == 0)
            {
                return;
            }
            sErrorCode = String.Format("0x{0:x8} [HEX]", iReturnCode);
            MessageBox.Show(sErrorCode);
            iErrorCode = iReturnCode;
        }

        //-------------------------------------------------------------------------------------------
        //필요할까 해서 해놧더니 필요 없네
        public string StringToHex(string str)
        {
            var sb = new StringBuilder();
            var bytes = Encoding.Unicode.GetBytes(str);
            foreach(var t in bytes)
            {
                sb.Append(t.ToString("X2"));
            }

            return sb.ToString();
        }

        public string HexToString(string hexString)
        {
            var bytes = new byte[hexString.Length / 2];
            for(var i = 0; i < bytes.Length; i++)
            {
                bytes[i] = Convert.ToByte(hexString.Substring(i*2,2),16);
            }

            return Encoding.Unicode.GetString(bytes);
        }

        public string IntToHex(int _int)
        {
            string sHex = _int.ToString("X");
            return sHex;
        }

        public int HexToInt(string _string)
        {
            int iInt = int.Parse(_string,System.Globalization.NumberStyles.HexNumber);
            return iInt;
        }
        //----------------------------------------------------------------------------------
    }
}

 

추가된 부분

public int GetDoubleDevice(string device)

public bool SetDoubleDevice(string address, int value)

 

실제 사용한 소스 파일 포함

MxComponentV4.zip
0.48MB

반응형