ESP32

ESP32 BLE를 사용하여 LED 제어하기

지구빵집 2024. 4. 1. 07:48
반응형

 

 

 

 

목차

  1. 소개
  2. ESP32 및 BLE 이해
  3. BLE와 클래식 블루투스 비교
  4. 개발 환경 설정
  5. BLE 프로젝트를 통해 ESP32를 사용하여 LED 제어하기:
  6. 실습 데모

 

소개 ESP32 BLE(Bluetooth 저에너지)를 사용한 LED 제어 - 빠르게 진화하는 사물 인터넷(IoT) 및 임베디드 시스템 환경에서 ESP32 마이크로컨트롤러는 초석 기술로 부상하고 있습니다. 다목적성과 고급 기능으로 유명한 이 컨트롤러는 수많은 애플리케이션에서 광범위하게 사용되고 있습니다. 다양한 기능 중 눈에 띄는 것은 저전력 블루투스(BLE) 연결입니다. BLE는 에너지 효율성과 사용 편의성을 강조하는 무선 통신의 패러다임 전환을 나타냅니다. 이 문서에서는 이 기술의 실제 적용 사례인 ESP32 BLE(Bluetooth 저에너지)를 사용한 LED 제어에 대해 자세히 설명합니다.

 

이 프로젝트는 최신 IoT 솔루션의 두 축인 하드웨어 상호 작용과 무선 통신의 융합을 잘 보여줍니다. 한편으로 ESP32는 강력한 처리 능력과 Wi-Fi 및 BLE를 비롯한 다양한 기능을 제공합니다. 다른 한편으로는 저전력 소비와 소비자 가전제품에서 폭넓게 수용되는 블루투스 저에너지로 IoT 애플리케이션에 이상적인 선택이 될 수 있습니다.

 

LED 제어는 간단해 보이지만 무선 명령을 통해 물리적 장치와 상호 작용하는 IoT의 본질을 담고 있습니다. 이 프로젝트는 단순한 기술 연습이 아니라 ESP32와 BLE를 결합하여 실현할 수 있는 가능성을 살펴볼 수 있는 창구 역할을 합니다. 애호가와 전문가 모두가 IoT와 스마트 디바이스 통합의 방대한 잠재력을 탐구할 수 있는 디딤돌입니다. 

 

ESP32 및 BLE 이해 ESP32는 특히 사물 인터넷(IoT) 영역에서 임베디드 시스템에 접근하는 방식에 혁신을 가져온 정교하면서도 비용 효율적인 시스템 온 칩(SoC)입니다. ESP32는 최대 240MHz로 실행할 수 있는 듀얼 코어 프로세서와 최대 520KB의 SRAM 및 최대 16MB의 플래시 메모리 등 상당한 메모리 할당량을 갖춘 효율성과 다용도성을 위해 설계되었습니다. 따라서 복잡한 작업을 처리할 수 있을 만큼 강력하면서도 배터리로 작동하는 디바이스에는 효율적입니다.  

 

ESP32의 가장 주목할 만한 기능 중 하나는 무선 통신 기능입니다. 이 제품은 근거리 통신을 위해 설계된 기술인 저전력 블루투스(BLE)를 포함하여 Wi-Fi와 블루투스를 기본적으로 지원합니다. Bluetooth 저에너지는 전력을 절약하는 Bluetooth의 변형으로, 에너지 효율이 가장 중요한 시나리오에 이상적입니다. 연속적인 고속 데이터 스트리밍에 최적화된 기존 Bluetooth와 달리 BLE는 작은 데이터 패킷을 간헐적으로 전송하는 데 적합합니다. 

 

ESP32에 BLE를 통합하면 스마트폰부터 기타 IoT 디바이스까지 다양한 디바이스와 원활하게 상호 작용할 수 있습니다. 이러한 상호 작용은 지속적인 데이터 전송이 불필요하고 전력 절약이 중요한 시나리오에서 매우 중요합니다. Bluetooth 저에너지는 연결이 시작될 때까지 절전 모드를 유지하여 기존 Bluetooth에 비해 전력 소비를 크게 줄임으로써 이러한 효율성을 달성합니다.

 

BLE의 아키텍처는 일반 속성 프로필(GATT)과 일반 액세스 프로필(GAP)이라는 두 가지 핵심 개념을 중심으로 구성됩니다. GATT는 데이터가 구조화되고 디바이스 간에 통신되는 방식을 다루며, GAP는 디바이스 검색 및 연결을 관리합니다. ESP32의 맥락에서 이는 애플리케이션의 요구 사항에 따라 데이터의 게시자(서버) 및 구독자(클라이언트) 역할을 모두 수행할 수 있음을 의미합니다.

 

