#include <SPI.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 20, 4); //IC PCF8574T USE 0x27 0x3F
unsigned short C_01 = 0;
unsigned short C_02 = 0;
unsigned short C_03 = 0;
unsigned short C_04 = 0;
unsigned short C_05 = 0;
unsigned short P_01 = 0;
unsigned short P_02 = 0;
unsigned short P_03 = 0;
unsigned short P_04 = 0;
unsigned short P_05 = 0;
byte flag_01 = 0;
byte flag_02 = 0;
byte flag_03 = 0;
byte flag_04 = 0;
byte flag_05 = 0;
byte led_sys = 2;
byte sw_start = 3;
int pump1 = 4;
byte led_drain = 5;
byte led_lowtank = 6;
byte led_fulltank = 7;
int pizo = 8; //กำหนดขา 11 (pizzo) เป็นชนิด int
int tricker = 10; //กำหนดขา 13 (Tricker) เป็นชนิด int (จำนวนเต็ม)
int echo = 9; //กำหนดขา 12 (Echo) เป็นชนิด int (จำนวนเต็ม)
int temp01 = A0; // กำหนดขา A0 (temp01) เป็นชนิด int (จำนวนเต็ม)
int pressure_01 = A1; // กำหนดขา A1 (pressure_01) เป็นชนิด int (จำนวนเต็ม)
//******************* กำหนดชนิดค่าตัวแปร *******************//
float cm = 0; //กำหนดค่า cm (เซ็นติเมตร) เป็นชนิด int (จำนวนเต็ม)และให้มีค่าเริ่มต้นที่ 0
int inch = 0; //กำหนดค่า inch (นิ้ว) เป็นชนิด int (จำนวนเต็ม)และให้มีค่าเริ่มต้นที่ 0
long distance = 0; //กำหนดค่าระยะทาง (distance) เป็นชนิด long (มีทศนิยม)
byte led_state = 1; //กำหนดตัวแปรสถานะ led_sys ชื่อ state เป็นชนิด byte มีค่าเป็น HIGH
byte pump1_status = 0; //ค่าตัวแปร pump1_status เป็นชนิด byte มีค่าเริ่มต้น = 0
byte press_status = 0; //ค่าตัวแปร press_status เป็นชนิด byte มีค่าเริ่มต้น = 0
byte sw_status = 0; //ค่าตัวแปร sw_status เป็นชนิด byte มีค่าเริ่มต้น = 0
int water_L1 = 30; //ระดับน้ำ (Water Level 1) ในแท็งค์ 30 cm. ระยะห่างจากหัว Sensor ถึงระดับน้ำ
int water_L2 = 35; //ระดับน้ำ (Water Level 2) ในแท็งค์ 35 cm. ระยะห่างจากหัว Sensor ถึงระดับน้ำ
int water_L3 = 150; //ระดับน้ำ (Water Level 3) ในแท็งค์ 150 cm. ระยะห่างจากหัว Sensor ถึงระดับน้ำ
byte water_S1 = 0; //ตัวแปรสถานะของน้ำในถัง Full Tank water_S1 = HIGH
byte water_S2 = 0; //ตัวแปรสถานะของน้ำในถัง Low Tank water_S2 = HIGH
float press_L1 = 40.50; //Pressure Level กำหนดค่าแรงดันที่จะให้ระบบ Drain ทำงาน (40.5 psi, หรือ 2.79 bar)
float val_psi = 0;
float val_bar = 0;
float val_kcm = 0;
float val_kpa = 0;
byte drain_status = 0;
bool button_state_01 = false; //ตัวแปรเก็บสถานะของ sw_start เป็นชนิด Boolean มีค่า 2 สถานะ คือ True, False
void setup() {
Serial.begin(9600);
lcd.begin(20, 4); //เริ่มต้นใช้งานจอ LCD เป็นชนิด 20 ตัวอักษร 4 แถว
lcd.clear(); //Clear หน้าจอ LCD ทั้งหมดให้ว่าง
lcd.backlight(); //เปิด Back Light
lcd.setCursor(0, 0); //Set ตำแหน่ง Cursor ไปที่ อัษรตัวที่ 1 แถวที่ 1
lcd.display(); //เปิดใช้งานจอ LCD
pinMode(led_sys, OUTPUT); //กำหนด led_sys = ขา 2 เป็นขา Output
pinMode(sw_start, INPUT_PULLUP); //กำหนด sw_start = ขา 3 เป็นขา Input_pullup
pinMode(pump1, OUTPUT); //กำหนด pump1 = ขา 8 เป็นขา Output
pinMode(led_drain, OUTPUT); //กำหนด led_drain = ขา 5 เป็นขา Output
pinMode(led_lowtank, OUTPUT); //กำหนด led_lowtank = ขา 6 เป็นขา Output
pinMode(led_fulltank, OUTPUT); //กำหนด led_fulltank = ขา 7 เป็นขา Output
pinMode(tricker, OUTPUT); //กำหนด tricker = ขา 13 เป็นขา Output
pinMode(echo, INPUT); //กำหนด echo = ขา 12 เป็นขา Input
pinMode(pizo, OUTPUT); //กำหนด pizo = ขา 11 เป็นขา Output
pinMode(temp01, INPUT); //กำหนดขา temp01 (ขา A0) เป็นขา INPUT; (รับสัญญาณ Analog จาก NTC Termisistor 10K)
pinMode(pressure_01, INPUT); //กำหนดงขา pressure_01 (ขา A1) เป็นขา output; (sensor แรงดัน)
}
void loop() {
led_system();
ultarsonic();
push_start();
pressure_s1();
display();
Serial.print("Pump_Status : ");
Serial.print(pump1_status);
Serial.print(" Pressure Status : ");
Serial.print(press_status);
Serial.print(" Pump : ");
Serial.print(digitalRead(pump1));
Serial.print(" button_state_01 : ");
Serial.println(button_state_01);
}
/**************************** Function System LED Brink Program ***************************/
void led_system() {
C_01 = millis();
if (C_01 - P_01 >= 200) { // ถ้าค่าของเวลาปัจุบัน (C_01) - เวลา P_01 มีค่ามากกว่า 200 mS ถ้าค่าเป็นจริง
P_01 = C_01; // ให้ค่าเวลาที่ผ่านมา (P_01) = เวลาปัจจุบัน (C)
flag_01 = 1; // ให้ flag_01 มีค่า = 1 (เปลี่ยนสถานะจาก 0 ให้เป็น 1)
if (flag_01 == 1) { flag_01 = 0; } // ถ้า flag_01 = 1 ให้ Clear flag_01 = 0
if (led_state == 1) { led_state = 0; } // ถ้าค่าของ state_01 = 1 ให้ Clear ค่า state_01 = 0
else if (led_state == 0) { led_state = 1; } // ถ้าค่าของ state_01 = 0 ให้ Clear ค่า state_01 = 1
digitalWrite(led_sys, led_state); }
}
/**************************** Function Ultarsonic Water Level *****************************/
void ultarsonic() {
C_02 = millis();
if (C_02 - P_02 >= 250) { // ถ้าค่าของเวลาปัจุบัน (C) - เวลา P_04 มีค่ามากกว่า 1000 mS ถ้าค่าเป็นจริง
P_02 = C_02; // ให้ค่าเวลาที่ผ่านมา (P_04) = เวลาปัจจุบัน (C)
flag_02 = 1; // เให้ flag_04 มีค่า = 1 (เปลี่ยนสถานะจาก 0 ให้เป็น 1)
if (flag_02 == 1) { flag_02 = 0; } // ถ้า flag_04 = 1
for (int i = 0; i <= 10; i++) {
digitalWrite(tricker, LOW); //สั่งให้ขา tricker (ขา 2) เป็น LOW
digitalWrite(tricker, HIGH); //สั่งให้ขา tricker (ขา 2) เป็น HIGH
digitalWrite(tricker, LOW); //สั่งให้ขา tricker (ขา 2) เป็น LOW
distance = pulseIn(echo, HIGH); //รับสัญญาณ HIGH จากขา echco แล้วไปเก็บไว้ที่ distance
cm = distance * 0.0343 / 2; //เสียงเดินทางด้วยความเร็ว 346.3 m/S ที่อุณหภูมิ 25c (346.3)
inch = distance * 0.01362 / 2; //แปลงหน่วยจาก cm. เป็นinch = 0.0346/2.54
delay (10); }
if ((cm < water_L1) && (cm <= water_L2)) { //ถ้าระดับน้ำในแท็งค์ถึง Sensor ห่างน้อยกว่า water_L1 (30 cm.) และมีค่ามากกว่าหรือเท่ากับ water_L2 (35 cm.)
water_S1 = 1; //ให้ตัวแปรสถานะของน้ำในถัง Full Tank water_S1 = HIGH (ค่าเดิมเป็น LOW)
water_S2 = 0; //ให้ตัวแปรสถานะของน้ำในถัง Low Tank water_S2 = LOW (ค่าเดิมเป็น LOW)
pump1_status = 0; //ให้ค่าตัวแปรสถานะของ PUMP = LOW
digitalWrite(led_fulltank, HIGH); //ให้ LED FULL TANK ติด
digitalWrite(led_lowtank, LOW); //ให้ LED LOW TANK ดับ
if (press_status == 1) { //ถ้าสถานะของแรงดัน = 1
digitalWrite(pump1, HIGH); //ให้ Pump1 ทำงาน
pump1_status = 1;
delay(20); }
if((press_status == 0)) {
digitalWrite(pump1, LOW); } //ให้ PUMP หยุดการทำงาน
}
else if ((cm >= water_L2) && (cm <= water_L3)) { //ถ้าระดับน้ำในแท็งค์ถึง Sensor ห่างมากกว่า water_L2 (35 cm.) และมีค่าน้อยกว่าหรือเท่ากับ water_L3 (150 cm.)
water_S1 = 0; //ให้ตัวแปรสถานะของน้ำในถัง Full Tank water_S1 = LOW (ค่าเดิมเป็น LOW)
water_S2 = 0; //ให้ตัวแปรสถานะของน้ำในถัง Low Tank water_S2 = LOW (ค่าเดิมเป็น LOW)
pump1_status = 1; //ให้ค่าตัวแปรสถานะของ PUMP = HIGH
digitalWrite(led_fulltank, LOW); //ให้ LED FULL TANK ดับ
digitalWrite(pump1, HIGH); //ให้ PUMP ทำงาน
digitalWrite(led_lowtank, LOW); //ให้ LED LOW TANK ดับ
delay (100); }
else if (cm > water_L3) { //ถ้าระดับน้ำในแท็งค์ถึง Sensor ห่างมากกว่า water_L3 (150 cm.)
water_S1 = 0; //ให้ตัวแปรสถานะของน้ำในถัง Full Tank water_S1 = LOW (ค่าเดิมเป็น LOW)
water_S2 = 1; //ให้ตัวแปรสถานะของน้ำในถัง Low Tank water_S2 = HIGH (ค่าเดิมเป็น LOW)
pump1_status = 1; //ให้ค่าตัวแปรสถานะของ PUMP = HIGH
digitalWrite(led_fulltank, LOW); //LED Full Tank ดับ
digitalWrite(pump1, HIGH); //สั่งให้ Pump บาดาล ทำงาน สูบน้ำไปเก็บไว้ใน Tank
digitalWrite(led_lowtank, HIGH); //LED Low Tank ติด
tone(pizo, 600, 50); //Pizzo ส่งสัญญาณเตือน 60 Hz ทุก 100 mS
delay(200);
digitalWrite(led_lowtank,LOW); }
else { pump1_status = 0; }
}
//Serial.print("Distance : ");
//Serial.print(cm);
//Serial.println(" cm.");
}
/******************************** Function Pressure Sensor ********************************/
void pressure_s1() {
float analogValue_01 = analogRead(pressure_01);
int spec_sensor = 60; // pressure sensor 30 psi : 4.5 v
val_psi = (analogValue_01 / (1023 / spec_sensor)); // ค่าที่อ่านได้ / (1203 / สเป็คของ Pressure Senson ? psi)
val_bar = (val_psi * 0.0689475729); // 1 psi = 0.0689475729 bar
val_kcm = (val_psi * 0.070307); // 1 psi = 0.070307 Kg/cm2
val_kpa = (val_psi * 6.89476); // 1 psi = 6.89476 Kpa
C_05 = millis(); // ตัวแปรเก็บค่าเวลาปัจจุบัน กำหนดให้เป็น millis()
//********* ถ้าความดันในระบบกรองกรองทราย สูงกว่าค่าที่กำหนด ให้หน่วงเวลาก่อนเปิดระบบ Darin น้ำทิ้ง 0.2 วินาที ********//
if ((val_psi >= press_L1)) { //ถ้าค่าแรงดันที่อ่านได้ (val_psi) มีค่าเท่ากับหรือมากกว่า press_L1 (40.5 psi 2.79 bar)
for (int i = 0; i <= 10; i++) { //วนลูปตรวจเช็คโดยใช้คำสั่ง for ตรวจเช็คแรงดันในชุดกรองทราย โดยวน 10 ครั้ง ทุกๆ 20 mS
press_status = 1; //เมื่อเป็นจริง ให้ค่าตัวแปร press_status = 1
pump1_status = 1; //เมื่อเป็นจริง ให้ค่าตัวแปร pump1_status = 1
digitalWrite(pump1, HIGH); //สั่งให้ Pump1 ทำงาน เพื่อดันน้ำให้ล้าระบบกรอง
digitalWrite(led_drain, HIGH); //สั่งเปิด Solenoid valve เพื่อทำการ Darin น้ำในระบบกรองทรายทิ้ง
delay(20); }
}
//***************************** ส่วนของ Program Muti Tasking หน่วงเวลา 30 วินาที่ **************************//
if (C_05 - P_05 >= 30000) { // ถ้าค่าของเวลาปัจุบัน (C_05) - เวลา P_05 มีค่ามากกว่า 30000 mS (30 sec.) ถ้าค่าเป็นจริง
P_05 = C_05; // ให้ค่าเวลาที่ผ่านมา (P_05) = เวลาปัจจุบัน (C_05)
flag_05 = 1; // ให้ flag_05 มีค่า = 1 (เปลี่ยนสถานะจาก 0 ให้เป็น 1)
if (flag_05 == 1) { flag_05 = 0; } // ถ้า flag_05 = 1 Clear flag_05 = 0
//********************** หลังจากมีการ Drain น้ำเพื่อล้างเครื่องกรอง เป็นเวลา 30 Sec. แล้ว ***********************//
pump1_status = 0; // ให้ค่าตัวแปร pump1_status กลับไปมีค่า = 0
press_status = 0; // ให้ค่าตัวแปร press_status กลับไปมีค่า = 0
if ((pump1_status == 0) && (press_status == 0)) { //ถ้าตัวแปร pump1_status มีค่าเท่ากับ 0, และ press_status มีค่าเท่ากับ 0
digitalWrite(pump1, LOW); //สั่งให้ Pump 1 หยุดการทำงาน
digitalWrite(led_drain, LOW); } //สั่งให้ led_darin ดับ
}
// Serial.print("Pressure : ");
// Serial.print(val_psi);
// Serial.print(" psi ");
// Serial.print(val_bar);
// Serial.print(" bar ");
// Serial.print(val_kcm);
// Serial.print(" K/cm2 ");
// Serial.print(val_kpa);
// Serial.println(" Kpa");
}
// pressure sensor (1 psi = 0.0689475729 bar = 0.070307 kg/cm2 = 6.89476 Kpa)
// 05 psi (0.3447378647 bar) = 0.900 v/psi
// 15 psi (1.034213594 bar) = 0.300 v/psi
// 30 psi (2.068427188 bar) = 0.150 v/psi
// 60 psi (4.1368 bar) = 0.075 v/psi
// 100 psi (6.8947572932 bar) = 0.045 v/psi
// 150 psi (10.34213594 bar) = 0.030 v/psi
// 200 psi (13.789514586 bar) = 0.023 v/psi
// 300 psi (20.68427188 bar) = 0.015 v/psi
// 500 psi (34.473786466 bar) = 0.009 v/psi
// 1000 psi (68.947572932 bar) = 0.0045 v/psi
/************************************** Function LCD **************************************/
void display() {
String ft = "FULL TANK";
String pw = "PUMP WORK";
String lt = "LOW TANK";
String dw = "DRAIN WATER";
String nm = "NORMAL";
C_04 = millis(); // ตัวแปรเก็บค่าเวลาปัจจุบัน กำหนดให้เป็น millis()
if (C_04 - P_04 >= 250) { // ถ้าค่าของเวลาปัจุบัน (C) - เวลา P_10 มีค่ามากกว่า 50 mS ถ้าค่าเป็นจริง
P_04 = C_04; // ให้ค่าเวลาที่ผ่านมา (P_10) = เวลาปัจจุบัน (C)
flag_04 = 1; // เให้ flag_10 มีค่า = 1 (เปลี่ยนสถานะจาก 0 ให้เป็น 1)
if (flag_04 == 1) { flag_04 = 0; } // ถ้า flag_10 = 1 Clear flag_10 = 0
lcd.setCursor(0, 0);
lcd.print(" GUNTAR SUBMER PUMP");
lcd.setCursor(0, 1); //Set Cursor ของ LCD ไปยังแถวที่ 1 ตำแหน่งที่ 1
lcd.print(cm); //แสดงผล counter_01
lcd.setCursor(5, 1); //Set Cursor ของ LCD ไปยังแถวที่ 1 ตำแหน่งที่ 5
lcd.print("cm "); //แสดงผล counter_01
if ((water_S1 == HIGH) && (water_S2 == LOW)) { //ถ้าค่าตัวแปร water_S1 = 1 และ water_S2 = 0
lcd.setCursor(9, 1); //Set Cursor ของ LCD ไปยังแถวที่ 1 ตำแหน่งที่ 8
lcd.print("");
lcd.print(ft); //Clear แถวที่ 2 (16 ตัวอักษรให้ว่าง)
} else if ((water_S1 == LOW) && (water_S2 == LOW)) {
lcd.setCursor(9, 1); //Set Cursor ของ LCD ไปยังแถวที่ 1 ตำแหน่งที่ 8
lcd.print("");
lcd.print(pw);
} else if ((water_S1 == LOW) && (water_S2 == HIGH)) { //ต่อกับขา 6
lcd.setCursor(9, 1); //Set Cursor ของ LCD ไปยังแถวที่ 1 ตำแหน่งที่ 8
lcd.print("");
lcd.print(lt); }
lcd.setCursor(0, 2);
lcd.print("Pressure : ");
lcd.setCursor(11, 2);
lcd.print(val_psi);
lcd.setCursor(17, 2);
lcd.print("psi");
lcd.setCursor(12, 3);
lcd.print(val_bar);
lcd.setCursor(17, 3);
lcd.print("bar");
if (press_status == 1) { //ถ้าแรงดันในชุดกรองทราย มีความดันสูงกว่าค่าตัวแปร press_status
lcd.setCursor(0, 3);
lcd.print(" ");
lcd.setCursor(0, 3);
lcd.print(dw); }
else {
lcd.setCursor(0, 3);
lcd.print(" ");
lcd.setCursor(1, 3);
lcd.print(nm); }
}
}
/**************************** Function Switch Push ON Push OFF ****************************/
void push_start() {
if (!digitalRead(sw_start)) { //ถ้าค่าของ sw_start_01 ไม่เท่ากับ HIGH (เนื่องจาก sw_start เป็น INPUT_PULLUP)
button_state_01 = !button_state_01; //ค่าเริ่มต้นของ button_state_01 = false เปลี่ยนเป็น True
if(button_state_01 == true) { //ถ้าค่าของ button_state_01 เท่ากับ true
pump1_status = 1; //ให้ค่าของตัวแปร pump1_status = 1
press_status = 1; //ให้ค่าของตัวแปร press_status = 1
digitalWrite(pump1, button_state_01); //ให้ pump1 มีค่า = button_state_01 (มีค่าเป็น true หรือ HIGH)
delay(100);
} else if (button_state_01 == false) { //ถ้าค่าของ button_state_01 = false (0)
pump1_status = 0; //ให้ค่าของตัวแปร pump1_status = 0
press_status = 0; } //ให้ค่าของตัวแปร press_status = 0
C_05 = millis(); // ตัวแปรเก็บค่าเวลาปัจจุบัน กำหนดให้เป็น millis()
if (C_05 - P_05 >= 1000) { // ถ้าค่าของเวลาปัจุบัน (C) - เวลา P_10 มีค่ามากกว่า 50 mS ถ้าค่าเป็นจริง
P_05 = C_05; // ให้ค่าเวลาที่ผ่านมา (P_10) = เวลาปัจจุบัน (C)
flag_05 = 1; // เให้ flag_10 มีค่า = 1 (เปลี่ยนสถานะจาก 0 ให้เป็น 1)
if (flag_05 == 1) { flag_05 = 0; } // ถ้า flag_10 = 1 Clear flag_10 = 0
button_state_01 = false; } // หน่วงเวลา 500 ms แล้วให้ค่าของ button_state_01 เท่ากับ false (0)
}
}