How to re-start this subfuction each time? Switch case

Hi, Im struggling with this I got a temperature dependable program,to make complete bulletproof I need to re-start this machine each time is called, but just execute it once. I cant find a way to acomplish this.

This is the machine:

void refrigerationOFF(){ 

/*
This subrutine is intended to start the refrigeration cycle 
in a ladder way to prevent high current spikes on the lines
making the start easier by the release of the pressurized 
refrigerant. 

*/

  //  boolean refrigerattionOFFHasEnd = false;
    

    if(refrigerattionOFFHasEnd == false )             // if the refrigerattion has no ended properly 
        {                                          // re-statrt the FSM 

          Serial.println("Se ha reinciado la maquina de refrigeracion OFF");
          pascomOff = 0;
          compOff = 0;
          refrigerattionOFF = true;                  //enable the statrt of the FSM         
          refrigerattionOFFHasEnd = true;         //this var make refrigeration once  
        }


if ( refrigerattionOFF == true )                      //if there is the first time this is called 
{
    if( millis()- comOffTime  >= comOffDelay)      //take delay for each operation on FSTM
      {
      compOff ++; 
      comOffTime = millis(); 
      }

    if(compOff > pascomOff )
        {

          switch(compOff)
                { 
                 case 1: 
                        lcd.setCursor(0,0);  lcd.print(F("      FIN   DE      "));
                        lcd.setCursor(0,1);  lcd.print(F("    REFRIGERACION   ")); 
                        lcd.setCursor(0,2);  lcd.print(F("                    "));
                        break; 
  
                 case 2:
                        lcd.setCursor(0,0);  lcd.print(F("FIN DE REFRIGERACION"));
                        lcd.setCursor(0,1);  lcd.print(F("       APAGANDO     ")); 
                        lcd.setCursor(0,2);  lcd.print(F("      COMPRESOR     "));
                        digitalWrite(compressor, HIGH);
                        break; 
  
                 case 3: 
                        lcd.setCursor(0,0);  lcd.print(F("FIN DE REFRIGERACION"));
                        lcd.setCursor(0,1);  lcd.print(F("       APAGANDO     ")); 
                        lcd.setCursor(0,2);  lcd.print(F("        VENT"));
                        for( int c = 0; c < NumFans ; c++)
                           {    
                           digitalWrite(fanPins[c], HIGH);
                           lcd.setCursor(13,2);  lcd.print(c);
                           }
                        break; 
  
                case 5:
                      lcd.setCursor(0,0);  lcd.print(F("FIN DE REFRIGERACION"));
                      lcd.setCursor(0,1);  lcd.print(F("       APAGANDO     ")); 
                      lcd.setCursor(0,2);  lcd.print(F("      SOLENOIDE     "));
                      digitalWrite(solenoid, HIGH); 
                      break; 

                case 6:
                      lcd.setCursor(0,0);  lcd.print(F("                    "));
                      lcd.setCursor(0,1);  lcd.print(F("                    ")); 
                      lcd.setCursor(0,2);  lcd.print(F("                    "));

                      refrigerattionOFF = false;   //this var make refrigeration once
                      compOff = 0;             //byte to control the switch case statment 
                      pascomOff = 0;
                      //refrigerattionOFFHasEnd = true; //this cheks if the FSM has ended properly 
                      break;
        

      }   
    }
    }

}

This is the thermostat that call the subrutine:

