Introduction.
This application note discusses interfacing a Honeywell humidity sensor with a PICAXE-18X.
The HIH-3610 is a three terminal single inline package (SIP) which provides a linear voltage output proportional to relative humidity. This voltage is read using a 10-bit A/D on the PICAXE-18X and the relative humidity is calculated. A Dallas DS18B20 is used to measure temperature and adjust the raw RH reading.
I developed this routine for measuring the relative humidity at a single location. However, the routine could be easily extended to multiple points with a HIH-3610 and a DS18B20 located at each location.
Detailed Discussion
The output of the HIH-3610 relative humidity sensor is;
Vad = Vref * (0.0062 * RH_raw + 0.16)
This may be arranged;
RH_raw = 161.29 * Vad / Vref - 25.80
or
RH_raw = 161.29 * ADVal / 1024 - 25.8
At first glance, this appeared formidable for a processor not having floating point capability. However, it turned out to be simpler than I had thought.
The above equation might be multiplied by 10;
RH_raw_10 = 1613 * ADVal / 1024 - 258Note that the product of 1613 and ADVal may well overflow a word (65535 max) and thus I opted to use two words to store the product;
HighWord = 1613 ** ADval LowWord = 1613 * ADValThe division by 1024 is then a matter of shifting this 32-bit quantity, ten places to the right;
' RH_10 = LowWord / 1024 + Highword * 64 - 258 RH10 = LowWord / 1024 ' lowest six bits LowWord = Highword * 64 ' put highword in the high ten bits of lowword RH10 = RH10 + LowWord RH10 = RH10 - 258The RH reading is then compensated for temperature by multiplying by;
1 / (1.0546 - 0.00216 * Tc)This poses a real challenge. Using Excel, this factor was calculated for temperatures over the range of -40 to 120 degrees C.
X Tc TFactor 0 -40 0.87 1 -30 0.89 2 -20 0.91 3 -10 0.93 4 0 0.95 5 10 0.97 6 20 0.99 7 30 1.01 8 40 1.03 9 50 1.06 10 60 1.08 11 70 1.11 12 80 1.13 13 90 1.16 14 100 1.19 15 110 1.22 16 120 1.26The temperature is measured using a DS18B20 and divided by 10. If the temperature is negative, the index X is calculated as 4 - (TC/10) and if positive as 4 + (Tc/10).
If Tc < 128 Then Positive
SignBit = 1 ' minus
Tc = Tc ^ $ff + 1 ' 2's compliment
X = Tc / 10
X = 4 - X
GoTo Continue1
Positive:
SignBit = 0
X = Tc / 10
X = X + 4
A lookup table is then used to map index X into the temperature compensation factor and the RH is multiplied by this factor;
TempCorrection:
Lookup X, (87, 89, 91, 93, 95, 97, 99, 101, 103, 106, 108, 110, 113, 116, 119, 122, 126), TFactor
' -40 -30 -20 -10 0 10 20 30 40 50 60 70 80 90 100 110 120
If TFactor < 100 Then TempCorrection_1
TFactor = TFactor % 100
Dig = TFactor / 10
RH10 = RH10 * Dig / 10 + RH10
TFactor = TFactor % 10
Dig = TFactor
RH10 = RH10 * Dig / 100 + RH10
TempCorrection_2:
Return
TempCorrection_1:
Dig = TFactor / 10
RH10 = RH10 * Dig / 10
TFactor = TFactor % 10
Dig = TFactor
RH10 = RH10 * Dig / 100 + RH10
GoTo TempCorrection_2
Program HIH3610.Bas
' HIH3610.Bas
'
' Illustrates an interface with a Honeywell HIH-3610 humidity sensor and a DS18B20 to
' measure relative humidity.
'
' The program continually loops, displaying the temperature compensated RH and the temperature.
'
' HIH-3610 --------------------- AN2 (term 1)
'
' DS18B20 ---------------------- INPUT6 (term 15)
'
' Note that a 4.7K Ohm pull up to +5 is required on the DQ lead associated with the DS18B20.
'
' copyright, Peter H Anderson, Baltimore, MD, Jan, '04
Symbol ADVal = W0
Symbol HighWord = W1
Symbol LowWord = W2
Symbol RH10 = W3
Symbol Whole = B0
Symbol Fract = B1
Symbol X = B0
Symbol Dig = B1
Symbol TFactor = B2
Symbol Tc = B3
Symbol SignBit = B4
Top:
ReadADC10 2, ADVal ' perform A/D
HighWord = 1613 ** ADval ' calculate RH
LowWord = 1613 * ADVal
RH10 = LowWord / 1024
LowWord = Highword * 64
RH10 = RH10 + LowWord
RH10 = RH10 - 258
ReadTemp 6, Tc ' read Tc
If Tc < 128 Then Positive
SignBit = 1 ' minus
Tc = Tc ^ $ff + 1 ' 2's compliment
X = Tc / 10
X = 4 - X
GoTo Continue1
Positive:
SignBit = 0
X = Tc / 10
X = X + 4
Continue1:
GoSub TempCorrection ' compensate RH
Whole = RH10 / 10 ' display RH
Fract = RH10 % 10
If Whole > 99 Then OverRange
If Whole > 127 Then UnderRange
Continue2:
SerTxD (#Whole, ".", #Fract, " ")
If SignBit = 0 Then Continue3 ' display temperature
SerTxD ("-")
Continue3:
SerTxD (#Tc, 13, 10)
Wait 1
GoTo Top
OverRange:
Whole = 99
Fract = 9
GoTo Continue2
UnderRange:
Whole = 0
Fract = 0
GoTo Continue2
TempCorrection:
Lookup X, (87, 89, 91, 93, 95, 97, 99, 101, 103, 106, 108, 110, 113, 116, 119, 122, 126), TFactor
' -40 -30 -20 -10 0 10 20 30 40 50 60 70 80 90 100 110 120
If TFactor < 100 Then TempCorrection_1
TFactor = TFactor % 100
Dig = TFactor / 10
RH10 = RH10 * Dig / 10 + RH10
TFactor = TFactor % 10
Dig = TFactor
RH10 = RH10 * Dig / 100 + RH10
TempCorrection_2:
Return
TempCorrection_1:
Dig = TFactor / 10
RH10 = RH10 * Dig / 10
TFactor = TFactor % 10
Dig = TFactor
RH10 = RH10 * Dig / 100 + RH10
GoTo TempCorrection_2