Khi ta truy cập vào phpMyadmin, ta sẽ thấy được giao diện quản lý Database (Hình 5.12). Ta thấy được phía bên trái, trong mục phpMyadmin, Database “wrjkwmkr_Database” mà ta đã tạo. Ta bấm vào nút dấu cộng “+” bên cạnh nó, để tạo mới một bảng lưu dữ liệu. Khi nhấn vào nút dâu cộng “+”, ta nhấn New để tạo bảng, giao diện tạo bảng được trình bày trong hình 5.13.
Hình 5. 13: Giao diện tạo mới bảng lưu dữ liệu
Nhập tên bảng ở mục “table name”, và tên các trường lưu dữ liệu vào cột “Name”. Kiểu dữ liệu ở cột “Type” tùy thuộc vào từng loại dữ liệu. Sau khi đã nhập hoàn tất, ta sẽ được một bảng có các trường dùng để lưu dữ liệu như Hình 5.14 sau:
Ta có thể tạo rất nhiều bảng để lưu dữ liệu, mỗi bảng có thể tạo rất nhiều trường. Trong bảng “dung_iot”, nhóm đã tạo 26 trường dùng để lưu dữ liệu cũng như tín hiệu điều khiển.
Vậy là việc tạo một Server dùng để lưu dữ liệu và tín hiệu điều khiển dùng cho đồ án đã hoàn tất.
KẾT LUẬN
Trong đề tài này, nhóm chúng em đã thiết kế thành công mô hình hệ thống điều khiển, giám sát phân tán vườn thông minh và đưa ra các phương án khảo sát.
Đề tài hoạt động dựa trên công nghệ truyền thông Lora và Internet, giúp người dùng có thể dễ dàng điều chỉnh các điều kiện sinh trưởng của cây trồng, giúp đạt năng suất cao mà chỉ với một vài thao tác đơn giản. Nhờ đó, người trồng có thể chăm sóc cả khu vườn rộng lớn mà không cần tiêu tốn nhiều thời gian và công sức. Từ đó có thể giảm thiểu nhân công chăm sóc, giúp giảm chi phí sản xuất một cách đáng kể. Bên cạnh đó, việc điều chỉnh các điều kiện sinh trưởng của cây trồng này được thực hiện bằng cách điều khiển từ xa, không cần điều khiển trực tiếp, do đó có thể giảm thiểu tối đa việc tai nạn lao động.
Hơn nữa, hệ thống sử dụng công nghệ Lora và Internet, chúng đều là các công nghệ an toàn đối với sức khỏe của con người. Đồng thời, hệ thống không sinh ra sản phẩm phụ trong quá trình hoạt động. Do đó, hệ thống là an toàn đối với con người và môi trường. Bên cạnh đó, việc ứng dụng Lora để xây dựng các hệ thống IoT giúp góp phần mở rộng mạng Lora, tạo nên một mạng IoT kết nối vạn vật toàn thế giới.
Về kết quả đạt được:
• Đã khảo sát được các hệ thống vườn thông minh trong thực tế và đưa ra phương án thiết kế cho mô hình trong đề tài.
• Đã thiết kế thành công một mô hình hệ thống điều khiển, giám sát phân tán vườn thông minh sử dụng 5 vi điều khiển Arduino và ESP8266 có các chức năng cơ bản như đã đề ra. Mô hình hoạt động tốt và ổn định. Trong mô hình có bốn vi điều khiển Arduino Uno và Arduino Nano điều khiển và thu thập thông tin từ cảm biến nhiệt độ, độ ẩm của các khu vực trong vườn. Các vi điều khiển ở các khu vực này được kết nối với vi điều khiển ESP8266 ở trung tâm. Vi điều khiển trung tâm này sẽ truyền nhận dữ liệu lên Server thông qua Internet giúp người dùng có thể theo dõi tình trạng vườn.
• Đã lập trình cho các vi điều khiển ở khu vực và trung tâm, đã thực hiện đúng chức năng của hệ thống. Các trạm khu vực hoạt động rất ổn định, thu thập dữ liệu chính xác cũng như điều khiển trơn tru các thiết bị vận hành tại chính các
khu vực đó. Đồng thời, trạm điều khiển trung tâm hoạt động tốt, không bị lỗi, đáp ứng tốt yêu cầu của hệ thống đã đề ra từ lúc đầu.
• Trong mô hình đề tài đã thực hiện thành công trong việc kết nối Lora giữa các vi điều khiển và kết nối Internet giữa vi điều khiển và Server. Việc kết nối truyền thông giữa các vi điều khiển hoạt động tốt. Dữ liệu từ trạm khu vực gửi lên trạm điều khiển trung tâm cũng như từ trạm điều khiển trung tâm xuống trạm khu vực thì không bị lỗi, bị méo hay mất dữ liệu. Bên cạnh đó, dữ liệu mà trạm trung tâm gửi lên Server cũng hoàn toàn đầy đủ, không bị lỗi hay bất cứ vấn đề gì. Truyền nhận dữ liệu giữa các vi điều khiển cũng như giữa trạm trung tâm với Server có tốc độ cao, chính xác.
• Thiết kế thành công giao diện giám sát hệ thống mô hình điều khiển và giám sát phân tán vườn thông minh trên Web giúp người dùng giám sát các thông số tại vườn.
Hiện tại hệ thống của nhóm chỉ là mô hình thử nghiệm cũng như thiếu kinh nghiệm nên nhóm chưa thực hiện xây dựng nhiều chức năng hơn cho mô hình. Chính vì vậy, nhóm xin đưa ra hướng phát triển cho đề tài như sau:
• Có thể xây dựng nhiều chế độ hoạt động hơn cho hệ thống, tỉ như tự động tưới tiêu, điều chỉnh môi trường sống thích hợp cho từng loại cây trồng theo từng mùa khác nhau.
• Mở rộng phạm vi thu thập dữ liệu hơn bằng cách tăng số lượng trạm khu vực cũng như trạm thu thập dữ liệu trung tâm nếu vườn có diện tích lớn.
• Tích hợp việc giám sát vườn bằng Camera.
• Đưa mô hình ra vận hành ngoài thực tế.
TÀI LIỆU THAM KHẢO
[1] Nguyễn Duy Đức (2013). Vườn thông minh, Luận văn tốt nghiệp, Trường đại học Công Nghệ TP.HCM.
[2] Lê Đặng Thái Phong, Nguyễn Trọng Nhiên (2021), Hệ thống IoT phục vụ cho nông nghiệp ứng dụng công nghệ Lora, Luận văn tốt nghiệp, Trường đại học Sư phạm Kỹ thuật, Đại học Đà Nẵng.
[3] Lê Hồ Bảo Anh, Nguyễn Trần Quốc Thái (2017), Thiết kế vườn thông minh dựa trên OpenHab, Đồ án môn học, Trường đại học Bách khoa, Đại học quốc gia TP. Hồ Chí Minh.
[4] Yang Jiaqiang, Jin Yulong, Gao Jian (2013), An Intelligent Green House Control System, TELKOMNIKA, Vol.11, No.8, tr.4631
[5] Bộ Giáo dục và đào tạo (2021), Sinh học 11, Tái bản lần thứ 13, Nhà xuất bản Giáo dục Việt Nam.
[6] TS. Hoàng Minh Sơn (2005), Hệ thống điều khiển phân tán, Bộ môn điều khiển tự động, Khoa Điện, Trường đại học Bách Khoa Hà Nội.
[7] HSHOP Điện tử và Robot, Mạch thu phát RF SPI Lora SX1278 433MHz Ra-02 Ai- Thinker, https://hshop.vn/products/mach-thu-phat-rf-spi-lora-sx1278-433mhz-ra-02 (16/05/2022)
[8] Wikipedia, ESP8266, https://vi.wikipedia.org/wiki/ESP8266. (Ngày truy cập: 16/12/2022)
[9] NSHOP Linh kiện điện tử, Module thu phát Wifi ESP8266 NodeMCU Lua CP2102, https://nshopvn.com/product/module-thu-phat-wifi-esp8266-nodemcu-lua- cp2102/ (Ngày truy cập :16/05/2022)
[10] VINA FE, Cảm biến nhiệt độ, độ ẩm DHT11, https://dientutuonglai.com/cam- bien-nhiet-do-va-do-am-dht11.html (Ngày truy cập: 16/05/2022)
[11] E360, Cảm biến độ ẩm đất, https://dientu360.com/cam-bien-do-am-dat. (Ngày truy cập: 16/05/2022)
[12] Ngô Huỳnh Ngọc Khánh (2014), Giới thiệu về Arduino, http://arduino.vn/bai- viet/. (Ngày truy cập: 18/05/2022)
[13] VINA FE, Giới thiệu về Arduino, https://dientutuonglai.com/gioi-thieu-arduino- nano.html (Ngày truy cập: 16/05/2022)
[14] Công ty TNHH Công nghệ Đo lường BFF, Lora là gì?, https://bff-tech.com/lora-
la-gi/. (Ngày truy cập: 18/05/2022)
[15] Taoufik Bouguera, Jean-Francois Diouris, Jean-Jacques Chaillout, Randa Jaouadi and Guillaume Andrieux (2018), Energy Consumption Model for Sensor Nodes Based on LoRa and LoRaWAN, Multidisciplinary Digital Publishing Institute (MDPI), Sensors 2018, 18, 2104 tr.9
[16] Công ty TNHH công nghệ Việt Thái Dương, Công nghệ Lora và LoraWAN,
https://cnttshop.vn/blogs/tin-tuc/cong-nghe-lora-va-lorawan-11111 (Ngày truy cập: 16/05/2022)
[17] Tập đoàn viễn thông quân đội Viettel, Internet là gì? Internet có lợi ích gì trong cuộc sống?, https://capquangviettel.vn/internet-la-gi/. (Ngày truy cập: 26/05/2022) [18] Tập đoàn FPT, Tìm hiểu chi tiết về Wifi: Wifi là gì và ưu nhược điểm của Wifi,
https://fptshop.com.vn/tin-tuc/danh-gia/wifi-la-gi-tim-hieu-chi-tiet-ve-wifi-59065,
PHỤ LỤC
Phụ lục 1: Chương trình của trạm điều khiển trung tâm
/*
Author: Dang Quoc Dung Control led: On: LOW */ #include <ESP8266WiFi.h> #include <ESP8266HTTPClient.h> #include <WiFiClient.h> #include <LoRa.h> #include <SPI.h> #include <ArduinoJson.h> #include <time.h> #include <WiFiManager.h>
// Khai báo nguyên mẫu hàm
void Connect_Wifi();
void Lora_Data_Processing(String payload);
void SQL_Data_Processing(String payload);
void Send_Data_To_SQL();
void Get_Data_From_SQL();
void Connect_Lora();
void Send_Lora(int ID, String device1, String device2, int status1, int status2);
void Send_Answer_To_Slave(int ID, String Status);
void Request(int ID);
void Receive_Lora();
void Update_Data_to_SQL();
void Led_Blink(int x);
void Get_Time();
void Config_Get_Time();
void Auto_Mode_Control();
void Update_Auto_Mode(int c);
void configModeCallback (WiFiManager *myWiFiManager);
void setWifi(); void Clear_Old_Wifi(); void Request_All_Data(); void Auto_Control(); int timezone = 7*3600; int dst = 0;
// Khai báo chân SS, RST, DIO0 cho chip Lora
#define SS 15
#define RST 0 // D3
#define DIO0 4 // D2
// Khai báo chân đèn led
#define Led_Wifi 2 // D4
#define Led_Lora 16 // D0
// Khai bao nut nhan
#define btn 5 // D1
WiFiClient wificlient;
// Khai báo biến
long last = 0; long last1 = 0; long last2 = 0; long last3 = 0; long wait = 0; int counter = 11; int DV1, DV2, DV3, DV4, DV5, DV6, DV7, DV8; String payload = ""; String Data_Receive = "";
float temp, temp1, temp2, temp3, temp4;
float humi, humi1, humi2, humi3, humi4;
float soilhumi, soilhumi1, soilhumi2, soilhumi3, soilhumi4;
unsigned char id, rq;
int hour, minute;
int time_stop, time_compare;
boolean check;
boolean check_auto, all_auto;
int counter_auto = 0; boolean check_auto_control; /***************************************************************************** *********/ /***************************************************************************** *********/ void setup() { Serial.begin(115200);
pinMode(Led_Wifi, OUTPUT);
pinMode(Led_Lora, OUTPUT);
pinMode(btn, INPUT);
digitalWrite(Led_Lora, HIGH);
digitalWrite(Led_Wifi, HIGH);
setWifi();
Config_Get_Time();
last = last1 = last2 = last3 = wait = millis();
DV1 = DV2 = DV3 = DV4 = DV5 = DV6 = DV7 = DV8 = 0;
temp = temp1 = temp2 = temp3 = temp4 = 0;
humi = humi1 = humi2 = humi3 = humi4 = 0;
check = check_auto = all_auto = check_auto_control = false;
} /***************************************************************************** *********/ /***************************************************************************** *********/ void loop() { Clear_Old_Wifi(); Receive_Lora(); if(millis() - last >=300000) { Send_Data_To_SQL(); last = millis(); } if(millis() - last2 >= 240000) { Request_All_Data(); } if(millis() - last1 >= 10000) { Get_Data_From_SQL(); last1 = millis(); } if(millis() - last3 >= 6000) { Auto_Mode_Control(); last3 = millis(); } } /***************************************************************************** *********/ /***************************************************************************** *********/ // Hàm kết nối Lora void Connect_Lora() {
LoRa.setPins(SS, RST, DIO0);
if(!LoRa.begin(433E6))
{
delay(100);
while (1);
}
else {
Serial.println("Esp connected lora");
Led_Blink(10);
}
Data_Receive.reserve(200);
digitalWrite(Led_Lora, LOW); }
/***************************************************************************** *********/
void Send_Lora(int ID, String device1, String device2, int status1, int status2)
{
// tạo chuỗi Json để gửi đi
String string_send = "";
string_send = "{\"ID\":\"" + String (ID) + "\"," +
"\"" + String(device1) + "\":\"" +String (status1) + "\","+
"\"" + String(device2) + "\":\"" +String (status2) + "\"}";
LoRa.beginPacket();
LoRa.print(string_send); LoRa.endPacket();
Serial.println("Esp send lora: ");
Serial.println(string_send);
Led_Blink(2);
delay(250); }
/***************************************************************************** *********/
// Hàm yêu cầu Arduino gửi dữ liệu về ESP
void Request(int ID) { String a = ""; a = "{\"ID\":\"" + String (ID) +"\"}"; LoRa.beginPacket(); LoRa.print(a); LoRa.endPacket(); Led_Blink(2); } /***************************************************************************** *********/ void Receive_Lora() {
int packetSize = LoRa.parsePacket(); if(packetSize)
{
Serial.println("Esp Receive packet");
while (LoRa.available())
{
Data_Receive = LoRa.readString();
Serial.println(Data_Receive);
Led_Blink(3);
}
//Serial.println();
Lora_Data_Processing(Data_Receive); // xử lý dữ liệu nhận từ Lora
Data_Receive = ""; } } /***************************************************************************** *********/ // Hàm kết nối wifi // void Connect_Wifi() {
// // Disconnect wifi trước đó nếu còn vướng lại // WiFi.disconnect(); // delay(1000); // // Kết nối Wifi // WiFi.begin(ssid, pass); // Serial.println(" "); // Serial.print("WIFI Connecting...");
// while (WiFi.status() != WL_CONNECTED) { // Kiểm tra kết nối Wifi // digitalWrite(Led_Wifi, LOW); // delay(200); // Serial.print("."); // digitalWrite(Led_Wifi, HIGH); // } // if (WiFi.status() == WL_CONNECTED) { // Serial.println("Connected"); // Serial.print("IP Address: "); // Serial.println(WiFi.localIP()); // In ra địa chỉ IP // digitalWrite(Led_Wifi, LOW); // } // } /***************************************************************************** *********/
// Hàm gửi dữ liệu lên Server
void Send_Data_To_SQL() {
HTTPClient http; String postData;
temp = humi = soilhumi = 0;
unsigned int sl = 0;
// tính giá trị trung bình nhiệt độ, độ ẩm, độ ẩm đất
temp = temp + temp1;
sl++;
}
if(temp2 != 0){
temp = temp + temp2;
sl++;
}
if(temp3 != 0){
temp = temp + temp3;
sl++;
}
if(temp4 != 0){
temp = temp + temp4;
sl++;
}
temp = temp/sl;
sl = 0;
if(humi1 != 0){
humi = humi + humi1;
sl++;
}
if(humi2 != 0){
humi = humi + humi2;
sl++;
}
if(humi3 != 0){
humi = humi + humi3;
sl++;
}
if(humi4 != 0){
humi = humi + humi4;
sl++;
}
humi = humi/sl;
sl = 0;
if(soilhumi1 != 0){
soilhumi = soilhumi + soilhumi1;
sl++;
}
if(soilhumi2 != 0){
soilhumi = soilhumi + soilhumi2;
sl++;
}
if(soilhumi3 != 0){
soilhumi = soilhumi + soilhumi3;
}
if(soilhumi4 != 0){
soilhumi = soilhumi + soilhumi4;
sl++;
}
soilhumi = soilhumi/sl;
// Gán giá trị nhiệt độ, độ ẩm để gửi lên Server
postData = "temp="+String(temp,2)+ "&temp1="+String(temp1,2)+
"&temp2="+String(temp2,2)+ "&temp3="+String(temp3,2)+
"&temp4="+String(temp4,2)+
"&humi="+String(humi, 2) + "&humi1="+String(humi1, 2)+
"&humi2="+String(humi2, 2)+ "&humi3="+String(humi3, 2)+
"&humi4="+String(humi4, 2)+
"&soilhumi="+String(soilhumi, 2) +
"&soilhumi1="+String(soilhumi1, 2)+ "&soilhumi2="+String(soilhumi2, 2)+
"&soilhumi3="+String(soilhumi3, 2)+ "&soilhumi4="+String(soilhumi4, 2)+
"&dv1="+String(DV1)+"&dv2="+String(DV2)+"&dv3="+String(DV3)+"&dv4 ="+String(DV4)+"&dv5="+String(DV5)+
"&dv6="+String(DV6) + "&dv7="+String(DV7) + "&dv8="+String(DV8);
http.begin(wificlient,"http://dungblog.xyz/post.php");
http.addHeader("Content-Type", "application/x-www-form-urlencoded");
int httpcode = http.POST(postData); // gửi lên server
if(httpcode == 200)
{
Serial.println("Send Data Successfully");
Serial.println(http.getString());
}
else
{
Serial.println("Send Data Fail");
} http.end(); } /***************************************************************************** *********/ // Hàm nhận dữ liệu từ Server void Get_Data_From_SQL() { payload = ""; HTTPClient http;
http.begin(wificlient, "http://dungblog.xyz/get.php");
http.addHeader("Content-Type", "application/x-www-form-urlencoded");
// Kiem tra da nhan du lieu thanh cog hay khong
int httpcode = http.GET();
{ payload = http.getString(); SQL_Data_Processing(payload); } http.end(); } /***************************************************************************** *********/
// Hàm cập nhật trạng thái thiết bị đầu cuối
void Update_Data_to_SQL() {
HTTPClient http;
String updateData = "";
updateData =
"dv1="+String(DV1)+"&dv2="+String(DV2)+"&dv3="+String(DV3)+"&dv4="+String(DV4)
+"&dv5="+String(DV5)+"&dv6="+String(DV6)
+"&dv7="+String(DV7)+"&dv8="+String(DV8);
Serial.print("data update: ");
Serial.println(updateData);
http.begin(wificlient, "http://dungblog.xyz/update.php");
http.addHeader("Content-Type", "application/x-www-form-urlencoded");
http.POST(updateData);
int httpCode = http.GET();
if(httpCode > 0)
{
Serial.println(http.getString());
} http.end(); } /***************************************************************************** *********/ // Hàm Xử lý dữ liệu nhận từ lora
void Lora_Data_Processing(String a) { DynamicJsonDocument JSON(256); deserializeJson(JSON, a); id = (int) JSON["ID"]; rq = (int) JSON["RQ"]; switch (id) { case 1: if(rq == 0){
temp1 = (float) JSON["T"];
humi1 = (float)JSON["H"];
soilhumi1 = (float)JSON["SH"];
DV2 = (float) JSON["DV2"]; check = false; if(counter == 11){counter = 12;} } else if(rq == 1){ DV1 = (int) JSON["DV1"]; DV2 = (int) JSON["DV2"]; Update_Data_to_SQL();
for(unsigned char i = 0; i < 3; i++){
Send_Answer_To_Slave(101, "OK"); } } break; case 2: if(rq == 0){
temp2 = (float) JSON["T"];
humi2 = (float) JSON["H"];
soilhumi2 = (float)JSON["SH"];
DV3 = (int) JSON["DV3"]; DV4 = (int) JSON["DV4"]; check = false; if(counter == 12){counter = 13;} } else if(rq == 1){ DV3 = (int) JSON["DV3"]; DV4 = (int) JSON["DV4"]; Update_Data_to_SQL();
for(unsigned char i = 0; i < 3; i++){
Send_Answer_To_Slave(102, "OK"); } } break; case 3: if(rq == 0){
temp3 = (float) JSON["T"];
humi3 = (float) JSON["H"];
soilhumi3 = (float)JSON["SH"];
DV5 = (int) JSON["DV5"]; DV6 = (int) JSON["DV6"]; check = false; if(counter == 13){counter = 14;} } else if(rq == 1){ DV5 = (int) JSON["DV5"]; DV6 = (int) JSON["DV6"]; Update_Data_to_SQL();
Send_Answer_To_Slave(103, "OK"); } } break; case 4: if(rq == 0){
temp4 = (float) JSON["T"];
humi4 = (float) JSON["H"];
soilhumi4 = (float)JSON["SH"];
DV7 = (int) JSON["DV7"]; DV8 = (int) JSON["DV8"]; check = false; if(counter == 14){counter = 15;} } else if(rq == 1){ DV7 = (int) JSON["DV7"]; DV8 = (int) JSON["DV8"]; Update_Data_to_SQL();
for(unsigned char i = 0; i < 3; i++){
Send_Answer_To_Slave(104, "OK"); } } break; default: break; } JSON.clear(); } /***************************************************************************** *********/
// Hàm xử lý dữ liệu từ Server gửi về // khi điểu khiển trên web . ESP điểu khiển ở trạm khu vực
void SQL_Data_Processing(String Data_SQL) {
DynamicJsonDocument JSON(256);
deserializeJson(JSON, Data_SQL);
if((int) JSON["DV1"] != DV1 || (int) JSON["DV2"] != DV2)
{ DV1 = (int) JSON["DV1"]; DV2 = (int) JSON["DV2"]; //last1 = millis(); Send_Lora(1, "DV1", "DV2", DV1, DV2); Send_Lora(1, "DV1", "DV2", DV1, DV2); }
{ DV3 = (int) JSON["DV3"]; DV4 = (int) JSON["DV4"]; Send_Lora(2, "DV3", "DV4", DV3, DV4); Send_Lora(2, "DV3", "DV4", DV3, DV4); }
if((int) JSON["DV5"] != DV5 || (int) JSON["DV6"] != DV6)
{ DV5 = (int) JSON["DV5"]; DV6 = (int) JSON["DV6"]; Send_Lora(3, "DV5", "DV6", DV5, DV6); Send_Lora(3, "DV5", "DV6", DV5, DV6); }
if((int) JSON["DV7"] != DV7 || (int) JSON["DV8"] != DV8)
{ DV7 = (int) JSON["DV7"]; DV8 = (int) JSON["DV8"]; Send_Lora(4, "DV7", "DV8", DV7, DV8); Send_Lora(4, "DV7", "DV8", DV7, DV8); } } /***************************************************************************** *********/
void configModeCallback (WiFiManager *myWiFiManager) {
Serial.println("Entered config mode");
Serial.println(WiFi.softAPIP());
Serial.println(myWiFiManager->getConfigPortalSSID()); } /***************************************************************************** *********/ void setWifi() { WiFiManager wifiManager;
wifiManager.setAPCallback(configModeCallback);
if(!wifiManager.autoConnect())
{
Serial.println("failed to connect and hit timeout");
//Nếu kết nối thất bại, thử kết nối lại bằng cách reset thiết bị
ESP.reset();
delay(1000);
}
Serial.println("connected...yeey :)");
digitalWrite(Led_Wifi, LOW); }
/***************************************************************************** *********/
void Led_Blink(int x) {