public ModbusItem(ModbusItem src)   // copy contructor
 {
     ModbusAddress   = src.ModbusAddress;
     ComPortName     = src.ComPortName;
     BaudRate        = src.BaudRate;
     Databits        = src.Databits;
     StopBits        = src.StopBits;
     Parity          = src.Parity;
     ReadTimeout     = src.ReadTimeout;
     WriteTimeout    = src.WriteTimeout;
     ModbusInterface = src.ModbusInterface;
 }
        ///////////////////// Singleton end //////////////////



        public ModbusInterface_Base GetModbusInterface(byte modbusAddress, string portName, int baudRate = 115200, int databits = 8, StopBits stopBits = StopBits.One, Parity parity = Parity.None, int mbReadTimeout = 50, int mbWriteTimeout = 30)
        {
            string currentMethod = "GetModbusInterface";

            ModbusItem mbItemInfo = _modbusDevices.FirstOrDefault(p => p.ModbusAddress == modbusAddress && p.ComPortName.ToLower() == portName.ToLower());

            if (mbItemInfo != null)
            {
                throw new Exception(string.Format("There is already a device connected to port {0} with modbus address {1}.", portName, modbusAddress));
            }

            mbItemInfo = _modbusDevices.FirstOrDefault(p => p.ComPortName.ToLower() == portName.ToLower());
            if (mbItemInfo == null)
            {
                // this is the first modbus device for this com port
                mbItemInfo = new ModbusItem()
                {
                    ModbusAddress = modbusAddress,
                    ComPortName   = portName,
                    BaudRate      = baudRate,
                    Databits      = databits,
                    StopBits      = stopBits,
                    Parity        = parity,
                    ReadTimeout   = mbReadTimeout,
                    WriteTimeout  = mbWriteTimeout
                };

                var mbConnection = new ModbusInterface_Base();
                mbConnection.ConnectModbusInterface(portName, baudRate, databits, stopBits, parity, mbReadTimeout, mbWriteTimeout);

                mbItemInfo.ModbusInterface = mbConnection;
                _modbusDevices.Add(mbItemInfo);
            }
            else
            {
                // there is already another modbus device connected to this com port - check connection parameters
                if (baudRate != mbItemInfo.BaudRate || databits != mbItemInfo.Databits || stopBits != mbItemInfo.StopBits || parity != mbItemInfo.Parity)
                {
                    throw new Exception(string.Format("Com port {0} already used with different connection parameters. Currently used: baud={1} databits={2} stopbits={3} parity={4}    Requested: baud={5} databits={6} stopbits={7} parity={8}", portName, mbItemInfo.BaudRate, mbItemInfo.Databits, mbItemInfo.StopBits.ToString(), mbItemInfo.Parity.ToString(), baudRate, databits, stopBits.ToString(), parity.ToString()));
                }

                if (mbReadTimeout != mbItemInfo.ReadTimeout || mbWriteTimeout != mbItemInfo.WriteTimeout)
                {
                    log.Warn("[{0}] - Different timeouts requested but modbus is still in use. Already used: readtimeout={1} writetimeout={2}   requested: readtimeout={3} writetimeout={4}", currentMethod, mbItemInfo.ReadTimeout, mbItemInfo.WriteTimeout, mbReadTimeout, mbWriteTimeout);
                }

                ModbusItem mbNewItemInfo = new ModbusItem(mbItemInfo);
                mbNewItemInfo.ModbusAddress = modbusAddress;
                _modbusDevices.Add(mbNewItemInfo);
            }

            return(mbItemInfo.ModbusInterface);
        }
        public void CloseModbusInterface(byte modbusAddress, ModbusInterface_Base mbInterface)
        {
            string currentMethod = "CloseModbusInterface";

            if (mbInterface == null)
            {
                return;
            }

            ModbusItem mbItemInfo = _modbusDevices.FirstOrDefault(p => p.ModbusAddress == modbusAddress && p.ComPortName.ToLower() == mbInterface.ComPortName.ToLower());

            if (mbItemInfo == null)
            {
                // no modbus device found to close
                log.Warn("[{0}] - No modbus device found which could be closed. (modbusaddress={1}  comport={2})", currentMethod, modbusAddress, mbInterface.ComPortName);
            }
            else
            {
                string comPort = mbItemInfo.ComPortName;

                // remove found modbus device from list
                _modbusDevices.Remove(mbItemInfo);

                // check if there are other devices uses the same com port
                mbItemInfo = _modbusDevices.FirstOrDefault(p => p.ComPortName.ToLower() == mbInterface.ComPortName.ToLower());

                if (mbItemInfo == null)
                {
                    // there is no other modbus device uses the same com port --> close com port
                    log.Debug("[{0}] - Modbus interface on comport={1} will be closed.", currentMethod, comPort);
                    mbInterface.CloseModbusInterface();
                }
                else
                {
                    log.Debug("[{0}] - Modbus interface on comport={1} will not be closed because it's used by other modbus devices.", currentMethod, comPort);
                }
            }
        }
