PDA

View Full Version : Code for SHT21



Mike2545
- 6th August 2017, 15:47
Hello all,

I have been using SHT11 and Tracy Allen's code for some time. I recently got a SHT21 and found the conversion does not work.

I found this on the Basic Stamp Forum:


Just to compare in red and blue, the formulae for the SHT2x:
°C = -46.85 + 175.72 * rawT / (2^resT) resT is 14 bits default
%RH = -6 + 125 * rawH / (2^resH) resH is 12 bits default
res = resolution, tradeoff with speed, set in the user register.

with formulae for SHT1x:
°C = -40.1 + 0.01 * rawT on 14 bit setting and 5V supply
%RH1 = -2.0468 + 0.0367 * rawH - 1.5955E-6 * rawH^2 on 12 bit setting
then temperature compensation
%RH = (°C - 25) * (.01 + 0.00008 * rawH) + RH1
The SHT1x too has both high and low resolution modes.


Does anyone else use a SHT21 and what does the code actually look like?

Thanks in advance

Mike2545

mpgmike
- 7th August 2017, 16:31
Not familiar with the SHT11, but at a glance I can say the PIC will not work with decimals or negatives. However. if you wanted to add -46.85 + 175.72 it could be structured

(17572 - 4685) / 100

Multiplication works similarly; Var * 1.75 becomes (Var * 175) / 100.

Something tells me I'm not even getting close to the jist of your question. If you can elaborate some, I'll see if I can help.

Mike2545
- 7th August 2017, 22:35
mpgmike,
Thanks for the response. I'll link the code for the sht11 on the parallax site and the data sheet for the sht21.
https://www.parallax.com/sites/default/files/downloads/28018-Sensirion-Temperature-Humidity-Sensor-BASIC-Stamp-Example-Code.zip
http://www.mouser.com/ds/2/682/Sensirion_Humidity_SHT21_Datasheet_V4-469715.pdf

If you don't have the BS2 editor here is the code:


' ================================================== ============================
'
' File...... SHT11.BS2
' Purpose... Interface to Sensirion SHT11 temperature/humidity sensor
' E-mail.... [email protected]
' Date...... 12/30/02
'
' {$STAMP BS2}
'
' ================================================== ============================


' ------------------------------------------------------------------------------
' Program Description
' ------------------------------------------------------------------------------
'
' This program demonstrates the interface and conversion of SHT11 data to
' usable program values.
'
' For detailed information on the use and application of the ** operator,
' see Tracy Allen's web page at this link:
'
' -- http://www.emesystems.com/BS2math1.htm
'
' For Tracy's SHT1x code [very advanced]:
'
' -- http://www.emesystems.com/OL2sht1x.htm
'
' For SHT11/15 documentation and app notes, visit:
'
' -- http://www.sensirion.com


' ------------------------------------------------------------------------------
' I/O Definitions
' ------------------------------------------------------------------------------

ShtData CON 1 ' bi-directional data
Clock CON 0


' ------------------------------------------------------------------------------
' Constants
' ------------------------------------------------------------------------------

ShtTemp CON %00011 ' read temperature
ShtHumi CON %00101 ' read humidity
ShtStatW CON %00110 ' status register write
ShtStatR CON %00111 ' status register read
ShtReset CON %11110 ' soft reset (wait 11 ms after)

Ack CON 0
NoAck CON 1

No CON 0
Yes CON 1

MoveTo CON 2 ' for DEBUG control
ClrRt CON 11 ' clear DEBUG line to right

DegSym CON 186 ' degrees symbol for DEBUG


' ------------------------------------------------------------------------------
' Variables
' ------------------------------------------------------------------------------

ioByte VAR Byte ' data from/to SHT1x
ackBit VAR Bit ' ack/nak from/to SHT1x
toDelay VAR Byte ' timeout delay timer
timeOut VAR Bit ' timeout status

soT VAR Word ' temp counts from SHT1x
tC VAR Word ' temp - celcius
tF VAR Word ' temp - fahrenheit

soRH VAR Word ' humidity counts from SHT1x
rhLin VAR Word ' humidity; linearized
rhTrue VAR Word ' humidity; temp compensated

status VAR Byte ' SHT1x status byte


' ------------------------------------------------------------------------------
' EEPROM Data
' ------------------------------------------------------------------------------


' ------------------------------------------------------------------------------
' Initialization
' ------------------------------------------------------------------------------

Initialize:
GOSUB SHT_Connection_Reset ' reset device connection

PAUSE 250 ' let DEBUG window open
DEBUG CLS
DEBUG "SHT1x Demo", CR
DEBUG "----------", CR

' GOTO Main ' skip heater demo

' ------------------------------------------------------------------------------
' Program Code
' ------------------------------------------------------------------------------

