Problem finding issue.

Hello Arduino forum friends.

I’m having a bit of an issue finding the problem in my code. The code is for a pool solar heater with bypass system. When the solar temp is above pool temp the pump shots off and the water valve is set to feed the solar heater and heat the pool. When the solar heater temp goes equal or below pool temp the valve bypasses the solar heater.

How it currently preforms.
During power up when pool is warmer then solar regardless of valve position. Valve locates to bypass followed by activating the pump. If then solar temp increases above the pool the system switches over to solar. All good up to now. If temp switches again having the pool warmer the system doesn’t do anything though it shows up in serial that the code is in bypass while loop. By cycling power the system switches over and works until it’s back in solar position where it freezes again.

/*
 * 0 deg C = 24Kohm = value 182
 * 100deg C = 1kohm = value 890
 */


volatile int Manual_Auto_ByPass_Switch = 3; //Bypass switch. Auto manual control. LED indicating if bypass switch is ON
volatile int Manual_Switch_Vlv_Moto = 4;    //Push button to rotate valve to next indicator position. Bypass solar or solar
volatile int Manual_Switch_Pump_Moto = 7;   //Togle switch to manually activate pump
int SolPos = 5;                             //Valve positio sensor Set to solar pool heater
int BypassPos = 6;                          //Valve positio sensor Set to solar bypass 
int pump = 9;                               //Turns on pool pump
int vlvmotor = 10;                          //Turns on motor to change valve position
int poolTmp = A0;                           //Pool temp sensor (analog input). 1-23kohm thermistor with 5kohm resistor
int solTmp = A1;                            //Solar temp sensor (analog input). 1-23kohm thermistor with 5kohm resistor
int poolADJ = A2;                           // Pot to adjust pool temp. 10kohm
int solADJ = A3;                            // Pot to adjust solar temp. 10kohm

volatile float solTmpVal = 0;               //Stored value of solar temp
volatile float poolTmpVal = 0;              //Stored value of pool temp
int SolPosVal;                              //Stored value of valve solar pos
int BypassPosVal;                           //Stored value of bypass solar pos
int Manual_Auto_ByPass_Switch_Value;        //Stored value of bypass switch
int Manual_Vlv_Motor_Value;                 //Stored value for manual ON/OFF of valve motor
int Manual_Pump_Moto_Value;                 //Stored value for manual ON/OFF of pool pump


void setup()
{
  Serial.begin(9600);
  pinMode(Manual_Auto_ByPass_Switch, INPUT);
  pinMode(Manual_Switch_Vlv_Moto, INPUT);
  pinMode(Manual_Switch_Pump_Moto, INPUT);
  pinMode(poolADJ, INPUT);
  pinMode(solADJ, INPUT);
  pinMode(SolPos, INPUT);
  pinMode(BypassPos, INPUT);
  pinMode(pump, OUTPUT);
  pinMode(vlvmotor, OUTPUT);
  pinMode(poolTmp, INPUT);
  pinMode(solTmp, INPUT);
  digitalWrite(vlvmotor, LOW);
  digitalWrite(pump, LOW);
  int readtemp(const int);
  attachInterrupt(digitalPinToInterrupt(Manual_Auto_ByPass_Switch), ManualMode, HIGH);
}
void loop()
{
  solTmpVal = readtemp(solTmp,solADJ);                          //read temp of solar
  poolTmpVal = readtemp(poolTmp,poolADJ);                       //read temp of pool
  Serial.print(" Sol "); Serial.print(solTmpVal); Serial.print(" pool "); Serial.print(poolTmpVal); 
  
  while (solTmpVal > poolTmpVal)                                //when solar temp is higher then pool by 1deg start loop
  {
    Serial.println(" SolarON ");
    SolPosVal = digitalRead(SolPos);                            //read position of solar bypass valve and store in vlvHstr
    while (SolPosVal != HIGH)                                   //while(SolPosVal != HIGH)  
    {
      Serial.println(" SolarValveON ");
      digitalWrite(pump, LOW);
      digitalWrite(vlvmotor, HIGH);
      SolPosVal = digitalRead(SolPos);                          //read position of solar bypass valve and store in vlvHstr
    }
    //for (int a=0;a<=20;a++)digitalWrite(vlvmotor, LOW);
    //for (int a=0;a<=20;a++)digitalWrite(pump, HIGH);
    digitalWrite(vlvmotor, LOW);
    digitalWrite(pump, HIGH);
    
    delay(500);   
    solTmpVal = readtemp(solTmp,solADJ);                        //read temp of solar
    poolTmpVal = readtemp(poolTmp,poolADJ);                     //read temp of pool
    Serial.print(" Sol ");  Serial.print(solTmpVal);  Serial.print(" pool "); Serial.print(poolTmpVal);
  }

  while (poolTmpVal >= solTmpVal)                               //when solar temp is higher then pool by 1deg start loop
  {
    Serial.println(" SolarOFF ");
    SolPosVal = digitalRead(SolPos);                            //read position of solar bypass valve and store in vlvHstr
    while (BypassPosVal != HIGH)
    {
      Serial.println(" BypassValveON ");
      digitalWrite(pump, LOW);
      digitalWrite(vlvmotor, HIGH);
      BypassPosVal = digitalRead(BypassPos);                    //read position of solar bypass valve and store in vlvBstr
    }
    digitalWrite(vlvmotor, LOW);
    digitalWrite(pump, HIGH);
    //for (int a=0;a<=20;a++)digitalWrite(vlvmotor, LOW);
    //for (int a=0;a<=20;a++)digitalWrite(pump, HIGH);
    delay(500);
    solTmpVal = readtemp(solTmp, solADJ);                       //read temp of solar
    poolTmpVal = readtemp(poolTmp, poolADJ);                    //read temp of pool
    Serial.print(" Sol ");  Serial.print(solTmpVal);  Serial.print(" pool "); Serial.print(poolTmpVal);
  }
}
float readtemp(int temp,int adj)
{
  float tempADJ= map(analogRead(adj),0,1023,-20.0,20.0);
  float y;
  float z;
  for (int x = 0; x <= 2000 ; x++)
  {
    y=map(analogRead(temp),182,890,0.0,100.0);
    z += y;
  }
  z = z / 2000;
  z=z+tempADJ;
  return z;
}

