Thursday, October 15, 2015

DHT11 Proteus Simulation

DHT11 Sensor Proteus Simulation

Let's continue our projects about the Digital Temperature and Humidity sensor DHT11 and see how to simulate these two sensors using Poroteus software.
Proteus version 8.1 or higher is required to do this simulation and the DHT11 library is included in these versions and there is no need to add it manually (Proteus version 8.0 or lower will not work so you have to update your version).
First of all you have to read the DHT11 datasheet in order to understand how this device works and also to understand the programming codes.
The DHT11 uses one-wire protocol to communicate with master device (microprocessor or microcontroller), first the master device sends a start signal and then when this start signal detected by the sensor it sends a response signal to the master device, after that the sensor starts sending data which has 40-bit long, first 16 bits for humidity (byte 1 and byte 2) and the second 16 bits for temperature (byte 1 and byte 2) and the last byte is a check-sum to know whether the data has been sent correctly or not. Note that data is sent byte by byte and for the DHT11 humidity byte 2 and temperature byte 2 are both zeros.

Interfacing PIC18F4550 with DHT11 digital humidity and temperature sensor:

The following circuit schematic is the simulation of DHT11 with PIC18F4550 microcontroller using Proteus:
dht11 proteus simulation dhtxx.mdf

The internal oscillator for the microcontroller is used at 8MHz and the MCLR pin is disabled.
The data pin of the sensor is connected to RD0 of the microcontroller and pulled up by 4.7 K Ohm resistor where this resistor must be set to DIGITAL as shown on the picture above, it can be done easily by editing the properties of the resistor.
Interfacing PIC18F4550 with DHT11 MikroC code: 

 //PIC18F4550 DHT11 digital humidity and
 //       temperature sensor MikroC code
//Written by: BENCHEROUDA Okba
//electronnote@gmail.com
//Internal crystal used at 8MHz
//Use at your own risk


// LCD module connections
 sbit LCD_RS at RB0_bit;
 sbit LCD_EN at RB1_bit;
 sbit LCD_D4 at RB2_bit;
 sbit LCD_D5 at RB3_bit;
 sbit LCD_D6 at RB4_bit;
 sbit LCD_D7 at RB5_bit;
 sbit LCD_RS_Direction at TRISB0_bit;
 sbit LCD_EN_Direction at TRISB1_bit;
 sbit LCD_D4_Direction at TRISB2_bit;
 sbit LCD_D5_Direction at TRISB3_bit;
 sbit LCD_D6_Direction at TRISB4_bit;
 sbit LCD_D7_Direction at TRISB5_bit;
 // End LCD module connections
 unsigned char  Check, T_byte1, T_byte2,
                RH_byte1, RH_byte2, Ch ;
 unsigned Temp, RH, Sum ;
void StartSignal(){
 TRISD.F0 = 0;    //Configure RD0 as output
 PORTD.F0 = 0;    //RD0 sends 0 to the sensor
 delay_ms(18);
 PORTD.F0 = 1;    //RD0 sends 1 to the sensor
 delay_us(30);
 TRISD.F0 = 1;    //Configure RD0 as input
  }
 //////////////////////////////
 void CheckResponse(){
 Check = 0;
 delay_us(40);
 if (PORTD.F0 == 0){
 delay_us(80);
 if (PORTD.F0 == 1)   Check = 1;   delay_us(40);}
 }
 //////////////////////////////
 char ReadData(){
 char i, j;
 for(j = 0; j < 8; j++){
 while(!PORTD.F0); //Wait until PORTD.F0 goes HIGH
 delay_us(30);
 if(PORTD.F0 == 0)
       i&= ~(1<<(7 - j));  //Clear bit (7-b)
 else {i|= (1 << (7 - j));  //Set bit (7-b)
 while(PORTD.F0);}  //Wait until PORTD.F0 goes LOW
 }
 return i;
 }
 //////////////////////////////
