You are on page 1of 9

ATmega8 SHT71 Temperature Humidity and Dew point example

http://www.electronics-base.com/projects/complete-projects/152-atmega8-sht71temperature-humidity-and-dew-point-example
\
Published on Monday, 19 March 2012 20:54 | Written by Super User | Hits: 4918

In this article is provided 100% tested and working


C code for AVR readout of SHT71 Temperature, Humidity and Dew point. Code itself is well
commented and is easy to understand if combined with SHT71 Humidity and Temperature
Sensor IC article.
DATA pin is connected to Port C pin 0.
SCK pin is connected to Port C pin 1.
Pull-up resistor must be placed on DATA pin. Pull-up resistor of 10k to +5V is used in this
example.
Be careful that if you use Port C for other things lines that change its direction will change it. For
example
?

1 DDRC = 0b00000011;

//

If this is the case just change only bits for selected pins for DATA and SCK.

Complete project written in Codevision AVR C compiler written for ATmega8 can be downloaded
from this link. Complete code is provided below this text and video showing demonstration of this
code in action can be found at the bottom of this page. Data is read from serial port by com port
terminal - development tool.
?

1
2
3
4
5
6
7
8
9
10
11
12

/*****************************************************
Complete example with more comments and further support can be found at
www.Electronics-Base.com under complete projects section
Date
: 3/19/2012
Author : www.Electronics-Base.com
Chip type
: ATmega8
Program type
: Application
AVR Core Clock frequency: 8.000000 MHz
Memory model
: Small
External RAM size
: 0
Data Stack size
: 256
www.Electronics-Base.com
*****************************************************/
#include <mega8.h>
// Standard Input/Output functions

13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57

#include <stdio.h>
//must be included
#include <delay.h>
//must be included
#include <stdlib.h
//must be included
#include <math.h >

to use delay functions


to use itoa ftoa functions
>
to use log10 functions

typedef union
{ unsigned int i;
float f;
} value;
enum {TEMP,HUMI};
#define
DATA_OUT
#define
DATA_IN
#define
SCK
#define noACK 0
#define ACK
1

PORTC.0
PINC.0
PORTC.1

//adr command r/w


#define STATUS_REG_W 0x06
//000
0011
0
#define STATUS_REG_R 0x07
//000
0011
1
#define MEASURE_TEMP 0x03
//000
0001
1
#define MEASURE_HUMI 0x05
//000
0010
1
#define RESET
0x1e
//000
1111
0
// Declare your global variables here
unsigned int tempervalue[2]={0,0};
/***********************************/
char SHT_WriteByte(unsigned char bytte)
{
unsigned char i,error=0;
DDRC = 0b00000011;
//
for (i=0x80;i>0;i/=2) //shift bit for masking
{
if (i & bytte)
DATA_OUT=1; //masking value with i , write to SENSI-BUS
else DATA_OUT=0;
SCK=1;
//clk for SENSI-BUS
delay_us(5); //pulswith approx. 5 us
SCK=0;
}
DATA_OUT=1;
//release dataline
DDRC = 0b00000010;
// DATA is Output
SCK=1;
//clk #9 for ack
delay_us(2);
error=DATA_IN;
//check ack (DATA will be pulled down by SHT11)
delay_us(2);
SCK=0;
return error;
//error=1 in case of no acknowledge
}
//--------------------------------------------------------------------------------// reads a byte form the Sensibus and gives an acknowledge in case of
"ack=1"
//-----------------------------------------------------------------------

58 ----------59 char SHT_ReadByte(unsigned char ack)


