PIR Motion Sensor
pir_sensor.ino
/*
Project: Smart Home
Component: PIR Motion Sensor
Sketch Description: This sketch has functions to detect motion around a PIR sensor.
Author: STEMVentor Educonsulting
This code is copyrighted. Please do not reuse or share for any purpose other than for learning with subscribed STEMVentor programs. This code is for educational purposes only and is not for production use.
*/
// LIBRARIES
// PIN DEFINITIONS
// #define PIR_MOTION_SENSOR_PIN 3 // Needs to be an interrupt pin.
// GLOBAL CONSTANTS
// GLOBAL VARIABLES
bool motion_detected = false; // Default to no motion detected.
// INITIALIZE OBJECTS
/* Libraries usually follow an object-oriented approach that requires
* an instance of the class to call its methods.
*/
/* LOCAL FUNCTIONS */
// Instead of continuously reading for a sensor pin value
// we can use the concept of interrupts if supported by the board.
// Each interrupt pin can only have one interrupt service routine (ISR) attached to it at a time.
// If you attach a new ISR, it will replace the previous one.
// In the case of motion detection there are two values we need to detect,
// when motion is detected (HIGH) and when motion is stopped (LOW).
// Interrupts can be set to be triggered by the following conditions:
// On CHANGE: whenever the pin changes value
// On RISING: when the pin goes from low to high,
// On FALLING: when the pin goes from high to low.
// The best choice in this case would be to trigger the interrupt on CHANGE and within
// the interrupt service routine (ISR) check if it's returning HIGH or LOW.
// The Interrupt Service Routine (ISR) to be triggered on CHANGE in value.
void isrPIRMotionSensorValueChange() {
// DO NOT Serial.println() or print to LCD within an interrupt function.
// Interrupts are disabled during an ISR, and the Serial and LCD library functions
// often rely on interrupts for communication (e.g., the Wire library for I2C).
// Read the data from the PIR sensor when an interrupt is recieved.
readPIRMotionSensorValue();
}
void PIRMotionSensorSetup() // function to LCD setup
{
digitalWrite(LED_BUILTIN, LOW); // For now this is being used as the motion indicator.
// Define the pin mode
pinMode(PIR_MOTION_SENSOR_PIN, INPUT);
// pinMode(PIR_MOTION_SENSOR_PIN, INPUT_PULLUP); // Not sure if this is required.
// Attach the ISR to trigger when the pin output value changes.
attachInterrupt(digitalPinToInterrupt(PIR_MOTION_SENSOR_PIN), isrPIRMotionSensorValueChange, CHANGE);
lcd_text = "The PIR sensor is ready!";
if(OPERATING_MODE == 'D'){
Serial.println("The PIR sensor is ready!");
}
}
// Read PIR sensor value and take action.
// Note that this function can be called in a loop or call inside the ISR.
// If called inside an ISR follow the same restrictions that apply to an ISR.
boolean readPIRMotionSensorValue(){
// Since we cannot return a value from here to the main sketch if using the ISR
// we will set a global value for the PIR sensor reading and act on that.
// If a HIGH value is read from the PIR sensor.
pir_motion_sensor_value = digitalRead(PIR_MOTION_SENSOR_PIN);
}