VIC-D 시리즈 (엠에프씨코리아 ) 제어 클래스 C#

Software/C#|2023. 3. 22. 10:17
반응형

엠에프씨코리아 업체의 Digital MFC 제품인 VIC - D 시리즈의 통신 제어를 위한 클래스 코드 입니다. 

시리얼 통신을 통해 유량을 제어하고 현재 유량값을 읽어 올수 있습니다.

 

 

public class CVIC_DSeries
{
    /*******************************************************************************
    * CLASS: CVIC_DSeries
    * Version : 1.0.0
    * MFC (Flow Controller) Program  (Manufactured by MFC Korea)
    * Programed by Sihwan Kim
    * Copyright (C) 2019 Photondays, Inc.  All rights reserved.
    * PROTOCOL   :  START, ADDRESS, COMMAND, DATA TYPE, DATA, CHECKSUM, END   (ASCII 형식) 
    * Bytes Num. :    1       2        2          2     0~64      2      1 
    *******************************************************************************/

    private SerialPort m_ComPort;
    private byte[] m_Address = new byte[2];
    private float m_MaxFlow;

    public float MaxFlow
    {
        get { return m_MaxFlow; }
    }

    public CVIC_DSeries(SerialPort ComPort, byte Address)
    {
        m_ComPort = ComPort;
        m_Address = ByteToHexAscii(Address);
    }

    private byte[] ByteToHexAscii(byte value)       // 1바이트를 2바이트 아스키로 변환 
    {
        string strHex = value.ToString("X2");
        byte[] StrByte = Encoding.UTF8.GetBytes(strHex);

        return StrByte;
    }

    private byte[] CheckSum(byte[] Data, int Count)
    {
        byte[] result = new byte[2];
        byte checksum = Data[0];

        for (int loop = 1; loop < Count; loop++)
        {
            checksum = (byte)(checksum ^ Data[loop]);
        }

        result = ByteToHexAscii(checksum);

        return result;
    }

    public bool Initialize()
    {
        bool result = true ;
        byte[] bTemp = new byte[2];
        byte[] send_buffer = new byte[] { 0x3a, m_Address[0], m_Address[1], 0x32, 0x31, 0x30, 0x30, 0x33, 0x39, 0x0d };
        byte[] Receive_Buff = new byte[50];

        bTemp = CheckSum(send_buffer, 7);
        send_buffer[7] = bTemp[0];
        send_buffer[8] = bTemp[1];

        m_ComPort.Write(send_buffer, 0, 10);
        Thread.Sleep(200);
       
        try
        {
            m_ComPort.Read(Receive_Buff, 0, 50);

            if (Receive_Buff[0] == 0x3A && Receive_Buff[2] == m_Address[1]) result = true;
            else result = false;
        }
        catch
        {
            result = false;
        }
        
        return result;
    }

    public bool Serial_Mode()
    {
        bool result = true;
        byte[] bTemp = new byte[] { 0x00, 0x00 };
        byte[] send_buffer = new byte[] { 0x3A, m_Address[0], m_Address[1], 0x35, 0x38, 0x30, 0x32, 0x30, 0x31, 0x33, 0x38, 0x0D };
        byte[] Receive_Buff = new byte[50];

        bTemp = CheckSum(send_buffer, 9);
        send_buffer[9] = bTemp[0];
        send_buffer[10] = bTemp[1];

        m_ComPort.Write(send_buffer, 0, 12);
        Thread.Sleep(50);

        try
        {
            m_ComPort.Read(Receive_Buff, 0, 50);
        }
        catch { }

        return result;
    }