요약하면, ESP32는 BLE를 통합하여 IoT 분야에서 활용도를 높일 뿐만 아니라 에너지 효율적인 무선 임베디드 시스템을 개발하려는 개발자에게 선호되는 선택입니다. LED 제어와 같은 간단한 프로젝트부터 보다 복잡한 IoT 애플리케이션까지, ESP32의 BLE 기능은 무선 통신 영역에서 가능성의 세계를 열어줍니다. 

 

BLE와 클래식 블루투스 비교

 

측면 블루투스 저에너지(BLE) 클래식 블루투스  

 

항목 BLE 클래식 블루투스
주요 용도  작은 데이터 패킷의 짧고 간헐적인 전송을 위해 설계되었습니다.  데이터 처리량이 높은 지속적인 무선 통신에 적합합니다. 
전력 소비  전력 소비가 현저히 낮아 배터리로 작동하는 디바이스에 이상적입니다.  지속적인 연결과 더 높은 데이터 속도로 인해 전력 소비가 더 높습니다. 
데이터 전송 속도  더 낮은 데이터 전송 속도(최신 버전에서 최대 2Mbps).  더 높은 데이터 전송 속도(Bluetooth 2.0+EDR에서 최대 3Mbps). 
연결 모델  주기적인 통신에 적합한 비동기 연결 없는(ACL) 모델.  지속적인 데이터 스트리밍을 위한 동기 연결 중심 모델.
지연 시간  짧은 지연 시간(수 밀리초)으로 빠르고 주기적인 데이터 전송에 유리합니다.  BLE에 비해 지연 시간이 길지만 오디오 스트리밍과 같은 사용 사례에 적합합니다. 
복잡성 및 비용  더 간단한 변조 방식으로 복잡성과 비용이 낮습니다.  더 복잡한 변조 방식으로 일반적으로 구현 비용이 더 비쌉니다. 
범위 클래식  블루투스와 비슷한 범위, 일반적으로 최대 100미터.  최적의 조건에서 최대 100미터까지 비슷한 범위. 
적용 예 IoT 디바이스, 건강 모니터, 비콘 및 소형 센서에 이상적입니다.  오디오 스트리밍, 파일 전송 및 핸즈프리 통화에 가장 적합합니다. 
버전 도입  블루투스 4.0과 함께 도입.  기존 블루투스 사양의 일부.  
사용 사례 빈도 일정한 간격으로 데이터를 업데이트해야 하는 애플리케이션에 적합합니다.  중단 없는 지속적인 데이터 흐름이 필요한 애플리케이션에 더 적합합니다.

 

 

개발 환경 설정


소프트웨어 설정


아두이노 IDE: Arduino IDE(통합 개발 환경)는 단순성과 광범위한 지원 커뮤니티로 인해 ESP32 개발에 널리 사용됩니다. 공식 Arduino 웹사이트에서 다운로드하여 설치하세요.

Arduino IDE의 ESP32 보드 패키지: Arduino IDE에 ESP32 보드를 추가합니다. IDE의 환경 설정에 다음 ESP32 보드 관리자 URL을 포함하면 됩니다.

 

https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json

 

 

 

그런 다음 아두이노 IDE의 보드 관리자를 사용하여 ESP32 패키지를 설치하세요. 이렇게 하려면 '도구'를 클릭한 다음 '보드' 위로 마우스를 가져간 다음 하위 메뉴에서 '보드 관리자...'를 선택합니다.

 

 

 

보드 관리자 창의 검색창에 'esp32'를 입력합니다. ESP32 패키지가 나열됩니다. 클릭하여 설치하기만 하면 됩니다. 제 경우에는 이미 설치되어 있습니다.

 

 

 

 

필요한 라이브러리 설치


ESP32용 BLE 라이브러리는 Arduino IDE를 사용하는 ESP32의 BLE 프로젝트에 필수적입니다. 아두이노 IDE의 라이브러리 관리자를 통해 설치할 수 있습니다.

ESP32 BLE(Bluetooth 저에너지) 라이브러리를 설치하려면 먼저 아두이노 IDE에서 '스케치'를 클릭합니다. 그런 다음 드롭다운 메뉴에서 '라이브러리 포함'을 선택하고 마지막으로 '라이브러리 관리...'를 선택합니다.

 

 

 

 

라이브러리 관리자 창에서 검색창에 'esp32 ble arduino'를 입력합니다. 닐 콜반의 'ESP32 BLE 아두이노'가 표시됩니다. 이를 선택하고 설치를 클릭하기만 하면 됩니다.

 

 

 

esp32 ble 아두이노 라이브러리가 성공적으로 설치되었습니다.

 

 

 

IDE 구성


Arduino IDE에서 적절한 ESP32 보드를 선택하려면 먼저 '도구'를 클릭한 다음 '보드' 위로 마우스를 가져간 다음 하위 메뉴에서 'ESP32 개발 모듈'을 선택합니다.

 

 

 

