/// <summary>
        /// Command code 46:  Read the data from continuous registers.
        /// </summary>
        /// <param name="slaveStationNo">Slave Station No</param>
        /// <param name="numberOfPoints">Number Of Points.</param>
        /// <param name="mType">Memory Type.</param>
        /// <param name="startRegister">Start register No(6 or 7 words)</param>
        /// <param name="dType">Data Type.</param>
        /// <returns>object[]</returns>
        public object[] ReadRegisters(int slaveStationNo, ushort numberOfPoints, MemoryType mType, ushort startRegister, DataType dType)
        {
            List <object> result = new List <object>();

            try
            {
                string frame = this.GetMessageReadRegisters(slaveStationNo, CommandCode.READ_THE_DATA_FROM_CONTINUOUS_REGISTERS, numberOfPoints, mType, startRegister, dType);
                objSerialPort.WriteLine(frame);

                // Read SerialPort
                int CONST = 4;
                switch (dType)
                {
                case DataType.INT:
                case DataType.WORD:
                    CONST = 4;
                    break;

                case DataType.DINT:
                case DataType.DWORD:
                case DataType.REAL:
                    CONST = 8;
                    break;

                default:
                    throw new InvalidOperationException("Data type is invalid");
                }
                int      sizeOfMessageReceiver = numberOfPoints * CONST + 9;
                string   buffReceiver          = string.Empty;
                DateTime startDateTime         = DateTime.Now;
                do
                {
                    this.CheckBufferReceiver(buffReceiver);
                    buffReceiver = objSerialPort.ReadExisting();
                    System.Threading.Thread.Sleep(100);
                } while (buffReceiver.Length < sizeOfMessageReceiver && (DateTime.Now.Subtract(startDateTime).TotalMilliseconds < objSerialPort.ReadTimeout));
                //Console.WriteLine("ReadTimeout: {0}", DateTime.Now.Subtract(startDateTime).TotalMilliseconds);
                string errorMsg = this.GetException(buffReceiver);
                if (!string.IsNullOrEmpty(errorMsg) || !string.IsNullOrWhiteSpace(errorMsg))
                {
                    throw new Exception(errorMsg);
                }

                int    index        = 0;
                string dataReceiver = string.Empty;
                string valueString  = string.Empty;

                dataReceiver = buffReceiver.Substring(6, numberOfPoints * CONST); // data.
                switch (dType)
                {
                case DataType.INT:
                    do
                    {
                        valueString = dataReceiver.Substring(CONST * index, CONST);
                        short value = Conversion.HEXToINT(valueString);
                        result.Add(value);
                    } while (++index < numberOfPoints);
                    break;

                case DataType.WORD:
                    do
                    {
                        valueString = dataReceiver.Substring(CONST * index, CONST);
                        ushort value = Conversion.HEXToWORD(valueString);
                        result.Add(value);
                    } while (++index < numberOfPoints);
                    break;

                case DataType.DINT:
                    do
                    {
                        valueString = dataReceiver.Substring(CONST * index, CONST);
                        int value = Conversion.HEXToDINT(valueString);
                        result.Add(value);
                    } while (++index < numberOfPoints);
                    break;

                case DataType.DWORD:
                    do
                    {
                        valueString = dataReceiver.Substring(CONST * index, CONST);
                        uint value = Conversion.HEXToDWORD(valueString);
                        result.Add(value);
                    } while (++index < numberOfPoints);
                    break;

                case DataType.REAL:
                    do
                    {
                        valueString = dataReceiver.Substring(CONST * index, CONST);
                        float value = Conversion.HEXToREAL(valueString);
                        result.Add(value);
                    } while (++index < numberOfPoints);
                    break;

                default:
                    throw new InvalidOperationException("Data type is invalid");
                }
                //Console.WriteLine("buffReceiver: {0}", buffReceiver);
                //Console.WriteLine("dataReceiver: {0}", dataReceiver);
            }
            catch (Exception ex)
            {
                throw ex;
            }
            return(result.ToArray());
        }
        /// <summary>
        /// Command code 48:  Mixed read the random discrete status or register data.
        /// </summary>
        /// <param name="slaveStationNo">Slave Station No</param>
        /// <param name="numberOfPoints">Number Of Points.</param>
        /// <param name="components">List<RandomRegister></param>
        /// <returns>string</returns>
        public RandomRegister[] ReadRadomDiscreteOrRegisters(int slaveStationNo, ushort numberOfPoints, List <RandomRegister> components)
        {
            List <RandomRegister> result = new List <RandomRegister>();

            try
            {
                string frame = this.GetMessageReadRadomDiscreteOrRegisters(slaveStationNo, CommandCode.MIXED_READ_THE_RADOM_DISCRETE_STATUS_OF_REGISTER_DATA, numberOfPoints, components);
                objSerialPort.WriteLine(frame);


                // Read SerialPort
                int CONST = 0;
                foreach (RandomRegister item in components)
                {
                    switch (item.DataType)
                    {
                    case DataType.BOOL:
                        CONST += 1;
                        break;

                    case DataType.INT:
                    case DataType.WORD:
                        CONST += 4;
                        break;

                    case DataType.DINT:
                    case DataType.DWORD:
                    case DataType.REAL:
                        CONST += 8;
                        break;

                    default:
                        throw new InvalidOperationException("Data type is invalid");
                    }
                }

                int      sizeOfMessageReceiver = CONST + 9;
                string   buffReceiver          = string.Empty;
                DateTime startDateTime         = DateTime.Now;
                do
                {
                    this.CheckBufferReceiver(buffReceiver);
                    buffReceiver = objSerialPort.ReadExisting();
                    System.Threading.Thread.Sleep(100);
                } while (buffReceiver.Length < sizeOfMessageReceiver && (DateTime.Now.Subtract(startDateTime).TotalMilliseconds < objSerialPort.ReadTimeout));
                //Console.WriteLine("ReadTimeout: {0}", DateTime.Now.Subtract(startDateTime).TotalMilliseconds);
                string errorMsg = this.GetException(buffReceiver);
                if (!string.IsNullOrEmpty(errorMsg) || !string.IsNullOrWhiteSpace(errorMsg))
                {
                    throw new Exception(errorMsg);
                }

                int    index        = 0;
                string dataReceiver = string.Empty;
                string valueString  = string.Empty;

                dataReceiver = buffReceiver.Substring(6, CONST); // data.

                foreach (RandomRegister item in components)
                {
                    switch (item.DataType)
                    {
                    case DataType.BOOL:
                        valueString = dataReceiver.Substring(index, 1);
                        item.Value  = !"0".Equals(valueString) ? true : false;
                        index      += 1;
                        break;

                    case DataType.INT:
                        valueString = dataReceiver.Substring(index, 4);
                        item.Value  = Conversion.HEXToINT(valueString);
                        index      += 4;
                        break;

                    case DataType.WORD:
                        valueString = dataReceiver.Substring(index, 4);
                        item.Value  = Conversion.HEXToWORD(valueString);
                        index      += 4;
                        break;

                    case DataType.DINT:
                        valueString = dataReceiver.Substring(index, 8);
                        item.Value  = Conversion.HEXToDINT(valueString);
                        index      += 8;
                        break;

                    case DataType.DWORD:
                        valueString = dataReceiver.Substring(index, 8);
                        item.Value  = Conversion.HEXToDWORD(valueString);
                        index      += 8;
                        break;

                    case DataType.REAL:
                        valueString = dataReceiver.Substring(index, 8);
                        item.Value  = Conversion.HEXToREAL(valueString);
                        index      += 8;
                        break;

                    default:
                        throw new InvalidOperationException("Data type is invalid");
                    }
                    result.Add(item);
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
            return(result.ToArray());
        }
        /// <summary>
        /// FATEK PLC Information
        /// </summary>
        /// <param name="slaveStationNo">Slave Station No</param>
        /// <returns>FATEK PLC Information</returns>
        public string GetPLCInfo(int slaveStationNo)
        {
            StringBuilder result = new StringBuilder();

            try
            {
                string frame = this.GetMessageOfPLCStatus(slaveStationNo, CommandCode.PLC_STATUS);
                objSerialPort.WriteLine(frame);

                // Read SerialPort
                int      sizeOfMessageReceiver = 15;
                string   buffReceiver          = string.Empty;
                DateTime startDateTime         = DateTime.Now;
                do
                {
                    this.CheckBufferReceiver(buffReceiver);
                    buffReceiver = objSerialPort.ReadExisting();
                    System.Threading.Thread.Sleep(100);
                } while (buffReceiver.Length < sizeOfMessageReceiver && (DateTime.Now.Subtract(startDateTime).TotalMilliseconds < objSerialPort.ReadTimeout));
                string errorMsg = this.GetException(buffReceiver);
                if (!string.IsNullOrEmpty(errorMsg) || !string.IsNullOrWhiteSpace(errorMsg))
                {
                    throw new Exception(errorMsg);
                }

                string dataReceiver = buffReceiver.Substring(6, 2); // STATUS 1.
                ushort plcStatus    = Conversion.HEXToWORD(dataReceiver);

                result.AppendLine("FATEK PLC COMMUNICATION PROTOCOL VIA SERIALPORT");
                result.AppendLine("===============================================================");
                PLCMode objPLCMode = (PLCMode)plcStatus;
                result.AppendLine(string.Format("B0. PLC Mode: {0}", objPLCMode));

                LADDER_CHECKSUM ladder = (LADDER_CHECKSUM)((plcStatus & (ushort)Math.Pow(2, 2)) >> 2);
                result.AppendLine(string.Format("B2. Ladder Checksum: {0}", ladder));

                USE_ROM_PACK_OR_NOT_USE objUseRomPack = (USE_ROM_PACK_OR_NOT_USE)((plcStatus & (ushort)Math.Pow(2, 3)) >> 3);
                result.AppendLine(string.Format("B3. Use ROM Pack: {0}", objUseRomPack));

                WDT_TIMEOUT_OR_NORMAL objWDTTimeout = (WDT_TIMEOUT_OR_NORMAL)((plcStatus & (ushort)Math.Pow(2, 4)) >> 4);
                result.AppendLine(string.Format("B4. WDT Timeout: {0}", objWDTTimeout));

                SET_ID_OR_NOT_SET_ID objSetID = (SET_ID_OR_NOT_SET_ID)((plcStatus & (ushort)Math.Pow(2, 5)) >> 5);
                result.AppendLine(string.Format("B5. Set ID: {0}", objSetID));

                EMERGENCY_STOP_OR_NORMAL objEmergencyStop = (EMERGENCY_STOP_OR_NORMAL)((plcStatus & (ushort)Math.Pow(2, 6)) >> 6);
                result.AppendLine(string.Format("B6. Emergency Stop: {0}", objEmergencyStop));

                //RESERVE FOR FUTURE
                result.AppendLine("B7. Reserver For Future");
                result.AppendLine("===============================================================");
                result.AppendLine("Designed By Industrial Networks");
                result.AppendLine("Skype: katllu");
                result.AppendLine("Mobile: (+84) 909.886.483");
                result.AppendLine("E-mail: [email protected]");
                result.AppendLine("Youtube: https://www.youtube.com/industrialnetworks");
                result.AppendLine();
            }
            catch (Exception ex)
            {
                throw ex;
            }
            return(result.ToString());
        }