    public bool Set_Flow_Point(int FlowValue)
    {
        bool result = false;
        int index = 7;
        float percentage;
        byte[] bTemp = new byte[2];
        byte[] send_buffer = new byte[] { 0x3A, m_Address[0], m_Address[1], 0x30, 0x31, 0x30, 0x37, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d};
        byte[] Receive_Buff = new byte[50];

        percentage = ((float)FlowValue * 100.0f) / m_MaxFlow;          // 유량설정은 퍼센트로 한다. 
        byte[] dByte = BitConverter.GetBytes(percentage);       // IEEE754 형식의 float

        for (int loop = 3; loop > -1; loop--)
        {
            bTemp = ByteToHexAscii(dByte[loop]);
            send_buffer[index++] = bTemp[0];
            send_buffer[index++] = bTemp[1];
        }

        bTemp = CheckSum(send_buffer, 15);

        send_buffer[15] = bTemp[0];
        send_buffer[16] = bTemp[1];   

        m_ComPort.Write(send_buffer, 0, 18);
        Thread.Sleep(100);

        try
        {
            m_ComPort.Read(Receive_Buff, 0, 50);   // 라즈베리파이는 데이타가 들어오지 않으면 예외를 발생시킨다.

            if (Receive_Buff[0] == 0x3A && Receive_Buff[17] == 0x0D)
            {
                result = true;
            }
        }
        catch
        {
            result = false;
        }

        return result;
    }

    public int Read_Flow_Value(ref float flowValue)
    {
        int result = 0;
        byte[] send_buffer = new byte[] { 0x3A, m_Address[0], m_Address[1], 0x30, 0x33, 0x30, 0x30, 0x33, 0x39, 0x0D };
        byte[] bcheck = CheckSum(send_buffer, 7);
        send_buffer[7] = bcheck[0];
        send_buffer[8] = bcheck[1];
        System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();

        m_ComPort.Write(send_buffer, 0, send_buffer.Count());
        sw.Start();

        try
        {
            while (true)
            {
                Thread.Sleep(10);

                if (m_ComPort.BytesToRead > 0)
                {
                    Thread.Sleep(10);
                    byte[] Receive_Buff = new byte[m_ComPort.BytesToRead + 2];

                    m_ComPort.Read(Receive_Buff, 0, m_ComPort.BytesToRead);

                    if (Receive_Buff[0] == 0x3A && Receive_Buff[17] == 0x0D)
                    {
                        byte[] bTemp = new byte[8];
                        Array.Copy(Receive_Buff, 7, bTemp, 0, 8);

                        try
                        {
                            var percentage = FromHexString(Encoding.Default.GetString(bTemp));      // IEEE754 -> float 
                            flowValue = (percentage * m_MaxFlow) / 100.0f;

                            if (flowValue <= 0) flowValue = 0f;
                        }
                        catch
                        {
                            flowValue = 0f;
                            result = -2;
                        }
                    }

                    break;
                }

                var time = (int)(sw.ElapsedMilliseconds / 1000);
                if (time > 5)           //  Timeout 5sec 시간 경과 
                {
                    result = -1;
                    break;  
                }
            }
        }
        finally 
        { 
            sw.Stop(); 
        }

        return result;
    }

    public int Get_Max_Flow()
    {
        int result = 0;

        byte[] bTemp = new byte[8];
        byte[] send_buffer = new byte[] { 0x3A, m_Address[0], m_Address[1], 0x33, 0x33, 0x30, 0x30, 0x33, 0x39, 0x0D };
        byte[] Receive_Buff = new byte[50];                                     

        byte[] bcheck = CheckSum(send_buffer, 7);
        send_buffer[7] = bcheck[0];
        send_buffer[8] = bcheck[1];

        m_ComPort.Write(send_buffer, 0, send_buffer.Count());
        Thread.Sleep(100);

        try
        {
            m_ComPort.Read(Receive_Buff, 0, 50);

            if (Receive_Buff[0] == 0x3A && Receive_Buff[17] == 0x0D)
            {
                Array.Copy(Receive_Buff, 7, bTemp, 0, 8);

                try
                {
                    m_MaxFlow = FromHexString(Encoding.Default.GetString(bTemp));      // IEEE754 -> float 
                }
                catch
                {
                    m_MaxFlow = -999.99f;
                    result = -2;
                }
            }
        }
        catch
        {
            m_MaxFlow = -999.99f;
            result = -1;
        }

        return result;
    }
    private float FromHexString(string s)
    {
        var i = Convert.ToInt32(s, 16);
        var bytes = BitConverter.GetBytes(i);
        return BitConverter.ToSingle(bytes, 0);
    }
}
반응형

댓글()