Done

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

Committer:
bhakti08
Date:
Tue Jun 03 04:26:54 2014 +0000
Revision:
0:8f6eb1fedc58
Done

Who changed what in which revision?

UserRevisionLine numberNew contents of line
bhakti08 0:8f6eb1fedc58 1 /****************************************************************************************/
bhakti08 0:8f6eb1fedc58 2 /* INTERNET OF THINGS ASSIGNMENT 7 */
bhakti08 0:8f6eb1fedc58 3 /*This assignment implements a thermostat which turns ON/OFF depending on the set and */
bhakti08 0:8f6eb1fedc58 4 /*current temperature. The thermostat can be turned ON/OFF by following ways: */
bhakti08 0:8f6eb1fedc58 5 /* 1. Joustick up button on the application board. */
bhakti08 0:8f6eb1fedc58 6 /* 2. Depending on if there is movement or not */
bhakti08 0:8f6eb1fedc58 7 /* 3. Remotely through xively */
bhakti08 0:8f6eb1fedc58 8 /*The program also updates following things on xively: */
bhakti08 0:8f6eb1fedc58 9 /* 1. Current Temperature */
bhakti08 0:8f6eb1fedc58 10 /* 2. Movement detection */
bhakti08 0:8f6eb1fedc58 11 /****************************************************************************************/
bhakti08 0:8f6eb1fedc58 12
bhakti08 0:8f6eb1fedc58 13 #include "mbed.h"
bhakti08 0:8f6eb1fedc58 14 #include "rtos.h"
bhakti08 0:8f6eb1fedc58 15 #include "C12832_lcd.h"
bhakti08 0:8f6eb1fedc58 16 #include "EthernetInterface.h"
bhakti08 0:8f6eb1fedc58 17
bhakti08 0:8f6eb1fedc58 18 #include "xively.h"
bhakti08 0:8f6eb1fedc58 19 #include "xi_err.h"
bhakti08 0:8f6eb1fedc58 20 #include "LM75B.h"
bhakti08 0:8f6eb1fedc58 21 #include "DebouncedIn.h"
bhakti08 0:8f6eb1fedc58 22 #include "MMA7660.h"
bhakti08 0:8f6eb1fedc58 23
bhakti08 0:8f6eb1fedc58 24 #define XI_FEED_ID 1443794017 // set Xively Feed ID (numerical, no quoutes)
bhakti08 0:8f6eb1fedc58 25 #define XI_API_KEY "iydtzKtHKHNpc4mQqq5Quv8jhi5nMwg6EKXSN6UkspZcXTrI"
bhakti08 0:8f6eb1fedc58 26 // set Xively API key (double-quoted string)
bhakti08 0:8f6eb1fedc58 27
bhakti08 0:8f6eb1fedc58 28 #define SEC 1000 //macro for no. of msec in sec
bhakti08 0:8f6eb1fedc58 29 #define MIN 60*SEC //macro for no. of msec in min
bhakti08 0:8f6eb1fedc58 30 #define hys 3
bhakti08 0:8f6eb1fedc58 31 #define TIME 20 //Time after which system should turn OFF if
bhakti08 0:8f6eb1fedc58 32 //no movement detected
bhakti08 0:8f6eb1fedc58 33 #define OFF 0
bhakti08 0:8f6eb1fedc58 34 #define ON 1
bhakti08 0:8f6eb1fedc58 35
bhakti08 0:8f6eb1fedc58 36 Mutex LCD;
bhakti08 0:8f6eb1fedc58 37 C12832_LCD lcd;
bhakti08 0:8f6eb1fedc58 38 Serial pc (USBTX,USBRX);
bhakti08 0:8f6eb1fedc58 39 //LM75B current(p28,p27);
bhakti08 0:8f6eb1fedc58 40 MMA7660 MMA(p28,p27);
bhakti08 0:8f6eb1fedc58 41
bhakti08 0:8f6eb1fedc58 42 BusOut move(p23,p24,p25);
bhakti08 0:8f6eb1fedc58 43
bhakti08 0:8f6eb1fedc58 44 //System ON/OFF
bhakti08 0:8f6eb1fedc58 45 BusIn heat_on (p16,p13);
bhakti08 0:8f6eb1fedc58 46
bhakti08 0:8f6eb1fedc58 47 //Increase Temperature
bhakti08 0:8f6eb1fedc58 48 DebouncedIn temp_up (p15);
bhakti08 0:8f6eb1fedc58 49
bhakti08 0:8f6eb1fedc58 50 //Decrease Temperature
bhakti08 0:8f6eb1fedc58 51 DebouncedIn temp_down (p12);
bhakti08 0:8f6eb1fedc58 52
bhakti08 0:8f6eb1fedc58 53 //System ON/OFF LED
bhakti08 0:8f6eb1fedc58 54 DigitalOut thermostat (LED1);
bhakti08 0:8f6eb1fedc58 55
bhakti08 0:8f6eb1fedc58 56 //Heater ON/OFF LED. This can be furthur connected to the relay
bhakti08 0:8f6eb1fedc58 57 DigitalOut heater (LED2);
bhakti08 0:8f6eb1fedc58 58
bhakti08 0:8f6eb1fedc58 59
bhakti08 0:8f6eb1fedc58 60 int temp = 10;
bhakti08 0:8f6eb1fedc58 61 bool status = 0;
bhakti08 0:8f6eb1fedc58 62 bool remote_state = ON;
bhakti08 0:8f6eb1fedc58 63
bhakti08 0:8f6eb1fedc58 64 void update_lcd(void const *args); //Thread 1
bhakti08 0:8f6eb1fedc58 65 void Thermostat_logic (void const *args); //Thread 2
bhakti08 0:8f6eb1fedc58 66 void check_movement(void const *args); //Thread 3
bhakti08 0:8f6eb1fedc58 67
bhakti08 0:8f6eb1fedc58 68 bool no_move;
bhakti08 0:8f6eb1fedc58 69 float acc_x = MMA.x();
bhakti08 0:8f6eb1fedc58 70 float acc_y = MMA.y();
bhakti08 0:8f6eb1fedc58 71 float acc_z = MMA.z();
bhakti08 0:8f6eb1fedc58 72 float acc_x_old,acc_y_old,acc_z_old;
bhakti08 0:8f6eb1fedc58 73
bhakti08 0:8f6eb1fedc58 74 /****************************************************************************************/
bhakti08 0:8f6eb1fedc58 75 /*Thread update_lcd: This thread is used to update the lcd. The LCD will dispaly current*/
bhakti08 0:8f6eb1fedc58 76 /*time, Set temperature and the actual temperature. If the system is OFF lcd will show */
bhakti08 0:8f6eb1fedc58 77 /*current time and message 'System OFF' */
bhakti08 0:8f6eb1fedc58 78 /****************************************************************************************/
bhakti08 0:8f6eb1fedc58 79 void update_lcd(void const *args)
bhakti08 0:8f6eb1fedc58 80 {
bhakti08 0:8f6eb1fedc58 81 set_time(1391739990);
bhakti08 0:8f6eb1fedc58 82 while (true) {
bhakti08 0:8f6eb1fedc58 83 time_t seconds = time(NULL);
bhakti08 0:8f6eb1fedc58 84 LCD.lock();
bhakti08 0:8f6eb1fedc58 85 lcd.locate(0,0);
bhakti08 0:8f6eb1fedc58 86 lcd.printf("%s",ctime(&seconds));
bhakti08 0:8f6eb1fedc58 87 lcd.locate(0,10);
bhakti08 0:8f6eb1fedc58 88 if (status) {
bhakti08 0:8f6eb1fedc58 89 lcd.printf("Current: %.2f",current.read());
bhakti08 0:8f6eb1fedc58 90 lcd.locate(1,20);
bhakti08 0:8f6eb1fedc58 91 lcd.printf("Set: %d",temp);
bhakti08 0:8f6eb1fedc58 92 } else {
bhakti08 0:8f6eb1fedc58 93 lcd.cls();
bhakti08 0:8f6eb1fedc58 94 lcd.locate(0,0);
bhakti08 0:8f6eb1fedc58 95 lcd.printf("%s",ctime(&seconds));
bhakti08 0:8f6eb1fedc58 96 lcd.locate(0,10);
bhakti08 0:8f6eb1fedc58 97 lcd.printf("System OFF");
bhakti08 0:8f6eb1fedc58 98 }
bhakti08 0:8f6eb1fedc58 99 LCD.unlock();
bhakti08 0:8f6eb1fedc58 100 Thread::wait(200); //wait for 200 msec
bhakti08 0:8f6eb1fedc58 101 }
bhakti08 0:8f6eb1fedc58 102 }
bhakti08 0:8f6eb1fedc58 103 /****************************************************************************************/
bhakti08 0:8f6eb1fedc58 104
bhakti08 0:8f6eb1fedc58 105
bhakti08 0:8f6eb1fedc58 106 /****************************************************************************************/
bhakti08 0:8f6eb1fedc58 107 /*Thread: thermostat logic: This thread implements the logic of the thermostat. It turns*/
bhakti08 0:8f6eb1fedc58 108 /*ON/OFF the thermostat depending on temperature, movement and the web control. It also */
bhakti08 0:8f6eb1fedc58 109 /*allows the user to set the temperature from the push button switches. The setting of */
bhakti08 0:8f6eb1fedc58 110 /*temperature can also be done remotely through xively. Currently the program just */
bhakti08 0:8f6eb1fedc58 111 /*controls turning ON/OFF the system remotely. */
bhakti08 0:8f6eb1fedc58 112 /****************************************************************************************/
bhakti08 0:8f6eb1fedc58 113 void Thermostat_logic(void const *args)
bhakti08 0:8f6eb1fedc58 114 {
bhakti08 0:8f6eb1fedc58 115 while (true) {
bhakti08 0:8f6eb1fedc58 116 if (heat_on == 0x2 || (/*!no_move ||*/ remote_state == ON))
bhakti08 0:8f6eb1fedc58 117 {
bhakti08 0:8f6eb1fedc58 118 thermostat = 1;
bhakti08 0:8f6eb1fedc58 119 status = 1;
bhakti08 0:8f6eb1fedc58 120 } else if (heat_on == 0x1 || /*no_move ||*/ remote_state == OFF) {
bhakti08 0:8f6eb1fedc58 121 thermostat = 0;
bhakti08 0:8f6eb1fedc58 122 heater = 0;
bhakti08 0:8f6eb1fedc58 123 status = 0;
bhakti08 0:8f6eb1fedc58 124 }
bhakti08 0:8f6eb1fedc58 125
bhakti08 0:8f6eb1fedc58 126 /*If the joystick is pushed upwards increase set temperature by 2
bhakti08 0:8f6eb1fedc58 127 And print the set temperature on LCD.*/
bhakti08 0:8f6eb1fedc58 128 if (temp_up.rising()) {
bhakti08 0:8f6eb1fedc58 129 temp = temp + 0x2;
bhakti08 0:8f6eb1fedc58 130 }
bhakti08 0:8f6eb1fedc58 131
bhakti08 0:8f6eb1fedc58 132 /*else if the joystick is pushed downwards decrease set temperature by 2
bhakti08 0:8f6eb1fedc58 133 And print the set temperature on LCD.*/
bhakti08 0:8f6eb1fedc58 134
bhakti08 0:8f6eb1fedc58 135 else if (temp_down.rising()) {
bhakti08 0:8f6eb1fedc58 136 temp = temp - 0x2;
bhakti08 0:8f6eb1fedc58 137 }
bhakti08 0:8f6eb1fedc58 138
bhakti08 0:8f6eb1fedc58 139 //Comparison logic and turn Heater ON/OFF
bhakti08 0:8f6eb1fedc58 140 if ((temp > (current.read()+ hys)) & thermostat == 1)
bhakti08 0:8f6eb1fedc58 141 heater = 1;
bhakti08 0:8f6eb1fedc58 142 else if ((temp < (current.read()- hys)) | thermostat == 0)
bhakti08 0:8f6eb1fedc58 143 heater = 0;
bhakti08 0:8f6eb1fedc58 144
bhakti08 0:8f6eb1fedc58 145 if (acc_x_old != MMA.x() || acc_y_old != MMA.y() || acc_z_old != MMA.x())
bhakti08 0:8f6eb1fedc58 146 {
bhakti08 0:8f6eb1fedc58 147 no_move = 0;
bhakti08 0:8f6eb1fedc58 148 }
bhakti08 0:8f6eb1fedc58 149
bhakti08 0:8f6eb1fedc58 150 Thread::wait(100); //wait for 100 msec
bhakti08 0:8f6eb1fedc58 151 }
bhakti08 0:8f6eb1fedc58 152 }
bhakti08 0:8f6eb1fedc58 153 /****************************************************************************************/
bhakti08 0:8f6eb1fedc58 154
bhakti08 0:8f6eb1fedc58 155
bhakti08 0:8f6eb1fedc58 156 /****************************************************************************************/
bhakti08 0:8f6eb1fedc58 157 /*Thread check movement: This thread detects if there is movement nearby the thermostat.*/
bhakti08 0:8f6eb1fedc58 158 /*If there is no movement this thread sets a variable called no_move which is furthur */
bhakti08 0:8f6eb1fedc58 159 /*used to turn ON/OFF the system. Logic implemented for movement detection is as follows*/
bhakti08 0:8f6eb1fedc58 160 /*This thread is executed once every minute. Every time this thread is executed it */
bhakti08 0:8f6eb1fedc58 161 /*compares the accelerometer reading with its previous value. If the reading is same */
bhakti08 0:8f6eb1fedc58 162 /*(no movement detected) it increments a counter. When this counter reaches 20 (which */
bhakti08 0:8f6eb1fedc58 163 /*means there is no movement for 20 mins) it sets the variable no_move to turn OFF the */
bhakti08 0:8f6eb1fedc58 164 /*system. When a different accelerometer value is detected(movement present) it resets */
bhakti08 0:8f6eb1fedc58 165 /*the variable which will in turn turn the system ON. */
bhakti08 0:8f6eb1fedc58 166 /****************************************************************************************/
bhakti08 0:8f6eb1fedc58 167
bhakti08 0:8f6eb1fedc58 168 void check_movement(void const *args)
bhakti08 0:8f6eb1fedc58 169 {
bhakti08 0:8f6eb1fedc58 170 static int move_cntr = 0;
bhakti08 0:8f6eb1fedc58 171 while (true) {
bhakti08 0:8f6eb1fedc58 172 acc_x_old = acc_x;
bhakti08 0:8f6eb1fedc58 173 acc_y_old = acc_y;
bhakti08 0:8f6eb1fedc58 174 acc_z_old = acc_z;
bhakti08 0:8f6eb1fedc58 175 acc_x = MMA.x();
bhakti08 0:8f6eb1fedc58 176 acc_y = MMA.y();
bhakti08 0:8f6eb1fedc58 177 acc_z = MMA.z();
bhakti08 0:8f6eb1fedc58 178 if (acc_x_old == acc_x && acc_y_old == acc_y && acc_z_old == acc_z)
bhakti08 0:8f6eb1fedc58 179 {
bhakti08 0:8f6eb1fedc58 180 move_cntr++;
bhakti08 0:8f6eb1fedc58 181 pc.printf("Value of move_cntr = %d\r\n",move_cntr);
bhakti08 0:8f6eb1fedc58 182 move = 011;
bhakti08 0:8f6eb1fedc58 183 }
bhakti08 0:8f6eb1fedc58 184 else {
bhakti08 0:8f6eb1fedc58 185 move_cntr = 0;
bhakti08 0:8f6eb1fedc58 186 pc.printf("Move_cntr reset\r\n");}
bhakti08 0:8f6eb1fedc58 187 //If the Accelerometer value remains constant for 20 mins no movement detected
bhakti08 0:8f6eb1fedc58 188 if (move_cntr >= TIME)
bhakti08 0:8f6eb1fedc58 189 no_move = 1;
bhakti08 0:8f6eb1fedc58 190 else
bhakti08 0:8f6eb1fedc58 191 no_move = 0;
bhakti08 0:8f6eb1fedc58 192 Thread::wait(1*MIN);
bhakti08 0:8f6eb1fedc58 193 }
bhakti08 0:8f6eb1fedc58 194 }
bhakti08 0:8f6eb1fedc58 195 /****************************************************************************************/
bhakti08 0:8f6eb1fedc58 196
bhakti08 0:8f6eb1fedc58 197
bhakti08 0:8f6eb1fedc58 198 /****************************************************************************************/
bhakti08 0:8f6eb1fedc58 199 /*Thread main: This is the main thread which instantiates all other threads. This thread*/
bhakti08 0:8f6eb1fedc58 200 /*is also used to communicate with xively. It updates xively with the current temoerature*/
bhakti08 0:8f6eb1fedc58 201 /*and the movement status. It also reads the status command from xively and turns ON/OFF */
bhakti08 0:8f6eb1fedc58 202 /*the system accordingly. This thread is also used for setting up ethernet connection */
bhakti08 0:8f6eb1fedc58 203 /****************************************************************************************/
bhakti08 0:8f6eb1fedc58 204
bhakti08 0:8f6eb1fedc58 205 int main() {
bhakti08 0:8f6eb1fedc58 206
bhakti08 0:8f6eb1fedc58 207 Thread lcd_display(update_lcd,NULL, osPriorityAboveNormal);
bhakti08 0:8f6eb1fedc58 208 Thread thermostat_thread(Thermostat_logic,NULL, osPriorityAboveNormal);
bhakti08 0:8f6eb1fedc58 209 Thread accel_thread(check_movement,NULL,osPriorityAboveNormal);
bhakti08 0:8f6eb1fedc58 210
bhakti08 0:8f6eb1fedc58 211 EthernetInterface eth;
bhakti08 0:8f6eb1fedc58 212
bhakti08 0:8f6eb1fedc58 213 int s = eth.init(); //Use DHCP
bhakti08 0:8f6eb1fedc58 214 if( s != NULL )
bhakti08 0:8f6eb1fedc58 215 {
bhakti08 0:8f6eb1fedc58 216 pc.printf( "Could not initialise. Will halt!\n" );
bhakti08 0:8f6eb1fedc58 217 exit( 0 );
bhakti08 0:8f6eb1fedc58 218 }
bhakti08 0:8f6eb1fedc58 219
bhakti08 0:8f6eb1fedc58 220 s = eth.connect();
bhakti08 0:8f6eb1fedc58 221
bhakti08 0:8f6eb1fedc58 222 if( s != NULL )
bhakti08 0:8f6eb1fedc58 223 {
bhakti08 0:8f6eb1fedc58 224 pc.printf( "Could not connect. Will halt!\n" );
bhakti08 0:8f6eb1fedc58 225 exit( 0 );
bhakti08 0:8f6eb1fedc58 226 }
bhakti08 0:8f6eb1fedc58 227 else
bhakti08 0:8f6eb1fedc58 228 {
bhakti08 0:8f6eb1fedc58 229 pc.printf( "IP: %s\n", eth.getIPAddress() );
bhakti08 0:8f6eb1fedc58 230 }
bhakti08 0:8f6eb1fedc58 231
bhakti08 0:8f6eb1fedc58 232 xi_feed_t feed;
bhakti08 0:8f6eb1fedc58 233 memset( &feed, NULL, sizeof( xi_feed_t ) );
bhakti08 0:8f6eb1fedc58 234
bhakti08 0:8f6eb1fedc58 235 feed.feed_id = XI_FEED_ID;
bhakti08 0:8f6eb1fedc58 236 feed.datastream_count = 4;
bhakti08 0:8f6eb1fedc58 237
bhakti08 0:8f6eb1fedc58 238 /*Data stream for temperature*/
bhakti08 0:8f6eb1fedc58 239 feed.datastreams[0].datapoint_count = 1;
bhakti08 0:8f6eb1fedc58 240 xi_datastream_t* temperature_datastream = &feed.datastreams[0];
bhakti08 0:8f6eb1fedc58 241 strcpy( temperature_datastream->datastream_id, "Temperature" );
bhakti08 0:8f6eb1fedc58 242 xi_datapoint_t* current_temperature = &temperature_datastream->datapoints[0];
bhakti08 0:8f6eb1fedc58 243
bhakti08 0:8f6eb1fedc58 244 /*Data stream for movement*/
bhakti08 0:8f6eb1fedc58 245 feed.datastreams[1].datapoint_count = 1;
bhakti08 0:8f6eb1fedc58 246 xi_datastream_t* orientation_datastream = &feed.datastreams[1];
bhakti08 0:8f6eb1fedc58 247 strcpy( orientation_datastream->datastream_id, "Movement" );
bhakti08 0:8f6eb1fedc58 248 xi_datapoint_t* current_orientation = &orientation_datastream->datapoints[0];
bhakti08 0:8f6eb1fedc58 249
bhakti08 0:8f6eb1fedc58 250 /*Data stream for status control (Input datastream)*/
bhakti08 0:8f6eb1fedc58 251 feed.datastreams[2].datapoint_count = 1;
bhakti08 0:8f6eb1fedc58 252 xi_datastream_t* control_datastream = &feed.datastreams[2];
bhakti08 0:8f6eb1fedc58 253 strcpy( control_datastream->datastream_id, "System" );
bhakti08 0:8f6eb1fedc58 254 xi_datapoint_t* current_state = &control_datastream->datapoints[0];
bhakti08 0:8f6eb1fedc58 255
bhakti08 0:8f6eb1fedc58 256 // create the cosm library context
bhakti08 0:8f6eb1fedc58 257 xi_context_t* xi_context
bhakti08 0:8f6eb1fedc58 258 = xi_create_context( XI_HTTP, XI_API_KEY, feed.feed_id );
bhakti08 0:8f6eb1fedc58 259 if( xi_context == NULL )
bhakti08 0:8f6eb1fedc58 260 {
bhakti08 0:8f6eb1fedc58 261 pc.printf("Error in Xi_Context\r\n");
bhakti08 0:8f6eb1fedc58 262 exit (0);
bhakti08 0:8f6eb1fedc58 263 }
bhakti08 0:8f6eb1fedc58 264
bhakti08 0:8f6eb1fedc58 265 while (true) {
bhakti08 0:8f6eb1fedc58 266 xi_set_value_f32( current_temperature, current.read() );
bhakti08 0:8f6eb1fedc58 267 if (no_move == 1)
bhakti08 0:8f6eb1fedc58 268 {
bhakti08 0:8f6eb1fedc58 269 xi_set_value_str( current_orientation, "No movement" );
bhakti08 0:8f6eb1fedc58 270 }
bhakti08 0:8f6eb1fedc58 271 else
bhakti08 0:8f6eb1fedc58 272 {
bhakti08 0:8f6eb1fedc58 273 xi_set_value_str( current_orientation, "Movement Present" );
bhakti08 0:8f6eb1fedc58 274 }
bhakti08 0:8f6eb1fedc58 275 // read remote value
bhakti08 0:8f6eb1fedc58 276 xi_datastream_get( xi_context, feed.feed_id
bhakti08 0:8f6eb1fedc58 277 , control_datastream->datastream_id
bhakti08 0:8f6eb1fedc58 278 , control_datastream->datapoints);
bhakti08 0:8f6eb1fedc58 279 current_state = &control_datastream->datapoints[0];
bhakti08 0:8f6eb1fedc58 280 int system_status = current_state->value.i32_value;
bhakti08 0:8f6eb1fedc58 281 if (system_status == 0)
bhakti08 0:8f6eb1fedc58 282 {
bhakti08 0:8f6eb1fedc58 283 remote_state = OFF;
bhakti08 0:8f6eb1fedc58 284 }
bhakti08 0:8f6eb1fedc58 285 else
bhakti08 0:8f6eb1fedc58 286 {
bhakti08 0:8f6eb1fedc58 287 remote_state = ON;
bhakti08 0:8f6eb1fedc58 288 }
bhakti08 0:8f6eb1fedc58 289
bhakti08 0:8f6eb1fedc58 290 pc.printf("Status value is %d\r\n",system_status);
bhakti08 0:8f6eb1fedc58 291 pc.printf("Done\r\n");
bhakti08 0:8f6eb1fedc58 292 xi_feed_update( xi_context, &feed );
bhakti08 0:8f6eb1fedc58 293 Thread::wait(15*SEC);
bhakti08 0:8f6eb1fedc58 294 }
bhakti08 0:8f6eb1fedc58 295 }
bhakti08 0:8f6eb1fedc58 296 /****************************************************************************************/