라즈베리파이4와 안드로이드 사이에 블루투스 연결을 시도했습니다. 라즈베리파이4에서 블루투스 통신을 하기 위한 코드는 파이썬으로 작성했습니다.
라즈베리파이, 안드로이드, 블루투스 통신 관련 포스팅은 많았지만 돌발변수가 많아서 대부분의 포스팅이 저에게 도움이 되질 않았습니다;ㅅ; 하지만 긴 삽질 끝에 겨우 custom 안드로이드 앱 개발까지 성공했습니다.. 어떤 문제가 있었는지, 어떻게 해결했는지를 간략하게 정리했습니다.
1. 필요한 라이브러리 설치
// 라즈베리파이 업데이트
Sudo apt-get update
Sudo apt-get upgrade
// 필요한 라이브러리 설치
Sudo apt-get install bluetooth blueman bluez
Sudo apt-get install python-bluetooth
// 재부팅
Sudo reboot
2. 블루투스 페어링
sudo bluetoothctl
아래와 같이 [bluetooth]# 으로 변경됩니다.
scan on
scan on 명령어를 통해서 주변 블루투스 기기를 스캔합니다.
저의 스마트폰의 MAC 주소는 50:77:05:5F:37:5C였습니다.
pair MAC주소
trust MAC주소
저는 연결을 위해서 "pair 50:77:05:5F:37:5C"을 터미널에 입력했습니다.
pair 명령어를 치면, 스마트폰에서는 블루투스 연결 요청이 뜹니다.
확인을 눌러주셔야 블루투스 연결이 됩니다.
라즈베리파이에서도 Confirm passkey OOOOOO (yes/no): 하고 입력창이 뜹니다.
yes라고 타이핑해주셔야 블루투스 연결이 됩니다.
여기까지 하면 라즈베리파이↔️안드로이드 블루투스 페어링이 설정되었습니다.
3. 데이터 송/수신
데이터 송/수신 테스트를 위해서 Blueterm 어플을 설치합니다.
라즈베리파이에서 데이터를 수신하기 위한 코드는 파이썬으로 작성했습니다. 저는 라즈베리파이에 기본으로 설치되어있는 Tonny Python IDE를 사용했습니다.
상단의 라즈비안 아이콘>Programming>Thonny Python IDE를 켜고 아래 코드를 복붙 해주세요. 파일 이름은 example.py 정도로 저장해주세요. 절대 bluetooth.py로 저장하시면 안 됩니다!
from bluetooth import *
server_socket= BluetoothSocket(RFCOMM)
port = 1
server_socket.bind(("", port))
server_socket.listen(1)
client_socket, address = server_socket.accept()
print("Accepted connection from ", address)
client_socket.send("bluetooth connected!")
while True:
data = client_socket.recv(1024)
print("Received: %s" %data)
if(data=="q"):
print("Quit")
break
client_socket.close()
server_socket.close()
IDE에서 RUN 버튼을 눌러서 코드를 실행시킵니다.
그러고 나서 Blueterm에서 raspberrypi와 연결을 요청합니다.
연결에 성공하면 blueterm에서 "bluetooth connected!"가 출력됩니다.
Python IDE의 쉘을 확인하면 제 스마트폰 MAC주소를 가진 기기와 연결이 되었다는 메시지가 출력됩니다. 이제 스마트폰에서 문자를 치면 한 글자씩 보내집니다.
4. 이 짧은 포스팅을 위해 삽질한 것들
(1) 한번 페어링이 되고 나면, scan on을 했을 때 스캔되지 않는 문제
스마트폰 설정> 블루투스에서 페어링 된 기기를 삭제하고 나면, 다시 스캔이 되었습니다.
(2) Blueterm 말고 되는 다른 어플
라즈베리파이↔️안드로이드 블루투스 연결 관련 포스팅은 모두 Blueterm을 사용하라는 말 뿐이었습니다. Blueterm은 마지막 업데이트가 2013년인 어플입니다. 더 좋은 어플을 찾기 위해서 구글 플레이에 존재하는 대부분의 블루투스 어플을 깔아본 것 같습니다.
결론부터 말씀드리자면 더 좋은 어플 찾는 건 실패했습니다. 이 많은 어플 중에서 Blueterm과 Pi3 Bluetooth Manager만 라즈베리파이와 블루투스 연결이 되었습니다. 이전에 제가 만든 안드로이드 블루투스 어플도 연결에 실패했습니다.
(3) 안드로이드 Custom 앱 코드
제가 만든 어플리케이션에서 코드를 계속 수정해서 확인한 결과,
read failed, socket might closed or timeout, read ret: -1
에러가 나면서 블루투스 연결에 실패하더라구요.
이 문제의 해결방법은 StackOverflow에서 자세한 해결방법을 찾을 수 있었는데요, 행운인지 아닌지 Blueterm의 코드가 깃헙에 올라와있었습니다.
깃헙의 코드를 참고해서, 제가 만든 안드로이드 블루투스 어플의 MainActivity.java의 160번째 줄부터 시작하는 create&connect socket부분 코드를 다음과 같이 수정했습니다.
// create & connect socket
try {
btSocket = createBluetoothSocket(device);
} catch (IOException e) {
flag = false;
textStatus.setText("socket creation failed!");
e.printStackTrace();
}
/* 주석처리
try {
btSocket.connect();
} catch (IOException e) {
flag = false;
textStatus.setText("connection failed!");
e.printStackTrace();
}
// start bluetooth communication
if(flag){
textStatus.setText("connected to "+name);
connectedThread = new ConnectedThread(btSocket);
connectedThread.start();
}
*/
// Make a connection to the BluetoothSocket
try {
btSocket.connect();
} catch (IOException e) {
// Close the socket
try {
btSocket.close();
} catch (IOException e2) {
Log.e(TAG, "unable to close() socket during connection failure", e2);
}
}
connectedThread = new ConnectedThread(btSocket);
textStatus.setText("connected to "+name);
connectedThread.start();
기존의 connect는 주석 처리하고 blueterm의 코드를 가져왔습니다.
소켓과 connect 하는 코드를 변경하니까 라즈베리파이와 연결에 성공했습니다.
connect가 성공하면 SEND A버튼을 눌렀을 때, 라즈베리파이에 a가 전송됩니다.
긴 삽질을 하고 나니까 소켓 connect와 관련된 공부를 하고 나니까 왜 블루투스 연결이 되는 어플이 있고, 아닌 어플이 있는지 알게 되었습니다..
(4) 안드로이드→라즈베리파이로 보낸 데이터 형식
안드로이드에서 라즈베리파이로 데이터를 보내는 것에는 성공했지만, 문제는 문자열 a만 보내도 라즈베리파이에서 b'a'로 읽어졌습니다. 이 문제는 아직까지 해결을 못했습니다. 그래서 q를 보내도 python의 while문 탈출이 안됩니다. b'q'로 변경해도 마찬가지로 안됐습니다.
저는 안드로이드 앱 custom이 제일 급해서 이 문제는 뒷전이었는데요, 나중에 해결방법을 찾으면 공유하겠습니다.
잘못된 내용이 있다면 언제든지 댓글이나 메일로 알려주시면 감사하겠습니다.
이 포스팅이 도움이 되었다면 공감 부탁드립니다.
궁금한 점은 언제든지 댓글 남겨주시면 답변해드리겠습니다:D
'관리하지않음 > 라즈베리파이' 카테고리의 다른 글
라즈베리파이 공식 7인치 터치스크린 리뷰 (2) | 2020.10.23 |
---|---|
라즈베리파이 웹서버 - Django 설치 및 외부접속 설정 (0) | 2020.10.08 |