이제 올바른 포트를 선택하세요.

 

 

 

이제 개발 환경은 esp32 BLE(Bluetooth 저에너지) 프로젝트를 만드는 데 사용할 준비가 되었습니다.

 

 

BLE 프로젝트를 통해 ESP32를 사용하여 LED 제어하기:


필요한 구성 요소

 

  • ESP32 개발 보드: 프로젝트의 핵심으로, BLE 통신이 가능합니다.
  • LED: 출력 장치로 사용되는 표준 발광 다이오드입니다.
  • 저항기: 330옴 저항으로 LED로 흐르는 전류를 제한하고 소손을 방지합니다.
  • 브레드보드: 납땜 없이 연결할 수 있는 브레드보드입니다.
  • 점퍼 와이어: 브레드보드에서 구성 요소를 서로 연결하기 위한 전선입니다.

 

ESP32 BLE로 LED 제어하기 회로도:

 

 

 

 

 

BLE(Bluetooth 저에너지)를 통해 LED를 제어하는 데 사용되는 ESP32 마이크로컨트롤러가 포함된 회로도. ESP32는 듀얼 코어 프로세서와 내장 Wi-Fi 및 BLE 기능으로 인해 IoT 프로젝트에 널리 사용되는 마이크로컨트롤러입니다.

이 회로에는 4개의 LED가 있으며, 각 LED는 ESP32의 특정 GPIO(범용 입력/출력) 핀에 연결됩니다. 사용되는 GPIO 핀은 27, 26, 25, 33번입니다. 각 LED는 해당 GPIO 핀에 저항과 직렬로 연결됩니다. 저항은 LED가 소손되는 것을 방지하기 위해 LED에 흐르는 전류를 제한하는 역할을 합니다. 각 LED의 다른 쪽 끝(일반적으로 더 짧은 다리로 표시된 음극)은 ESP32의 공통 접지(GND)에 연결됩니다.

GPIO 핀은 ESP32에서 실행되는 소프트웨어로 제어할 수 있는 디지털 출력 역할을 합니다. GPIO 핀이 높은 상태로 설정되면 작동 전압(ESP32의 경우 일반적으로 3.3V)이 출력되어 저항을 통해 전류가 흐르고 LED에 불이 켜집니다. 핀이 낮은 상태로 설정되면 전류가 흐르지 않고 LED가 꺼집니다.

ESP32는 BLE를 사용하여 스마트폰과 같은 다른 BLE 지원 장치와 통신할 수 있습니다. 사용자는 스마트폰 앱에서 ESP32로 명령을 전송하여 GPIO 핀의 상태를 제어할 수 있습니다. 이를 통해 LED를 무선으로 제어할 수 있어 표시등, 알림 또는 시각적 출력이 필요한 대형 시스템의 일부로 사용할 수 있습니다.

이 회로는 ESP32를 통해 전원이 공급되며, 다이어그램의 USB 포트에 표시된 것처럼 USB를 통해 전원에 연결될 가능성이 높습니다. 다이어그램의 색상은 일반적으로 서로 다른 연결을 구분하고 회로를 쉽게 추적할 수 있는 방법을 제공하기 위해 사용됩니다. 검은색은 일반적으로 접지 연결용이며 다른 색은 각각의 저항과 LED가 있는 GPIO 핀에 대한 연결을 나타냅니다.

요약하면, 이 회로도는 LED가 GPIO 핀으로 개별적으로 제어되고 BLE를 통해 원격으로 작동할 수 있는 ESP32 마이크로 컨트롤러를 사용한 기본 LED 제어 설정에 대해 설명합니다.

 

 

esp32 BLE용 안드로이드 스튜디오 애플리케이션

 

 

 

제가 디자인한 이 안드로이드 애플리케이션은 안드로이드 스튜디오에서 ESP32 BLE(블루투스 저에너지) 기술을 통해 LED를 무선으로 제어하기 위한 전용 인터페이스 역할을 합니다. 직관적인 레이아웃에 토글 버튼이 있어 LED를 쉽게 켜고 끌 수 있으며, 사용자 친화적인 컨트롤과 BLE 통신의 고급 기능이 원활하게 통합되어 있습니다. 이 애플리케이션은 홈 오토메이션에 관심이 있는 사람, 전자공학 분야의 애호가, 디지털 인터페이스와 물리적 하드웨어 간의 실질적인 상호작용을 시연하고자 하는 기술 분야의 교육자를 위해 제작되었습니다.

ESP32 BLE 애플리케이션 다운로드: project testing download the Android application 

 

 

ESP32 BLE 프로그래밍을 사용하여 LED 제어하기:

 

 

#include <BLEDevice.h>
#include <BLEServer.h>
#include <BLEUtils.h>
#include <BLE2902.h>
#include <BLEClient.h>
BLEClient* pClient;

