05주차 ‐ 블루투스 통신 실습 - gitjs523/SmartDevice2025 GitHub Wiki

1. 근거리 무선 통신(Near Field Wireless Communication)

1-1. 근거리 무선 통신이란?

  • 짧은 거리(수 cm ~ 수 m) 내에서 선 연결 없이 데이터를 송수신하는 기술
  • 특징
    • 전력 소모 낮음
    • 간편한 연결
    • 다양한 디지털 기기와 연결
    • 교통, 티켓, 지불 등 여러 서비스에서 사용 가능
    • 대표적인 예시로 블루투스가 있음

1-2. 블루투스 외에 근거리 무선 통신의 종류

(1) NFC(Near Field Communication)

  • 주파수 대역: 13.56 MHz
  • 통신 거리: 약 4cm(약 1.6인치) ~ 10cm
  • 전송 속도: 최대 424 Kbps
  • 중간 주파수 대역인 13.56MHz를 사용하여 투과성이 우수
  • 터치만으로 연결 가능
  • 통신 거리가 짧아 보안 걱정이 적음
  • 카카오 페이, 삼성 페이, 교통 카드, 티켓 등 이용

(2) Wi-Fi Direct

  • 통신 거리: 200m (Wi-Fi 커버리지 내)
  • 전송 속도: 250 Mbps 이상
  • Wi-Fi 기술을 활용한 P2P통신
    • P2P(Peer to Peer): 컴퓨터끼리의 양방향 파일 전송 시스템(중앙 서버 필요 없음).
  • 스마트폰 간 대용량 파일 전송, 무선 프린팅, 미러링 등에 이용

(3) Zigbee

  • 주파수 대역: 2.4 GHz
  • 통신 거리: 최대 100m
  • 전송 속도: 최대 250 Kbps
  • 전력 소모가 매우 적음
  • 수천 개 노드 연결 가능(Mesh 네트워크 가능)
    • Mesh 네트워크: 네트워크의 각 노드가 다른 여러 노드들과 직접 연결되는 분산형 네트워크 구조
  • 스마트홈, 스마트미터, 공장 자동화 등에 이용 가능

(4) 초광대역(Ultra-Wideband)

  • 정의: 기존의 스펙트럼에 비해 매우 넓은 대역에 걸쳐 낮은 전력으로 대용량의 정보를 전송하는 무선 통신 기술
    • UWB라고도 부름
  • 주파수 대역: 3.1 GHz ~ 10.6 GHz
  • 통신 거리: 수 m ~ 10m 내외
  • 전송속도 : 480Mbps
  • 10cm 이하 위치 인식 가능할 정도의 정확성
  • 디지털 키, 정밀 위치 측위, AR/VR 등에 사용 가능

2. 블루투스(Bluetooth)

2-1.블루투스의 개요와 특징

  • 1994년에 스웨덴의 에릭슨이 최초로 개발한 디지털 통신 기기를 위한 개인 근거리 무선 통신 산업 표준
  • ESP32에서는 클래식 블루투스(Classic Bluetooth)와 BLE(Bluetooth Low Energy) 두 가지 방식 지원
  • 주파수 대역: 2.4 GHz ISM Band
  • 전송 속도: 최대 3 Mbps (Bluetooth 2.0 + EDR 기준)
  • 전송 거리
    • Class 1: 최대 100m
    • Class 2: 최대 10m
    • Class 3: 최대 1m

일반적인 스마트폰에서는 Class 2를 이용한다.

  • 무선 이어폰, 키보드, 스마트워치, 차량 내 통신, 게임기(닌텐도같은 게임기에서도 블루투스 기능 지원하는 경우 있음) 등 사용

2-2. 클래식 블루투스(Classic Bluetooth)와 BLE(Bluetooth Low Energy)의 비교

(1) 클래식 블루투스(Classic Bluetooth)

  • 원래의 블루투스 표준
  • BLE보다 전력 소모가 높음.
  • 데이터 전송 속도 높음.
  • 먼 곳까지 통신 연결 가능.

(2) BLE(Bluetooth Low Energy)

  • 이름 그대로 저전력 블루투스를 의미
  • 저전력 장치 간의 데이터 통신을 위해 사용되는 무선 통신 기술
  • 클래식 블루투스보다 전력 소모 적음.
  • 데이터 전송 속도 낮음.
  • 통신 연결 범위가 짧음.

IoT 시스템에서는 BLE가 주로 사용되며, 센서 데이터 전송, 게이트웨이 연결 등의 역할을 수행.

3. 블루투스 통신 실습

3-1. 클래식 블루투스 데이터 송수신

  • ESP32를 블루투스 장치로 설정하고 스마트폰에 “Serial Bluetooth Terminal” 앱을 설치하여 데이터를 주고받기
  • 회로 연결: 별도의 회로 연결 없이 ESP32 단독 사용

아두이노 IDE에서 제공하는 예제를 사용하든 강의 자료에 있는 코드를 사용하든 같은 결과가 나옴.

사용한 코드 내용

#include "BluetoothSerial.h"

BluetoothSerial SerialBT;

