Done

Dependencies:   C12832_lcd EthernetInterface LM75B MMA7660 NTPClient libxively mbed-rtos mbed

Revision:
0:8f6eb1fedc58
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Tue Jun 03 04:26:54 2014 +0000
@@ -0,0 +1,296 @@
+/****************************************************************************************/
+/*                               INTERNET OF THINGS ASSIGNMENT 7                        */
+/*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 xively                                        */
+/*The program also updates following things on xively:                                  */
+/*                    1. Current Temperature                                            */
+/*                    2. Movement detection                                             */
+/****************************************************************************************/
+
+#include "mbed.h"
+#include "rtos.h"
+#include "C12832_lcd.h"
+#include "EthernetInterface.h"
+
+#include "xively.h"
+#include "xi_err.h"
+#include "LM75B.h"
+#include "DebouncedIn.h"
+#include "MMA7660.h"
+
+#define XI_FEED_ID 1443794017 // set Xively Feed ID (numerical, no quoutes)
+#define XI_API_KEY "iydtzKtHKHNpc4mQqq5Quv8jhi5nMwg6EKXSN6UkspZcXTrI" 
+                                 // set Xively API key (double-quoted string)
+
+#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 OFF 0
+#define ON 1
+
+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;
+bool remote_state = ON;
+
+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;
+
+/****************************************************************************************/
+/*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.cls();               
+            lcd.locate(0,0);
+                        lcd.printf("%s",ctime(&seconds));               
+            lcd.locate(0,10);                   
+            lcd.printf("System OFF");
+        }     
+    LCD.unlock();
+    Thread::wait(200);     //wait for 200 msec
+    }
+}
+/****************************************************************************************/
+
+
+/****************************************************************************************/
+/*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 ||  (/*!no_move ||*/ remote_state == ON))
+        {
+            thermostat = 1;                                    
+            status = 1;                                        
+        } else if (heat_on == 0x1 || /*no_move ||*/ remote_state == OFF) {                                                 
+            thermostat = 0;                                    
+            heater = 0;                                       
+            status = 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);      //wait for 100 msec
+    }
+}
+/****************************************************************************************/
+
+
+/****************************************************************************************/
+/*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 the Accelerometer value remains constant for 20 mins no movement detected
+    if (move_cntr >= TIME)   
+        no_move = 1;
+    else
+        no_move = 0;
+    Thread::wait(1*MIN);
+    } 
+}
+/****************************************************************************************/
+
+
+/****************************************************************************************/
+/*Thread main: This is the main thread which instantiates all other threads. This thread*/
+/*is also used to communicate with xively. It updates xively with the current temoerature*/
+/*and the movement status. It also reads the status command from xively and turns ON/OFF */
+/*the system accordingly. This thread is also used for setting up ethernet connection    */
+/****************************************************************************************/
+
+int main() {
+    
+    Thread lcd_display(update_lcd,NULL,  osPriorityAboveNormal);
+    Thread thermostat_thread(Thermostat_logic,NULL,  osPriorityAboveNormal);
+    Thread accel_thread(check_movement,NULL,osPriorityAboveNormal);
+    
+    EthernetInterface eth;
+    
+    int s = eth.init(); //Use DHCP
+    if( s != NULL )
+    {
+        pc.printf( "Could not initialise. Will halt!\n" );        
+        exit( 0 );
+    }    
+        
+    s = eth.connect();
+    
+    if( s != NULL )
+    {
+        pc.printf( "Could not connect. Will halt!\n" );
+        exit( 0 );
+    }
+    else 
+    {
+        pc.printf( "IP: %s\n", eth.getIPAddress() );    
+    }
+        
+        xi_feed_t feed;
+        memset( &feed, NULL, sizeof( xi_feed_t ) );
+    
+        feed.feed_id = XI_FEED_ID;
+        feed.datastream_count = 4;
+    
+        /*Data stream for temperature*/
+        feed.datastreams[0].datapoint_count = 1;
+        xi_datastream_t* temperature_datastream = &feed.datastreams[0];
+        strcpy( temperature_datastream->datastream_id, "Temperature" );
+        xi_datapoint_t* current_temperature = &temperature_datastream->datapoints[0];
+        
+        /*Data stream for movement*/
+        feed.datastreams[1].datapoint_count = 1;
+        xi_datastream_t* orientation_datastream = &feed.datastreams[1];
+        strcpy( orientation_datastream->datastream_id, "Movement" );
+        xi_datapoint_t* current_orientation = &orientation_datastream->datapoints[0];
+
+        /*Data stream for status control (Input datastream)*/
+        feed.datastreams[2].datapoint_count = 1;
+        xi_datastream_t* control_datastream = &feed.datastreams[2];
+        strcpy( control_datastream->datastream_id, "System" );
+        xi_datapoint_t* current_state = &control_datastream->datapoints[0];
+                       
+    // create the cosm library context
+        xi_context_t* xi_context
+            = xi_create_context( XI_HTTP, XI_API_KEY, feed.feed_id );
+        if( xi_context == NULL )
+        {
+            pc.printf("Error in Xi_Context\r\n");
+            exit (0);
+        }
+
+        while (true) {
+            xi_set_value_f32( current_temperature, current.read() ); 
+            if (no_move == 1) 
+            {
+                xi_set_value_str( current_orientation, "No movement" );
+            }
+            else
+            {
+                xi_set_value_str( current_orientation, "Movement Present" );
+            }
+            // read remote value
+            xi_datastream_get( xi_context, feed.feed_id
+                    , control_datastream->datastream_id
+                    , control_datastream->datapoints);      
+                        current_state = &control_datastream->datapoints[0];   
+            int system_status = current_state->value.i32_value;
+            if (system_status == 0)
+            {
+                remote_state = OFF;
+            }
+            else
+            {
+                remote_state = ON;
+            }
+        
+            pc.printf("Status value is %d\r\n",system_status); 
+            pc.printf("Done\r\n"); 
+            xi_feed_update( xi_context, &feed );
+            Thread::wait(15*SEC);
+        }
+}
+/****************************************************************************************/
\ No newline at end of file