BLEServer* pServer;
BLECharacteristic* pCharacteristic;
BLECharacteristic* pReceiveCharacteristic;
bool deviceConnected = false;
bool oldDeviceConnected = false;

const int ledPin1 = 27;
const int ledPin2 = 26;
const int ledPin3 = 25;
const int ledPin4 = 33;

bool led1State = false; // State of LED 1
bool led2State = false; // State of LED 2
bool led3State = false; // State of LED 2
bool led4State = false; // State of LED 2

class MyCallbacks: public BLECharacteristicCallbacks {
    void onWrite(BLECharacteristic *pCharacteristic) {
      std::string value = pCharacteristic->getValue();

   if (value.length() > 0) {
            if (value == "199") {
                led1State = true;
                Serial.println("LED 1 is ON");
                digitalWrite(ledPin1, HIGH);
            } else if (value == "222") {
                led1State = false;
                Serial.println("LED 1 is OFF");
                digitalWrite(ledPin1, LOW);
            } else if (value == "333") {
                led2State = true;
                Serial.println("LED 2 is ON");
                digitalWrite(ledPin2, HIGH);
            } else if (value == "444") {
                led2State = false;
                Serial.println("LED 2 is OFF");
                digitalWrite(ledPin2, LOW);
            } else if (value == "555") {
                led3State = true;
                Serial.println("LED 3 is ON");
                digitalWrite(ledPin3, HIGH);
            } else if (value == "666") {
                led3State = false;
                Serial.println("LED 3 is OFF");
                digitalWrite(ledPin3, LOW);
            } else if (value == "777") {
                led4State = true;
                Serial.println("LED 4 is ON");
                digitalWrite(ledPin4, HIGH);
            } else if (value == "888") {
                led4State = false;
                Serial.println("LED 4 is OFF");
                digitalWrite(ledPin4, LOW);
            }
        }
    }
};

class MyServerCallbacks: public BLEServerCallbacks {
    void onConnect(BLEServer* pServer) {
      deviceConnected = true;
      BLEDevice::startAdvertising();
    };

    void onDisconnect(BLEServer* pServer) {
      deviceConnected = false;
    }
};

void setup() {
  Serial.begin(9600);
  Serial.println("Connect to MyESP32");
  BLEDevice::init("MyESP32");
  pServer = BLEDevice::createServer();
  pServer->setCallbacks(new MyServerCallbacks());
  
  pinMode(ledPin1, OUTPUT);
  pinMode(ledPin2, OUTPUT);
  pinMode(ledPin3, OUTPUT);
  pinMode(ledPin4, OUTPUT);

  BLEService *pService = pServer->createService("0000180d-0000-1000-8000-00805f9b34fb");
  pCharacteristic = pService->createCharacteristic(
      "00002a37-0000-1000-8000-00805f9b34fb",
      BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_WRITE // Added write property
  );

  pCharacteristic->addDescriptor(new BLE2902());
  pCharacteristic->setCallbacks(new MyCallbacks());

  pService->start();
  BLEAdvertising *pAdvertising = pServer->getAdvertising();
  pAdvertising->start();
  // Initialize BLE client for central role
  pClient = BLEDevice::createClient();
}

void loop() {
  if (deviceConnected) {
    
    String ledStates = String(led1State) + "," + String(led2State) + "," + String(led3State) + "," + String(led4State);

    pCharacteristic->setValue(ledStates.c_str());
    pCharacteristic->notify();

    // Handle LED control commands from the central device
   
    delay(1000); // Adjust the update interval as needed
  }

  // Disconnecting
  if (!deviceConnected && oldDeviceConnected) {
    delay(500); // Give the Bluetooth stack the chance to get things ready
    pServer->startAdvertising(); // Restart advertising
    Serial.println("Start advertising");
    oldDeviceConnected = deviceConnected;
  }
  // Connecting
  if (deviceConnected && !oldDeviceConnected) {
    // Do stuff here on connecting
    oldDeviceConnected = deviceConnected;
  }
}

 

 

코드 설명:

 

#include <BLEDevice.h>
#include <BLEServer.h>
#include <BLEUtils.h>
#include <BLE2902.h>
#include <BLEClient.h>

 

 

 

#include <BLEDevice.h>: 이 헤더 파일은 전체 BLE 디바이스 기능을 캡슐화하는 BLEDevice 클래스를 사용하기 위해 포함됩니다. 이 파일은 ESP32에서 BLE 스택을 초기화하고, 이름을 사용하여 장치를 설정하고, BLE 장치의 상태(예: 검색 가능 여부, 연결 가능 여부 등)를 관리하는 역할을 담당합니다.

#include <BLEServer.h>: 여기에는 ESP32에서 BLE 서버를 만들고 관리하는 데 필요한 정의가 포함되어 있습니다. BLE 서버는 다른 장치에 데이터를 제공하는 장치입니다. BLE 서버를 생성하면 다른 BLE 장치가 ESP32에 연결하고 상호 작용할 수 있습니다.