예제 #4
0
        /// <summary>
        /// 写变量
        /// </summary>
        /// <param name="aModbusItem">变量</param>
        /// <param name="aValue">值</param>
        /// <returns>是否写成功</returns>
        public bool WriteItem(ref ModbusItem aModbusItem, Iolist aValue)
        {
            //如果值相等则不需再重写
            //if (aModbusItem.Value.ToString().Trim() == "" || aValue.Values.Value.ToString().Trim() == "")
            //    return false;

            if (aModbusItem.Value.ToString() == aValue.Values.Value.ToString() &&
                Convert.ToDecimal(aValue.Values.Value) != decimal.MaxValue)
            {
                return(false);
            }

            //if (aModbusItem.Direction == RwDirection.ReadWrite
            //                && (aValue.TagName == "FormerBreakageCount")
            //                || aValue.TagName == "RunCounting"
            //                || aValue.TagName == "StopCounting")
            //{
            //    Log.WriteLog(Host.ToString() + "MODBUS WriteJob : " + aValue.TagName
            //        + " , " + aValue.TagCode
            //        + " , " + aModbusItem.Value
            //        + " , " + aValue.Values.ModbusValue.ToString()
            //        + " , " + aValue.Values.Value.ToString()
            //        + " , " + aValue.Values.OPCValue.ToString()
            //        + " , " + aModbusItem.Status.ToString());
            //}

            //写圈或写寄存器模式
            CoilOrRegister iCoilOrRegiterMode = CoilOrRegister.Register;

            //写长度
            UInt16 uint16WriteLenth = 0;

            //写缓存
            byte[] bWriteBuffer = new byte[0];

            //写数值
            ItemValue ivItemValue = new ItemValue();

            //判断数据类型
            switch (aModbusItem.ItemType)
            {
            //WORD类型打包
            case "WORD":
                ivItemValue.Word = Convert.ToInt16(aValue.Values.Value.ToString());
                bWriteBuffer     = new byte[2];
                bWriteBuffer[0]  = ivItemValue.B1;
                bWriteBuffer[1]  = ivItemValue.B0;
                uint16WriteLenth = 1;
                break;

            //DWORD类型打包
            case "DWORD":
                ivItemValue.DWord = Convert.ToInt32(aValue.Values.Value.ToString());
                bWriteBuffer      = new byte[4];
                bWriteBuffer[0]   = ivItemValue.B1;
                bWriteBuffer[1]   = ivItemValue.B0;
                bWriteBuffer[2]   = ivItemValue.B3;
                bWriteBuffer[3]   = ivItemValue.B2;
                uint16WriteLenth  = 2;
                break;

            //FLOAT类型打包
            case "FLOAT":
                ivItemValue.Float = (float)Convert.ToDouble(aValue.Values.Value.ToString());
                bWriteBuffer      = new byte[4];
                bWriteBuffer[0]   = ivItemValue.B1;
                bWriteBuffer[1]   = ivItemValue.B0;
                bWriteBuffer[2]   = ivItemValue.B3;
                bWriteBuffer[3]   = ivItemValue.B2;
                uint16WriteLenth  = 2;
                break;

            //STRING类型打包
            case "STRING":
                //数值转换为字符串
                string strValue = Convert.ToString(aValue.Values.Value.ToString());

                //缓存
                bWriteBuffer = new byte[10];
                //char[] cBuffer = new char[10];

                //数据打包
                for (int i = 0; i < bWriteBuffer.Length && i < strValue.Length; i++)
                {
                    bWriteBuffer[i] = (byte)strValue[i];
                }

                //Array.Copy((byte[])cBuffer, 0, bWriteBuffer, 0, 10);
                uint16WriteLenth = 5;
                break;

            case "BOOLEAN":
                iCoilOrRegiterMode = CoilOrRegister.Coil;
                bWriteBuffer       = new byte[1];
                bWriteBuffer[0]    = Convert.ToByte(aValue.Values.Value);
                uint16WriteLenth   = 1;
                break;

            default:
                uint16WriteLenth = 0;
                break;
            }

            //写
            if (uint16WriteLenth > 0)
            {
                switch (iCoilOrRegiterMode)
                {
                case CoilOrRegister.Coil:
                    //写线圈
                    if (WriteSingleCoil(aModbusItem.SlaveID, aModbusItem.ItemAddress, Convert.ToUInt16(bWriteBuffer[0])) == uint16WriteLenth)
                    {
                        //更新值
                        aModbusItem.Value      = aValue.Values.Value;
                        aModbusItem.UpdateTime = DateTime.Now;
                        return(true);
                    }
                    else
                    {
                        return(false);
                    }

                //break;
                case CoilOrRegister.Register:
                    //写寄存器
                    if (WriteMultipleRegisters(aModbusItem.SlaveID, aModbusItem.ItemAddress, uint16WriteLenth, bWriteBuffer) == uint16WriteLenth * 2)
                    {
                        //更新值
                        aModbusItem.Value      = aValue.Values.Value;
                        aModbusItem.UpdateTime = DateTime.Now;
                        return(true);
                    }
                    else
                    {
                        return(false);
                    }

                //break;
                default:
                    return(false);
                    //break;
                }
            }
            else
            {
                return(false);
            }

            //return true;
        }
