uartTaskV2.lua 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606
  1. --- 模块功能:串口1功能测试
  2. -- @author openLuat
  3. -- @module uart.uartTask
  4. -- @license MIT
  5. -- @copyright openLuat
  6. -- @release 2018.03.27
  7. module(...,package.seeall)
  8. require "utils"
  9. require "pm"
  10. require "sys"
  11. require "log"
  12. require "nvm"
  13. --[[
  14. 功能定义:
  15. uart按照帧结构接收外围设备的输入,收到正确的指令后,回复ASCII字符串
  16. 帧结构如下:
  17. 帧头:1字节,0x01表示扫描指令,0x02表示控制GPIO命令,0x03表示控制端口命令
  18. 帧体:字节不固定,跟帧头有关
  19. 帧尾:1字节,固定为0xC0
  20. 收到的指令帧头为0x01时,回复"CMD_SCANNER\r\n"给外围设备;例如接收到0x01 0xC0两个字节,就回复"CMD_SCANNER\r\n"
  21. 收到的指令帧头为0x02时,回复"CMD_GPIO\r\n"给外围设备;例如接收到0x02 0xC0两个字节,就回复"CMD_GPIO\r\n"
  22. 收到的指令帧头为0x03时,回复"CMD_PORT\r\n"给外围设备;例如接收到0x03 0xC0两个字节,就回复"CMD_PORT\r\n"
  23. 收到的指令帧头为其余数据时,回复"CMD_ERROR\r\n"给外围设备;例如接收到0x04 0xC0两个字节,就回复"CMD_ERROR\r\n"
  24. ]]
  25. --串口ID,1对应uart1
  26. --如果要修改为uart2,把UART_ID赋值为2即可
  27. -- air720UH 可用串口1和2,rfid串口用1
  28. -- air724UH 可用串口1、2、3,rfid串口用3
  29. local UART_ID = nvm.get("rfidUartId")
  30. local UART_ID_BAUD_RATE = nvm.get("rfidUartBaudRate")
  31. local rfidOfflineTimeout = nvm.get("rfidOfflineTimeout")
  32. local rfidMinDiffTime = nvm.get("rfidMinDiffTime") or 3
  33. --local UART_ID = 3
  34. --帧头以及帧尾
  35. local FRM_HEAD,FRM_TAIL = 0xaa55,0x0d0a
  36. --rfid 去重缓存的超时时间
  37. local rfid_buffer_timeout = 20
  38. local rfid_buffer_max_count = 100
  39. --串口读到的数据缓冲区
  40. local rdbuf = ""
  41. --rfid串口初始化定参数时器
  42. local rfid_uart_config_init_timer_id = nil
  43. local rfidType = nvm.get("rfidType")
  44. local timerSyncResult = false
  45. --是否厂测读rfid标签模式
  46. local isFactoryTestReadRfidMode = false
  47. --厂测模式读rifd号
  48. local factoryTestReadRfid = ""
  49. --是否已开始心跳
  50. local isStartHeartbeat = false
  51. local isCmdReadRfidMode = false
  52. local cmdReadRfid = ""
  53. require "misc"
  54. local function getTime()
  55. local tm = misc.getClock()
  56. return string.format("%04d/%02d/%02d,%02d:%02d:%02d", tm.year, tm.month, tm.day, tm.hour, tm.min, tm.sec)
  57. end
  58. --初始化rfid缓冲池
  59. local start_time = os.time()
  60. local rfids_buf = {["start_time"]=start_time,["rfid_count"]=0,["buf"]={}}
  61. --rfid缓冲池最大存储标签个数
  62. local rfidsBufMaxCount = 3000
  63. --任联rfid数据解析
  64. local function parse_rfid_renlian(body)
  65. if not body then return false end
  66. if body:len() ~= 9 then
  67. log.info("parse_rfid_renlian fail,body.length != 9")
  68. return false
  69. end
  70. local id = string.sub(body,1,6):toHex()
  71. local type = tonumber(string.byte(body,7))
  72. local status = tonumber(string.byte(body,8))
  73. local rssi = tonumber(string.byte(body,9))
  74. local rfid = {["id"]=id,["type"]=type,["status"]=status,["rssi"]=rssi}
  75. return rfid
  76. end
  77. --任联rfid数据解析
  78. local function parse_rfid_tiandiren(body)
  79. if not body then return false end
  80. if body:len() ~= 18 then
  81. log.info("parse_rfid_tiandiren fail,body.length != 18",body:toHex())
  82. return false
  83. end
  84. local id = string.sub(body,5,8):toHex()
  85. if not id then
  86. log.info("parse_rfid_tiandiren fail,id empty! body:",body:toHex())
  87. return false
  88. end
  89. local sn = string.byte(body,2)
  90. local dev_type = string.byte(body,3)*16 + string.byte(body,4)
  91. local cmd_type = string.byte(body,9)
  92. local crc = string.byte(body,15) + string.byte(body,16) * 16
  93. local content = string.sub(body,10,14):toHex()
  94. local status = string.byte(body,17)
  95. local rssi = string.byte(body,18)
  96. --local rfid = {["id"]=id,["cmd_type"]=cmd_type,["dev_type"]=dev_type,["sn"]=sn}
  97. local rfid = {["id"]=id,["type"]=cmd_type,["status"]=status,["rssi"]=rssi,["dev_type"]=dev_type,["sn"]=sn,["content"]=content}
  98. return rfid
  99. end
  100. --[[
  101. 函数名:parse_renlian
  102. 功能 :按照帧结构解析处理一条完整的帧数据
  103. 参数 :
  104. data:所有未处理的数据
  105. 返回值:第一个返回值是一条完整帧报文的处理结果,第二个返回值是未处理的数据
  106. ]]
  107. local function parse_renlian(data)
  108. if not data then return end
  109. if data:len() < 14 then
  110. return false, data
  111. end
  112. local frm_head = tonumber(string.format( "%02x",string.byte(data,1)) .. string.format( "%02x",string.byte(data,2)),16)
  113. local tail = string.find(data,string.char(0x0d)..string.char(0x0a))
  114. if not tail then
  115. log.info("end char:0x0d0a not found,wait for more ... ", data:toHex())
  116. return false,data
  117. end
  118. if frm_head ~= FRM_HEAD then
  119. log.info("FRM_HEAD ERROR,drop it, frm_head = ", frm_head, ", FRM_HEAD = ", FRM_HEAD)
  120. return false,string.sub(data,tail+2,-1)
  121. end
  122. local frm_len = tonumber(string.byte(data,3))
  123. local body,result = string.sub(data,4,tail-1)
  124. --检测body完整性
  125. if (frm_len-2) ~= body:len() then
  126. log.info("frm body length error, frm_len-2 = ",frm_len-2,", body:len() = ", body:len(), ", body:toHex() = ", body:toHex())
  127. return false,string.sub(data,tail+2,-1)
  128. end
  129. --log.info("uart1Task.parse",data:toHex(),frm_head,body:toHex())
  130. --解析rfid
  131. local rfid_info = parse_rfid_renlian(body)
  132. if not rfid_info then
  133. log.info("parse_rfid_renlian() failed!")
  134. return false,string.sub(data,tail+2,-1)
  135. end
  136. --检测到超时时,发布数据并重置 rfids_buf
  137. local cur_time = os.time()
  138. if (cur_time - rfids_buf.start_time >= rfid_buffer_timeout) or (rfids_buf.rfid_count >= rfid_buffer_max_count) then
  139. if rfids_buf.rfid_count > 0 then
  140. --log.info(">>>>>>> uart1Task.parse pub_packet_data", cur_time)
  141. sys.publish("pub_packet_data_renlian", rfids_buf)
  142. end
  143. rfids_buf = {["start_time"]=cur_time,["rfid_count"]=0,["buf"]={}}
  144. end
  145. --新增数据
  146. if not rfids_buf["buf"][rfid_info.id] then
  147. --log.info(">>>>>>> push rfid to buf,rfid:", rfid_info.id)
  148. rfids_buf.rfid_count = rfids_buf.rfid_count + 1
  149. rfids_buf["buf"][rfid_info.id] = {["time"]=cur_time,["recv_count"]=1,["rssi"]=rfid_info.rssi,["type"]=rfid_info.type,["status"]=rfid_info.status}
  150. return true,string.sub(data,tail+2,-1)
  151. end
  152. --更新数据
  153. local recv_count = rfids_buf["buf"][rfid_info.id]["recv_count"] + 1
  154. rfids_buf["buf"][rfid_info.id] = {["time"]=cur_time,["recv_count"]=recv_count,["rssi"]=rfid_info.rssi,["type"]=rfid_info.type,["status"]=rfid_info.status}
  155. --log.info(">>>>>>> update rfid_buf,rfid:", rfid_info.id, ", recv_count:", recv_count)
  156. return true,string.sub(data,tail+2,-1)
  157. end
  158. --[[
  159. 函数名:parse_tiandiren
  160. 功能 :按照帧结构解析处理一条完整的帧数据
  161. 参数 :
  162. data:所有未处理的数据
  163. 返回值:第一个返回值是一条完整帧报文的处理结果,第二个返回值是未处理的数据
  164. ]]
  165. local function parse_tiandiren(data)
  166. local rfidRssiFilterVal = nvm.get("rfidRssiFilterVal")
  167. local enableFilterTdrRfid = nvm.get("enableFilterTdrRfid")
  168. local onlyDevTypeVal = nvm.get("onlyDevTypeVal")
  169. if not data then return end
  170. if data:len() < 22 then
  171. --log.info("uartTaskV2.parse_tiandiren","data length < 22", data:toHex())
  172. return false, data
  173. end
  174. local frm_head = tonumber(string.format( "%02x",string.byte(data,1)) .. string.format( "%02x",string.byte(data,2)),16)
  175. local tail = string.find(data,string.char(0x0d)..string.char(0x0a))
  176. if not tail then
  177. log.info("uartTaskV2.parse_tiandiren","end char:0x0d0a not found,wait for more ... ", data:toHex())
  178. return false,data
  179. end
  180. if frm_head ~= FRM_HEAD then
  181. log.info("uartTaskV2.parse_tiandiren","FRM_HEAD ERROR,drop it, frm_head = ", frm_head, ", FRM_HEAD = ", FRM_HEAD)
  182. return false,string.sub(data,tail+2,-1)
  183. end
  184. local frm_len = tonumber(string.byte(data,3))
  185. local body,result = string.sub(data,4,tail-1)
  186. --检测body完整性
  187. if (frm_len-2) ~= body:len() then
  188. log.info("uartTaskV2.parse_tiandiren","frm body length error, frm_len-2 = ",frm_len-2,", body:len() = ", body:len(), ", body:toHex() = ", body:toHex())
  189. return false,string.sub(data,tail+2,-1)
  190. end
  191. --log.info("uart1Task.parse",data:toHex(),frm_head,body:toHex())
  192. --解析rfid
  193. local rfid_info = parse_rfid_tiandiren(body)
  194. if not rfid_info then
  195. log.info("uartTaskV2.parse_tiandiren", "parse_rfid_tiandiren() failed!",data:toHex())
  196. return false,string.sub(data,tail+2,-1)
  197. end
  198. if rfidRssiFilterVal > 0 and rfid_info.rssi > rfidRssiFilterVal then
  199. log.info("uartTaskV2.parse_tiandiren", "rfid_info.rssi > ".. rfidRssiFilterVal..", drop it! rfid_info.rssi =", rfid_info.rssi, "rfid:", rfid_info.id)
  200. return false,string.sub(data,tail+2,-1)
  201. end
  202. -- 过滤原天地人的标签,根据运维平台过滤开关是否过滤 不是3开头,十进制长度不足7位,不上报
  203. if enableFilterTdrRfid == 1 and ( (#tostring(tonumber(rfid_info.id, 16)) ~= 7) or ( tonumber(string.sub(tonumber(rfid_info.id, 16), 1, 1) ) ~= 3 ) ) then
  204. local id_decnum = tonumber(rfid_info.id, 16)
  205. log.info("uartTaskV2.parse_tiandiren", "rfid_info.id head ~= ".. 3 ..", drop it! rfid_info.id =", rfid_info.id, "id_decnum:", id_decnum)
  206. return false,string.sub(data,tail+2,-1)
  207. end
  208. -- 只报配置dev_type的标签
  209. if onlyDevTypeVal ~= "" then
  210. local transDevTypeVal = tonumber(string.sub(onlyDevTypeVal, 0, 2), 16)*16 + tonumber(string.sub(onlyDevTypeVal, 3, -1), 16)
  211. if rfid_info.dev_type ~= transDevTypeVal then
  212. log.info("uartTaskV2.parse_tiandiren", "rfid_info.dev_type ~= ".. onlyDevTypeVal ..", drop it! rfid_info.id =", rfid_info.id, "rfid_info.dev_type:", rfid_info.dev_type,"transDevTypeVal:", transDevTypeVal)
  213. return false,string.sub(data,tail+2,-1)
  214. end
  215. end
  216. local cur_time = os.time()
  217. --进入厂测读rfid标签信号模式
  218. if isFactoryTestReadRfidMode then
  219. --读到rfid标签信号后,退出厂测模式
  220. if factoryTestReadRfid == rfid_info.id then
  221. sys.publish("factory_test_read_rfid_success",{rssi=rfid_info.rssi,rfid=rfid_info.id})
  222. isFactoryTestMode = false
  223. factoryTestReadRfid = ""
  224. end
  225. return true,string.sub(data,tail+2,-1)
  226. end
  227. --进入指令读rfid标签信号模式
  228. if isCmdReadRfidMode then
  229. --读到rfid标签信号后,退出读标签模式
  230. if cmdReadRfid == rfid_info.id then
  231. log.info("uartTaskV2.parse_tiandiren", "rfid_info:", json.encode(rfid_info))
  232. sys.publish("cmd_read_rfid_success",{rssi=rfid_info.rssi,rfid=rfid_info.id})
  233. isCmdReadRfidMode = false
  234. cmdReadRfid = ""
  235. end
  236. return true,string.sub(data,tail+2,-1)
  237. end
  238. --新增数据
  239. if not rfids_buf["buf"][rfid_info.id] then
  240. --log.info(">>>>>>> push rfid to buf,rfid:", rfid_info.id)
  241. if rfids_buf.rfid_count > rfidsBufMaxCount then
  242. log.warn("uartTaskV2.parse_tiandiren", "rfids_buf.rfid_count > ", rfidsBufMaxCount, ", drop it", rfid_info.id)
  243. return true,string.sub(data,tail+2,-1)
  244. end
  245. rfids_buf.rfid_count = rfids_buf.rfid_count + 1
  246. rfids_buf["buf"][rfid_info.id] = {["id"]=rfid_info.id,["first_time"]=cur_time,["time"]=cur_time,["recv_count"]=1,["rssi"]=rfid_info.rssi,["type"]=rfid_info.type,["status"]=rfid_info.status,["dev_type"]=rfid_info.dev_type,["sn"]=rfid_info.sn,["content"]=content}
  247. --发布rfid首个信号
  248. sys.publish("pub_packet_data_tiandiren_rfid_info", rfids_buf["buf"][rfid_info.id])
  249. return true,string.sub(data,tail+2,-1)
  250. end
  251. local first_time = rfids_buf["buf"][rfid_info.id]["first_time"]
  252. --更新数据
  253. local recv_count = rfids_buf["buf"][rfid_info.id]["recv_count"] + 1
  254. rfids_buf["buf"][rfid_info.id] = {["id"]=rfid_info.id,["first_time"]=first_time,["time"]=cur_time,["recv_count"]=recv_count,["rssi"]=rfid_info.rssi,["type"]=rfid_info.type,["status"]=rfid_info.status,["dev_type"]=rfid_info.dev_type,["sn"]=rfid_info.sn,["content"]=content}
  255. --log.info(">>>>>>> update rfid_buf,rfid:", rfid_info.id, ", recv_count:", recv_count)
  256. return true,string.sub(data,tail+2,-1)
  257. end
  258. --[[
  259. 函数名:proc
  260. 功能 :处理从串口读到的数据
  261. 参数 :
  262. data:当前一次从串口读到的数据
  263. 返回值:无
  264. ]]
  265. local function proc(data)
  266. if not data or string.len(data) == 0 then return end
  267. if not rfidType then
  268. log.info("uartTask.proc","rfidType undefined!!")
  269. rfidType = nvm.get("rfidType")
  270. return false
  271. end
  272. --追加到缓冲区
  273. rdbuf = rdbuf..data
  274. local result,unproc
  275. unproc = rdbuf
  276. --根据帧结构循环解析未处理过的数据
  277. while true do
  278. if rfidType == 'renlian' then
  279. result,unproc = parse_renlian(unproc)
  280. elseif rfidType == 'tiandiren' then
  281. result,unproc = parse_tiandiren(unproc)
  282. else
  283. log.info("uartTask.proc","rfidType invalid!!")
  284. return false
  285. end
  286. if not unproc or unproc == "" or not result then
  287. break
  288. end
  289. end
  290. rdbuf = unproc or ""
  291. if #rdbuf > 1000 then
  292. log.warn("uartTaskV2.proc","rdbuf length > 1000!! rdbuf:", #rdbuf)
  293. end
  294. end
  295. --[[
  296. 函数名:read
  297. 功能 :读取串口接收到的数据
  298. 参数 :无
  299. 返回值:无
  300. ]]
  301. local function read()
  302. local data = ""
  303. --底层core中,串口收到数据时:
  304. --如果接收缓冲区为空,则会以中断方式通知Lua脚本收到了新数据;
  305. --如果接收缓冲器不为空,则不会通知Lua脚本
  306. --所以Lua脚本中收到中断读串口数据时,每次都要把接收缓冲区中的数据全部读出,这样才能保证底层core中的新数据中断上来,此read函数中的while语句中就保证了这一点
  307. while true do
  308. data = uart.read(UART_ID,"*l")
  309. if not data or string.len(data) == 0 then break end
  310. --打开下面的打印会耗时
  311. --log.info("uartTask.read bin",data)
  312. --log.info("uartTask.read hex",data:toHex())
  313. --处理串口收到的rfid数据
  314. proc(data)
  315. end
  316. end
  317. --[[
  318. 函数名:write
  319. 功能 :通过串口发送数据
  320. 参数 :
  321. s:要发送的数据
  322. 返回值:无
  323. ]]
  324. function write(s)
  325. log.info("uartTask.write",s)
  326. uart.write(UART_ID,s.."\r\n")
  327. end
  328. local function writeOk()
  329. log.info("uartTask.writeOk")
  330. end
  331. --[[
  332. --检测 rfids_buf是否超时
  333. sys.timerLoopStart(function ()
  334. if not timerSyncResult then
  335. log.info("uartTask.timerLoopStart","wait TIMER_SYNC_SUCCESS message ...")
  336. return false
  337. end
  338. if not rfidType then
  339. log.info("uartTask.timerLoopStart","rfidType undefined!!")
  340. rfidType = nvm.get("rfidType")
  341. return false
  342. end
  343. --log.info(">>>>>>> uart1Task.timerLoopStart ")
  344. --检测到超时时,发布数据并重置 rfids_buf
  345. local cur_time = os.time()
  346. if (cur_time - rfids_buf.start_time >= rfid_buffer_timeout) or (rfids_buf.rfid_count >= rfid_buffer_max_count) then
  347. if rfids_buf.rfid_count > 0 then
  348. if rfidType == 'renlian' then
  349. --log.info("uartTask.timerLoopStart",">>>>>>> uart1Task.timerLoopStart pub_packet_data_renlian", cur_time)
  350. sys.publish("pub_packet_data_renlian", rfids_buf)
  351. elseif rfidType == 'tiandiren' then
  352. sys.publish("pub_packet_data_tiandiren", rfids_buf)
  353. --sys.publish("pub_packet_data_renlian", rfids_buf)
  354. else
  355. log.info("uartTask.timerLoopStart","rfidType invalid!!")
  356. return false
  357. end
  358. end
  359. rfids_buf = {["start_time"]=cur_time,["rfid_count"]=0,["buf"]={}}
  360. end
  361. end, 100)
  362. ]]
  363. --等待时间同步成功消息通知
  364. sys.subscribe("TIMER_SYNC_SUCCESS", function ( ... )
  365. log.info("uartTask.subscribe","TIMER_SYNC_SUCCESS")
  366. timerSyncResult = true
  367. end)
  368. --启动厂测读rfid标签模式,读取指定rfid标签信号
  369. sys.subscribe("factory_test_start_read_rfid", function ( data )
  370. if data.rfid then
  371. log.info("uartTaskV2.subscribe","factory test mode,start read rifd:",data.rfid)
  372. isFactoryTestReadRfidMode = true
  373. factoryTestReadRfid = data.rfid
  374. if not isStartHeartbeat then
  375. sys.publish("MESSAGE_TYPE_START_HEARTBEAT")
  376. end
  377. else
  378. log.error("uartTaskV2.subscribe.factory_test_start_read_rfid","data.rfid not existed!!")
  379. end
  380. end)
  381. --退出厂测读rfid标签模式
  382. sys.subscribe("factory_test_stop_read_rfid", function ( )
  383. log.info("uartTaskV2.subscribe.factory_test_stop_read_rfid","factory test stop read rifd")
  384. isFactoryTestReadRfidMode = false
  385. factoryTestReadRfid = ""
  386. end)
  387. --启动读rfid标签模式,读取指定rfid标签信号
  388. sys.subscribe("cmd_start_read_rfid", function ( data )
  389. if not isStartHeartbeat then
  390. sys.publish("MESSAGE_TYPE_START_HEARTBEAT")
  391. end
  392. if data.rfid then
  393. log.info("uartTaskV2.subscribe.cmd_start_read_rfid","cmd start read rifd:",data.rfid)
  394. isCmdReadRfidMode = true
  395. cmdReadRfid = data.rfid
  396. else
  397. log.error("uartTaskV2.subscribe.cmd_start_read_rfid","data.rfid not existed!!")
  398. end
  399. end)
  400. --退出厂测读rfid标签模式
  401. sys.subscribe("cmd_stop_read_rfid", function ( )
  402. log.info("uartTaskV2.subscribe.cmd_stop_read_rfid","cmd stop read rifd")
  403. isCmdReadRfidMode = false
  404. cmdReadRfid = ""
  405. end)
  406. --保持系统处于唤醒状态,此处只是为了测试需要,所以此模块没有地方调用pm.sleep("uartTask")休眠,不会进入低功耗休眠状态
  407. --在开发“要求功耗低”的项目时,一定要想办法保证pm.wake("uartTask")后,在不需要串口时调用pm.sleep("uartTask")
  408. pm.wake("uartTask")
  409. --sys.timerStart(function ( ... )
  410. --初始化rfid串口配置参数
  411. rfid_uart_config_init_timer_id = sys.timerLoopStart(function ()
  412. if not UART_ID then
  413. log.info("UART_ID empty, attempt from nvm.get")
  414. UART_ID = nvm.get("rfidUartId")
  415. return false
  416. end
  417. if not UART_ID_BAUD_RATE then
  418. log.info("UART_ID_BAUD_RATE empty, attempt from nvm.get")
  419. UART_ID_BAUD_RATE = nvm.get("rfidUartBaudRate")
  420. return false
  421. end
  422. if not rfid_uart_config_init_timer_id then
  423. log.info("rfid_uart_config_init_timer_id empty")
  424. return false
  425. end
  426. log.info("init rfid uart","UART_ID:",UART_ID,"UART_ID_BAUD_RATE:",UART_ID_BAUD_RATE)
  427. --注册串口的数据接收函数,串口收到数据后,会以中断方式,调用read接口读取数据
  428. --uart.on(UART_ID,"receive",read)
  429. uart.on(UART_ID,"receive",function() sys.publish("UART_RECEIVE") end)
  430. --注册串口的数据发送通知函数
  431. uart.on(UART_ID,"sent",writeOk)
  432. --配置并且打开串口
  433. --波特率,可选1200,2400,4800,9600,10400,14400,19200,28800,38400,57600,115200,230400,460800,921600
  434. --uart.setup(UART_ID,115200,8,uart.PAR_NONE,uart.STOP_1)
  435. uart.setup(UART_ID,UART_ID_BAUD_RATE,8,uart.PAR_NONE,uart.STOP_1)
  436. --如果需要打开“串口发送数据完成后,通过异步消息通知”的功能,则使用下面的这行setup,注释掉上面的一行setup
  437. --uart.setup(UART_ID,115200,8,uart.PAR_NONE,uart.STOP_1,nil,1)
  438. log.info("uart timer loop stop","rfid_uart_config_init_timer_id:",rfid_uart_config_init_timer_id)
  439. sys.timerStop(rfid_uart_config_init_timer_id)
  440. end, 1000)
  441. --end, 10000)
  442. local function taskRead()
  443. --等心跳开启时,再开始接收串口rfid数据
  444. while true do
  445. log.info("uartTaskV2.taskRead","wait MESSAGE_TYPE_START_HEARTBEAT message ...")
  446. local res,data = sys.waitUntil("MESSAGE_TYPE_START_HEARTBEAT", 3600*1000)
  447. if res then
  448. log.info("uartTaskV2.taskRead","receive MESSAGE_TYPE_START_HEARTBEAT messages, start UART_RECEIVE task...")
  449. isStartHeartbeat = true
  450. break
  451. else
  452. log.info("uartTaskV2.taskRead","wait MESSAGE_TYPE_START_HEARTBEAT timeout")
  453. end
  454. end
  455. local cacheData = ""
  456. local count = 0
  457. while true do
  458. cacheData = uart.read(UART_ID,"*l")
  459. if cacheData == "" then
  460. if not sys.waitUntil("UART_RECEIVE",100) then
  461. --log.info("uartTask.taskRead","100ms no data")
  462. end
  463. else
  464. --log.info("uartTask.read hex",cacheData:toHex())
  465. proc(cacheData)
  466. cacheData = ""
  467. count = count + 1
  468. if count > 1200 then
  469. sys.wait(50)
  470. count = 0
  471. end
  472. end
  473. end
  474. end
  475. --启动串口数据接收任务
  476. sys.taskInit(taskRead)
  477. sys.timerLoopStart(function()
  478. log.info("uartTaskV2.timerLoopStart","打印占用的内存:", _G.collectgarbage("count"))-- 打印占用的RAM
  479. log.info("uartTaskV2.timerLoopStart","打印可用的空间", rtos.get_fs_free_size())-- 打印剩余FALSH,单位Byte
  480. log.info("uartTaskV2.timerLoopStart", "rfidMinDiffTime:",rfidMinDiffTime)
  481. end, 10000)
  482. --rfid离线检测任务
  483. sys.taskInit(function()
  484. while true do
  485. while true do
  486. if rfids_buf["rfid_count"] > 0 then
  487. break
  488. else
  489. log.info("uartTaskV2.rfidOfflineCheckTask","rfids_buf empty,wait ...")
  490. sys.wait(1000)
  491. end
  492. end
  493. local now = os.time()
  494. --log.info("uartTaskV2.rfidOfflineCheckTask","start time:",now)
  495. local tmp = {["rfid_count"]=0,["buf"]={}}
  496. local checkCount = 0
  497. local onlineCount = 0
  498. local offlineCount = 0
  499. local totalCount = 0
  500. for rfid, rfid_info in pairs(rfids_buf["buf"]) do
  501. totalCount = totalCount + 1
  502. if rfid_info.time and rfid_info.time > 0 then
  503. checkCount = checkCount + 1
  504. if now - rfid_info.time <= rfidOfflineTimeout then
  505. if rfid == "953651BE" then
  506. --log.info("uartTaskV2.rfidOfflineCheckTask","rfid is online,skip! rfid:", rfid, "rfid_info.time:", rfid_info.time)
  507. end
  508. tmp["buf"][rfid] = rfid_info
  509. tmp["rfid_count"] = tmp["rfid_count"] + 1
  510. onlineCount = onlineCount + 1
  511. else
  512. --首末次信号时间差超过最小时间差值,才认为是有效的末次信号
  513. if rfid_info.time - rfid_info.first_time > rfidMinDiffTime then
  514. offlineCount = offlineCount + 1
  515. if rfid == "953651BE" then
  516. log.info("uartTaskV2.rfidOfflineCheckTask","rfid offline! rfid:", rfid, "rfid_info.time:", rfid_info.time, "now:", now, "rfidOfflineTimeout:", rfidOfflineTimeout)
  517. end
  518. --上报离线后,末次信号
  519. if rfids_buf["buf"][rfid] then
  520. sys.publish("pub_packet_data_tiandiren_rfid_info", rfids_buf["buf"][rfid])
  521. if offlineCount >= 100 and offlineCount%100 == 0 then
  522. --log.info("uartTaskV2.rfidOfflineCheckTask","wait 3s")
  523. sys.wait(50)
  524. end
  525. end
  526. else
  527. log.info("uartTaskV2.rfidOfflineCheckTask","drop it, because: rfid_info.time - rfid_info.first_time <=",rfidMinDiffTime)
  528. end
  529. end
  530. end
  531. end
  532. rfids_buf = tmp
  533. log.info("uartTaskV2.rfidOfflineCheckTask", "totalCount:",totalCount, "checkCount:",checkCount, "onlineCount:",onlineCount, "offlineCount:",offlineCount)
  534. sys.wait(rfidOfflineTimeout*1000 + 2000)
  535. end
  536. end)