개발 관련/아두이노,IOT

아두이노와 안드로이드간의 블루투스 통신 [1]::HC-06 설정하기

snoworca 2014. 6. 21. 19:56



  Arduino 와 Android 디바이스와의 블루투스 통신을 하기 위하여 다른 모듈 대비 저렴한 HC-06 을 사용하였다. HC-06 블루투스 모듈은 블루투스 2.0 을 사용하고 슬레이브 모드(마스터 모드와 슬레이브 모드가 있다. 슬레이브 모드는 기기를 한 대 밖에 연결하지 못 한다. 관련 설명 페이지)만을 사용하며 가격이 다른 모듈에 비해 비교적 저렴한 것이 특징이다. 또 관련 자료도 많이 접할 수 있다. 옥션 같은 곳에서 12,000 원대에 구할 수 있지만 이베이에서는 국내 판매 가격보다 훨씬 저렴한 가격으로 구할 수 있다.  그냥 HC-06 알맹이만 있는 녀석은 4$~5$ 정도 한다. 다만, 배송비의 압박이 만만치 않다. 나는 5v 로 사용할 수 있는 HC-06 시리얼 모듈을 구입하였다.

   모듈을 구입하자 마자 안드로이드와 통신을 시도 하였는데, 뭐가 잘못 되었는지 번번히 실패 했었다.  결국 HC-06의 옵션값을 설정 해본 결과 안드로이드 디바이스와 데이터를 주고 받는데 성공하였다.  HC-06 의 옵션 값들은 시리얼로 연결하여 문자열로 직접 값들을 날리는 아주 간단한 방법으로 설정할 수 있다. 그리고, 시리얼 포트는 하나밖에 없기 때문에 아두이노 IDE 시리얼 모니터의 커맨드 창으로 명령어를 주기 위하여 디지털 I/O 핀을 이용한 소프트웨어 시리얼을 사용해야 한다. 

  

::HC-06 의 옵션값 (HC-06 버전에 따라 반환값이 달라질 수 있다.)

1. 테스트

   명령어 : AT 

   반환값 : OK

 

2. 버전 확인

    명령어 : AT+VERSION

    반환값 : OKlinvorV1.8 


3. 이름 변경

    명령어 : AT+NAME이름

    반환값 : OKsetname


4. 보레이트 설정

    명령어 : AT+BAUD보레이트 메뉴값.

    보레이트 메뉴 :

     1 - 1200,  2 - 2400, 3 - 4800,  4 - 9600

     5 - 19200,  6 - 38400, 7 - 57600,  8 - 115200 

    반환값 : OK보레이트 (예 : OK9600)


5. PIN설정

    명령어 : AT+PIN네 자리 숫자

    반환값 : OKsetPIN


::시리얼 모니터를 통하여 옵션값을 HC-06으로 전송하는 스케치 코드

#include <SoftwareSerial.h> #define rxPin 2 #define txPin 3 SoftwareSerial SwSerial(txPin, rxPin); char data; void setup() { Serial.begin(9600); SwSerial.begin(9600); Serial.println("Ready.."); } void loop() { // 시리얼 버퍼를 비운다. Serial.flush(); Serial.print("cmd : "); // 버퍼에 값이 들어올 때 까지 대기. while(!Serial.available()); // HC-06 으로 명령어를 날린다. while(Serial.available()) { data = Serial.read(); if(data == -1) break; SwSerial.print(data); Serial.print(data); // 시리얼 통신에서는 9600bps 기준으로 // read 를 사용할 때 1ms 의 딜레이를 줘야 한다. delay(1); } Serial.println(); // HC-06에서 처리할 시간을 준다. delay(1000); Serial.print("return : "); // HC-06 으로 부터 받아온 리턴 값을 출력한다. while(SwSerial.available()) { data = SwSerial.read(); if(data == -1) break; Serial.print(data); delay(1); } Serial.print("\n\n"); }

  위 코드를 이용하기 위하여 블루투스 HC-06 의 RX  핀에는 Digital I/O 2 번, TX 에는 Digital I/O 3 번 을 연결하고 VCC 와 GND 에도 각각 라인을 연결해 줘야한다. 

 

     위 회로대로 연결해도 문제가 없는 모듈을 사용했다. SoftwareSerial 을 사용했기 때문에 0번과 1번 핀이 아닌 2번과 3번 핀에 연결하였다. 여기서 소개하는 5v 전용으로 간편하게 사용할 수 있는  블루투스 모듈이 아닌 경우 사용 전압을 잘 보고 연결해야 한다. (만약  3.3v 를 사용하는 녀석이라면 저항을 연결해줘야 한다.)

   만약 HC-06 알맹이(?)만 있는 녀석이라면 이 곳(wifi 쉴드 없이 블루투스와 안드로이드를 이용하여 인터넷을 사용하는 것에 대하여 나와있다.)  에 나와있는 회로를 참고하시라.


