之前在做一个通过ModBus-RTU通讯协议来读取变送器数据的功能。通过发送一个指令,变送器收到指令后会返回数据。在发送指令然后接受到从机数据并进行处理。在.net下System.IO.Ports有一个SerialPort类,我们可以使用该类来进行串口通讯。对于Winforms也有相应串口通讯的控件。如何使用在这里不再进行赘述,网上可以找到很多相关的代码。
例如:
从机地址 | 功能码 | 数据地址(H) | 数据地址(L) | 数据(H) | 数据(L) | CRC16(L) | CRC16(H) |
---|---|---|---|---|---|---|---|
0X01 | 0X03 | 0X00 | 0X00 | 0X00 | 0X01 | 0X84 | 0X0A |
这一串指令的意思的是把数据0x01,写入到从机地址为01,从机数据地址为0的位置中。
对于CRC校验码,这个是通过前面的数据计算的出的。
例如:
从机地址 | 功能码 | 字节数 | 数据 | CRC16(L) | CRC16(H) |
---|---|---|---|---|---|
01 | 03 | 04 | BE40E612 | 15 | A2 |
其中数据BE 40 E6 12 为 IEEE754(二进制浮点数算术标准)的浮点数。
在读取串口数据时可以使用BytesToRead,来获取接收缓冲区中数据的字节数。
int nLen = sptPress.BytesToRead;//缓冲区中字节长度
然后对返回字节长度进行判断,如果达到要求则进行读取
byte[] bRec = new byte[nLen];
sptPress.Read(bRec, 0, nLen);//读取数据
在读取数据并储存在数组中之后,我的做法是将字节数组转换成字符串然后进行处理。
string s = BitConverter.ToString(bRec).Replace("-", “”);
下面是微软的示例代码,可以参考一下。
// Example of the BitConverter.ToString( byte[ ] ) method.
using System;
class BytesToStringDemo
{
// Display a byte array with a name.
public static void WriteByteArray( byte[ ] bytes, string name )
{
const string underLine = "--------------------------------";
Console.WriteLine( name );
Console.WriteLine( underLine.Substring( 0,
Math.Min( name.Length, underLine.Length ) ) );
Console.WriteLine( BitConverter.ToString( bytes ) );
Console.WriteLine( );
}
public static void Main( )
{
byte[ ] arrayOne = {
0, 1, 2, 4, 8, 16, 32, 64, 128, 255 };
byte[ ] arrayTwo = {
32, 0, 0, 42, 0, 65, 0, 125, 0, 197,
0, 168, 3, 41, 4, 172, 32 };
byte[ ] arrayThree = {
15, 0, 0, 128, 16, 39, 240, 216, 241, 255,
127 };
byte[ ] arrayFour = {
15, 0, 0, 0, 0, 16, 0, 255, 3, 0,
0, 202, 154, 59, 255, 255, 255, 255, 127 };
Console.WriteLine( "This example of the " +
"BitConverter.ToString( byte[ ] ) \n" +
"method generates the following output.\n" );
WriteByteArray( arrayOne, "arrayOne" );
WriteByteArray( arrayTwo, "arrayTwo" );
WriteByteArray( arrayThree, "arrayThree" );
WriteByteArray( arrayFour, "arrayFour" );
}
}
/*
This example of the BitConverter.ToString( byte[ ] )
method generates the following output.
arrayOne
--------
00-01-02-04-08-10-20-40-80-FF
arrayTwo
--------
20-00-00-2A-00-41-00-7D-00-C5-00-A8-03-29-04-AC-20
arrayThree
----------
0F-00-00-80-10-27-F0-D8-F1-FF-7F
arrayFour
---------
0F-00-00-00-00-10-00-FF-03-00-00-CA-9A-3B-FF-FF-FF-FF-7F
*/
然后截取字符串中的数据,再将其转换成浮点数数据。
当然也可以直接将byte类型的数组直接进行转换,可以设置数组的起始位置。
uint x = Convert.ToUInt32(s.Substring(6, 8), 16);//字符串转16进制32位无符号整数
float fy = BitConverter.ToSingle(BitConverter.GetBytes(x), 0);//字节转换float