dht.ino 6.48 KB
#include <Adafruit_Sensor.h>
#include <DHT.h>
#include <DHT_U.h>

#define DHTPIN 2   
#define DHTTYPE    DHT22 
DHT_Unified dht(DHTPIN, DHTTYPE);

uint32_t delayMS;

// 미세먼지 센서
int dust_sensor = A0;   // 미세먼지 핀 번호
float dust_value = 0;  // 센서에서 입력 받은 미세먼지 값
float dustDensityug=0;  // ug/m^3 값을 계산
int sensor_led = 12;      // 미세먼지 센서 안에 있는 적외선 led 핀 번호
int sampling = 280;    // 적외선 led를 키고, 센서 값을 읽어 들여 미세먼지를 측정하는 샘플링 시간
int waiting = 40;    
float stop_time = 9680;   // 센서를 구동하지 않는 시간

// 블루투스 모듈
#include <SoftwareSerial.h>
#define BT_RX 7
#define BT_TX 8

SoftwareSerial HM10(BT_RX,BT_TX);  // RX핀(7번)은 HM10의 TX에 연결 
                                   // TX핀(8번)은 HM10의 RX에 연결  
// at 설정
char recv_str[100];

// 변화 유무
bool tempBool;
bool humidBool;
bool dustBool;


void setup(){ 
    Serial.begin(9600);

    // 온습도 센서
    dht.begin();
    sensor_t sensor;
    dht.temperature().getSensor(&sensor);
    dht.humidity().getSensor(&sensor);
    delayMS = sensor.min_delay / 1000;

    // 미세먼지 센서
    pinMode(sensor_led,OUTPUT); // 미세먼지 적외선 led를 출력으로 설정
    pinMode(4, OUTPUT);

    // 블루투스 모듈
    HM10.begin(9600);

    // 블루투스 작동확인
    while(1)
    {
        if(sendBlueToothCommand("AT") == 0)
        {
            if(strcmp((char *)recv_str, (char *)"OK") == 0)
            {
                Serial.println("Bluetooth exists\r\n");
                break;
            }
        }
        delay(500);

    }
    sendBlueToothCommand("AT+NAMEDUSTSENSOR"); // 블루투스 장치 이름설정
    sendBlueToothCommand("AT+MODE3"); // 블루투스 모드 설정
    sendBlueToothCommand("AT+TYPE3");

    tempBool = true;
    humidBool = true;
    dustBool = true;

}


void loop(){
    delay(delayMS);
    sensors_event_t event;
    
    if(tempBool)
    {
        dht.temperature().getEvent(&event);
        double temp_val = (double)event.temperature;
        if (isnan(temp_val)) {
            HM10.println(F("Error reading temperature!"));
        }
        else {
            HM10.write(F("temp "));
            HM10.println(temp_val);
            delay(2000);
        }
    }

    if(humidBool)
    {
        dht.humidity().getEvent(&event);
        double humid_val = (double)event.relative_humidity;
        if (isnan(humid_val)) {
            HM10.println(F("Error reading humidity!"));
        }
        else {
            HM10.write(F("humd "));
            HM10.println(humid_val);
            delay(2000);
        }
    }

    if(dustBool)
    {
        // 미세먼지 센서
        digitalWrite(sensor_led, LOW);    // LED 켜기
        delayMicroseconds(sampling);   // 샘플링해주는 시간. 

        dust_value = analogRead(dust_sensor); // 센서 값 읽어오기
  
        delayMicroseconds(waiting);  // 너무 많은 데이터 입력을 피해주기 위해 잠시 멈춰주는 시간. 

        digitalWrite(sensor_led, HIGH); // LED 끄기
        delayMicroseconds(stop_time);   // LED 끄고 대기  

        // 미세먼지 농도 값
        dustDensityug = (0.17 * (dust_value * (5.0 / 1024.0)) - 0.1) * 1000;    // 미세먼지 값 계산
        double dust_val = dustDensityug;
        // 센서 값 전송
        HM10.write("dust ");
        HM10.println(dustDensityug);
        delay(2000);
    }


    while(1)
    {
        delay(1000);

        digitalWrite(sensor_led, LOW);    // LED 켜기
        delayMicroseconds(sampling);   // 샘플링해주는 시간. 
        dust_value = analogRead(dust_sensor); // 센서 값 읽어오기
        delayMicroseconds(waiting);  // 너무 많은 데이터 입력을 피해주기 위해 잠시 멈춰주는 시간. 
        digitalWrite(sensor_led, HIGH); // LED 끄기
        delayMicroseconds(stop_time);   // LED 끄고 대기  
        is_dust_different(dustDensityug, dust_val, dustBool);

        dht.temperature().getEvent(&event);
        is_temp_different((double)event.temperature, temp_val, tempBool);
        
        dht.humidity().getEvent(&event);
        is_humid_different((double)event.relative_humidity, humid_val, humidBool);

        if(dustBool || tempBool || humidBool){
            break;
        }
    }
}

// 10의 자리수에 변화가 발생시 값 전송 함수
bool is_dust_different(double now_dustVal, double& past_dustV bool& dustBool){
    if((now_dustVal/10)!=(past_dustV/10)){
        return true;
    }
    else{
        return false;
    }
}

// 이전 값과 4 초과의 차이가 발생시 값 전송 함수
bool is_humid_different(double now_humidVal, double& past_humidV bool& humidBool){
    if((now_humidVal>past_humidV+2) || (now_humidVal<past_humidV-2)){
        return true;
    }
    else{
        return false;
    }
}

// 이전 값과 1.5 초과의 차이가 발생시 값 전송 함수
bool is_temp_different(double now_tempVal, double& past_tempV bool& tempBool){
    if((now_tempVal>past_tempV+0.75) || (now_tempVal<past_tempV-0.75)){
        return true;
    }
    else{
        return false;
    }
}

// at 설정용 함수
int sendBlueToothCommand(char command[])
{
    Serial.print("send: ");
    Serial.print(command);
    Serial.println("");
#if NLCR
    HM10.println(command);
#else
    HM10.print(command);
#endif    
    delay(300);

    if(recvMsg(200) != 0) return -1;

    Serial.print("recv: ");
    Serial.print(recv_str);
    Serial.println("");
    return 0;
}

int recvMsg(unsigned int timeout)
{
    //wait for feedback
    unsigned int time = 0;
    unsigned char num;
    unsigned char i;

    //waiting for the first character with time out
    i = 0;
    while(1)
    {
        delay(50);
        if(HM10.available())
        {
            recv_str[i] = char(HM10.read());
            i++;
            break;
        }
        time++;
        if(time > (timeout / 50)) return -1;
    }

    //read other characters from uart buffer to string
    while(HM10.available() && (i < 100))
    {                                              
        recv_str[i] = char(HM10.read());
        i++;
    }
#if NLCR    
    recv_str[i-2] = '\0';       //discard two character \n\r
#else
    recv_str[i] = '\0';
#endif
    return 0;
}