PDA

Просмотр полной версии : Некорректно обрабатываемый ответ от контроллера ПЛК-150



kolyagl
15.06.2017, 17:19
Здравствуйте, не так много времени прошло с того момента как я создал первую тему на этом форуме) и снова у меня возникли трудности теперь с обработкой ответа, а именно с тем, что каким то мне пока не понятным образом программа написанная мною на C# некорректно обрабатывает ответ от ПЛК-150. Суть проблемы вот в чём ПЛК отправляет мне значение float в виде 4-х байт, задача стоит в том, чтобы эти 4-е байта преобразовать в значение float которое отправляет мне ПЛК. С этой задачей я вроде справился т.к полученные байты я преобразую во float но тут выяснилось, что эти значения не совпадают+ к этому значения в моей программе постоянно изменяются причем не незначительно а как то рандомно. При этом в Modscan всё отлично работает и запрос отправляемый мной полностью совпадает с запросом отправляемым Modscan. А теперь основной вопрос как так получилось, что при одинаковом запросе я получаю разные ответы?) скрины и код к рассказу прилагаются . Да и ещё один интересный факт данная программа нормально работала с ТРМ-138 по суть основа и была взята из той программы
namespace ТРМ_138
{

public partial class Form1 : Form
{
SerialPort serialPort1 = new SerialPort("COM5", 115200, Parity.None, 8, StopBits.One);
public Form1()
{
InitializeComponent();

}

private void Form1_Load(object sender, EventArgs e)
{
serialPort1.Open();
}

//Метод формирования запроса ModBus RTU
public static byte[] ReadHoldingRegister(byte id, byte command, byte startAddress, byte length)
{
byte[] data = new byte[8];
byte High, Low;
//Адрес устройства
data[0] = Convert.ToByte(001);
//Код функции Modbus
data[1] = Convert.ToByte(004);
//Начальный адрес регистра
byte[] _adr = BitConverter.GetBytes(startAddress);
data[2] = 00;//[1] младший
data[3] = 00;//[0] старший
//Колличество регистров которое необходимо считать
byte[] _length = BitConverter.GetBytes(length);
data[4] = 00;//[1]
data[5] = 02;//[0]
//Контрольная сумма CRC
myCRC(data, 6, out High, out Low);
data[6] = Low;//[1]
data[7] = High;//[0]
return data;
}

//Метод расчёта контрольной суммы CRC-16
public static void myCRC(byte[] message, int length, out byte CRCHigh, out byte CRCLow)
{
ushort CRCFull = 0xFFFF;
for (int i = 0; i < length; i++)
{
CRCFull = (ushort)(CRCFull ^ message[i]);
for (int j = 0; j < 8; j++)
{
if ((CRCFull & 0x0001) == 0)
CRCFull = (ushort)(CRCFull >> 1);
else
{
CRCFull = (ushort)((CRCFull >> 1) ^ 0xA001);
}
}
}
CRCHigh = (byte)((CRCFull >> 8) & 0xFFFF);
CRCLow = (byte)(CRCFull & 0xFFFF);
}

private void button1_Click(object sender, EventArgs e)
{

timer1.Enabled=true;
}
private void timer1_Tick(object sender, EventArgs e)
{

{ //Отправка команды для ПЛК-150
serialPort1.Write(ReadHoldingRegister(16, 004, 0000, 0010), 0, 8);

//Побайтовое считывание ответа от ПЛК-150
byte[] IntArr = new byte[9];
for (int i = 0; 8 >= i; ++i)
{
IntArr[i] = Convert.ToByte(serialPort1.ReadByte());
}

string otv = string.Concat(IntArr[0], " ", IntArr[1], " ", IntArr[2], " ", IntArr[3], " ", IntArr[4], " ", IntArr[5], " ", IntArr[6], " ", IntArr[7], " ", IntArr[8]);
textBox5.Text = otv;

//Конвертирование 4-х байт полученных от ПЛК-150 во float
float value1 =BitConverter.ToSingle(IntArr,2);
textBox1.Text = value1.ToString();

}
}
}
}


31697

31696

31695

31694

Помогите советом дельным)))

mf_
15.06.2017, 20:38
Это издевательство выводить значения в десятеричной системе. В том ли порядке вы считываете байты?

kolyagl
16.06.2017, 09:00
В смысле издевательство выводить значения в десятеричной системе? Байты отвечающие за число float 3, 4, 5, 6 в C# есть метод конвертации 4-х байт в число float собственно вот он float value1 =BitConverter.ToSingle(IntArr,2); байтовый массив создаётся в том порядке в котором байты приходят из порта, как я могу их считать не в том порядке? т.е я имею ответ 1 4 4 2 байта данных 2 байта данных CRC в такой последовательности я их и читаю.

capzap
16.06.2017, 09:05
Байты отвечающие за число float 3, 4, 5, 6перед формированием флоата, поменяйте местами например 6,5,4,3 или на две другие оставишиеся комбинации и получите свои 21 градус цельсия

kolyagl
16.06.2017, 11:07
на какие две другие комбинации? комбинаций с 3 4 5 6 побольше двух получится и что это за пробор такой в котором такие манипуляции надо производить, что бы адекватный ответ получить.

kolyagl
16.06.2017, 11:20
перестановка не помогла пробовал.

capzap
16.06.2017, 11:29
что это за пробор такой в котором такие манипуляции надо производить, что бы адекватный ответ получить.

слышали что нибудь про младшим/старшим байтом/словом вперед?

mf_
16.06.2017, 11:30
на какие две другие комбинации? комбинаций с 3 4 5 6 побольше двух получится и что это за пробор такой в котором такие манипуляции надо производить, что бы адекватный ответ получить.
Про порядок big endian и little endian не слышали, что-ли?

Упс.. опередили, почти слово-в-слово :)

capzap
16.06.2017, 11:36
слышали что нибудь про младшим/старшим байтом/словом вперед?

ЗЫ например можно перечитать документацию на конфигурацию контроллера, на предмет зачем в мастере выделенный на картинке пункт

kolyagl
19.06.2017, 09:00
Слышал, поэтому попробовал разные вариации, но это не помогло. Сейчас перечитаю. Спасибо за ответы.

kolyagl
19.06.2017, 10:07
Мне не совсем понятно зачем мне этот параметр ковырять?

kolyagl
19.06.2017, 10:46
С проблемой разобрался. Дело было действительно в порядке) всем спасибо за помощь.