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; } }
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(); }