Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- NAS HDD교체
- OnlineIDE
- nas
- docker
- 3D
- Kotlin
- ci/cd
- 3D프린터 입문
- IoTNetwork
- 3D프린터입문
- Notification
- octoprint
- 3D 프린터 용어
- 네이버클라우드
- linux job
- 코틀린개발환경
- kubernetes
- 3d프린터 초보
- git
- docker container
- gitlab
- 리눅스 파일동기화
- 3D모델링
- github
- 데이터 직렬화 포맷
- Jenkins
- C언어
- 3D프린터
- Token인증방식
- data serialization formats
Archives
- Today
- Total
0과 1을 공부하다.
[Communication] 구형 건축물에서의 스마트홈 구축 프로젝트 - 블루투스 통신 본문
728x90
개요
본 프로젝트의 기획단계에서 기기간의 연결성과 사용자와 상호작용을 위해 서버와 센서간 Bluetooth 통신을 계획했다. 이번 게시물은 스마트홈에 빌드하여 바로 적용하는 코드가 아닌 서버-센서간 통신을 위한 기초 예제이다. 본 예제는 향후 Sensor에서 다루는 내용에 기본적으로 포함되는 예제이므로 반드시 확인하고 넘어가야하는 항목 중 하나이다.
Arduino
가. 환경구성
- 앞서 2-1에서 Arduino IDE를 설치했다면 별도의 환경구성은 필요없다.
- 본 예제에서 사용된 MCU와 센서는 Arduino UNO, HC-06)을 사용하였다.
나. 회로연결
- 블루투스 모듈(HC-06)에 Arduino에서 5V를 인가한다. (5v, GUD 결선)
- 소스코드에서 지정한 RX(수신) 아날로그 포트와 블루투스 모듈의 TX(송신) 포트 결선한다.
- 소스코드에서 지정한 TX(송신) 아날로그 포트와 블루투스 모듈의 RX(수신) 포트 결선한다.
다. 소스코드
#include <SoftwareSerial.h>
// 송/수신 포트지정
int RX=7; // 아두이노 디지털 7번 핀과 BT 모듈 TX 연결
int TX=8; // 아두이노 디지털 8번 핀과 BT 모듈 RX 연결
SoftwareSerial bluetooth(RX, TX);
void setup(){
Serial.begin(9600);
bluetooth.begin(9600);
}
void loop(){
// 데이터 수신
if (bluetooth.available()) // 블루투스 시리얼에서 읽을 수 있는 바이트의 수가 0이 아니면
{
Serial.write(bluetooth.read());
}
// 데이터 송신
if (Serial.available()) // 아두이노 시리얼에서 읽을 수 있는 바이트의 수가 0이 아니면
{
bluetooth.write(Serial.read());
}
}
라. 코드 분석
- 아날로그 송/수신 포트를 지정하고 아두이노의 RX(수신) TX(송신)를 블루투스의 RX(수신) TX(송신)와 크로스 연결(반대로)한다.
// 송/수신 포트지정
int RX=7; // 아두이노 디지털 7번 핀과 BT 모듈 TX 연결
int TX=8; // 아두이노 디지털 8번 핀과 BT 모듈 RX 연결
- 블루투스 객체 생성
SoftwareSerial bluetooth(RX, TX);
- 각 기기의 시리얼 통신을 통해 입/출력된 데이터가 존재한다면 데이터 송신 및 출력
// 데이터 수신
if (bluetooth.available()) {...} // 블루투스 시리얼에서 읽을 수 있는 바이트의 수가 0이 아니면
// 데이터 송신
if (Serial.available()) {...} // 아두이노 시리얼에서 읽을 수 있는 바이트의 수가 0이 아니면
마. Github Link: Github
Raspberry PI
가. 환경 구성
- Raspberry PI 내 Bluetooth 모듈 내장으로 별도의 회로 연결은 필요없다.
- 2-1에서 공개한 쉘스크립트를 실행하면 별도의 라이브러리 설치는 불필요하다.
- 2-1의 쉘스크립트에서 라이브러리를 설치하지 않았다면 아래의 라이브러리를 설치한다.
$ sudo apt-get install bluetooth blueman bluez
$ sudo apt-get install python-bluetooth
$ sudo apt-get install bluez libbluetooth-dev pi-bluetooth
$ pip3 install pybluez
나. 블루투스 스캔/페어링
- sudo 명령을 통해 블루투스 컨트롤(bluetoothctl)을 시작한다.
- 전원을 켜고(power) 블루투스 검색(scan)을 한다.
- 검색된 목록에서 자신이 연결하고자 하는 모듈을 찾는다. (필자는 HC-06 모듈을 찾았다.)
- 찾은 모듈의 MAC주소를 메모장에 잠시 기입한다.
- 찾은 모듈을 연결(pair)한다.
- 연결한 장치에 대한 신뢰(trust) 설정을 한다.
- 코드기입 방법은 아래의 코드를 참고한다.
# 블루투스 컨트롤 시작
$ sudo bluetoothctl
# 블루투스 전원 on
> power on
# 블루투스 검색(스캔)
> scan on
# 블루투스 페어링
> pair Bluetooth_Mac주소 # ex) pair 98:DA:D0:00:56:A2
# 장치 신뢰 설정
> trust Bluetooth_Mac주소 # ex) trust 98:DA:D0:00:56:A2
다. 소스코드
import threading
from bluetooth import *
import sys
socket = BluetoothSocket(RFCOMM)
#socket.connect((sys.argv[1], 1)) # 대상 디바이스의 맥주소를 실행시 인자값으로 받음
mac_add = "98:DA:D0:00:56:A2"
try:
socket.connect((mac_add, 1)) # 대상 디바이스 맥주소 입력
except:
print("Con't Connect Bluetooth Pair.")
socket.close(s)
exit()
print("Bluetooth connected!")
# Arduino to Python Data 수신 함수
def data_receive():
while True:
data = socket.recv(1024)
decode_data = data.decode() # 문자열 형태임
decode_data = decode_data.strip() # 문자열 끝 개행제거
if (decode_data.isdigit()==True):
result = int(decode_data)
else:
result = decode_data
print()
print("receive message :", result)
# Python to Arduino Data 송신 함수
def data_send():
msg = input("send message : ")
socket.send(msg)
# 메세지를 받는 쓰레드 생성
receive_t = threading.Thread(target=data_receive, args=())
receive_t.start()
while True:
data_send()
socket.close()
라. 코드 분석
- bluetooth소켓 생성 및 연결
- bluetooth 소켓을 생성하고 연결한다.
- connect()에 MAC주소를 전달 할 때 실행 인자값으로 전달하거나 직접 입력하거나 본인의 선택에 따라 입력한다.
- try-except를 통해 connect에 대한 예외처리를 한다.
socket = BluetoothSocket(RFCOMM)
socket.connect((sys.argv[1], 1)) # 대상 디바이스의 맥주소를 실행시 인자값으로 받음
socket.connect(("98:DA:D0:00:56:A2", 1)) # 직접 입력
- 데이터 송/수신
- 생성한 소켓에서 데이터를 송/수신한다.
- recv()를 통해 라즈베리로부터 데이터를 수신한다. 인자로 수신할 바이트의 크기를 지정한다.
- send()를 통해 아두이노로 데이터를 송신한다. 송신할 데이터를 인지로 전달한다.
socket.recv(1024)
socket.send("안녕")
- 병렬처리
- 데이터 송/수신을 동시에 진행하려면 병렬처리가 필요하다. 그 이유는 라즈베리파이에서 데이터 송신을 위해 사용자 입력을 대기(wait)하고 있는 상태에서는 다른 코드를 실행하지 않기 때문이다.
- 멀티쓰레드를 통해 데이터 송/수신을 동시적으로 구현한다.
- threading 모듈을 import한다.
- 데이터를 수신받는 함수를 구현하고 쓰레드를 생성(Thread)한다.
- 쓰레드를 시작(start)한다.
import threading
receive_t = threading.Thread(target=data_receive, args=())
receive_t.start()
마. GitHub Link: Github
실행결과
위 아두이노 스케치 파일을 보드에 업로드하고 라즈베리파이에서 Python으로 실행한다.
실행하고 라즈베리파이에서 아두이노로 메세지를 보내면 아두이노의 시리얼 모니터에서 정상적으로 출력함을 확인할 수 있다.
이어서 아두이노 시리얼 모니터에서 메세지를 보내면 라즈베리파이에서 정상적으로 메세지를 출력함을 확인할 수 있다.
참고문헌
[1] arduino
[2] Raspberry PI
- https://blog.naver.com/jihoonine/221877730529
- https://m.blog.naver.com/beaqon/221412580559
- http://theyoonicon.com/raspi-%EB%B8%94%EB%A3%A8%ED%88%AC%EC%8A%A4%EB%A1%9C-led-%EC%A0%9C%EC%96%B4%ED%95%98%EA%B8%B0/
[3] ETC
※ 본 게시글의 정보가 잘못 되었거나 부족한 부분에 대한 피드백을 환영합니다.
※ 본 프로젝트는 오픈소스 프로젝트로 인용 /수정 /사용을 허용합니다.
* CopyRight 2022. Jay Park All rights reserved.
728x90
'Project > Smart Home' 카테고리의 다른 글
[Environment] 구형 건축물에서의 스마트홈 구축 프로젝트 - 개발환경 구성 (0) | 2022.02.02 |
---|---|
[Architecture] 구형 건축물에서의 스마트홈 구축 프로젝트 - 기획 및 설계 (0) | 2022.02.02 |
Comments