함수와 클래스

문주은·2021년 1월 1일
0

메디컬IOT

목록 보기
7/13

1. 함수 프로토타입

함수의 요약 정보. 즉, 돌려받을 변수혀으 함수 이름, 매개 변수의 속성 정보나 개수를 미리 선언

int sum(int a, int b); 	//미리 사용할 함수를 선언해 줘야 한다.
void sum(float a, float b, float &c);

void setup(){...}
void loop(){...}
int sum(int c, int d){......}
void sum(float c, float d, float &e){.......}

👉 코드의 위치가 loop()뒤에 올때, 프로토타입을 변수 선언처럼 setup() 앞부분에 미리 선언해야 한다.

serial-led-func-go 예제

  #define LED_PIN LED_BUILTIN

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

  #define ON_MIL 3000
  #define OFF_MIL 500

  bool onVal;
  bool offVal;

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

  bool blinkOn;
  unsigned long nextMil;

  void ledInit(int pin, bool INonVal) {
    onVal = INonVal;
    offVal = !onVal;

    mode = LED_OFF;
    onMil = ON_MIL;
    offMil = OFF_MIL;
    pinMode(pin,OUTPUT);
    digitalWrite(pin,offVal); // off
  }

  void ledSetOnMil(int INval) {
    onMil = INval;
  }

  void ledSetOffMil(int INval) {
    offMil = INval;
  }

  void ledOff() {
     digitalWrite(LED_PIN,offVal);
  }

  void ledOn() {
     digitalWrite(LED_PIN,onVal);
  }

  void ledBlink() {
    digitalWrite(LED_PIN,onVal);                
    blinkOn = true;
    nextMil = millis() + onMil;
  }

  void ledRun() {
    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;
      }
    }
  }

  void setup() {
    Serial.begin(115200);
    Serial.println();

    Serial.println("Input m 0 for led off");
    Serial.println("Input m 1 for led on");
    Serial.println("Input m 2 for led blink");
    Serial.println("Input n nnn for onMil");
    Serial.println("Input f nnn for offMil");

    ledInit(LED_PIN,LOW); // PIN, onVal
  }

  void loop() {
    while(Serial.available()) {
      char c = Serial.read();
      if (c == 'm') {
        int val = Serial.parseInt();
        switch (val) {
          case 0 : mode = LED_OFF;
                   ledOff();              
                   Serial.println("mode=LED_OFF");
                   break;
          case 1 : mode = LED_ON;
                   ledOn();
                   Serial.println("mode=LED_ON");
                   break;
          case 2 : mode = LED_BLINK;
                   ledBlink();
                   Serial.println("mode=LED_BLINK");
                   break;
          default: Serial.println("mode ERROR!!");
        }
      }
      else if (c == 'n') {
        int val = Serial.parseInt();
        ledSetOnMil(val);
        Serial.printf("ledSetOnMil=%d\n",val);
      }
      else if (c == 'f') {
        int val = Serial.parseInt();
        ledSetOffMil(val);
        Serial.printf("ledSetOffMil=%d\n",val);
      }
    }
    ledRun(); // LED_BLINK일 때 ON,OFF
  }

👉 m0입력 → mode=LED_OFF
👉m1입력 → mode=LED_OFF
👉m2입력 → mode=LED_BLINK
👉n1000입력 → blink할 때의 ON_MIL 시간을 3000에서 1000으로 바꿔준다.
👉f200입력 → blink할 때의 OFF_MIL 시간을 500에서 200으로 바꿔준다.

2. 클래스 만들기

  • serial-led-class
#define LED_PIN LED_BUILTIN
#include "Led.h"
Led led(LED_PIN,LOW);  // PIN, onVal 

👉 #include "새로운 파일 이름"
👉 led가 2개 있을 시 : Led led1(LED1_PIN,HIGH); 추가(헤더파일을 공통으로 사용)

void setup() {
  Serial.begin(115200);
  Serial.println(); 
}
void loop() {
  while(Serial.available()) {
    char c = Serial.read();
    if (c == 'm') {
      int val = Serial.parseInt();
      switch (val) {
        case 0 : led.off();      
                 Serial.println("mode=LED_OFF");
                 break;
        case 1 : led.on();
                 Serial.println("mode=LED_ON");
                 break;
        case 2 : led.blink();
                 Serial.println("mode=LED_BLINK");
                 break;
        default: Serial.println("mode ERROR!!");
      }
    }
    else if (c == 'n') {
      int val = Serial.parseInt();
      led.setOnMil(val);
      Serial.printf("ledSetOnMil=%d\n",val);
    }
    else if (c == 'f') {
      int val = Serial.parseInt();
      led.setOffMil(val);
      Serial.printf("ledSetOffMil=%d\n",val);
    }
  }
  led.run(); // LED_BLINK일 때 ON,OFF
}

Led.h

#define LED_OFF 0
#define LED_ON 1
#define LED_BLINK 2
#define ON_MIL 3000
#define OFF_MIL 500
// class 이름 첫글자는 대문자가 좋음
class Led {
  // 외부에 알려짐
  public:
    // constructor
    // class 이름 사용
    // void가 없음
    Led(int pin, bool onVal);
    void setOnMil(int val);
    void setOffMil(int val);
    void off();
    void on();
    void blink();
    void run();
  // 내부에서만 사용
  private:
    int pin;  
    bool onVal;
    bool offVal;
    int mode; // 0:LED_OFF, 1:LED_ON, 2:LED_BLINK
    int onMil;
    int offMil;
    bool blinkOn;
    unsigned long nextMil;
}; // {}의 끝에 ;이 있음
// constructor,void가 없음
LED::Led(int INpin, bool INonVal) {
  pin = INpin;
  onVal = INonVal;
  offVal = !onVal;
  mode = LED_OFF;
  onMil = ON_MIL;
  offMil = OFF_MIL;
  pinMode(pin,OUTPUT);
  digitalWrite(pin,offVal); // off
}

👉범위 지정 연산자(::)
class문 밖에서 클래스에 속한 메소드 작성할 때 class_name::을 붙여 소속을 표시

void LED::setOnMil(int INval) {
  onMil = INval;
}
void LED:setOffMil(int INval) {
  offMil = INval;
}
void LED::off() {
  mode = LED_OFF;
  digitalWrite(pin,offVal);
}
void LED::on() {
  mode = LED_ON;
  digitalWrite(pin,onVal);
}
void LED::blink() {
  mode = LED_BLINK;
  digitalWrite(pin,onVal);                
  blinkOn = true;
  nextMil = millis() + onMil;
}
void LED::run() {
  if (mode == LED_BLINK) {
    if(blinkOn && millis() > nextMil) {
      digitalWrite(pin,offVal);
      blinkOn = false;
      nextMil = millis() + offMil;
    }
    else if(!blinkOn && millis() > nextMil) {
      digitalWrite(pin,onVal);
      blinkOn = true;
      nextMil = millis() + onMil; 
    }
  }
}

클래스를 사용하는 이유 : led가 여러개가 생겨도 반복적으로 기능을 수행할 수 있다.

profile
Data Engineer

0개의 댓글