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
| // LCD module connections
sbit LCD_RS at RD1_bit;
sbit LCD_RW at RD2_bit;
sbit LCD_EN at RD3_bit;
sbit LCD_D4 at RD4_bit;
sbit LCD_D5 at RD5_bit;
sbit LCD_D6 at RD6_bit;
sbit LCD_D7 at RD7_bit;
sbit LCD_RS_Direction at TRISD1_bit;
sbit LCD_RW_Direction at TRISD2_bit;
sbit LCD_EN_Direction at TRISD3_bit;
sbit LCD_D4_Direction at TRISD4_bit;
sbit LCD_D5_Direction at TRISD5_bit;
sbit LCD_D6_Direction at TRISD6_bit;
sbit LCD_D7_Direction at TRISD7_bit;
//Output Pins
sbit led_pin at RA0_bit;
sbit led_heater at RA1_bit;
sbit heater_relay at RA2_bit;
//Button Input Pins
sbit button_up at RB0_bit;
sbit button_down at RB1_bit;
sbit button_ok at RB2_bit;
sbit button_swop at RB3_bit;
//SPI pins
sbit spi_sck at RC0_bit;
sbit spi_cs at RC1_bit;
sbit spi_si at RC2_bit;
//Variables
unsigned int target_temp, button_press_count, return_state, state, case1, a, b;
unsigned int current_temp, state_, spi_out;
long overshoot, tmp_temp, last_temp;
unsigned short i, j, temp_direction;
unsigned char buffer, cur[7], tar[7], arrayFlow[7], temparray[7];
void get_current_temp(){
//;read the value from MAX6675
//;in some libraries, they suggest performing a "dummy read"
//;to force the device to re-sample the temperature
spi_cs = 0;
Delay_ms(2);
spi_cs = 1;
Delay_ms(220); //;the device should now have a new temperature in its buffer
spi_cs = 0; //;enable CS so we can read data back from the device
Delay_ms(50); //;give the device time to settle
// current_temp = spi1_read(buffer) <<8; // upper 8 bit from MAX6675
// current_temp|= Spi1_Read(buffer); // lower 8 bit
// if (current_temp == 0x04);{current_temp = 999;} //;bit 2 is normally low, and goes high when the thermistor is not connected
/* current_temp = current_temp >> 3; //;bit-shift three places to the right
// current_temp = current_temp * 0.25; //?the temperature reported has a resolution of 0.25 deg C so convert to actual degrees
if (current_temp == 0); { //;something has gone wrong here
current_temp = 999;
}
*/
}
void show_overshoot(){
Lcd_cmd(_LCD_CLEAR); //Clear display
Lcd_out (1,1,"Overshoot:");
IntToStr(overshoot, arrayFlow);
Lcd_out_cp(arrayFlow);
}
void show_target_temp(){
Lcd_cmd(_LCD_CLEAR); //Clear display
Lcd_out (1,1,"Target:");
IntToStr(target_temp, arrayFlow);
Lcd_out_cp(arrayFlow);
}
void IntMain() {
TRISA = 0;
ADCON1 = 6;
TRISB = 0x0f; //Portb set button input pins
TRISC = 0x04; //PortC set SPI pins I/O
PORTA = 0;
OPTION_REG.B7 = 0; //enable pullups on portb (RBPU)
SSPCON.B5 =1; //Turn on SPI
//SPIPrepare OSC / 16 = 1.25mhz clk Sample data at end Clk idle Low SPI receive on clk edge High to Low
SPI1_Init_Advanced(_SPI_MASTER_OSC_DIV16, _SPI_DATA_SAMPLE_END, _SPI_CLK_IDLE_LOW, _SPI_HIGH_2_LOW);
spi_cs = 1; //Set cs pin high SPI device wait(sample)
spi_sck = 0; //Set sck pin low SPI CLK idle
}
void main() {
IntMain();
Lcd_init(); //Initialise LCD
Lcd_Cmd(_LCD_CLEAR); // Clear display
Lcd_Cmd(_LCD_CURSOR_OFF); //no cursor on the lcd display
led_heater = 0; //make sure we boot up with the heater off
heater_relay = 1; //heater indicator is off
last_temp =0;
state = 0;
overshoot = 0;
temp_direction = 0;
current_temp = 10;
target_temp = 20;
Lcd_Cmd(_LCD_CLEAR); //Clear display
Lcd_Out(1,1,"Temperature");
Lcd_Out(2,1,"Controller");
Delay_ms(1000);
target_temp = eeprom_read (2); //Read target temp value from eeprom
if (target_temp == 0x0ff) {target_temp = 50;}
overshoot = eeprom_read (4); //Read overshoot value from eeprom
if (overshoot == 0x0ff) {overshoot = 10;}
while (1){
switch (state) {
case 0: //show the target and current temperature(s)
get_current_temp();
Lcd_cmd(_LCD_CLEAR); //Clear display
Lcd_out (1,1,"Target:");
// target_temp = 1234;
IntToStr(target_temp, arrayFlow);
Lcd_out_cp(arrayFlow);
Lcd_out (2,1,"Actual:");
current_temp = 40;
IntToStr(current_temp, arrayFlow);
Lcd_out_cp(arrayFlow);
Delay_ms(1000);
state = 1;
break;
case 1: //;monitor the current temp and the target temp
get_current_temp();
led_heater = 1;
tmp_temp = target_temp - overshoot;
if (current_temp == 999) {
heater_relay = 0; //;something has gone wrong
led_heater = 0;
Lcd_out (2,1,"**** ERROR! ****");
}
if (last_temp <= current_temp) {temp_direction = 1;} //temperature is rising
else temp_direction = 0; //temperature is falling
if (current_temp > target_temp) {
heater_relay = 0; //we're over the target temperature so shut the heaters off
led_heater = 0;
}
if (current_temp > tmp_temp) {
led_heater = 0; //;threshold exceeded, turn off the heater(s)
heater_relay = 0;
} //temperature is rising
else {
led_heater = 1;
heater_relay = 1;
} //;still not quite there, keep the heaters on
if (current_temp < tmp_temp) {
heater_relay = 1; //;weve cooled down too much, turn the heaters on again
led_heater = 1;
}
else {
heater_relay = 0; //;were cooling down, but are still pretty close to the target
led_heater = 0; //;temperature, so allow a little more cooling
last_temp = current_temp;
}
//;now while the temperature is being monitored, check for button presses
//;(on a button press, turn off the heater(s) just for good measure, and
//;go to a new state just for handling changing the settings
if ((button_up == 0)||(button_down == 0)||(button_ok == 0)) {
heater_relay = 0;
led_heater = 0;
Delay_ms(50);
while ((button_up == 0)||(button_down == 0)||(button_ok == 0)) {
Delay_ms(50); //;wait f the button to be released
}
state = 2;
}
//Delay_ms(1000);
break;
case 2: //;press buttons to change menu option
Lcd_cmd(_LCD_CLEAR); //Clear display
Lcd_out (1,1,"> Change Target");
Lcd_out (2,3,"Edit Overshoot");
state = 3;
break;
case 3:
if ((button_up == 0)||(button_down == 0)) {
Delay_ms(50);
while ((button_up == 0)||(button_down == 0)) {
Delay_ms (50); //;wait f the button to be released
}
state = 4;
}
if (button_ok == 0) {
Delay_ms(50);
while (button_ok == 0) {
Delay_ms(50); //;wait f the button to be released
}
a = 0;
state = 6;
}
break;
case 4: //;press buttons to change menu option
Lcd_cmd(_LCD_CLEAR); //Clear display
Lcd_out (1,3,"Change Target");
Lcd_out (2,1,"> Edit Overshoot");
state = 5;
break;
case 5:
if ((button_up == 0)||(button_down == 0)) {
Delay_ms(50);
while (button_up == 0) (button_down == 0);{ Delay_ms(50); }//;wait for the button to be released
state = 2;
}
if (button_ok == 0) {
Delay_ms(50); //;debounce the button press
while (button_ok == 0) {Delay_ms(50);}
a = 1;
state = 6;
}
break;
case 6: //;change the target temperature value
if (a == 0) {
show_target_temp();
return_state = 6;
state = 7;
}
if (a == 1) {
show_overshoot();
return_state = 7;
state = 7;
}
break;
case 7: //;button presses to alter target temperature/overshoot value
if (button_up == 0) {
Delay_ms(50);
button_press_count = 0;
while (button_up == 0) {
//;wait for the button to be released
button_press_count = button_press_count + 1;
Delay_ms(100);
if (button_press_count >= 5) {
if (a == 0) {
if (target_temp < 500) { target_temp = target_temp + 10; }
else target_temp = 500;
show_target_temp();
}
else {
if (overshoot < 500) { overshoot = overshoot + 10; }
else overshoot = 500;
show_overshoot();
}
Delay_ms(200);
//;stop the counter from rolling over
button_press_count = 5;
}
if (button_press_count < 5) {
if (a==0) {
if (target_temp < 500) {Target_temp = target_temp + 1;}
else target_temp = 500;
show_target_temp();
}
if (a==1) {
if (overshoot < 500) {overshoot = overshoot + 1;}
else overshoot = 500;
show_overshoot();
}
}
state = return_state;
}
}
if (button_down == 0) {
Delay_ms(50);
button_press_count = 0;
while (button_down == 0) {
//;wait for the button to be released
button_press_count = button_press_count + 1;
Delay_ms(100);
if (button_press_count >= 5) {
if (a == 0) {
if (target_temp > 10) { target_temp = target_temp - 10; }
else target_temp = 0;
show_target_temp();
}
else {
if (overshoot > 10) { overshoot = overshoot - 10; }
else overshoot = 0;
show_overshoot();
}
Delay_ms(200);
//;stop the counter from rolling over
button_press_count = 5;
}
if (button_press_count < 5) {
if (a==0) {
if (target_temp > 1) {Target_temp = target_temp - 1;}
else target_temp = 0;
show_target_temp();
}
if (a==1) {
if (overshoot > 1) {overshoot = overshoot - 1;}
else overshoot = 0;
show_overshoot();
}
}
state = return_state;
}
}
/*
if (button_ok == 0) {
Delay_ms(50); //;simple debounce
while (button_ok == 0) {Delay_ms(50);} //;wait for button to be released
if (a == 0) {
b = target_temp; // Load target temp into write file
eeprom_write (2,b); //;write the new target temp to eeprom
}
if (a == 1) {
b = overshoot; // Load target temp into write file
eeprom_write (4,b); //;write the new overshoot value to eeprom
}
state = 0;
} */
break;
}
}
} |