Radar.lua 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. --重要声明!!!
  2. --该代码仅供学习参考使用,未经量产验证;
  3. --思路可以借鉴,但是不要直接用在项目开发上,一定要结合自己项目做!!!
  4. --================================================================
  5. local Radar = {}--RS485空气开关控制
  6. log.info("4G_RTU", "Radar")
  7. kong_Value=0--空高
  8. liao_Value=0--料高
  9. Radar_State=0--雷达状态2024.11.16雷达状态,等于0表示未连接,1表示连接成功
  10. --=============================================================
  11. local uartid = 2 -- 根据实际设备选取不同的uartid,2代表uart2
  12. --初始化串口
  13. local result = uart.setup(
  14. uartid,--串口id
  15. 115200,--波特率
  16. 8,--数据位
  17. 1--停止位
  18. )
  19. log.info("uart2", "雷达串口初始化完成")
  20. --=============================================================
  21. --读雷达命令
  22. local Device_Address=0x01 --根据实际情况设置
  23. --读雷达状态,功能码03
  24. --1.同时读取空高/料高:01 03 00 00 00 04 44 09
  25. local Read_Radar_Date=string.char(Device_Address,0x03,0x00,0x00,0x00,0x04,0x44,0x09)
  26. --2.同时读取空高/料高/SNR/温度:01 03 00 00 00 08 44 0C
  27. local Read_4_Date=string.char(Device_Address,0x03,0x00,0x00,0x00,0x08,0x44,0x0C)
  28. --3.同时读取空高/料高/SNR/温度/湿度/俯仰角/横滚角:01 03 00 00 00 0E C4 0E
  29. local Read_7_Date=string.char(Device_Address,0x03,0x00,0x00,0x00,0x0E,0xC4,0x0E)
  30. --4.读取波特率:01 03 20 01 00 01 DE 0A
  31. local Read_Baud_rate=string.char(Device_Address,0x03,0x20,0x01,0x00,0x01,0xDE,0x0A)
  32. --=============================================================
  33. --crc16校验函数
  34. function crc16(buf,len)
  35. local init = 0xFFFF;
  36. local poly = 0xA001;
  37. local ret = init;
  38. local byte=0;
  39. for j=1,len,1 do
  40. byte = string.byte(buf,j);
  41. ret=((ret ~ byte) & 0xFFFF);
  42. for i=1,8,1 do
  43. if((ret & 0x0001)>0) then
  44. ret = (ret >> 1);
  45. ret = ((ret ~ poly) & 0xFFFF);
  46. else
  47. ret= (ret >> 1);
  48. end;
  49. end
  50. end
  51. local hi = ((ret >> 8) & 0xFF);
  52. local lo = (ret & 0xFF);
  53. ret = ((lo << 8) | hi);
  54. return ret;
  55. end
  56. --=============================================================
  57. function get_warn()--判断报警标志位
  58. if warn_type==1 and liao_Value<warn_data then
  59. my_type=0
  60. log.info("正常水位")
  61. elseif warn_type==1 and liao_Value>warn_data and liao_Value<warn_high_data then
  62. my_type=0
  63. log.info("告警水位")
  64. elseif warn_type==1 and liao_Value>warn_high_data then
  65. my_type=1
  66. log.info("超高水位告警")
  67. --================
  68. elseif warn_type==2 and kong_Value>warn_kong_data then
  69. my_type=0
  70. log.info("正常空高")
  71. elseif warn_type==2 and kong_Value<warn_kong_data and kong_Value>warn_kong_high_data then
  72. my_type=0
  73. log.info("告警空高休眠")
  74. elseif warn_type==2 and kong_Value<warn_kong_high_data and kong_Value>0 then
  75. my_type=2
  76. log.info("空高超高告警")
  77. end
  78. end
  79. --=============================================================
  80. --采集雷达数据
  81. local function get_radar_date()
  82. while true do
  83. sys.waitUntil("IP_READY",3000)
  84. --给三秒的联网时间,联不上也给雷达供电
  85. gpio.setup(27, 1)--3819使能打开,GPIO27,PIN脚=16
  86. gpio.setup(38, 1, gpio.PULLUP)--12V输出打开,GPIO38,PIN脚=51,对照表是对的2024.7.24
  87. sys.wait(10000)--在等2秒后测试雷达是否在线
  88. uart.write(uartid,Read_4_Date)
  89. log.info("发送读波特率命令")
  90. sys.wait(2000)--在等2秒后测试雷达是否在线
  91. if Radar_State==1 then
  92. log.info("雷达在线")
  93. else--雷达不在线,尝试一次断电,不管成功与否,20秒后都会断电
  94. log.info("雷达不在线")
  95. Radar_State=0--标志位置成0
  96. gpio.setup(27, 0)--3819使能打开,GPIO27,PIN脚=16,不回
  97. sys.wait(2000)--等2秒放电
  98. gpio.setup(27, 1)--3819使能打开,GPIO27,PIN脚=16
  99. sys.wait(6000)--在等2秒后测试雷达是否在线
  100. uart.write(uartid,Read_4_Date)
  101. log.info("雷达重新上电完成")
  102. end
  103. end
  104. end
  105. --=============================================================
  106. --注册串口事件回调
  107. uart.on(uartid, "receive", function(id, len)
  108. local s = ""
  109. repeat --repeadt类似C语言的do…while循环,repeat重复执行循环,直到until指定条件为真
  110. s = uart.read(id, len)
  111. --log.info("uart", "receive", id, #s, s)
  112. log.info("串口2", "receive", id, #s, s:toHex())
  113. --log.info("第三个数string.byte(s,3)=", string.byte(s,3))
  114. if #s > 0 then -- #s 是取字符串的长度,string.byte(s,3)==8判断师回复的那条命令
  115. -- 如果传输二进制/十六进制数据, 部分字符不可见, 不代表没收到
  116. -- 关于收发hex值,请查阅 https://doc.openluat.com/article/583
  117. log.info("第三个数string.byte(s,3)=", string.byte(s,3))
  118. local crc16=crc16(s,#s-2)
  119. local crc16_high=crc16 >> 8
  120. local crc16_low=crc16 & 0xFF
  121. log.info("CRC校验高位",crc16_high,"CRC校验低位",crc16_low)
  122. --打印其hex字符串形式
  123. --数据转换为数值string.byte,用于crc校验
  124. local receive_crc_high = string.byte(s,#s-1)
  125. local receive_crc_low = string.byte(s,#s)
  126. local receive_Switch_state = string.byte(s,#s-2)
  127. log.info("接收到的CRC校验高位", "接收到的CRC校验低位", receive_crc_high, receive_crc_low)
  128. log.info("uart", "receive", id, #s, s:toHex())
  129. --=============================================================
  130. --识别读取数据并将数据赋值给空高料高变量
  131. --if crc16_high==receive_crc_high and crc16_low==receive_crc_low and string.byte(s,3)==8 then
  132. if crc16_high==receive_crc_high and crc16_low==receive_crc_low and string.byte(s,3)==16 then--判断10数据
  133. --注意,string.byte(s,3)==16,收到字符串的第3个数据,判断时要转换为十进制数,第三个数为0x10,十进制数为16
  134. log.info("crc检验通过数据合法")
  135. --先将字符串转为hex格式
  136. local hexStr, len = string.toHex(s) -- 返回值"3132",2,后面的2是长度
  137. --log.info("收到的16进制字符串=",hexStr,len)
  138. --print(hexStr,len) -- 将输出 3132
  139. --截取空高数据,并加上0x个前缀
  140. local kong_high="0x"..string.sub(hexStr,7,14)--将0x拼接到字符串上,string.sub(hexStr,7,14)是一个数字算一个
  141. --截取料高数据,并加上0x个前缀
  142. local liao_high="0x"..string.sub(hexStr,15,22)--将0x拼接到字符串上
  143. --信噪比
  144. local SNR_Date="0x"..string.sub(hexStr,23,30)--将0x拼接到字符串上
  145. --雷达温度
  146. local temp_Date="0x"..string.sub(hexStr,31,38)--将0x拼接到字符串上
  147. log.info("空高16进制字符串=",kong_high)
  148. log.info("料高16进制字符串=",liao_high)
  149. log.info("信噪比16进制字符串=",SNR_Date)
  150. log.info("雷达温度比16进制字符串=",temp_Date)
  151. --将hex格式转化为浮点型数据
  152. local kong_temp = string.pack("<L",kong_high)
  153. kong_Value = string.unpack("f",kong_temp)
  154. log.info("空高=",kong_Value)
  155. local liao_temp = string.pack("<L",liao_high)
  156. liao_Value = string.unpack("f",liao_temp)
  157. log.info("料高=",liao_Value)
  158. local SNR_temp = string.pack("<L",SNR_Date)
  159. SNR = string.unpack("f",SNR_temp)
  160. log.info("信噪比=",SNR)
  161. local xinhao_temp = string.pack("<L",temp_Date)
  162. Radar_temp = string.unpack("f",xinhao_temp)
  163. log.info("雷达温度=",Radar_temp)
  164. --uart.write(1, s)--正常采集不透传给串口1,也就是传给蓝牙
  165. log.info("采集空高回传串口1", "receive", id, #s, s)
  166. get_warn()--采集完雷达,设置报警标志位
  167. sys.publish("雷达完成")
  168. Radar_State=1--2024.11.16,雷达在线标志位
  169. --=============================================================
  170. --如果不是采集命令,则透传给串口1
  171. elseif crc16_high==receive_crc_high and crc16_low==receive_crc_low then
  172. log.info("串口2透传给串口1数据且雷达在线了", "receive", id, #s, s)
  173. -- log.info("uart", "receive", id, #s, s:toHex())
  174. uart.write(1, s)--暂时不透传给串口1
  175. elseif crc16_high~=receive_crc_high or crc16_low~=receive_crc_low then
  176. log.info("无数据或crc检验不通过")
  177. --my_type=3--水位故障标志位--这里会导致出现正常数据报故障的问题
  178. kong_Value=-100--空高
  179. liao_Value=-100--料高
  180. uart.write(1, s)--暂时不透传给串口1
  181. --两种情况,一种是采集失败,一种是采集回波曲线
  182. end
  183. end
  184. if #s == len then
  185. --log.info("程序经过这里1")
  186. break
  187. end
  188. until s == ""
  189. --log.info("程序经过这里2")
  190. end)
  191. --=============================================================
  192. --=============================================================
  193. -- 并非所有设备都支持sent事件
  194. uart.on(uartid, "sent", function(id)
  195. log.info("uart", "sent", id)
  196. end)
  197. --=============================================================
  198. --开启协程
  199. sys.taskInit(get_radar_date)
  200. --=============================================================
  201. --测试串口时使用
  202. --循环发数据
  203. --sys.timerLoopStart(uart.write,5000,uartid,Read_Radar_Date)
  204. --=============================================================
  205. --=============================================================
  206. --crc16校验函数用法
  207. --local data = string.pack("BBBBBB", 0x01, 0x03, 0x00, 0x00, 0x00, 0x02);--需要校验CRC16的内容
  208. --local datacrc = crc16(data,6);
  209. --print( datacrc >> 8 ) --输出196 == 0xC4
  210. --print( datacrc & 0xFF ) --输出11 == 0x0B
  211. --=============================================================