예제 #5
0
        /// <summary>
        /// 读变量表
        /// </summary>
        /// <param name="aModbusItem">需要更新的变量表</param>
        /// <returns>读写是否成功</returns>
        public bool ReadItems(ref ModbusItem[] aModbusItem)
        {
            //读线圈或读寄存器模式
            CoilOrRegister iCoilOrRegiterMode = CoilOrRegister.Register;

            //从轮询地址
            byte bSlaveID = 0;

            //变量长度
            int iCount = 0;

            //开始地址
            UInt16 uint16StartAddr = 0;

            //排序
            var varSortItem = from item in aModbusItem
                              orderby item.SlaveID, item.ItemAddress
                              select item;
            ModbusItem[] mbItems = varSortItem.ToArray();

            //获得变量个数
            iCount = mbItems.Length;

            //读取变量
            //遍历更新所有变量
            for (int i = 0; i < iCount; i++)
            {
                //读取长度
                UInt16 uint16Length = 0;

                //获得从轮询地址
                bSlaveID = Convert.ToByte(mbItems[i].SlaveID);

                //获得开始地址
                uint16StartAddr = Convert.ToUInt16(mbItems[i].ItemAddress);

                //判断需要缓存的长度
                switch (mbItems[i].ItemType)
                {
                    case "WORD":
                        uint16Length += 1;
                        break;
                    case "DWORD":
                    case "FLOAT":
                        uint16Length += 2;
                        break;
                    case "STRING":
                        uint16Length += 5;
                        break;
                    case "BOOLEAN":
                        iCoilOrRegiterMode = CoilOrRegister.Coil;
                        uint16Length += 1;
                        break;
                }

                //当有读取长度时
                if (uint16Length > 0)
                {
                    if (iCoilOrRegiterMode == CoilOrRegister.Coil)
                    {
                        //数据缓存
                        byte[] bBuffer = new byte[uint16Length];

                        try
                        {
                            //读线圈
                            if (ReadCoils(bSlaveID, uint16StartAddr, uint16Length, bBuffer) == uint16Length)
                            {
                                //获得变量值缓存索引
                                int iItemValueBufferIndex = (mbItems[i].ItemAddress - uint16StartAddr);

                                //更新状态
                                mbItems[i].Status = ValueState.STATUS_GOOG;

                                //时间戳
                                mbItems[i].UpdateTime = DateTime.Now;

                                //值
                                mbItems[i].Value = Convert.ToBoolean(bBuffer[iItemValueBufferIndex]);
                            }
                            else
                            {
                                //更新状态
                                mbItems[i].Status = ValueState.STATUS_BAD;

                                //时间戳
                                mbItems[i].UpdateTime = DateTime.Now;
                            }
                        }
                        catch
                        {
                            //更新状态
                            mbItems[i].Status = ValueState.STATUS_BAD;

                            //时间戳
                            mbItems[i].UpdateTime = DateTime.Now;

                            //读失败
                            return false;
                        }
                    }
                    else if (iCoilOrRegiterMode == CoilOrRegister.Register)
                    {
                        //数据缓存
                        byte[] bBuffer = new byte[uint16Length * 2];

                        try
                        {
                            //读寄存器
                            if (ReadHoldingRegisters(bSlaveID, uint16StartAddr, uint16Length, bBuffer) == uint16Length * 2)
                            {
                                //获得变量值缓存索引
                                int iItemValueBufferIndex = (mbItems[i].ItemAddress - uint16StartAddr) * 2;

                                //更新状态
                                mbItems[i].Status = ValueState.STATUS_GOOG;

                                //时间戳
                                mbItems[i].UpdateTime = DateTime.Now;

                                //变量数值缓存
                                ItemValue ivValue = new ItemValue();

                                //数值解析
                                switch (mbItems[i].ItemType)
                                {
                                    //word类型数据解析
                                    case "WORD":
                                        ivValue.B0 = bBuffer[iItemValueBufferIndex + 1];
                                        ivValue.B1 = bBuffer[iItemValueBufferIndex];
                                        mbItems[i].Value = Convert.ToDecimal(ivValue.Word);
                                        break;

                                    //dword类型解析
                                    case "DWORD":
                                        ivValue.B0 = bBuffer[iItemValueBufferIndex + 1];
                                        ivValue.B1 = bBuffer[iItemValueBufferIndex];
                                        ivValue.B2 = bBuffer[iItemValueBufferIndex + 3];
                                        ivValue.B3 = bBuffer[iItemValueBufferIndex + 2];
                                        mbItems[i].Value = Convert.ToDecimal(ivValue.DWord);
                                        break;

                                    //float类型解析
                                    case "FLOAT":
                                        ivValue.B0 = bBuffer[iItemValueBufferIndex + 1];
                                        ivValue.B1 = bBuffer[iItemValueBufferIndex];
                                        ivValue.B2 = bBuffer[iItemValueBufferIndex + 3];
                                        ivValue.B3 = bBuffer[iItemValueBufferIndex + 2];
                                        mbItems[i].Value = Convert.ToDecimal(ivValue.Float);
                                        break;

                                    //字符串类型解析
                                    case "STRING":
                                        char[] cStrBuf = new char[10];
                                        Array.Copy(bBuffer, iItemValueBufferIndex, cStrBuf, 0, 10);
                                        string strValue = new string(cStrBuf);
                                        mbItems[i].Value = strValue = strValue.Replace(new String(new Char[] { '\0' }), "");
                                        break;
                                }
                            }
                            else
                            {
                                //更新状态
                                mbItems[i].Status = ValueState.STATUS_BAD;

                                //时间戳
                                mbItems[i].UpdateTime = DateTime.Now;

                                //读失败
                                return false;
                            }
                        }
                        catch (Exception ex)
                        {
                            //更新状态
                            mbItems[i].Status = ValueState.STATUS_BAD;

                            //时间戳
                            mbItems[i].UpdateTime = DateTime.Now;

            #if DEBUG
                            Log.WriteLog(ex.ToString());
            #else
                            //Log.WriteLog(ex.ToString());
            #endif
                        }
                    }
                    else
                    {
                        //更新状态
                        mbItems[i].Status = ValueState.STATUS_BAD;

                        //时间戳
                        mbItems[i].UpdateTime = DateTime.Now;
                    }
                }
            }

            //读成功
            return true;
        }
