sd_read
Posts: 13
Joined: Sat Dec 01, 2012 12:06 am

Adding a second but different I2C device to the BMP085

Sat Jan 12, 2013 5:44 pm

Hello,

I have successfully attached a BMP085 board to a Raspberry Pi and am logging pressure and temperature to cosm.com. This was fairly easy as I simply followed the instructions.

Then, I added a second I2C device a Honeywell HIH6131 which is a humidity and temperature sensor.
Image

Finally, I wrote code (well maybe hacked is a better description) but it is not working correctly and would like some help.

First let me explain the HIH6131 which resides at the I2C address of 0x27. From the data sheet it does not have registers rather you simply read and write values. So the only write command is a "measurement request" command which causes the device to initiate a measurement. The command is shown in figure 1.

From the data sheet it is "a Measurement Request command consists of the Slave address plus the WRITE bit (0). Once the sensor responds with an acknowledge (ACK), the Master generates a stop condition."

Image
Figure 1

Next I can either read two bytes for a humidity reading or four bytes for a humidity and temperature reading. For this question I will focus on a two byte humidity reading which is shown in figure 2.

Image
Figure 2

From the data sheet "the Master generates a START condition and sends the sensor Slave address followed by a read bit (shown in Figure 2). After the sensor generates an acknowledge (ACK), it will transmit up to four bytes of data – the first two bytes containing the compensated temperature output and the second two bytes containing the optional compensated temperature output.


Now my testing. I am able to confirm that both devices are present as a sudo i2cdetect -y 0 command reveals both the BMP085 at 0x77 and the HIH6131 at 0x27.

Second, I am convinced the wiring of my new HIH6131 device is working because if I remove the clock wire to the HIH6131 I get "Error accessing 0x27: Check your I2C address" which of course is the correct device.

The problem is that I read back the same byte every time. So a two byte read is two bytes of the same value and a four byte read is four. However, they will change in value if I breath hot air on the sensor".

So, I think that tells me that I am issuing the measurement request since the byte is changing and therefore my problem is in reading the data back.

Now I will describe the part of my code where it goes wrong.

The first thing I did is added two commands to Adafruit_I2C.py:

Code: Select all

  def write0(self):
    "Puts only device address on bus with write bit set"
    try:
      self.bus.write_quick(self.address)
      if (self.debug):
        print("I2C: Cannot access device")
    except IOError, err:
      print "Error accessing 0x%02X: Check your I2C address" % self.address
      return -1

  def read0(self):
    "reads I2C bus"
    try:
      result = self.bus.read_byte(self.address)
      if (self.debug):
        print "I2C: Device 0x%02X error" % self.address
      return result
    except IOError, err:
      print "Error accessing 0x%02X: Check your I2C address" % self.address
      return -1
I choose self.bus.write_quick(self.address) and self.bus.read_byte(self.address) as the best selection that I found from here:
http://wiki.erazor-zone.de/wiki:linux:python:smbus:doc

Then I created a new file called Adafruit_HIH6131.py and used the same format as Adafruit_BMP085.py.

I will focus on the two byte humidity read command:

Code: Select all

  def readRawHumidity(self): # byte 1 = humidity msb, byte 2 = humidity lsb
    "Reads the raw (uncompensated) humidity from the sensor"
    self.i2c.write0()
    time.sleep(0.500)    # allow time for the conversion
    msb = self.i2c.read0()
    lsb = self.i2c.read0()
    raw = (msb << 8) + lsb
    return raw
As I suggested I believe the self.i2c.write0() is working however the two self.i2c.read0() are not as they both return the same value.

Can anyone help me?

Thank you.

sd_read
Posts: 13
Joined: Sat Dec 01, 2012 12:06 am

Re: Adding a second but different I2C device to the BMP085

Sun Jan 13, 2013 2:37 pm

I think I am confusing the I2C protocol with the SPI protocol which I more commonly work with.

What I need is an equivalent to "read_word_data(addr,cmd)" but does not use the addr or cmd arguments.

So, using the format of figure 2 in my original post a "read_word_data(addr,cmd)" would look like this:

(slave address + Read Bit) (addr) (cmd) (Data Byte 1) (Data Byte 2)

What I really need is a command which does this:

