FlexLua DTU01 Modbus 函数库

168 阅读12分钟

FlexLua DTU01 Modbus 函数库

Modbus数据转换


r1 = LIB_MbRtuMasterSendTrans(p1~p4)

函数描述: 根据p1不同的modbus功能码以及p1之后的参数,生成符合modbus协议格式的hex数据流,并以table数组形式返回

p1字符串类型
p1可为如下八个Modbus功能码之一
"01","02","03","04","05","06","0F","10"
p2整数型
需要通信的从机地址,1~255
p3和p4数据类型不固定
当p1="01"时,表示读线圈。p3=起始地址(0-0xFFFF),p4=个数(1-256)
当p1="02"时,表示读离散输入量。p3=起始地址(0-0xFFFF),p4=个数(1-256)
当p1="03"时,表示读保持寄存器。p3=起始地址(0-0xFFFF),p4=个数(1-100)
当p1="04"时,表示读输入寄存器。p3=起始地址(0-0xFFFF),p4=个数(1-100)
当p1="05"时,表示写单个线圈。p3=起始地址(0-0xFFFF),p4=线圈值(0或1)
当p1="06"时,表示写单个寄存器。p3=起始地址(0-0xFFFF),p4=16位寄存器值
当p1="0F"时,表示写多个线圈。p3=起始地址(0-0xFFFF),p4=数组,数组中元素的个数等于要写入的线圈个数,0和1代表线圈值 ,注意:元素个数不能超过256个
当p1="10"时,表示写多个寄存器。p3=起始地址(0-0xFFFF),p4=数组,数组中元素的个数等于要写入的寄存器个数,值即是要写入的寄存器的值 ,注意:元素个数不能超过123个
r1数组类型
返回的数组即为符合modbus协议格式的hex数据流数组

应用示例:

--读线圈(设备地址=0x03,起始地址=0x0000,个数=3)
LIB_Uart0Send(LIB_MbRtuMasterSendTrans("01", 0x03, 0x0000, 3))
--读离散输入量(设备地址=0x03,起始地址=0x0000,个数=2)
LIB_Uart0Send(LIB_MbRtuMasterSendTrans("02", 0x03, 0x0000, 2))
--读保持寄存器(设备地址=0x03,起始地址=0x0000,个数=1)
LIB_Uart0Send(LIB_MbRtuMasterSendTrans("03", 0x03, 0x0000, 1))
--读输入寄存器(设备地址=0x03,起始地址=0x0000,个数=5)
LIB_Uart0Send(LIB_MbRtuMasterSendTrans("04", 0x03, 0x0000, 5))
--写单个线圈(设备地址=0x03,起始地址=0x0000,线圈值=0)
LIB_Uart0Send(LIB_MbRtuMasterSendTrans("05", 0x03, 0x0000, 0))
--写单个寄存器(设备地址=0x03,起始地址=0x0000,寄存器值=0x1234)
LIB_Uart0Send(LIB_MbRtuMasterSendTrans("06", 0x03, 0x0000, 0x1234))
--写多个线圈(设备地址=0x03,起始地址=0x0000)
tab = {1,0,1,1}--写入的四个线圈值分别为1,0,1,1
LIB_Uart0Send(LIB_MbRtuMasterSendTrans("0F", 0x03, 0x0000, tab))
--写多个寄存器(设备地址=0x03,起始地址=0x0000)
tab = {0x2222, 0x3333}--写入的两个寄存器值分别为0x2222,0x3333
LIB_Uart0Send(LIB_MbRtuMasterSendTrans("10", 0x03, 0x0000, tab))

r1,r2 = LIB_MbRtuMasterRecvTrans(p1,p2)

函数描述: 根据p1功能码的类型,将从机发来的应答结果hex数据流数组p2解析出结果

p1字符串类型
p1可为如下八个Modbus功能码之一
"01","02","03","04","05","06","0F","10"
p2table型
从机发来的应答数据(需要被解析的数据流数组)
r1整数型,表示结果
r1大于0表示应答正确,小于等于零表示有问题。例如-1表示应答报文格式有问题,其他值为Modbus异常
r2table型
r2仅在读取类型的功能码时才会有,根据读取的类容不同,返回的table包含的数据意义也不同,比如"01"时包含的是各个线圈的值,"03"时包含的是各个寄存器的值

应用示例:

--例如我们通过recv_flag,recv_tab=LIB_Uart0Recv()获取到recv_tab数组中包含的从机发来的应答数据流
--解析从机发来的读线圈应答
if recv_flag == 1 then
	result,content=LIB_MbRtuMasterRecvTrans("01",recv_tab)
	if result > 0 then --打印content数组中的所有结果
		for i, v in ipairs(content) do 
	    	print(i, v)
		end
	else
		print("fail,re=%d",result)
	end
