IR remote to start/stop process

This code is for an ATO (auto top off) process. Eventually, I will also have a drain/fill process included.

The idea was to use an IR remote to start and stop the two processes. Press UP to turn ATO on, down to turn it off, left to turn on drain, right to turn it off…

The problem is that the if loop doesn’t loop after the button is pressed… so if I press ‘UP’ it reads the float sensors and responds accordingly, but doesn’t continue to read the sensors and react properly. If the float states change, I would have to press up again to get the desired output.

If I run the process without the remote, it works as planned other than repeating:
"tank is full
fill pump off
over and over infinitely while the proper conditions are met, which should not affect the output (if it’s already off, you can’t switch it off again), but annoys the hell out of me while debugging.

I know that’s two problems, but any help on either would be much appreciated!

Also, disclaimer - I’m completely new to programming, and this code has been through a lot of re-writes so forgive any goofiness in the code.

#include <IRremote.h>                                        
                                           // INPUTS
const int floatT = 13;                     // main tank top                      
const int floatB = 12;                     // main tain bottom                 
const int floatH = 11;                     // holding tank bottom                
int RECV_PIN = 9;                          // IR Remote
IRrecv irrecv(RECV_PIN);
decode_results results;

                                           // OUTPUTS
const int pF = 2;                          // fill pump             
const int pD = 3;                          // drain pump                   
const int pH = 4;                          // power head                    

int floatTstate;                           // variables to hold float states              
int floatBstate;                           //            
int floatHstate;                           //  
int valB;                                  //    
int valT;                                  // variables for reading float statuses 
int valH;                                  //      
int pumpFmode = 0;                         // is the fill pump on or off? 
int pumpDmode = 0;                         // is the drain pump on or off?             
int pHMode = 0;                            // is the power head on or off? 


void setup() {
 pinMode(floatT, INPUT_PULLUP);
 pinMode(floatB, INPUT_PULLUP);
 pinMode(floatH, INPUT_PULLUP);
  
 pinMode(pF, OUTPUT);
 pinMode(pD, OUTPUT);
 pinMode(pH, OUTPUT);

 Serial.begin(9600);                       // set up serial communication at 9600 bps  
                 
 floatTstate = digitalRead(floatT);                 
 floatBstate = digitalRead(floatB);        // read the initial states of inputs                
                 
 
 irrecv.enableIRIn();                     // Start the receiver
}

void loop() {
                                           // read input values and store in val
  valT = digitalRead(floatT);              // ...Top
  valB = digitalRead(floatB);              // ...Bottom 
  valH = digitalRead(floatH);              // ...Holding Tank

if (irrecv.decode(&results)) {

   if(results.value==0xff629d){
    Serial.println("ATO on");
    
   if (valT == LOW && valH == HIGH){         // check if top level is low and fill 
                                           //       ...pump is submerged
  if (pumpFmode == 0) {                    // fill pump is off
    pumpFmode = 1;                         // fill pump is on
    delay(200);                             // debounce
    Serial.println("water is low");
    delay(1000);
    digitalWrite(pF, HIGH);                 // turn on fill pump
    Serial.println("fill pump on");
  }
}else {
    pumpFmode = 0;                         // fill pump is off
    delay(200);                            // debounce
    Serial.println("tank is full");
    digitalWrite(pF, LOW);                 // turn off fill pump
    Serial.println("fill pump off");
}
    
   }
   if(results.value==0xffa857){
    Serial.println("ATO off");
   }
     irrecv.resume();                           // Receive the next value 
}}
   }
     irrecv.resume();                           // Receive the next value
}}

Maybe you can tell when this gets called, but with that piss-poor indenting and sloppy crap with multiple curly braces on one line, I can't. So, I'm going to guess that it is not being called at the correct time.

Sorry, I’m still learning.

Is this better?

#include <IRremote.h>                                        
                                           // INPUTS
const int floatT = 13;                     // main tank top                      
const int floatB = 12;                     // main tain bottom                 
const int floatH = 11;                     // holding tank bottom                
int RECV_PIN = 9;                          // IR Remote
IRrecv irrecv(RECV_PIN);
decode_results results;

                                           // OUTPUTS
const int pF = 2;                          // fill pump             
const int pD = 3;                          // drain pump                   
const int pH = 4;                          // power head                    

int floatTstate;                           // variables to hold float states              
int floatBstate;                           //            
int floatHstate;                           //  
int valB;                                  //    
int valT;                                  // variables for reading float statuses 
int valH;                                  //      
int pumpFmode = 0;                         // is the fill pump on or off? 
int pumpDmode = 0;                         // is the drain pump on or off?             
int pHMode = 0;                            // is the power head on or off? 


void setup() {
 pinMode(floatT, INPUT_PULLUP);
 pinMode(floatB, INPUT_PULLUP);
 pinMode(floatH, INPUT_PULLUP);
  
 pinMode(pF, OUTPUT);
 pinMode(pD, OUTPUT);
 pinMode(pH, OUTPUT);

 Serial.begin(9600);                       // set up serial communication at 9600 bps  
                 
 floatTstate = digitalRead(floatT);                 
 floatBstate = digitalRead(floatB);        // read the initial states of inputs                
                 
 
 irrecv.enableIRIn();                      // Start the receiver
}

