실시간 산불 감시 시스템 - SMS 알림 기능 포함
부품 및 소모품
Itead Gboard Pro 800 SIM800 GSM/GPRS 모듈 (3.3V ATmega2560 메인보드)
×
1
아두이노 UNO
×
1
DHT11 온습도 센서 (3핀)
×
2
점퍼 와이어 (범용)
×
1
앱 및 온라인 서비스
프로젝트 소개
산불 감지 프로세스는 숲속 나무에 심어진 노드 중 어디서든 시작됩니다. 숲에는 적절한 간격으로 노드 네트워크가 구축되어 있으며, 노드들은 (본 프로젝트에서는 RF 모듈로) 통신하고 아두이노를 사용합니다. 어떤 노드(소스 노드) 근처에서 대기 파라미터(온도 상승, 연기 등 오염)가 임계값 이상으로 변하면, 정보는 가장 가까운 중간 노드로 전달되고, 최종적으로 메인/헤드 터미널까지 릴레이됩니다. 메인 터미널은 GSM 모뎀을 통해 휴대폰(산불 감시 센터)으로 정보를 전송합니다.
물리 모델의 송신부
산불 감지 모듈은 세 단계로 작동합니다.
1단계: 온도, 연기 등 외부 환경 파라미터 읽기. 센서로 아날로그 데이터를 디지털로 변환. 온도, 습도, 공기 질을 읽고 다음 노드로 전송.
2단계: 정보가 최종 노드 또는 메인 터미널에 도달할 때까지 노드 간 릴레이 반복.
3단계: 메인 터미널에서 GSM 모뎀으로 산불 감시 부서에 정보 전송.
각 노드에는 온습도 센서, 연기 센서, 마이크로컨트롤러 유닛이 있습니다. 아두이노를 마이크로컨트롤러로 사용합니다. 센서가 아두이노와 상호작용하며 정보를 저장해 비교합니다. 각 파라미터마다 사전 정의된 임계값이 있고, 마이크로프로세서는 정기적으로 센서 값을 임계값과 비교합니다. 센서 값이 임계값을 초과하면 노드는 인근 노드로 정보를 전송하고, 이는 연쇄적으로 다음 노드로 전달됩니다. 이렇게 메시지 흐름이 조절됩니다.
장치의 물리 모델
물리 모델의 송신부 (상세)
시리얼 모니터 읽기값
GSM 모듈 수신 메시지
코드
수신부 및 송신부 아두이노 모듈 코드 Python
이 코드는 온습도 모니터링용 수신부 아두이노 모듈을 구성합니다. 값이 임계값을 초과하면 베이스 스테이션에 SMS 알림을 보냅니다. 송신부 노드에서 값 상승이 감지되면 송신부 아두이노 우노의 RF 송신 모듈을 통해 수신부 아두이노 우노의 RF 수신 모듈로 전달됩니다. 아래 코드는 "수신부 아두이노"용과 "송신부 아두이노"용 두 부분으로 구성됩니다.
########( PART-1 )###### 수신부 아두이노 코드 ##########################
// RadioHead ASK 라이브러리 포함
#include <SoftwareSerial.h>
#include <RH_ASK.h>
// 의존 SPI 라이브러리 포함
#include <SPI.h>
#include <DHT.h>
SoftwareSerial mySerial(4, 3); // GSM용 소프트웨어 시리얼
// 상수
#define DHTPIN 2
#define DHTTYPE DHT11
int smokeA0 = A5;
int sensorThres = 400;
// 변수
DHT dht(DHTPIN, DHTTYPE);
float hum;
float temp;
String str_humid;
String str_temp;
String str_smk;
String str_out;
RH_ASK rf_driver;
void setup() {
pinMode(smokeA0, INPUT);
dht.begin();
rf_driver.init();
Serial.begin(9600);
mySerial.begin(115200);
}
void loop() {
delay(2000);
hum = dht.readHumidity();
temp = dht.readTemperature();
Serial.print("Reciever Humidity = ");
Serial.print(hum);
Serial.print('\n');
Serial.print("Reciever Temperature = ");
Serial.println(temp);
int analogSensor = analogRead(smokeA0);
String smk;
if (analogSensor > sensorThres) {
Serial.print("Smoke at Reciever");
Serial.print('\n');
smk = "Smoke";
} else {
Serial.print("Clean at Reciever");
Serial.print('\n');
smk = "Clean";
}
uint8_t buf[20];
uint8_t buflen = sizeof(buf);
if (rf_driver.recv(buf, &buflen)) {
str_out = String((char*)buf);
for (int i = 0; i < str_out.length(); i++) {
if (str_out.substring(i, i+1) == ",") {
str_humid = str_out.substring(0, i);
str_temp = str_out.substring(i+1, i+6);
str_smk = str_out.substring(i+7, i+12);
break;
}
}
}
Serial.print("Humidity: ");
Serial.print(str_humid);
Serial.print(" - Temperature: ");
Serial.println(str_temp);
Serial.print(" - Air Quality: ");
Serial.println(str_smk);
// 수신부에서 화재 감지
if (hum >= 60 && temp >= 25) {
Serial.print("Fire Detected at Reciever ");
mySerial.println("AT+CMGF=1");
delay(1000);
mySerial.println("AT+CMGS=\"+918744984131\"\r"); // 휴대폰 번호로 변경
delay(1000);
mySerial.println(" FIRE ALERT !! ");
Serial.println('\n');
mySerial.println("Fire at Reciever Node ");
Serial.println('\n');
mySerial.println("Temperature : " + String(temp));
Serial.print('\n');
mySerial.println("Humidity : " + String(hum));
Serial.print('\n');
mySerial.println("Air Quality : " + smk);
delay(100);
mySerial.println((char)26); // CTRL+Z
delay(1000);
}
// 송신부에서 화재 감지
if (str_humid.toInt() >= 60 && str_temp.toInt() >= 25) {
Serial.print("Fire Detected at Transmitter ");
mySerial.println("AT+CMGF=1");
delay(1000);
mySerial.println("AT+CMGS=\"+918744984131\"\r");
delay(1000);
mySerial.println(" FIRE ALERT !! ");
Serial.println('\n');
mySerial.println("Fire at Transmitter Node ");
Serial.println('\n');
mySerial.println("Temperature : " + str_temp);
Serial.print('\n');
mySerial.println("Humidity : " + str_humid);
Serial.print('\n');
mySerial.println("Air Quality : " + String(str_smk));
delay(100);
mySerial.println((char)26);
delay(1000);
}
}
#######( PART-2 )############ 송신부 아두이노 코드 ############
############################################################################
#include <RH_ASK.h>
#include <SPI.h>
#include <DHT.h>
#define DHTPIN 2
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);
int smokeA0 = A5;
int sensorThres = 400;
float hum;
float temp;
float smk;
String str_humid;
String str_temp;
String str_smk;
String str_out;
RH_ASK rf_driver;
void setup() {
dht.begin();
pinMode(smokeA0, INPUT);
rf_driver.init();
}
void loop() {
delay(2000);
hum = dht.readHumidity();
temp = dht.readTemperature();
str_humid = String(hum);
Serial.print(hum);
str_temp = String(temp);
Serial.print(temp);
int analogSensor = analogRead(smokeA0);
if (analogSensor > sensorThres) {
str_smk = "1";
} else {
str_smk = "0";
}
if (str_smk == "1") {
str_out = str_humid + "," + str_temp + "," + "Smoke";
}
if (str_smk == "0") {
str_out = str_humid + "," + str_temp + "," + "Clean";
}
const char *msg = str_out.c_str();
rf_driver.send((uint8_t *)msg, strlen(msg));
rf_driver.waitPacketSent();
}
회로도