::결과


  명령어라고 해봤자 얼마 되지 않지만, 사실 이 것을 바꿔줄려면 외우든지 찾든지 해야 한다. 좀 귀찮은 일이 아닐 수 없다. 그래서 앞으로 조금만 더 쉽게 사용 하려고 메뉴 화면을 만들었다.  어차피 한 번 만들면 유지보수 같은 것 필요 없는 코드라 대충 날림으로 만들었다. 



조금 편하게 사용하기.

#include <SoftwareSerial.h> #define PIN_RX 2 #define PIN_TX 3 SoftwareSerial gSoftSerial(PIN_TX, PIN_RX); const char* gMenu = "HC-06 Settings.\n1) name\n2) pin\n3) baud rate\n4) Version\n"; const char* gMenuBaud = "1) 1200\n2) 2400\n3) 4800\n4) 9600\n5) 19200\n6) 38400\n7) 57600\n8) 115200\nNote: If you modify baud rate, must be modified together code.\n( gSoftSerial.begin(baud rate) in seting() function. )\n"; const char* gMsgName = "> Name : "; const char* gMsgPin = "> pin(4 digits only) : "; const char* gMsgInvalidCmd = "Please enter a valid command.\n\n"; const char* gMsgResponseError = "Error : No response from HC-06.\n\n"; const char* gCmdPin = "AT+PIN"; const char* gCmdName = "AT+NAME"; const char* gCmdBaud = "AT+BAUD"; const char* gCmdVer = "AT+VERSION"; char gInChar; char gSelectMode = 0; char gCharBuffer[256]; void setup() { gSoftSerial.begin(9600); Serial.begin(9600); } void loop() { Serial.print(gMenu); Serial.print(">"); clearBuffer(); gInChar = readStr(0)[0]; if(gInChar < '1' || gInChar > '4') { Serial.print(gMsgInvalidCmd); gSelectMode = 'a'; } else { gSelectMode = gInChar; } if(gSelectMode == '1') { Serial.print(gMsgName); clearBuffer(); strcat(gCharBuffer, gCmdName); readStr(strlen(gCmdName)); Serial.println(gCharBuffer); sendCmd(gCharBuffer); } else if(gSelectMode == '2') { Serial.print(gMsgPin); clearBuffer(); strcat(gCharBuffer, gCmdPin); readStr(strlen(gCmdPin)); Serial.println(gCharBuffer); sendCmd(gCharBuffer); } else if(gSelectMode == '4') { clearBuffer(); strcat(gCharBuffer, gCmdVer); Serial.println(gCharBuffer); sendCmd(gCharBuffer); }else if(gSelectMode == '3') { Serial.print(gMenuBaud); Serial.print(">"); clearBuffer(); gInChar = readStr(0)[0]; if(gInChar < '1' || gInChar > '8') { Serial.print(gMsgInvalidCmd); gSelectMode = 'a'; } else { clearBuffer(); strcat(gCharBuffer, gCmdBaud); uint8_t len = strlen(gCharBuffer); gCharBuffer[len] = gInChar; gCharBuffer[len + 1] = '\0'; Serial.println(gCharBuffer); sendCmd(gCharBuffer); } } } void sendCmd(char* cmd) { Serial.println(); gSoftSerial.write(cmd); for(uint8_t i = 0; i < 5; ++i) { delay(200); Serial.print('.'); } if(!gSoftSerial.available()) { Serial.print(gMsgResponseError); } else { while(gSoftSerial.available()) { delay(10); Serial.print((char)gSoftSerial.read()); } } Serial.println("\n"); } char* readStr(uint8_t offset) { uint8_t index = offset; while(!Serial.available()); while(Serial.available()) { delay(10); gInChar = Serial.read(); gCharBuffer[index] = gInChar; Serial.print(gInChar); index++; } Serial.print("\n"); return gCharBuffer; } void clearBuffer() { memset(gCharBuffer, '\0', 256); }


아래 스크린샷과 같이 메뉴가 출력된다. 

  


참고 자료. 

 HC-06 모듈에 대한 설명 : http://mcuoneclipse.com/2013/06/19/using-the-hc-06-bluetooth-module/