00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include "pic24_all.h"
00030 #include <stdio.h>
00031 #include "reflow_oven.h"
00032
00037 #define MIN_WETTING_TIME 60 //seconds
00038
00039
00040 uint16 u16_peakTime;
00041 int16 i16_maxTemp;
00042 uint16 u16_startWetting;
00043 uint16 u16_endWetting;
00044 uint8 coolingFlag;
00045 uint16 u16_startReflow;
00046 uint16 u16_endReflow;
00047
00048 void resetStats(void) {
00049 i16_maxTemp = 0;
00050 coolingFlag = 0;
00051 u16_startWetting = 0;
00052 u16_endWetting = 0;
00053 }
00054
00055 void printStats (void) {
00056 uint16 u16_wettingTime;
00057 uint16 u16_reflowTime;
00058 if (u16_endWetting == 0) u16_wettingTime = u16_tenthSeconds - u16_startWetting;
00059 else u16_wettingTime = u16_endWetting - u16_startWetting;
00060 if (u16_endReflow == 0) u16_reflowTime = u16_tenthSeconds - u16_startReflow;
00061 else u16_reflowTime = u16_endReflow - u16_startReflow;
00062
00063 printf ("\nMax temp: %u, Temp Overshoot: %d, Wetting time: %d (s), Reflow Time: %d (s), Elapsed time: %u (s)\n",
00064 i16_maxTemp, i16_maxTemp - profiles[u8_currentProfile].i16_reflowTemp,
00065 u16_wettingTime/10, u16_reflowTime/10, u16_tenthSeconds/10 );
00066 }
00067
00068 int16 updateStats(void) {
00069 int16 i16_tempC;
00070 i16_tempC = getCelsiusI16Temp();
00071 if (i16_tempC > i16_maxTemp) i16_maxTemp = i16_tempC;
00072 if (i16_tempC > profiles[u8_currentProfile].i16_wetTemp &&
00073 u16_startWetting == 0) u16_startWetting = u16_tenthSeconds;
00074 if (coolingFlag && (i16_tempC < profiles[u8_currentProfile].i16_wetTemp)
00075 && u16_endWetting == 0)
00076 u16_endWetting = u16_tenthSeconds;
00077 if (i16_tempC > profiles[u8_currentProfile].i16_reflowTemp &&
00078 u16_startReflow == 0) u16_startReflow = u16_tenthSeconds;
00079 if (coolingFlag && (i16_tempC < profiles[u8_currentProfile].i16_reflowTemp)
00080 && u16_endReflow == 0)
00081 u16_endReflow = u16_tenthSeconds;
00082 return(i16_tempC);
00083 }
00084
00085 uint16 tempToPower(int16 i16_t) {
00086 uint16 u16_i;
00087
00088 for (u16_i=0; u16_i <= 100; u16_i++) {
00089 if (fdata.caldata.temp[u16_i] >= i16_t) return(u16_i);
00090 }
00091 reportError("Reflow application error: Unable to find power setting for target temp");
00092 return(0);
00093 }
00094
00095 void doRampUp(int16 i16_targetTemp, uint16 u16_targetTime) {
00096 int16 i16_tempC, i16_lastTemp;
00097 uint8 u8_endPower;
00098 uint16 u16_endTime;
00099
00100 u16_endTime = u16_tenthSeconds + u16_targetTime*10;
00101 i16_tempC = updateStats();
00102 u8_endPower = tempToPower(i16_targetTemp);
00103 setPower(100);
00104 do {
00105 i16_tempC = updateStats();
00106 printf("Current temp/time: %u %u Power: %u\n",i16_tempC,u16_tenthSeconds, getPower());
00107 DELAY_MS(1000);
00108 if (u16_tenthSeconds > u16_endTime) return;
00109 } while ((i16_targetTemp - i16_tempC) > 10 );
00110 setPower(30);
00111 i16_lastTemp = i16_tempC;
00112 do {
00113 DELAY_MS(1000);
00114 i16_tempC = updateStats();
00115 printf("Current temp/time: %u %u Power: %u\n",i16_tempC,u16_tenthSeconds, getPower());
00116 if ((i16_tempC < i16_lastTemp) && (i16_tempC < i16_targetTemp ) ) {
00117
00118 setPower(u8_endPower);
00119 } else setPower(30);
00120 i16_lastTemp = i16_tempC;
00121 } while (u16_tenthSeconds < u16_endTime);
00122 }
00123
00124
00125
00126 #if 0
00127 void doRampDown (int16 i16_targetTemp, uint16 u16_targetTime) {
00128 int16 i16_tempC;
00129
00130 setPower(0);
00131 while (u16_targetTime) {
00132 i16_tempC = updateStats();
00133 printf("Current temp/time: %u %u Power: %u\n",i16_tempC,u16_tenthSeconds, getPower());
00134 DELAY_MS(1000);
00135 u16_targetTime--;
00136 }
00137 }
00138 #endif
00139 void doRampDown(void) {
00140 int16 i16_tempC;
00141 uint16 u16_wetTime;
00142 uint8 u8_openDoorFlag;
00143
00144 setPower(0);
00145 u8_openDoorFlag = 0;
00146 do {
00147 u16_wetTime = u16_tenthSeconds - u16_startWetting;
00148 if ((u16_wetTime > MIN_WETTING_TIME) && !u8_openDoorFlag) {
00149 printf("\n\nWetting time is met, open door to aid cooling\n");
00150 u8_openDoorFlag = 1;
00151 }
00152 i16_tempC = updateStats();
00153 printf("Current temp/time: %u %u Power: %u\n",i16_tempC,u16_tenthSeconds, getPower());
00154 DELAY_MS(1000);
00155 } while (i16_tempC > 100);
00156 }
00157
00158
00159 void doHold (int16 i16_targetTemp, uint16 u16_targetTime) {
00160 uint16 u16_endTime, u16_maxExitTime;
00161 int16 i16_tempC, i16_lastTemp;
00162 uint8 u8_endPower;
00163
00164
00165 u16_maxExitTime = u16_tenthSeconds + u16_targetTime*10*5;
00166 i16_tempC = updateStats();
00167 u8_endPower = tempToPower(i16_targetTemp);
00168 if (i16_tempC < i16_targetTemp)setPower(100) ;
00169 while (i16_tempC < i16_targetTemp) {
00170 DELAY_MS(1000);
00171 i16_tempC = updateStats();
00172 printf("Current temp/time: %u %u Power: %u\n",i16_tempC,u16_tenthSeconds, getPower());
00173 if (u16_tenthSeconds > u16_maxExitTime)return;
00174 }
00175 i16_lastTemp = i16_tempC;
00176 u16_endTime = u16_tenthSeconds + u16_targetTime*10;
00177 do {
00178 DELAY_MS(1000);
00179 i16_tempC = updateStats();
00180 printf("Current temp/time: %u %u Power: %u\n",i16_tempC, u16_tenthSeconds, getPower());
00181 if ((i16_tempC < i16_lastTemp) && (i16_tempC < i16_targetTemp ) ) {
00182
00183 setPower(u8_endPower);
00184 } else setPower(30);
00185 i16_lastTemp = i16_tempC;
00186 } while (u16_tenthSeconds < u16_endTime);
00187 }
00188
00189
00190 void doReflow(void) {
00191
00192 uint8 u8_rdyFlag,u8_c;
00193 uint16 i16_tempC;
00194
00195 u8_rdyFlag = 0;
00196 do {
00197 printf("\n\nOpen door, place board in oven, close door.\n");
00198 printf("Turn 'TEMP' knob to 'Toast On/Bake Off'\n");
00199 printf("Ensure that end of thermocouple is not touching\n");
00200 printf("the board or metal. \n");
00201 printf("Enter 'y' to continue or 'n' to exit...\n");
00202 u8_c = inCharEcho();
00203 if (u8_c == 'n') return;
00204 } while (u8_c != 'y');
00205
00206 u16_tenthSeconds = 0;
00207 u8_c = ZEROCROSS;
00208 while (u8_c == ZEROCROSS) {
00209 if (u16_tenthSeconds > 4) break;
00210 doHeartbeat();
00211 }
00212 if (u16_tenthSeconds > 4) {
00213 printf("\nExiting, power is not on to oven, cannot detect 60Hz cycling.\n");
00214 return;
00215 }
00216 u16_tenthSeconds = 0;
00217 resetStats();
00218
00219 i16_tempC = getCelsiusI16Temp();
00220 printf("\nStart Preheat (temp = %uC)\n",i16_tempC);
00221 doRampUp(profiles[u8_currentProfile].i16_preheatTemp,
00222 profiles[u8_currentProfile].u16_preheatTime);
00223
00224 i16_tempC = getCelsiusI16Temp();
00225 printf("\nStart Soak (temp = %uC), Elapsed time: %u s\n",i16_tempC,
00226 u16_tenthSeconds/10);
00227 doRampUp(profiles[u8_currentProfile].i16_soakTemp,
00228 profiles[u8_currentProfile].u16_soakTime);
00229
00230 printf("\nStart Reflow (temp = %uC), Elapsed time: %u s\n",i16_tempC,
00231 u16_tenthSeconds/10);
00232 doRampUp(profiles[u8_currentProfile].i16_reflowTemp,
00233 profiles[u8_currentProfile].u16_reflowTime);
00234 printf("\nStart Reflow Hold (temp = %uC), Elapsed time: %u s\n",i16_tempC,
00235 u16_tenthSeconds/10);
00236 doHold(profiles[u8_currentProfile].i16_reflowTemp,
00237 profiles[u8_currentProfile].u16_reflowHoldTime);
00238
00239
00240 coolingFlag = 1;
00241 setPower(0);
00242 printf("\nStart Cool1 (temp = %uC), Elapsed time: %u s\n",i16_tempC,
00243 u16_tenthSeconds/10);
00244 doRampDown();
00245 #if 0
00246
00247 doRampDown(profiles[u8_currentProfile].i16_coolTemp,
00248 profiles[u8_currentProfile].u16_coolTime);
00249
00250 #endif
00251
00252 printStats();
00253
00254 }
00255
00256