da221.lua 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. local da221={}
  2. local i2cId = 0
  3. local intPin = gpio.WAKEUP2
  4. local interruptMode = true -- 中断模式
  5. -- 是否打印日志
  6. local logSwitch = true
  7. local moduleName = "da221"
  8. local da221Addr = 0x27
  9. local soft_reset = {0x00, 0x24} -- 软件复位地址
  10. local chipid_addr = 0x01 -- 芯片ID地址
  11. local rangeaddr = {0x0f, 0x00} -- 设置加速度量程,默认2g
  12. -- local rangeaddr = {0x0f, 0x01} -- 设置加速度量程,默认4g
  13. -- local rangeaddr = {0x0f, 0x10} -- 设置加速度量程,默认8g
  14. local int_set1_reg = {0x16, 0x87} --设置x,y,z发生变化时,产生中断
  15. local int_set2_reg = {0x17, 0x10} --使能新数据中断,数据变化时,产生中断,本程序不设置
  16. local int_map1_reg = {0x19, 0x04} --运动的时候,产生中断
  17. local int_map2_reg = {0x1a, 0x01}
  18. local active_dur_addr = {0x27, 0x01} -- 设置激活时间,默认0x01
  19. local active_ths_addr = {0x28, 0x33} -- 设置激活阈值,灵敏度最高
  20. -- local active_ths_addr = {0x28, 0x80} -- 设置激活阈值,灵敏度适中
  21. -- local active_ths_addr = {0x28, 0xFE} -- 设置激活阈值,灵敏度最低
  22. local odr_addr = {0x10, 0x08} -- 设置采样率 100Hz
  23. local mode_addr = {0x11, 0x00} -- 设置正常模式
  24. local int_latch_addr = {0x21, 0x02} -- 设置中断锁存
  25. local x_lsb_reg = 0x02 -- X轴LSB寄存器地址
  26. local x_msb_reg = 0x03 -- X轴MSB寄存器地址
  27. local y_lsb_reg = 0x04 -- Y轴LSB寄存器地址
  28. local y_msb_reg = 0x05 -- Y轴MSB寄存器地址
  29. local z_lsb_reg = 0x06 -- Z轴LSB寄存器地址
  30. local z_msb_reg = 0x07 -- Z轴MSB寄存器地址
  31. local active_state = 0x0b -- 激活状态寄存器地址
  32. local active_state_data
  33. --[[
  34. 获取da221的xyz轴数据
  35. @api da221.read_xyz()
  36. @return number x轴数据,number y轴数据,number z轴数据
  37. @usage
  38. local x,y,z = da221.read_xyz() --读取x,y,z轴的数据
  39. log.info("x", x..'g', "y", y..'g', "z", z..'g')
  40. ]]
  41. function da221.read_xyz()
  42. -- da221是LSB在前,MSB在后,每个寄存器都是1字节数据,每次读取都是6个寄存器数据一起获取
  43. -- 因此直接从X轴LSB寄存器(0x02)开始连续读取6字节数据(X/Y/Z各2字节),避免出现数据撕裂问题
  44. i2c.send(i2cId, da221Addr, x_lsb_reg, 1)
  45. local recv_data = i2c.recv(i2cId, da221Addr, 6)
  46. -- LSB数据格式为: D[3] D[2] D[1] D[0] unused unused unused unused
  47. -- MSB数据格式为: D[11] D[10] D[9] D[8] D[7] D[6] D[5] D[4]
  48. -- 数据位为12位,需要将MSB数据左移4位,LSB数据右移4位,最后进行或运算
  49. -- 解析X轴数据 (LSB在前,MSB在后)
  50. local x_data = (string.byte(recv_data, 2) << 4) | (string.byte(recv_data, 1) >> 4)
  51. -- 解析Y轴数据 (LSB在前,MSB在后)
  52. local y_data = (string.byte(recv_data, 4) << 4) | (string.byte(recv_data, 3) >> 4)
  53. -- 解析Z轴数据 (LSB在前,MSB在后)
  54. local z_data = (string.byte(recv_data, 6) << 4) | (string.byte(recv_data, 5) >> 4)
  55. -- 转换为12位有符号整数
  56. -- 判断X轴数据是否大于2047,若大于则表示数据为负数
  57. -- 因为12位有符号整数的范围是 -2048 到 2047,原始数据为无符号形式,大于2047的部分需要转换为负数
  58. -- 通过减去4096 (2^12) 将无符号数转换为对应的有符号负数
  59. if x_data > 2047 then x_data = x_data - 4096 end
  60. -- 判断Y轴数据是否大于2047,若大于则进行同样的有符号转换
  61. if y_data > 2047 then y_data = y_data - 4096 end
  62. -- 判断Z轴数据是否大于2047,若大于则进行同样的有符号转换
  63. if z_data > 2047 then z_data = z_data - 4096 end
  64. -- 转换为加速度值(单位:g)
  65. local x_accel = x_data / 1024
  66. local y_accel = y_data / 1024
  67. local z_accel = z_data / 1024
  68. -- 输出加速度值(单位:g)
  69. return x_accel, y_accel, z_accel
  70. end
  71. local function da221_init()
  72. gpio.setup(24, 1, gpio.PULLUP) -- gsensor 开关
  73. gpio.setup(164, 1, gpio.PULLUP) -- air8000 和解码芯片公用
  74. gpio.setup(147, 1, gpio.PULLUP) -- camera的供电使能脚
  75. log.info("da221 init...")
  76. --关闭i2c
  77. i2c.close(i2cId)
  78. --重新打开i2c,i2c速度设置为低速
  79. i2c.setup(i2cId, i2c.SLOW)
  80. sys.wait(50)
  81. i2c.send(i2cId, da221Addr, soft_reset, 1)
  82. sys.wait(50)
  83. i2c.send(i2cId, da221Addr, chipid_addr, 1)
  84. local chipid = i2c.recv(i2cId, da221Addr, 1)
  85. log.info("i2c", "chipid",chipid:toHex())
  86. if string.byte(chipid) == 0x13 then
  87. log.info("da221 init success")
  88. sys.publish("DA221_INIT_SUCCESS")
  89. else
  90. log.info("da221 init fail")
  91. end
  92. -- 设置寄存器
  93. i2c.send(i2cId, da221Addr, rangeaddr, 1) --设置加速度量程,默认2g
  94. sys.wait(5)
  95. i2c.send(i2cId, da221Addr, int_set1_reg, 1) --设置x,y,z发生变化时,产生中断
  96. sys.wait(5)
  97. i2c.send(i2cId, da221Addr, int_map1_reg, 1)--运动的时候,产生中断
  98. sys.wait(5)
  99. i2c.send(i2cId, da221Addr, active_dur_addr, 1)-- 设置激活时间,默认0x00
  100. sys.wait(5)
  101. i2c.send(i2cId, da221Addr, active_ths_addr, 1)-- 设置激活阈值
  102. sys.wait(5)
  103. i2c.send(i2cId, da221Addr, mode_addr, 1)-- 设置模式
  104. sys.wait(5)
  105. i2c.send(i2cId, da221Addr, odr_addr, 1)-- 设置采样率
  106. sys.wait(5)
  107. i2c.send(i2cId, da221Addr, int_latch_addr, 1)-- 设置中断锁存 中断一旦触发将保持,直到手动清除
  108. sys.wait(5)
  109. end
  110. --[[
  111. 打开da221
  112. @api da221.open(mode)
  113. @number da221模式设置,1、静态/微动检测,使用场景:微振动检测、手势识别;2、常规运动监测,使用场景:运动监测、车载设备;3、高动态冲击检测,使用场景:碰撞检测、工业冲击
  114. @return nil
  115. @usage
  116. da221.open(1)
  117. ]]
  118. function da221.open(mode)
  119. if mode==1 or tonumber(mode)==1 then
  120. --轻微检测
  121. log.info("轻微检测")
  122. rangeaddr = {0x0f, 0x00} -- 设置加速度量程,默认2g
  123. active_ths_addr = {0x28, 0x1A} -- 设置激活阈值
  124. odr_addr = {0x10, 0x04} -- 设置采样率 15.63Hz
  125. active_dur_addr = {0x27, 0x01} -- 设置激活时间,默认0x01
  126. elseif mode==2 or tonumber(mode)==2 then
  127. --常规检测
  128. rangeaddr = {0x0f, 0x01} -- 设置加速度量程,默认4g
  129. active_ths_addr = {0x28, 0x26} -- 设置激活阈值
  130. odr_addr = {0x10, 0x08} -- 设置采样率 250Hz
  131. active_dur_addr = {0x27, 0x14} -- 设置激活时间,默认0x01
  132. elseif mode==3 or tonumber(mode)==3 then
  133. --高动态检测
  134. rangeaddr = {0x0f, 0x10} -- 设置加速度量程,默认8g
  135. active_ths_addr = {0x28, 0x80} -- 设置激活阈值
  136. odr_addr = {0x10, 0x0F} -- 设置采样率 1000Hz
  137. active_dur_addr = {0x27, 0x04} -- 设置激活时间,默认0x01
  138. end
  139. sys.taskInit(da221_init)
  140. end
  141. return da221