wsk3q

导航

C#控制TH300(韩荣/志和)温湿度控制器

// C#控制TH300(韩荣/志和)温湿度控制器

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.IO.Ports;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;

namespace JohnKit
{
    /// <summary>
    /// 温箱控制 TH300
    /// H.Z.XIN 2021-11-30
    /// Modified:
    ///     2021-11-30 create
    ///
    /// </summary>
    public class Temper
    {
        private SerialPort mComPort = new SerialPort();
        private string mMachineNum; //"001";
        private byte[] mRecvBuffer = new byte[2048];

        private static readonly byte STX = 0x02;
        //private static readonly byte ETX = 0x03;
        private static readonly byte[] ECL = { 0x03, 0x0D, 0x0A };

        class TRetData
        {
            public TRetData()
            {
                bok = false;
                data = new List<byte[]>();
            }
            public bool bok;
            public List<byte[]> data;
        }

        public Temper(string machineNum, int nReadTimeOut = 4000)
        {
            mMachineNum = machineNum;
            mComPort.ReadTimeout = nReadTimeOut < 0 ? SerialPort.InfiniteTimeout : nReadTimeOut;
            mComPort.BaudRate = 38400;
            mComPort.DataBits = 8;
            mComPort.Parity = Parity.None;
            mComPort.StopBits = StopBits.One;
            mComPort.RtsEnable = false;
        }

        /// <summary>
        /// 尝试打开串口
        /// </summary>
        /// <returns>
        /// -1 -- COM口不存在
        ///  0 -- COM口打开失败
        ///  1 -- COM口打开成功
        /// </returns>
        public int TryOpenCOM(string scom)
        {
            mComPort.PortName = scom;
            try
            {
                mComPort.Open();
            }
            catch (IOException)
            {
                Debug.WriteLine(string.Format("{0} not exist", scom));
                return -1;
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.Message);
                return 0;
            }
            return mComPort.IsOpen ? 1 : 0;
        }

        private List<byte> ComRead(int nMaxRead = 100)
        {
            var lsby = new List<byte>();
            int nGet = -1;
            ResetBuf();

            try
            {
                //sret = mComPort.ReadLine();
                //Debug.WriteLine($"ret: {sret}");
                nGet = mComPort.Read(mRecvBuffer, 0, nMaxRead);
            }
            catch (System.Exception ex)
            {
                Debug.WriteLine(ex.Message);
            }

            int iStart = -1;
            int iEnd = -1;
            for (int i = 0; i < nGet; i++)
            {
                if (mRecvBuffer[i] == STX)
                {
                    iStart = i;
                }
                else if (i <= nGet - ECL.Length)
                {
                    bool bFound = true;
                    for (int j = 0; j < ECL.Length; j++)
                    {
                        if (mRecvBuffer[i + j] != ECL[j])
                        {
                            bFound = false;
                            break;
                        }
                    }
                    if (bFound)
                    {
                        iEnd = i;
                    }
                }
            }

            if (iStart < iEnd && iStart >= 0)
            {
                for (int i = iStart; i < iEnd + ECL.Length; i++)
                {
                    lsby.Add(mRecvBuffer[i]);
                }
            }
            return lsby;
        }

        private bool ComWrite(byte[] cSendData, int iStart, int n)
        {
            try
            {
                mComPort.Write(cSendData, iStart, n);
            }
            catch (System.Exception ex)
            {
                Debug.WriteLine(ex.Message);
                return false;
            }
            return true;
        }

        public void ComClose()
        {
            mComPort.Close();
        }
        public bool IsConnected()
        {
            bool bok = mComPort.IsOpen;
            return bok;
        }

        #region 内部函数
        private static byte[] Short2Byte(short n)
        {
            var bys = new byte[2];
            bys[0] = (byte)((n & 0xFF00) >> 8);
            bys[1] = (byte)((n & 0x00FF) >> 0);
            return bys;
        }

