Automatic Water Level Controller Using Arduino

by muralysunam in Circuits > Arduino

3556 Views, 11 Favorites, 0 Comments

Automatic Water Level Controller Using Arduino

DSC06882.JPG

Hi all,

This instructable helps you to make an automatic water level controller using Arduino. I am using automatic water level controller in my home since 2016. There were some minor upgrades during this period and the latest version is completed using Arduino and is working since 2018. There were no major issues reported yet. I am not pretty good with documentation, but I will try my level best to put this together. You may feel free to comment any doubts after going through this article.

As I remember I have inititaly used instructables for realizing a line follower robot earlier in 2014 (The instructable by Midhun helped me to create this. He used an Atmega32 microcontroller whereas I used a PIC 16F877a.) I had to clear a lot of issues as the PIC microcontroller was not having sufficient resources and optimized compiler. The test video is available here and it helped me a lot in my life.

This automatic water level controller can be used in three ways

  1. Automatic with dry run protection - One sensor line and one common line is required in the well/ground level tank, two sensor lines and one common line is required in the overhead tank and the motor should be connected to the water level controller.
  2. Automatic - Same as above but sensor line and common line is not required in well/ground level tank.
  3. Manual - This method needs only two sensor lines and one common line in the overhead tank.

Safety warning : This project deals with working on power lines which needs to be implemented with an experienced electrician. In case you are pumping water from a well, there are several hazards while putting sense lines in the well. Take all sorts of precautions while executing this instructable. If you don't have prior experience how to solder, you may try using a breadboard and don't use soldering iron unless you don't have prior experience.

Supplies

This instructable needs following items

  1. Arduino Nano (clone version will be sufficient).
  2. Power adapter (12V/0.5A).
  3. Relay (12VDC).
  4. Transistor - BC547 (most of the NPN transistors will work fine).
  5. Diode - 1N4148 (Free wheeling diode).
  6. Bi colour LED - Green Red - three legged common cathode - 2 Nos.
  7. Resistor - 220 ohms - LED current limiting resistor - 4 Nos.
    • If red is glowing brighter than green use a higher value such as 330 ohm (or series 270 ohms) for red.
  8. Resistor - 10k - for transistor biasing/current limiting.
  9. Resistor - 220k - for pulling up of sense lines (you may check 100k to 470k as required)
  10. Capacitor - 0.01uF (103) - 4 Nos.
  11. Pluggable connector/PCB solderable screw terminal - 5 way (minimum) - for connecting sense lines from tank/well
  12. Barrel connector - for connecting 12 V from power adapter
  13. PCB solderable screw terminal - 2 way - For connection from Barrel connector to common PCB and PCB to relay excitation - 2 Nos. (Optional)
  14. Wires for line sensing and for motor contact.
  15. Soldering iron and common PCB. You may also use a breadboard.

Understanding the Requirements

Before starting any project understand the requirements so that it will be easier to realize it. This automatic water level controller is developed for meeting following requirements.

  • To show the status of the water level in the tank.
  • To switch ON the motor on the following conditions :-
    • When the water level of the overhead tank is lower than the lowest sense level.
    • The motor should not be switched ON when there is no sufficient water available in the well/ground level tank.
  • To switch OFF the motor on the following conditions
    • When the water level of the overhead tank reaches the highest sense level.
    • When the well/ground level tank water is drained while pumping.
    • When the motor ON time exceeds preset time(highest level sensor not working).
  • The motor should not be toggled continuously as it reaches the highest sense point OR lowest sense point (or due to ripples).
  • The failure of the controller should not affect the manual operation of the motor.

The above shown are the main requirements. There are few optional requirements which are good to have as illustrated below.

  • Provision to show the health/status of the system
  • Provision to show the motor status.
  • Provision to display errors (if found).
  • An alert using a buzzer.

