예제 #1
0
        //调用前应对地址数组排序(是否加锁?),先一整块PDU读取到 缓存中,然后再逐个从缓存中 读取到各变量地址中
        public static ItemData <Storage>[] PLCReadMultiple(this IPLCDriver plc, ICache cache, DeviceAddress[] addrsArr)
        {
            if (addrsArr == null || cache == null || addrsArr.Length == 0)
            {
                return(null);
            }
            int len = addrsArr.Length;                                 //读取的 变量地址的个数

            ItemData <Storage>[] items = new ItemData <Storage> [len]; //需要填充的列表
            int            offset = 0; long now = DateTime.Now.ToFileTime();
            List <PDUArea> areas = cache.AssignFromPDU(plc.PDU, addrsArr);

            foreach (PDUArea area in areas)
            {
                byte[] rcvBytes = plc.ReadBytes(area.Start, (ushort)area.Len);
                Buffer.BlockCopy(rcvBytes, 0, cache.Cache, offset, rcvBytes.Length);
                offset += rcvBytes.Length / cache.ByteCount;
            }
            for (int i = 0; i < len; i++)
            {
                switch (addrsArr[i].VarType)
                {
                case DataType.BOOL:
                    items[i].Value.Boolean = cache.ReadBit(addrsArr[i]).Value;
                    break;

                case DataType.BYTE:
                    items[i].Value.Byte = cache.ReadByte(addrsArr[i]).Value;
                    break;

                case DataType.WORD:
                    items[i].Value.Word = cache.ReadUInt16(addrsArr[i]).Value;
                    break;

                case DataType.SHORT:
                    items[i].Value.Int16 = cache.ReadInt16(addrsArr[i]).Value;
                    break;

                case DataType.DWORD:
                    items[i].Value.DWord = cache.ReadUInt32(addrsArr[i]).Value;
                    break;

                case DataType.INT:
                    items[i].Value.Int32 = cache.ReadInt32(addrsArr[i]).Value;
                    break;

                case DataType.FLOAT:
                    items[i].Value.Single = cache.ReadFloat(addrsArr[i]).Value;
                    break;

                case DataType.STR:
                    var item = cache.ReadString(addrsArr[i], addrsArr[i].DataSize);
                    break;
                }
                items[i].Quality   = QUALITIES.QUALITY_GOOD;
                items[i].TimeStamp = now;
            }
            return(items);
        }
예제 #2
0
 public TagListGroup(short id, string name, int updateRate, int size, bool active, IPLCDriver plcReader)
 {
     this._id         = id;
     this._updateRate = updateRate;
     this._isActive   = active;
     this._reader     = plcReader;
     this._name       = name;
     this._server     = _reader.Parent;
 }
예제 #3
0
        public static int PLCWriteMultiple(this IPLCDriver plc, ICache cache, DeviceAddress[] addrArr, object[] buffer,
                                           int limit)
        {
            if (cache == null || addrArr == null || buffer == null || addrArr.Length != buffer.Length)
            {
                return(-1);
            }
            if (addrArr.Length == 1)
            {
                return(plc.WriteValue(addrArr[0], buffer[0]));
            }
            lock (plc) //不锁定会有并发冲突问题;锁定也不能保障绝对安全,如有人现场操作会导致数据刷新
            {
                List <PDUArea> areas  = cache.AssignFromPDU(plc.PDU, addrArr);
                int            offset = 0;
                foreach (PDUArea area in areas)
                {
                    byte[] rcvBytes = plc.ReadBytes(area.Start, (ushort)area.Len);
                    if (rcvBytes == null)
                    {
                        return(-1);
                    }
                    Buffer.BlockCopy(rcvBytes, 0, cache.Cache, offset, rcvBytes.Length);
                    offset += rcvBytes.Length / cache.ByteCount;
                }

                DeviceAddress start      = addrArr[0];
                int           startIndex = 0;
                int           endIndex   = 0;
                while (endIndex < addrArr.Length)
                {
                    if (start.Area != addrArr[endIndex].Area || start.DBNumber != addrArr[endIndex].DBNumber ||
                        endIndex - startIndex >= limit)
                    {
                        for (int i = startIndex; i < endIndex; i++)
                        {
                            cache.WriteValue(addrArr[i], buffer[i]);
                        }

                        int    c1    = start.CacheIndex;
                        int    c2    = addrArr[endIndex - 1].CacheIndex;
                        byte[] bytes = new byte[cache.ByteCount * (c2 - c1 + 1)];
                        Buffer.BlockCopy(cache.Cache, c1, bytes, 0, bytes.Length);
                        if (plc.WriteBytes(start, bytes) < 0)
                        {
                            return(-1);
                        }
                        start      = addrArr[endIndex];
                        startIndex = endIndex;
                    }

                    endIndex++;
                }
            }

            return(0);
        }
예제 #4
0
 public PLCGroup(short id, string name, int updateRate, bool active, IPLCDriver plcReader)
 {
     this._id          = id;
     this._name        = name;
     this._updateRate  = updateRate;
     this._isActive    = active;
     this._plcReader   = plcReader;
     this._server      = _plcReader.Parent;
     this._changedList = new List <int>();
     this._cacheReader = new ByteCacheReader();
     this._timer       = new Timer();
 }
예제 #5
0
 public NetBytePLCGroup(short id, string name, int updateRate, bool active, IPLCDriver plcReader)
 {
     this._id          = id;
     this._name        = name;
     this._updateRate  = updateRate;
     this._isActive    = active;
     this._plcReader   = plcReader;
     this._server      = _plcReader.Parent;
     this._timer       = new Timer();
     this._changedList = new List <int>();
     //this._cacheReader = new NetByteCacheReader();//这个是网络字节序,big endian
     this._cacheReader = new ByteCacheReader();//这个是小端字节序,little endian
 }