From b1060ab9f432084ff1b1c0db3336cf6eedbf63f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20K=C3=B6gl?= Date: Wed, 3 Oct 2012 20:09:27 +0200 Subject: [PATCH] almost done --- reflowctl/reflowctl.ino | 274 +++++++++++++++++++++++++--------------- 1 file changed, 172 insertions(+), 102 deletions(-) diff --git a/reflowctl/reflowctl.ino b/reflowctl/reflowctl.ino index dfb56a4..4d6bc7e 100644 --- a/reflowctl/reflowctl.ino +++ b/reflowctl/reflowctl.ino @@ -10,23 +10,25 @@ #define ERROR_STATE 8 // error conditions -#define E_RAMPUP 1 // oven heats up too fast -#define E_RAMPDOWN_TOO_FAST 2 // oven cools down too fast -#define E_RAMPDOWN_TOO_SLOW 3 // oven cools down too slow +#define E_DT_MIN 1 // temperatur dt too small +#define E_DT_MAX 2 // temperatur dt too big #define E_TIME_MAX 4 // reflow process does take too long -#define E_PEAK_TOO_LONG 5 // package was roasted +#define E_PEAK_TOO_LONG 8 // package was roasted unsigned int time = 0; // profile seconds unsigned int temperatur = 25; // actual oven temp unsigned int last_temperatur = 25; +unsigned int actual_dt = 0; // profile stuff -unsigned int Ts_max = 200; // °C unsigned int Ts_min = 150; // °C +unsigned int Ts_max = 200; // °C unsigned int Tp = 260; // 245-260°C + unsigned int rampup_rate = 50; // 3°C/s unsigned int preheat_duration = 100; // 60-180s + unsigned int Tl = 217; // 217°C unsigned int Tl_duration = 100; // 60-150s unsigned int peak_duration = 30; // 20-40s @@ -43,6 +45,7 @@ unsigned int Tp_time_end = 0; unsigned int error_condition = 0; boolean is_oven_heating = false; +boolean led_on = false; byte state = START_STATE; @@ -52,77 +55,121 @@ int hysteresis = 0; int set_min = 0; int set_max = 0; +int set_dt_min = 0; +int set_dt_max = 0; void setup() { Serial.begin(9600); - get_temp(); - last_temperatur = temperatur; - control_oven(Tp, Tp); + delay(2000); + set_start_state(); + } -void set_temp(int min, int max) { - set_min = min; - set_max = max; -} - void control_oven() { - if (temperatur < set_min) { + if (temperatur < set_min && (!is_oven_heating)) { is_oven_heating = true; Serial.println("Oven turned on"); } - else if (temperatur < set_max) { + else if (temperatur > set_max && is_oven_heating) { is_oven_heating = false; Serial.println("Oven turned off"); } } +void set_temp(int min, int max, int dt_min, int dt_max) { + set_min = min; + set_max = max; + set_dt_min = dt_min; + set_dt_max = dt_max; +} + void get_temp() { - // simulating an +1K/s rampup oven last_temperatur = temperatur; temperatur = int(float(analogRead(analogPin)) * 0.2929); + actual_dt = temperatur - last_temperatur; } -void check_rampup_rate() { - if (temperatur - last_temperatur > rampup_rate) { - error_condition = E_RAMPUP; - control_oven(false); +void check_dt() { + if (actual_dt > set_dt_max) { + error_condition |= E_DT_MAX; } - else - control_oven(true); -} - -boolean check_rampdown_rate() { - unsigned int dt = temperatur - last_temperatur; - if (dt > rampdown_max) { - error_condition = E_RAMPDOWN_TOO_FAST; - return false; - } - - if (dt < rampdown_min) { - error_condition = E_RAMPDOWN_TOO_SLOW; - return false; - } - return true; -} - - -boolean check_max_duration() { - if (time > time_max) { - error_condition = E_TIME_MAX; - return false; + if (actual_dt < set_dt_min) { + error_condition |= E_DT_MIN; } } +void print_debug() { + Serial.print("Time: "); + Serial.print(time); + Serial.print(", temperatur: "); + Serial.print(temperatur); + Serial.print(", last_temperatur: "); + Serial.print(last_temperatur); + Serial.print(", state: "); + Serial.print(state); + Serial.print(", Error: "); + Serial.println(error_condition); +} + +// boolean check_max_duration() { +// if (time > time_max) { +// error_condition = E_TIME_MAX; +// return false; +// } +// } +/* boolean check_Tl_duration() { if (time > time_max) { error_condition = E_TIME_MAX; return false; } +}*/ + +void set_start_state() { + get_temp(); + last_temperatur = temperatur; + set_temp(Tp-5, Tp, 0, rampup_rate); } +void set_preheat_state() { +} + +void set_ramp_up_state() { + +} + +void set_tal_first_state() { +} + +void set_peak_state() { + Serial.println("Changed state to PEAK_STATE"); +} + +void set_tal_second_state() { + Serial.println("Changed state to TAL_SECOND_STATE"); + set_temp(25, 25, -3, -6); + state++; +} + +void set_ramp_down_state() { + Serial.println("Changed state to RAMP_DOWN_STATE"); + state++; +} + +void set_end_state() { + state = END_STATE; +} + +void set_error_state() { + if (state != ERROR_STATE) { + set_temp(0, 0, 0, 0); + state = ERROR_STATE; + } +} void handle_start_state() { + Serial.println("START_STATE"); if (temperatur > Ts_min) { Serial.println("Changing state to PREHEAT_STATE"); Ts_min_time = time; @@ -132,98 +179,121 @@ void handle_start_state() { -void handle_peak_state() { - Serial.println("PEAK_STATE"); - if (temperatur > Tp) - control_oven(false); - else - control_oven(true); - - if (time - Tp_time_start > peak_duration) { - Serial.println("Changed state to TAL_SECOND_STATE"); - Tp_time_end = time; +void handle_preheat_state() { + Serial.println("PREHEAT_STATE"); + if (temperatur > Ts_max) { + Serial.println("Changed state to RAMP_UP_STATE"); + Ts_max_time = time; state++; } } +void handle_rampup_state() { + Serial.println("RAMP_UP_STATE"); + if (temperatur > Tl) { + Serial.println("Changed state to TAL_FIRST_STATE"); + Tl_time_start = time; + state++; + } +} + +void handle_tal_first_state() { + Serial.println("TAL_FIRST_STATE"); + if (temperatur > Tp - 5) { + Serial.println("Changed state to PEAK_STATE"); + Tp_time_start = time; + state++; + set_peak_state(); + } +} + +void handle_peak_state() { + Serial.println("PEAK_STATE"); + + if (time - Tp_time_start > peak_duration) { + Tp_time_end = time; + set_tal_second_state(); + } +} + + +void handle_tal_second_state() { + if (temperatur < Tl) { + set_ramp_down_state(); + } +} + +void handle_ramp_down_state() { + if (temperatur < Ts_min) { + Serial.println("Changed state to END_STATE"); + state++; + } +} + + +void handle_error_state() { + if (led_on) { + digitalWrite(13, LOW); + led_on = false; + } + else { + digitalWrite(13, HIGH); + led_on = true; + } + if (error_condition & E_DT_MIN) + Serial.print("Error: delta °K/second too low"); + if (error_condition & E_DT_MAX) + Serial.print("Error: delta °K/second too big"); +} + void loop() { time = millis() / 1000; get_temp(); - Serial.print(time); - Serial.print(" "); - Serial.print(temperatur); - Serial.print(" "); - Serial.print(last_temperatur); - Serial.print(" "); - Serial.println(state); + check_dt(); + + if (error_condition) { + set_error_state(); + } + else { + print_debug(); + } + - switch (state) { case START_STATE: - Serial.println("START_STATE"); - // going from room temp to preheat, nothing to check here handle_start_state(); break; case PREHEAT_STATE: - Serial.println("PREHEAT_STATE"); - check_rampup_rate(); - if (temperatur > Ts_max) { - Serial.println("Changed state to RAMP_UP_STATE"); - Ts_max_time = time; - state++; - } + handle_preheat_state(); break; case RAMP_UP_STATE: - Serial.println("RAMP_UP_STATE"); - check_rampup_rate(); - if (temperatur > Tl) { - Serial.println("Changed state to TAL_FIRST_STATE"); - Tl_time_start = time; - state++; - } + handle_rampup_state(); break; case TAL_FIRST_STATE: - Serial.println("TAL_FIRST_STATE"); - check_rampup_rate(); - if (temperatur > Tp - 5) { - Serial.println("Changed state to PEAK_STATE"); - Tp_time_start = time; - state++; - } + handle_tal_first_state(); break; case PEAK_STATE: handle_peak_state(); break; case TAL_SECOND_STATE: - Serial.println("TAL_SECOND_STATE"); - if (temperatur < Tl) { - Serial.println("Changed state to RAMP_DOWN_STATE"); - Tl_time_end = time; - state++; - } + Tl_time_end = time; + handle_tal_second_state(); break; case RAMP_DOWN_STATE: - Serial.println("RAMP_DOWN_STATE"); - if (temperatur < Ts_min) { - Serial.println("Changed state to END_STATE"); - state++; - } + handle_ramp_down_state(); break; case END_STATE: Serial.println("END_STATE"); + break; + case ERROR_STATE: + handle_error_state(); + break; default: break; } control_oven(); delay(1000); - - return; - -error: - state = END_STATE; - Serial.print("Error: "); - Serial.println(error_condition); }