void ManualMode()
{
  digitalWrite(pump, LOW);
  digitalWrite(vlvmotor, LOW);
  Manual_Auto_ByPass_Switch_Value = digitalRead(Manual_Auto_ByPass_Switch);
  while (Manual_Auto_ByPass_Switch_Value == HIGH)
  {
    Manual_Vlv_Motor_Value = digitalRead(Manual_Switch_Vlv_Moto);
    Manual_Pump_Moto_Value = digitalRead(Manual_Switch_Pump_Moto);
    SolPosVal = digitalRead(SolPos);                            //read position of solar bypass valve and store in vlvHstr
    BypassPosVal = digitalRead(BypassPos);
    if (Manual_Vlv_Motor_Value == HIGH)
    {
      digitalWrite(vlvmotor, HIGH);
      delay(10);
      while ((SolPosVal != HIGH) &&  (BypassPosVal != HIGH))
      {
        digitalWrite(vlvmotor, HIGH);
        SolPosVal = digitalRead(SolPos);                        //read position of solar bypass valve and store in vlvHstr
        BypassPosVal = digitalRead(BypassPos);
      }
      digitalWrite(vlvmotor, LOW);
    }
    if (Manual_Pump_Moto_Value == HIGH) 
    {
      digitalWrite(pump, HIGH);
      solTmpVal = readtemp(solTmp,solADJ);                      //read temp of solar
      poolTmpVal = readtemp(poolTmp,poolADJ);                   //read temp of pool
      Serial.print(" Sol "); Serial.print(solTmpVal); Serial.print(" pool "); Serial.println(poolTmpVal); 
    }
    else digitalWrite(pump, LOW);
    Manual_Auto_ByPass_Switch_Value = digitalRead(Manual_Auto_ByPass_Switch);
  }
}

I appreciate any suggestions in fixing this.

I don't understand your confusing explanation of the problem, but I looked a bit through the code. I stopped when I encountered this statement:

 attachInterrupt(digitalPinToInterrupt(Manual_Auto_ByPass_Switch), ManualMode, HIGH);
  1. It is poor programming practice to use interrupts to read switches. Doing so creates more problems than it solves.

  2. Especially, do NOT use an interrupt that continually interrupts your program when the switch input is HIGH.

  3. Your program freezes because you are trying to print from within an interrupt routine. Printing requires interrupts, which are turned off when executing an interrupt. See what I mean?

  4. Learn to program without using delay(). Use millis() instead -- great tutorial here: https://www.gammon.com.au/blink

Nothing happens so fast in a water heating system that an interrupt is needed to detect it. Polling (i.e. checking the switch on each iteration of loop() ) will be sufficient and make the code very much simpler.

Have a look at how the switch works in the demo Several Things at a Time

Have a look at how the code is organized. Note how each function runs very briefly and returns to loop() so the next one can be called. None of the functions tries to complete a task in one call. And there may be dozens of calls to a function before it is actually time for it to do anything.

Note, also, that WHILE and FOR loops also block the Arduino and should generally only be used when they complete within about 1 millisec.

...R

Thanks for the help guys.

Firstly, I found the problem. I had SolPosVal = digitalRead(SolPos);instead of BypassPosVal = digitalRead(BypassPos); in the second loop. This seems to have solved the problem.

Delays(). Yes I know it’s best not to use them as the program just sits there during a delay but that is what I wanted it to do. No contemplating life, no thinking about philosophy.

Interrupts. I read a bit about them but I wasn’t fully aware of all that can happen thanks to them. When I wrote the code stuff worked so I kept it.

While() loop. This was a brain fart. I had if() statements but changed to while() as I got it in my head that it would restart the pump every time it passed the statement. This obviously isn’t the case.

To wrap it up I got rid of the interrupt, and the delay. I changed the while to a if and generally cleaned the code up.

Thanks again.