I have bought a GY-86 sensor. it is comprised of an accelerometer/gyroscope (Mpu6050) a magnetometer(HMC5883L) and a barometer(MS5611-01BA01). all these sensors have I2C interface.
I am reading the temperature and pressure from the barometer. the device appears to work fine. It responds to commands accordingly(I can write and read from sensor as described in datasheet). but the problem is that I keep reading a constant value(temp=20.0005625). temperature and pressure do not change. while in fact the the value should be jumping up and down!!!
also regardless of what resolution I use for conversion(256 or 1024 or 4096 bit ADC conversion), I get the same value.
could you please help me? I have raspbian OS. to test the sensor I have written a code in python. I also used i2cset and i2cget commands and got the same result
edited:
I found the problem. I have enclosed my code below. this code is modified. I am coding in python and I use smbus library.
in the previous code I used to call write_byte() function to send a command to sensor and then call read_byte() function to get the response. But the sensor returns more than one byte.
if I call write_byte() to tell the sensor to start the conversion and then call read_byte() 2 times, I get IO Exception the second time. in that case I can read only one byte.
in cases that the sensor returns 2 bytes I can use read_word_data(addr,cmd).
but in some cases the sensor returns 3 bytes. for that used read_block_data(addr,cmd) which returns returns long[]. but when I call this function the program halts and the raspberry does not respond any more.I have to reboot raspberry.
for reading more that 2 bytes there is another function in smbus library. when I call read_i2c_block_data(addr,cmd) it returns an array of size 32. while the sensor is supposed to return only 3 bytes.
example output of read_i2c_block_data: [127,80,66,63,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255]
how should I exactly read 3 bytes from i2c interface?
read start_conversion and get_conversion methods
#!/usr/bin/python
import smbus
import time
import sys
class MS5611:
ms5611_addr= 0x77
ms5611_d1= 0x40
ms5611_d2= 0x50
ms5611_reset=0x1e
ms5611_adc_read=0
ms5611_osr_256= 0x00
ms5611_osr_512= 0x02
ms5611_osr_1024= 0x04
ms5611_osr_2048= 0x06
ms5611_osr_4096= 0x08
ms5611_prom_base_addr= 0xa2
ms5611_prom_reg_count= 6
ms5611_prom_reg_size= 2
conversion_time= .1 #time in seconds
extra_precision=5
channel=1;
prom=[]
def __init__(self,addr):
self.lastTempConv =0
self.lastPresConv =0
self.presCache=-1
self.tempCache=-1
self.ms5611_addr=addr
self.bus=smbus.SMBus(self.channel)
self.reset()
self.readPROM()
print(self.prom)
def reset(self):
self.bus.write_byte(self.ms5611_addr,self.ms5611_reset)
time.sleep(0.01)
def readPROM(self):
for i in range(self.ms5611_prom_reg_count):
temp=self.ms5611_prom_base_addr + (i *self.ms5611_prom_reg_size)
t1=self.bus.read_word_data(self.ms5611_addr,temp)
# self.bus.write_byte(self.ms5611_addr,temp)
# time.sleep(0.01)
# t1= self.bus.read_byte(self.ms5611_addr)
# time.sleep(0.01)
self.prom.append(t1)
def getConversion(self):
# self.bus.write_byte(self.ms5611_addr,self.ms5611_adc_read)
# t1= self.bus.read_byte(self.ms5611_addr)
t1= self.bus.read_i2c_block_data(self.ms5611_addr, self.ms5611_adc_read)
print("inside getconversion: " + str(t1))
return t1
def startConversion(self,command):
self.bus.write_byte(self.ms5611_addr,command)
def readBlock(self,command):
return self.bus.read_i2c_block_data(self.ms5611_addr,command)
def rawTemperature(self,osr):
now = time.time()
if self.lastTempConv !=0 and (now - self.lastTempConv) >= self.conversion_time:
self.lastTempConv=0
return self.getConversion()
else:
if self.lastTempConv ==0 and self.lastPresConv==0:
self.startConversion(self.ms5611_d2 + osr)
self.lastTempConv = now
elif self.lastPresConv!=0 :
return self.tempCache
else:
return None
def rawPressure(self,osr):
now = time.time()
if self.lastPresConv !=0 and (now - self.lastPresConv) >= self.conversion_time:
self.lastPresConv=0
return self.getConversion()
else:
if self.lastPresConv ==0 and self.lastTempConv==0:
self.startConversion(self.ms5611_d1 + osr)
self.lastPresConv = now
return None
def getDeltaTemp(self,osr):
rawTemp = self.rawTemperature(osr)
if rawTemp != None:
return rawTemp - (self.prom[4]<<8)
else:
return None
def getTemperature(self,osr):
dt=self.getDeltaTemp(osr)
print("inside getTemperatue.dt: "+str(dt))
if dt!= None:
return((1<<self.extra_precision)*20001 + ( (dt * self.prom[5]) >> (23-self.extra_precision) ) ) /((1<<self.extra_precision) * 100.0)
else:
return None
def getPressure(self,osr):
rawPress = self.rawPressure(osr)
dt = self.getDeltaTemp(osr)
if(dt==None or rawPress==None):
return None
off= (self.prom[1] <<16) + ((self.prom[3] * dt) >> 7)
sens= (self.prom[0] <<15) + ((self.prom[2] * dt) >>8)
return ((((rawPress * sens) >> 21) -off) >> (15-self.extra_precision)) / ((1<<self.extra_precision) * 100)