#include <BLEUtils.h>: 이 파일에는 ESP32에서 BLE로 작업할 때 유용한 유틸리티 함수 및 정의가 포함되어 있습니다. 여기에는 BLE 주소, 상태 코드 및 개발에 도움이 될 수 있는 기타 유용한 정보를 인쇄하는 등 디버깅을 위한 도구가 포함될 수 있습니다.

#include <BLE2902.h>: 여기에는 클라이언트 구성에 일반적으로 사용되는 BLE2902 디스크립터의 정의가 포함됩니다. 이 디스크립터는 특성에 첨부되어 BLE 클라이언트가 특성 값 변경에 대한 알림 또는 표시를 구독할 수 있도록 합니다.

#include <BLEClient.h>: BLE 클라이언트를 만드는 데 필요한 클래스와 함수를 제공합니다. BLE 클라이언트는 BLE 서버를 검색하고, 연결하고, 상호 작용하는 디바이스입니다. 이 라이브러리를 사용하면 ESP32는 서비스를 제공하는 다른 BLE 장치에 연결하고, 읽기 및 쓰기 기능을 수행하고, 알림을 구독할 수 있습니다.

 

 

BLEClient* pClient;
BLEServer* pServer;
BLECharacteristic* pCharacteristic;
BLECharacteristic* pReceiveCharacteristic;
bool deviceConnected = false;
bool oldDeviceConnected = false;

const int ledPin1 = 27;
const int ledPin2 = 26;
const int ledPin3 = 25;
const int ledPin4 = 33;

bool led1State = false; // State of LED 1
bool led2State = false; // State of LED 2
bool led3State = false; // State of LED 2
bool led4State = false; // State of LED 2

 

 

 

BLEClient* pClient; ESP32가 다른 BLE 서버에 연결하는 클라이언트 역할을 하는 경우 사용되는 BLEClient 객체에 대한 포인터를 생성합니다. 그러나 나머지 코드의 컨텍스트에서는 ESP32가 서버로 구성되어 있으므로 이 포인터는 활용되지 않습니다.

BLEServer* pServer; BLEServer 객체에 대한 포인터를 선언합니다. 이는 ESP32에서 BLE(Bluetooth 저에너지) 서버를 인스턴스화하고 관리하는 데 사용되어 다른 BLE 클라이언트(예: 스마트폰 앱)가 연결하고 통신할 수 있도록 합니다.

BLECharacteristic* pCharacteristic;  객체에 대한 포인터를 선언합니다. BLE의 특성은 서버와 클라이언트가 통신하는 데이터 포인트입니다. 이 특정 특성은 ESP32에서 연결된 클라이언트로 데이터를 전송하는 데 사용될 가능성이 높습니다.

 

 

또한 클라이언트에서 데이터를 수신하기 위해 별도의 특성을 사용할 계획이 있을 수 있음을 시사하는 BLECharacteristic에 대한 포인터를 선언합니다. 그러나 이 특성은 제공한 나머지 코드에서는 설정되거나 사용되지 않습니다.

bool deviceConnected = false; BLE 클라이언트가 현재 서버에 연결되어 있는지 여부를 추적하는 부울 변수입니다. false로 시작하여 연결이 설정되면 true로 설정됩니다.

bool oldDeviceConnected = false; 연결 상태의 변화를 추적하는 데 도움이 되는 부울 변수입니다. 장치가 연결이 끊어진 시점을 감지하기 위해 루프에서 사용됩니다.

const int ledPin1 = 27; 에 const int ledPin4 = 33; 네 개의 LED가 연결된 GPIO 핀 번호를 나타내는 상수를 선언합니다. const 키워드는 설정된 후에는 값이 변경되지 않음을 나타냅니다.

bool led1State = false; to bool led4State = false; 각 LED의 상태에 대한 부울 변수를 거짓으로 시작하여 LED가 꺼짐에 해당하는 값으로 선언합니다. 클라이언트에서 수신한 BLE 명령에 따라 해당 LED를 켜거나 끄기 위해 참 또는 거짓으로 토글됩니다.

이 설정은 ESP32가 사용자 인터페이스(모바일 앱 등)와 물리적 하드웨어(LED, 모터, 센서 등) 사이의 다리 역할을 하는 IoT 애플리케이션에서 일반적입니다. ESP32는 앱의 명령을 기다렸다가 그에 따라 하드웨어를 제어하는 동시에 하드웨어의 상태를 앱에 다시 보고합니다.

 

class MyCallbacks: public BLECharacteristicCallbacks {

