da221.lua 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. local i2cId = 0
  2. local intPin = 39
  3. -- 是否打印日志
  4. local logSwitch = true
  5. local moduleName = "da221"
  6. local da221Addr = 0x27
  7. local soft_reset = {0x00, 0x24} -- 软件复位地址
  8. local chipid_addr = 0x01 -- 芯片ID地址
  9. local rangeaddr = {0x0f, 0x00} -- 设置加速度量程,默认2g
  10. local int_set1_reg = {0x16, 0x87} --设置x,y,z发生变化时,产生中断
  11. local int_set2_reg = {0x17, 0x10} --使能新数据中断,数据变化时,产生中断,本程序不设置
  12. local int_map1_reg = {0x19, 0x04} --运动的时候,产生中断
  13. local int_map2_reg = {0x1a, 0x01}
  14. local active_dur_addr = {0x27, 0x00} -- 设置激活时间,默认0x00
  15. local active_ths_addr = {0x28, 0x05} -- 设置激活阈值
  16. local mode_addr = {0x11, 0x34} -- 设置模式
  17. local odr_addr = {0x10, 0x08} -- 设置采样率
  18. local int_latch_addr = {0x21, 0x02} -- 设置中断锁存
  19. local x_lsb_reg = 0x02
  20. local active_state = 0x0b
  21. local active_state_data
  22. local function logF(...)
  23. if logSwitch then
  24. log.info(moduleName, ...)
  25. end
  26. end
  27. --字符串转字节数组
  28. local function stringToBytes(hexStr)
  29. local bytes = {}
  30. for i = 1, #hexStr, 2 do
  31. local byteStr = hexStr:sub(i, i+1)
  32. local byte = tonumber(byteStr, 16)
  33. table.insert(bytes, byte)
  34. end
  35. return bytes
  36. end
  37. local interruptCount = 0 -- 计数器
  38. local function ind()
  39. logF("int", gpio.get(intPin))
  40. --gsensor() -- 调用gsensor函数,计算设备是否处于运动状态
  41. if gpio.get(intPin) == 1 then
  42. -- interruptCount = interruptCount + 1 -- 增加计数器
  43. -- if interruptCount >= 2 then -- 判断是否达到2次
  44. -- gsensor() -- 调用gsensor函数
  45. -- interruptCount = 0 -- 重置计数器
  46. -- end
  47. -- manage.setLastCrashLevel()
  48. --读取x,y,z轴的数据
  49. i2c.send(i2cId, da221Addr, 0x02, 1)
  50. local data = i2c.recv(i2cId, da221Addr, 6)
  51. if data and #data == 6 then
  52. logF("XYZ ORIGIN DATA", data:toHex())
  53. local xl, xm, yl, ym, zl, zm = string.byte(data, 1, 1), string.byte(data, 2, 2), string.byte(data, 3, 3), string.byte(data, 4, 4), string.byte(data, 5, 5), string.byte(data, 6, 6)
  54. local x, y, z = (xm << 8 | xl) >> 4, (ym << 8 | yl) >> 4, (zm << 8 | zl) >> 4
  55. logF("x:", x, "y:", y, "z:", z)
  56. else
  57. sys.publish("RESTORE_GSENSOR")
  58. return
  59. end
  60. end
  61. end
  62. -- gpio.debounce(intPin, 100)
  63. gpio.setup(intPin, ind)
  64. local function init()
  65. log.info("da221 init...")
  66. --关闭i2c
  67. i2c.close(i2cId)
  68. --重新打开i2c,i2c速度设置为低速
  69. i2c.setup(i2cId, i2c.SLOW)
  70. sys.wait(50)
  71. i2c.send(i2cId, da221Addr, soft_reset, 1)
  72. sys.wait(50)
  73. i2c.send(i2cId, da221Addr, chipid_addr, 1)
  74. local chipid = i2c.recv(i2cId, da221Addr, 1)
  75. log.info("i2c", "chipid",chipid:toHex())
  76. if string.byte(chipid) == 0x13 then
  77. log.info("da221 init success")
  78. else
  79. log.info("da221 init fail")
  80. end
  81. -- 设置寄存器
  82. i2c.send(i2cId, da221Addr, int_set1_reg, 1)--设置x,y,z发生变化时,产生中断
  83. sys.wait(5)
  84. i2c.send(i2cId, da221Addr, int_map1_reg, 1)--运动的时候,产生中断
  85. sys.wait(5)
  86. i2c.send(i2cId, da221Addr, active_dur_addr, 1)-- 设置激活时间,默认0x00
  87. sys.wait(5)
  88. i2c.send(i2cId, da221Addr, active_ths_addr, 1)-- 设置激活阈值
  89. sys.wait(5)
  90. i2c.send(i2cId, da221Addr, mode_addr, 1)-- 设置模式
  91. sys.wait(5)
  92. i2c.send(i2cId, da221Addr, odr_addr, 1)-- 设置采样率
  93. sys.wait(5)
  94. i2c.send(i2cId, da221Addr, int_latch_addr, 1)-- 设置中断锁存 中断一旦触发将保持,直到手动清除
  95. sys.wait(5)
  96. end
  97. sys.taskInit(function()
  98. mcu.altfun(mcu.I2C, i2cId, 13, 2, 0)
  99. mcu.altfun(mcu.I2C, i2cId, 14, 2, 0)
  100. -- while true do
  101. init()
  102. while true do
  103. -- --等待da221传感器数据不正确,复位的消息
  104. -- local result = sys.waitUntil("RESTORE_GSENSOR", 60 * 1000)
  105. -- --如果接收到了复位消息,则跳出读取数据的循环,重新执行init()函数
  106. -- if result then
  107. -- break
  108. -- end
  109. -- --读取da221传感器的型号值,默认是0x13
  110. -- i2c.send(i2cId, da221Addr, 0x01, 1)
  111. -- local data = i2c.recv(i2cId, da221Addr, 1)
  112. -- if not data or data == "" or string.byte(data) ~= 0x13 then
  113. -- break
  114. -- end
  115. -- 读取三轴速度
  116. i2c.send(i2cId, da221Addr, x_lsb_reg, 1)
  117. local recv_data_xyz = i2c.recv(i2cId, da221Addr, 6)
  118. local hex_data_xyz = stringToBytes(recv_data_xyz:toHex())
  119. log.info("recv_data_xyz", recv_data_xyz:toHex())
  120. if recv_data_xyz and #recv_data_xyz == 6 then
  121. -- local data_xyz = {}
  122. -- for i = 1, #recv_data_xyz do
  123. -- -- 将提取的子字符串添加到结果表中
  124. -- table.insert(data_xyz, recv_data_xyz:sub(i, i):toHex())
  125. -- end
  126. -- data_xyz = data_xyz:byte()
  127. log.info(string.format("Byte: %02X %02X %02X %02X %02X %02X", hex_data_xyz[1], hex_data_xyz[2], hex_data_xyz[3], hex_data_xyz[4], hex_data_xyz[5], hex_data_xyz[6]))
  128. -- 提取X轴数据
  129. local acc_x = ((hex_data_xyz[2] << 8)|hex_data_xyz[1])>>4;
  130. -- 提取Y轴数据
  131. local acc_y = ((hex_data_xyz[4] << 8)|hex_data_xyz[3])>>4;
  132. -- 提取Z轴数据
  133. local acc_z = ((hex_data_xyz[6] << 8)|hex_data_xyz[5])>>4;
  134. log.info(string.format("acc_x %.1f", acc_x))
  135. log.info(string.format("acc_y %.1f", acc_y))
  136. log.info(string.format("acc_z %.1f", acc_z))
  137. -- sys.publish("gsensor", {x = acc_x, y = acc_y, z = acc_z})
  138. end
  139. sys.wait(4000)
  140. end
  141. -- end
  142. end)