Gagan Luthra
Published

PIR Motion Sensing

Implement an analog front end (AFE) for a Pyroelectric Infrared (PIR) motion sensor, using the PSoC Analog Coprocessor.

IntermediateFull instructions provided2 hours2,496
PIR Motion Sensing

Things used in this project

Hardware components

PSoC Analog Coprocessor Pioneer Kit
Cypress PSoC Analog Coprocessor Pioneer Kit
×1
Zilog ZRE200GE
×1

Software apps and online services

PSoC Creator
Cypress PSoC Creator
Cypress PSoC Analog Coprocessor Kit Software Setup

Story

Read more

Code

PSoC Creator project - PIR Motion Sensing

C/C++
No preview (download only).

PSoC Creator main.c code

C/C++
/******************************************************************************
* Project Name      : CE211301_PIR_Motion_Sensing
* Version           : 1.0
* Device Used       : CY8C4A45LQI-L483
* Software Used     : PSoC Creator 3.3 CP3
* Compiler Used     : ARM GCC 4.9.3 
* Related Hardware  : CY8CKIT-048 PSoC Analog Coprocessor Pioneer Kit 
*******************************************************************************

/*******************************************************************************
* Theory of Operation: This example demonstrates how to implement an analog front end 
* (AFE) for a Pyroelectric Infrared (PIR) motion sensor using PSoC Analog Coprocessor.
* The code example is designed to measure the voltage signal from a PIR sensor to detect 
* the movement of IR emitting object. The sensor data is communicated over I2C. 
* Also, RGB LED is also turned ON once the motion is detected.
*******************************************************************************/

/* Header File Includes */
#include <project.h>

#define LED_ON                      (0u)
#define LED_OFF                     (1u)
#define MOTION_DETECTED             (1u)
#define MOTION_NOT_DETECTED         (0u)
#define THREE_FEET                  (3u)
#define TEN_FEET                    (10u)
#define TWENTY_FEET                 (20u)
#define ADC_CHANNEL_PIR             (0u)
#define SENSOR_RAW_INITIAL          (0)
/* EzI2C Read/Write Boundary */
#define READ_WRITE_BOUNDARY         (1u)

/* High and low thresholds for the motion detection are determined 
	through experiments */ 
	
/* High Threshold for 3 feet detection (80% of positive peak count) */
#define PIR_WINDOW_HIGH_3FT         (1200)
/* Low Threshold for 3 feet detection (80% of negative peak count) */
#define PIR_WINDOW_LOW_3FT          (-1200)   
/* High Threshold for 10 feet detection (80% of positive peak count) */
#define PIR_WINDOW_HIGH_10FT        (600)
/* Low Threshold for 10 feet detection (80% of negative peak count) */
#define PIR_WINDOW_LOW_10FT         (-600)
/* High Threshold for 20 feet detection (80% of positive peak count) */    
#define PIR_WINDOW_HIGH_20FT        (1200)
/* Low Threshold for 20 feet detection (80% of negative peak count) */   
#define PIR_WINDOW_LOW_20FT         (-1200)
	
/* Structure that holds the sensor values                                        */
/* Use __attribute__((packed)) for GCC and MDK compilers to pack structures      */
/* For other compilers use the corresponding directive.                          */
/* For example, for IAR use the following directive                              */
/* typedef __packed struct {..}struct_name;                                      */
typedef struct __attribute__((packed))
{
    uint8 detectionDistance;      	/* PIR detection distance */
	int16 sensorRawValue;        	/* ADC result */
	int16 highThreshold;		    /* High threshold for motion detection */
	int16 lowThreshold;			    /* Low threshold for motion detection */
    uint8 motionDetected;		    /* Motion detection flag */
}pir_sensor_data;


/* Function Prototypes */
void InitResources(void );
CY_ISR(TIMEBASE_ISR);

/* Declare the i2cBuffer to exchange sensor data between Bridge Control Panel (BCP) and PSoC Analog Coprocessor */
pir_sensor_data i2cBuffer = {THREE_FEET, SENSOR_RAW_INITIAL, 
                             PIR_WINDOW_HIGH_3FT, PIR_WINDOW_LOW_3FT, 
                             MOTION_NOT_DETECTED};

