공부/기초설계

온습도 + 미세먼지 (3)

오비루 2021. 11. 18. 12:58
728x90
728x90

목표로 하고자 하는 5가지의 과정을 모두 수행해 놓았다.

이제 금요일에 조원과 만나 미세먼지 센서를 기존 코드에 넣어주면 코드 작성은 완성하게 된다!

 

미세먼지 센서의 동작 방식을 설명하자면 총 3가지의 led 출력으로 표현할 예정이다.

쾌적(초록) - 중간(노랑) - 나쁨(빨강)

자세한 수치는 최종적으로 프로젝트를 완성하게되면 함께 올리겠다.

 

밑에 적힌 수행목록은 현재 집에서 할 수 있는 최대한의 과제들이다.

(괄호는 해당 수행을 통해 얻고자 하는 데이터)

1. 블루투스간에 송수신 가능한것 확인.

2. 마스터 부분의 버튼눌러서 led켜기
(버튼 눌렀을때 센서값 받아들이기로 사용)

3. 온도센서의 값을 송신
(온도센서 값이 송신 되는가 확인용)

4. 버튼 눌렀을때만 온도센서 값을 받아들이기
(주제와 목표 동일)

5. 온도센서 값을 받았을때 모터가 작동하는가
(최종 목표)

 

어제를 기점으로 4번과 5번까지 달성하며 마지막 과제까지 끝을내었다.

코드에 재능이 있지는 않지만 한꺼번에 최종 목표를 수행하려는 것 보다 차근차근 작은 목표부터 수행하며 진행을 하니 어느새 최종 목표까지 도달하였다는것에 신기하고 어떤 일에도 순서대로 천천히만 한다면 못할것도 없지 않을까 생각이 들었다.

 

다시 본론으로 넘어와서 이전 글에 적혀있던 6번의 경우 머릿속으로는 구상이 이루어 진듯하나 해당 부분을 코드로서 풀어내기에 실력이 부족하여 현재로서 최선인 '버튼을 누른 상태에서만' 동작이 가능하게 설계하였다.

4번 코드는 5번 코드의 일부이기에 5번에 대한 코드만 올리겠다.

 

 

//마스터(수신부) 버튼누르고 온도값을 lcd에 출력하고 값에 따라 스텝모터 동작하는곳.

#include <Wire.h>
#include <hd44780.h>
#include <HD44780ioClass/hd44780_I2Cexp.h>//lcd 함수
#include <SoftwareSerial.h>
#include <Stepper.h> //스텝모터 라이브러리 불러옴
#define SW 7 //스위치 핀
#define LED 6

hd44780_I2Cexp lcd; //LCD 객체
SoftwareSerial BTSerial(2,3); //블루투스의 Tx, Rx핀을 2번 3번핀으로 설정

int steps = 2048; // 한바퀴에 해당하는 값 선언
Stepper stepper(steps, 12, 10, 11, 9);//IN4,IN2,IN3,IN1
int step_count = 0; //스텝모터 동작 여부 판단을 위한 카운트

//문자열 받아들이는 변수
String sData = "";
String sTemp = "";
String sHumi = "";
String sCopy = "";
char cData, cTemp, cHumi; //데이터 저장변수, 온도 저장변수, 습도 저장변수
int index_h = 0, index_t = 0, sCount = 0;

float humi,temp;

void setup() {
  Serial.begin(9600);
  Serial.println("Received OK!");
  BTSerial.begin(9600);  
  pinMode(SW, INPUT);
  pinMode(LED, OUTPUT);
  lcd.begin(16,2);
  stepper.setSpeed(10);
  // rpm : 1분당 도는 횟수, 너무 큰값을 하면 안돌아감. -높을수록 빨라짐-
}