void setup() {
  Serial.begin(115200);
  SerialBT.begin("ESP32-BT-SlaveOJS"); // 블루투스 장치 이름 설정
  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); // 블루투스 데이터를 시리얼로 출력
  }
}
  1. 블루투스 설정에서 ESP32 기기 연결

Screenshot_20250406_220250_Settings

  1. Serial Bluetooth Terminal 앱 이용해 메시지 보내기("Hello ESP32")

Screenshot_20250406_220617_Serial Bluetooth Terminal

  1. 시리얼 모니터에서 메시지 수신

화면 캡처 2025-04-06 220807

  1. 시리얼 모니터에서 휴대폰으로 메시지 보내기("Hi OhJiSung")

화면 캡처 2025-04-06 221551

  1. 휴대폰에서 메시지 수신

Screenshot_20250406_221458_Serial Bluetooth Terminal

3-2. 클래식 블루투스를 이용한 LED 제어

  • Serial Bluetooth Terminal 앱을 이용하여 LED 제어하기

코드 내용

#include "BluetoothSerial.h"

BluetoothSerial SerialBT;

const int ledPin = 22; // 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");
    }
  }
}

실행 결과 영상

20250406_224536.mp4

3-3. BLE를 이용한 RGB LED 제어

BLE 방식으로 ESP32와 스마트폰 간 통신을 통해 RGB LED 색상을 변경해보기

  • RGB LED 모듈 연결

    • R 핀 → D4
    • G 핀 → D15
    • B 핀 → D2
    • VCC → 3.3V
    • GND → GND
  • 코드는 카카오톡으로 제공받은 코드를 이용한다.

코드 내용

#include <BLEDevice.h>
#include <BLEServer.h>
#include <BLEUtils.h>
#include <BLE2902.h>
#define SERVICE_UUID        "4fafc201-1fb5-459e-8fcc-c5c9c331914b"
#define RGB_CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8"
#define NOTYFY_CHARACTERISTIC_UUID "d501d731-f0f9-4121-a7f6-2c0f959f1583"
#define RED_PIN   4
#define GREEN_PIN 15
#define BLUE_PIN  2
BLEServer *pServer; //BLE 서버 객체
BLEService *pService; // BLE 서비스 객체
BLECharacteristic *pRGBCharacteristic = NULL; //BLE 특성 객체
BLECharacteristic* pCharacteristic = NULL; //BLE 특성 객체
int redValue = 0;
int greenValue = 0;
int blueValue = 0;
class MyCallbacks : public BLECharacteristicCallbacks {
  void onWrite(BLECharacteristic *pCharacteristic) {
    String value = pCharacteristic->getValue().c_str(); //특성의 값을 문자열로 읽어옵니다.

    if (value.length() > 0) {
      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();

        analogWrite(RED_PIN, 255 - redValue);
        analogWrite(GREEN_PIN, 255 - greenValue);
        analogWrite(BLUE_PIN, 255 - blueValue);
      }
    }
  }
};

void setup() {
  BLEDevice::init("RGB LED Control");
  pServer = BLEDevice::createServer();
  pService = pServer->createService(SERVICE_UUID);
  
  pRGBCharacteristic = pService->createCharacteristic(
    RGB_CHARACTERISTIC_UUID,
    BLECharacteristic::PROPERTY_WRITE
  );  
  pRGBCharacteristic->setCallbacks(new MyCallbacks());

  pCharacteristic = pService->createCharacteristic(
                      NOTYFY_CHARACTERISTIC_UUID,
                      BLECharacteristic::PROPERTY_NOTIFY |
                      BLECharacteristic::PROPERTY_INDICATE
                    );
  pCharacteristic->addDescriptor(new BLE2902());

  pService->start();

  BLEAdvertising *pAdvertising = pServer->getAdvertising();
  pAdvertising->start();

  digitalWrite(RED_PIN, HIGH);
  digitalWrite(GREEN_PIN, HIGH);
  digitalWrite(BLUE_PIN, HIGH);
}

void loop() {
  char hexValue[8]; 
  sprintf(hexValue, "#%02X%02X%02X", redValue, greenValue, blueValue);
  pCharacteristic->setValue(hexValue); 
  pCharacteristic->notify(); //Notify를 통해 값을 전달합니다.

  delay(100);  // 알림 간격을 조절할 수 있습니다.
}
  1. 빨간색으로 출력해보기 Screenshot_20250406_232723_nRF Connect

20250406_232749

  1. 초록색으로 출력해보기 Screenshot_20250406_232816_nRF Connect

20250406_232825

  1. 파란색으로 출력해보기 Screenshot_20250406_232839_nRF Connect

20250406_232904

  1. 자주색으로 출력해보기 Screenshot_20250406_233019_nRF Connect

20250406_233027

4. 실습 후기

ESP32 보드와 내 스마트폰이 연결 가능하다는 것을 블루투스 덕분에 알게 되었다. 마지막 실습 때 (255,255,255) 값을 넣어 하얀빛을 출력해보려고 시도했는데 실제로 나온 빛은 하얀색보다는 매우 밝은 분홍색으로 보였다.

⚠️ **GitHub.com Fallback** ⚠️