    void onWrite(BLECharacteristic *pCharacteristic) {

      std::string value = pCharacteristic->getValue();




   if (value.length() > 0) {

            if (value == "199") {

                led1State = true;

                Serial.println("LED 1 is ON");

                digitalWrite(ledPin1, HIGH);

            } else if (value == "222") {

                led1State = false;

                Serial.println("LED 1 is OFF");

                digitalWrite(ledPin1, LOW);

            } else if (value == "333") {

                led2State = true;

                Serial.println("LED 2 is ON");

                digitalWrite(ledPin2, HIGH);

            } else if (value == "444") {

                led2State = false;

                Serial.println("LED 2 is OFF");

                digitalWrite(ledPin2, LOW);

            } else if (value == "555") {

                led3State = true;

                Serial.println("LED 3 is ON");

                digitalWrite(ledPin3, HIGH);

            } else if (value == "666") {

                led3State = false;

                Serial.println("LED 3 is OFF");

                digitalWrite(ledPin3, LOW);

            } else if (value == "777") {

                led4State = true;

                Serial.println("LED 4 is ON");

                digitalWrite(ledPin4, HIGH);

            } else if (value == "888") {

                led4State = false;

                Serial.println("LED 4 is OFF");

                digitalWrite(ledPin4, LOW);

            }

        }

    }

};

 

 

MyCallbacks 클래스는 ESP32용 BLE 라이브러리에서 제공하는 BLECharacteristicCallbacks 클래스에서 상속하는 사용자 지정 클래스입니다. 이 사용자 지정 클래스는 onWrite 메서드를 재정의하여 BLE 클라이언트가 이 콜백에 연결된 특성에 데이터를 쓸 때 특정 동작을 정의합니다.

다음은 MyCallbacks 내부의 onWrite 메서드에 대한 분석입니다:

 

  • onWrite 메서드가 트리거되면 먼저 std::문자열을 반환하는 pCharacteristic->getValue()를 사용하여 특성에 기록된 값을 검색합니다.
  • 그런 다음 value.length() > 0을 사용하여 수신된 문자열 값이 비어 있지 않은지 확인합니다. 데이터가 있는 경우 값을 미리 정의된 명령(예: "199", "222" 등)과 비교하기 위해 계속 진행합니다.
  • 수신된 명령에 따라 LED의 상태 변수(led1State, led2State, led3State, led4State)가 각각 LED의 "켜짐" 및 "꺼짐" 상태를 나타내는 true 또는 false로 업데이트됩니다.
  • 각 명령에 대해 어떤 LED가 켜져 있는지 또는 꺼져 있는지를 나타내는 메시지를 직렬 모니터에 출력하는 Serial.println 호출이 수반됩니다. 이는 개발 중 시스템의 동작을 디버깅하고 모니터링하는 데 유용합니다.
  • 마지막으로 해당 LED 핀 번호와 상태("켜짐"의 경우 HIGH, "꺼짐"의 경우 LOW)를 사용하여 디지털 쓰기 함수를 호출합니다. 이 함수는 ESP32의 GPIO 핀을 직접 제어하여 연결된 LED를 켜거나 끕니다.

 

예를 들어

 

  • BLE 클라이언트가 "199"를 보내면 ESP32는 이 값을 수신하여 led1State를 true로 설정하고 직렬 모니터에 "LED 1은 켜짐"을 출력한 다음 LED 1에 연결된 GPIO 핀을 HIGH로 설정하여 LED를 켭니다.
  • "222"를 받으면 LED 1을 끄고 다른 LED도 해당 값에 따라 비슷한 조치가 취해집니다.

 

class MyServerCallbacks: public BLEServerCallbacks {

    void onConnect(BLEServer* pServer) {

      deviceConnected = true;

      BLEDevice::startAdvertising();

    };

    void onDisconnect(BLEServer* pServer) {

      deviceConnected = false;

    }

};

 

MyServerCallbacks 클래스는 ESP32 BLE Arduino 라이브러리의 일부인 BLEServerCallbacks에서 상속하는 사용자 정의 클래스입니다. 이 클래스는 서버의 BLE 연결 상태와 관련된 이벤트를 처리하도록 설계되었습니다. BLEServerCallbacks에서 상속함으로써 MyServerCallbacks는 두 가지 주요 이벤트 핸들러 메서드인 onConnect와 onDisconnect를 재정의할 수 있습니다.

 

 

각 메서드의 기능은 다음과 같습니다:

 

  • void onConnect(BLEServer* pServer): 이 메서드는 BLE 클라이언트가 ESP32 BLE 서버와 연결을 설정할 때마다 호출됩니다. 이 메서드 내에서 전역 변수 deviceConnected는 활성 장치 연결을 나타내기 위해 true로 설정됩니다. 연결이 설정된 직후 BLEDevice::startAdvertising() 함수가 호출되어 광고가 다시 시작됩니다. 이렇게 하면 한 클라이언트에 연결되어 있는 동안에도 다른 클라이언트에서 ESP32를 검색할 수 있으므로 다중 연결을 지원하는 디바이스에 유용합니다.
  • void onDisconnect(BLEServer* pServer): 이 메서드는 연결된 BLE 클라이언트가 ESP32 BLE 서버에서 연결을 끊을 때 호출됩니다. deviceConnected 변수는 서버가 더 이상 클라이언트에 연결되지 않았음을 반영하여 false로 설정됩니다.

 