We are trying to realize these requirements with Arduino nano.

  • For powering the motor, one relay is used.
  • To show the status of water level in the tank one bi colour LED is used.
    • It will show Orange if the tank is full (water level greater than highest sense level).
    • It will show Green if the tank is having sufficient water (in between highest and lowest sense level).
    • It will show Red if the tank is not having sufficient water (lower than lowest sense level).
    • If it doesn't glow, there is some issue with the controller. Try turning OFF the system for 1 minute and then turn ON again.
  • The status of the lower tank/motor is shown using the second bi colour LED.
    • It won't glow in normal condition.
    • It will glow green when the motor is switched ON by the controller.
    • It will glow red when the well/ground level tank is not having sufficient water.
    • If it glows Orange, there is some issue with the controller. It means motor is ON even though the well/ground level tank is not having sufficient water. Try turning OFF the system for 1 minute and then turn ON again.
  • In order to avoid the ripples issue, two sensors are provided in the overhead tank for properly verifying the state of water level (during pumping the water and using (draining)).
  • The frequent ON and OFF of the motor is taken care in software by using a minimum time delay for normal operation. Large time delay is provided in case the motor gets stopped due to insufficient water in the well/ground level tank.
  • The manual operation of the motor is not disturbed as we are using non latching relay and we are connecting the relay in parallel to the motor's switch
    • In case the relay becomes short, after turning off the entire power, the connection to the relay can be removed and insulated properly for normal operation.
  • The additional requirement of health/error indication is provided using the arduino nano's inbuilt LED. It wasn't easy but I made a separate function for showing 'n' number of single bit status using that single LED which can be easily identified.
  • The same method used for displaying health/error status is used for buzzer notification.

In the next step we will go through the arduino code.

The Logic and Code

Arduino IDE.png

Here I will try to explain the logic for meeting these requirements and I will try to explain some points of the code also.

This project has four key portions

  1. First portion is monitoring.
    • This portion independently checks the status and glows the LEDs as required.
    • This portion will call required functions for buzzer operation.
  2. Second portion is motor controlling.
    • This portion is actually responsible for turning ON and OFF the motor.
    • This must ensure that
      • The motor is not turning ON and OFF frequently.
      • The motor is not in ON position for a long time.
      • The motor is getting switched OFF in case of insufficient level of water in the well/ground level tank.
  3. Third portion is exception handling.
    • In case of any unexpected condition, the program flow will change to this portion.
    • This won't affect the LED status.
  4. Fourth portion is health/error indication.
    • This portion is showing the health/error of the program
    • Actually it shows the exception status via LED
    • Buzzer notification is also executed with this portion.

The code is attached and I tried to give proper comments in the code itself. I will mention the use of some definitions, variables and functions.

low_tank_nowater_delay - If well/ground level tank level is insufficient, the motor will be turned OFF. The system won't retry unless sufficient water is available in the well/ground level tank for low_tank_nowater_delay time. In between if it shows insufficient water, the timer will reset.

max_motor_run_time - The time limit for the motor to stay in ON condition. This should be set greater than the time required for pumping from lowest level to highest level. This is helpful if the highest level sensor fails.

min_motor_toggle_time - If the relay tries to turn ON or OFF less than min_motor_toggle_time time, the operation won't be executed and it will be isolated. In case of emergency, turning OFF may work irrespective of this time.

top_high_sensor_faulty_delay - If the highest level sensor of the overhead tank is not working, it will stop pumping with the help of max_motor_run_time. But it will wait for the set time. Not mandatory.

top_low_sensor_faulty_delay - If the low level sensor of the overhead tank is not working, it will stop pumping with the help of the high sensor, but it may continue to pump again. In this situation, it is mandatory to make a delay otherwise the motor will turn ON for a short duration (almost continuously).

buzzer_intervel - This is to control the buzzer notification interval.

sequence_count and bits_in_a_sequence - health/error status and buzzer notification is working as a sequence. These are used for properly displaying health/error status and for buzzer notification.

no_delay_helper - This structure is provided for storing any of the delay's start time and end time.

sequence_helper - This structure is provided for properly displaying health/error status and for buzzer notification.

low_tank_no_water_skip - This variable is used for blocking the motor_key generation in the program. Once the ground level tank water level is insufficient, low_tank_no_water_skip will be set and it won't be reset unless ground level tank water is sufficient for low_tank_no_water_delay milliseconds continuously.

motor_key - This is the motor_key which needs to be set for turning ON the motor. Setting this variable doesn't ensure the motor is ON. motor_driver() will turn ON the motor only after ensuring the proper interval. This needs to be reset for turning OFF the motor.

status_byte - The least three bits (as defined by bits_in_a_sequence) of this variable are shown as health status. If all are zero, it means no exceptions found and the system is healthy. If any of the bits is set, it means that an exception is found.

emergency - This variable is used when the motor needs to be turned off (without honoring the time delay provided by min_motor_toggle_time).

indication_updater() - Used for glowing LEDs as required and calls necessary function for buzzer operation. Purely independent function.

motor_driver() - Used for energizing the motor and ensuring it is not frequently turned ON & OFF.

sequence_update() - This needs to be called in all loops otherwise the health display and buzzer notification won't be proper.

