L ỜI CAM ĐOAN
5. Kết luận
2.5 Lưu đồ thuật toán lấy mẫu bụi
49
CHƯƠNG 3: KẾT QUẢ THỰC NGHIỆM VÀ ĐÁNH GIÁ
3.1 Kết quả phần cứng
Sau khi tiến hành nghiên cứu thiết kế. Học viên đã đạt được một số kết quảban đầu cho mạch lấy mẫu bụi. Mạch lấy mẫu bụi thể hiện trên Hình 3.1.
Hình 3. 1 Khối lấy mẫu bụi
Khí lấy mẫu được bơm hút cho đi qua bộ lọc tách nước trước khi vào bình lấy mẫu. Bình này được thông ra ngoài môi trường nhằm cân bằng áp suất. Một mạch đo nhiệt độ, độẩm cũng được thiết kếđểđo nhiệt độvà độẩm của khí lấy mẫu này. Do bụi cần đo là bụi lơ lửng nên việc đặt vị trí các điểm lấy mẫu để đưa đến cảm biến đo là quan trọng.
Mạch điều khiển lấy mẫu làm việc dựa trên STM32. Phần điều khiển trung tâm của mạch lấy mẫu thể hiện trên hình 3.2. Mặc dù tính năng lấy mẫu là một tính năng quan trọng, nhưng mạch này còn thực hiện thêm nhiều công việc khác. Do nội dung nghiên cứu của đề tài này là một phần trong đề tài lớn về thiết kế hệ thống đo bụi trong công nghiệp.
50
Hình 3. 2 Mạch kết nối cảm biến với vi điều khiển STM32F103
Những kết quả ban đầu đạt được của phần lấy mẫu thể hiện trong phần kết quảđo bụi, thể hiện trong Mục 3.2 của chương này.
3.2 Kết quả phần mềm
Các đường lấy mẫu đo bụi từ hệ lấy mẫu này sẽ cho kết quả thông qua các cảm biến đo, bao gồm thông số về nồng độ bụi PM2.5, PM10 và bụi tổng TSP, ngoài ra các số liệu về nhiệt độ, độ ẩm cũng được thể hiện trên màn hình LCD. Số liệu về nồng độ bụi PM10 thể hiện trên Hình 3.3.
51 Nồng độ bụi PM2.5 thể hiện trên Hình 3.4.
Hình 3. 4 Kết quả mẫu bụi PM2.5
Nồng độ bụi tổng TSP thể hiện trên Hình 3.5.
Hình 3. 5 Kết quả mẫu bụi TSP
Độ chính xác của các phép đo này bước đầu đã được kiểm định tại trung tâm kiểm định của Tổng cục môi trường đã cho thấy kết quảđo là chính xác, điều đó chứng tỏ hệ thống lấy mẫu đã hoạt động đúng.
52
KẾT LUẬN
Trong quá trình thực hiện luận văn với đề tài “Nghiên cứu thiết kế hệ lấy mẫu bụi trong công nghiệp” đây là một phần của đề tài nghiên cứu về Hệ thống đo và giám sát nồng đồ bụi trong công nghiệp, Học viên đã thu được những kết quả sau đây:
• Nghiên cứu về bụi, các đặc điểm về dòng bụi lấy mẫu trong công nghiệp
• Nghiên cứu về phần mềm cho vi điều khiển STM32
• Nghiên cứu về thiết kế mạch cho hệ lấy mẫu
• Tính toán thiết kế mạch lấy mẫu
• Thiết kế được hệ lấy mẫu phục vụ cho Hệ thống đo và giám sát nồng độ bụi trong công nghiệp.
• Đã chạy hệ lấy mẫu để phục vụ hệđo và giám nồng độ bụi trong công nghiệp hoạt động.
Mặc dù đã đạt được một số kết quả ban đầu nên trên, đề tài cũng tồn tại nhiều nhược điểm cần tiếp tục được cải tiến như:
• Cho phép điều khiển lưu lượng lấy mẫu thông qua các thuật toán PID cài đặt trong vi điều khiển
• Tính toán lại bình lấy mẫu để đo được nhiều loại khí khác nhau ứng dụng cho các hệ thống quan trắc chất lượng không khí.
53
DANH MỤC TÀI LIỆU THAM KHẢO
[1]. “A Lab Project on the Design and Implementation of Programmable and Configurable Embedded Systems” by Sousa, L. ,Antao,S. ; Germano, J in
Education, IEEE Transactions on (Volume:56 , Issue: 3), pp 322-328, 10 Nov
2012.
[2]. “Air to liquid sample collection devices using microfluidic gas/liquid interfaces” by Greenwood, J. Darning Cheng ; Ye Liu ; Hongrui Jiang in Sensors,
2008 IEEE, pp 720-723, 26-29 Oct. 2008.
[3]. “An Embedded Software Reliability Model with Consideration of Hardware Related Software Failures” by Jinhee Park, Hyeon-Jeong, Kim ; Ju-Hwan Shin ; Jongmoon Baik in Software Security and Reliability (SERE), 2012 IEEE
Sixth International Conference on ,pp 207 – 214, 20-22 June 2012.
[4]. “Component-based software engineering for embedded systems” by Crnkovic, I. in Software Engineering, 2005. ICSE 2005. Proceedings. 27th International Conference, pp 712-713, 15-21 May 2005.
[5]. Embedded C, Michael J. Pont.
[6]. “Embedded System Design”(paperback) by P.Marwedel, Springer Verlag, December 2005.
[7]. “Embedded Systems -- A Security Paradigm for Pervasive Computing” by Sharma, S in Communication Systems and Network Technologies (CSNT), 2013
International Conference, pp 472-477, 6-8 April 2013.
[8]. “Embedded systems design — Scientific challenges and work directions” by Sifakis, J. Verimag in Formal Methods in Computer-Aided Design
(FMCAD), 2010, pp 11, 20-23 Oct. 2010.
[9]. F8X14 Series User Manual.
[10]. “Methods of Air Sampling and Analysis, 3rd ed” by James Lodge, Jr in
Environ. Sci. Technol, pp 938, 23 August 1989.
[11] Patterns for time-triggered embedded systems, Michael J. Pont. [12] QC12864 datasheet.
54 [13] SDS011 datasheet.
[14]. STMicroelectronics.Reference_Manual.
[15]. “Teaching embedded systems engineering in a software-oriented computing degree” by Fernandes, J.M. Machado, R.Jn in Frontiers In Education
Conference - Global Engineering: Knowledge Without Borders, Opportunities Without Passports, 2007. FIE '07. 37th Annual, pp F3H-5 - F3H-10, 10-13 Oct.
2007.
[16]. www.arm.vn/ [17]. www.hocavr.com/ [18]. www.icviet.vn/
55
PHỤ LỤC
1. Chương trình điều khiển bơm qua giao tiếp USART
#include “stm32f10x.h” #include “stm32f10x_usart.h” #include “stm32f10x_it.h” int main()
{
// cài đặt cho công giao tiếp USART3
GPIO_InitTypeDef GPIO_USART3; USART_InitTypeDef USART_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; //cấu hình các thông số cho USART3
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3,ENABLE); USART_InitStructure.USART_BaudRate = 115200; USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_StopBits = USART_StopBits_1; USART_InitStructure.USART_Parity = USART_Parity_No; USART_InitStructure.USART_HardwareFlowControl USART_HardwareFlowControl_None; USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_ITConfig(USART3,USART_IT_RXNE, ENABLE);//cho phep ngát RX USART_Init(USART3,&USART_InitStructure); USART_Cmd(USART3,ENABLE); //cài đặt chân TX GPIO_USART3.GPIO_Mode =GPIO_Mode_AF_PP; GPIO_USART3.GPIO_Speed =GPIO_Speed_2MHz; GPIO_USART3.GPIO_Pin =GPIO_Pin_10;
56 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); GPIO_Init(GPIOB,&GPIO_USART3); //cài đặt chân RX GPIO_USART3.GPIO_Mode =GPIO_Mode_IPU; GPIO_USART3.GPIO_Speed =GPIO_Speed_2MHz; GPIO_USART3.GPIO_Pin =GPIO_Pin_11; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); GPIO_Init(GPIOB,&GPIO_USART3); //cấu hình ngắt USART3 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); /* Enable the USART3 Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority =0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure);
// cài đặt cho chân PE1:
GPIO_InitTypeDef GPIO_Role; RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOE | RCC_APB2Periph_AFIO, ENABLE); GPIO_Role.GPIO_Pin=GPIO_Pin_1; GPIO_Role.GPIO_Mode=GPIO_Mode_Out_PP; GPIO_Role.GPIO_Speed= GPIO_Speed_2MHz; GPIO_Init(GPIOE,&GPIO_Role); GPIO_SetBits(GPIOE,GPIO_Pin_1);//bat role //vòng lặp While(1){}; } void USART3_IRQHandler()
57 {
static char p=0;
if (USART_GetITStatus(USART3, USART_IT_RXNE) != RESET) { Data3[p++] = USART_ReceiveData(USART3); if(p==4) { p=0; if(Data3[0]==0xee) {
if(Data3[1]==0xb2) GPIO_SetBits(GPIOE,GPIO_Pin_1); //bật bơm else if(Data3[1]==0xd8) GPIO_ResetBits(GPIOE,GPIO_Pin_1);//tắt bơm
} } } USART_ClearITPendingBit(USART3,USART_IT_RXNE); } }
2. Chương trình lập trình trên KeilC
Tổng kết lại các hàm của từng thư viện: - Thư viện USART_TM.h:
+ USART2_Init_TM() : thiết lập cổng USART2 để giao tiếp với SDS011.
+ USART2_IRQHandler() : nhận dữ liệu mỗi khi SDS011 truyền tới.
+ USART3_Init_TM() : thiết lập cổng USART3 để giao tiếp với module GPRS.
- Thư viện GLCD_TM.h:
58
+ GLCD_Send_Bit() : gửi một bit . + GLCD_Send_Instruction() : gửi một byte lệnh. + GLCD_Send_Data() : gửi một byte dữ liệu. + GLCD_Gotoxy() : đưa con trỏđến một vịtrí cho trước. + GLCD_Putchar() : ghi một ký tự lên GLCD.
+ GLCD_Puts() : ghi một chuối lên GLCD. + GLCD_Clear() : xóa toàn màn hình GLCD. + GLCD_Init() : khởi tạo GLCD.
+ Check_usart() : kiểm tra dữ liệu hợp lệ thu được từ SDS011 và SDS198.
+ GLCD_Update() : thu thập dữ liệu để hiện thị GLCD và truyên lên module GPRS.
- Thư viện bổ trợ delay.h:
+ delay_init() : cài đặt đồng hồ thời gian thực. + delay_ms() : tạo trễđơn vị miligiây.
+ delay_us() : tạo trễđơn vị microgiây.
- File thư viện main.h gồm các thư viện đã được tạo trước đó: #include "stm32f10x.h" #include "GLCD_TM.h" #include "USART_TM.h" #include "string.h" #include "stdio.h" #include "delay.h" File chương chình chính:
#include "main.h" //include các thư viện //khai báo các biến chứa dữ liệu thu được
volatile unsigned char Data2[10]=""; //lưu dữ liệu nhận được từ SDS011 int main()
59 //khởi tạo GLCD_Delay(2000); GLCD_Init(); //khởi tạo GLCD delay_init(72); //khởi tạo trễ thời gian thực USART2_Init_TM(); //khởi tạo cổng USART2 USART3_Init_TM(); //khởi tạo cổng USART3 delay_ms(300); //tạo trễ300ms để hệ thống chạy ổn định while(1) {
GLCD_Update(); //thu thập dữ liệu hiển thị lên GLCD và gửi lên server
delay_ms(1000); //tạo trễ 1 giây rồi quay lại vòng lặp }
3. Thiết lập giao tiếp với SDS011
void USART2_Init_TM(void) // đặt cổng USART2 để nhận dữ liệu từ SDS011 { //định nghĩa các biến GPIO_InitTypeDef GPIO_USART2; USART_InitTypeDef USART_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; //cấu hình các thông số RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE); USART_InitStructure.USART_BaudRate = 9600; USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_StopBits = USART_StopBits_1; USART_InitStructure.USART_Parity = USART_Parity_No; USART_InitStructure.USART_HardwareFlowControl= USART_HardwareFlowControl_None;
60 USART_Init(USART2,&USART_InitStructure); USART_ITConfig(USART2,USART_IT_RXNE, ENABLE);//cho phép ngắt //RX USART_Cmd(USART2,ENABLE); //cài đặt chân TX GPIO_USART2.GPIO_Mode=GPIO_Mode_AF_PP; GPIO_USART2.GPIO_Speed=GPIO_Speed_2MHz; GPIO_USART2.GPIO_Pin=GPIO_Pin_2; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); GPIO_Init(GPIOA,&GPIO_USART2); //cài đặt chân RX GPIO_USART2.GPIO_Mode=GPIO_Mode_IPU; GPIO_USART2.GPIO_Speed=GPIO_Speed_2MHz; GPIO_USART2.GPIO_Pin=GPIO_Pin_3; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); GPIO_Init(GPIOA,&GPIO_USART2); // cấu hình ngắt USART2 để thu dữ liệu NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); }
void USART2_IRQHandler() //hàm nhận dữ liệu trong ngắt {
if (USART_GetITStatus(USART2, USART_IT_RXNE) != RESET) {
61 if(n==10) n=0;
USART_ClearITPendingBit(USART2,USART_IT_RXNE); }
}
//Biến Data2 được dùng đểlưu số liệu nhận được từ SDS011 char check_usart(char i, unsigned char *da)
{
if(i==1) //kiểm tra tính hợp lệ của dữ liệu nhận được từ SDS198 { if((da[0]!=0xAA)||(da[1]!=0xCF)||(da[9]!=0xAB)||(da[8]!=(unsigned char)(da[2]+da[3]+da[4]+da[5]+da[6]+da[7]))) return 0; else return 1; }
else if(i==2) //kiểm tra tính hợp lệ của dữ liệu nhận được từ SDS011 { if((da[0]!=0xAA)||(da[1]!=0xC0)||(da[9]!=0xAB)||(da[8]!=(unsigned char)(da[2]+da[3]+da[4]+da[5]+da[6]+da[7]))) return 0; else return 1; } return 0; } Để kiểm tra tính hợp lệ của dữ liệu nhận được từ SDS011.
Gọi hàm check_usart(2, Data2) nếu hàm trả về 1 dữ liệu hợp lê, trả về 0 dữ liệu không hợp lệ.
62
4. Tập lệnh LCD
- Display clear: xóa LCD, lệnh này xóa toàn bộ nội dung DDRAM và vì thế xóa toàn bộ hiển thị trên LCD. Vì đây là 1 lệnh ghi Instruction nên chân RS phải được reset về0 trước khi ghi lệnh này lên LCD. Mã lệnh xóa LCD là 0x01.
- Return home: đưa con trỏ về vịtrí đầu, dòng 1 của LCD: lệnh này thực hiện việc đưa con trỏ về vịtrí đầu tiên của bộ nhớ DDRAM, vì thế nếu sau lệnh này một biến được ghi vào DDRAM thì biến này sẽ nằm ở vịtrí đầu tiên (1;1). RS cũng phải bằng 0 trước khi ghi lệnh. Mã lệnh là 0x02 hoặc 0x03(chọn 1 trong 2 mã lệnh, tùy ý).
- Entry mode set: xác lập các hiện thị liên tiếp cho LCD: lệnh này chỉ ra cách mà ta muốn hiển thị một ký tự tiếp theo 1 ký tựtrước đó. Ví dụ nếu muốn hiện thị 2 ký tự liên tiếp AB, trước hết ta viết A tại vị trí 5, dòng 1. Sau đó ghi B vào LCD, lúc này có 4 cách mà LCD có thể hiển thị B như sau: hiển thị B bên phải A tại vị trí số 6 (cách 1); B cũng có thểđược hiển thị bên trái A, tại vị trí số 4(cách 2); hoặc LCD có thể tự dịch chuyển A về bên trái đến vị trí 4 sau đó hiển thị B bên phải A, tại vị trí 5(cách 3); và khảnăng cuối cùng là LCD dịch chuyển A về bên phải đến vị trí 6 sau đó hiển thị B bên trái A, tại vị trí 5(cách 4). Chúng ta có thể chọn 1 trong 4 cách hiển thị trên thông qua lệnh Entry mode set. Đây là lệnh ghi Instruction nên RS=0, 5 bit cao D7:3=00000, bit D2=1, hai bit còn lại D1:0 chứa mã lệnh để lựa chọn 1 trong 4 cách hiển thị. Xem lại bảng 2, bit D1 chứa giá trị I/D và D0 chứa S. Trong đó I/D nghĩa là tăng hoặc giảm (Increment or Decrement). I/D= 1 là hiển thị tăng tức ký tự sau sẽ hiển thị bên phải ký tựtrước, nếu I/D = 0 thì hiển thị giảm, tức ký tự sau hiển thị bên trái ký tự trước. S là giá trị Shift, nếu S = 1 thì các ký tự trước đó sẽ được “đẩy” đi, ký tự sau chiếm chỗ ký tự trước, ngược lại nếu S=0 thì vị trí hiển thị của các ký tựtrước đó không thay đổi. Có thể tóm tắt 4 mode hiển thị ứng với 4 mã lệnh như sau:
+ D7:0 = 0x04 (00000100) : hiển thị giảm và không shift. + D7:0 = 0x05 (00000101) : hiển thị giảm và shift.
63
+ D7:0 = 0x06 (00000110) : hiển thịtăng và không shift. + D7:0 = 0x07 (00000111) : hiển thịtăng và shift.
- Display control: xác lập cách hiển thị cho LCD: lệnh này bao gồm các thông số cho phép LCD hiển thị, cho phép hiển thị cursor và mở/tắt blinking. Đây cũng là một lệnh ghi Instrcution nên RS phải bằng 0. Mã lệnh cho lệnh này có dạng 00001DCB trong đó D (Display) cho phép hiển thị LCD nếu mang giá trị 1, C (Cursor) bằng 1 thì cursor sẽđược hiển thị và B là blinking cho cursor tại vị trí hiển thị (blinking là dạng 1 ô đen nhấp nháy tại vị trí ký tựđang hiển thị). Mã lệnh được dùng phổ biến cho lệnh này là 0x0E (00001110 - hiển thị cursor nhưng không hiển thị blinking).
- Function set: xác lập chức năng cho LCD: đây là lệnh thiết lập phương thức giao tiếp với LCD, kích thước font chữ và số lượng line của LCD. RS cũng phải bằng 0 khi sử dụng lệnh này. Mã lệnh function set có dạng 001(DL)x(RE)xx. Trong đó nếu DL=1 (DL: Data Length) thì mode giao tiếp 8 bit sẽ được dùng, lúc này tất cả các chân từD0 đến D7 phải được kết nối với bộđiều khiển ngoài. Nếu DL=0 thì mode 4 bit được dùng, trong trường hợp này chỉ có 4 chân D4:7 được dùng để truyền nhận dữ liệu và kết nối với bộ điều khiển ngoài, các chân D0:3 được để trống. RE quy định nhóm lệnh muốn sử dụng, ởđây ta đang sử dụng nhóm lệnh cơ sở RE=0 dùng cho text, nhóm lệnh mở rộng dùng cho graphic RE=1 không được xét đến.
- Set DDRAM address: định vị trí con trỏ cho DDRAM: di chuyển con trỏ đến một vị trí tùy ý trong DDRAM và vì thế có thể được dùng để chọn vị trí cần hiển thị trên LCD. Để thực hiện lệnh này cần reset RS=0. Bit MSB của mã lệnh (D7) phải bằng 1, 7 bit còn lại của mã lệnh chính là địa chỉ DDRAM muốn di chuyển đến. Ví dụ chúng ta muốn di chuyển con trỏđến vị trí thứ 3 trên dòng 2 của LCD (địa chỉ 42) chúng ta cần ghi mã lệnh 0xAA vì 0xAA=10101010 (binary) trong đó bit MSB bằng 1, bảy bit còn lại là 0101010=42, địa chỉ của ô nhớ muốn đến.
64
- Write RAM: ghi dữ liệu vào RAM: vì đây không phải là lệnh ghi instruction mà là 1 lệnh ghi dữ liệu nên chân RS cần được set lên 1 trước khi ghi lệnh vào LCD. Lệnh này cho phép ghi mã ASCII của một ký tự cần hiển thị vào thanh ghi DDRAM.
* Giao tiếp nối tiếp:
- Như đã trình bày ở trên, chíp GLCD QC12864B có thể hoạt động ở hai chế độ giao tiếp: giao tiếp nối tiếp và giao tiếp song (8 bit hoặc 4 bit), mặc định GLCD được thiết kết giao tiếp nối tiếp, cũng là giao tiếp được sử dụng trong mạch đo bụi.
- Các chân liên quan đến giao tiếp nối tiếp gồm có: chân CS(RS) để chọn chip tích cực cao, SID(RW) để ghi dữ liệu vào chíp và SCLK(E) tạo xung clock.
- Để sử dụng giao tiếp nối tiếp, ta nối đất chân PSB của chip.
- Giao tiếp nối tiếp hoạt động như sau: khi chip select (CS) ở mức thấp, SCLK và SID ở trạng thái reset. Muốn giao tiếp ta kéo chân CS lên mức cao, bắt đầu truyền, 1 byte start được yêu cầu gồm 5 bit ‘1’ liên tiếp sau đó là 1 bit 0(write bit) và register/data selected RS bit này bằng 1 khi truyền dữ liệu và bằng 0 khi truyền lệnh. Bit cuối cùng là bit ‘0’. Sau khi truyền xong byte start, các byte sau(byte lệnh hoặc byte dữ liệu) sẽ được truyền vào theo 2 byte một, byte đầu tiên gồm 4 bit cao của byte (lệnh hoặc dữ liệu) ta muốn truyền và 4 bit ‘0’ phía sau, byte thứ 2 gồm 4 bit thấp của byte (lệnh hoặc dữ liệu) theo sau bởi 4 bit ‘0’.
65
Ví dụ: ta muốn truyền một byte dữ liệu ‘abcdefgh’ vào chip thì thì thủ tục truyền như sau:
Truyền byte start ‘11111010’, tiếp theo là 2 byte ‘abcd0000’ và ‘efgh0000’, Nếu byte cần truyền là lệnh thì ta thay byte start ban đầu thành 11111000.
5. Thiết lập cho GLCD
GLCD_TM.h #define OUT 0 #define IN 1
#define CS(k) GPIO_WriteBit(GPIOD, GPIO_Pin_14, (BitAction)k) #define SID(k) GPIO_WriteBit(GPIOD, GPIO_Pin_13, (BitAction)k) #define SCLK(k) GPIO_WriteBit(GPIOD, GPIO_Pin_12, (BitAction)k) void GLCD_Delay(float k) // tạo thời gian delay
{
k=k*20; while(k--); }
void GLCD_Send_Bit(char k) // gửi một bit tới GLCD { SID((k & 0x01)); SCLK(1); GLCD_Delay(1); SCLK(0); GLCD_Delay(1);