BLE 서버 설정 내에서 이러한 콜백을 사용하는 것은 서버의 상태를 관리하고 클라이언트가 연결 또는 연결 해제될 때 적절한 조치를 취하는 데 매우 중요합니다. 예를 들어 디바이스가 언제 연결되었는지 파악하면 필요할 때만 광고를 표시하여 전력 소비를 관리하거나 활성 연결 중에만 발생해야 하는 다른 작업을 트리거하는 데 사용할 수 있습니다. 마찬가지로 연결 끊김을 감지하는 것은 연결 상태를 정리하고 향후 연결을 위해 서버를 준비하는 데 필수적일 수 있습니다.

 

 

void setup() {

  Serial.begin(9600);

  Serial.println("Connect to MyESP32");

  BLEDevice::init("MyESP32");

  pServer = BLEDevice::createServer();

  pServer->setCallbacks(new MyServerCallbacks());

  pinMode(ledPin1, OUTPUT);

  pinMode(ledPin2, OUTPUT);

  pinMode(ledPin3, OUTPUT);

  pinMode(ledPin4, OUTPUT);

  BLEService *pService = pServer->createService("0000180d-0000-1000-8000-00805f9b34fb");

  pCharacteristic = pService->createCharacteristic(

      "00002a37-0000-1000-8000-00805f9b34fb",

      BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_WRITE // Added write property

  );

  pCharacteristic->addDescriptor(new BLE2902());

  pCharacteristic->setCallbacks(new MyCallbacks());

  pService->start();

  BLEAdvertising *pAdvertising = pServer->getAdvertising();

  pAdvertising->start();

  // Initialize BLE client for central role

  pClient = BLEDevice::createClient();

}

 

 

 

setup() 함수는 프로그램이 시작될 때 한 번 실행되는 아두이노 스케치의 기본 부분입니다. 변수, 핀 모드, 라이브러리 사용 시작 등을 초기화하는 데 사용됩니다. 주어진 코드의 맥락에서 setup() 함수는 ESP32가 BLE 서버로 작동하도록 구성하고 LED에 연결된 핀을 초기화합니다. 다음은 코드의 각 섹션이 수행하는 작업의 세부 내용입니다:

 

  • begin(9600); 초당 9600비트로 직렬 통신을 초기화합니다. 이를 통해 디버깅 목적으로 ESP32에서 컴퓨터로 메시지를 보낼 수 있습니다.
  • println("Connect to MyESP32"); 직렬 모니터에 메시지를 전송하여 코드가 실행되기 시작했는지 디버깅하고 확인하는 데 유용하게 사용할 수 있습니다.
  • BLEDevice::init("MyESP32"); BLE 스택을 초기화하고 스캔하는 동안 다른 BLE 디바이스에 표시될 디바이스 이름을 "MyESP32"로 설정합니다.
  • pServer = BLEDevice::createServer(); ESP32에 BLE 서버 인스턴스를 생성하고 이를 글로벌 포인터 pServer에 할당합니다.
  • pServer->setCallbacks(new MyServerCallbacks()); 연결 및 연결 해제 이벤트를 처리할 커스텀 서버 콜백 클래스 MyServerCallbacks를 서버에 할당합니다.
  • pinMode(ledPin1, OUTPUT); 에 핀모드(ledPin4, OUTPUT); LED에 연결된 GPIO 핀을 출력으로 설정합니다. 이렇게 하면 ESP32가 이 핀을 HIGH 또는 LOW로 설정하여 LED를 제어할 수 있습니다.
  • BLEService *pService = pServer->createService(...); BLE 서비스를 식별하는 표준 방법인 지정된 UUID(범용 고유 식별자)를 사용하여 새 BLE 서비스를 생성합니다.
  • pCharacteristic = pService->createCharacteristic(...); 클라이언트가 읽거나 쓸 수 있는 서비스와 관련된 특성을 생성합니다. 특성에는 읽기와 쓰기를 모두 허용하는 속성이 주어집니다.
  • pCharacteristic->addDescriptor(new BLE2902()); 특성에 설명자를 추가합니다. BLE2902 디스크립터는 일반적으로 알림 또는 표시를 활성화하여 클라이언트가 특성 값의 업데이트를 구독할 수 있도록 하는 데 사용됩니다.
  • pCharacteristic->setCallbacks(new MyCallbacks()); BLE 클라이언트가 특성을 기록할 때 사용자 지정 콜백을 설정합니다.
  • pService->start(); BLE 서비스를 시작하여 클라이언트가 활성화하고 검색할 수 있도록 합니다.
  • BLEAdvertising *pAdvertising = pServer->getAdvertising(); pAdvertising->start(); BLE 서비스 광고를 시작하여 장치를 검색하는 BLE 클라이언트에 표시되도록 합니다.
  • pClient = BLEDevice::createClient(); BLE 클라이언트 인스턴스를 생성합니다. 이 줄은 BLE 서버 설정의 맥락에서 벗어난 것으로 보이며 제공된 코드 스니펫의 다른 곳에서는 사용되지 않습니다. 일반적으로 ESP32가 클라이언트로서 다른 BLE 장치에 연결하려는 경우에 사용됩니다.

 

