如何解决为什么我不能使用带有 Raspberry Pi 的 BMP388 传感器打印温度?
我有一个 RaspBerry Pi Zero,我将它用于女巫的一个项目,我必须测量温度。我使用的传感器是 BMP388,它连接到 I2C 引脚(GPIO2 和 GPIO3)。我还有另一个传感器连接到 I2C 引脚,但我现在不使用它。我用作 bmp388 传感器库的代码是从以下网站复制的:https://github.com/DFRobot/DFRobot_BMP388。
来自github的代码:
#name=bmp388library.py
import time
import datetime
import sys
import smbus
import spidev
import RPi.GPIO as GPIO
from math import pow
class DFRobot_BMP388:
def __init__(self):
self.op_mode = 0
self.par_t1 = 0
self.par_t2 = 0
self.par_t3 = 0
self.par_p1 = 0
self.par_p2 = 0
self.par_p3 = 0
self.par_p4 = 0
self.par_p5 = 0
self.par_p6 = 0
self.par_p7 = 0
self.par_p8 = 0
self.par_p9 = 0
self.par_p10 = 0
self.par_p11 = 0
chip_id = self.bmp3_get_regs(0x00,1)[0]
if (chip_id != 0x50):
print("chip id error!")
sys.exit()
return
self.get_calib_data()
self.set_config()
def get_calib_data(self):
calib = self.bmp3_get_regs(0x31,21)
self.parse_calib_data(calib)
def uint8_int(self,num):
if(num>127):
num = num - 256
return num
def parse_calib_data(self,calib):
temp_var = 0.00390625
self.par_t1 = ((calib[1]<<8)|calib[0])/temp_var
temp_var = 1073741824.0
self.par_t2 = ((calib[3]<<8)|calib[2])/temp_var
temp_var = 281474976710656.0
calibTemp = self.uint8_int(calib[4])
self.par_t3 = (calibTemp)/temp_var
temp_var = 1048576.0
calibTempA = self.uint8_int(calib[6])
calibTempB = self.uint8_int(calib[5])
self.par_p1 = ((calibTempA|calibTempB)-16384)/temp_var
#print((calibTempA<<8)|calibTempB)
temp_var = 536870912.0
calibTempA = self.uint8_int(calib[8])
calibTempB = self.uint8_int(calib[7])
self.par_p2 = (((calibTempA<<8)|calibTempB)-16384)/temp_var
#print((calibTempA<<8)|calibTempB)
temp_var = 4294967296.0
calibTemp = self.uint8_int(calib[9])
self.par_p3 = calibTemp/temp_var
#print(calibTemp)
temp_var = 137438953472.0
calibTemp = self.uint8_int(calib[10])
self.par_p4 = calibTemp/temp_var
#print(calibTemp)
temp_var = 0.125
self.par_p5 = ((calib[12]<<8)|calib[11])/temp_var
#print((calib[12]<<8)|calib[11])
temp_var = 64.0
self.par_p6 = ((calib[14]<<8)|calib[13])/temp_var
#print((calib[14]<<8)|calib[13])
temp_var = 256.0
calibTemp = self.uint8_int(calib[15])
self.par_p7 = calibTemp/temp_var
#print(calibTemp)
temp_var = 32768.0
calibTemp = self.uint8_int(calib[16])
self.par_p8 = calibTemp/temp_var
#print(calibTemp)
temp_var = 281474976710656.0
self.par_p9 = ((calib[18]<<8)|calib[17])/temp_var
#print((calib[18]<<8)|calib[17])
temp_var = 281474976710656.0
calibTemp = self.uint8_int(calib[19])
self.par_p10 = (calibTemp)/temp_var
#print(calibTemp)
temp_var = 36893488147419103232.0
calibTemp = self.uint8_int(calib[20])
self.par_p11 = (calibTemp)/temp_var
#print(calibTemp)
def set_config(self):
settings_sel = 2|4|16|32|128
self.bmp3_set_sensor_settings(settings_sel)
self.op_mode = 0x03
self.write_power_mode()
def bmp3_set_sensor_settings(self,settings_sel):
#set_pwr_ctrl_settings
reg_data = self.bmp3_get_regs(0x1b,1)[0]
if(settings_sel & 2):
reg_data = (reg_data&~(0x01))|(0x01&0x01)
if(settings_sel & 4):
reg_data = (reg_data&~(0x02))|((0x01<<0x01)&0x02)
#data = bytearray(1)
data = [reg_data]
#print(data)
#print(data[0])
self.bmp3_set_regs(0x1b,data)
def write_power_mode(self):
op_mode_reg_val = self.bmp3_get_regs(0x1b,1)[0]
op_mode_reg_val = (op_mode_reg_val&~(0x30))|((self.op_mode<<0x04)&0x30)
#data = bytearray(1)
#data[0] = op_mode_reg_val
data = [op_mode_reg_val]
self.bmp3_set_regs(0x1b,data)
def readTemperature(self):
return round(self.bmp3_get_sensor_data(2),2)
def readPressure(self):
return round(self.bmp3_get_sensor_data(1),2)
def bmp3_get_sensor_data(self,sensor_comp):
rslt = self.bmp3_get_regs(0x04,6)
#parse_sensor_data
xlsb = rslt[0]
lsb = rslt[1] << 8
msb = rslt[2] << 16
uncomp_pressure = msb|lsb|xlsb
xlsb = rslt[3]
lsb = rslt[4] << 8
msb = rslt[5] << 16
uncomp_temperature = msb|lsb|xlsb
#print(uncomp_temperature)
value = self.compensate_data(sensor_comp,uncomp_pressure,uncomp_temperature)
return value
def compensate_data(self,sensor_comp,uncomp_temperature):
if(sensor_comp & 0x03):
value = self.compensate_temperature(uncomp_temperature)
if(sensor_comp & 0x01):
value = self.compensate_pressure(uncomp_pressure,value)
return value
def compensate_temperature(self,uncomp_temperature):
uncomp_temp = uncomp_temperature
partial_data1 = (uncomp_temp - self.par_t1)
partial_data2 = (partial_data1 * self.par_t2)
comp_temp = partial_data2 + (partial_data1 * partial_data1)*self.par_t3
return comp_temp
def compensate_pressure(self,t_lin):
partial_data1 = self.par_p6 * t_lin
partial_data2 = self.par_p7 * pow(t_lin,2)
partial_data3 = self.par_p8 * pow(t_lin,3)
partial_out1 = self.par_p5 + partial_data1 + partial_data2 + partial_data3
#print(partial_data1,partial_data2,partial_data3)
#print(partial_out1)
partial_data1 = self.par_p2 * t_lin
partial_data2 = self.par_p3 * pow(t_lin,2)
partial_data3 = self.par_p4 * pow(t_lin,3)
partial_out2 = uncomp_pressure *(self.par_p1-0.000145 + partial_data1 + partial_data2 + partial_data3)
#print(partial_out2)
partial_data1 = pow(uncomp_pressure,2)
partial_data2 = self.par_p9 + self.par_p10 * t_lin
partial_data3 = partial_data1 * partial_data2
partial_data4 = partial_data3 + pow(uncomp_pressure,3) * self.par_p11
#print(partial_data4)
comp_press = partial_out1 + partial_out2 + partial_data4
#print(comp_press)
#print(t_lin)
return comp_press;
def readCalibratedAltitude(self,seaLevel):
pressure = self.readPressure()
return round((1.0 - pow(pressure / seaLevel,0.190284)) * 287.15 / 0.0065,2)
def readSeaLevel(self,altitude):
pressure = self.readPressure()
return round(pressure / pow(1.0 - (altitude / 44330.0),5.255),2)
def readAltitude(self):
pressure = self.readPressure()
return round((1.0 - pow(pressure / 101325,2)
def INTEnable(self):
reg_data = [0x40]
reg_addr = 0x19
self.bmp3_set_regs(reg_addr,reg_data)
def INTdisable(self):
reg_data = [0x00]
reg_addr = 0x19
self.bmp3_set_regs(reg_addr,reg_data)
class DFRobot_BMP388_SPI(DFRobot_BMP388):
def __init__(self,cs):
self.spi = spidev.SpiDev(0,0)
self.cs = cs
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
GPIO.setup(self.cs,GPIO.OUT,initial=1)
super(DFRobot_BMP388_SPI,self).__init__()
def bmp3_get_regs(self,reg,len):
regAddr = [reg|0x80]
GPIO.output(self.cs,0)
self.spi.xfer(regAddr)
rslt = self.spi.readbytes(len+1)
GPIO.output(self.cs,1)
data = bytearray(len)
for i in range(0,len):
data[i] = rslt[i+1]
return data
def bmp3_set_regs(self,data):
value = []
for i in range(0,len(data)):
value.append(data[i])
regAddr = [reg&0x7f]
GPIO.output(self.cs,0)
self.spi.xfer(regAddr)
self.spi.xfer(value)
GPIO.output(self.cs,1)
class DFRobot_BMP388_I2C(DFRobot_BMP388):
def __init__(self,addr):
self._addr = addr
self.i2c = smbus.SMBus(1)
super(DFRobot_BMP388_I2C,len):
rslt = self.i2c.read_i2c_block_data(self._addr,len)
return rslt
def bmp3_set_regs(self,data):
self.i2c.write_i2c_block_data(self._addr,data)
为了编写另一个导入库并打印温度的代码,我需要知道传感器地址,因此,在终端中,我输入了sudo i2cdetect -y 1,得到两个地址,bmp388 为 29,另一个传感器为 68。
打印温度的代码是:
#name=bmp388_temp.py
import bmp388library
import time
bmp388 = bmp388library.DFRobot_BMP388_I2C(0x29)
while 1:
temp = bmp388.readTemperature()
print(temp)
time.sleep(1)
当我运行此代码时,我收到一条消息,指出 chip id error!,我认为这与库代码中的第 31 行有关:print("chip id error! ")。
我尝试将地址更改为 0x77 并出现不同的错误:
Traceback (most recent call last):
File "/home/pi/Desktop/bmp388_temp.py",line 5,in <module>
bmp388 = bmp388library.DFRobot_BMP388_I2C(0x77)
File "/home/pi/Desktop/bmp388library.py",line 248,in __init__
super(DFRobot_BMP388_I2C,self).__init__()
File "/home/pi/Desktop/bmp388library.py",line 26,in __init__
chip_id = self.bmp3_get_regs(0x00,1)[0]
File "/home/pi/Desktop/bmp388library.py",line 251,in bmp3_get_regs
rslt = self.i2c.read_i2c_block_data(self._addr,len)
OSError: [Errno 121] Remote I/O error
chip_id = self.bmp3_get_regs(0x00,1)[0]
if (chip_id != 0x50):
print("chip id error!")
sys.exit()
return
有谁知道导致这种情况的问题可能是什么?如果有,请回复。
谢谢,
阿方索
解决方法
芯片 ID 不是 i2c 地址。根据他们提供的示例,i2c 地址只能是 0x76
或 0x77
,具体取决于 sdo
引脚状态。
如果这些都不起作用,您需要验证您的连接
# 3.3v(1) VCC
# GND(6) GND
# SCL(5) SCL
# SDA(3) SDA
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。