Pump stop/start code problem

Good evening,

I’m looking for some help with a project I’m building for an automated dog watering bowl. The set up I have is as follows,

Ardunio Uno R3 board

2 x water tanks one for supply with fresh water and one which I'm classing as the dog bowl and is topped up from the supply tank.
Both tanks are fitted with temperature monitoring and level monitoring, the levels are HC-SR04 ultrasonic detectors which are calculating the water level in each tank.

In both tanks are 12v submersible water pumps, the one in the supply tank is called PUMP_TANK and is connected to pin 10 and set as output. This pump is meant to fill the bowl from the supply tank. the second pump is in the bowl and is called PUMP_BOWL and is connected to pin 11 and set to output.

The code I have below is working as described but I'm trying to add pump logic to do the following, when the water level in the bowl drops below 3cm for > 3seconds I want the PUMP_TANK to run and keep running until the level in the bowl is > 10cm then stop and return to monitoring mode. Also after 1 hour timer had elapsed I want a re-fill sequence to run which does the following, runs PUMP_BOWL for 15 seconds to drain the bowl, then run PUMP_TANK for 15 seconds to refill the bowl with fresh water.

I have tried all sorts of logic code but I just can't get the pump to switch off when it hits the >10cm trigger. I've not got to the re-fill sequence bit yet as I can't even get the pump to come on at <3cm and go off at >10cm, it seems to just run the PUMP_TANK continuously regardless of the setpoint I put in.

I have ran some basic code such as pushbutton on/off to activate the two pump output pins and this works fine so I know my wiring is all ok in relation to the pumps and their outputs.

I'm thinking it's maybe something with the variable its using for the level and the setpoint I'm providing. I can't understand why a simple if (levelBowl <3cm) {digitalWrite (PUMP_BOWL_PIN, HIGH)} isn't working.

Any help would be greatly appreciated.

