05주차 ‐ 블루투스 통신 실습 - movie-01/SmartDevice GitHub Wiki
- 무선통신
- 블루투스
- 클래식 블루투스 데이터 송수신
- BLE
- BLE를 이용한 RGB LED 제어 실습
전선 없이 전자기파(라디오파, 마이크로파, 적외선 등)를 이용하여 정보를 주고받는 통신 방식.
- 예시: 라디오, TV 방송, 위성통신, 모바일 통신, Wi-Fi
짧은 거리(수 cm ~ 수십 m)에서 정보를 주고받는 무선통신 기술
- 특징:
- 저전력
- 실내/개인용 기기 간 통신에 최적
- 연결 속도는 빠르지만 전송 거리는 제한적
기술명 | 전송 거리 | 전송 속도 | 주요 용도 | 특징 |
---|---|---|---|---|
Bluetooth | 최대 100m | 최대 3 Mbps 이상 | 무선 이어폰, 웨어러블, 차량 연결 등 | 저전력, 짧은 거리에서 안정적인 연결 |
Wi-Fi | 약 20~50m | 최대 수 Gbps | 인터넷 접속, 데이터 공유 | 고속 전송, 네트워크 기반 연결 |
NFC | 약 10cm 이내 | 424 kbps | 모바일 결제, 인증, 교통카드 등 | 매우 짧은 거리, 빠른 반응, 높은 보안성 |
Zigbee | 약 10~100m | 250 kbps | 스마트홈, IoT 센서 | 저전력, 다기기 네트워크 구성 가능 |
Infrared | 수 m 이내 | 수백 kbps 수준 | 리모컨, 센서 통신 | 직선 통신 필요, 장애물에 민감 |
💡 Tip: 위 기술들은 각각 용도와 환경에 따라 선택되며, 상호 보완적으로 사용되기도 다.
블루투스(Bluetooth)는 단거리 무선 통신 기술이며, 모바일 기기, 컴퓨터, 웨어러블 기기 등에서 데이터를 송수신하는 데 사용된다. 블루투스는 **클래식 블루투스(Classic Bluetooth, BR/EDR)**와 **저전력 블루투스(Bluetooth Low Energy, BLE)**로 구분된다.

클래식 블루투스는 지속적인 데이터 전송이 필요한 장치에서 주로 사용된다. 무선 오디오 장치🎧, 키보드⌨, 마우스🖱 등이 대표적인 예시이다.
- 연결을 지속적으로 유지해야 한다.
- 전력 소비가 상대적으로 크다. 🔋
- 최대 전송 속도는 3Mbps이다.
- A2DP(오디오 전송), HFP(핸즈프리), HID(입력 장치) 등의 프로파일을 지원한다.


#include "BluetoothSerial.h"
BluetoothSerial SerialBT;
void setup() {
Serial.begin(115200);
SerialBT.begin("ESP32-BT-Slave"); // 블루투스 장치 이름 설정
Serial.println("Bluetooth Started! Pair with ESP32-BT-Slave");
}
void loop() {
if (Serial.available()) {
char incoming = Serial.read();
SerialBT.write(incoming); // 시리얼 데이터를 블루투스로 전송
}
if (SerialBT.available()) {
char incoming = SerialBT.read();
Serial.write(incoming); // 블루투스 데이터를 시리얼로 출력
}
}
안드로이드 스마트폰 플레이스토어 앱에서 "Serial Bluetooth Terminal" 다운로드
스마트폰에서 “Serial Bluetooth Terminal”앱 실행후 페어링




