100 Air202F iic读取BMP280 读出数据没变化

折腾了一个星期了,读出的数据没有变化,麻烦帮忙看看!

代码如下:

 module(...,package.seeall)

require"utils"
require"ntp"
require"misc"
require"pins"


local i2cId = 2


local slen = string.len

local BMP280_ADDR        = 0x76
local BMP280_TEMP_ADDR   = 0xFA
local BMP280_PRESS_ADDR  = 0xF7
local dig_t1
local dig_t2
local dig_t3
local dig_p1
local dig_p2
local dig_p3
local dig_p4
local dig_p5
local dig_p6
local dig_p7
local dig_p8
local dig_p9

local function sourcesInfo()
print("mem:",_G.collectgarbage("count"))  -- 打印占用的RAM
print("flash:",rtos.get_fs_free_size()) -- 打印剩余FALSH,单位Byte
end


---i2c初始化
---i2c.FAST (400KHz), i2c.SLOW (100KHz)
---Max Frequency: 400kHz
local function i2cInit()
if i2c.setup(i2cId,i2c.SLOW) ~= i2c.SLOW then
        log.info("I2C","I2c.init fail.")
        return
    end
end

---i2c写数据
local function i2cWrite(i2caddr,regaddr,data)
---写寄存器
i2c.send(i2cId,i2caddr,regaddr)
---写数据
i2c.send(i2cId,i2caddr,data)
end

---i2c读数据
local function i2cRead(i2caddr,regaddr,size)
---读寄存器
i2c.send(i2cId,i2caddr,regaddr)
---读数据
return string.toHex(i2c.recv(i2cId,i2caddr,size))
end

----------------------------------------
---2个数据和3个数据的高低位顺序不一样---
----------------------------------------

---i2c读连续地址3个数据
local function i2cReadThreeData(i2caddr,regaddr)
log.info("i2cReadThreeData","addr:"..i2caddr.." reg:"..regaddr)
local msb  = i2cRead(i2caddr,regaddr,1)
local lsb  = i2cRead(i2caddr,regaddr+1,1)
local xlsb = i2cRead(i2caddr,regaddr+2,1)
if msb == "" or lsb == "" or xlsb == "" or msb == nil or lsb == nil or xlsb == nil then
log.info("BMP280 three data","the data is null")
else
    --20位精度
    log.info("BMP280 three data","msb:"..msb.." lsb:"..lsb.." xlsb:"..xlsb)
return bit.lshift(tonumber(msb,16),12) + bit.lshift(tonumber(lsb,16),4) + bit.rshift(tonumber(xlsb,16),4)
end
end

---i2c读连续地址2个数据
local function i2cReadTwoData(i2caddr,regaddr)
local lsb = i2cRead(i2caddr,regaddr,1)
local msb = i2cRead(i2caddr,regaddr+1,1)
if lsb == "" or msb == "" or lsb == nil or msb == nil then
log.info("BMP280 two data","the data is null")
else
log.info("BMP280 two data","msb:"..msb.." lsb:"..lsb)
return bit.lshift(tonumber(msb,16),8) + tonumber(lsb,16)
end
end



---bmp280初始化
local id
local function bmp280Init()
id = i2cRead(BMP280_ADDR,0xd0,1)
log.info("bmp280 id:",id)

---读取压力补偿值
dig_t1 = i2cReadTwoData(BMP280_ADDR,0x88)
dig_t2 = i2cReadTwoData(BMP280_ADDR,0x8a)
dig_t3 = i2cReadTwoData(BMP280_ADDR,0x8c)
dig_p1 = i2cReadTwoData(BMP280_ADDR,0x8e)
dig_p2 = i2cReadTwoData(BMP280_ADDR,0x90)
dig_p3 = i2cReadTwoData(BMP280_ADDR,0x92)
dig_p4 = i2cReadTwoData(BMP280_ADDR,0x94)
dig_p5 = i2cReadTwoData(BMP280_ADDR,0x96)
dig_p6 = i2cReadTwoData(BMP280_ADDR,0x98)
dig_p7 = i2cReadTwoData(BMP280_ADDR,0x9a)
dig_p8 = i2cReadTwoData(BMP280_ADDR,0x9c)
dig_p9 = i2cReadTwoData(BMP280_ADDR,0x9e)

i2cWrite(BMP280_ADDR,0xe0,0xb6)
sys.wait(1000)
i2cWrite(BMP280_ADDR,0xf4,0xff)
i2cWrite(BMP280_ADDR,0xf5,0x00)
end

