From ba568a574e2b192c0bd5a06eca55ec260dbd681f Mon Sep 17 00:00:00 2001 From: dj99k Date: Sat, 18 Jul 2026 01:02:30 +0900 Subject: [PATCH] =?UTF-8?q?=ED=8C=8C=EC=9D=BC=EC=9D=84=20"/"=20=EB=A1=9C?= =?UTF-8?q?=20=EC=97=85=EB=A1=9C=EB=93=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- BLE_Serial_rx_tx.ino | 155 ++++++++++++++++++++++++++++++++++++++++ BLE_Serial_rx_tx_01.ino | 155 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 310 insertions(+) create mode 100644 BLE_Serial_rx_tx.ino create mode 100644 BLE_Serial_rx_tx_01.ino diff --git a/BLE_Serial_rx_tx.ino b/BLE_Serial_rx_tx.ino new file mode 100644 index 0000000..3ea899f --- /dev/null +++ b/BLE_Serial_rx_tx.ino @@ -0,0 +1,155 @@ +#include +#include +#include +#include + +#define LED_PIN1 8 // 수신 데이터에 따라 제어할 LED +#define LED_PIN2 7 // BLE 연결 상태 표시 LED + +BLEServer *pServer = NULL; +BLECharacteristic *pTxCharacteristic; // ESP32 -> Central (Notify) +BLECharacteristic *pRxCharacteristic; // Central -> ESP32 (Write) + +bool deviceConnected = false; +bool oldDeviceConnected = false; + +// Nordic UART UUID 세트 (원본 블로그와 동일) +#define SERVICE_UUID "6E400001-B5A3-F393-E0A9-E50E24DCCA9E" // UART service UUID +#define CHARACTERISTIC_UUID_RX "6E400002-B5A3-F393-E0A9-E50E24DCCA9E" // Central -> ESP32 +#define CHARACTERISTIC_UUID_TX "6E400003-B5A3-F393-E0A9-E50E24DCCA9E" // ESP32 -> Central + +// 서버 콜백: 연결 / 해제 상태 갱신 +class MyServerCallbacks : public BLEServerCallbacks { + void onConnect(BLEServer* pServer) { + deviceConnected = true; + }; + void onDisconnect(BLEServer* pServer) { + deviceConnected = false; + } +}; + +// Rx 콜백: Central에서 보낸 데이터를 수신해서 UART와 LED에 반영 +class MyCallbacks : public BLECharacteristicCallbacks { + void onWrite(BLECharacteristic *pCharacteristic) { + // Arduino String 타입으로 받기 (ESP32 BLE 예제와 동일) + String rxValue = pCharacteristic->getValue(); + if (rxValue.length() > 0) { + Serial.print("BLE Rx: "); + Serial.println(rxValue); + digitalWrite(LED_PIN1, LOW); + + /* + // 첫 글자로 LED 제어 (원본 예제와 같은 방식) + char cmd = rxValue[0]; // char cmd = rxValue; -> rwValue[0]; + if (cmd == 'a') { + digitalWrite(LED_PIN1, LOW); // 예: LED ON + } else if (cmd == 'b') { + digitalWrite(LED_PIN1, HIGH); // 예: LED OFF + } + */ + + + // 받은 데이터를 그대로 UART로 에코 (양방향 브리지) + Serial.print("Echo to UART: "); + Serial.println(rxValue); + digitalWrite(LED_PIN1, HIGH); + } + } +}; + +void setup() { + // UART 초기화 + Serial.begin(115200); + while (!Serial) { + ; // USB 시리얼 준비 대기 (PC 연결 환경에 따라 생략 가능) + } + + // LED 핀 설정 (원본 글과 동일 핀) + pinMode(LED_PIN1, OUTPUT); + pinMode(LED_PIN2, OUTPUT); + digitalWrite(LED_PIN1, HIGH); // 초기 OFF + digitalWrite(LED_PIN2, HIGH); // 초기 OFF (연결 안 된 상태 표시) + + // 1) BLE Device 생성 (장치 이름 설정) + BLEDevice::init("ECPC3 UART"); + + // 2) BLE Server 생성 및 콜백 등록 + pServer = BLEDevice::createServer(); + pServer->setCallbacks(new MyServerCallbacks()); + + // 3) BLE Service 생성 + BLEService *pService = pServer->createService(SERVICE_UUID); + + // 4) TX Characteristic 생성 (Notify) + pTxCharacteristic = pService->createCharacteristic( + CHARACTERISTIC_UUID_TX, + BLECharacteristic::PROPERTY_NOTIFY + ); + pTxCharacteristic->addDescriptor(new BLE2902()); // Client에서 Notify 활성화용 + + // 5) RX Characteristic 생성 (Write) + pRxCharacteristic = pService->createCharacteristic( + CHARACTERISTIC_UUID_RX, + BLECharacteristic::PROPERTY_WRITE + ); + pRxCharacteristic->setCallbacks(new MyCallbacks()); // 수신 처리 콜백 연결 + + // 6) Service 시작 + pService->start(); + + // 7) Advertising 시작 (스캔 가능하게) + pServer->getAdvertising()->start(); + Serial.println("Waiting a client connection to notify..."); +} + +void loop() { + // BLE 연결 상태에 따라 LED2 제어 및 통신 처리 + if (deviceConnected) { + digitalWrite(LED_PIN2, LOW); // 연결됨 표시 + + // UART에서 들어온 데이터를 읽어서 BLE로 전송 (양방향: UART -> BLE) + if (Serial.available() > 0) { + String uartData = Serial.readStringUntil('\n'); // 한 줄 단위로 읽기 + uartData.trim(); // 앞뒤 공백 제거 + + if (uartData.length() > 0) { + Serial.print("UART Rx: "); + Serial.println(uartData); + + // BLE TX characteristic에 값 설정 후 Notify + pTxCharacteristic->setValue(uartData.c_str()); + pTxCharacteristic->notify(); + + Serial.println("Sent to BLE (Notify)."); + } + } + + } else { + digitalWrite(LED_PIN2, HIGH); // 연결 안 됨 표시 + } + + // disconnect 처리: 끊어진 후 다시 광고 시작 (원본 예제 패턴) + if (!deviceConnected && oldDeviceConnected) { + delay(500); // BLE 스택 정리 시간 + pServer->startAdvertising(); // 광고 재시작 + Serial.println("start advertising"); + oldDeviceConnected = deviceConnected; + } + + // connect 처리: 최초 연결 시 한 번만 처리할 내용이 있다면 여기에 + if (deviceConnected && !oldDeviceConnected) { + // 연결 직후에만 실행할 코드가 있으면 여기에 추가 + digitalWrite(LED_PIN1, HIGH); + delay(500); + digitalWrite(LED_PIN1, LOW); + delay(500); + digitalWrite(LED_PIN1, HIGH); + delay(500); + digitalWrite(LED_PIN1, LOW); + oldDeviceConnected = deviceConnected; + } + + // 너무 자주 패킷을 보내면 스택이 혼잡해질 수 있으므로, 짧게 딜레이 + delay(10); +} + diff --git a/BLE_Serial_rx_tx_01.ino b/BLE_Serial_rx_tx_01.ino new file mode 100644 index 0000000..3ea899f --- /dev/null +++ b/BLE_Serial_rx_tx_01.ino @@ -0,0 +1,155 @@ +#include +#include +#include +#include + +#define LED_PIN1 8 // 수신 데이터에 따라 제어할 LED +#define LED_PIN2 7 // BLE 연결 상태 표시 LED + +BLEServer *pServer = NULL; +BLECharacteristic *pTxCharacteristic; // ESP32 -> Central (Notify) +BLECharacteristic *pRxCharacteristic; // Central -> ESP32 (Write) + +bool deviceConnected = false; +bool oldDeviceConnected = false; + +// Nordic UART UUID 세트 (원본 블로그와 동일) +#define SERVICE_UUID "6E400001-B5A3-F393-E0A9-E50E24DCCA9E" // UART service UUID +#define CHARACTERISTIC_UUID_RX "6E400002-B5A3-F393-E0A9-E50E24DCCA9E" // Central -> ESP32 +#define CHARACTERISTIC_UUID_TX "6E400003-B5A3-F393-E0A9-E50E24DCCA9E" // ESP32 -> Central + +// 서버 콜백: 연결 / 해제 상태 갱신 +class MyServerCallbacks : public BLEServerCallbacks { + void onConnect(BLEServer* pServer) { + deviceConnected = true; + }; + void onDisconnect(BLEServer* pServer) { + deviceConnected = false; + } +}; + +// Rx 콜백: Central에서 보낸 데이터를 수신해서 UART와 LED에 반영 +class MyCallbacks : public BLECharacteristicCallbacks { + void onWrite(BLECharacteristic *pCharacteristic) { + // Arduino String 타입으로 받기 (ESP32 BLE 예제와 동일) + String rxValue = pCharacteristic->getValue(); + if (rxValue.length() > 0) { + Serial.print("BLE Rx: "); + Serial.println(rxValue); + digitalWrite(LED_PIN1, LOW); + + /* + // 첫 글자로 LED 제어 (원본 예제와 같은 방식) + char cmd = rxValue[0]; // char cmd = rxValue; -> rwValue[0]; + if (cmd == 'a') { + digitalWrite(LED_PIN1, LOW); // 예: LED ON + } else if (cmd == 'b') { + digitalWrite(LED_PIN1, HIGH); // 예: LED OFF + } + */ + + + // 받은 데이터를 그대로 UART로 에코 (양방향 브리지) + Serial.print("Echo to UART: "); + Serial.println(rxValue); + digitalWrite(LED_PIN1, HIGH); + } + } +}; + +void setup() { + // UART 초기화 + Serial.begin(115200); + while (!Serial) { + ; // USB 시리얼 준비 대기 (PC 연결 환경에 따라 생략 가능) + } + + // LED 핀 설정 (원본 글과 동일 핀) + pinMode(LED_PIN1, OUTPUT); + pinMode(LED_PIN2, OUTPUT); + digitalWrite(LED_PIN1, HIGH); // 초기 OFF + digitalWrite(LED_PIN2, HIGH); // 초기 OFF (연결 안 된 상태 표시) + + // 1) BLE Device 생성 (장치 이름 설정) + BLEDevice::init("ECPC3 UART"); + + // 2) BLE Server 생성 및 콜백 등록 + pServer = BLEDevice::createServer(); + pServer->setCallbacks(new MyServerCallbacks()); + + // 3) BLE Service 생성 + BLEService *pService = pServer->createService(SERVICE_UUID); + + // 4) TX Characteristic 생성 (Notify) + pTxCharacteristic = pService->createCharacteristic( + CHARACTERISTIC_UUID_TX, + BLECharacteristic::PROPERTY_NOTIFY + ); + pTxCharacteristic->addDescriptor(new BLE2902()); // Client에서 Notify 활성화용 + + // 5) RX Characteristic 생성 (Write) + pRxCharacteristic = pService->createCharacteristic( + CHARACTERISTIC_UUID_RX, + BLECharacteristic::PROPERTY_WRITE + ); + pRxCharacteristic->setCallbacks(new MyCallbacks()); // 수신 처리 콜백 연결 + + // 6) Service 시작 + pService->start(); + + // 7) Advertising 시작 (스캔 가능하게) + pServer->getAdvertising()->start(); + Serial.println("Waiting a client connection to notify..."); +} + +void loop() { + // BLE 연결 상태에 따라 LED2 제어 및 통신 처리 + if (deviceConnected) { + digitalWrite(LED_PIN2, LOW); // 연결됨 표시 + + // UART에서 들어온 데이터를 읽어서 BLE로 전송 (양방향: UART -> BLE) + if (Serial.available() > 0) { + String uartData = Serial.readStringUntil('\n'); // 한 줄 단위로 읽기 + uartData.trim(); // 앞뒤 공백 제거 + + if (uartData.length() > 0) { + Serial.print("UART Rx: "); + Serial.println(uartData); + + // BLE TX characteristic에 값 설정 후 Notify + pTxCharacteristic->setValue(uartData.c_str()); + pTxCharacteristic->notify(); + + Serial.println("Sent to BLE (Notify)."); + } + } + + } else { + digitalWrite(LED_PIN2, HIGH); // 연결 안 됨 표시 + } + + // disconnect 처리: 끊어진 후 다시 광고 시작 (원본 예제 패턴) + if (!deviceConnected && oldDeviceConnected) { + delay(500); // BLE 스택 정리 시간 + pServer->startAdvertising(); // 광고 재시작 + Serial.println("start advertising"); + oldDeviceConnected = deviceConnected; + } + + // connect 처리: 최초 연결 시 한 번만 처리할 내용이 있다면 여기에 + if (deviceConnected && !oldDeviceConnected) { + // 연결 직후에만 실행할 코드가 있으면 여기에 추가 + digitalWrite(LED_PIN1, HIGH); + delay(500); + digitalWrite(LED_PIN1, LOW); + delay(500); + digitalWrite(LED_PIN1, HIGH); + delay(500); + digitalWrite(LED_PIN1, LOW); + oldDeviceConnected = deviceConnected; + } + + // 너무 자주 패킷을 보내면 스택이 혼잡해질 수 있으므로, 짧게 딜레이 + delay(10); +} +