Done
Dependencies: C12832_lcd EthernetInterface LM75B MMA7660 NTPClient libxively mbed-rtos mbed
main.cpp
00001 /****************************************************************************************/ 00002 /* INTERNET OF THINGS ASSIGNMENT 7 */ 00003 /*This assignment implements a thermostat which turns ON/OFF depending on the set and */ 00004 /*current temperature. The thermostat can be turned ON/OFF by following ways: */ 00005 /* 1. Joustick up button on the application board. */ 00006 /* 2. Depending on if there is movement or not */ 00007 /* 3. Remotely through xively */ 00008 /*The program also updates following things on xively: */ 00009 /* 1. Current Temperature */ 00010 /* 2. Movement detection */ 00011 /****************************************************************************************/ 00012 00013 #include "mbed.h" 00014 #include "rtos.h" 00015 #include "C12832_lcd.h" 00016 #include "EthernetInterface.h" 00017 00018 #include "xively.h" 00019 #include "xi_err.h" 00020 #include "LM75B.h" 00021 #include "DebouncedIn.h" 00022 #include "MMA7660.h" 00023 00024 #define XI_FEED_ID 1443794017 // set Xively Feed ID (numerical, no quoutes) 00025 #define XI_API_KEY "iydtzKtHKHNpc4mQqq5Quv8jhi5nMwg6EKXSN6UkspZcXTrI" 00026 // set Xively API key (double-quoted string) 00027 00028 #define SEC 1000 //macro for no. of msec in sec 00029 #define MIN 60*SEC //macro for no. of msec in min 00030 #define hys 3 00031 #define TIME 20 //Time after which system should turn OFF if 00032 //no movement detected 00033 #define OFF 0 00034 #define ON 1 00035 00036 Mutex LCD; 00037 C12832_LCD lcd; 00038 Serial pc (USBTX,USBRX); 00039 //LM75B current(p28,p27); 00040 MMA7660 MMA(p28,p27); 00041 00042 BusOut move(p23,p24,p25); 00043 00044 //System ON/OFF 00045 BusIn heat_on (p16,p13); 00046 00047 //Increase Temperature 00048 DebouncedIn temp_up (p15); 00049 00050 //Decrease Temperature 00051 DebouncedIn temp_down (p12); 00052 00053 //System ON/OFF LED 00054 DigitalOut thermostat (LED1); 00055 00056 //Heater ON/OFF LED. This can be furthur connected to the relay 00057 DigitalOut heater (LED2); 00058 00059 00060 int temp = 10; 00061 bool status = 0; 00062 bool remote_state = ON; 00063 00064 void update_lcd(void const *args); //Thread 1 00065 void Thermostat_logic (void const *args); //Thread 2 00066 void check_movement(void const *args); //Thread 3 00067 00068 bool no_move; 00069 float acc_x = MMA.x(); 00070 float acc_y = MMA.y(); 00071 float acc_z = MMA.z(); 00072 float acc_x_old,acc_y_old,acc_z_old; 00073 00074 /****************************************************************************************/ 00075 /*Thread update_lcd: This thread is used to update the lcd. The LCD will dispaly current*/ 00076 /*time, Set temperature and the actual temperature. If the system is OFF lcd will show */ 00077 /*current time and message 'System OFF' */ 00078 /****************************************************************************************/ 00079 void update_lcd(void const *args) 00080 { 00081 set_time(1391739990); 00082 while (true) { 00083 time_t seconds = time(NULL); 00084 LCD.lock(); 00085 lcd.locate(0,0); 00086 lcd.printf("%s",ctime(&seconds)); 00087 lcd.locate(0,10); 00088 if (status) { 00089 lcd.printf("Current: %.2f",current.read()); 00090 lcd.locate(1,20); 00091 lcd.printf("Set: %d",temp); 00092 } else { 00093 lcd.cls(); 00094 lcd.locate(0,0); 00095 lcd.printf("%s",ctime(&seconds)); 00096 lcd.locate(0,10); 00097 lcd.printf("System OFF"); 00098 } 00099 LCD.unlock(); 00100 Thread::wait(200); //wait for 200 msec 00101 } 00102 } 00103 /****************************************************************************************/ 00104 00105 00106 /****************************************************************************************/ 00107 /*Thread: thermostat logic: This thread implements the logic of the thermostat. It turns*/ 00108 /*ON/OFF the thermostat depending on temperature, movement and the web control. It also */ 00109 /*allows the user to set the temperature from the push button switches. The setting of */ 00110 /*temperature can also be done remotely through xively. Currently the program just */ 00111 /*controls turning ON/OFF the system remotely. */ 00112 /****************************************************************************************/ 00113 void Thermostat_logic(void const *args) 00114 { 00115 while (true) { 00116 if (heat_on == 0x2 || (/*!no_move ||*/ remote_state == ON)) 00117 { 00118 thermostat = 1; 00119 status = 1; 00120 } else if (heat_on == 0x1 || /*no_move ||*/ remote_state == OFF) { 00121 thermostat = 0; 00122 heater = 0; 00123 status = 0; 00124 } 00125 00126 /*If the joystick is pushed upwards increase set temperature by 2 00127 And print the set temperature on LCD.*/ 00128 if (temp_up.rising()) { 00129 temp = temp + 0x2; 00130 } 00131 00132 /*else if the joystick is pushed downwards decrease set temperature by 2 00133 And print the set temperature on LCD.*/ 00134 00135 else if (temp_down.rising()) { 00136 temp = temp - 0x2; 00137 } 00138 00139 //Comparison logic and turn Heater ON/OFF 00140 if ((temp > (current.read()+ hys)) & thermostat == 1) 00141 heater = 1; 00142 else if ((temp < (current.read()- hys)) | thermostat == 0) 00143 heater = 0; 00144 00145 if (acc_x_old != MMA.x() || acc_y_old != MMA.y() || acc_z_old != MMA.x()) 00146 { 00147 no_move = 0; 00148 } 00149 00150 Thread::wait(100); //wait for 100 msec 00151 } 00152 } 00153 /****************************************************************************************/ 00154 00155 00156 /****************************************************************************************/ 00157 /*Thread check movement: This thread detects if there is movement nearby the thermostat.*/ 00158 /*If there is no movement this thread sets a variable called no_move which is furthur */ 00159 /*used to turn ON/OFF the system. Logic implemented for movement detection is as follows*/ 00160 /*This thread is executed once every minute. Every time this thread is executed it */ 00161 /*compares the accelerometer reading with its previous value. If the reading is same */ 00162 /*(no movement detected) it increments a counter. When this counter reaches 20 (which */ 00163 /*means there is no movement for 20 mins) it sets the variable no_move to turn OFF the */ 00164 /*system. When a different accelerometer value is detected(movement present) it resets */ 00165 /*the variable which will in turn turn the system ON. */ 00166 /****************************************************************************************/ 00167 00168 void check_movement(void const *args) 00169 { 00170 static int move_cntr = 0; 00171 while (true) { 00172 acc_x_old = acc_x; 00173 acc_y_old = acc_y; 00174 acc_z_old = acc_z; 00175 acc_x = MMA.x(); 00176 acc_y = MMA.y(); 00177 acc_z = MMA.z(); 00178 if (acc_x_old == acc_x && acc_y_old == acc_y && acc_z_old == acc_z) 00179 { 00180 move_cntr++; 00181 pc.printf("Value of move_cntr = %d\r\n",move_cntr); 00182 move = 011; 00183 } 00184 else { 00185 move_cntr = 0; 00186 pc.printf("Move_cntr reset\r\n");} 00187 //If the Accelerometer value remains constant for 20 mins no movement detected 00188 if (move_cntr >= TIME) 00189 no_move = 1; 00190 else 00191 no_move = 0; 00192 Thread::wait(1*MIN); 00193 } 00194 } 00195 /****************************************************************************************/ 00196 00197 00198 /****************************************************************************************/ 00199 /*Thread main: This is the main thread which instantiates all other threads. This thread*/ 00200 /*is also used to communicate with xively. It updates xively with the current temoerature*/ 00201 /*and the movement status. It also reads the status command from xively and turns ON/OFF */ 00202 /*the system accordingly. This thread is also used for setting up ethernet connection */ 00203 /****************************************************************************************/ 00204 00205 int main() { 00206 00207 Thread lcd_display(update_lcd,NULL, osPriorityAboveNormal); 00208 Thread thermostat_thread(Thermostat_logic,NULL, osPriorityAboveNormal); 00209 Thread accel_thread(check_movement,NULL,osPriorityAboveNormal); 00210 00211 EthernetInterface eth; 00212 00213 int s = eth.init(); //Use DHCP 00214 if( s != NULL ) 00215 { 00216 pc.printf( "Could not initialise. Will halt!\n" ); 00217 exit( 0 ); 00218 } 00219 00220 s = eth.connect(); 00221 00222 if( s != NULL ) 00223 { 00224 pc.printf( "Could not connect. Will halt!\n" ); 00225 exit( 0 ); 00226 } 00227 else 00228 { 00229 pc.printf( "IP: %s\n", eth.getIPAddress() ); 00230 } 00231 00232 xi_feed_t feed; 00233 memset( &feed, NULL, sizeof( xi_feed_t ) ); 00234 00235 feed.feed_id = XI_FEED_ID; 00236 feed.datastream_count = 4; 00237 00238 /*Data stream for temperature*/ 00239 feed.datastreams[0].datapoint_count = 1; 00240 xi_datastream_t* temperature_datastream = &feed.datastreams[0]; 00241 strcpy( temperature_datastream->datastream_id, "Temperature" ); 00242 xi_datapoint_t* current_temperature = &temperature_datastream->datapoints[0]; 00243 00244 /*Data stream for movement*/ 00245 feed.datastreams[1].datapoint_count = 1; 00246 xi_datastream_t* orientation_datastream = &feed.datastreams[1]; 00247 strcpy( orientation_datastream->datastream_id, "Movement" ); 00248 xi_datapoint_t* current_orientation = &orientation_datastream->datapoints[0]; 00249 00250 /*Data stream for status control (Input datastream)*/ 00251 feed.datastreams[2].datapoint_count = 1; 00252 xi_datastream_t* control_datastream = &feed.datastreams[2]; 00253 strcpy( control_datastream->datastream_id, "System" ); 00254 xi_datapoint_t* current_state = &control_datastream->datapoints[0]; 00255 00256 // create the cosm library context 00257 xi_context_t* xi_context 00258 = xi_create_context( XI_HTTP, XI_API_KEY, feed.feed_id ); 00259 if( xi_context == NULL ) 00260 { 00261 pc.printf("Error in Xi_Context\r\n"); 00262 exit (0); 00263 } 00264 00265 while (true) { 00266 xi_set_value_f32( current_temperature, current.read() ); 00267 if (no_move == 1) 00268 { 00269 xi_set_value_str( current_orientation, "No movement" ); 00270 } 00271 else 00272 { 00273 xi_set_value_str( current_orientation, "Movement Present" ); 00274 } 00275 // read remote value 00276 xi_datastream_get( xi_context, feed.feed_id 00277 , control_datastream->datastream_id 00278 , control_datastream->datapoints); 00279 current_state = &control_datastream->datapoints[0]; 00280 int system_status = current_state->value.i32_value; 00281 if (system_status == 0) 00282 { 00283 remote_state = OFF; 00284 } 00285 else 00286 { 00287 remote_state = ON; 00288 } 00289 00290 pc.printf("Status value is %d\r\n",system_status); 00291 pc.printf("Done\r\n"); 00292 xi_feed_update( xi_context, &feed ); 00293 Thread::wait(15*SEC); 00294 } 00295 } 00296 /****************************************************************************************/
Generated on Wed Jul 13 2022 23:39:29 by 1.7.2