Smart Garage monitor and control system

Dependencies:   mbed HBridge MQ7 Ton SimpleScheduler Pir_sensor

main.cpp

Committer:
pkunnals
Date:
2021-03-19
Revision:
5:00c71adb66e9
Parent:
4:ae0a21e468bb

File content as of revision 5:00c71adb66e9:

#include "mbed.h"          
#include "math.h"
#include "Pir_sensor.h"
#include "MQ7.h"
#include <string>
#include "SimpleScheduler.h"
#include "ESP8266.h"
#include "Thingspeak.h"
#include "HBridge.h"
#include "Ton.h"

#define TIMER_PERIODICITY (1) /* 1 second */
#define SCHEDULER_TASK_PERIODICITY (500) /* 500ms */
#define GARAGE_LIGHT_TURN_OFF_DELAY (10)

Ton t1(15000); // Timer ON delay of 15 seconds.
Ton t2(15000); // Timer ON delay of 15 seconds.

Serial PC(USBTX, USBRX);
/* pir senor input */
Pir_sensor PIR(D2); 
/* Garage lamp output */
DigitalOut Garage_Lamp_Status(D7);
/* Garage CO sensor output */
MQ7 CO_Sensor(A0,D3);
DigitalOut PIR_DetectionLight(LED2);
HBridge Motor(D5,D6,D4);

Ticker ticker;
SimpleScheduler *scheduler;

typedef enum {

    DOOR_IS_OPEN = 1,
    DOOR_IS_CLOSED = 2,
    DOOR_IS_SAFE_OPEN = 3,
} eDoor_Status_t;


typedef enum {

    MOVEMENT_DETECTED = 1,
    NO_MOVEMENT_DETECTED = 2,
} ePIR_Status_t;

typedef enum {
    
    OPEN_DOOR = 1,
    CLOSE_DOOR = 2,
    SAFE_OPEN_DOOR = 3,
} eDoor_Command_t;

eDoor_Status_t doorStatus       = DOOR_IS_CLOSED;
eDoor_Command_t doorControl     = CLOSE_DOOR;
eDoor_Command_t prevDoorControl = CLOSE_DOOR;
char garage_light_delay_counter = 0;
ePIR_Status_t PIR_Status        = NO_MOVEMENT_DETECTED;
int CO_Level                    = 1;
/*!
 * Periodic Timer Interrupt controlling garage lights 
 * 
 * =============================================================================
 */
void Periodic_Interrupt ( void )
{
    if ( garage_light_delay_counter > 0 )
    {
        garage_light_delay_counter--;
    }
    else
    {
        if ( DOOR_IS_CLOSED == doorStatus ) 
        {
            Garage_Lamp_Status = 0;
        }
        
        PIR_Status = NO_MOVEMENT_DETECTED;
    }
}

/*!
 * Function used monitor and control door status, CO level and garage lights 
 * 
 * =============================================================================
 */
void Garage_Monitor_Runnable ( void )
{
    /* Development In Progress */
    if( PIR.read() )
    {
         PIR_DetectionLight = 0;
         Garage_Lamp_Status = 1;
         PC.printf("\n\r*** MOTION DETECTED *** \n\r");
         PIR_Status = MOVEMENT_DETECTED;
         PC.printf("\r\n*** GARAGE LIGHT IS ON *** \r\n");
         garage_light_delay_counter = GARAGE_LIGHT_TURN_OFF_DELAY;
    } 
    else
    {
        if ( PIR_DetectionLight == 0 )
        {
            PC.printf("\n\r*** NO MOTION DETECTED *** \n\r");
        }
        PIR_DetectionLight = 1;
    }
    
    CO_Level = CO_Sensor.get_CO_value ();
    if ( CO_Level == 1 )
    {
        PC.printf("\r\n*** GARAGE CO LEVEL IS SAFE/LOW *** \r\n");
    }
    else if ( CO_Level == 2 )
    {
        PC.printf("\r\n*** WARNING!! GARAGE CO LEVEL IS MODERATE *** \r\n");
    }
    else
    {
        PC.printf("\r\n*** DANGER!!! GARAGE CO LEVEL IS HIGH *** \r\n");
    }
    PC.printf("\n\r=========================================================================\n\r");
    PC.printf("\n\rGarage Door Status = %d \n\rGarage CO Level = %d\n\rPIR Status = %d \n\r", (int)doorStatus,  CO_Level, (int)PIR_Status);
    PC.printf("\n\r=========================================================================\n\r");

    if ( t2 ) 
    {
        /* Send garage status to Thingspeak channel */
        Send_to_Thingspeak ( (int)doorStatus, CO_Level, (int)PIR_Status ) ;
        t2 = Ton::Off;
        t2.reset();
        t1 = Ton::On;
    }
}

