微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

为什么我不能使用带有 Raspberry Pi 的 BMP388 传感器打印温度?

如何解决为什么我不能使用带有 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

我还尝试将地址保留为 0x29 并从库代码删除以下行:

chip_id = self.bmp3_get_regs(0x00,1)[0]
    if (chip_id != 0x50):
      print("chip id error!")
      sys.exit()
      return

现在,我没有收到任何错误,但显示的温度始终为 0.0

有谁知道导致这种情况的问题可能是什么?如果有,请回复

谢谢,

阿方索

解决方法

芯片 ID 不是 i2c 地址。根据他们提供的示例,i2c 地址只能是 0x760x77,具体取决于 sdo 引脚状态。

如果这些都不起作用,您需要验证您的连接

#   3.3v(1)         VCC
#   GND(6)          GND
#   SCL(5)          SCL
#   SDA(3)          SDA

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。