PIC18 MCU IR motion detector
Using a PIC18 MCU a IR motion detector circuit that is currently configured for security purposes was built. The code and I/O devices can be changed for other functions such as triggering an automatic door with a servo or many other functions that require a motion sensor to be used. The circuit is built on a breadboard and uses the PIC18F45K20 MCU connected to a PIR sensor configured as an input device, the range of the sensor was adjusted to monitor an area of approximately 3 meters and adjusted to reset after 3 seconds. Three devices are configured for output from the MCU, these are an LED, buzzer and LCD display. The PIC18F45K20 MCU is programmed to display the message “NO MOTION” on the LCD during the circuit’s steady state process. When motion is detected in the designated area a signal is sent from the PIR sensor to the MCU, the MCU processes the data and activates the LCD to display “MOTION DETECTED!” accompanied by turning on an LED and buzzer. After 5 seconds, the system will reset and await for the next signal from the PIR sensor. After the 5 seconds have passed from time of activation the circuit will go back to its steady state condition.




Below is the code written in C for this design.
/* IR Motion Sensor for Security
* This program will detect motion using a PIR sensor. If no motion is detected an LCD
* will give a message "NO MOTION." When motion is detected an LED and buzzer will turn
* on, and the LCD message will change to "MOTION DETECTED!." The IR sensor takes 5 seconds
* to reset and after that it will be ready to trigger the alarms again.
*/
// RB0 wired to LCD rs (pin 33)
// RB1 wired to LCD en (pin 34)
// RB2 wired to PIR sensor (pin 35)
// RC0 wired to LED (pin 15)
// RC1 wired to Buzzer (pin 16)
#pragma config FOSC = INTIO67 //Internal oscillator block, port function on RA6 and RA7
#pragma config BORV = 30, PWRT = ON //Brown-Out-Rese Voltage=3V, Power-up Timer enable enabled
#pragma config WDTEN = OFF //Watchdog timer disabled
#pragma config PBADEN = OFF //PORT A/D disabled
#pragma config HFOFST = OFF, MCLRE = OFF //Fast Start-up and MCLR pin disabled
#include <pic18f45k20.h>
#define ldata PORTD //lcd data pins on PORTD
#define rs PORTBbits.RB0 //rs of lcd on PORTB0 (pin 33)
#define en PORTBbits.RB1 //en of lcd on PORTB1 (pin 34))
void MSDelay(unsigned char); //Function to create 1 ms of delay
void lcdcmd(unsigned char); //command function
void lcddata (unsigned char); //data function
void __interrupt(high_priority) Motion_Sensor(void) //Interrupt from trigger of motion sensor
{
INTCON3bits.INT2IF = 0; //clear INT2IF flag
PORTCbits.RC0 = 1; //turns on LED (RC0, pin 15))
lcdcmd(0x01); //clear LCD
lcddata('M'); //display M
lcddata('O'); //display O
lcddata('T'); //display T
lcddata('I'); //display I
lcddata('O'); //display O
lcddata('N'); //display N
lcddata(' '); //display _
lcddata('D'); //display D
lcddata('E'); //display E
lcddata('T'); //display T
lcddata('E'); //display E
lcddata('C'); //display C
lcddata('T'); //display T
lcddata('E'); //display E
lcddata('D'); //display D
lcddata('!'); //display !
unsigned char a, b; //loop delay for sensor to reset
for(a=0; a<255; a++)
{
PORTCbits.RC1 = 1; //Set Buzzer (RC1, pin 16)
MSDelay(1);
PORTCbits.RC1 = 0; //Clear Buzzer (RC1, pin 16)
MSDelay(1);
for(b=0; b<56; b++);
}
//Could add LED to turn off here rather than having it turn off in main
}
void main(void)
{
TRISB = 0xFC; //defining RB2 as input, RB0,RB1,RB3,RB4... as output
TRISC = 0; //defining PORTC as output
TRISD = 0; //defining PORTD as output for LCD data
RCONbits.IPEN = 1; //enable priority
INTCONbits.GIEH = 1; //Global high priority enable
INTCONbits.GIEL = 1; //Global peripheral enable
INTCON3bits.INT2IE = 1; //Enable INT2
INTCON3bits.INT2IP = 1; //define INT2 as high priority
INTCON2bits.INTEDG2 = 1; //trigger INT2 on rising edge
PORTCbits.RC0 = 0; //Turns off LED (RC0, pin 15)
PORTCbits.RC1 = 0; //Turns off Buzzer (RC1, pin 16)
en = 0; //initializing, clear enable
MSDelay(50);
lcdcmd(0x38); //initialize LCD 2 lines, 5x7 matrix
lcdcmd(0x0E); //display on, cursor
lcdcmd(0x01); //clear LCD
lcdcmd(0x06); //shift cursor right
lcddata('N'); //display N
lcddata('O'); //display O
lcddata(' '); //display _
lcddata('M'); //display M
lcddata('O'); //display O
lcddata('T'); //display T
lcddata('I'); //display I
lcddata('O'); //display O
lcddata('N'); //display N
MSDelay(255);
}
void lcdcmd(unsigned char value) //command
{
ldata = value; //put received argument on PORTD
rs = 0; //its the data
en = 1; //set enable
MSDelay(2);
en = 0; //clear enable
MSDelay(5);
}
void lcddata (unsigned char value) //data
{
ldata = value; //put received argument on PORTD
rs = 1; //sets the data
en = 1; //set enable
MSDelay(2);
en = 0; //clear enable
MSDelay(5);
}
void MSDelay(unsigned char mili) //For loop delay, loops for 1ms
{
unsigned char i, j;
for(i=0; i < mili; i++)
for(j=0; j < 100; j++);
}