예제 #6
0
        /// <summary>
        /// 写变量
        /// </summary>
        /// <param name="aModbusItem">变量</param>
        /// <param name="aValue">值</param>
        /// <returns>是否写成功</returns>
        public bool WriteItem(ref ModbusItem aModbusItem, Iolist aValue)
        {
            //如果值相等则不需再重写
            if (aModbusItem.Value.ToString().ToUpper() == aValue.Values.Value.ToString().ToUpper()
                && Convert.ToDecimal(aValue.Values.Value) != decimal.MaxValue)
                return false;

            //写圈或写寄存器模式
            CoilOrRegister iCoilOrRegiterMode = CoilOrRegister.Register;

            //写长度
            UInt16 uint16WriteLenth = 0;

            //写缓存
            byte[] bWriteBuffer = new byte[0];

            //写数值
            ItemValue ivItemValue = new ItemValue();

            //判断数据类型
            switch (aModbusItem.ItemType)
            {
                //WORD类型打包
                case "WORD":
                    ivItemValue.Word = Convert.ToInt16(aValue.Values.Value.ToString());
                    bWriteBuffer = new byte[2];
                    bWriteBuffer[0] = ivItemValue.B1;
                    bWriteBuffer[1] = ivItemValue.B0;
                    uint16WriteLenth = 1;
                    break;

                //DWORD类型打包
                case "DWORD":
                    ivItemValue.DWord = Convert.ToInt32(aValue.Values.Value.ToString());
                    bWriteBuffer = new byte[4];
                    bWriteBuffer[0] = ivItemValue.B1;
                    bWriteBuffer[1] = ivItemValue.B0;
                    bWriteBuffer[2] = ivItemValue.B3;
                    bWriteBuffer[3] = ivItemValue.B2;
                    uint16WriteLenth = 2;
                    break;

                //FLOAT类型打包
                case "FLOAT":
                    ivItemValue.Float = (float)Convert.ToDouble(aValue.Values.Value.ToString());
                    bWriteBuffer = new byte[4];
                    bWriteBuffer[0] = ivItemValue.B1;
                    bWriteBuffer[1] = ivItemValue.B0;
                    bWriteBuffer[2] = ivItemValue.B3;
                    bWriteBuffer[3] = ivItemValue.B2;
                    uint16WriteLenth = 2;
                    break;

                //STRING类型打包
                case "STRING":
                    //数值转换为字符串
                    string strValue = Convert.ToString(aValue.Values.Value.ToString());

                    //缓存
                    bWriteBuffer = new byte[10];
                    //char[] cBuffer = new char[10];

                    //数据打包
                    for (int i = 0; i < bWriteBuffer.Length && i < strValue.Length; i++) bWriteBuffer[i] = (byte)strValue[i];

                    //Array.Copy((byte[])cBuffer, 0, bWriteBuffer, 0, 10);
                    uint16WriteLenth = 5;
                    break;
                case "BOOLEAN":
                    iCoilOrRegiterMode = CoilOrRegister.Coil;
                    bWriteBuffer = new byte[1];
                    bWriteBuffer[0] = Convert.ToByte(aValue.Values.Value);
                    uint16WriteLenth = 1;
                    break;
                default:
                    uint16WriteLenth = 0;
                    break;
            }

            //写
            if (uint16WriteLenth > 0)
            {
                switch (iCoilOrRegiterMode)
                {
                    case CoilOrRegister.Coil:
                        //写线圈
                        if (WriteSingleCoil(aModbusItem.SlaveID, aModbusItem.ItemAddress, Convert.ToUInt16(bWriteBuffer[0])) == uint16WriteLenth)
                        {
                            //更新值
                            aModbusItem.Value = aValue.Values.Value;
                            aModbusItem.UpdateTime = DateTime.Now;
                            return true;
                        }
                        else
                        {
                            return false;
                        }
                        //break;
                    case CoilOrRegister.Register:
                        //写寄存器
                        if (WriteMultipleRegisters(aModbusItem.SlaveID, aModbusItem.ItemAddress, uint16WriteLenth, bWriteBuffer) == uint16WriteLenth * 2)
                        {
                            //更新值
                            aModbusItem.Value = aValue.Values.Value;
                            aModbusItem.UpdateTime = DateTime.Now;
                            return true;
                        }
                        else
                        {
                            return false;
                        }
                        //break;
                    default:
                        return false;
                        //break;
                }

            }
            else
            {
                return false;
            }

            //return true;
        }