Sensor_Demo:
GOSUB SHT_Measure_Temp
DEBUG MoveTo, 0, 3
DEBUG "tF...... "
DEBUG DEC (tF / 10), ".", DEC1 tF, DegSym, ClrRt, CR

GOSUB SHT_Measure_Humidity
DEBUG "rhLin... "
DEBUG DEC (rhLin / 10), ".", DEC1 rhLin, "%", ClrRt, CR, CR

Heater_On:
DEBUG "SHT1x heater on", CR
status = %00000100 ' heater bit = On
GOSUB SHT_Write_Status
DEBUG "Waiting 2 seconds", CR
PAUSE 2000

Heater_Off:
DEBUG "SHT1x heater off", CR, CR
status = %00000000 ' heater bit = Off
GOSUB SHT_Write_Status

GOSUB SHT_Measure_Temp
DEBUG "tF...... "
DEBUG DEC (tF / 10), ".", DEC1 tF, DegSym, ClrRt, CR

GOSUB SHT_Measure_Humidity
DEBUG "rhLin... "
DEBUG DEC (rhLin / 10), ".", DEC1 rhLin, "%", ClrRt, CR, CR

PAUSE 5000

Main:
DEBUG CLS
DEBUG "SHT1x Demo", CR
DEBUG "----------", CR

Main2:
GOSUB SHT_Measure_Temp
DEBUG MoveTo, 0, 3
DEBUG "soT...... "
DEBUG DEC soT, ClrRt, CR
DEBUG "tC....... "
DEBUG DEC (tC / 10), ".", DEC1 tC, DegSym, ClrRt, CR
DEBUG "tF....... "
DEBUG DEC (tF / 10), ".", DEC1 tF, DegSym, ClrRt

GOSUB SHT_Measure_Humidity
DEBUG MoveTo, 0, 7
DEBUG "soRH..... "
DEBUG DEC soRH, ClrRt, CR
DEBUG "rhLin.... "
DEBUG DEC (rhLin / 10), ".", DEC1 rhLin, "%", ClrRt, CR
DEBUG "rhTrue... "
DEBUG DEC (rhTrue / 10), ".", DEC1 rhTrue, "%", ClrRt

PAUSE 1000 ' minimum delay between readings
GOTO Main2

END


' ------------------------------------------------------------------------------
' Subroutines
' ------------------------------------------------------------------------------

' connection reset: 9 clock cyles with ShtData high, then start sequence
'
SHT_Connection_Reset:
SHIFTOUT ShtData, Clock, LSBFIRST, [$FFF\9]

' generates SHT1x "start" sequence
' _____ _____
' ShtData |_______|
' ___ ___
' Clock ___| |___| |___
'
SHT_Start:
INPUT ShtData ' let pull-up take line high
LOW Clock
HIGH Clock
LOW ShtData
LOW Clock
HIGH Clock
INPUT ShtData
LOW Clock
RETURN


' measure temperature
' -- celcius = soT * 0.01 - 40
' -- fahrenheit = soT * 0.018 - 40
'
SHT_Measure_Temp:
GOSUB SHT_Start ' alert device
ioByte = ShtTemp ' temperature command
GOSUB SHT_Write_Byte ' send command
GOSUB SHT_Wait ' wait until measurement done
ackBit = Ack ' another read follows
GOSUB SHT_Read_Byte ' get MSB
soT.HIGHBYTE = ioByte
ackBit = NoAck ' last read
GOSUB SHT_Read_Byte ' get LSB
soT.LOWBYTE = ioByte

' Note: Conversion factors are multiplied by 10 to return the
' temperature values in tenths of degrees

tC = soT / 10 - 400 ' convert to tenths C
tF = soT ** 11796 - 400 ' convert to tenths F
RETURN


' measure humidity
'
SHT_Measure_Humidity:
GOSUB SHT_Start ' alert device
ioByte = ShtHumi ' humidity command
GOSUB SHT_Write_Byte ' send command
GOSUB SHT_Wait ' wait until measurement done
ackBit = Ack ' another read follows
GOSUB SHT_Read_Byte ' get MSB
soRH.HIGHBYTE = ioByte
ackBit = NoAck ' last read
GOSUB SHT_Read_Byte ' get LSB
soRH.LOWBYTE = ioByte

' linearize humidity
' rhLin = (soRH * 0.0405) - (soRH^2 * 0.0000028) - 4
'
' for the BASIC Stamp:
' rhLin = (soRH * 0.0405) - (soRH * 0.004 * soRH * 0.0007) - 4
'
' Conversion factors are multiplied by 10 and then rounded to
' return tenths
'
rhLin = (soRH ** 26542)
rhLin = rhLin - ((soRH ** 3468) * (soRH ** 3468) + 50 / 100)
rhLin = rhLin - 40

