-
Notifications
You must be signed in to change notification settings - Fork 3
/
CoffeeRoastingController.ino
793 lines (663 loc) · 26.9 KB
/
CoffeeRoastingController.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
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
/****************************************************************************
// https://gist.github.com/soemarko/9ac80d5df13155fb3302
// ORIGINAL RoastLoggerMax6675.ino
This sketch is for use with MAX 31855 thermocouple interface chips.
See the "Contributed Libraries" section of http://www.arduino.cc/en/Reference/Libraries
for details of how to install it.
Revision history: - of RoastLoggerMax6675
20120201: Version 1.2 - Made available for download from downloads page
20120303: Version 1.3 - Added #define CELSIUS as default, user to comment out for Fahrenheit output
20120324: Version 1.4 - Serial output limited to 1 decimal place
20200115: Version 1.5 - Updated to include 4 relay PWM outputs and MAX31855 for temperature inputs, removed LCD output and potentiometer control, only control via computer
****************************************************************************/
// ------------------------------------------------------------------------------------------
// Copyright (c) 2011-2012, Tom Coxon (GreenBean TMC)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, are
// permitted provided that the following conditions are met:
//
// Redistributions of source code must retain the above copyright notice, this list of
// conditions and the following disclaimer.
//
// Redistributions in binary form must reproduce the above copyright notice, this list
// of conditions and the following disclaimer in the documentation and/or other materials
// provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
// OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// ------------------------------------------------------------------------------------------
/****************************************************************************
*
* Arduino control of a Hottop roaster by T R Coxon
*
* Using an Arduino Duemilanove 328 on Hottop P and B Roasters
*
* Sends data and receives instructions as key=value pairs.
* Sends temperatures T1 and T2 at sendTimePeriod intervals as "T1=123.6"
* Accepts instructions for power level, set temperature etc.
* Example: Send to Arduino "power=80" or "setT=240.6"
****************************************************************************/
/****************************************************************************
*
* Connections to Arduino and Behmor for heater power control:
*
* Please note that the following describes the modifications to my Behmor
* 1600+. You should not attempt this unless you are suitably qualified /
* experienced. Modifying your roaster will probably void your warranty
* and may result in damage or injury. You do this at your own risk.
*
* http://blog.soemarko.com/post/109402505018/behmor-mod-phase-2-heat-control-with-arduino
*
****************************************************************************/
/****************************************************************************
*
* Modified by Soemarko Ridwan
* 25 Jan 2015
* for modded Behmor 1600+
* * Change log.
*
* 31 Jan 2015:
* - Remove PID dependencies
* - Add support for a potentiometer (5V, Pin A0)
* - Add I2C LCD
* - Add support for Artisan
*
****************************************************************************/
/****************************************************************************
*
* Modified by Chris St.Amand
* 15 Jan 2020
* for modded BM/HG
*
* 15 Jan 2020:
* - Normalized Variables
* - Added support for 4 PWM Relays (fan, heat, cooling fan, motor
* - Must download MAX31855 library - https://learn.adafruit.com/thermocouple/arduino-code
* - Control only from Artisan
*
****************************************************************************/
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <SPI.h>
#include "Adafruit_MAX31855.h"
#if defined(ARDUINO) && ARDUINO >= 100
#define printByte(args) write(args);
#else
#define printByte(args) print(args,BYTE);
#endif
#define CELSIUS //RoastLogger default is Celsius - To output data in Fahrenheit comment out this one line
#define DP 1 // No. decimal places for serial output
#define maxLength 30 // maximum length for strings used
const int arduino = 1; // controlled via digitalRead on ctrlPin
const int computer = 0;
/****************************************************************************
*
* Arduino pin assignments
*
* The following are the pin assignments used by my setup.
*
* You only need to change the following 5 constants to suit the pin
* assignments used by your setup.
*
****************************************************************************/
bool isArtisan = false;
// PWM Relay Setup
const int PWM1Pin = 10; // digital pin for pulse width modulation of heater
char PWM1Name[] = "power"; // label to take from Artisan
const int PWM2Pin = 9; // digital pin for pulse width modulation of fan
char PWM2Name[] = "fan"; // label to take from Artisan
const int PWM3Pin = 6; // digital pin for drum/motor/cooling fan/drop door/etc
char PWM3Name[] = "motor"; // label to take from Artisan
const int PWM4Pin = 5; // digital pin for drum/motor/cooling fan/drop door/etc
char PWM4Name[] = "cooling"; // label to take from Artisan
// thermocouple reading Max 6675 pins
const int SCKa = 13; // SCK on UNO (usually pin 13) to CLK pin on MAX31855
const int TC1CS = 7; // Thermocouple 1 CS pin on MAX31855
const int TC2CS = 8; // Thermocouple 2 CS pin on MAX31855
const int SO = 12; // SO on UNO (usually pin 12) to DO pin on MAX31855
const int ctrlPin = 2; // if using arduino to adjust -- was 12
// const int RelayCtrlPin1 = 3; // if using arduino to adjust -- was 11
// const int RelayCtrlPin2 = 4; // if using arduino to adjust -- was 11
// initialize the Thermocouple
Adafruit_MAX31855 thermocouple1(SCKa, TC1CS, SO);
Adafruit_MAX31855 thermocouple2(SCKa, TC2CS, SO);
// pots 1
const int Pot1Pin = A0;
const int Pot1Max = 1020;
int Pot1Val = 0;
float Pot1SmoothedVal = 0;
float Pot1LastReadVal = 0;
float Pot1Alpha = 0.5;
// pots 2
const int Pot2Pin = A1;
const int Pot2Max = 1020;
int Pot2Val = 0;
float Pot2SmoothedVal = 0;
float Pot2LastReadVal = 0;
float Pot2Alpha = 0.5;
// LM35
// const int lmPin = A2;
// float lmTemp = 0.0;
// LCD
byte pcChar[8] = {
0b11111,
0b00101,
0b00101,
0b00010,
0b00000,
0b01110,
0b10001,
0b10001
};
byte ardChar[8] = {
0b01110,
0b10001,
0b01010,
0b00100,
0b01010,
0b10001,
0b01110,
0b00000
};
LiquidCrystal_I2C lcd(0x27,16,2);
/****************************************************************************
* After setting the above pin assignments you can use the remainder of this
* sketch as is or change it, if you wish, to add additional functionality
*
****************************************************************************/
// time constants
const int PWM1timePeriod = 2000; // total time period of PWM milliseconds see note on setupPWM1 before changing, maybe 1250/1500
const int PWM2timePeriod = 2000; // total time period of PWM milliseconds see note on setupPWM2 before changing, maybe 1250/1500
const int PWM3timePeriod = 2000; // total time period of PWM milliseconds see note on setupPWM1 before changing, maybe 1250/1500
const int PWM4timePeriod = 2000; // total time period of PWM milliseconds see note on setupPWM2 before changing, maybe 1250/1500
const int SubLoopTimePeriod = 250; // 250 ms loop to read thermocouples
// thermocouple settings
float TC1Calibrate = 0.0; // Temperature compensation for T1
float TC2Calibrate = 0.0; // Temperature compensation for T2
// set global variables
//temporary values for temperature to be read
float TC1Temp = 0.0; // temporary temperature variable
float TC2Temp = 0.0; // temporary temperature variable
float t0 = 0 ; // ambient for TC4
float TC1AvgTemp = 0.0; // Last average temperature on thermocouple 1, Environment Temp - average of four readings
float TC2AvgTemp = 0.0; // Last average temperature on thermocouple 2, Bean Temp - average of four readings
float TC1Cumulative = 0.0; // cumulative total of temperatures read before averaged
float TC2Cumulative = 0.0; // cumulative total of temperatures read before averaged
int TC1BadReading = 0; // counter of no. of good readings for average calculation
int TC2BadReading = 0; // counter of no. of good readings for average calculation
int inByte = 0; // incoming serial byte
String inString = String(maxLength); // input String
// loop control variables
unsigned long lastTCTimerLoop; // for timing the thermocouple loop
int tcLoopCount = 0; // counter to run serial output once every 4 loops of 250 ms t/c loop
// PWM variables
int TC1timeOn; // millis PWM is on out of total of timePeriod (timeOn = timePeriod for 100% power)
int TC2timeOn; // millis PWM is on out of total of timePeriod (timeOn = timePeriod for 100% power)
int TC3timeOn; // millis PWM is on out of total of timePeriod (timeOn = timePeriod for 100% power)
int TC4timeOn; // millis PWM is on out of total of timePeriod (timeOn = timePeriod for 100% power)
unsigned long TC1lastTimePeriod; // millis since last turned on pwm
unsigned long TC2lastTimePeriod; // millis since last turned on pwm
unsigned long TC3lastTimePeriod; // millis since last turned on pwm
unsigned long TC4lastTimePeriod; // millis since last turned on pwm
int power1 = 0; //use as %, 100 is always on, 0 always off default 100
int power2 = 0; //use as %, 100 is always on, 0 always off default 100
int power3 = 0; //use as %, 100 is always on, 0 always off default 100
int power4 = 0; //use as %, 100 is always on, 0 always off default 100
// int currentMotor = 0;
int controlBy = arduino; // default is arduino control. PC sends "pccontrol" to gain control or
// swapped back to Arduino control if PC sends "arduinocontrol"
/****************************************************************************
* MAIN SETUP
****************************************************************************/
void setup()
{
// start serial port at 115200 baud:
Serial.begin(115200);
setupPWM1();
setupPWM2();
setupPWM3();
setupPWM4();
//set up pin modes for Max31855's
pinMode(TC1CS, OUTPUT);
pinMode(TC2CS, OUTPUT);
pinMode(SO, INPUT);
pinMode(SCKa, OUTPUT);
// deselect both Max31855's
digitalWrite(TC1CS, HIGH);
digitalWrite(TC2CS, HIGH);
//pinMode(5, OUTPUT); digitalWrite(5, LOW); // force LCD to be off -- WAS 13
//lcd.init();
//lcd.backlight();
//lcd.createChar(0, ardChar);
//lcd.createChar(1, pcChar);
//pinMode(ctrlPin, INPUT);
//pinMode(RelayCtrlPin1, INPUT);
// pinMode(RelayCtrlPin2, INPUT);
Serial.println("Reset"); // flag that Arduino has reset used for debugging
}
/****************************************************************************
* Main loop must not use delay! PWM heater control relies on loop running
* at least every 40 ms. If it takes longer then heater will be on slightly
* longer than planned. Not a big problem if 1% becomes 1.2%! But keep loop fast.
* Currently loop takes about 4-5 ms to run so no problem.
****************************************************************************/
void loop(){
controlBy = digitalRead(ctrlPin);
getSerialInput();// check if any serial data waiting
// loop to run once every 250 ms to read TC's, update Pots, etc.
if (millis() - lastTCTimerLoop >= SubLoopTimePeriod)
{
lastTCTimerLoop = millis();
doSubLoop();
}
doPWM1(); // Toggle Heat on/off based on power setting
doPWM2(); // Toggle Fan on/off based on power setting
doPWM3(); // Toggle Heat on/off based on power setting
doPWM4(); // Toggle Fan on/off based on power setting
}
/****************************************************************************
* Set up power pwm control for heater. Hottop uses a triac that switches
* only on zero crossing so normal pwm will not work.
* Minimum time slice is a half cycle or 10 millisecs in UK.
* Loop in this prog may need up to 10 ms to complete.
* I will use 20 millisecs as time slice with 100 power levels that
* gives 2000 milliseconds total time period.
* The Hottop heater is very slow responding so 2 sec period is not a problem.
****************************************************************************/
void setupPWM1() {
// set the digital pin as output:
pinMode(PWM1Pin, OUTPUT);
//setup PWM
TC1lastTimePeriod = millis();
digitalWrite(PWM1Pin, LOW); //set PWM 1 pin off to start
}
void setupPWM2() {
// set the digital pin as output:
pinMode(PWM2Pin, OUTPUT);
//setup PWM
TC2lastTimePeriod = millis();
digitalWrite(PWM2Pin, LOW); //set PWM 2 pin off to start
}
void setupPWM3() {
// set the digital pin as output:
pinMode(PWM3Pin, OUTPUT);
//setup PWM
TC3lastTimePeriod = millis();
digitalWrite(PWM3Pin, LOW); //set PWM 3 pin off to start
}
void setupPWM4() {
// set the digital pin as output:
pinMode(PWM4Pin, OUTPUT);
//setup PWM
TC4lastTimePeriod = millis();
digitalWrite(PWM4Pin, LOW); //set PWM 4 pin off to start
}
/****************************************************************************
* Toggles the heater on/off based on the current power level. Power level
* may be determined by arduino or computer.
****************************************************************************/
void doPWM1()
{
TC1timeOn = PWM1timePeriod * power1 / 100; //recalc the millisecs on to get this power level, user may have changed
if (millis() - TC1lastTimePeriod > PWM1timePeriod) TC1lastTimePeriod = millis();
if (millis() - TC1lastTimePeriod < TC1timeOn ){
// if (millis() - TC1lastTimePeriod < TC1timeOn && digitalRead(RelayCtrlPin1)){
digitalWrite(PWM1Pin, HIGH); // turn on
} else {
digitalWrite(PWM1Pin, LOW); // turn off
}
}
void doPWM2()
{
TC2timeOn = PWM2timePeriod * power2 / 100; //recalc the millisecs on to get this power level, user may have changed
if (millis() - TC2lastTimePeriod > PWM2timePeriod) TC2lastTimePeriod = millis();
if (millis() - TC2lastTimePeriod < TC2timeOn ){
// if (millis() - TC2lastTimePeriod < TC2timeOn && digitalRead(RelayCtrlPin2)){
digitalWrite(PWM2Pin, HIGH); // turn on
} else {
digitalWrite(PWM2Pin, LOW); // turn off
}
}
void doPWM3()
{
TC3timeOn = PWM3timePeriod * power3 / 100; //recalc the millisecs on to get this power level, user may have changed
if (millis() - TC3lastTimePeriod > PWM3timePeriod) TC3lastTimePeriod = millis();
if (millis() - TC3lastTimePeriod < TC3timeOn ){
digitalWrite(PWM3Pin, HIGH); // turn on
} else {
digitalWrite(PWM3Pin, LOW); // turn off
}
}
void doPWM4()
{
TC4timeOn = PWM4timePeriod * power4 / 100; //recalc the millisecs on to get this power level, user may have changed
if (millis() - TC4lastTimePeriod > PWM4timePeriod) TC4lastTimePeriod = millis();
if (millis() - TC4lastTimePeriod < TC4timeOn ){
digitalWrite(PWM4Pin, HIGH); // turn on
} else {
digitalWrite(PWM4Pin, LOW); // turn off
}
}
/****************************************************************************
* Called to set power level. Now always safe as hardware only turns heater on
* if BOTH the Arduino AND the Hottop control board call for heat.
****************************************************************************/
void setPowerLevel1(int p)
{
if (p > -1 && p < 101) power1 = p;
}
void setPowerLevel2(int p)
{
if (p > -1 && p < 101) power2 = p;
}
void setPowerLevel3(int p)
{
if (p > -1 && p < 101) power3 = p;
}
void setPowerLevel4(int p)
{
if (p > -1 && p < 101) power4 = p;
}
/****************************************************************************
* Called when an input string is received from computer
* designed for key=value pairs or simple text commands.
* Performs commands and splits key and value
* and if key is defined sets value otherwise ignores
****************************************************************************/
void doInputCommand()
{
float v = -1;
inString.toLowerCase();
int indx = inString.indexOf('=');
if (indx < 0) { //this is a message not a key value pair
if(inString.equals("chan;1200")) {
isArtisan = true;
Serial.println("# Active channels set to 2");
}
else if(inString.equals("read")) {
String x = String(TC2AvgTemp) + "," + String(TC1AvgTemp);
// String x = String(lmTemp) + "," + String(TC2AvgTemp) + "," + String(TC1AvgTemp);
Serial.println(x);
}
Serial.flush();
}
else { //this is a key value pair for decoding
String key = inString.substring(0, indx);
String value = inString.substring(indx+1, inString.length());
//parse string value and return float v
char buf[value.length()+1];
value.toCharArray(buf,value.length()+1);
v = atof (buf);
//only set value if we have a valid positive number - atof will return 0.0 if invalid
if (v >= 0)
{
if (key.equals(PWM1Name) && controlBy == computer && v < 101){
setPowerLevel1((long) v);//convert v to integer for power
}
else if (key.equals(PWM2Name) && controlBy == computer && v < 101) {
setPowerLevel2((long) v);//convert v to integer for power
}
else if (key.equals(PWM3Name) && controlBy == computer && v < 101) {
setPowerLevel3((long) v);//convert v to integer for power
}
else if (key.equals(PWM4Name) && controlBy == computer && v < 101) {
setPowerLevel4((long) v);//convert v to integer for power
}
}
}
}
/****************************************************************************
* check if serial input is waiting if so add it to inString.
* Instructions are terminated with \n \r or 'z'
* If this is the end of input line then call doInputCommand to act on it.
****************************************************************************/
void getSerialInput()
{
//check if data is coming in if so deal with it
if (Serial.available() > 0) {
// read the incoming data as a char:
char inChar = Serial.read();
// if it's a newline or return or z, print the string:
if ((inChar == '\n') || (inChar == '\r') || (inChar == 'z')) {
//do whatever is commanded by the input string
if (inString.length() > 0) doInputCommand();
inString = ""; //reset for next line of input
}
else {
// if we are not at the end of the string, append the incoming character
if (inString.length() < maxLength) {
inString += inChar;
}
else {
// empty the string and set it equal to the incoming char:
// inString = inChar;
inString = "";
inString += inChar;
}
}
}
}
/****************************************************************************
* Send data to computer once every second. Data such as temperatures, etc.
* This allows current settings to be checked by the controlling program
* and changed if, and only if, necessary.
* This is quicker that resending data from the controller each second
* and the Arduino having to read and interpret the results.
****************************************************************************/
void doSerialOutput() {
if (isArtisan) {
return;
}
//send data to logger
// float tt0;
float t1;
float t2;
// tt0 = t0;
t1 = TC1AvgTemp;
t2 = TC2AvgTemp;
// Serial.print("t0="); // Ambient always 0
// Serial.println(tt0,DP);
Serial.print("Temp 1: "); // Environment Temp
Serial.println(t1,DP);
//Comment out the next two lines if using only one thermocouple
Serial.print("Temp 2: ");
Serial.println(t2,DP);
/*
Serial.print(PWM1Name);
Serial.print(": ");
Serial.print(power1);
Serial.println("%");
Serial.print(PWM2Name);
Serial.print(": ");
Serial.print(power2);
Serial.println("%");
Serial.print(PWM3Name);
Serial.print(": ");
Serial.print(power3);
Serial.println("%");
Serial.print(PWM4Name);
Serial.print(": ");
Serial.print(power4);
Serial.println("%");
*/
// only need to send these if Arduino controlling by potentiometer
if (controlBy == arduino)
{
Serial.print("pots1=");
Serial.println(Pot1Val);
Serial.print("pots2=");
Serial.println(Pot2Val);
// Serial.print("lm35=");
// Serial.println(lmTemp);
}
}
/****************************************************************************
* Read temperatures from Max31855 chips Sets t1 and t2, -1 if an error
* occurred. Max31855 needs 240 ms between readings or will return last
* value again. I am reading it once per second.
****************************************************************************/
void getTemperatures()
{
TC1Temp = readThermocouple(TC1CS, TC1Calibrate);
TC2Temp = readThermocouple(TC2CS, TC2Calibrate);
if (TC1Temp > 0.0)
{
TC1Cumulative = TC1Cumulative + TC1Temp;
TC1BadReading ++;
}
if (TC2Temp > 0.0)
{
TC2Cumulative = TC2Cumulative + TC2Temp;
TC2BadReading ++;
}
}
/****************************************************************************
* Purpose to adjust power based on the value from the potentiometer
****************************************************************************/
void updatePot1(){
Pot1Val = analogRead(Pot1Pin);
Pot1LastReadVal = Pot1Val;
Pot1SmoothedVal = (Pot1Alpha) * Pot1SmoothedVal + (1-Pot1Alpha) * Pot1LastReadVal;
Pot1Val = Pot1SmoothedVal;
int pow = map(Pot1Val, 15, Pot1Max, 25, 100);
setPowerLevel1(pow);
}
void updatePot2(){
Pot2Val = analogRead(Pot2Pin);
Pot2LastReadVal = Pot2Val;
Pot2SmoothedVal = (Pot2Alpha) * Pot2SmoothedVal + (1-Pot2Alpha) * Pot2LastReadVal;
Pot2Val = Pot2SmoothedVal;
int pow = map(Pot2Val, 15, Pot2Max, 25, 100);
setPowerLevel2(pow);
}
/****************************************************************************
* Purpose to gauge the internal temperature of the box
****************************************************************************/
//void updateLM35() {
// analogRead(lmPin); delay(40);
// int reading = analogRead(lmPin);
// lmTemp = reading * 5.0*100.0 / 1023.0;
//}
/****************************************************************************
* Update the values on the LCD
****************************************************************************/
void outputLCD() {
int col2 = 2;
int col3 = 10;
if (controlBy == arduino) {
//lcd.setCursor(0,0); lcd.write(byte(0));
lcd.setCursor(0,0); lcd.printByte(0);
lcd.setCursor(0,1); lcd.print(" ");
}
else {
lcd.setCursor(0,0); lcd.print(" ");
//lcd.setCursor(0,1); lcd.write(byte(1));
lcd.setCursor(0,1); lcd.printByte(1);
}
lcd.setCursor(col2,0);
lcd.print(TC1AvgTemp,DP);
lcd.write(B11011111);
lcd.setCursor(col3,0);
lcd.print(TC1AvgTemp,DP);
lcd.write(B11011111);
lcd.setCursor(col2,1); // row 2
char powChar[3];
// sprintf(powChar, "%3d", power1 * digitalRead(RelayCtrlPin1));
lcd.print(powChar);
lcd.print("%");
// lcd.setCursor(col3,1);
// lcd.print(lmTemp, DP);
// lcd.write(B11011111);
}
/****************************************************************************
* Called by main loop once every XXX ms
* Used to read each thermocouple once every XXX ms
*
* Once per second averages temperature results, updates potentiometer and outputs data
* to serial port.
****************************************************************************/
void doSubLoop()
{
getTemperatures();
if (tcLoopCount > 3) // once every four loops (1 second) calculate average temp, update Pot and do serial output
{
tcLoopCount = 0;
if (TC1BadReading > 0) TC1AvgTemp = TC1Cumulative / TC1BadReading; else TC1AvgTemp = -1.0;
if (TC2BadReading > 0) TC2AvgTemp = TC2Cumulative / TC2BadReading; else TC2AvgTemp = -1.0;
TC1BadReading = 0;
TC2BadReading = 0;
TC1Cumulative = 0.0;
TC2Cumulative = 0.0;
// updateLM35();
doSerialOutput(); // once per second
}
tcLoopCount++;
// only use Pot if in Arduino control. If Computer control power is set by computer
//if (controlBy == arduino){
// updatePot1();
// updatePot2();
// }
// outputLCD();
}
/*****************************************************************
* Read the Max31855 device 1 or 2. Returns temp as float or -1.0
* if an error reading device.
* Note at least 240 ms should elapse between readings of a device
* to allow it to settle to new reading. If not the last reading
* will be returned again.
*****************************************************************/
float readThermocouple(int CS, float calibrate) //device selected by passing in the relavant CS (chip select)
{
int value = 0;
int error_tc = 0;
float temp = 0.0;
digitalWrite(CS,LOW); // Enable device
// wait for it to settle
delayMicroseconds(1);
/* Cycle the clock for dummy bit 15 */
digitalWrite(SCKa,HIGH);
digitalWrite(SCKa,LOW);
//wait for it to settle
delayMicroseconds(1);
/* Read each MAX31855 for the Temp
storing the value, depending on F or C
*/
digitalWrite(SCKa,HIGH); // Set Clock to HIGH
if(CS == TC1CS) {
#ifdef CELSIUS // If Celcius is defined then get Celcius for Thermoocouple 1
value = thermocouple1.readCelsius();
#else
value = thermocouple1.readFarenheit();
#endif
}
if(CS == TC2CS) {
#ifdef CELSIUS // If Celcius is defined then get Celcius for Thermoocouple 2
value = thermocouple2.readCelsius();
#else
value = thermocouple2.readFarenheit();
#endif
}
digitalWrite(SCKa,LOW); // Set Clock to LOW
// Read the TC input to check for error
//digitalWrite(SCKa,HIGH); // Set Clock to HIGH
// error_tc = digitalRead(SO); // Read data
// digitalWrite(SCKa,LOW); // Set Clock to LOW
// digitalWrite(CS,HIGH); // Disable device 1
temp = value + calibrate; // Add the calibration value
// temp = value;
// return -1 if an error occurred, otherwise return temp
// if(error_tc == 0) {
return temp;
// }
// else {
// return -1.0;
// }
}