Bài 10: Mô phỏng hệ thống giám sát môi trường trong nông nghiệp thông minh (Tổng hợp) - MakerEdu Starter Kit for Arduino: Difference between revisions

From MakerLab Wiki
Jump to navigation Jump to search
No edit summary
No edit summary
 
(12 intermediate revisions by 2 users not shown)
Line 1: Line 1:
== Danh sách thiết bị ==
== Mô tả dự án ==
Trong bài thực hành tổng hợp này các bạn sẽ thực hiện mô phỏng lại một hệ thống giám sát môi trường trong nông nghiệp thông minh với các thông số ánh sáng, nhiệt độ, độ ẩm và báo hiệu khi các thông số vượt quá mức quy định.
[[File:Shutterstock 1347945488-800x450.jpg|alt=Hệ thống giám sát môi trường nông nghiệp thông minh|none|thumb|700x700px|Hệ thống giám sát môi trường nông nghiệp thông minh]]
 
== Video ==
 
<youtube width="700" height="400">qPMvq2SYIPY</youtube>
 
== Các bước thực hiện ==


=== Danh sách thiết bị ===
* 1x [[Mạch Vietduino Uno (Arduino Uno Compatible)]]
* 1x [[Mạch Vietduino Uno (Arduino Uno Compatible)]]
* 1x [[Mạch MakerEdu Shield for Vietduino]]
* 1x [[Mạch MakerEdu Shield for Vietduino]]
* 1x Cáp USB-C
* 1x [[Cảm biến độ ẩm nhiệt độ MKE-S14 DHT11 temperature and humidity sensor]]
* 1x [[Cảm biến độ ẩm nhiệt độ MKE-S14 DHT11 temperature and humidity sensor]]
* 1x [[Cảm biến ánh sáng quang trở MKE-S02 LDR light sensor]]
* 1x [[Cảm biến ánh sáng quang trở MKE-S02 LDR light sensor]]
* 1x [[Mạch còi báo MKE-M03 buzzer module]]
* 1x [[Mạch còi báo MKE-M03 buzzer module]]
* 1x [[Mạch hiển thị MKE-M07 LCD1602 I2C module]]
* 1x [[Mạch hiển thị MKE-M07 LCD1602 I2C module]]
* 1x Cáp USB-C


== Mô tả dự án ==
===Chuẩn bị trước dự án===
 
_ Trong bài này, bạn sẽ làm một mô hình mô phỏng hệ thống giám sát môi trường trong nông nghiệp
 
_ Hệ thống sử dụng cảm biến DHT11 để lấy thông số Nhiệt độ và Độ ẩm. Và ra quyết định phù hợp.
 
_ Bạn lưu ý, trong mô hình này mình sẽ xem thông số Độ ẩm không khí của cảm biến như là Độ ẩm đất.
 
_ Dựa theo các thông tin mình tìm hiểu được:
* Độ ẩm thích hợp cho các loại cây trồng sẽ dao động trong khoảng từ 60% - 70%.
* Giới hạn độ ẩm cao nhất khi phụ thuộc vào các thành phần cơ giới và kết cấu của đất sẽ là khoảng từ 70 - 85%.
* Nếu nhiệt độ trên nhiệt kế cho biết mức nhiệt dưới 25 độ C thì bạn có thể tiến hành tưới cây một cách an toàn.
* Tuy nhiên nếu nhiệt kế cho kết quả trên 30 độ C bạn nên cân nhắc việc tưới cây trời nắng bởi có thể nó sẽ gây ảnh hưởng bất lợi đến cho cây trồng.


_ Mình sẽ lập trình cho mô hình vận hành như sau:
*Kết nối mạch MakerEdu Shield với mạch Vietduino Uno [[Mạch MakerEdu Shield for Vietduino|theo hướng dẫn.]]
* Nếu độ ẩm thấp hơn 60% → còi báo.
*Kết nối mạch Vietduino Uno với máy tính qua cáp USB-C sẽ thấy đèn nguồn (ON) trên mạch MakerEdu Shield phát sáng, cài đặt Driver và cấu hình mạch trên phần mềm Arduino [[Mạch Vietduino Uno (Arduino Uno Compatible)|theo hướng dẫn tại đây.]]
** Và nếu nhiệt độ dưới 30 độ C → Thông báo tưới cây.
*Tìm hiểu về cấu trúc của một chương trình trên phầm mềm Arduino và ngôn ngữ lập trình Arduino [[Ngôn ngữ lập trình Arduino|tại đây.]]
** Ngược lại nhiệt độ trên 30 độ C → Thông báo tưới cây cẩn thận.
[[File:Kết nối mạch Vietduino Uno + MakerEdu Shield với máy tính.jpg|alt=Kết nối mạch Vietduino Uno + MakerEdu Shield với máy tính|none|thumb|700x700px|Kết nối mạch Vietduino Uno + MakerEdu Shield với máy tính]]
* Nếu độ ẩm cao hơn 85% → còi báo → Thông báo xử lý đất.


== Các bước thực hiện ==
===Cài đặt bộ thư viện (Library)===  


