라즈베리파이에서 파이썬 BT/BLE 프로그래밍을 위한 라이브러리 설치와 동작확인하는 과정 정리
Bluetooth 기능을 내장한 라즈베리파이3 B 모델 – 블루투스 제어용 Python 라이브러리 사용법입니다.
1. 블루투스 모듈 설치
파이썬 설치 시 블루투스 모듈이 추가 되게 하기 위해 블루투스 모듈을 먼저 설치합니다.
1
|
$sudo apt-get install bluez libbluetooth-dev pi-bluetooth
|
설치시에 대문자 Y를 누른다.
아래는 실행화면이다.
pi@raspberrypi:~ $ sudo apt-get install bluez libbluetooth-dev pi-bluetooth
Reading package lists... Done
Building dependency tree
Reading state information... Done
bluez is already the newest version.
bluez set to manually installed.
The following NEW packages will be installed:
libbluetooth-dev
The following packages will be upgraded:
pi-bluetooth
1 upgraded, 1 newly installed, 0 to remove and 321 not upgraded.
Need to get 151 kB/155 kB of archives.
After this operation, 426 kB of additional disk space will be used.
Do you want to continue? [Y/n] Y
Get:1 http://archive.raspberrypi.org/debian/ jessie/main libbluetooth-dev armhf 5.23-2+rpi2 [151 kB]
Fetched 151 kB in 1s (109 kB/s)
Reading changelogs... Done
(Reading database ... 126241 files and directories currently installed.)
Preparing to unpack .../pi-bluetooth_0.1.3_armhf.deb ...
Unpacking pi-bluetooth (0.1.3) over (0.1.1) ...
Selecting previously unselected package libbluetooth-dev.
Preparing to unpack .../libbluetooth-dev_5.23-2+rpi2_armhf.deb ...
Unpacking libbluetooth-dev (5.23-2+rpi2) ...
Setting up pi-bluetooth (0.1.3) ...
Setting up libbluetooth-dev (5.23-2+rpi2) ...
pi@raspberrypi:~ $
2. Python 설치
파이썬 관련 유틸리티가 설치가 된 상태에서 파이썬을 재빌드해서 설치해야 이후에 블루투스 관련 모듈을 사용할 수 있습니다.
1
2
3
4
5
6
7
8
|
$mkdir temp
$cd temp
$wget https://www.python.org/ftp/python/3.6.5/Python-3.6.5.tgz
$tar -xvf Python-3.6.5.tgz
$cd Python-3.6.5
$./configure
$sudo make && sudo make install
|
파이썬 소스 빌드 과정은 30~40분 정도 소요된다.
3. 시리얼 포트 등록
1
|
$sudo sdptool add SP
|
4. 블루투스 서비스 실행 옵션 수정
1
2
3
4
5
|
$sudo nano /lib/systemd/system/bluetooth.service
$ExecStart=/usr/lib/bluetooth/bluetoothd -C 로 수정
$sudo systemctl daemon-reload - 설정 수정사항 재로딩
$sudo systemctl restart bluetooth - 블루투스 서비스 재실행
$sudo systemctl enable bluetooth - 재부팅 시 서비스 자동 등록
|
3번과 4번 명령을 실행한 결과 창을 아래에 표시한다.
1
2
3
4
5
6
7
8
9
10
11
12
|
pi@raspberrypi:~ $
pi@raspberrypi:~ $ sudo sdptool add SP
pi@raspberrypi:~ $
pi@raspberrypi:~ $
pi@raspberrypi:~ $ sudo nano /lib/systemd/system/bluetooth.service
pi@raspberrypi:~ $ sudo systemctl daemon-reload
pi@raspberrypi:~ $ sudo systemctl restart bluetooth
pi@raspberrypi:~ $ sudo systemctl enable bluetooth
Synchronizing state of bluetooth.service with SysV service script with /lib/systemd/systemd-sysv-install.
Executing: /lib/systemd/systemd-sysv-install enable bluetooth
pi@raspberrypi:~ $
|
5. 장치 내 블루투스 Discoverable 상태로 변경
1
|
$sudo hciconfig hci0 piscan
|
이후 스마트폰에서 블루투스를 선택해 라즈베리파이가 검색되는지 확인합니다.
이렇게 하고 스마트 블루투스를 열어 raspberrypi 라고 떠서 등록한 화면을 올린다. 이미지 맨 위에 raspberrypi 가 보인다.
6. pybluez 모듈 설치
BT/BLE 프로그래밍을 위해 PIP를 이용해 pybluez와 pybleno를 설치합니다.
1
|
$sudo pip3 install pybluez pybleno
|
실행 화면입니다. 친절하게 pip 업데이트 하라고 알려줘서 업데이트까지 했습니다. ^^
1
2
3
4
5
6
7
8
9
10
11
12
|
pi@raspberrypi:~ $ sudo pip3 install pybluez pybleno
Collecting pybluez
Downloading https://www.piwheels.org/simple/pybluez/PyBluez-0.22-cp36-cp36m-linux_armv7l.whl (113kB)
100% |████████████████████████████████| 122kB 161kB/s
Collecting pybleno
Downloading https://www.piwheels.org/simple/pybleno/pybleno-0.10-py3-none-any.whl
Installing collected packages: pybluez, pybleno
Successfully installed pybleno-0.10 pybluez-0.22
You are using pip version 9.0.3, however version 19.1.1 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.
pi@raspberrypi:~ $
|
위 노란 명령어를 사용하여 pip 업데이트 한 화면입니다. ㅎㅎ
1
2
3
4
5
6
7
8
|
pi@raspberrypi:~ $ pip install --upgrade pip
Collecting pip
Downloading https://files.pythonhosted.org/packages/5c/e0/be401c003291b56efc55aeba6a80ab790d3d4cece2778288d65323009420/pip-19.1.1-py2.py3-none-any.whl (1.4MB)
100% |████████████████████████████████| 1.4MB 191kB/s
Installing collected packages: pip
Successfully installed pip-19.1.1
pi@raspberrypi:~ $
|
7. 확인
bluetoothctl – 블루투스 쉘로 접속해서 주변 BT 장치들을 스캔해 봅니다.
1
2
3
4
5
6
7
8
9
10
11
|
$sudo bluetoothctl
[bluetooth] scan on
......
Discovery started
[CHG] Controller B8:27:EB:11:19:07 Discovering: yes
[NEW] Device 00:07:79:0C:90:6F 00-07-79-0C-90-6F
[NEW] Device 98:D3:31:FC:3B:E7 iot_test
[NEW] Device C4:73:1E:96:61:75 C4-73-1E-96-61-75
[bluetooth] scan off
|
위 명령어를 사용해 라즈베리파이에서 접속하여 실행한 화면입니다. 아주 기가 막히게 동작하는 모습을 확인할 수 있습니다.
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
|
pi@raspberrypi:~ $ sudo bluetoothctl
[NEW] Controller B8:27:EB:06:B7:03 raspberrypi [default]
[NEW] Device 94:8B:C1:4A:42:57 Galaxy S8
[bluetooth]# scan on
Discovery started
[CHG] Controller B8:27:EB:06:B7:03 Discovering: yes
[NEW] Device C2:01:19:00:02:7D MiniBeacon_19437
[NEW] Device FD:CB:70:A9:F4:9B Plutocon
[CHG] Device C2:01:19:00:02:7D RSSI: -51
[CHG] Device C2:01:19:00:02:7D RSSI: -62
[CHG] Device C2:01:19:00:02:7D RSSI: -52
[bluetooth]# scan on
Failed to start discovery: org.bluez.Error.InProgress
[bluetooth]# scan off
[CHG] Device FD:CB:70:A9:F4:9B RSSI is nil
[CHG] Device C2:01:19:00:02:7D TxPower is nil
[CHG] Device C2:01:19:00:02:7D RSSI is nil
Discovery stopped
[CHG] Controller B8:27:EB:06:B7:03 Discovering: no
[bluetooth]# scan on
Discovery started
[CHG] Controller B8:27:EB:06:B7:03 Discovering: yes
[CHG] Device C2:01:19:00:02:7D RSSI: -52
[CHG] Device C2:01:19:00:02:7D TxPower: 0
[CHG] Device FD:CB:70:A9:F4:9B RSSI: -50
[CHG] Device C2:01:19:00:02:7D RSSI: -64
[bluetooth]#
|
블루투스 쉘에서 빠져나올 때는 quit 명령어, 혹은 ctrl-z로 나옵니다. quit 하세요.
주변에 내가 설정해둔 BT 기기가 있다면 그 기기의 6 byte MAC address 가 필요합니다. 이제 이 기기에 연결을 해보겠습니다.
1
2
3
4
5
6
7
8
9
10
11
|
[bluetooth] agent NoInputNoOutput
......
[bluetooth] pair xx:xx:xx:xx:xx:xx
......
==> PIN 코드 입력
......
[bluetooth] connect xx:xx:xx:xx:xx:xx
......
[bluetooth] disconnect xx:xx:xx:xx:xx:xx
[bluetooth] quit
|
일부 BT 기기에 연결할 때 PIN 코드 입력 메시지가 뜨지 않는 문제가 발생하곤 합니다. 그런 기기들은 Python 코드로 접속할 때도 “연결 요청이 거부되었습니다” 에러 메시지 뱉으면서 접속이 안됩니다.
그런 경우 bluetoothctl 쉘에서 agent NoInputNoOutput 명령어 실행해주고 pairing, connection 한번 해주면 됩니다.
8. Python 코드
라즈베리파이가 Master 역할을 해서 주변 센서장치를 탐색하고 연결할 때는 아래 코드를 사용합니다.
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
|
from bluetooth import *
#######################################################
# Scan
#######################################################
target_name = "iot_test" # target device name
target_address = None
port = 1 # RFCOMM port
nearby_devices = discover_devices()
# scanning for target device
for bdaddr in nearby_devices:
print(lookup_name( bdaddr ))
if target_name == lookup_name( bdaddr ):
target_address = bdaddr
break
if target_address is not None:
print('device found. target address %s' % target_address)
else:
print('could not find target bluetooth device nearby')
#######################################################
# Connect
#######################################################
# establishing a bluetooth connection
try:
sock=BluetoothSocket( RFCOMM )
sock.connect((target_address, port))
while True:
try:
recv_data = sock.recv(1024)
print(recv_data)
sock.send(recv_data)
except KeyboardInterrupt:
print("disconnected")
sock.close()
print("all done")
except btcommon.BluetoothError as err:
print('An error occurred : %s ' % err)
pass
|
센서 장치가 데이터를 보내주면 받은 데이터를 그대로 다시 전송해주는 echo 예제입니다. 크게 scan 파트와 connection 파트로 나누어져 있으며, 코드 자체는 어렵지 않으니 응용해서 사용하세요.
다음 예제는 라즈베리파이가 센서장치처럼 slave 역할을 하는 코드입니다. 핸드폰에 앱을 만들어서 연결한 뒤, 데이터를 보내주면 받은 데이터를 그대로 다시 전송해주는 echo 예제입니다.
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
|
from bluetooth import *
def receiveMsg():
uuid = "94f39d29-7d6d-437d-973b-fba39e49d4ee"
# RFCOMM 포트를 통해 데이터 통신을 하기 위한 준비
server_sock=BluetoothSocket( RFCOMM )
server_sock.bind(('',PORT_ANY))
server_sock.listen(1)
port = server_sock.getsockname()[1]
# 블루투스 서비스를 Advertise
advertise_service( server_sock, "BtChat",
service_id = uuid,
service_classes = [ uuid, SERIAL_PORT_CLASS ],
profiles = [ SERIAL_PORT_PROFILE ] )
print("Waiting for connection : channel %d" % port)
# 클라이언트가 연결될 때까지 대기
client_sock, client_info = server_sock.accept()
print('accepted')
while True:
print("Accepted connection from ", client_info)
try:
# 들어온 데이터를 역순으로 뒤집어 전달
data = client_sock.recv(1024)
if len(data) == 0: break
print("received [%s]" % data)
print("send [%s]" % data[::-1])
client_sock.send(data[::-1])
except IOError:
print("disconnected")
client_sock.close()
server_sock.close()
print("all done")
break
except KeyboardInterrupt:
print("disconnected")
client_sock.close()
server_sock.close()
print("all done")
break
receiveMsg()
|
*본 문서는 다음 링크를 참조하였습니다.
http://www.hardcopyworld.com/ngine/aduino/index.php/archives/3126
참고자료
- Bluetooth programming in Python 참고자료 링크
- BT BETWEEN RASPBERRY PI AND ARDUINO
- Bluetooth shell commands
이미지 출처: 글도 참고 https://www.instructables.com/id/Control-Bluetooth-LE-Devices-From-A-Raspberry-Pi/
'개발자 > Raspberry Pi3' 카테고리의 다른 글
RASPBERRY PI 3 B+ 블루투스 스캐너 설정 (0) | 2019.08.05 |
---|---|
라즈베리파이를 사용할 때 알아야 할 것들. (0) | 2019.08.05 |
시리얼 통신을 지원하는 PySerial 설치하기 (0) | 2019.07.03 |
라즈베리파이 화면 꺼짐 중지, Disable Screen Saver In Raspberrypi (0) | 2019.05.17 |
라즈베리파이 LCD 터치스크린 케이스 White(흰색) / 100-3894 (0) | 2019.05.14 |
라즈베리파이 카메라에 대한 상세한 자료 정리 [링크] (0) | 2019.05.10 |
Installing LCD 7 (B) to Raspberry Pi 3 터치스크린 LCD 설치 (0) | 2019.05.10 |
라즈베리 파이 ssh 접속 과 Putty 사용법 (0) | 2019.01.22 |
더욱 좋은 정보를 제공하겠습니다.~ ^^