//Sterilization Chamber => Tank 2, used for sterilizing the water // -> Handle the Sterilization Chamber and Post UV on storage // -> Dependency: water bank's float switch Low and High // chamber's float switch Low and High // storage's float switch Low and High #define CHAMBER_STATE_NONE 0 #define CHAMBER_STATE_IDLE 1 #define CHAMBER_STATE_START_FILLING 2 #define CHAMBER_STATE_CHECK_FILLING_TO_LOWER 3 #define CHAMBER_STATE_CHECK_FILLING_TO_UPPER 4 #define CHAMBER_STATE_STERILIZING 5 #define CHAMBER_STATE_START_UNLOAD 6 #define CHAMBER_STATE_START_UNLOAD_TO_LOWER 7 #define CHAMBER_STATE_START_UNLOAD_TO_UPPER 8 //uint32_t chamberSterilizationOzoneDuration = 1*60*1000; uint32_t chamberSterilizationUvDuration = 5*60*1000; //uint32_t chamberSterilizationPostUvDuration = 5*60*1000; uint32_t chamberExpectedTimeToFilledLower = 1*60*1000;//in mulliseconds uint32_t chamberExpectedTimeToFilledUpper = 3*60*1000;//in mulliseconds uint32_t chamberExpectedTimeToUnloadFilledLower = 1*60*1000;//in mulliseconds uint32_t chamberExpectedTimeToUnloadFilledUpper = 3*60*1000;//in mulliseconds uint32_t chamberTick = 0; bool chamberPostUvEnable = true; uint32_t chamberPostUvDuration = 1*60*1000; uint32_t chamberPostUvTick = 0; uint32_t chamberInverterStartupTick = 0; int chamberState = WATER_BANK_STATE_NONE; bool chamberAutomatic = false; #define CHAMBER_ERROR_NONE 0 #define CHAMBER_ERROR_LOWER_FLOAT_SWITCH 1 //lower switch error #define CHAMBER_ERROR_UPPER_FLOAT_SWITCH 2 //upper switch error #define CHAMBER_ERROR_UPPER_FLOAT_SWITCH_OR_NO_WATER 3 #define CHAMBER_ERROR_LOWER_FLOAT_SWITCH_OR_NO_WATER 4 #define CHAMBER_ERROR_STORAGE_LOWER_FLOAT_SWITCH 5 //lower switch error #define CHAMBER_ERROR_STORAGE_UPPER_FLOAT_SWITCH 6 //upper switch error #define CHAMBER_ERROR_STORAGE_UPPER_FLOAT_SWITCH_OR_NO_WATER 7 #define CHAMBER_ERROR_STORAGE_LOWER_FLOAT_SWITCH_OR_NO_WATER 8 #define CHAMBER_ERROR_TANK_LOWER_FLOAT_SWITCH 9 //lower switch error #define CHAMBER_ERROR_TANK_UPPER_FLOAT_SWITCH 10 //upper switch error #define CHAMBER_ERROR_TANK_UPPER_FLOAT_SWITCH_OR_NO_WATER 11 #define CHAMBER_ERROR_TANK_LOWER_FLOAT_SWITCH_OR_NO_WATER 12 #define CHAMBER_ERROR_LOWER_FLOAT_SWITCH_OR_LEAKED 13 bool chamberError = false; byte chamberErrorCode = CHAMBER_ERROR_NONE; String chamberErrorString = ""; //penampungan hasil sterilisasi (tank 3) bool chamber_SterilizedLowerFloatSwitchStateCurrent = false; bool chamber_SterilizedLowerFloatSwitchStatePrevious = false; bool chamber_SterilizedUpperFloatSwitchStateCurrent = false; bool chamber_SterilizedUpperFloatSwitchStatePrevious = false; //ruang sterilisasi bool chamber_SterilizationLowerFloatSwitchStateCurrent = false; bool chamber_SterilizationLowerFloatSwitchStatePrevious = false; bool chamber_SterilizationUpperFloatSwitchStateCurrent = false; bool chamber_SterilizationUpperFloatSwitchStatePrevious = false; //water tank sebelum sterilisasi bool chamber_TankLowerFloatSwitchStateCurrent = false; bool chamber_TankLowerFloatSwitchStatePrevious = false; bool chamber_TankUpperFloatSwitchStateCurrent = false; bool chamber_TankUpperFloatSwitchStatePrevious = false; bool chamberSterilizationSuccess = false; uint32_t GetSterilizationRemainingMillis(){ uint32_t t = 0; if (chamberState==CHAMBER_STATE_STERILIZING){ t = (chamberSterilizationOzoneDuration - (millis()-chamberTick)); if (t>chamberSterilizationOzoneDuration) t = 0; return t; } if (GetSwitchState(STERILIZED_UV_SWITCH)){ t = chamberPostUvDuration - (millis()-chamberPostUvTick); if (t>chamberPostUvDuration) t = 0; } return t; } bool OnOzoneStrelization(){ if (GetSwitchState(STERILIZATION_OZONE_AND_UV_SWITCH)) return true; return (chamberState==CHAMBER_STATE_STERILIZING); } bool OnPostUV(){ if (GetSwitchState(STERILIZED_UV_SWITCH)){ return true; } return false; } bool IsChamberFilling(){ return (chamberState>=CHAMBER_STATE_START_FILLING) && (chamberState<=CHAMBER_STATE_CHECK_FILLING_TO_UPPER); } bool IsChamberUnload(){ return (chamberState>=CHAMBER_STATE_START_UNLOAD) && (chamberState<=CHAMBER_STATE_START_UNLOAD_TO_UPPER); } bool ChamberIsSuccess(){ return chamberSterilizationSuccess; } bool ChamberIsError(){ return chamberError; } String ChamberErrorString(){ if (chamberError) return chamberErrorString; return ""; } bool ChamberIsIdle(){ return (chamberState==CHAMBER_STATE_IDLE) || (chamberState==WATER_BANK_STATE_NONE); } bool IsChamberSystemRunning(){ if (GetSwitchState(STERILIZATION_OZONE_AND_UV_SWITCH) || GetSwitchState(INVERTER_SWITCH)) return true; if (!chamberAutomatic) return (chamberState!=WATER_BANK_STATE_NONE); return (chamberState>CHAMBER_STATE_IDLE); } void ClearChamberError(){ chamberError = false; chamberErrorCode = CHAMBER_ERROR_NONE; chamberErrorString = ""; } void ChamberTurnOffAllSwitch(bool exceptInverterAndPostUv=true){ //make sure ozone, cycling pump, fill in pump, fill out pump, uv1, uv2 is off //inverter if (!exceptInverterAndPostUv){ if (GetSwitchState(INVERTER_SWITCH)){ Serial.println("ChamberSystemRoutine: INVERTER_SWITCH OFF"); SetSwitchState(INVERTER_SWITCH, false); } } //ozone if (GetSwitchState(STERILIZATION_OZONE_AND_UV_SWITCH)){ Serial.println("ChamberSystemRoutine: STERILIZATION_OZONE_AND_UV_SWITCH OFF"); SetSwitchState(STERILIZATION_OZONE_AND_UV_SWITCH, false); } //post uv if (!exceptInverterAndPostUv){ if (GetSwitchState(STERILIZED_UV_SWITCH)){ Serial.println("ChamberSystemRoutine: "); SetSwitchState(STERILIZED_UV_SWITCH, false); } } //fill in pump if (GetSwitchState(STERILIZATION_CHAMBER_FILL_PUMP_SWITCH)){ Serial.println("ChamberSystemRoutine: STERILIZATION_CHAMBER_FILL_PUMP_SWITCH OFF"); SetSwitchState(STERILIZATION_CHAMBER_FILL_PUMP_SWITCH, false); } //fill out pump if (GetSwitchState(STERILIZED_CHAMBER_FILL_PUMP_SWITCH)){ Serial.println("ChamberSystemRoutine: STERILIZED_CHAMBER_FILL_PUMP_SWITCH OFF"); SetSwitchState(STERILIZED_CHAMBER_FILL_PUMP_SWITCH, false); } //circulation pump if (GetSwitchState(STERILIZATION_CHAMBER_CIRCULATION_PUMP_SWITCH)){ Serial.println("ChamberSystemRoutine: STERILIZATION_CHAMBER_CIRCULATION_PUMP_SWITCH OFF"); SetSwitchState(STERILIZATION_CHAMBER_CIRCULATION_PUMP_SWITCH, false); } } //system running state ===================================================== void ChamberSystemRoutine(){ //handle the post uv timer independently ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ bool ctrlLowerSwitchState = GetInSwitchState(STERILIZED_CHAMBER_FLOAT_SWITCH_LOWER); if ((!ctrlLowerSwitchState) || ((GetSwitchState(STERILIZED_UV_SWITCH) && (millis()-chamberPostUvTick)>=chamberPostUvDuration)) || (!chamberPostUvEnable)){ if (GetSwitchState(STERILIZED_UV_SWITCH)){ Serial.println("ChamberSystemRoutine: "); SetSwitchState(STERILIZED_UV_SWITCH, false); } //if ((chamberState==CHAMBER_STATE_NONE) || (chamberState==CHAMBER_STATE_IDLE) || ((chamberState>=CHAMBER_STATE_START_FILLING) && (chamberState<=CHAMBER_STATE_START_FILLING_TO_UPPER))){ if (chamberState==CHAMBER_STATE_NONE){ //ChamberTurnOffAllSwitch(false);//turn off all }else if ((chamberState!=CHAMBER_STATE_NONE) && (chamberState!=CHAMBER_STATE_STERILIZING)){ SetSwitchState(STERILIZED_UV_SWITCH, false);//turn off post uv SetSwitchState(INVERTER_SWITCH, false);//turn off inverter //ChamberTurnOffAllSwitch(false);//turn off all } } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ switch(chamberState){ case CHAMBER_STATE_NONE:{ ChamberTurnOffAllSwitch(true); }; break; case CHAMBER_STATE_IDLE:{ //this is the state when use automatic mode ChamberTurnOffAllSwitch(true); //except inverter if post uv if running //in case mismatch, prevent auto monitoring if (!chamberAutomatic){ chamberState = CHAMBER_STATE_NONE; Serial.println("CHAMBER_STATE_IDLE -> CHAMBER_STATE_NONE"); } //trigger condition: // state => STORAGE_STATE_CHECK_IF_EMPTY: sterilized bank is empty chamber_SterilizedLowerFloatSwitchStateCurrent = GetInSwitchState(STERILIZED_CHAMBER_FLOAT_SWITCH_LOWER); bool intoFilling = false; if ((chamber_SterilizedLowerFloatSwitchStateCurrent!=chamber_SterilizedLowerFloatSwitchStatePrevious) && (!chamber_SterilizedLowerFloatSwitchStateCurrent)){ intoFilling = true; Serial.println("CHAMBER_STATE_IDLE -> Trigger reason: Storage empty"); } //storage kosong dan water tank menjadi penuh chamber_TankLowerFloatSwitchStateCurrent = GetInSwitchState(WATER_BANK_FLOAT_SWITCH_LOWER); chamber_TankUpperFloatSwitchStateCurrent = GetInSwitchState(WATER_BANK_FLOAT_SWITCH_UPPER); if (!chamber_SterilizedLowerFloatSwitchStateCurrent && (chamber_TankUpperFloatSwitchStateCurrent!=chamber_TankUpperFloatSwitchStatePrevious) && (chamber_TankUpperFloatSwitchStateCurrent && chamber_TankLowerFloatSwitchStateCurrent)){ intoFilling = true; //Serial.println("Tank baru penuh dan pemampungan sterilisasi kosong."); Serial.println("CHAMBER_STATE_IDLE -> Trigger reason: Storage empty and Water Tank just full"); } //update state chamber_SterilizedLowerFloatSwitchStatePrevious = chamber_SterilizedLowerFloatSwitchStateCurrent; chamber_TankLowerFloatSwitchStatePrevious = chamber_TankLowerFloatSwitchStateCurrent; chamber_TankUpperFloatSwitchStatePrevious = chamber_TankUpperFloatSwitchStateCurrent; if (intoFilling){ chamberSterilizationSuccess = false; ClearChamberError(); chamberState = CHAMBER_STATE_START_FILLING; Serial.println("CHAMBER_STATE_IDLE -> CHAMBER_STATE_START_FILLING"); } }; break; case CHAMBER_STATE_START_FILLING:{ chamberSterilizationSuccess = false; chamber_SterilizedLowerFloatSwitchStateCurrent = GetInSwitchState(STERILIZED_CHAMBER_FLOAT_SWITCH_LOWER); chamber_SterilizedUpperFloatSwitchStateCurrent = GetInSwitchState(STERILIZED_CHAMBER_FLOAT_SWITCH_UPPER); //cek error lain dari float switch: // -> storage switch upper lower harus benar // -> tank switch upper lower harus benar (water tank penuh) //cek penampungan harus kosong if (chamber_SterilizedLowerFloatSwitchStateCurrent){ //switch back to idle chamberError = true; chamberErrorString = "Penampungan harus kosong dahulu untuk memulai sterilisasi."; chamberState = CHAMBER_STATE_IDLE; Serial.print("Error: "); Serial.println(chamberErrorString); Serial.println("CHAMBER_STATE_START_FILLING -> CHAMBER_STATE_IDLE"); return; } //check if: full -> CHAMBER_STATE_STERILIZING // empty -> CHAMBER_STATE_CHECK_FILLING_TO_LOWER // lower -> CHAMBER_STATE_CHECK_FILLING_TO_UPPER //jika chamber penuh langsung ke sterilisasi chamber_SterilizationLowerFloatSwitchStateCurrent = GetInSwitchState(STERILIZATION_CHAMBER_FLOAT_SWITCH_LOWER); chamber_SterilizationUpperFloatSwitchStateCurrent = GetInSwitchState(STERILIZATION_CHAMBER_FLOAT_SWITCH_UPPER); if (chamber_SterilizationLowerFloatSwitchStateCurrent && chamber_SterilizationUpperFloatSwitchStateCurrent){ chamberTick = millis(); chamberState = CHAMBER_STATE_STERILIZING; Serial.println("Sterilization chamber already full."); Serial.println("CHAMBER_STATE_START_FILLING -> CHAMBER_STATE_STERILIZING"); return; } chamber_TankLowerFloatSwitchStateCurrent = GetInSwitchState(WATER_BANK_FLOAT_SWITCH_LOWER); chamber_TankUpperFloatSwitchStateCurrent = GetInSwitchState(WATER_BANK_FLOAT_SWITCH_UPPER); Serial.print("Water Tank lower float switch: "); Serial.println(chamber_TankLowerFloatSwitchStateCurrent); Serial.print("Water Tank upper float switch: "); Serial.println(chamber_TankUpperFloatSwitchStateCurrent); //tank penampung harus penuh dulu baru mau dong if (chamber_TankLowerFloatSwitchStateCurrent && chamber_TankUpperFloatSwitchStateCurrent){ //cek jika chamber kosong total if (!chamber_SterilizationLowerFloatSwitchStateCurrent && !chamber_SterilizationUpperFloatSwitchStateCurrent){ //kosong total chamberTick = millis(); chamberState = CHAMBER_STATE_CHECK_FILLING_TO_LOWER; Serial.println("CHAMBER_STATE_START_FILLING -> CHAMBER_STATE_CHECK_FILLING_TO_LOWER"); }else if (chamber_SterilizationLowerFloatSwitchStateCurrent && !chamber_SterilizationUpperFloatSwitchStateCurrent){ //ada sedikit, mayan chamberTick = millis(); chamberState = CHAMBER_STATE_CHECK_FILLING_TO_UPPER; Serial.println("CHAMBER_STATE_START_FILLING -> CHAMBER_STATE_CHECK_FILLING_TO_UPPER"); }else{ //float switch error ini hadeh chamberError = true; chamberErrorString = "Float switch sterilisasi error."; chamberState = CHAMBER_STATE_IDLE; Serial.print("Error: "); Serial.println(chamberErrorString); Serial.println("CHAMBER_STATE_START_FILLING -> CHAMBER_STATE_IDLE"); return; } }else{ chamberError = true; chamberErrorString = "Tangki penampung air harus penuh dahulu untuk dapat memulai pengisian tangki sterilisasi."; Serial.print("Error: "); Serial.println(chamberErrorString); if (chamberAutomatic){ chamberState = CHAMBER_STATE_IDLE; Serial.println("CHAMBER_STATE_START_FILLING -> CHAMBER_STATE_IDLE"); }else{ chamberState = CHAMBER_STATE_NONE; Serial.println("CHAMBER_STATE_START_FILLING -> CHAMBER_STATE_NONE"); } return; } }; break; case CHAMBER_STATE_CHECK_FILLING_TO_LOWER:{ //waiting for filling into lower level, or stop when timeout //switch on the pump if (!GetSwitchState(STERILIZATION_CHAMBER_FILL_PUMP_SWITCH)){ Serial.println("ChamberSystemRoutine: TURN ON FILL PUMP SWITCH"); SetSwitchState(STERILIZATION_CHAMBER_FILL_PUMP_SWITCH, true); } //monitoring water level or timed out bool lowerSwitchState = GetInSwitchState(STERILIZATION_CHAMBER_FLOAT_SWITCH_LOWER); bool upperSwitchState = GetInSwitchState(STERILIZATION_CHAMBER_FLOAT_SWITCH_UPPER); //chamber_TankLowerFloatSwitchStateCurrent = GetInSwitchState(WATER_BANK_FLOAT_SWITCH_LOWER); //if (lowerSwitchState || upperSwitchState || !chamber_TankLowerFloatSwitchStateCurrent){ if (lowerSwitchState || upperSwitchState){ //check if lower float switch on //try to fill till full ClearChamberError(); chamberTick = millis(); chamberState = CHAMBER_STATE_CHECK_FILLING_TO_UPPER; Serial.println("CHAMBER_STATE_CHECK_FILLING_TO_LOWER -> CHAMBER_STATE_CHECK_FILLING_TO_UPPER"); }else{ //check if timed out if (millis()-chamberTick>=chamberExpectedTimeToFilledLower){ chamberError = true; chamberErrorCode = CHAMBER_ERROR_LOWER_FLOAT_SWITCH; chamberErrorString = "Tank 2 insufficient input water, or lower float switch error, or input pump error."; Serial.println("Chamber Error -> CHAMBER_ERROR_LOWER_FLOAT_SWITCH"); if (chamberAutomatic){ chamberState = CHAMBER_STATE_IDLE; Serial.println("CHAMBER_STATE_CHECK_FILLING_TO_LOWER -> CHAMBER_STATE_IDLE"); }else{ chamberState = CHAMBER_STATE_NONE; Serial.println("CHAMBER_STATE_CHECK_FILLING_TO_LOWER -> CHAMBER_STATE_NONE"); } } } }; break; case CHAMBER_STATE_CHECK_FILLING_TO_UPPER:{ //waiting for filling into lower level, or stop when timeout //switch on the pump if (!GetSwitchState(STERILIZATION_CHAMBER_FILL_PUMP_SWITCH)){ Serial.println("ChamberSystemRoutine: TURN ON FILL PUMP SWITCH"); SetSwitchState(STERILIZATION_CHAMBER_FILL_PUMP_SWITCH, true); } //monitoring water level or timed out bool upperSwitchState = GetInSwitchState(STERILIZATION_CHAMBER_FLOAT_SWITCH_UPPER); chamber_TankLowerFloatSwitchStateCurrent = GetInSwitchState(WATER_BANK_FLOAT_SWITCH_LOWER); if (upperSwitchState || (!chamber_TankLowerFloatSwitchStateCurrent)){ //check if upper float switch on or chamber's water below switch SetSwitchState(STERILIZATION_CHAMBER_FILL_PUMP_SWITCH, false); //matiin pompa ClearChamberError(); chamberTick = millis(); chamberState = CHAMBER_STATE_STERILIZING; Serial.println("CHAMBER_STATE_CHECK_FILLING_TO_UPPER -> CHAMBER_STATE_STERILIZING"); }else{ //check if timed out if (millis()-chamberTick>=chamberExpectedTimeToFilledUpper){ SetSwitchState(STERILIZATION_CHAMBER_FILL_PUMP_SWITCH, false); //matiin pompa chamberError = true; chamberErrorCode = CHAMBER_ERROR_UPPER_FLOAT_SWITCH; chamberErrorString = "Tank 2 insufficient input water, or upper float switch error, or input pump error."; Serial.println("Chamber Error -> CHAMBER_ERROR_UPPER_FLOAT_SWITCH"); if (chamberAutomatic){ chamberState = CHAMBER_STATE_IDLE; Serial.println("CHAMBER_STATE_CHECK_FILLING_TO_UPPER -> CHAMBER_STATE_IDLE"); }else{ chamberState = CHAMBER_STATE_NONE; Serial.println("CHAMBER_STATE_CHECK_FILLING_TO_UPPER -> CHAMBER_STATE_NONE"); } } } }; break; case CHAMBER_STATE_STERILIZING:{ //make sure turn off filling in and filling out pump if (GetSwitchState(STERILIZATION_CHAMBER_FILL_PUMP_SWITCH)) SetSwitchState(STERILIZATION_CHAMBER_FILL_PUMP_SWITCH, false); if (GetSwitchState(STERILIZED_CHAMBER_FILL_PUMP_SWITCH)) SetSwitchState(STERILIZED_CHAMBER_FILL_PUMP_SWITCH, false); //if inverter not turned -> switch it first, but wait for 2 seconds if (!GetSwitchState(INVERTER_SWITCH)){ //make sure turn off ozone and circulation if (GetSwitchState(STERILIZATION_OZONE_AND_UV_SWITCH)) SetSwitchState(STERILIZATION_OZONE_AND_UV_SWITCH, false); if (GetSwitchState(STERILIZATION_CHAMBER_CIRCULATION_PUMP_SWITCH)) SetSwitchState(STERILIZATION_CHAMBER_CIRCULATION_PUMP_SWITCH, false); chamberInverterStartupTick = millis(); SetSwitchState(INVERTER_SWITCH, true); Serial.println("Starting up the inveter."); return; }else{ if ((millis()-chamberInverterStartupTick)<2000){ chamberTick = millis(); //keep reset it return; } } //turn on ozone and circulation pump if (!GetSwitchState(STERILIZATION_OZONE_AND_UV_SWITCH)) SetSwitchState(STERILIZATION_OZONE_AND_UV_SWITCH, true); if (!GetSwitchState(STERILIZATION_CHAMBER_CIRCULATION_PUMP_SWITCH)) SetSwitchState(STERILIZATION_CHAMBER_CIRCULATION_PUMP_SWITCH, true); //wait till done, or if water is empty by accident (leaking) => back to idle with error state bool lowerSwitchState = GetInSwitchState(STERILIZATION_CHAMBER_FLOAT_SWITCH_LOWER); if (!lowerSwitchState){ //wah error atau bocor nih ChamberTurnOffAllSwitch(false); //turn off all switch including inverter chamberError = true; chamberErrorCode = CHAMBER_ERROR_LOWER_FLOAT_SWITCH_OR_LEAKED; chamberErrorString = "Tank 2 leaked, or lower float switch error"; Serial.print("Error: "); Serial.println(chamberErrorString);; chamberState = CHAMBER_STATE_NONE; Serial.println("CHAMBER_STATE_STERILIZING -> CHAMBER_STATE_NONE"); return; } //tunggu hingga selesai sterilisasi if ((millis()-chamberTick)>=chamberSterilizationOzoneDuration){ chamberPostUvTick = millis();//reset uv post tick too bool keepInverter = chamberPostUvEnable && (chamberPostUvDuration>0); ChamberTurnOffAllSwitch(keepInverter); chamberTick = millis(); //keep reset it chamberState = CHAMBER_STATE_START_UNLOAD; Serial.println("CHAMBER_STATE_STERILIZING -> CHAMBER_STATE_START_UNLOAD"); } }; break; case CHAMBER_STATE_START_UNLOAD:{ bool lowerSwitchState = GetInSwitchState(STERILIZED_CHAMBER_FLOAT_SWITCH_LOWER); bool upperSwitchState = GetInSwitchState(STERILIZED_CHAMBER_FLOAT_SWITCH_LOWER); chamberTick = millis(); //reset it if (!lowerSwitchState && !upperSwitchState){ //fill to lower first chamberState = CHAMBER_STATE_START_UNLOAD_TO_LOWER; Serial.println("CHAMBER_STATE_START_UNLOAD -> CHAMBER_STATE_START_UNLOAD_TO_LOWER"); }else if (lowerSwitchState && !upperSwitchState){ //fill to upper chamberState = CHAMBER_STATE_START_UNLOAD_TO_UPPER; Serial.println("CHAMBER_STATE_START_UNLOAD -> CHAMBER_STATE_START_UNLOAD_TO_UPPER"); }else if (lowerSwitchState && upperSwitchState){ //already full ChamberTurnOffAllSwitch(false); //turn off all switch including inverter if (chamberAutomatic){ chamberState = CHAMBER_STATE_IDLE; Serial.println("CHAMBER_STATE_START_UNLOAD -> CHAMBER_STATE_IDLE"); }else{ chamberState = CHAMBER_STATE_NONE; Serial.println("CHAMBER_STATE_START_UNLOAD -> CHAMBER_STATE_NONE"); } chamberSterilizationSuccess = true; }else{ //float switch error ChamberTurnOffAllSwitch(false); //turn off all switch including inverter chamberError = true; chamberErrorCode = CHAMBER_ERROR_STORAGE_LOWER_FLOAT_SWITCH; chamberErrorString = "Tank 3 float switch error"; Serial.print("Error: "); Serial.println(chamberErrorString);; chamberState = CHAMBER_STATE_NONE; Serial.println("CHAMBER_STATE_START_UNLOAD -> CHAMBER_STATE_NONE"); return; } //switch post uv when it reach at least lowest level and used if (chamberPostUvEnable && lowerSwitchState){ chamberPostUvTick = millis();//reset uv post tick too if (chamberPostUvEnable && (chamberPostUvDuration>0)){ //turn on uv SetSwitchState(STERILIZED_UV_SWITCH, true); } } }; break; case CHAMBER_STATE_START_UNLOAD_TO_LOWER:{ //switch on the pump if (!GetSwitchState(STERILIZED_CHAMBER_FILL_PUMP_SWITCH)){ Serial.println("ChamberSystemRoutine: TURN ON OUT PUMP SWITCH"); SetSwitchState(STERILIZED_CHAMBER_FILL_PUMP_SWITCH, true); } bool lowerSwitchState = GetInSwitchState(STERILIZED_CHAMBER_FLOAT_SWITCH_LOWER); bool upperSwitchState = GetInSwitchState(STERILIZED_CHAMBER_FLOAT_SWITCH_UPPER); if (lowerSwitchState || upperSwitchState){ //check if lower float switch on //try to fill till full ClearChamberError(); chamberTick = millis(); chamberState = CHAMBER_STATE_START_UNLOAD_TO_UPPER; Serial.println("CHAMBER_STATE_START_UNLOAD_TO_LOWER -> CHAMBER_STATE_START_UNLOAD_TO_UPPER"); }else{ //check if timed out if (millis()-chamberTick>=chamberExpectedTimeToUnloadFilledLower){ ChamberTurnOffAllSwitch(false); //turn off all switch including inverter chamberError = true; chamberErrorCode = CHAMBER_ERROR_STORAGE_LOWER_FLOAT_SWITCH_OR_NO_WATER; chamberErrorString = "Tank 2 leaked, or Tank 3 lower float switch error, or output pump error."; Serial.println("Chamber Error -> CHAMBER_ERROR_STORAGE_LOWER_FLOAT_SWITCH_OR_NO_WATER"); if (chamberAutomatic){ chamberState = CHAMBER_STATE_IDLE; Serial.println("CHAMBER_STATE_CHECK_FILLING_TO_LOWER -> CHAMBER_STATE_IDLE"); }else{ chamberState = CHAMBER_STATE_NONE; Serial.println("CHAMBER_STATE_CHECK_FILLING_TO_LOWER -> CHAMBER_STATE_NONE"); } return; } //check if tank 2 empty. indicate leaking chamber_SterilizationLowerFloatSwitchStateCurrent = GetInSwitchState(STERILIZATION_CHAMBER_FLOAT_SWITCH_LOWER); if (!chamber_SterilizationLowerFloatSwitchStateCurrent){ ChamberTurnOffAllSwitch(false); //turn off all switch including inverter chamberError = true; chamberErrorCode = CHAMBER_ERROR_LOWER_FLOAT_SWITCH; chamberErrorString = "Tank 2 leaked or lower float switch error"; Serial.println("Chamber Error -> CHAMBER_ERROR_LOWER_FLOAT_SWITCH"); if (chamberAutomatic){ chamberState = CHAMBER_STATE_IDLE; Serial.println("CHAMBER_STATE_CHECK_FILLING_TO_LOWER -> CHAMBER_STATE_IDLE"); }else{ chamberState = CHAMBER_STATE_NONE; Serial.println("CHAMBER_STATE_CHECK_FILLING_TO_LOWER -> CHAMBER_STATE_NONE"); } return; } } //manage post uv if (chamberPostUvEnable && lowerSwitchState){ chamberPostUvTick = millis();//reset uv post tick too if (chamberPostUvEnable && (chamberPostUvDuration>0)){ //turn on uv SetSwitchState(STERILIZED_UV_SWITCH, true); } } }; break; case CHAMBER_STATE_START_UNLOAD_TO_UPPER:{ //switch on the pump if (!GetSwitchState(STERILIZED_CHAMBER_FILL_PUMP_SWITCH)){ Serial.println("ChamberSystemRoutine: TURN ON OUT PUMP SWITCH"); SetSwitchState(STERILIZED_CHAMBER_FILL_PUMP_SWITCH, true); } //manage post uv bool lowerSwitchState = GetInSwitchState(STERILIZED_CHAMBER_FLOAT_SWITCH_LOWER); if (chamberPostUvEnable && lowerSwitchState){ if (chamberPostUvEnable && (chamberPostUvDuration>0) && (!GetSwitchState(STERILIZED_UV_SWITCH) && (millis()-chamberPostUvTick CHAMBER_STATE_IDLE"); }else{ chamberState = CHAMBER_STATE_NONE; Serial.println("CHAMBER_STATE_START_UNLOAD_TO_UPPER -> CHAMBER_STATE_NONE"); } }else{ //check if timed out if (millis()-chamberTick>=chamberExpectedTimeToUnloadFilledUpper){ ChamberTurnOffAllSwitch(false); //turn off all switch including inverter chamberError = true; chamberErrorCode = CHAMBER_ERROR_STORAGE_UPPER_FLOAT_SWITCH_OR_NO_WATER; chamberErrorString = "Tank 2 leaked, or Tank 1 upper float switch error, or output pump error."; Serial.println("Chamber Error -> CHAMBER_ERROR_STORAGE_UPPER_FLOAT_SWITCH_OR_NO_WATER"); if (chamberAutomatic){ chamberState = CHAMBER_STATE_IDLE; Serial.println("CHAMBER_STATE_CHECK_FILLING_TO_UPPER -> CHAMBER_STATE_IDLE"); }else{ chamberState = CHAMBER_STATE_NONE; Serial.println("CHAMBER_STATE_CHECK_FILLING_TO_UPPER -> CHAMBER_STATE_NONE"); } return; } } }; break; } } //========================================================================== void StartChamberSystem(bool automatic, bool forceRunIfAutomatic = false, bool usePostUv=false){ ClearChamberError(); chamberAutomatic = automatic; chamberPostUvEnable = usePostUv; chamberSterilizationSuccess = false; bool runNow = false; if (chamberAutomatic){ RefreshInSwitchState(); chamberState = CHAMBER_STATE_IDLE; runNow = forceRunIfAutomatic; if (!runNow) Serial.println("StartChamberSystem -> CHAMBER_STATE_IDLE"); }else{ runNow = true; } if (runNow){ RefreshInSwitchState(); chamberState = CHAMBER_STATE_START_FILLING; Serial.println("StartChamberSystem -> CHAMBER_STATE_START_FILLING"); } } void StopChamberSystem(){ ClearChamberError(); chamberState = CHAMBER_STATE_NONE; ChamberSystemRoutine(); //call it once ChamberTurnOffAllSwitch(false);//make sure to turn off all } void ChamberSetPostUvDuration(uint32_t v){ chamberPostUvDuration = v; } void ChamberSetSterlizationDuration(uint32_t v){ chamberSterilizationOzoneDuration = v; }