예제 #7
0
        /// <summary>
        /// 读模拟量数据块
        /// </summary>
        /// <param name="aModbusItem">modbus变量表</param>
        /// <returns>读写是否成功</returns>
        public bool ReadItemsSimulationPiece(ref ModbusItem[] aModbusItem)
        {
            //从轮询地址
            byte bSlaveID = 0;

            //开始地址
            UInt16 uint16StartAddr = 0;

            //读取长度
            UInt16 uint16Length = 0;

            //排序
            var varSortItem = from item in aModbusItem
                              where item.ItemType != "BOOLEAN"
                              orderby item.SlaveID, item.ItemAddress
                              select item;
            ModbusItem[] mbItems = varSortItem.ToArray();

            //获得开始地址
            uint16StartAddr = Convert.ToUInt16(mbItems[0].ItemAddress);

            //获得读取长度
            uint16Length = Convert.ToUInt16(mbItems[mbItems.Length - 1].ItemAddress - uint16StartAddr);

            //判断最后一位需要缓存的长度
            switch (mbItems[mbItems.Length - 1].ItemType)
            {
                case "WORD":
                    uint16Length += 1;
                    break;
                case "DWORD":
                case "FLOATINVERSE":
                case "FLOAT":
                    uint16Length += 2;
                    break;
                case "STRING":
                    uint16Length += 5;
                    break;
            }

            //获取从轮寻地址
            bSlaveID = Convert.ToByte(mbItems[0].SlaveID);

            //当有读取长度时
            if (uint16Length > 0)
            {
                //数据缓存
                byte[] bBuffer = new byte[uint16Length * 2];

                try
                {
                    //读寄存器
                    if (ReadHoldingRegisters(bSlaveID, uint16StartAddr, uint16Length, bBuffer) == uint16Length * 2)
                    {

                        for (int i = 0; i < mbItems.Length; i++)
                        {
                            //获得变量值缓存索引
                            int iItemValueBufferIndex = (mbItems[i].ItemAddress - uint16StartAddr) * 2;

                            //更新状态
                            mbItems[i].Status = ValueState.STATUS_GOOG;

                            //时间戳
                            mbItems[i].UpdateTime = DateTime.Now;

                            //变量数值缓存
                            ItemValue ivValue = new ItemValue();

                            //数值解析
                            switch (mbItems[i].ItemType)
                            {
                                //word类型数据解析
                                case "WORD":
                                    ivValue.B0 = bBuffer[iItemValueBufferIndex + 1];
                                    ivValue.B1 = bBuffer[iItemValueBufferIndex];
                                    mbItems[i].Value = Convert.ToDecimal(ivValue.Word);
                                    break;

                                //dword类型解析
                                case "DWORD":
                                    ivValue.B0 = bBuffer[iItemValueBufferIndex + 1];
                                    ivValue.B1 = bBuffer[iItemValueBufferIndex];
                                    ivValue.B2 = bBuffer[iItemValueBufferIndex + 3];
                                    ivValue.B3 = bBuffer[iItemValueBufferIndex + 2];
                                    mbItems[i].Value = Convert.ToDecimal(ivValue.DWord);
                                    break;

                                //float类型解析
                                case "FLOAT":
                                    ivValue.B0 = bBuffer[iItemValueBufferIndex + 1];
                                    ivValue.B1 = bBuffer[iItemValueBufferIndex];
                                    ivValue.B2 = bBuffer[iItemValueBufferIndex + 3];
                                    ivValue.B3 = bBuffer[iItemValueBufferIndex + 2];
                                    mbItems[i].Value = Convert.ToDecimal(ivValue.Float);
                                    break;

                                //float inverse类型解析
                                case "FLOATINVERSE":
                                    ivValue.B0 = bBuffer[iItemValueBufferIndex + 3];
                                    ivValue.B1 = bBuffer[iItemValueBufferIndex + 2];
                                    ivValue.B2 = bBuffer[iItemValueBufferIndex + 1];
                                    ivValue.B3 = bBuffer[iItemValueBufferIndex];
                                    mbItems[i].Value = Convert.ToDecimal(ivValue.Float);
                                    break;

                                //字符串类型解析
                                case "STRING":
                                    char[] cStrBuf = new char[10];
                                    Array.Copy(bBuffer, iItemValueBufferIndex, cStrBuf, 0, 10);
                                    string strValue = new string(cStrBuf);
                                    mbItems[i].Value = strValue = strValue.Replace(new String(new Char[] { '\0' }), "");
                                    break;
                            }
                        }
                    }
                    else
                    {
                        for (int i = 0; i < mbItems.Length; i++)
                        {
                            //更新状态
                            mbItems[i].Status = ValueState.STATUS_BAD;

                            //时间戳
                            mbItems[i].UpdateTime = DateTime.Now;
                        }
            #if DEBUG
                        Log.WriteLog("ReadItemsSimulationPiece error");
            #else
                        Log.WriteLog("ReadItemsSimulationPiece error");
            #endif
                        //读失败
                        return false;
                    }
                }
                catch (Exception ex)
                {
                    for (int i = 0; i < mbItems.Length; i++)
                    {
                        //更新状态
                        mbItems[i].Status = ValueState.STATUS_BAD;

                        //时间戳
                        mbItems[i].UpdateTime = DateTime.Now;
                    }
            #if DEBUG
                    Log.WriteLog(ex.ToString());
            #else
                    //Log.WriteLog(ex.ToString());
            #endif
                }
            }

            //读取成功
            return true;
        }
