[아두이노] [강좌] 44. 블루투스 통신 (3) - RN42 모듈에서 직접 접속하기
이번 강좌에서는 RN-42 모듈의 커맨드를 이용하여 아두이노에서 다른 기기로 접속을 시도하는 실습을 진행해보자. 어렵지 않아요.
보통 아두이노에서 블루투스를 사용하는 경우는 스마트 폰과 연동하기 위해 사용되는 경우가 많으므로, 아두이노에서 직접 다른 기기를 검색하거나 연결하는 경우는 많지 않다. 하지만 만일 아두이노와 아두이노 간에 블루투스를 이용하여 통신하기를 원한다면 이번 실습이 꽤 유용할껄?
아두이노에는 이전 강좌에서 사용했던 MultiSerialMega 예제(메가 외의 보드에서는 SoftwareSerialExample 예제)가 업로드 된 상태여야 한다. RN-42와의 연결은 말할 것도 없고.
지지난 강좌에서 커맨드 모드로 진입하고 설정을 확인하던 실습이 기억날 것이다. 이번 실습은 커맨드 모드에서 진행되는 실습이므로, 혹시 아직 이전 강좌를 못 봤다면 먼저 보고 올 것.
그럼 바로 실습 고고!!
아두이노에서 직접 다른 기기를 검색하고 통신하기 위한 순서는 다음과 같다.
1. 커맨드 모드 진입
2. 주변 기기 검색
3. 연결
4. 데이터 송수신
음, 쉽네.
그러기 전, 연결할 대상의 블루투스 모드가 접속 가능한 모드여야 한다. 지난 강좌에서 데이터 실습을 위해 사용했던 "RN Bluetooth Chat" 어플을 다시 한번 이용해보자.
어플을 실행한 후 화면에서 메뉴 버튼을 누르면 화면 하단에 아래와 같은 메뉴가 나타난다.
두 번째의 "Make discoverable" 버튼을 선택하여 현재 상태를 검색 가능한 상태로 변경한다. 그럼 스마트 폰 쪽의 설정은 끝.
다시 아두이노로 돌아와서.
스케치 툴의 시리얼 모니터를 실행한 후 "$$$" 명령으로 커맨드 모드에 진입해보자.
"$$$" 명령을 보낼 때 종료 문자 삽입 설정이 "No line ending"이어야 한다는 것에 유의. "CMD"라는 응답이 수신되면 커맨드 모드에 제대로 진입한 것이다.
두 번째, 주변 기기를 검색하자. 어떻게?
다음은 RN-42 모듈의 사용자 매뉴얼 중 'Action Commands'에 대해 간단히 요약한 부분이다.
빨간 색으로 표시한 부분 중 "I,<time>,<cod>"라고 된 부분을 보자. 기기를 검색하는 커맨드이다. 뒤에 붙는 '<time>'과 '<cod>'는 매개 변수로 검색 시간과 필터링할 코드 지정을 할 수 있다. 안 넣어도 된다.
시간은 기본 10초로 설정되어 있으며, 최대 48초까지 설정할 수 있다. 필터링 코드의 기본 값은 '0'으로 필터링하지 않고 검색된 모든 기기를 표시한다.
난 시간만 지정해보도록 하겠다. 10초만 검색하도록, "i,10"이라고 전송하자.(명령어는 대소문자 상관 없음) 단, 현재 상태는 커맨드 모드여야 하며, 종료 문자 삽입 설정은 "캐리지 리턴" 혹은 "Both NL & CR"이어야 한다.
위 그림처럼 하나의 기기를 찾았다는 "Found 1" 문구와 함께, 검색된 기기의 MAC 주소와 이름이 표시된다. 마지막의 "5A020C"는 기기의 코드를 나타낸다.
혹시 검색을 했는데 스마트 폰 또는 찾고자 하는 기기가 검색이 되지 않는다면, 기기의 설정을 확인하거나 검색 시간을 늘려서 다시 시도해보도록. "i,30" 처럼.
이제 검색된 기기로 연결을 요청하자. 'Action Commands'에서 첫 번째 빨간 색 표시된 명령이 연결 요청 명령 "C". 매개 변수로 '<address>' 값을 주는데, 기기의 MAC 주소를 의미한다. 만일 '<address>' 값을 주지 않을 경우 'REM(Remote Address)'에 저장된 주소를 가져와 연결을 시도한다.
이후에도 계속 같은 주소로 접속을 요청할 것 같으면, "SR,<address>" 명령을 이용하여 주소를 저장한 뒤 "C" 명령만 사용하면 된다.
아닐 경우에는 "C," 다음에 연결할 기기의 MAC 주소를 주면 되고. 다음과 같이.
위 그림처럼 "TRYING"이라는 응답이 오면 연결을 요청한 것이다. 아쉬운 점은, 연결이 성공했다는 표시가 엄서. ㅜㅜ 그냥 이게 끝. 대신 실패하면 실패했다는 응답이 온다.
실패 응답이 없고, RN-42 모듈의 'Connect' LED가 On 되어있다면 정상적으로 연결된 것. 시리얼 모니터 상에서나 소스 상에서 연결 상태를 알고 싶다면 "GK" 커맨드를 이용하면 된다. (응답이 '0'이면 연결 안됨,N'1'이면 연결 됨)
연결이 정상적으로 된 것을 확인했다면, 이제 데이터를 보내보자. "hi~"
(무서운 일관성)
스마트 폰 쪽을 확인해볼까?
오, 도착했다!
그럼 스마트 폰에서도 보내보자. "hello"
정상적으로 데이터를 주고 받는 것을 확인할 수 있다.
사실 시리얼 모니터로 명령을 보내는 경우는 거의 없고, 대부분 소스 상에서 명령어를 출력하게 된다. 소스 상에서 "D" 명령을 보내서 설정을 확인하려면 수신된 데이터들 중 원하는 정보를 걸러내기 위한 절차가 필요하고, "I" 명령을 보내서 검색된 기기들의 정보를 확인하기 위해서도 데이터 파싱 기법이 필요하다.
String만 잘 다룰 수 있다면 어려운 부분은 아니다. 이 부분은 다음에 기회가 된다면 "Project" 포스팅에서 다룰 수 있었으면 좋겠.. 네요, 여러분. 하하.
그래도 아쉬우니, 간단하게 명령을 보내고 응답을 확인하는 코드를 살짝 투척하면서. 다음 강좌,N'프로토콜 만들기'에서 또 만나요, 안녕!
boolean SendBTCommand(String cmd, String ack, boolean bCr=true) { unsigned long preMillis = millis(); String strRxData = ""; boolean bOk=false;
// '\r'을 붙일지 여부 확인 후 명령어 전송 if(bCr) Serial1.println(cmd); else Serial1.print(cmd);
while(!bOk) { if(Serial1.available() > 0) { char c = Serial1.read(); strRxData += c; if(strRxData.indexOf(ack) > -1) bOk=true; // ack 명령 수신 확인 } if(millis() - preMillis > 3000) return false; // 타임 아웃 (3초) }
return true; } void loop() { SendBTCommand("$$$", "CMD", false); // 커맨드 모드 진입 SendBTCommand("SN,MyBT", "AOK", true); // 이름 변경 SendBTCommand("---", "END"); // 커맨드 모드 해제 // ... } |