树莓派如何解析 MODBUS 中的浮点型数据

一、前言

工业树莓派支持 MODBUS TCP/RTU 通讯协议,因此,在使用Modbus协议的温湿度传感器、电子天平、PLC等设备场景中应用十分广泛。当工业树莓派作为MODBUS TCP/RTU主站时,最多可以连接30个从站设备,由此可见,工业树莓派具有较好的可扩展性。

二、面临的问题

MODBUS从站设备有16位整型数据,但应用更多的是32位浮点型数据,这是因为32位浮点型数据能够在通讯过程中的控制更加精准,这类常应用于如电子天平的体重数据、温湿度传感器的温度/湿度数据、电机的转速等场景。
但在这个过程中会面临数据解析的问题:浮点型数据的应用需要遵循IEE745的数据转换规则,以实现与整型数据的转换和利用。
寄存器只能存放16位数据,所以浮点型数据会被拆分成两个数据部分,分别存放在相邻的两个寄存器中,具体如下:
– 在进行数据读取的时候,需要把两个寄存器数据通过数据解析还原成浮点型数据(如图1中所示);
– 在进行数据写入的时候,要通过数据解析把一个浮点型数据拆分成两个十六进制分别写入到相应的寄存器内(如图2中所示)。


图1 寄存器数据合并成浮点型数据


图2 浮点型数据写入到寄存器中

三、数据解析方法

针对此类问题,虹科提供一种解析方法,具体如下:
1、读取两个寄存器数据,通过位操作把两个寄存器数据合并成浮点型数据。

#Spe_h8和Spe_l8是MODBUS中的两个寄存器  
def int2float():  
    speed_Int = readFromName('Spe_h8')  
    speed_float = readFromName('Spe_l8')  
    speedlist = []  
    speedlist.append(speed_Int>>8 & 0xff)  
    speedlist.append(speed_Int & 0xff)  
    speedlist.append(speed_float>>8 & 0xff)  
    speedlist.append(speed_float>>8 & 0xff)  
    print(struct.unpack('>f',struct.pack('4B',*speedlist))[0])  

#0.1对应的十六进制是3D CC CC CD  
#存放在两个寄存器里分别是两个十进制数:15820 53429  
speed_int = 15820  
speed_float = 52429  
speedlist = []  
  
speedlist.append(speed_int>>8 & 0xff)  
speedlist.append(speed_int & 0xff)  
speedlist.append(speed_float>>8 & 0xff)  
speedlist.append(speed_float & 0xff)  
print(struct.unpack('>f',struct.pack('4B',*speedlist))[0])  


2、写入一个浮点型数据,通过位运算把32位浮点型数据拆分成两个16位整型数据,分别写入到两个寄存器中。

#把浮点型数据解析分别存放在两个变量里面,然后同时写入到寄存器中  
def float2int():  
    buf = struct.pack('>f',0.1)  
    list = []  
    list.append((buf[0]<<8 & 0xffff) +buf[1])  
    list.append((buf[2]<<8 & 0xffff)+ buf[2])  
    print (list[0],list[1])  

四、总结

工业树莓派采用Debian系统,开源性较高,可以通过 C/C++、Java、C#、Python 等方式进行编程。关于浮点型数据转换成16进制整型数据并进行数据解析可以试用的方法有很多,以上仅为其中一种数据解析方法,这种解析方法存在误差,误差范围为 ±0.01,可以适用于对浮点型数据精度要求不是特别高的情况。针对以上场景,如有其他解析方法,欢迎添加虹科工程师微信进行交流。



坐沙发

发表评论

你的邮件地址不会公开


*