논블로킹,블로킹 프로그램

문주은·2020년 12월 30일
1

메디컬IOT

목록 보기
5/13

1. 주기적으로 if블록 실행하기

👉일정한 간격(1초, 2초...)으로 값을 받아오는 것

블록을 주기적으로 실행하는 코드로 계속적으로 값을 받아온다. 자주 사용

static unsigned long nextMil = millis() + 실행 간격;
if(millis() > nextMil){
	nextMil = millis() + 실행 간격;
    	//실행할 코드(ex,온습도 값을 받아오시오, 외부 통신을 통해 값을 받아오는 코드 입력)
}
  void setup() {
    Serial.begin(115200);
    Serial.println();
  }
  void loop() {
    Serial.println("변수선언 테스트용");
    static unsigned long loopCnt = 0;	//static 변수는 loop문 안에서도 한번만 수행된다(아두이노에서만)
    static unsigned long nextMil = millis() + 1000;
    Serial.printf("mills ----");
    Serial.println(millis());
    Serial.printf("nextMil -----");
    Serial.println(nextMil);
    loopCnt++;
    if(millis()>nextMil){
        nextMil = millis() + 2000;
        Serial.println("loopCnt=%d",loopCnt);
        Serial.println("==========if loopCnt=================");
        loopCnt = 0;
      }
  }
  

프로그램 작성 시 장치들에 골고루 시간을 할당해야 한다.
특정 기능 수행에 로직을 묶어 놓아서 다른 일을 못하게 되면프로그램이 블로킹 되었다고 한다.
여러 기능을 수행하기 위해 논블로킹 방식으로 프로그래밍해야 한다.

  • 블로킹 방식
#define LED_PIN LED_BUILTIN
#define LED_OFF 0
#define LED_ON 1
#define LED_BLINK 
bool onVal = LOW;
bool offVal = HIGH;
int mode; //0:off, 1:on, 2:blink
int onMil = 3000;
int offMil = 1000;
void setup() {
  Serial.begin(115200);
  Serial.println();
  pinMode(LED_PIN,OUTPUT);
}
void loop() {
  while(Serial.available()){
    char c = Serial.read();
    if(c == 'm'){
      int val = Serial.parseInt();
      switch(val){
        case 0 : mode = LED_OFF;
                 digitalWrite(LED_PIN,HIGH);
                 Serial.println("mode=LED_OFF");
                 break;
        case 1: mode = LED_ON;
                digitalWrite(LED_PIN,onVal);
                Serial.println("mode=LED_ON");
                break;
        case 2: mode = LED_BLINK; 
                Serial.println("mode=LED_BLINK");
                break;
        default: Serial.println("mode Error!");
                break;            
      }
    }  
  }
  if(mode == LED_BLINK){
    digitalWrite(LED_PIN,onVal);
    delay(onMil);
    digitalWrite(LED_PIN,offVal);
    delay(offMil);  
  }
}

delay(onMil) ~ delay(offMil)의 밀리초 동안에는 블로킹 되어 ON, OFF와 같은 다른 기능을 못한다. 그렇기 때문에 delay() 사용하지 않는 것이 좋다.

👉 pinMode(LED_PIN,OUTPUT)일 때, 전류 싱킹 방식으로 LOW=1, HIGH=0
👉 pinMode(LED_PIN,INPUT)일 때, 전류 소싱 방식으로 HIGH=1, LOW=0

mode=LED_BLINK일 때, 블로킹 없이 ON/OFF 상태를 바꿀 수 있다.

    #define LED_PIN LED_BUILTIN
    #define LED_OFF 0
    #define LED_ON 1
    #define LED_BLINK 2

    bool onVal = LOW;
    bool offVal = HIGH;

    int mode; //0:off, 1:on, 2:blink
    int onMil = 2000;
    int offMil = 1000;

    bool blinkOn;
    unsigned long nextMil;

    void setup() {
      Serial.begin(115200);
      Serial.println();
      pinMode(LED_PIN,OUTPUT);
    }

    void loop() {
      while(Serial.available()){
        char c = Serial.read();
        if(c == 'm'){
          int val = Serial.parseInt();
          switch(val){
            case 0: mode = LED_OFF;
                    digitalWrite(LED_PIN, offVal);
                    Serial.println("mode=LED_OFF");
                    break;
            case 1: mode = LED_ON;
                    digitalWrite(LED_PIN, onVal);
                    Serial.println("mode=LED_ON");
                    break;
            case 2: mode = LED_BLINK;
                    digitalWrite(LED_PIN, onVal);
                    blinkOn = true;
                    nextMil = millis() + onMil;
                    Serial.println("mode=LED_BLINK");
                    break;
            default:Serial.println("mode=Error!");
                    break;
          }
        }
      }
      if(mode == LED_BLINK){
        if(blinkOn && millis()>nextMil){
          digitalWrite(LED_PIN,offVal);
          blinkOn = false;
          nextMil = millis() + offMil;  
        }
        else if(!blinkOn && millis() > nextMil){
          digitalWrite(LED_PIN,onVal);
          blinkOn = true;
          nextMil = millis() + onMil;
        }  
      }
    }
profile
Data Engineer

0개의 댓글