-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathReflowWizard.ino
More file actions
245 lines (209 loc) · 8.37 KB
/
Copy pathReflowWizard.ino
File metadata and controls
245 lines (209 loc) · 8.37 KB
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
/*******************************************************************************
* ControLeo Reflow Oven Controller
* Author: Peter Easton
* Website: whizoo.com
* Software written to work best on ControLeo2 (www.whizoo.com)
*
* This is an example of a reflow oven controller. The reflow curve below is for a
* lead-free profile. The Reflow Wizard is capable of self-calibrating a reflow oven
* to the J-STD-20 reflow specification.
*
* Temperature (Degree Celcius) Magic Happens Here!
* 245-| x x
* | x x
* | x x
* | x x
* 200-| x x
* | x | | x
* | x | | x
* | x | |
* 150-| x | |
* | x | | |
* | x | | |
* | x | | |
* | x | | |
* | x | | |
* | x | | |
* 30 -| x | | |
* |< 60 - 90 s >|< 60 - 120 s >|< 60 - 150 s >|
* | Preheat Stage | Soaking Stage | Reflow Stage | Cool
* 0 |_ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
* Time (Seconds)
*
* This firmware builds on the work of other talented individuals:
* ==========================================
* Rocketscream (www.rocketscream.com)
* Produced the Arduino reflow oven shield ands code that inspired this project.
*
* ==========================================
* Limor Fried of Adafruit (www.adafruit.com)
* Author of Arduino MAX6675 library. Adafruit has been the source of tonnes of
* tutorials, examples, and libraries for everyone to learn.
*
* Disclaimer
* ==========
* Dealing with high voltage is a very dangerous act! Please make sure you know
* what you are dealing with and have proper knowledge before hand. Your use of
* any information or materials on this reflow oven controller is entirely at
* your own risk, for which we shall not be liable.
*
* Released under WTFPL license.
*
* Revision Description
* ======== ===========
* 1.0 Initial public release. (21 October 2014)
* 1.1 Bug fixes (30 December 2014)
* - Oven temperature might not reach configured maximum temperature
* - Adjusted values so learning happens faster
* - Other minor improvements
*******************************************************************************/
// ***** INCLUDES *****
#include <ControLeo2.h>
#include "ReflowWizard.h"
// **** Door Servo ****
#include <VarSpeedServo.h>
// ***** TYPE DEFINITIONS *****
ControLeo2_LiquidCrystal lcd;
ControLeo2_MAX31855 thermocouple;
int mode = 0;
// **** Door Servo ****
VarSpeedServo myservo; // create servo object to control a servo
#define SERVO_PIN 3
int servoclosePos= 170; //Door Closed
int servoopenPos= 30; //Door Open
int servospeed= 50; //How fast does the servo move
int servocurrPos;
void setup() {
// *********** Start of ControLeo2 initialization ***********
// Set up the buzzer and buttons
pinMode(CONTROLEO_BUZZER_PIN, OUTPUT);
pinMode(CONTROLEO_BUTTON_TOP_PIN, INPUT_PULLUP);
pinMode(CONTROLEO_BUTTON_BOTTOM_PIN, INPUT_PULLUP);
// Set the relays as outputs and turn them off
// The relay outputs are on D4 to D7 (4 outputs)
for (int i=4; i<8; i++) {
pinMode(i, OUTPUT);
digitalWrite(i, LOW);
}
// Set up the Door Servo Pins
myservo.attach(SERVO_PIN); // attaches the servo pin to the servo object
myservo.write(servoclosePos,255,true); // set the initial position of the servo (Door Closed), as fast as possible, wait until done
servocurrPos = myservo.read(); // capture the current servo position
// Set up the LCD's number of rows and columns
lcd.begin(16, 2);
// Create the degree symbol for the LCD - you can display this with lcd.print("\1") or lcd.write(1)
unsigned char degree[8] = {12,18,18,12,0,0,0,0};
lcd.createChar(1, degree);
// *********** End of ControLeo2 initialization ***********
// Log data to the computer using USB
Serial.begin(57600);
// Write the initial message on the LCD screen
lcdPrintLine(0, " ControLeo2");
lcdPrintLine(1, "Reflow Oven v1.1");
delay(100);
playTones(TUNE_STARTUP);
delay(3000);
lcd.clear();
// Initialize the EEPROM, after flashing bootloader
InitializeSettingsIfNeccessary();
// Go straight to reflow menu if learning is complete
if (getSetting(SETTING_LEARNING_MODE) == false)
mode = 2;
Serial.println(F("ControLeo2 Reflow Oven controller v1.1"));
}
// The main menu has 3 options
boolean (*action[NO_OF_MODES])() = {Testing, Config, Reflow};
const char* modes[NO_OF_MODES] = {"Test Outputs?", "Setup?", "Start Reflow?"};
// This loop is executed 20 times per second
void loop()
{
static boolean drawMenu = true;
static boolean showMainMenu = true;
static int counter = 0;
if (showMainMenu) {
if (drawMenu) {
drawMenu = false;
lcdPrintLine(0, modes[mode]);
lcdPrintLine(1, " Yes ->");
}
// Update the temperature roughtly once per second
if (counter++ % 20 == 0)
displayTemperature(thermocouple.readThermocouple(CELSIUS));
// Get the button press to select the mode or move to the next mode
switch (getButton()) {
case CONTROLEO_BUTTON_TOP:
// Move to the next mode
mode = (mode + 1) % NO_OF_MODES;
drawMenu = true;
break;
case CONTROLEO_BUTTON_BOTTOM:
// Move to the selected mode
showMainMenu = false;
drawMenu = true;
break;
}
}
else {
// Go to the mode's menu system
if ((*action[mode])() == NEXT_MODE)
showMainMenu = true;
}
// Execute this loop 20 times per second
delay(50);
}
// Determine if a button was pressed (with debounce)
// A button can only be pressed once every 200ms. If a button is
// pressed and held, a button press will be generated every 200ms.
// Returns:
// CONTROLEO_BUTTON_NONE if no button are pressed
// CONTROLEO_BUTTON_TOP if the top button was pressed
// CONTROLEO_BUTTON_BOTTOM if the bottom button was pressed
// Note: If both buttons are pressed simultaneously, CONTROLEO_BUTTON_TOP will be returned
#define DEBOUNCE_INTERVAL 200
int getButton()
{
static long lastChangeMillis = 0;
long nowMillis = millis();
int buttonValue;
// If insufficient time has passed, just return none pressed
if (lastChangeMillis + DEBOUNCE_INTERVAL > nowMillis)
return CONTROLEO_BUTTON_NONE;
// Read the current button status
buttonValue = CONTROLEO_BUTTON_NONE;
if (digitalRead(CONTROLEO_BUTTON_TOP_PIN) == LOW) {
buttonValue = CONTROLEO_BUTTON_TOP;
playTones(TUNE_TOP_BUTTON_PRESS);
}
else if (digitalRead(CONTROLEO_BUTTON_BOTTOM_PIN) == LOW) {
buttonValue = CONTROLEO_BUTTON_BOTTOM;
playTones(TUNE_BOTTOM_BUTTON_PRESS);
}
// Note the time the button was pressed
if (buttonValue != CONTROLEO_BUTTON_NONE)
lastChangeMillis = nowMillis;
return buttonValue;
}
// Display a line on the LCD screen
// The provided string is padded to take up the whole line
// There is less flicker when overwriting characters on the screen, compared
// to clearing the screen and writing new information
void lcdPrintLine(int line, const char* str) {
char buffer[17] = " ";
// Sanity check on the parameters
if (line < 0 || line > 1 || !str || strlen(str) > 16)
return;
lcd.setCursor(0, line);
strncpy(buffer, str, strlen(str));
lcd.print(buffer);
}
// Displays the temperature in the bottom left corner of the LCD display
void displayTemperature(double temperature) {
lcd.setCursor(0, 1);
if (THERMOCOUPLE_FAULT(temperature)) {
lcd.print(" ");
return;
}
lcd.print(temperature);
// Print degree Celsius symbol
lcd.print("\1C ");
}