```cpp

#include "Wire.h"
#include "OneWire.h"
#include "DallasTemperature.h"
#include "U8x8lib.h"

#define TEMP_SENSOR_TANK_PIN 8
#define TRIG_PIN_TANK 6
#define ECHO_PIN_TANK 7
#define TANK_HEIGHT 179
#define PUMP_TANK_PIN 10

#define TEMP_SENSOR_BOWL_PIN 9
#define TRIG_PIN_BOWL 3
#define ECHO_PIN_BOWL 4
#define BOWL_HEIGHT 135
#define PUMP_BOWL_PIN 11

OneWire oneWireTank(TEMP_SENSOR_TANK_PIN);
DallasTemperature sensorsTank(&oneWireTank);
U8X8_SH1106_128X64_NONAME_HW_I2C u8x8(/* reset=*/ U8X8_PIN_NONE);

OneWire oneWireBowl(TEMP_SENSOR_BOWL_PIN);
DallasTemperature sensorsBowl(&oneWireBowl);

// Function declarations
float getWaterTemperature(String sensorType);
int getWaterDistance(String sensorType);

void setup() {
  Serial.begin(9600);
  Wire.begin();
  u8x8.begin();
  u8x8.setFont(u8x8_font_chroma48medium8_r);

  sensorsTank.begin();
  sensorsBowl.begin();

  pinMode(TRIG_PIN_TANK, OUTPUT);
  pinMode(ECHO_PIN_TANK, INPUT);
  pinMode(PUMP_TANK_PIN, OUTPUT);

  pinMode(TRIG_PIN_BOWL, OUTPUT);
  pinMode(ECHO_PIN_BOWL, INPUT);
  pinMode(PUMP_BOWL_PIN, OUTPUT);
}


   void loop() {
  // Tank Data
  float tempTank = getWaterTemperature("Tank");
  int levelTankSensor = getWaterDistance("Tank");
  int levelTank = TANK_HEIGHT - levelTankSensor;  // Calculate true level

  // Bowl Data
  float tempBowl = getWaterTemperature("Bowl");
  int levelBowlSensor = getWaterDistance("Bowl");
  int levelBowl = BOWL_HEIGHT - levelBowlSensor;  // Calculate true level

    // Print live data to Serial Monitor
    Serial.println("Tank Level: " + String(levelTank) + "mm");
    Serial.println("Tank Temperature: " + String(tempTank, 1) + "C");

    Serial.println("Bowl Level: " + String(levelBowl) + "mm");
    Serial.println("Bowl Temperature: " + String(tempBowl, 1) + "C");

    // Clear OLED display
    u8x8.clearDisplay();

    // Display temperature and level on OLED
    u8x8.setCursor(1, 0);
    u8x8.print("TankLev: ");
    u8x8.print(levelTank);
    u8x8.print("mm");

    u8x8.setCursor(1, 2);
    u8x8.print("TankTemp: ");
    u8x8.print(tempTank, 1);
    u8x8.print("C");

    u8x8.setCursor(1, 4);
    u8x8.print("BowlLev: ");
    u8x8.print(levelBowl);
    u8x8.print("mm");

    u8x8.setCursor(1, 6);
    u8x8.print("BowlTemp: ");
    u8x8.print(tempBowl, 1);
    u8x8.print("C");

    // Monitor Tank
    if (levelTank < 10 || tempTank > 25) {
      // Halt the system and display error message

      u8x8.clearDisplay();
      u8x8.setCursor(4, 2);
      u8x8.print("Tank");
      u8x8.setCursor(3, 4);
      u8x8.print("out of spec");
      u8x8.setCursor(2, 6);
      u8x8.print("Attention needed");
    }

  
    }

  else {
    // Check if conditions are back within the setpoint range to resume normal operation
    float tempTank = getWaterTemperature("Tank");
    /*int levelTank = getWaterDistance("Tank");*/
    int LevelTank;
    if (levelTank >= 10 && tempTank <= 18) {
     
    }
  }

  delay(5000);  // Refresh every 5 seconds
}
   
float getWaterTemperature(String sensorType) {
  if (sensorType == "Tank") {
    sensorsTank.requestTemperatures();
    return sensorsTank.getTempCByIndex(0);
  } else if (sensorType == "Bowl") {
    sensorsBowl.requestTemperatures();
    return sensorsBowl.getTempCByIndex(0);
  }
}

int getWaterDistance(String sensorType) {
  int trigPin, echoPin;

  if (sensorType == "Tank") {
    trigPin = TRIG_PIN_TANK;
    echoPin = ECHO_PIN_TANK;
  } else if (sensorType == "Bowl") {
    trigPin = TRIG_PIN_BOWL;
    echoPin = ECHO_PIN_BOWL;
  }

  // Trigger ultrasonic sensor
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);

  // Read echo pulse duration
  long duration = pulseIn(echoPin, HIGH);

  // Calculate distance in mm
  int distance = duration * 0.343 / 2;

  return distance;
}
     u8x8.print("Attention needed");
    }

  
    } **<< I think this doesn't belong here**

  else {
    // Check if conditions are back within the setpoint range to resume normal operation
    float tempTank = getWaterTemperature("Tank");
    /*int levelTank = getWaterDistance("Tank");*/

Sorry I realised I hadn't included an example of the pump on/off logic code. Below is a basic example I've tried to use to get the pump to run should the level drop below 3cm for more then 3 seconds. When this code is loaded the PUMP_BOWL doesn't run at all regardless of the simulated level.

  // Check if the bowl level is below 3cm for more than 3 seconds
  if (levelBowl < 3) {
    unsigned long currentTime = millis();

    if (currentTime - lowLevelStartTime > 3000) {
      // Run the tank pump for 5 seconds
      digitalWrite(PUMP_TANK_PIN, HIGH);
      Serial.println("Pump on");
      delay(5000);
      digitalWrite(PUMP_TANK_PIN, LOW);
      Serial.println("Pump off");
    }
  } else {
    lowLevelStartTime = millis(); // Reset the timer when the level is above 3cm
  }

  delay(3000);  // Refresh every 3 seconds
}

You keep resetting currentTime going into it

if (levelBowl < 3) {
    unsigned long currentTime = millis();

and then you keep resetting lowLevelStartTime in the else

} else {
    lowLevelStartTime = millis(); 

They will never differ by 3000

I Stand Corrected. The delay (3000) should take care of that

Your dog and I want to know if when you plan to install a Peltier device on each vessel of water and add code for maintaining an optimum temperature.

a7

Schematics and links to datasheets for critical devices, please. Words, novels are not the way.

Hi, @wallac85

How are you protecting the HC units from moisture/humidity.

I would be using more reliable float switches to indicate max and min levels in each tank.

Tom.. :grinning: :+1: :coffee: :australia:

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.