일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- 군산명소
- 아두이노
- 아두이노 블루투스
- 목포명소
- 이럴때아니면언제이런거보겠어
- 신안선
- 당일치기여행
- 보석 관람
- 시퀀스 그리는 프로그램
- 완도 명소
- 너무작잖아...
- 군산
- 익산 보석 박물관
- 비트맵 띄우기
- oled
- 완도 구경
- 해양 전시회
- 시퀀스 프로그램
- 눈에보양
- 해양문화재연구소
- HC-06
- 대중음악박물관
- 128x64
- 목포 박물관
- 목포
- 익산 명소
- 군산 구경
- HC-06 사용법
- u8glib
- 좀더큰규모일줄알았다규..
- Today
- Total
RS's Travel & Electronic
HC-06 : 블루투스 수신함수의 기본형 본문
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문에서 처리할 수 있도록 만들어보면 좀 더 효율적인 코드가 될 거 같습니다만.. 현재는 궁리만 하고 있을 뿐 잘 모르겠네요 ㅎㅎ;;
'시퀀스와 아두이노' 카테고리의 다른 글
PLC XBC-DR20SU 테스트회로 (0) | 2021.07.29 |
---|---|
HC-06 : 페어링이 유지되는지 확인하는 코드 (1) | 2021.07.18 |
HC-06 : 연결안됨과 AT명령어일람 (5) | 2021.07.17 |
u8glib : OLED에 한글 비트맵 출력 (0) | 2021.07.15 |
u8glib : OLED에 비트맵 이미지 출력하기 (0) | 2021.07.14 |