setup() 함수는 ESP32가 BLE 클라이언트와 통신하고 수신된 BLE 명령에 따라 연결된 LED를 제어하는 데 필요한 BLE 환경을 설정합니다.

 

 

void loop() {

  if (deviceConnected) {

    String ledStates = String(led1State) + "," + String(led2State) + "," + String(led3State) + "," + String(led4State);

    pCharacteristic->setValue(ledStates.c_str());

    pCharacteristic->notify();

    // Handle LED control commands from the central device

    delay(1000); // Adjust the update interval as needed

  }

  // Disconnecting

  if (!deviceConnected && oldDeviceConnected) {

    delay(500); // Give the Bluetooth stack the chance to get things ready

    pServer->startAdvertising(); // Restart advertising

    Serial.println("Start advertising");

    oldDeviceConnected = deviceConnected;

  }

  // Connecting

  if (deviceConnected && !oldDeviceConnected) {

    // Do stuff here on connecting

    oldDeviceConnected = deviceConnected;

  }

}

 

 

 

ESP32 프로그램의 loop() 함수에서는 BLE 연결 및 LED 상태를 지속적으로 모니터링하고 처리합니다. 이 함수는 처음에 BLE 디바이스가 연결되어 있는지 확인합니다. 장치가 실제로 연결되어 있으면 쉼표로 구분된 4개의 LED 상태를 하나의 문자열로 연결합니다. 그런 다음 이 문자열을 BLE 특성 값으로 설정하고 연결된 BLE 클라이언트에 알림을 전송하여 클라이언트가 최신 LED 상태로 업데이트되도록 합니다. 이 프로세스는 지연(1000) 문에 표시된 대로 매초마다 반복되어 정기적인 업데이트를 제공합니다.

디바이스 연결이 끊어지는 시나리오에서 이 함수는 deviceConnected와 oldDeviceConnected를 비교하여 연결 상태의 변화를 감지합니다. 디바이스가 방금 연결이 끊어진 경우(deviceConnected가 false이고 oldDeviceConnected가 true인 경우) ESP32는 BLE 스택이 준비되었는지 확인하기 위해 잠시 기다린 다음 다른 클라이언트가 연결할 수 있도록 광고 자체를 다시 시작합니다. 디버깅 목적으로 광고가 시작되었음을 나타내는 메시지가 직렬 모니터에 인쇄됩니다.

 

 

반대로, 새 연결이 설정되면(deviceConnected가 true이고 oldDeviceConnected가 false로 감지됨) 현재 코드에서는 특정 작업을 수행하지 않지만 이 조건을 사용하여 새 연결이 이루어진 직후 작업을 실행할 수 있습니다.

전반적으로 이 루프는 BLE 연결을 효율적으로 관리하여 ESP32가 항상 새로운 연결에 대비할 수 있도록 하는 동시에 연결된 클라이언트에 LED 상태를 지속적으로 업데이트하여 무선 제어 및 모니터링을 위한 강력한 시스템을 구축합니다.

실제 데모:


 먼저 USB 케이블을 사용하여 ESP32 모듈의 전원을 켭니다. 제 경우에는 ESP32 개발 보드를 사용하고 있습니다. ESP32 모듈의 전원이 켜지면 휴대폰에서 Bluetooth 설정을 열고 장치와 페어링합니다.

 

그런 다음 ESP32 BLE(Bluetooth 저에너지) 용으로 설계된 애플리케이션을 엽니다.

 

 

 

Android 애플리케이션을 열면 ESP32 BLE(Bluetooth 저에너지)에 자동으로 연결되고 '장치 연결됨'이라는 토스트 메시지가 표시됩니다. 그 후 LED를 제어할 준비가 완료됩니다.

 

마지막으로 프로젝트를 테스트합니다.

 

TagsBleble controlling systembluetooth low energycontrolling with bleesp32 bleesp32 ble controlling

 

위 글 출처: Controlling an LED using ESP32 BLE (Bluetooth Low Energy) 

 

 

 

반응형