当前位置: 代码迷 >> 综合 >> 【LuatOS-sensor】2 气压BMP180
  详细解决方案

【LuatOS-sensor】2 气压BMP180

热度:95   发布时间:2023-12-05 20:26:51.0

1 前言

尝试获取BMP180的参数。

2 官方源码

BMP180气压传感器:https://doc.openluat.com/wiki/21?wiki_page_id=2729

参考资料:BMP180气压传感器详解与示例(STM32 附带源码)
这篇文章写的特别好。

此外还可以从arduino中获取bmp180驱动,对照着改。

3 硬件

在这里插入图片描述
i2c设备都类似,重点在于addr,BMP180为0x77。
BMP180只有四个引脚,上图为BH1750。不用连addr

4 官方代码问题

4.1 i2c.send返回值变化导致打印error log

我的开发板是esp32的,应该是bsp改动了,所以导致之前的源码不适用。

现象:log提示i2c.send返回错误
原因:官方示例中i2c,send()返回值为数据个数,而现在返回值为true/false

在这里插入图片描述

在这里插入图片描述

4.2 math.pow弃用

math.pow 在lua5.3被弃用了。使用运算符^

    -- local altitude = 44330 * (1-math.pow(((p) / 101325.0),(1.0/5.255)))local altitude = 44330 * (1-((p) / 101325.0)^(1.0/5.255))-- math.pow 在lua5.3被弃用了。使用运算符^

4.3 常用单位换算

源码中温度乘上0.1,气压/1000换算为kPa,海拔/1000换算为m

5 代码

BMP180.lua

