Sebelumnya saya sudah pernah memposting Tutorial SHT11 dengan Bascom AVR, untuk mengetahui lebih detail tentang SHT11 bisa dilihat pada postingan tersebut.
Kali ini bedanya hanya pada bahasa pemrogramannya saja, yaitu bahasa C dengan CodeVision AVR.
Software yang saya gunakan adalah CV AVR versi 2.05.03 bisa didownload disini.
Pada tutorial ini data suhu dan kelembaban akan ditampilkan pada LCD. Skematiknya sebagai berikut:
Listing programnya sbb:
/*****************************************************
Program SHT11 dengan CodeVision AVR
Programmer : Wahyu Rahmaniar
Company : Technologination
*****************************************************/
#include <mega8535.h> //crystal 8MHz
#include <alcd.h>
#include <stdio.h>
#include <delay.h>
#include <stdlib.h >
#include <math.h >
//Deklarasi varaibel
unsigned char buf[33];
unsigned char error,checksum;
char inp;
typedef union
{ unsigned int i;
float f;
} value;
enum {TEMP,HUMI};
#define DATA_OUT PORTC.6
#define DATA_IN PINC.6
#define SCK PORTC.7
#define noACK 0
#define ACK 1
//adr command r/w
#define STATUS_REG_W 0x06 //000 0011 0
#define STATUS_REG_R 0x07 //000 0011 1
#define UKUR_SUHU 0x03 //000 0001 1
#define UKUR_HUMI 0x05 //000 0010 1
#define RESET 0x1e //000 1111 0
unsigned int nilaisuhu[2]={0,0};
//Untuk menulis data ke SHT11
char tulis_SHT(unsigned char bytte)
{
unsigned char i,error=0;
DDRC = 0b11000000;
for (i=0x80;i>0;i/=2) //shift bit
{
if (i & bytte)
DATA_OUT=1;
else DATA_OUT=0;
SCK=1; //clk
delay_us(5); //delay 5 us
SCK=0;
}
DATA_OUT=1;
DDRC = 0b10000000; // DATA Output
SCK=1; //clk #9 ack
delay_us(2);
error=DATA_IN; //cek ack (DATA akan di pull down oleh SHT11)
delay_us(2);
SCK=0;
return error; //cek jika ada error
}
//Untuk membaca data dari SHT11
char baca_SHT(unsigned char ack)
{
unsigned char i,val=0;
DDRC = 0b10000000; // DATA Input
for (i=0x80;i>0;i/=2) //shift bit
{ SCK=1; //clk
delay_us(2);
if (DATA_IN) val=(val | i); //baca bit
delay_us(2);
SCK=0;
}
DDRC = 0b11000000; // DATA Output
DATA_OUT=!ack; //"ack==1" pull down DATA-Line
SCK=1; //clk #9 ack
delay_us(5); //delay 5 us
SCK=0;
DATA_OUT=1; //DATA-line
return val;
}
//----------------------------------------------------------------------------------
// menghasilkan sinyal awal untuk transmisi data
// _____ ________
// DATA: |_______|
// ___ ___
// SCK : ___| |___| |______
//----------------------------------------------------------------------------------
//Untuk memulai transmisi data
void start_SHT(void)
{
DDRC = 0b11000000; // DATA Output
DATA_OUT=1; SCK=0; //Inisial state
delay_us(2);
SCK=1;
delay_us(2);
DATA_OUT=0;
delay_us(2);
SCK=0;
delay_us(5);
SCK=1;
delay_us(2);
DATA_OUT=1;
delay_us(2);
SCK=0;
DDRC = 0b10000000; // DATA Input
}
//----------------------------------------------------------------------------------
// reset: DATA-line=1 dengan 9 SCK cycle di awal
// _____________________________________________________ ________
// DATA: |_______|
// _ _ _ _ _ _ _ _ _ ___ ___
// SCK : __| |__| |__| |__| |__| |__| |__| |__| |__| |______| |___| |______
//----------------------------------------------------------------------------------
//Untuk mereset koneksi dengan SHT11
void reset_SHT(void)
{
unsigned char i;
DDRC = 0b11000000; // DATA output
DATA_OUT=1; SCK=0; //Inisial state
for(i=0;i<9;i++) //9 SCK cycle
{ SCK=1;
delay_us(1);
SCK=0;
delay_us(1);
}
start_SHT(); //start transmisi data
DDRC = 0b10000000; // DATA Input
}
//Mengecek status register sensor
char StatusReg_SHT(unsigned char *p_value, unsigned char *p_checksum)
{
unsigned char error=0;
start_SHT(); //start transmisi data
error=tulis_SHT(STATUS_REG_R); //mengirim command ke sensor
*p_value=baca_SHT(ACK); //baca status register (8-bit)
*p_checksum=baca_SHT(noACK); //baca checksum (8-bit)
return error; //error=1 jika tidak ada respon dari sensor
}
//Membaca data hasil pengukuran
char ukur_SHT(unsigned char *p_value, unsigned char *p_checksum, unsigned char mode)
{
unsigned error=0;
unsigned int temp=0;
start_SHT(); //start transmisi data
switch(mode){ //mengirim command ke sensor
case TEMP : error+=tulis_SHT(UKUR_SUHU); break;
case HUMI : error+=tulis_SHT(UKUR_HUMI); break;
default : break;
}
DDRC = 0b10000000; // DATA input
while (1)
{
if(DATA_IN==0) break;
Program SHT11 dengan CodeVision AVR
Programmer : Wahyu Rahmaniar
Company : Technologination
*****************************************************/
#include <mega8535.h> //crystal 8MHz
#include <alcd.h>
#include <stdio.h>
#include <delay.h>
#include <stdlib.h >
#include <math.h >
//Deklarasi varaibel
unsigned char buf[33];
unsigned char error,checksum;
char inp;
typedef union
{ unsigned int i;
float f;
} value;
enum {TEMP,HUMI};
#define DATA_OUT PORTC.6
#define DATA_IN PINC.6
#define SCK PORTC.7
#define noACK 0
#define ACK 1
//adr command r/w
#define STATUS_REG_W 0x06 //000 0011 0
#define STATUS_REG_R 0x07 //000 0011 1
#define UKUR_SUHU 0x03 //000 0001 1
#define UKUR_HUMI 0x05 //000 0010 1
#define RESET 0x1e //000 1111 0
unsigned int nilaisuhu[2]={0,0};
//Untuk menulis data ke SHT11
char tulis_SHT(unsigned char bytte)
{
unsigned char i,error=0;
DDRC = 0b11000000;
for (i=0x80;i>0;i/=2) //shift bit
{
if (i & bytte)
DATA_OUT=1;
else DATA_OUT=0;
SCK=1; //clk
delay_us(5); //delay 5 us
SCK=0;
}
DATA_OUT=1;
DDRC = 0b10000000; // DATA Output
SCK=1; //clk #9 ack
delay_us(2);
error=DATA_IN; //cek ack (DATA akan di pull down oleh SHT11)
delay_us(2);
SCK=0;
return error; //cek jika ada error
}
//Untuk membaca data dari SHT11
char baca_SHT(unsigned char ack)
{
unsigned char i,val=0;
DDRC = 0b10000000; // DATA Input
for (i=0x80;i>0;i/=2) //shift bit
{ SCK=1; //clk
delay_us(2);
if (DATA_IN) val=(val | i); //baca bit
delay_us(2);
SCK=0;
}
DDRC = 0b11000000; // DATA Output
DATA_OUT=!ack; //"ack==1" pull down DATA-Line
SCK=1; //clk #9 ack
delay_us(5); //delay 5 us
SCK=0;
DATA_OUT=1; //DATA-line
return val;
}
//----------------------------------------------------------------------------------
// menghasilkan sinyal awal untuk transmisi data
// _____ ________
// DATA: |_______|
// ___ ___
// SCK : ___| |___| |______
//----------------------------------------------------------------------------------
//Untuk memulai transmisi data
void start_SHT(void)
{
DDRC = 0b11000000; // DATA Output
DATA_OUT=1; SCK=0; //Inisial state
delay_us(2);
SCK=1;
delay_us(2);
DATA_OUT=0;
delay_us(2);
SCK=0;
delay_us(5);
SCK=1;
delay_us(2);
DATA_OUT=1;
delay_us(2);
SCK=0;
DDRC = 0b10000000; // DATA Input
}
//----------------------------------------------------------------------------------
// reset: DATA-line=1 dengan 9 SCK cycle di awal
// _____________________________________________________ ________
// DATA: |_______|
// _ _ _ _ _ _ _ _ _ ___ ___
// SCK : __| |__| |__| |__| |__| |__| |__| |__| |__| |______| |___| |______
//----------------------------------------------------------------------------------
//Untuk mereset koneksi dengan SHT11
void reset_SHT(void)
{
unsigned char i;
DDRC = 0b11000000; // DATA output
DATA_OUT=1; SCK=0; //Inisial state
for(i=0;i<9;i++) //9 SCK cycle
{ SCK=1;
delay_us(1);
SCK=0;
delay_us(1);
}
start_SHT(); //start transmisi data
DDRC = 0b10000000; // DATA Input
}
//Mengecek status register sensor
char StatusReg_SHT(unsigned char *p_value, unsigned char *p_checksum)
{
unsigned char error=0;
start_SHT(); //start transmisi data
error=tulis_SHT(STATUS_REG_R); //mengirim command ke sensor
*p_value=baca_SHT(ACK); //baca status register (8-bit)
*p_checksum=baca_SHT(noACK); //baca checksum (8-bit)
return error; //error=1 jika tidak ada respon dari sensor
}
//Membaca data hasil pengukuran
char ukur_SHT(unsigned char *p_value, unsigned char *p_checksum, unsigned char mode)
{
unsigned error=0;
unsigned int temp=0;
start_SHT(); //start transmisi data
switch(mode){ //mengirim command ke sensor
case TEMP : error+=tulis_SHT(UKUR_SUHU); break;
case HUMI : error+=tulis_SHT(UKUR_HUMI); break;
default : break;
}
DDRC = 0b10000000; // DATA input
while (1)
{
if(DATA_IN==0) break;
//tunggu hingga sensor selesai melakukan pengukuran
}
if(DATA_IN) error+=1;
}
if(DATA_IN) error+=1;
// jika sudah timeout (2 detik)
switch(mode){ //mengirim command ke sensor
case TEMP : temp=0;
temp=baca_SHT(ACK);
temp<<=8;
nilaisuhu[0]=temp;
temp=0;
temp=baca_SHT(ACK);
nilaisuhu[0]|=temp;
break;
case HUMI : temp=0;
temp=baca_SHT(ACK);
temp<<=8;
nilaisuhu[1]=temp;
temp=0;
temp=baca_SHT(ACK);
nilaisuhu[1]|=temp;
break;
default : break;
}
*p_checksum =baca_SHT(noACK); //baca checksum
return error;
}
const float C1=-4.0;
const float C2=+0.0405;
const float C3=-0.0000028;
const float T1=+0.01;
const float T2=+0.00008;
float hitung_SHT(float p_humidity, float *p_temperature)
{
float rh_lin; // rh_lin: Kelembaban linear
float rh_true; // rh_true: Suhu untuk kompensasi kelembaban
float t_C; // t_C : nilai Suhu
t_C=*p_temperature*0.01-40;
switch(mode){ //mengirim command ke sensor
case TEMP : temp=0;
temp=baca_SHT(ACK);
temp<<=8;
nilaisuhu[0]=temp;
temp=0;
temp=baca_SHT(ACK);
nilaisuhu[0]|=temp;
break;
case HUMI : temp=0;
temp=baca_SHT(ACK);
temp<<=8;
nilaisuhu[1]=temp;
temp=0;
temp=baca_SHT(ACK);
nilaisuhu[1]|=temp;
break;
default : break;
}
*p_checksum =baca_SHT(noACK); //baca checksum
return error;
}
const float C1=-4.0;
const float C2=+0.0405;
const float C3=-0.0000028;
const float T1=+0.01;
const float T2=+0.00008;
float hitung_SHT(float p_humidity, float *p_temperature)
{
float rh_lin; // rh_lin: Kelembaban linear
float rh_true; // rh_true: Suhu untuk kompensasi kelembaban
float t_C; // t_C : nilai Suhu
t_C=*p_temperature*0.01-40;
//mengubah nilai Suhu menjadi derajat Celcius [°C]
rh_lin=C3*(p_humidity)*(p_humidity) + C2*(p_humidity) + C1;
rh_lin=C3*(p_humidity)*(p_humidity) + C2*(p_humidity) + C1;
//mengubah nilai kelembaban dalam % [%RH]
rh_true=(t_C-25)*(T1+T2*(p_humidity))+rh_lin;
rh_true=(t_C-25)*(T1+T2*(p_humidity))+rh_lin;
//mengkompensasikan nilai suhu dan kelembaban[%RH]
if(rh_true>100)rh_true=100;
if(rh_true<0.1)rh_true=0.1;
*p_temperature=t_C;
return rh_true;
}
void main(void)
{
value humi_val,temp_val;
PORTA=0x00;
DDRA=0x00;
PORTB=0xFF;
DDRB=0x00;
PORTC=0x00;
DDRC=0xC0;
PORTD=0xF0;
DDRD=0xF0;
// USART initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART Receiver: On
// USART Transmitter: On
// USART Mode: Asynchronous
// USART Baud Rate: 9600
UCSRA=0x00;
UCSRB=0x18;
UCSRC=0x86;
UBRRH=0x00;
UBRRL=0x47;
ACSR=0x80;
SFIOR=0x00;
ADCSRA=0x00;
SPCR=0x00;
TWCR=0x00;
// Alphanumeric LCD initialization
// Connections specified in the
// Project|Configure|C Compiler|Libraries|Alphanumeric LCD menu:
// RS - PORTA Bit 0
// RD - PORTA Bit 1
// EN - PORTA Bit 2
// D4 - PORTA Bit 4
// D5 - PORTA Bit 5
// D6 - PORTA Bit 6
// D7 - PORTA Bit 7
// Characters/line: 16
lcd_init(16);
lcd_clear();
lcd_gotoxy(3,0);
lcd_putsf("Data Suhu");
lcd_gotoxy(1,1);
lcd_putsf("dan Kelembaban");
delay_ms(1000);
lcd_init(16);
lcd_clear();
lcd_gotoxy(0,0);
lcd_putsf("Wahyu Rahmaniar");
lcd_gotoxy(0,1);
lcd_putsf("===============");
delay_ms(1000);
lcd_init(16);
lcd_clear();
lcd_gotoxy(0,0);
lcd_putsf("TECHNOLOGINATION");
lcd_gotoxy(0,1);
lcd_putsf("================");
delay_ms(1000);
reset_SHT();
while (1)
{
//delay_ms(500);
error=0;
error+=ukur_SHT((unsigned char*)( &humi_val.i),&checksum,HUMI); //mengukur kelembaban
error+=ukur_SHT((unsigned char*) (&temp_val.i),&checksum,TEMP); //mengukur suhu
error += StatusReg_SHT(&inp, &checksum);
if(error!=0)
{
reset_SHT(); //jika ada error, reset koneksi
putsf("Error");
}
else
{
humi_val.f=(float)nilaisuhu[1];
if(rh_true>100)rh_true=100;
if(rh_true<0.1)rh_true=0.1;
*p_temperature=t_C;
return rh_true;
}
void main(void)
{
value humi_val,temp_val;
PORTA=0x00;
DDRA=0x00;
PORTB=0xFF;
DDRB=0x00;
PORTC=0x00;
DDRC=0xC0;
PORTD=0xF0;
DDRD=0xF0;
// USART initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART Receiver: On
// USART Transmitter: On
// USART Mode: Asynchronous
// USART Baud Rate: 9600
UCSRA=0x00;
UCSRB=0x18;
UCSRC=0x86;
UBRRH=0x00;
UBRRL=0x47;
ACSR=0x80;
SFIOR=0x00;
ADCSRA=0x00;
SPCR=0x00;
TWCR=0x00;
// Alphanumeric LCD initialization
// Connections specified in the
// Project|Configure|C Compiler|Libraries|Alphanumeric LCD menu:
// RS - PORTA Bit 0
// RD - PORTA Bit 1
// EN - PORTA Bit 2
// D4 - PORTA Bit 4
// D5 - PORTA Bit 5
// D6 - PORTA Bit 6
// D7 - PORTA Bit 7
// Characters/line: 16
lcd_init(16);
lcd_clear();
lcd_gotoxy(3,0);
lcd_putsf("Data Suhu");
lcd_gotoxy(1,1);
lcd_putsf("dan Kelembaban");
delay_ms(1000);
lcd_init(16);
lcd_clear();
lcd_gotoxy(0,0);
lcd_putsf("Wahyu Rahmaniar");
lcd_gotoxy(0,1);
lcd_putsf("===============");
delay_ms(1000);
lcd_init(16);
lcd_clear();
lcd_gotoxy(0,0);
lcd_putsf("TECHNOLOGINATION");
lcd_gotoxy(0,1);
lcd_putsf("================");
delay_ms(1000);
reset_SHT();
while (1)
{
//delay_ms(500);
error=0;
error+=ukur_SHT((unsigned char*)( &humi_val.i),&checksum,HUMI); //mengukur kelembaban
error+=ukur_SHT((unsigned char*) (&temp_val.i),&checksum,TEMP); //mengukur suhu
error += StatusReg_SHT(&inp, &checksum);
if(error!=0)
{
reset_SHT(); //jika ada error, reset koneksi
putsf("Error");
}
else
{
humi_val.f=(float)nilaisuhu[1];
//mengubah integer menjadi float
temp_val.f=(float)nilaisuhu[0];
humi_val.f=hitung_SHT(humi_val.f,&temp_val.f);
temp_val.f=(float)nilaisuhu[0];
humi_val.f=hitung_SHT(humi_val.f,&temp_val.f);
//menghitung suhu, kelembaban
//menampilkan pada LCD
lcd_clear();
lcd_gotoxy(0,0);
sprintf(buf,"SUHU = %0.2f \xdfC",temp_val.f);
lcd_puts(buf);
lcd_gotoxy(0,1);
sprintf(buf,"RH = %0.2f %%",humi_val.f);
lcd_puts(buf);
}
delay_ms(1000);
}
}
Souce code lengkap dan simulasi dengan proteus bisa didownload disini.//menampilkan pada LCD
lcd_clear();
lcd_gotoxy(0,0);
sprintf(buf,"SUHU = %0.2f \xdfC",temp_val.f);
lcd_puts(buf);
lcd_gotoxy(0,1);
sprintf(buf,"RH = %0.2f %%",humi_val.f);
lcd_puts(buf);
}
delay_ms(1000);
}
}
-ayuchan-