示例#1
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;
        }
示例#2
0
        /// <summary>
        /// 读变量表
        /// </summary>
        /// <param name="aModbusItem">需要更新的变量表</param>
        /// <returns>读写是否成功</returns>
        public bool  ReadItems(ref ModbusItem[] aModbusItem)
        //        public bool ReadItems(ref ModbusItem aModbusItem)//改成与WriteItem格式一样,去掉[]
        {
            //读线圈或读寄存器模式
            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);
        }