6ae01a0809
BLE UART1(GPIO20(TX), GPIO21(RX)) ---> CSC Check ---> SEND BLE ---> Adroid BLE 수신.
217 lines
6.3 KiB
Arduino
217 lines
6.3 KiB
Arduino
/*--------------------------------------
|
|
2026-07-22 PAYLOAD
|
|
|
|
----------------------------------------*/
|
|
|
|
#include <BLEDevice.h>
|
|
#include <BLEServer.h>
|
|
#include <BLEUtils.h>
|
|
#include <BLE2902.h>
|
|
|
|
#define LED_PIN1 8 // 수신 데이터에 따라 제어할 LED ESP32-C3
|
|
#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"
|
|
#define CHARACTERISTIC_UUID_RX "6E400002-B5A3-F393-E0A9-E50E24DCCA9E"
|
|
#define CHARACTERISTIC_UUID_TX "6E400003-B5A3-F393-E0A9-E50E24DCCA9E"
|
|
|
|
// UART1 객체 생성 (USB CDC 대신 GPIO20/21 사용)
|
|
HardwareSerial MySerial(1);
|
|
|
|
|
|
// --- CSC 계산 관련 함수 ---
|
|
char nibbleToAscii(uint8_t nibble) {
|
|
return (nibble < 10) ? ('0' + nibble) : ('A' + (nibble - 10));
|
|
}
|
|
|
|
String calcChecksum(String data) {
|
|
uint32_t sum = 0;
|
|
for (int i = 0; i < data.length(); i++) {
|
|
sum += (uint8_t)data[i];
|
|
}
|
|
uint8_t oneByte = sum & 0xFF;
|
|
|
|
char csc[3];
|
|
csc[0] = nibbleToAscii((oneByte >> 4) & 0x0F);
|
|
csc[1] = nibbleToAscii(oneByte & 0x0F);
|
|
csc[2] = '\0';
|
|
|
|
return String(csc);
|
|
}
|
|
|
|
String verifyPacket(String cmd, String len, String payload, String recvCsc) {
|
|
String body = cmd + len + payload;
|
|
String calcCsc = calcChecksum(body);
|
|
return (calcCsc == recvCsc) ? "True" : "Fault";
|
|
}
|
|
|
|
// --- BLE 서버 콜백 ---
|
|
class MyServerCallbacks : public BLEServerCallbacks {
|
|
void onConnect(BLEServer* pServer) {
|
|
deviceConnected = true;
|
|
};
|
|
void onDisconnect(BLEServer* pServer) {
|
|
deviceConnected = false;
|
|
}
|
|
};
|
|
|
|
// --- BLE RX 콜백 ---
|
|
class MyCallbacks : public BLECharacteristicCallbacks {
|
|
void onWrite(BLECharacteristic *pCharacteristic) {
|
|
String rxValue = pCharacteristic->getValue();
|
|
if (rxValue.length() > 0) {
|
|
Serial.print("BLE Rx: ");
|
|
Serial.println(rxValue);
|
|
|
|
// UART1로 에코
|
|
MySerial.print("Echo to UART: ");
|
|
MySerial.println(rxValue);
|
|
|
|
digitalWrite(LED_PIN1, HIGH); // test LED
|
|
delay(500);
|
|
digitalWrite(LED_PIN1, LOW);
|
|
}
|
|
}
|
|
};
|
|
|
|
void setup() {
|
|
Serial.begin(115200); //USB to Serial Port
|
|
// while (!Serial) { ; }
|
|
// UART1 초기화 (GPIO20=RX, GPIO21=TX)
|
|
MySerial.begin(115200, SERIAL_8N1, 20, 21);
|
|
|
|
// LED 핀 설정
|
|
pinMode(LED_PIN1, OUTPUT);
|
|
pinMode(LED_PIN2, OUTPUT);
|
|
digitalWrite(LED_PIN1, HIGH);
|
|
digitalWrite(LED_PIN2, HIGH);
|
|
|
|
// BLE 초기화
|
|
BLEDevice::init("MMS UART");
|
|
pServer = BLEDevice::createServer();
|
|
pServer->setCallbacks(new MyServerCallbacks());
|
|
|
|
BLEService *pService = pServer->createService(SERVICE_UUID);
|
|
|
|
pTxCharacteristic = pService->createCharacteristic(
|
|
CHARACTERISTIC_UUID_TX,
|
|
BLECharacteristic::PROPERTY_NOTIFY
|
|
);
|
|
pTxCharacteristic->addDescriptor(new BLE2902());
|
|
|
|
pRxCharacteristic = pService->createCharacteristic(
|
|
CHARACTERISTIC_UUID_RX,
|
|
BLECharacteristic::PROPERTY_WRITE
|
|
);
|
|
pRxCharacteristic->setCallbacks(new MyCallbacks());
|
|
|
|
pService->start();
|
|
pServer->getAdvertising()->start();
|
|
Serial.println("Waiting a client connection to notify...");
|
|
}
|
|
|
|
void loop() {
|
|
if (deviceConnected) {
|
|
digitalWrite(LED_PIN2, LOW);
|
|
|
|
// UART1에서 들어온 데이터를 BLE로 전송
|
|
if (MySerial.available() > 0) {
|
|
String uartData = MySerial.readStringUntil('\n');
|
|
uartData.trim();
|
|
|
|
if (uartData.length() > 7) {
|
|
Serial.print("UART Rx(BLE SEND): ");
|
|
Serial.println(uartData);
|
|
|
|
// 파싱: CMD(1) + LEN(4) + PAYLOAD + CSC(2)
|
|
String cmd = uartData.substring(0, 1);
|
|
String len = uartData.substring(1, 5);
|
|
String payload = uartData.substring(5, uartData.length() - 2);
|
|
String recvCsc = uartData.substring(uartData.length() - 2);
|
|
|
|
Serial.print("CMD: "); Serial.println(cmd);
|
|
Serial.print("LEN: "); Serial.println(len);
|
|
Serial.print("PAYLOAD: "); Serial.println(payload);
|
|
Serial.print("Recv CSC: "); Serial.println(recvCsc);
|
|
|
|
String result = verifyPacket(cmd, len, payload, recvCsc);
|
|
Serial.print("CSC Verify Result: ");
|
|
Serial.println(result);
|
|
|
|
if (result == "True") {
|
|
// LED ON
|
|
digitalWrite(LED_PIN1, HIGH);
|
|
|
|
// BLE Notify 전송 (True일 때만)
|
|
pTxCharacteristic->setValue(uartData.c_str());
|
|
pTxCharacteristic->notify();
|
|
Serial.println("Sent to BLE (Notify).");
|
|
|
|
delay(500);
|
|
digitalWrite(LED_PIN1, LOW);
|
|
} else {
|
|
// Fault일 경우 데이터 버림, LED OFF
|
|
Serial.println("Fault detected, data discarded.");
|
|
digitalWrite(LED_PIN1, HIGH);
|
|
delay(100);
|
|
digitalWrite(LED_PIN1, LOW);
|
|
delay(100);
|
|
digitalWrite(LED_PIN1, HIGH);
|
|
delay(100);
|
|
digitalWrite(LED_PIN1, LOW);
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
digitalWrite(LED_PIN2, HIGH);
|
|
}
|
|
|
|
if (!deviceConnected && oldDeviceConnected) {
|
|
delay(500);
|
|
pServer->startAdvertising();
|
|
Serial.println("start advertising");
|
|
oldDeviceConnected = deviceConnected;
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
|
|
/*
|
|
방금 올려주신 BLE/UART 브리지 코드에 UART 수신 데이터 CSC 검증을 그대로 적용한 버전을 준비했습니다.
|
|
이제 시리얼로 입력된 패킷을 <CMD><LEN><PAYLOAD><CSC> 구조로 파싱하고, CSC가 맞으면 "True", 틀리면 "Fault"를 출력하며 LED1 상태도 반영합니다.
|
|
CSC 계산 함수(calcChecksum)와 검증 함수(verifyPacket) 추가.
|
|
loop()에서 UART 수신 시 패킷을 파싱하고 CSC 검증 수행.
|
|
결과 "True"/"Fault"를 시리얼 출력.
|
|
LED1은 "True"일 때 ON, "Fault"일 때 OFF.
|
|
BLE Notify는 원본 UART 데이터를 그대로 전송.
|
|
|
|
|
|
Fault 일떄는 데이터를 버리고, 다음 데이터 수신하여 true이면 ble로 전송하도록 할 것
|
|
-> CSC 검증 후 "Fault"일 경우:
|
|
BLE 전송 하지 않음.
|
|
데이터 버림.
|
|
LED1 OFF.
|
|
"True"일 경우:
|
|
BLE Notify 전송.
|
|
LED1 ON.
|
|
*/ |