Page 1 of 1

HTU21D - kolejny tani czujnik temperatury i wilgotności

Posted: 20 October 2016, 17:58 - Thu
by pancio
HTU21D to prosty w użyciu czujnik temperatury i wilgotności zasilany napięciem od 3,0 V do 3,6 V. Czujnik komunikuje się poprzez interfejs I2C. Ten tani (3$) czujnik z powodzeniem można zastosować w naszej stacji pogodowej i kontroli warunków panujących w pomieszczeniach zamkniętych. Istnieje też wersja "odporna" na warunki pogodowe oznaczona literką F. Układ może pracować z rozdzielczością od 8 do 14 bitów, co można konfigurować za pomocą wbudowanego rejestru.Do prawidłowego działania wystarczy podłączyć zasilanie oraz linie magistrali I2C. Układ dostępny jest pod adresem 0x40.

Update 2017-02-21:
Dostępny jest bardziej dokładny czujnik Si7021, którego sterowanie i obsługa jest identyczna jak HTU...


zacznijmy od sprawdzenia czy układ odpowiada:

Code: Select all

pancio@desktop:~$ ct-dev 

  ____      _     _      _                   _    
 / ___|   _| |__ (_) ___| |_ _ __ _   _  ___| | __
| |  | | | | '_ \| |/ _ \ __| '__| | | |/ __| |/ /
| |__| |_| | |_) | |  __/ |_| |  | |_| | (__|   < 
 \____\__,_|_.__/|_|\___|\__|_|   \__,_|\___|_|\_\
                                                  

Last login: Thu Oct 20 17:59:18 2016 from 192.168.2.202

Load: 0.01, 0.04, 0.05 - Board: 29.8°C - Drive: C - Memory: 1930Mb

root@ctdev:~# i2cdetect -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: 40 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- --                         
root@ctdev:~# 
Widzimy, że układ jest obecny pod adresem 0x40.

Prosty programik w Pythonie by odczytać zawartość interesujących nas rejestrów (słowo rejestr jest troszkę na wyrost, gdyż do poszczególnych informacji odwołujemy się nie poprzez podanie numeru rejestru ale poprzez wysłanie komendy do układu w wyniku której należy spodziewać się odpowiedzi w postaci 2+1 bajtów danych (LSB + MSB + CRC). Pozwolę sobie przedstawić zrzut ekranu z analizatora logicznego (~8$), dzięki któremu można obserwować reakcję naszego układu i interakcję z programem:
Write command (0xE3 - temp_measure_hold)
Write command (0xE3 - temp_measure_hold)
Widzimy 2 ramki pomiędzy zielonymi kropkami (bity startu), pierwsza wywołuje urządzenie nr 0x40 w trybie do zapisu a druga zawiera kod instrukcji temp_measure_hold (0xE3). Sekwencja ta informuje układ by rozpoczął pomiar temperatury w trybie przytrzymania (zablokowania) Mastera (naszego Cubie). Do momentu aż HTU21D nie zmierzy temperatury i odpowie, CT nie będzie mógł komunikować się z pozostałymi układami magistrali. Istnieje też tryb nieblokujący ale jego implementacja test znacznie trudniejsza...

Teraz omawiany program:

Code: Select all

################################################################
# HDU21D Python Demo
################################################################
import time
import smbus
import math


#bus number and I2C address
bus = smbus.SMBus(1) # bus number (check which number do you have by using i2cdetect)
address = 0x40       # This is the address value read via the i2cdetect 

# HTU21D-F Commands
temp_measure_hold 			= 0xE3
temp_measure_no_hold 		= 0xF3
humidity_measure_hold 		= 0xE5
humidity_measure_no_hold 	= 0xF5
register_write				= 0xE6
register_read				= 0xE7
soft_reset					= 0xFE

def read_word(arg):
    high = bus.read_byte_data(address, arg)
    low = bus.read_byte_data(address, arg+1)
    val = (high << 8) + low
    return val

def read_word_2c(arg):
    val = read_word(arg)
    if (val >= 0x8000):
        return -((65535 - val) + 1)
    else:
        return val
        
def write_byte (arg,value):
	""" Function doc """
	bus.write_byte_data(address, arg, value)
	

def htu_reset():
   bus.write_byte(address, soft_reset)
   time.sleep(0.2)

def read_i2c_block(address,command,value):
    try:
        return bus.read_i2c_block_data(address,command,value)
    except IOError:
        print "IOError - read_i2c_block"
        return -1

def read_i2c_byte(address):
    try:
        return bus.read_byte(address)
    except IOError:
        print "IOError -read_i2c_byte() "
        return -1  
  
def read_temperature():
	time.sleep(0.055)
	buf = read_i2c_block(address,temp_measure_hold,3)
	temp = buf[0]*256 + buf[1]
	temperature = ((175.72*temp/65536)-46.85)	
	return temperature
	
def read_humidity ():
	""" Function doc """
	buf = read_i2c_block(address,humidity_measure_hold,3)
	humidity_raw = buf[0]*256 + buf[1]
	humidity = ((125 * (humidity_raw)/65536)-6)	
	return humidity
	
	
	

htu_reset()
print "HTU21D Sensor said:"
print "Temperature: ","{:5.2f}".format(read_temperature()),"C"
print "Humidity:    ",read_humidity(),"%"


W naszym przypadku dokonywany jest pomiar temperatury i wilgotności bez modyfikacji rozdzielczości przetwornika. Polecm zapoznanie się z dokumentacją układu:
HumidityTemperature.pdf
HTU21D(F) Sensor Documentation
(983.58 KiB) Downloaded 1421 times