{
60
unsigned char i,val=0;
61
DDRC = 0b00000010;
// DATA is Input
for (i=0x80;i>0;i/=2)
//shift bit for masking
62
{ SCK=1;
//clk for SENSI-BUS
63
delay_us(2);
64
if (DATA_IN) val=(val | i);
//read bit
65
delay_us(2);
66
SCK=0;
}
67
DDRC = 0b00000011;
// DATA is Output
68
DATA_OUT=!ack;
//in case of "ack==1" pull down DATA-Line
69
SCK=1;
//clk #9 for ack
70
delay_us(5);
//pulswith approx. 5 us
71
SCK=0;
DATA_OUT=1;
//release DATA-line //ADD BY
72
LUBING
73
return val;
74 }
75 //----------------------------------------------------------------------76 ----------77 // generates a transmission start
_____
________
78 //
// DATA:
|_______|
79 //
___
___
80 // SCK : ___|
|___|
|______
//----------------------------------------------------------------------81
82 ----------void SHT_Transstart(void)
83 {
84
DDRC = 0b00000011;
// DATA is Output
85
DATA_OUT=1; SCK=0;
//Initial state
delay_us(2);
86
SCK=1;
87
delay_us(2);
88
DATA_OUT=0;
89
delay_us(2);
90
SCK=0;
delay_us(5);
91
SCK=1;
92
delay_us(2);
93
DATA_OUT=1;
94
delay_us(2);
SCK=0;
95
DDRC = 0b00000010;
// DATA is Input
96
}
97
//----------------------------------------------------------------------98 ----------99 // communication reset: DATA-line=1 and at least 9 SCK cycles followed by
100 transstart
_____________________________________________________
101 //
________
102

|_______|
103 // DATA:
//
_
_
_
_
_
_
_
_
_
___
___
104
// SCK : __| |__| |__| |__| |__| |__| |__| |__| |__| |______|
|___|
|
105 ______
106 //----------------------------------------------------------------------107 ----------108 void SHT_ConnectionRest(void)
{
109 unsigned char i;
110 DDRC = 0b00000011;
// DATA is output
111 DATA_OUT=1; SCK=0;
//Initial state
for(i=0;i<9;i++)
//9
SCK cycles
112
{
SCK=1;
113
delay_us(1);
114
SCK=0;
115
delay_us(1);
116 }
//transmission start
117 SHT_Transstart();
DDRC = 0b00000010;
// DATA is Input
118
}
119 //----------------------------------------------------------------------120 ----------121 // resets the sensor by a softreset
122 //--------------------------------------------------------------------------------123 char SHT_SoftRst(void)
124 {
125 unsigned char error=0;
//reset communication
126 SHT_ConnectionRest();
error+=SHT_WriteByte(RESET);
//send RESET-command to sensor
127
return error;
//error=1 in case of no response form
128 the sensor
129 }
130 //----------------------------------------------------------------------131 ----------reads the status register with checksum (8-bit)
132 //
//----------------------------------------------------------------------133 ----------134 char SHT_Read_StatusReg(unsigned char *p_value, unsigned char *p_checksum)
135 {
136 unsigned char error=0;
SHT_Transstart();
//transmission start
137 error=SHT_WriteByte(STATUS_REG_R); //send command to sensor
138 *p_value=SHT_ReadByte(ACK);
//read status register (8-bit)
139 *p_checksum=SHT_ReadByte(noACK);
//read checksum (8-bit)
return
error;
//error=1
in case of no response form
140
the sensor
141
}
142 //----------------------------------------------------------------------143 ----------144 // writes the status register with checksum (8-bit)
145 //--------------------------------------------------------------------------------146 char SHT_Write_StatusReg(unsigned char *p_value)
147 {

148 unsigned char error=0;


//transmission start
149 SHT_Transstart();
error+=SHT_WriteByte(STATUS_REG_W);//send command to sensor
150 error+=SHT_WriteByte(*p_value);
//send value of status register
151 return error;
//error>=1 in case of no response form
152 the sensor
153 }
//----------------------------------------------------------------------154 ----------155 // makes a measurement (humidity/temperature) with checksum
156 //----------------------------------------------------------------------157 ----------158 char SHT_Measure(unsigned char *p_value, unsigned char *p_checksum,
unsigned char mode)
159 {
160 unsigned error=0;
161 unsigned int temp=0;
//transmission start
162 SHT_Transstart();
switch(mode){
//send command to sensor
163
case TEMP
: error+=SHT_WriteByte(MEASURE_TEMP); break;
164
case HUMI
: error+=SHT_WriteByte(MEASURE_HUMI); break;
165
default
: break;
166 }
// DATA is input
167 DDRC = 0b00000010;
while
(1)
168
{
169
if(DATA_IN==0) break; //wait until sensor has finished the measurement
170 }
171 if(DATA_IN) error+=1;
// or timeout (~2 sec.) is
172 reached
//send command to sensor
173 switch(mode){
case TEMP
: temp=0;
174
temp=SHT_ReadByte(ACK);
175
temp<<=8;
176
tempervalue[0]=temp;
temp=0;
177
temp=SHT_ReadByte(ACK);
178
tempervalue[0]|=temp;
179
break;
180
case HUMI
: temp=0;
temp=SHT_ReadByte(ACK);
181
temp<<=8;
182
tempervalue[1]=temp;
183
temp=0;
184
temp=SHT_ReadByte(ACK);
185
tempervalue[1]|=temp;
break;
186
default
: break;
187
188 }
189 *p_checksum =SHT_ReadByte(noACK); //read checksum
return error;
190 }
191 //----------------------------------------------------------------------192 -----------------