exception() - This function is used while any unexpected cases are found. There are three defined exceptions.

  1. Exception 1 indicates that the motor tried to turn ON/OFF frequently. It will be automatically reset after max_motor_run_time duration.
  2. Exception 2 indicates that the overhead tank's low sensor is not working properly. It won't make any issues (other than unintentional motor ON (more frequent than required). This will be automatically reset after top_low_sensor_faulty_delay duration.
  3. Exception 3 indicates that the overhead tank's higher sensor is not working properly (or heavy water usage which doesn't allow the water tank to be full). It will be automatically reset after top_high_sensor_faulty_delay duration.

This program is having a non blocking approach and hence it doesn't use any delay(). If you use any delay() the program may not function as expected.

I haven't explained much about generate_sequence() and sequence_update(). These will be useful for you in following situations

  1. If you are writing non blocking codes.
  2. If you wanna use multiple types of beeps (two beeps, three beeps or beeps with different intervals) for notification.
  3. If you wanna use a single LED for conveying multiple bit statuses.
  4. Only if the data is not changing fastly.

There is a separate library available in github which is designed for this purpose with lot of control. You can visit https://github.com/muralysunam/Health-State-Indicator-OR-Sequence-Generator for more details.

I think this much explanation is only required for the code. If you don't know much, simply adjust low_tank_nowater_delay, max_motor_run_time, min_motor_toggle_time, top_high_sensor_faulty_delay, top_low_sensor_faulty_delay and buzzer_interval as required and use directly.

I hope you all know how to upload the program to arduino nano. You need to open the file in the Arduino IDE. Then connect Arduino to the PC. From Tools, you can select the board as Arduino nano, select the IC and COM port. If the COM port is not visible, you might have bought some clone which needs the CH340 usb driver to be installed separately. After selecting COM port, you can press the upload button in the IDE which will compile the program and upload to the board. After uploading you can open Serial Monitor and check whether any message is sent from Arduino. Mostly you will see "Initialization done" message which ensures the program successfully uploaded to the Arduino.

The cleaned code (AWLC_v1.05_cleaned) is attached which is properly commented. If you wanna know about some history and see some of my change logs, you may download and see AWLC_v1.03 which is not properly commented. In case you are having any difficulty, use AWLC_v1.03. Please note the buzzer won't work in AWLC_v1.03.

In the next step I will try to explain about hardware required for this instructable.

Circuit, Wiring and Implementation

AWLC_200x.png
Lower_Tank_200x.png
Tank_200x.png
Power routing1_200x.png

The coding part is simple. Hardware is not very difficult. But implementation & casing are difficult.

I made my circuit using a common PCB. My soldering skills are bad and I haven't made a box for my current system. My second water level controller was neatly cased.

The schematic is attached below.

Please ensure the following points while making the connections

  • Try to connect all the capacitors near to the arduino board.
  • One capacitor which is not mentioned in the schematic should be connected from VCC to GND of the Arduino board.
  • Ensure pluggable connectors are used in all sense lines (otherwise it won't be easy to remove the board and trouble shoot in any case).
  • You need totally 5 sense lines, out of that two are ground lines.
    • Three lines are from the overhead tank. First line is for the upper level to identify the fill level, the second line is the connection to identify the bottom and the third line is the common line which must be positioned below the bottom level.
    • Two lines from well/ground level tank. This should be near to bottom of the tank
    • ENSURE the upper level sensor is placed well less than the actual capacity of the tank. Similarly the lower level sensor line must be positioned well above the bottom of the tank. Check the diagram. Give sufficient clearance between top and bottom.
    • You may take a PVC pipe and put holes at the required levels, then take SS (stainless steel) 304 wires OR round bars for perfect contact in the water. You can join the copper wires taken from the board and the stainless steel taken from the tank/well, nearby tank/well. After proper joint, use some silica gel or araldite for sealing the joint so that there won't be much corrosion.
    • Check the drawing for more details.
    • If you don't wanna check the well/ground level tank, short L1 & L2.
  • It is better to keep the relay module separately and ensure proper gauge wires with proper insulation are used for relay contact. RELAY AND WIRES USED IN CONTACT PORTION MUST HAVE SUFFICIENT CURRENT CAPABILITY. DON'T REFER MY WIRING.
  • Please take all necessary precautions while working on power lines.
  • Ensure you are labelling all wires (level sense lines, power lines from distribution box, power lines to motor).

Conclusion

DSC06856.JPG
DSC06875.JPG
DSC06872.JPG
DSC06873.JPG
DSC06878.JPG
DSC06862.JPG
DSC06882.JPG
DSC06888.JPG

I hope you were able to complete the project. I am sharing some pictures of the water level controller which I am using in my home. I marked some suggestions and remarks in these photos. I hope you can do better than this. Once again, please don't refer to my photos for assessing the wire type.