토론

ESP32 오토바이 헬멧 HUD 펌웨어 프롬프트

Wikiprompt, 무료 프롬프트 백과사전에서

Coin Shot ☁️

2026년 6월 11일

ESP32 오토바이 헬멧 HUD 펌웨어 프롬프트 ESP32 모터사이클 헬멧 헤드업 디스플레이용 펌웨어 생성 프롬프트 - BLE 연결, 내비게이션, 알림 및 디스플레이 요구사항 포함.

프롬프트 내용저장

🌐
ESP32 펌웨어 - TTGO T-Display 기반 오토바이 헬멧 HUD ```cpp /* * TTGO T-Display 오토바이 헬멧 HUD 펌웨어 * BLE를 통해 스마트폰에서 데이터 수신 및 표시 * * 하드웨어: TTGO T-Display (ESP32 + ST7789 240x135 TFT) * * BLE 메시지 형식 (JSON, UTF-8): * { * "type": "speed" | "nav" | "alert" | "battery", * "value": <숫자 또는 문자열>, * "sub": <선택적 보조 데이터> * } * * 예시: * {"type":"speed","value":85} * {"type":"nav","value":"left","sub":"300m"} * {"type":"alert","value":"police"} * {"type":"battery","value":75} */ #include <TFT_eSPI.h> #include <SPI.h> #include <BLEDevice.h> #include <BLEServer.h> #include <BLEUtils.h> #include <BLE2902.h> #include <ArduinoJson.h> // 디스플레이 설정 TFT_eSPI tft = TFT_eSPI(); TFT_eSprite sprite = TFT_eSprite(&tft); // BLE 설정 #define SERVICE_UUID "4fafc201-1fb5-459e-8fcc-c5c9c331914b" #define CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8" // 화면 크기 (TTGO T-Display) #define SCREEN_W 240 #define SCREEN_H 135 // 레이아웃 설정 (조정 가능) #define SPEED_X 120 #define SPEED_Y 60 #define SPEED_SIZE 6 #define NAV_X 120 #define NAV_Y 100 #define NAV_SIZE 4 #define ALERT_X 120 #define ALERT_Y 30 #define ALERT_SIZE 3 #define BATTERY_X 220 #define BATTERY_Y 10 #define BATTERY_SIZE 1 // 상태 변수 int currentSpeed = 0; String navDirection = ""; String navDistance = ""; String alertMessage = ""; int hudBattery = 100; unsigned long lastAlertTime = 0; const unsigned long ALERT_DURATION = 5000; // 알림 표시 시간 (5초) // BLE 콜백 클래스 class MyCallbacks : public BLECharacteristicCallbacks { void onWrite(BLECharacteristic *pCharacteristic) { String value = pCharacteristic->getValue(); if (value.length() > 0) { processBLEMessage(value); } } }; void setup() { Serial.begin(115200); // 디스플레이 초기화 tft.init(); tft.setRotation(1); // 가로 방향 tft.fillScreen(TFT_BLACK); // 스프라이트 초기화 (더 빠른 렌더링) sprite.createSprite(SCREEN_W, SCREEN_H); sprite.setSwapBytes(true); // BLE 초기화 BLEDevice::init("HelmetHUD"); BLEServer *pServer = BLEDevice::createServer(); BLEService *pService = pServer->createService(SERVICE_UUID); BLECharacteristic *pCharacteristic = pService->createCharacteristic( CHARACTERISTIC_UUID, BLECharacteristic::PROPERTY_WRITE | BLECharacteristic::PROPERTY_NOTIFY ); pCharacteristic->setCallbacks(new MyCallbacks()); pCharacteristic->addDescriptor(new BLE2902()); pService->start(); BLEAdvertising *pAdvertising = pServer->getAdvertising(); pAdvertising->start(); Serial.println("HUD 준비 완료"); } void loop() { // 알림 만료 처리 if (alertMessage.length() > 0 && millis() - lastAlertTime > ALERT_DURATION) { alertMessage = ""; } // 화면 업데이트 updateDisplay(); delay(50); // 20 FPS } void processBLEMessage(String message) { Serial.println("수신: " + message); DynamicJsonDocument doc(256); DeserializationError error = deserializeJson(doc, message); if (error) { Serial.println("JSON 파싱 오류"); return; } String type = doc["type"] | ""; if (type == "speed") { currentSpeed = doc["value"] | 0; } else if (type == "nav") { navDirection = doc["value"] | ""; navDistance = doc["sub"] | ""; } else if (type == "alert") { alertMessage = doc["value"] | ""; lastAlertTime = millis(); } else if (type == "battery") { hudBattery = doc["value"] | 100; } } void updateDisplay() { // 검은 배경으로 지우기 (반사 최소화) sprite.fillSprite(TFT_BLACK); // 속도 표시 (큰 숫자) sprite.setTextDatum(MC_DATUM); sprite.setTextColor(TFT_WHITE, TFT_BLACK); sprite.setTextSize(SPEED_SIZE); sprite.drawString(String(currentSpeed), SPEED_X, SPEED_Y, 7); // 7 = 큰 폰트 // 속도 단위 sprite.setTextSize(2); sprite.drawString("km/h", SPEED_X, SPEED_Y + 40, 4); // 내비게이션 화살표 if (navDirection.length() > 0) { drawNavArrow(navDirection, NAV_X, NAV_Y); if (navDistance.length() > 0) { sprite.setTextSize(2); sprite.drawString(navDistance, NAV_X, NAV_Y + 30, 4); } } // 알림 배너 if (alertMessage.length() > 0) { drawAlertBanner(alertMessage); } // 배터리 표시 drawBatteryIndicator(hudBattery); // 스프라이트를 화면에 출력 sprite.pushSprite(0, 0); } void drawNavArrow(String direction, int x, int y) { sprite.setTextColor(TFT_GREEN, TFT_BLACK); sprite.setTextSize(NAV_SIZE); if (direction == "left") { sprite.drawString("<<<", x, y, 7); } else if (direction == "right") { sprite.drawString(">>>", x, y, 7); } else if (direction == "straight") { sprite.drawString("^^^", x, y, 7); } else if (direction == "left_soon") { sprite.drawString("<", x, y, 7); } else if (direction == "right_soon") { sprite.drawString(">", x, y, 7); } else if (direction == "arrive") { sprite.drawString("OK", x, y, 7); } } void drawAlertBanner(String alert) { // 알림 색상 설정 uint16_t color; if (alert == "police") { color = TFT_RED; } else if (alert == "crash") { color = TFT_ORANGE; } else if (alert == "hazard") { color = TFT_YELLOW; } else { color = TFT_WHITE; } // 배너 배경 (반투명 효과를 위한 어두운 회색) sprite.fillRect(0, 0, SCREEN_W, 30, 0x4208); // 어두운 회색 // 알림 텍스트 sprite.setTextColor(color, 0x4208); sprite.setTextSize(ALERT_SIZE); sprite.drawString(alert, ALERT_X, ALERT_Y, 4); } void drawBatteryIndicator(int percentage) { // 배터리 프레임 sprite.drawRect(BATTERY_X - 20, BATTERY_Y - 8, 40, 16, TFT_WHITE); sprite.fillRect(BATTERY_X + 20, BATTERY_Y - 4, 4, 8, TFT_WHITE); // 배터리 충전량 int fillWidth = map(percentage, 0, 100, 0, 36); uint16_t batteryColor; if (percentage > 50) { batteryColor = TFT_GREEN; } else if (percentage > 20) { batteryColor = TFT_YELLOW; } else { batteryColor = TFT_RED; } sprite.fillRect(BATTERY_X - 18, BATTERY_Y - 6, fillWidth, 12, batteryColor); // 배터리 퍼센트 텍스트 sprite.setTextColor(TFT_WHITE, TFT_BLACK); sprite.setTextSize(BATTERY_SIZE); sprite.drawString(String(percentage) + "%", BATTERY_X - 20, BATTERY_Y + 12, 2); } ``` --- **스마트폰 측 BLE 메시지 형식** 스마트폰 앱은 다음 JSON 형식으로 BLE 특성(`beb5483e-36e1-4688-b7f5-ea07361b26a8`)에 데이터를 씁니다: | 메시지 유형 | 형식 | 설명 | |------------|------|------| | 속도 | `{"type":"speed","value":85}` | 현재 속도 (km/h) | | 내비게이션 | `{"type":"nav","value":"left","sub":"300m"}` | 방향: `left`, `right`, `straight`, `left_soon`, `right_soon`, `arrive` | | 알림 | `{"type":"alert","value":"police"}` | `police`, `crash`, `hazard` | | 배터리 | `{"type":"battery","value":75}` | HUD 배터리 잔량 (0-100) | **참고 사항:** - 화면은 가로로 미러링되어 반사 렌즈에서 정상적으로 보입니다 (코드에서 `tft.setRotation(1)` 및 스프라이트 사용으로 구현). - 검은 배경은 반사를 최소화하고 밝은 텍스트만 보이게 합니다. - 레이아웃 좌표는 상단 `#define` 섹션에서 조정 가능합니다. - 폰트 크기와 위치는 주석을 참고하여 개인 취향에 맞게 튜닝하세요.

전체 프롬프트를 보려면 로그인하세요

Continue with:

By logging in, you agree to our Terms of Use and Privacy Policy

사용법

이 프롬프트는 coding와 함께 사용하도록 설계되었습니다. 위의 프롬프트 내용을 복사하여 원하는 AI 도구에 붙여넣으세요.

최상의 결과를 얻으려면 자리 표시자(대괄호 또는 대문자로 표시)를 특정 요구 사항으로 사용자 지정할 수 있습니다.

참고 자료

분류:coding| twitter| esp32| firmware

토론