void loop() {
                                           // read input values and store in val
  valT = digitalRead(floatT);              // ...Top
  valB = digitalRead(floatB);              // ...Bottom 
  valH = digitalRead(floatH);              // ...Holding Tank

  if (irrecv.decode(&results)) {
     
    if(results.value==0xff629d){                // 'up' pressed
      Serial.println("ATO on");
     
      if (valT == LOW && valH == HIGH){         // check if top level is low and fill 
                                                //       ...pump is submerged
        if (pumpFmode == 0) {                   // fill pump is off
        pumpFmode = 1;                          // fill pump is on
        delay(200);                             // debounce
        Serial.println("water is low");
        delay(1000);
        digitalWrite(pF, HIGH);                 // turn on fill pump
        Serial.println("fill pump on");
        }
      }
      else {
      pumpFmode = 0;                            // fill pump is off
      delay(200);                               // debounce
      Serial.println("tank is full");
      digitalWrite(pF, LOW);                    // turn off fill pump
      Serial.println("fill pump off");
      }
    } 
    if(results.value==0xffa857){                // 'down' pressed
    Serial.println("ATO off");
    delay(1000);
    Serial.println("fill pump off");
    digitalWrite(pF, LOW);                      // turn off fill pump   
    }
  irrecv.resume();                              // Receive the next value 
  }
}

The code to read your level switches is inside the code that checks for receiving that signal. So it will only check the levels when it receives that signal.

Instead, let receiving an IR signal set a flag that says the ATO is on or off and in the loop if that flag is true then read your switches and run your ATO.

pseudocode:

boolean atoFlag = false;

void loop(){
    if(received signal to turn ATO on){
        atoFlag = true;
    }
    if(received signal to turn ATO off){
        atoFlag = false;
    }

    if(atoFlag) {
        // ATO is on, check levels and top off the tank
    }

I think that worked!

I’m still experiencing the issue with the infinite repeating in the serial monitor… is that a problem, or just an annoyance?

#include <IRremote.h>                                        
                                           // INPUTS
const int floatT = 13;                     // main tank top                      
const int floatB = 12;                     // main tain bottom                 
const int floatH = 11;                     // holding tank bottom                
int RECV_PIN = 9;                          // IR Remote
IRrecv irrecv(RECV_PIN);
decode_results results;

                                           // OUTPUTS
const int pF = 2;                          // fill pump             
const int pD = 3;                          // drain pump                   
const int pH = 4;                          // power head                    

int floatTstate;                           // variables to hold float states              
int floatBstate;                           //            
int floatHstate;                           //  
int valB;                                  //    
int valT;                                  // variables for reading float statuses 
int valH;                                  //      
int pumpFmode = 0;                         // is the fill pump on or off? 
int pumpDmode = 0;                         // is the drain pump on or off?             
int pHMode = 0;                            // is the power head on or off? 

int atoFlag;

void setup() {
 pinMode(floatT, INPUT_PULLUP);
 pinMode(floatB, INPUT_PULLUP);
 pinMode(floatH, INPUT_PULLUP);
  
 pinMode(pF, OUTPUT);
 pinMode(pD, OUTPUT);
 pinMode(pH, OUTPUT);

 Serial.begin(9600);                       // set up serial communication at 9600 bps  
                 
 floatTstate = digitalRead(floatT);                 
 floatBstate = digitalRead(floatB);        // read the initial states of inputs                
                 
 
 irrecv.enableIRIn();                      // Start the receiver
 boolean atoFlag = false;
}

void loop() {
                                           // read input values and store in val
  valT = digitalRead(floatT);              // ...Top
  valB = digitalRead(floatB);              // ...Bottom 
  valH = digitalRead(floatH);              // ...Holding Tank

  if (irrecv.decode(&results)) {
     
    if(results.value==0xff629d){                // 'up' pressed
      atoFlag = true;
    }
    if(results.value==0xffa857){                // 'down' pressed
      atoFlag = false;
      Serial.println("ATO off");
      delay(1000);
      Serial.println("fill pump off");
      digitalWrite(pF, LOW);                      // turn off fill pump   
    }  
    irrecv.resume();                              // Receive the next value 
  }

  if(atoFlag) { 
    Serial.println("ATO on");
     
      if (valT == LOW && valH == HIGH){         // check if top level is low and fill 
                                                //       ...pump is submerged
      delay(200);                             // debounce
      Serial.println("water is low");
      delay(1000);
      digitalWrite(pF, HIGH);                 // turn on fill pump
      Serial.println("fill pump on");
      }
      else {
      delay(200);                               // debounce
      Serial.println("tank is full");
      digitalWrite(pF, LOW);                    // turn off fill pump
      Serial.println("fill pump off");
      }
  }
}

Yes, the loop function is going to turn over fast and spam your monitor. Maybe you should only print thing when they change. Or you could use the Blink Without Delay technique to only print something every so often.

Get those delays out of your code or you're going to miss a transition on one of your floats and over fill your tank.

The delays are primarily there so I can read the serial monitor- otherwise it's just instantly a solid wall of text. There is still much testing (and building) to be done before I leave this to run autonomously.

The delays are primarily there so I can read the serial monitor-

You can uncheck scrolling in the serial monitor.
.