0

I have a Raspberry PI 2 and I am having a hard time getting any scripts that work to read the HTU21D-F.

This the errors I am getting.

Traceback (most recent call last): File "Adafruit_HTU21D_example.py", line 14, in temp = htu.readTemperatureData() File "/home/pi/Adafruit_HTU21D/Adafruit_HTU21D.py", line 36, in readTemperatureData value = self.i2c.readList(self.TRIGGER_TEMP_MEASURE_HOLD, 3) File "/home/pi/Adafruit_HTU21D/Adafruit_I2C.py", line 94, in readList results = self.bus.read_i2c_block_data(self.address, reg, length) AttributeError: 'Adafruit_I2C' object has no attribute 'bus'

This the script I run.

#!/usr/bin/python

import time
from Adafruit_HTU21D import HTU21D

# Initialise the HTU21D
htu = HTU21D()

for _ in range(100):
temp = htu.readTemperatureData()
rh = htu.readHumidityData()

if temp > -40 and rh > 0:
    print "Temperature: %.2f C, Humidity: %.2f %%" % (temp, rh)
elif temp == -255:
    print "Temperature data CRC failed"
elif rh == -255:
    print "RH data CRC failed"
else:
    print "Invalid:" + str(temp) + ", " + str(rh)

time.sleep(1)

Supporting file 1.

#!/usr/bin/python

import time
from Adafruit_I2C import Adafruit_I2C

# =========================================================================
# HTU21D Class
# 
# Code only test with a Sparkfun HTU21D Sensor module on a Beaglebone Black.
# It has been reported that an I2C address issue was seen on a Pi.
# =========================================================================

class HTU21D:
   i2c = None

# HTU21D Address
address = 0x40

# Commands
TRIGGER_TEMP_MEASURE_HOLD = 0xE3
TRIGGER_HUMD_MEASURE_HOLD = 0xE5
READ_USER_REG = 0xE7

# Constructor
def __init__(self):
    self.i2c = Adafruit_I2C(self.address)

def readUserRegister(self):
    "Read the user register byte"
    return self.i2c.readU8(self.READ_USER_REG)

def readTemperatureData(self):
    "Read 3 temperature bytes from the sensor"
    # value[0], value[1]: Raw temperature data
    # value[2]: CRC
    value = self.i2c.readList(self.TRIGGER_TEMP_MEASURE_HOLD, 3)

    # CRC Check
    if not self.crc8check(value):
        return -255

    rawTempData = ( value[0] << 8 ) + value[1]

    # Clear the status bits
    rawTempData = rawTempData & 0xFFFC;

    # Calculate the actual temperature
    actualTemp = -46.85 + (175.72 * rawTempData / 65536)

    return actualTemp

def readHumidityData(self):
    "Read 3 humidity bytes from the sensor"
    # value[0], value[1]: Raw relative humidity data
    # value[2]: CRC
    value = self.i2c.readList(self.TRIGGER_HUMD_MEASURE_HOLD, 3)

    # CRC Check
    if not self.crc8check(value):
        return -255

    rawRHData = ( value[0] << 8 ) + value[1]

    # Clear the status bits
    rawRHData = rawRHData & 0xFFFC;

    # Calculate the actual RH
    actualRH = -6 + (125.0 * rawRHData / 65536)

    return actualRH

 def crc8check(self, value):
    "Calulate the CRC8 for the data received"
    # Ported from Sparkfun Arduino HTU21D Library:   https://github.com/sparkfun/HTU21D_Breakout
    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

Supporting file 2.

#!/usr/bin/python

import smbus

# =========================================================================
# Adafruit_I2C Class
# =========================================================================

class Adafruit_I2C(object):

    @staticmethod
      def getPiRevision():
      "Gets the version number of the Raspberry Pi board"
# Courtesy quick2wire-python-api
# https://github.com/quick2wire/quick2wire-python-api
# Updated revision info from: http://elinux.org/RPi_HardwareHistory#Board_Revision_History
try:
  with open('/proc/cpuinfo','r') as f:
    for line in f:
      if line.startswith('Revision'):
        return 1 if line.rstrip()[-1] in ['2','3'] else 2
except:
  return 0

@staticmethod
def getPiI2CBusNumber():
# Gets the I2C bus number /dev/i2c#
return 1 if Adafruit_I2C.getPiRevision() > 1 else 0

