#include "oven_control.h" #include #include #include "profile.h" //Pin assignments for SainSmart LCD Keypad Shield LiquidCrystal lcd(8, 9, 4, 5, 6, 7); DFR_Key keypad; Profile profile; OvenCtl::OvenCtl() { time = 0; temperature = 1; last_temperature = 1; actual_dt = 0.f; // timestamps of event beginnings/ends Ts_time_start = 0; Ts_time_end = 0; Tl_time_start = 0; Tl_time_end = 0; Tp_time_start = 0; Tp_time_end = 0; // thermostat set_min = 0; set_max = 0; set_dt_min = 0; set_dt_max = 0; op_state = OP_CONFIG; profile_state = START_STATE; error_condition = 0; is_oven_heating = false; actual_hysteresis = ramp_up_hysteresis = 1.0; // s ramp_down_hysteresis = 1.0; // s // ui stuff disable_checks = false; lcd.begin(16, 2); } void OvenCtl::reset() { digitalWrite(7, LOW); } void OvenCtl::send_state() { Serial.write(time & 0xff); Serial.write((time>>8) & 0xff); Serial.write(temperature & 0xff); Serial.write((temperature >> 8) & 0xff); Serial.write(last_temperature & 0xff); Serial.write((last_temperature >> 8) & 0xff); Serial.write(profile_state & 0xff); Serial.write((profile_state >> 8) & 0xff); Serial.write(error_condition & 0xff); Serial.write((error_condition >> 8) & 0xff); Serial.write(is_oven_heating); Serial.flush(); } void OvenCtl::send_config() { int tmp; for (int i=0;i < PI_END; i++) { tmp = profile.data[i]; Serial.write(tmp & 0xff); Serial.write((tmp >> 8 ) & 0xff); } Serial.flush(); } void OvenCtl::recv_config() { } void OvenCtl::dispatch_input_config(int cmd) { if (cmd == 255) send_config(); else if (cmd == 254) recv_config(); else if (cmd == 250) reset(); else if (cmd == 253) ; } void OvenCtl::handle_stand_alone_state() { time++; get_temp(); check_dt(); } void OvenCtl::handle_remote_state() { time++; get_temp(); check_dt(); } /** * handles input, dispatching state dependend modes to state handlers * * */ void OvenCtl::loop() { int cmd = -1; switch (op_state) { case OP_CONFIG: // if (profile.handle_config_state()) // set_start_state(); break; case OP_STAND_ALONE: // if (profile.handle_config_state()) // set_start_state(); // break; case OP_REMOTE: // if (profile.handle_config_state()) // set_start_state(); break; } // if (error_condition != 0) { // set_error_state(); // } if (Serial.available() > 0) { cmd = Serial.read(); if (cmd == 255) send_config(); else if (cmd == 254) send_state(); else if (cmd == 253) recv_config(); else if (cmd == 252) reset(); // else if (cmd == 251) // set_start_state(); } control_oven(); if (profile_state > 0) { print_status(); delay(1000); } } void OvenCtl::print_status() { if (error_condition == 0) { String tmp("T: "); if (time < 10) tmp += "00"; else if (time < 100) tmp += "0"; tmp += time; tmp += " Tmp: "; if (temperature < 10) tmp += "00"; else if (temperature < 100) tmp += "0"; tmp += temperature; lcd.setCursor(0, 0); lcd.print(tmp); tmp = "Profile: "; tmp += profile_state; tmp += "/"; tmp += END_STATE; lcd.setCursor(0, 1); lcd.print(tmp); lcd.setCursor(13, 1); if (is_oven_heating) lcd.print("on "); else lcd.print("off"); } else { lcd.clear(); lcd.print("Error:"); lcd.setCursor(0, 1); if (error_condition & E_DT_MIN) lcd.print("K/s too low"); if (error_condition & E_DT_MAX) lcd.print("K/s too high"); if (error_condition & E_TIME_MAX) lcd.print("reflow too long"); if (error_condition & E_TS_TOO_SHORT) lcd.print("ts too short"); if (error_condition & E_TS_TOO_LONG) lcd.print("ts too long"); if (error_condition & E_TL_TOO_SHORT) lcd.print("tal too short"); if (error_condition & E_TL_TOO_LONG) lcd.print("tal too long"); if (error_condition & E_TP_TOO_LONG) lcd.print("peak too short"); if (error_condition & E_TP_TOO_SHORT) lcd.print("peak too long"); } } void OvenCtl::control_oven() { if (temperature <= set_min + actual_hysteresis && !is_oven_heating) { is_oven_heating = true; // Serial.println("Oven turned on"); } else if (temperature >= set_min + actual_hysteresis && is_oven_heating) { is_oven_heating = false; } } void OvenCtl::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 OvenCtl::get_temp() { last_temperature = temperature; temperature = int(float(analogRead(2)) * 0.2929); actual_dt = float(temperature) - last_temperature; } void OvenCtl::check_dt() { if (disable_checks) return; if (actual_dt > set_dt_max) { error_condition |= E_DT_MAX; } if (actual_dt < set_dt_min) { error_condition |= E_DT_MIN; } }