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"