#define START_STATE 0 #define PREHEAT_STATE 1 #define RAMP_UP_STATE 2 #define TAL_FIRST_STATE 3 #define PEAK_STATE 4 #define TAL_SECOND_STATE 5 #define RAMPDOWN_STATE 6 #define END_STATE 7 #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_TIME_MAX 4 // reflow process does take too long unsigned int time = 0; // profile seconds unsigned int temperatur = 25; // actual oven temp unsigned int last_temperatur = 25; unsigned int Ts_max = 200; // °C unsigned int Ts_min = 150; // °C unsigned int Tp = 260; // 245-260°C unsigned int rampup_rate = 3; // 3°C/s unsigned int preheat_duration = 100; // 60-180s unsigned int tal = 217; // 217°C unsigned int tal_duration = 100; // 60-150s unsigned int peak_duration = 30; // 20-40s unsigned int rampdown_max = 6; // 6°C/s max unsigned int rampdown_min = 2; // 2°C/s max unsigned int time_max = 480; // 8*60s max unsigned int Ts_min_time = 0; unsigned int Ts_max_time = 0; unsigned int Tl_time = 0; unsigned int Tl_time_end = 0; unsigned int Tp_time = 0; unsigned int Tl_end_time = 0; unsigned int error_condition = 0; byte state = START_STATE; void setup() { pinMode(13, OUTPUT); Serial.begin(9600); } void get_temp() { // simulating an +1K/s rampup oven last_temperatur = temperatur++; } boolean check_rampup_rate() { if (temperatur - last_temperatur > rampup_rate) { error_condition = E_RAMPUP; return false; } return 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 time_max_check() { if (time > time_max) { error_condition = E_TIME_MAX; return false; } } boolean check_tal_duration() { if (time > time_max) { error_condition = E_TIME_MAX; return false; } } void loop() { time = millis() / 1000; get_temp(); Serial.print(time); Serial.print(" "); Serial.print(temperatur); Serial.print(" "); Serial.println(last_temperatur); switch (state) { case START_STATE: // going from room temp to preheat, nothing to check here if (!check_rampup_rate()) goto error; if (temperatur > Ts_min) { Serial.println("Changed state to PREHEAT_STATE"); Ts_min_time = time; state++; } case PREHEAT_STATE: if (temperatur > Ts_max) { Serial.println("Changed state to PREHEAT_STATE"); Ts_max_time = time; state++; } break; case TAL_FIRST_STATE: break; case PEAK_STATE: break; case TAL_SECOND_STATE: break; case RAMPDOWN_STATE: break; case END_STATE: default: break; } delay(1000); return; error: state = END_STATE; Serial.println(error_condition); }