This is a Reflow Oven Controller ported to the mbed platform Original article: http://www.circuitcellar.com/renesas/winners/Abstracts/H3323%20abstract.pdf
main.cpp@0:9526e71a200f, 2012-01-15 (annotated)
- Committer:
- jpelletier
- Date:
- Sun Jan 15 06:13:50 2012 +0000
- Revision:
- 0:9526e71a200f
This port compiles but I haven\t tested it on hardware yet. There may be some adjustments to the LCD commands to be done.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
jpelletier | 0:9526e71a200f | 1 | //----------------------------------------------------------------------- |
jpelletier | 0:9526e71a200f | 2 | // reflow oven controller |
jpelletier | 0:9526e71a200f | 3 | // |
jpelletier | 0:9526e71a200f | 4 | // Version 1.0 - December 2003 |
jpelletier | 0:9526e71a200f | 5 | // |
jpelletier | 0:9526e71a200f | 6 | // ATOM-Pro basic for Renesas '3687 |
jpelletier | 0:9526e71a200f | 7 | // |
jpelletier | 0:9526e71a200f | 8 | // Copyright (name deleted) |
jpelletier | 0:9526e71a200f | 9 | |
jpelletier | 0:9526e71a200f | 10 | // This project is a port from the original basic code for the Basic Micro EVB87 |
jpelletier | 0:9526e71a200f | 11 | // Renesas evaluation board to the mbed in C. |
jpelletier | 0:9526e71a200f | 12 | // |
jpelletier | 0:9526e71a200f | 13 | // We use the same setup as the original project: |
jpelletier | 0:9526e71a200f | 14 | // For the thermocouple, a AD595 cnnected to one of the analog input of the mbed. |
jpelletier | 0:9526e71a200f | 15 | // For the buttons, 3 push buttons connected to ground and pullups. |
jpelletier | 0:9526e71a200f | 16 | // For the heater, any driver configuration. |
jpelletier | 0:9526e71a200f | 17 | // |
jpelletier | 0:9526e71a200f | 18 | // http://www.circuitcellar.com/renesas/winners/Abstracts/H3323%20abstract.pdf |
jpelletier | 0:9526e71a200f | 19 | //----------------------------------------------------------------------- |
jpelletier | 0:9526e71a200f | 20 | |
jpelletier | 0:9526e71a200f | 21 | #include "mbed.h" |
jpelletier | 0:9526e71a200f | 22 | #include "TextLCD.h" |
jpelletier | 0:9526e71a200f | 23 | |
jpelletier | 0:9526e71a200f | 24 | //TextLCD lcd(p6, p7, p8, p13, p14, p15, p16); // rs, rw, e, d4, d5, d6, d7 |
jpelletier | 0:9526e71a200f | 25 | TextLCD lcd(p6, p8, p13, p14, p15, p16); // rs, e, d4, d5, d6, d7 |
jpelletier | 0:9526e71a200f | 26 | |
jpelletier | 0:9526e71a200f | 27 | // 0 button pressed, 1 button released |
jpelletier | 0:9526e71a200f | 28 | DigitalIn IN8(p30); |
jpelletier | 0:9526e71a200f | 29 | DigitalIn IN9(p29); |
jpelletier | 0:9526e71a200f | 30 | DigitalIn IN10(p28); |
jpelletier | 0:9526e71a200f | 31 | |
jpelletier | 0:9526e71a200f | 32 | // 0 off, 1 on |
jpelletier | 0:9526e71a200f | 33 | DigitalOut HeaterOutput(p27); |
jpelletier | 0:9526e71a200f | 34 | |
jpelletier | 0:9526e71a200f | 35 | // Use the USB link as serial port |
jpelletier | 0:9526e71a200f | 36 | Serial pc(USBTX, USBRX); // tx, rx |
jpelletier | 0:9526e71a200f | 37 | |
jpelletier | 0:9526e71a200f | 38 | // The 0.0v to 3.3v range of the AnalogIn is represented in software |
jpelletier | 0:9526e71a200f | 39 | // as a normalised floating point number from 0.0 to 1.0. |
jpelletier | 0:9526e71a200f | 40 | AnalogIn ain(p15); |
jpelletier | 0:9526e71a200f | 41 | |
jpelletier | 0:9526e71a200f | 42 | // AD595 10mv/'C at 3.3V -> 330'C |
jpelletier | 0:9526e71a200f | 43 | |
jpelletier | 0:9526e71a200f | 44 | //======================================================================= |
jpelletier | 0:9526e71a200f | 45 | // variables |
jpelletier | 0:9526e71a200f | 46 | //======================================================================= |
jpelletier | 0:9526e71a200f | 47 | |
jpelletier | 0:9526e71a200f | 48 | int PreheatSlope; // 1 to 255, 1/10° per sec |
jpelletier | 0:9526e71a200f | 49 | int DryingTemp; // 20 to 250, °C |
jpelletier | 0:9526e71a200f | 50 | int Hysteresis; // 1 to 20, °C |
jpelletier | 0:9526e71a200f | 51 | int DryingTime; // 1 to 255, seconds |
jpelletier | 0:9526e71a200f | 52 | int HeatingSlope; // 1 to 255, 1/10° per sec |
jpelletier | 0:9526e71a200f | 53 | int ReflowTemp; // 150 to 255, °C |
jpelletier | 0:9526e71a200f | 54 | int ReflowTime; // 1 to 255, seconds |
jpelletier | 0:9526e71a200f | 55 | int CoolingSlope; // 1 to 255, 1/10° per sec |
jpelletier | 0:9526e71a200f | 56 | int Kd; // kd muliplier for pid, in 1/10 |
jpelletier | 0:9526e71a200f | 57 | |
jpelletier | 0:9526e71a200f | 58 | char status; // state machine status |
jpelletier | 0:9526e71a200f | 59 | int t; // current temperature |
jpelletier | 0:9526e71a200f | 60 | int tini; // initial temperature |
jpelletier | 0:9526e71a200f | 61 | int tset10; // set temperature times 10 |
jpelletier | 0:9526e71a200f | 62 | int tset; // set temperature |
jpelletier | 0:9526e71a200f | 63 | int remaining_time; // remaining time in s |
jpelletier | 0:9526e71a200f | 64 | char heater; // heater on/off |
jpelletier | 0:9526e71a200f | 65 | int tprec; // previous temperature |
jpelletier | 0:9526e71a200f | 66 | int testim; // estimated future temperature |
jpelletier | 0:9526e71a200f | 67 | |
jpelletier | 0:9526e71a200f | 68 | // Used to toggle between 2 display screens |
jpelletier | 0:9526e71a200f | 69 | char dispcycle; // display cycle (0/1/0/1...) |
jpelletier | 0:9526e71a200f | 70 | |
jpelletier | 0:9526e71a200f | 71 | int alow; |
jpelletier | 0:9526e71a200f | 72 | int ahigh; |
jpelletier | 0:9526e71a200f | 73 | |
jpelletier | 0:9526e71a200f | 74 | char *lcd_status[] = { |
jpelletier | 0:9526e71a200f | 75 | "UpDry ","WtDry ","Drying ","UpFlow ","WtFlow ","Reflow ","Coolng " |
jpelletier | 0:9526e71a200f | 76 | }; |
jpelletier | 0:9526e71a200f | 77 | |
jpelletier | 0:9526e71a200f | 78 | #define PREHEAT 1 |
jpelletier | 0:9526e71a200f | 79 | #define WAIT_DRYING 2 |
jpelletier | 0:9526e71a200f | 80 | #define DRYING 3 |
jpelletier | 0:9526e71a200f | 81 | #define HEAT 4 |
jpelletier | 0:9526e71a200f | 82 | #define WAIT_REFLOW 5 |
jpelletier | 0:9526e71a200f | 83 | #define REFLOW 6 |
jpelletier | 0:9526e71a200f | 84 | #define COOLING 7 |
jpelletier | 0:9526e71a200f | 85 | |
jpelletier | 0:9526e71a200f | 86 | void heater_off(void) { |
jpelletier | 0:9526e71a200f | 87 | HeaterOutput = 0; |
jpelletier | 0:9526e71a200f | 88 | } |
jpelletier | 0:9526e71a200f | 89 | |
jpelletier | 0:9526e71a200f | 90 | void heater_on(void) { |
jpelletier | 0:9526e71a200f | 91 | HeaterOutput = 1; |
jpelletier | 0:9526e71a200f | 92 | } |
jpelletier | 0:9526e71a200f | 93 | |
jpelletier | 0:9526e71a200f | 94 | //======================================================================= |
jpelletier | 0:9526e71a200f | 95 | // Subroutines |
jpelletier | 0:9526e71a200f | 96 | //======================================================================= |
jpelletier | 0:9526e71a200f | 97 | |
jpelletier | 0:9526e71a200f | 98 | // Initialisation |
jpelletier | 0:9526e71a200f | 99 | void Init(void) { |
jpelletier | 0:9526e71a200f | 100 | // Welcome screen |
jpelletier | 0:9526e71a200f | 101 | lcd.cls(); |
jpelletier | 0:9526e71a200f | 102 | lcd.printf(" REFLOW CONTROL "); |
jpelletier | 0:9526e71a200f | 103 | lcd.locate(0,1); |
jpelletier | 0:9526e71a200f | 104 | lcd.printf(" V1.0 "); |
jpelletier | 0:9526e71a200f | 105 | |
jpelletier | 0:9526e71a200f | 106 | wait_ms(10); |
jpelletier | 0:9526e71a200f | 107 | |
jpelletier | 0:9526e71a200f | 108 | // Initialize variables to default values |
jpelletier | 0:9526e71a200f | 109 | PreheatSlope = 10; // 1 to 255, 1/10° per sec |
jpelletier | 0:9526e71a200f | 110 | DryingTemp = 100; // 20 to 250, °C |
jpelletier | 0:9526e71a200f | 111 | Hysteresis = 5; // 1 to 20, °C |
jpelletier | 0:9526e71a200f | 112 | DryingTime = 120; // 1 to 255, seconds |
jpelletier | 0:9526e71a200f | 113 | HeatingSlope = 40; // 1 to 255, 1/10° per sec |
jpelletier | 0:9526e71a200f | 114 | ReflowTemp = 250; // 150 to 255, °C |
jpelletier | 0:9526e71a200f | 115 | ReflowTime = 45; // 1 to 255, seconds |
jpelletier | 0:9526e71a200f | 116 | CoolingSlope = 20; // 1 to 255, 1/10° per sec |
jpelletier | 0:9526e71a200f | 117 | Kd = 10; // 0 to 100, kd multiplier in 1/10 |
jpelletier | 0:9526e71a200f | 118 | } |
jpelletier | 0:9526e71a200f | 119 | |
jpelletier | 0:9526e71a200f | 120 | void editnum(int *value,int minval,int maxval) { |
jpelletier | 0:9526e71a200f | 121 | int v; |
jpelletier | 0:9526e71a200f | 122 | |
jpelletier | 0:9526e71a200f | 123 | v = *value; |
jpelletier | 0:9526e71a200f | 124 | |
jpelletier | 0:9526e71a200f | 125 | do { |
jpelletier | 0:9526e71a200f | 126 | wait_ms(200); |
jpelletier | 0:9526e71a200f | 127 | lcd.locate(10,0); |
jpelletier | 0:9526e71a200f | 128 | lcd.printf("%d ",v); |
jpelletier | 0:9526e71a200f | 129 | lcd.locate(0,1); |
jpelletier | 0:9526e71a200f | 130 | lcd.printf("[2+][1-] [0:end]"); |
jpelletier | 0:9526e71a200f | 131 | |
jpelletier | 0:9526e71a200f | 132 | if (IN9 == 0) { |
jpelletier | 0:9526e71a200f | 133 | v--; |
jpelletier | 0:9526e71a200f | 134 | if (v < minval) v = minval; |
jpelletier | 0:9526e71a200f | 135 | } |
jpelletier | 0:9526e71a200f | 136 | |
jpelletier | 0:9526e71a200f | 137 | if (IN10 == 0) { |
jpelletier | 0:9526e71a200f | 138 | v++; |
jpelletier | 0:9526e71a200f | 139 | if (v > maxval) v = maxval; |
jpelletier | 0:9526e71a200f | 140 | } |
jpelletier | 0:9526e71a200f | 141 | |
jpelletier | 0:9526e71a200f | 142 | } while (IN8 != 0); |
jpelletier | 0:9526e71a200f | 143 | |
jpelletier | 0:9526e71a200f | 144 | *value = v; |
jpelletier | 0:9526e71a200f | 145 | } |
jpelletier | 0:9526e71a200f | 146 | |
jpelletier | 0:9526e71a200f | 147 | void UpdateStateMachine(void) { |
jpelletier | 0:9526e71a200f | 148 | if (status == 0) return; |
jpelletier | 0:9526e71a200f | 149 | |
jpelletier | 0:9526e71a200f | 150 | switch (status - 1) { |
jpelletier | 0:9526e71a200f | 151 | case PREHEAT: |
jpelletier | 0:9526e71a200f | 152 | tset10 = tset10 + PreheatSlope; |
jpelletier | 0:9526e71a200f | 153 | tset = tset10/10; |
jpelletier | 0:9526e71a200f | 154 | |
jpelletier | 0:9526e71a200f | 155 | if (tset > DryingTemp) { |
jpelletier | 0:9526e71a200f | 156 | tset10 = DryingTemp * 10; |
jpelletier | 0:9526e71a200f | 157 | status = WAIT_DRYING; |
jpelletier | 0:9526e71a200f | 158 | dispcycle = 1; |
jpelletier | 0:9526e71a200f | 159 | } |
jpelletier | 0:9526e71a200f | 160 | break; |
jpelletier | 0:9526e71a200f | 161 | |
jpelletier | 0:9526e71a200f | 162 | case WAIT_DRYING: |
jpelletier | 0:9526e71a200f | 163 | if ((t + Hysteresis) > DryingTemp) { |
jpelletier | 0:9526e71a200f | 164 | remaining_time = DryingTime; |
jpelletier | 0:9526e71a200f | 165 | status = DRYING; |
jpelletier | 0:9526e71a200f | 166 | dispcycle = 1; |
jpelletier | 0:9526e71a200f | 167 | } |
jpelletier | 0:9526e71a200f | 168 | break; |
jpelletier | 0:9526e71a200f | 169 | |
jpelletier | 0:9526e71a200f | 170 | case DRYING: |
jpelletier | 0:9526e71a200f | 171 | if (remaining_time == 0) { |
jpelletier | 0:9526e71a200f | 172 | remaining_time = (10 * (ReflowTemp - DryingTemp))/HeatingSlope; |
jpelletier | 0:9526e71a200f | 173 | status = HEAT; |
jpelletier | 0:9526e71a200f | 174 | dispcycle = 1; |
jpelletier | 0:9526e71a200f | 175 | } |
jpelletier | 0:9526e71a200f | 176 | break; |
jpelletier | 0:9526e71a200f | 177 | |
jpelletier | 0:9526e71a200f | 178 | case HEAT: |
jpelletier | 0:9526e71a200f | 179 | tset10 = tset10 + HeatingSlope; |
jpelletier | 0:9526e71a200f | 180 | tset = tset10/10; |
jpelletier | 0:9526e71a200f | 181 | if (tset > ReflowTemp) { |
jpelletier | 0:9526e71a200f | 182 | tset10 = 10 * ReflowTemp; |
jpelletier | 0:9526e71a200f | 183 | status = WAIT_REFLOW; |
jpelletier | 0:9526e71a200f | 184 | dispcycle = 1; |
jpelletier | 0:9526e71a200f | 185 | } |
jpelletier | 0:9526e71a200f | 186 | break; |
jpelletier | 0:9526e71a200f | 187 | |
jpelletier | 0:9526e71a200f | 188 | case WAIT_REFLOW: |
jpelletier | 0:9526e71a200f | 189 | if ((t + Hysteresis) > ReflowTemp) { |
jpelletier | 0:9526e71a200f | 190 | remaining_time = ReflowTime; |
jpelletier | 0:9526e71a200f | 191 | status = REFLOW; |
jpelletier | 0:9526e71a200f | 192 | dispcycle = 1; |
jpelletier | 0:9526e71a200f | 193 | } |
jpelletier | 0:9526e71a200f | 194 | break; |
jpelletier | 0:9526e71a200f | 195 | |
jpelletier | 0:9526e71a200f | 196 | case REFLOW: |
jpelletier | 0:9526e71a200f | 197 | if (remaining_time == 0) { |
jpelletier | 0:9526e71a200f | 198 | remaining_time = (10 * (ReflowTemp - tini))/CoolingSlope; |
jpelletier | 0:9526e71a200f | 199 | status = COOLING; |
jpelletier | 0:9526e71a200f | 200 | dispcycle = 1; |
jpelletier | 0:9526e71a200f | 201 | } |
jpelletier | 0:9526e71a200f | 202 | break; |
jpelletier | 0:9526e71a200f | 203 | |
jpelletier | 0:9526e71a200f | 204 | case COOLING: |
jpelletier | 0:9526e71a200f | 205 | tset10 = tset10 - CoolingSlope; |
jpelletier | 0:9526e71a200f | 206 | tset = tset10/10; |
jpelletier | 0:9526e71a200f | 207 | if (tset < tini) { |
jpelletier | 0:9526e71a200f | 208 | tset10 = 10 * tini; |
jpelletier | 0:9526e71a200f | 209 | status = 0; |
jpelletier | 0:9526e71a200f | 210 | dispcycle = 1; |
jpelletier | 0:9526e71a200f | 211 | } |
jpelletier | 0:9526e71a200f | 212 | break; |
jpelletier | 0:9526e71a200f | 213 | |
jpelletier | 0:9526e71a200f | 214 | default: |
jpelletier | 0:9526e71a200f | 215 | status = 0; |
jpelletier | 0:9526e71a200f | 216 | } |
jpelletier | 0:9526e71a200f | 217 | } |
jpelletier | 0:9526e71a200f | 218 | |
jpelletier | 0:9526e71a200f | 219 | // Read current temperature |
jpelletier | 0:9526e71a200f | 220 | // return temperature in ahigh (degrees) and alow (tens of a degree) |
jpelletier | 0:9526e71a200f | 221 | void readtemperature(void) { |
jpelletier | 0:9526e71a200f | 222 | long int atemp; |
jpelletier | 0:9526e71a200f | 223 | long int a; // temporary |
jpelletier | 0:9526e71a200f | 224 | int i; |
jpelletier | 0:9526e71a200f | 225 | |
jpelletier | 0:9526e71a200f | 226 | a = 0; |
jpelletier | 0:9526e71a200f | 227 | |
jpelletier | 0:9526e71a200f | 228 | /* 1000 readings */ |
jpelletier | 0:9526e71a200f | 229 | for (i=1; i <= 1000; i++) { |
jpelletier | 0:9526e71a200f | 230 | atemp = ain * 330; // 3.3V from an AD595 at 10mV/'C -> 330'C |
jpelletier | 0:9526e71a200f | 231 | a += atemp; |
jpelletier | 0:9526e71a200f | 232 | } |
jpelletier | 0:9526e71a200f | 233 | /* a = 1000 * avg temp */ |
jpelletier | 0:9526e71a200f | 234 | // ex: 300.2 a = 300200 |
jpelletier | 0:9526e71a200f | 235 | |
jpelletier | 0:9526e71a200f | 236 | a = a/100; // a = 3002 |
jpelletier | 0:9526e71a200f | 237 | |
jpelletier | 0:9526e71a200f | 238 | /* ahigh = */ |
jpelletier | 0:9526e71a200f | 239 | ahigh = a/10; // ahigh = 300 |
jpelletier | 0:9526e71a200f | 240 | alow = a - ahigh*10; // alow = 3002 - 3000 = 2 |
jpelletier | 0:9526e71a200f | 241 | } |
jpelletier | 0:9526e71a200f | 242 | |
jpelletier | 0:9526e71a200f | 243 | void RunMode() { |
jpelletier | 0:9526e71a200f | 244 | // initialise run mode |
jpelletier | 0:9526e71a200f | 245 | status = 1; |
jpelletier | 0:9526e71a200f | 246 | dispcycle = 0; |
jpelletier | 0:9526e71a200f | 247 | t = 0; |
jpelletier | 0:9526e71a200f | 248 | readtemperature(); |
jpelletier | 0:9526e71a200f | 249 | |
jpelletier | 0:9526e71a200f | 250 | t = ahigh; |
jpelletier | 0:9526e71a200f | 251 | tini = t; |
jpelletier | 0:9526e71a200f | 252 | tset10 = 10*t; |
jpelletier | 0:9526e71a200f | 253 | remaining_time = (10*(DryingTemp - t))/PreheatSlope; |
jpelletier | 0:9526e71a200f | 254 | heater = 0; |
jpelletier | 0:9526e71a200f | 255 | |
jpelletier | 0:9526e71a200f | 256 | // wait for run button released |
jpelletier | 0:9526e71a200f | 257 | while (IN8 == 0); |
jpelletier | 0:9526e71a200f | 258 | wait_ms(10); |
jpelletier | 0:9526e71a200f | 259 | |
jpelletier | 0:9526e71a200f | 260 | do { |
jpelletier | 0:9526e71a200f | 261 | tprec = t; |
jpelletier | 0:9526e71a200f | 262 | |
jpelletier | 0:9526e71a200f | 263 | // read new temperature |
jpelletier | 0:9526e71a200f | 264 | readtemperature(); |
jpelletier | 0:9526e71a200f | 265 | t = ahigh; |
jpelletier | 0:9526e71a200f | 266 | |
jpelletier | 0:9526e71a200f | 267 | // estimate future temperature using kd |
jpelletier | 0:9526e71a200f | 268 | testim = ((10*t) + (t-tprec) * Kd)/10; |
jpelletier | 0:9526e71a200f | 269 | |
jpelletier | 0:9526e71a200f | 270 | tset = tset10/10; |
jpelletier | 0:9526e71a200f | 271 | |
jpelletier | 0:9526e71a200f | 272 | // display screen |
jpelletier | 0:9526e71a200f | 273 | lcd.cls(); |
jpelletier | 0:9526e71a200f | 274 | lcd.printf("Temp:%dC ", ahigh); |
jpelletier | 0:9526e71a200f | 275 | lcd.locate(10,0); |
jpelletier | 0:9526e71a200f | 276 | |
jpelletier | 0:9526e71a200f | 277 | if (dispcycle == 1) { |
jpelletier | 0:9526e71a200f | 278 | lcd.printf("%d/7",status); |
jpelletier | 0:9526e71a200f | 279 | } else { |
jpelletier | 0:9526e71a200f | 280 | lcd.puts(lcd_status[status-1]); |
jpelletier | 0:9526e71a200f | 281 | } |
jpelletier | 0:9526e71a200f | 282 | |
jpelletier | 0:9526e71a200f | 283 | lcd.locate(0,1); |
jpelletier | 0:9526e71a200f | 284 | lcd.printf("Tset:%dC ", tset); |
jpelletier | 0:9526e71a200f | 285 | lcd.locate(10,1); |
jpelletier | 0:9526e71a200f | 286 | lcd.printf("sec %d", remaining_time); |
jpelletier | 0:9526e71a200f | 287 | |
jpelletier | 0:9526e71a200f | 288 | // decrement time (in seconds, due to the 1 second pause) |
jpelletier | 0:9526e71a200f | 289 | if (remaining_time != 0) remaining_time--; |
jpelletier | 0:9526e71a200f | 290 | |
jpelletier | 0:9526e71a200f | 291 | // check if abort requested |
jpelletier | 0:9526e71a200f | 292 | if (IN8 == 0) { |
jpelletier | 0:9526e71a200f | 293 | status = 0; |
jpelletier | 0:9526e71a200f | 294 | heater_off(); |
jpelletier | 0:9526e71a200f | 295 | |
jpelletier | 0:9526e71a200f | 296 | // wait for run button released |
jpelletier | 0:9526e71a200f | 297 | while (IN8 == 0); |
jpelletier | 0:9526e71a200f | 298 | wait_ms(10); |
jpelletier | 0:9526e71a200f | 299 | } |
jpelletier | 0:9526e71a200f | 300 | |
jpelletier | 0:9526e71a200f | 301 | UpdateStateMachine(); |
jpelletier | 0:9526e71a200f | 302 | |
jpelletier | 0:9526e71a200f | 303 | tset = tset10/10; |
jpelletier | 0:9526e71a200f | 304 | |
jpelletier | 0:9526e71a200f | 305 | // control heater |
jpelletier | 0:9526e71a200f | 306 | if (heater == 0) { |
jpelletier | 0:9526e71a200f | 307 | if (testim < (tset - Hysteresis)) heater = 1; |
jpelletier | 0:9526e71a200f | 308 | } |
jpelletier | 0:9526e71a200f | 309 | |
jpelletier | 0:9526e71a200f | 310 | if (heater == 1) { |
jpelletier | 0:9526e71a200f | 311 | if (testim > (tset + Hysteresis)) heater = 0; |
jpelletier | 0:9526e71a200f | 312 | } |
jpelletier | 0:9526e71a200f | 313 | |
jpelletier | 0:9526e71a200f | 314 | if (heater == 0) |
jpelletier | 0:9526e71a200f | 315 | heater_off(); |
jpelletier | 0:9526e71a200f | 316 | else |
jpelletier | 0:9526e71a200f | 317 | heater_on(); |
jpelletier | 0:9526e71a200f | 318 | |
jpelletier | 0:9526e71a200f | 319 | // send current values to uart |
jpelletier | 0:9526e71a200f | 320 | pc.printf("S%d,%d,%d,%d\n",tset, t, status, heater); |
jpelletier | 0:9526e71a200f | 321 | |
jpelletier | 0:9526e71a200f | 322 | // wait for 1 second |
jpelletier | 0:9526e71a200f | 323 | wait(1); |
jpelletier | 0:9526e71a200f | 324 | |
jpelletier | 0:9526e71a200f | 325 | // next dispcycle |
jpelletier | 0:9526e71a200f | 326 | dispcycle = 1 - dispcycle; |
jpelletier | 0:9526e71a200f | 327 | } while (status != 0); |
jpelletier | 0:9526e71a200f | 328 | } |
jpelletier | 0:9526e71a200f | 329 | |
jpelletier | 0:9526e71a200f | 330 | void ConfigurationMode(void) { |
jpelletier | 0:9526e71a200f | 331 | int i; |
jpelletier | 0:9526e71a200f | 332 | |
jpelletier | 0:9526e71a200f | 333 | for (i = 1; i <= 9; i++) { |
jpelletier | 0:9526e71a200f | 334 | lcd.cls(); |
jpelletier | 0:9526e71a200f | 335 | lcd.locate(0,0); |
jpelletier | 0:9526e71a200f | 336 | |
jpelletier | 0:9526e71a200f | 337 | switch (i) { |
jpelletier | 0:9526e71a200f | 338 | case 1: |
jpelletier | 0:9526e71a200f | 339 | lcd.printf("DrySlope"); |
jpelletier | 0:9526e71a200f | 340 | editnum(&PreheatSlope,1,255); |
jpelletier | 0:9526e71a200f | 341 | break; |
jpelletier | 0:9526e71a200f | 342 | case 2: |
jpelletier | 0:9526e71a200f | 343 | lcd.printf("DryTemp "); |
jpelletier | 0:9526e71a200f | 344 | editnum(&DryingTemp,40,150); |
jpelletier | 0:9526e71a200f | 345 | break; |
jpelletier | 0:9526e71a200f | 346 | case 3: |
jpelletier | 0:9526e71a200f | 347 | lcd.printf("Hysteres"); |
jpelletier | 0:9526e71a200f | 348 | editnum(&Hysteresis,1,40); |
jpelletier | 0:9526e71a200f | 349 | break; |
jpelletier | 0:9526e71a200f | 350 | case 4: |
jpelletier | 0:9526e71a200f | 351 | lcd.printf("DryTime "); |
jpelletier | 0:9526e71a200f | 352 | editnum(&DryingTime,1,255); |
jpelletier | 0:9526e71a200f | 353 | break; |
jpelletier | 0:9526e71a200f | 354 | case 5: |
jpelletier | 0:9526e71a200f | 355 | lcd.printf("HeatSlpe"); |
jpelletier | 0:9526e71a200f | 356 | editnum(&HeatingSlope,1,255); |
jpelletier | 0:9526e71a200f | 357 | break; |
jpelletier | 0:9526e71a200f | 358 | case 6: |
jpelletier | 0:9526e71a200f | 359 | lcd.printf("FlowTemp"); |
jpelletier | 0:9526e71a200f | 360 | editnum(&ReflowTemp,120,255); |
jpelletier | 0:9526e71a200f | 361 | break; |
jpelletier | 0:9526e71a200f | 362 | case 7: |
jpelletier | 0:9526e71a200f | 363 | lcd.printf("Flowtime"); |
jpelletier | 0:9526e71a200f | 364 | editnum(&ReflowTime,1,255); |
jpelletier | 0:9526e71a200f | 365 | break; |
jpelletier | 0:9526e71a200f | 366 | case 8: |
jpelletier | 0:9526e71a200f | 367 | lcd.printf("Coolslop"); |
jpelletier | 0:9526e71a200f | 368 | editnum(&CoolingSlope,1,255); |
jpelletier | 0:9526e71a200f | 369 | break; |
jpelletier | 0:9526e71a200f | 370 | case 9: |
jpelletier | 0:9526e71a200f | 371 | lcd.printf("Kd "); |
jpelletier | 0:9526e71a200f | 372 | editnum(&Kd,0,200); |
jpelletier | 0:9526e71a200f | 373 | break; |
jpelletier | 0:9526e71a200f | 374 | } |
jpelletier | 0:9526e71a200f | 375 | } |
jpelletier | 0:9526e71a200f | 376 | } |
jpelletier | 0:9526e71a200f | 377 | |
jpelletier | 0:9526e71a200f | 378 | //======================================================================= |
jpelletier | 0:9526e71a200f | 379 | // Main program |
jpelletier | 0:9526e71a200f | 380 | //======================================================================= |
jpelletier | 0:9526e71a200f | 381 | |
jpelletier | 0:9526e71a200f | 382 | int main(void) { |
jpelletier | 0:9526e71a200f | 383 | // Initialisations |
jpelletier | 0:9526e71a200f | 384 | Init(); |
jpelletier | 0:9526e71a200f | 385 | |
jpelletier | 0:9526e71a200f | 386 | lcd.cls(); |
jpelletier | 0:9526e71a200f | 387 | |
jpelletier | 0:9526e71a200f | 388 | // Main loop |
jpelletier | 0:9526e71a200f | 389 | while (1) { |
jpelletier | 0:9526e71a200f | 390 | // heater off |
jpelletier | 0:9526e71a200f | 391 | heater_off(); |
jpelletier | 0:9526e71a200f | 392 | |
jpelletier | 0:9526e71a200f | 393 | // Display current temperature |
jpelletier | 0:9526e71a200f | 394 | lcd.locate(0,0); |
jpelletier | 0:9526e71a200f | 395 | readtemperature(); |
jpelletier | 0:9526e71a200f | 396 | lcd.printf("Temp : %d.%dC ", ahigh, alow); |
jpelletier | 0:9526e71a200f | 397 | lcd.locate(0,1); |
jpelletier | 0:9526e71a200f | 398 | |
jpelletier | 0:9526e71a200f | 399 | // Display menu |
jpelletier | 0:9526e71a200f | 400 | lcd.printf("[1:CONF] [0:RUN]"); |
jpelletier | 0:9526e71a200f | 401 | |
jpelletier | 0:9526e71a200f | 402 | wait_ms(10); |
jpelletier | 0:9526e71a200f | 403 | |
jpelletier | 0:9526e71a200f | 404 | // Run button ? |
jpelletier | 0:9526e71a200f | 405 | if (IN8 == 0) |
jpelletier | 0:9526e71a200f | 406 | RunMode(); |
jpelletier | 0:9526e71a200f | 407 | else if (IN9 == 0) ConfigurationMode(); |
jpelletier | 0:9526e71a200f | 408 | } |
jpelletier | 0:9526e71a200f | 409 | } |