(slave address + Read Bit) (Data Byte 1) (Data Byte 2)

sd_read
Posts: 13
Joined: Sat Dec 01, 2012 12:06 am

Calls to Smbus

Mon Jan 14, 2013 2:13 pm

I am confused why no one can help me?

I think all I am looking for is the correct function call?

Refering to Adafruit_I2C.py I need a call similar to "self.bus.read_byte_data(self.address, reg)" only it doesn't require or use the address or register data.

And I think these calls come from "import smbus".

techpaul
Posts: 1512
Joined: Sat Jul 14, 2012 6:40 pm
Location: Reading, UK
Contact: Website

Re: Adding a second but different I2C device to the BMP085

Mon Jan 14, 2013 2:32 pm

Personally I look at forums occassionally and have a lot of paying work to do, things that take longer to look at might get read by me and others, when they can.

Cannot comment on others that is just my status. Yes this is I2C which I could comment yours needs some time to read and digest. If I get time I will do not today.
Just another techie on the net - For GPIO boards see http:///www.facebook.com/pcservicesreading
or http://www.pcserviceselectronics.co.uk/pi/

gragib
Posts: 99
Joined: Sat Dec 22, 2012 8:09 pm
Location: Calgary, AB, Canada

Re: Adding a second but different I2C device to the BMP085

Tue Jan 15, 2013 8:31 am

I don't have an HIH-6130/6131 to test, but I think the problem lies here:

Code: Select all

result = self.bus.read_byte(self.address)
and

Code: Select all

msb = self.i2c.read0()
lsb = self.i2c.read0()
I think you reading just one byte at a time, and you are reading the same byte twice. The other bytes aren't captured because you've moved onto the next line of code. I say that because I'm reading some Arduino example code and it looks like this:

Code: Select all

Wire.requestFrom((int)address, (int) 4);
Hum_H = Wire.receive();
Hum_L = Wire.receive();
Temp_H = Wire.receive();
Temp_L = Wire.receive();
Wire.endTransmission();
Wire.requestFrom asks for 4 bytes (2 for humidity and 2 for temperature), and they come in a stream. Your code is reading just the first byte before moving on to the next line of code.

Try replacing the first bit with this:

Code: Select all

h_msb = self.bus.read_byte(self.address)
h_lsb = self.bus.read_byte(self.address)
result = (h_msb << 8) + h_lsb
I have no idea if it'll actually work.

Also, take a look at Quick2Wire's Python library. Folks on Twitter have had success using it with the HIH-6130

sd_read
Posts: 13
Joined: Sat Dec 01, 2012 12:06 am

Re: Adding a second but different I2C device to the BMP085

Tue Jan 15, 2013 6:34 pm

Thank you for your help graglib.

I am at work where I was able to connect an I2C monitor and I have confirmed what I suspect is happening. Now the challenge is to explain it.

The problem is that this part does not have any registers. You simply read and write to it.

Looking at the I2C monitor your code shown:

Code: Select all

h_msb = self.bus.read_byte(self.address)
h_lsb = self.bus.read_byte(self.address)
result = (h_msb << 8) + h_lsb
results in this:
<address:r> <msb byte>
<address:r> <lsb byte>

What I really need is:
<address:r> <msb byte> <lsb byte>

or a command like:

Code: Select all

humidity = self.bus.read_word(self.address)
Which would fetch two bytes in sequence.


I hope this is clear?

gragib
Posts: 99
Joined: Sat Dec 22, 2012 8:09 pm
Location: Calgary, AB, Canada

Re: Adding a second but different I2C device to the BMP085

Tue Jan 15, 2013 6:50 pm

I understand what's happening. self.bus.read_byte(self.address) apparently can only read 1 byte at a time, so you never get bytes 2-4.

Like I mentioned before, why don't you try using the Quick2Wire library?

sd_read
Posts: 13
Joined: Sat Dec 01, 2012 12:06 am

Re: Adding a second but different I2C device to the BMP085

Tue Jan 15, 2013 7:51 pm

I will try that tonight.

After reading your previous post I have been looking at it (when the boss isn't around) and I don't unserstand how to use it? I tried searching for documenation which defines the available commands but couldn't find anything.

For example I see commands like this:
i2c.reading(address, 1))[0][0]
I don't know what this means or what other calls or functions are available.