        private static short toLSB(short n)
        {
            short sval = 0;
            sval |= (short)((n & 0xFF00) >> 8);
            sval |= (short)((n & 0x00FF) << 8);
            return sval;
        }
        private static byte[] Str2Byte(string s)
        {
            return System.Text.Encoding.ASCII.GetBytes(s);
        }
        private static string Byte2Str(byte[] bys)
        {
            return System.Text.Encoding.ASCII.GetString(bys);
        }

        private static byte[] MakePackage(byte[] bydat)
        {
            int nLen = 1 + 3 + bydat.Length; // STX + bydat + ECL
            var bys = new byte[nLen];
            int i = 0;
            bys[i++] = STX;
            for (var j = 0; j < bydat.Length; j++)
            {
                bys[i++] = bydat[j];
            }
            for (var j = 0; j < ECL.Length; j++)
            {
                bys[i++] = ECL[j];
            }
            return bys;
        }

        private void ResetBuf()
        {
            for (int i = 0; i < mRecvBuffer.Length; i++)
            {
                mRecvBuffer[i] = 0;
            }
        }

        // 解包
        private static bool ExtractPackage(List<byte> lsby, ref TRetData res)
        {
            var poss = new List<int>();
            for(int i=0; i<lsby.Count; i++)
            {
                if(0x2C == lsby[i])
                {
                    poss.Add(i);
                }
            }

            if (poss.Count < 1)
            {
                return false;
            }

            int iDiv = poss[0];
            int iNextDiv = poss.Count > 1 ? poss[1] : lsby.Count;            
            int nLen = iNextDiv-iDiv-1;
            var byTemp = new byte[nLen];
            lsby.CopyTo(iDiv + 1, byTemp, 0, nLen);
            bool bok = "OK".Equals(Byte2Str(byTemp), StringComparison.InvariantCultureIgnoreCase);
            res.data.Clear();

            int nDiv = poss.Count;
            for(int i=1; i<nDiv; i++)
            {
                if(i==nDiv-1)
                {
                    iDiv = poss[i];
                    iNextDiv = iDiv;
                    bool bEndsign = false;
                    while(iNextDiv<=lsby.Count-ECL.Length)
                    {
                        bool bsign = true;
                        for(int k=0; k<ECL.Length; k++)
                        {
                            if(lsby[iNextDiv+k] != ECL[k])
                            {
                                bsign = false;
                                break;
                            }
                        }
                        if(bsign)
                        {
                            bEndsign = true;
                            break; //!
                        }
                        iNextDiv++;
                    }
                    if(!bEndsign)
                    {
                        Debug.WriteLine("*返回数据没有找到ECL");
                    }
                    iNextDiv = bEndsign ? iNextDiv : lsby.Count;
                }
                else
                {
                    iDiv = poss[i];
                    iNextDiv = poss[i + 1];                    
                }

                nLen = iNextDiv-iDiv-1;
                byTemp = new byte[nLen];
                lsby.CopyTo(iDiv + 1, byTemp, 0, nLen);
                res.data.Add(byTemp);
            }
            return res.data.Count > 0;
        }

        private static object BytesToStruct(byte[] bytes, Type strcutType)
        {
            int size = Marshal.SizeOf(strcutType);
            IntPtr buffer = Marshal.AllocHGlobal(size);
            try
            {
                Marshal.Copy(bytes, 0, buffer, size);
                return Marshal.PtrToStructure(buffer, strcutType);
            }
            catch(Exception ex)
            {
                Debug.WriteLine(ex.Message);
            }
            finally
            {
                Marshal.FreeHGlobal(buffer);
            }
            return null;
        }

        private static float packTemp(float fraw)
        {
            return (fraw + 100.00F) * 100.00F;
        }
        private static float unpackTemp(float fraw)
        {
            return fraw/100.00F - 100.00F;
        }

        #endregion

        public bool GetMachineVersion(ref string sVer)
        {
            sVer = string.Empty;
            if (!mComPort.IsOpen)
            {
                return false;
            }

            var scmd = string.Format("{0}WHO", mMachineNum);
            var bys = MakePackage(Str2Byte(scmd));
            List<byte> byRead;

            {
                //Debug.Assert(10 == bys.Length);
                if (!ComWrite(bys, 0, bys.Length))
                {
                    return false;
                }

                byRead = ComRead(64);
            }
            var pRet = new TRetData();
            if (!ExtractPackage(byRead, ref pRet))
            {
                return false;
            }

            if (pRet.data.Count > 0)
            {
                sVer = Byte2Str(pRet.data[0]);
                return true;
            }
            return false;
        }

