Radar_485.lua 10 KB

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