Forum - MCS Electronics

 

FAQFAQ SearchSearch RegisterRegister Log inLog in

HTU21D temperature and humidity sensor 3V3

 
Post new topic   Reply to topic    www.mcselec.com Forum Index -> Share your working BASCOM-AVR code here
View previous topic :: View next topic  
Author Message
beatkrik

Bascom Member



Joined: 17 May 2006
Posts: 13

netherlands.gif
PostPosted: Mon Mar 02, 2015 12:30 pm    Post subject: HTU21D temperature and humidity sensor 3V3 Reply with quote

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
View user's profile Visit poster's website
beatkrik

Bascom Member



Joined: 17 May 2006
Posts: 13

netherlands.gif
PostPosted: Mon Mar 02, 2015 12:55 pm    Post subject: Reply with quote

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
View user's profile Visit poster's website
albertsm

Administrator



Joined: 09 Apr 2004
Posts: 6197
Location: Holland

blank.gif
PostPosted: Tue Mar 03, 2015 9:31 pm    Post subject: Reply with quote

Hello beatkrik,

Thanks for sharing your code. Seems like an great sensor. Is this one better than the SH sensor ?

_________________
Mark
Back to top
View user's profile Visit poster's website
beatkrik

Bascom Member



Joined: 17 May 2006
Posts: 13

netherlands.gif
PostPosted: Fri Mar 13, 2015 12:52 pm    Post subject: Reply with quote

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
View user's profile Visit poster's website
O-Family

Bascom Expert



Joined: 23 May 2010
Posts: 338
Location: Japan

japan.gif
PostPosted: Fri Mar 13, 2015 2:36 pm    Post subject: Reply with quote

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
View user's profile Visit poster's website
beatkrik

Bascom Member



Joined: 17 May 2006
Posts: 13

netherlands.gif
PostPosted: Mon Mar 16, 2015 12:22 pm    Post subject: Reply with quote

Thank's O-Family

I wil try to implement your CRC code in my program. Great work !
Back to top
View user's profile Visit poster's website
Display posts from previous:   
Post new topic   Reply to topic    www.mcselec.com Forum Index -> Share your working BASCOM-AVR code here All times are GMT + 1 Hour
Page 1 of 1

 
Jump to:  
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