airgsensor.lua 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. local airgsensor = {}
  2. local intPin = gpio.WAKEUP2
  3. dnsproxy = require("dnsproxy")
  4. dhcpsrv = require("dhcpsrv")
  5. httpplus = require("httpplus")
  6. local run_state = false -- 判断本UI DEMO 是否运行
  7. local interrupt_state = false -- true 开始读取运动传感器数据,false 停止读取
  8. local da221Addr = 0x27
  9. local soft_reset = {0x00, 0x24} -- 软件复位地址
  10. local chipid_addr = 0x01 -- 芯片ID地址
  11. local rangeaddr = {0x0f, 0x00} -- 设置加速度量程,默认2g
  12. local int_set1_reg = {0x16, 0x87} --设置x,y,z发生变化时,产生中断
  13. local int_set2_reg = {0x17, 0x10} --使能新数据中断,数据变化时,产生中断,本程序不设置
  14. local int_map1_reg = {0x19, 0x04} --运动的时候,产生中断
  15. local int_map2_reg = {0x1a, 0x01}
  16. local active_dur_addr = {0x27, 0x04} -- 设置激活时间
  17. local active_ths_addr = {0x28, 0x14} -- 设置激活阈值
  18. local odr_addr = {0x10, 0x08} -- 设置采样率 100Hz
  19. local mode_addr = {0x11, 0x00} -- 设置正常模式
  20. local int_latch_addr = {0x21, 0x02} -- 设置中断锁存
  21. local i2cId = 0
  22. local x_lsb_reg = 0x02
  23. local x_msb_reg = 0x03
  24. local y_lsb_reg = 0x04
  25. local y_msb_reg = 0x05
  26. local z_lsb_reg = 0x06
  27. local z_msb_reg = 0x07
  28. local x,y,z=0,0,0
  29. local is_da221_init = false
  30. local logSwitch = true
  31. local moduleName = "da221"
  32. local function start_interrupt()
  33. interrupt_state = true
  34. end
  35. local function stop_interrupt()
  36. interrupt_state = false
  37. end
  38. ----是否打印日志
  39. local function logF(...)
  40. if logSwitch then
  41. log.info(moduleName, ...)
  42. end
  43. end
  44. -- ------取ACTIVE_THS (28H)寄存器的中断阈值
  45. -- active_th 为写入寄存器的数值(此处为 1),K 为与量程相关的系数:
  46. -- ±2g 量程:K = 3.91 mg(1 LSB 对应 3.91 mg)。
  47. -- ±4g 量程:K = 7.81 mg。
  48. -- ±8g 量程:K = 15.625 mg。
  49. local function read_xyz() ---读取三轴数据
  50. -- da221是LSB在前,MSB在后,每个寄存器都是1字节数据,每次读取都是6个寄存器数据一起获取
  51. -- 因此直接从X轴LSB寄存器(0x02)开始连续读取6字节数据(X/Y/Z各2字节),避免出现数据撕裂问题
  52. i2c.send(i2cId, da221Addr, x_lsb_reg, 1)
  53. local recv_data = i2c.recv(i2cId, da221Addr, 6)
  54. -- LSB数据格式为: D[3] D[2] D[1] D[0] unused unused unused unused
  55. -- MSB数据格式为: D[11] D[10] D[9] D[8] D[7] D[6] D[5] D[4]
  56. -- 数据位为12位,需要将MSB数据左移4位,LSB数据右移4位,最后进行或运算
  57. -- 解析X轴数据 (LSB在前,MSB在后)
  58. local x_data = (string.byte(recv_data, 2) << 4) | (string.byte(recv_data, 1) >> 4)
  59. -- 解析Y轴数据 (LSB在前,MSB在后)
  60. local y_data = (string.byte(recv_data, 4) << 4) | (string.byte(recv_data, 3) >> 4)
  61. -- 解析Z轴数据 (LSB在前,MSB在后)
  62. local z_data = (string.byte(recv_data, 6) << 4) | (string.byte(recv_data, 5) >> 4)
  63. -- 转换为12位有符号整数
  64. -- 判断X轴数据是否大于2047,若大于则表示数据为负数
  65. -- 因为12位有符号整数的范围是 -2048 到 2047,原始数据为无符号形式,大于2047的部分需要转换为负数
  66. -- 通过减去4096 (2^12) 将无符号数转换为对应的有符号负数
  67. if x_data > 2047 then x_data = x_data - 4096 end
  68. -- 判断Y轴数据是否大于2047,若大于则进行同样的有符号转换
  69. if y_data > 2047 then y_data = y_data - 4096 end
  70. -- 判断Z轴数据是否大于2047,若大于则进行同样的有符号转换
  71. if z_data > 2047 then z_data = z_data - 4096 end
  72. -- 原始值除以1024得实际加速度(单位:g)
  73. local x_accel = x_data / 1024
  74. local y_accel = y_data / 1024
  75. local z_accel = z_data / 1024
  76. --↑ 原理:1024 = 2¹⁰,表明传感器量程为±2g(满量程对应±1024)
  77. -- 例如:静止时Z轴≈1024 → 1g,水平放置时X/Y轴≈0
  78. return x_accel, y_accel, z_accel
  79. end
  80. local intstu=false
  81. -- local function x1int()
  82. -- x1,y1,z1 = read_xyz()
  83. -- end
  84. -- sysplus.taskInit(x1int)
  85. -- 中断模式
  86. local function ind()
  87. if interrupt_state then --如果点击开始按钮
  88. if gpio.get(intPin) == 1 then
  89. intstu=true --触发中断就更改电平状态
  90. --中断情况
  91. --log.info("超过阈值")
  92. x,y,z = read_xyz() --读取x,y,z轴的数据
  93. -- log.info("测试x", x, "y", y, "z", z)
  94. else
  95. intstu=false
  96. end
  97. end
  98. end
  99. local function da221_init()
  100. log.info("da221 init...")
  101. --关闭i2c
  102. gpio.setup(intPin, ind)
  103. i2c.close(i2cId) ------初始化i2c
  104. --重新打开i2c,i2c速度设置为低速
  105. i2c.setup(i2cId, i2c.SLOW)
  106. sys.wait(50)
  107. i2c.send(i2cId, da221Addr, soft_reset, 1)
  108. sys.wait(50)
  109. i2c.send(i2cId, da221Addr, chipid_addr, 1)
  110. local chipid = i2c.recv(i2cId, da221Addr, 1)
  111. log.info("i2c", "chipid",chipid:toHex())
  112. if string.byte(chipid) == 0x13 then
  113. log.info("da221 init success")
  114. is_da221_init = true -- da221 初始化成功
  115. --sys.publish("DA221_INIT_SUCCESS")
  116. else
  117. is_da221_init = false -- da221 初始化失败
  118. --log.info("da221 init fail")
  119. end
  120. -----初始化gsensor------
  121. -- 设置寄存器
  122. i2c.send(i2cId, da221Addr, rangeaddr, 1) --设置加速度量程,默认2g
  123. sys.wait(5)
  124. i2c.send(i2cId, da221Addr, int_set1_reg, 1) --设置x,y,z发生变化时,产生中断
  125. sys.wait(5)
  126. i2c.send(i2cId, da221Addr, int_map1_reg, 1)--运动的时候,产生中断
  127. sys.wait(5)
  128. i2c.send(i2cId, da221Addr, active_dur_addr, 1)-- 设置激活时间,默认0x00
  129. sys.wait(5)
  130. i2c.send(i2cId, da221Addr, active_ths_addr, 1)-- 设置激活阈值
  131. sys.wait(5)
  132. i2c.send(i2cId, da221Addr, mode_addr, 1)-- 设置模式
  133. sys.wait(5)
  134. i2c.send(i2cId, da221Addr, odr_addr, 1)-- 设置采样率
  135. sys.wait(5)
  136. i2c.send(i2cId, da221Addr, int_latch_addr, 1)-- 设置中断锁存 中断一旦触发将保持,直到手动清除
  137. sys.wait(5)
  138. end
  139. local function da221_run()
  140. -- 轮询读取三轴速度
  141. log.info("interrupt_state123",is_da221_init,interrupt_state )
  142. da221_init()
  143. log.info("interrupt_state",is_da221_init,interrupt_state )
  144. while true do
  145. if is_da221_init then
  146. -- return -- i2c 如果已经初始化 就直接退出这个函数,不往下执行
  147. -- 读取三轴速度
  148. x,y,z = read_xyz() --读取x,y,z轴的数据
  149. log.info("x", x, "y", y, "z", z)
  150. end
  151. sys.wait(10000)
  152. end
  153. end
  154. --------------------------------以下是UI页面核心程序-------------------
  155. function airgsensor.run()
  156. log.info("airgsensor.run")
  157. lcd.setFont(lcd.font_opposansm12_chinese) -- 设置中文字体
  158. run_state = true
  159. sys.taskInit(da221_run) --读取先,y,z值
  160. while true do
  161. sys.wait(10)
  162. lcd.clear(_G.bkcolor) --清除页面
  163. lcd.drawStr(10,80,"运动传感器测试" )
  164. ----- 传感器任务----
  165. lcd.drawStr(15,110, "X:")
  166. lcd.drawStr(15,130, "Y:")
  167. lcd.drawStr(15,150, "Z:")
  168. lcd.drawStr(15,170, "中断阈值:")
  169. lcd.drawStr(15,190, "中断情况:")
  170. lcd.drawStr(28,110, x.."g") ---显示X轴加速度数值
  171. lcd.drawStr(28,130, y.."g")
  172. lcd.drawStr(28,150, z.."g")
  173. lcd.drawStr(70,170, "78.2mg") ----中断阈值的值 20*K=20*3.91 ,可根据实际情况换算修改
  174. lcd.showImage(20,360,"/luadb/back.jpg")
  175. if interrupt_state then --如果是开始状态下
  176. if intstu then --如果触发了中断
  177. lcd.drawStr(70,190, "触发中断")
  178. lcd.drawStr(28,110, x.."g")
  179. lcd.drawStr(28,130, y.."g")
  180. lcd.drawStr(28,150, z.."g")
  181. else
  182. lcd.drawStr(70,190, "未触发")
  183. lcd.showImage(130,370,"/luadb/start.jpg") -- 关闭中断模式
  184. end
  185. --lcd.showImage(130,370,"/luadb/stop.jpg") -- 开启中断模式
  186. else
  187. lcd.showImage(130,370,"/luadb/start.jpg") -- 关闭中断模式
  188. end
  189. lcd.showImage(20,360,"/luadb/back.jpg")
  190. lcd.showImage(0,448,"/luadb/Lbottom.jpg")
  191. lcd.flush()--刷新页面
  192. if not run_state then -- 等待结束,返回主界面
  193. x,y,z=0,0,0
  194. sysplus.taskInitEx(stop_interrupt, "stop_interrupt")
  195. return true
  196. end
  197. end
  198. end
  199. function airgsensor.tp_handal(x,y,event)
  200. if x > 20 and x < 100 and y > 360 and y < 440 then -- 返回主界面
  201. run_state = false
  202. elseif x > 130 and x < 230 and y > 370 and y < 417 then
  203. if not interrupt_state then
  204. sysplus.taskInitEx(start_interrupt, "start_interrupt")
  205. else
  206. --sysplus.taskInitEx(stop_interrupt, "stop_interrupt")
  207. end
  208. end
  209. end
  210. return airgsensor