IF statement not doing anything?

Hi all, I have a quite complex program that controls a pump.

Basically I have everything reading correctly and measuring correctly. However my IF statement(s) that control the pump do not work at all. The serial output shows non of the flags activating when the logic in the IF statements should of turned them on.

I've attached the scripts if someone could have a look that would be great!!!

I've also included a copy of the serial output on the Arduino.

psi=0.01, smooth=0.00, setpoint=0.20, Delta=0.00, Person=false, pumpOn=false

At this point surely it should activate the first IF statement in the program?

    // ---------------------------------
    // Control the pump
    // ---------------------------------
    // This part runs every 200ms.
    // If that is too slow, perhaps this should be run outside the millis() software counter,
    // or another millis() software counter could be used.

    static int pumpCountOn = 2;
    //if there is NOT someone on the mattress AND actual pressure is smaller than 0.2PSI
    //then activate the pump. If NOT then deactivate the pump
   
  if ((flagPerson == false) && (smoothPSI < setpoint))
    pumpOn = true;
  else
    pumpOn = false;
 
    // if someone IS one the mattress AND actual pressure is smaller than the setpoint
    //then activate the pump. OTHERWISe deactivate the pump
  if ((flagPerson == true) && (smoothPSI < setpoint))
    pumpOn = true;
  else
    pumpOn = false;
  
    // if the pumpOn flag is true then activate the transistor to allow the pump to come on.
    //if not then make sure the transistor is off.
  if (pumpOn == true)
    digitalWrite(transistorPin, HIGH);
   else
    digitalWrite(transistorPin, LOW);
    
  //if noone is on the mattress but the pressure is over 0.2PSI then let some air out.
  if ((flagPerson == false) && (smoothPSI > 0.2))
    prvOpen = true;
    else
    prvOpen = false;
    
  //if someone is on the mattress and the pressure is over the desired setpoint then let some air out.
  if ((flagPerson == true) && (smoothPSI > setpoint))
    prvOpen = true;
  else
  prvOpen = false;
  
//turn on the PRV if the flag is set true.
  if (prvOpen == true)
    digitalWrite(prvPin, HIGH);
  else
    digitalWrite(prvPin, LOW);

  }
}

What is flagPerson suppose to be telling us? What would personOnMattress tell us?

How much do you know about the values in the variables when you print them only 1 of 8 times that loop() seems to do anything?

    boolean switchActive;
    int buttonState = digitalRead(pushButton);
    if (buttonState == LOW)
      switchActive = true;
    else
      switchActive = false;

At the end, switchActive = !digitalRead(pushButton);. Why use 6 lines to accomplish what could be done in 1?

  if ((flagPerson == false) && (setpoint != 0.2) && (smoothPSI > 0.6))

You should never use == with floating point values. Even

  float setPoint = 0.2;
  if(setPoint == 0.2)

could result in the statement being false, due to how floating point numbers are stored. Only a very small number of floating point values can be stored exactly.

Back to your questions.

At this point surely it should activate the first IF statement in the program?

If statements are not activated. The if statement is EVALUATED. The result of the evaluation is true or false. If true, the body of the statement is executed. If not, it is not. If there is an else clause, that will be executed when the statement evaluates to false.

Now, what proof do you have that the statement is not setting pumpOn to true?

Perhaps the second statement is undoing what the first one does.

Appropriately placed Serial.print() statements would provide the proof needed.

      Serial.print(F("psi="));
      Serial.print(psi);
      Serial.print(F(", smooth="));
      Serial.print(smoothPSI);
      Serial.print(F(", setpoint="));
      Serial.print(setpoint);
      Serial.print(F(", Delta="));
      Serial.print(pressureDelta);
      Serial.print(F(", Person="));
      Serial.print( flagPerson ? F("true") : F("false"));
      Serial.print(F(", pumpOn="));
      Serial.print( pumpOn ? F("true") : F("false"));

It's great that you label the output. The problem is that when labels don't match what is printed, the labels are often worse that useless. smooth != smoothPSI. Delta != pressureDelta. Person != flagPerson.

flagPerson basically finds out whether someone is led on the air inflated mattress.

personOnMattress got deleted can't find where I've left that in the script?

Initially I had it on 0 so it constantly refreshes but I wanted to slow it down to make it a little more readable. Either way the results don't alter.

Makes a little more sense, my programming skills are far from excellent to be honest. Thanks for all of those tips.

How can I prove that a certain if statement is not working? With the boolean serial outputs I thought true and false was the only two outputs it could give?

personOnMattress got deleted can't find where I've left that in the script?

You didn't. My point was that personOnMattress is self-explanatory. flagPerson obviously wasn't.

How can I prove that a certain if statement is not working? With the boolean serial outputs I thought true and false was the only two outputs it could give?