예제 #8
0
        /// <summary>
        /// 读取数字量
        /// </summary>
        /// <param name="aModbusItem">modbus变量表</param>
        /// <returns>读写是否成功</returns>
        public bool ReadItemsFigurePiece(ref ModbusItem[] aModbusItem)
        {
            //从轮询地址
            byte bSlaveID = 0;

            //开始地址
            UInt16 uint16StartAddr = 0;

            //读取长度
            UInt16 uint16Length = 0;

            //排序
            var varSortItem = from item in aModbusItem
                              where item.ItemType == "BOOLEAN"
                              orderby item.SlaveID, item.ItemAddress
                              select item;
            ModbusItem[] mbItems = varSortItem.ToArray();

            if (mbItems.Count() > 0)
            {

                //获得开始地址
                uint16StartAddr = Convert.ToUInt16(mbItems[0].ItemAddress);

                //获得读取长度
                uint16Length = Convert.ToUInt16(mbItems[mbItems.Length - 1].ItemAddress - uint16StartAddr + 1);

                //获取从轮寻地址
                bSlaveID = Convert.ToByte(mbItems[0].SlaveID);

                //当有读取长度时
                if (uint16Length > 0)
                {
                    UInt16 uiLenth = 0;
                    if (uint16Length % 8 > 0)
                    {
                        uiLenth = Convert.ToUInt16(uint16Length / 8 + 1);
                    }
                    else
                    {
                        uiLenth = Convert.ToUInt16(uint16Length / 8);
                    }

                    //数据缓存
                    byte[] bBuffer = new byte[uiLenth];

                    try
                    {
                        //读线圈
                        if (ReadCoils(bSlaveID, uint16StartAddr, uint16Length, bBuffer) == uint16Length)
                        {
                            for (int i = 0; i < mbItems.Length; i++)
                            {
                                //获得变量值缓存索引
                                int iItemValueBufferIndex = (mbItems[i].ItemAddress - uint16StartAddr) / 8;

                                //更新状态
                                mbItems[i].Status = ValueState.STATUS_GOOG;

                                //时间戳
                                mbItems[i].UpdateTime = DateTime.Now;

                                //值
                                byte[] bByte = BitConverter.GetBytes(bBuffer[iItemValueBufferIndex]);
                                BitArray baList = new BitArray(bByte);
                                mbItems[i].Value = Convert.ToDecimal(baList[(mbItems[i].ItemAddress - uint16StartAddr) % 8]);
                            }
                        }
                        else
                        {
                            for (int i = 0; i < mbItems.Length; i++)
                            {
                                //值
                                //mbItems[i].Value = false;

                                //更新状态
                                mbItems[i].Status = ValueState.STATUS_BAD;

                                //时间戳
                                mbItems[i].UpdateTime = DateTime.Now;
                            }
            #if DEBUG
                            Log.WriteLog("ReadItemsFigurePiece error");
            #else
                            Log.WriteLog("ReadItemsFigurePiece error");
            #endif
                        }
                    }
                    catch (Exception ex)
                    {
                        for (int i = 0; i < mbItems.Length; i++)
                        {
                            //更新状态
                            mbItems[i].Status = ValueState.STATUS_BAD;

                            //时间戳
                            mbItems[i].UpdateTime = DateTime.Now;
                        }
            #if DEBUG
                        Log.WriteLog(ex.ToString());
            #else
                        //Log.WriteLog(ex.ToString());
            #endif
                        return false;
                    }
                }
            }
            //读取成功
            return true;
        }