designedrat
Published © GPL3+

Watersource Controller

This Arduino project automatically switches the watersource solenoid depending on the available stored rainwater.

IntermediateShowcase (no instructions)8,651
Watersource Controller

Things used in this project

Hardware components

Arduino Nano R3
Arduino Nano R3
×1
Resistor 10k ohm
Resistor 10k ohm
×6
0.96" OLED 64x128 Display Module
ElectroPeak 0.96" OLED 64x128 Display Module
any oled display will do, just see you make the right connections. A4 -> SDA A5 -> SCL
×1
Relay Module (Generic)
this should be a common ground relay that switches when the pin is pulled low. Otherwise you have to change the code accordingly.
×1
Pushbutton switch 12mm
SparkFun Pushbutton switch 12mm
×1
1N4007 – High Voltage, High Current Rated Diode
1N4007 – High Voltage, High Current Rated Diode
any diode will do, and they should be put on the solenoid valves. They are important to prevent causing resets of the arduino due to current spikes when the solenoids close again. The diode should be put so that they conduct electricity from GND to VCC. This is called a flyback diode setup.
×1

Hand tools and fabrication machines

Soldering iron (generic)
Soldering iron (generic)

Story

Read more

Schematics

schematics

Code

code

Arduino
#include <Wire.h>
#include <ACROBOTIC_SSD1306.h>

int Off = LOW;
int On = HIGH;

//initializing states
int WaterRelayState = On;
int PowerRelayState = On;
int MemoryState = Off;
int ServerState = 0;
int TSSourceCity = 0;
int TSSourceRain = 0;

//setting GPIO pins
const int ManualOverride = 8;
const int WaterSupplySwitch = 7;
const int PowerSupplySwitch = 6;
const int PressureSensor = A0;
const int BottomSensor = 4;
const int TopSensor = 5;

//pressure var
float CurrentPressure = 0;
float WaterPressureToggle = 0;
float WaterPressureToggleHIGH = 0;
float WaterPressureRef = 0;
int LowValue = 0;
int HighValue = 0;

boolean FLOW = false;
boolean RECALIBRATED = true;
boolean ManualFlow = false;

String Source = "";
String val = "";

//variables for delay without using delay
unsigned long CurrentMillis = 0;    // stores the value of millis() in each iteration of loop()
unsigned long PreviousMillis = 0;
unsigned long flowmillis = 0;


//variable to protect against disconnected hose
unsigned long RunningWater = 0;

//constants
const long Interval = 1000;
//const long Interval_Wifi = 15000;
const int MaxWaterDuration = 300;
 
const int led = 13;



void calibrate(){
  CurrentPressure = analogRead(PressureSensor);
  WaterPressureRef = CurrentPressure;
  }

void setup(void) {
  Serial.begin(115200);
  pinMode(ManualOverride, INPUT);
  pinMode(WaterSupplySwitch, OUTPUT);
  pinMode(PowerSupplySwitch, OUTPUT);
  pinMode(BottomSensor, INPUT);
  pinMode(TopSensor, INPUT);
  pinMode(PressureSensor, INPUT);

  digitalWrite(PowerSupplySwitch, PowerRelayState);
  digitalWrite(WaterSupplySwitch, WaterRelayState);
  FLOW = true;
  //checkwaterlevel(1);
  delay(5000);
  FLOW = false;
  
  calibrate();
  
  Wire.begin();  
  oled.init();                      // Initialze SSD1306 OLED display
  oled.clearDisplay();              // clear screen
}

void loop(void) {

  CurrentMillis = millis();

  if(digitalRead(ManualOverride) == LOW){
    ManualFlow = true;}
    else{
    ManualFlow = false;
  }
  
  if(CurrentMillis - PreviousMillis >= Interval) {
      PreviousMillis = CurrentMillis; 
    CurrentPressure = analogRead(PressureSensor);
    Serial.print("CurrentPressure");
    Serial.println(CurrentPressure);
    checkwaterlevel(0);
    }
}