The second question isn't really a question, is it? It is a statement. The value in a boolean is either true or false. What that equates to in terms of serial output is not as cut and dried. That is why you used:

      Serial.print(F(", pumpOn ="));
      Serial.print( pumpOn ? F("true") : F("false"));

to output the value. And THAT is the answer to the first question. Copy that code after the if/else statement. If the value is not what you expect, you have one issue. If it is, but changes before it is used, you have another issue.

What issue is it we are trying to solve?

Right ok sorry, I did comment that in the setup part explaining what it is used for.

Ok so I've moved the serial output for the pumpon flag just after the first If statement:

 // ---------------------------------
    // Control the pump
    // ---------------------------------
    // This part runs every 200ms.
    // If that is too slow, perhaps this should be run outside the millis() software counter,
    // or another millis() software counter could be used.

    static int pumpCountOn = 2;
    //if there is NOT someone on the mattress AND actual pressure is smaller than 0.2PSI
    //then activate the pump. If NOT then deactivate the pump
   
  if ((flagPerson == false) && (smoothPSI < setpoint))
    pumpOn = true;
  else
    pumpOn = false;
 Serial.print(F(", pumpOn="));
      Serial.print( pumpOn ? F("true") : F("false"));

The serial output now shoes the pump flag as being true?

But if I then put the flag after the next IF statement then the flag is false?

  // if someone IS one the mattress AND actual pressure is smaller than the setpoint
    //then activate the pump. OTHERWISe deactivate the pump
  if ((flagPerson == true) && (smoothPSI < setpoint))
    pumpOn = true;
  else
    pumpOn = false;

After that the flag is false? How is that?

Right ok sorry, I did comment that in the setup part explaining what it is used for.

Comments are not code. I ignore them. Most people will, until they encounter a dumb name. Then, they'll ask themselves "what was this doofus thinking? Or was he?". Don't let that happen to you.

Ok so I've moved the serial output

Copy != Move. No one said to move anything.

After that the flag is false?

Let's get something straight. A question ends with a question mark. A statement ends with a period or an exclamation point. Is this a question or a statement?

If it's a question, you know how to answer that. Print the value again.

If it's a statement, stop using question marks at the end.

How is that?

If we assume that the relationship between setpoint and smoothPSI hasn't changed, and they can't the way the code is currently written, then your code can be rearranged:

if(smoothPSI < setpoint)
{
  if (flagPerson == false)
    pumpOn = true;
  else
    pumpOn = false;

  if (flagPerson == true)
    pumpOn = true;
  else
    pumpOn = false;
}

and then it is perfectly easy to understand that there is a logic error in the code.

Ahhh! I can see now that they contradict eachother. I feel stupid now! :frowning:

So I've got this now. I've ran it quickly through my test setup and it seems to work fine. Can you spot anything that could potentially be wrong?

 // ---------------------------------
    // Control the pump
    // ---------------------------------
    // This part runs every 200ms.
    // If that is too slow, perhaps this should be run outside the millis() software counter,
    // or another millis() software counter could be used.

    static int pumpCountOn = 2;
    //if there is NOT someone on the mattress AND actual pressure is smaller than 0.2PSI
    //then activate the pump. If NOT then deactivate the pump
   
  if(smoothPSI < 0.2)
{
  if (flagPerson == false)
    pumpOn = true;
}
  if(smoothPSI > 0.2)
{
  if (flagPerson == false)
    pumpOn = false;
    prvOpen = true;
}

/////////////////////////////

  if(smoothPSI < setpoint)
{
  if (flagPerson == true)
    pumpOn = true;
}
  if(smoothPSI > setpoint)
{
  if (flagPerson == true)
    pumpOn = false;
    prvOpen = true;
}

    // if the pumpOn flag is true then activate the transistor to allow the pump to come on.
    //if not then make sure the transistor is off.
  if (pumpOn == true)
    digitalWrite(transistorPin, HIGH);
   else
    digitalWrite(transistorPin, LOW);
     
//turn on the PRV if the flag is set true.
  if (prvOpen == true)
    digitalWrite(prvPin, HIGH);
  else
    digitalWrite(prvPin, LOW);

  }
}

Thanks for all your help!

Reading it I could also of used Else if I believe!

  if (flagPerson == false)
    pumpOn = false;
    prvOpen = true;

Indenting means nothing. What is supposed to happen if flagPerson is false?

 if(smoothPSI < 0.2)
{
}
  if(smoothPSI > 0.2)
{
}

If smoothPSI IS 0.2, what should happen?

 if(smoothPSI < setpoint)
{
}
  if(smoothPSI > setpoint)
{
}

Is smoothPSI IS equal to setpoint, what should happen?

if flagPerson = false then I'd like it to only regulate to 0.2PSI... If that makes sense to you?

if it is 0.2PSI then do nothing.. or pumpOn=false

Again if smoothPSI is equal to setpoint then pumpOn=false.

Guessing I should include that also, what do you think?

Yes, you need to not exclude the equals cases.