Arduino Control System

Here is the Problem:

My parents live in Costa Rica and they have their own water system. The water system consists of a handmade well for the water supply and an elevated tank for storage. A pump is used to bring the water from the well to the storage tank. There is an overflow pipe at the top of the tank which leaks water out to indicate that the tank is full. Unfortunately, the amount of water in the well is limited. The pump can only run for about 22 minutes in the rainy season and for 12 minutes in the dry season before the well runs out of water.  After the well runs out, it takes two hours for the water in the well to be replenished.

My family has managed this system by physically walking to the water management site, and manually activating the pump as often as every 2 hours, then waiting until the well runs dry to turn off the pump. As you can image, this is a very tedious and inconvenient process. The need to keep the tank full is constant and the frequency at which the pump needs to be turned on increases with increasing water demands. On a positive note, despite the inconvenience, this method has served my family for about 15 years.

Here are a couple of pictures of the water management site:

IMG-20160110-WA0016

IMG-20160110-WA0015

Here is a schematic representation of the water system:

image

 

Here is the Solution:

After considering many options to provide my family with a more convenient solution to manage the water system, I selected the following method: I programmed an Arduino Uno to control the system autonomously. The water pump is 220VAC. I used two 220VAC 25A rated solid state relays to turn on and off the pump through a +5VDC signal from the Arduino. The relays were properly mounted on heat sinks using thermal paste to maintain adequate heat dissipation. A digital liquid level sensor powered by the Arduino was installed on the overflow pipe of the tank. This sensor will tell the Arduino when the tank is full. The Arduino will constantly turn on the pump for 10 minutes every two hours year-round. When the water sensor tells the Arduino that the tank is full, the Arduino will turn off the pump and wait for two hours before turning on the pump again. I also installed a manual switch which, when activated, overrides the system and forces the pump to be on. I installed two indicator LEDs. One turns on when the pump is on and the other indicates that the water level sensor has been activated. The system has been successfully working for four weeks now.

Here is a picture of inside the Arduino control box:

20151101_143915

Here is a picture of the installed control box and relays which adapts to the current electrical system control set up:

20151220_102147

The feedback sensor at the end of the overflow pipe:

20151219_152318

  The schematic of the control system is as follows:

 

image

 

The control system design was influenced by the previous electrical wiring and water pipes, as well as the contraints that come with tropical environments. Were the system to fail, the set up is such that it can easily be returned to the previous method with minimum effort.

 

