#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; // thermostat set_min = 0; set_max = 0; set_dt_min = 0; set_dt_max = 0; oven_mode = OM_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::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_remote_cmd(COMMAND cmd) { switch (cmd) { case SEND_CONFIG: send_config(); break; case RECV_CONFIG: recv_config(); break; case SEND_STATE: recv_config(); break; case RECV_STEPS: break; default: ; } } 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 (oven_mode) { case OM_CONFIG: // if (profile.handle_config_state()) // set_start_state(); break; case OM_CALIBRATION: break; case OM_STAND_ALONE: // if (profile.handle_config_state()) // set_start_state(); // break; case OM_REMOTE: // if (profile.handle_config_state()) // set_start_state(); break; } // if (error_condition != 0) { // set_error_state(); // } // else if (cmd == 251) // set_start_state(); control_oven(); if (oven_mode != OM_CONFIG) { 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 (is_oven_heating) { if (temperature >= set_min + actual_hysteresis) { is_oven_heating = false; } } else { if (temperature <= set_min + actual_hysteresis) { is_oven_heating = true; } } } 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; } }