forked from arunram85/Embedded_TASK_climate_control
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathClimate_control_10_1.ino
431 lines (298 loc) · 12.6 KB
/
Climate_control_10_1.ino
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
/*
* Embedded systems LAB SS17 : Task : Climate Control
*
*/
#define SET_TEMPERATURE A0 // A0 pin is set temperature value
#define TEMPERATURE_SENSOR 15
#include <Servo.h>
#include <OneWire.h>
#include <Wire.h>
#include <SPI.h>
#include <digitalWriteFast.h>
#include <GraphicsLib.h>
#include <MI0283QT2.h>
#define LINE_1 1
#define LINE_2 2
#define LINE_3 3
#define INCREASING_TEMPERATURE 4
#define DECREASING_TEMPERATURE 5
#define NO_ACTION 6
#define SERVO_CONTROL 9
/* ################################################################################################################################# */
//Global initializations and constants settings
const int loopDelay =1000;
const double TemperatureOffset =0.5; // in degree centigrade ===============> change this as per the user requirement.Recommended value =0.5
/**Calibrate the initial position of the Servo motor to vertical(neutral) position **/
const int servo_angle_calibration_offset = 8;// in degrees ===============> change this as per the user requirement
const int neutral_pos_angle =90+servo_angle_calibration_offset;// ===============> change this as per the user requirement
const int angle_of_rotation_from_neutral_pos = 18;// in degrees // ===============> change this as per the user requirement
const int min_angle = neutral_pos_angle-angle_of_rotation_from_neutral_pos;
const int max_angle = neutral_pos_angle+angle_of_rotation_from_neutral_pos;
/** duration in seconds **/
const int button_press_duration= 1; //in seconds ================> change this as per requirement .Recommended value = 2 to 3 seconds
/** repeatition_interval in seconds **/
const int button_press_repeatition_interval= 10; //in seconds ================> change this as per requirement .Recommended value = 10 minutes ie 600 seconds
/* #################################################################################################################################### */
int decrease_temperature_counter=0;
int increase_temperature_counter=0;
Servo servo;
MI0283QT2 lcd;
//Temperature chip I/o
OneWire ds(TEMPERATURE_SENSOR);
/**
*Setup and initialization.This function does the initial setup of inputs,servo motor and the LCD
*/
void setup()
{
//=========================================
pinMode(SET_TEMPERATURE, INPUT);
pinMode(TEMPERATURE_SENSOR, INPUT);
pinMode(SERVO_CONTROL, OUTPUT);
servo.attach(SERVO_CONTROL);
//==================================
// Basic initial display
lcd.begin();
lcd.fillScreen(RGB(255, 255, 255));
lcd.drawText(0, 5, "** CLIMATE **", RGB(0, 0, 0), RGB(255, 150, 80), 3);
lcd.drawText(0, 40,"** CONTROL **", RGB(0, 0, 0), RGB(255, 150, 80), 3);
lcd.drawText(0, 65,"====================", RGB(0, 0, 0), RGB(200, 200, 200), 2);
lcd.drawText(2, 85,"Temperature value: ", RGB(0, 0, 0), RGB(153, 204, 255), 2);
lcd.drawText(2, 105," (in Celsius) ", RGB(0, 0, 0), RGB(153, 204, 255), 2);
lcd.drawText(0, 180,"--------------------", RGB(0, 0, 0), RGB(255, 255, 102), 2);
}
//==========================================================
/**
*This is the Main Loop of the program which is ececuted periodically
*/
void loop()
{
//---------------------------------------------------------
//Read values from inputs POT
int setTempereatureValue = analogRead(SET_TEMPERATURE);
//---------------------------------------------------------
double set_temp_Celcius = Compute_set_temprature_in_Celcius(setTempereatureValue);
double set_temp_Farenheit = Compute_temprature_in_Farenheit(set_temp_Celcius);
// Display the temperature on LCD
Display_temperature(set_temp_Celcius,LINE_1);
//---------------------------------------------------------------
// Get the temerature reading from the temperature sensor
double curr_temp_Celcius = get_temprature_in_Celcius();
double curr_temp_Farenheit = Compute_temprature_in_Farenheit(curr_temp_Celcius);
// Display the temperature on LCD
Display_temperature(curr_temp_Celcius,LINE_2);
//---------------------------------------------------------------
// calculate offset between current and set temeperature.
double offset = (set_temp_Celcius - curr_temp_Celcius);
//Take action based on offset
if(offset> TemperatureOffset) // if offset is positive
{
// servo rotates clockwise and presses "HEAT" button so that temperatrure increases.
IncreaseTemperature();
Display_action(INCREASING_TEMPERATURE);
}
else if( offset< -TemperatureOffset) // if offset is negative
{
// servo rotates counter clockwise and presses "COLD" button so that temperatrure decreases.
DecreaseTemperature();
Display_action(DECREASING_TEMPERATURE);
}
else // if the offset is within the range
{
//Then position the Servo motor in neutral postion so that none of the buttons are pressed
decrease_temperature_counter=increase_temperature_counter=0;
Servo_in_neutral_position();
Display_action(NO_ACTION);
}
delay(loopDelay);
} // main loop ends
//==========================================================================
//Helper functions
/**
*This method computes the set temerature in degree celcius.It takes the Analog value from the POT as input
*/
double Compute_set_temprature_in_Celcius(int value)
{
double highResolution_SetTemperature= double(value*5 *6)/1024 +10 ;
return highResolution_SetTemperature;
}
//=============================================================================
/**
*This method can be used to convert the temperature ffrom degree celcius to degree farenheit.
*/
double Compute_temprature_in_Farenheit( double temp_celcius)
{
return (temp_celcius*9.0/5.0+32);
}
//=============================================================================
int curr_position=0;
/**
*This method takes action to increase the temperature by initiating the servo motor to rotate clock-wise
*/
void IncreaseTemperature()
{
if(increase_temperature_counter%button_press_repeatition_interval==0 || increase_temperature_counter>button_press_repeatition_interval)
{
increase_temperature_counter=0;
RotateServoClockwise();
}
if(increase_temperature_counter==button_press_duration)
{
Servo_in_neutral_position();
}
increase_temperature_counter++;
}
/**
*This method sends commands to the servo motor to rotate clock-wise
*/
void RotateServoClockwise()
{
while ( curr_position <= max_angle )
{
servo.write(curr_position);
curr_position ++; delay(10);
}
}
//==========================================================================
/**
*This method takes action to decrease the temperature by initiating the servo motor to rotate counter clock-wise
*/
void DecreaseTemperature()
{
if(decrease_temperature_counter%button_press_repeatition_interval==0 || decrease_temperature_counter>button_press_repeatition_interval)
{
decrease_temperature_counter=0;
RotateServoAntiClockwise();
}
if(decrease_temperature_counter==button_press_duration)
{
Servo_in_neutral_position();
}
decrease_temperature_counter++;
}
/**
*This method sends commands to the servo motor to rotate counter clock-wise
*/
void RotateServoAntiClockwise()
{
while ( curr_position >= min_angle )
{
servo.write(curr_position);
curr_position --; delay(10);
}
}
//=============================================================================
/**
*This method sends commands to the servo motor to return to neutral position
*/
void Servo_in_neutral_position()
{
/* if the difference between " Set temperature" and "Current temperature" is within the range
* then position the servo in neutral position ( ie 90 degrees ) so that neither "HEAT" or "COLD" button is pressed.
*/
if (curr_position <=min_angle)
{
while ( curr_position <= neutral_pos_angle )
{
servo.write(curr_position);
curr_position ++; delay(10);
}
}
else if (curr_position >=max_angle)
{
while ( curr_position >= neutral_pos_angle )
{
servo.write(curr_position);
curr_position --; delay(10);
}
}
}
//====================================================================================
/**
*This method is responsible for displaying the dynamically changing value of the temperature at the specified line on the LCD.
*/
void Display_temperature(double temperature ,int line_num)
{
switch(line_num)
{
char data[30];
case LINE_1:
sprintf(data, "SET : %02i.%02i ", ( int)temperature,(unsigned int)(abs(temperature)*100)%100);
lcd.drawText(2, 135, data, RGB(0, 0, 0), RGB(200, 200, 200), 2);
break;
case LINE_2 :
sprintf(data, "CURRENT : %02i.%02i ", ( int)temperature,(unsigned int)(abs(temperature)*100)%100);
lcd.drawText(2, 160, data, RGB(0, 0, 0), RGB(200, 200, 200), 2);
break;
}
}
/**
*This method is responsible for displaying the current action executed like Increasing or Decreasing temperature or no action.
*/
int current_state=0;
void Display_action( int action)
{
if(action == INCREASING_TEMPERATURE && current_state != INCREASING_TEMPERATURE)
{
current_state=INCREASING_TEMPERATURE;
lcd.drawText(20,200," ", RGB(255, 255, 2555), RGB(255, 255, 255), 2);
lcd.drawText(20,220," ", RGB(255, 255, 2555), RGB(255, 255, 255), 2);
lcd.drawText(2,200,"Increasing the ", RGB(0, 0, 0), RGB(255, 180, 180), 2);
lcd.drawText(2,220,"current Temperature", RGB(0, 0, 0), RGB(255, 180, 180), 2);
}
else if(action == DECREASING_TEMPERATURE && current_state != DECREASING_TEMPERATURE)
{
current_state=DECREASING_TEMPERATURE;
lcd.drawText(20,200," ", RGB(255, 255, 2555), RGB(255, 255, 255), 2);
lcd.drawText(20,220," ", RGB(255, 255, 2555), RGB(255, 255, 255), 2);
lcd.drawText(2,200,"Decreasing the ", RGB(0, 0, 0), RGB(255, 180, 180), 2);
lcd.drawText(2,220,"current Temperature", RGB(0, 0, 0), RGB(255, 180, 180), 2);
}
else if( action == NO_ACTION && current_state != NO_ACTION )
{
current_state=NO_ACTION;
lcd.drawText(0,200," ", RGB(255, 255, 2555), RGB(255, 255, 255), 2);
lcd.drawText(0,220," ", RGB(255, 255, 255), RGB(255, 255, 255), 2);
lcd.drawText(2,200,"TEMPERATURE is OK ", RGB(0, 0, 0), RGB(51, 255, 51), 2);
lcd.drawText(2,220,"( within range ) ", RGB(0, 0, 0), RGB(51, 255, 51), 2);
action = 7;
}
}
//========================================================================
/**
*This method reads the temerature sensor DFR0024 DFRobot and converts the reading into equivalent temerature in degree celcuis.
*/
double get_temprature_in_Celcius()
{
byte data[12];
byte addr[8];
if ( !ds.search(addr))
{
ds.reset_search();
return -1000;
}
if ( OneWire::crc8( addr, 7) != addr[7])
{
return -1000;
}
if ( addr[0] != 0x10 && addr[0] != 0x28)
{
return -1000;
}
ds.reset();
ds.select(addr);
ds.write(0x44,1);
byte present = ds.reset();
ds.select(addr);
ds.write(0xBE); // Read Scratchpad
for (int i = 0; i < 9; i++)
{
data[i] = ds.read();
}
ds.reset_search();
byte MSB = data[1];
byte LSB = data[0];
float tempRead = ((MSB << 8) | LSB);
float TemperatureSum = tempRead / 16;
return TemperatureSum;
}
/*************************************************** END OF PROGRAM **********************************************/