Part List:

  • Micro-Controller: Arduino Uno (QTY: 1)
  • Liquid Level Sensor: Optomax Series Digital Range LLT600D3SH (QTY: 1)
  • Solid State Relays: Crydom D2425 (QTY: 2)
  • Heat Sinks (QTY: 2)
  • Enclosure box (QTY: 1)
  • Prototype Printed Circuit Board (QTY: 1)
  • Dsub9 connector (QTY: 1)
  • 9V Power Supply (QTY: 1)
  • Indicator LEDs (QTY: 2)
  • Resistors 320 ohms (QTY: 2)
  • ON-OFF Switch (QTY: 1)
  • Electrical Wire Assorted Colors (~20AWG)
  • Screw terminal blocks (QTY: 2)
  • Heat shrinks Assorted Sizes
  • Fastening Screws Assorted Sizes
  •  

    *Code:

    /*============================================================================================

    ==============================================================================================

    ==============================================================================================

    Costa Rica Water Tank / Water Well Management

    Fully Autonomous with Switch Option

    Created by Ruander Cardenas

    Last Updated on: 12/19/2015

    ==============================================================================================

    ==============================================================================================

    =============================================================================================*/

    //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

    //+++++++++++++++++++++++++++++ USER INPUTS +++++++++++++++++++++++++++++++++++++++++++++++++

    //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

    //Define Pins to be Used

    #define pinSensor 12 // Water Sensor: Not using 13 due to onboard LED circuit

    #define pinRelay1 11 // Relay No. 1 signal

    #define pinRelay2 10 // Relay No. 2 signal

    #define pinLED1 9 // Pump On or Off status LED

    #define pinLED2 8 // Sensor Air or Water LED

    #define pinButton 7 // Manual on and off switch

    //Define Constants

    const unsigned long ontime = 600000; // Units of millisecons: (min)x(s/min)x(ms/s)=ms (10 mins --> 600000 ms)

    const unsigned long offtime = 7200000; // (10/60/60)*(60)*(60)*(1000); //Units of millisecons:(hr)x(min/hr)x(s/min)x(ms/s)=ms (2.5 hrs --> 9000000 ms)

    const int t_inc = 250; // Milliseconds to wait inside the loop

    // Define Variables

    int sensorState; // Variable for tank full (LOW) or not full (HIGH)

    int buttonState; // Variable for manual switch: ON (LOW) or OFF (HIGH)

    unsigned long t_on = 0; // Variable for time pump has been on. Assumes pump has not been on

    unsigned long t_off = offtime; // Variable for time pump has been off. Assumes pump has been off for atleast offtime limit

    unsigned long ti; // Time at the start of the loop

    unsigned long tf; // Time at the end of the loop

    //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

    //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

    //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

    void setup() {

    // put your setup code here, to run once:

    pinMode(pinSensor, INPUT);

    pinMode(pinButton, INPUT_PULLUP);

    pinMode(pinRelay1, OUTPUT);

    pinMode(pinRelay2, OUTPUT);

    pinMode(pinLED1, OUTPUT);

    pinMode(pinLED2, OUTPUT);

    // Initialize Serial for debugging purposes

    //Serial.begin (9600);

    }

    void loop() {

    // put your main code here, to run repeatedly:

    ti=micros();

    sensorState = digitalRead(pinSensor);

    buttonState = digitalRead(pinButton);

    if (sensorState == LOW) { //Turn on LED2 to indicate tank is full

    digitalWrite(pinLED2,HIGH);

    t_off=0; //Reset off time to zero (prevents jerking on and off pump)

    }

    if (sensorState == HIGH) { //Turn off LED2 to indicate tank is not full

    digitalWrite(pinLED2,LOW);

    }

    if (buttonState == LOW) { on2(); //Pump on

    } else {

    if (t_off < offtime) {off(); //Pump off while water in well replenishes

    } else {

    if (sensorState == LOW) {off(); //Pump off since tank is full

    } else {

    if (t_on < ontime) { on(); //Pump on

    }

    if (t_on > ontime) { off(); //Pump off

    }

    }

    }

    }

    delay(t_inc);

    tf=micros();

    //Serial Commands for debugging Purposes

    //Serial.print("On Time = ");

    //Serial.println(t_on);

    //Serial.print("Off Time = ");

    //Serial.println(t_off);

    }

    //=================================================================================

    //=================================================================================

    //=================================================================================

    void on(){

    digitalWrite(pinRelay1,HIGH);

    digitalWrite(pinRelay2,HIGH);

    digitalWrite(pinLED1,HIGH);

    t_on = t_on + t_inc;

    if(t_on > ontime - t_inc){ t_off=0; //Reset off time to zero

    }

    }

    //=================================================================================

    //=================================================================================

    //=================================================================================

    void off(){

    digitalWrite(pinRelay1,LOW);

    digitalWrite(pinRelay2,LOW);

    digitalWrite(pinLED1,LOW);

    t_off = t_off + t_inc;

    if(t_off > offtime - t_inc){ t_on=0; //Reset on time to zero

    }

    }

    //=================================================================================

    //=================================================================================

    //=================================================================================

    void on2(){

    digitalWrite(pinRelay1,HIGH);

    digitalWrite(pinRelay2,HIGH);

    digitalWrite(pinLED1,HIGH);

    t_off = 0; //Assumes well needs a full braek after manual switch

    t_on = ontime; // Assmes pump was manually turned on for the max time

    }

    *Please note that the timing of the code is based on a 250ms delay. Therefore, times are approximations and not exact (code takes around 48 us to run without delay). For my applications, this is just fine. I did an error approximation test and my expected times are off by about 1.5 seconds every 2 hours. I did look into timing rollover and variable overflow (http://playground.arduino.cc/Code/TimingRollover) but decided to go with the delay option since for my application, this was simpler and adequate.

    No comments:

    Post a Comment