Esempio n. 1
0
        private void spDataReceived()
        {
            //Эмулятор ответов
            byte[] buff = new byte[45] {
                0x01, 0x03, 0x28, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x08, 0xA1, 0x09, 0xA2, 0xAB, 0xCD, 0x01, 0x02, 0x03, 0xE8, 0x13, 0x8A, 0x00, 0x00, 0x00, 0x00, 0x74, 0x40
            };
            Console.Out.WriteLine(DateTime.Now + " << [" + BitConverter.ToString(buff, 0) + "]");
            Console.Write(" >> [" + BitConverter.ToString(buff) + "]");

            if (buff.Count() >= buffSize)
            {
                //ответ полный, проверяем контрольную сумму и анализируем ответ
                byte[] resp   = buff.Take(buffSize - 2).ToArray();         //без 2-х последних байтов ответа (CRC16)
                byte[] crc    = buff.Skip(buffSize - 2).Take(2).ToArray(); //2 последних байта ответа (CRC16)
                ushort crcRCV = BitConverter.ToUInt16(crc, 0);
                ushort _crc16 = MainForm.CRC.ComputeChecksum(resp);
                Console.Out.WriteLine(DateTime.Now + " << " + crcRCV + " / " + _crc16);

                if (crcRCV != _crc16)
                {
                    //return;
                    if (resp[2] != 0x28)
                    {
                        return;//TODO сделать анализ ошибок modbus
                    }
                }
                sw.Stop();
                Register.RegType rT = (Register.RegType)BitConverter.ToInt16(resp, 1);
                //var tmpColl = Devices[MainForm.currDevice].Registers.Where(r => r.Type == rT);
                var tmpColl = MainForm.currDevice.Registers.Where(r => r.Type == rT);
                int index   = 3;//первые 3 байта ответа - номер устройства, номер команды, признак ошибки/корректного ответа - пропускаем
                int skip    = 0;
                foreach (Register r in tmpColl)
                {
                    if (skip > 0)
                    {
                        r.Status = false;
                        skip--;
                    }
                    else
                    {
                        r.Status = true;
                        int bytesNum = Convert.ToInt32(r.ByteNum());
                        skip = bytesNum / 2 - 1;//сколько регистров необходимо пропустить для случая, если значение занимает несколько регистров

                        byte[] tmp = buff.Skip(index).Take(bytesNum).ToArray();

                        r.ValArr = tmp;
                        //Console.Out.Write(BitConverter.ToString(r.ValArr)+"\n");
                        index += bytesNum;
                    }
                }

                QueriesNumRCV++;

                totalRCV = 0;
            }
        }
Esempio n. 2
0
        private void spDataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            //try
            //{
            lock (MainForm.locker)
            {
                byte[] buff = new byte[buffSize];
                //byte[] buff = new byte[Port.BytesToRead];
                //Console.Out.WriteLine(DateTime.Now + " << [" + Port.BytesToRead + "]");
                //Port.Read(buff, 0, Port.BytesToRead);
                //Console.Out.WriteLine(DateTime.Now + " << " + BitConverter.ToString(buff));


                //byte[] resp = buff.Take(buffSize - 2).ToArray();//без 2-х последних байтов ответа (CRC16)
                //byte[] crc = buff.Skip(buffSize - 2).Take(2).ToArray();//2 последних байта ответа (CRC16)
                //TODO предусмотреть прием ответа частями
                if (Port.BytesToRead >= buffSize)
                {
                    //ответ полный, проверяем контрольную сумму и анализируем ответ
                    Port.Read(buff, 0, buffSize);
                    Console.Write(" << " + BitConverter.ToString(buff));

                    byte[] resp   = buff.Take(buffSize - 2).ToArray();         //без 2-х последних байтов ответа (CRC16)
                    byte[] crc    = buff.Skip(buffSize - 2).Take(2).ToArray(); //2 последних байта ответа (CRC16)
                    ushort crcRCV = BitConverter.ToUInt16(crc, 0);
                    ushort _crc16 = MainForm.CRC.ComputeChecksum(resp);

                    if (crcRCV != _crc16)
                    {
                        return;
                    }

                    sw.Stop();
                    Register.RegType rT = (Register.RegType)BitConverter.ToInt16(resp, 1);
                    var tmpColl         = MainForm.currDevice.Registers.Where(r => r.Type == rT);
                    int num             = tmpColl.Count();
                    if (num > 0)
                    {
                        int index      = 3;//пропускаем первые 3 байта ответа - номер устройства, номер команды, количество байт ответа
                        int skip       = 0;
                        int regPointer = 0;
                        int lastAdrr   = 0;
                        int firstAdrr  = 0;

                        foreach (Register r in tmpColl)
                        {
                            int adr = (int)r.realAdress;


                            //if (prevAdrr == 0)
                            //    prevAdrr = adr;

                            int bytesNum = Convert.ToInt32(r.ByteNum());

                            //regPointer += (adr - prevAdrr);
                            if (lastAdrr == 0) //TODO разобраться со вставкой регистров меньше начального
                            {
                                lastAdrr = firstAdrr = adr;
                            }

                            //if (adr <= startRegister){
                            //    nextAdrr = adr;
                            //    startRegister = adr;
                            //}
                            regPointer = (adr - startRegister);

                            if (regPointer >= 0)
                            {
                                r.Status = !((adr > firstAdrr) && (adr < lastAdrr));
                                skip     = regPointer * 2 + 3;//смещение в ответе к значению текущего регистра

                                byte[] tmp = buff.Skip(skip).Take(bytesNum).ToArray();
                                r.ValArr = tmp;



                                if (bytesNum > 2)
                                {
                                    firstAdrr = adr;
                                    lastAdrr  = adr + (bytesNum / 2);//запоминаем текущий адрес как предыдущий
                                }
                            }
                        }
                    }

                    QueriesNumRCV++;

                    totalRCV = 0;
                    //dataProcessed = true;
                }
            }
            //} catch(Exception exept)
            //{
            //    Console.Write(exept.Message);
            //}
            //OnDataReady();
        }