I have a hard time understanding these higher level languages as my experience is limited to C and assembler.

techpaul
Posts: 1512
Joined: Sat Jul 14, 2012 6:40 pm
Location: Reading, UK
Contact: Website

Re: Adding a second but different I2C device to the BMP085

Tue Jan 15, 2013 7:52 pm

Do you have a link to the datasheet?

To do the 'Measurement Request' in python smbus you write_quick(addr) to just address the device and stop.

How much time is needed between a measurement request and reading out the values?

What will the device do if you write a byte, then immediately Read data?

However whenver you perform almost any other function with python smbus it will
  • For Write - address the device, write a byte (cmd), then any write data if relevant
  • For Read - address the device, write a byte (cmd), then address the device, then any READ data
Noting in python smbus
  • Number of bytes is determined by function (byte,word) or size of array
  • for word read or write it is LS byte first
As long as HIH-6130/6131 can handle the way python smbus works, this can be used to read the registers (yes it does have registers not ones you normally address).

A useful reference for how python smbus works from function to I2C activity is on this site http://git.kernel.org/?p=linux/kernel/g ... s-protocol
Just another techie on the net - For GPIO boards see http:///www.facebook.com/pcservicesreading
or http://www.pcserviceselectronics.co.uk/pi/

techpaul
Posts: 1512
Joined: Sat Jul 14, 2012 6:40 pm
Location: Reading, UK
Contact: Website

Re: Adding a second but different I2C device to the BMP085

Tue Jan 15, 2013 7:58 pm

Also seen for a 2 byte read in python smbus you must use read_word_data(addr,cmd)

For 4 byte read
  • Define an array as 4 elements long
  • Use read_i2c_block_data(addr,cmd) put results into array e.g. results = read_i2c_block_data(addr,cmd)
Just another techie on the net - For GPIO boards see http:///www.facebook.com/pcservicesreading
or http://www.pcserviceselectronics.co.uk/pi/

gragib
Posts: 99
Joined: Sat Dec 22, 2012 8:09 pm
Location: Calgary, AB, Canada

Re: Adding a second but different I2C device to the BMP085

Tue Jan 15, 2013 8:15 pm

Also take a look at these Python libraries: RPi.GPIO and rpiSht1x. The methods for getting readings from the SHT-1x and HIH-613x are very similar, but some modifications may be required.

Just looking at the code, one thing that stood out is

Code: Select all

self.__getData16Bit()
That may be the key to solving your problem.

sd_read
Posts: 13
Joined: Sat Dec 01, 2012 12:06 am

Re: Adding a second but different I2C device to the BMP085

Tue Jan 15, 2013 10:09 pm

Here is a link to the data sheet:
http://www.phanderson.com/arduino/I2CCommunications.pdf

Looking at what you posted above there is a command that is almost what I want:
SMBus Receive Byte: i2c_smbus_read_byte()
==========================================

This reads a single byte from a device, without specifying a device
register. Some devices are so simple that this interface is enough; for
others, it is a shorthand if you want to read the same register as in
the previous SMBus command.

S Addr Rd [A] [Data] NA P

Functionality flag: I2C_FUNC_SMBUS_READ_BYTE
This is what I need but I need it to read two bytes sequentially.

At present I am using massive time delay between initiating a conversion and reading the results.

So techpaul where you said:
For Read - address the device, write a byte (cmd), then address the device, then any READ data
I don't think this will work as there are no registers in this device.

Similarly:
read_word_data(addr,cmd)
for the same reason.

The command:

Code: Select all

self.__getData16Bit()
looks like it might work but I have no idea how to use it.

I have formated a fresh sd card and will try quick2wire but I still welcome any other help.

techpaul
Posts: 1512
Joined: Sat Jul 14, 2012 6:40 pm
Location: Reading, UK
Contact: Website

Re: Adding a second but different I2C device to the BMP085

Wed Jan 16, 2013 12:03 am

sd_read wrote:Here is a link to the data sheet:
http://www.phanderson.com/arduino/I2CCommunications.pdf

Looking at what you posted above there is a command that is almost what I want:
SMBus Receive Byte: i2c_smbus_read_byte()
==========================================