end
--解析从机发来的读离散输入量应答
if recv_flag == 1 then
	result,content=LIB_MbRtuMasterRecvTrans("02",recv_tab)
	if result > 0 then --打印content数组中的所有结果
		for i, v in ipairs(content) do 
	    	print(i, v)
		end
	else
		print("fail,re=%d",result)
	end
end
--解析从机发来的读保持寄存器应答
if recv_flag == 1 then
	result,content=LIB_MbRtuMasterRecvTrans("03",recv_tab)
	if result > 0 then --打印content数组中的所有结果
		for i, v in ipairs(content) do 
	    	print(i, v)
		end
	else
		print("fail,re=%d",result)
	end
end
--解析从机发来的读输入寄存器应答
if recv_flag == 1 then
	result,content=LIB_MbRtuMasterRecvTrans("04",recv_tab)
	if result > 0 then --打印content数组中的所有结果
		for i, v in ipairs(content) do 
	    	print(i, v)
		end
	else
		print("fail,re=%d",result)
	end
end
--解析从机发来的写单个线圈应答
if recv_flag == 1 then
	result=LIB_MbRtuMasterRecvTrans("05",recv_tab)
	if result > 0 then 
		print("write single coil ok")
	else
		print("fail")
	end
end
--解析从机发来的写单个寄存器应答
if recv_flag == 1 then
	result=LIB_MbRtuMasterRecvTrans("06",recv_tab)
	if result > 0 then 
		print("write single register ok")
	else
		print("fail")
	end
end
--解析从机发来的写多个线圈应答
if recv_flag == 1 then
	result=LIB_MbRtuMasterRecvTrans("0F",recv_tab)
	if result > 0 then 
		print("write multiple coil ok")
	else
		print("fail")
	end
end
--解析从机发来的写多个寄存器应答
if recv_flag == 1 then
	result=LIB_MbRtuMasterRecvTrans("10",recv_tab)
	if result > 0 then 
		print("write multiple register ok")
	else
		print("fail")
	end
end

RS485 Modbus数据采集极简函数(Uart1)


LIB_ModbusToJsonConfig(p1)

函数描述: 配置RS485 Modbus转Json功能(固定使用Uart1接口),并设置将要转换出来的Json最大字符串长度限制 注意:调用该函数前需要调用LIB_Uart1Rs485Config()函数

p1整数型
设置 Json 最大字符串长度,该值必须小于256

应用示例:

--配置RS485 Modbus转Json功能,并设置最终Json字符串最大长度为180字节
--例如mqtt单包传输字符串不能超过180字节,所以这里设置180
LIB_ModbusToJsonConfig(180)


--完整应用示例请参考LIB_ModbusToJsonSendCheck()函数的介绍


LIB_ModbusToJsonAdd(p1,p2,p3,p4)

函数描述: 增加一条需要读取的Modbus数据的寄存器起始地址、该数据的类型、小数个数、以及该数据的Json名称

p1整数型
需要读取的某个数据的寄存器起始地址,该值必须小于65536
p2字符串型
"S_AB":带符号16位整数,AB型
"S_BA":带符号16位整数,BA型
"U_AB":不带符号16整数,AB型
"U_BA":不带符号16整数,BA型
"UL_ABCD":不带符号32位整数,ABCD型
"UL_CDAB":不带符号32位整数,CDAB型
"UL_BADC":不带符号32位整数,BADC型
"UL_DCBA":不带符号32位整数,DCBA型
"L_ABCD":带符号32位整数,ABCD型
"L_CDAB":带符号32位整数,CDAB型
"L_BADC":带符号32位整数,BADC型
"L_DCBA":带符号32位整数,DCBA型
"F_ABCD":32位浮点数,ABCD型
"F_CDAB":32位浮点数,CDAB型
"F_BADC":32位浮点数,BADC型
"F_DCBA":32位浮点数,DCBA型
"D_ABCDEFGH":64位Double,ABCDEFGH"型
"D_GHEFCDAB":64位Double,GHEFCDAB型
"D_BADCFEHG":64位Double,BADCFEHG型
"D_HGFEDCBA":64位Double,HGFEDCBA型
"BIT":读线圈或读离散输入量时必须填"BIT"
p3整数型
小数个数 ,注意:该值不能超过6
情况1:整数时,有些RS485传感器厂家喜欢用整数表示小数(会指明几个小数),这时可将p3设置为相对应的小数个数
情况2:浮点数时,p3可用来指示该浮点数需要保留的小数个数
情况3:读线圈或读离散量时,p3可为任意值,一般设置成0
p4字符串型
要读的数据的Json名称。该字符串请尽量短一些减少通信字节数,最长不能超过32字节

应用示例:

--寄存器起始地址0x0002,数据类型"UL_ABCD",0位小数,Json名称"Temperature"
LIB_ModbusToJsonAdd(0x0002,"UL_ABCD",0,"Temperature")
--寄存器起始地址0x0004,数据类型"UL_ABCD",2位小数,Json名称"Humidity"
LIB_ModbusToJsonAdd(0x0004,"UL_ABCD",2,"Humidity")


