Dựa trên những lí thuyết căn bản về thiết kế mạch ta tiến hành xây dựng sơ đồ khối của hệ thống. Từ sơ đồ khối đó, ta tiến hành phân tích hoạt động và chức năng của từng khối. Bên cạnh đó chúng ta cũng cần tìm hiểu thêm về các giao thức truyền dữ liệu của vi điều khiển PIC 18F4520 với các thiết bị ngoại vi như: Giao thức I2C, RS232… để phục vụ cho việc viết chương trình cho mạch điện ở chương tiếp theo.
CHƯƠNG 3
MÔ HÌNH THỰC NGHIỆM VÀ KẾT QUẢ 3.1. Mô hình thực nghiệm
3.1.1. Sơ đồ nguyên lí
Hình 3. 1. Sơ đồ nguyên lí
Sơ đồ nguyên lí gồm 7 khối: Khối nguồn, khối thời gian thực, khối nút nhấn, khối vi điều khiển, khối cảm biến, khối LCD, khối thiết bị (máy bơm). Khi mạch được cấp điện áp 12VDC, khối cảm biến và khối thời gian thực sẽ lấy các giá trị nhiệt độ, độ ẩm và thời gian đưa về khối vi điều khiển để xử lí. Sau khi nhận dữ liệu từ các khối hỗ trợ, vi điều khiển tiến hành so sánh các giá trị thời gian, nhiệt độ, độ ẩm với các giá trị tương ứng được nhập từ 4 nút nhấn ở khối Button. Sau khi kiểm tra và tính toán các giá trị trên, nếu thỏa mã điều kiện cài đặt, vi điều khiển sẽ phát tín hiệu cho khối thiết bị (ở đây là máy bơm), khi máy bơm nhận được tín hiệu của vi điều khiển sẽ thực hiện bơm nước tự động trong khoảng thời gian cài đặt tại khối nút nhấn. Tất cả các giá trị thời gian, nhiệt độ, độ ẩm và các bước cài đặt cho hệ thống sẽ được hiển thị trên LCD 16x2.
3.1.2. Sơ đồ mạch in và mạch thực tế
3.1.2.1. Sơ đồ mạch in
Mạch PCB được vẽ trên phần mềm Altium 17.0.11, đây là phần mềm khá mạnh về thiết kế mạch hiện nay và được rất nhiều công ty sử dụng.
Altium Designer cung cấp một ứng dụng kết hợp tất cả công nghệ và chức năng cần thiết cho việc phát triển sản phẩm điện tử hoàn chỉnh, như thiết kế hệ thống ở mức bo mạch và FPGA, phát triển phần mềm nhúng cho FPGA và các bộ xử lý rời rạc, bố trí mạch in (PCB)… Altium Designer thống nhất toàn bộ các quá trình lại và cho phép bạn quản lý được mọi mặt quá trình phát triển hệ thống trong môi trường tích hợp duy nhất. Khả năng đó kết hợp với khả năng quản lý dữ liệu thiết kế hiện đại cho phép người sử dụng Altium Designer tạo ra nhiều hơn những sản phẩm điện tử thông minh, với chi phí sản phẩm thấp hơn và thời gian phát triển ngắn hơn. Thực ra điều này khiến Altium khá nặng nề, nhiều chức năng người dùng không dùng đến.
Hình 3. 2. Mạch in 2D
Hình 3. 3. Mạch khi được khởi tạo
Mạch điện khi được nạp chương trình sẽ hiển thị thời gian thực tế, thời gian kiểm tra nhiệt độ, độ ẩm và thời gian duy trì hoạt động của thiết bị (máy bơm).
Hình 3. 4. Cài đặt thời gian
Khi thời gian của mạch chưa được cập nhật so với thực tế, ta tiến hành cài đặt thời gian thông qua nút Set_BT.
Hình 3. 5. Cài đặt nhiệt độ, độ ẩm
Cài đặt nhiệt độ và độ ẩm để cảm biến DHT11 khi nhận giá trị nhiệt độ, độ ẩm thực tế sẽ gửi tín hiệu cho vi điều khiển. Sau khi tiếp nhận tín hiệu vi điều khiển sẽ so sánh với nhiệt độ, độ ẩm cài đặt. Nếu nhiệt độ, độ ẩm thỏa mãn với điều kiện ban đầu máy bơm sẽ hoạt động.
3.2. Đánh giá và kết luận 3.2.1. Kết quả đạt được
Về phần cứng:
- Tìm hiểu được về vi điều khiển PIC, để có thể tạo thành một mạch điện hoàn chỉnh vi điều khiển cần được ghép thêm với các thiết bị ngoại vi bên ngoài như bộ nhớ và các thiết bị khác. Trong đề tài này các thiết bị
- Có thêm nhiều kiến thức về các linh kiện như: điện trở, tụ điện…cũng như cách thiết kế mạch trên phần mềm Altium Designer và làm mạch thủ công.
Về phần mềm:
- Thiết kế mạch điện trên cơ sở lí thuyết của chương 2 và mô phỏng được mạch điện thông qua phần mềm Proteus. Phần mềm bao gồm 2 chương trình: ISIS cho phép mô phỏng mạch và ARES dùng để vẽ mạch in. Proteus là
công cụ mô phỏng cho các loại vi điều khiển khá tốt, nó hỗ trợ các dòng vi điều khiển PIC, 8051, PIC, dsPIC, AVR, HC11, MSP430, ARM7/LPC2000 ... các giao tiếp I2C, SPI, CAN, USB, Ethenet... ngoài ra còn mô phỏng các mạch số, mạch tương tự một cách hiệu quả. Proteus là bộ công cụ chuyên về mô phỏng mạch điện tử.
- Viết chương trình cho hệ thống dựa trên phần mềm CCS. Đây là trình biên dịch bằng ngôn ngữ C cho dòng vi điều khiển PIC đang được sử dụng phổ biến hiện nay hơn một số trình biên dịch khác vì nó là sự tích hợp của 3 trình biên dịch riêng biệt cho 3 dòng PIC khác nhau: PCB cho dòng PIC 12- bit opcodes, PCM cho dòng PIC 14-bit opcodes, PCH cho dòng PIC 16 và 18- bit. Tất cả 3 trình biên dich này đuợc tích hợp lại vào trong một chương trình bao gồm cả trình soạn thảo và biên dịch là CCS, phiên bản mới nhất là PCWH Compiler Ver 3.227. Giống như nhiều trình biên dich C khác cho PIC, CCS giúp cho người sử dụng nắm bắt nhanh được vi điều khiển PIC và sử dụng PIC trong các dự án. Các chương trình điều khiển sẽ được thực hiện nhanh chóng và đạt hiệu quả cao thông qua việc sử dụng ngôn ngữ lạp trình cấp cao – Ngôn ngữ C Tài liệu hướng dẫn sử dụng có rất nhiều, nhưng chi tiết nhất chính là bản Help đi kèm theo phần mềm (tài liệu Tiếng Anh). Trong bản trợ giúp nhà sản xuất đã mô tả rất nhiều về hằng, biến, chỉ thị tiền xủa lý, cấu trúc các câu lệnh trong chương trình, các hàm tạo sẵn cho người sử dụng…
Bên cạnh đó, đi sâu vào tìm hiểu giao thức I2C- là chuẩn giao tiếp ngoại vi cho rất nhiều loại IC khác nhau như: PIC, AVR, ARM…
Thiết kế được hệ thống đơn giản và đã chạy thực nghiệm trong thực tế.
3.2.2. Kết luận chương 3
Đề tài có tính ứng dụng khá nhiều trong cuộc sống:
- Tiết kiệm nước: Với việc sử dụng cảm biến đo nhiệt độ và độ ẩm.
Người sử dụng có thể thiết lập được thời gian máy bơm hoạt động để tưới nước trong một khoảng thời gian hợp lí.
nhiều sự tác động của con người. hoàn toàn có thể tự vận hành. Với các hệ thống có khả năng “cảm nhận” nhiệt độ hoặc độ ẩm thì nó hoàn toàn có khả năng đáp ứng đúng lúc và kịp thời nhu cầu của cây trồng dù trời mưa hay nắng.
- Thêm nữa, hệ thống này giúp giảm thiểu tối đa nhân công và số lượng người lao động nếu ứng dụng trên một diện tích tưới lớn.
Do việc thiết kế chỉ dừng lại ở mô hình nên chưa áp dụng được một số công nghệ mới, hiện đại: Trí tuệ nhân tạo (AI), IOT…
Hướng phát triển
Đề tài có thể phát triển thêm không chỉ tự động tưới mà chúng ta có thể theo dõi và điều khiển hệ thống qua Internet, module SIM hoặc máy tính để có thể điều khiển hệ thống từ xa chỉ cần các thiết bị được kết nối với mạng Internet, thuận tiện cho việc điều khiển hệ thống khi đi công tác để đảm bảo hệ thống có thể hoạt động một cách tối ưu nhất.
Vì lí do thời gian và những lí do khách quan nên đồ án được thực hiện vẫn còn nhiều khiếm khuyết. Em rất mong nhận được những ý kiến đóng góp quý báu của thầy cô.
TÀI LIỆU THAM KHẢO
[1] Vũ Trung Kiên – Phạm Văn Chiến – Nguyễn Văn Tùng [2014], Giáo trình vi điều khiển PIC, Nhà xuất bản khoa học và kĩ thuật Hà Nội.
[2] Các hệ thống tưới nước tự động
https://sites.google.com/site/caitiennongnhiep/cong-nghe-tuoi-nho-giot/cach- lua-chon-he-thong-tuoi-nho-giot
[3] Microchip, Datasheet PIC18F4520.
https://ww1.microchip.com/downloads/en/DeviceDoc/39631E.pdf [4] Cảm biến LM35 https://hshop.vn/products/cam-bien-nhiet-do-lm35-2 [5] Cảm biến Hs1101 http://hotro.banlinhkien.vn/t/cam-bien-do-am-hs1101-cach-su-dung/120 [8] Dallas, Datasheet Ds1307. https://www.sparkfun.com/datasheets/Components/DS1307.pdf [9] Khối hiển thị LCD https://toc.123doc.net/document/1411121-so-do-khoi-khoi-hien-thi-lcd.htm [10] Datasheet LM2576 http://entertech.vn/tin-tuc/huong-dan-su-dung-ic-nguon-lm2576/ [11] Giao thức I2C http://arduino.vn/bai-viet/1053-giao-tiep-i2c-voi-nhieu-module [12] http://dammedientu.vn/altium-designer-17-0-11-build-656-moi-nhat-full- crack-bid20-html/
PHỤ LỤC
//7-12-2020 : Mpdify code to use DHT11 //8-12-2020 : Change condition turn off pump #include <main.h>
#include <define_18f4520.h>
#use i2c(Master, sda = PIN_C4, scl=PIN_C3) #include <ds1307.c>
#define Slave_add 0x68 //Dia chi thanh ghi Ds1307 #define Read 1
#define Write 0
#define temp_add 10 //Dia chi eeproom nhiet do #define humi_add 15 //Dia chi eeproom do am #define hour_add 1 //Dia chi eeproom gio kiem tra #define minute_add 2 //Dia chi eeproom phut kiem tra
#define time_set_start_add 20 // Dia chi eeprom thoi diem bat dau kiem tra nhiet do , do am
#define time_turn_on_pump_add 25 //Dia chi eeproom bat may bom trong bao lau
//Define for BUTTON #define Set_BT RC0 #define Next_BT RC1 #define Up_BT RC2 #define Down_BT RD0
#define TRIS_Set_BT TRISC0 #define TRIS_Next_BT TRISC1 #define TRIS_Up_BT TRISC2 #define TRIS_Down_BT TRISD0
//Define for Pump Machine #define May_Bom RC5
#define TRIS_May_Bom TRISC5 //Define for Led test
#define Led_test RD2
#define TRIS_Led_test TRISD2 //Define For LCD
#define LCD_ENABLE_PIN PIN_B3 #define LCD_RS_PIN PIN_B5
#define LCD_RW_PIN PIN_B4 #define LCD_DATA4 PIN_B2 #define LCD_DATA5 PIN_B1 #define LCD_DATA6 PIN_B0 #define LCD_DATA7 PIN_D7
#define Data_Pin RD6 // Pin mapped to PORTB.0
#define Data_Pin_Direction TRISD6 // Pin direction mapped to TRISB.0
short Time_out;
unsigned int8 T_byte1, T_byte2, RH_byte1, RH_byte2, CheckSum ;
signed int8 sec,min,hrs,day,month,yr,dow;
int8 time_turn_on_pump = 1; // Turn on pump in 10 minute Signed int process_control = 0 ;
float nhiet_do = 10,do_am = 10;
float temp_point = 0 ,humi_point = 0 ; signed int hrs_point,min_point;
int16 time_display_lcd = 100;
int16 display = 0,time_set_finish = 0, point_finish= 0; boolean flag_turn_on_pump = 0;
void display_time(); void display_tem(); void main_ini();
void write_float_eeporm(long int n, float data); float read_float_eeprom(long int n);
void write_int32_eeporm(long int n, int32 data); int32 read_int32_eeprom(long int n);
void control_input_value_int(int8 *input_value); void set_time();
void control_input_value_float(float *input_value); void set_conditon_turn_on_pump();
void check_turn_on_pump(); void check_turn_off_pump(); void start_signal();
short check_response(); unsigned int8 Read_Data();
void main() {
main_ini(); lcd_init();
lcd_gotoxy(1,1);
lcd_putc(" Phi Hung "); delay_ms(2000);
ds1307_init();// khoi tao DS1307
// ds1307_set_date_time(6,5,20,5,22,48,0); ds1307_get_date(day,month,yr,dow); ds1307_get_time(hrs,min,sec);
if (Set_BT == 0 ) {
set_time(); // Set time by BUTTON } delay_ms(2); //check_before_start(); while(TRUE) { Time_out = 0; Start_signal(); if(check_response())
{ // If there is response from sensor
RH_byte1 = Read_Data(); // read RH byte1 RH_byte2 = Read_Data(); // read RH byte2 T_byte1 = Read_Data(); // read T byte1 T_byte2 = Read_Data(); // read T byte2
Checksum = Read_Data(); // read checksum }
ds1307_get_date(day,month,yr,dow); ds1307_get_time(hrs,min,sec); display++;
///display= 30 ; //Test chi hien thi do am
if (display < time_display_lcd)display_time(); // 2s hien thi thoi gian if (display >= time_display_lcd) // 2s hien thi nhiet do , do am
{ display_tem(); if (display >= (time_display_lcd*2))display = 0; } nhiet_do = T_byte1; do_am = RH_byte1; check_turn_on_pump(); check_turn_off_pump(); if (Set_BT == 0 ) { set_conditon_turn_on_pump(); } if (Up_BT == 0 ) { Led_test =1 ; May_Bom=1; } if(Down_BT == 0) { Led_test = 0 ;
May_Bom=0; } } } void display_time() { lcd_gotoxy(1,1); printf(lcd_putc,"Time: %d:%d:%d ",hrs,min,sec); if (flag_turn_on_pump ==0) { lcd_gotoxy(1,2); printf(lcd_putc,"Check:%d:%dIn%d ",hrs_point,min_point, time_turn_on_pump ); } else { lcd_gotoxy(1,2);
printf(lcd_putc,"%d-%d/Remain: %Lu ",hrs_point,min_point, (int16) (point_finish-min) ); } } void display_tem() { lcd_gotoxy(1,1); printf(lcd_putc," T:%2.1f/H:%2.1f ",nhiet_do,do_am); lcd_gotoxy(1,2);
printf(lcd_putc,"Set:%2.1f&%2.1f ",temp_point,humi_point); }
void main_ini() {
//Set Pin OF LCD is Output TRISB3 = 0 ; TRISB5 = 0 ; TRISB4 = 0 ; TRISB2 = 0 ; TRISB1 = 0 ; TRISB0 = 0 ; TRISD7 = 0 ; TRIS_Led_test = 0 ; TRIS_May_Bom = 0 ; TRIS_Up_BT = 1; TRIS_Down_BT = 1; TRIS_Set_BT = 1; TRIS_Next_BT = 1;
//Turn off led and pump machine Led_test = 0 ;
May_Bom=0;
// Read eeprom
temp_point = read_float_eeprom(temp_add); humi_point = read_float_eeprom (humi_add);
hrs_point = read_EEPROM (hour_add); min_point = read_EEPROM (minute_add);
time_turn_on_pump = read_EEPROM (time_turn_on_pump_add);
}
void start_signal() {
Data_Pin_Direction = 0; // Configure connection pin as output Data_Pin = 0; // Connection pin output low
delay_ms(25);
Data_Pin = 1; // Connection pin output high delay_us(30);
Data_Pin_Direction = 1; // Configure connection pin as input }
short check_response() {
delay_us(40); if(!Data_Pin)
{ // Read and test if connection pin is low delay_us(80);
if(Data_Pin)
{ // Read and test if connection pin is high delay_us(50);
return 1; }
} }
{
unsigned int8 i, k, _data = 0; // k is used to count 1 bit reading duration if(Time_out)
break;
for(i = 0; i < 8; i++){ k = 0;
while(!Data_Pin){ // Wait until pin goes high k++;
if (k > 100) {Time_out = 1; break;} delay_us(1);}
delay_us(30); if(!Data_Pin)
bit_clear(_data, (7 - i)); // Clear bit (7 - i) else{
bit_set(_data, (7 - i)); // Set bit (7 - i)
while(Data_Pin){ // Wait until pin goes low k++; if (k > 100) {Time_out = 1; break;} delay_us(1);} } } return _data; }
void write_float_eeporm(long int n, float data) {
int i;
for (i=0;i<4;i++) {
} }
float read_float_eeprom(long int n) {
int i;int8 read_data = 0; float data; for(i=0;i<4;i++) { read_data = read_EEPROM(i+n); *((int8*)&data + i ) = read_EEPROM(i+n); } return(data); }
void write_int32_eeporm(long int n, int32 data) { int i; for (i=0;i<4;i++) { write_eeprom(i+n,*((int8*)&data + i)); } }
int32 read_int32_eeprom(long int n) {
int i;int8 read_data = 0; int32 data;
for(i=0;i<4;i++) {
read_data = read_EEPROM(i+n);
}
return(data); }
void control_input_value_int(int8 *input_value) {
int8 control_value = *input_value; if (Up_BT == 0 ) {delay_ms(200);control_value = control_value + 1 ;} if (Down_BT == 0 ) {delay_ms(200);control_value = control_value -1 ;} *input_value = control_value; } void set_time() { lcd_gotoxy(1,1); lcd_putc("Set Time : "); delay_ms(1000); while(Set_BT == 0){delay_ms(100);} while(TRUE) { switch(process_control) {
case 0: //Set date lcd_gotoxy(1,1);
printf(lcd_putc,"Set date: %d ",day); control_input_value_int(&day);
if (day > 31)day = 1; if (day == 0 ) day= 31;
break;
case 1: //Set month lcd_gotoxy(1,1);
printf(lcd_putc,"Set month: %d ",month); control_input_value_int(&month);
if (month>12) month = 1; if (month < 1) month = 12; break;
case 2: //Set Year lcd_gotoxy(1,1);
printf(lcd_putc,"Set Year: %d ",yr); control_input_value_int(&yr);
if (yr > 50) yr = 20; if (yr < 20) yr = 50; break;
case 3: //Set Hour lcd_gotoxy(1,1); printf(lcd_putc,"Set Hour: %d ",hrs); control_input_value_int(&hrs); if (hrs > 23) hrs = 0 ; if (hrs < 0) hrs = 23 ; break;
case 4: //Set Minute lcd_gotoxy(1,1);
printf(lcd_putc,"Set Minute: %d ",min); control_input_value_int(&min);
if (min >59) min = 0; if (min <0) min = 59; break;
} if (Next_BT == 0 ) { while(Next_BT == 0)delay_ms(100); process_control++; if (process_control == 5) { process_control = 0; ds1307_set_date_time(day,month,yr,5,hrs,min,0); break; } } if (Set_BT == 0 ) { while(Set_BT == 0)delay_ms(100); process_control--; if (process_control < 0){process_control = 0;} } } }
void control_input_value_float(float *input_value1) {
float control_value = *input_value1; if (Up_BT == 0 ) {delay_ms(100);control_value = control_value + 1 ;} if (Down_BT == 0 ) {delay_ms(100);control_value = control_value - 1 ;} *input_value1 = control_value;
}
void set_conditon_turn_on_pump() {
lcd_gotoxy(1,1);
lcd_putc("Set time turn "); lcd_gotoxy(1,2);
lcd_putc("on the pump "); delay_ms(2000); while(Set_BT == 0){delay_ms(100);} while(TRUE) { switch(process_control) {
case 0: //Set temperature lcd_gotoxy(1,1);
printf(lcd_putc,"Set temperature: "); lcd_gotoxy(1,2);
printf(lcd_putc,"%f ",temp_point); control_input_value_float(&temp_point);
if (temp_point > 50) temp_point = -10 ; // De nhiet do cai dat chi nam trong : -20 -> 80, co the sua
if (temp_point <-10) temp_point = 50 ; break;
case 1: //Set humidity lcd_gotoxy(1,1);
printf(lcd_putc,"Set humidity: "); lcd_gotoxy(1,2);
printf(lcd_putc,"%f ",humi_point); control_input_value_float(&humi_point);
if (humi_point > 100) humi_point = 0 ; if (humi_point <0) humi_point = 100 ; break;
case 2: //Set Hour lcd_gotoxy(1,1);
printf(lcd_putc,"Set Hour: %d ",hrs_point); lcd_gotoxy(1,2); printf(lcd_putc," "); control_input_value_int(&hrs_point); if (hrs_point > 23) hrs_point = 0 ; if (hrs_point < 0) hrs_point = 23 ; break;
case 3: //Set Minute lcd_gotoxy(1,1);
printf(lcd_putc,"Set Minute: %d ",min_point); lcd_gotoxy(1,2); printf(lcd_putc," "); control_input_value_int(&min_point); if (min_point >59) min_point = 0; if (min_point<0) min_point =59; break;
case 4: // Set time turn on Pump lcd_gotoxy(1,1);
printf(lcd_putc,"Time turn on Pump "); lcd_gotoxy(1,2);
printf(lcd_putc," %d ",time_turn_on_pump); control_input_value_int(&time_turn_on_pump); break;
if (Next_BT == 0 ) { while(Next_BT == 0)delay_ms(100); process_control++; if (process_control == 5) { process_control = 0; write_float_eeporm(temp_add, temp_point); delay_ms(1); write_float_eeporm(humi_add, humi_point); delay_ms(1); write_eeprom(hour_add , hrs_point); delay_ms(1); write_eeprom(minute_add , min_point); delay_ms(1); write_eeprom(time_turn_on_pump_add, time_turn_on_pump); lcd_gotoxy(1,1); printf(lcd_putc,"Set done "); lcd_gotoxy(1,2); printf(lcd_putc," "); May_Bom = 0; Led_test =0 ; flag_turn_on_pump = 0 ; delay_ms(1000); break; } } if (Set_BT == 0 ) {
while(Set_BT == 0)delay_ms(100); process_control--; if (process_control < 0){process_control = 0;} } } } void check_turn_on_pump() {
if (hrs == hrs_point && min == min_point && sec < 5) {
if (nhiet_do > temp_point || do_am < humi_point) {
May_Bom = 1; Led_test =1 ;
if (flag_turn_on_pump ==0) {
write_int32_eeporm (time_set_start_add, min); }
time_set_finish= min + time_turn_on_pump; point_finish = time_set_finish;
if(time_set_finish >=60 )time_set_finish = time_set_finish -60; flag_turn_on_pump = 1; } } } void check_turn_off_pump() {
if (flag_turn_on_pump == 1 ) { if (min == time_set_finish) { May_Bom = 0; Led_test =0 ; flag_turn_on_pump = 0 ; lcd_gotoxy(12,2); printf(lcd_putc," "); } } }