        private bool sendWRP(string sReg, byte[] byCmd)
        {
            if (!mComPort.IsOpen)
            {
                return false;
            }

            //机号    WRP    ,    REG号    ,    Data            
            var byList = new List<byte>();
            var stemp = string.Format("{0}WRP,{1},", mMachineNum, sReg);
            byList.AddRange(Str2Byte(stemp));
            byList.AddRange(byCmd);

            var bys = MakePackage(byList.ToArray());
            //Debug.Assert(18 == bys.Length);
            if (!ComWrite(bys, 0, bys.Length))
            {
                return false;
            }

            var byRead = ComRead(40);
            var pRet = new TRetData();
            if (!ExtractPackage(byRead, ref pRet))
            {
                return false;
            }

            bool bok = false;
            if (pRet.data.Count > 0)
            {
                var sRet = Byte2Str(pRet.data[0]);
                bok = sReg.Equals(sRet);
            }
            return bok;
        }
        public bool startRun()
        {
            var sReg = "0001";
            var byCmd = new byte[] { 0x00, 0x01 };
            return sendWRP(sReg, byCmd);
        }

        public bool stopRun()
        {
            var sReg = "0001";
            var byCmd = new byte[] { 0x00, 0x00 };
            return sendWRP(sReg, byCmd);
        }

        public bool setTemperature(float ftemp)
        {   
            var sReg = "0012";
            var fval = packTemp(ftemp);
            var byCmd = Short2Byte((short)fval);
            return sendWRP(sReg, byCmd);
        }


        [StructLayoutAttribute(LayoutKind.Sequential,Pack=1)]
        struct TCurValue
        {
            public short TSV;
            public short TPV;
            public short TMV;
            public short HSV;
            public short HPV;
            public short HMV;
            public short TIpS;
            public short TpS;
            public short ApS;
            public short RY;
            public short OpC;
            public short DpI;
            public byte  RM;
            public short RTH;
            public byte  RTM;
            public byte  RTS;
            public short SRTH;
            public byte  SRTM;
            public short SFTH;
            public byte  SFTM;
            public short RPTN;
            public byte  RSEG;
            public short RPRC;
            public short RPRN;
            public byte  RLC;
            public byte  RLN;
            public byte  UDSW;
        }

        private bool sendRCV(string sReg, ref TCurValue pval)
        {
            if (!mComPort.IsOpen)
            {
                return false;
            }

            //机号    RCV
            var byList = new List<byte>();
            var stemp = string.Format("{0}RCV", mMachineNum);
            byList.AddRange(Str2Byte(stemp));
            var bys = MakePackage(byList.ToArray());
            //Debug.Assert(10 == bys.Length);
            if (!ComWrite(bys, 0, bys.Length))
            {
                return false;
            }

            var byRead = ComRead(59);
            var pRet = new TRetData();
            if (!ExtractPackage(byRead, ref pRet))
            {
                return false;
            }

            bool bok = pRet.data.Count > 0;
            if (bok)
            {
                var oval = (TCurValue?)BytesToStruct(pRet.data[0], typeof(TCurValue));
                bok = oval.HasValue;
                if (bok)
                {
                    pval = oval.Value;
                }
            }
            return bok;
        }


        public bool getTemperature(out float ftemp)
        {
            ftemp = 0.0f;
            var sReg = "0012";

            TCurValue tval=new TCurValue();
            if (!sendRCV(sReg, ref tval))
            {
                return false;
            }
            
            ftemp = unpackTemp(toLSB(tval.TPV));
            //float ftsv = unpackTemp(toLSB(tval.TSV));
            return true;
        }

    }
}

posted on 2021-12-02 11:43  wsk3q  阅读(282)  评论(0编辑  收藏  举报