Hình 3.6: Sơ đồ nguyên lý toàn mạch
- Khối điều khiển và xử lí trung tâm
Hình 3.7: Khối điều khiển và xử lí trung tâm
Khối xử lý trung tâm là Arduino nano, tiếp nhận tín hiệu đƣợc truyền từ các khối cảm biến sau đó phân tích và đƣa ra tín hiệu để điều khiển đèn báo, đồng thời hiển thị nội dung kết quả thực hiện trên màn hình LCD.
- Khối nguồn
Hình 3.8: Khối nguồn
Khối nguồn sử dụng nguồn 12V và mạch hạ áp lm2596 để chia nguồn cho các thiết bị.
- Khối cảm biến
Hình 3.9: Khối cảm biến
Khối cảm biến có chức năng đo các thông số (độ mặn, độ pH và xác định thời gian thực) truyền tín hiệu đến khối vi điều khiển trung tâm để xử lý. - Khối nút nhấn
Hình 3.10: Khối nút nhấn
- Khối hiển thị
Hình 3.11: Khối hiển thị
Khối hiển thị có nhiệm vụ nhận tín hiệu từ khối vi điều khiển trung tâm và hiển thị thông báo trên màn hình LCD.
Sử dụng module chuyển đổi I2C giúp việc giao tiếp đƣợc dễ dàng hơn, đồng thời tiết kiệm tài nguyên đầu ra cho vi điều khiển.
3.3.2 Tìm hiểu về các linh kiện điện tử trong hệ thống
- Arduino nano:
Arduino nano có thể sử dụng vi điều khiển ATmega328P. Bộ não này có thể xử lí những tác vụ đơn giản nhƣ điều khiển đèn LED nhấp nháy, xử lí tín hiệu cho xe điều khiển từ xa, làm một trạm đo nhiệt độ - độ ẩm, đo tốc độ động cơ và hiển thị lên màn hình LCD,…
Hình 3.12: Arduino uno
Bảng 3.1: Thông số kĩ thuật của arduino nano
Arduino Nano Thông số kỹ thuật
Số chân analog I/O 8
Tốc độ xung 16 MHz
Dòng tiêu thụ I/O 40mA
Số chân Digital I/O 22
ộ nhớ EEPROM 1 KB
ộ nhớ Flash 32 KB
Điện áp ng vào (7-12) Volts
Vi điều khiển ATmega328P
Điện áp hoạt động 5V
Kích thƣớc bo mạch 18 x 45 mm
Nguồn tiêu thụ 19mA
Ng ra PWM 6
SRAM 2KB
- LCD 162:
Thiết bị hiển thị LCD 162 đƣợc dùng rất nhiều trong ứng dụng của vi điều khiển. LCD 162 có rất nhiều ƣu điểm so với các thiết bị khác nhƣ: khả năng hiển thị kí tự da dạng đƣa vào mạch ứng dùng nhiều giao thức giao tiếp khác nhau dễ dàng, tiêu tốn rất ít tài nguyên hệ thống , giá thành rẻ, …
Hình 3.13: LCD 16*2
Chức năng của từng chân LCD 162:
Chân số 1 - VSS : chân nối đất cho LCD đƣợc nối với GND của mạch điều khiển
Chân số 2 - VDD : chân cấp nguồn cho LCD, đƣợc nối với VCC=5V của mạch điều khiển
Chân số 3 - VE : điều chỉnh độ tƣơng phản của LCD
Chân số 4 - RS : chân chọn thanh ghi, đƣợc nối với logic "0" hoặc logic "1":
Chân số 5 - R/W : chân chọn chế độ đọc/ghi (Read/Write), đƣợc nối với logic “0” để ghi hoặc nối với logic “1” đọc
Chân số 6 - EN : chân cho phép (Enable). Sau khi các tín hiệu đƣợc đặt lên bus DB0-DB7, các lệnh chỉ đƣợc chấp nhận khi có 1 xung cho phép
Chân số 7 đến 14 - D0 đến D7: 8 đƣờng của bus dữ liệu dùng để trao đổi thông tin với MPUChân số 15 - A : nguồn dƣơng cho đèn nền
Chân số 16 - K : nguồn âm cho đèn nền - Modun chuyển đổi i2c giao tiếp LCD:
Hình 3.14:Modun chuyển đổi i2c
Mục đích sử dụng : Chuyển đổi giao tiếp giữa vi điều khiển và LCD Thông số kĩ thuật :
Kích thƣớc: 41.5mm(L)X19mm(W)X15.3MM(H)
Trọng lƣợng : 5g
- Relay:
Rơle (relay) là một chuyển mạch hoạt động bằng điện. Dòng điện chạy qua cuộn dây của rơle tạo ra một từ trƣờng hút lõi sắt non làm thay đổi công tắc chuyển mạch. Dòng điện qua cuộn dây có thể đƣợc bật hoặc tắt vì thế rơle có hai vị trí chuyển mạch qua lại. Nó là một công tắc vì có 2 trạng thái ON và OFF. Rơ le ở trạng thái ON hay OFF phụ thuộc vào có dòng điện chạy qua rơ le hay không.
Hình 3.15: Module 4 Relay
Thông số kỹ thuật:
Số kênh relay: 4 kênh
Opto 817C cách li, chống nhiễu tốt
Led báo đóng ngắt trên relay
Điện áp điều khiển 5VDC
Đầu ra đóng ngắt : 30VDC/10A, 250VAC/10A o IN1…IN4: tín hiệu đầu vào, hoạt đông mức thấp o NO1…NO4: công tắc thƣờng mở
Hình 3.16: Sơ đồ chân của relay
- Module giao tiếp thời gian thực:
IC thời gian thực (RTC) DS1307 có chức năng cung cấp thông tin thời gian hiện tại (thời gian thực): giờ, phút, giây, thứ, ngày tháng, năm một cách chính xác ngay cả khi thiết bị đã bị tắt (ngắt điện ngoài). Giao tiếp với vi điều khiển thông qua chuẩn I2C, và đóng vai trò là slave khi kết nối đến bus I2C này. Có thể đếm thời gian theo định dạng 24 giờ hoặc 12 giờ với chỉ thị AM/PM. Ngoài ra bên trong 41hip có bộ dò phát hiện mất nguồn và tự động chuyển sang sử dụng nguồn pin dự phòng.
Tính năng nổi bật của IC RTC DS1307 :
Lƣu trữ và cung cấp các thông tin thời gian thực: ngày, tháng, năm, giờ, phút, giây,…
Khả năng thiết lập ngày đến năm 2100.
Tiêu thụ điện năng thấp: dòng tiêu thụ dƣới 500mA khi hoạt động bằng pin.
Tự động chuyển sang nguồn pin trong trƣờng hợp mất điện.
Đồng hồ 24 giờ hoặc 12 giờ với chỉ báo AM/PM.
Sử dụng chuẩn giao tiếp I2C.
Hình 3.17: Module giao tiếp thời gian thực
- Mạch Giảm Áp DC LM2596 3A:
Mạch giảm áp DC LM2596 3A nhỏ gọn có khả năng giảm áp từ 30V xuống 1.5V mà vẫn đạt hiệu suất cao (92%) . Thích hợp cho các ứng dụng chia nguồn, hạ áp, cấp cho các thiết bị nhƣ camera, motor, robot,…
Hình 3.18: Mạch Giảm Áp DC LM2596 3A
Thông số kỹ thuật:
Điện áp đầu vào: Từ 3V đến 30V.
Điện áp đầu ra: Điều chỉnh đƣợc trong khoảng 1.5V đến 30V.
Dòng đáp ứng tối đa là 3A.
Hiệu suất: 92%
Công suất: 15W
- Động cơ giảm tốc mini:
Hình 3.19: Motor giảm tốc mini
Thông số kỹ thuật
Điện áp hoạt động : 3 – 9VDC
Mẫu điện tiêu thụ: 110 – 140mA
Tỉ số truyền: 1:48
Moment: 0.8KG.CM
3.4 Chế tạo, thử nghiệm và đánh giá hệ thống 3.4.1 Chế tạo 3.4.1 Chế tạo
Thiết kế sơ đồ mạch in:
Hình 3.21: Mạch khi đã hoàn thành
3.4.2 Thử nghiệm
- So sánh các thông số giữa kiểu đo truyền thống và qua cảm biến:
Bảng 3.2: Bảng đánh giá độ pH qua giấy thử và cảm biến đo
Lần đo Giấy thử (Δ1) Cảm biến pH (Δ2) Sai số (|Δ1- Δ2|)
1 3 2.78 0.22 2 4 3.5 0.5 3 6 5.6 0.4 4 8 8.6 0.4 5 10 9.8 0.2 6 11 10.4 0.4 - Nhận xét:
Nguyên nhân sai số: do giấy thử có màu sắc tƣơng đối giống nhau (khi pH gần nhau) nên sẽ gây ra sai lệch (không quá 1 màu)
Cách khắc phục: đo nhiều lần để đảm bảo màu trong ngƣỡng gần nhất
Bảng 3.3: Bảng đánh giá độ mặn qua thước đo độ mặn và cảm biến đo
Lần đo Thƣớc đo độ mặn (Δ1) Cảm biến độ mặn(Δ2) Sai số (|Δ1- Δ2|)
1 1.5 2 0.5
2 2.7 3 0.3
3 4 4 0
- Nhận xét:
Nguyên nhân sai số: tỷ trọng là đại lƣợng ảnh hƣởng bởi nhiệt độ nên sẽ có sai lệch
Cách khắc phục: cần phải kiểm tra nhiệt độ của mẫu, đƣa mẫu về mức tiêu chuẩn để thực hiện đo với độ chính xác cao nhất.
3.4.3 Đánh giá hệ thống
Ƣu điểm:
Mô hình sản phẩm hoạt động ổn định
Chi phí đầu tƣ hợp lý
Mô hình chắc chắn, đảm bảo về hình dáng lẫn kết cấu
Nhƣợc điểm:
Không chịu đƣợc va đập mạnh
Tính thẩm mỹ còn hạn chế
KẾT LUẬN VÀ ĐÈ XUẤT PHÁT TRIỂN Kết luận
- Hệ thống giám sát và cảnh báo tự động một số thông số môi trƣờng trong các ao nuôi tôm hoạt động ổn định trong quá trình thử nghiệm. - Các chức năng hoạt động của hệ thống bao gồm chế độ điều khiển bằng
tay, chế độ chạy tự động theo thời gian cài đặt và chức năng cảnh báo khi các thông số trong ao nuôi nằm ngoài ngƣỡng cho phép (7,5 < pH < 8,5; 2 < S < 4) hoạt động đúng theo yêu cầu đặt ra.
- Trong nghiên cứu này, nhóm đã tiến hành đánh giá so sánh kết quả đo của hệ thống với một số kỹ thuật đo thƣờng dùng trong nuôi trồng thủy sản hiện nay, bƣớc đầu cho thấy hệ thống có thể đáp ứng yêu cầu đo trong nuôi trồng thủy sản.
- Tuy nhiên hệ thống còn nhiều hạn chế. Trong thời gian tới, chúng em sẽ tiếp tục nghiên cứu, thử nghiệm để phát triển hệ thống có thêm đầu đo cho các thông số khác của môi trƣờng ao nuôi; thiết kế thêm chức năng lƣu trữ dữ liệu hỗ trợ cho quá trình giám sát ao nuôi trong thời gian dài, đánh giá sai số của hệ thống chế tạo đƣợc với các thiết bị đo lƣờng tiêu chuẩn.
Đề xuất phát triển đề tài:
- Nghiên cứu phát triển tích hợp một số chức năng khác nhƣ: độ kiềm, nồng độ khoáng chất, nồng độ nitrat, nồng độ phốt pho,…và pin năng lƣợng tự điều chỉnh theo ánh sáng mặt trời.
- Chế tạo hệ thống giám sát và cảnh báo tự động để giám sát từ xa môi trƣờng nƣớc của ao nuôi thông qua một ứng dụng đƣợc cài đặt trên điện thoại thông minh.
- Cải tiến kỹ thuật giúp sản phẩm có khả năng đo các chỉ số chính xác hơn.
- Thiết kế mô hình có tính thẩm mỹ và kỹ thuật cao hơn.
TÀI LIỆU THAM KHẢO
1. "Phenolphthalein",
https://thietbikhoahoccongnghe.com.vn/phenolphthalein.html
2."Tỷ trọng kế bằng thủy tinh", https://matsu.vn/product/c-210/Ty-trong-ke- thuy-tinh.html
3."Tỷ trọng kế cầm tay bằng nhựa'', http://tanhoa.net/san-pham/ty-trong-ke- chuyen-dung-amarellduc.htmls
4. ''Khúc xạ kế''. https://maydochuyendung.com/khuc-xa-ke
5.''Hóa chất và thuốc thử đo DO'', https://emin.vn/hoa-chat-va-thuoc-thu- 779/pc.html
6. ''Độ bão hòa oxy dựa vào nhiệt độ và độ mặn'', https://thinhphu.vn/oxy- hoa-tan-do-la-gi.html
7. ''Cảm biến đo pH'', https://mlab.vn/index.php?_route_=2433600-cam-bien- do-ph.html
8. ''Module cảm biến đo độ ẩm'', https://www.dientudat.com/cam-bien-do-am
9. ''Bảng chuyển đổi đơn vị đo giữa độ dẫn điện dung dịch và độ mặn của dung dịch'', https://tp-tech.vn/bang-chuyen-doi-do-man-tds-do-dan-dien/
10.'' Pin năng lượng mặt trời'', https://vuphong.vn/cau-tao-pin-nang-luong- mat-troi/
11. ''Cấu tạo của pin năng lượng mặt trờ''i, https://vuphong.vn/cau-tao-pin- nang-luong-mat-troi/
12. ''Mạch chuyển đồi điện từ năng lượng mặt trời'', https://vi.jf-parede.pt/9- simple-solar-battery-charger-circuits
Vũ Trung Kiên.Giáo trình môn vi điều khiển. Hà Nội : KHKT, 2014.
Lê Ngọc Duy. Giáo trình môn cảm biến và hệ thống đo. Hà Nội : KH&KT, 2019.
PHỤ LỤC Chƣơng trình điều khiển:
#include<Wire.h> #include<LiquidCrystal_I2C.h> LiquidCrystal_I2C lcd(0x27, 16, 2); /* Địa chỉ của DS1307 */ const byte DS1307 = 0x68; /* Số byte dữ liệu sẽ đọc từ DS1307 */ const byte NumberOfFields = 7;
/* khai báo các biến thời gian */
int second, minute, hour, day, wday, month, year; #define maybom 11 #define dongco1 7 #define dongco2 8 #define dongco3 9 #define dongco4 10 #define congtac1 2 #define congtac2 3 #define congtac3 4 #define congtac4 5 #define congtac5 6 #define led 12 #define led2 A0 int time1 = 0;
#define ph123 A3 #define doam A2 #define Offset 0.70 int doman;
unsigned long int avgValue; float value;
float phValue;
int cout1, cout2, cout3, cout4, cout5; int mode = 2;
#define samplingInterval 20 #define printInterval 800
#define ArrayLenth 40 //times of collection
int pHArray[ArrayLenth]; //Store the average value of the sensor feedback
int pHArrayIndex = 0; void setup() {
// put your setup code here, to run once: Wire.begin();
/* cài đặt thời gian cho module */ //setTime(23, 40, 0, 4, 18, 5, 22); Serial.begin(9600);
lcd.init(); lcd.backlight(); lcd.setCursor(0, 1);
pinMode(maybom, OUTPUT); pinMode(dongco1, OUTPUT); pinMode(dongco2, OUTPUT); pinMode(dongco3, OUTPUT); pinMode(dongco4, OUTPUT);
pinMode(congtac1, INPUT_PULLUP); pinMode(congtac2, INPUT_PULLUP); pinMode(congtac3, INPUT_PULLUP); pinMode(congtac4, INPUT_PULLUP); pinMode(congtac5, INPUT_PULLUP);
digitalWrite(maybom, LOW); digitalWrite(dongco1, LOW); digitalWrite(dongco2, LOW); digitalWrite(dongco3, LOW); digitalWrite(dongco4, LOW);
pinMode(led, INPUT_PULLUP); pinMode(led2, INPUT_PULLUP); digitalWrite(led, LOW); digitalWrite(led2, LOW);
cout1 = 1; cout2 = 1; cout3 = 1; cout4=1; cout5 = 1; } void doman123() { value = analogRead(doam);
if (value > 270 && value < 600) doman = 0.0; else {
doman = map(value, 0, 1023, 500, 0) * 0.01; }
//Serial.println(doman); lcd.setCursor(0, 1);
lcd.print("S:"); lcd.setCursor(3, 1); lcd.print(doman); if (doman >= 2) { digitalWrite(led, HIGH); } else { digitalWrite(led, LOW); } } void ph() {
static unsigned long samplingTime = millis(); static unsigned long printTime = millis(); static float pHValue, voltage;
if (millis() - samplingTime > samplingInterval) {
pHArray[pHArrayIndex++] = analogRead(ph123); if (pHArrayIndex == ArrayLenth)pHArrayIndex = 0; voltage = avergearray(pHArray, ArrayLenth) * 5.0 / 1024; pHValue = 3.5 * voltage + Offset;
for (int i = 2; i < 3; i++) { phValue += pHValue; delay(100);
phValue = phValue / 2; samplingTime = millis(); }
if (millis() - printTime > printInterval) //Every 800 milliseconds, print a numerical, convert the state of the LED indicator
{ Serial.print("Voltage:"); Serial.print(voltage, 2); Serial.print(" pH value: "); Serial.println(pHValue, 2); printTime = millis(); } lcd.setCursor(6, 1); lcd.print("PH:"); lcd.setCursor(10, 1); lcd.print(pHValue); delay(100); if (phValue > 8.5 || phValue < 6.5 ) { //digitalWrite(maybom,LOW); digitalWrite(led2, HIGH); } else {
//digitalWrite(maybom,HIGH); digitalWrite(led2, LOW); }
}
double avergearray(int* arr, int number) { int i;
int max, min; double avg; long amount = 0; if (number <= 0) {
Serial.println("Error number for the array to avraging!/n"); return 0;
}
if (number < 5) { //less than 5, calculated directly statistics for (i = 0; i < number; i++) {
amount += arr[i]; }
avg = amount / number; return avg;
} else {
if (arr[0] < arr[1]) {
min = arr[0]; max = arr[1]; }
min = arr[1]; max = arr[0]; }
for (i = 2; i < number; i++) { if (arr[i] < min) {
amount += min; //arr<min min = arr[i];
} else {
if (arr[i] > max) {
amount += max; //arr>max max = arr[i];
} else {
amount += arr[i]; //min<=arr<=max }
}//if }//for
avg = (double)amount / (number - 2); }//if return avg; } void readDS1307() { Wire.beginTransmission(DS1307); Wire.write((byte)0x00); Wire.endTransmission();
Wire.requestFrom(DS1307, NumberOfFields); second = bcd2dec(Wire.read() & 0x7f);
minute = bcd2dec(Wire.read() );
hour = bcd2dec(Wire.read() & 0x3f); // chế độ 24h. wday = bcd2dec(Wire.read() ); day = bcd2dec(Wire.read() ); month = bcd2dec(Wire.read() ); year = bcd2dec(Wire.read() ); year += 2000; }
/* Chuyển từ format BCD (Binary-Coded Decimal) sang Decimal */ int bcd2dec(byte num)
{
return ((num / 16 * 10) + (num % 16)); }
/* Chuyển từ Decimal sang BCD */ int dec2bcd(byte num)
{
return ((num / 10 * 16) + (num % 10)); }
void LCDClockDisplay() {
// digital clock display of the time lcd.setCursor(0, 0);
lcd.print(hour); lcd.print(":"); lcd.setCursor(3, 0); lcd.print(minute); lcd.print(":"); lcd.setCursor(6, 0); lcd.print(second); if (hour < 10) { lcd.setCursor(0, 0); lcd.print("0"); lcd.print(hour); lcd.print(":"); } if (minute < 10) { lcd.setCursor(3, 0); lcd.print("0"); lcd.print(minute); lcd.print(":"); } if (second < 10) { lcd.setCursor(6, 0); lcd.print("0"); lcd.print(second);
} }
void printDigits(int digits) {
// các thành phần thời gian đƣợc ngăn chách bằng dấu : lcd.print(":"); if (digits < 10) { Serial.print('0'); lcd.print("0"); lcd.print(digits); Serial.print(digits); } }
/* cài đặt thời gian cho DS1307 */
void setTime(byte hr, byte min, byte sec, byte wd, byte d, byte mth, byte yr)
{
Wire.beginTransmission(DS1307); Wire.write(byte(0x00)); // đặt lại pointer Wire.write(dec2bcd(sec));
Wire.write(dec2bcd(min)); Wire.write(dec2bcd(hr));
Wire.write(dec2bcd(wd)); // day of week: Sunday = 1, Saturday = 7 Wire.write(dec2bcd(d));
Wire.write(dec2bcd(yr)); Wire.endTransmission(); }
void loop() {
// put your main code here, to run repeatedly: for (int i = 0; i < 100; i++) {
ph(); readDS1307(); LCDClockDisplay(); doman123(); // Serial.println(digitalRead(congtac1)); if (digitalRead(congtac1) == 0) { delay(25); if (digitalRead(congtac1) == 0) { while(digitalRead(congtac1) == 0); if (cout1 != 2){ mode = 1; //Serial.println("Chedotudong"); digitalWrite(dongco1, LOW); digitalWrite(dongco2, LOW); digitalWrite(dongco3, LOW); digitalWrite(dongco4, LOW);
} else if (cout1 == 2) { mode = 2; cout1 = 0; digitalWrite(dongco1, LOW); digitalWrite(dongco2, LOW); digitalWrite(dongco3, LOW); digitalWrite(dongco4, LOW); } cout1++; } } // if (digitalRead(congtac2) == 0) // { // digitalWrite(dongco1, HIGH); // cout2++; // if (cout2 == 2) { // digitalWrite(dongco1, LOW); // cout2 = 0; // } // } if (mode == 1){
if (digitalRead(congtac2) == 0) { delay(25); if (digitalRead(congtac2) == 0) { while(digitalRead(congtac2) == 0); if (cout2 != 2){ Serial.println("chedochay"); digitalWrite(dongco1, HIGH);