vl6180.lua 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. --[[
  2. @module vl6180
  3. @summary VL6180激光测距传感器
  4. @version 1.0
  5. @date 2023.11.14
  6. @author dingshuaifei
  7. @usage
  8. --MCU vl6180
  9. --3V3 VIN
  10. --GND GND
  11. --I2CSCL SCL
  12. --I2CSDA SDA
  13. --GPIO GPIO1(SHDN/中断输出)
  14. --GPIO GPIO0(CE)
  15. vl6180测量说明:
  16. 1、只能单次测量,测量0-10cm的绝对距离
  17. 2、测量有效范围在20-30cm
  18. --注意:因使用了sys.wait()所有api需要在协程中使用
  19. -- 用法实例
  20. vl6180=require"vl6180"
  21. local CE=4
  22. local INT=21
  23. local I2C_ID=0
  24. sys.taskInit(function()
  25. sys.wait(2000)
  26. log.info('初始化')
  27. vl6180.init(CE,INT,I2C_ID)
  28. while true do
  29. sys.wait(200)
  30. --单次测量开始
  31. log.info('距离:',vl6180.get())
  32. end
  33. end)
  34. ]]
  35. vl6180={}
  36. --配置GPIO为CE和INT
  37. local CE --gpio
  38. local INT --gpio
  39. --i2c id
  40. local i2c_id
  41. --设备地址
  42. local addr=0x29
  43. --测量距离数据
  44. local vldata
  45. --设置中断和CE
  46. local function it_ce_init()
  47. --设置CE引脚上拉输出,默认1
  48. gpio.setup(CE, 0, gpio.PULLUP)
  49. --设置INT引脚中断,测量完成后会进入回调
  50. gpio.setup(INT, function(val)
  51. sys.publish("VL6180_INC")
  52. end, gpio.PULLUP)
  53. end
  54. --配置i2c
  55. local function i2c_init()
  56. --i2c 1 快速模式
  57. i2c.setup(i2c_id,i2c.FAST)
  58. end
  59. --[[
  60. 写设备寄存器值:
  61. 写入寄存器会判断写入的值是否写入成功,若不成功则会打印出相应的寄存器地址,以及当前寄存器的值。
  62. 注意:有的寄存器位写入值后,会被硬件清除,不代表写失败,具体参考相应寄存器
  63. @regaddr 寄存器地址
  64. @val 写入的值
  65. ]]
  66. local function write_register(regaddr,val)
  67. local stu=i2c.send(i2c_id,addr,string.char(regaddr>>8,regaddr&0xff,val))
  68. i2c.send(i2c_id,addr,string.char(regaddr>>8,regaddr&0xff))
  69. local reg=i2c.recv(i2c_id,addr,1)
  70. if string.byte(reg) ~= val then
  71. log.info('写入失败地址',string.toHex(string.char(regaddr)),'读值',string.toHex(reg),'写发送状态',stu)
  72. end
  73. end
  74. --[[
  75. 读设备寄存器的值:
  76. @regaddr 寄存器地址
  77. @bit 读多少位
  78. ]]
  79. local function read_register(regaddr,bit)
  80. local regval
  81. i2c.send(i2c_id,addr,string.char(regaddr>>8,regaddr&0xff))
  82. regval=i2c.recv(i2c_id,addr,bit)
  83. return string.byte(regval)
  84. end
  85. --[[
  86. 系统功能配置
  87. ]]
  88. local function SetMode()
  89. --设置GPIO1为中断输出,极性低
  90. write_register(0x0011,0x10)
  91. --复位平均采样周期
  92. write_register(0x010A,0x30)
  93. --模拟增益设置1.0
  94. write_register(0x003F,0x46)
  95. --系统范围VHV重复率
  96. write_register(0x0031,0xFF)
  97. --积分周期100ms
  98. write_register(0x0041,0x63)
  99. --对测距传感器进行单次温度校准
  100. --write_register(0x002E,0x00)
  101. write_register(0x002E,0x01)
  102. --测量周期,10ms
  103. write_register(0x001B,0x09)
  104. write_register(0x003E,0x31)
  105. --系统中断配置GPIO
  106. write_register(0x0014,0x24)
  107. end
  108. --[[
  109. vl6180初始化
  110. @api vl6180.init(ce,int,id)
  111. @number ce gpio编号[控制]
  112. @number int gpio编号[中断]
  113. @number id i2c总线id
  114. @return bool 成功返回true失败返回false
  115. @usage
  116. vl6180.Init(4,21,0)
  117. ]]
  118. function vl6180.init(ce,int,i2cid)
  119. --判断id是否存在
  120. if i2c.exist(i2cid)~=true then
  121. log.info('i2c不存在')
  122. return false
  123. end
  124. --赋值
  125. CE =ce
  126. INT =int
  127. i2c_id =i2cid
  128. --初始化INT和CE
  129. it_ce_init()
  130. --初始化i2c
  131. i2c_init()
  132. --开启vl6180
  133. gpio.set(CE, 0)
  134. sys.wait(10)
  135. gpio.set(CE, 1)
  136. --读设备号
  137. local send_s=i2c.send(i2c_id,addr,string.char(0x00,0x00))
  138. if send_s ~=true then
  139. log.info('设备不存在')
  140. return false
  141. end
  142. local recv_data=i2c.recv(i2c_id,addr,1)
  143. log.info('设备号:',string.toHex(recv_data))
  144. --系统模式配置
  145. SetMode()
  146. return true
  147. end
  148. --[[
  149. vl6180获取测量距离值 单位:mm
  150. @api vl6180.get()
  151. @return number 成功返回vl6180数据,失败返回0
  152. @usage
  153. local data=vl6180.get()
  154. log.info("measuring val:",data)
  155. ]]
  156. function vl6180.get()
  157. --等待设备就绪
  158. local recv_data=read_register(0x004D,1)
  159. if recv_data & 0x1 ~=0 then
  160. --启动测量,单次测距
  161. i2c.send(i2c_id,addr,string.char(0x00,0x18,0x01))
  162. --判断ALS低阈值事件
  163. recv_data=read_register(0x004F,1)
  164. if recv_data & 0x04 ~= 0 then
  165. --读取距离数据,单位mm
  166. vldata = read_register(0x0062,1)
  167. --清除全部中断标志位
  168. i2c.send(i2c_id,addr,string.char(0x00,0x15,0x07))
  169. if sys.waitUntil("VL6180_INC") then
  170. return vldata
  171. else
  172. return 0
  173. end
  174. else
  175. log.info('低阈值事件等待就绪')
  176. end
  177. else
  178. log.info('设备忙')
  179. return 0
  180. end
  181. end
  182. return vl6180