if( temperature == highTemp)
        {
        refrigerationON();

Now... if for any reason (like error in the sensor reading) all will be off by;

if(rawTemp < -30.00) // if the sensor dont read 
     {
      temperature = error ;
      stopAll();

How to make the machine start over each time is called and just the firs time is called?

Ii was trying to use a local variable;

//  boolean refrigerattionOFFHasEnd = false;
    

    if(refrigerattionOFFHasEnd == false )             // if the refrigerattion has no ended properly 
        {                                          // re-statrt the FSM 

          Serial.println("Se ha reinciado la maquina de refrigeracion OFF");
          pascomOff = 0;
          compOff = 0;
          refrigerattionOFF = true;                  //enable the statrt of the FSM         
          refrigerattionOFFHasEnd = true;         //this var make refrigeration once  
        }

But dint work... each loop gets 0 and never executes the machine.
If I declare the same variable as global, there is no warranty the machine complete its task and get ready to next time.

I dont know the proper name but I need something like this;

void loop()
{//Pseudocode
if(temperature == high) refriON(); //this will be called many times 
}

refriON()
{

startrefri { //clears all the variables to the machine works properly each time the machine is called
but just do it for one time during the machine is runnign...}

It has to be local, for work each time the machine is called. Clear all the variables and prevent miss functions.

I was using a variable at the end of the switch case, but in errors the switch case will be interrupted and It wont be re-inicialized.

Is there a Way to call this... One time only during each start of the machine?

if(refrigerattionOFFHasEnd == false )             // if the refrigerattion has no ended properly 
        {                                          // re-statrt the FSM 

          Serial.println("Se ha reinciado la maquina de refrigeracion OFF");
          pascomOff = 0;
          compOff = 0;
          refrigerattionOFF = true;                  //enable the statrt of the FSM         
          refrigerattionOFFHasEnd = true;         //this var make refrigeration once  
        }

Just once but each time the machine has start... this is the last part and its getting omplicated.

Thanks.
-Alex.

It looks like you're using a state machine. It looks like maybe you need to wrap another state machine around that, to control the rules on when it attempts to start.

Can you draw the state diagram? A pencil sketch photographed with a smartphone is OK. Show us what you want the machine to do. It starts from "dead" off. What causes it to move out of that state into the next state? What causes it to move out of that state into the re-start state?

Yes ... in deed the program has several state machines and one big state machine...let me draw a diagram.

Im doing something like this;

if( refrigerattionON == true)
  {

      if( millis()- comOnTime  >= comOnDelay ) //increase counter in 1 each delay 
        {
           compOn ++; 
           comOnTime = millis(); 
        }

if(compOn > pascomOn ) //only once the new state it does something, 
      {
          switch(compOn)
              { 
              case 1: ...etc

             case 6:
                      lcd.setCursor(0,0);  lcd.print(F("                    "));
                      lcd.setCursor(0,1);  lcd.print(F("                    ")); 
                      lcd.setCursor(0,2);  lcd.print(F("                    "));

                      refrigerattionOFF = false;   //this var make refrigeration once
                      compOff = 0;             //byte to control the switch case statment 
                      pascomOff = 0;
                      //refrigerattionOFFHasEnd = true; //this cheks if the FSM has ended properly 
                      break;
        
//this is the termination and re-start but... if something interrups the code... dont launch again. 
Or I can put the  refrigerattionOFF = false; variable in the refrigeration stop machine, but I want to be able the fuction to do by itself. To prevent problems or erros.

Here is the simplest way I can think of draw this... @MorganS

I hope the diagram helps in something...

Imgur

Main problems are;
if any of the machines is started and interrupted by an error in the DS1820
Once the temperature reading becomes stable...
Must start from the begining.
And each function must do its job just once while is been called.

if (temp == HIGH) turnOnrefrigeration()

turnOnrefrigeration()
refrigerationstate = 0; //just once 
refrigerationstate++;
switch(refrigerattionstate) 
compresor ON
fan1 ON 
...fanX ON 
end refrigeration.

Hi,
The diagrams didn't take.
Can you post your complete sketch please.
If it is too big can you attach it to your post, your images may have to be attached as well.

Tom..... :slight_smile:

Well I will leave in here the complete code...

Must of it works just fine with two exceptions;

If there is an error the SM make strange things (like continue in the last step were they were)

The ventilation cyclefans subroutine dont enters, but it must be a minor problem with the termostat, Im more concern about make the code to operates clearly if there is an error on it.

Thanks for the help... I dont have much more ideas now.

The principal file is " tablero_tala_modificado_ultima_version.ino"
-Alex.

cycleFans.ino (5.87 KB)

stopAll.ino (374 Bytes)

tablero_tala_modificado_ultima_version.ino (6.81 KB)

tempReading.ino (3.37 KB)

thermostat.ino (1.59 KB)

turnOffCompressor.ino (3.25 KB)

turnOnRefrigeration.ino (3.4 KB)