void Garage_Door_Control_Runnable( void ) 
{
           
    if ( t1 ) 
    {
        // This code will be executed once the timer times out.
        doorControl = ( eDoor_Command_t ) Read_from_Thingspeak();
        PC.printf("\r\n Door Command received from Thingspeak = %d \r\n", doorControl);
        t1 = Ton::Off;
        t1.reset();
        t2 = Ton::On;
    }
    if ( ( CO_Level > 1 ) && ( prevDoorControl != OPEN_DOOR ) )
    {
        doorControl = SAFE_OPEN_DOOR;
    }
    if ( ( doorControl == OPEN_DOOR ) && ( prevDoorControl != OPEN_DOOR ) )
    {
        Garage_Lamp_Status = 1;
        garage_light_delay_counter = GARAGE_LIGHT_TURN_OFF_DELAY;
        PC.printf("\r\n*** GARAGE LIGHT IS TURNED ON *** \r\n");
        Motor.forward ();
        if ( doorStatus == DOOR_IS_CLOSED )
        {   
            wait(8);
        }
        else if ( doorStatus == DOOR_IS_SAFE_OPEN )
        {
            wait(6);
        }
        Motor.stop ();
        doorStatus = DOOR_IS_OPEN;
        PC.printf("\r\n*** DOOR IS OPEN ***\r\n");
    }
    else if ( ( doorControl == SAFE_OPEN_DOOR ) && ( prevDoorControl == CLOSE_DOOR ) )
    {
        Garage_Lamp_Status = 1;
        garage_light_delay_counter = GARAGE_LIGHT_TURN_OFF_DELAY;
        PC.printf("\r\n*** GARAGE LIGHT IS TURNED ON *** \r\n");
        Motor.forward ();
        wait(2);
        Motor.stop ();
        doorStatus = DOOR_IS_SAFE_OPEN;
        PC.printf("\r\n*** DOOR IS SAFETY OPEN ***\r\n");
    }
    else if ( ( doorControl == CLOSE_DOOR ) && ( prevDoorControl != CLOSE_DOOR ) )
    {
        Garage_Lamp_Status = 1;
        garage_light_delay_counter = GARAGE_LIGHT_TURN_OFF_DELAY;
        PC.printf("\r\n*** GARAGE LIGHT IS TURNED ON *** \r\n");
        Motor.backward ();
        if ( doorStatus == DOOR_IS_OPEN )
        {   
            wait(9);
        }
        else if ( doorStatus == DOOR_IS_SAFE_OPEN )
        {
            wait(2);
        }
        Motor.stop ();
        PC.printf("\r\n*** DOOR IS CLOSED *** \r\n");
        doorStatus = DOOR_IS_CLOSED;
    }
    else
    {
        
    }
    prevDoorControl = doorControl;
}

void Task_500ms_Runnable(SimpleTask *task) {
           
    Garage_Door_Control_Runnable ();
    
    Garage_Monitor_Runnable ();
}

/*!
 * Main function, user application starts from here.  
 * 
 * =============================================================================
 */
int main ( void ) 
{
    /* Baud rate used for communicating with Tera-term on PC */
    PC.baud(115200);           
    PC.printf("\n\r\n\r");
    PC.printf(" ######  ##     ##  ######  #####   ########    ####     ######   #####     ######    ####    ########    ######  ##    ##  ######  ######## ######## ##     ##\n\r");
    PC.printf("##    ## ###   ### ##    ## ##   ##    ##      ##   ##  ##    ##  ##   ##  ##    ##  ##   ##  ##         ##    ##  ##  ##  ##    ##    ##    ##       ###   ###\n\r");
    PC.printf("##       #### #### ##    ## ##   ##    ##      ##       ##    ##  ##   ##  ##    ##  ##       ##         ##         ####   ##          ##    ##       #### ####\n\r");
    PC.printf(" ######  ## ### ## ######## ## ###     ##      ##  ###  ########  ## ###   ########  ##  ###  ######      ######     ##     ######     ##    ######   ## ### ##\n\r");
    PC.printf("      ## ##     ## ##    ## ##  ##     ##      ##   ##  ##    ##  ##  ##   ##    ##  ##   ##  ##               ##    ##          ##    ##    ##       ##     ##\n\r");
    PC.printf("##    ## ##     ## ##    ## ##   ##    ##      ##   ##  ##    ##  ##   ##  ##    ##  ##   ##  ##         ##    ##    ##    ##    ##    ##    ##       ##     ##\n\r");
    PC.printf(" ######  ##     ## ##    ## ##   ##    ##       ####    ##    ##  ##   ##  ##    ##   ####    ########    ######     ##     ######     ##    ######## ##     ##\n\r");
    PC.printf("-----------------------------------------------------------------------------------------\n\r");
    PC.printf("Developed By: Priyanka Kunnal Siddalingappa\n\r");
    PC.printf("-----------------------------------------------------------------------------------------\n\r\n\r");
    
    PC.printf("\n\n\rInitial ESP...\n\n\r");  
    /* Initialize ESP wifi module */
    Esp8266_Init();
    
    doorStatus  = DOOR_IS_CLOSED;
    doorControl = CLOSE_DOOR;
    prevDoorControl = CLOSE_DOOR;
    PIR_Status  = NO_MOVEMENT_DETECTED;
    garage_light_delay_counter = 0;
    if (!t1.isRunning()) 
    {
        t1 = Ton::On;
        doorControl = ( eDoor_Command_t ) Read_from_Thingspeak();
    }
    
    PC.printf("\n\n\rStarting Periodic Interrupt...\n\n\r");
    /*  Trigger the interrupt periodically */
    ticker.attach(Periodic_Interrupt, TIMER_PERIODICITY);
    
    PC.printf("\n\n\rStarting Scheduler...\n\n\r");
    scheduler = new SimpleScheduler;
    scheduler
        ->addTask( new SimpleTask(SCHEDULER_TASK_PERIODICITY, Task_500ms_Runnable) )
    ;
    scheduler->run();  
        
    /*!
     * Wait forever
     * ========================
    */ 
    while (1) 
    {   
        ;
    }
}