void main() {
 OSCCON =  0X70;       // Set internal oscillator at 8MHz
 ADCON1 = 0x0F;        // Configure AN pins as digital
 TRISD.F1 = 0;
 Lcd_Init();
 Lcd_Cmd(_LCD_CURSOR_OFF);        // cursor off
 Lcd_Cmd(_LCD_CLEAR);            // clear LCD
 while(1){
 StartSignal();
  CheckResponse();
  if(Check == 1){
  RH_byte1 = ReadData();
  RH_byte2 = ReadData();
  T_byte1 = ReadData();
  T_byte2 = ReadData();
  Sum = ReadData();
  if(Sum == ((RH_byte1+RH_byte2+T_byte1+T_byte2) & 0XFF)){
  Temp = T_byte1;
  RH = RH_byte1;
  Lcd_Out(1, 6, "Temp:   C");
  Lcd_Out(2, 2, "Humidity:   %");
  LCD_Chr(1, 12, 48 + ((Temp / 10) % 10));
  LCD_Chr(1, 13, 48 + (Temp % 10));
  LCD_Chr(2, 12, 48 + ((RH / 10) % 10));
  LCD_Chr(2, 13, 48 + (RH % 10));
  }
  else{
  Lcd_Cmd(_LCD_CURSOR_OFF);        // cursor off
  Lcd_Cmd(_LCD_CLEAR);             // clear LCD
  Lcd_Out(1, 1, "Check sum error");}
  }
  else {
  Lcd_Out(1, 3, "No response");
  Lcd_Out(2, 1, "from the sensor");
  }
  delay_ms(1000);
  }
}

Proteus Simulation Video:




Interfacing PIC16F887 with DHT11 digital humidity and temperature sensor:
Let's do our interfacing and simulation using another microcontroller which is PIC16F887, the circuit shown below:
dht11 proteus simulation mikroc code

 For this microcontroller the internal oscillator is used at 8MHz and the MCLR pin is disabled.
Interfacing PIC16F887 with DHT11 MikroC code:

 //PIC16F887 DHT11 digital humidity and
 //       temperature sensor MikroC code
//Written by: BENCHEROUDA Okba
//electronnote@gmail.com
//Internal crystal used at 8MHz
//Use at your own risk


// LCD module connections
 sbit LCD_RS at RB0_bit;
 sbit LCD_EN at RB1_bit;
 sbit LCD_D4 at RB2_bit;
 sbit LCD_D5 at RB3_bit;
 sbit LCD_D6 at RB4_bit;
 sbit LCD_D7 at RB5_bit;
 sbit LCD_RS_Direction at TRISB0_bit;
 sbit LCD_EN_Direction at TRISB1_bit;
 sbit LCD_D4_Direction at TRISB2_bit;
 sbit LCD_D5_Direction at TRISB3_bit;
 sbit LCD_D6_Direction at TRISB4_bit;
 sbit LCD_D7_Direction at TRISB5_bit;
 // End LCD module connections
 unsigned char  Check, T_byte1, T_byte2,
                RH_byte1, RH_byte2, Ch ;
 unsigned Temp, RH, Sum ;
void StartSignal(){
 TRISD.F0 = 0;    //Configure RD0 as output
 PORTD.F0 = 0;    //RD0 sends 0 to the sensor
 delay_ms(18);
 PORTD.F0 = 1;    //RD0 sends 1 to the sensor
 delay_us(30);
 TRISD.F0 = 1;    //Configure RD0 as input
  }
 //////////////////////////////
 void CheckResponse(){
 Check = 0;
 delay_us(40);
 if (PORTD.F0 == 0){
 delay_us(80);
 if (PORTD.F0 == 1)   Check = 1;   delay_us(40);}
 }
 //////////////////////////////
 char ReadData(){
 char i, j;
 for(j = 0; j < 8; j++){
 while(!PORTD.F0); //Wait until PORTD.F0 goes HIGH
 delay_us(30);
 if(PORTD.F0 == 0)
       i&= ~(1<<(7 - j));  //Clear bit (7-b)
 else {i|= (1 << (7 - j));  //Set bit (7-b)
 while(PORTD.F0);}  //Wait until PORTD.F0 goes LOW
 }
 return i;
 }
 //////////////////////////////
void main() {
 OSCCON =  0X70;       // Set internal oscillator at 8MHz
 ANSEL = 0;        // Configure AN pins as digital
 ANSELH = 0;
 TRISD.F1 = 0;
 Lcd_Init();
 Lcd_Cmd(_LCD_CURSOR_OFF);        // cursor off
 Lcd_Cmd(_LCD_CLEAR);            // clear LCD
 while(1){
 StartSignal();
  CheckResponse();
  if(Check == 1){
  RH_byte1 = ReadData();
  RH_byte2 = ReadData();
  T_byte1 = ReadData();
  T_byte2 = ReadData();
  Sum = ReadData();
  if(Sum == ((RH_byte1+RH_byte2+T_byte1+T_byte2) & 0XFF)){
  Temp = T_byte1;
  RH = RH_byte1;
  Lcd_Out(1, 6, "Temp:   C");
  Lcd_Out(2, 2, "Humidity:   %");
  LCD_Chr(1, 12, 48 + ((Temp / 10) % 10));
  LCD_Chr(1, 13, 48 + (Temp % 10));
  LCD_Chr(2, 12, 48 + ((RH / 10) % 10));
  LCD_Chr(2, 13, 48 + (RH % 10));
  }
  else{
  Lcd_Cmd(_LCD_CURSOR_OFF);        // cursor off
  Lcd_Cmd(_LCD_CLEAR);             // clear LCD
  Lcd_Out(1, 1, "Check sum error");}
  }
  else {
  Lcd_Out(1, 3, "No response");
  Lcd_Out(2, 1, "from the sensor");
  }
  delay_ms(1000);
  }
}