/*******************************************************************************
* Function Name: main
********************************************************************************
*
* Summary:
*  This function initializes all the resources, and in an infinite loop, performs tasks to measure all the sensor
*  parameters from sensors and to send the data over I2C.
*
* Parameters:
*  None
*
* Return:
*  int
*
* Side Effects:
*   None
*******************************************************************************/
int main()
{
	/* Sensor raw value */
	int16 sensorRawValue = 0;
	
	/* Motion detection thresholds */
	int16 highThreshold = PIR_WINDOW_HIGH_3FT;		                           
	int16 lowThreshold = PIR_WINDOW_LOW_3FT;
	
    /* Variable that stores the previous detection distance, used for checking if 
        the detection distance is changed by the master(BCP) */
    uint8 prevDetectionDistance = THREE_FEET;
    
    /* Variable to store the status returned by CyEnterCriticalSection() */
    uint8 interruptState = 0;
    
    /* Enable global interrupts */
    CyGlobalIntEnable;
    
    /* Initialize all the hardware resources */
    InitResources();
    
    /* Infinite Loop */
    for(;;)
    {        
        /* If the master(BCP) changed the detection distance, change the second stage 
            amplifier (PGA) gain and the thresholds for the required detection distance*/
        if (i2cBuffer.detectionDistance != prevDetectionDistance)
        {
            prevDetectionDistance = i2cBuffer.detectionDistance;
            
            /* Set the required detection distance */
            switch (i2cBuffer.detectionDistance)
            {
                case THREE_FEET:
                    /* Set second stage PGA gain and thresholds that gives 
                        3 feet detection distance */
                    PIRAmplifierStage2_SetGain(PIRAmplifierStage2_GAIN_1);
                    highThreshold = PIR_WINDOW_HIGH_3FT;
                    lowThreshold = PIR_WINDOW_LOW_3FT;
                    break;
                case TEN_FEET:
                    /* Set second stage PGA gain and thresholds that gives 
                        10 feet detection distance */
                    PIRAmplifierStage2_SetGain(PIRAmplifierStage2_GAIN_2);
                    highThreshold = PIR_WINDOW_HIGH_10FT;
                    lowThreshold = PIR_WINDOW_LOW_10FT;
                    break;
                case TWENTY_FEET:
                    /* Set second stage PGA gain and thresholds that gives 
                        20 feet detection distance */
                    PIRAmplifierStage2_SetGain(PIRAmplifierStage2_GAIN_32);
                    highThreshold = PIR_WINDOW_HIGH_20FT;
                    lowThreshold = PIR_WINDOW_LOW_20FT;
                    break;
                default:
                    /* Set second stage PGA gain and thresholds that gives 
                        3 feet detection distance */
                    PIRAmplifierStage2_SetGain(PIRAmplifierStage2_GAIN_1);
                    highThreshold = PIR_WINDOW_HIGH_3FT;
                    lowThreshold = PIR_WINDOW_LOW_3FT;
                    break;
            }
        }            
        /* Check if ADC data is ready */
        if(ADC_IsEndConversion(ADC_RETURN_STATUS))
        {
            /* Read ADC result */
            sensorRawValue = ADC_GetResult16(ADC_CHANNEL_PIR);
            
            /* Check if motion is detected */
            if((sensorRawValue > highThreshold) || 
               (sensorRawValue < lowThreshold))
            {
                /* Once the motion is detected, the RGB LED is driven with RED color for 5s
                   and the motion detected variable in I2C buffer is latched to '1' for 5s.
                   If another motion is detected before 5s elapsed the timer is restarted 
                   to maintain 5s time window */
               	
				/* Stop the timer */
                Timebase5s_Stop();
				
				/* Reload the counter */
				Timebase5s_WriteCounter(Timebase5s_TC_PERIOD_VALUE);
				
				/* Start the 5s timer */
                Timebase5s_Start();
				
				/* Update the status of motion detection */
				i2cBuffer.motionDetected = MOTION_DETECTED;
				
				/* Turn ON the LED */
                Pin_LED_Write(LED_ON);
            }
        } 
		
		/* Enter critical section to check if I2C bus is busy or not */
        interruptState = CyEnterCriticalSection();
            
        if(!(EzI2C_EzI2CGetActivity() & EzI2C_EZI2C_STATUS_BUSY))
        {
            /* Update the I2C buffer  */
            i2cBuffer.sensorRawValue = sensorRawValue;
			i2cBuffer.highThreshold = highThreshold;
			i2cBuffer.lowThreshold = lowThreshold;							
        }
		
		/* Exit critical section */
        CyExitCriticalSection(interruptState);		
    }    
}

/*******************************************************************************
* Function Name: void InitResources(void)
********************************************************************************
*
* Summary:
*  This function initializes all the hardware resources
*
* Parameters:
*  None
*
* Return:
*  None
*
* Side Effects:
*   None
*******************************************************************************/
void InitResources(void)
{
    /* Start EZI2C Slave Component and initialize buffer */
    EzI2C_Start();
    EzI2C_EzI2CSetBuffer1(sizeof(i2cBuffer), READ_WRITE_BOUNDARY, (uint8*)&i2cBuffer);
    
    /* Enable LED timebase ISR */
    isr_Timebase5s_Start();
    isr_Timebase5s_StartEx(TIMEBASE_ISR);   
    
    /* Start the Scanning SAR ADC Component and start conversion */
    ADC_Start();
    ADC_StartConvert();
    
    /* Start the Reference Buffer */
    RefBuffer_Start();
    
    /* Start Programmable Voltage Reference */
    PVref_Start();
    
    /* Enable Programmable Voltage Reference */
    PVref_Enable();
    
    /* Start the first stage amplifier */
    PIRAmplifierStage1_Start();
    
    /* Start the second stage amplifier (PGA) */
    PIRAmplifierStage2_Start();    
 }

/*******************************************************************************
* Function Name: CY_ISR(TIMEBASE_ISR)
********************************************************************************
*
* Summary:
*  This function implements the ISR for 5s timebase
* 
* Parameters:
*  None
*
* Return:
*  None
*
* Side Effects:
*   None
*******************************************************************************/
CY_ISR(TIMEBASE_ISR)
{
   	/* Reset the motion detection flag */
    i2cBuffer.motionDetected = MOTION_NOT_DETECTED;
    /* Turn OFF the LED */
    Pin_LED_Write(LED_OFF);
    /* Stop the 5s timer */
    Timebase5s_Stop();
}
/* [] END OF FILE */

Credits

Gagan Luthra

Gagan Luthra

1 project • 1 follower
Cypress PSoC

Comments