--完整应用示例请参考LIB_ModbusToJsonSendCheck()函数的介绍


LIB_ModbusToJsonSend(p1~p7)

函数描述: 设置RS485通信参数以及Modbus相关参数

p1字符串类型,波特率选择
"BAUDRATE_1200"
"BAUDRATE_2400"
"BAUDRATE_4800"
"BAUDRATE_9600"
"BAUDRATE_14400"
"BAUDRATE_19200"
"BAUDRATE_28800"
"BAUDRATE_31250"
"BAUDRATE_38400"
"BAUDRATE_56000"
"BAUDRATE_57600"
"BAUDRATE_76800"
"BAUDRATE_115200"
"BAUDRATE_230400"
"BAUDRATE_250000"
"BAUDRATE_460800"
"BAUDRATE_921600"
"BAUDRATE_1000000"
p2字符串类型,校验方式选择
"NoneParity"
"EvenParity"
OddParity"
p3字符串类型,停止位选择
"StopBit_1"
"StopBit_1_5"
"StopBit_2"
p4字符串类型 ,Modbus功能码选择
p4可为如下四个Modbus读取类功能码之一
"01","02","03","04"
p5整数型,Modbus从机地址
0~255
p6整数型,Modbus应答最大等待时间(单位:毫秒)
该时间取决于485传感器的响应时间,不同的传感器可能不同,一般设置100ms既能应对大多数场景,特殊情况请查看相应传感器厂家提供的说明书以适当增加该时间值
p7整数型,Modbus包与包之间最小间隔时间(单位:毫秒)
由于每次最多只能读取100个连续的寄存器,当我们要读取的寄存器地址太过分散导致超过100个时,系统会自动分包读取,所以需要考虑该间隔时间。该间隔时间取决于传感器,一般设置100ms,特殊情况甚至需要达到1~2秒,所以请查看相应传感器厂家提供的说明书以适当增加该时间值

应用示例:

--从机参数设置(9600,无校验,1位停止位,功能码"03",从机地址0x01,应答最长等待100ms,包与包最短间隔50ms)
LIB_ModbusToJsonSend("BAUDRATE_9600","NoneParity","StopBit_1","03",0x01,100,50)

--完整应用示例请参考LIB_ModbusToJsonSendCheck()函数的介绍

r1,r2,r3 = LIB_ModbusToJsonFinishCheck()

函数描述: 查询modbus通信是否结束,以及结果(成功或失败),和故障信息

r1整数型,指示通信是否结束
0: 未结束
1: 结束
r2字符串,Json结果
注意:通信失败时将返回null,而不是传感器Json数据字符串
正常返回形如: {"temp":26.5, "humi":70}
r3字符串,Error错误信息
注意:通信失败时将返回错误信息,正常时仅返回null
返回 "Modbus read timeout" 表示RS485通信失败,检查下RS485硬件及线路是否正常
返回 "Modbus error: xx"表示Modbus数据格式错误、寄存器地址错误、寄存器数量超出范围等

应用示例:

--配置Uart1作为485接口,初始默认波特率19200,并且D8作为自动收发切换引脚
LIB_Uart1Rs485Config("BAUDRATE_19200","D8")
while(GC(1) == true)
do
	--当某个条件触发时,读取某个温湿度传感器的温度值和湿度值,并print打印输出Json结果字符串
	--Json字符串示例: {"temp":26, "humi":70.00}
	if something hanppen then
		--配置RS485 Modbus转Json功能,并设置Json字符串最大长度为180字节
		--例如mqtt单包传输字符串不能超过180字节,所以这里设置180
		LIB_ModbusToJsonConfig(180)
		--寄存器地址0x0002,类型"UL_ABCD",0位小数,Json名称"Temperature"
		LIB_ModbusToJsonAdd(0x0002,"UL_ABCD",0,"Temperature")
		--寄存器地址0x0004,类型"UL_ABCD",2位小数,Json名称"Humidity"
		LIB_ModbusToJsonAdd(0x0004,"UL_ABCD",2,"Humidity")
		--参数设置(9600,无校验,1位停止位,功能码"03",从机地址0x01,应答最长等待1000ms,包与包最短间隔50ms)
		--注意1:应答最长等待时间取决于通信数据量以及传感器,请查阅传感器说明书,通信失败时请尝试增加该值
		--注意2:包与包最短间隔时间取决于传感器,请查阅传感器说明书,通信失败时请尝试增加该值
		--开始Uart1 RS485通信
		LIB_ModbusToJsonSend("BAUDRATE_9600","NoneParity","StopBit_1","03",0x01,1000,50)
		--等待RS485通信结束
		while true do 
			Finish,Data,Err = LIB_ModbusToJsonFinishCheck()
			if Finish == 1 then
				print(Data)
				print(Err)
				break --跳出while循环
			end
		end
	end
end