This reads a single byte from a device, without specifying a device
register. Some devices are so simple that this interface is enough; for
others, it is a shorthand if you want to read the same register as in
the previous SMBus command.

S Addr Rd [A] [Data] NA P

Functionality flag: I2C_FUNC_SMBUS_READ_BYTE
This is what I need but I need it to read two bytes sequentially.
No you need I2C function for word or 4 bytes.
At present I am using massive time delay between initiating a conversion and reading the results.
according to datasheet about 37ms delay is needed.
So techpaul where you said:
For Read - address the device, write a byte (cmd), then address the device, then any READ data
I don't think this will work as there are no registers in this device.
Actually it does on most devices that dont have 'registers' as you put it. What is important is how the device responds, lots of devices like PCF8575 if given a byte of 0 and not a full 16 bit write data ignore the byte, then will work on the 16 bit read. Looking at datasheet yours might not.

NOT because it does 'not have registers', but because a write of any sort initiates a measurement cycle. However if you were to actually try it you might find that doing a quick access, delay 37ms at least, then doing the read_word will read last result and start a new conversion..

What have you to lose by trying it?
Similarly:
read_word_data(addr,cmd)
for the same reason.
For same reason why not try it anyway?
It would take a few minutes to code and try, wont hurt to try it.
Just another techie on the net - For GPIO boards see http:///www.facebook.com/pcservicesreading
or http://www.pcserviceselectronics.co.uk/pi/

sd_read
Posts: 13
Joined: Sat Dec 01, 2012 12:06 am

Re: Adding a second but different I2C device to the BMP085

Wed Jan 16, 2013 1:01 am

I have been using a delay of 500ms. I wanted to ensure that it would not interfere with my coding.

You are suggesting that I use:

Code: Select all

read_word_data(addr,cmd) 
But, I am a real dummy with this stuff so I am not sure how I should use this.

I am not sure what addr and cmd values I should use?

So I am trying this:
result = self.bus.read_word_data(0x27,0)
which works without errors but still does not produce valid results but I will take it to work tomorrow to connect to the I2C monitor.

techpaul
Posts: 1512
Joined: Sat Jul 14, 2012 6:40 pm
Location: Reading, UK
Contact: Website

Re: Adding a second but different I2C device to the BMP085

Wed Jan 16, 2013 2:03 am

sd_read wrote:I have been using a delay of 500ms. I wanted to ensure that it would not interfere with my coding.

You are suggesting that I use:

Code: Select all

read_word_data(addr,cmd) 
But, I am a real dummy with this stuff so I am not sure how I should use this.

I am not sure what addr and cmd values I should use?
addr = i2c address (7 bit)

cmd in this case can be anything as hopefully the device will ignore it.
So I am trying this:

Code: Select all

result = self.bus.read_word_data(0x27,0)
which works without errors but still does not produce valid results but I will take it to work tomorrow to connect to the I2C monitor.
Make sure your first access is using the quick method to ensure you do start a measurement to read later, I suggest you drop delay to 50ms, then do a read_word.

Remember read_word assumes first byte on I2C is Low byte, so you may just need to swap bytes to get correct value.If I remember the device outputs High byte first. Dont forget you status bits in there as well. Be interesting to know what the status bits are.

If this method does not work then try the array of 4 values and read 4 bytes, then get the bytes into words From a 4 byte array called val, assumes byte order on I2C is HIGH humidity, LOW humidity, HIGH temp, LOW temp

Code: Select all

val = {0,0,0,0]

#do quick access and delay

val = self.bus.read_i2c_block_data( 0x27, 0 )
staus = (val[0] & 0xC0) / 64
humidity =  ( (val[0] & 0x3F) * 256) + val[1]
temp =  (val[2] * 64) + (val[3] /4 )

# then do the calculations to convert to correct units from A/D values
You should be able to do a reverse calculation to see what you expected temperature reading should be for room temperature between 15 and 25 degrees C and see what A/D values you get to check your calculations are right.
Just another techie on the net - For GPIO boards see http:///www.facebook.com/pcservicesreading
or http://www.pcserviceselectronics.co.uk/pi/

sd_read
Posts: 13
Joined: Sat Dec 01, 2012 12:06 am

Re: Adding a second but different I2C device to the BMP085

