아두이노 블루투스 HC-06 과 안드로이드 블루투스 SPP 통신..

안드로이드 블루투스 프로그래밍 공부도 할 겸 한번 만들어 보았다.
안드로이드 app에서 블루투스를 통해 커맨드를 보내면, 아두이노에 연결된 블루투스 모듈 (HC-06)을 통해 커맨드를 받고, LED를 켜고 끄는 예제를 만들어 보았다.

아두이노 블루투스 (HC-06)

아두이노와 블루투스 모듈, LED는 아래 그림처럼 연결했다.

아두이노와 블루투스 모듈 HC-06은 시리얼 통신으로 설정 및 데이터를 주고받을 수 있다.
시리얼 통신은 아두이노 스케치에서 제공하는 SoftwareSerial을 사용하면 된다.
SoftwareSerial을 사용하여 아래와 같이 HC-06과의 통신 코드를 구현하였다.

#include <SoftwareSerial.h>
int BT_Tx_Pin = 3;
int BT_Rx_Pin = 2;
SoftwareSerial BTComm(BT_Tx_Pin, BT_Rx_Pin);
String ReadBT()
{
     String _data = “”;
while (BTComm.available())
{
          _data += (char)BTComm.read();
delay(5);
}
return _data;
}
void WriteBT(String _data)
{
     BTComm.print(_data);
}
void ConnectBT(long baud_rate)
{
     long baud_rates[] = {9600, 115200, 1200, 2400, 4800, 19200, 38400, 57600};
if (BTComm.isListening())
{
     BTComm.end();
}
if (baud_rate != 0)
{
     BTComm.begin(baud_rate);
return;
}
for (int i = 0; i < 7; i++)
{
     String ReadMsg = “”;
     BTComm.begin(baud_rates[i]);
WriteBT(“AT”);
delay(1500);
     ReadMsg = ReadBT();
if (!ReadMsg.equals(“”))
{
return;
}
     BTComm.end();
}
// if not found. connect default baudrate BTComm.begin(9600);
}

HC-06의 설정 방법은 시리얼 통신으로 HC-06에  AT 커맨드를 쓰면 설정할 수 있다.

1. 통신 테스트
send : AT
receive : OK
2. baud rate 설정
send : AT+BAUD8
receive : OK115200
* BAUD1~8까지 설정 가능하다. default4이다.
1 > 1200
2 > 2400
3 > 4800
4 > 9600
5 > 19200
6 > 38400
7 > 57600
8 > 115200
3. Bluetooth 이름 설정
send : AT+NAMEdevicename
receive : OKsetname
* devicename에 원하는 이름을 설정한다.
4. Pincode 설정
send : AT+PINxxxx
receive : OKsetPIN
* xxxx에 원하는 pincode를 넣는다.

 

안드로이드 app에서 LEDON 커맨드를 보내면 led를 켜고, LEDOFF 커맨드를 보내면 led를 끄도록 구현하였다.

int ledPin = 8;
void setup() {
     ...
     pinMode(ledPin, OUTPUT);
}
void loop()
{
     String ReadData = ReadBT();
     ...
     if (ReadData.substring(0, 3) == “LED”)
     {
          if (ReadData.substring(3, 5) == “ON”)
          {
               digitalWrite(ledPin, HIGH);
               WriteBT(“OK LED ON”);
          }
          else if (ReadData.substring(3, 6) == “OFF”)
          {
               digitalWrite(ledPin, LOW);
               WriteBT(“OK LED OFF”);
          }
     }
     delay(50);
}

아래 이미지는 실제 동작시 출력되는 로그 메시지이다. 가끔 글자가 깨지는 경우가 있다.

안드로이드 블루투스 SPP(Serial Port Profile)

안드로이드에서는 페어링 된 디바이스 리스트를 받아와 Bluetooth 소켓을 열고 InputStream,outputStream을 사용하여 데이터를 읽고 쓰는 방식으로 구현하였다.

페어링 된 블루투스 디바이스의 리스트를 받아오는 방법은 아래 코드와 같다.

BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
Set<BluetoothDevice> pairDevices = mBluetoothAdapter.getBondedDevices();
if(pairDevices.size() > 0)
{
     for(BluetoothDevice device : pairDevices)
     {
          mPairedDevicesArrayAdapter.add(device.getName() + “\n” + device.getAddress());
     }
}

블루투스 소켓은 위에서 받아온 디바이스를 사용해 생성할 수 있다.
소켓 생성 시 SPP용 uuid (“00001101-0000-1000-8000-00805f9b34fb”)를 사용해 생성해야 한다.

BluetoothSocket mSocket = null;
...
{
     ....
     BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
     mSocket = connect(mDevice);
     ....
}
private BluetoothSocket connect(BluetoothDevice btdevice)
{
     BluetoothSocket socket = null;
     UUID uuid = UUID.fromString(“00001101-0000-1000-8000-00805f9b34fb”);
     if(btdevice == null)
     {
          return null;
     }
     try
     {
          socket = btdevice.createRfcommSocketToServiceRecord(uuid);
     }catch (IOException e)
     {
          Log.e(TAG,“BT Socket Creation Fail”,e);
          return null;
     }
     try
     {
          socket.connect();
     }
     catch (IOException e)
     {
          Log.e(TAG,“BT Socket connect Fail”,e);
          close(socket);
          return null;
     }
     return socket;
}

 

InputStream과 OutputStream은 아래와 같이 생성한다.

private InputStream GetInputStream(BluetoothSocket socket)
{
     InputStream tmpIn = null;
     if(socket == null)
     {
          return null;
     }
     try {
          tmpIn = socket.getInputStream();
     }
     catch (IOException e)
     {
          Log.e(TAG, “GetInputStream”, e);
          return null;
     }
     return tmpIn;
}
private OutputStream GetOutStream(BluetoothSocket socket)
{
     OutputStream tmpout = null;
     if(socket == null)
     {
          return null;
     }
     try {
          tmpout = socket.getOutputStream();
     }
     catch (IOException e)
     {
          Log.e(TAG, “GetOutStream”, e);
          return null;
     }
     return tmpout;
}

 

bluetooth를 통해 데이터를 전송할때는 아래와 같고,

mOutStream.write(buffer);

데이터를 읽을떄는 아래와 같다

int len = mInStream.read(buffer);

아래 이미지는 실제 동작시 화면을 캡쳐한 것이다.
왼쪽은 페어링된 디비아스의 리스트를 표시한 이미지이고, 오른쪽은 데이터를 주고 받을때의 화면을 켭쳐한 것이다.

테스트 영상

아두이노에 펌웨어를 올린 다음, 안드로이드 폰에서 bluetooth 디바이스 페어링 하였다.
그 후, 구현한 안드로이드 app을 실행하여 테스트하였다.

아두이노 Bluetooth (HC-06) 와 안드로이드 Bluetooth 통신 예제

통신 중 가끔 글자가 깨지는 문제가 있어 추후에 개선해야 할 것 같다.
블루투스 모듈 HC-06은 SPP용으로 사용하기 편리하긴 한데, Slave모드(Device모드)만 있어서 아쉽다.
아두이노끼리 Bluetooth 통신하기 위해선 다른 블루투스 모듈을 찾아봐야 할 것 같다.

댓글 남기기

이메일은 공개되지 않습니다. 필수 입력창은 * 로 표시되어 있습니다