Long range wireless water level controller using arduino and ultrasonic sensor with the following features:
- Wireless long range using nrf24l01 PA.
- Contactless water level measurement using ultrasonic sensor.
- Compatible with variable tank height
- Relay to automatically turn on/off the water pump
Material Required
- Amazon.in
- Arduino Nano: https://amzn.to/3tIm4n7
- NRF24L01+PA+LNA Module (1pc): https://amzn.to/3TOkCtZ
- 2.4 Inch TFT LCD Display: http://amzn.to/2iNWUCi
- Arduino Uno: https://amzn.to/3u1R8yx
- Ultrasonic Sensor: http://amzn.to/2cUi2Em
- Amazon.com
- 2pcs NRF24L01+PA+LNA Module: https://amzn.to/2rI2ms3
- Arduino Nano: https://amzn.to/3XfaLQQ
- 2.4 Inch TFT LCD Display: http://amzn.to/2EYlpn5
- Arduino Uno: http://amzn.to/2CoHDNl Ultrasonic Sensor: https://amzn.to/3XkPXYq
Arduino Library for 2.4 Inch TFT LCD Display
Transmitter Connection
Ultrasonic sensor Trigger Pin = 3
Ultrasonic sensor Echo Pin = 5
Transmitter Code:
#include <SPI.h>
#include "RF24.h"
#include <NewPing.h>
#define TRIGGER_PIN 3
#define ECHO_PIN 5
#define MAX_DISTANCE 80
RF24 myRadio (A5, 10); //CE, CSN
byte addresses[][6] = {"0"};
NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE);
struct package
{
int distance=1;
};
typedef struct package Package;
Package data;
void setup()
{
Serial.begin(115200);
delay(100);
myRadio.begin();
myRadio.setChannel(115);
myRadio.setPALevel(RF24_PA_MIN);
myRadio.setDataRate( RF24_250KBPS ) ;
myRadio.openWritingPipe( addresses[0]);
delay(100);
}
void loop()
{
myRadio.write(&data, sizeof(data));
data.distance=(sonar.ping_cm());
Serial.print("distance: ");
Serial.print(data.distance);
Serial.println(" cm");
delay(10);
}
Receiver Connection
For LCD
- YP = A1
- XM = A2
- YM = 7
- XP = 6
- LCD_CS = A3
- LCD_CD = A2
- LCD_WR = A1
- LCD_RD = A0
- LCD_RESET = A4
Buzzer pin = A6
Relay pin = A7
Receiver Code:
//EPROM
#include <EEPROM.h>
//LCD
#include <SPFD5408_Adafruit_GFX.h>
#include <SPFD5408_Adafruit_TFTLCD.h>
#include <SPFD5408_TouchScreen.h>
#if defined(__SAM3X8E__)
#undef __FlashStringHelper::F(string_literal)
#define F(string_literal) string_literal
#endif
#define YP A1
#define XM A2
#define YM 7
#define XP 6
#define LCD_CS A3
#define LCD_CD A2
#define LCD_WR A1
#define LCD_RD A0
#define LCD_RESET A4
#define BLACK 0x0000
#define BLUE 0x001f
#define WATER 0x07FF
#define DARKBLUE 0xFFD0
#define RED 0xf800
#define GREEN 0x07e0
#define CYAN 0x07FF
#define MAGENTA 0xF81F
#define YELLOW 0xffe0
#define WHITE 0xffff
TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300);
Adafruit_TFTLCD tft(LCD_CS, LCD_CD, LCD_WR, LCD_RD, LCD_RESET);
//NRF
#include <SPI.h>
#include "RF24.h"
RF24 myRadio (A5, 10); //CE, CSN
struct package
{
int distance;
};
byte addresses[][6] = {"0"};
typedef struct package Package;
Package data;
int switch1Color = 0;
int switch1Color1 = 0;
int old_distance;
int buzzer = A6; // for buzzer
int relay = A7; // for relay
int height = EEPROM.read(0);
int valve = EEPROM.read(3);
int erase;
void setup()
{
Serial.begin(115200);
delay(1000);
pinMode(relay, OUTPUT);
pinMode(buzzer, OUTPUT);
tft.reset();
tft.begin(0x9341);
tft.setRotation(2);
startPage();
myRadio.begin();
myRadio.setChannel(115);
myRadio.setPALevel(RF24_PA_MAX);
myRadio.setDataRate( RF24_250KBPS ) ;
myRadio.openReadingPipe(1, addresses[0]);
myRadio.startListening();
delay(500);
erase = 316;
}
void loop()
{
if ( myRadio.available())
{
while (myRadio.available())
{
myRadio.read( &data, sizeof(data) );
Serial.print("distance: ");
Serial.print(data.distance);
Serial.print(" cm ");
int distance = data.distance;
int rawData = map(distance, valve, height, 61, 316);
Serial.print("new data: ");
Serial.println(rawData);
if ( rawData > erase)
{
tft.fillRect(37, erase, 199, rawData - erase, BLACK);
}
if ( rawData < erase)
{
tft.fillRect(37, rawData, 199, erase - rawData, CYAN);
}
erase = rawData;
/*tft.fillRect(37, erase, 199, old_distance - distance, BLACK);
tft.fillRect(37, 316 - distance, 199, distance, CYAN);
erase = 316 - distance;
old_distance = distance;*/
}
}
else
{
Serial.println("No Data Available...");
}
touchUpdate();
}
void startPage()
{
int x = 3;
int y = 50;
int height = EEPROM.read(0);
int valve = EEPROM.read(3);
tft.fillScreen(CYAN);
tft.setTextSize (2);
tft.setTextColor(BLACK);
tft.setCursor (55, 6);
tft.println("WATER LEVEL");
tft.setCursor (60, 26);
tft.println("CONTROLLER");
tft.fillRect(x, y, 234, 200, GREEN);
tft.drawRect(x, y, 234, 200, BLACK);
tft.setTextSize (3);
tft.drawRect(x + 3, y + 5, 228, 66, BLACK);
tft.setCursor (x + 20, y + 9);
tft.println("TANK HEIGHT");
tft.fillRect(x + 76, y + 38, 83, 28, WHITE);
tft.drawRect(x + 75, y + 37, 85, 30, BLACK);
tft.setCursor (x + 80, y + 43);
tft.println(height);
tft.setCursor (x + 175, y + 43);
tft.println("+");
tft.setCursor (x + 45, y + 43);
tft.println("-");
tft.drawRect(x + 3, y + 82, 228, 66, BLACK);
tft.setCursor (x + 10, y + 86);
tft.println("VALVE HEIGHT");
tft.fillRect(x + 76, y + 115, 83, 28, WHITE);
tft.drawRect(x + 75, y + 114, 85, 30, BLACK);
tft.setCursor (x + 80, y + 120);
tft.println(valve);
tft.setCursor (x + 175, y + 120);
tft.println("+");
tft.setCursor (x + 45, y + 120);
tft.println("-");
tft.fillRect(x + 4, y + 160, 111, 30, WHITE);
tft.drawRect(x + 4, y + 160, 111, 30, BLACK);
tft.setCursor (x + 6, y + 165);
tft.println(" SKIP ");
tft.fillRect(x + 119, y + 160, 111, 30, WHITE);
tft.drawRect(x + 119, y + 160, 111, 30, BLACK);
tft.setCursor (x + 122, y + 165);
tft.println("UPDATE");
takeInput();
}
TSPoint takeInput()
{ int x = 3;
int y = 50;
int height = EEPROM.read(0);
int valve = EEPROM.read(3);
L1:
TSPoint p;
do
{
p = ts.getPoint();
pinMode(XM, OUTPUT);
pinMode(YP, OUTPUT);
}
while ((p.z < 10 ) || (p.z > 1000));
if ( (p.x > 660 && p.x < 740) && (p.y > 220 && p.y < 320) )
{
// height +
tft.fillRect(x + 76, y + 38, 83, 28, WHITE);
tft.setCursor (x + 80, y + 43);
tft.println(height + 1);
height = height + 1;
delay(100);
goto L1;
}
if ( (p.x > 660 && p.x < 740) && (p.y > 620 && p.y < 750) )
{
// height -
tft.fillRect(x + 76, y + 38, 83, 28, WHITE);
tft.setCursor (x + 80, y + 43);
tft.println(height - 1);
height = height - 1;
delay(100);
goto L1;
}
if ( (p.x > 475 && p.x < 555) && (p.y > 220 && p.y < 320) )
{
// valve +
tft.fillRect(x + 76, y + 115, 83, 28, WHITE);
tft.setCursor (x + 80, y + 120);
tft.println(valve + 1);
valve = valve + 1;
delay(100);
goto L1;
}
if ( (p.x > 475 && p.x < 5505) && (p.y > 620 && p.y < 750) )
{
// valve -
tft.fillRect(x + 76, y + 115, 83, 28, WHITE);
tft.setCursor (x + 80, y + 120);
tft.println(valve - 1);
valve = valve - 1;
delay(100);
goto L1;
}
if ( (p.x > 370 && p.x < 440) && (p.y > 500 && p.y < 840) )
{
// skip
homepage();
}
else if ( (p.x > 370 && p.x < 440) && (p.y > 125 && p.y < 460) )
{
// update
EEPROM.update(0, height); //Number 7 at the address number 0
EEPROM.update(3, valve); //Number 50 at the address number 3
homepage();
}
else if ( (p.x > 120 && p.x < 140) && (p.y > 580 && p.y < 680) )//parameterPage (book logo)
{
startPage();
}
else if ( (p.x > 120 && p.x < 140) && (p.y > 730 && p.y < 840) )//homePage
{
homepage();
}
else goto L1;
return p;
}
void homepage()
{
tft.fillRect(0, 0, 240, 320, GREEN);
tft.fillRect(3, 3, 234, 20, BLACK);
tft.setTextColor(CYAN);
tft.setTextSize(2);
tft.setCursor(55, 6);
tft.println("WATER LEVEL");
tft.drawRect(35, 40, 203, 278, BLACK);
tft.drawRect(36, 40, 201, 277, WHITE); //(x, y, w, h, Colour);
tft.fillRect(37, 40, 199, 276, BLACK);
tft.setRotation(1);
tft.fillRect(11, 1, 95, 29, BLACK);
tft.fillRect(13, 3, 95, 29, RED);
tft.drawRect(13, 3, 95, 29, BLACK);
tft.drawRect(0, 7, 12, 15, BLACK);
tft.fillRect(0, 8, 12, 13, CYAN);
tft.drawRect(108, 7, 152, 15, BLACK);
tft.fillRect(108, 8, 152, 13, WHITE);
tft.drawRect(260, 7, 15, 35, BLACK);
tft.drawRect(259, 22, 15, 20, BLACK);
tft.fillRect(260, 8, 14, 35, WHITE);
tft.setTextSize (3);
tft.setTextColor(BLACK);
tft.setCursor (17, 7);
tft.println("MOTOR");
tft.setRotation(2);
}
void touchUpdate()
{
TSPoint p = ts.getPoint();
pinMode(XM, OUTPUT);
pinMode(YP, OUTPUT);
if (p.z > 10 && p.z < 1000)
{
Serial.print("X = "); Serial.print(p.x);
Serial.print("\tY = "); Serial.print(p.y);
Serial.print("\tPressure = "); Serial.println(p.z);
if ( (p.x > 180 && p.x < 420) && (p.y > 780 && p.y < 870) )
{
motorUpdate();
}
if ( (p.x > 120 && p.x < 140) && (p.y > 580 && p.y < 680) )//parameterPage (book logo)
{
startPage();
}
if ( (p.x > 120 && p.x < 140) && (p.y > 730 && p.y < 840) )//homePage
{
homepage();
}
}
}
void motorUpdate()
{
if (switch1Color == 0 )
{
switch1Color = switch1Color + 1 ;
tft.setRotation(1);
tft.fillRect(11, 1, 95, 29, BLACK);
tft.fillRect(13, 3, 95, 29, GREEN);
tft.drawRect(13, 3, 95, 29, BLACK);
tft.fillRect(108, 8, 152, 13, CYAN);
tft.fillRect(260, 8, 14, 35, CYAN);
tft.setTextSize (3);
tft.setTextColor(BLACK);
tft.setCursor (17, 7);
tft.println("MOTOR");
tft.setRotation(2);
digitalWrite(relay, HIGH);
delay (200);
}
else if (switch1Color == 1)
{
switch1Color = switch1Color - 1;
tft.setRotation(1);
tft.fillRect(11, 1, 95, 29, BLACK);
tft.fillRect(13, 3, 95, 29, RED);
tft.drawRect(13, 3, 95, 29, BLACK);
tft.fillRect(108, 8, 152, 13, WHITE);
tft.fillRect(260, 8, 14, 35, WHITE);
tft.setTextSize (3);
tft.setTextColor(BLACK);
tft.setCursor (17, 7);
tft.println("MOTOR");
tft.setRotation(2);
digitalWrite(relay, LOW);
delay (200);
}
}