Project: Automatic Light Control with LDR and PIC16F877A bonkers image project automatic light

1. Introduction

In this project, we will build an automatic light control system using a Light Dependent Resistor (LDR) and the PIC16F877A microcontroller. The microcontroller reads ambient light intensity via the LDR and automatically turns an LED or relay-controlled lamp ON in darkness and OFF in brightness.

Real-World Applications:

  • Streetlights that turn on at night
  • Energy-saving home lighting
  • Automatic garden or security lights

2. Learning Objectives

  • Learn how to read analog signals using PIC ADC (Analog-to-Digital Converter)
  • Understand light sensing with an LDR voltage divider
  • Use conditional logic to drive outputs based on sensor input
  • Control devices like LEDs or relays with transistors and PIC I/O

3. Tools and Components

Hardware Required:

  • PIC16F877A microcontroller
  • Light Dependent Resistor (LDR)
  • 10kΩ resistor (for LDR voltage divider)
  • LED or 5V Relay with NPN transistor (e.g., BC547)
  • Flyback diode (e.g., 1N4007) for relay
  • Resistors: 330Ω for LED, 1kΩ for transistor base
  • Power supply: 5V regulated
  • Breadboard, jumper wires
  • Crystal oscillator (20MHz) + 22pF capacitors (if external)
  • MPLAB X IDE + XC8 Compiler
  • PIC Programmer (e.g., PICKIT 3)

4. Background Concepts

  • LDR (Light Dependent Resistor): Resistance decreases as light intensity increases.
  • Voltage Divider: Converts LDR resistance changes into voltage readable by the PIC ADC.
  • ADC (Analog-to-Digital Converter): Converts voltage (0-5V) to a 10-bit digital value (0-1023).
  • Thresholding: Define a light level threshold; below it, we turn the light ON.

5. Step-by-Step Assembly and Code

Circuit Wiring Overview

  1. LDR Voltage Divider:
    • Connect one leg of the LDR to 5V.
    • Connect the other leg to both:
      • RA0 (AN0) of PIC
      • One leg of the 10kΩ resistor; connect the other end of resistor to GND.
    • Result: Analog voltage at RA0 changes with light intensity.
  2. Output Control (LED or Relay):
    • LED Option:
      • Connect LED anode to RB0 via 330Ω resistor.
      • LED cathode to GND.
    • Relay Option:
      • RB0 → 1kΩ resistor → Base of BC547 transistor.
      • Emitter to GND.
      • Relay coil between 5V and collector.
      • Diode across relay (cathode to 5V) to protect from voltage spikes.

Source Code with Comments (XC8)

#include <xc.h>
#define _XTAL_FREQ 20000000 // 20MHz Oscillator

// Configuration Bits
#pragma config FOSC = HS, WDTE = OFF, PWRTE = ON, BOREN = ON, LVP = OFF, CPD = OFF, WRT = OFF, CP = OFF

void ADC_Init();
unsigned int ADC_Read(unsigned char channel);

void main() {
unsigned int light_value;
const unsigned int threshold = 500; // Set threshold (adjust as needed)

TRISA = 0x01; // RA0 as input (AN0)
TRISB0 = 0; // RB0 as output
PORTB = 0x00; // Initialize outputs to 0

ADC_Init(); // Initialize ADC

while(1) {
light_value = ADC_Read(0); // Read LDR analog value

if (light_value < threshold) {
RB0 = 1; // Turn ON light (LED or relay)
} else {
RB0 = 0; // Turn OFF light
}

__delay_ms(500); // Sampling delay
}
}

// ADC Initialization Function
void ADC_Init() {
ADCON1 = 0x80; // Right justified, Fosc/32
ADCON0 = 0x01; // Enable ADC, select AN0
}

// ADC Read Function
unsigned int ADC_Read(unsigned char channel) {
ADCON0 = (channel << 3) | 0x01; // Select channel and turn on ADC
__delay_us(20); // Acquisition delay
GO_nDONE = 1; // Start conversion
while (GO_nDONE); // Wait until conversion completes
return ((ADRESH << 8) + ADRESL); // Return result
}

6. Testing and Debugging Tips

  • LDR not responding: Verify LDR connections and check voltage at RA0 using a multimeter.
  • ADC reads 0 or erratic values: Confirm ADC initialization and sampling time. Add a capacitor (~0.1µF) across LDR for stability.
  • Light doesn’t switch ON/OFF properly: Adjust the threshold value based on your room lighting conditions. Test different values between 300–700.
  • Relay chattering or no activation: Ensure sufficient base current to the transistor. Check diode placement across relay coil.

7. Project Extensions

  • Add an LCD display to show real-time light levels.
  • Incorporate manual override switch to force the light ON/OFF.
  • Use EEPROM to store the threshold and allow dynamic adjustment.
  • Implement PWM dimming instead of ON/OFF switching for adjustable brightness.