- LED 모듈
- S: D4
- VCC: 3.3V
- GND: GND
#include "BluetoothSerial.h"
BluetoothSerial SerialBT;
const int ledPin = 4; // LED가 연결된 핀 번호
void setup() {
Serial.begin(115200);
SerialBT.begin("ESP32-BT-LED"); // 블루투스 장치 이름 설정
Serial.println("Bluetooth Started! Pair with ESP32-BT-LED");
pinMode(ledPin, OUTPUT); // LED 핀을 출력으로 설정
digitalWrite(ledPin, LOW); // 초기 상태를 OFF로 설정
}
void loop() {
if (SerialBT.available()) {
char incoming = SerialBT.read();
Serial.write(incoming); // 수신된 데이터를 시리얼 모니터에 출력
if (incoming == '1') {
digitalWrite(ledPin, HIGH); // '1'을 수신하면 LED ON
Serial.println("LED ON");
} else if (incoming == '0') {
digitalWrite(ledPin, LOW); // '0'을 수신하면 LED OFF
Serial.println("LED OFF");
}
}
}
Serial Bluetooth Terminal앱에 "0" 입력 시 LED 불빛이 꺼지고 "1" 입력 시 불빛이 켜진다.
LED.mp4
클래식 블루투스는 RFCOMM (Radio Frequency Communication) 프로토콜을 사용하여 직렬 포트(Serial Port) 기반으로 데이터를 송수신한다. 이를 활용하면 텍스트, 파일📂, 센서 데이터 등을 쉽게 전송할 수 있다.
BLE는 저전력 소모를 특징으로 하며, IoT(사물 인터넷) 기기, 웨어러블, 센서 등의 장치에서 활용된다.
- 필요할 때만 데이터를 전송하여 배터리 소모를 최소화한다. 🔋
- 낮은 대역폭을 사용하여 센서 데이터 및 알림 전송에 적합하다.
- 최대 전송 속도는 1Mbps이다.
- GATT (Generic Attribute Profile) 구조를 사용하여 데이터 통신이 이루어진다.
BLE를 활용하면 스마트폰📱이나 기타 BLE 지원 기기에서 RGB LED💡를 원격으로 제어할 수 있다. 스마트폰에서 특정 값을 전송하면, BLE 모듈이 이를 수신하고 LED의 색상을 변경한다.
🔹 회로 연결
- RGB LED 모듈
- R 핀 → D4
- G 핀 → D15
- B 핀 → D2
- VCC → 3.3V
- GND → GND
🔹RGB LED 제어 값 입력으로 RGB LED 제어 테스트
#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEServer.h>
// BLE 서버와 특성 객체 포인터 선언
BLEServer* pServer;
BLECharacteristic* pCharacteristic;
void setup() {
Serial.begin(115200); // 시리얼 통신 시작 (디버깅용)
BLEDevice::init("ESP32-RGB-Control"); // BLE 장치 이름 초기화
pServer = BLEDevice::createServer(); // BLE 서버 생성
// BLE 서비스 생성 (UUID: 0x1812는 HID 서비스로 예시 사용)
BLEService *pService = pServer->createService(BLEUUID((uint16_t)0x1812));
// 쓰기 및 알림 속성을 가진 특성 생성 (UUID: 0x2A56)
pCharacteristic = pService->createCharacteristic(
BLEUUID((uint16_t)0x2A56),
BLECharacteristic::PROPERTY_WRITE | BLECharacteristic::PROPERTY_NOTIFY
);
pService->start(); // 서비스 시작
// 광고 시작 (BLE 주변 장치에서 탐색 가능하게 함)
BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
pAdvertising->addServiceUUID(pService->getUUID());
pAdvertising->start();
}
void loop() {
// 클라이언트로부터 값이 수신되었을 때 처리
if (pCharacteristic->getValue().length() > 0) {
std::string rgbValue = pCharacteristic->getValue();
Serial.println(rgbValue.c_str()); // 수신된 RGB 값 출력
}
}
하지만 24줄 코드에서 오류가 발생하는 상황이 나온다.
Arduino에서는 기본적으로 String
클래스(Arduino 전용)를 사용한다.
하지만 BLECharacteristic의 getValue()
함수는 **C++ 표준의 std::string
**을 반환한다.
std::string rgbValue = pCharacteristic->getValue(); // ❌ 오류 발생
✅ 해결 방법
- std::string 대신 String 사용하기 String rgbValue = String(pCharacteristic->getValue().c_str()); // ✅ 안전하게 변환
getValue()로 받은 std::string을 .c_str()로 const char*로 변환한 뒤
String() 생성자로 감싸서 Arduino 전용 String 객체로 변환한다.
잘못된 코드 ❌ | 수정된 코드 ✅ |
---|---|
std::string rgb = pCharacteristic->getValue(); |
String rgb = String(pCharacteristic->getValue().c_str()); |
#include <BLEDevice.h>
#include <BLEServer.h>
#include <BLEUtils.h>
#include <BLE2902.h>
//서비스와 특성에 대한 UUID를 정의
#define SERVICE_UUID "b42238ee-404f-4a11-bd3a-06d6eff0757d"
#define RGB_CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8"
#define NOTYFY_CHARACTERISTIC_UUID "d501d731-f0f9-4121-a7f6-2c0f959f1583"
//RGB LED에 사용될 핀 번호를 정의
#define RED_PIN 4
#define GREEN_PIN 15
#define BLUE_PIN 2
//BLE 관련 객체를 선언
BLEServer *pServer; //BLE 서버 객체
BLEService *pService; // BLE 서비스 객체
BLECharacteristic *pRGBCharacteristic = NULL; //BLE 특성 객체
BLECharacteristic* pCharacteristic = NULL; //BLE 특성 객체
//RGB 값을 저장할 변수들을 초기화
int redValue = 0;
int greenValue = 0;
int blueValue = 0;
//BLE 특성에 대한 콜백 클래스를 정의
class MyCallbacks : public BLECharacteristicCallbacks {
//특성의 값을 읽어와 RGB 값을 파싱하고 LED를 제어
void onWrite(BLECharacteristic *pCharacteristic) {
String value = pCharacteristic->getValue().c_str(); //특성의 값을 문자열로 읽음
// 값이 유효한 경우에만 처리
if (value.length() > 0) {
// RGB 값을 파싱하여 각각의 변수에 저장
int delimiterPos1 = value.indexOf(',');
int delimiterPos2 = value.lastIndexOf(',');
if (delimiterPos1 != -1 && delimiterPos2 != -1 \
&& delimiterPos2 < value.length() - 1) {
redValue = value.substring(0, delimiterPos1).toInt();
greenValue = value.substring(delimiterPos1 + 1, delimiterPos2).toInt();
blueValue = value.substring(delimiterPos2 + 1).toInt();
// RGB 값을 LED의 밝기로 변환하여 제어
analogWrite(RED_PIN, 255 - redValue);
analogWrite(GREEN_PIN, 255 - greenValue);
analogWrite(BLUE_PIN, 255 - blueValue);
}
}
}
};
void setup() {
// BLE 초기화하고 이름을 "RGB LED Control"로 설정
BLEDevice::init("RGB LED Control");
pServer = BLEDevice::createServer();
pService = pServer->createService(SERVICE_UUID);
// RGB 특성 생성 및 설정
pRGBCharacteristic = pService->createCharacteristic(
RGB_CHARACTERISTIC_UUID,
BLECharacteristic::PROPERTY_WRITE
);
pRGBCharacteristic->setCallbacks(new MyCallbacks());
// Notify/Indicate 특성 생성 및 설정
pCharacteristic = pService->createCharacteristic(
NOTYFY_CHARACTERISTIC_UUID,
BLECharacteristic::PROPERTY_NOTIFY |
BLECharacteristic::PROPERTY_INDICATE
);
// Create a BLE Descriptor
pCharacteristic->addDescriptor(new BLE2902());
// 서비스를 서버에 추가
pService->start();
// BLE 광고 시작
BLEAdvertising *pAdvertising = pServer->getAdvertising();
pAdvertising->start();
// 모든 핀을 HIGH로 설정하여 LED를 꺼진 상태로 초기화
digitalWrite(RED_PIN, HIGH);
digitalWrite(GREEN_PIN, HIGH);
digitalWrite(BLUE_PIN, HIGH);
}
void loop() {
// RGB 값을 16진수 형태로 변환하여 Notify
char hexValue[8];
sprintf(hexValue, "#%02X%02X%02X", redValue, greenValue, blueValue);
//Notify 특성의 값을 hexValue로 설정
pCharacteristic->setValue(hexValue);
pCharacteristic->notify(); //Notify를 통해 값을 전달
delay(100); // 알림 간격을 조절할 수 있다.
}
코드를 실행하기 위해서는 UUID 값을 조정해야 실행이 된다.



빨간색은 "255,0,0", 초록색은 "0,255,0,", 파란색은 "0,0,255"


