
Temperature and Humidity Monitoring System Using DHT11 and PIC16F877A
This project will interface a DHT11 temperature and humidity sensor with a PIC16F877A microcontroller, displaying the readings on an LCD. The guide includes wiring, code, explanations, and troubleshooting tips.
1. Introduction
This project monitors temperature and humidity using the DHT11 sensor and displays the readings on a 16×2 LCD. It’s useful in weather stations, greenhouse monitoring, and industrial environments.
Key Features:
✅ Uses PIC16F877A microcontroller
✅ Interfaces with DHT11 sensor
✅ Displays real-time temperature & humidity on LCD
✅ Embedded C code with comments for clarity
2. Learning Objectives
By completing this project, you will:
✔ Learn to interface DHT11 with PIC16F877A
✔ Use an LCD with PIC microcontrollers
✔ Understand communication protocols (Single-Wire Protocol of DHT11)
✔ Implement delay functions for accurate data retrieval
3. Tools and Components
Hardware:
- PIC16F877A microcontroller
- DHT11 Temperature & Humidity Sensor
- 16×2 LCD Display (HD44780 Compatible)
- Crystal Oscillator (20MHz)
- Capacitors (2 x 22pF)
- Resistors (10KΩ, 4.7KΩ)
- Potentiometer (10KΩ) – for LCD contrast adjustment
- Push Buttons & LEDs (for debugging)
- Breadboard & Jumper Wires
- Power Supply (5V)
- PIC Programmer (Pickit 3/4)
Software:
- MPLAB X IDE
- XC8 Compiler
- Proteus (for simulation, optional)
4. Background Information
DHT11 Sensor Working Principle
- DHT11 measures temperature using a thermistor and humidity using a capacitive sensor.
- It uses a single-wire communication protocol, sending data in a 40-bit sequence.
- Requires a start signal from the microcontroller to trigger data transmission.
PIC16F877A LCD Interfacing
- Uses 4-bit or 8-bit mode for communication.
- Requires control signals (RS, RW, E) and data lines (D4-D7 for 4-bit mode).
5. Circuit Diagram & Connections
DHT11 to PIC16F877A:
| DHT11 Pin | Connection to PIC |
|---|---|
| VCC | 5V |
| DATA | RB0 (Port B Pin 0) |
| GND | Ground |
| Pull-up | 4.7KΩ (between VCC & DATA) |
LCD to PIC16F877A (4-bit mode):
| LCD Pin | Connection to PIC |
|---|---|
| VSS | GND |
| VDD | 5V |
| V0 | 10KΩ Potentiometer (Contrast) |
| RS | RD0 |
| RW | GND (Always Write Mode) |
| E | RD1 |
| D4 | RD2 |
| D5 | RD3 |
| D6 | RD4 |
| D7 | RD5 |
| LED+ | 5V (via 330Ω resistor) |
| LED- | GND |
6. Source Code (XC8)
cCopyEdit#include <xc.h>
#include <stdio.h>
#include <stdint.h>
#define _XTAL_FREQ 20000000 // 20MHz Crystal Oscillator
#define DHT11_PIN RB0 // Data pin connected to RB0
// LCD Functions
#define RS RD0
#define EN RD1
#define D4 RD2
#define D5 RD3
#define D6 RD4
#define D7 RD5
void Lcd_Init();
void Lcd_Cmd(char);
void Lcd_Char(char);
void Lcd_String(const char *);
void DHT11_Start();
uint8_t DHT11_Check_Response();
uint8_t DHT11_Read_Data();
void main() {
TRISB = 0x01; // RB0 as input
TRISD = 0x00; // LCD Port as Output
Lcd_Init();
char temp[10], hum[10];
uint8_t humidity, temperature;
while(1) {
DHT11_Start();
if (DHT11_Check_Response()) {
humidity = DHT11_Read_Data();
DHT11_Read_Data(); // Ignore decimal part
temperature = DHT11_Read_Data();
DHT11_Read_Data(); // Ignore decimal part
DHT11_Read_Data(); // Checksum (ignored)
sprintf(temp, "Temp: %dC", temperature);
sprintf(hum, "Hum: %d%%", humidity);
Lcd_Cmd(0x80); // Move to first line
Lcd_String(temp);
Lcd_Cmd(0xC0); // Move to second line
Lcd_String(hum);
}
__delay_ms(2000);
}
}
// LCD Functions
void Lcd_Init() {
Lcd_Cmd(0x02); // Initialize in 4-bit mode
Lcd_Cmd(0x28); // 2-line, 5x7 matrix
Lcd_Cmd(0x0C); // Display ON, Cursor OFF
Lcd_Cmd(0x06); // Increment cursor
Lcd_Cmd(0x01); // Clear display
}
void Lcd_Cmd(char cmd) {
RS = 0;
D4 = (cmd >> 4) & 1;
D5 = (cmd >> 3) & 1;
D6 = (cmd >> 2) & 1;
D7 = (cmd >> 1) & 1;
EN = 1; __delay_ms(2); EN = 0;
D4 = cmd & 1;
D5 = (cmd >> 1) & 1;
D6 = (cmd >> 2) & 1;
D7 = (cmd >> 3) & 1;
EN = 1; __delay_ms(2); EN = 0;
}
void Lcd_Char(char data) {
RS = 1;
Lcd_Cmd(data);
}
void Lcd_String(const char *str) {
while(*str) Lcd_Char(*str++);
}
// DHT11 Functions
void DHT11_Start() {
TRISB0 = 0; RB0 = 0;
__delay_ms(18);
RB0 = 1;
TRISB0 = 1;
__delay_us(30);
}
uint8_t DHT11_Check_Response() {
return (RB0 == 0);
}
uint8_t DHT11_Read_Data() {
uint8_t data = 0;
for (int i = 0; i < 8; i++) {
while (!RB0);
__delay_us(40);
data = (data << 1) | (RB0 ? 1 : 0);
while (RB0);
}
return data;
}
7. Troubleshooting & Debugging
Common Issues & Fixes
| Issue | Possible Cause | Solution |
|---|---|---|
| No LCD Display | Incorrect wiring | Check connections & contrast |
| DHT11 not responding | No pull-up resistor | Use a 4.7KΩ pull-up on DATA |
| Incorrect temperature | Timing issue | Adjust delays in code |
| LCD shows random characters | Noise/interference | Use shorter wires, decoupling caps |
8. Extensions
🔹 Add a buzzer if temperature exceeds a limit
🔹 Log data to SD card or EEPROM
🔹 Display on 7-segment display
🔹 Use a WiFi module (ESP8266) for IoT connectivity