Senin, 22 Oktober 2012

Tutorial Sensor Suhu dan Kelembaban SHT11 dengan CodeVision AVR

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; 
//tunggu hingga sensor selesai melakukan pengukuran
  }
  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; 
//mengubah nilai Suhu menjadi derajat Celcius [°C]
  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; 
//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];                   
//mengubah integer menjadi float
       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.

Tempat Jual Komponen dan Elektronik.

-ayuchan-