본문 바로가기
전자공학/아두이노

[아두이노 코딩] 시리얼 모니터로 핀 번호, 주파수 입력 받아 led 깜박이기 ( 사용자가 입력 할 때까지 기다렸다가 입력 받기 )

by ohj921189 2020. 6. 1.
반응형

문제 : 핀 번호와 주파수를 입력받아 LED가 입력된 주파수로 깜박이도록 하는 함수를 만드시오.
*주파수는 주기의 역수라는 점을 이용하시오. 

 

int pin_num = 0, freq = 0, c = 0;

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

void loop() {
  int pin,freq1;
  Serial.println("핀 번호와 주파수를 입력하시오");
  pin=input_num();
  freq1=input_freq();
  pinMode(pin,OUTPUT);
  digitalWrite(pin,HIGH);
  freq_to_time(pin,freq1);
  digitalWrite(pin,LOW);

  Serial.println("Input any key to continue..");
  while(Serial.available() == 0) {}

  c = Serial.read();   // 시리얼 입력이 다음으로 넘어가는 것을 방지하기 위한 코드
  Serial.println(" ");
}

int input_num(){
  Serial.end();
  Serial.begin(9600);
  Serial.print("Pin num: ");
  while(Serial.available() == 0) {}
  pin_num = Serial.parseInt();
  Serial.println(pin_num);
  return pin_num;
  }

int input_freq(){
  Serial.end();
  Serial.begin(9600);
  Serial.print("freq: ");
  while(Serial.available() == 0) {}
  delay(1000);
  freq = Serial.parseInt();
  Serial.println(freq);
  return freq;
  }

void freq_to_time(int pin, int freq1){
  float Time= 1.0f / (float)freq1;
  Serial.println(Time);
  Time=Time*1000;//ms 단위로 변경
  delay(Time);
  }

코드에 대한 해석과 함께 아두이노에서 쓰이는 함수들에 대해 알아보도록 합시다. 

 

 

우선 input_num 함수에 대해 설명드리도록 하겠습니다. 

 

 

input_num 함수는 Serial.end()로 시작이 됩니다. 그 이유는 사용자가 시리얼 모니터에 값을 입력할 때까지 기다리게 하는 것에 목적이 있습니다. 아두이노는 기본적으로 loop 함수를 통해 동작하기 때문에 c언어의 scanf처럼 입력받을 때까지 기다리는 함수가 따로 존재하지 않습니다. 

 

 

그럼 사용자가 입력받을 때까지 입력을 기다리게 하는 코드는 어떻게 짜야 할까요? 

 

 

바로 Serial.available() 함수를 이용하는 것입니다. Serial.available()은 Serial을 통해 수신한 데이터가 있을 때 1을 리턴하는 함수입니다. PC와 시리얼 통신을 시작하는 것을 확인하면 1을 리턴하는 것입니다.



while 문을 이용하여 while( Serial.available() ==0 ) {}이라는 코드를 만들어 줍니다. 이 문장은 사용자가 Serial을 통해 어떤 문자를 입력하기 전까지 아무 코드도 수행하지 않습니다. 사용자가 Serial에 문자를 입력한다면 while 문을 빠져나와 그다음 문장을 수행할 수 있게 합니다. 통신 시작을 확인하는 함수를 이용하여 이러한 방식으로 코딩할 수 있습니다.



그럼 while( Serial.available() ==0 ) {} 이 문장만 사용하면, 계속해서 사용자가 문자를 시리얼 모니터를 통해 입력할 때까지 멈춰 있는 것일까요?

 

 

답은 아닙니다. 왜냐하면 이미 한 번 문자를 시리얼 모니터를 통해 입력하게 되면 다음에 while( Serial.available() ==0 ) {} 이 문장을 만나게 되더라도 Serial.available()은 이미 1이기 때문에 자연스럽게 다음 코드로 넘어가기 때문입니다.



그럼 사용자가 시리얼 모니터를 통해 입력하기 전까지 기다리게 하는 것을 계속해서 할 수는 없는 걸까요?



이 방법을 써보도록 합시다. PC와 시리얼 모니터와의 통신을 중간에 끊어주는 것입니다. 그러기 위해서 사용하는 함수가 Serial.end()입니다. Serial.end()로 통신을 끊었다가 Serial.begin()으로 통신을 다시 연결해 준 다음 while( Serial.available() ==0 ) {} 이 문장을 사용하는 것입니다.

 

 

다시 input_num 함수로 넘어와서 Serial.parseInt() 함수를 이용하여 숫자를 입력받습니다. 입력받는 함수로 보통 Serial.read()를 많이 사용하는데 Serial.read()는 숫자 데이터도 char로 인식하기 때문에, 1을 입력하면 49로 반환이 됩니다.  

 

 

Serial.parseInt()는 시리얼 통신으로 받은 데이터가 숫자 형식의 데이터일 경우 그 값을 숫자로 변환하여 반환하기 때문에 유용하게 사용할 수 있습니다.

 

핀 번호와 주파수를 이러한 함수들을 이용하여 값을 받아온 뒤에 주파수는 float Time= 1.0f / (float) freq1; 이러한 식을 이용해서 주기(second)로 바꿔준 뒤 digitalWrite 함수를 이용하여 깜빡여 줍니다. 

 

 

반응형

댓글