Proteus Simulation Video:



Interfacing PIC16F877A with DHT11 digital humidity and temperature sensor:
The following circuit schematic shows Proteus circuit of connecting PIC16F877A with DHT11 sensor. 


dht11 proteus simulation dht11 proteus library


Interfacing PIC16F877A with DHT11 MikroC code:

 //PIC16F877A DHT11 digital humidity and
 //       temperature sensor MikroC code
//Written by: BENCHEROUDA Okba
//electronnote@gmail.com
//Crystal used : 12MHz
//Use at your own risk


// LCD module connections
 sbit LCD_RS at RB0_bit;
 sbit LCD_EN at RB1_bit;
 sbit LCD_D4 at RB2_bit;
 sbit LCD_D5 at RB3_bit;
 sbit LCD_D6 at RB4_bit;
 sbit LCD_D7 at RB5_bit;
 sbit LCD_RS_Direction at TRISB0_bit;
 sbit LCD_EN_Direction at TRISB1_bit;
 sbit LCD_D4_Direction at TRISB2_bit;
 sbit LCD_D5_Direction at TRISB3_bit;
 sbit LCD_D6_Direction at TRISB4_bit;
 sbit LCD_D7_Direction at TRISB5_bit;
 // End LCD module connections
 unsigned char  Check, T_byte1, T_byte2,
                RH_byte1, RH_byte2, Ch ;
 unsigned Temp, RH, Sum ;
void StartSignal(){
 TRISD.F0 = 0;    //Configure RD0 as output
 PORTD.F0 = 0;    //RD0 sends 0 to the sensor
 delay_ms(18);
 PORTD.F0 = 1;    //RD0 sends 1 to the sensor
 delay_us(30);
 TRISD.F0 = 1;    //Configure RD0 as input
  }
 //////////////////////////////
 void CheckResponse(){
 Check = 0;
 delay_us(40);
 if (PORTD.F0 == 0){
 delay_us(80);
 if (PORTD.F0 == 1)   Check = 1;   delay_us(40);}
 }
 //////////////////////////////
 char ReadData(){
 char i, j;
 for(j = 0; j < 8; j++){
 while(!PORTD.F0); //Wait until PORTD.F0 goes HIGH
 delay_us(30);
 if(PORTD.F0 == 0)
       i&= ~(1<<(7 - j));  //Clear bit (7-b)
 else {i|= (1 << (7 - j));  //Set bit (7-b)
 while(PORTD.F0);}  //Wait until PORTD.F0 goes LOW
 }
 return i;
 }
 //////////////////////////////
void main() {
 TRISD.F1 = 0;
 Lcd_Init();
 Lcd_Cmd(_LCD_CURSOR_OFF);        // cursor off
 Lcd_Cmd(_LCD_CLEAR);            // clear LCD
 while(1){
 StartSignal();
  CheckResponse();
  if(Check == 1){
  RH_byte1 = ReadData();
  RH_byte2 = ReadData();
  T_byte1 = ReadData();
  T_byte2 = ReadData();
  Sum = ReadData();
  if(Sum == ((RH_byte1+RH_byte2+T_byte1+T_byte2) & 0XFF)){
  Temp = T_byte1;
  RH = RH_byte1;
  Lcd_Out(1, 6, "Temp:   C");
  Lcd_Out(2, 2, "Humidity:   %");
  LCD_Chr(1, 12, 48 + ((Temp / 10) % 10));
  LCD_Chr(1, 13, 48 + (Temp % 10));
  LCD_Chr(2, 12, 48 + ((RH / 10) % 10));
  LCD_Chr(2, 13, 48 + (RH % 10));
  }
  else{
  Lcd_Cmd(_LCD_CURSOR_OFF);        // cursor off
  Lcd_Cmd(_LCD_CLEAR);             // clear LCD
  Lcd_Out(1, 1, "Check sum error");}
  }
  else {
  Lcd_Out(1, 3, "No response");
  Lcd_Out(2, 1, "from the sensor");
  }
  delay_ms(1000);
  }
}


Proteus Simulation Video:



Simulation files download:
The Proteus files for the three microcontroller are at the following link:
Download