--- 模块功能:I2C BMP180功能测试.
-- @author denghai,youkai
-- @module i2c.BMP180
-- @license MIT
-- @copyright openLuat
-- @release 2021.09.22--[[ BMP180_REG_ID = 0xD0, //contains 0x55 after power onBMP180_REG_RESET = 0xE0, //write 0xB6 to resetBMP180_REG_STATUS = 0xF3, //bit 0: im_update, bit 3: measuringBMP180_REG_CTRL_MEAS = 0xF4, //sets data acquisition options of device BMP180_REG_CONFIG = 0xF5, //sets the rate, filter and interface options of the device.BMP180_REG_OUT = 0xF6, //raw conversion resultsBMP180_REG_CAL_AC1 = 0xAA, //2 bytes each. can never be 0x0000 or oxFFFFBMP180_REG_CAL_AC2 = 0xAC,BMP180_REG_CAL_AC3 = 0xAE,BMP180_REG_CAL_AC4 = 0xB0,BMP180_REG_CAL_AC5 = 0xB2,BMP180_REG_CAL_AC6 = 0xB4,BMP180_REG_CAL_B1 = 0xB6,BMP180_REG_CAL_B2 = 0xB8,BMP180_REG_CAL_MB = 0xBA,BMP180_REG_CAL_MC = 0xBC,BMP180_REG_CAL_MD = 0xBE, ]]BMP180_REG_ID = 0xD0			--contains 0x55 after power on
BMP180_REG_RESET = 0xE0		--write 0xB6 to reset
BMP180_REG_STATUS = 0xF3		--bit 0: im_update bit 3: measuring
BMP180_REG_CTRL_MEAS = 0xF4	--sets data acquisition options of device 
BMP180_REG_CONFIG = 0xF5		--sets the rate filter and interface options of the device.
BMP180_REG_OUT = 0xF6			--raw conversion resultsBMP180_REG_CAL_AC1 = 0xAA		--2 bytes each. can never be 0x0000 or oxFFFF
BMP180_REG_CAL_AC2 = 0xAC
BMP180_REG_CAL_AC3 = 0xAE
BMP180_REG_CAL_AC4 = 0xB0
BMP180_REG_CAL_AC5 = 0xB2
BMP180_REG_CAL_AC6 = 0xB4BMP180_REG_CAL_B1 = 0xB6
BMP180_REG_CAL_B2 = 0xB8BMP180_REG_CAL_MB = 0xBA
BMP180_REG_CAL_MC = 0xBC
BMP180_REG_CAL_MD = 0xBEBMP180_CMD_RESET = 0xB6--register 0xD0
BMP180_MASK_ID = 0xFF--register 0xE0
BMP180_MASK_RESET = 0xFF--register 0xF4
BMP180_MASK_OSS = 0xC0
BMP180_MASK_SCO = 0x20
BMP180_MASK_MCTRL = 0x1FBMP180_CMD_TEMP = 0x2E      --start temperature conversion
BMP180_CMD_PRESS = 0x34     --start pressure conversion-- i2c ID
i2cid = 0-- i2c 速率
speed = 100000BMP180_i2c_addr = 0x77-- 初始化
function BMP180_init_i2c(address)if i2c.setup(i2cid, speed, -1, 1) ~= speed thenlog.error("i2c", "setup fail", addr)returnendaddr = address-- print("BMP180 addr:",addr)
end-- 读取数据
function BMP180_send(...)sys.wait(10)-- print("addr",addr)if not addr thenlog.info("i2c", "addr err")returnendlocal t = {
    ...}-- print("t",t[1],t[2])temp_t =  i2c.send(i2cid, addr, t)-- print("#t",#t)-- print("temp_t",temp_t)-- if temp_t ~= #t then -- 现在i2c.BMP180_send()返回值为true了,不是个数if temp_t ~= true thenlog.error("i2c", "BMP180_send fail", #t)returnendreturn true
end-- 发送数据
function BMP180_read(n)sys.wait(10)if not addr thenlog.info("i2c", "addr err")return "\x00"endval = i2c.recv(i2cid, addr, n)-- log.info("BMP180_read", val:toHex())if val and #val > 0 then return val endreturn "\x00"
end-- 读取short 值 
function BMP180_short(addr, n)-- print("addr",addr)BMP180_send(addr)      -- 只传地址?-- print("BMP180_send addr")-- print("n",n)if n thenf, val = pack.unpack(BMP180_read(2), ">H")elsef, val = pack.unpack(BMP180_read(2), ">h")end-- log.info("val", f, val)return f and val or 0
endfunction BMP180_init()BMP180_init_i2c(BMP180_i2c_addr)      -- 传入i2c地址0x77 = 119BMP180_send(BMP180_REG_ID)      -- 传入地址0xD0, 寄存器idlocal id = BMP180_read(1)-- print("bmp180 reg id ",id)if "U"~=id then print("error id",id)sys.restart("error i2c id!")returnend-- 复位BMP180_send(BMP180_REG_RESET,BMP180_CMD_RESET)     -- 0xE0,0XB6-- https://blog.csdn.net/weixin_50622833/article/details/118611152AC1 = BMP180_short(BMP180_REG_CAL_AC1)  -- 0xAA --2 bytes each. can never be 0x0000 or oxFFFFAC2 = BMP180_short(BMP180_REG_CAL_AC2)  -- 0xACAC3 = BMP180_short(BMP180_REG_CAL_AC3)  -- 0xAEAC4 = BMP180_short(BMP180_REG_CAL_AC4,true)    -- 0xB0AC5 = BMP180_short(BMP180_REG_CAL_AC5,true)    -- 0xB2AC6 = BMP180_short(BMP180_REG_CAL_AC6,true)    -- 0xB4B1  = BMP180_short(BMP180_REG_CAL_B1)  -- 0xB6B2  = BMP180_short(BMP180_REG_CAL_B2)  -- 0xB8MB  = BMP180_short(BMP180_REG_CAL_MB)  -- 0xBAMC  = BMP180_short(BMP180_REG_CAL_MC)  -- 0xBCMD  = BMP180_short(BMP180_REG_CAL_MD)  -- 0xBE 
endfunction BMP180_get_temp_press()-- 温度 ℃BMP180_send(BMP180_REG_CTRL_MEAS,BMP180_CMD_TEMP)     --0xF4表示测量,0x2E表示温度sys.wait(1000)log.info("温度raw", BMP180_short(BMP180_REG_OUT))        --0xF6数据输出UT = BMP180_short(BMP180_REG_OUT)                  -- 温度数值-- print("UT",UT)-- 气压 PaBMP180_send(BMP180_REG_CTRL_MEAS,BMP180_CMD_PRESS)     --0xF4,0x34sys.wait(1000)BMP180_send(BMP180_REG_OUT)_, UP = pack.unpack(BMP180_read(2), "<H")          -- 气压数值-- print("UP",UP)log.info("气压raw", UP)return BMP_UncompemstatedToTrue(UT,UP)endfunction BMP180_test()-- sys.wait(8000)BMP180_init()while true dosys.wait(2000)BMP180_get_temp_press()endend--https://blog.csdn.net/weixin_50622833/article/details/118611152--//用获取的参数对温度和大气压进行修正,并计算海拔
function BMP_UncompemstatedToTrue(UT,UP)local Press = 0local X1 = (UT - AC6) * AC5/32768       -- 2^15,数据右移15位-- log.info("X1 ",X1,"UT ",UT,"AC6 ",AC6)-- local X2 = bit.lshift(MC,11) / (X1 + MD)local X2 = MC*2048 / (X1 + MD)          -- 2^11,左移11位-- log.info("X2",MC,"MC",X2,"MD",MD)local B5 = X1 + X2-- log.info("B5",B5)-- local Temp = bit.rshift((B5 + 8) ,4)local Temp  = (B5 + 8)/16Temp = Temp * 0.1log.info("温度: ",Temp.." °C")local B6 = B5 - 4000-- log.info("B6",B6)X1 = (B2 *((B6 * B6)/4096))/2048-- X1 = bit.rshift(B2 * bit.rshift(B6 * B6,12) ,11)-- log.info("X1",X1,"B2",B2,"B6",B6)X2 = (AC2 * B6)/2048-- X2 = bit.rshift(AC2 * B6,11)-- log.info("X2",X2,"AC2",AC2)local X3 = X1 + X2-- log.info("X3",X3)local B3 = ((AC1 * 4 + X3) + 2) /4-- log.info("B3",B3,"AC1",AC1)X1 = (AC3 * B6)/8192-- X1 = bit.rshift(AC3 * B6 ,13)-- log.info("X1",X1,"AC3",AC3)X2 = (B1 *((B6*B6)/4096)) /65536-- X2 = bit.rshift((B1 *bit.rshift(B6*B6 ,12)) ,16)-- log.info("X2",X2,"B1",B1)-- X3 = bit.rshift(X1 + X2 + 2, 2)X3 = (X1 + X2 + 2)/4-- log.info("X3",X3)local B4 = (AC4 * (X3 + 32768))/32768-- local B4 = bit.rshift(AC4 * (X3 + 32768) ,15)-- log.info("B4",B4,"AC4",AC4)local B7 = (UP - B3) * 50000-- log.info("B7",B7,"UP",UP)if(B7 < 0x80000000) thenPress = (B7 * 2) / B4elsePress = (B7 / B4) * 2end-- log.info("Press",Press)X1 = (Press/256) * (Press/256)-- X1 = bit.rshift(Press ,8) * bit.rshift(Press,8)-- log.info("X1",X1)X1 = (X1 * 3038)/65536-- X1 = bit.rshift(X1 * 3038,16)-- log.info("X1",X1)X2 = (-7357 * Press)/65536-- X2 = bit.rshift(-7357 * Press, 16)-- log.info("X2",X2)Press = Press + (X1 + X2 + 3791)/16-- Press = Press + bit.rshift(X1 + X2 + 3791,4)-- log.info("气压修正", Press)-- Press = Press * 0.001log.info("气压: ", Press * 0.001 .." kPa")local altitude = 44330 * (1-((Press) / 101325.0)^1.0/5.255)altitude = altitude * 0.001log.info("海拔: ", altitude.." m")return Temp,Press * 0.001,altitude
end 

main.lua

PROJECT = "BMP180"
VERSION = "1.0.0"_G.sys = require("sys")-- 加载I?C功能测试模块
require ("BMP180")sys.taskInit(function()-- ps:有wait不能放在外面BMP180_test()-- sys.wait(1500)while 1 dosys.wait(100)end
end)sys.run()

6 结果

在这里插入图片描述
个人感觉这个精准度不高。

  相关解决方案