' temperature compensated humidity
' rhTrue = (tC - 25) * (soRH * 0.00008 + 0.01) + rhLin
'
' Conversion factors are multiplied by 100 to improve accuracy and then
' rounded off.
'
rhTrue = ((tC / 10 - 25) * (soRH ** 524 + 1) + (rhLin * 10)) + 5 / 10
RETURN


' sends "status"
'
SHT_Write_Status:
GOSUB SHT_Start ' alert device
ioByte = ShtStatW ' write to status reg command
GOSUB SHT_Write_Byte ' send command
ioByte = status
GOSUB SHT_Write_Byte
RETURN


' returns "status"
'
SHT_Read_Status:
GOSUB SHT_Start ' alert device
ioByte = ShtStatW ' write to status reg command
GOSUB SHT_Read_Byte ' send command
ackBit = NoAck ' only one byte to read
GOSUB SHT_Read_Byte
RETURN


' sends "ioByte"
' returns "ackBit"
'
SHT_Write_Byte:
SHIFTOUT ShtData, Clock, MSBFIRST, [ioByte] ' send byte
SHIFTIN ShtData, Clock, LSBPRE, [ackBit\1] ' get ack bit
RETURN


' returns "ioByte"
' sends "ackBit"
'
SHT_Read_Byte:
SHIFTIN ShtData, Clock, MSBPRE, [ioByte] ' get byte
SHIFTOUT ShtData, Clock, LSBFIRST, [ackBit\1] ' send ack bit
INPUT ShtData ' release data line
RETURN


' wait for device to finish measurement (pulls data line low)
' -- timeout after ~1/4 second
'
SHT_Wait:
INPUT ShtData ' data line is input
FOR toDelay = 1 TO 250 ' give ~1/4 second to finish
timeOut = INS.LOWBIT(ShtData) ' scan data line
IF (timeOut = No) THEN SHT_Wait_Done ' if low, we're done
PAUSE 1
NEXT

SHT_Wait_Done:
RETURN


' reset SHT1x with soft reset
'
SHT_Soft_Reset:
GOSUB SHT_Connection_Reset ' reset the connection
ioByte = ShtReset ' reset command
ackBit = NoAck ' only one byte to send
GOSUB SHT_Write_Byte ' send it
PAUSE 11 ' wait at least 11 ms
RETURN


What I am trying to do is, write code to read the SHT21 temperature and humidity.

Mike2545
- 8th August 2017, 01:24
mpgmike, I got the sensor to respond to my finger temp difference. Here is the code so far:

Yes, yes, I am prototyping on a Stamp :/


' {$STAMP BS2p}
' {$PBASIC 2.0}

tf VAR Byte
tc VAR Byte
rawT VAR Word
rawRH VAR Byte

PAUSE 250 ' let DEBUG window open
DEBUG CLS
DEBUG "SHT21 Demo", CR
DEBUG "----------", CR

Main:

I2COUT 0 ,%10000000, [%11100011]
PAUSE 50
I2CIN 1 , %10000001, [rawT]
DEBUG 2, 0, 3
DEBUG "rawT...... "
DEBUG DEC rawT, 11, CR
rawT= rawT <<2
tC = (rawT & $fffc) ** 17572 - 4685
DEBUG "Deg C......", DEC tC
PAUSE 500


GOTO main


Getting elevated readings on the SHT21
The SHT21 temp says my room is 42°C (107.6°F) Actual temperature is ~ 23.8°C (75°F)
rawT @ 42°C = 111

richard
- 9th August 2017, 03:42
don't know much about stamp code but here goes

from the sensiron web example


//================================================== ============================
float SHT2x_CalcTemperatureC(u16t u16sT)
//================================================== ============================
{
ft temperatureC; // variable for result
u16sT &= ~0x0003; // clear bits [1..0] (status bits)
//-- calculate temperature [°C] --
temperatureC= -46.85 + 175.72/65536 *(ft)u16sT; //T= -46.85 + 175.72 * ST/2^16
return temperatureC;
}


the reading is not shifted <<2 places the two lsb are just masked off

so
rawT= rawT <<2
becomes
rawT= rawT & ~3 ;ie %1111111111111100



I2COUT 0 ,%10000000, [%11100011]

is hold master mode is that what you need ?

try
I2COUT 0 ,%10000000, [%11110011]

might be better



I2COUT 0 ,%10000000, [%11100011]
PAUSE 50 is this long enough at max resoloution ?
I2CIN 1 , %10000001, [rawT]



rawT @ 42°C = 111

by my calcs rawT should be 33132 @ 42°C

what rawT do you actually get ?