Hw6

Dependencies:   C12832_lcd LM75B MMA7660 NTPClient WiflyInterface HOMEWORK_6 mbed

main.cpp

Committer:
bhakti08
Date:
2014-06-09
Revision:
0:ec9669ff706c

File content as of revision 0:ec9669ff706c:

/****************************************************************************************/
/*                               INTERNET OF THINGS ASSIGNMENT 6                        */
/*This assignment implements a thermostat which turns ON/OFF depending on the set and   */
/*current temperature. The thermostat can be turned ON/OFF by following ways:           */
/*                    1. Joustick up button on the application board.                   */
/*                    2. Depending on if there is movement or not                       */
/*                    3. Remotely through wifly(Telnet)                                 */
/****************************************************************************************/

#include "mbed.h"
#include "rtos.h"
#include "C12832_lcd.h"
#include "NTPClient.h"
#include "WiflyInterface.h"
#include "LM75B.h"
#include "DebouncedIn.h"
#include "MMA7660.h"

#define SEC 1000                     //macro for no. of msec in sec
#define MIN 60*SEC                  //macro for no. of msec in min
#define hys 3
#define TIME 20                    //Time after which system should turn OFF if
                                   //no movement detected
#define ECHO_SERVER_PORT   7       //Server port for HTTP client.

Mutex LCD;
C12832_LCD lcd;
Serial pc (USBTX,USBRX);
LM75B current(p28,p27);
MMA7660 MMA(p28,p27);
BusOut move(p23,p24,p25);

//System ON/OFF
BusIn heat_on (p16,p13); 
                                      
//Increase Temperature
DebouncedIn temp_up (p15); 

//Decrease Temperature                                    
DebouncedIn temp_down (p12);                                   

//System ON/OFF LED
DigitalOut thermostat (LED1);

//Heater ON/OFF LED. This can be furthur connected to the relay                                  
DigitalOut heater (LED2);                                  


int temp = 10;
bool status = 0;

void update_lcd(void const *args);       //Thread 1
void Thermostat_logic (void const *args);      //Thread 2
void check_movement(void const *args);      //Thread 3

bool no_move;
float acc_x = MMA.x();
float acc_y = MMA.y();
float acc_z = MMA.z();
float acc_x_old,acc_y_old,acc_z_old;
bool wifly_on = 0;

WiflyInterface wifly(p9, p10, p30, p29, "MY_WIFI", "", NONE);

/****************************************************************************************/
/*Thread update_lcd: This thread is used to update the lcd. The LCD will dispaly current*/
/*time, Set temperature and the actual temperature. If the system is OFF lcd will show  */
/*current time and message 'System OFF'                                                 */
/****************************************************************************************/
void update_lcd(void const *args)
{
    set_time(1391739990); 
    while (true) {
    time_t seconds = time(NULL);
    LCD.lock();
    lcd.locate(0,0);
    lcd.printf("%s",ctime(&seconds));
    lcd.locate(0,10);
    if (status) {                                          
            lcd.printf("Current: %.2f",current.read());
            lcd.locate(1,20);
            lcd.printf("Set: %d",temp);
        } else {                                               
            lcd.printf("System OFF");
        }     
    LCD.unlock();
    Thread::wait(200);        //LCD will update after every 200msec.
    }
}
/****************************************************************************************/

/****************************************************************************************/
/*Thread: thermostat logic: This thread implements the logic of the thermostat. It turns*/
/*ON/OFF the thermostat depending on temperature, movement and the web control. It also */
/*allows the user to set the temperature from the push button switches. The setting of  */
/*temperature can also be done remotely through xively. Currently the program just      */
/*controls turning ON/OFF the system remotely.                                          */
/****************************************************************************************/
void Thermostat_logic(void const *args)
{
    while (true) {
        if (heat_on == 0x2  || wifly_on || !no_move) 
        {
            thermostat = 1;                                    
            status = 1;   
            wifly_on = 1;                                     
        } else if ( wifly_on == 0 ){              
            thermostat = 0;                                    
            heater = 0;                                       
            status = 0;   
            wifly_on = 0;                                    
        }
        else if (heat_on == 0x1 || no_move ) {                
            thermostat = 0;                                    
            heater = 0;                                       
            status = 0;   
            wifly_on = 0;                                    
        }
        
        /*If the joystick is pushed upwards increase set temperature by 2
        And print the set temperature on LCD.*/
        if (temp_up.rising()) {                                
            temp = temp + 0x2;                                                      
        }
        
        /*else if the joystick is pushed downwards decrease set temperature by 2
        And print the set temperature on LCD.*/ 
        
        else if (temp_down.rising()) {                       
            temp = temp - 0x2;                                 
        }

        //Comparison logic and turn Heater ON/OFF
        if ((temp > (current.read()+ hys)) && thermostat == 1)
            heater =  1;
        else if ((temp < (current.read()- hys)) || thermostat == 0)
            heater = 0;
            
        if (acc_x_old != MMA.x() || acc_y_old != MMA.y() || acc_z_old != MMA.x())
       {
           no_move = 0;
       }
         
        Thread::wait(100);      //Temperature comparison will take place after 
                                      //every 100msec.
    }
}
/****************************************************************************************/


