Components and supplies
5 mm LED: Red
Arduino Nano R3
Resistor 220 ohm
5 mm LED: Green
RGB Backlight LCD - 16x2
Pushbutton Switch, Pushbutton
Buzzer
5 mm LED: Yellow
Ultrasonic Sensor - HC-SR04
Through Hole Resistor, 120 ohm
HC-12 Wireless Module
Tools and machines
Soldering iron (generic)
Project description
Code
Transmitter unit code
c_cpp
1 2// Created and Designed by Manusha Ramanayake 3// Email : ramanayakemanusha@gmail.com 4 5 6//Transmitter and Sensor Unit 7 8# include <SoftwareSerial.h> 9SoftwareSerial HC12(4, 5); 10 11//Change the values below to calibrate the meter 12int MinLevel = 24; //This is the sensor reading when the tank is empty 13int MaxLevel = 102; //This is the sensor reading when the tank is full 14 15int power = 6; 16long dist_1 = 0; 17long dist_2 = 0; 18int Time = 0; 19int trig = 3; //trigger pin of ultrasonic sensor 20int echo = 2; //Echo pin of ultrasonic sensor 21 22void setup() { 23//To calibrate the sensor delete the comment symbols in the following code 24 //Serial.begin(9600); 25 HC12.begin(9600); 26 pinMode(trig, OUTPUT); 27 digitalWrite(trig, LOW); 28 pinMode(echo, INPUT); 29 pinMode(power, OUTPUT); 30 digitalWrite(power, 1); 31} 32 33 34void loop() { 35 36 Time++; 37 // Standerd code for getting value from the ultrasonic sensor 38 digitalWrite(trig, LOW); 39 delayMicroseconds(5); 40 digitalWrite(trig, HIGH); 41 delayMicroseconds(10); 42 digitalWrite(trig, LOW); 43 44 dist_1 = ( pulseIn(echo, HIGH))*0.034/2; //this gets the value in centimeters 45 46 if (dist_1 < MaxLevel+100){ //change if needed 47 Send_data(dist_1);} 48 49 //debuging code 50 //Serial.print(dist_1); 51 //Serial.print('\n'); 52 delay(500); 53 54} 55void Send_data(int dist_1){ 56//maps the sensor values to a number between 0 and 100 57 int sent = map (dist_1, MinLevel, MaxLevel, 100, 0); 58 59 //This sends data every 100 ms 60 if (Time == 100) { 61 HC12.write(sent); 62 Time = 0; 63 } 64 //This sends data instantly when tank water level is changing 65 if (dist_1 != dist_2) { 66 HC12.write(sent); 67 dist_2 = dist_1; 68 } 69 70 //To calibrate the sensor delete the comment symbols in the following code 71 72 /* 73 Serial.print(" sensor read- "); 74 Serial.print(dist_1); 75 Serial.print(" sent value - "); 76 Serial.print(sent); 77 Serial.print('\n'); 78 */ 79} 80
Receiver unit code
c_cpp
1 2 3// Created and Designed by Manusha Ramanayake 4// Email : ramanayakemanusha@gmail.com 5 6// Reciver Unit 7 8//Pins 9/* 10 * 11 * --LCD-- 12 * RS: pin D12 13 * E: pin D11 14 * D4: pin D2 15 * D5: pin D3 16 * D6: pin D4 17 * D7: pin D5 18 * Vo: A4 19 * D13: gnd 20 * 21 * --HC 12-- 22 * Tx: pin 7 23 * Rx: pin 8 24 * 25 * --Button-- 26 * B1: pin 9 27 * B2: pin 10 28 * 29 * --LED pins-- 30 * G_led: pin A1 31 * R_led: pin A0 32 * Y_led:pin A2 33 * 34 * buzzer:A3 35*/ 36 37// defining libraries 38#include <LiquidCrystal.h> //for LCD 39#include <SoftwareSerial.h> //for HC-12 wireless module 40 41SoftwareSerial HC12(7, 8); 42LiquidCrystal lcd{12, 11, 2, 3, 4, 5}; 43 44int backlight_time = 30000; //The time LCD backlight is turned on in miliseconds 45int buzzer_freq = 1000; //Frequenzy of the buzzer 46 47 48int refill_time = 17000; //delay time for the "refilling.." massege 49int re_disp_time = 35000; //"refilling.." massege display time 50 51 52int refill_Maxtime = 0; 53int button1 = 9; 54boolean backlight_state = 0; 55boolean button2_stat = 0; 56boolean button_check = 0; 57int button2_state[3] ={ 0, 0, 0}; // to check the button2 is pressed when level is low 58int value1 =0; 59int check1 = 0; 60int value2 = 0; 61boolean refill_check[3] = {0, 0, 0}; // to check the button2 is pressed when level is high 62int data = 50; 63int previous_data = 0; 64int button2 = 10; 65int red_led = A0; 66int yellow_led = A2; 67int green_led = A1; 68int buzzer = A3; 69int ground = 13; 70int contrast = A4; 71int backlight = A5; 72 73// variablals for mult-tasking 74long p3Mili = 0; 75long p1Mili = 0; 76long p2Mili = 0; 77long p4Mili = 0; 78long p5Mili = 0; 79 80//custom charachtors for the presantage bar 81byte p10[8] = {B00000, B00000, B00000, B00000, B00000, B00000, B00000, B00000}; 82byte p20[8] = {B10000, B10000, B10000, B10000, B10000, B10000, B10000, B10000}; 83byte p40[8] = {B11000, B11000, B11000, B11000, B11000, B11000, B11000, B11000}; 84byte p60[8] = {B11100, B11100, B11100, B11100, B11100, B11100, B11100, B11100}; 85byte p80[8] = {B11110, B11110, B11110, B11110, B11110, B11110, B11110, B11110}; 86byte p100[8] = {B11111, B11111, B11111, B11111, B11111, B11111, B11111, B11111}; 87 88void setup() { 89 //Serial.begin(9600); 90 lcd.begin(16,2); 91 HC12.begin(9600); 92 93 pinMode(button1, INPUT); 94 pinMode(button2, INPUT); 95 pinMode(red_led, OUTPUT); 96 pinMode(yellow_led, OUTPUT); 97 pinMode(green_led, OUTPUT); 98 pinMode(buzzer, OUTPUT); 99 pinMode(contrast, OUTPUT); 100 pinMode(ground, OUTPUT); 101 pinMode(backlight, OUTPUT); 102 103 lcd.createChar(0,p10); 104 lcd.createChar(1,p20); 105 lcd.createChar(2,p40); 106 lcd.createChar(3,p60); 107 lcd.createChar(4,p80); 108 lcd.createChar(5,p100); 109 110 111 analogWrite(contrast,10); 112 digitalWrite(ground, 0); 113 114 // Boot-up message 115 lcd.setCursor(0,0); 116 lcd.print(" WELCOME "); 117 lcd.setCursor(0,1); 118 lcd.print(" -Manusha-"); 119 120} 121 122void loop() { 123 unsigned long currentMillis = millis(); // Getinng the current timer for multitasking 124 boolean button1_state = digitalRead(button1); //button for backlight 125 backlight_on(button1_state); 126 while(HC12.available ()){ 127 lcd.clear(); 128 129 data = HC12.read(); 130 if ((data<104) or (data>=0)){ 131 previous_data = data; 132 } 133 if ((data>103) or (data<0)){ 134 data = previous_data; 135 } 136 display_bar(data); 137 miniNote(data); 138 display_present(data); 139 } 140 button2_stat = button2_check(data); //Button for muting 141 level_1(data); //led control and alarm 142 143 refill(data); 144 value1 = data; 145 if(value2 < value1){ 146 refill_check[0] = 1; 147 } 148 if((value2 != value1)&(value2 != (value1 + 1))) { 149 refill_Maxtime = 0; 150 } 151 value2 = value1; 152 153 if( (data > 90) & (data <110)){ //for muting the refilling alarm 154 if (button_check == 0){ 155 button_check = digitalRead(button2); 156 } 157 }else button_check = 0; 158 159} 160 161int refill(int data){ 162 unsigned long currentMillis = millis(); 163 if(refill_check[0] == 1){ //Starting the timer for check a seconadry value. 164 if(refill_check[1] == 0){ 165 check1 = data; 166 p4Mili = currentMillis ; 167 refill_check[1] = 1; //starts the second condition 168 } 169 } 170 171 if(refill_check[1] == 1){ 172 if(currentMillis - p4Mili > refill_time){ 173 if(check1 < data){ 174 refill_check[2] = 1; //start to display refilling message 175 refill_check[0] = 0; 176 refill_check[1] = 0; 177 p4Mili = currentMillis ; 178 }else { 179 refill_check[0] = 0; 180 refill_check[1] = 0; 181 182 } 183 }} 184 185 186 if (refill_check[2] == 1){ 187 if((currentMillis - p5Mili < re_disp_time)&((data>=0) & (data<100))&(refill_Maxtime<12000)){ 188 refill_Maxtime++; 189 lcd.setCursor(0,1); 190 lcd.print("Refilling..."); 191 boolean button1_state = 1; //turn the backlight 192 backlight_on(button1_state); 193 button1_state = 0; 194 }else{ 195 refill_Maxtime = 0; 196 refill_check[2] = 0;} 197 198 }else p5Mili = currentMillis ; 199 200 201 202 if( (data > 90) & (data <100)){ 203 if (button_check == 0){ //check for button press 204 if (refill_check[2] == 1){ //check whether refilling is started 205 if(currentMillis - p3Mili < 300){ //buzzer delay time 206 tone(buzzer, buzzer_freq);} 207 208 else if (currentMillis - p3Mili > (map(data, 90, 100, 700, 300))){ //for lowering effect 209 p3Mili = currentMillis; 210 } 211 else noTone(buzzer); 212 213 } 214 }else noTone(buzzer); 215 } else noTone(buzzer); 216 217 return refill_check; 218 } 219 220int button2_check(int data){ 221 //first alarm starts when the level is below 16% 222 if ((data < 16) || (data > 200)){ //for low level alarm 223 if (button2_stat == 0){ 224 button2_stat = digitalRead(button2); 225 if (button2_state[0] == 0){ //turn the backlight whenever button is pressed. 226 button2_state[0] = 1; //only run once when limit is below 15 227 boolean button1_state = 1; 228 backlight_on(button1_state); 229 button1_state = 0; 230 } 231 232 } 233 //Second alarm starts when the level is below 10% 234 else if((button2_state[1] == 0) & (data < 10)){ 235 button2_state[1] = 1; //run once when limit is below 10 236 boolean button1_state = 1; //turn the backlight 237 backlight_on(button1_state); 238 button1_state = 0; 239 button2_stat = 0; 240 } 241//Third alarm starts when the level is below 5% 242 else if((button2_state[2] == 0) & (data < 5)){ 243 button2_state[2] = 1; //run once when limit is below 5 244 boolean button1_state = 1; //turn the backlight 245 backlight_on(button1_state); 246 button1_state = 0; 247 button2_stat = 0; 248 } } 249 250 else { 251 button2_state[0] = 0; 252 button2_state[2] = 0; 253 button2_state[1] = 0; 254 button2_stat = 0; 255 } 256 return button2_stat; 257 } 258 259//This function displays a messages 260void miniNote(int data){ 261 262 if ((data < 8) || (data > 200)){ 263 lcd.setCursor(0,1); 264 lcd.print("Almost Empty "); //Keep 16 charachtors between "" 265 } 266 else if( (data > 7) & (data < 15)){ 267 lcd.setCursor(0,1); 268 lcd.print("Refill "); 269 } 270 else if ((data >14) & (data < 95)){ 271 lcd.setCursor(0,1); 272 lcd.print("Normal "); 273 } 274 else if ((data>94) & (data<101)){ 275 lcd.setCursor(0,1); 276 lcd.print("Tank Full "); 277 } 278 else if ((data>100) & (data<110)){ 279 lcd.setCursor(0,1); 280 lcd.print("Overfolwing "); 281 } 282} 283 284//For the LEDs 285int level_1(int data){ 286 unsigned long currentMillis = millis(); 287 //turn red led and buzzer when level is below 15 288 if ((data < 16) || (data > 200)){ 289 digitalWrite(red_led, 1); 290 digitalWrite(green_led, 0); 291 digitalWrite(yellow_led, 0); 292 293 //for the buzzer 294 if (button2_stat == 0){ 295 if(currentMillis - p3Mili < 300){ 296 tone(buzzer, buzzer_freq);} 297 298 else if (currentMillis - p3Mili > 600){ 299 p3Mili = currentMillis; 300 } 301 else { 302 noTone(buzzer); 303 } 304 } 305 else noTone(buzzer); 306 } 307 //turn yellow led when level is between 15 and 30 308 else if ((data > 15) & (data < 31)){ 309 digitalWrite(yellow_led, 1);//turn yellow led 310 digitalWrite(green_led, 0); 311 digitalWrite(red_led, 0); 312 noTone(buzzer); 313 } 314 315 //turn green led when level is between 30 and 100 316 else if ((data > 30) & (data < 110)){ 317 digitalWrite(green_led, 1);//turn green led 318 digitalWrite(yellow_led, 0); 319 digitalWrite(red_led, 0); 320 321 } 322 else { 323 digitalWrite(red_led, 0); 324 digitalWrite(yellow_led, 0); 325 digitalWrite(green_led, 0); 326 noTone(buzzer); 327 } 328 if ((data > 16)&(data<90)){ 329 noTone(buzzer); 330 } 331} 332 333//turns the backlight on 334int backlight_on(int button1_state){ //for lcd backlight 335 unsigned long currentMillis = millis(); 336 if (button1_state == 1){ 337 p2Mili = currentMillis;} 338 if(currentMillis - p2Mili < backlight_time){ 339 digitalWrite(backlight, 1); 340 } 341 else digitalWrite(backlight, 0); 342 } 343 344// displays the presantage 345void display_present(int data) { 346 //Serial.print('\n'); 347 //Serial.print(data); 348 //Serial.print('\n'); 349 if(data<10){ 350 lcd.setCursor(14, 1);} //for one digit values 351 if((data<100) & (data>9)){ 352 lcd.setCursor(13, 1); //for two digit values 353 } 354 if((data<1000) & (data>99)){ 355 lcd.setCursor(12, 1); //for three digit values 356 } 357 lcd.print(data); 358 lcd.print("%"); 359 360} 361 362//displays the water level as a bar 363void display_bar(int data){ 364 if((data >= 0) & (data < 110)){ 365 int dplay = map(data, 0, 100, 0, 80); 366 if( dplay > 80){ 367 dplay = 80; 368 } 369 int qution = dplay / 5; //for full blocks 370 int reminder = dplay % 5; //for partial blocks 371 372 for(int x=0;x<qution;x++){ 373 lcd.setCursor(x, 0); 374 lcd.write(5); 375 } 376 lcd.setCursor(qution, 0); 377 lcd.write(int(reminder)); 378 379 380 } 381} 382 383
Transmitter unit code
c_cpp
1 2// Created and Designed by Manusha Ramanayake 3// Email : ramanayakemanusha@gmail.com 4 5 6//Transmitter 7 and Sensor Unit 8 9# include <SoftwareSerial.h> 10SoftwareSerial HC12(4, 5); 11 12//Change 13 the values below to calibrate the meter 14int MinLevel = 24; //This is the sensor 15 reading when the tank is empty 16int MaxLevel = 102; //This is the sensor reading 17 when the tank is full 18 19int power = 6; 20long dist_1 = 0; 21long dist_2 = 22 0; 23int Time = 0; 24int trig = 3; //trigger pin of ultrasonic sensor 25int echo 26 = 2; //Echo pin of ultrasonic sensor 27 28void setup() { 29//To calibrate the 30 sensor delete the comment symbols in the following code 31 //Serial.begin(9600); 32 33 HC12.begin(9600); 34 pinMode(trig, OUTPUT); 35 digitalWrite(trig, LOW); 36 pinMode(echo, 37 INPUT); 38 pinMode(power, OUTPUT); 39 digitalWrite(power, 1); 40} 41 42 43void 44 loop() { 45 46 Time++; 47 // Standerd code for getting value from the ultrasonic 48 sensor 49 digitalWrite(trig, LOW); 50 delayMicroseconds(5); 51 digitalWrite(trig, 52 HIGH); 53 delayMicroseconds(10); 54 digitalWrite(trig, LOW); 55 56 dist_1 57 = ( pulseIn(echo, HIGH))*0.034/2; //this gets the value in centimeters 58 59 60 if (dist_1 < MaxLevel+100){ //change if needed 61 Send_data(dist_1);} 62 63 64 //debuging code 65 //Serial.print(dist_1); 66 //Serial.print('\ 67'); 68 delay(500); 69 70 71} 72void Send_data(int dist_1){ 73//maps the sensor values to a number 74 between 0 and 100 75 int sent = map (dist_1, MinLevel, MaxLevel, 100, 0); 76 77 78 //This sends data every 100 ms 79 if (Time == 100) { 80 HC12.write(sent); 81 82 Time = 0; 83 } 84 //This sends data instantly when tank water level is changing 85 86 if (dist_1 != dist_2) { 87 HC12.write(sent); 88 dist_2 = dist_1; 89 90 } 91 92 //To calibrate the sensor delete the comment symbols in the following 93 code 94 95 /* 96 Serial.print(" sensor read- "); 97 Serial.print(dist_1); 98 99 Serial.print(" sent value - "); 100 Serial.print(sent); 101 Serial.print('\ 102'); 103 104 */ 105} 106
Downloadable files
Transmitter unit
Transmitter unit
Transmitter unit
Transmitter unit
Receiver unit
Receiver unit
Receiver unit
Receiver unit
Comments
Only logged in users can leave comments