193 // calculates temperature [?] and humidity [%RH]


194 // input : humi [Ticks] (12 bit)
//
temp [Ticks] (14 bit)
195 // output: humi [%RH]
196 //
temp [?]
197 //----------------------------------------------------------------------198 ----------------199
float C1=-4.0;
// for 12 Bit
200 const
const float C2=+0.0405;
// for 12 Bit
201 const float C3=-0.0000028;
// for 12 Bit
202 const float T1=+0.01;
// for 14 Bit @ 5V
// for 14 Bit @ 5V
203 const float T2=+0.00008;
204
205 float Calc_SHT71(float p_humidity ,float *p_temperature)
206 {
float rh_lin;
// rh_lin: Humidity linear
207
float rh_true;
// rh_true: Temperature compensated
208 humidity
// t:
Temperature [Ticks] 14 Bit
209 float t=*p_temperature;
float
rh=p_humidity;
//
rh:
Humidity
[Ticks] 12 Bit
210
float t_C;
// t_C
: Temperature [?]
211 t_C=t*0.01 - 40;
//calc. temperature from ticks to [?]
212 rh_lin=C3*rh*rh + C2*rh + C1;
//calc. humidity from ticks to [%RH]
213 rh_true=(t_C-25)*(T1+T2*rh)+rh_lin;
//calc. temperature compensated
humidity
[%RH]
214
//cut if the value is outside of
215 if(rh_true>100)rh_true=100;
if(rh_true<0.1)rh_true=0.1;
//the physical possible range
216 *p_temperature=t_C;
//return temperature [?]
217
return rh_true;
218 }
219 //-------------------------------------------------------------------220 float Calc_dewpoint(float h,float t)
//-------------------------------------------------------------------221 // calculates dew point
222 // input:
humidity [%RH], temperature [?]
//
output:
dew point [?]
223
{
float
logEx,dew_point;
224
225 logEx=0.66077+7.5*t/(237.3+t)+(log10(h)-2);
dew_point = (logEx - 0.66077)*237.3/(0.66077+7.5-logEx);
226 return dew_point;
227 }
228 // Declare your global variables here
229 void main(void)
{
230 // Declare your local variables here
231 value humi_val,temp_val;
232 unsigned char error,checksum;
233 float dewpoint=0.0;
234 //unsigned char outp;
//unsigned int humi;
235 char inp;
236 unsigned char Humidity[5]={0,0,0,0,0};
237 unsigned char Temperture[5]={0,0,0,0,0};

238 unsigned char Depoint[5]={0,0,0,0,0};


239
240 // Input/Output Ports initialization
// Port B initialization
241 // Func7=In Func6=In Func5=In Func4=In Func3=In
242 Func0=In
243 // State7=T State6=T State5=T State4=T State3=T
244 State0=T
PORTB=0x00;
245 DDRB=0x00;
246 // Port C initialization
247 // Func6=In Func5=In Func4=In Func3=In Func2=In
248 // State6=T State5=T State4=T State3=T State2=T
249 PORTC=0x00;
DDRC=0x00;
250 // Port D initialization
251 // Func7=In Func6=In Func5=In Func4=In Func3=In
252 Func0=In
253 // State7=T State6=T State5=T State4=T State3=T
254 State0=T
PORTD=0x00;
255 DDRD=0x00;
256 // Timer/Counter 0 initialization
257 // Clock source: System Clock
258 // Clock value: Timer 0 Stopped
TCCR0=0x00;
259 TCNT0=0x00;
260 // Timer/Counter 1 initialization
261 // Clock source: System Clock
262 // Clock value: Timer1 Stopped
263 // Mode: Normal top=FFFFh
// OC1A output: Discon.
264 // OC1B output: Discon.
265 // Noise Canceler: Off
266 // Input Capture on Falling Edge
267 // Timer1 Overflow Interrupt: Off
268 // Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
269 // Compare B Match Interrupt: Off
270 TCCR1A=0x00;
271 TCCR1B=0x00;
272 TCNT1H=0x00;
273 TCNT1L=0x00;
ICR1H=0x00;
274 ICR1L=0x00;
275 OCR1AH=0x00;
276 OCR1AL=0x00;
277 OCR1BH=0x00;
278 OCR1BL=0x00;
// Timer/Counter 2 initialization
279 // Clock source: System Clock
280 // Clock value: Timer2 Stopped
281 // Mode: Normal top=FFh
282 // OC2 output: Disconnected

Func2=In Func1=In
State2=T State1=T

Func1=In Func0=In
State1=T State0=T

Func2=In Func1=In
State2=T State1=T

283 ASSR=0x00;
284 TCCR2=0x00;
TCNT2=0x00;
285 OCR2=0x00;
286 // External Interrupt(s) initialization
287 // INT0: Off
288 // INT1: Off
289 MCUCR=0x00;
// Timer(s)/Counter(s) Interrupt(s) initialization
290 TIMSK=0x00;
291 // USART initialization
292 // Communication Parameters: 8 Data, 1 Stop, No Parity
293 // USART Receiver: Off
// USART Transmitter: On
294 // USART Mode: Asynchronous
295 // USART Baud Rate: 9600
296 UCSRA=0x00;
297 UCSRB=0x08;
298 UCSRC=0x86;
UBRRH=0x00;
299 UBRRL=0x33;
300 // Analog Comparator initialization
301 // Analog Comparator: Off
302 // Analog Comparator Input Capture by Timer/Counter 1: Off
303 ACSR=0x80;
SFIOR=0x00;
304 SHT_ConnectionRest();
305
306 while (1)
307
{
// Place your code here
308
delay_ms(500);
309
error=0;
310
error+=SHT_Measure((unsigned char*)( &humi_val.i),&checksum,HUMI);
311 //measure humidity
error+=SHT_Measure((unsigned char*) (&temp_val.i),&checksum,TEMP);
312
//measure
temperature
313
error += SHT_Read_StatusReg(&inp, &checksum);
314
if(error!=0)
315
{
316
SHT_ConnectionRest();
//in case of an error:
317 connection reset
putsf("Error");
318
}
319
else
320
{
321
humi_val.f=(float)tempervalue[1];
//converts
integer
to
float
322
temp_val.f=(float)tempervalue[0];
//converts
323
integer to float
324
humi_val.f=Calc_SHT71(humi_val.f,&temp_val.f);
//calculate
325 humidity, temperature
dewpoint=Calc_dewpoint(humi_val.f,temp_val.f) ;
326
ftoa(humi_val.f,2,Humidity);
327

328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353 }
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369

putsf(" Humidity: ");


puts(Humidity);
ftoa(temp_val.f,2,Temperture);
putsf(" Temperature: ");
puts(Temperture);
ftoa(dewpoint,2,Depoint);
putsf(" dewpoint: ");
puts(Depoint);
}
delay_ms(100);
putchar(13);
};

You might also like