RS's Travel & Electronic

HC-06 : 블루투스 수신함수의 기본형 본문

시퀀스와 아두이노

HC-06 : 블루투스 수신함수의 기본형

RS 2021. 7. 17. 22:57
SMALL

HC-06을 slave모드로 바꿔놓고 스마트폰 앱과 연결해서 사용하면 송신과 수신이 다 가능합니다.

보통은 공장 출고 당시에 slave가 기본 모드니까 손 안 댔다면 바꿀 필요가 없지만요.

 

송수 신중에 송신의 경우는 어떠한 트리거.. 가령 사용자에 의해 버튼이 눌렸다든지, 센서의 값이 일정량을 넘었다던지 할 때 보내게 되므로, 따로 예시를 들지 않을 겁니다. 그때그때 다르거든요.

 

수신은 송신과 다릅니다.

수신을 담당하는 함수는 들어올 수 있는 모든 경우의 신호들에 대해서 준비가 되어 있어야 하죠.

그래서 송신과 달리 수신의 경우는 기본형이라고 할 것이 있습니다.

 

코드에서 설명하죠.

 

 

#include <SoftwareSerial.h>
#define BLUE_TX      2
#define BLUE_RX      3

SoftwareSerial hc06 (BLUE_TX, BLUE_RX);

boolean blueConnect = false;

void hc06Receive () {
  String answer = "";
  while (hc06.available())
  {
    char val = hc06.read();
    answer += val;
    
    unsigned long atThisTime = millis();
    do
    {
        ;
    }while (atThisTime+5 > millis() );// 데이터 끊김 방지
  }
  
  if (answer != "") {
    if ( answer == "SIG1" ){
      Serial.println ("Receive SIG1");
    }
    else if ( answer == "SIG2" ){
      Serial.println ("Receive SIG2");
    }
    else if ( answer == "SIG3" ){
      Serial.println ("Receive SIG3");
    }
    else if ( answer == "SIG4" ){
      Serial.println ("Receive SIG4");
    }
    else if (answer == "BLUE") {
      blueConnect = true;
      Serial.println ( "Bluetooth Connect!");
    }
}

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

  Serial.println ("start.");
}

void loop() {
  hc06Receive ();
}

 

아주 기본적인 블루투스 수신의 형태입니다.

hc06Receive 함수는 자신이 호출될 때마다 hc06 객체로 수신 데이터가 있는지 확인하고 만약 있다면 전부 answer라는 String 객체에 전부 때려 박습니다. 넣을 것이 없을 때까지요.

한 글자 저장이 끝날 때마다 데이터 끊김 방지를 위해서 5밀리 초만큼의 딜레이를 한 번씩 주죠.

이 딜레이를 위해서 delay함수를 쓰면 안 됩니다. 아두이노를 완전히 수면상태로 집어넣어 버리는 게 목적이 아니니까요.

 

신호가 들어와서 answer가 ""값이 아니라면, 아래에 있는 if ~ else if 문들의 반복으로 경우의 수를 확인, 실행합니다.

위에선 기본형만 보여드리려고 SIG1,2,3,4라는 식으로 나열했지만 저기에 뭐 LED라는 문자열이 수신됐다면 아두이노에 연결된 해당 LED를 턴온, 턴오프하는 식으로 실행하게 되죠.

 

else if의 끝단에 있는 BLUE라는 신호의 경우는 아두이노에 연결된 HC-06과 어떤 장치(앱 or HC-06) 이 연결되었을 때 곧바로 보내도록 하는 제 나름의 약속입니다. 블루투스가 연결되었다는 것을 사용자는 알 수 있지만 아두이노는 모르거든요. 아두이노 너도 연결되었다는 사실은 알고 있어라!라는 의미로 blueConnect라는 boolean 변수를 true로 만들어 준겁니다.

 

 

 

이런 느낌으로 사용하고 있습니다만...

이 코드는 문제가 있긴 합니다.

어디가 문제가 있냐면 if ~ else if ~ else if를 반복하고 있는 부분이요.

 

이런 구조는 상정되는 데이터(문자열)의 종류가 많아질수록 비효율적이죠. 거기다 가독성도 엉망입니다.

switch를 쓰면 좋겠습니다만, C++에서는 switch가 판별할 수 있는 건 '문자' 지 "문자열"이 아니잖아요.

(정확히 말하자면 정수형만 가능한 거지만, 문자도 아스키 값으로 치면 정수니까)

 

오가는 신호의 특성상 한 개짜리 문자로 통신하는 것도 좋지 않습니다.

종류가 많아지면 프로그래머가 헷갈려서 실수를 할 확률이 높습니다.

 

들어올 신호가 한 네댓 가지 정도라면 그냥 if 쓰던가 아님 switch 쓰면서 문자로만 해도 괜찮겠지만 한 열몇 가지~몇십 가지라면 낭비가 심한 코드가 되기도 합니다. 여태껏 이런 기본형을 사용했을 때 딱히 문제가 있었던 적은 없었습니다만..

 

C++11부터 추가된 키워드인 constexpr를 사용해서 상대측에서 전송해온 문자열을 switch문에서 처리할 수 있도록 만들어보면 좀 더 효율적인 코드가 될 거 같습니다만.. 현재는 궁리만 하고 있을 뿐 잘 모르겠네요 ㅎㅎ;;

 

LIST
Comments