0

I'm new at this.

I bought an Si7021 temperature and humidity sensor, and it's wired to a breadboard -- I believe correctly. I have code, here, from the book "Make: Jumpstarting the Raspberry Pi Zero W".

(Now, I have a Raspberry Pi 3 B+, but I can't see why that would make a difference.)

Well, when I run the Python code in the book, I get a couple of errors. Namely:

Traceback (most recent call last):
  File "/home/pi/temp.py", line 99, in <module>
    sensor = Si7021(1)
  File "/home/pi/temp.py", line 29, in __init__
    self.fwrite.write(self.SOFT_RESET)    # soft reset
TypeError: a bytes-like object is required, not 'str'

Here's the Python:

import time
import array
import io
import fcntl

class Si7021:
ADDRESS = 0x40
I2C_SLAVE=0x0703
READ_TEMP_HOLD = "\xE3"
READ_TEMP_NOHOLD = "\xF3"
READ_HUM_HOLD = "\xE5"
READ_HUM_NOHOLD = "\xF5"
SOFT_RESET = "\xFE"

def __init__(self, bus):
    # Open the I2C bus:
    self.fread  = io.open("/dev/i2c-%d" % bus, "rb", buffering=0)
    self.fwrite = io.open("/dev/i2c-%d" % bus, "wb", buffering=0)

    # initialize the device as a slave:
    fcntl.ioctl(self.fread, self.I2C_SLAVE, self.ADDRESS)
    fcntl.ioctl(self.fwrite, self.I2C_SLAVE, self.ADDRESS)

    self.fwrite.write(self.SOFT_RESET)    # soft reset
    time.sleep(.1)

def close(self):
    self.fread.close()
    self.fwrite.close()

def readI2C(self, cmd):
    # These give errors:
    # data = self.bus.read_i2c_block_data(self.address, cmd)
    # word = self.bus.read_word_data(self.address, cmd)
    # This works to read the first byte,
    # but the second byte read is just a repeat of the first:
    # self.bus.write_byte(self.address, cmd)
    # time.sleep(self.pausetime)
    # byte0 = self.bus.read_byte(self.address)
    # time.sleep(self.pausetime)
    # byte1 = self.bus.read_byte(self.address)

    # So instead, read/write directly from/to the /dev/i2c* device.
    self.fwrite.write(cmd)
    time.sleep(.1)

    data = self.fread.read(3)
    buf = array.array('B', data)

    if self.crc8check(buf):
        return buf
    else:
        return None

def read_temperature_c(self):
    buf = self.readI2C(self.READ_TEMP_NOHOLD)
    if not buf:
        return -273.15    # absolute zero

    return ((buf[0] << 8 | buf [1]) & 0xFFFC) * 175.72 / 65536.0 - 46.85

def read_humidity(self):
    buf = self.readI2C(self.READ_HUM_NOHOLD)
    if not buf:
        return -1

    return ((buf[0] << 8 | buf [1]) & 0xFFFC) * 125.0 / 65536.0 - 6.0

    # return ((hum0 * 256 + hum1) * 125 / 65536.0) - 6

def crc8check(self, value):
    # Ported from the Sparkfun Arduino HTU21D Library,
    # https://github.com/sparkfun/HTU21D_Breakout, by way of
    # https://www.raspberrypi.org/forums/viewtopic.php?f=44&t=76688
    remainder = ( ( value[0] << 8 ) + value[1] ) << 8
    remainder |= value[2]

    # POLYNOMIAL = 0x0131 = x^8 + x^5 + x^4 + 1
    # divsor = 0x988000 is the 0x0131 polynomial shifted
    # to farthest left of three bytes
    divsor = 0x988000

    for i in range(0, 16):
        if( remainder & 1 << (23 - i) ):
            remainder ^= divsor
        divsor = divsor >> 1

    if remainder == 0:
        return True
    else:
        return False

if __name__ == '__main__':
sensor = Si7021(1)
ctemp = sensor.read_temperature_c()
print("Temperature:  %.2f F (%.2f C)" % ctemp * 1.8 + 32, ctemp)
print("Relative Humidity: %.1f %%" % sensor.read_humidity())
sensor.close()

Thank you for any help.

  • this defines a string SOFT_RESET = "\xFE" .... this defines a byte ADDRESS = 0x40 ...... look at the error message – jsotola Feb 16 at 20:40
  • It may be written for a different Python version. If you are running with Python 2 try running with Python 3 instead (and vice versa). – joan Feb 16 at 21:14
  • @joan Thanks for the idea. Running it in Python 2 seems to have solved the previous problem. Now there is this: ` Traceback (most recent call last): File "Si7021.py", line 99, in <module> sensor = Si7021(1) File "Si7021.py", line 29, in init self.fwrite.write(self.SOFT_RESET) # soft reset IOError: [Errno 121] Remote I/O error' ` Any idea what that's about? – Aurelius180 Feb 17 at 5:24
  • The device isn't properly wired to the I2C bus. Also see (my) abyz.me.uk/rpi/pigpio/examples.html#Python_Si7021_py for alternative software. – joan Feb 17 at 9:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.