View previous topic :: View next topic |
Author |
Message |
beatkrik
Joined: 17 May 2006 Posts: 13
|
Posted: Mon Mar 02, 2015 12:30 pm Post subject: HTU21D temperature and humidity sensor 3V3 |
|
|
Tested the HTU21D Sensor, you can order an Arduino breakout board
14bit's resolution temperature reading
12bit's resolution humidity readout
have to check out CRC.
Code: |
'Name: M32 HTU21D Test04.bas
'Purpose: Validation Test
'Date: 26-02-2015
$regfile = "m32adef.dat" ' specify the used micro
$crystal = 16000000 ' used crystal frequency
$hwstack = 100 ' default use 32 for the hardware stack
$swstack = 100 ' default use 10 for the SW stack
$framesize = 150 ' default use 40 for the frame space
$baud = 19200
'
'------- For Timer 0 routine --------
Dim Cnt As Byte
Dim Timestamp As Dword
Dim Sec_flag As Bit
'--------------HTU21D----------------
dim temp as single
dim hum as single
dim hum_comp as single
'--------- Config I/O Pin's ---------
Config Portd.7 = Output 'Enable pin for Alive LED
Reset Portd.7
Led Alias Portd.7
'
Config Porta.7 = Output 'RS485 enable pin
Rs485_en Alias Porta.7
Reset Rs485_en
'
'------------------------- SUB Routine's ---------------------------------------
declare function HTU21D_temp() as single
declare function HTU21D_hum() as single
declare sub init_htu21d
'------------------- Config Timer0 for 1 second TICK ---------------------------
Const Timer0reload = 250
Config Timer0 = Timer , Prescale = 256
On Ovf0 Timer0_isr_250ms
Load Timer0 , Timer0reload
Enable Timer0
Start Timer0
'------------------- Config and init I2C bus -----------------------------------
Config Sda = Portc.1
Config Scl = Portc.0
Config I2cdelay = 10 '100KHz clock
I2cinit
'-------------------------------------------------------------------------------
'
'--------------------- Open Soft comport for data output -----------------------
Open "comc.3:38400,8,n,1" For Output As #2
Print #2,"#" ; Version(3) ; ",";
Print #2,Version(1)
print #2,"HTU21D Output"
'
'-------------------------------------------------------------------------------
Enable Interrupts
'*******************************************************************************
'------------------------------------- MAIN ------------------------------------
call init_htu21d
Do
If Sec_flag = 1 Then
Reset Sec_flag
Toggle Led
print #2,timestamp;",";
temp=htu21d_temp()
print #2, fusing(temp,"#.##");",";
hum=htu21d_hum()
print #2, fusing(hum,"#.##");",";
hum_comp=25-temp
hum_comp=hum_comp*-.15
hum_comp=hum+hum_comp
print #2,fusing(hum_comp,"#.##")
End If
loop
'
close #2
'
End
'*******************************************************************************
'------------------------------ Sub routine's ----------------------------------
'-------------------------------------------------------------------------------
Timer0_isr_250ms:
Load Timer0 , Timer0reload
Incr Cnt
If Cnt > 249 Then
Cnt = 0
Incr Timestamp 'Increase every Second
Set Sec_flag
End If
Return
'-------------------------------------------------------------------------------
function htu21d_temp() as single
local msb as byte
local lsb as byte
local crc as byte
local temp as single
I2cstart
I2cwbyte &H80
i2cwbyte &HE3 'temp hold
I2cstart
i2cwbyte &H81
I2crbyte msb,ack
I2crbyte lsb , Ack
I2crbyte crc , Nack
I2cstop
temp=msb
shift temp, left ,8
temp=temp+lsb
shift temp,right,2 'trunc LSB status bits
shift temp,left,2
temp=temp/65536
temp=temp*175.72
temp=-46.85+temp
htu21d_temp=temp
end function
'-------------------------------------------------------------------------------
function htu21d_hum() as single
local msb as byte
local lsb as byte
local crc as byte
local hum as single
I2cstart
I2cwbyte &H80
i2cwbyte &HE5 'hum hold
I2cstart
i2cwbyte &H81
I2crbyte msb,ack
I2crbyte lsb , Ack
I2crbyte crc , Nack
I2cstop
hum=msb
shift hum, left ,8
hum=hum+lsb
SHIFT hum,right,2 'Trunc lsb status bits
shift hum,left,2
hum=hum/65536
hum=hum*125
hum=-6+hum
htu21d_hum=hum
end function
'-------------------------------------------------------------------------------
sub init_htu21d
'HTU21D Sensor Start up (set in idle mode)
set portc.1 'SCL
waitms 20
reset portc.1 'SCL
'Soft Reset
I2cstart
I2cwbyte &H80
i2cwbyte &HFE
I2cstop
end sub
|
|
|
Back to top |
|
|
beatkrik
Joined: 17 May 2006 Posts: 13
|
Posted: Mon Mar 02, 2015 12:55 pm Post subject: |
|
|
Dewpoint calculation added
Code: |
'Name: M32 HTU21D Test05.bas
'Purpose: Validation Test
'Date: 02-03-2015
$regfile = "m32adef.dat" ' specify the used micro
$crystal = 16000000 ' used crystal frequency
$hwstack = 100 ' default use 32 for the hardware stack
$swstack = 100 ' default use 10 for the SW stack
$framesize = 150 ' default use 40 for the frame space
$baud = 19200
'
'------- For Timer 0 routine --------
Dim Cnt As Byte
Dim Timestamp As Dword
Dim Sec_flag As Bit
'--------------HTU21D----------------
dim temp as single
dim hum as single
dim hum_comp as single
dim tdew as single
'---------- Constant's --------------
const a=8.1332
const b=1762.39
const c=235.66
'--------- Config I/O Pin's ---------
Config Portd.7 = Output 'Enable pin for Alive LED
Reset Portd.7
Led Alias Portd.7
'
Config Porta.7 = Output 'RS485 enable pin
Rs485_en Alias Porta.7
Reset Rs485_en
'
'------------------------- SUB Routine's ---------------------------------------
declare function HTU21D_temp() as single
declare function HTU21D_hum() as single
declare function Calc_Dew() as single
declare sub init_htu21d
'------------------- Config Timer0 for 1 second TICK ---------------------------
Const Timer0reload = 250
Config Timer0 = Timer , Prescale = 256
On Ovf0 Timer0_isr_250ms
Load Timer0 , Timer0reload
Enable Timer0
Start Timer0
'------------------- Config and init I2C bus -----------------------------------
Config Sda = Portc.1
Config Scl = Portc.0
Config I2cdelay = 10 '100KHz clock
I2cinit
'-------------------------------------------------------------------------------
'
'--------------------- Open Soft comport for data output -----------------------
Open "comc.3:38400,8,n,1" For Output As #2
Print #2,"#" ; Version(3) ; ",";
Print #2,Version(1)
print #2,"HTU21D Output"
'
'-------------------------------------------------------------------------------
Enable Interrupts
'*******************************************************************************
'------------------------------------- MAIN ------------------------------------
call init_htu21d
Do
If Sec_flag = 1 Then
Reset Sec_flag
Toggle Led
print #2,timestamp;",";
temp=htu21d_temp()
print #2, fusing(temp,"#.##");",";
hum=htu21d_hum()
print #2, fusing(hum,"#.##");",";
hum_comp=25-temp
hum_comp=hum_comp*-.15
hum_comp=hum+hum_comp
print #2,fusing(hum_comp,"#.##");",";
tdew=calc_dew()
print #2,fusing(tdew,"#.##")
End If
loop
'
close #2
'
End
'*******************************************************************************
'------------------------------ Sub routine's ----------------------------------
'-------------------------------------------------------------------------------
Timer0_isr_250ms:
Load Timer0 , Timer0reload
Incr Cnt
If Cnt > 249 Then
Cnt = 0
Incr Timestamp 'Increase every Second
Set Sec_flag
End If
Return
'-------------------------------------------------------------------------------
function htu21d_temp() as single
local msb as byte
local lsb as byte
local crc as byte
local temp as single
I2cstart
I2cwbyte &H80
i2cwbyte &HE3 'temp hold
I2cstart
i2cwbyte &H81
I2crbyte msb,ack
I2crbyte lsb , Ack
I2crbyte crc , Nack
I2cstop
temp=msb
shift temp, left ,8
temp=temp+lsb
shift temp,right,2 'trunc LSB status bits
shift temp,left,2
temp=temp/65536
temp=temp*175.72
temp=-46.85+temp
htu21d_temp=temp
end function
'-------------------------------------------------------------------------------
function htu21d_hum() as single
local msb as byte
local lsb as byte
local crc as byte
local hum as single
I2cstart
I2cwbyte &H80
i2cwbyte &HE5 'hum hold
I2cstart
i2cwbyte &H81
I2crbyte msb,ack
I2crbyte lsb , Ack
I2crbyte crc , Nack
I2cstop
hum=msb
shift hum, left ,8
hum=hum+lsb
SHIFT hum,right,2 'Trunc lsb status bits
shift hum,left,2
hum=hum/65536
hum=hum*125
hum=-6+hum
htu21d_hum=hum
end function
'-------------------------------------------------------------------------------
sub init_htu21d
'HTU21D Sensor Start up (set in idle mode)
set portc.1 'SCL
waitms 20
reset portc.1 'SCL
'Soft Reset
I2cstart
I2cwbyte &H80
i2cwbyte &HFE
I2cstop
end sub
'-------------------------------------------------------------------------------
function Calc_Dew() as single
local PPtamb as single
local Tdew as single
PPtamb=temp+c
pptamb=b/pptamb
pptamb=a-pptamb
pptamb=10^pptamb
tdew=pptamb/100
tdew=tdew*hum
tdew=log10(tdew)
tdew=tdew-a
tdew=b/tdew
tdew=tdew+c
tdew=tdew*-1
calc_dew=tdew
end function
'-------------------------------------------------------------------------------
|
|
|
Back to top |
|
|
albertsm
Joined: 09 Apr 2004 Posts: 5913 Location: Holland
|
Posted: Tue Mar 03, 2015 9:31 pm Post subject: |
|
|
Hello beatkrik,
Thanks for sharing your code. Seems like an great sensor. Is this one better than the SH sensor ? _________________ Mark |
|
Back to top |
|
|
beatkrik
Joined: 17 May 2006 Posts: 13
|
Posted: Fri Mar 13, 2015 12:52 pm Post subject: |
|
|
Hi Mark,
If you compare the datasheets, The resolution and accuracy between the HTU21 and the SHT21 are equal.
The HTU21 is a bit faster though.
If i have time, i will make some measurements with both sensors. |
|
Back to top |
|
|
O-Family
Joined: 23 May 2010 Posts: 320 Location: Japan
|
Posted: Fri Mar 13, 2015 2:36 pm Post subject: |
|
|
Hi beatkrik
I also just made a SHT21 of program.
Because I was calculating the CRC, please refer to.
Code: |
'
' **********************************************
' * SHT21 Temperature & Humidity sensor test *
' * O-Family 2015. 3.13 *
' **********************************************
'
$regfile = "m88pdef.dat"
$crystal = 16000000
'
$hwstack = 64
$swstack = 10
$framesize = 24
Dim I2cbuff(20) As Byte
Dim Sht21comsel As Byte
Dim Temperature As Integer
Dim Humidity As Integer
'
Dim Tempw1 As Word
Dim Templ1 As Long
Dim Tempstr As String * 20
' * LCD initialization *
Config Lcdmode = Port
Config Lcdbus = 4
Config Lcdpin = Pin , Db4 = Portb.3 , Db5 = Portb.2
Config Lcdpin = Pin , Db6 = Portb.1 , Db7 = Portb.0
Config Lcdpin = Pin , E = Portb.4 , Rs = Portb.5
Config Lcd = 16 * 2
'
Deflcdchar 0 , &H08 , &H14 , &H08 , &H06 , &H09 , &H08 , &H09 , &H06
Cursor Off
Cls
' * I2C initialization *
Config Scl = Portd.3
Config Sda = Portd.2
I2cinit
Main:
'
' * Send the measure command to SHT21 *
'
If Sht21comsel = 0 Then 'Temperature measurement?
I2cbuff(5) = &B1111_0011 'Send the Temperature measurement trigger(no-hold) command.
Sht21comsel = 1
Else
I2cbuff(5) = &B1111_0101 'Send the Humidity measurement trigger(no-hold) command.
Sht21comsel = 0
End If
'
I2cstart
I2cwbyte &H80
If Err <> 0 Then Goto Sht21error1 '[ACK] has not come back?
I2cwbyte I2cbuff(5)
Waitus 20 'no-hold waiting time.(20uS)
I2cstop
Waitms 100 'Waiting for measuring time.
'
' * Receive the measurement data from SHT21 *
'
I2cstart
I2cwbyte &H81
If Err <> 0 Then Goto Sht21error2 'Measurement is not finished?
I2crbyte I2cbuff(1) , Ack 'Read the MSB data.
I2crbyte I2cbuff(2) , Ack 'Read the LSB data.
I2crbyte I2cbuff(3) , Nack 'Read the checksum.
I2cstop
'
Gosub Sht21crc 'Calculate the CRC8 for SHT21.
If I2cbuff(3) <> I2cbuff(4) Then Goto Sht21error3 'CRC Error?
'
' * Display the measurement data to LCD *
'
If I2cbuff(2).1 = 0 Then 'Temperature data?
Locate 1 , 1 'Received data HEX display.
Lcd Hex(i2cbuff(1)) ; Hex(i2cbuff(2)) ; Hex(i2cbuff(3)) ; " ";
'
I2cbuff(2) = I2cbuff(2) And &B1111_1100 'Mask the status bit.
Tempw1 = Makeint(i2cbuff(2) , I2cbuff(1)) 'Convert the 2-byte to one word.
Templ1 = 17572 * Tempw1 'Calculation of temperature conversion.
Temperature = Highw(templ1) '1/2^16
Temperature = -4685 + Temperature
Tempstr = Str(temperature)
If Temperature < 0 Then 'Negative value?
Lcd Format(tempstr , " 0.00") ; " " ; Chr(0)
Else
Lcd Format(tempstr , " 0.00") ; " " ; Chr(0)
End If
Else 'Case of humidity data.
Locate 2 , 1 'Received data HEX display.
Lcd Hex(i2cbuff(1)) ; Hex(i2cbuff(2)) ; Hex(i2cbuff(3)) ; " ";
'
I2cbuff(2) = I2cbuff(2) And &B1111_0000 'Mask the status bit.
Tempw1 = Makeint(i2cbuff(2) , I2cbuff(1)) 'Convert the 2-byte to one word.
Templ1 = 12500 * Tempw1 'Calculation of humidity conversion.
Humidity = Highw(templ1) '1/2^16
Humidity = -600 + Humidity
Tempstr = Str(humidity)
Lcd Format(tempstr , " 0.00") ; " %"
End If
'
Main1:
Waitms 900 'Waiting time of 1 second cycle.
Goto Main
'
' * SHT21 Error (ACK is not returned) *
'
Sht21error1:
Locate 2 , 1
Lcd "#SHT21 ACK Error"
Goto Main1
'
' * SHT21 Error (Has not been completed measurement) *
'
Sht21error2:
I2cstop
Locate 2 , 1
Lcd "#SHT21 NACK Ret."
Goto Main1
'
' * SHT21 Error (CRC Error) *
'
Sht21error3:
Locate 2 , 1
Lcd "#SHT21 CRC Error"
'
Locate 1 , 1
Lcd Hex(i2cbuff(1)) ; Hex(i2cbuff(2)) ; Hex(i2cbuff(3)) ; ":" ; Hex(i2cbuff(4)) ; Spc(7)
Goto Main1
'
' * Calculate the CRC8 for SHT21 *
'
Sht21crc:
Loadadr I2cbuff(1) , Z
$asm
LDI R16,$02 'Number of bytes to calculate.
CLR R24 'CRC value.
LDI R22,$31 'POLYNOMIAL = 0x131 P(x)=x^8+x^5+x^4+1 = 1_0011_0001
Sht21crc1:
LD R25,Z+ 'To read the calculated byte.
EOR R24,R25 'CRC = CRC EXOR I2cbuff(x)
LDI R17,$08
Sht21crc2:
LSL R24 'CRC to the left I 1bit shift.
BRcc Sht21crc3 'bit7 of shift before the CRC [1]?
EOR R24,R22 'CRC = CRC EXOR &H31
Sht21crc3:
DEC R17
BRNE Sht21crc2 '8-bit or end?
DEC R16
BRNE Sht21crc1 'Number of bytes to calculate is over?
ADIW R30,1 'Stores the calculated CRC value for the next received byte CRC.
ST Z,R24
$end Asm
Return
'
'
End
|
|
|
Back to top |
|
|
beatkrik
Joined: 17 May 2006 Posts: 13
|
Posted: Mon Mar 16, 2015 12:22 pm Post subject: |
|
|
Thank's O-Family
I wil try to implement your CRC code in my program. Great work ! |
|
Back to top |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum You cannot attach files in this forum You cannot download files in this forum
|
|