BME280.lua 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. --- 模块功能:BME280功能测试.
  2. -- @author openLuat
  3. -- @module BME280
  4. -- @license MIT
  5. -- @copyright openLuat
  6. -- @release 2021.09.13
  7. module(...,package.seeall)
  8. require"utils"
  9. local i2cid = 2
  10. local i2cslaveaddr = 0x76
  11. local cmd,i ={0xD0,0xE0,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0XFB,0xFc,who="read all"}
  12. local pressure_data={0xF7,0xF8,0xF9,who="pressure"}
  13. local temprature_data={0xFA,0xFB,0xFC,who="temprature"}
  14. local chip_id={0xD0,who="chip_ID"}
  15. local dig_T={0x88,0x89,0x8A,0x8B,0x8C,0x8D,who="dig_T"}
  16. local dig_P={0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F,who="dig_P"}
  17. local i2copen_flag=false --i2c开启标志位
  18. local setup --初始化函数
  19. local read_T --读取温度函数
  20. local read_P --读取压力函数
  21. local ctrl_meas=0x3F --默认配置,根据需要自行修改
  22. local temprature --校准计算后的温度数据
  23. local pressure --校准计算后的压力数据
  24. local temperature__correction --采集实际环境中的温度作为后续计算气压值的校准数据
  25. --读取数据
  26. local function readdata(table)
  27. if type(table)=="table" then
  28. log.debug("who",dig_T.who)
  29. sys.taskInit(function()
  30. if i2c.setup(i2cid,100000) ~= 100000 then
  31. print("init fail")
  32. return
  33. end
  34. for i=1,#table,1 do
  35. --向从设备i2cslaveaddr发送寄存器地址cmd[i]
  36. i2c.send(i2cid,i2cslaveaddr,table[i])
  37. --向从设备i2cslaveaddr发送要写入从设备寄存器内的数据cmd[i+1]
  38. print("testI2c.init",string.format("%02X",table[i]),string.toHex(i2c.recv(i2cid,i2cslaveaddr,1)))
  39. end
  40. i2c.close(i2cid)
  41. end)
  42. else log.warn("BME280 readdata ","input data type not table")
  43. end
  44. end
  45. --初始化函数
  46. setup=function()
  47. sys.taskInit(function()
  48. if i2c.setup(i2cid,100000) ~= 100000 then
  49. print("HDC2080 init fail")
  50. i2copen_flag=false
  51. return i2copen_flag
  52. end
  53. i2c.send(i2cid,i2cslaveaddr, {0xE0, 0xB6}) --执行复位
  54. sys.wait(1000)
  55. i2c.send(i2cid,i2cslaveaddr, {0xF4, ctrl_meas})
  56. sys.wait(10)
  57. end)
  58. i2copen_flag=true
  59. return i2copen_flag
  60. end
  61. --[[ 此部分注释放开即可使用724-A13等开发板按键触发检测
  62. require "powerKey"
  63. local function longCb()
  64. sys.taskInit(read_P)
  65. end
  66. local function shortCb()
  67. sys.taskInit(read_T)
  68. end
  69. powerKey.setup(3000, longCb, shortCb)
  70. ]]
  71. read_T= function ()
  72. temprature=nil
  73. if i2copen_flag then --判断当前i2c是否打开
  74. log.info("BME280","i2c opening")
  75. else
  76. if i2c.setup(i2cid,100000) ~= 100000 then
  77. print("BME280 init fail")
  78. i2copen_flag=false
  79. return false
  80. else
  81. i2copen_flag=true
  82. end
  83. end
  84. i2c.send(i2cid,i2cslaveaddr, {0xF4, ctrl_meas}) --写入默认配置,如需修改请参考手册中0xF4
  85. sys.wait(1000)
  86. i2c.send(i2cid,i2cslaveaddr,0xF7) --读取adc采集温度数据
  87. local zwdata=i2c.recv(i2cid,i2cslaveaddr,6)
  88. local data=string.sub(string.toHex(zwdata),7,11)
  89. i2c.send(i2cid,i2cslaveaddr,0x88) --读取温度校准数据
  90. local dig_T_data=string.toHex(i2c.recv(i2cid,i2cslaveaddr,6))
  91. local dig_T1=string.sub(dig_T_data,3,4)..string.sub(dig_T_data,1,2)
  92. local dig_T2=string.sub(dig_T_data,7,8)..string.sub(dig_T_data,5,6)
  93. local dig_T3=string.sub(dig_T_data,11,12)..string.sub(dig_T_data,9,10)
  94. i2c.close(i2cid)
  95. i2copen_flag=false
  96. --结束数据获取开始运算实际温度数据
  97. if data=="80000" then log.debug("BME280 err:","initial data")
  98. else
  99. data=tonumber(data,16)
  100. dig_T1=tonumber(dig_T1,16)
  101. dig_T2=tonumber(dig_T2,16)
  102. dig_T3=tonumber(dig_T3,16)
  103. if dig_T1 and dig_T2 and dig_T3 then
  104. local var1 = ((data) / 16384.0 - (dig_T1) / 1024.0) * (dig_T2)
  105. local var2 = (((data) / 131072.0 - (dig_T1) / 8192.0) * ((data) / 131072.0 - (dig_T1) / 8192.0)) * (dig_T3)
  106. local temprature=(var1+var2)/5120
  107. temperature__correction=var1+var2
  108. log.info("BME280 ",(string.format("实际温度%.2f℃\n",temprature)))
  109. else
  110. log.debug("BME280 err ",":recv data nil ")
  111. end
  112. return temprature
  113. end
  114. end
  115. read_P=function ()
  116. pressure=nil
  117. if i2copen_flag then --判断当前i2c是否打开
  118. log.info("BME280","i2c opening")
  119. else
  120. if i2c.setup(i2cid,100000) ~= 100000 then
  121. print("BME280 init fail")
  122. i2copen_flag=false
  123. return false
  124. else i2copen_flag=true
  125. end
  126. end
  127. i2c.send(i2cid,i2cslaveaddr, {0xF4, ctrl_meas}) --写入默认配置,如需修改请参考手册中0xF4
  128. sys.wait(1000)
  129. i2c.send(i2cid,i2cslaveaddr,0xF7) --读取adc采集压力数据
  130. local zwdata=i2c.recv(i2cid,i2cslaveaddr,6)
  131. local data=string.sub(string.toHex(zwdata),1,5)
  132. i2c.send(i2cid,i2cslaveaddr,0x8E) --读取压力校准数据
  133. local dig_P_data=string.toHex(i2c.recv(i2cid,i2cslaveaddr,18))
  134. local dig_P1=string.sub(dig_P_data,3,4)..string.sub(dig_P_data,1,2)
  135. local dig_P2=string.sub(dig_P_data,7,8)..string.sub(dig_P_data,5,6)
  136. local dig_P3=string.sub(dig_P_data,11,12)..string.sub(dig_P_data,9,10)
  137. local dig_P4=string.sub(dig_P_data,15,16)..string.sub(dig_P_data,13,14)
  138. local dig_P5=string.sub(dig_P_data,19,20)..string.sub(dig_P_data,17,18)
  139. local dig_P6=string.sub(dig_P_data,23,24)..string.sub(dig_P_data,21,22)
  140. local dig_P7=string.sub(dig_P_data,27,28)..string.sub(dig_P_data,25,26)
  141. local dig_P8=string.sub(dig_P_data,31,32)..string.sub(dig_P_data,29,30)
  142. local dig_P9=string.sub(dig_P_data,35,36)..string.sub(dig_P_data,33,34)
  143. i2c.close(i2cid)
  144. if data=="80000" then log.debug("BME280 err:","initial data")
  145. else
  146. data=tonumber(data,16)
  147. dig_P1=tonumber(dig_P1,16)
  148. dig_P2=tonumber(dig_P2,16)
  149. dig_P3=tonumber(dig_P3,16)
  150. dig_P4=tonumber(dig_P4,16)
  151. dig_P5=tonumber(dig_P5,16)
  152. dig_P6=tonumber(dig_P6,16)
  153. dig_P7=tonumber(dig_P7,16)
  154. dig_P8=tonumber(dig_P8,16)
  155. dig_P9=tonumber(dig_P9,16)
  156. i2copen_flag=false
  157. --结束数据获取开始运算实际压力数据
  158. local var1, var2, p
  159. var1 = (temperature__correction/ 2.0) - 64000.0
  160. var2 = var1 * var1 * (dig_P6) / 32768.0
  161. var2 = var2 + var1 * (dig_P5) * 2.0
  162. var2 = (var2 / 4.0) + ((dig_P4) * 65536.0)
  163. var1 = ((dig_P3) * var1 * var1 / 524288.0 + (dig_P2) * var1) / 524288.0
  164. var1 = (1.0 + var1 / 32768.0) * (dig_P1)
  165. if(0.0 == var1) then
  166. return 0 -- avoid exception caused by division by zero
  167. end
  168. p = 1048576.0 -data
  169. p = (p - (var2 / 4096.0)) * 6250.0 / var1
  170. var1 = (dig_P9) * p * p / 2147483648.0
  171. var2 = p * (dig_P8) / 32768.0
  172. p = p + (var1 + var2 + (dig_P7)) / 16.0
  173. pressure =p
  174. log.info("BME280 ",(string.format("实际压力%.2f Pa\n",pressure)))
  175. return pressure
  176. end
  177. end
  178. sys.taskInit(function()
  179. sys.wait(5000)
  180. setup()
  181. read_T()
  182. read_P()
  183. end)