def __init__(self, address, busnum=-1, debug=False):
self.address = address
# By default, the correct I2C bus is auto-detected using /proc/cpuinfo
# Alternatively, you can hard-code the bus version below:
# self.bus = smbus.SMBus(0); # Force I2C0 (early 256MB Pi's)
self.bus = smbus.SMBus(1); # Force I2C1 (512MB Pi's) # UNCOMMENT THIS LINE
#self.bus = smbus.SMBus(busnum if busnum >= 0 else       Adafruit_I2C.getPiI2CBusNumber())
self.debug = debug

def reverseByteOrder(self, data):
 "Reverses the byte order of an int (16-bit) or long (32-bit) value"
# Courtesy Vishal Sapre
byteCount = len(hex(data)[2:].replace('L','')[::2])
val       = 0
for i in range(byteCount):
  val    = (val << 8) | (data & 0xff)
  data >>= 8
return val

def errMsg(self):
 print "Error accessing 0x%02X: Check your I2C address" % self.address
 return -1

 def write8(self, reg, value):
  "Writes an 8-bit value to the specified register/address"
   try:
    self.bus.write_byte_data(self.address, reg, value)
    if self.debug:
    print "I2C: Wrote 0x%02X to register 0x%02X" % (value, reg)
 except IOError, err:
  return self.errMsg()

 def write16(self, reg, value):
  "Writes a 16-bit value to the specified register/address pair"
    try:
      self.bus.write_word_data(self.address, reg, value)
      if self.debug:
       print ("I2C: Wrote 0x%02X to register pair 0x%02X,0x%02X" %
       (value, reg, reg+1))
  except IOError, err:
  return self.errMsg()

 def writeRaw8(self, value):
   "Writes an 8-bit value on the bus"
     try:
      self.bus.write_byte(self.address, value)
  if self.debug:
    print "I2C: Wrote 0x%02X" % value
   except IOError, err:
     return self.errMsg()

  def writeList(self, reg, list):
"Writes an array of bytes using I2C format"
try:
  if self.debug:
    print "I2C: Writing list to register 0x%02X:" % reg
    print list
  self.bus.write_i2c_block_data(self.address, reg, list)
except IOError, err:
  return self.errMsg()

 def readList(self, reg, length):
"Read a list of bytes from the I2C device"
try:
  results = self.bus.read_i2c_block_data(self.address, reg, length)
  if self.debug:
    print ("I2C: Device 0x%02X returned the following from reg 0x%02X" %
     (self.address, reg))
    print results
  return results
except IOError, err:
  return self.errMsg()

 def readU8(self, reg):
"Read an unsigned byte from the I2C device"
try:
  result = self.bus.read_byte_data(self.address, reg)
  if self.debug:
    print ("I2C: Device 0x%02X returned 0x%02X from reg 0x%02X" %
     (self.address, result & 0xFF, reg))
  return result
except IOError, err:
  return self.errMsg()

def readS8(self, reg):
"Reads a signed byte from the I2C device"
try:
  result = self.bus.read_byte_data(self.address, reg)
  if result > 127: result -= 256
  if self.debug:
    print ("I2C: Device 0x%02X returned 0x%02X from reg 0x%02X" %
     (self.address, result & 0xFF, reg))
  return result
except IOError, err:
  return self.errMsg()

def readU16(self, reg, little_endian=True):
"Reads an unsigned 16-bit value from the I2C device"
try:
  result = self.bus.read_word_data(self.address,reg)
  # Swap bytes if using big endian because read_word_data assumes little 
  # endian on ARM (little endian) systems.
  if not little_endian:
    result = ((result << 8) & 0xFF00) + (result >> 8)
  if (self.debug):
    print "I2C: Device 0x%02X returned 0x%04X from reg 0x%02X" % (self.address, result & 0xFFFF, reg)
  return result
except IOError, err:
  return self.errMsg()

def readS16(self, reg, little_endian=True):
"Reads a signed 16-bit value from the I2C device"
try:
  result = self.readU16(reg,little_endian)
  if result > 32767: result -= 65536
  return result
except IOError, err:
  return self.errMsg()

if __name__ == '__main__':
  try:
   bus = Adafruit_I2C(address=0)
   print "Default I2C bus is accessible"
  except:
   print "Error accessing default I2C bus"
0

Ok this did not resolve my issue with this code but it did help in getting the issue fixed. I had to run sudo asps-config and enable the IC2 on boot. Then after looking at the code for 20 hours I noticed that I need to remove the # from the line with self.bus = smbus.SMBus(1); # Force I2C1 (512MB Pi's).

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.