Hi everybody,
this is my first comment/question in this forum an more important, my first programming Project and my english is not perfect, so please be patient. If the project hub is more suitible, please let me know.
"The big picture":
I´m working on a controll-unit for a mobile heating system since 3 weeks. Until now the heater is controlled manually, this causes serveral problems. Like all mobile heaters or engines with diesel, it needs a propper preheating phase. If the delays are not taken into account correctly while heating up manually, the combustion chamber is fast filled with to much diesel und it smokes like engines 100 years ago... So I need a propper and stable System.
"Why do I need youre help / input:"
As I mentioned, my programming skills are very rudimentary. I try to learn as much as possible about the basics, like loops, hardware, const and variables. But it terms of programm-architecture (failsafe) and efficiency, I would be more then happy to get some feedback from experts. FOr example I´m wondering how it´s possible to implement a countdown in a for loop, wich is part of a state.
"Functions"
On / Off (debounced with millis() ) // if button pressed change Variable "mainSwitchInt" between 0 / 1
Automatic Preheating Phase{
if combustion chamber is cold{
- Fan on
- wait 4 sec
if delayButton is pressed put the the countdown on hold for manual intervention - Preheater on
- wait 10 sec und show countdown an display
if delayButton is pressed put the the countdown on hold for manual intervention - Magnetic Valve Diesel on
- wait 10 sec und show countdown an display
if delayButton is pressed put the the countdown on hold for manual intervention
}
if combustion chamber hot go to state HEATING
else (it is cold) go to state ERROR
} // Preheating Phase end
"Test build":
For testing i connected a Arduino Uno with 6 LEDs, 3 buttons, 1 switch and a 16x2 display on a breadboard.
const int FAN_LED = 2; // displays aktive fan
const int DIESEL_LED = 3; // display open magnetic valve for DIESEL
const int PREHEATING_LED = 4; // displays aktive preheater
const int HEATING_LED = 5; // displays case HEATING
const int ERROR_LED =6; // desplay ERROR (blinking)
const int AKTIVE_LED = 7; // displays CPU-Activity
const int MAIN_SWITCH = 12; // On / Off Main switch
const int RESET = 11; // Softwarereset (go to case OFF)
const int TEMP_SENSOR = 13; // displays combustion chamber = hot
const int DELAY_MAIN_SWITCH = 10; // if switch is aktive, preheatingphases
// are on hold for manual intervention
The next important Part was how to organize the different states like On, Off, Preheating, Heating, Error.
I used a Statemachine with some advantages und disadvantages. The main problem I have, is the architecture of Statemachines. As I understood they only go once in the State, if there is a impulse set a StateChange. In my case it is due to the if conditions, you will see below...
// Lists of States
enum State {OFF, PREHEATING, HEATING, SHUT_DOWN, ERROR};
State currentState;
State lastState = OFF;
And then in the void loop i started to organize the states via if conditions:
///////////////////////////////////////
//// ERROR STATES ////
///////////////////////////////////////
// Diesel empty or comustion Chamber cold (during case == HEATING)
if (currentState == HEATING && cold) {
lcd.setCursor(0,1); //
lcd.print(" ");
lcd.setCursor(0,1);
lcd.print("Temp / Diesel ?");
currentState = ERROR;}
// if RESET_BUTTON is presset, go to case == OFF
if (currentState == ERROR && reset){currentState = OFF; mainSwitchInt = 0;}
///////////////////////////////////////
//// OPERATING STATES ////
///////////////////////////////////////
if(mainSwitchInt == 1) {
if (currentState == OFF && (cold || hot)) {currentState = PREHEATING;}
if (currentState == SHUT_DOWN) {mainSwitchInt = 0;}
}
if(mainSwitchInt == 0) {
if(currentState == PREHEATING) {currentState = OFF;}
if(currentState == HEATING && hot) {currentState = SHUT_DOWN;}
if(currentState == SHUT_DOWN && cold) {currentState = OFF;}
}
///////////////////////////////////////
//// CPU-AKTIVITY-Test ////
///////////////////////////////////////
// diplays the CPU-AKTIVITY
if (currentState != ERROR){
if(millis() >= (resetTime + betriebsDelay)) {
resetTime = millis();
if(digitalRead(AKTIVE_LED) == LOW){digitalWrite(AKTIVE_LED, HIGH);}
else{digitalWrite(AKTIVE_LED, LOW);}
}
}
else{
digitalWrite(AKTIVE_LED, LOW);
}
And now the states themselves:
///////////////////////////////////////
//// STATEMACHINE ////
///////////////////////////////////////
// State-Change, if Main switch changes between 0 || 1
if(currentState != lastState){
lastState = currentState;
switch(currentState) {
case OFF:
//easy LED stuff
break;
case PREHEATING:
// see "Functions" above
break;
case HEATING:
//easy LED stuff
break;
case SHUT_DOWN:
//easy LED stuff
break;
case ERROR:
//easy LED stuff
break;
The problem I have is the state PREHEATING, because of the need of waiting loops with abort conditions if comustion chamber is hot. I tried to use millis(), but wasn´t succsessfull. I managed to get it working with for loops.
I try to attache the whole file. If it´s not working You will find it on github:
Thank you for new input, thoughts and Ideas, especially for the quite complex PREHEATING state!
Cheers