Wed Jan 16, 2013 6:38 pm

Today is busy at work so I have been limited in time.

But I changed the delay to 50ms and put in the following code:

Code: Select all

 def readDeviceData(self): 
    self.i2c.write0()
    time.sleep(0.050)    # allow time for the conversion
    val = [0,0,0,0]
    self.i2c.read_i2c_block_data( 0X27, 0, 0 )
    status = (val[0] & 0xC) / 64
    humidity = ( (val[0] & 0x3f) * 256) + val[1]
    temp = (val[2]  * 64) + (val[3] / 4 )
    return temp
But it produces the following error:

Code: Select all

AttributeError: Adafruit_I2C instance has no attribute 'read_i2c_block_data'
Not sure what this error means?

techpaul
Posts: 1512
Joined: Sat Jul 14, 2012 6:40 pm
Location: Reading, UK
Contact: Website

Re: Adding a second but different I2C device to the BMP085

Wed Jan 16, 2013 7:55 pm

sd_read wrote:Today is busy at work so I have been limited in time.

But I changed the delay to 50ms and put in the following code:

Code: Select all

 def readDeviceData(self): 
    self.i2c.write0()
    time.sleep(0.050)    # allow time for the conversion
    val = [0,0,0,0]
    self..2c.read_i2c_block_data( 0X27, 0, 0 )
    status = (val[0] & 0xC) / 64
    humidity = ( (val[0] & 0x3f) * 256) + val[1]
    temp = (val[2]  * 64) + (val[3] / 4 )
    return temp
But it produces the following error:

Code: Select all

AttributeError: Adafruit_I2C instance has no attribute 'read_i2c_block_data'
Not sure what this error means?
Means it could not find the function in the Adafruit i2C library, I was refering to python-smbus functions which you referred to in your first post..

Firstly the whole code would be helpful to see if you have the correct imports and assignments before the functions.

Secondly once you import the python-smbus correctly try to copy correctly suggestions you have a few mistakes not copied correctly.

Code: Select all

 def readDeviceData(self): 
   # this call only needed once at very first start and the delay should be in higher level
    self.i2c.write0()
    time.sleep(0.050)    # allow time for the conversion
    # normally would expect an array defined at higher level
    val = [0,0,0,0]
    # tell python which array to store results into and give correct number of parameters
    val = self.bus.i2c.read_i2c_block_data( 0X27, 0 )
    status = (val[0] & 0xC) / 64
    humidity = ( (val[0] & 0x3f) * 256) + val[1]
    temp = (val[2]  * 64) + (val[3] / 4 )
    #if val defined as file scope then can be accessed easier or array returned
    val[0] = status
    val[1] = humidity
    val[2] = temp
    return temp
Just another techie on the net - For GPIO boards see http:///www.facebook.com/pcservicesreading
or http://www.pcserviceselectronics.co.uk/pi/

sd_read
Posts: 13
Joined: Sat Dec 01, 2012 12:06 am

Re: Adding a second but different I2C device to the BMP085

Thu Jan 17, 2013 1:59 pm

I finally have it running but I first want to thank you techpaul for your help. I appreciate your help and persistance in helping me.

Your last post suggested seeing the code and I did not want to post it as it involve 3 separate files so I decided to re-write it in one module. You see I was trying to follow the format of the existing Adafruit code for the BMP085.

Any way, after an evening of googling how to do this I realized it eliminated a lot of complexity of dealing with calls to other routines. That eliminated many of the cryptic errors I was getting. So I finally have this single file running and the code is here:

Code: Select all

#!/usr/bin/python

import sys
import time
import datetime
import eeml
import smbus
from smbus import SMBus
b = SMBus(0)    # 0 indicates /dev/i2c-0


