C# 将IEEE754格式响应转换为C中的双精度值#
如何将IEEE754格式的浮点返回值转换为可读值 设备的响应返回为C# 将IEEE754格式响应转换为C中的双精度值#,c#,serial-port,modbus,rs485,C#,Serial Port,Modbus,Rs485,如何将IEEE754格式的浮点返回值转换为可读值 设备的响应返回为02 03 04 43 5D 38 10 5F 69,其中: 02-从机地址 03-功能代码 04-字节计数 43 5D 38 10-从设备返回的值 5F 69-CRC 下面是我使用的代码: void ModbusHandler() { try { while (run) { byte[] resp = new byte[9]; whi
02 03 04 43 5D 38 10 5F 69
,其中:
02-从机地址
03-功能代码
04-字节计数
43 5D 38 10-从设备返回的值
5F 69-CRC
下面是我使用的代码:
void ModbusHandler()
{
try
{
while (run)
{
byte[] resp = new byte[9];
while (!modread.TheReadingFunction(startaddr, datalength, devid, fn, ref resp)) ;
if (resp != null)
{
if (!dataevents.IsDisposed)
UpdateTextBox( PrintBytes(resp));
string myFloat = floatConversion(resp).ToString();
if (!dataevents.IsDisposed)
UpdateTextBox($"Conversion: {myFloat}");
double val0 = ToFloat(resp);
if (!dataevents.IsDisposed)
UpdateTextBox($"Value 0: {val0}");
double val1 = Math.Round(Convert.ToDouble(resp[3] << 8 | resp[4] & 0xFF), 3, MidpointRounding.AwayFromZero);
if (!dataevents.IsDisposed)
UpdateTextBox($"Value 1: {val1}");
double val2 = Math.Round(Convert.ToDouble(resp[5] << 8 | resp[6] & 0xFF), 3, MidpointRounding.AwayFromZero);
if (!dataevents.IsDisposed)
UpdateTextBox($"Value 2: {val2}");
double res1 = (resp[3] << 8 | resp[4] & 0xFF);
double res2 = (resp[5] << 8 | resp[6] & 0xFF);
if (!dataevents.IsDisposed)
UpdateTextBox($"Byte 1: {res1}|Byte 2: {res2}");
}
else
{
if (!dataevents.IsDisposed)
UpdateTextBox("Reponse is null");
}
}
}
catch (Exception err)
{
if (!dataevents.IsDisposed)
UpdateTextBox($"Error in modbus read: {err.Message.ToString()}");
}
}
float floatConversion(byte[] data)
{
float result = BitConverter.ToSingle(BitConverter.IsLittleEndian ? data.Reverse().ToArray() : data, 0);
return result;
}
float ToFloat(byte[] input)
{
byte[] newArray = new[] { input[2], input[3], input[0], input[1] };
return BitConverter.ToSingle(newArray, 0);
}
设备上的当前值为~207.686V这是一个功率计如果结果为221.219V,则:
Array.Reverse(resp, 3, 4);
float volts = BitConverter.ToSingle(resp, 3)
您的IEEE754数字是以大端为单位的(而您的计算机是以小端为单位的),因此您可以反转字节并进行转换。如果结果是真的221.219V,则:
Array.Reverse(resp, 3, 4);
float volts = BitConverter.ToSingle(resp, 3)
您的IEEE754数字是以大端为单位的(而您的计算机是以小端为单位的),因此您可以反转字节并进行转换。您确定响应告诉您IEEE754中的电压吗?因为207.686将是
9eaf4f43
,所以您可以自己查看它:Single sing=207.686f;var iee=BitConverter.GetBytes(sing);Console.WriteLine(位转换器.ToString(iee))代码>如果实际结果为221V,则var arr1=new byte[]{0x43,0x5D,0x38,0x10};反向排列(arr1);var flt=位转换器.ToSingle(arr1,0)代码>给出了它。所以你可以:Array.Reverse(resp,3,4);浮动电压=位转换器至单个(分别为3)代码>并且您的IEEE754是big-endian格式。您确定响应告诉您IEEE754中的电压吗?因为207.686将是9eaf4f43
,所以您可以自己查看它:Single sing=207.686f;var iee=BitConverter.GetBytes(sing);Console.WriteLine(位转换器.ToString(iee))代码>如果实际结果为221V,则var arr1=new byte[]{0x43,0x5D,0x38,0x10};反向排列(arr1);var flt=位转换器.ToSingle(arr1,0)代码>给出了它。所以你可以:Array.Reverse(resp,3,4);浮动电压=位转换器至单个(分别为3)代码>并且你的IEEE754是大端格式的。我认为你是对的,但是看看操作代码。这float result=BitConverter.ToSingle(BitConverter.IsLittleEndian?data.Reverse().ToArray():数据,0)
也这样做,应该会给出正确的结果……尽管我注意到他是针对所有响应而不是真实数据这样做的:)@Pikoh并且反转整个响应会更改各个字段的开始索引。。。最好是反转需要反转的单个“片段”信息。是的。该过程应首先将响应拆分为不同的部分,然后反转它们并位转换器。ToSingle
。那应该管用fine@xanatos,你在主要帖子上的评论是对的。。我把所有字节都放入位转换器。我想只取字节[3]-字节[6]。响应发送所有字节,包括,start,datalen,crc,所以我的错误是转换所有字节。你的评论是对的,我想你是对的,但是看看操作码。这float result=BitConverter.ToSingle(BitConverter.IsLittleEndian?data.Reverse().ToArray():数据,0)
也这样做,应该会给出正确的结果……尽管我注意到他是针对所有响应而不是真实数据这样做的:)@Pikoh并且反转整个响应会更改各个字段的开始索引。。。最好是反转需要反转的单个“片段”信息。是的。该过程应首先将响应拆分为不同的部分,然后反转它们并位转换器。ToSingle
。那应该管用fine@xanatos,你在主要帖子上的评论是对的。。我把所有字节都放入位转换器。我想只取字节[3]-字节[6]。响应发送所有字节,包括,start,datalen,crc,所以我的错误是转换所有字节。你的评论是对的