Got the above sensor for my RPi 3 model B.
Was unable to get it working using the SMbus library and commands (I tried all read write combinations hah!). I think this is due to the sensor not reading and writing from registers but just raw data. The closest I got was writing a raw command byte and then trying to receive 2 raw bytes back but it was only reading the MSB twice.
I have got it working using the pigpio library and the Si7021 datasheet which is good but it does require the pigpiod daemon to be running which isn't a massive problem because I can get it to start on boot but I'm looking for a slightly cleaner way of doing it.
Am I right in thinking that https://github.com/adafruit/Adafruit_Python_GPIO library would help me out here or am I barking up the wrong tree? I've also had a quick look at WiringPi which might be another solution?
Any help will be greatly appreciated!
For anyone interested this is how I've got it working with the pigpio code:
Code: Select all
##I2C and smbus driver for Si7021 temperature humidity sensor##
import smbus
import time
import pigpio
#set the bus up e.g./dev/i2c-1
bus = smbus.SMBus(1)
#Si7021 device address - set in hardware and un-changeable
address = 0x40
# #read the user register (Si7021 setup)
# read_user_register = bus.read_byte_data(address,0xE7) & 0xFF
# time.sleep(0.1)
# print("{:08b}".format(read_user_register)) #prints the value in bits
###PIGPIO TEST###
#opens gpio for the pi to the daemon
pi = pigpio.pi()
if pi.connected:
print("the pi is connected to pigpio")
else:
print("the pi is not connected to pigpio")
#Returns a handle (>=0) for the device at the I2C bus address. Handle used for read and write commands
temphumid_handle = pi.i2c_open(1,address) #only needs setting once while daemon is open
pi.i2c_write_device(temphumid_handle,[0xF5]) #writes the command byte to start humidity reading
time.sleep(0.5) #gives time for the write to finish
humid_count, humid_bytes = pi.i2c_read_device(temphumid_handle,2) #reads 2 bytes from sensor. stores a tuple of no.bytes read
#and bytearray of received bytes.
time.sleep(0.5)
#TEMP read doesnt have to write a temp command as a temperature read is done automatically after humidity for compensation.
#this reads the data after the humidity word
temp_word = pi.i2c_read_word_data(temphumid_handle,0xE0) #This uses the pigpio import rather than the below smbus
#temp_word = bus.read_word_data(address,0xE0) #This works off the smbus as it fits the correct byte commands
time.sleep(0.5)
temp_byte_object = temp_word.to_bytes(2,byteorder='big',signed=False) #split int into bytes(to swap the MSB and LSB)
#the i2c read puts the MSB in the LSB spot in the word
temp_word = int.from_bytes(temp_byte_object, byteorder='little',signed=False) #puts bytes back together in correct order with little endian
temp_value = ((175.72*temp_word)/65536.0)-46.85 #calculation from datasheet for temperature in DegC
humid_MSB = humid_bytes[0] #assign most significant bit (docs say this is Tx'd first
humid_LSB = humid_bytes[1] #assign least significant bit (docs say this is Tx'd second
humid_word = (humid_MSB<<8) + humid_LSB #moves the MSB up 8 bits and adds the LSB to it creating a full word of data
humid_value = ((125.0*humid_word)/65536.0)-6.0 #calulation from datasheet for humidity in %
print(str(humid_value) +"%")
print(str(temp_value) +" DegC")
pi.i2c_close(temphumid_handle) #closes the handle so when the script re-runs it doesnt assign another address to the same device.
#once assigned it keeps the handle unless the deamon closes.
pi.stop() #releases pigpio resources