local function readbmp280Press()

local adc_T = i2cReadThreeData(BMP280_ADDR,BMP280_TEMP_ADDR)
local adc_P = i2cReadThreeData(BMP280_ADDR,BMP280_PRESS_ADDR)
if adc_P == nil then
return 0
end
local var1 = (adc_T/16384.0-dig_t1/1024.0) * dig_t2
local var2 = (adc_T/131072.0 - dig_t1/8192.0) * (adc_T/131072.0 - dig_t1/8192.0) * dig_t3
local t_fine = var1 + var2

T = (var1+var2)/5120.0

var1 = t_fine/2.0 - 64000.0
var2 = var1 * var1 * dig_p6 / 32768.0
var2 = var2 + var1 * dig_p5 * 2.0
var2 = (var2/4.0) + dig_p4 
var1 = dig_p3*var1*var1/524288.0 + dig_p2*var1/524288.0
var1 = (1.0+var1/32768.0) * dig_p1
local p = 1048576.0 - adc_P
p = (p - var2/4096.0) * 6250.0/var1
var1 = dig_p9*p*p/2147483648.0
var2 = p*dig_p8/32768.0
p = p + (var1 + var2 + dig_p7)/16.0

return p
end



local function task()
---i2c初始化
i2cInit()
---bmp280初始化
bmp280Init()
while true do
---打印数据
log.info("bmp280气压值:"..readbmp280Press().."Pa".." id:"..id)
sys.wait(1000)
end
end


sys.taskInit(task)
请先 登录 后评论

7 个回答

丁小泉ZJ

在 Reset 状态时候,MSB 值是 0x80,LSB 和 XLSB 是 0x00,启动后什么都还没做的时候,是 reset state

要启动它,根据手册说明,写入 0xFF 进去 0xF4 它就工作了。但为什么没用作?因为没写入成功啊,修改写函数。再就是每次读取数据前写入ff到f4。唤醒休眠。


---i2c写数据
local function i2cWrite(i2caddr,regaddr,data)
    ---写寄存器
    --i2c.send(i2cId,i2caddr,regaddr)
    ---写数据
    --i2c.send(i2cId,i2caddr,data)

    --修改成:
    i2c.send(i2cId,i2caddr,{regaddr,data})
end
请先 登录 后评论
丁仁君 - 物联网

attachments-2019-03-2vjV0Gfe5c9dcea3cfb22.png

读出数据没有变化,SDO已经接地。

请先 登录 后评论
丁仁君 - 物联网

没有变化,SDO已经接地。

请先 登录 后评论
晨旭 - 菜鸟

数据处理不对

比如这里:bit.lshift(tonumber(msb,16),12) + bit.lshift(tonumber(lsb,16),4) + bit.rshift(tonumber(xlsb,16),4)

你可能是照着c代码写的:temp = (long)(((unsigned long)msb << 12)|((unsigned long)lsb << 4)|((unsigned long)xlsb >> 4));

应该改成这样(其他部分也自己照着改吧):

string.byte(msb)*4096 + string.byte(lsb)*8 + string.byte(xlsb)/8

请先 登录 后评论
so_zhou

兄弟,你的问题解决了吗?我也遇到相同问题

请先 登录 后评论
李仁

---i2c写数据

local function i2cWrite(i2caddr,regaddr,data)

---写寄存器

TX_buf= {regaddr,data}

i2c.send(i2cId,i2caddr,TX_buf)

---写数据

--i2c.send(i2cId,i2caddr,data)

end

请先 登录 后评论
辛工

attachments-2020-08-9hDWFX565f3258d1a0d37.png2c.recv()

向从设备读取数据

  • 语法

i2c.recv( id, slave,size )

  • 参数
idi2c接口id,目前支持 i2c id=2 即模块的i2c3
slavei2c 外设地址 0x00-0x7f
size读取数据字节数
  • 返回值

返回读取的数据,二进制数据会包含非可见字符,请使用 string.byte 打印数据流


读出来的数据使用data=pack.unpack(i2c.recv(i2cId,i2caddr,size),'b2')返回十六进制数据,后面的运算不用转换直接进行,比如左移8位,data*256

另外BMP280初始化指令你的模式设置的不对,所以读出来的数据一直没有变化,应用设置成normal mode,目前我用的Air202,源程序在网页上运行是正确的下载下去就会重启看了下内存也都够,不知道哪里出问题了

请先 登录 后评论
  • 1 关注
  • 0 收藏,4425 浏览
  • 丁仁君 提出于 2019-03-29 15:43

相似问题