=== Tạo code ===
*Tải và cài đặt bộ thư viện [https://github.com/makerlabvn/LiquidCrystal_I2C LiquidCrystal_I2C] theo [[Cách cài đặt các thư viện phần cứng Arduino Library|hướng dẫn tại đây.]]
*Tải và cài đặt bộ thư viện [https://github.com/makerlabvn/DHT-sensor-library DHT-sensor-library] theo [[Cách cài đặt các thư viện phần cứng Arduino Library|hướng dẫn tại đây.]]
*Tải và cài đặt bộ thư viện [https://github.com/adafruit/Adafruit_Sensor Adafruit_Sensor] theo [[Cách cài đặt các thư viện phần cứng Arduino Library|hướng dẫn tại đây.]] (bộ thư viện này cần cài đặt để có thể chạy được bộ thư viện [https://github.com/adafruit/DHT-sensor-library DHT-sensor-library] ở phía trên).


# Mở phần mềm '''IDE Arduino''' và thêm các bộ thư viện sau vào IDE (nếu chưa có):
===Chương trình ===
#* '''"LiquidCrystal_I2C"'''
#Mở phần mềm '''IDE Arduino''' và tạo một chương trình ('''Sketch)''' mới.
#* '''"Adafruit_Sensor.h"'''
#Copy đoạn code sau vào chương trình và tiến nạp chương trình (Upload) theo [[Mạch Vietduino Uno (Arduino Uno Compatible)|hướng dẫn tại đây.]]
#* '''"DHT.h"'''
# Sau đó tạo một '''Sketch''' mới và copy đoạn code sau vào file dự án.


<source lang="C++">
<source lang="C++">
// Thêm bộ thư viện LCD
// Hệ thống giám sát môi trường nông nghiệp thông minh / MakerEdu Starter Kit for Arduino
/* ----------------------------------------------------- */
// Thêm bộ thư viện cho cảm biến DHT và LCD
#include <LiquidCrystal_I2C.h>
#include <LiquidCrystal_I2C.h>
// Thêm bộ thư viện DHT
#include <DHT.h>
#include <DHT.h>


Line 65: Line 61:
DHT dht(9, DHT11);
DHT dht(9, DHT11);


// Các biến lưu giá trị "nhiệt độ" và "độ ẩm" đọc từ cảm biến
// Các biến lưu giá trị "nhiệt độ" và "độ ẩm" đọc từ cảm biến theo kiểu số thực
float temp, humi;
float temp, humi;


// Tạo biến lưu giá trị của cảm biến ánh sáng LDR
// Tạo biến lưu giá trị của cảm biến ánh sáng LDR và biến đếm
int rawLDR = 0;
int minlightValue = 0;
int valueLDR = 0;
int valueLDR = 0;
int rawLDR = 0;
int count = 0;
int count = 0;
int minlightValue = 0;


// Lưu thời điểm cập nhập dữ liệu mới
// Tạo các biến trạng thái Logic
unsigned long pointUpdate = millis();
 
// Bật (true) hoặc tắt (false) còi
bool warning1 = false;
bool warning1 = false;
bool warning2 = false;
bool warning2 = false;
Line 86: Line 79:
void setup()
void setup()
{
{
   // Mở cổng Serial Baudrate 115200 bps
   // Mở cổng Serial Baudrate 115200bps
   Serial.begin(115200);
   Serial.begin(115200);


Line 101: Line 94:
   lcd.backlight();
   lcd.backlight();


   // Khởi động cảm biến DHT11
   //Căn chỉnh giá trị của cảm biến ánh sáng
  dht.begin();
   lcd.setCursor(0, 0); // Cột 0 dòng 0
 
   lcd.setCursor(0, 0); // Cột 1 dòng 1
   lcd.print("Light SS Calib");
   lcd.print("Light SS Calib");
   lcd.setCursor(0, 1); // Cột 1 dòng 1
   lcd.setCursor(0, 1); // Cột 0 dòng 1
   lcd.print("Cover the sensor");
   lcd.print("Cover the sensor");
 
  //Căn chỉnh giá trị của cảm biến ánh sáng
   Serial.println("Xin để cảm biến ở chỗ tối nhất!");
   Serial.println("Xin để cảm biến ở chỗ tối nhất!");
   delay(2000);
   delay(2000);
   for (count = 5; count >= 1; count--)
   for (count = 5; count >= 1; count--)
   {
   {
Line 129: Line 117:
   lcd.clear();
   lcd.clear();


    // In khung nội dung mẫu lên LCD
  // In khung nội dung mẫu lên LCD
   lcd.setCursor(0, 0); // Cột 1 dòng 1
   lcd.setCursor(0, 0); // Cột 0 dòng 0
   lcd.print("T:");
   lcd.print("T:");
   lcd.setCursor(10, 0); // Cột 11 dòng 1
   lcd.setCursor(10, 0); // Cột 10 dòng 0
   lcd.print("H:");
   lcd.print("H:");
   lcd.setCursor(0, 1); // Cột 1 dòng 2
   lcd.setCursor(0, 1); // Cột 0 dòng 1
   lcd.print("LDR: ");
   lcd.print("LDR: ");
  // Khởi động cảm biến DHT11
  dht.begin();
}
}


Line 142: Line 133:
void loop()
void loop()
{
{
   // Lấy dữ liệu từ cảm biến DHT11
   // Lấy dữ liệu từ cảm biến DHT11 và cảm biến ánh sáng
   rawLDR = analogRead(LDR_PIN);
   rawLDR = analogRead(LDR_PIN);
   temp = dht.readTemperature();
   temp = dht.readTemperature();
   humi = dht.readHumidity();
   humi = dht.readHumidity();
   // Lấy dữ liệu từ cảm biến Quang trở
   // Quy đổi dử liệu cảm biến ánh sáng ra dạng 0~100%
   valueLDR = map(rawLDR, 0, minlightValue, 100, 0);
   valueLDR = map(rawLDR, 0, minlightValue, 100, 0);
  //Hiển thị các giá trị lên Serial Monitor
   Serial.print("LDR: ");
   Serial.print("LDR: ");
   Serial.println(rawLDR);
   Serial.println(rawLDR);
Line 155: Line 148:
   Serial.println(humi);
   Serial.println(humi);


  //////////
   // In giá trị "nhiệt độ" tại vị trí cột 2 dòng 0
 
   // In giá trị "nhiệt độ" tại vị trí cột 3 dòng 1
   lcd.setCursor(2, 0);
   lcd.setCursor(2, 0);
   lcd.print(temp, 1);
   lcd.print(temp, 1);
   lcd.write(0xDF); // In kí tự (°)
   lcd.write(0xDF); // In kí tự (°)
   lcd.print("C ");
   lcd.print("C ");
   // In giá trị "độ ẩm" tại vị trí cột 13 dòng 1
   // In giá trị "độ ẩm" tại vị trí cột 12 dòng 0
   lcd.setCursor(12, 0);
   lcd.setCursor(12, 0);
   lcd.print(humi, 0);
   lcd.print(humi, 0);
   lcd.print("% ");
   lcd.print("% ");
   // In giá trị "quang trở" tại vị trí cột 6 dòng 2
   // In giá trị "quang trở" tại vị trí cột 5 dòng 1
   lcd.setCursor(5, 1);
   lcd.setCursor(5, 1);
   lcd.print(valueLDR);
   lcd.print(valueLDR);
   lcd.print("% - ");
   lcd.print("% - ");
  //So sánh giá trị cảm biến ánh sáng để hiện thông báo Ngày  / 
   if (valueLDR >= 30)
   if (valueLDR >= 30)
     lcd.print("DAY  ");
     lcd.print("DAY  ");
Line 175: Line 167:
     lcd.print("NIGHT ");
     lcd.print("NIGHT ");


   //////////
   // So sánh giá trị độ ẩm với giá trị định mức bật cảnh báo.
 
  if (humi > 85)
  if (humi > 85)
     {
     {
       warning1 = true; // Bật cảnh báo
       warning1 = true; // Bật cảnh báo
       Serial.println("Độ ẩm cao vượt mức quy định (85)");
       Serial.println("Độ ẩm cao vượt mức quy định (85)");
       lcd.setCursor(15, 0); // Cột 11 dòng 1
       lcd.setCursor(15, 0); // Cột 15 dòng 0
       lcd.print("!");
       lcd.print("!");
     }
     }
Line 188: Line 179:
       warning1 = true; // Bật cảnh báo
       warning1 = true; // Bật cảnh báo
       Serial.println("Độ ẩm thấp dưới mức quy định (40)");
       Serial.println("Độ ẩm thấp dưới mức quy định (40)");
       lcd.setCursor(15, 0); // Cột 11 dòng 1
       lcd.setCursor(15, 0); // Cột 15 dòng 0
       lcd.print("!");
       lcd.print("!");
     }
     }
Line 194: Line 185:
     {
     {
       warning1 = false; // Tắt cảnh báo
       warning1 = false; // Tắt cảnh báo
       lcd.setCursor(15, 0); // Cột 11 dòng 1
       lcd.setCursor(15, 0); // Cột 15 dòng 0
       lcd.print(" ");
       lcd.print(" ");
     }
     }
/////////////////////////////
 
  // So sánh giá trị nhiệt độ với giá trị định mức bật cảnh báo.
  if (temp > 30)
  if (temp > 30)
     {
     {
       warning2 = true; // Bật cảnh báo
       warning2 = true; // Bật cảnh báo
       Serial.println("Cảnh báo!: Nhiệt độ cao quá mức quy định (30)");
       Serial.println("Cảnh báo!: Nhiệt độ cao quá mức quy định (30)");
       lcd.setCursor(8, 0); // Cột 11 dòng 1
       lcd.setCursor(8, 0); // Cột 8 dòng 0
       lcd.print("!");
       lcd.print("!");
     }
     }
Line 209: Line 201:
       warning2 = true; // Bật cảnh báo
       warning2 = true; // Bật cảnh báo
       Serial.println("Cảnh báo!: Nhiệt độ thấp dưới mức quy định (25)");
       Serial.println("Cảnh báo!: Nhiệt độ thấp dưới mức quy định (25)");
       lcd.setCursor(8, 0); // Cột 11 dòng 1
       lcd.setCursor(8, 0); // Cột 8 dòng 0
       lcd.print("!");
       lcd.print("!");
     }
     }
Line 215: Line 207:
     {
     {
       warning2 = false; // Tắt cảnh báo
       warning2 = false; // Tắt cảnh báo
       lcd.setCursor(8, 0); // Cột 11 dòng 1
       lcd.setCursor(8, 0); // Cột 8 dòng 0
       lcd.print(" ");
       lcd.print(" ");
     }
     }
  //////////


   // Cho còi kêu tick...tick khi bật cảnh báo
   // Bật cảnh báo nếu có giá trị vượt mức quy định.
   if (warning2||warning1)
   if (warning2||warning1)
   {
   {
Line 227: Line 218:
   }
   }


   // Chờ 0.5s mới đo lại
   // Chờ 0.5s mới đo lại.
   delay(500);
   delay(500);
}
}
</source>
</source>


=== Giải thích code ===
===Giải thích code===
Để có thể sử dụng các hàm để điều khiển màn hình [[Mạch hiển thị MKE-M07 LCD1602 I2C module|MKE-M07 LCD1602 I2C]]  và cảm biến [[Cảm biến độ ẩm nhiệt độ MKE-S14 DHT11 temperature and humidity sensor|MKE-S14 DHT11]] đầu tiên ta cần thêm bộ thư viện vào đầu chương trình:
 
<code>#include <LiquidCrystal_I2C.h></code>: Thêm bộ thư viện LiquidCrystal_I2C.h với các hàm điều khiển màn hình.
 
<code>#include <DHT.h></code>: Thêm bộ thư viện DHT.h với các hàm điều khiển cảm biến MKE-S14 DHT11.
 
Sau đó ta cần khai báo đối tượng cần điều khiển của bộ thư viện LiquidCrystal_I2C như ở đây ta khai báo là "lcd", bạn cũng có thể khai báo thêm "lcd1", "lcd2" tuỳ thích, khi đó các hàm điều khiển phía sau sẽ phải gắn với các đối tượng này:
 
<code>LiquidCrystal_I2C lcd(0x27, 16, 2)</code>: Khai báo đối tượng màn hình "lcd" với địa chỉ 0x27, 16 ký tự, 2 dòng.{{Tr-Info
|name=Lưu ý:
|value=Để điều khiển thêm các LCD khác bạn cần phải thiết lập địa chỉ khác với địa chỉ mặc định 0x27, [https://wiki.makerlab.vn/index.php/M%E1%BA%A1ch_hi%E1%BB%83n_th%E1%BB%8B_MKE-M07_LCD1602_I2C_module tham khảo tài liệu sau] để biết cách thiết lập địa chỉ LCD.
}}Tương tự ta khai báo đối tượng cần điều khiển của bộ thư viện DHT như ở đây ta khai báo là "dht", bạn cũng có thể khai báo thêm "dht1", "dht2" tuỳ thích, khi đó các hàm điều khiển phía sau sẽ phải gắn với các đối tượng này:
 
<code>DHT dht(9, DHT11);</code>: Khai báo đối tượng cảm biến "dht" tại Port D9.{{Tr-Info
|name=Lưu ý:
|value=Để điều khiển thêm các cảm biến DHT khác bạn bạn có thể kết nối và khai báo thiết lập ở các Port chưa sử dụng như D10, D11,...
}}Chương trình chính gồm các câu lệnh được đặt trong 2 hàm bắt buộc của một chương trình Arduino là <code>void setup()</code> và <code>void loop()</code>
 
<code>void setup()</code> (chứa các câu lệnh chỉ khởi chạy 1 lần khi khởi động)
 
* <code>Serial.begin(''baudrate'')</code>: khởi động cổng kết nối Serial trên mạch Vietduino Uno với tốc độ (baudrate) mong muốn, các tốc độ hỗ trợ thường là: 9600, 115200,...
* <code>pinMode(''Pin'', OUTPUT)</code>: cấu hình chân tín hiệu mong muốn là chân xuất tín hiệu (OUTPUT).
* <code>digitalWrite(''Pin'', HIGH);</code>: Xuất tín hiệu Digital mức cao (HIGH) ra chân tín hiệu mong muốn.
 
* <code>lcd.init()</code>: khởi động màn hình "lcd", là câu lệnh bắt buộc để bắt đầu điều khiển màn hình.
* <code>lcd.clear()</code>: xoá toàn bộ nội dung trên màn hình "lcd".
* <code>lcd.backlight()</code>: bật đèn nền màn hình "lcd".
* <code>analogRead(''Pin'')</code>: hàm này sẽ trả về giá trị của chân Analog cần đọc với dải giá trị điện áp tương ứng 0~5VDC là giá trị số nguyên từ 0~1023.
* <code>dht.begin()</code>: khởi động cảm biến DHT.
 
<code>void loop()</code> (chứa các câu lệnh chạy lặp đi lặp lại )
 
* <code>dht.readTemperature()</code>: đọc giá trị nhiệt độ của cảm biến DHT.
* <code>dht.readHumidity()</code>: đọc giá trị độ ẩm của cảm biến DHT.
* <code>map(value,original_min,original_max,new_min,new_max)</code>: hàm quy đổi giá trị <code>value</code> trong thang đo gốc "<code>original_min,original_max</code>" sang thang đo mới "<code>new_min,new_max".</code>
* <code>lcd.setCursor(''column, row'')</code>: chuyển con trỏ đến vị trí cột và dòng mong muốn của "lcd" trước khi in ký tự.
* <code>lcd.print(''data'')</code>: In dữ liệu mong muốn tại vị trí con trỏ của "lcd", nếu là dạng ký tự thì cần bỏ trong dấu "", với số thực nếu muốn in số chữ số sau dấu phẩy ta thêm số chữ số mong muốn theo dạng <code>lcd.print(float, số chữ số mong muốn sau dấu phẩy).</code>
* <code>Serial.print(''data'')</code>: gửi dữ liệu từ mạch Vietduino Uno lên máy tính, nếu dữ liệu là kiểu ký tự thì cần để trong dấu "", với số thực nếu muốn in số chữ số sau dấu phẩy ta thêm số chữ số mong muốn theo dạng <code>Serial.print(float, số chữ số mong muốn sau dấu phẩy)</code>, sử dụng <code>Serial.println(data)</code> để in có xuống dòng.
* <code>delay(''time'')</code>: yêu cầu Vietduino Uno chờ (''không làm gì cả)'' trong một khoảng thời gian nhất định, đơn vị là mili giây (ms).


Quá trình vận hành của chương trình như sau:
Quá trình vận hành của chương trình như sau:
_ Trước khi bắt đầu, chương trình sẽ mở cổng giao tiếp Serial, khởi động LCD và cảm biến DHT11.
_ Xong các bước chuẩn bị trên, chương trình sẽ thực hiện tuần tự như sau, và cứ thế lặp lại:
# Lấy giá trị Nhiệt độ và độ ẩm từ cảm biến DHT11.
# Cho hiển thị 2 giá trị mới nhất này lên màn hình LCD.
# Lấy giá trị (%) cường độ sáng từ cảm biến Quang trở.
# Cho hiển thị giá trị mới nhất này lên màn hình LCD.
# Đồng thời cũng cho biết luôn đang là "DAY" hay "NIGHT".
# Dùng giá trị Nhiệt độ và Độ ẩm vừa rồi, để ra xử lý có bật còi hay không cũng như có gửi thông báo lên Serial hay ko.
# Nếu còi được phép thì bật còi, để tạo âm thanh cảnh báo tick...tick


=== Sơ đồ kết nối ===
* Khởi động đối tượng "lcd" tại địa chỉ 0x27 với cấu hình là 16 ký tự, 2 dòng.
* Đọc và căn chỉnh giá trị của cảm biến ánh sáng LDR.
* Khởi động cảm biến DHT.
* Đọc và lưu các giá trị nhiệt độ và độ ẩm của cảm biến DHT vào hai biến số thực là Temp và Humi.
* Hiển thị các thông tin độ ẩm và nhiệt độ của cảm biến DHT lên màn hình LCD và Serial Monitor.
* Hiển thị thông tin của cảm biến ánh sáng LDR lên màn hình LCD và Serial Monitor.
* So sánh giá trị của cảm biến ánh sáng LDR để hiển thị trời Sáng hay Tối lên màn hình LCD.
* So sánh giá trị nhiệt độ và độ ẩm của cảm biến DHT để hiển thị cảnh báo lên màn hình LCD khi vượt quá mức quy định và kích hoạt còi báo hiệu.


===Sơ đồ kết nối===
{| class="wikitable"
{| class="wikitable"
!MakerEDU Shield
!MakerEDU Shield
!Thiết bị
!Thiết bị
!Cáp kết nối
|-
|Port I2C
|[[Mạch led đơn MKE-M01 10mm single LED module|Mạch hiển thị MKE-M07 LCD1602 I2C module]]
|MakerEdu XH2.54 4Wires
|-
|-
|Port D9
|Port D9
|[MKE-S14] - Cảm biến DHT11
|[[Cảm biến độ ẩm nhiệt độ MKE-S14 DHT11 temperature and humidity sensor]]
|MakerEdu XH2.54 3Wires
|-
|-
|Port A1
|Port A1
|[MKE-S02] - Cảm biến Quang trở
|[[Cảm biến ánh sáng quang trở MKE-S02 LDR light sensor]]
|MakerEdu XH2.54 3Wires
|-
|-
|Port D10
|Port D10
|[MKE-M03] - Mạch còi Buzzer
|[[Mạch còi báo MKE-M03 buzzer module]]
|-
|MakerEdu XH2.54 3Wires
|Port I2C
|[MKE-M07] - LCD 16x02
|}
|}


=== Nạp code ===
==Kết quả ==
Sau khi đã nạp code thành công bạn có thể xem kết quả trực tiếp trên màn hình LCD, phía sau màn hình LCD có một biến trở (màu xanh dương) để chỉnh "độ tương phản" bạn có thể dùng tua vít để điều chỉnh bạn thấy quá đậm hoặc quá mờ.
[[File:5048C6D5-A4C2-4507-B1D8-4B7A69862F5A 1 201 a.jpg|alt=Hiển thị thông tin nhiệt độ (T), độ ẩm (H) và ánh sáng (LDR) lên màn hình LCD|none|thumb|900x900px|Hiển thị thông tin nhiệt độ (T), độ ẩm (H) và ánh sáng (LDR) lên màn hình LCD]]
Nhấn vào ''"biểu tượng kính lúp"'' hoặc chọn ''Tools > Serial Monitor'' để mở Serial Monitor, chọn đúng tốc độ Baudrate là 115200bps để thấy giá trị cảm biến hiển thị lên Serial Monitor.
[[File:Screenshot 2023-07-15 at 17.55.52.png|alt=Giá trị cảm biến hiển thị lên Serial Monitor|none|thumb|700x700px|Giá trị cảm biến hiển thị lên Serial Monitor]]
 
==Bài tập thêm (nâng cao)==
<u>Bài tập 1</u>:


# Kết nối Module DHT11 đến '''Port D9''' của MakerEdu Shield.
* Viết chương trình hiển thị các giá trị của '''DHT11''' (độ ẩm, nhiệt độ) và '''Quang trở''' (ánh sáng) lên màn hình '''LCD'''.
# Kết nối Cảm biến Quang trở đến '''Port A1''' của MakerEdu Shield.
* '''Còi''' báo động khi một trong hai giá trị ''"nhiệt độ"'' hoặc ''"độ ẩm"'' vượt ngưỡng.
# Kết nối Module Buzzer đến '''Port D10''' của MakerEdu Shield.
* Với nhiệt độ ngưỡng giá trị là trên <u>30ºC</u>, còn với độ ẩm ngưỡng giá trị là trên <u>80%</u>.
# Kết nối Module LCD 16x02 đến '''Port I2C''' của MakerEdu Shield.
* Thêm mạch đèn '''Led''' để tự động bật đèn khi trời tối, độ sáng đèn sẽ được điều chỉnh bằng '''Biến trở'''.
# Dùng cáp USB-C kết nối giữa bo Vietduino Uno và máy tính.
→ [[Lời giải các bài tập thực hành - MakerEdu Starter Kit for Arduino|Lời giải.]]
# Vào mục '''Tools...''' thiết lập các cấu hình cho đúng với bo [[Mạch Vietduino Uno (Arduino Uno Compatible) | Vietduino Uno]] đang dùng.
# Nhấn vào ''"nút →"'' hoặc phím tắt '''[Ctrl+U]''' để nạp code cho bo mạch.


== Kết quả ==
== Nguồn tài liệu (tham khảo thêm) ==


# Sau khi đã nạp code thành công.
* [https://www.techtarget.com/iotagenda/definition/smart-farming What is smart farming? Definition from WhatIs.com (techtarget.com)]
# Bạn hãy thử đặt ngón tay lên cảm biến DHT11 và xem kết quả phản hồi như thế nào.
* [https://docs.arduino.cc/learn/starting-guide/getting-started-arduino Getting Started with Arduino | Arduino Documentation]
# Tương tự với cảm biến Quang trở bạn hãy thử lấy tay che cảm biến lại.


{{Tr-Info
== Bài viết liên quan ==
|name=Tip:
|value=Phía sau Module màn hình LCD, có một biến trở (màu xanh dương) để chỉnh ''"độ tương phản"'' hiển thị trên màn hình.
}}


... thêm ảnh hay hoặc video
* [[Bộ MakerEdu Starter Kit for Arduino|Bộ MakerEdu Starter Kit for Arduino - MakerLab Wiki]]
* [[Bài 9: Đo nhiệt độ độ ẩm bằng cảm biến DHT11 hiển thị lên LCD1602 (Library) - MakerEdu Starter Kit for Arduino|Bài 9: Đo nhiệt độ độ ẩm bằng cảm biến DHT11 hiển thị lên LCD1602 (Library)]]

Latest revision as of 09:02, 24 August 2023

Mô tả dự án

Trong bài thực hành tổng hợp này các bạn sẽ thực hiện mô phỏng lại một hệ thống giám sát môi trường trong nông nghiệp thông minh với các thông số ánh sáng, nhiệt độ, độ ẩm và báo hiệu khi các thông số vượt quá mức quy định.

Hệ thống giám sát môi trường nông nghiệp thông minh
Hệ thống giám sát môi trường nông nghiệp thông minh

Video

Các bước thực hiện

Danh sách thiết bị

Chuẩn bị trước dự án

  • Kết nối mạch MakerEdu Shield với mạch Vietduino Uno theo hướng dẫn.
  • Kết nối mạch Vietduino Uno với máy tính qua cáp USB-C sẽ thấy đèn nguồn (ON) trên mạch MakerEdu Shield phát sáng, cài đặt Driver và cấu hình mạch trên phần mềm Arduino theo hướng dẫn tại đây.
  • Tìm hiểu về cấu trúc của một chương trình trên phầm mềm Arduino và ngôn ngữ lập trình Arduino tại đây.
Kết nối mạch Vietduino Uno + MakerEdu Shield với máy tính
Kết nối mạch Vietduino Uno + MakerEdu Shield với máy tính

Cài đặt bộ thư viện (Library)

Chương trình

  1. Mở phần mềm IDE Arduino và tạo một chương trình (Sketch) mới.
  2. Copy đoạn code sau vào chương trình và tiến nạp chương trình (Upload) theo hướng dẫn tại đây.
// Hệ thống giám sát môi trường nông nghiệp thông minh / MakerEdu Starter Kit for Arduino
/* ----------------------------------------------------- */
// Thêm bộ thư viện cho cảm biến DHT và LCD
#include <LiquidCrystal_I2C.h>
#include <DHT.h>

/* ----------------------------------------------------- */

// Chọn chân đọc cảm biến Quang trở
#define LDR_PIN A1 // A1

// Chọn chân điều khiển còi Buzzer
#define BUZZ_PIN 10 // D10

/* ----------------------------------------------------- */

// Khởi tạo màn hình MKE-M07 LCD1602 I2C với đối tượng là "lcd"
LiquidCrystal_I2C lcd(0x27,16,2);
// Cài đặt địa chỉ I2C là 0x27
// Mỗi dòng 16 ký tự
// 2 dòng hiển thị

// Khởi tạo cảm biến MKE-S14 DHT11 với đối tượng là "dht" tại Port D9
DHT dht(9, DHT11);

// Các biến lưu giá trị "nhiệt độ" và "độ ẩm" đọc từ cảm biến theo kiểu số thực
float temp, humi;

// Tạo biến lưu giá trị của cảm biến ánh sáng LDR và biến đếm
int rawLDR = 0;
int minlightValue = 0;
int valueLDR = 0;
int count = 0;

// Tạo các biến trạng thái Logic
bool warning1 = false;
bool warning2 = false;
bool stateBuzz = 0;

/* ----------------------------------------------------- */

void setup()
{
  // Mở cổng Serial Baudrate 115200bps
  Serial.begin(115200);

  // Thiết lập chân D10 là Output để điều khiển còi
  pinMode(BUZZ_PIN, OUTPUT);
  // Khi mới khởi động, tắt còi
  digitalWrite(BUZZ_PIN, LOW);

  // Khởi động màn hình LCD
  lcd.init();
  // Xóa toàn bộ nội dung trên màn hình LCD (nếu có)
  lcd.clear();
  // Bật đèn nền màn hình LCD
  lcd.backlight();

  //Căn chỉnh giá trị của cảm biến ánh sáng
  lcd.setCursor(0, 0); // Cột 0 dòng 0
  lcd.print("Light SS Calib");
  lcd.setCursor(0, 1); // Cột 0 dòng 1
  lcd.print("Cover the sensor");
  Serial.println("Xin để cảm biến ở chỗ tối nhất!");
  delay(2000);
  for (count = 5; count >= 1; count--)
  {
    delay(1000);
    //Đọc giá trị cảm biến ánh sáng LDR
    rawLDR = analogRead(LDR_PIN);
    minlightValue = minlightValue + rawLDR;
    Serial.println(rawLDR);
  }
  //Lấy giá trị trung bình 5 lần đo + 10% sai số
  minlightValue = minlightValue / 4.5;
  Serial.print("Đo giá trị cảm biến lúc tối nhất:");
  Serial.println(minlightValue);

  // Xóa toàn bộ nội dung trên màn hình LCD (nếu có)
  lcd.clear();

  // In khung nội dung mẫu lên LCD
  lcd.setCursor(0, 0); // Cột 0 dòng 0
  lcd.print("T:");
  lcd.setCursor(10, 0); // Cột 10 dòng 0
  lcd.print("H:");
  lcd.setCursor(0, 1); // Cột 0 dòng 1
  lcd.print("LDR: ");

  // Khởi động cảm biến DHT11
  dht.begin();
}

/* ----------------------------------------------------- */

void loop()
{
  // Lấy dữ liệu từ cảm biến DHT11 và cảm biến ánh sáng
  rawLDR = analogRead(LDR_PIN);
  temp = dht.readTemperature();
  humi = dht.readHumidity();
  // Quy đổi dử liệu cảm biến ánh sáng ra dạng 0~100%
  valueLDR = map(rawLDR, 0, minlightValue, 100, 0);

  //Hiển thị các giá trị lên Serial Monitor
  Serial.print("LDR: ");
  Serial.println(rawLDR);
  Serial.print("Temp: ");
  Serial.println(temp);
  Serial.print("Humi: ");
  Serial.println(humi);

  // In giá trị "nhiệt độ" tại vị trí cột 2 dòng 0
  lcd.setCursor(2, 0);
  lcd.print(temp, 1);
  lcd.write(0xDF); // In kí tự (°)
  lcd.print("C ");
  // In giá trị "độ ẩm" tại vị trí cột 12 dòng 0
  lcd.setCursor(12, 0);
  lcd.print(humi, 0);
  lcd.print("% ");
  // In giá trị "quang trở" tại vị trí cột 5 dòng 1
  lcd.setCursor(5, 1);
  lcd.print(valueLDR);
  lcd.print("% - ");
  //So sánh giá trị cảm biến ánh sáng để hiện thông báo Ngày  /  
  if (valueLDR >= 30)
    lcd.print("DAY  ");
  else
    lcd.print("NIGHT ");

  // So sánh giá trị độ ẩm với giá trị định mức bật cảnh báo.
 if (humi > 85)
    {
      warning1 = true; // Bật cảnh báo
      Serial.println("Độ ẩm cao vượt mức quy định (85)");
      lcd.setCursor(15, 0); // Cột 15 dòng 0
      lcd.print("!");
    }
  else if (humi < 40)
    {
      warning1 = true; // Bật cảnh báo
      Serial.println("Độ ẩm thấp dưới mức quy định (40)");
      lcd.setCursor(15, 0); // Cột 15 dòng 0
      lcd.print("!");
    }
  else
    {
      warning1 = false; // Tắt cảnh báo
      lcd.setCursor(15, 0); // Cột 15 dòng 0
      lcd.print(" ");
    }

  // So sánh giá trị nhiệt độ với giá trị định mức bật cảnh báo.
 if (temp > 30)
    {
      warning2 = true; // Bật cảnh báo
      Serial.println("Cảnh báo!: Nhiệt độ cao quá mức quy định (30)");
      lcd.setCursor(8, 0); // Cột 8 dòng 0
      lcd.print("!");
    }
  else if (temp < 25)
    {
      warning2 = true; // Bật cảnh báo
      Serial.println("Cảnh báo!: Nhiệt độ thấp dưới mức quy định (25)");
      lcd.setCursor(8, 0); // Cột 8 dòng 0
      lcd.print("!");
    }
  else
    {
      warning2 = false; // Tắt cảnh báo
      lcd.setCursor(8, 0); // Cột 8 dòng 0
      lcd.print(" ");
    }

  // Bật cảnh báo nếu có giá trị vượt mức quy định.
  if (warning2||warning1)
  {
      stateBuzz = !stateBuzz;
      digitalWrite(BUZZ_PIN, stateBuzz);
  }

  // Chờ 0.5s mới đo lại.
  delay(500);
}

Giải thích code

Để có thể sử dụng các hàm để điều khiển màn hình MKE-M07 LCD1602 I2C và cảm biến MKE-S14 DHT11 đầu tiên ta cần thêm bộ thư viện vào đầu chương trình:

#include <LiquidCrystal_I2C.h>: Thêm bộ thư viện LiquidCrystal_I2C.h với các hàm điều khiển màn hình.

#include <DHT.h>: Thêm bộ thư viện DHT.h với các hàm điều khiển cảm biến MKE-S14 DHT11.

Sau đó ta cần khai báo đối tượng cần điều khiển của bộ thư viện LiquidCrystal_I2C như ở đây ta khai báo là "lcd", bạn cũng có thể khai báo thêm "lcd1", "lcd2" tuỳ thích, khi đó các hàm điều khiển phía sau sẽ phải gắn với các đối tượng này:

LiquidCrystal_I2C lcd(0x27, 16, 2): Khai báo đối tượng màn hình "lcd" với địa chỉ 0x27, 16 ký tự, 2 dòng.

Icon-Info-White.png Lưu ý:
Để điều khiển thêm các LCD khác bạn cần phải thiết lập địa chỉ khác với địa chỉ mặc định 0x27, tham khảo tài liệu sau để biết cách thiết lập địa chỉ LCD.

Tương tự ta khai báo đối tượng cần điều khiển của bộ thư viện DHT như ở đây ta khai báo là "dht", bạn cũng có thể khai báo thêm "dht1", "dht2" tuỳ thích, khi đó các hàm điều khiển phía sau sẽ phải gắn với các đối tượng này: DHT dht(9, DHT11);: Khai báo đối tượng cảm biến "dht" tại Port D9.

Icon-Info-White.png Lưu ý:
Để điều khiển thêm các cảm biến DHT khác bạn bạn có thể kết nối và khai báo thiết lập ở các Port chưa sử dụng như D10, D11,...

Chương trình chính gồm các câu lệnh được đặt trong 2 hàm bắt buộc của một chương trình Arduino là void setup()void loop()

void setup() (chứa các câu lệnh chỉ khởi chạy 1 lần khi khởi động)

  • Serial.begin(baudrate): khởi động cổng kết nối Serial trên mạch Vietduino Uno với tốc độ (baudrate) mong muốn, các tốc độ hỗ trợ thường là: 9600, 115200,...
  • pinMode(Pin, OUTPUT): cấu hình chân tín hiệu mong muốn là chân xuất tín hiệu (OUTPUT).
  • digitalWrite(Pin, HIGH);: Xuất tín hiệu Digital mức cao (HIGH) ra chân tín hiệu mong muốn.
  • lcd.init(): khởi động màn hình "lcd", là câu lệnh bắt buộc để bắt đầu điều khiển màn hình.
  • lcd.clear(): xoá toàn bộ nội dung trên màn hình "lcd".
  • lcd.backlight(): bật đèn nền màn hình "lcd".
  • analogRead(Pin): hàm này sẽ trả về giá trị của chân Analog cần đọc với dải giá trị điện áp tương ứng 0~5VDC là giá trị số nguyên từ 0~1023.
  • dht.begin(): khởi động cảm biến DHT.

void loop() (chứa các câu lệnh chạy lặp đi lặp lại )

  • dht.readTemperature(): đọc giá trị nhiệt độ của cảm biến DHT.
  • dht.readHumidity(): đọc giá trị độ ẩm của cảm biến DHT.
  • map(value,original_min,original_max,new_min,new_max): hàm quy đổi giá trị value trong thang đo gốc "original_min,original_max" sang thang đo mới "new_min,new_max".
  • lcd.setCursor(column, row): chuyển con trỏ đến vị trí cột và dòng mong muốn của "lcd" trước khi in ký tự.
  • lcd.print(data): In dữ liệu mong muốn tại vị trí con trỏ của "lcd", nếu là dạng ký tự thì cần bỏ trong dấu "", với số thực nếu muốn in số chữ số sau dấu phẩy ta thêm số chữ số mong muốn theo dạng lcd.print(float, số chữ số mong muốn sau dấu phẩy).
  • Serial.print(data): gửi dữ liệu từ mạch Vietduino Uno lên máy tính, nếu dữ liệu là kiểu ký tự thì cần để trong dấu "", với số thực nếu muốn in số chữ số sau dấu phẩy ta thêm số chữ số mong muốn theo dạng Serial.print(float, số chữ số mong muốn sau dấu phẩy), sử dụng Serial.println(data) để in có xuống dòng.
  • delay(time): yêu cầu Vietduino Uno chờ (không làm gì cả) trong một khoảng thời gian nhất định, đơn vị là mili giây (ms).

Quá trình vận hành của chương trình như sau:

  • Khởi động đối tượng "lcd" tại địa chỉ 0x27 với cấu hình là 16 ký tự, 2 dòng.
  • Đọc và căn chỉnh giá trị của cảm biến ánh sáng LDR.
  • Khởi động cảm biến DHT.
  • Đọc và lưu các giá trị nhiệt độ và độ ẩm của cảm biến DHT vào hai biến số thực là Temp và Humi.
  • Hiển thị các thông tin độ ẩm và nhiệt độ của cảm biến DHT lên màn hình LCD và Serial Monitor.
  • Hiển thị thông tin của cảm biến ánh sáng LDR lên màn hình LCD và Serial Monitor.
  • So sánh giá trị của cảm biến ánh sáng LDR để hiển thị trời Sáng hay Tối lên màn hình LCD.
  • So sánh giá trị nhiệt độ và độ ẩm của cảm biến DHT để hiển thị cảnh báo lên màn hình LCD khi vượt quá mức quy định và kích hoạt còi báo hiệu.

Sơ đồ kết nối

MakerEDU Shield Thiết bị Cáp kết nối
Port I2C Mạch hiển thị MKE-M07 LCD1602 I2C module MakerEdu XH2.54 4Wires
Port D9 Cảm biến độ ẩm nhiệt độ MKE-S14 DHT11 temperature and humidity sensor MakerEdu XH2.54 3Wires
Port A1 Cảm biến ánh sáng quang trở MKE-S02 LDR light sensor MakerEdu XH2.54 3Wires
Port D10 Mạch còi báo MKE-M03 buzzer module MakerEdu XH2.54 3Wires

Kết quả

Sau khi đã nạp code thành công bạn có thể xem kết quả trực tiếp trên màn hình LCD, phía sau màn hình LCD có một biến trở (màu xanh dương) để chỉnh "độ tương phản" bạn có thể dùng tua vít để điều chỉnh bạn thấy quá đậm hoặc quá mờ.

Hiển thị thông tin nhiệt độ (T), độ ẩm (H) và ánh sáng (LDR) lên màn hình LCD
Hiển thị thông tin nhiệt độ (T), độ ẩm (H) và ánh sáng (LDR) lên màn hình LCD

Nhấn vào "biểu tượng kính lúp" hoặc chọn Tools > Serial Monitor để mở Serial Monitor, chọn đúng tốc độ Baudrate là 115200bps để thấy giá trị cảm biến hiển thị lên Serial Monitor.

Giá trị cảm biến hiển thị lên Serial Monitor
Giá trị cảm biến hiển thị lên Serial Monitor

Bài tập thêm (nâng cao)

Bài tập 1:

  • Viết chương trình hiển thị các giá trị của DHT11 (độ ẩm, nhiệt độ) và Quang trở (ánh sáng) lên màn hình LCD.
  • Còi báo động khi một trong hai giá trị "nhiệt độ" hoặc "độ ẩm" vượt ngưỡng.
  • Với nhiệt độ ngưỡng giá trị là trên 30ºC, còn với độ ẩm ngưỡng giá trị là trên 80%.
  • Thêm mạch đèn Led để tự động bật đèn khi trời tối, độ sáng đèn sẽ được điều chỉnh bằng Biến trở.

Lời giải.

Nguồn tài liệu (tham khảo thêm)

Bài viết liên quan