コード例 #1
0
 public PID(double pG, double iG, double dG,
            double pMax, double pMin, double oMax, double oMin,
            GetDouble pvFunc, GetDouble spFunc, SetDouble outFunc)
 {
     kp      = pG;
     ki      = iG;
     kd      = dG;
     pvMax   = pMax;
     pvMin   = pMin;
     outMax  = oMax;
     outMin  = oMin;
     readPV  = pvFunc;
     readSP  = spFunc;
     writeOV = outFunc;
 }
コード例 #2
0
        public IPID Create(double kp, double i, double d, double pMax, double pMin, double oMax, double oMin, GetDouble GetCurrentValueFunc, GetDouble GetSetPointFunc, SetDouble SetProcessValue)
        {
            IPID ipid = new PID(kp, i, d, pMax, pMin, oMax, oMin, GetCurrentValueFunc, GetSetPointFunc, SetProcessValue);

            //
            return(ipid);
        }
コード例 #3
0
        //Convert.ToSingle(OV)
        private void radButton1_Click(object sender, System.EventArgs e)
        {
            if (!m_MainClass.m_Define_Class.isMFC_Con)
            {
                MessageBox.Show("MFC가 연결되지 않았습니다.");
            }
            else if (!m_MainClass.m_Define_Class.isConTempSensor)
            {
                MessageBox.Show("온도센서 연결되지 않았습니다.");
            }
            else if (!m_MainClass.m_Define_Class.isMFC_Valve_Open)
            {
                MessageBox.Show("MFC 밸브가 닫혀 있습니다.");
            }
            else if (m_MainClass.m_Define_Class.isAutoRun)
            {
                DialogResult dialogResult = MessageBox.Show("Sure", "온도제어를 중지 하겠습니까?", MessageBoxButtons.YesNo);
                if (dialogResult == DialogResult.Yes)
                {
                    m_MainClass.m_Define_Class.isAutoRun = false;
                    btnAutoRun.BackColor = Color.LightGray;
                    m_MainClass.m_PidClass.Disable();
                }
            }
            else
            {
                m_MainClass.m_Define_Class.isAutoRun = true;
                btnAutoRun.BackColor = Color.Lime;

                ReadPV  = new GetDouble(setPV);
                ReadSP  = new GetDouble(setSP);
                WriteOV = new SetDouble(getOV);

                m_MainClass.m_PidClass = new PID(
                    m_MainClass.stPIDGain.kp,
                    m_MainClass.stPIDGain.ki,
                    m_MainClass.stPIDGain.kd,
                    m_MainClass.stPIDGain.inputMax,
                    m_MainClass.stPIDGain.inputMin,
                    m_MainClass.stPIDGain.outMax,
                    m_MainClass.stPIDGain.outMin,
                    ReadPV, ReadSP, WriteOV);
                m_MainClass.m_PidClass.Enable();
            }



            //System.Console.WriteLine("Send Message : " + System.Text.Encoding.ASCII.GetString(buff));

            /*
             *
             * // (1) 한 byte 를 Hex 문자로 변환하는 방법
             *  byte b1 = 0xFE;
             *  string hex1 = b1.ToString("X2");
             *
             *  // (2) byte[] 을 Hex 문자열로 변환하는 방법
             *  byte[] bytes = new byte[] { 0xA1, 0xB2, 0xC3, 0x11, 0x2F };
             *  string h = string.Concat(Array.ConvertAll(bytes, byt => byt.ToString("X2")));
             *  // 혹은
             *  // h = BitConverter.ToString(bytes).Replace("-", "");
             *
             *
             *  // (3) 한 Hex 문자를 byte 로 변환하는 방법
             *  byte b2 = Convert.ToByte("3F", 16);
             *  // 혹은
             *  // b2 = byte.Parse("3F", NumberStyles.HexNumber);
             *
             *  // (4) 여러 Hex 문자열을 byte[] 로 변환하는 방법
             *  string hexString = "A1B2C3";
             *  byte[] xbytes = new byte[hexString.Length / 2];
             *  for (int i = 0; i < xbytes.Length; i++)
             *  {
             *      xbytes[i] = Convert.ToByte(hexString.Substring(i*2, 2), 16);
             *  }
             */

            /*
             * The Compute routine is where the meat of the algorithm lies. Basically, it starts out reading the process variable (pv) and set point (sp). It then Clamp's them to pvMin and pvMax, then scales them so they are a percentage between -100% and 100% of the scale. It then figures out the error percentage and starts running the PID calculation.
             *
             * The calculation is pretty simple; it starts out finding the pTerm, which is the error times the gain (kp). Then, inside the if statement, we do what is called anti-windup reset, where we only calculate the iTerm if the process variable isn't pegged at or above the process variable range. This helps to limit the output of the system, and keeps the error from blowing up when the process variable gets out of range.
             *
             * The last thing it does is simply sum the three terms to obtain the output value, clamp it to +/-100% of the output range, then scale it to come up with a real output number. It then uses the SetDouble delegate called writeOV (write output variable) to set the output value.
             *
             * And there you have it. If we have a more real-time or critical process, we can set the runThread priority to something higher, but I wouldn't recommend going above "High" since it will cause other things to become preempted too often.
             *
             * This is a very versatile class; setting the I gain term to zero will give you a PD controller, and if you wanted, you could have a strictly P controller by setting both the I and D gains to zero.
             */

            //}
            //else if(m_MainClass.m_Define_Class.isAutoRun)
            //{
            //    m_MainClass.m_Define_Class.isAutoRun = false;
            //    btnAutoRun.BackColor = Color.LightGray;
            //    m_MainClass.m_PidClass.Disable();
            //}
            //else
            //{
            //}
        }