void loop() {
      if(BTSerial.available()){//블루투스에서 넘어온 데이터가 있다면
    
    //온습도 값 받아들여서 시리얼 모니터에 출력하는 함수들
      sData = BTSerial.readString();
      //Serial.println("sData = "+String(sData)); //문자열을 읽어들여 데이터 값에 저장후 문자열로 출력
      sCopy = sData;//데이터 값을 copy변수로 저장
      
      index_h = sCopy.indexOf('h');//h문자를 찾아내기
      //Serial.println("index_h = "+(String)index_h); //몇번째에 위치한지 찾아내기

      if(index_h != -1){//습도주소에 오류가 없다면
        sHumi = sCopy.substring(0, index_h);//substring(from,to) 0~문자가 있는 부분까지 sHumi 변수에 저장
        //Serial.println(sHumi);
        sCopy = sCopy.substring(index_h + 1);//sCopy에 h주소값에 1을 더해주어 다음 주소값이 나오도록 변수저장(shift)
      }
      
      index_t = sCopy.indexOf('t');//t문자 찾아내기
      //Serial.println("index_t= "+(String)index_t);//위치 출력
      
      if(index_t != -1){//t주소에 오류 없다면
        sTemp = sCopy.substring(0, index_t);
        //Serial.println(sTemp);
        sCopy = sCopy.substring(index_t + 1);//sCopy에 t주소값에 1을 더해 새로이 주소저장(shift)
      }

      if((index_h == -1) && (index_t == -1)){//오류가 있다면 finished출력
      Serial.println("sCopy = "+(String)sCopy);
      Serial.println("Finished..");
      }        
  }
  
  u8 key = digitalRead(SW); //버튼 값 읽어 key 변수에 저장
    
  if(key == HIGH){//스위치가 눌렸을때
    
      BTSerial.write('1');//버튼을 누르면 블루투스를 통해 1 이라는 데이터값을 전송
      digitalWrite(LED, HIGH);

      //습도와 온도 문자열을 실수값으로 변환
      humi = sHumi.toFloat();
      temp = sTemp.toFloat();  
    

      lcd.backlight(); //LCD 백라이트 켜짐
      lcd.clear(); //LCD 출력내용 지우기
      lcd.setCursor(0,0);
      lcd.print("TEM: ");
      lcd.print(temp);
      lcd.print("'C");
      lcd.setCursor(0,1);
      lcd.print("HUM: ");
      lcd.print(humi);
      lcd.print("%");     
      

        
      Serial.println("현재 습도와 온도는");

      Serial.println("Huminity = "+(String)sHumi+"%");
      Serial.println("Temperature = "+(String)sTemp+"'C");//온도와 습도 출력

      if(26<= temp && temp <= 27 && step_count == 0){ // 26~27 도 + 스텝 카운트가 0 일때에는 1번 구역
        stepper.step(steps/360 * 90); //1번구역
        step_count = 1;//스텝 카운트 1번으로 구역화 만들어둠
        Serial.println("1번구역");
      }
      else if(temp <= 25 && step_count == 0){ // 25도 이하 + 스텝 카운트 0 일때 2번 구역
        stepper.step(steps/360 * 180);//2번 구역
        step_count = 2;//이하 동문
        Serial.println("2번구역");
      }
      else if(27 < temp && temp <= 30 && step_count == 0){ // 27~30 + 스텝 카운트 0일때 3번 구역
        stepper.step(steps/360 * 270);//3번 구역
        step_count = 3;
        Serial.println("3번구역");
      }
      else if(temp > 30 && step_count == 0){ // 30도 초과 + 스텝 카운트 0일때 4번 구역
        stepper.step(steps);
        step_count = 4;
        Serial.println("4번구역");
      }

      else{
        stepper.step(0);// 이외의 경우 스텝 모터는 구동하지 않는다.
        Serial.println("동작 안함 high");        
      }

      
      //센서가 측정하지 못할 경우 측정 종료
      if(isnan(humi)||isnan(temp)){
        Serial.print("Failed to read from DHT sensor!");
        return;
      }
    
      delay(300); 
      }

  else{//스위치가 low 일때
    
     Serial.println("none signal");
     BTSerial.write('0');//0이란 데이터를 전송하여 측정을 멈추기    
     lcd.noBacklight();//LCD 백라이트 꺼짐
     
     
     if(step_count == 1){
      stepper.step(-steps/360 * 90); //1번구역 + 이동한 만큼 역회전 , 이하동문
      step_count = 0;//스텝 카운트 변수를 버튼을 뗀 상태일때 초기화 해준다. 이하 동문
      Serial.println("스텝모터 초기화");
      }
      
     else if(step_count == 2){
      stepper.step(-steps/360 * 180); //2번구역
      step_count = 0;
      Serial.println("스텝모터 초기화");
      }
      
     else if(step_count == 3){
      stepper.step(-steps/360 * 270); //3번구역
      step_count = 0;
      Serial.println("스텝모터 초기화");
      }
      
     else if(step_count == 4){ //4번 구역
        stepper.step(-steps);
        step_count = 0;
        Serial.println("스텝모터 초기화");
      }
      
     else {
      stepper.step(0);//이외의 경우는 스텝모터 작동하지 않는다.
      Serial.println("동작 안함 low");
     }
      
     digitalWrite(LED, LOW);//불끄기
     delay(300);
  }
}

 

