Cảm biến bụi (Dust Sensor) là thiết bị giúp chúng ta đo đạc, tính toán ra lượng bụi trong không khí để biết chất lượng không khí trong khu vực đo đang như thế nào. Tuy nhiên kết quả Output của cảm biến này lại là Analog nên Raspberry Pi sẽ không ghi nhận được dữ liệu này.
Vì vậy, chúng ta sẽ cần thêm bo mạch Adapter ARPI600 – một adapter board dùng cho Raspberry Pi và Arduino để giúp chúng ta đọc các dữ liệu Analog. ARPI600 còn có rất nhiều tính năng hữu hiệu khác như Real-time, Xbee, …
Chuẩn bị phần cứng để đọc dữ liệu cảm biến bụi trên Raspberry Pi
Chúng ta sẽ cần
Sơ đồ kết nối để đọc dữ liệu cảm biến bụi trên Raspberry Pi
Module cảm biến bụi | ARPI600 đã kết nối RPi | |
VCC | → | 3.3V |
GND | → | GND |
AOUT | → | T_A6 |
iLED | → | P1 |
Hình ảnh kết nối
Kịch bản đo và báo cáo kết quả nồng độ bụi trong không khí với Raspberry Pi
- Kích hoạt các diot hồng ngoại bằng cách thiết lập các pin LED ở mức HIGH.
- Chờ 0.28ms, sau đó bắt đầu để lấy mẫu điện áp từ pin Aout của module. Ghi chú rằng tín hiệu đầu ra sẽ mất 0.28ms để đạt trạng thái ổn định sau khi diot hồng ngoại được kích hoạt
- Chu kì lấy mẫu là 0.004ms . Khi hoàn tất, thiết lập các pin LED LOW để vô hiệu hóa các diot hồng ngoại.
- Tính nồng độ bụi theo mối quan hệ giữa điện áp đầu ra và nồng độ bụi.
Bảng quan hệ giữa giá trị điện áp ra và nồng độ bụi
Và giờ thì chúng ta bắt tay vào đo thôi.
Ứng dụng mẫu đo và cảnh báo mức độ ô nhiễm trong văn phòng qua cảm biến bụi
Trước hết, chúng ta cần thực hiện cài thư viện wiringPi
cd /tmp wget https://project-downloads.drogon.net/wiringpi-latest.deb sudo dpkg -i wiringpi-latest.deb
Sau khi cài đặt, chúng ta sẽ chạy lệnh dưới đây để kiểm tra xem wiringPi đã cài chưa
gpio -v
Kết quả sẽ hiển thị như thế này
Chúng ta sẽ tạo 1 file tên là General_Sensor.c thông qua lệnh
sudo nano General_Sensor.c
Và chúng ta copy đoạn code dưới đây vào
#include <stdio.h> #include <wiringPi.h> #define Clock 27 #define Address 28 #define DataOut 29 #define COV_RATIO 0.2 //ug/mmm / mv #define NO_DUST_VOLTAGE 400 //mv #define SYS_VOLTAGE 3300 #define D0 0 #define S0 1 //iLed int adcvalue = 0; float voltage = 0; int Filter(int m) { static int flag_first = 0, _buff[10], sum; const int _buff_max = 10; int i; if(flag_first == 0) { flag_first = 1; for(i = 0, sum = 0; i < _buff_max; i++) { _buff[i] = m; sum += _buff[i]; } return m; } else { sum -= _buff[0]; for(i = 0; i < (_buff_max - 1); i++) { _buff[i] = _buff[i + 1]; } _buff[9] = m; sum += _buff[9]; i = sum / 10.0; return i; } } unsigned int ADC_Read(unsigned char channel) { unsigned int value; unsigned char i; unsigned char LSB = 0, MSB = 0; channel = channel << 4; for (i = 0; i < 4; i ++) { if(channel & 0x80) digitalWrite(Address,1); else digitalWrite(Address,0); digitalWrite(Clock ,1); digitalWrite(Clock ,0); channel = channel << 1; } for (i = 0; i < 6;i ++) { digitalWrite(Clock ,1); digitalWrite(Clock ,0); } delayMicroseconds(15); for (i = 0; i < 2; i ++) { digitalWrite(Clock ,1); MSB <<= 1; if (digitalRead(DataOut)) MSB |= 0x1; digitalWrite(Clock ,0); } for (i = 0; i < 8; i ++) { digitalWrite(Clock ,1); LSB <<= 1; if (digitalRead(DataOut)) LSB |= 0x1; digitalWrite(Clock ,0); } value = MSB; value <<= 8; value |= LSB; return value; } void Level_Polution( float den){ if(den <= 35) { printf(" Moi Truong sach!\n"); } else if(den <= 75) { printf(" Moi Truong o muc trung binh!\n"); } else if(den <= 115) { printf(" Moi Truong o muc o nhiem nhe!\n"); } else if(den <= 150) { printf(" Moi Truong o muc o nhiem vua!\n"); } else if(den <= 250) { printf(" Moi Truong o muc o nhiem nang!\n"); } else { printf(" Moi Truong o nhiem nghiem trong!\n"); } } int main() { if (wiringPiSetup() < 0)return 1 ; pinMode (DataOut,INPUT); pullUpDnControl(DataOut, PUD_UP); pinMode(Clock,OUTPUT); pinMode(Address,OUTPUT); pinMode(D0,INPUT); digitalWrite(D0,0); float density = 0; pinMode(S0, OUTPUT); while(1) { //lay tin hieu dien ap digitalWrite(S0, HIGH); // bat dau lay tin hieu analog delayMicroseconds(280); // chờ 280us adcvalue = ADC_Read(6); digitalWrite(S0, LOW); // ket thuc lay tin hieu //loc tin hieu adcvalue = Filter(adcvalue); // tinh toan voltage =( SYS_VOLTAGE/1024.0)*adcvalue*11; if(voltage >= NO_DUST_VOLTAGE ) { voltage -= NO_DUST_VOLTAGE; density = voltage * COV_RATIO; } else density = 0; printf(" Do bui: %f ug/m3\n", density); Level_Polution(density); delay(1000); } }
Chúng ta bấm Ctrl + X để thoát trình soạn thảo nano, sau đó bấm Y và Enter để lưu lại file
Tiếp theo, chúng ta sẽ biên dịch file này thông qua lệnh
gcc -Wall -o General_Sensor General_Sensor.c -lwiringPi
Cuối cùng, chúng ta sẽ thử xem kết quả hiển thị thế nào thông qua lệnh
sudo ./General_Sensor
Và tèn ten, nếu chúng ta làm đúng, kết quả sẽ như thế này