简体   繁体   中英

Why can't I print the temperature using a BMP388 sensor with Raspberry Pi?

I have a Raspberry Pi Zero and I am using it for a project in witch I have to measure the temperature. The sensor that I am using is a BMP388 and it is connected to the I2C pins (GPIO2 and GPIO3). I also have another sensor connected to the I2C pins, but I am not using it for now. The code that I used as a library for the bmp388 sensor was copied from this website: https://github.com/DFRobot/DFRobot_BMP388 .

Code from 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_pressure,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,uncomp_pressure,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, 0.190284)) * 287.15 / 0.0065,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,reg,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,self).__init__()

  def bmp3_get_regs(self,reg,len):
    rslt = self.i2c.read_i2c_block_data(self._addr,reg,len)
    return rslt

  def bmp3_set_regs(self,reg,data):
    self.i2c.write_i2c_block_data(self._addr,reg,data)

In order to write another code that imports the library and prints the temperature, I needed to know the sensor address, so, in the terminal, I typed sudo i2cdetect -y 1 , and got two addresses, the bmp388 at 29 , and the other sensor at 68.

The code to print the temperature is:

#name=bmp388_temp.py

import bmp388library
import time

bmp388 = bmp388library.DFRobot_BMP388_I2C(0x29)

while 1:
  temp = bmp388.readTemperature()
  print(temp)
  time.sleep(1)

When I run this code I get a message that says chip id error! , that I think has to do with line 31 from the library code : print("chip id error!") .

I tried changing the address to 0x77 and appears a different error:

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,reg,len)
OSError: [Errno 121] Remote I/O error

I also tried leaving the address as 0x29 and deleting from the library code the following lines:

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

Now, I don't get any error but the temperature displayed is always 0.0

Does anybody know what might be the problem that is causing this? If so, please reply.

Thank you,

Afonso

The chip id is not the i2c address. According to the example they provide, the i2c address can only be 0x76 or 0x77 depending upon sdo pin state.

If neither of those work, you need to verify your connections

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM