lis2dh12.lua 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304
  1. --[[
  2. @module lis2dh12
  3. @summary lis2dh12 三轴传感器
  4. @version 1.0
  5. @date 2022.04.20
  6. @author Dozingfiretruck
  7. @usage
  8. --注意:因使用了sys.wait()所有api需要在协程中使用
  9. -- 用法实例
  10. local lis2dh12 = require "lis2dh12"
  11. i2cid = 0
  12. i2c_speed = i2c.FAST
  13. sys.taskInit(function()
  14. i2c.setup(i2cid,i2c_speed)
  15. lis2dh12.init(i2cid)--初始化,传入i2c_id
  16. while 1 do
  17. local lis2dh12_data = lis2dh12.get_data()
  18. log.info("lis2dh12_data", "lis2dh12_data.x"..(lis2dh12_data.x),"lis2dh12_data.y"..(lis2dh12_data.y),"lis2dh12_data.z"..(lis2dh12_data.z),"lis2dh12_data.temp"..(lis2dh12_data.temp))
  19. sys.wait(1000)
  20. end
  21. end)
  22. ]]
  23. local lis2dh12 = {}
  24. local sys = require "sys"
  25. local i2cid
  26. local LIS2DH12_ADDRESS_ADR
  27. local LIS2DH12_ADDRESS_ADR_LOW = 0x18
  28. local LIS2DH12_ADDRESS_ADR_HIGH = 0x19
  29. local LIS2DH12_CHIP_ID_CHECK = 0x0F
  30. local LIS2DH12_CHIP_ID = 0x33
  31. ---器件所用地址
  32. local LIS2DH12_STATUS_REG_AUX = 0x07
  33. local LIS2DH12_OUT_TEMP_L = 0x0C
  34. local LIS2DH12_OUT_TEMP_H = 0x0D
  35. local LIS2DH12_CTRL_REG0 = 0x1E
  36. local LIS2DH12_TEMP_CFG_REG = 0x1F
  37. local LIS2DH12_CTRL_REG1 = 0x20
  38. local LIS2DH12_CTRL_REG2 = 0x21
  39. local LIS2DH12_CTRL_REG3 = 0x22
  40. local LIS2DH12_CTRL_REG4 = 0x23
  41. local LIS2DH12_CTRL_REG5 = 0x24
  42. local LIS2DH12_CTRL_REG6 = 0x25
  43. local LIS2DH12_REFERENCE = 0x26
  44. local LIS2DH12_STATUS_REG = 0x27
  45. local LIS2DH12_OUT_X_L = 0x28
  46. local LIS2DH12_OUT_X_H = 0x29
  47. local LIS2DH12_OUT_Y_L = 0x2A
  48. local LIS2DH12_OUT_Y_H = 0x2B
  49. local LIS2DH12_OUT_Z_L = 0x2C
  50. local LIS2DH12_OUT_Z_H = 0x2D
  51. local LIS2DH12_FIFO_CTRL_REG = 0x2E
  52. local LIS2DH12_FIFO_SRC_REG = 0x2F
  53. local LIS2DH12_INT1_CFG = 0x30
  54. local LIS2DH12_INT1_SRC = 0x31
  55. local LIS2DH12_INT1_THS = 0x32
  56. local LIS2DH12_INT1_DURATION = 0x33
  57. local LIS2DH12_INT2_CFG = 0x34
  58. local LIS2DH12_INT2_SRC = 0x35
  59. local LIS2DH12_INT2_THS = 0x36
  60. local LIS2DH12_INT2_DURATION = 0x37
  61. local LIS2DH12_CLICK_CFG = 0x38
  62. local LIS2DH12_CLICK_SRC = 0x39
  63. local LIS2DH12_CLICK_THS = 0x3A
  64. local LIS2DH12_TIME_LIMIT = 0x3B
  65. local LIS2DH12_TIME_LATENCY = 0x3C
  66. local LIS2DH12_TIME_WINDOW = 0x3D
  67. local LIS2DH12_ACT_THS = 0x3E
  68. local LIS2DH12_ACT_DUR = 0x3F
  69. local LIS2DH12_POWER_DOWN = 0
  70. local LIS2DH12_ODR_1Hz = 1
  71. local LIS2DH12_ODR_10Hz = 2
  72. local LIS2DH12_ODR_25Hz = 3
  73. local LIS2DH12_ODR_50Hz = 4
  74. local LIS2DH12_ODR_100Hz = 5
  75. local LIS2DH12_ODR_200Hz = 6
  76. local LIS2DH12_ODR_400Hz = 7
  77. local LIS2DH12_ODR_1kHz620_LP = 8
  78. local LIS2DH12_ODR_5kHz376_LP = 9
  79. local LIS2DH12_ODR_1kHz344_NM_HP = 9
  80. local LIS2DH12_2g = 0
  81. local LIS2DH12_4g = 1
  82. local LIS2DH12_8g = 2
  83. local LIS2DH12_16g = 3
  84. local LIS2DH12_HR_12bit = 0
  85. local LIS2DH12_NM_10bit = 1
  86. local LIS2DH12_LP_8bit = 2
  87. local PROPERTY_DISABLE = 0
  88. local PROPERTY_ENABLE = 1
  89. local LIS2DH12_TEMP_DISABLE = 0
  90. local LIS2DH12_TEMP_ENABLE = 3
  91. --器件ID检测
  92. local function chip_check()
  93. i2c.send(i2cid, LIS2DH12_ADDRESS_ADR_LOW, LIS2DH12_CHIP_ID_CHECK)--读器件地址
  94. local revData = i2c.recv(i2cid, LIS2DH12_ADDRESS_ADR_LOW, 1)
  95. if revData:byte() ~= nil then
  96. LIS2DH12_ADDRESS_ADR = LIS2DH12_ADDRESS_ADR_LOW
  97. else
  98. i2c.send(i2cid, LIS2DH12_ADDRESS_ADR_HIGH, LIS2DH12_CHIP_ID_CHECK)--读器件地址
  99. sys.wait(50)
  100. local revData = i2c.recv(i2cid, LIS2DH12_ADDRESS_ADR_HIGH, 1)
  101. if revData:byte() ~= nil then
  102. LIS2DH12_ADDRESS_ADR = LIS2DH12_ADDRESS_ADR_HIGH
  103. else
  104. log.info("i2c", "Can't find lis2dh12 device")
  105. return false
  106. end
  107. end
  108. i2c.send(i2cid, LIS2DH12_ADDRESS_ADR, LIS2DH12_CHIP_ID_CHECK)--读器件地址
  109. sys.wait(50)
  110. local revData = i2c.recv(i2cid, LIS2DH12_ADDRESS_ADR, 1)
  111. if revData:byte() == LIS2DH12_CHIP_ID then
  112. log.info("Device i2c id is: lis2dh12")
  113. else
  114. log.info("i2c", "Can't find lis2dh12 device")
  115. return false
  116. end
  117. return true
  118. end
  119. local function lis2dh12_read_reg(reg)
  120. i2c.send(i2cid, LIS2DH12_ADDRESS_ADR,reg)
  121. return i2c.recv(i2cid, LIS2DH12_ADDRESS_ADR, 1):byte(1)
  122. end
  123. local function lis2dh12_write_reg(reg,val)
  124. i2c.send(i2cid, LIS2DH12_ADDRESS_ADR,{reg,val})
  125. end
  126. local function lis2dh12_block_data_update_set(val)
  127. local rdval = lis2dh12_read_reg(LIS2DH12_CTRL_REG4)
  128. val = (val==1) and 0x80 or 0x00
  129. rdval = bit.band(rdval,0x7F)
  130. rdval = bit.bor(rdval, val)
  131. lis2dh12_write_reg(LIS2DH12_CTRL_REG4,rdval)
  132. end
  133. local function lis2dh12_data_rate_set(val)
  134. val = bit.lshift(bit.band(val,0x0F),4)
  135. local rdval = lis2dh12_read_reg(LIS2DH12_CTRL_REG1)
  136. rdval = bit.band(rdval,0x0F)
  137. rdval = bit.bor(rdval, val)
  138. lis2dh12_write_reg(LIS2DH12_CTRL_REG1,rdval)
  139. end
  140. local function lis2dh12_full_scale_set(val)
  141. val = bit.lshift(bit.band(val,0x03),4)
  142. local rdval = lis2dh12_read_reg(LIS2DH12_CTRL_REG4)
  143. rdval = bit.band(rdval,0xCF)
  144. rdval = bit.bor(rdval, val)
  145. lis2dh12_write_reg(LIS2DH12_CTRL_REG4,rdval)
  146. end
  147. local function lis2dh12_temperature_meas_set( val)
  148. val = bit.lshift(bit.band(val,0x03),6)
  149. local rdval = lis2dh12_read_reg(LIS2DH12_TEMP_CFG_REG)
  150. rdval = bit.band(rdval,0x3F)
  151. rdval = bit.bor(rdval, val)
  152. lis2dh12_write_reg(LIS2DH12_TEMP_CFG_REG,rdval)
  153. end
  154. local function lis2dh12_operating_mode_set(val)
  155. local rdval, lpen, hr
  156. if val == LIS2DH12_HR_12bit then
  157. lpen = 0x00
  158. hr = 0x08
  159. elseif val == LIS2DH12_NM_10bit then
  160. lpen = 0x00
  161. hr = 0x00
  162. elseif val == LIS2DH12_LP_8bit then
  163. lpen = 0x80
  164. hr = 0x00
  165. end
  166. rdval = lis2dh12_read_reg(LIS2DH12_CTRL_REG1)
  167. rdval = bit.band(rdval,0xF7)
  168. rdval = bit.bor(rdval, lpen)
  169. lis2dh12_write_reg(LIS2DH12_CTRL_REG1,rdval)
  170. rdval = lis2dh12_read_reg(LIS2DH12_CTRL_REG4)
  171. rdval = bit.band(rdval,0xF7)
  172. rdval = bit.bor(rdval, hr)
  173. lis2dh12_write_reg(LIS2DH12_CTRL_REG4,rdval)
  174. end
  175. local function lis2dh12_status_get()
  176. return lis2dh12_read_reg(LIS2DH12_STATUS_REG)
  177. end
  178. local function lis2dh12_temp_data_ready_get()
  179. local rdval = lis2dh12_read_reg(LIS2DH12_STATUS_REG_AUX)
  180. return bit.band(rdval,0x20)
  181. end
  182. local function lis2dh12_acceleration_raw_get()
  183. local xl,xh,yl,yh,zl,zh,x,y,z
  184. xl = lis2dh12_read_reg(LIS2DH12_OUT_X_L)
  185. xh = lis2dh12_read_reg(LIS2DH12_OUT_X_H)
  186. yl = lis2dh12_read_reg(LIS2DH12_OUT_Y_L)
  187. yh = lis2dh12_read_reg(LIS2DH12_OUT_Y_H)
  188. zl = lis2dh12_read_reg(LIS2DH12_OUT_Z_L)
  189. zh = lis2dh12_read_reg(LIS2DH12_OUT_Z_H)
  190. x = xh * 256 + xl
  191. y = yh * 256 + yl
  192. z = zh * 256 + zl
  193. return x,y,z
  194. end
  195. local function lis2dh12_temperature_raw_get()
  196. local tl,th
  197. tl = lis2dh12_read_reg(LIS2DH12_OUT_TEMP_L)
  198. th = lis2dh12_read_reg(LIS2DH12_OUT_TEMP_H)
  199. return th * 256 + tl
  200. end
  201. --器件初始化
  202. function lis2dh12.init(i2c_id)
  203. i2cid = i2c_id
  204. sys.wait(20)
  205. if chip_check() then
  206. lis2dh12_block_data_update_set(PROPERTY_ENABLE)
  207. lis2dh12_data_rate_set(LIS2DH12_ODR_10Hz)
  208. lis2dh12_full_scale_set(LIS2DH12_2g)
  209. lis2dh12_temperature_meas_set(LIS2DH12_TEMP_ENABLE)
  210. lis2dh12_operating_mode_set(LIS2DH12_HR_12bit)
  211. sys.wait(20)--跳过首次数据
  212. log.info("lis2dh12 init_ok")
  213. return true
  214. end
  215. return false
  216. end
  217. local function LIS2DH12_FROM_FS_2g_HR_TO_mg(lsb) return (bit.rshift(lsb,4)) * 1.0 end
  218. local function LIS2DH12_FROM_FS_4g_HR_TO_mg(lsb) return (bit.rshift(lsb,4)) * 2.0 end
  219. local function LIS2DH12_FROM_FS_8g_HR_TO_mg(lsb) return (bit.rshift(lsb,4)) * 4.0 end
  220. local function LIS2DH12_FROM_FS_16g_HR_TO_mg(lsb) return (bit.rshift(lsb,4)) * 12.0 end
  221. local function LIS2DH12_FROM_LSB_TO_degC_HR(lsb) return (bit.rshift(lsb,6)) / 4.0 +25.0 end
  222. --[[
  223. 获取lis2dh12数据
  224. @api lis2dh12.get_data()
  225. @return table lis2dh12数据
  226. @usage
  227. local lis2dh12_data = lis2dh12.get_data()
  228. log.info("lis2dh12_data", "lis2dh12_data.x"..(lis2dh12_data.x),"lis2dh12_data.y"..(lis2dh12_data.y),"lis2dh12_data.z"..(lis2dh12_data.z),"lis2dh12_data.temp"..(lis2dh12_data.temp))
  229. ]]
  230. function lis2dh12.get_data()
  231. local lis2dh12_data={}
  232. lis2dh12_data.raw_x,lis2dh12_data.raw_y,lis2dh12_data.raw_z = lis2dh12_acceleration_raw_get()
  233. if lis2dh12_temp_data_ready_get() >0 then
  234. local temp_raw = lis2dh12_temperature_raw_get()
  235. lis2dh12_data.temp = LIS2DH12_FROM_LSB_TO_degC_HR(temp_raw)
  236. end
  237. -- x, y, z 轴加速度
  238. local acc_x = math.abs(LIS2DH12_FROM_FS_2g_HR_TO_mg(lis2dh12_data.raw_x))
  239. local acc_y = math.abs(LIS2DH12_FROM_FS_2g_HR_TO_mg(lis2dh12_data.raw_y))
  240. local acc_z = math.abs(LIS2DH12_FROM_FS_2g_HR_TO_mg(lis2dh12_data.raw_z))
  241. lis2dh12_data.x = acc_x
  242. lis2dh12_data.y = acc_y
  243. lis2dh12_data.z = acc_z
  244. -- 重力加速度
  245. lis2dh12_data.acc_g = math.sqrt(math.pow(acc_x, 2) + math.pow(acc_y, 2) + math.pow(acc_z, 2))
  246. if acc_z > lis2dh12_data.acc_g then
  247. acc_z = lis2dh12_data.acc_g
  248. end
  249. -- angle_z/90 = asin(acc_z/acc_g)/π/2
  250. local angle_z = math.asin(acc_z/lis2dh12_data.acc_g) * 2 / 3.14 * 90
  251. angle_z = 90 - angle_z
  252. if angle_z < 0 then
  253. angle_z = 0
  254. end
  255. lis2dh12_data.angle_z = angle_z
  256. return lis2dh12_data
  257. end
  258. return lis2dh12