간단히 설명하자면, 이곳은 마스터 즉 온습도 값을 받아내어 lcd, 스텝모터를 이용하여 출력하는 곳이다.

버튼을 눌렀을때 블루투스로 '1'이라는 데이터 값을 송신하고, led가 켜지면서 lcd, 스텝모터가 동작한다. 여기서 출력을 위해서는 기존 문자열로 받아낸 통신을 실수로 바꾸어야 비교문 사용이 가능하기에 toFloat() 함수를 사용하여 문자열을 실수화 하였다. 

실수로 받아낸 온도 값을 비교문을 통해 스텝모터의 동작 범위를 다르게 설정하였고, 버튼을 떼어내면 스텝모터의 리셋. lcd의 화면 꺼짐과 동시에 led또한 꺼진다. 이를 통해 동작이 멈추었음을 표현하였다.

 

//슬레이브(송신부) 온습도값 측정하는 곳

#include <SoftwareSerial.h>
#include <DHT.h>
#include <DHT_U.h>
#define DHTPIN 4
#define DHTTYPE DHT11
#define LED 11

DHT dht(DHTPIN, DHTTYPE);

SoftwareSerial BTSerial(2,3); // RX, TX

int BTstates=0; //블루투스 신호 상태 저장용 변수

void setup() {
  Serial.begin(9600);
  BTSerial.begin(9600);
  Serial.println("Read sensor");
  Serial.println("Transmit OK!");
  dht.begin();//온습도 센서 작동
}

void loop() {

  if(BTSerial.available()){//블루투스에서 넘어온 데이터가 있다면
    char str = BTSerial.read();
    if(str == '1'){//1 이라는 데이터 값이 들어오면
      
    float humi = dht.readHumidity(); //습도 측정
  
      Serial.print(humi);
      Serial.print("h");
      BTSerial.print(humi);
      BTSerial.print("h");
      
   float temp = dht.readTemperature(); //온도 측정  
     
      Serial.print(temp);
      Serial.println("t");
      BTSerial.print(temp);
      BTSerial.println("t");
      delay(300);
      
    }
  }
}

 

다음은 슬레이브측 온습도 측정하는 코드이다.

앞전에 마스터를 통해 버튼을 눌렀을때 발생하는 '1' 값을 받아내면 온습도 값을 측정하기 시작한다.

측정된 값은 블루투스 시리얼을 통해 t와 h신호를 붙여 마스터로 전송을 하고 마스터 측에서 해당 값을 온도와 습도값으로 다시 저장해준다. 그러기 위해 마스터 측은 문자열 String 을 사용하였다.

 

자세한 동작 영상은 차후에 미세먼지와 함께 올리겠다.

728x90
반응형

'공부 > 기초설계' 카테고리의 다른 글

온습도 + 미세먼지 (최종)  (0) 2021.12.22
온습도 + 미세먼지 (4)  (0) 2021.11.20
온습도+미세먼지 (2)  (0) 2021.11.16
온습도 + 미세먼지 측정을 캐릭터 표현(1)  (0) 2021.11.09