def main():
    # this call only needed once at very first start and the delay should be in higher level
    b.write_quick(0x27)
    time.sleep(0.050)    # allow time for the conversion
    # normally would expect an array defined at higher level
    val = [0,0,0,0]
    # tell python which array to store results into and give correct number of parameters
    val = b.read_i2c_block_data( 0X27, 0 )

    X1 = (val[0] << 8) + val[1]
    Y1 = (val[2] << 8) + val[3]
    #print"%02x" % Y1
    Y2 = Y1 >> 2
    #print"%02x" % Y2
    Y3 = Y2 * 165
    #print"%02x" % Y3
    Y4 = Y3 / 16381
    #print"%02x" % Y4
    Y5 = Y4 - 40
    print"%.2f" % Y5

    status = (val[0] & 0xC) / 64
    humidity = ( (val[0] & 0x3f) * 256) + val[1]
    temp = (val[2]  * 64) + (val[3] / 4 )
    #if val defined as file scope then can be accessed easier or array returned
    val[0] = status
    val[1] = humidity
    val[2] = temp
    #print "Status:      %.2f" % status
    #print "Humidity:    %.2f" % humidity
    #print "Temperature: %.2f C" % temp
There are still some things to do but I am getting valid temperature readings. I did add many intermediate steps so I could follow through with my calculator to verify it was making sense.

Here is a screenshot of the I2C monitor tool:
Image
This is a capture of running this program once. I am not sure why it sent the write twice with the second one writing a zero.
But, the read is what I want with no addressing of registers. Now the data sheet says it will provide four bytes after the read request but I seem to be getting away with readin many more. I suspect that is the reason for the NACK which is indicated by the '*' in the I2C Bus Monitor.

Thank you for everyone that helped.


techpaul
Posts: 1512
Joined: Sat Jul 14, 2012 6:40 pm
Location: Reading, UK
Contact: Website

Re: Adding a second but different I2C device to the BMP085

Thu Jan 17, 2013 7:52 pm

sd_read wrote:I finally have it running but I first want to thank you techpaul for your help. I appreciate your help and persistance in helping me.
Not a problem, just help when I can some of these things can be difficult to get your head round in a short time.
Your last post suggested seeing the code and I did not want to post it as it involve 3 separate files so I decided to re-write it in one module. You see I was trying to follow the format of the existing Adafruit code for the BMP085.
Well a smaller working segment of code is easier to debug and easier to then have a working example to incorporate into larger code.
There are still some things to do but I am getting valid temperature readings. I did add many intermediate steps so I could follow through with my calculator to verify it was making sense.
Nothing like getting intermediate results to check things make sense and no other coding errors hiding the real problems.
This is a capture of running this program once. I am not sure why it sent the write twice with the second one writing a zero.
That is because unfortunately the python-smbus module when performing

Code: Select all

    # tell python which array to store results into and give correct number of parameters
    val = b.read_i2c_block_data( 0X27, 0 )
The parameter 0 is what is sent in the write immediately before the read, thnakfully the chip still produces results, more later.
But, the read is what I want with no addressing of registers. Now the data sheet says it will provide four bytes after the read request but I seem to be getting away with readin many more. I suspect that is the reason for the NACK which is indicated by the '*' in the I2C Bus Monitor.
I suspect the extra output is a 'diagnostic' mode of the device from writing '0' before the read, seen this sort of thing before on other devices, even one I am building the 5th ASIC tester for, a mixed signal device aerospace part with its own I2C master built in. If you want peculiar I2C master operation this device has it in spades :-)

I would suggest trying the I2C monitor whilst changing the '0' parameter to other values and see what happens, you may find a magic value which means only four bytes are sent that make sense.
Thank you for everyone that helped.
Well glad you are working.
Just another techie on the net - For GPIO boards see http:///www.facebook.com/pcservicesreading
or http://www.pcserviceselectronics.co.uk/pi/

jbuehl
Posts: 32
Joined: Fri Jun 08, 2012 2:49 pm
Location: Los Angeles

Re: Adding a second but different I2C device to the BMP085

Tue Mar 05, 2013 6:51 pm

This thread was very useful. I have this sort of working, however when I use read_i2c_block_data(), the status that is returned has a value of 1, even if I increase the delay after the write. The device is also sending a lot more than 4 bytes of data. Looking at this document http://www.phanderson.com/arduino/Comma ... ctions.pdf it seems that the device isn't just going to ignore the byte that is written to it and what is being returned is actually the contents of the EEPROM at address 0.

Here's my program:

Code: Select all