/****************************************************************************************/
/*Thread check movement: This thread detects if there is movement nearby the thermostat.*/
/*If there is no movement this thread sets a variable called no_move which is furthur   */
/*used to turn ON/OFF the system. Logic implemented for movement detection is as follows*/
/*This thread is executed once every minute. Every time this thread is executed it      */
/*compares the accelerometer reading with its previous value. If the reading is same    */
/*(no movement detected) it increments a counter. When this counter reaches 20 (which   */
/*means there is no movement for 20 mins) it sets the variable no_move to turn OFF the  */
/*system. When a different accelerometer value is detected(movement present) it resets  */
/*the variable which will in turn turn the system ON.                                   */
/****************************************************************************************/
void check_movement(void const *args)
{
    static int move_cntr = 0;
    while (true) {
    acc_x_old = acc_x;
    acc_y_old = acc_y;
    acc_z_old = acc_z;
    acc_x = MMA.x();
    acc_y = MMA.y();
    acc_z = MMA.z();
    if (acc_x_old == acc_x && acc_y_old == acc_y && acc_z_old == acc_z)
    {
        move_cntr++;
        pc.printf("Value of move_cntr = %d\r\n",move_cntr);
        move = 011;
    }
    else {
        move_cntr = 0;
        pc.printf("Move_cntr reset\r\n");}
    if (move_cntr >= TIME)    //If the Accelerometer value remains constant for 20 mins no movement detected
        no_move = 1;
    else
        no_move = 0;
    Thread::wait(1*MIN);
    }
    
}
/****************************************************************************************/


/****************************************************************************************/
/*Thread main: This is the main thread which instantiates all other threads. The main   */
/*thread also initializes the wifly module and communicates with the mbed via wifly.    */
/*If the HTTP client is not connected, the main thread continues its operation through  */
/*the on board joystick. Turning ON/OFF the thermostat remotely is not possible in such */
/*a case. The other controls like the joystick and the accelorometer operate normally.  */
/****************************************************************************************/
int main() {
    
    Thread lcd_display(update_lcd,NULL,  osPriorityAboveNormal);
    Thread thermostat_thread(Thermostat_logic,NULL,  osPriorityAboveNormal);
    Thread accel_thread(check_movement,NULL,osPriorityAboveNormal);
    
    wifly.init(); //Use DHCP
    while (!wifly.connect());
    pc.printf("IP Address is %s\n\r", wifly.getIPAddress());
 
    TCPSocketServer server;
    
    server.bind(ECHO_SERVER_PORT);
    server.listen();
 
    printf("\nWait for new connection...\r\n");
    TCPSocketConnection client;
    server.accept(client);
    char buffer[3];   
    // NTPClient ntp;
    //ntp.setTime("nist1.symmetricom.com");

        while (true) {
            if (client.is_connected()){          
            int n = client.receive(buffer, sizeof(buffer));
            if (n <= 0)continue; 
            buffer[n] = 0;
            pc.printf("Buffer is %s\r\n",buffer);
            if (!(strcmp(buffer,"o")))
               wifly_on = 1;
            else if (!(strcmp(buffer,"f"))){
               wifly_on = 0;
               pc.printf("wifi off\r\n");
            }
                Thread::wait(100);
        client.send_all(buffer,n);
        pc.printf("Sent data is %s\r\n",buffer);
        }
        else
        Thread::wait(1*SEC);
        Thread::wait(100);   //This wait is necessary for the condition in which http
                                     //client is connected but it does not receive anything.
                                     //if n<= 0
        }
}
/****************************************************************************************/