Done
Dependencies: C12832_lcd EthernetInterface LM75B MMA7660 NTPClient libxively mbed-rtos mbed
main.cpp
- Committer:
- bhakti08
- Date:
- 2014-06-03
- Revision:
- 0:8f6eb1fedc58
File content as of revision 0:8f6eb1fedc58:
/****************************************************************************************/ /* 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); } } /****************************************************************************************/