SparkFun Forums 

Where electronics enthusiasts find answers.

Have questions about a SparkFun product or board? This is the place to be.
By TheGrandPoohbah
Preamble -

I have a SI7021 board from SparkFun attached to a RPiZW using 4 wires (3.3v, ground, SCL, SDA). "i2cdetect -y 1" shows only the SI7021 on the bus at address 0x40. This seems good. Does this mean the connection is correct? I didn't remove the pull-up on the SI7021 board.

The problem -

When running a simple test, I get alternating errors of:
IOError: [Errno 5] Input/output error
IOError: {Errno 121} Remote I/O error
On the line with the first read:
RH_raw = bus.read_word_data(0x40, 0xE5)

Any ideas what would cause this? Better yet, any ideas of how to fix it? I set the bus speed to 400000 and 100000 with no difference in results. I tried different python libraries (smbus, pigpio, adafruit's smbus equivalent, a "home-brew-POS", smbus' I2C interface) and get the same results. I'm a bit frustrated. :)

Here is the full code:
Code: Select all
import smbus

# our device is on bus 1.
bus = smbus.SMBus(1)

# read relative humidity (RH)
RH_raw = bus.read_word_data(0x40, 0xE5)
rh_raw = RH_raw[0]<<8 | RH_raw[1]

# 0xE0 retrieves the temperature measurement used for RH instead of measuring again using 0xE3
T_raw = bus.read_word_data(0x40, 0xE0)
t_raw = T_raw[0]<<8 | T_raw[1]

# compute and save humidity and temp values
RH = 125.0*rh_raw/65536.0 - 6.0
Tc = 175.72*t_raw/65536.0 - 46.85
Tf = Tc * 1.8 + 32

print("tempf {0} tempc {1} humidity {2}".format(Tf, Tc, RH))
Thanks for any/all help or ideas.
By paulvha
what happens if you send a reset first : bus.write_byte(0x40, 0xfe)?
Have you tried an i2cget instruction and see whether that works : i2get -y 1 0x40 0xe0 w
do you have the right access- permission to access /dev/i2c-1?
By TheGrandPoohbah
Thanks for the ideas! In reverse order -
it appears I need to use sudo for each of my programs (not a big thing, thanks!)
i2cget -y 1 0x40 0xe0 w returns 0x0000 after the reset (sudo i2cset -y 1 0x40 0xfe)
I added the reset to the program and still got the remote IO error; however, I think I'll try the timed mode (write the command, wait, read the response) instead of the master-wait mode. I'll return with an update as soon as I can.

Great ideas that pushed me in a new direction. Thanks!!
By TheGrandPoohbah
Got it! I'm not sure if this is the most efficient way but it works. Again, I have to run it using sudo.
Code: Select all
import smbus
import time

bus = smbus.SMBus(1)

# reset device
bus.write_byte(0x40, 0xfe)

# read relative humidity (no hold master mode)
bus.write_byte(0x40, 0xF5)
err = True
while err:
		rh_raw = bus.read_byte(0x40)
		err = False
rh_raw += bus.read_byte(0x40) << 8

# 0xE0 get the temperature measurement from RH measurement instead of measuring again using 0xF3
bus.write_byte(0x40, 0xE0)
t_raw = bus.read_byte(0x40)
t_raw += bus.read_byte(0x40) << 8

# compute and save human readable humidity and temp values
RH = 125.0*rh_raw/65536.0 - 6.0
Tc = 175.72*t_raw/65536.0 - 46.85
Tf = Tc * 1.8 + 32

print("tempf {0} tempc {1} humidity {2}".format(Tf, Tc, RH))
Thanks for all your help.