import smbus
import time
b = smbus.SMBus(1)
d = []
addr = 0x27
b.write_quick(addr)
time.sleep(0.050)
d = b.read_i2c_block_data(addr, 0)
status = (d[0] & 0xc0) >> 6
humidity = (((d[0] & 0x3f) << 8) + d[1])*100/16383
tempC = ((d[2] << 6) + ((d[3] & 0xfc) >> 2))*165/16383 - 40
tempF = tempC*9/5 + 32
print "Data:       ", "%02x "*len(d)%tuple(d)
print "Status:     ", status
print "Humidity:   ", humidity, "%"
print "Temperature:", tempF, "F"
And here's the output. The humidity and temperature values are plausible, but I know that the temperature is a couple of degrees low.

Code: Select all

# python humidity.py 
Data:        5b d6 58 05 6f 59 60 15 bd 65 80 56 f5 96 01 5b d6 58 05 6f 59 60 15 bd 65 80 56 f5 96 01 5b d6 
Status:      1
Humidity:    43 %
Temperature: 60 F
If I use read_byte() which doesn't send the command, the status is zero, but of course I can only read the first byte.

Code: Select all

import smbus
import time
b = smbus.SMBus(1)
d = []
addr = 0x27
b.write_quick(addr)
time.sleep(0.050)
d = b.read_byte(addr)
status = (d & 0xc0) >> 6
humidity = ((d & 0x3f) << 8)*100/16383
print "Data:       ", "%02x "%d
print "Status:     ", status
print "Humidity:   ", humidity, "%"
And the output:

Code: Select all

python humidity.py 
Data:        1b 
Status:      0
Humidity:    42 %
Last edited by jbuehl on Tue Mar 05, 2013 8:17 pm, edited 1 time in total.

techpaul
Posts: 1512
Joined: Sat Jul 14, 2012 6:40 pm
Location: Reading, UK
Contact: Website

Re: Adding a second but different I2C device to the BMP085

Tue Mar 05, 2013 8:16 pm

I suspect you are continuously reading the device, as you have not specified a size of transfer for python-smbus to read from the device.

If you preassign the array size of d as in

Code: Select all

d = [ 0, 0, 0, 0 ]
Then it will only get 4 bytes.

As you have not assigned a size to the transfer due to unitialised array python-smbus is calling with the default transfer size for SMBUS when no size is defined (by size of variable/array) which is 16 bytes.
Just another techie on the net - For GPIO boards see http:///www.facebook.com/pcservicesreading
or http://www.pcserviceselectronics.co.uk/pi/

jbuehl
Posts: 32
Joined: Fri Jun 08, 2012 2:49 pm
Location: Los Angeles

Re: Adding a second but different I2C device to the BMP085

Tue Mar 05, 2013 8:22 pm

Actually it doesn't work that way. Setting the array size to 4 doesn't prevent it reading a lot of bytes. I originally initialized it to [0,0,0,0] and it was much larger after I did the read. Anyway, that doesn't explain the status of 1.

techpaul
Posts: 1512
Joined: Sat Jul 14, 2012 6:40 pm
Location: Reading, UK
Contact: Website

Re: Adding a second but different I2C device to the BMP085

Tue Mar 05, 2013 8:34 pm

jbuehl wrote:Actually it doesn't work that way. Setting the array size to 4 doesn't prevent it reading a lot of bytes. I originally initialized it to [0,0,0,0] and it was much larger after I did the read. Anyway, that doesn't explain the status of 1.
As in a post way back if you change the 0 in this command

Code: Select all

d = b.read_i2c_block_data(addr, 0)
To other values what happens.

From previous post
techpaul wrote:I would suggest trying the I2C monitor whilst changing the '0' parameter to other values and see what happens, you may find a magic value which means only four bytes are sent that make sense
Just another techie on the net - For GPIO boards see http:///www.facebook.com/pcservicesreading
or http://www.pcserviceselectronics.co.uk/pi/

jbuehl
Posts: 32
Joined: Fri Jun 08, 2012 2:49 pm
Location: Los Angeles

Re: Adding a second but different I2C device to the BMP085

Tue Mar 05, 2013 8:46 pm

Thanks techpaul. I am not familiar with the I2C monitor. Is that a hardware device?

It occurs to me that I might be using a different version of the python smbus binding or the i2c-dev driver. I'm using Arch linux and I don't remember where I got the i2c-tools package from. That could account for the difference. Which are you using?

Return to “Python”