void sense(){
      WaterPressureToggle = ((100/WaterPressureRef)*CurrentPressure);
      if(Source == "Citywater"){LowValue = 85;HighValue = 89;}
      else{LowValue = 65;HighValue = 80;
      }      
      Serial.print("WaterPressureToggle");
        if(WaterPressureToggle < LowValue or ManualFlow == true){
          FLOW =  true;
        }
        else{
            if(WaterPressureToggle > HighValue){
            FLOW = false;
            WaterPressureToggleHIGH = WaterPressureToggle;
            }
          }
    }

void checkwaterlevel(int x) {
  Serial.print("Flow state = ");
  Serial.println(ManualFlow);
  /*if (RunningWater > MaxWaterDuration) {
    sensorfault();
  }*/

  if (x==0){sense();}

  if (FLOW or ManualFlow) {
    flowmillis = millis();
    PowerRelayState = On;
    RunningWater += (Interval / 1000);
    if (digitalRead(BottomSensor) == LOW and digitalRead(TopSensor) == LOW) {//LOW means sensor is floating
      WaterRelayState = On;
      MemoryState = WaterRelayState; 
      Source = "Rainwater";
      Serial.println("Bottomsensor and Topsensor closed, running on rainwater");
    }
    else{
      if(digitalRead(BottomSensor) == LOW){
        WaterRelayState = MemoryState;
        if(WaterRelayState == On){Source = "Rainwater";}
        else{Source = "Citywater";}
        }
      else{
        WaterRelayState = Off;
        MemoryState = WaterRelayState; 
        Source = "Citywater";
        Serial.println("Bottomsensor open, running on Pidpa");}
      }
  }
  else
  {
      if(CurrentMillis - flowmillis >= Interval * 10)
      {
        calibrate();
        PowerRelayState = Off;
        WaterRelayState = Off;
        Source = "No power ";
        RunningWater = 0;
    }
  }
  lcd();
  digitalWrite(PowerSupplySwitch, PowerRelayState);
  digitalWrite(WaterSupplySwitch, WaterRelayState);
  
}

void lcd() {
  oled.setTextXY(0, 0);             // Set cursor position, start of line 0
  oled.putString("Running on ");
  oled.setTextXY(1, 0);             // Set cursor position, start of line 1
  oled.putString(Source);
  oled.setTextXY(2,0);
  oled.putString("Top=");
  oled.setTextXY(2,4);
  if (digitalRead(TopSensor) == LOW){oled.putString("WET");}else{oled.putString("DRY");}
  oled.setTextXY(2,9);
  oled.putString("Bot=");
  oled.setTextXY(2,13);
  if (digitalRead(BottomSensor) == LOW){oled.putString("WET");}else{oled.putString("DRY");}
  
  oled.setTextXY(3, 0);
  oled.putString("LO ");
  oled.setTextXY(3,4);
  oled.putString("     ");
  oled.setTextXY(3,4);
  oled.putNumber(WaterPressureToggle);
  oled.setTextXY(3,9);
  oled.putString("HI ");
  oled.setTextXY(3,13);
  oled.putString("     ");
  oled.setTextXY(3,13);
  oled.putNumber(WaterPressureToggleHIGH);
  oled.setTextXY(4, 0);
  if (PowerRelayState == On)
  {
    oled.putString("valves opened");
  }
  else
  {
    oled.putString("valves closed");
  }
  oled.setTextXY(5, 0);
  val = digitalRead(WaterSupplySwitch);
  oled.putString("          ");
  oled.setTextXY(5, 0);
  oled.putString(val);
  oled.setTextXY(6, 0);
  oled.putString("    ");
  oled.setTextXY(6, 0);
  oled.putNumber(WaterPressureToggle);
}

Credits

designedrat
0 projects • 8 followers

Comments